/* 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; }