static errno_t utun_detach_ip( ifnet_t interface, protocol_family_t protocol, socket_t pf_socket) { errno_t result = EPROTONOSUPPORT; /* Attempt a detach */ if (protocol == PF_INET) { struct ifreq ifr; bzero(&ifr, sizeof(ifr)); snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", ifnet_name(interface), ifnet_unit(interface)); result = sock_ioctl(pf_socket, SIOCPROTODETACH, &ifr); } else if (protocol == PF_INET6) { struct in6_ifreq ifr6; bzero(&ifr6, sizeof(ifr6)); snprintf(ifr6.ifr_name, sizeof(ifr6.ifr_name), "%s%d", ifnet_name(interface), ifnet_unit(interface)); result = sock_ioctl(pf_socket, SIOCPROTODETACH_IN6, &ifr6); } return result; }
static void utun_remove_address( ifnet_t interface, protocol_family_t protocol, ifaddr_t address, socket_t pf_socket) { errno_t result = 0; /* Attempt a detach */ if (protocol == PF_INET) { struct ifreq ifr; bzero(&ifr, sizeof(ifr)); snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", ifnet_name(interface), ifnet_unit(interface)); result = ifaddr_address(address, &ifr.ifr_addr, sizeof(ifr.ifr_addr)); if (result != 0) { printf("utun_remove_address - ifaddr_address failed: %d", result); } else { result = sock_ioctl(pf_socket, SIOCDIFADDR, &ifr); if (result != 0) { printf("utun_remove_address - SIOCDIFADDR failed: %d", result); } } } else if (protocol == PF_INET6) { struct in6_ifreq ifr6; bzero(&ifr6, sizeof(ifr6)); snprintf(ifr6.ifr_name, sizeof(ifr6.ifr_name), "%s%d", ifnet_name(interface), ifnet_unit(interface)); result = ifaddr_address(address, (struct sockaddr*)&ifr6.ifr_addr, sizeof(ifr6.ifr_addr)); if (result != 0) { printf("utun_remove_address - ifaddr_address failed (v6): %d", result); } else { result = sock_ioctl(pf_socket, SIOCDIFADDR_IN6, &ifr6); if (result != 0) { printf("utun_remove_address - SIOCDIFADDR_IN6 failed: %d", result); } } } }
/* ----------------------------------------------------------------------------- attach the PPPx interface ifp to the network protocol IP, called when the ppp interface is ready for ppp traffic ----------------------------------------------------------------------------- */ errno_t ppp_ip_attach(ifnet_t ifp, protocol_family_t protocol) { int ret; struct ifnet_attach_proto_param reg; struct ppp_if *wan = (struct ppp_if *)ifnet_softc(ifp); LOGDBG(ifp, ("ppp_ip_attach: name = %s, unit = %d\n", ifnet_name(ifp), ifnet_unit(ifp))); if (wan->ip_attached) return 0; // already attached bzero(®, sizeof(struct ifnet_attach_proto_param)); reg.input = ppp_ip_input; reg.pre_output = ppp_ip_preoutput; reg.ioctl = ppp_ip_ioctl; ret = ifnet_attach_protocol(ifp, PF_INET, ®); LOGRETURN(ret, ret, "ppp_ip_attach: ifnet_attach_protocol error = 0x%x\n"); LOGDBG(ifp, ("ppp_i6_attach: ifnet_attach_protocol family = 0x%x\n", protocol)); ifnet_find_by_name("lo0", &wan->lo_ifp); wan->ip_attached = 1; return 0; }
/* * Set the data link type of a BPF instance. */ static int bpf_setdlt(struct bpf_d *d, uint32_t dlt) { int error, opromisc; struct ifnet *ifp; struct bpf_if *bp; if (d->bd_bif->bif_dlt == dlt) return (0); ifp = d->bd_bif->bif_ifp; for (bp = bpf_iflist; bp; bp = bp->bif_next) { if (bp->bif_ifp == ifp && bp->bif_dlt == dlt) break; } if (bp != NULL) { opromisc = d->bd_promisc; bpf_detachd(d); error = bpf_attachd(d, bp); if (error) { printf("bpf_setdlt: bpf_attachd %s%d failed (%d)\n", ifnet_name(bp->bif_ifp), ifnet_unit(bp->bif_ifp), error); return error; } reset_d(d); if (opromisc) { lck_mtx_unlock(bpf_mlock); error = ifnet_set_promiscuous(bp->bif_ifp, 1); lck_mtx_lock(bpf_mlock); if (error) printf("bpf_setdlt: ifpromisc %s%d failed (%d)\n", ifnet_name(bp->bif_ifp), ifnet_unit(bp->bif_ifp), error); else d->bd_promisc = 1; } } return (bp == NULL ? EINVAL : 0); }
static errno_t utun_ctl_getopt( __unused kern_ctl_ref kctlref, __unused u_int32_t unit, void *unitinfo, int opt, void *data, size_t *len) { struct utun_pcb *pcb = unitinfo; errno_t result = 0; switch (opt) { case UTUN_OPT_FLAGS: if (*len != sizeof(u_int32_t)) result = EMSGSIZE; else *(u_int32_t *)data = pcb->utun_flags; break; case UTUN_OPT_EXT_IFDATA_STATS: if (*len != sizeof(int)) result = EMSGSIZE; else *(int *)data = (pcb->utun_ext_ifdata_stats) ? 1 : 0; break; case UTUN_OPT_IFNAME: *len = snprintf(data, *len, "%s%d", ifnet_name(pcb->utun_ifp), ifnet_unit(pcb->utun_ifp)) + 1; break; case UTUN_OPT_GENERATE_CRYPTO_KEYS_IDX: result = utun_ctl_generate_crypto_keys_idx(kctlref, unit, unitinfo, opt, data, len); break; case UTUN_OPT_MAX_PENDING_PACKETS: { *len = sizeof(u_int32_t); *((u_int32_t *)data) = pcb->utun_max_pending_packets; break; } default: result = ENOPROTOOPT; break; } return result; }
static errno_t ipsec_ctl_getopt(__unused kern_ctl_ref kctlref, __unused u_int32_t unit, void *unitinfo, int opt, void *data, size_t *len) { struct ipsec_pcb *pcb = unitinfo; errno_t result = 0; switch (opt) { case IPSEC_OPT_FLAGS: if (*len != sizeof(u_int32_t)) result = EMSGSIZE; else *(u_int32_t *)data = pcb->ipsec_flags; break; case IPSEC_OPT_EXT_IFDATA_STATS: if (*len != sizeof(int)) result = EMSGSIZE; else *(int *)data = (pcb->ipsec_ext_ifdata_stats) ? 1 : 0; break; case IPSEC_OPT_IFNAME: *len = snprintf(data, *len, "%s%d", ifnet_name(pcb->ipsec_ifp), ifnet_unit(pcb->ipsec_ifp)) + 1; break; case IPSEC_OPT_OUTPUT_TRAFFIC_CLASS: { if (*len != sizeof(int)) { result = EMSGSIZE; break; } *(int *)data = so_svc2tc(pcb->ipsec_output_service_class); break; } default: result = ENOPROTOOPT; break; } return result; }
IOReturn darwin_iwi3945::enable( IONetworkInterface * netif ) { if (!fifnet) { char ii[4]; sprintf(ii,"%s%d" ,fNetif->getNamePrefix(), fNetif->getUnitNumber()); ifnet_find_by_name(ii,&fifnet); IWI_DEBUG("ifnet_t %s%d = %x\n",ifnet_name(fifnet),ifnet_unit(fifnet),fifnet); struct ieee80211_local* loc=hw_to_local(priv->hw); memcpy(&loc->mdev->name,ii,sizeof(ii)); loc->mdev->ifindex=fNetif->getUnitNumber(); priv->interface_id=fNetif->getUnitNumber(); } if (firstifup==0) { firstifup=1; return -1; } IWI_DEBUG("ifconfig up\n"); if ((fNetif->getFlags() & IFF_RUNNING)==0) { IWI_DEBUG("ifconfig going up\n "); //super::enable(fNetif); //fNetif->setPoweredOnByUser(true); //fNetif->setLinkState(kIO80211NetworkLinkUp); //(if_flags & ~mask) | (new_flags & mask) if mask has IFF_UP if_updown fires up (kpi_interface.c in xnu) if (priv->status & STATUS_AUTH) ifnet_set_flags(fifnet, IFF_RUNNING, IFF_RUNNING ); //fNetif->inputEvent(kIONetworkEventTypeLinkUp,NULL); fTransmitQueue->setCapacity(1024); fTransmitQueue->service(IOBasicOutputQueue::kServiceAsync); fTransmitQueue->start(); return kIOReturnSuccess; } else { IWI_DEBUG("ifconfig already up\n"); return kIOReturnExclusiveAccess; } }
//////////////////////////////////////////////////////////////////////////////// // // firewire_attach_inet // // IN: ifnet_t ifp // // Invoked by: // firewire_attach_inet will be invoked from IOFWInterface::attachToDataLinkLayer // //////////////////////////////////////////////////////////////////////////////// int firewire_attach_inet(ifnet_t ifp, protocol_family_t protocol_family) { struct ifnet_attach_proto_param proto; struct ifnet_demux_desc demux[2]; u_short en_native=htons(FWTYPE_IP); u_short arp_native=htons(FWTYPE_ARP); errno_t error; bzero(&demux[0], sizeof(demux)); demux[0].type = DLIL_DESC_ETYPE2; demux[0].data = &en_native; demux[0].datalen = sizeof(en_native); demux[1].type = DLIL_DESC_ETYPE2; demux[1].data = &arp_native; demux[1].datalen = sizeof(arp_native); bzero(&proto, sizeof(proto)); proto.demux_list = demux; proto.demux_count = sizeof(demux) / sizeof(demux[0]); proto.input = inet_firewire_input; proto.pre_output = inet_firewire_pre_output; proto.ioctl = firewire_inet_prmod_ioctl; proto.event = firewire_inet_event; proto.resolve = firewire_inet_resolve_multi; proto.send_arp = firewire_inet_arp; error = ifnet_attach_protocol(ifp, protocol_family, &proto); if (error && error != EEXIST) { printf("WARNING: firewire_attach_inet can't attach ip to %s%d\n", ifnet_name(ifp), ifnet_unit(ifp)); } return error; }
static void utun_cleanup_family( ifnet_t interface, protocol_family_t protocol) { errno_t result = 0; socket_t pf_socket = NULL; ifaddr_t *addresses = NULL; int i; if (protocol != PF_INET && protocol != PF_INET6) { printf("utun_cleanup_family - invalid protocol family %d\n", protocol); return; } /* Create a socket for removing addresses and detaching the protocol */ result = sock_socket(protocol, SOCK_DGRAM, 0, NULL, NULL, &pf_socket); if (result != 0) { if (result != EAFNOSUPPORT) printf("utun_cleanup_family - failed to create %s socket: %d\n", protocol == PF_INET ? "IP" : "IPv6", result); goto cleanup; } /* always set SS_PRIV, we want to close and detach regardless */ sock_setpriv(pf_socket, 1); result = utun_detach_ip(interface, protocol, pf_socket); if (result == 0 || result == ENXIO) { /* We are done! We either detached or weren't attached. */ goto cleanup; } else if (result != EBUSY) { /* Uh, not really sure what happened here... */ printf("utun_cleanup_family - utun_detach_ip failed: %d\n", result); goto cleanup; } /* * At this point, we received an EBUSY error. This means there are * addresses attached. We should detach them and then try again. */ result = ifnet_get_address_list_family(interface, &addresses, protocol); if (result != 0) { printf("fnet_get_address_list_family(%s%d, 0xblah, %s) - failed: %d\n", ifnet_name(interface), ifnet_unit(interface), protocol == PF_INET ? "PF_INET" : "PF_INET6", result); goto cleanup; } for (i = 0; addresses[i] != 0; i++) { utun_remove_address(interface, protocol, addresses[i], pf_socket); } ifnet_free_address_list(addresses); addresses = NULL; /* * The addresses should be gone, we should try the remove again. */ result = utun_detach_ip(interface, protocol, pf_socket); if (result != 0 && result != ENXIO) { printf("utun_cleanup_family - utun_detach_ip failed: %d\n", result); } cleanup: if (pf_socket != NULL) sock_close(pf_socket); if (addresses != NULL) ifnet_free_address_list(addresses); }