static int pflog_clone_create(struct if_clone *ifc, u_int32_t unit, __unused void *params) { struct pflog_softc *pflogif; struct ifnet_init_eparams pf_init; int error = 0; if (unit >= PFLOGIFS_MAX) { /* Either the interface cloner or our initializer is broken */ panic("%s: unit (%d) exceeds max (%d)", __func__, unit, PFLOGIFS_MAX); /* NOTREACHED */ } if ((pflogif = if_clone_softc_allocate(&pflog_cloner)) == NULL) { error = ENOMEM; goto done; } bzero(&pf_init, sizeof (pf_init)); pf_init.ver = IFNET_INIT_CURRENT_VERSION; pf_init.len = sizeof (pf_init); pf_init.flags = IFNET_INIT_LEGACY; pf_init.name = ifc->ifc_name; pf_init.unit = unit; pf_init.type = IFT_PFLOG; pf_init.family = IFNET_FAMILY_LOOPBACK; pf_init.output = pflogoutput; pf_init.demux = pflogdemux; pf_init.add_proto = pflogaddproto; pf_init.del_proto = pflogdelproto; pf_init.softc = pflogif; pf_init.ioctl = pflogioctl; pf_init.detach = pflogfree; bzero(pflogif, sizeof (*pflogif)); pflogif->sc_unit = unit; pflogif->sc_flags |= IFPFLF_DETACHING; error = ifnet_allocate_extended(&pf_init, &pflogif->sc_if); if (error != 0) { printf("%s: ifnet_allocate failed - %d\n", __func__, error); if_clone_softc_deallocate(&pflog_cloner, pflogif); goto done; } ifnet_set_mtu(pflogif->sc_if, PFLOGMTU); ifnet_set_flags(pflogif->sc_if, IFF_UP, IFF_UP); error = ifnet_attach(pflogif->sc_if, NULL); if (error != 0) { printf("%s: ifnet_attach failed - %d\n", __func__, error); ifnet_release(pflogif->sc_if); if_clone_softc_deallocate(&pflog_cloner, pflogif); goto done; } #if NBPFILTER > 0 bpfattach(pflogif->sc_if, DLT_PFLOG, PFLOG_HDRLEN); #endif lck_rw_lock_shared(pf_perim_lock); lck_mtx_lock(pf_lock); LIST_INSERT_HEAD(&pflogif_list, pflogif, sc_list); pflogifs[unit] = pflogif->sc_if; pflogif->sc_flags &= ~IFPFLF_DETACHING; lck_mtx_unlock(pf_lock); lck_rw_done(pf_perim_lock); done: return (error); }
static errno_t utun_ctl_connect( kern_ctl_ref kctlref, struct sockaddr_ctl *sac, void **unitinfo) { struct ifnet_init_eparams utun_init; struct utun_pcb *pcb; errno_t result; struct ifnet_stats_param stats; /* kernel control allocates, interface frees */ pcb = utun_alloc(sizeof(*pcb)); if (pcb == NULL) return ENOMEM; /* Setup the protocol control block */ bzero(pcb, sizeof(*pcb)); *unitinfo = pcb; pcb->utun_ctlref = kctlref; pcb->utun_unit = sac->sc_unit; printf("utun_ctl_connect: creating interface utun%d\n", pcb->utun_unit - 1); /* Create the interface */ bzero(&utun_init, sizeof(utun_init)); utun_init.ver = IFNET_INIT_CURRENT_VERSION; utun_init.len = sizeof (utun_init); utun_init.flags = IFNET_INIT_LEGACY; utun_init.name = "utun"; utun_init.unit = pcb->utun_unit - 1; utun_init.family = utun_family; utun_init.type = IFT_OTHER; utun_init.output = utun_output; utun_init.demux = utun_demux; utun_init.framer_extended = utun_framer; utun_init.add_proto = utun_add_proto; utun_init.del_proto = utun_del_proto; utun_init.softc = pcb; utun_init.ioctl = utun_ioctl; utun_init.detach = utun_detached; result = ifnet_allocate_extended(&utun_init, &pcb->utun_ifp); if (result != 0) { printf("utun_ctl_connect - ifnet_allocate failed: %d\n", result); utun_free(pcb); return result; } OSIncrementAtomic(&utun_ifcount); /* Set flags and additional information. */ ifnet_set_mtu(pcb->utun_ifp, 1500); ifnet_set_flags(pcb->utun_ifp, IFF_UP | IFF_MULTICAST | IFF_POINTOPOINT, 0xffff); /* The interface must generate its own IPv6 LinkLocal address, * if possible following the recommendation of RFC2472 to the 64bit interface ID */ ifnet_set_eflags(pcb->utun_ifp, IFEF_NOAUTOIPV6LL, IFEF_NOAUTOIPV6LL); /* Reset the stats in case as the interface may have been recycled */ bzero(&stats, sizeof(struct ifnet_stats_param)); ifnet_set_stat(pcb->utun_ifp, &stats); /* Attach the interface */ result = ifnet_attach(pcb->utun_ifp, NULL); if (result != 0) { printf("utun_ctl_connect - ifnet_allocate failed: %d\n", result); ifnet_release(pcb->utun_ifp); utun_free(pcb); } /* Attach to bpf */ if (result == 0) bpfattach(pcb->utun_ifp, DLT_NULL, 4); /* The interfaces resoures allocated, mark it as running */ if (result == 0) ifnet_set_flags(pcb->utun_ifp, IFF_RUNNING, IFF_RUNNING); return result; }
int vboxNetAdpOsCreate(PVBOXNETADP pThis, PCRTMAC pMACAddress) { int rc; struct ifnet_init_params Params; RTUUID uuid; struct sockaddr_dl mac; pThis->u.s.hEvtDetached = NIL_RTSEMEVENT; rc = RTSemEventCreate(&pThis->u.s.hEvtDetached); if (RT_FAILURE(rc)) { printf("vboxNetAdpOsCreate: failed to create semaphore (rc=%d).\n", rc); return rc; } pThis->u.s.nTapMode = BPF_MODE_DISABLED; mac.sdl_len = sizeof(mac); mac.sdl_family = AF_LINK; mac.sdl_alen = ETHER_ADDR_LEN; mac.sdl_nlen = 0; mac.sdl_slen = 0; memcpy(LLADDR(&mac), pMACAddress->au8, mac.sdl_alen); RTStrPrintf(pThis->szName, VBOXNETADP_MAX_NAME_LEN, "%s%d", VBOXNETADP_NAME, pThis->iUnit); vboxNetAdpDarwinComposeUUID(pThis, &uuid); Params.uniqueid = uuid.au8; Params.uniqueid_len = sizeof(uuid); Params.name = VBOXNETADP_NAME; Params.unit = pThis->iUnit; Params.family = IFNET_FAMILY_ETHERNET; Params.type = IFT_ETHER; Params.output = vboxNetAdpDarwinOutput; Params.demux = vboxNetAdpDarwinDemux; Params.add_proto = vboxNetAdpDarwinAddProto; Params.del_proto = vboxNetAdpDarwinDelProto; Params.check_multi = ether_check_multi; Params.framer = ether_frameout; Params.softc = pThis; Params.ioctl = (ifnet_ioctl_func)ether_ioctl; Params.set_bpf_tap = NULL; Params.detach = vboxNetAdpDarwinDetach; Params.event = NULL; Params.broadcast_addr = "\xFF\xFF\xFF\xFF\xFF\xFF"; Params.broadcast_len = ETHER_ADDR_LEN; errno_t err = ifnet_allocate(&Params, &pThis->u.s.pIface); if (!err) { err = ifnet_attach(pThis->u.s.pIface, &mac); if (!err) { err = bpf_attach(pThis->u.s.pIface, DLT_EN10MB, ETHER_HDR_LEN, vboxNetAdpDarwinBpfSend, vboxNetAdpDarwinBpfTap); if (err) { LogRel(("vboxnetadp: bpf_attach failed with %d\n", err)); } err = ifnet_set_flags(pThis->u.s.pIface, IFF_RUNNING | IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST, 0xFFFF); if (!err) { ifnet_set_mtu(pThis->u.s.pIface, VBOXNETADP_MTU); return VINF_SUCCESS; } else Log(("vboxNetAdpDarwinRegisterDevice: Failed to set flags (err=%d).\n", err)); ifnet_detach(pThis->u.s.pIface); } else Log(("vboxNetAdpDarwinRegisterDevice: Failed to attach to interface (err=%d).\n", err)); ifnet_release(pThis->u.s.pIface); } else Log(("vboxNetAdpDarwinRegisterDevice: Failed to allocate interface (err=%d).\n", err)); RTSemEventDestroy(pThis->u.s.hEvtDetached); pThis->u.s.hEvtDetached = NIL_RTSEMEVENT; return RTErrConvertFromErrno(err); }
static errno_t utun_ctl_connect( kern_ctl_ref kctlref, struct sockaddr_ctl *sac, void **unitinfo) { struct ifnet_init_eparams utun_init; struct utun_pcb *pcb; errno_t result; struct ifnet_stats_param stats; /* kernel control allocates, interface frees */ MALLOC(pcb, struct utun_pcb *, sizeof(*pcb), M_DEVBUF, M_WAITOK | M_ZERO); *unitinfo = pcb; pcb->utun_ctlref = kctlref; pcb->utun_unit = sac->sc_unit; pcb->utun_max_pending_packets = 1; printf("utun_ctl_connect: creating interface utun%d\n", pcb->utun_unit - 1); /* Create the interface */ bzero(&utun_init, sizeof(utun_init)); utun_init.ver = IFNET_INIT_CURRENT_VERSION; utun_init.len = sizeof (utun_init); utun_init.name = "utun"; utun_init.start = utun_start; utun_init.unit = pcb->utun_unit - 1; utun_init.family = utun_family; utun_init.subfamily = IFNET_SUBFAMILY_UTUN; utun_init.type = IFT_OTHER; utun_init.demux = utun_demux; utun_init.framer_extended = utun_framer; utun_init.add_proto = utun_add_proto; utun_init.del_proto = utun_del_proto; utun_init.softc = pcb; utun_init.ioctl = utun_ioctl; utun_init.detach = utun_detached; /* * Upon success, this holds an ifnet reference which we will * release via ifnet_release() at final detach time. */ result = ifnet_allocate_extended(&utun_init, &pcb->utun_ifp); if (result != 0) { printf("utun_ctl_connect - ifnet_allocate failed: %d\n", result); *unitinfo = NULL; FREE(pcb, M_DEVBUF); return result; } /* Set flags and additional information. */ ifnet_set_mtu(pcb->utun_ifp, UTUN_DEFAULT_MTU); ifnet_set_flags(pcb->utun_ifp, IFF_UP | IFF_MULTICAST | IFF_POINTOPOINT, 0xffff); /* The interface must generate its own IPv6 LinkLocal address, * if possible following the recommendation of RFC2472 to the 64bit interface ID */ ifnet_set_eflags(pcb->utun_ifp, IFEF_NOAUTOIPV6LL, IFEF_NOAUTOIPV6LL); /* Reset the stats in case as the interface may have been recycled */ bzero(&stats, sizeof(struct ifnet_stats_param)); ifnet_set_stat(pcb->utun_ifp, &stats); /* Attach the interface */ result = ifnet_attach(pcb->utun_ifp, NULL); if (result != 0) { printf("utun_ctl_connect - ifnet_allocate failed: %d\n", result); /* Release reference now since attach failed */ ifnet_release(pcb->utun_ifp); *unitinfo = NULL; FREE(pcb, M_DEVBUF); } else { /* Attach to bpf */ bpfattach(pcb->utun_ifp, DLT_NULL, UTUN_HEADER_SIZE(pcb)); /* The interfaces resoures allocated, mark it as running */ ifnet_set_flags(pcb->utun_ifp, IFF_RUNNING, IFF_RUNNING); } return result; }