/* * This function compares two net addresses by family and returns TRUE * if they are the same host. * If there is any doubt, return FALSE. * The AF_INET family is handled as a special case so that address mbufs * don't need to be saved to store "struct in_addr", which is only 4 bytes. * Ditto for AF_INET6 which is only 16 bytes. */ static int netaddr_match( int family, union nethostaddr *haddr, mbuf_t nam) { struct sockaddr_in *inetaddr; struct sockaddr_in6 *inet6addr; switch (family) { case AF_INET: inetaddr = mbuf_data(nam); if ((inetaddr->sin_family == AF_INET) && (inetaddr->sin_addr.s_addr == haddr->had_inetaddr)) return (1); break; case AF_INET6: inet6addr = mbuf_data(nam); if ((inet6addr->sin6_family == AF_INET6) && !bcmp(&inet6addr->sin6_addr, &haddr->had_inet6addr, sizeof(inet6addr->sin6_addr))) return (1); break; } return (0); }
/* ----------------------------------------------------------------------------- called from pppenet_proto when data need to be sent ----------------------------------------------------------------------------- */ int pptp_ip_output(mbuf_t m, u_int32_t from, u_int32_t to) { struct ip *ip, ip_data; #if 0 u_int8_t *d, i; d = mtod(m, u_int8_t *); for (i = 0; i < 64; i+=16) { IOLog("pptp_ip_output: data 0x %x %x %x %x %x %x %x %x - %x %x %x %x %x %x %x %x\n", d[i+0],d[i+1],d[i+2],d[i+3],d[i+4],d[i+5], d[i+6], d[i+7], d[i+8], d[i+9], d[i+10], d[i+11], d[i+12], d[i+13], d[i+14], d[i+15]); } #endif if (mbuf_prepend(&m, sizeof(struct ip), MBUF_WAITOK) != 0) return 1; ip = &ip_data; memcpy(ip, mbuf_data(m), sizeof(ip_data)); ip->ip_tos = 0; ip->ip_off = 0; ip->ip_p = IPPROTO_GRE; ip->ip_len = mbuf_pkthdr_len(m); ip->ip_src.s_addr = from; ip->ip_dst.s_addr = to; ip->ip_ttl = MAXTTL; memcpy(mbuf_data(m), ip, sizeof(ip_data)); lck_mtx_unlock(ppp_domain_mutex); ip_gre_output((struct mbuf *)m); lck_mtx_lock(ppp_domain_mutex); return 0; }
static bool mdict_free_obj(void *ctx, void *obj) { struct MDictElem *el = obj; struct MDict *dict = ctx; cx_free(dict->cx, mbuf_data(&el->key)); cx_free(dict->cx, mbuf_data(&el->val)); cx_free(dict->cx, el); return true; }
int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, uint32_t fDst) { NOREF(pvIfData); int rc = VINF_SUCCESS; ifnet_t pIfNet = vboxNetFltDarwinRetainIfNet(pThis); if (pIfNet) { /* * Create a mbuf for the gather list and push it onto the wire. * * Note! If the interface is in the promiscuous mode we need to send the * packet down the stack so it reaches the driver and Berkeley * Packet Filter (see @bugref{5817}). */ if ((fDst & INTNETTRUNKDIR_WIRE) || vboxNetFltDarwinIsPromiscuous(pThis)) { mbuf_t pMBuf = vboxNetFltDarwinMBufFromSG(pThis, pSG); if (pMBuf) { errno_t err = ifnet_output_raw(pIfNet, PF_LINK, pMBuf); if (err) rc = RTErrConvertFromErrno(err); } else rc = VERR_NO_MEMORY; } /* * Create a mbuf for the gather list and push it onto the host stack. */ if (fDst & INTNETTRUNKDIR_HOST) { mbuf_t pMBuf = vboxNetFltDarwinMBufFromSG(pThis, pSG); if (pMBuf) { /* This is what IONetworkInterface::inputPacket does. */ unsigned const cbEthHdr = 14; mbuf_pkthdr_setheader(pMBuf, mbuf_data(pMBuf)); mbuf_pkthdr_setlen(pMBuf, mbuf_pkthdr_len(pMBuf) - cbEthHdr); mbuf_setdata(pMBuf, (uint8_t *)mbuf_data(pMBuf) + cbEthHdr, mbuf_len(pMBuf) - cbEthHdr); mbuf_pkthdr_setrcvif(pMBuf, pIfNet); /* will crash without this. */ errno_t err = ifnet_input(pIfNet, pMBuf, NULL); if (err) rc = RTErrConvertFromErrno(err); } else rc = VERR_NO_MEMORY; } vboxNetFltDarwinReleaseIfNet(pThis, pIfNet); } return rc; }
/* * Call portmap to lookup a port number for a particular rpc program * Returns non-zero error on failure. */ int krpc_portmap( struct sockaddr_in *sin, /* server address */ u_int prog, u_int vers, u_int proto, /* host order */ u_int16_t *portp) /* network order */ { struct sdata { u_int32_t prog; /* call program */ u_int32_t vers; /* call version */ u_int32_t proto; /* call protocol */ u_int32_t port; /* call port (unused) */ } *sdata; struct rdata { u_int16_t pad; u_int16_t port; } *rdata; mbuf_t m; int error; /* The portmapper port is fixed. */ if (prog == PMAPPROG) { *portp = htons(PMAPPORT); return 0; } error = mbuf_gethdr(MBUF_WAITOK, MBUF_TYPE_DATA, &m); if (error) return error; mbuf_setlen(m, sizeof(*sdata)); mbuf_pkthdr_setlen(m, sizeof(*sdata)); sdata = mbuf_data(m); /* Do the RPC to get it. */ sdata->prog = htonl(prog); sdata->vers = htonl(vers); sdata->proto = htonl(proto); sdata->port = 0; sin->sin_port = htons(PMAPPORT); error = krpc_call(sin, SOCK_DGRAM, PMAPPROG, PMAPVERS, PMAPPROC_GETPORT, &m, NULL); if (error) return error; rdata = mbuf_data(m); if (mbuf_len(m) >= sizeof(*rdata)) { *portp = rdata->port; } if (mbuf_len(m) < sizeof(*rdata) || !rdata->port) error = EPROGUNAVAIL; mbuf_freem(m); return (error); }
/* Network Interface functions */ static errno_t utun_output( ifnet_t interface, mbuf_t data) { struct utun_pcb *pcb = ifnet_softc(interface); errno_t result; if (m_pktlen(data) >= 4) { bpf_tap_out(pcb->utun_ifp, DLT_NULL, data, 0, 0); } if (pcb->utun_flags & UTUN_FLAGS_NO_OUTPUT) { /* flush data */ mbuf_freem(data); return 0; } // otherwise, fall thru to ctl_enqueumbuf if (pcb->utun_ctlref) { int length; // only pass packets to utun-crypto if crypto is enabled and 'suspend data traffic' is not. if ((pcb->utun_flags & (UTUN_FLAGS_CRYPTO | UTUN_FLAGS_CRYPTO_STOP_DATA_TRAFFIC)) == UTUN_FLAGS_CRYPTO) { if (utun_pkt_crypto_output(pcb, &data) == 0) { return 0; } } /* * The ABI requires the protocol in network byte order */ if (m_pktlen(data) >= 4) *(u_int32_t *)mbuf_data(data) = htonl(*(u_int32_t *)mbuf_data(data)); length = mbuf_pkthdr_len(data); result = ctl_enqueuembuf(pcb->utun_ctlref, pcb->utun_unit, data, CTL_DATA_EOR); if (result != 0) { mbuf_freem(data); printf("utun_output - ctl_enqueuembuf failed: %d\n", result); ifnet_stat_increment_out(interface, 0, 0, 1); } else { if (!pcb->utun_ext_ifdata_stats) ifnet_stat_increment_out(interface, 1, length, 0); } } else mbuf_freem(data); return 0; }
static errno_t utun_output(ifnet_t interface, mbuf_t data) { struct utun_pcb *pcb = ifnet_softc(interface); errno_t result; VERIFY(interface == pcb->utun_ifp); if (m_pktlen(data) >= (int32_t)UTUN_HEADER_SIZE(pcb)) { bpf_tap_out(pcb->utun_ifp, DLT_NULL, data, 0, 0); } if (pcb->utun_flags & UTUN_FLAGS_NO_OUTPUT) { /* flush data */ mbuf_freem(data); return 0; } // otherwise, fall thru to ctl_enqueumbuf if (pcb->utun_ctlref) { int length; /* * The ABI requires the protocol in network byte order */ if (m_pktlen(data) >= (int32_t)UTUN_HEADER_SIZE(pcb)) { *(u_int32_t *)mbuf_data(data) = htonl(*(u_int32_t *)mbuf_data(data)); } length = mbuf_pkthdr_len(data); result = ctl_enqueuembuf(pcb->utun_ctlref, pcb->utun_unit, data, CTL_DATA_EOR); if (result != 0) { mbuf_freem(data); printf("utun_output - ctl_enqueuembuf failed: %d\n", result); ifnet_stat_increment_out(interface, 0, 0, 1); } else { if (!pcb->utun_ext_ifdata_stats) ifnet_stat_increment_out(interface, 1, length, 0); } } else mbuf_freem(data); return 0; }
/* ----------------------------------------------------------------------------- callback from ip ----------------------------------------------------------------------------- */ mbuf_t pptp_ip_input(mbuf_t m, int len, int other) { struct ip *ip, ip_data; u_int32_t from; int success; #if 0 u_int8_t *d, i; d = mtod(m, u_int8_t *); for (i = 0; i < 64; i+=16) { IOLog("pptp_ip_input: data 0x %x %x %x %x %x %x %x %x - %x %x %x %x %x %x %x %x\n", d[i+0],d[i+1],d[i+2],d[i+3],d[i+4],d[i+5], d[i+6], d[i+7], d[i+8], d[i+9], d[i+10], d[i+11], d[i+12], d[i+13], d[i+14], d[i+15]); } #endif ip = &ip_data; memcpy(ip, mbuf_data(m), sizeof(ip_data)); from = ip->ip_src.s_addr; /* remove the IP header */ mbuf_adj(m, ip->ip_hl * 4); lck_mtx_lock(ppp_domain_mutex); success = pptp_rfc_lower_input(m, from); lck_mtx_unlock(ppp_domain_mutex); if (success) return NULL; return m; }
bool mdict_put_str(struct MDict *dict, const char *key, unsigned klen, const char *val, unsigned vlen) { char *kptr, *vptr = NULL; struct MDictElem *el; if (val) { vptr = cx_alloc(dict->cx, vlen + 1); if (!vptr) return false; memcpy(vptr, val, vlen); vptr[vlen] = 0; } el = cbtree_lookup(dict->tree, key, klen); if (el) { cx_free(dict->cx, mbuf_data(&el->val)); mbuf_init_fixed_reader(&el->val, vptr, vlen); } else { kptr = cx_alloc(dict->cx, klen + 1); if (!kptr) return false; memcpy(kptr, key, klen); kptr[klen] = 0; el = cx_alloc(dict->cx, sizeof(*el)); if (!el) return false; mbuf_init_fixed_reader(&el->key, kptr, klen); mbuf_init_fixed_reader(&el->val, vptr, vlen); if (!cbtree_insert(dict->tree, el)) return false; } return true; }
/* ----------------------------------------------------------------------------- Handle a CCP packet. `rcvd' is 1 if the packet was received, 0 if it is about to be transmitted. mbuf points to the ccp payload (doesn't include FF03 and 80FD) ----------------------------------------------------------------------------- */ void ppp_comp_ccp(struct ppp_if *wan, mbuf_t m, int rcvd) { u_char *p = mbuf_data(m); int slen; slen = CCP_LENGTH(p); if (slen > mbuf_pkthdr_len(m)) { LOGDBG(wan->net, ("ppp_comp_ccp: not enough data in mbuf (expected = %d, got = %d)\n", slen, mbuf_pkthdr_len(m))); return; } switch (CCP_CODE(p)) { case CCP_CONFREQ: case CCP_TERMREQ: case CCP_TERMACK: /* CCP must be going down - disable compression */ wan->sc_flags &= ~(rcvd ? SC_COMP_RUN : SC_DECOMP_RUN); break; case CCP_CONFACK: if (wan->sc_flags & SC_CCP_OPEN && !(wan->sc_flags & SC_CCP_UP) && slen >= CCP_HDRLEN + CCP_OPT_MINLEN && slen >= CCP_OPT_LENGTH(p + CCP_HDRLEN) + CCP_HDRLEN) { if (rcvd) { /* peer is agreeing to send compressed packets. */ if (wan->rc_state && (*wan->rcomp->decomp_init) (wan->rc_state, p + CCP_HDRLEN, slen - CCP_HDRLEN, ifnet_unit(wan->net), 0, wan->mru, ifnet_flags(wan->net) & IFF_DEBUG)) { wan->sc_flags |= SC_DECOMP_RUN; wan->sc_flags &= ~(SC_DC_ERROR | SC_DC_FERROR); } } else { /* we're agreeing to send compressed packets. */ if (wan->xc_state && (*wan->xcomp->comp_init) (wan->xc_state, p + CCP_HDRLEN, slen - CCP_HDRLEN, ifnet_unit(wan->net), 0, ifnet_mtu(wan->net), ifnet_flags(wan->net) & IFF_DEBUG)) { wan->sc_flags |= SC_COMP_RUN; } } } break; case CCP_RESETACK: if (wan->sc_flags & SC_CCP_UP) { if (rcvd) { if (wan->rc_state && (wan->sc_flags & SC_DECOMP_RUN)) { (*wan->rcomp->decomp_reset)(wan->rc_state); wan->sc_flags &= ~SC_DC_ERROR; } } else { if (wan->xc_state && (wan->sc_flags & SC_COMP_RUN)) (*wan->xcomp->comp_reset)(wan->xc_state); } } break; } }
IOReturn MbufUtils::copyFromBufferToMbuf(mbuf_t mbuf, UInt32 from, UInt32 bufferSize, void *data) { if (bufferSize > (UInt32) MbufUtils::mbufTotalLength(mbuf)-from) { IOLog("MbufUtils::copyFromBufferToMbuf(): Got insufficiently large buffer (mbuf too small).\n"); return kIOReturnNoMemory; } UInt8 *inBuffer = (UInt8 *)data; UInt8 *mbufBuffer = (UInt8 *)mbuf_data(mbuf); size_t mbufLength = mbuf_len(mbuf); UInt32 bytesLeft = bufferSize; skip_mbuf_macro(); while (bytesLeft) { ensure_mbuf_macro(); *mbufBuffer = *inBuffer; ++mbufBuffer; ++inBuffer; --mbufLength; --bytesLeft; } return kIOReturnSuccess; }
static errno_t utun_framer( __unused ifnet_t interface, mbuf_t *packet, __unused const struct sockaddr *dest, __unused const char *desk_linkaddr, const char *frame_type, u_int32_t *prepend_len, u_int32_t *postpend_len) { struct utun_pcb *pcb = ifnet_softc(interface); VERIFY(interface == pcb->utun_ifp); u_int32_t header_length = UTUN_HEADER_SIZE(pcb); if (mbuf_prepend(packet, header_length, MBUF_DONTWAIT) != 0) { printf("utun_framer - ifnet_output prepend failed\n"); ifnet_stat_increment_out(interface, 0, 0, 1); // just return, because the buffer was freed in mbuf_prepend return EJUSTRETURN; } if (prepend_len != NULL) *prepend_len = header_length; if (postpend_len != NULL) *postpend_len = 0; // place protocol number at the beginning of the mbuf *(protocol_family_t *)mbuf_data(*packet) = *(protocol_family_t *)(uintptr_t)(size_t)frame_type; return 0; }
static errno_t utun_framer( __unused ifnet_t interface, mbuf_t *packet, __unused const struct sockaddr *dest, __unused const char *desk_linkaddr, const char *frame_type, u_int32_t *prepend_len, u_int32_t *postpend_len) { if (mbuf_prepend(packet, sizeof(protocol_family_t), MBUF_DONTWAIT) != 0) { printf("utun_framer - ifnet_output prepend failed\n"); ifnet_stat_increment_out(interface, 0, 0, 1); // just return, because the buffer was freed in mbuf_prepend return EJUSTRETURN; } if (prepend_len != NULL) *prepend_len = sizeof(protocol_family_t); if (postpend_len != NULL) *postpend_len = 0; // place protocol number at the beginning of the mbuf *(protocol_family_t *)mbuf_data(*packet) = *(protocol_family_t *)(uintptr_t)(size_t)frame_type; return 0; }
static errno_t utun_ctl_send( __unused kern_ctl_ref kctlref, __unused u_int32_t unit, void *unitinfo, mbuf_t m, __unused int flags) { /* * The userland ABI requires the first four bytes have the protocol family * in network byte order: swap them */ if (m_pktlen(m) >= 4) *(protocol_family_t *)mbuf_data(m) = ntohl(*(protocol_family_t *)mbuf_data(m)); else printf("%s - unexpected short mbuf pkt len %d\n", __func__, m_pktlen(m) ); return utun_pkt_input((struct utun_pcb *)unitinfo, m); }
static int smb_ioc_request( void * hContext, struct smb_header * header, const mbuf_t words, const mbuf_t bytes, mbuf_t response) { struct smbioc_rq krq; bzero(&krq, sizeof(krq)); krq.ioc_version = SMB_IOC_STRUCT_VERSION; krq.ioc_cmd = header->command; /* XXX For large I/O requests where the uint16_t byte count * (ioc_tbc) wraps to 0, this interface will get horribly * confused. I don't think we can fix this without revving the * ioctl version -- jpeach */ /* Set transmit words buffer ... */ krq.ioc_twc = mbuf_len(words) / sizeof(uint16_t); krq.ioc_twords = mbuf_data(words); /* Set transmit bytes buffer ... */ krq.ioc_tbc = mbuf_len(bytes); krq.ioc_tbytes = mbuf_data(bytes); /* Set receive buffer, reserving space for the word count and byte count ... */ krq.ioc_rpbufsz = (int32_t)mbuf_maxlen(response); krq.ioc_rpbuf = mbuf_data(response); if (smb_ioctl_call(((struct smb_ctx *)hContext)->ct_fd, SMBIOC_REQUEST, &krq) == -1) { return errno; } header->flags = krq.ioc_flags; header->flags2 = krq.ioc_flags2; header->status = krq.ioc_ntstatus; mbuf_setlen(response, krq.ioc_rpbufsz); return 0; }
/* ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- */ void ppp_comp_logmbuf(char *msg, mbuf_t m) { int i, lcount, copycount, count; char lbuf[16], *data; if (m == NULL) return; IOLog("%s: \n", msg); for (count = mbuf_len(m), data = mbuf_data(m); m != NULL; ) { /* build a line of output */ for(lcount = 0; lcount < sizeof(lbuf); lcount += copycount) { if (!count) { m = mbuf_next(m); if (m == NULL) break; count = mbuf_len(m); data = mbuf_data(m); } copycount = (count > sizeof(lbuf) - lcount) ? sizeof(lbuf) - lcount : count; bcopy(data, &lbuf[lcount], copycount); data += copycount; count -= copycount; } /* output line (hex 1st, then ascii) */ IOLog("%s: 0x ", msg); for(i = 0; i < lcount; i++) { if (i == 8) IOLog(" "); IOLog("%02x ", (u_char)lbuf[i]); } for( ; i < sizeof(lbuf); i++) { if (i == 8) IOLog(" "); IOLog(" "); } IOLog(" '"); for(i = 0; i < lcount; i++) IOLog("%c",(lbuf[i]>=040 && lbuf[i]<=0176)?lbuf[i]:'.'); IOLog("'\n"); } }
//////////////////////////////////////////////////////////////////////////////// // // in_firewire_arp_input // // IN: register struct mbuf *m // // Invoked by : // firewire_arpintr calls it from the context of dlil_input_thread queue // // ARP for Internet protocols on 10 Mb/s Ethernet. // Algorithm is that given in RFC 826. // In addition, a sanity check is performed on the sender // protocol address, to catch impersonators. // We no longer handle negotiations for use of trailer protocol: // Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent // along with IP replies if we wanted trailers sent to us, // and also sent them in response to IP replies. // This allowed either end to announce the desire to receive trailer packets. // We no longer reply to requests for ETHERTYPE_TRAIL protocol either, // but formerly didn't normally send requests. // //////////////////////////////////////////////////////////////////////////////// static void inet_firewire_arp_input( mbuf_t m) { IP1394_ARP *fwa; struct sockaddr_dl sender_hw; struct sockaddr_in sender_ip; struct sockaddr_in target_ip; ifnet_t ifp = mbuf_pkthdr_rcvif((mbuf_t)m); IOFWInterface *fwIf = (IOFWInterface*)ifnet_softc(ifp); if(fwIf == NULL) return; IOFireWireIP *fwIpObj = (IOFireWireIP*)fwIf->getController(); if(fwIpObj == NULL) return; if (mbuf_len(m) < (int)sizeof(IP1394_ARP) && mbuf_pullup(&m, sizeof(IP1394_ARP)) != 0) return; fwa = (IP1394_ARP*)mbuf_data(m); // Verify this is an firewire/ip arp and address lengths are correct if (fwa->hardwareType != htons(ARP_HDW_TYPE) || fwa->protocolType != htons(FWTYPE_IP) || fwa->hwAddrLen != sizeof(IP1394_HDW_ADDR) || fwa->ipAddrLen != IPV4_ADDR_SIZE) { mbuf_free(m); return; } bzero(&sender_ip, sizeof(sender_ip)); sender_ip.sin_len = sizeof(sender_ip); sender_ip.sin_family = AF_INET; sender_ip.sin_addr.s_addr = fwa->senderIpAddress; target_ip = sender_ip; target_ip.sin_addr.s_addr = fwa->targetIpAddress; bzero(&sender_hw, sizeof(sender_hw)); sender_hw.sdl_len = sizeof(sender_hw); sender_hw.sdl_family = AF_LINK; sender_hw.sdl_type = IFT_IEEE1394; sender_hw.sdl_alen = FIREWIRE_ADDR_LEN; bcopy(&fwa->senderUniqueID, LLADDR(&sender_hw), FIREWIRE_ADDR_LEN); if(fwIpObj->arpCacheHandler(fwa)) inet_arp_handle_input(ifp, ntohs(fwa->opcode), &sender_hw, &sender_ip, &target_ip); mbuf_free((mbuf_t)m); }
/** * Rx Interrupt Handler **/ void AttansicL2Ethernet::at_intr_rx(at_adapter *adapter) { DbgPrint("at_intr_rx()\n"); rx_desc_t* rxd; mbuf_t skb = NULL; //DbgPrint("at_intr_rx() begin rxd_write_ptr=%d\n",adapter->rxd_write_ptr); do { rxd = adapter->rxd_ring+adapter->rxd_write_ptr; if (!rxd->status.update) break; // end of tx // clear this flag at once rxd->status.update = 0; if (rxd->status.ok && rxd->status.pkt_size >= 60) { int rx_size = (int)(rxd->status.pkt_size - 4); //DbgPrint("at_intr_rx() begin receive data , pkt_size %d\n",rxd->status.pkt_size); // alloc new buffer skb = allocatePacket(rx_size + 2); if (NULL == skb) { DbgPrint("at_intr_rx() Allocate n_skb failed!\n"); break; } memcpy(mbuf_data(skb), rxd->packet, rx_size); //TO-DO: Add network stack notification netIface_->inputPacket(skb, rx_size, IONetworkInterface::kInputOptionQueuePacket); netIface_->flushInputQueue(); // rx statistics: netStats_->inputPackets++; } else { netStats_->inputErrors++; } // advance write ptr if (++adapter->rxd_write_ptr == adapter->rxd_ring_size) adapter->rxd_write_ptr = 0; } while (1); // update mailbox ? adapter->rxd_read_ptr = adapter->rxd_write_ptr; AT_WRITE_REGW(&adapter->hw, REG_MB_RXD_RD_IDX, adapter->rxd_read_ptr); }
static errno_t vboxNetAdpDarwinOutput(ifnet_t pIface, mbuf_t pMBuf) { PVBOXNETADP pThis = VBOXNETADP_FROM_IFACE(pIface); Assert(pThis); if (pThis->u.s.nTapMode & BPF_MODE_OUTPUT) { Log2(("vboxnetadp: out len=%d\n%.*Rhxd\n", mbuf_len(pMBuf), 14, mbuf_data(pMBuf))); bpf_tap_out(pIface, DLT_EN10MB, pMBuf, NULL, 0); } mbuf_freem_list(pMBuf); return 0; }
bool mdict_urldecode(struct MDict *dict, const char *str, unsigned len) { const char *s = str; const char *end = s + len; const char *k, *v; unsigned klen, vlen; struct MDictElem *el; while (s < end) { v = NULL; vlen = 0; el = NULL; /* read key */ k = urldec_str(dict->cx, &s, end, &klen); if (!k) goto fail; /* read value */ if (s < end && *s == '=') { s++; v = urldec_str(dict->cx, &s, end, &vlen); if (!v) goto fail; } if (s < end && *s == '&') s++; /* insert value */ el = cbtree_lookup(dict->tree, k, klen); if (el) { cx_free(dict->cx, mbuf_data(&el->val)); mbuf_init_fixed_reader(&el->val, v, vlen); } else { el = cx_alloc(dict->cx, sizeof(*el)); if (!el) goto fail; mbuf_init_fixed_reader(&el->key, k, klen); mbuf_init_fixed_reader(&el->val, v, vlen); if (!cbtree_insert(dict->tree, el)) goto fail; } } return true; fail: if (k) cx_free(dict->cx, k); if (v) cx_free(dict->cx, v); if (el) cx_free(dict->cx, el); return false; }
errno_t utun_pkt_input (struct utun_pcb *pcb, mbuf_t m) { errno_t result; protocol_family_t protocol = 0; mbuf_pkthdr_setrcvif(m, pcb->utun_ifp); if (m_pktlen(m) >= 4) { protocol = *(u_int32_t *)mbuf_data(m); bpf_tap_in(pcb->utun_ifp, DLT_NULL, m, 0, 0); } if (pcb->utun_flags & UTUN_FLAGS_NO_INPUT) { /* flush data */ mbuf_freem(m); return 0; } // quick exit for keepalive packets if (protocol == AF_UTUN && pcb->utun_flags & UTUN_FLAGS_CRYPTO) { if (utun_pkt_crypto_output(pcb, &m) == 0) { return 0; } printf("%s: utun_pkt_crypto_output failed, flags %x\n", __FUNCTION__, pcb->utun_flags); return EINVAL; } if (!pcb->utun_ext_ifdata_stats) { struct ifnet_stat_increment_param incs; bzero(&incs, sizeof(incs)); incs.packets_in = 1; incs.bytes_in = mbuf_pkthdr_len(m); result = ifnet_input(pcb->utun_ifp, m, &incs); } else { result = ifnet_input(pcb->utun_ifp, m, NULL); } if (result != 0) { ifnet_stat_increment_in(pcb->utun_ifp, 0, 0, 1); printf("%s - ifnet_input failed: %d\n", __FUNCTION__, result); mbuf_freem(m); } return 0; }
errno_t mbuf_adjustlen(mbuf_t m, int amount) { /* Verify m_len will be valid after adding amount */ if (amount > 0) { int used = (size_t)mbuf_data(m) - (size_t)mbuf_datastart(m) + m->m_len; if ((size_t)(amount + used) > mbuf_maxlen(m)) return (EINVAL); } else if (-amount > m->m_len) { return (EINVAL); } m->m_len += amount; return (0); }
/* * Copy data from an mbuf chain into a buffer. This code is derived * from m_copydata in sys/uipc_mbuf.c. */ static void bpf_mcopy(const void *src_arg, void *dst_arg, size_t len) { struct mbuf *m = _cast_non_const(src_arg); u_int count; u_char *dst; dst = dst_arg; while (len > 0) { if (m == 0) panic("bpf_mcopy"); count = min(m->m_len, len); bcopy(mbuf_data(m), dst, count); m = m->m_next; dst += count; len -= count; } }
/* Network Interface functions */ static errno_t utun_demux( __unused ifnet_t interface, mbuf_t data, __unused char *frame_header, protocol_family_t *protocol) { while (data != NULL && mbuf_len(data) < 1) { data = mbuf_next(data); } if (data == NULL) return ENOENT; *protocol = *(u_int32_t *)mbuf_data(data); return 0; }
void net_habitue_device_SC101::handleResolvePacket(sockaddr_in *addr, mbuf_t m, size_t len, outstanding *out, void *ctx) { clock_get_uptime(&_lastReply); if (mbuf_len(m) < out->len && mbuf_pullup(&m, out->len) != 0) { KINFO("pullup failed"); return; } KDEBUG("resolve succeeded!"); psan_resolve_response_t *res = (psan_resolve_response_t *)mbuf_data(m); sockaddr_in part; bzero(&part, sizeof(part)); part.sin_len = sizeof(part); part.sin_family = AF_INET; part.sin_port = htons(PSAN_PORT); part.sin_addr = res->ip4; OSData *partData = OSData::withBytes(&part, sizeof(part)); if (partData) { setProperty(gSC101DevicePartitionAddressKey, partData); partData->release(); } OSData *rootData = OSData::withBytes(addr, sizeof(*addr)); if (rootData) { setProperty(gSC101DeviceRootAddressKey, rootData); rootData->release(); } IODelete(out, outstanding, 1); mbuf_freem(m); if (!getProperty(gSC101DeviceSizeKey)) disk(); }
/** * Checks whether this is an mbuf created by vboxNetFltDarwinMBufFromSG, * i.e. a buffer which we're pushing and should be ignored by the filter callbacks. * * @returns true / false accordingly. * @param pThis The instance. * @param pMBuf The mbuf. * @param pvFrame The frame pointer, optional. */ DECLINLINE(bool) vboxNetFltDarwinMBufIsOur(PVBOXNETFLTINS pThis, mbuf_t pMBuf, void *pvFrame) { NOREF(pThis); /* * Lookup the tag set by vboxNetFltDarwinMBufFromSG. */ PCVBOXNETFLTTAG pTagData; size_t cbTagData; errno_t err = mbuf_tag_find(pMBuf, g_idTag, 0 /* type */, &cbTagData, (void **)&pTagData); if (err) return false; AssertReturn(cbTagData == sizeof(*pTagData), false); /* * Dig out the ethernet header from the mbuf. */ PCRTNETETHERHDR pEthHdr = (PCRTNETETHERHDR)pvFrame; if (!pEthHdr) pEthHdr = (PCRTNETETHERHDR)mbuf_pkthdr_header(pMBuf); if (!pEthHdr) pEthHdr = (PCRTNETETHERHDR)mbuf_data(pMBuf); /* ASSUMING that there is enough data to work on! */ if ( pEthHdr->DstMac.au8[0] != pTagData->EthHdr.DstMac.au8[0] || pEthHdr->DstMac.au8[1] != pTagData->EthHdr.DstMac.au8[1] || pEthHdr->DstMac.au8[2] != pTagData->EthHdr.DstMac.au8[2] || pEthHdr->DstMac.au8[3] != pTagData->EthHdr.DstMac.au8[3] || pEthHdr->DstMac.au8[4] != pTagData->EthHdr.DstMac.au8[4] || pEthHdr->DstMac.au8[5] != pTagData->EthHdr.DstMac.au8[5] || pEthHdr->SrcMac.au8[0] != pTagData->EthHdr.SrcMac.au8[0] || pEthHdr->SrcMac.au8[1] != pTagData->EthHdr.SrcMac.au8[1] || pEthHdr->SrcMac.au8[2] != pTagData->EthHdr.SrcMac.au8[2] || pEthHdr->SrcMac.au8[3] != pTagData->EthHdr.SrcMac.au8[3] || pEthHdr->SrcMac.au8[4] != pTagData->EthHdr.SrcMac.au8[4] || pEthHdr->SrcMac.au8[5] != pTagData->EthHdr.SrcMac.au8[5] || pEthHdr->EtherType != pTagData->EthHdr.EtherType) { Log3(("tagged, but the ethernet header has changed\n")); return false; } return true; }
void ieee80211_sta_tx(struct net_device *dev, mbuf_t skb, int encrypt) { struct ieee80211_sub_if_data *sdata; struct ieee80211_tx_packet_data *pkt_data; //sdata = IEEE80211_DEV_TO_SUB_IF(dev); (void*)sdata = netdev_priv(dev); //skb->dev = sdata->local->mdev; //skb_set_mac_header(skb, 0); //skb_set_network_header(skb, 0); //skb_set_transport_header(skb, 0); pkt_data = (struct ieee80211_tx_packet_data *) mbuf_data(skb);//->cb; memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); pkt_data->ifindex = sdata->dev->ifindex; pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT); pkt_data->do_not_encrypt = !encrypt; //dev_queue_xmit(skb); clone->outputPacket(skb,0); }
/* * Find the gre interface associated with our src/dst/proto set. */ static inline struct gre_softc * gre_lookup(mbuf_t m, u_int8_t proto) { struct ip *ip = mbuf_data(m); gre_hash_lock_shared(); struct gre_softc *sc = gre_hash_find(ip->ip_dst, ip->ip_src, proto); gre_hash_unlock_shared(); // up and running if (sc) { if ((ifnet_flags(sc->sc_ifp) & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING)) { gre_sc_release(sc); sc = NULL; #ifdef DEBUG printf("%s: found gre_softc but interface is down", __FUNCTION__); #endif } } return sc; }
IOReturn MbufUtils::copyAudioFromMbufToBuffer(mbuf_t mbuf, UInt32 from, UInt32 bufferSize, UInt8 *inBuffer) { if (bufferSize > (UInt32) MbufUtils::mbufTotalLength(mbuf)-from) { IOLog("MbufUtils::copyAudioFromMbufToBuffer(): Got insufficiently large buffer (mbuf too small).\n"); return kIOReturnNoMemory; } if (0 != bufferSize % (REAC_RESOLUTION*2)) { IOLog("MbufUtils::copyAudioFromMbufToBuffer(): Buffer size must be a multiple of %d.\n", REAC_RESOLUTION*2); return kIOReturnBadArgument; } UInt8 *inBufferEnd = inBuffer + bufferSize; UInt8 intermediaryBuffer[6]; UInt8 *mbufBuffer = (UInt8 *)mbuf_data(mbuf); size_t mbufLength = mbuf_len(mbuf); skip_mbuf_macro(); while (inBuffer < inBufferEnd) { for (UInt32 i=0; i<sizeof(intermediaryBuffer); i++) { ensure_mbuf_macro(); intermediaryBuffer[i] = *mbufBuffer; ++mbufBuffer; --mbufLength; } inBuffer[0] = intermediaryBuffer[1]; inBuffer[1] = intermediaryBuffer[0]; inBuffer[2] = intermediaryBuffer[3]; inBuffer[3] = intermediaryBuffer[2]; inBuffer[4] = intermediaryBuffer[5]; inBuffer[5] = intermediaryBuffer[4]; inBuffer += REAC_RESOLUTION*2; } return kIOReturnSuccess; }
static void test_mdict(void *p) { struct MDict *d; struct MBuf buf; const char *s; d = mdict_new(NULL); str_check(xget(d, "key"), "NULL"); int_check(mdict_put(d, "key", "val"), 1); int_check(mdict_put(d, "key2", "foo"), 1); int_check(mdict_put(d, "key2", ""), 1); int_check(mdict_put(d, "key3", NULL), 1); int_check(mdict_put(d, "key4", "v1"), 1); int_check(mdict_del(d, "key4"), 1); str_check(xget(d, "key"), "val"); str_check(xget(d, "key2"), ""); str_check(xget(d, "key3"), "NULL"); str_check(xget(d, "key4"), "NULL"); str_check(xget(d, "key5"), "NULL"); int_check(mdict_del(d, "key5"), 0); mbuf_init_dynamic(&buf); int_check(mdict_urlencode(d, &buf), 1); int_check(mbuf_write_byte(&buf, 0), 1); str_check(mbuf_data(&buf), "key=val&key2=&key3"); mbuf_free(&buf); mdict_free(d); d = mdict_new(NULL); s = "key=val&key2=&key3"; int_check(mdict_urldecode(d, s, strlen(s)), 1); str_check(xget(d, "key"), "val"); str_check(xget(d, "key2"), ""); str_check(xget(d, "key3"), "NULL"); mdict_free(d); end:; }