static Iface_DEFUN sendMessage(struct Message* msg, struct Iface* iface) { struct ETHInterface_pvt* ctx = Identity_containerOf(iface, struct ETHInterface_pvt, pub.generic.iface); struct Sockaddr* sa = (struct Sockaddr*) msg->bytes; Assert_true(msg->length >= Sockaddr_OVERHEAD); Assert_true(sa->addrLen <= ETHInterface_Sockaddr_SIZE); struct ETHInterface_Sockaddr sockaddr = { .generic = { .addrLen = 0 } }; Message_pop(msg, &sockaddr, sa->addrLen, NULL); struct sockaddr_ll addr; Bits_memcpyConst(&addr, &ctx->addrBase, sizeof(struct sockaddr_ll)); if (sockaddr.generic.flags & Sockaddr_flags_BCAST) { Bits_memset(addr.sll_addr, 0xff, 6); } else { Bits_memcpyConst(addr.sll_addr, sockaddr.mac, 6); } struct ETHInterface_Header hdr = { .version = ETHInterface_CURRENT_VERSION, .zero = 0, .length_be = Endian_hostToBigEndian16(msg->length + ETHInterface_Header_SIZE), .fc00_be = Endian_hostToBigEndian16(0xfc00) }; Message_push(msg, &hdr, ETHInterface_Header_SIZE, NULL); sendMessageInternal(msg, &addr, ctx); return NULL; } static void handleEvent2(struct ETHInterface_pvt* context, struct Allocator* messageAlloc) { struct Message* msg = Message_new(MAX_PACKET_SIZE, PADDING, messageAlloc); struct sockaddr_ll addr; uint32_t addrLen = sizeof(struct sockaddr_ll); // Knock it out of alignment by 2 bytes so that it will be // aligned when the idAndPadding is shifted off. Message_shift(msg, 2, NULL); int rc = recvfrom(context->socket, msg->bytes, msg->length, 0, (struct sockaddr*) &addr, &addrLen); if (rc < ETHInterface_Header_SIZE) { Log_debug(context->logger, "Failed to receive eth frame"); return; } Assert_true(msg->length >= rc); msg->length = rc; //Assert_true(addrLen == SOCKADDR_LL_LEN); struct ETHInterface_Header hdr; Message_pop(msg, &hdr, ETHInterface_Header_SIZE, NULL); // here we could put a switch statement to handle different versions differently. if (hdr.version != ETHInterface_CURRENT_VERSION) { Log_debug(context->logger, "DROP unknown version"); return; } uint16_t reportedLength = Endian_bigEndianToHost16(hdr.length_be); reportedLength -= ETHInterface_Header_SIZE; if (msg->length != reportedLength) { if (msg->length < reportedLength) { Log_debug(context->logger, "DROP size field is larger than frame"); return; } msg->length = reportedLength; } if (hdr.fc00_be != Endian_hostToBigEndian16(0xfc00)) { Log_debug(context->logger, "DROP bad magic"); return; } struct ETHInterface_Sockaddr sockaddr = { .zero = 0 }; Bits_memcpyConst(sockaddr.mac, addr.sll_addr, 6); sockaddr.generic.addrLen = ETHInterface_Sockaddr_SIZE; if (addr.sll_pkttype == PACKET_BROADCAST) { sockaddr.generic.flags |= Sockaddr_flags_BCAST; } Message_push(msg, &sockaddr, ETHInterface_Sockaddr_SIZE, NULL); Assert_true(!((uintptr_t)msg->bytes % 4) && "Alignment fault"); Iface_send(&context->pub.generic.iface, msg); } static void handleEvent(void* vcontext) { struct ETHInterface_pvt* context = Identity_check((struct ETHInterface_pvt*) vcontext); struct Allocator* messageAlloc = Allocator_child(context->pub.generic.alloc); handleEvent2(context, messageAlloc); Allocator_free(messageAlloc); } List* ETHInterface_listDevices(struct Allocator* alloc, struct Except* eh) { struct ifaddrs* ifaddr = NULL; if (getifaddrs(&ifaddr) || ifaddr == NULL) { Except_throw(eh, "getifaddrs() -> errno:%d [%s]", errno, strerror(errno)); } List* out = List_new(alloc); for (struct ifaddrs* ifa = ifaddr; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_PACKET) { List_addString(out, String_new(ifa->ifa_name, alloc), alloc); } } freeifaddrs(ifaddr); return out; } static int closeSocket(struct Allocator_OnFreeJob* j) { struct ETHInterface_pvt* ctx = Identity_check((struct ETHInterface_pvt*) j->userData); close(ctx->socket); return 0; } struct ETHInterface* ETHInterface_new(struct EventBase* eventBase, const char* bindDevice, struct Allocator* alloc, struct Except* exHandler, struct Log* logger) { struct ETHInterface_pvt* ctx = Allocator_calloc(alloc, sizeof(struct ETHInterface_pvt), 1); Identity_set(ctx); ctx->pub.generic.iface.send = sendMessage; ctx->pub.generic.alloc = alloc; ctx->logger = logger; struct ifreq ifr = { .ifr_ifindex = 0 }; ctx->socket = socket(AF_PACKET, SOCK_DGRAM, Ethernet_TYPE_CJDNS); if (ctx->socket == -1) { Except_throw(exHandler, "call to socket() failed. [%s]", strerror(errno)); } Allocator_onFree(alloc, closeSocket, ctx); CString_strncpy(ifr.ifr_name, bindDevice, IFNAMSIZ - 1); ctx->ifName = String_new(bindDevice, alloc); if (ioctl(ctx->socket, SIOCGIFINDEX, &ifr) == -1) { Except_throw(exHandler, "failed to find interface index [%s]", strerror(errno)); } ctx->ifindex = ifr.ifr_ifindex; if (ioctl(ctx->socket, SIOCGIFFLAGS, &ifr) < 0) { Except_throw(exHandler, "ioctl(SIOCGIFFLAGS) [%s]", strerror(errno)); } if (!((ifr.ifr_flags & IFF_UP) && (ifr.ifr_flags & IFF_RUNNING))) { Log_info(logger, "Bringing up interface [%s]", ifr.ifr_name); ifr.ifr_flags |= IFF_UP | IFF_RUNNING; if (ioctl(ctx->socket, SIOCSIFFLAGS, &ifr) < 0) { Except_throw(exHandler, "ioctl(SIOCSIFFLAGS) [%s]", strerror(errno)); } } ctx->addrBase = (struct sockaddr_ll) { .sll_family = AF_PACKET, .sll_protocol = Ethernet_TYPE_CJDNS, .sll_ifindex = ctx->ifindex, .sll_hatype = ARPHRD_ETHER, .sll_pkttype = PACKET_OTHERHOST, .sll_halen = ETH_ALEN }; if (bind(ctx->socket, (struct sockaddr*) &ctx->addrBase, sizeof(struct sockaddr_ll))) { Except_throw(exHandler, "call to bind() failed [%s]", strerror(errno)); } Socket_makeNonBlocking(ctx->socket); Event_socketRead(handleEvent, ctx, ctx->socket, eventBase, alloc, exHandler); return &ctx->pub; }
uv_err_t uv_interface_addresses(uv_interface_address_t** addresses, int* count) { struct ifaddrs *addrs, *ent; char ip[INET6_ADDRSTRLEN]; uv_interface_address_t* address; if (getifaddrs(&addrs) != 0) { return uv__new_sys_error(errno); } *count = 0; /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) || (ent->ifa_addr == NULL) || (ent->ifa_addr->sa_family == AF_LINK)) { continue; } (*count)++; } *addresses = (uv_interface_address_t*) malloc(*count * sizeof(uv_interface_address_t)); if (!(*addresses)) { return uv__new_artificial_error(UV_ENOMEM); } address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { bzero(&ip, sizeof (ip)); if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) { continue; } if (ent->ifa_addr == NULL) { continue; } /* * On Mac OS X getifaddrs returns information related to Mac Addresses for * various devices, such as firewire, etc. These are not relevant here. */ if (ent->ifa_addr->sa_family == AF_LINK) { continue; } address->name = strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); } else { address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); } if (ent->ifa_netmask->sa_family == AF_INET6) { address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); } else { address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); } address->is_internal = ent->ifa_flags & IFF_LOOPBACK ? 1 : 0; address++; } freeifaddrs(addrs); return uv_ok_; }
void network_init() { #ifdef INET6 struct ifaddrs *ifap, *ifp; struct ipv6_mreq mreq6; int ifindex, s; #endif int ecode; struct addrinfo hints, *res; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; if ((ecode = getaddrinfo(NULL, "sunrpc", &hints, &res))) { if (debugging) fprintf(stderr, "can't get local ip4 address: %s\n", gai_strerror(ecode)); } else { local_in4 = (struct sockaddr_in *)malloc(sizeof *local_in4); if (local_in4 == NULL) { if (debugging) fprintf(stderr, "can't alloc local ip4 addr\n"); } memcpy(local_in4, res->ai_addr, sizeof *local_in4); } #ifdef INET6 hints.ai_family = AF_INET6; if ((ecode = getaddrinfo(NULL, "sunrpc", &hints, &res))) { if (debugging) fprintf(stderr, "can't get local ip6 address: %s\n", gai_strerror(ecode)); } else { local_in6 = (struct sockaddr_in6 *)malloc(sizeof *local_in6); if (local_in6 == NULL) { if (debugging) fprintf(stderr, "can't alloc local ip6 addr\n"); } memcpy(local_in6, res->ai_addr, sizeof *local_in6); } /* * Now join the RPC ipv6 multicast group on all interfaces. */ if (getifaddrs(&ifp) < 0) return; mreq6.ipv6mr_interface = 0; inet_pton(AF_INET6, RPCB_MULTICAST_ADDR, &mreq6.ipv6mr_multiaddr); s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); /* * Loop through all interfaces. For each interface, see if the * network portion of its address is equal to that of the client. * If so, we have found the interface that we want to use. */ for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) { if (ifap->ifa_addr->sa_family != AF_INET6 || !(ifap->ifa_flags & IFF_MULTICAST)) continue; ifindex = if_nametoindex(ifap->ifa_name); if (ifindex == mreq6.ipv6mr_interface) /* * Already did this one. */ continue; mreq6.ipv6mr_interface = ifindex; if (setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6, sizeof mreq6) < 0) if (debugging) warn("setsockopt v6 multicast"); } #endif /* close(s); */ }
static int lc_local_addresses(lua_State *L) { #ifndef _WIN32 /* Link-local IPv4 addresses; see RFC 3927 and RFC 5735 */ const long ip4_linklocal = htonl(0xa9fe0000); /* 169.254.0.0 */ const long ip4_mask = htonl(0xffff0000); struct ifaddrs *addr = NULL, *a; #endif int n = 1; int type = luaL_checkoption(L, 1, "both", type_strings); const char link_local = lua_toboolean(L, 2); /* defaults to 0 (false) */ const char ipv4 = (type == 0 || type == 1); const char ipv6 = (type == 0 || type == 2); #ifndef _WIN32 if (getifaddrs(&addr) < 0) { lua_pushnil(L); lua_pushfstring(L, "getifaddrs failed (%d): %s", errno, strerror(errno)); return 2; } #endif lua_newtable(L); #ifndef _WIN32 for (a = addr; a; a = a->ifa_next) { int family; char ipaddr[INET6_ADDRSTRLEN]; const char *tmp = NULL; if (a->ifa_addr == NULL || a->ifa_flags & IFF_LOOPBACK) continue; family = a->ifa_addr->sa_family; if (ipv4 && family == AF_INET) { struct sockaddr_in *sa = (struct sockaddr_in *)a->ifa_addr; if (!link_local &&((sa->sin_addr.s_addr & ip4_mask) == ip4_linklocal)) continue; tmp = inet_ntop(family, &sa->sin_addr, ipaddr, sizeof(ipaddr)); } else if (ipv6 && family == AF_INET6) { struct sockaddr_in6 *sa = (struct sockaddr_in6 *)a->ifa_addr; if (!link_local && IN6_IS_ADDR_LINKLOCAL(&sa->sin6_addr)) continue; if (IN6_IS_ADDR_V4MAPPED(&sa->sin6_addr) || IN6_IS_ADDR_V4COMPAT(&sa->sin6_addr)) continue; tmp = inet_ntop(family, &sa->sin6_addr, ipaddr, sizeof(ipaddr)); } if (tmp != NULL) { lua_pushstring(L, tmp); lua_rawseti(L, -2, n++); } /* TODO: Error reporting? */ } freeifaddrs(addr); #else if (ipv4) { lua_pushstring(L, "0.0.0.0"); lua_rawseti(L, -2, n++); } if (ipv6) { lua_pushstring(L, "::"); lua_rawseti(L, -2, n++); } #endif return 1; }
int sharedaemon_bcast_send(void) { struct ifaddrs *if_list; struct ifaddrs *dev; shpeer_t *peer; char hostname[NI_MAXHOST+1]; int err; err = getifaddrs(&if_list); if (err) return (-errno); /* cycle through all non loop-back interfaces. */ for (dev = if_list; dev; dev = dev->ifa_next) { if (dev->ifa_addr == NULL) continue; err = SHERR_OPNOTSUPP; memset(hostname, 0, sizeof(hostname)); switch (dev->ifa_addr->sa_family) { case AF_INET: err = getnameinfo(dev->ifa_addr, sizeof(struct sockaddr_in), hostname, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (err) break; if (0 == strncmp(hostname, "127.0.0.", strlen("127.0.0."))) { /* local loop-back */ err = SHERR_AGAIN; break; } fprintf(stderr, "DEBUG: found inet device '%s' with addr '%s'\n", dev->ifa_name, hostname); err = 0; break; case AF_INET6: err = getnameinfo(dev->ifa_addr, sizeof(struct sockaddr_in6), hostname, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (err) break; if (0 == strcmp(hostname, "::1")) { /* local loop-back */ err = SHERR_AGAIN; break; } fprintf(stderr, "DEBUG: found inet6 device '%s' with addr '%s'\n", dev->ifa_name, hostname); err = 0; break; default: fprintf(stderr, "DEBUG: found unknown (fam %d) device '%s' with addr '%s'\n", dev->ifa_addr->sa_family, dev->ifa_name, hostname); break; } if (err) { /* .. */ continue; } sprintf(hostname + strlen(hostname), " %d", server_port); peer = shpeer_init("shared", hostname); fprintf(stderr, "DEBUG: sharedaemon_bcast_send: %d = sharedaemon_bcast_send_peer(\"%s\")\n", err, hostname); err = sharedaemon_bcast_send_peer(peer); shpeer_free(&peer); if (err) { /* .. */ } } return (0); }
uv_err_t uv_interface_addresses(uv_interface_address_t** addresses, int* count) { #ifdef SUNOS_NO_IFADDRS return uv__new_artificial_error(UV_ENOSYS); #else struct ifaddrs *addrs, *ent; char ip[INET6_ADDRSTRLEN]; uv_interface_address_t *address; if (getifaddrs(&addrs) != 0) { return uv__new_sys_error(errno); } *count = 0; /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) || (ent->ifa_addr == NULL) || (ent->ifa_addr->sa_family == PF_PACKET)) { continue; } (*count)++; } *addresses = (uv_interface_address_t *)malloc(*count * sizeof(uv_interface_address_t)); if (!(*addresses)) { return uv__new_artificial_error(UV_ENOMEM); } address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { memset(&ip, 0, sizeof(ip)); if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) { continue; } if (ent->ifa_addr == NULL) { continue; } address->name = strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6 *)ent->ifa_addr); } else { address->address.address4 = *((struct sockaddr_in *)ent->ifa_addr); } address->is_internal = ent->ifa_flags & IFF_PRIVATE || ent->ifa_flags & IFF_LOOPBACK ? 1 : 0; address++; } freeifaddrs(addrs); return uv_ok_; #endif /* SUNOS_NO_IFADDRS */ }
/* * 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); }
/* return the Media Access Control (MAC) address of the FIRST network interface card (NIC) */ int mac_address(unsigned char *data_ptr, size_t data_len) { /* sanity check arguments */ if (data_ptr == NULL || data_len < MAC_LEN) return FALSE; #if defined(HAVE_IFADDRS_H) && defined(HAVE_NET_IF_DL_H) && defined(HAVE_GETIFADDRS) /* use getifaddrs(3) on BSD class platforms (xxxBSD, MacOS X, etc) */ { struct ifaddrs *ifap; struct ifaddrs *ifap_head; const struct sockaddr_dl *sdl; unsigned char *ucp; int i; if (getifaddrs(&ifap_head) < 0) return FALSE; for (ifap = ifap_head; ifap != NULL; ifap = ifap->ifa_next) { if (ifap->ifa_addr != NULL && ifap->ifa_addr->sa_family == AF_LINK) { sdl = (const struct sockaddr_dl *)ifap->ifa_addr; ucp = (unsigned char *)(sdl->sdl_data + sdl->sdl_nlen); if (ucp != NULL && sdl->sdl_alen > 0) { for (i = 0; i < MAC_LEN && i < sdl->sdl_alen; i++, ucp++) data_ptr[i] = (unsigned char)(*ucp & 0xff); freeifaddrs(ifap_head); return TRUE; } } } freeifaddrs(ifap_head); } #endif #if defined(HAVE_NET_IF_H) && defined(SIOCGIFHWADDR) /* use SIOCGIFHWADDR ioctl(2) on Linux class platforms */ { struct ifreq ifr; struct sockaddr *sa; int s; int i; if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) return FALSE; sprintf(ifr.ifr_name, "eth0"); if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { close(s); return FALSE; } sa = (struct sockaddr *)&ifr.ifr_addr; for (i = 0; i < MAC_LEN; i++) data_ptr[i] = (unsigned char)(sa->sa_data[i] & 0xff); close(s); return TRUE; } #endif #if defined(SIOCGARP) /* use SIOCGARP ioctl(2) on SVR4 class platforms (Solaris, etc) */ { char hostname[MAXHOSTNAMELEN]; struct hostent *he; struct arpreq ar; struct sockaddr_in *sa; int s; int i; if (gethostname(hostname, sizeof(hostname)) < 0) return FALSE; if ((he = gethostbyname(hostname)) == NULL) return FALSE; if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) return FALSE; memset(&ar, '\0', sizeof(ar)); sa = (struct sockaddr_in *)((void *)&(ar.arp_pa)); sa->sin_family = AF_INET; memcpy(&(sa->sin_addr), *(he->h_addr_list), sizeof(struct in_addr)); if (ioctl(s, SIOCGARP, &ar) < 0) { close(s); return FALSE; } for (i = 0; i < MAC_LEN; i++) data_ptr[i] = (unsigned char)(ar.arp_ha.sa_data[i] & 0xff); close(s); return TRUE; } #endif return FALSE; }
int Lwm2mCore_GetIPAddressFromInterface(const char * interface, int addressFamily, char * destAddress, size_t destAddressLength) { int returnCode = 0; #ifndef CONTIKI if (addressFamily != AF_INET && addressFamily != AF_INET6) { Lwm2m_Error("Unsupported address family: %d. Only AF_INET and AF_INET6 are supported.\n", addressFamily); returnCode = 1; goto error; } struct ifaddrs *interfaceAddresses, *interfaceAddress; char host[NI_MAXHOST]; if (getifaddrs(&interfaceAddresses) == -1) { perror("getifaddrs"); returnCode = 1; goto error; } char linkLocalIpv6Address[NI_MAXHOST] = { 0 }; char globalIpv6Address[NI_MAXHOST] = { 0 }; bool found = false; int index = 0; for (interfaceAddress = interfaceAddresses; interfaceAddress != NULL; interfaceAddress = interfaceAddress->ifa_next) { if (interfaceAddress->ifa_addr == NULL) { continue; } if ((strcmp(interfaceAddress->ifa_name, interface)==0)&&(interfaceAddress->ifa_addr->sa_family==addressFamily)) { int socketAddressLength = 0; switch(addressFamily) { case AF_INET: socketAddressLength = sizeof(struct sockaddr_in); break; default: socketAddressLength = sizeof(struct sockaddr_in6); break; } returnCode = getnameinfo(interfaceAddress->ifa_addr, socketAddressLength, host, sizeof(host), NULL, 0, NI_NUMERICHOST); if (returnCode != 0) { Lwm2m_Error("getnameinfo() failed: %s\n", gai_strerror(returnCode)); goto error_free; } size_t addressLength = strlen(host); if (destAddressLength < addressLength) { Lwm2m_Error("Error: Address is longer than %zu characters\n", destAddressLength); goto error_free; } switch(addressFamily) { case AF_INET: strcpy(destAddress, host); found = true; break; default: if (strncmp(host, "fe80", 4) == 0) { Lwm2m_Debug("Address %d: %s (local)\n", index, host); strcpy(linkLocalIpv6Address, host); } else { Lwm2m_Debug("Address %d: %s (global)\n", index, host); strcpy(globalIpv6Address, host); } break; } index++; } } if (addressFamily == AF_INET6) { if (strlen(globalIpv6Address) > 0) { Lwm2m_Debug("Global IPv6 address found for interface %s: %s\n", interface, globalIpv6Address); strcpy(destAddress, globalIpv6Address); found = true; } else if (strlen(linkLocalIpv6Address) > 0) { Lwm2m_Warning("No global IPv6 address found for interface %s: using local: %s\n", interface, linkLocalIpv6Address); strcpy(destAddress, linkLocalIpv6Address); found = true; } } if (!found) { Lwm2m_Error("Could not find an %s IP address for interface %s\n", addressFamily == AF_INET? "IPv4" : "IPv6", interface); returnCode = 1; } error_free: freeifaddrs(interfaceAddresses); error: #endif return returnCode; }
static krb5_error_code find_all_addresses (krb5_context context, krb5_addresses *res, int flags) { struct sockaddr sa_zero; struct ifaddrs *ifa0, *ifa; krb5_error_code ret = ENXIO; int num, idx; krb5_addresses ignore_addresses; res->val = NULL; if (getifaddrs(&ifa0) == -1) { ret = errno; krb5_set_error_string(context, "getifaddrs: %s", strerror(ret)); return (ret); } memset(&sa_zero, 0, sizeof(sa_zero)); /* First, count all the ifaddrs. */ for (ifa = ifa0, num = 0; ifa != NULL; ifa = ifa->ifa_next, num++) /* nothing */; if (num == 0) { freeifaddrs(ifa0); krb5_set_error_string(context, "no addresses found"); return (ENXIO); } if (flags & EXTRA_ADDRESSES) { /* we'll remove the addresses we don't care about */ ret = krb5_get_ignore_addresses(context, &ignore_addresses); if(ret) return ret; } /* Allocate storage for them. */ res->val = calloc(num, sizeof(*res->val)); if (res->val == NULL) { krb5_free_addresses(context, &ignore_addresses); freeifaddrs(ifa0); krb5_set_error_string (context, "malloc: out of memory"); return (ENOMEM); } /* Now traverse the list. */ for (ifa = ifa0, idx = 0; ifa != NULL; ifa = ifa->ifa_next) { if ((ifa->ifa_flags & IFF_UP) == 0) continue; if (ifa->ifa_addr == NULL) continue; if (memcmp(ifa->ifa_addr, &sa_zero, sizeof(sa_zero)) == 0) continue; if (krb5_sockaddr_uninteresting(ifa->ifa_addr)) continue; if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) { /* We'll deal with the LOOP_IF_NONE case later. */ if ((flags & LOOP) == 0) continue; } ret = krb5_sockaddr2address(context, ifa->ifa_addr, &res->val[idx]); if (ret) { /* * The most likely error here is going to be "Program * lacks support for address type". This is no big * deal -- just continue, and we'll listen on the * addresses who's type we *do* support. */ continue; } /* possibly skip this address? */ if((flags & EXTRA_ADDRESSES) && krb5_address_search(context, &res->val[idx], &ignore_addresses)) { krb5_free_address(context, &res->val[idx]); flags &= ~LOOP_IF_NONE; /* we actually found an address, so don't add any loop-back addresses */ continue; } idx++; } /* * If no addresses were found, and LOOP_IF_NONE is set, then find * the loopback addresses and add them to our list. */ if ((flags & LOOP_IF_NONE) != 0 && idx == 0) { for (ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next) { if ((ifa->ifa_flags & IFF_UP) == 0) continue; if (ifa->ifa_addr == NULL) continue; if (memcmp(ifa->ifa_addr, &sa_zero, sizeof(sa_zero)) == 0) continue; if (krb5_sockaddr_uninteresting(ifa->ifa_addr)) continue; if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) { ret = krb5_sockaddr2address(context, ifa->ifa_addr, &res->val[idx]); if (ret) { /* * See comment above. */ continue; } if((flags & EXTRA_ADDRESSES) && krb5_address_search(context, &res->val[idx], &ignore_addresses)) { krb5_free_address(context, &res->val[idx]); continue; } idx++; } } } if (flags & EXTRA_ADDRESSES) krb5_free_addresses(context, &ignore_addresses); freeifaddrs(ifa0); if (ret) free(res->val); else res->len = idx; /* Now a count. */ return (ret); }
int ipmi_intf_socket_connect(struct ipmi_intf * intf) { struct ipmi_session_params *params; struct sockaddr_storage addr; struct addrinfo hints; struct addrinfo *rp0 = NULL, *rp; char service[NI_MAXSERV]; if (!intf) { return -1; } params = &intf->ssn_params; if (params->hostname == NULL || strlen((const char *)params->hostname) == 0) { lprintf(LOG_ERR, "No hostname specified!"); return -1; } /* open port to BMC */ memset(&addr, 0, sizeof(addr)); sprintf(service, "%d", params->port); /* Obtain address(es) matching host/port */ memset(&hints, 0, sizeof(hints)); hints.ai_family = intf->ai_family; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ hints.ai_flags = 0; /* use AI_NUMERICSERV for no name resolution */ hints.ai_protocol = IPPROTO_UDP; /* */ if (getaddrinfo(params->hostname, service, &hints, &rp0) != 0) { lprintf(LOG_ERR, "Address lookup for %s failed", params->hostname); return -1; } /* getaddrinfo() returns a list of address structures. * Try each address until we successfully connect(2). * If socket(2) (or connect(2)) fails, we (close the socket * and) try the next address. */ for (rp = rp0; rp != NULL; rp = rp->ai_next) { /* We are only interested in IPv4 and IPv6 */ if ((rp->ai_family != AF_INET6) && (rp->ai_family != AF_INET)) { continue; } intf->fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (intf->fd == -1) { continue; } if (rp->ai_family == AF_INET) { if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) { hints.ai_family = rp->ai_family; break; /* Success */ } } else if (rp->ai_family == AF_INET6) { struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)rp->ai_addr; char hbuf[NI_MAXHOST]; socklen_t len; /* The scope was specified on the command line e.g. with -H FE80::219:99FF:FEA0:BD95%eth0 */ if (addr6->sin6_scope_id != 0) { len = sizeof(struct sockaddr_in6); if (getnameinfo((struct sockaddr *)addr6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) { lprintf(LOG_DEBUG, "Trying address: %s scope=%d", hbuf, addr6->sin6_scope_id); } if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) { hints.ai_family = rp->ai_family; break; /* Success */ } } else { /* No scope specified, try to get this from the list of interfaces */ struct ifaddrs *ifaddrs = NULL; struct ifaddrs *ifa = NULL; if (getifaddrs(&ifaddrs) < 0) { lprintf(LOG_ERR, "Interface address lookup for %s failed", params->hostname); break; } for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr == NULL) { continue; } if (ifa->ifa_addr->sa_family == AF_INET6) { struct sockaddr_in6 *tmp6 = (struct sockaddr_in6 *)ifa->ifa_addr; /* Skip unwanted addresses */ if (IN6_IS_ADDR_MULTICAST(&tmp6->sin6_addr)) { continue; } if (IN6_IS_ADDR_LOOPBACK(&tmp6->sin6_addr)) { continue; } len = sizeof(struct sockaddr_in6); if ( getnameinfo((struct sockaddr *)tmp6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) { lprintf(LOG_DEBUG, "Testing %s interface address: %s scope=%d", ifa->ifa_name != NULL ? ifa->ifa_name : "???", hbuf, tmp6->sin6_scope_id); } if (tmp6->sin6_scope_id != 0) { addr6->sin6_scope_id = tmp6->sin6_scope_id; } else { /* * No scope information in interface address information * On some OS'es, getifaddrs() is returning out the 'kernel' representation * of scoped addresses which stores the scope in the 3rd and 4th * byte. See also this page: * http://www.freebsd.org/doc/en/books/developers-handbook/ipv6.html */ if (IN6_IS_ADDR_LINKLOCAL(&tmp6->sin6_addr) && (tmp6->sin6_addr.s6_addr[1] != 0)) { addr6->sin6_scope_id = ntohs(tmp6->sin6_addr.s6_addr[1]); } } /* OK, now try to connect with the scope id from this interface address */ if (addr6->sin6_scope_id != 0 || !IN6_IS_ADDR_LINKLOCAL(&tmp6->sin6_addr)) { if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) { hints.ai_family = rp->ai_family; lprintf(LOG_DEBUG, "Successful connected on %s interface with scope id %d", ifa->ifa_name, tmp6->sin6_scope_id); break; /* Success */ } } } } freeifaddrs(ifaddrs); } } if (hints.ai_family != AF_UNSPEC) { break; } close(intf->fd); intf->fd = -1; } /* No longer needed */ freeaddrinfo(rp0); return ((intf->fd != -1) ? 0 : -1); }
/* configure using getifaddrs(3) */ static int if_bsdx_open(void) { struct ifaddrs **ifadd_list; struct ifaddrs *cur_ifaddrs; struct sockaddr_in* sin_addr; /* * the manpage claims that getifaddrs() allocates the memory, * and freeifaddrs() is later used to release the allocated memory. * however, without this malloc the call to getifaddrs() segfaults */ ifadd_list = (struct ifaddrs **) malloc(sizeof(struct ifaddrs*)); /* create the linked list of ifaddrs structs */ if (getifaddrs(ifadd_list) < 0) { opal_output(0, "opal_ifinit: getifaddrs() failed with error=%d\n", errno); return OPAL_ERROR; } for (cur_ifaddrs = *ifadd_list; NULL != cur_ifaddrs; cur_ifaddrs = cur_ifaddrs->ifa_next) { opal_if_t *intf; struct in_addr a4; /* skip non- af_inet interface addresses */ if (AF_INET != cur_ifaddrs->ifa_addr->sa_family) { continue; } /* skip interface if it is down (IFF_UP not set) */ if (0 == (cur_ifaddrs->ifa_flags & IFF_UP)) { continue; } /* skip interface if it is a loopback device (IFF_LOOPBACK set) */ if (!opal_if_retain_loopback && 0 != (cur_ifaddrs->ifa_flags & IFF_LOOPBACK)) { continue; } /* or if it is a point-to-point interface */ /* TODO: do we really skip p2p? */ if (0 != (cur_ifaddrs->ifa_flags & IFF_POINTOPOINT)) { continue; } sin_addr = (struct sockaddr_in *) cur_ifaddrs->ifa_addr; intf = OBJ_NEW(opal_if_t); if (NULL == intf) { opal_output(0, "opal_ifinit: unable to allocate %d bytes\n", (int) sizeof(opal_if_t)); return OPAL_ERR_OUT_OF_RESOURCE; } intf->af_family = AF_INET; /* fill values into the opal_if_t */ memcpy(&a4, &(sin_addr->sin_addr), sizeof(struct in_addr)); strncpy(intf->if_name, cur_ifaddrs->ifa_name, IF_NAMESIZE); intf->if_index = opal_list_get_size(&opal_if_list) + 1; ((struct sockaddr_in*) &intf->if_addr)->sin_addr = a4; ((struct sockaddr_in*) &intf->if_addr)->sin_family = AF_INET; ((struct sockaddr_in*) &intf->if_addr)->sin_len = cur_ifaddrs->ifa_addr->sa_len; intf->if_mask = prefix( sin_addr->sin_addr.s_addr); intf->if_flags = cur_ifaddrs->ifa_flags; intf->if_kernel_index = (uint16_t) if_nametoindex(cur_ifaddrs->ifa_name); opal_list_append(&opal_if_list, &(intf->super)); } /* of for loop over ifaddrs list */ return OPAL_SUCCESS; }
/* for when all other options fail, as can happen on Android, if the permissions for the socket-based method are broken. Down side is that it while it gets the interface name and broadcast, it doesn't get the local address for that interface. */ int scrapeProcNetRoute() { if (debug & DEBUG_OVERLAYINTERFACES) DEBUG("called"); FILE *f=fopen("/proc/net/route","r"); if (!f) return WHY_perror("fopen(\"/proc/net/route\")"); char line[1024],name[1024],dest[1024],mask[1024]; /* skip header line */ line[0]=0; fgets(line,1024,f); line[0]=0; fgets(line,1024,f); while(line[0]) { int r; if ((r=sscanf(line,"%s %s %*s %*s %*s %*s %*s %s",name,dest,mask))==3) { struct in_addr addr = {.s_addr=strtol(dest,NULL,16)}; struct in_addr netmask = {.s_addr=strtol(mask,NULL,16)}; overlay_interface_register(name,addr,netmask); } line[0]=0; fgets(line,1024,f); } fclose(f); return 0; } #endif #ifdef SIOCGIFCONF /* Not present in Linux */ #ifndef _SIZEOF_ADDR_IFREQ #define _SIZEOF_ADDR_IFREQ(x) sizeof(struct ifreq) #endif int lsif(void) { char buf[8192]; struct ifconf ifc; int sck, nInterfaces, ofs; struct ifreq *ifr; struct in_addr addr, netmask; if (debug & DEBUG_OVERLAYINTERFACES) DEBUG("called"); /* Get a socket handle. */ sck = socket(PF_INET, SOCK_DGRAM, 0); if(sck < 0) { WHY_perror("socket"); return 1; } /* Query available interfaces. */ ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if(ioctl(sck, SIOCGIFCONF, &ifc) < 0) { WHY_perror("ioctl(SIOCGIFCONF)"); close(sck); return 1; } /* Iterate through the list of interfaces. */ nInterfaces = 0; ofs = 0; while (ofs < ifc.ifc_len && ofs < sizeof(buf)) { ifr = (struct ifreq *)(ifc.ifc_ifcu.ifcu_buf + ofs); ofs += _SIZEOF_ADDR_IFREQ(*ifr); /* We're only interested in IPv4 addresses */ if (ifr->ifr_ifru.ifru_addr.sa_family != AF_INET) { if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Skipping non-AF_INET address on %s", ifr->ifr_name); continue; } addr = ((struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr)->sin_addr; /* Get interface flags */ if (ioctl(sck, SIOCGIFFLAGS, ifr) == -1) FATAL_perror("ioctl(SIOCGIFFLAGS)"); /* Not broadcast? Not interested.. */ if ((ifr->ifr_ifru.ifru_flags & IFF_BROADCAST) == 0) { if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Skipping non-broadcast address on %s", ifr->ifr_name); continue; } /* Get netmask */ if (ioctl(sck, SIOCGIFNETMASK, ifr, sizeof(*ifr)) != 0) { WHY_perror("ioctl(SIOCGIFNETMASK)"); continue; } netmask = ((struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr)->sin_addr; overlay_interface_register(ifr->ifr_name, addr, netmask); nInterfaces++; } if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Examined %d interface addresses", nInterfaces); close(sck); return 0; } #endif #ifdef HAVE_IFADDRS_H int doifaddrs(void) { struct ifaddrs *ifaddr, *ifa; char *name; struct in_addr addr, netmask; if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("called"); if (getifaddrs(&ifaddr) == -1) return WHY_perror("getifaddr()"); for (ifa = ifaddr; ifa != NULL ; ifa = ifa->ifa_next) { /* We're only interested in IPv4 addresses */ if (ifa->ifa_addr->sa_family != AF_INET) { if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Skipping non-AF_INET address on %s", ifa->ifa_name); continue; } /* Not broadcast? Not interested.. */ if ((ifa->ifa_flags & IFF_BROADCAST) == 0) { if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Skipping non-broadcast address on %s", ifa->ifa_name); continue; } name = ifa->ifa_name; addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; netmask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr; overlay_interface_register(name, addr, netmask); } freeifaddrs(ifaddr); return 0; }
__private_extern__ int si_inet_config(uint32_t *inet4, uint32_t *inet6) { int status, checkit; struct ifaddrs *ifa, *ifap; pthread_mutex_lock(&net_config_mutex); checkit = 1; if (net_config_token < 0) { status = notify_register_check(kNotifySCNetworkChange, &net_config_token); if (status != 0) net_config_token = -1; } if (net_config_token >= 0) { status = notify_check(net_config_token, &checkit); if (status != 0) checkit = 1; } status = 0; if (checkit != 0) { if (getifaddrs(&ifa) < 0) { status = -1; } else { net_v4_count = 0; net_v6_count = 0; for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next) { if (ifap->ifa_addr == NULL) continue; if ((ifap->ifa_flags & IFF_UP) == 0) continue; if (ifap->ifa_addr->sa_family == AF_INET) { net_v4_count++; } else if (ifap->ifa_addr->sa_family == AF_INET6) { net_v6_count++; } } freeifaddrs(ifa); } } if (inet4 != NULL) *inet4 = net_v4_count; if (inet6 != NULL) *inet6 = net_v6_count; pthread_mutex_unlock(&net_config_mutex); return status; }
/* * this function gets the hardware type and address of an interface, * determines the link layer token length and checks it against * the defined prefixes */ int setup_deviceinfo(int sock, struct Interface *iface) { struct ifaddrs *addresses, *ifa; struct ifreq ifr; struct AdvPrefix *prefix; char zero[sizeof(iface->if_addr)]; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface->Name, IFNAMSIZ-1); ifr.ifr_name[IFNAMSIZ-1] = '\0'; if (ioctl(sock, SIOCGIFMTU, &ifr) < 0) { flog(LOG_ERR, "ioctl(SIOCGIFMTU) failed for %s: %s", iface->Name, strerror(errno)); goto ret; } dlog(LOG_DEBUG, 3, "mtu for %s is %d", iface->Name, ifr.ifr_mtu); iface->if_maxmtu = ifr.ifr_mtu; if (getifaddrs(&addresses) != 0) { flog(LOG_ERR, "getifaddrs failed: %s(%d)", strerror(errno), errno); goto ret; } for (ifa = addresses; ifa != NULL; ifa = ifa->ifa_next) { if (strcmp(ifa->ifa_name, iface->Name) != 0) continue; if (ifa->ifa_addr == NULL) continue; if (ifa->ifa_addr->sa_family != AF_LINK) continue; struct sockaddr_dl *dl = (struct sockaddr_dl*)ifa->ifa_addr; if (dl->sdl_alen > sizeof(iface->if_addr)) { flog(LOG_ERR, "address length %d too big for", dl->sdl_alen, iface->Name); goto ret; } memcpy(iface->if_hwaddr, LLADDR(dl), dl->sdl_alen); iface->if_hwaddr_len = dl->sdl_alen << 3; switch(dl->sdl_type) { case IFT_ETHER: case IFT_ISO88023: iface->if_prefix_len = 64; break; case IFT_FDDI: iface->if_prefix_len = 64; break; default: iface->if_prefix_len = -1; iface->if_maxmtu = -1; break; } dlog(LOG_DEBUG, 3, "link layer token length for %s is %d", iface->Name, iface->if_hwaddr_len); dlog(LOG_DEBUG, 3, "prefix length for %s is %d", iface->Name, iface->if_prefix_len); if (iface->if_prefix_len != -1) { memset(zero, 0, dl->sdl_alen); if (!memcmp(iface->if_hwaddr, zero, dl->sdl_alen)) flog(LOG_WARNING, "WARNING, MAC address on %s is all zero!", iface->Name); } prefix = iface->AdvPrefixList; while (prefix) { if ((iface->if_prefix_len != -1) && (iface->if_prefix_len != prefix->PrefixLen)) { flog(LOG_WARNING, "prefix length should be %d for %s", iface->if_prefix_len, iface->Name); } prefix = prefix->next; } freeifaddrs(addresses); return 0; } ret: iface->if_maxmtu = -1; iface->if_hwaddr_len = -1; iface->if_prefix_len = -1; freeifaddrs(addresses); return -1; }
int main(int argc,char *argv[]) { char *dev,errbuf[PCAP_ERRBUF_SIZE]; pcap_t *handle; /* Session handle */ struct bpf_program fp; /* compiled filter expression */ char filter_exp[]="ether proto \\ip"; //"ip proto \\udp or \\tcp or \\icmp"; /* Filter expression */ bpf_u_int32 mask; /* netmask of sniffing device */ bpf_u_int32 net; /* IP address of const struct pcap_pkthdrsniffing device */ struct sigaction *act_alarm,*act_int; struct pcap_pkthdr header; const u_char *packet=NULL; act_alarm=(struct sigaction*)malloc(sizeof(struct sigaction)); act_int=(struct sigaction*)malloc(sizeof(struct sigaction)); memset(act_alarm,'\0',sizeof(act_alarm)); memset(act_int,'\0',sizeof(act_int)); act_alarm->sa_handler=alarm_printhandler; sigemptyset(&act_alarm->sa_mask); act_alarm->sa_flags=0; sigaction(SIGALRM,act_alarm,NULL); act_int->sa_handler=INT_handler; sigemptyset(&act_int->sa_mask); act_int->sa_flags=0; sigaction(SIGINT,act_int,NULL); if(gettimeofday(¤t_time,NULL) != 0) { fprintf(stderr,"Error in gettimeofday(): %s\n",strerror(errno)); exit(1); } /* Handle commandline here */ memset(interface,'\0',sizeof(interface)); memset(filename,'\0',sizeof(filename)); memset(my_ip,'\0',sizeof(my_ip)); handle_commandline(argc,argv); newvalue=(struct itimerval*)malloc(sizeof(struct itimerval)); newvalue->it_interval.tv_sec=epoch; newvalue->it_interval.tv_usec=0; newvalue->it_value.tv_sec=epoch; newvalue->it_value.tv_usec=0; setitimer(ITIMER_REAL,newvalue,NULL); /* fetch ip address */ getifaddrs(&addr); while(addr) { if(addr->ifa_addr && addr->ifa_addr->sa_family == AF_INET && strcmp(addr->ifa_name,interface)==0) { struct sockaddr_in *paddr = (struct sockaddr_in *)addr->ifa_addr; //fprintf(stdout,"%s %s\n",addr->ifa_name,inet_ntoa(paddr->sin_addr)); //project strcpy(filename,inet_ntoa(paddr->sin_addr)); strcpy(my_ip,inet_ntoa(paddr->sin_addr)); break; } addr = addr->ifa_next; } //printf("Filename: %s",filename); if(epoch == 0) { epoch=1; // default is 1 sec } if(interface[0] == '\0') { dev=" "; } else { dev=interface; } //fprintf(stdout,"Device is %s\n",dev); /* Lookup network */ if(pcap_lookupnet(dev,&net,&mask,errbuf) == -1) { //fprintf(stderr, "Can't get netmask for device %s\n", dev); net = 0; mask = 0; } //printf("IP: %d\n",net); //printf("Mask: %d\n",mask); /* Opening device for sniffing */ if(read_file == NULL) { if((handle=pcap_create(dev,errbuf)) == NULL) { fprintf(stderr,"Error in pcap_create: %s",errbuf); exit(1); } if(pcap_set_promisc(handle,5) == PCAP_ERROR_ACTIVATED || pcap_set_timeout(handle,epoch*1000) == PCAP_ERROR_ACTIVATED ) { fprintf(stderr,"Capture handle already activated"); exit(1); } pcap_activate(handle); } else { filer=fopen(read_file,"r"); /* block the alarm handler too */ sigaddset(&act_alarm->sa_mask,SIGALRM); sigprocmask(SIG_BLOCK,&act_alarm->sa_mask,NULL); if(filer == NULL) { perror("Error in fopen file"); exit(1); } handle=pcap_fopen_offline(filer,errbuf); if(handle == NULL) { fprintf(stderr,"Error in pcap_open_offline(): %s",errbuf); exit(1); } } if(write_file != NULL) { filew=fopen(write_file,"w"); } if(handle == NULL) { fprintf(stderr,"Couldn't open device %s: %s\n",dev,errbuf); exit(1); } /* Determine the type of link-headers the device provides */ if(pcap_datalink(handle) != DLT_EN10MB) { fprintf(stderr,"Usage: ./traffana -v [-r filename] [-i interface] [-T epoch] [-w filename]\n"); exit(1); } /* Complie filter */ if(pcap_compile(handle,&fp, filter_exp,0,net) == -1) { fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle)); exit(1); } /* Set filter */ if (pcap_setfilter(handle, &fp) == -1) { fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle)); exit(1); } /* set the diection */ //pcap_setdirection(handle,PCAP_D_IN); /* Grab the packets */ if(read_file == NULL) { err_loop=pcap_loop(handle,-1,got_packet,(u_char *)filew); // count -1 or 0 for infinity packets AND pass argument the name // of th file if(err_loop == -1) { pcap_perror(handle,errbuf); fprintf(stderr,"Error in pcap_loop(): %s\n",errbuf); exit(1); } } if(read_file !=NULL) { while((packet = pcap_next(handle,&header))!=NULL) { got_packet(0,&header,packet); } } /* Close session */ if(read_file != NULL) { print_readfile_stats(sec1,usec1); /* to read the last epoch */ } pcap_freecode(&fp); pcap_close(handle); return 0; }
/* * NetBSD support auto-clonning, but only for tap device. * To access /dev/tapN we have to create it before. */ static int tuntap_sys_start_tap(struct device *dev, int tun) { int fd; struct ifreq ifr; struct ifaddrs *ifa; char name[IF_NAMESIZE + 5]; /* For /dev/IFNAMSIZ */ fd = -1; (void)memset(&ifr, '\0', sizeof ifr); (void)memset(name, '\0', sizeof name); /* Set the device path to open */ if (tun < TUNTAP_ID_MAX) { /* Create the wanted device */ tuntap_sys_create_dev(dev, TUNTAP_MODE_ETHERNET, tun); (void)snprintf(name, sizeof name, "/dev/tap%i", tun); } else if (tun == TUNTAP_ID_ANY) { /* Or use autocloning */ (void)memcpy(name, "/dev/tap", 8); } else { return -1; } if ((fd = open(name, O_RDWR)) == -1) { char buf[11 + MAXPATHLEN]; (void)memset(buf, 0, sizeof buf); snprintf(buf, sizeof buf, "Can't open %s", name); tuntap_log(TUNTAP_LOG_DEBUG, buf); return -1; } /* Get the interface name */ if (ioctl(fd, TAPGIFNAME, &ifr) == -1) { tuntap_log(TUNTAP_LOG_ERR, "Can't get interface name"); return -1; } (void)strlcpy(dev->if_name, ifr.ifr_name, sizeof dev->if_name); /* Get the interface default values */ if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) { tuntap_log(TUNTAP_LOG_ERR, "Can't get interface values"); return -1; } /* Save flags for tuntap_{up, down} */ dev->flags = ifr.ifr_flags; /* Save pre-existing MAC address */ if (getifaddrs(&ifa) == 0) { struct ifaddrs *pifa; for (pifa = ifa; pifa != NULL; pifa = pifa->ifa_next) { if (strcmp(pifa->ifa_name, dev->if_name) == 0) { struct ether_addr eth_addr; /* * The MAC address is from 10 to 15. * * And yes, I know, the buffer is supposed * to have a size of 14 bytes. */ (void)memcpy(dev->hwaddr, pifa->ifa_addr->sa_data + 10, ETHER_ADDR_LEN); (void)memset(ð_addr.ether_addr_octet, 0, ETHER_ADDR_LEN); (void)memcpy(ð_addr.ether_addr_octet, pifa->ifa_addr->sa_data + 10, ETHER_ADDR_LEN); break; } } if (pifa == NULL) tuntap_log(TUNTAP_LOG_WARN, "Can't get link-layer address"); freeifaddrs(ifa); } return fd; }
void CNetworkLinux::queryInterfaceList() { char macAddrRaw[6]; m_interfaces.clear(); #if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) // Query the list of interfaces. struct ifaddrs *list; if (getifaddrs(&list) < 0) return; struct ifaddrs *cur; for(cur = list; cur != NULL; cur = cur->ifa_next) { if(cur->ifa_addr->sa_family != AF_INET) continue; GetMacAddress(cur->ifa_name, macAddrRaw); // Add the interface. m_interfaces.push_back(new CNetworkInterfaceLinux(this, cur->ifa_name, macAddrRaw)); } freeifaddrs(list); #else FILE* fp = fopen("/proc/net/dev", "r"); if (!fp) { // TBD: Error return; } char* line = NULL; size_t linel = 0; int n; char* p; int linenum = 0; while (getdelim(&line, &linel, '\n', fp) > 0) { // skip first two lines if (linenum++ < 2) continue; // search where the word begins p = line; while (isspace(*p)) ++p; // read word until : n = strcspn(p, ": \t"); p[n] = 0; // save the result std::string interfaceName = p; GetMacAddress(interfaceName, macAddrRaw); m_interfaces.push_back(new CNetworkInterfaceLinux(this, interfaceName, macAddrRaw)); } free(line); fclose(fp); #endif }
int tap_init(char *name) { #ifdef __MACH__ /* OSX */ char clonedev[255] = "/dev/"; /* XXX bad size */ strncpy(clonedev+5, name, 250); #else /* Linux */ struct ifreq ifr; const char *clonedev = "/dev/net/tun"; #endif /* implicitly create the tap interface */ if ((_native_tap_fd = open(clonedev , O_RDWR)) == -1) { err(EXIT_FAILURE, "open(%s)", clonedev); } #ifdef __MACH__ /* OSX */ struct ifaddrs* iflist; if (getifaddrs(&iflist) == 0) { for (struct ifaddrs *cur = iflist; cur; cur = cur->ifa_next) { if ((cur->ifa_addr->sa_family == AF_LINK) && (strcmp(cur->ifa_name, name) == 0) && cur->ifa_addr) { struct sockaddr_dl* sdl = (struct sockaddr_dl*)cur->ifa_addr; memcpy(_native_tap_mac, LLADDR(sdl), sdl->sdl_alen); break; } } freeifaddrs(iflist); } #else /* Linux */ memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; strncpy(ifr.ifr_name, name, IFNAMSIZ); if (ioctl(_native_tap_fd, TUNSETIFF, (void *)&ifr) == -1) { _native_in_syscall++; warn("ioctl TUNSETIFF"); warnx("probably the tap interface (%s) does not exist or is already in use", name); exit(EXIT_FAILURE); } /* TODO: use strncpy */ strcpy(name, ifr.ifr_name); /* get MAC address */ memset (&ifr, 0, sizeof (ifr)); snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", name); if (ioctl(_native_tap_fd, SIOCGIFHWADDR, &ifr) == -1) { _native_in_syscall++; warn("ioctl SIOCGIFHWADDR"); if (close(_native_tap_fd) == -1) { warn("close"); } exit(EXIT_FAILURE); } memcpy(_native_tap_mac, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); #endif DEBUG("_native_tap_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", _native_tap_mac[0], _native_tap_mac[1], _native_tap_mac[2], _native_tap_mac[3], _native_tap_mac[4], _native_tap_mac[5]); unsigned char *eui_64 = (unsigned char*)&_native_net_addr_long; eui_64[0] = _native_tap_mac[0]; eui_64[1] = _native_tap_mac[1]; eui_64[2] = _native_tap_mac[2]; eui_64[3] = 0xff; eui_64[4] = 0xfe; eui_64[5] = _native_tap_mac[3]; eui_64[6] = _native_tap_mac[4]; eui_64[7] = _native_tap_mac[5]; /* configure signal handler for fds */ register_interrupt(SIGIO, _native_handle_tap_input); #ifdef __MACH__ /* tuntap signalled IO is not working in OSX, * check http://sourceforge.net/p/tuntaposx/bugs/17/ */ sigio_child(); #else /* configure fds to send signals on io */ if (fcntl(_native_tap_fd, F_SETOWN, getpid()) == -1) { err(EXIT_FAILURE, "tap_init(): fcntl(F_SETOWN)"); } /* set file access mode to nonblocking */ if (fcntl(_native_tap_fd, F_SETFL, O_NONBLOCK|O_ASYNC) == -1) { err(EXIT_FAILURE, "tap_init(): fcntl(F_SETFL)"); } #endif /* not OSX */ DEBUG("RIOT native tap initialized.\n"); return _native_tap_fd; }
/* * Figure out whether the local machine is the same * as the remote machine (RM) entry (if it exists). */ char * checkremote(void) { char lname[NI_MAXHOST], rname[NI_MAXHOST]; struct addrinfo hints, *res, *res0; static char errbuf[128]; int error; struct ifaddrs *ifap, *ifa; const int niflags = NI_NUMERICHOST; #ifdef __KAME__ struct sockaddr_in6 sin6; struct sockaddr_in6 *sin6p; #endif remote = 0; /* assume printer is local on failure */ if (RM == NULL || *RM == '\0') return NULL; /* get the local interface addresses */ siginterrupt(SIGINT, 1); if (getifaddrs(&ifap) < 0) { (void)snprintf(errbuf, sizeof(errbuf), "unable to get local interface address: %s", strerror(errno)); siginterrupt(SIGINT, 0); return errbuf; } siginterrupt(SIGINT, 0); /* get the remote host addresses (RM) */ memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; res = NULL; siginterrupt(SIGINT, 1); error = getaddrinfo(RM, NULL, &hints, &res0); siginterrupt(SIGINT, 0); if (error) { (void)snprintf(errbuf, sizeof(errbuf), "unable to resolve remote machine %s: %s", RM, gai_strerror(error)); freeifaddrs(ifap); return errbuf; } remote = 1; /* assume printer is remote */ for (res = res0; res; res = res->ai_next) { siginterrupt(SIGINT, 1); error = getnameinfo(res->ai_addr, res->ai_addrlen, rname, sizeof(rname), NULL, 0, niflags); siginterrupt(SIGINT, 0); if (error != 0) continue; for (ifa = ifap; ifa; ifa = ifa->ifa_next) { #ifdef __KAME__ sin6p = (struct sockaddr_in6 *)ifa->ifa_addr; if (ifa->ifa_addr->sa_family == AF_INET6 && ifa->ifa_addr->sa_len == sizeof(sin6) && IN6_IS_ADDR_LINKLOCAL(&sin6p->sin6_addr) && *(u_int16_t *)&sin6p->sin6_addr.s6_addr[2]) { /* kame scopeid hack */ memcpy(&sin6, ifa->ifa_addr, sizeof(sin6)); sin6.sin6_scope_id = ntohs(*(u_int16_t *)&sin6p->sin6_addr.s6_addr[2]); sin6.sin6_addr.s6_addr[2] = 0; sin6.sin6_addr.s6_addr[3] = 0; siginterrupt(SIGINT, 1); error = getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, lname, sizeof(lname), NULL, 0, niflags); siginterrupt(SIGINT, 0); if (error != 0) continue; } else #endif siginterrupt(SIGINT, 1); error = getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len, lname, sizeof(lname), NULL, 0, niflags); siginterrupt(SIGINT, 0); if (error != 0) continue; if (strcmp(rname, lname) == 0) { remote = 0; goto done; } } } done: freeaddrinfo(res0); freeifaddrs(ifap); return NULL; }
uv_err_t uv_interface_addresses(uv_interface_address_t** addresses, int* count) { #ifndef HAVE_IFADDRS_H return uv__new_artificial_error(UV_ENOSYS); #else struct ifaddrs *addrs, *ent; char ip[INET6_ADDRSTRLEN]; uv_interface_address_t* address; if (getifaddrs(&addrs) != 0) { return uv__new_sys_error(errno); } *count = 0; /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) || (ent->ifa_addr == NULL) || (ent->ifa_addr->sa_family == PF_PACKET)) { continue; } (*count)++; } *addresses = (uv_interface_address_t*) malloc(*count * sizeof(uv_interface_address_t)); if (!(*addresses)) { return uv__new_artificial_error(UV_ENOMEM); } address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { bzero(&ip, sizeof (ip)); if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) { continue; } if (ent->ifa_addr == NULL) { continue; } /* * On Linux getifaddrs returns information related to the raw underlying * devices. We're not interested in this information. */ if (ent->ifa_addr->sa_family == PF_PACKET) { continue; } address->name = strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6 *)ent->ifa_addr); } else { address->address.address4 = *((struct sockaddr_in *)ent->ifa_addr); } address->is_internal = ent->ifa_flags & IFF_LOOPBACK ? 1 : 0; address++; } freeifaddrs(addrs); return uv_ok_; #endif }
void chk_reader(char *token, char *value, struct s_reader *rdr) { int32_t i; char *ptr, *ptr2, *ptr3, *saveptr1 = NULL; /* * case sensitive first */ if (!strcmp(token, "device")) { for (i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 3) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++) { trim(ptr); switch(i) { case 0: cs_strncpy(rdr->device, ptr, sizeof(rdr->device)); break; case 1: rdr->r_port = atoi(ptr); break; case 2: rdr->l_port = atoi(ptr); break; } } return; } #ifdef WITH_LIBUSB if (!strcmp(token, "device_out_endpoint")) { if (strlen(value) > 0) { sscanf(value, "0x%2X", &i); rdr->device_endpoint = i; } else { rdr->device_endpoint = 0; } return; } #endif if (!strcmp(token, "key")) { if (strlen(value) == 0){ return; } else if (key_atob_l(value, rdr->ncd_key, 28)) { fprintf(stderr, "Configuration newcamd: Error in Key\n"); memset(rdr->ncd_key, 0, sizeof(rdr->ncd_key)); } return; } if (!strcmp(token, "password")) { cs_strncpy(rdr->r_pwd, value, sizeof(rdr->r_pwd)); return; } if (!strcmp(token, "user")) { cs_strncpy(rdr->r_usr, value, sizeof(rdr->r_usr)); return; } #ifdef WEBIF if (!strcmp(token, "description")) { NULLFREE(rdr->description); if(strlen(value) > 0 && cs_malloc(&rdr->description, strlen(value)+1, -1)){ cs_strncpy(rdr->description, value, strlen(value)+1); } return; } #endif if (!strcmp(token, "mg-encrypted")) { uchar key[16]; uchar mac[6]; char tmp_dbg[13]; uchar *buf = NULL; int32_t len = 0; memset(&key, 0, 16); memset(&mac, 0, 6); for (i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 2) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++) { trim(ptr); switch(i) { case 0: len = strlen(ptr) / 2 + (16 - (strlen(ptr) / 2) % 16); if(!cs_malloc(&buf,len, -1)) return; key_atob_l(ptr, buf, strlen(ptr)); cs_log("enc %d: %s", len, ptr); break; case 1: key_atob_l(ptr, mac, 12); cs_log("mac: %s", ptr); break; } } if (!memcmp(mac, "\x00\x00\x00\x00\x00\x00", 6)) { #if defined(__APPLE__) || defined(__FreeBSD__) // no mac address specified so use mac of en0 on local box struct ifaddrs *ifs, *current; if (getifaddrs(&ifs) == 0) { for (current = ifs; current != 0; current = current->ifa_next) { if (current->ifa_addr->sa_family == AF_LINK && strcmp(current->ifa_name, "en0") == 0) { struct sockaddr_dl *sdl = (struct sockaddr_dl *)current->ifa_addr; memcpy(mac, LLADDR(sdl), sdl->sdl_alen); break; } } freeifaddrs(ifs); } #elif defined(__SOLARIS__) // no mac address specified so use first filled mac int32_t j, sock, niccount; struct ifreq nicnumber[16]; struct ifconf ifconf; struct arpreq arpreq; if ((sock=socket(AF_INET,SOCK_DGRAM,0)) > -1){ ifconf.ifc_buf = (caddr_t)nicnumber; ifconf.ifc_len = sizeof(nicnumber); if (!ioctl(sock,SIOCGIFCONF,(char*)&ifconf)){ niccount = ifconf.ifc_len/(sizeof(struct ifreq)); for(i = 0; i < niccount, ++i){ memset(&arpreq, 0, sizeof(arpreq)); ((struct sockaddr_in*)&arpreq.arp_pa)->sin_addr.s_addr = ((struct sockaddr_in*)&nicnumber[i].ifr_addr)->sin_addr.s_addr; if (!(ioctl(sock,SIOCGARP,(char*)&arpreq))){ for (j = 0; j < 6; ++j) mac[j] = (unsigned char)arpreq.arp_ha.sa_data[j]; if(check_filled(mac, 6) > 0) break; } } } close(sock); }
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { #ifndef HAVE_IFADDRS_H return -ENOSYS; #else struct ifaddrs *addrs, *ent; uv_interface_address_t* address; int i; struct sockaddr_ll *sll; if (getifaddrs(&addrs)) return -errno; *count = 0; *addresses = NULL; /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || (ent->ifa_addr == NULL) || (ent->ifa_addr->sa_family == PF_PACKET)) { continue; } (*count)++; } if (*count == 0) return 0; *addresses = uv__malloc(*count * sizeof(**addresses)); if (!(*addresses)) { freeifaddrs(addrs); return -ENOMEM; } address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) continue; if (ent->ifa_addr == NULL) continue; /* * On Linux getifaddrs returns information related to the raw underlying * devices. We're not interested in this information yet. */ if (ent->ifa_addr->sa_family == PF_PACKET) continue; address->name = uv__strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); } else { address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); } if (ent->ifa_netmask->sa_family == AF_INET6) { address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); } else { address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); } address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); address++; } /* Fill in physical addresses for each interface */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || (ent->ifa_addr == NULL) || (ent->ifa_addr->sa_family != PF_PACKET)) { continue; } address = *addresses; for (i = 0; i < (*count); i++) { if (strcmp(address->name, ent->ifa_name) == 0) { sll = (struct sockaddr_ll*)ent->ifa_addr; memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr)); } address++; } } freeifaddrs(addrs); return 0; #endif }
bool net_ifinfo_new(net_ifinfo_t *list) { unsigned k = 0; #if defined(_WIN32) && !defined(_XBOX) DWORD size; PIP_ADAPTER_ADDRESSES adapter_addresses, aa; PIP_ADAPTER_UNICAST_ADDRESS ua; DWORD rv = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &size); adapter_addresses = (PIP_ADAPTER_ADDRESSES)malloc(size); rv = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, adapter_addresses, &size); memset(list, 0, sizeof(net_ifinfo_t)); if (rv != ERROR_SUCCESS) goto error; for (aa = adapter_addresses; aa != NULL; aa = aa->Next) { char name[PATH_MAX_LENGTH]; memset(name, 0, sizeof(name)); WideCharToMultiByte(CP_ACP, 0, aa->FriendlyName, wcslen(aa->FriendlyName), name, PATH_MAX_LENGTH, NULL, NULL); for (ua = aa->FirstUnicastAddress; ua != NULL; ua = ua->Next) { char host[PATH_MAX_LENGTH]; struct net_ifinfo_entry *ptr = (struct net_ifinfo_entry*) realloc(list->entries, (k+1) * sizeof(struct net_ifinfo_entry)); if (!ptr) goto error; list->entries = ptr; memset(host, 0, sizeof(host)); getnameinfo(ua->Address.lpSockaddr, ua->Address.iSockaddrLength, host, sizeof(host), NULL, NI_MAXSERV, NI_NUMERICHOST); list->entries[k].name = strdup(name); list->entries[k].host = strdup(host); list->size = k + 1; k++; } } free(adapter_addresses); #else struct ifaddrs *ifa = NULL; struct ifaddrs *ifaddr = NULL; memset(list, 0, sizeof(net_ifinfo_t)); if (getifaddrs(&ifaddr) == -1) goto error; if (!list) goto error; for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { char host[NI_MAXHOST]; struct net_ifinfo_entry *ptr = NULL; if (!ifa->ifa_addr) continue; if (ifa->ifa_addr->sa_family != AF_INET) continue; if (getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) != 0) goto error; ptr = (struct net_ifinfo_entry*) realloc(list->entries, (k+1) * sizeof(struct net_ifinfo_entry)); if (!ptr) goto error; list->entries = ptr; list->entries[k].name = strdup(ifa->ifa_name); list->entries[k].host = strdup(host); list->size = k + 1; k++; } freeifaddrs(ifaddr); #endif return true; error: #ifdef _WIN32 if (adapter_addresses) free(adapter_addresses); #else freeifaddrs(ifaddr); #endif net_ifinfo_free(list); return false; }
/* * Return NICs information a-la ifconfig as a list of tuples. * TODO: on Solaris we won't get any MAC address. */ static PyObject* psutil_net_if_addrs(PyObject* self, PyObject* args) { struct ifaddrs *ifaddr, *ifa; int family; PyObject *py_retlist = PyList_New(0); PyObject *py_tuple = NULL; PyObject *py_address = NULL; PyObject *py_netmask = NULL; PyObject *py_broadcast = NULL; PyObject *py_ptp = NULL; if (py_retlist == NULL) return NULL; if (getifaddrs(&ifaddr) == -1) { PyErr_SetFromErrno(PyExc_OSError); goto error; } for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { if (!ifa->ifa_addr) continue; family = ifa->ifa_addr->sa_family; py_address = psutil_convert_ipaddr(ifa->ifa_addr, family); // If the primary address can't be determined just skip it. // I've never seen this happen on Linux but I did on FreeBSD. if (py_address == Py_None) continue; if (py_address == NULL) goto error; py_netmask = psutil_convert_ipaddr(ifa->ifa_netmask, family); if (py_netmask == NULL) goto error; if (ifa->ifa_flags & IFF_BROADCAST) { py_broadcast = psutil_convert_ipaddr(ifa->ifa_broadaddr, family); Py_INCREF(Py_None); py_ptp = Py_None; } else if (ifa->ifa_flags & IFF_POINTOPOINT) { py_ptp = psutil_convert_ipaddr(ifa->ifa_dstaddr, family); Py_INCREF(Py_None); py_broadcast = Py_None; } else { Py_INCREF(Py_None); Py_INCREF(Py_None); py_broadcast = Py_None; py_ptp = Py_None; } if ((py_broadcast == NULL) || (py_ptp == NULL)) goto error; py_tuple = Py_BuildValue( "(siOOOO)", ifa->ifa_name, family, py_address, py_netmask, py_broadcast, py_ptp ); if (! py_tuple) goto error; if (PyList_Append(py_retlist, py_tuple)) goto error; Py_DECREF(py_tuple); Py_DECREF(py_address); Py_DECREF(py_netmask); Py_DECREF(py_broadcast); Py_DECREF(py_ptp); } freeifaddrs(ifaddr); return py_retlist; error: if (ifaddr != NULL) freeifaddrs(ifaddr); Py_DECREF(py_retlist); Py_XDECREF(py_tuple); Py_XDECREF(py_address); Py_XDECREF(py_netmask); Py_XDECREF(py_broadcast); Py_XDECREF(py_ptp); return NULL; }
__private_extern__ void interface_update_ipv6(struct ifaddrs *ifap, const char *if_name) { struct ifaddrs *ifa; struct ifaddrs *ifap_temp = NULL; CFStringRef interface; boolean_t interfaceFound = FALSE; CFStringRef key = NULL; CFMutableDictionaryRef oldIFs; CFMutableDictionaryRef newDict = NULL; CFMutableDictionaryRef newIFs; int sock = -1; oldIFs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); newIFs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (!ifap) { if (getifaddrs(&ifap_temp) == -1) { SC_log(LOG_NOTICE, "getifaddrs() failed: %s", strerror(errno)); goto error; } ifap = ifap_temp; } for (ifa = ifap; ifa; ifa = ifa->ifa_next) { struct in6_ifreq ifr6; #define flags6 ifr6.ifr_ifru.ifru_flags6 struct sockaddr_in6 *sin6; if (ifa->ifa_addr->sa_family != AF_INET6) { continue; /* sorry, not interested */ } /* check if this is the requested interface */ if (if_name) { if (strncmp(if_name, ifa->ifa_name, IFNAMSIZ) == 0) { interfaceFound = TRUE; /* yes, this is the one I want */ } else { continue; /* sorry, not interested */ } } if (sock == -1) { sock = dgram_socket(AF_INET6); if (sock == -1) { goto error; } } /* get the current cache information */ interface = CFStringCreateWithCString(NULL, ifa->ifa_name, kCFStringEncodingMacRoman); key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, interface, kSCEntNetIPv6); CFRelease(interface); newDict = copyIF(key, oldIFs, newIFs); /* ALIGN: ifa->ifa_addr aligned (getifaddrs), cast ok. */ sin6 = (struct sockaddr_in6 *)(void *)ifa->ifa_addr; /* XXX: embedded link local addr check */ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr)) { u_int16_t index; index = sin6->sin6_addr.s6_addr16[1]; if (index != 0) { sin6->sin6_addr.s6_addr16[1] = 0; if (sin6->sin6_scope_id == 0) { sin6->sin6_scope_id = ntohs(index); } } } bzero((char *)&ifr6, sizeof(ifr6)); strncpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name)); ifr6.ifr_addr = *sin6; if (ioctl(sock, SIOCGIFAFLAG_IN6, &ifr6) == -1) { /* if flags not available for this address */ SC_log((errno != EADDRNOTAVAIL) ? LOG_NOTICE : LOG_DEBUG, "ioctl() failed: %s", strerror(errno)); } appendAddress (newDict, kSCPropNetIPv6Addresses, sin6); #ifdef NOTYET appendScopeID (newDict, sin6); #endif /* NOTYET */ /* ALIGN: ifa should be aligned (from getifaddrs), cast ok. * appendPrefixLen expect byte alignment */ appendPrefixLen(newDict, (struct sockaddr_in6 *)(void *)ifa->ifa_netmask); appendFlags (newDict, flags6); if (ifa->ifa_flags & IFF_POINTOPOINT && ifa->ifa_dstaddr != NULL) { struct sockaddr_in6 *dst6; /* ALIGN: ifa should be aligned (from getifaddrs), cast ok. */ dst6 = (struct sockaddr_in6 *)(void *)ifa->ifa_dstaddr; /* XXX: embedded link local addr check */ if (IN6_IS_ADDR_LINKLOCAL(&dst6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&dst6->sin6_addr)) { u_int16_t index; index = dst6->sin6_addr.s6_addr16[1]; if (index != 0) { dst6->sin6_addr.s6_addr16[1] = 0; if (dst6->sin6_scope_id == 0) { dst6->sin6_scope_id = ntohs(index); } } } appendAddress(newDict, kSCPropNetIPv6DestAddresses, dst6); } CFDictionarySetValue(newIFs, key, newDict); CFRelease(newDict); CFRelease(key); } /* if the last address[es] were removed from the target interface */ if (if_name && !interfaceFound) { interface = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingMacRoman); key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, interface, kSCEntNetIPv6); CFRelease(interface); newDict = copyIF(key, oldIFs, newIFs); CFDictionarySetValue(newIFs, key, newDict); CFRelease(newDict); CFRelease(key); } CFDictionaryApplyFunction(newIFs, updateStore, oldIFs); error : if (ifap_temp) freeifaddrs(ifap_temp); if (sock != -1) close(sock); CFRelease(oldIFs); CFRelease(newIFs); return; }
char * addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr, char *netid) { struct ifaddrs *ifap, *ifp, *bestif; #ifdef INET6 struct sockaddr_in6 *servsin6, *sin6mask, *clntsin6, *ifsin6, *realsin6; struct sockaddr_in6 *newsin6; #endif struct sockaddr_in *servsin, *sinmask, *clntsin, *newsin, *ifsin; struct netbuf *serv_nbp, *clnt_nbp = NULL, tbuf; struct sockaddr *serv_sa; struct sockaddr *clnt_sa; struct sockaddr_storage ss; struct netconfig *nconf; struct sockaddr *clnt = caller->buf; char *ret = NULL; #ifdef INET6 servsin6 = ifsin6 = newsin6 = NULL; /* XXXGCC -Wuninitialized */ #endif servsin = newsin = NULL; /* XXXGCC -Wuninitialized */ #ifdef RPCBIND_DEBUG if (debugging) fprintf(stderr, "addrmerge(caller, %s, %s, %s\n", serv_uaddr, clnt_uaddr, netid); #endif nconf = getnetconfigent(netid); if (nconf == NULL) return NULL; /* * Local merge, just return a duplicate. */ if (clnt_uaddr != NULL && strncmp(clnt_uaddr, "0.0.0.0.", 8) == 0) return strdup(clnt_uaddr); serv_nbp = uaddr2taddr(nconf, serv_uaddr); if (serv_nbp == NULL) return NULL; serv_sa = (struct sockaddr *)serv_nbp->buf; if (clnt_uaddr != NULL) { clnt_nbp = uaddr2taddr(nconf, clnt_uaddr); if (clnt_nbp == NULL) { free(serv_nbp); return NULL; } clnt_sa = (struct sockaddr *)clnt_nbp->buf; if (clnt_sa->sa_family == AF_LOCAL) { free(serv_nbp); free(clnt_nbp); free(clnt_sa); return strdup(serv_uaddr); } } else { clnt_sa = (struct sockaddr *) malloc(sizeof (struct sockaddr_storage)); memcpy(clnt_sa, clnt, clnt->sa_len); } if (getifaddrs(&ifp) < 0) { free(serv_nbp); free(clnt_sa); if (clnt_nbp != NULL) free(clnt_nbp); return 0; } /* * Loop through all interfaces. For each interface, see if the * network portion of its address is equal to that of the client. * If so, we have found the interface that we want to use. */ for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) { if (ifap->ifa_addr->sa_family != clnt->sa_family || !(ifap->ifa_flags & IFF_UP)) continue; switch (clnt->sa_family) { case AF_INET: /* * realsin: address that recvfrom gave us. * ifsin: address of interface being examined. * clntsin: address that client want us to contact * it on * servsin: local address of RPC service. * sinmask: netmask of this interface * newsin: initially a copy of clntsin, eventually * the merged address */ servsin = (struct sockaddr_in *)serv_sa; clntsin = (struct sockaddr_in *)clnt_sa; sinmask = (struct sockaddr_in *)ifap->ifa_netmask; newsin = (struct sockaddr_in *)&ss; ifsin = (struct sockaddr_in *)ifap->ifa_addr; if (!bitmaskcmp(&ifsin->sin_addr, &clntsin->sin_addr, &sinmask->sin_addr, sizeof (struct in_addr))) { goto found; } break; #ifdef INET6 case AF_INET6: /* * realsin6: address that recvfrom gave us. * ifsin6: address of interface being examined. * clntsin6: address that client want us to contact * it on * servsin6: local address of RPC service. * sin6mask: netmask of this interface * newsin6: initially a copy of clntsin, eventually * the merged address * * For v6 link local addresses, if the client contacted * us via a link-local address, and wants us to reply * to one, use the scope id to see which one. */ realsin6 = (struct sockaddr_in6 *)clnt; ifsin6 = (struct sockaddr_in6 *)ifap->ifa_addr; in6_fillscopeid(ifsin6); clntsin6 = (struct sockaddr_in6 *)clnt_sa; servsin6 = (struct sockaddr_in6 *)serv_sa; sin6mask = (struct sockaddr_in6 *)ifap->ifa_netmask; newsin6 = (struct sockaddr_in6 *)&ss; if (IN6_IS_ADDR_LINKLOCAL(&ifsin6->sin6_addr) && IN6_IS_ADDR_LINKLOCAL(&realsin6->sin6_addr) && IN6_IS_ADDR_LINKLOCAL(&clntsin6->sin6_addr)) { if (ifsin6->sin6_scope_id != realsin6->sin6_scope_id) continue; goto found; } if (!bitmaskcmp(&ifsin6->sin6_addr, &clntsin6->sin6_addr, &sin6mask->sin6_addr, sizeof (struct in6_addr))) goto found; break; #endif default: goto freeit; } } /* * Didn't find anything. Get the first possibly useful interface, * preferring "normal" interfaces to point-to-point and loopback * ones. */ bestif = NULL; for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) { if (ifap->ifa_addr->sa_family != clnt->sa_family || !(ifap->ifa_flags & IFF_UP)) continue; if (!(ifap->ifa_flags & IFF_LOOPBACK) && !(ifap->ifa_flags & IFF_POINTOPOINT)) { bestif = ifap; break; } if (bestif == NULL) bestif = ifap; else if ((bestif->ifa_flags & IFF_LOOPBACK) && !(ifap->ifa_flags & IFF_LOOPBACK)) bestif = ifap; } ifap = bestif; found: switch (clnt->sa_family) { case AF_INET: memcpy(newsin, ifap->ifa_addr, clnt_sa->sa_len); newsin->sin_port = servsin->sin_port; tbuf.len = clnt_sa->sa_len; tbuf.maxlen = sizeof (struct sockaddr_storage); tbuf.buf = newsin; break; #ifdef INET6 case AF_INET6: assert(newsin6); memcpy(newsin6, ifsin6, clnt_sa->sa_len); newsin6->sin6_port = servsin6->sin6_port; tbuf.maxlen = sizeof (struct sockaddr_storage); tbuf.len = clnt_sa->sa_len; tbuf.buf = newsin6; break; #endif default: goto freeit; } if (ifap != NULL) ret = taddr2uaddr(nconf, &tbuf); freeit: freenetconfigent(nconf); free(serv_sa); free(serv_nbp); if (clnt_sa != NULL) free(clnt_sa); if (clnt_nbp != NULL) free(clnt_nbp); freeifaddrs(ifp); #ifdef RPCBIND_DEBUG if (debugging) fprintf(stderr, "addrmerge: returning %s\n", ret); #endif return ret; }
/* Builds a list of interfaces that correspond to active verbs devices */ static int fi_ibv_getifaddrs(struct dlist_entry *verbs_devs) { struct ifaddrs *ifaddr, *ifa; char name[INET6_ADDRSTRLEN]; struct rdma_addrinfo *rai; struct rdma_cm_id *id; const char *ret_ptr; int ret, num_verbs_ifs = 0; char *iface = NULL; size_t iface_len = 0; int exact_match = 0; ret = getifaddrs(&ifaddr); if (ret) { VERBS_WARN(FI_LOG_FABRIC, "Unable to get interface addresses\n"); return ret; } /* select best iface name based on user's input */ if (fi_param_get_str(&fi_ibv_prov, "iface", &iface) == FI_SUCCESS) { iface_len = strlen(iface); if (iface_len > IFNAMSIZ) { VERBS_INFO(FI_LOG_EP_CTRL, "Too long iface name: %s, max: %d\n", iface, IFNAMSIZ); return -FI_EINVAL; } for (ifa = ifaddr; ifa && !exact_match; ifa = ifa->ifa_next) exact_match = !strcmp(ifa->ifa_name, iface); } for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) { if (!ifa->ifa_addr || !(ifa->ifa_flags & IFF_UP) || !strcmp(ifa->ifa_name, "lo")) continue; if(iface) { if(exact_match) { if(strcmp(ifa->ifa_name, iface)) continue; } else { if(strncmp(ifa->ifa_name, iface, iface_len)) continue; } } switch (ifa->ifa_addr->sa_family) { case AF_INET: ret_ptr = inet_ntop(AF_INET, &ofi_sin_addr(ifa->ifa_addr), name, INET6_ADDRSTRLEN); break; case AF_INET6: ret_ptr = inet_ntop(AF_INET6, &ofi_sin6_addr(ifa->ifa_addr), name, INET6_ADDRSTRLEN); break; default: continue; } if (!ret_ptr) { VERBS_WARN(FI_LOG_FABRIC, "inet_ntop failed: %s(%d)\n", strerror(errno), errno); goto err1; } ret = fi_ibv_create_ep(name, NULL, FI_NUMERICHOST | FI_SOURCE, NULL, &rai, &id); if (ret) continue; ret = fi_ibv_add_rai(verbs_devs, id, rai); if (ret) goto err2; VERBS_DBG(FI_LOG_FABRIC, "Found active interface for verbs device: " "%s with address: %s\n", ibv_get_device_name(id->verbs->device), name); rdma_destroy_ep(id); num_verbs_ifs++; } freeifaddrs(ifaddr); return num_verbs_ifs ? 0 : -FI_ENODATA; err2: rdma_destroy_ep(id); err1: fi_ibv_verbs_devs_free(verbs_devs); freeifaddrs(ifaddr); return ret; }
/* * Gets a unique id for this process instance * Uses the mac address right now * And combine with the unique port number, which is why it needs to be passed in * Needs to be a little more subtle: * Should stash the mac address or something, in case you have to replace a card. * * parameters- * Input params: * port - used in setting Node ID * hb_mode - Controls whether hb_addrp is filled out with the IP address. * config_interface_names - Pointer to an array of interface names if specified in the config file, * NULL if absent. * * Output params: * id - Node ID (address and port) * node_ipp - Pointer wherein the IP address is stored * hb_addrp - Pointer to a string wherein the heartbeat address is stored, as specified by hb_mode */ int cf_nodeid_get(unsigned short port, cf_node *id, char **node_ipp, hb_mode_enum hb_mode, char **hb_addrp, const char **config_interface_names) { // The default interface names can be overridden by the interface name passed into config const char **interface_names = default_interface_names; bool default_config = true; int jlimit = 11; if (config_interface_names) { interface_names = config_interface_names; default_config = false; jlimit = 1; } int fdesc = socket(AF_INET, SOCK_STREAM, 0); if (fdesc <= 0) { cf_warning(CF_MISC, "can't open socket: %d %s", errno, cf_strerror(errno)); return(-1); } struct ifreq req; bool done = false; for (int i = 0; interface_names[i]; i++) { for (int j = 0; j < jlimit; j++) { if (default_config) { sprintf(req.ifr_name, interface_names[i], j); } else { sprintf(req.ifr_name, interface_names[i]); } if (0 == ioctl(fdesc, SIOCGIFHWADDR, &req)) { if (cf_ipaddr_get(fdesc, req.ifr_name, node_ipp) == 0) { done = true; break; } } cf_debug(CF_MISC, "can't get physical address of interface %s: %d %s", req.ifr_name, errno, cf_strerror(errno)); } if (done) { break; } } if (! done) { if (default_config) { struct ifaddrs *interface_addrs = NULL; if (getifaddrs(&interface_addrs) == -1) { cf_warning(CF_MISC, "getifaddrs failed %d %s", errno, cf_strerror(errno)); return -1; } if (! interface_addrs) { cf_warning(CF_MISC, "getifaddrs returned NULL"); return -1; } struct ifaddrs *ifa; for (ifa = interface_addrs; ifa != NULL; ifa = ifa->ifa_next) { if (! ifa->ifa_data) { continue; } if (! is_biosdevname(ifa->ifa_name)) { continue; } if (check_mac_and_get_ipaddr(fdesc, ifa->ifa_name, &req, node_ipp)) { done = true; break; } } for (ifa = interface_addrs; ifa != NULL && (! done); ifa = ifa->ifa_next) { if (! ifa->ifa_data) { continue; } if (check_mac_and_get_ipaddr(fdesc, ifa->ifa_name, &req, node_ipp)) { done = true; break; } } freeifaddrs(interface_addrs); } else { cf_warning(CF_MISC, "can't get physical address of interface name specified in config file, tried %s. fatal: %d %s", interface_names[0], errno, cf_strerror(errno)); close(fdesc); return(-1); } } close(fdesc); if (! done) { cf_warning(CF_MISC, "Tried eth,bond,wlan,em and list of all available interfaces on device. Failed to retrieve physical address with errno %d %s\n", errno, cf_strerror(errno)); return(-1); } /* * Set the hb_addr to be the same as the ip address if the mode is mesh and the hb_addr parameter is empty * Configuration file overrides the automatic node ip detection * - this gives us a work around in case the node ip is somehow detected wrong in production */ if (hb_mode == AS_HB_MODE_MESH) { if (*hb_addrp == NULL) { *hb_addrp = cf_strdup(*node_ipp); } cf_info(CF_MISC, "Heartbeat address for mesh: %s", *hb_addrp); } *id = 0; memcpy(id, req.ifr_hwaddr.sa_data, 6); memcpy(((byte *)id) + 6, &port, 2); cf_debug(CF_MISC, "port %d id %"PRIx64, port, *id); return(0); }
int interface_add(const char *name) { struct interface *v4 = NULL, *v6 = NULL, *unicast; struct ifaddrs *ifap, *ifa; getifaddrs(&ifap); for (ifa = ifap; ifa; ifa = ifa->ifa_next) { if (strcmp(ifa->ifa_name, name)) continue; if (ifa->ifa_addr->sa_family == AF_INET && !v4) { struct sockaddr_in *sa; if (cfg_proto && (cfg_proto != 4)) continue; unicast = _interface_add(name, 0, 0); if (!unicast) continue; v4 = _interface_add(name, 1, 0); if (!v4) continue; sa = (struct sockaddr_in *) ifa->ifa_addr; memcpy(&v4->v4_addr, &sa->sin_addr, sizeof(v4->v4_addr)); memcpy(&unicast->v4_addr, &sa->sin_addr, sizeof(unicast->v4_addr)); inet_ntop(AF_INET, &sa->sin_addr, v4->v4_addrs, sizeof(v4->v4_addrs)); inet_ntop(AF_INET, &sa->sin_addr, unicast->v4_addrs, sizeof(unicast->v4_addrs)); sa = (struct sockaddr_in *) ifa->ifa_netmask; memcpy(&unicast->v4_netmask, &sa->sin_addr, sizeof(unicast->v4_netmask)); memcpy(&v4->v4_netmask, &sa->sin_addr, sizeof(v4->v4_netmask)); v4->peer = unicast; unicast->peer = v4; } if (ifa->ifa_addr->sa_family == AF_INET6 && !v6) { uint8_t ll_prefix[] = {0xfe, 0x80 }; struct sockaddr_in6 *sa6; if (cfg_proto && (cfg_proto != 6)) continue; sa6 = (struct sockaddr_in6 *) ifa->ifa_addr; if (memcmp(&sa6->sin6_addr, &ll_prefix, 2)) continue; unicast = _interface_add(name, 0, 1); if (!unicast) continue; v6 = _interface_add(name, 1, 1); if (!v6) continue; memcpy(&v6->v6_addr, &sa6->sin6_addr, sizeof(v6->v6_addr)); memcpy(&unicast->v6_addr, &sa6->sin6_addr, sizeof(unicast->v6_addr)); inet_ntop(AF_INET6, &sa6->sin6_addr, v6->v6_addrs, sizeof(v6->v6_addrs)); inet_ntop(AF_INET6, &sa6->sin6_addr, unicast->v6_addrs, sizeof(unicast->v6_addrs)); sa6 = (struct sockaddr_in6 *) ifa->ifa_netmask; memcpy(&v6->v6_netmask, &sa6->sin6_addr, sizeof(v6->v6_netmask)); memcpy(&unicast->v6_netmask, &sa6->sin6_addr, sizeof(unicast->v6_netmask)); v6->peer = unicast; unicast->peer = v6; } } freeifaddrs(ifap); return !v4 && !v6; }