static int bsd_get_mac(const char ifname[], uint8_t eth_addr[]) { struct ifreq *ifrp; struct ifconf ifc; char buffer[720]; int socketfd,error,len,space=0; ifc.ifc_len=sizeof(buffer); len=ifc.ifc_len; ifc.ifc_buf=buffer; socketfd=socket(AF_INET,SOCK_DGRAM,0); if((error=ioctl(socketfd,SIOCGIFCONF,&ifc))<0) { perror("ioctl faild"); exit(1); } if(ifc.ifc_len<=len) { ifrp=ifc.ifc_req; do { struct sockaddr *sa=&ifrp->ifr_addr; if(((struct sockaddr_dl *)sa)->sdl_type==IFT_ETHER) { if (strcmp(ifname, ifrp->ifr_name) == 0){ memcpy (eth_addr, LLADDR((struct sockaddr_dl *)&ifrp->ifr_addr), 6); return 0; } } ifrp=(struct ifreq*)(sa->sa_len+(caddr_t)&ifrp->ifr_addr); space+=(int)sa->sa_len+sizeof(ifrp->ifr_name); } while(space<ifc.ifc_len); } return 1; }
/* * Perform common duties while attaching to interface list */ void iso88025_ifattach(struct ifnet *ifp, const u_int8_t *lla, int bpf) { struct ifaddr *ifa; struct sockaddr_dl *sdl; ifa = NULL; ifp->if_type = IFT_ISO88025; ifp->if_addrlen = ISO88025_ADDR_LEN; ifp->if_hdrlen = ISO88025_HDR_LEN; if_attach(ifp); /* Must be called before additional assignments */ ifp->if_output = iso88025_output; ifp->if_input = iso88025_input; ifp->if_resolvemulti = iso88025_resolvemulti; ifp->if_broadcastaddr = iso88025_broadcastaddr; if (ifp->if_baudrate == 0) ifp->if_baudrate = TR_16MBPS; /* 16Mbit should be a safe default */ if (ifp->if_mtu == 0) ifp->if_mtu = ISO88025_DEFAULT_MTU; ifa = ifp->if_addr; KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__)); sdl = (struct sockaddr_dl *)ifa->ifa_addr; sdl->sdl_type = IFT_ISO88025; sdl->sdl_alen = ifp->if_addrlen; bcopy(lla, LLADDR(sdl), ifp->if_addrlen); if (bpf) bpfattach(ifp, DLT_IEEE802, ISO88025_HDR_LEN); return; }
const char * log_sockaddr(struct sockaddr *sa) { static char buf[NI_MAXHOST]; if (sa == NULL) return "(none)"; if (sa->sa_family == AF_UNIX) { if (strlen(((struct sockaddr_un *)sa)->sun_path)) return ((struct sockaddr_un *)sa)->sun_path; else return "(local user)"; } else if (sa->sa_family == AF_LINK) { return ether_ntoa((struct ether_addr *)LLADDR((struct sockaddr_dl *)sa)); } if (getnameinfo(sa, sa->sa_len, buf, sizeof(buf), NULL, 0, NI_NUMERICHOST)) return "(unknown)"; else return buf; }
bool getGatewayMacAddress(quint32 ipv4Host, QByteArray& mac) { std::vector<char> data(512 * 1024); int mib[6]; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = AF_INET; mib[4] = NET_RT_FLAGS; mib[5] = RTF_LLINFO; size_t cb = data.size(); if (sysctl(mib, 6, &data[0], &cb, NULL, 0) == 0) { const char *p = &data[0]; const char *pe = p + cb; const rt_msghdr *rtm; for (; p != pe; p += rtm->rtm_msglen) { rtm = reinterpret_cast<const rt_msghdr*>(p); const sockaddr_inarp *sin = reinterpret_cast<const sockaddr_inarp*>(rtm + 1); const sockaddr_dl *sdl = reinterpret_cast<const sockaddr_dl*>(sin + 1); if (sdl->sdl_alen) { if (ntohl(sin->sin_addr.s_addr) == ipv4Host) { u_char *cp = (u_char*)LLADDR(sdl); for (int i = 0; i < 6; i++) { mac.push_back(cp[i]); } return true; } } } } return false; }
/* * sifproxyarp - Make a proxy ARP entry for the peer. */ int sifproxyarp( int unit, uint32_t hisaddr) { struct arpreq arpreq; struct { struct sockaddr_dl sdl; char space[128]; } dls; BZERO(&arpreq, sizeof(arpreq)); /* * Get the hardware address of an interface on the same subnet * as our local address. */ if (!get_ether_addr(hisaddr, &dls.sdl)) { error("Cannot determine ethernet address for proxy ARP"); return 0; } arpreq.arp_ha.sa_len = sizeof(struct sockaddr); arpreq.arp_ha.sa_family = AF_UNSPEC; BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen); SET_SA_FAMILY(arpreq.arp_pa, AF_INET); ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; arpreq.arp_flags = ATF_PERM | ATF_PUBL; if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) { error("Couldn't add proxy arp entry: %m"); return 0; } proxy_arp_addr = hisaddr; return 1; }
void lladdropt_fill(struct sockaddr_dl *sdl, struct nd_opt_hdr *ndopt) { char *addr; ndopt->nd_opt_type = ND_OPT_SOURCE_LINKADDR; /* fixed */ switch (sdl->sdl_type) { case IFT_ETHER: #ifdef IFT_IEEE80211 case IFT_IEEE80211: #endif ndopt->nd_opt_len = (ROUNDUP8(ETHER_ADDR_LEN + 2)) >> 3; addr = (char *)(ndopt + 1); memcpy(addr, LLADDR(sdl), ETHER_ADDR_LEN); break; default: warnmsg(LOG_ERR, __func__, "unsupported link type(%d)", sdl->sdl_type); exit(1); } return; }
/* * Perform common duties while attaching to interface list. */ void atm_ifattach(struct ifnet *ifp) { struct ifaddr *ifa; struct sockaddr_dl *sdl; struct ifatm *ifatm = ifp->if_l2com; ifp->if_addrlen = 0; ifp->if_hdrlen = 0; if_attach(ifp); ifp->if_mtu = ATMMTU; ifp->if_output = atm_output; #if 0 ifp->if_input = atm_input; #endif ifp->if_snd.ifq_maxlen = 50; /* dummy */ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) if (ifa->ifa_addr->sa_family == AF_LINK) { sdl = (struct sockaddr_dl *)ifa->ifa_addr; sdl->sdl_type = IFT_ATM; sdl->sdl_alen = ifp->if_addrlen; #ifdef notyet /* if using ATMARP, store hardware address using the next line */ bcopy(ifp->hw_addr, LLADDR(sdl), ifp->if_addrlen); #endif break; } ifp->if_linkmib = &ifatm->mib; ifp->if_linkmiblen = sizeof(ifatm->mib); if(ng_atm_attach_p) (*ng_atm_attach_p)(ifp); if (atm_harp_attach_p) (*atm_harp_attach_p)(ifp); }
QT_BEGIN_INCLUDE_NAMESPACE # include <net/if_dl.h> QT_END_INCLUDE_NAMESPACE static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList) { QList<QNetworkInterfacePrivate *> interfaces; // on NetBSD we use AF_LINK and sockaddr_dl // scan the list for that family for (ifaddrs *ptr = rawList; ptr; ptr = ptr->ifa_next) if (ptr->ifa_addr && ptr->ifa_addr->sa_family == AF_LINK) { QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate; interfaces << iface; sockaddr_dl *sdl = (sockaddr_dl *)ptr->ifa_addr; iface->index = sdl->sdl_index; iface->name = QString::fromLatin1(ptr->ifa_name); iface->flags = convertFlags(ptr->ifa_flags); iface->hardwareAddress = iface->makeHwAddress(sdl->sdl_alen, (uchar*)LLADDR(sdl)); } return interfaces; }
static uint64_t _system_hostid_lookup( struct ifaddrs* ifaddr ) { unsigned int j; union { uint64_t id; unsigned char ALIGN(8) buffer[8]; } hostid; if( ifaddr->ifa_addr && ( ifaddr->ifa_addr->sa_family == AF_LINK ) ) { struct sockaddr_dl* addr_dl = (struct sockaddr_dl*)ifaddr->ifa_addr; FOUNDATION_ASSERT( addr_dl->sdl_alen == 6 ); hostid.id = 0; for( j = 0; j < 6; ++j ) hostid.buffer[5-j] = LLADDR(addr_dl)[j]; return hostid.id; } return 0; }
static int eth_get(const char *device, u8 ea[ETH_ALEN]) { struct if_msghdr *ifm; struct sockaddr_dl *sdl; u_char *p, *buf; size_t len; int mib[] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 }; if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) return -1; if ((buf = os_malloc(len)) == NULL) return -1; if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { os_free(buf); return -1; } for (p = buf; p < buf + len; p += ifm->ifm_msglen) { ifm = (struct if_msghdr *)p; sdl = (struct sockaddr_dl *)(ifm + 1); if (ifm->ifm_type != RTM_IFINFO || (ifm->ifm_addrs & RTA_IFP) == 0) continue; if (sdl->sdl_family != AF_LINK || sdl->sdl_nlen == 0 || os_memcmp(sdl->sdl_data, device, sdl->sdl_nlen) != 0) continue; os_memcpy(ea, LLADDR(sdl), sdl->sdl_alen); break; } os_free(buf); if (p >= buf + len) { errno = ESRCH; return -1; } return 0; }
/* Send router advertisement packet. */ static void rtadv_send_packet (int sock, struct interface *ifp) { struct msghdr msg; struct iovec iov; struct cmsghdr *cmsgptr; struct in6_pktinfo *pkt; struct sockaddr_in6 addr; #ifdef HAVE_STRUCT_SOCKADDR_DL struct sockaddr_dl *sdl; #endif /* HAVE_STRUCT_SOCKADDR_DL */ static void *adata = NULL; unsigned char buf[RTADV_MSG_SIZE]; struct nd_router_advert *rtadv; int ret; int len = 0; struct zebra_if *zif; struct rtadv_prefix *rprefix; u_char all_nodes_addr[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; struct listnode *node; /* * Allocate control message bufffer. This is dynamic because * CMSG_SPACE is not guaranteed not to call a function. Note that * the size will be different on different architectures due to * differing alignment rules. */ if (adata == NULL) { /* XXX Free on shutdown. */ adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo))); if (adata == NULL) zlog_err("rtadv_send_packet: can't malloc control data\n"); } /* Logging of packet. */ if (IS_ZEBRA_DEBUG_PACKET) zlog_debug ("Router advertisement send to %s", ifp->name); /* Fill in sockaddr_in6. */ memset (&addr, 0, sizeof (struct sockaddr_in6)); addr.sin6_family = AF_INET6; #ifdef SIN6_LEN addr.sin6_len = sizeof (struct sockaddr_in6); #endif /* SIN6_LEN */ addr.sin6_port = htons (IPPROTO_ICMPV6); memcpy (&addr.sin6_addr, all_nodes_addr, sizeof (struct in6_addr)); /* Fetch interface information. */ zif = ifp->info; /* Make router advertisement message. */ rtadv = (struct nd_router_advert *) buf; rtadv->nd_ra_type = ND_ROUTER_ADVERT; rtadv->nd_ra_code = 0; rtadv->nd_ra_cksum = 0; rtadv->nd_ra_curhoplimit = 64; /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */ rtadv->nd_ra_flags_reserved = zif->rtadv.AdvDefaultLifetime == 0 ? 0 : zif->rtadv.DefaultPreference; rtadv->nd_ra_flags_reserved <<= 3; if (zif->rtadv.AdvManagedFlag) rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED; if (zif->rtadv.AdvOtherConfigFlag) rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER; if (zif->rtadv.AdvHomeAgentFlag) rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT; rtadv->nd_ra_router_lifetime = htons (zif->rtadv.AdvDefaultLifetime); rtadv->nd_ra_reachable = htonl (zif->rtadv.AdvReachableTime); rtadv->nd_ra_retransmit = htonl (0); len = sizeof (struct nd_router_advert); if (zif->rtadv.AdvHomeAgentFlag) { struct nd_opt_homeagent_info *ndopt_hai = (struct nd_opt_homeagent_info *)(buf + len); ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION; ndopt_hai->nd_opt_hai_len = 1; ndopt_hai->nd_opt_hai_reserved = 0; ndopt_hai->nd_opt_hai_preference = htons(zif->rtadv.HomeAgentPreference); ndopt_hai->nd_opt_hai_lifetime = htons(zif->rtadv.HomeAgentLifetime); len += sizeof(struct nd_opt_homeagent_info); } if (zif->rtadv.AdvIntervalOption) { struct nd_opt_adv_interval *ndopt_adv = (struct nd_opt_adv_interval *)(buf + len); ndopt_adv->nd_opt_ai_type = ND_OPT_ADV_INTERVAL; ndopt_adv->nd_opt_ai_len = 1; ndopt_adv->nd_opt_ai_reserved = 0; ndopt_adv->nd_opt_ai_interval = htonl(zif->rtadv.MaxRtrAdvInterval); len += sizeof(struct nd_opt_adv_interval); } /* Fill in prefix. */ for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix)) { struct nd_opt_prefix_info *pinfo; pinfo = (struct nd_opt_prefix_info *) (buf + len); pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION; pinfo->nd_opt_pi_len = 4; pinfo->nd_opt_pi_prefix_len = rprefix->prefix.prefixlen; pinfo->nd_opt_pi_flags_reserved = 0; if (rprefix->AdvOnLinkFlag) pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_ONLINK; if (rprefix->AdvAutonomousFlag) pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO; if (rprefix->AdvRouterAddressFlag) pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR; pinfo->nd_opt_pi_valid_time = htonl (rprefix->AdvValidLifetime); pinfo->nd_opt_pi_preferred_time = htonl (rprefix->AdvPreferredLifetime); pinfo->nd_opt_pi_reserved2 = 0; memcpy (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.u.prefix6, sizeof (struct in6_addr)); #ifdef DEBUG { u_char buf[INET6_ADDRSTRLEN]; zlog_debug ("DEBUG %s", inet_ntop (AF_INET6, &pinfo->nd_opt_pi_prefix, buf, INET6_ADDRSTRLEN)); } #endif /* DEBUG */ len += sizeof (struct nd_opt_prefix_info); } /* Hardware address. */ #ifdef HAVE_STRUCT_SOCKADDR_DL sdl = &ifp->sdl; if (sdl != NULL && sdl->sdl_alen != 0) { buf[len++] = ND_OPT_SOURCE_LINKADDR; /* Option length should be rounded up to next octet if the link address does not end on an octet boundary. */ buf[len++] = (sdl->sdl_alen + 9) >> 3; memcpy (buf + len, LLADDR (sdl), sdl->sdl_alen); len += sdl->sdl_alen; /* Pad option to end on an octet boundary. */ memset (buf + len, 0, -(sdl->sdl_alen + 2) & 0x7); len += -(sdl->sdl_alen + 2) & 0x7; }
int get_macaddr(const char *ifname, U8 *addr) { #if defined(__NBR_OSX__) kern_return_t kernResult = KERN_SUCCESS; io_iterator_t intfIterator; UInt8 MACAddress[kIOEthernetAddressSize]; kernResult = FindEthernetInterfaces(&intfIterator); if (KERN_SUCCESS != kernResult) { //OSDEP_ERROUT(ERROR,SYSCALL,"FindEthernetInterfaces returned 0x%08x\n", kernResult); return NBR_ESYSCALL; } else { kernResult = GetMACAddress(intfIterator, addr, sizeof(MACAddress)); if (KERN_SUCCESS != kernResult) { //OSDEP_ERROUT(ERROR,SYSCALL,"GetMACAddress returned 0x%08x\n", kernResult); } else { TRACE("This system's built-in MAC address is %02x:%02x:%02x:%02x:%02x:%02x.\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); } } (void) IOObjectRelease(intfIterator); // Release the iterator. return kernResult == KERN_SUCCESS ? NBR_OK : NBR_ESYSCALL; #elif defined(__NBR_IOS__) int mib[6]; size_t len; char *buf; unsigned char *ptr; struct if_msghdr *ifm; struct sockaddr_dl *sdl; mib[0] = CTL_NET; mib[1] = AF_ROUTE; mib[2] = 0; mib[3] = AF_LINK; mib[4] = NET_RT_IFLIST; if ((mib[5] = if_nametoindex(ifname)) == 0) { TRACE("Error: if_nametoindex error\n"); return NBR_ESYSCALL; } if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { TRACE("Error: sysctl, take 1\n"); return NBR_ESYSCALL; } if ((buf = (char *)util::mem::alloc(len)) == NULL) { TRACE("Could not allocate memory. error!\n"); return NBR_EMALLOC; } if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { TRACE("Error: sysctl, take 2"); util::mem::free(buf); return NBR_ESYSCALL; } ifm = (struct if_msghdr *)buf; sdl = (struct sockaddr_dl *)(ifm + 1); ptr = (unsigned char *)LLADDR(sdl); util::mem::copy(addr, ptr, 6); util::mem::free(buf); TRACE("MAC ADDRESS (%s): [%02X:%02X:%02X:%02X:%02X:%02X]\n", ifname, *addr, *(addr+1), *(addr+2), *(addr+3), *(addr+4), *(addr+5)); return NBR_OK; #else int soc, ret; struct ifreq req; if ((soc = socket(AF_INET, SOCK_STREAM, 0)) < 0) { TRACE("socket fail: ret=%d,errno=%d",soc,errno); ret = soc; goto error; } util::str::copy(req.ifr_name, ifname, sizeof(req.ifr_name)); req.ifr_addr.sa_family = AF_INET; if ((ret = ioctl(soc, SIOCGIFHWADDR, &req)) < 0) { TRACE("ioctl fail: soc=%d,ret=%d,errno=%d",soc,ret,errno); goto error; } util::mem::copy(addr, &(req.ifr_addr.sa_data), 6); ret = 0; TRACE("MAC ADDRESS (%s): [%02X:%02X:%02X:%02X:%02X:%02X]\n", ifname, *addr, *(addr+1), *(addr+2), *(addr+3), *(addr+4), *(addr+5)); error: if (soc >= 0) { close(soc); } return ret; #endif }
struct libnet_ether_addr * libnet_get_hwaddr(libnet_t *l) { int mib[6]; size_t len; int8_t *buf, *next, *end; struct if_msghdr *ifm; struct sockaddr_dl *sdl; /* This implementation is not-reentrant. */ static struct libnet_ether_addr ea; mib[0] = CTL_NET; mib[1] = AF_ROUTE; mib[2] = 0; mib[3] = AF_LINK; mib[4] = NET_RT_IFLIST; mib[5] = 0; if (l == NULL) { return (NULL); } if (l->device == NULL) { if (libnet_select_device(l) == -1) { /* err msg set in libnet_select_device */ return (NULL); } } if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): sysctl(): %s", __func__, strerror(errno)); return (NULL); } buf = (int8_t *)malloc(len); if (buf == NULL) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): malloc(): %s", __func__, strerror(errno)); return (NULL); } if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): sysctl(): %s", __func__, strerror(errno)); free(buf); return (NULL); } end = buf + len; for (next = buf ; next < end ; next += ifm->ifm_msglen) { ifm = (struct if_msghdr *)next; if (ifm->ifm_version != RTM_VERSION) continue; if (ifm->ifm_type == RTM_IFINFO) { sdl = (struct sockaddr_dl *)(ifm + 1); if (sdl->sdl_type != IFT_ETHER && sdl->sdl_type != IFT_FASTETHER && sdl->sdl_type != IFT_FASTETHERFX && sdl->sdl_type != IFT_GIGABITETHERNET && sdl->sdl_type != IFT_L2VLAN) continue; if (strncmp(&sdl->sdl_data[0], l->device, sdl->sdl_nlen) == 0) { memcpy(ea.ether_addr_octet, LLADDR(sdl), ETHER_ADDR_LEN); break; } } } free(buf); if (next == end) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): interface %s of known type not found.", __func__, l->device); return NULL; } return (&ea); }
char * get_iface_mac(char *ifname) { #if defined(__linux__) int r, s; struct ifreq ifr; char *hwaddr, mac[13]; strcpy(ifr.ifr_name, ifname); s = socket(PF_INET, SOCK_DGRAM, 0); if (-1 == s) { debug(LOG_ERR, "get_iface_mac socket: %s", strerror(errno)); return NULL; } r = ioctl(s, SIOCGIFHWADDR, &ifr); if (r == -1) { debug(LOG_ERR, "get_iface_mac ioctl(SIOCGIFHWADDR): %s", strerror(errno)); close(s); return NULL; } hwaddr = ifr.ifr_hwaddr.sa_data; close(s); snprintf(mac, sizeof(mac), "%02X%02X%02X%02X%02X%02X", hwaddr[0] & 0xFF, hwaddr[1] & 0xFF, hwaddr[2] & 0xFF, hwaddr[3] & 0xFF, hwaddr[4] & 0xFF, hwaddr[5] & 0xFF ); return safe_strdup(mac); #elif defined(__NetBSD__) struct ifaddrs *ifa, *ifap; const char *hwaddr; char mac[13], *str = NULL; struct sockaddr_dl *sdl; if (getifaddrs(&ifap) == -1) { debug(LOG_ERR, "getifaddrs(): %s", strerror(errno)); return NULL; } for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { if (strcmp(ifa->ifa_name, ifname) == 0 && ifa->ifa_addr->sa_family == AF_LINK) break; } if (ifa == NULL) { debug(LOG_ERR, "%s: no link-layer address assigned"); goto out; } sdl = (struct sockaddr_dl *)ifa->ifa_addr; hwaddr = LLADDR(sdl); snprintf(mac, sizeof(mac), "%02X%02X%02X%02X%02X%02X", hwaddr[0] & 0xFF, hwaddr[1] & 0xFF, hwaddr[2] & 0xFF, hwaddr[3] & 0xFF, hwaddr[4] & 0xFF, hwaddr[5] & 0xFF); str = safe_strdup(mac); out: freeifaddrs(ifap); return str; #else return NULL; #endif }
/* * Set an individual arp entry */ int arptab_set(u_char *eaddr, u_int32_t host) { struct sockaddr_inarp *sin = &sin_m; struct rt_msghdr *rtm = &(m_rtmsg.m_rtm); struct sockaddr_dl *sdl; struct timeval now; int rt; getsocket(); pid = getpid(); sdl_m = blank_sdl; sin_m = blank_sin; sin->sin_addr.s_addr = host; memcpy((u_char *)LLADDR(&sdl_m), (char *)eaddr, 6); sdl_m.sdl_alen = 6; expire_time = 0; doing_proxy = flags = export_only = 0; gettimeofday(&now, 0); expire_time = now.tv_sec + 20 * 60; tryagain: if (rtmsg(RTM_GET) < 0) { syslog(LOG_ERR,"%s: %m", inet_ntoa(sin->sin_addr)); close(s); s = -1; return (1); } sin = (struct sockaddr_inarp *)((char *)rtm + rtm->rtm_hdrlen); sdl = (struct sockaddr_dl *)(sin->sin_len + (char *)sin); if (sin->sin_addr.s_addr == sin_m.sin_addr.s_addr) { if (sdl->sdl_family == AF_LINK && (rtm->rtm_flags & RTF_LLINFO) && !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) { case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: case IFT_ISO88024: case IFT_ISO88025: goto overwrite; default: break; } if (doing_proxy == 0) { syslog(LOG_ERR, "arptab_set: can only proxy for %s", inet_ntoa(sin->sin_addr)); close(s); s = -1; return (1); } if (sin_m.sin_other & SIN_PROXY) { syslog(LOG_ERR, "arptab_set: proxy entry exists for non 802 device"); close(s); s = -1; return(1); } sin_m.sin_other = SIN_PROXY; export_only = 1; goto tryagain; } overwrite: if (sdl->sdl_family != AF_LINK) { syslog(LOG_ERR, "arptab_set: cannot intuit interface index and type for %s", inet_ntoa(sin->sin_addr)); close(s); s = -1; return (1); } sdl_m.sdl_type = sdl->sdl_type; sdl_m.sdl_index = sdl->sdl_index; rt = rtmsg(RTM_ADD); close(s); s = -1; return (rt); }
signed openchannel (struct channel * channel) { #if defined (__linux__) struct ifreq ifreq; struct sockaddr_ll sockaddr_ll = { PF_PACKET, 0x0000, 0x0000, ARPHRD_ETHER, PACKET_HOST, ETHER_ADDR_LEN, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; /* * raw packets require root privileges on linux; one does not have to be * root when this program is installed setuid using 'chown root:root' and * 'chmod 4555'; */ if (geteuid ()) { error (1, EPERM, ERROR_NOTROOT); } memset (&ifreq, 0, sizeof (ifreq)); sockaddr_ll.sll_protocol = htons (channel->type); if ((channel->fd = socket (sockaddr_ll.sll_family, SOCK_RAW, sockaddr_ll.sll_protocol)) == -1) { error (1, errno, "%s", channel->ifname); } memcpy (ifreq.ifr_name, channel->ifname, sizeof (ifreq.ifr_name)); if (ioctl (channel->fd, SIOCGIFINDEX, &ifreq) == -1) { error (1, errno, "%s", ifreq.ifr_name); } channel->ifindex = sockaddr_ll.sll_ifindex = ifreq.ifr_ifindex; if (ioctl (channel->fd, SIOCGIFHWADDR, &ifreq) == -1) { error (1, errno, "%s", ifreq.ifr_name); } memcpy (sockaddr_ll.sll_addr, ifreq.ifr_ifru.ifru_hwaddr.sa_data, sizeof (sockaddr_ll.sll_addr)); if (bind (channel->fd, (struct sockaddr *) (&sockaddr_ll), sizeof (sockaddr_ll)) == -1) { error (1, errno, "%s", ifreq.ifr_name); } memcpy (channel->host, sockaddr_ll.sll_addr, sizeof (channel->host)); if (ioctl (channel->fd, SIOCGIFFLAGS, &ifreq) == -1) { error (1, errno, "%s", ifreq.ifr_name); } channel->ifstate = ifreq.ifr_flags; _setbits (ifreq.ifr_flags, (IFF_UP | IFF_BROADCAST | IFF_MULTICAST)); _clrbits (ifreq.ifr_flags, (IFF_ALLMULTI | IFF_PROMISC)); if (ioctl (channel->fd, SIOCSIFFLAGS, &ifreq) == -1) { error (1, errno, "%s", ifreq.ifr_name); } #else struct bpf_program bpf_program; static struct bpf_insn bpf_insn [] = { { BPF_LD + BPF_H + BPF_ABS, 0, 0, 12 }, { BPF_JMP + BPF_JEQ + BPF_K, 0, 18, 0 }, { BPF_LD + BPF_B + BPF_ABS, 0, 0, 0 }, { BPF_JMP + BPF_JEQ + BPF_K, 0, 10, 0 }, { BPF_LD + BPF_B + BPF_ABS, 0, 0, 1 }, { BPF_JMP + BPF_JEQ + BPF_K, 0, 8, 0 }, { BPF_LD + BPF_B + BPF_ABS, 0, 0, 2 }, { BPF_JMP + BPF_JEQ + BPF_K, 0, 6, 0 }, { BPF_LD + BPF_B + BPF_ABS, 0, 0, 3 }, { BPF_JMP + BPF_JEQ + BPF_K, 0, 4, 0 }, { BPF_LD + BPF_B + BPF_ABS, 0, 0, 4 }, { BPF_JMP + BPF_JEQ + BPF_K, 0, 2, 0 }, { BPF_LD + BPF_B + BPF_ABS, 0, 0, 5 }, { BPF_JMP + BPF_JEQ + BPF_K, 4, 0, 0 }, { BPF_LD + BPF_W + BPF_ABS, 0, 0, 0 }, { BPF_JMP + BPF_JEQ + BPF_K, 0, 4, 0xFFFFFFFF }, { BPF_LD + BPF_H + BPF_ABS, 0, 0, 4 }, { BPF_JMP + BPF_JEQ + BPF_K, 0, 2, 0xFFFF }, { BPF_LD + BPF_W + BPF_LEN, 0, 0, 0 }, { BPF_RET + BPF_A, 0, 0, 0 }, { BPF_RET + BPF_K, 0, 0, 0 } }; #if defined (__APPLE__) || defined (__OpenBSD__) || defined (__NetBSD__) struct ifreq ifreq; struct timeval timeval; struct bpf * bpf; char filename [sizeof (CHANNEL_BPFDEVICE) + 1]; unsigned count; unsigned state; int stat_errno = 0; int open_errno = 0; for (count = 0; count < 100; count++) { struct stat st; snprintf (filename, sizeof (filename), CHANNEL_BPFDEVICE, count); if (stat(filename, &st) == -1) { stat_errno = errno; continue; } if ((channel->fd = open (filename, O_RDWR)) != -1) { break; } else { open_errno = errno; } } if (channel->fd == -1) { if (open_errno) { error (1, open_errno, "Could not open bpf device"); } else { error (1, stat_errno, "No bpf device found"); } } memcpy (ifreq.ifr_name, channel->ifname, sizeof (ifreq.ifr_name)); if (ioctl (channel->fd, BIOCSETIF, &ifreq) == -1) { error (1, errno, "%s", ifreq.ifr_name); } channel->bpf = bpf = malloc (sizeof (* bpf)); if (ioctl (channel->fd, BIOCGBLEN, &bpf->bpf_length) == -1) { error (1, errno, "Can't determine buffer length: %s", ifreq.ifr_name); } bpf->bpf_bp = bpf->bpf_buffer = malloc (bpf->bpf_length); if (bpf->bpf_buffer == NULL) { error (1, errno, "Can't allocate receive buffer"); } #if defined (__APPLE__) || defined (__NetBSD__) state = 0; if (ioctl (channel->fd, BIOCSSEESENT, &state) == -1) { error (1, errno, "Can't hide outgoing frames: %s", ifreq.ifr_name); } #elif defined (__OpenBSD__) state = BPF_DIRECTION_OUT; if (ioctl (channel->fd, BIOCSDIRFILT, &state) == -1) { error (0, errno, "Can't hide outgoing frames"); } #else #error "Abandon all hope" #endif if (channel->capture > 1000) { timeval.tv_sec = channel->capture / 1000; timeval.tv_usec = 0; } else { #if defined (__MAC_10_6) /* * accommodate known bug in BPF on MAC OS X 10.6; shorter times cause socket read * operations to block indefinitely if no frames are waiting because tv_usec gets * clobbered; */ timeval.tv_sec = 1; timeval.tv_usec = 0; #else timeval.tv_sec = 0; timeval.tv_usec = channel->capture * 1000; #endif } if (ioctl (channel->fd, BIOCSRTIMEOUT, &timeval) == -1) { error (1, errno, "Can't set channel timeout: %s", ifreq.ifr_name); } state = 1; if (ioctl (channel->fd, BIOCIMMEDIATE, &state) == -1) { error (1, errno, "Can't set immediate mode: %s", ifreq.ifr_name); } #if 1 state = 1; if (ioctl (channel->fd, BIOCSHDRCMPLT, &state) == -1) { error (1, errno, "Can't set header complete mode: %s", ifreq.ifr_name); } #endif #if 1 gethwaddr (channel->host, channel->ifname); #else if (ioctl (channel->fd, SIOCGIFADDR, &ifreq) > 0) { error (1, errno, "%s", ifreq.ifr_name); } memcpy (channel->host, LLADDR (ifreq.ifr_ifru.ifru_addr), sizeof (channel->host)); #endif bpf_program.bf_len = sizeof (bpf_insn) / sizeof (struct bpf_insn); bpf_program.bf_insns = bpf_insn; if (channel->type == ETH_P_802_2) { bpf_insn [1].code = BPF_JMP + BPF_JGT + BPF_K; bpf_insn [1].jt = 18; bpf_insn [1].jf = 0; bpf_insn [1].k = ETHERMTU; } else { bpf_insn [1].code = BPF_JMP + BPF_JEQ + BPF_K; bpf_insn [1].jt = 0; bpf_insn [1].jf = 18; bpf_insn [1].k = channel->type; } bpf_insn [3].k = channel->host [0]; bpf_insn [5].k = channel->host [1]; bpf_insn [7].k = channel->host [2]; bpf_insn [9].k = channel->host [3]; bpf_insn [11].k = channel->host [4]; bpf_insn [13].k = channel->host [5]; if (ioctl (channel->fd, BIOCSETF, &bpf_program) == -1) { error (1, errno, "Can't store filter: %s", channel->ifname); } #elif defined (WINPCAP) || defined (LIBPCAP) channel->ifname = getifname (channel->ifindex); gethwaddr (channel->host, channel->ifname); channel->socket = pcap_open_live (channel->ifname, 65536, 0, channel->capture, channel->errbuf); snprintf ((char *)(channel->ifname), strlen (channel->ifname), "nic%d", channel->ifindex); if (!channel->socket) { error (1, errno, "Can't open interface: %s", channel->ifname); } bpf_program.bf_len = sizeof (bpf_insn)/sizeof (struct bpf_insn); bpf_program.bf_insns = bpf_insn; if (channel->type == ETH_P_802_2) { bpf_insn [1].code = BPF_JMP + BPF_JGT + BPF_K; bpf_insn [1].jt = 18; bpf_insn [1].jf = 0; bpf_insn [1].k = ETHERMTU; } else { bpf_insn [1].code = BPF_JMP + BPF_JEQ + BPF_K; bpf_insn [1].jt = 0; bpf_insn [1].jf = 18; bpf_insn [1].k = channel->type; } bpf_insn [3].k = channel->host [0]; bpf_insn [5].k = channel->host [1]; bpf_insn [7].k = channel->host [2]; bpf_insn [9].k = channel->host [3]; bpf_insn [11].k = channel->host [4]; bpf_insn [13].k = channel->host [5]; if (pcap_setfilter (channel->socket, &bpf_program) < 0) { error (1, errno, "Can't store filter: %s", channel->ifname); } if (pcap_setmintocopy (channel->socket, ETHER_MIN_LEN) < 0) { error (1, errno, "Can't set pcap mintocopy: %s", channel->ifname); } #else #error "Unknown Environment" #endif #endif return (0); }
/* * Set an individual neighbor cache entry */ int set(int argc, char **argv) { struct sockaddr_in6 *sin = &sin_m; struct sockaddr_dl *sdl; struct rt_msghdr *rtm = &(m_rtmsg.m_rtm); struct addrinfo hints, *res; int gai_error; u_char *ea; char *host = argv[0], *eaddr = argv[1]; getsocket(); argc -= 2; argv += 2; sdl_m = blank_sdl; sin_m = blank_sin; bzero(&hints, sizeof(hints)); hints.ai_family = AF_INET6; gai_error = getaddrinfo(host, NULL, &hints, &res); if (gai_error) { fprintf(stderr, "ndp: %s: %s\n", host, gai_strerror(gai_error)); return 1; } sin->sin6_addr = ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; #ifdef __KAME__ if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) { *(u_int16_t *)&sin->sin6_addr.s6_addr[2] = htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id); } #endif ea = (u_char *)LLADDR(&sdl_m); if (ndp_ether_aton(eaddr, ea) == 0) sdl_m.sdl_alen = 6; flags = 0; expire_time = 0; while (argc-- > 0) { if (strncmp(argv[0], "temp", 4) == 0) { struct timespec sp; clock_gettime(CLOCK_MONOTONIC, &sp); expire_time = sp.tv_sec + 20 * 60; } else if (strncmp(argv[0], "proxy", 5) == 0) flags |= RTF_ANNOUNCE; argv++; } if (rtmsg(RTM_GET) < 0) { perror(host); return (1); } sin = (struct sockaddr_in6 *)(rtm + 1); sdl = (struct sockaddr_dl *)(RT_ROUNDUP(sin->sin6_len) + (char *)sin); if (IN6_ARE_ADDR_EQUAL(&sin->sin6_addr, &sin_m.sin6_addr)) { if (sdl->sdl_family == AF_LINK && (rtm->rtm_flags & RTF_LLINFO) && !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) { case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: case IFT_ISO88024: case IFT_ISO88025: goto overwrite; } /* * IPv4 arp command retries with sin_other = SIN_PROXY here. */ fprintf(stderr, "set: cannot configure a new entry\n"); return 1; } overwrite: if (sdl->sdl_family != AF_LINK) { printf("cannot intuit interface index and type for %s\n", host); return (1); } sdl_m.sdl_type = sdl->sdl_type; sdl_m.sdl_index = sdl->sdl_index; return (rtmsg(RTM_ADD)); }
DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr, PDWORD type) { DWORD ret; struct if_msghdr *ifm; struct sockaddr_dl *sdl; u_char *p, *buf; size_t mibLen; int mib[] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 }; int addrLen; BOOL found = FALSE; if (!name || !len || !addr || !type) return ERROR_INVALID_PARAMETER; if (sysctl(mib, 6, NULL, &mibLen, NULL, 0) < 0) return ERROR_NO_MORE_FILES; buf = HeapAlloc(GetProcessHeap(), 0, mibLen); if (!buf) return ERROR_NOT_ENOUGH_MEMORY; if (sysctl(mib, 6, buf, &mibLen, NULL, 0) < 0) { HeapFree(GetProcessHeap(), 0, buf); return ERROR_NO_MORE_FILES; } ret = ERROR_INVALID_DATA; for (p = buf; !found && p < buf + mibLen; p += ifm->ifm_msglen) { ifm = (struct if_msghdr *)p; sdl = (struct sockaddr_dl *)(ifm + 1); if (ifm->ifm_type != RTM_IFINFO || (ifm->ifm_addrs & RTA_IFP) == 0) continue; if (sdl->sdl_family != AF_LINK || sdl->sdl_nlen == 0 || memcmp(sdl->sdl_data, name, max(sdl->sdl_nlen, strlen(name))) != 0) continue; found = TRUE; addrLen = min(MAX_INTERFACE_PHYSADDR, sdl->sdl_alen); if (addrLen > *len) { ret = ERROR_INSUFFICIENT_BUFFER; *len = addrLen; } else { if (addrLen > 0) memcpy(addr, LLADDR(sdl), addrLen); /* zero out remaining bytes for broken implementations */ memset(addr + addrLen, 0, *len - addrLen); *len = addrLen; #if defined(HAVE_NET_IF_TYPES_H) switch (sdl->sdl_type) { case IFT_ETHER: *type = MIB_IF_TYPE_ETHERNET; break; case IFT_FDDI: *type = MIB_IF_TYPE_FDDI; break; case IFT_ISO88024: /* Token Bus */ *type = MIB_IF_TYPE_TOKENRING; break; case IFT_ISO88025: /* Token Ring */ *type = MIB_IF_TYPE_TOKENRING; break; case IFT_PPP: *type = MIB_IF_TYPE_PPP; break; case IFT_SLIP: *type = MIB_IF_TYPE_SLIP; break; case IFT_LOOP: *type = MIB_IF_TYPE_LOOPBACK; break; default: *type = MIB_IF_TYPE_OTHER; } #else /* default if we don't know */ *type = MIB_IF_TYPE_ETHERNET; #endif ret = NO_ERROR; } } HeapFree(GetProcessHeap(), 0, buf); return ret; }
/* * Set an individual neighbor cache entry */ static int set(int argc, char **argv) { register struct sockaddr_in6 *sin = &sin_m; register struct sockaddr_dl *sdl; register struct rt_msghdr *rtm = &(m_rtmsg.m_rtm); struct addrinfo hints, *res; int gai_error; u_char *ea; char *host = argv[0], *eaddr = argv[1]; getsocket(); argc -= 2; argv += 2; sdl_m = blank_sdl; sin_m = blank_sin; bzero(&hints, sizeof(hints)); hints.ai_family = AF_INET6; gai_error = getaddrinfo(host, NULL, &hints, &res); if (gai_error) { fprintf(stderr, "ndp: %s: %s\n", host, gai_strerror(gai_error)); return 1; } sin->sin6_addr = ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; sin->sin6_scope_id = ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id; ea = (u_char *)LLADDR(&sdl_m); if (ndp_ether_aton(eaddr, ea) == 0) sdl_m.sdl_alen = 6; flags = expire_time = 0; while (argc-- > 0) { if (strncmp(argv[0], "temp", 4) == 0) { struct timeval now; gettimeofday(&now, 0); expire_time = now.tv_sec + 20 * 60; } else if (strncmp(argv[0], "proxy", 5) == 0) flags |= RTF_ANNOUNCE; argv++; } if (rtmsg(RTM_GET) < 0) { errx(1, "RTM_GET(%s) failed", host); /* NOTREACHED */ } sin = (struct sockaddr_in6 *)(rtm + 1); sdl = (struct sockaddr_dl *)(ALIGN(sin->sin6_len) + (char *)sin); if (IN6_ARE_ADDR_EQUAL(&sin->sin6_addr, &sin_m.sin6_addr)) { if (sdl->sdl_family == AF_LINK && !(rtm->rtm_flags & RTF_GATEWAY)) { switch (sdl->sdl_type) { case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: case IFT_ISO88024: case IFT_ISO88025: case IFT_L2VLAN: case IFT_BRIDGE: goto overwrite; } } fprintf(stderr, "set: cannot configure a new entry\n"); return 1; } overwrite: if (sdl->sdl_family != AF_LINK) { printf("cannot intuit interface index and type for %s\n", host); return (1); } sdl_m.sdl_type = sdl->sdl_type; sdl_m.sdl_index = sdl->sdl_index; return (rtmsg(RTM_ADD)); }
uint8* BNetworkAddress::LinkLevelAddress() const { return LLADDR(&(sockaddr_dl&)fAddress); }
/* * Attach/setup the common net80211 state. Called by * the driver on attach to prior to creating any vap's. */ void ieee80211_ifattach(struct ieee80211com *ic, const uint8_t macaddr[IEEE80211_ADDR_LEN]) { struct ifnet *ifp = ic->ic_ifp; struct sockaddr_dl *sdl; struct ifaddr *ifa; KASSERT(ifp->if_type == IFT_IEEE80211, ("if_type %d", ifp->if_type)); TAILQ_INIT(&ic->ic_vaps); /* Create a taskqueue for all state changes */ ic->ic_tq = taskqueue_create("ic_taskq", M_WAITOK | M_ZERO, taskqueue_thread_enqueue, &ic->ic_tq); taskqueue_start_threads(&ic->ic_tq, 1, TDPRI_KERN_DAEMON, -1, "%s taskq", ifp->if_xname); /* * Fill in 802.11 available channel set, mark all * available channels as active, and pick a default * channel if not already specified. */ ieee80211_media_init(ic); ic->ic_update_mcast = null_update_mcast; ic->ic_update_promisc = null_update_promisc; ic->ic_hash_key = karc4random(); ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT; ic->ic_lintval = ic->ic_bintval; ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX; ieee80211_crypto_attach(ic); ieee80211_node_attach(ic); ieee80211_power_attach(ic); ieee80211_proto_attach(ic); #ifdef IEEE80211_SUPPORT_SUPERG ieee80211_superg_attach(ic); #endif ieee80211_ht_attach(ic); ieee80211_scan_attach(ic); ieee80211_regdomain_attach(ic); ieee80211_dfs_attach(ic); ieee80211_sysctl_attach(ic); ifp->if_addrlen = IEEE80211_ADDR_LEN; ifp->if_hdrlen = 0; if_attach(ifp, NULL); ifp->if_mtu = IEEE80211_MTU_MAX; ifp->if_broadcastaddr = ieee80211broadcastaddr; ifp->if_output = null_output; ifp->if_input = null_input; /* just in case */ ifp->if_resolvemulti = NULL; /* NB: callers check */ ifa = ifaddr_byindex(ifp->if_index); KASSERT(ifa != NULL, ("%s: no lladdr!", __func__)); sdl = (struct sockaddr_dl *)ifa->ifa_addr; sdl->sdl_type = IFT_ETHER; /* XXX IFT_IEEE80211? */ sdl->sdl_alen = IEEE80211_ADDR_LEN; IEEE80211_ADDR_COPY(LLADDR(sdl), macaddr); // IFAFREE(ifa); }
bool bootpc_init(bool update_files, bool forever) { struct bootp_packet call; struct bootp_packet reply; static u_int32_t xid = ~0xFF; struct ifreq ireq; struct ifnet *ifp; struct socket *so; int j; int error; struct sockaddr_in myaddr; struct ifaddr *ifa; struct sockaddr_dl *sdl = NULL; char *delim; struct proc *procp = NULL; /* * If already filled in, don't touch it here */ if (nfs_diskless_valid) return true; /* * If we are to update the files create the root * file structure. */ if (update_files) if (rtems_create_root_fs () < 0) { printf("Error creating the root filesystem.\nFile not created.\n"); update_files = 0; } if (dhcp_hostname != NULL) { /* free it */ dhcp_hostname=bootp_strdup_realloc(dhcp_hostname,0); } /* * Find a network interface. */ for (ifp = ifnet; ifp != 0; ifp = ifp->if_next) if ((ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) == 0) break; if (ifp == NULL) { printf("bootpc_init: no suitable interface\n"); return false; } bzero(&ireq,sizeof(ireq)); sprintf(ireq.ifr_name, "%s%d", ifp->if_name,ifp->if_unit); printf("bootpc_init: using network interface '%s'\n", ireq.ifr_name); if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0,procp)) != 0) { printf("bootpc_init: socreate, error=%d", error); return false; } if (bootpc_fakeup_interface(&ireq,so,procp) != 0) { soclose(so); return false; } /* Get HW address */ for (ifa = ifp->if_addrlist;ifa; ifa = ifa->ifa_next) if (ifa->ifa_addr->sa_family == AF_LINK && (sdl = ((struct sockaddr_dl *) ifa->ifa_addr)) && sdl->sdl_type == IFT_ETHER) break; if (!sdl) { printf("bootpc: Unable to find HW address\n"); soclose(so); return false; } if (sdl->sdl_alen != EALEN ) { printf("bootpc: HW address len is %d, expected value is %d\n", sdl->sdl_alen,EALEN); soclose(so); return false; } printf("bootpc hw address is "); delim=""; for (j=0;j<sdl->sdl_alen;j++) { printf("%s%x",delim,((unsigned char *)LLADDR(sdl))[j]); delim=":"; } printf("\n"); #if 0 bootpboot_p_iflist(); bootpboot_p_rtlist(); #endif while (true) { bzero((caddr_t) &call, sizeof(call)); /* bootpc part */ call.op = 1; /* BOOTREQUEST */ call.htype= 1; /* 10mb ethernet */ call.hlen=sdl->sdl_alen; /* Hardware address length */ call.hops=0; xid++; call.xid = txdr_unsigned(xid); bcopy(LLADDR(sdl),&call.chaddr,sdl->sdl_alen); call.vend[0]=99; call.vend[1]=130; call.vend[2]=83; call.vend[3]=99; call.vend[4]=255; call.secs = 0; call.flags = htons(0x8000); /* We need an broadcast answer */ error = bootpc_call(&call,&reply,procp); if (!error) break; printf("BOOTP call failed -- error %d", error); if (!forever) { soclose(so); return false; } } /* * Initialize network address structures */ bzero(&myaddr,sizeof(myaddr)); bzero(&dhcp_netmask,sizeof(dhcp_netmask)); bzero(&dhcp_gw,sizeof(dhcp_gw)); myaddr.sin_len = sizeof(myaddr); myaddr.sin_family = AF_INET; dhcp_netmask.sin_len = sizeof(dhcp_netmask); dhcp_netmask.sin_family = AF_INET; dhcp_gw.sin_len = sizeof(dhcp_gw); dhcp_gw.sin_family= AF_INET; /* * Set our address */ myaddr.sin_addr = reply.yiaddr; printip("My ip address",myaddr.sin_addr); /* * Process BOOTP/DHCP options */ if (reply.vend[0]==99 && reply.vend[1]==130 && reply.vend[2]==83 && reply.vend[3]==99) { processOptions (&reply.vend[4], sizeof(reply.vend) - 4); } if (dhcpOptionOverload & 1) { processOptions ((unsigned char *)reply.file, sizeof reply.file); } else { if (reply.file[0]) rtems_bsdnet_bootp_boot_file_name = bootp_strdup_realloc(rtems_bsdnet_bootp_boot_file_name,reply.file); } if (dhcpOptionOverload & 2) { processOptions ((unsigned char *)reply.sname, sizeof reply.sname); } else { if (reply.sname[0]) rtems_bsdnet_bootp_server_name = bootp_strdup_realloc(rtems_bsdnet_bootp_server_name,reply.sname); } if (rtems_bsdnet_bootp_server_name) printf ("Server name is %s\n", rtems_bsdnet_bootp_server_name); if (rtems_bsdnet_bootp_boot_file_name) printf ("Boot file is %s\n", rtems_bsdnet_bootp_boot_file_name); if (rtems_bsdnet_bootp_cmdline) printf ("Command line is %s\n", rtems_bsdnet_bootp_cmdline); /* * Use defaults if values were not supplied by BOOTP/DHCP options */ if (!dhcp_gotnetmask) { if (IN_CLASSA(ntohl(myaddr.sin_addr.s_addr))) dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET); else if (IN_CLASSB(ntohl(myaddr.sin_addr.s_addr))) dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET); else dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET); } printip ("Subnet mask", dhcp_netmask.sin_addr); if (!dhcp_gotserver) rtems_bsdnet_bootp_server_address = reply.siaddr; printip ("Server ip address" ,rtems_bsdnet_bootp_server_address); if (!dhcp_gotgw) dhcp_gw.sin_addr = reply.giaddr; printip ("Gateway ip address", dhcp_gw.sin_addr); if (!dhcp_gotlogserver) rtems_bsdnet_log_host_address = rtems_bsdnet_bootp_server_address; printip ("Log server ip address", rtems_bsdnet_log_host_address); /* * Update the files if we are asked too. */ if (update_files) { char *dn = rtems_bsdnet_domain_name; char *hn = dhcp_hostname; if (!dn) dn = "mydomain"; if (!hn) hn = "me"; rtems_rootfs_append_host_rec(myaddr.sin_addr.s_addr, hn, dn); /* * Should the given domainname be used here ? */ if (dhcp_gotserver) { if (rtems_bsdnet_bootp_server_name) hn = rtems_bsdnet_bootp_server_name; else hn = "bootps"; rtems_rootfs_append_host_rec(rtems_bsdnet_bootp_server_address.s_addr, hn, dn); } if (dhcp_gotlogserver) { rtems_rootfs_append_host_rec(rtems_bsdnet_log_host_address.s_addr, "logs", dn); } /* * Setup the DNS configuration file /etc/resolv.conf. */ if (rtems_bsdnet_nameserver_count) { int i; char buf[64]; const char *bufl[1]; bufl[0] = buf; #define MKFILE_MODE (S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH) if (rtems_bsdnet_domain_name && (strlen(rtems_bsdnet_domain_name) < (sizeof(buf) - 1))) { strcpy(buf, "search "); strcat(buf, rtems_bsdnet_domain_name); strcat(buf, "\n"); rtems_rootfs_file_append ("/etc/resolv.conf", MKFILE_MODE, 1, bufl); } for (i = 0; i < rtems_bsdnet_nameserver_count; i++) { strcpy(buf, "nameserver "); strcat(buf, inet_ntoa(rtems_bsdnet_nameserver[i])); strcat(buf, "\n"); if (rtems_rootfs_file_append ("/etc/resolv.conf", MKFILE_MODE, 1, bufl)) break; } } } /* * Configure the interface with the new settings */ error = bootpc_adjust_interface(&ireq,so, &myaddr,&dhcp_netmask,&dhcp_gw,procp); soclose(so); return true; }
int main(int argc, char **argv) { char buf[8192] = {0}; struct ifconf ifc = {0}; struct ifreq *ifr = NULL; int sck = 0; int nInterfaces = 0; int i = 0; char ip[INET6_ADDRSTRLEN] = {0}; struct ifreq *item; struct sockaddr *addr; socklen_t salen; char hostname[NI_MAXHOST]; struct ifreq *flagsStruct; char *ignoreLoopbackFlag = "--ignoreloopback"; int ignoreLoopback = 0; int argIndex = 1; /* Process command-line arguments. */ for(; argIndex < argc; argIndex++) { if(strcmp(argv[argIndex], ignoreLoopbackFlag) == 0) ignoreLoopback = 1; else { fprintf(stderr, "Invalid argument (%s)\n", argv[argIndex]); return 1; } } /* Get a socket handle. */ sck = socket(PF_INET, SOCK_DGRAM, 0); if(sck < 0) { fatal_perror("socket"); return 1; } /* Query available interfaces. */ ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if(ioctl(sck, SIOCGIFCONF, &ifc) < 0) { fatal_perror("ioctl(SIOCGIFCONF)"); return 1; } /* Iterate through the list of interfaces. */ ifr = ifc.ifc_req; nInterfaces = ifc.ifc_len / sizeof(struct ifreq); for(i = 0; i < nInterfaces; i++) { bzero(hostname, NI_MAXHOST); item = &ifr[i]; if(get_flags(sck, flagsStruct)) return 1; /* Check if this is a loopback adapter and skip it if requested. */ if(ignoreLoopback && ((flagsStruct->ifr_flags & IFF_LOOPBACK) != 0)) { free(flagsStruct); continue; } /* Show the device name and IP address */ addr = &(item->ifr_addr); switch(addr->sa_family) { case AF_INET: salen = sizeof(struct sockaddr_in); break; case AF_INET6: salen = sizeof(struct sockaddr_in6); break; default: salen = 0; } /* the call to get the mac address changes what is stored in the item, meaning that we need to determine the hostname now */ getnameinfo(addr, salen, hostname, sizeof(hostname), NULL, 0, NI_NAMEREQD); /* Get the address * This may seem silly but it seems to be needed on some systems */ if(ioctl(sck, SIOCGIFADDR, item) < 0) { fatal_perror("ioctl(OSIOCGIFADDR)"); } printf("%s %s", item->ifr_name, get_ip_str(addr, ip, INET6_ADDRSTRLEN)); /* Lots of different ways to get the ethernet address */ #ifdef SIOCGIFHWADDR /* Linux */ /* Get the MAC address */ if(ioctl(sck, SIOCGIFHWADDR, item) < 0) { fatal_perror("ioctl(SIOCGIFHWADDR)"); return 1; } /* display result */ printf(" %02x:%02x:%02x:%02x:%02x:%02x", (unsigned char)item->ifr_hwaddr.sa_data[0], (unsigned char)item->ifr_hwaddr.sa_data[1], (unsigned char)item->ifr_hwaddr.sa_data[2], (unsigned char)item->ifr_hwaddr.sa_data[3], (unsigned char)item->ifr_hwaddr.sa_data[4], (unsigned char)item->ifr_hwaddr.sa_data[5]); #elif SIOCGENADDR /* Solaris and possibly all SysVR4 */ /* Get the MAC address */ if(ioctl(sck, SIOCGENADDR, item) < 0) { fatal_perror("ioctl(SIOCGENADDR)"); } /* display result */ printf(" %02x:%02x:%02x:%02x:%02x:%02x", (unsigned char)item->ifr_enaddr[0], (unsigned char)item->ifr_enaddr[1], (unsigned char)item->ifr_enaddr[2], (unsigned char)item->ifr_enaddr[3], (unsigned char)item->ifr_enaddr[4], (unsigned char)item->ifr_enaddr[5]); #elif __MACH__ || __NetBSD__ || __OpenBSD__ || __FreeBSD__ /* MacOS X and all modern BSD implementations (I hope) */ int mib[6] = {0}; int len = 0; char *macbuf; struct if_msghdr *ifm; struct sockaddr_dl *sdl; unsigned char *ptr; mib[0] = CTL_NET; mib[1] = AF_ROUTE; mib[2] = 0; mib[3] = AF_LINK; mib[4] = NET_RT_IFLIST; mib[5] = if_nametoindex(item->ifr_name); if(mib[5] == 0) continue; if(sysctl(mib, 6, NULL, (size_t*)&len, NULL, 0) != 0) { fatal_perror("sysctl"); } macbuf = (char *) malloc(len); if(macbuf == NULL) { fprintf(stderr, "\nUnable to allocate necessary memory: %d\n", len); exit(1); } if(sysctl(mib, 6, macbuf, (size_t*)&len, NULL, 0) != 0) { fatal_perror("sysctl"); } ifm = (struct if_msghdr *)macbuf; sdl = (struct sockaddr_dl *)(ifm + 1); ptr = (unsigned char *)LLADDR(sdl); printf(" %02x:%02x:%02x:%02x:%02x:%02x", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); free(macbuf); #else #error OS Distribution Not Recognized #endif printf(" %s\n", hostname); free(flagsStruct); } return 0; }
jbyteArray getHardwareAddress(JNIEnv* env, jstring ifName) { int sock = -1; struct ifreq ifr; jbyteArray hwaddr = NULL; char* name = NULL; jbyte* addr = NULL; int hwlen = 6; name = (char*)(*env)->GetStringUTFChars(env, ifName, NULL); if(!name) { return NULL; } #ifdef __linux__ sock = socket(AF_INET, SOCK_DGRAM, 0); if(sock == -1) { (*env)->ReleaseStringUTFChars(env, ifName, name); return NULL; } memset(&ifr, 0x00, sizeof(struct ifreq)); strncpy(ifr.ifr_name, name, IFNAMSIZ - 1); ifr.ifr_name[IFNAMSIZ - 1] = 0x00; if(ioctl(sock, SIOCGIFHWADDR, &ifr) != 0) { (*env)->ReleaseStringUTFChars(env, ifName, name); close(sock); return NULL; } close(sock); addr = (const jbyte*)ifr.ifr_hwaddr.sa_data; #else /* BSD like */ struct ifaddrs* addrs = NULL; struct ifaddrs* ifa = NULL; jbyte buf[hwlen]; if(getifaddrs(&addrs) != -1) { for(ifa = addrs ; ifa != NULL ; ifa = ifa->ifa_next) { if(ifa->ifa_addr->sa_family == AF_LINK && !strcmp(ifa->ifa_name, name)) { struct sockaddr_dl* sdl = (struct sockaddr_dl*)ifa->ifa_addr; if(sdl->sdl_type == IFT_ETHER) { memcpy(buf, LLADDR(sdl), hwlen); addr = buf; break; } } } freeifaddrs(addrs); } #endif if(addr) { hwaddr = (*env)->NewByteArray(env, hwlen); if(hwaddr) { /* copy the hardware address and return it */ (*env)->SetByteArrayRegion(env, hwaddr, 0, hwlen, addr); } } /* cleanup */ (*env)->ReleaseStringUTFChars(env, ifName, name); return hwaddr; }
static int ARP_Scan_Next(in_addr_t * IPAddr, char *PhysAddr, int *PhysAddrLen, u_long * ifType) #endif { #ifndef NETSNMP_CAN_USE_SYSCTL #ifdef linux if (arptab_current < arptab_size) { /* * copy values */ *IPAddr = at[arptab_current].at_iaddr.s_addr; *ifType = (at[arptab_current]. at_flags & ATF_PERM) ? 4 /*static */ : 3 /*dynamic */ ; *ifIndex = at[arptab_current].if_index; memcpy(PhysAddr, &at[arptab_current].at_enaddr, sizeof(at[arptab_current].at_enaddr)); *PhysAddrLen = at[arptab_current].at_enaddr_len; /* * increment to point next entry */ arptab_current++; /* * return success */ return (1); } #elif defined(hpux11) if (arptab_current < arptab_size) { /* * copy values */ *IPAddr = at[arptab_current].NetAddr; memcpy(PhysAddr, at[arptab_current].PhysAddr.o_bytes, at[arptab_current].PhysAddr.o_length); *ifType = at[arptab_current].Type; *ifIndex = at[arptab_current].IfIndex; *PhysAddrLen = at[arptab_current].PhysAddr.o_length; /* * increment to point next entry */ arptab_current++; /* * return success */ return (1); } #elif !defined(ARP_SCAN_FOUR_ARGUMENTS) || defined(hpux) register struct arptab *atab; while (arptab_current < arptab_size) { #ifdef STRUCT_ARPHD_HAS_AT_NEXT /* * The arp table is an array of linked lists of arptab entries. * Unused slots have pointers back to the array entry itself */ if (at_ptr == (auto_nlist_value(ARPTAB_SYMBOL) + arptab_current * sizeof(struct arphd))) { /* * Usused */ arptab_current++; at_ptr = at[arptab_current].at_next; continue; } if (!NETSNMP_KLOOKUP(at_ptr, (char *) &at_entry, sizeof(struct arptab))) { DEBUGMSGTL(("mibII/at:ARP_Scan_Next", "klookup failed\n")); break; } if (!NETSNMP_KLOOKUP(at_entry.at_ac, (char *) &at_com, sizeof(struct arpcom))) { DEBUGMSGTL(("mibII/at:ARP_Scan_Next", "klookup failed\n")); break; } at_ptr = at_entry.at_next; atab = &at_entry; *ifIndex = at_com.ac_if.if_index; /* not strictly ARPHD */ #else /* STRUCT_ARPHD_HAS_AT_NEXT */ atab = &at[arptab_current++]; #endif /* STRUCT_ARPHD_HAS_AT_NEXT */ if (!(atab->at_flags & ATF_COM)) continue; *ifType = (atab->at_flags & ATF_PERM) ? 4 : 3; *IPAddr = atab->at_iaddr.s_addr; #if defined (sunV3) || defined(sparc) || defined(hpux) memcpy(PhysAddr, (char *) &atab->at_enaddr, sizeof(atab->at_enaddr)); *PhysAddrLen = sizeof(atab->at_enaddr); #endif #if defined(mips) || defined(ibm032) memcpy(PhysAddr, (char *) atab->at_enaddr, sizeof(atab->at_enaddr)); *PhysAddrLen = sizeof(atab->at_enaddr); #endif return (1); } #endif /* linux || hpux11 || !ARP_SCAN_FOUR_ARGUMENTS || hpux */ return 0; /* we need someone with an irix box to fix this section */ #else /* !NETSNMP_CAN_USE_SYSCTL */ struct rt_msghdr *rtm; struct sockaddr_inarp *sin; struct sockaddr_dl *sdl; while (rtnext < lim) { rtm = (struct rt_msghdr *) rtnext; sin = (struct sockaddr_inarp *) (rtm + 1); sdl = (struct sockaddr_dl *) (sin + 1); rtnext += rtm->rtm_msglen; if (sdl->sdl_alen) { #ifdef irix6 *IPAddr = sin->sarp_addr.s_addr; #else *IPAddr = sin->sin_addr.s_addr; #endif memcpy(PhysAddr, (char *) LLADDR(sdl), sdl->sdl_alen); *PhysAddrLen = sdl->sdl_alen; *ifIndex = sdl->sdl_index; *ifType = 1; /* XXX */ return (1); } } return (0); /* "EOF" */ #endif /* !NETSNMP_CAN_USE_SYSCTL */ }
/* * returns interface list with detailed informations */ struct iface * if_list_get() { /* * Translating between Mac OS X internal representation of link and IP address * and Dibbler internal format. */ struct ifaddrs *addrs_lst = NULL; // list returned by system struct ifaddrs *addr_ptr = NULL; // single address struct iface *iface_lst = NULL; // interface list struct iface *iface_ptr = NULL; // pointer to single interface if (getifaddrs(&addrs_lst) != 0) { perror("Error in getifaddrs: "); return iface_lst; } /* First pass through entire addrs_lst: collect unique interface names and flags */ addr_ptr = addrs_lst; while (addr_ptr != NULL) { // check if this interface name is already on target list iface_ptr = iface_lst; while (iface_ptr!=NULL) { if (!strcmp(addr_ptr->ifa_name, iface_ptr->name)) break; iface_ptr = iface_ptr->next; } if (!iface_ptr) { // interface with that name not found, let's add one! iface_ptr = malloc(sizeof(struct iface)); memset(iface_ptr, 0, sizeof(struct iface)); strncpy(iface_ptr->name, addr_ptr->ifa_name, MAX_IFNAME_LENGTH - 1); iface_ptr->name[MAX_IFNAME_LENGTH-1] = 0; iface_ptr->id = if_nametoindex(iface_ptr->name); iface_ptr->flags = addr_ptr->ifa_flags; #ifdef LOWLEVEL_DEBUG printf("Detected interface %s, ifindex=%d, flags=%d\n", iface_ptr->name, iface_ptr->id, iface_ptr->flags); #endif // add this new structure to the end of the interfaces list iface_lst = if_list_add(iface_lst, iface_ptr); } addr_ptr = addr_ptr->ifa_next; } /* * Second pass through addrs_lst: collect link and IP layer info for each interface * by name */ // for each address... for (addr_ptr = addrs_lst; addr_ptr != NULL; addr_ptr = addr_ptr->ifa_next) { for (iface_ptr = iface_lst; iface_ptr != NULL; iface_ptr = iface_ptr->next) { // ... find its corresponding interface if (strncmp(iface_ptr->name, addr_ptr->ifa_name, strlen(addr_ptr->ifa_name))) continue; switch (addr_ptr->ifa_addr->sa_family) { case AF_INET6: { char * ptr = (char*)(&((struct sockaddr_in6 *) addr_ptr->ifa_addr)->sin6_addr); if (ptr[0] == 0xfe && ptr[1] == 0x80) { // link-local IPv6 address char * addrs = malloc( (iface_ptr->linkaddrcount+1)*16); memcpy(addrs, iface_ptr->linkaddr, 16*iface_ptr->linkaddrcount); memcpy(addrs + 16*iface_ptr->linkaddrcount, ptr, 16); free(iface_ptr->linkaddr); iface_ptr->linkaddr = addrs; iface_ptr->linkaddrcount++; } else { // this is global address char * addrs = malloc( (iface_ptr->globaladdrcount+1)*16); memcpy(addrs, iface_ptr->globaladdr, 16*iface_ptr->globaladdrcount); memcpy(addrs + 16*iface_ptr->globaladdrcount, ptr, 16); free(iface_ptr->globaladdr); iface_ptr->globaladdr = addrs; iface_ptr->globaladdrcount++; } break; } // end of AF_INET6 handling case AF_LINK: { struct sockaddr_dl *linkInfo; linkInfo = (struct sockaddr_dl *) addr_ptr->ifa_addr; // Note: sdl_type is unsigned character; hardwareType is integer iface_ptr->hardwareType = linkInfo->sdl_type; if (linkInfo->sdl_alen > 1) { memcpy(iface_ptr->mac, LLADDR(linkInfo), linkInfo->sdl_alen); iface_ptr->maclen = linkInfo->sdl_alen; } break; } default: break; // ignore other address families } } } /* Print out iface_lst data if debug mode */ #ifdef LOWLEVEL_DEBUG iface_ptr = iface_lst; while (iface_ptr) { if_print(iface_ptr); iface_ptr = iface_ptr->next; } #endif return iface_lst; } /* end of if_list_get */
/* * Use getifaddrs() to get a list of all the attached interfaces. For * each interface that's of type INET and not the loopback interface, * register that interface with the network I/O software, figure out * what subnet it's on, and add it to the list of interfaces. */ void discover_interfaces(struct interface_info *iface) { struct ifaddrs *ifap, *ifa; struct sockaddr_in foo; struct ifreq *tif; if (getifaddrs(&ifap) != 0) error("getifaddrs failed"); for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { if ((ifa->ifa_flags & IFF_LOOPBACK) || (ifa->ifa_flags & IFF_POINTOPOINT) || (!(ifa->ifa_flags & IFF_UP))) continue; if (strcmp(iface->name, ifa->ifa_name)) continue; /* * If we have the capability, extract link information * and record it in a linked list. */ if (ifa->ifa_addr->sa_family == AF_LINK) { struct sockaddr_dl *foo = (struct sockaddr_dl *)ifa->ifa_addr; iface->index = foo->sdl_index; iface->hw_address.hlen = foo->sdl_alen; iface->hw_address.htype = HTYPE_ETHER; /* XXX */ memcpy(iface->hw_address.haddr, LLADDR(foo), foo->sdl_alen); } else if (ifa->ifa_addr->sa_family == AF_INET) { struct iaddr addr; memcpy(&foo, ifa->ifa_addr, sizeof(foo)); if (foo.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) continue; if (!iface->ifp) { int len = IFNAMSIZ + ifa->ifa_addr->sa_len; if ((tif = malloc(len)) == NULL) error("no space to remember ifp"); strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ); memcpy(&tif->ifr_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len); iface->ifp = tif; iface->primary_address = foo.sin_addr; } addr.len = 4; memcpy(addr.iabuf, &foo.sin_addr.s_addr, addr.len); } } if (!iface->ifp) error("%s: not found", iface->name); /* Register the interface... */ if_register_receive(iface); if_register_send(iface); add_protocol(iface->name, iface->rfdesc, got_one, iface); freeifaddrs(ifap); }
int do_interface(const char *ifname, _unused unsigned char *hwaddr, _unused size_t *hwlen, struct in_addr *addr, struct in_addr *net, int get) { int s; struct ifconf ifc; int retval = 0, found = 0; int len = 10 * sizeof(struct ifreq); int lastlen = 0; char *p; union { char *buffer; struct ifreq *ifr; } ifreqs; struct sockaddr_in address; struct ifreq *ifr; struct sockaddr_in netmask; #ifdef AF_LINK struct sockaddr_dl *sdl; #endif if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) return -1; /* Not all implementations return the needed buffer size for * SIOGIFCONF so we loop like so for all until it works */ memset(&ifc, 0, sizeof(ifc)); for (;;) { ifc.ifc_len = len; ifc.ifc_buf = xmalloc((size_t)len); if (ioctl(s, SIOCGIFCONF, &ifc) == -1) { if (errno != EINVAL || lastlen != 0) { close(s); free(ifc.ifc_buf); return -1; } } else { if (ifc.ifc_len == lastlen) break; lastlen = ifc.ifc_len; } free(ifc.ifc_buf); ifc.ifc_buf = NULL; len *= 2; } for (p = (char *)ifc.ifc_buf; p < (char *)ifc.ifc_buf + ifc.ifc_len;) { /* Cast the ifc buffer to an ifreq cleanly */ ifreqs.buffer = p; ifr = ifreqs.ifr; #ifndef __linux__ if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_ifru)) p += offsetof(struct ifreq, ifr_ifru) + ifr->ifr_addr.sa_len; else #endif p += sizeof(*ifr); if (strcmp(ifname, ifr->ifr_name) != 0) continue; found = 1; #ifdef AF_LINK if (hwaddr && hwlen && ifr->ifr_addr.sa_family == AF_LINK) { sdl = xmalloc(ifr->ifr_addr.sa_len); memcpy(sdl, &ifr->ifr_addr, ifr->ifr_addr.sa_len); *hwlen = sdl->sdl_alen; memcpy(hwaddr, LLADDR(sdl), *hwlen); free(sdl); retval = 1; break; } #endif if (ifr->ifr_addr.sa_family == AF_INET) { memcpy(&address, &ifr->ifr_addr, sizeof(address)); if (ioctl(s, SIOCGIFNETMASK, ifr) == -1) continue; memcpy(&netmask, &ifr->ifr_addr, sizeof(netmask)); if (get) { addr->s_addr = address.sin_addr.s_addr; net->s_addr = netmask.sin_addr.s_addr; retval = 1; break; } else { if (address.sin_addr.s_addr == addr->s_addr && (!net || netmask.sin_addr.s_addr == net->s_addr)) { retval = 1; break; } } } }
/** * Prints interface information for the interface ifa */ void printInterfaceInfo(struct ifaddrs *ifa){ // create a puppet socket to act as a file descriptor for ioctl() // I can create it here, since I can reuse it int fd=socket(AF_INET,SOCK_DGRAM,0); // create the ifr & ifm // ifr is more general and more stuff can be retrieved, while // ifm is purely for media information struct ifreq ifr; struct ifmediareq ifm; size_t if_name_len=strlen(ifa->ifa_name); // ensure the interface name is not too long, since ifr_name is fixed length buffer if (if_name_len < sizeof(ifr.ifr_name) && if_name_len < sizeof(ifm.ifm_name) ) { // set name for IFR memcpy(ifr.ifr_name, ifa->ifa_name, if_name_len); ifr.ifr_name[if_name_len]=0; // set name for IFM memcpy(ifm.ifm_name, ifa->ifa_name, if_name_len); ifm.ifm_name[if_name_len]=0; } else { puts("Interface name is too long"); exit(1); } //output current interface printf("Interface: %s", ifa->ifa_name); if (fd==-1) { puts("Socket could not be created"); exit(1); } // print flags printHeader("Flags", &printFlags, ifa->ifa_flags); // prints the MTU if (ioctl(fd, SIOCGIFMTU, &ifr) != -1) printf("\tMTU: %d", ifr.ifr_metric); // prints the options if (ioctl(fd, SIOCGIFCAP, &ifr) != -1) printHeader("Options", &printCapabilities, ifr.ifr_curcap); // prints the MAC address if(ifa->ifa_addr->sa_family == AF_LINK){ struct sockaddr_dl *mac_addr = (struct sockaddr_dl *)ifa->ifa_addr; unsigned char mac[6]; // check if he address length is 6 bytes if (6 == mac_addr->sdl_alen) { memcpy(mac, LLADDR(mac_addr), mac_addr->sdl_alen); printf("\tMAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } } // print status if (ioctl(fd, SIOCGIFMEDIA, &ifm) != -1) printf("\tStatus:%s\n", ifm.ifm_status == 3 ? "Active" : ifm.ifm_status == 1 ? "Inactive" : "Unknown"); // 3 is active and 1 is inactive /** * I'm not going to handle media because it has way too many flags to implement * in a timely manner */ // IP printIPAddress("IP", IP_ADDR, fd, ifr); // Point to point printIPAddress("Point-to-Point", P2P_ADDR, fd, ifr); // broadcast printIPAddress("Broadcast", BCAST_ADDR, fd, ifr); //netmask printIPAddress("Netmask", MASK_ADDR, fd, ifr); //autoconf printIPAddress("Autoconf", AUTOCONF_ADDR, fd, ifr); //autoconf mask printIPAddress("Autoconf mask", AUTOCONF_MASK, fd, ifr); //ipv4all printIPAddress("IPv4All", IPV4ALL_ADDR, fd, ifr); //link level printIPAddress("Link level", LINK_LEVEL_ADDR, fd, ifr); close(fd); }
/* determines hardware address on client machine */ int get_hardware_address(int sock,char *interface_name){ #if defined(__linux__) struct ifreq ifr; strncpy((char *)&ifr.ifr_name,interface_name,sizeof(ifr.ifr_name)-1); ifr.ifr_name[sizeof(ifr.ifr_name)-1]='\0'; /* try and grab hardware address of requested interface */ if(ioctl(sock,SIOCGIFHWADDR,&ifr)<0){ printf(_("Error: Could not get hardware address of interface '%s'\n"),interface_name); exit(STATE_UNKNOWN); } memcpy(&client_hardware_address[0],&ifr.ifr_hwaddr.sa_data,6); #elif defined(__bsd__) /* King 2004 see ACKNOWLEDGEMENTS */ int mib[6], len; char *buf; unsigned char *ptr; struct if_msghdr *ifm; struct sockaddr_dl *sdl; mib[0] = CTL_NET; mib[1] = AF_ROUTE; mib[2] = 0; mib[3] = AF_LINK; mib[4] = NET_RT_IFLIST; if((mib[5] = if_nametoindex(interface_name)) == 0){ printf(_("Error: if_nametoindex error - %s.\n"), strerror(errno)); exit(STATE_UNKNOWN); } if(sysctl(mib, 6, NULL, &len, NULL, 0) < 0){ printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), interface_name, strerror(errno)); exit(STATE_UNKNOWN); } if((buf = malloc(len)) == NULL){ printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), interface_name, strerror(errno)); exit(4); } if(sysctl(mib, 6, buf, &len, NULL, 0) < 0){ printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), interface_name, strerror(errno)); exit(STATE_UNKNOWN); } ifm = (struct if_msghdr *)buf; sdl = (struct sockaddr_dl *)(ifm + 1); ptr = (unsigned char *)LLADDR(sdl); memcpy(&client_hardware_address[0], ptr, 6) ; /* King 2004 */ #elif defined(__sun__) || defined(__solaris__) /* Kompf 2000-2003 see ACKNOWLEDGEMENTS */ long stat; char dev[20] = "/dev/"; char *p; int unit; /* get last number from interfacename, eg lnc0, e1000g0*/ int i; p = interface_name + strlen(interface_name) -1; for(i = strlen(interface_name) -1; i > 0; p--) { if(isalpha(*p)) break; } p++; if( p != interface_name ){ unit = atoi(p) ; strncat(dev, interface_name, 6) ; } else{ printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg lnc0.\n"), interface_name); exit(STATE_UNKNOWN); } stat = mac_addr_dlpi(dev, unit, client_hardware_address); if(stat != 0){ printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); exit(STATE_UNKNOWN); } #elif defined(__hpux__) long stat; char dev[20] = "/dev/dlpi" ; int unit = 0; stat = mac_addr_dlpi(dev, unit, client_hardware_address); if(stat != 0){ printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); exit(STATE_UNKNOWN); } /* Kompf 2000-2003 */ #else printf(_("Error: can't get MAC address for this architecture. Use the --mac option.\n")); exit(STATE_UNKNOWN); #endif if(verbose) print_hardware_address(client_hardware_address); return OK; }