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); } } } }
/* ----------------------------------------------------------------------------- called from dlil when an ioctl is sent to the interface ----------------------------------------------------------------------------- */ errno_t ppp_ipv6_ioctl(ifnet_t ifp, protocol_family_t protocol, u_long command, void* argument) { struct sockaddr_in6 addr6; int error = 0; switch (command) { case SIOCSIFADDR: case SIOCAIFADDR: LOGDBG(ifp, ("ppp_ipv6_ioctl: cmd = SIOCSIFADDR/SIOCAIFADDR\n")); error = ifaddr_address(argument, (struct sockaddr *)&addr6, sizeof (addr6)); if (error != 0) { error = EAFNOSUPPORT; break; } // only an IPv6 address should arrive here if (addr6.sin6_family != AF_INET6) { error = EAFNOSUPPORT; break; } break; default : error = EOPNOTSUPP; } return error; }
IOReturn REACConnection::getInterfaceMacAddress(ifnet_t interface, UInt8* resultAddr, UInt32 addrLen) { ifaddr_t *addresses; ifaddr_t *address; REACSockaddr addr; IOReturn ret = kIOReturnError; if (ETHER_ADDR_LEN != addrLen) { return kIOReturnBadArgument; } if (ifnet_get_address_list_family(interface, &addresses, AF_LINK)) { return kIOReturnError; } address = addresses; while (*address) { if (0 == ifaddr_address(*address, (sockaddr*) &addr, sizeof(addr))) { if (addr.sdl_alen == ETHER_ADDR_LEN) { memcpy(resultAddr, addr.sdl_data+addr.sdl_nlen, addrLen); ret = kIOReturnSuccess; break; } } ++address; } ifnet_free_address_list(addresses); return ret; }
/* ----------------------------------------------------------------------------- called from dlil when an ioctl is sent to the interface ----------------------------------------------------------------------------- */ errno_t ppp_ip_ioctl(ifnet_t ifp, protocol_family_t protocol, u_long command, void* argument) { struct ppp_if *wan = (struct ppp_if *)ifnet_softc(ifp); struct sockaddr_in addr, dstaddr; int error = 0; switch (command) { case SIOCSIFADDR: case SIOCAIFADDR: LOGDBG(ifp, ("ppp_ip_ioctl: cmd = SIOCSIFADDR/SIOCAIFADDR\n")); error = ifaddr_address(argument, (struct sockaddr *)&addr, sizeof (addr)); if (error != 0) { error = EAFNOSUPPORT; break; } // only an IPv4 address should arrive here if (addr.sin_family != AF_INET) { error = EAFNOSUPPORT; break; } error = ifaddr_dstaddress(argument, (struct sockaddr *)&dstaddr, sizeof (dstaddr)); if (error != 0) { error = EAFNOSUPPORT; break; } // only an IPv4 address should arrive here if (dstaddr.sin_family != AF_INET) { error = EAFNOSUPPORT; break; } wan->ip_src.s_addr = addr.sin_addr.s_addr; wan->ip_dst.s_addr = dstaddr.sin_addr.s_addr; break; default : error = EOPNOTSUPP; } return error; }
errno_t firewire_inet_arp( ifnet_t ifp, u_short arpop, const struct sockaddr_dl* sender_hw, const struct sockaddr* sender_proto, const struct sockaddr_dl* target_hw, const struct sockaddr* target_proto) { mbuf_t m; errno_t result; register struct firewire_header *fwh; register IP1394_ARP *fwa; const struct sockaddr_in* sender_ip = (const struct sockaddr_in*)sender_proto; const struct sockaddr_in* target_ip = (const struct sockaddr_in*)target_proto; char *datap; IOFWInterface *fwIf = (IOFWInterface*)ifnet_softc(ifp); if(fwIf == NULL) return EINVAL; IOFireWireIP *fwIpObj = (IOFireWireIP*)fwIf->getController(); if(fwIpObj == NULL) return EINVAL; LCB *lcb = fwIpObj->getLcb(); if (target_ip == NULL) return EINVAL; if ((sender_ip && sender_ip->sin_family != AF_INET) || (target_ip && target_ip->sin_family != AF_INET)) return EAFNOSUPPORT; result = mbuf_gethdr(MBUF_DONTWAIT, MBUF_TYPE_DATA, &m); if (result != 0) return result; mbuf_setlen(m, sizeof(*fwa)); mbuf_pkthdr_setlen(m, sizeof(*fwa)); /* Move the data pointer in the mbuf to the end, aligned to 4 bytes */ datap = (char*)mbuf_datastart(m); datap += mbuf_trailingspace(m); datap -= (((u_long)datap) & 0x3); mbuf_setdata(m, datap, sizeof(*fwa)); fwa = (IP1394_ARP*)mbuf_data(m); bzero((caddr_t)fwa, sizeof(*fwa)); /* Prepend the ethernet header, we will send the raw frame */ result = mbuf_prepend(&m, sizeof(*fwh), MBUF_DONTWAIT); if(result != 0) return result; fwh = (struct firewire_header*)mbuf_data(m); fwh->fw_type = htons(FWTYPE_ARP); /* Fill out the arp packet */ fwa->hardwareType = htons(ARP_HDW_TYPE); fwa->protocolType = htons(FWTYPE_IP); fwa->hwAddrLen = sizeof(IP1394_HDW_ADDR); fwa->ipAddrLen = IPV4_ADDR_SIZE; fwa->opcode = htons(arpop); fwa->senderMaxRec = lcb->ownHardwareAddress.maxRec; fwa->sspd = lcb->ownHardwareAddress.spd; fwa->senderUnicastFifoHi = htons(lcb->ownHardwareAddress.unicastFifoHi); fwa->senderUnicastFifoLo = htonl(lcb->ownHardwareAddress.unicastFifoLo); /* Sender Hardware */ if (sender_hw != NULL) bcopy(CONST_LLADDR(sender_hw), &fwa->senderUniqueID, sizeof(fwa->senderUniqueID)); else ifnet_lladdr_copy_bytes(ifp, &fwa->senderUniqueID, FIREWIRE_ADDR_LEN); ifnet_lladdr_copy_bytes(ifp, fwh->fw_shost, sizeof(fwh->fw_shost)); /* Sender IP */ if (sender_ip != NULL) fwa->senderIpAddress = sender_ip->sin_addr.s_addr; else { ifaddr_t *addresses; struct sockaddr sa; if (ifnet_get_address_list_family(ifp, &addresses, AF_INET) == 0) { ifaddr_address( addresses[0], &sa, 16 ); fwa->senderIpAddress = ((UInt32)(sa.sa_data[5] & 0xFF)) << 24; fwa->senderIpAddress |= ((UInt32)(sa.sa_data[4] & 0xFF)) << 16; fwa->senderIpAddress |= ((UInt32)(sa.sa_data[3] & 0xFF)) << 8; fwa->senderIpAddress |= ((UInt32)(sa.sa_data[2] & 0xFF)); ifnet_free_address_list(addresses); } else { mbuf_free(m); return ENXIO; } } /* Target Hardware */ if (target_hw == 0) bcopy(fwbroadcastaddr, fwh->fw_dhost, sizeof(fwh->fw_dhost)); else bcopy(CONST_LLADDR(target_hw), fwh->fw_dhost, sizeof(fwh->fw_dhost)); /* Target IP */ fwa->targetIpAddress = target_ip->sin_addr.s_addr; ifnet_output_raw(ifp, PF_INET, m); return 0; }