diff --git a/net/ip/tools/coap-client.c b/net/ip/tools/coap-client.c index 8a7c33632d4..0c2ae3abfff 100644 --- a/net/ip/tools/coap-client.c +++ b/net/ip/tools/coap-client.c @@ -407,61 +407,73 @@ static int get_ifindex(const char *name) return ifr.ifr_ifindex; } -static int get_address(int ifindex, int family, void *address) +static int find_address(int family, struct ifaddrs *if_address, + const char *if_name, void *address) { - struct ifaddrs *ifaddr, *ifa; - int err = -ENOENT; - char name[IF_NAMESIZE]; + struct ifaddrs *tmp; + int error = -ENOENT; - if (!if_indextoname(ifindex, name)) - return -EINVAL; + for (tmp = if_address; tmp; tmp = tmp->ifa_next) { + if (tmp->ifa_addr && + !strncmp(tmp->ifa_name, if_name, IF_NAMESIZE) && + tmp->ifa_addr->sa_family == family) { - if (getifaddrs(&ifaddr) < 0) { - err = -errno; - fprintf(stderr, "Cannot get addresses err %d/%s", - err, strerror(-err)); - return err; - } - - for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) { - if (!ifa->ifa_addr) - continue; - - if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 && - ifa->ifa_addr->sa_family == family) { - if (family == AF_INET) { - struct sockaddr_in *in4 = (struct sockaddr_in *) - ifa->ifa_addr; + switch (family) { + case AF_INET: { + struct sockaddr_in *in4 = + (struct sockaddr_in *)tmp->ifa_addr; if (in4->sin_addr.s_addr == INADDR_ANY) continue; if ((in4->sin_addr.s_addr & IN_CLASSB_NET) == - ((in_addr_t) 0xa9fe0000)) + ((in_addr_t)0xa9fe0000)) continue; memcpy(address, &in4->sin_addr, - sizeof(struct in_addr)); - } else if (family == AF_INET6) { + sizeof(struct in_addr)); + error = 0; + goto out; + } + case AF_INET6: { struct sockaddr_in6 *in6 = - (struct sockaddr_in6 *)ifa->ifa_addr; - if (memcmp(&in6->sin6_addr, &in6addr_any, - sizeof(struct in6_addr)) == 0) + (struct sockaddr_in6 *)tmp->ifa_addr; + if (!memcmp(&in6->sin6_addr, &in6addr_any, + sizeof(struct in6_addr))) continue; if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr)) continue; memcpy(address, &in6->sin6_addr, - sizeof(struct in6_addr)); - } else { - err = -EINVAL; + sizeof(struct in6_addr)); + error = 0; + goto out; + } + default: + error = -EINVAL; goto out; } - - err = 0; - break; } } out: - freeifaddrs(ifaddr); + return error; +} + +static int get_address(const char *if_name, int family, void *address) +{ + struct ifaddrs *if_address; + int err; + + if (getifaddrs(&if_address) < 0) { + err = -errno; + fprintf(stderr, "Cannot get interface addresses for " + "interface %s error %d/%s", + if_name, err, strerror(-err)); + return err; + } + + err = find_address(family, if_address, if_name, address); + + freeifaddrs(if_address); + return err; } @@ -1669,7 +1681,12 @@ int main(int argc, char**argv) exit(-EINVAL); } - get_address(ifindex, family, address); + ret = get_address(interface, family, address); + if (ret < 0) { + printf("Cannot find suitable source address " + "for interface %s [%d/%s]\n", + interface, ret, strerror(-ret)); + } printf("Binding to %s\n", inet_ntop(family, address, addr_buf, sizeof(addr_buf))); diff --git a/net/ip/tools/dtls-client.c b/net/ip/tools/dtls-client.c index dfaee73c231..dc0adf607f4 100644 --- a/net/ip/tools/dtls-client.c +++ b/net/ip/tools/dtls-client.c @@ -303,86 +303,73 @@ static inline void reverse(unsigned char *buf, int len) } } -static int get_ifindex(const char *name) +static int find_address(int family, struct ifaddrs *if_address, + const char *if_name, void *address) { - struct ifreq ifr; - int sk, err; + struct ifaddrs *tmp; + int error = -ENOENT; - if (!name) - return -1; + for (tmp = if_address; tmp; tmp = tmp->ifa_next) { + if (tmp->ifa_addr && + !strncmp(tmp->ifa_name, if_name, IF_NAMESIZE) && + tmp->ifa_addr->sa_family == family) { - sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (sk < 0) - return -1; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1); - - err = ioctl(sk, SIOCGIFINDEX, &ifr); - - close(sk); - - if (err < 0) - return -1; - - return ifr.ifr_ifindex; -} - -static int get_address(int ifindex, int family, void *address) -{ - struct ifaddrs *ifaddr, *ifa; - int err = -ENOENT; - char name[IF_NAMESIZE]; - - if (!if_indextoname(ifindex, name)) - return -EINVAL; - - if (getifaddrs(&ifaddr) < 0) { - err = -errno; - fprintf(stderr, "Cannot get addresses err %d/%s", - err, strerror(-err)); - return err; - } - - for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) { - if (!ifa->ifa_addr) - continue; - - if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 && - ifa->ifa_addr->sa_family == family) { - if (family == AF_INET) { - struct sockaddr_in *in4 = (struct sockaddr_in *) - ifa->ifa_addr; + switch (family) { + case AF_INET: { + struct sockaddr_in *in4 = + (struct sockaddr_in *)tmp->ifa_addr; if (in4->sin_addr.s_addr == INADDR_ANY) continue; if ((in4->sin_addr.s_addr & IN_CLASSB_NET) == - ((in_addr_t) 0xa9fe0000)) + ((in_addr_t)0xa9fe0000)) continue; memcpy(address, &in4->sin_addr, - sizeof(struct in_addr)); - } else if (family == AF_INET6) { + sizeof(struct in_addr)); + error = 0; + goto out; + } + case AF_INET6: { struct sockaddr_in6 *in6 = - (struct sockaddr_in6 *)ifa->ifa_addr; - if (memcmp(&in6->sin6_addr, &in6addr_any, - sizeof(struct in6_addr)) == 0) + (struct sockaddr_in6 *)tmp->ifa_addr; + if (!memcmp(&in6->sin6_addr, &in6addr_any, + sizeof(struct in6_addr))) continue; if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr)) continue; memcpy(address, &in6->sin6_addr, - sizeof(struct in6_addr)); - } else { - err = -EINVAL; + sizeof(struct in6_addr)); + error = 0; + goto out; + } + default: + error = -EINVAL; goto out; } - - err = 0; - break; } } out: - freeifaddrs(ifaddr); + return error; +} + +static int get_address(const char *if_name, int family, void *address) +{ + struct ifaddrs *if_address; + int err; + + if (getifaddrs(&if_address) < 0) { + err = -errno; + fprintf(stderr, "Cannot get interface addresses for " + "interface %s error %d/%s", + if_name, err, strerror(-err)); + return err; + } + + err = find_address(family, if_address, if_name, address); + + freeifaddrs(if_address); + return err; } @@ -686,7 +673,7 @@ int main(int argc, char**argv) const char *target = NULL, *interface = NULL, *source = NULL; fd_set rfds; struct timeval tv = {}; - int ifindex = -1, on, port; + int on, port; void *address = NULL; session_t dst; struct client_data user_data; @@ -810,14 +797,13 @@ int main(int argc, char**argv) } if (!source) { - ifindex = get_ifindex(interface); - if (ifindex < 0) { - printf("Invalid interface %s\n", interface); - exit(-EINVAL); + ret = get_address(interface, family, address); + if (ret < 0) { + printf("Cannot find suitable source address " + "for interface %s [%d/%s]\n", + interface, ret, strerror(-ret)); } - get_address(ifindex, family, address); - printf("Binding to %s\n", inet_ntop(family, address, addr_buf, sizeof(addr_buf))); } @@ -830,14 +816,18 @@ int main(int argc, char**argv) } on = 1; + + if (family == AF_INET6) { #ifdef IPV6_RECVPKTINFO - if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, - sizeof(on) ) < 0) { + if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, + sizeof(on)) < 0) { #else /* IPV6_RECVPKTINFO */ - if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &on, - sizeof(on) ) < 0) { + if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &on, + sizeof(on)) < 0) { #endif /* IPV6_RECVPKTINFO */ - printf("setsockopt IPV6_PKTINFO: %s\n", strerror(errno)); + printf("setsockopt IPV6_PKTINFO: %s\n", + strerror(errno)); + } } signal(SIGINT, signal_handler); diff --git a/net/ip/tools/dtls-server.c b/net/ip/tools/dtls-server.c index a54dd942b12..e60716af2fd 100644 --- a/net/ip/tools/dtls-server.c +++ b/net/ip/tools/dtls-server.c @@ -129,61 +129,73 @@ static int bind_device(int fd, const char *interface, void *addr, int len) return ret; } -static int get_address(int ifindex, int family, void *address) +static int find_address(int family, struct ifaddrs *if_address, + const char *if_name, void *address) { - struct ifaddrs *ifaddr, *ifa; - int err = -ENOENT; - char name[IF_NAMESIZE]; + struct ifaddrs *tmp; + int error = -ENOENT; - if (!if_indextoname(ifindex, name)) - return -EINVAL; + for (tmp = if_address; tmp; tmp = tmp->ifa_next) { + if (tmp->ifa_addr && + !strncmp(tmp->ifa_name, if_name, IF_NAMESIZE) && + tmp->ifa_addr->sa_family == family) { - if (getifaddrs(&ifaddr) < 0) { - err = -errno; - fprintf(stderr, "Cannot get addresses err %d/%s", - err, strerror(-err)); - return err; - } - - for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) { - if (!ifa->ifa_addr) - continue; - - if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 && - ifa->ifa_addr->sa_family == family) { - if (family == AF_INET) { - struct sockaddr_in *in4 = (struct sockaddr_in *) - ifa->ifa_addr; + switch (family) { + case AF_INET: { + struct sockaddr_in *in4 = + (struct sockaddr_in *)tmp->ifa_addr; if (in4->sin_addr.s_addr == INADDR_ANY) continue; if ((in4->sin_addr.s_addr & IN_CLASSB_NET) == - ((in_addr_t) 0xa9fe0000)) + ((in_addr_t)0xa9fe0000)) continue; memcpy(address, &in4->sin_addr, - sizeof(struct in_addr)); - } else if (family == AF_INET6) { + sizeof(struct in_addr)); + error = 0; + goto out; + } + case AF_INET6: { struct sockaddr_in6 *in6 = - (struct sockaddr_in6 *)ifa->ifa_addr; - if (memcmp(&in6->sin6_addr, &in6addr_any, - sizeof(struct in6_addr)) == 0) + (struct sockaddr_in6 *)tmp->ifa_addr; + if (!memcmp(&in6->sin6_addr, &in6addr_any, + sizeof(struct in6_addr))) continue; if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr)) continue; memcpy(address, &in6->sin6_addr, - sizeof(struct in6_addr)); - } else { - err = -EINVAL; + sizeof(struct in6_addr)); + error = 0; + goto out; + } + default: + error = -EINVAL; goto out; } - - err = 0; - break; } } out: - freeifaddrs(ifaddr); + return error; +} + +static int get_address(const char *if_name, int family, void *address) +{ + struct ifaddrs *if_address; + int err; + + if (getifaddrs(&if_address) < 0) { + err = -errno; + fprintf(stderr, "Cannot get interface addresses for " + "interface %s error %d/%s", + if_name, err, strerror(-err)); + return err; + } + + err = find_address(family, if_address, if_name, address); + + freeifaddrs(if_address); + return err; } @@ -544,7 +556,7 @@ int main(int argc, char**argv) * we can listen correct addresses. We do not want to listen * link local addresses in this test. */ - get_address(ifindex, AF_INET, &addr4_recv.sin_addr); + get_address(interface, AF_INET, &addr4_recv.sin_addr); printf("IPv4: binding to %s\n", inet_ntop(AF_INET, &addr4_recv.sin_addr, addr_buf, sizeof(addr_buf))); @@ -553,7 +565,7 @@ int main(int argc, char**argv) addr6_recv.sin6_port = htons(SERVER_PORT); /* Bind to global unicast address instead of ll address */ - get_address(ifindex, AF_INET6, &addr6_recv.sin6_addr); + get_address(interface, AF_INET6, &addr6_recv.sin6_addr); printf("IPv6: binding to %s\n", inet_ntop(AF_INET6, &addr6_recv.sin6_addr, addr_buf, sizeof(addr_buf))); diff --git a/net/ip/tools/echo-client.c b/net/ip/tools/echo-client.c index 109736f8907..e51671d10f4 100644 --- a/net/ip/tools/echo-client.c +++ b/net/ip/tools/echo-client.c @@ -302,61 +302,73 @@ static int get_ifindex(const char *name) return ifr.ifr_ifindex; } -static int get_address(int ifindex, int family, void *address) +static int find_address(int family, struct ifaddrs *if_address, + const char *if_name, void *address) { - struct ifaddrs *ifaddr, *ifa; - int err = -ENOENT; - char name[IF_NAMESIZE]; + struct ifaddrs *tmp; + int error = -ENOENT; - if (!if_indextoname(ifindex, name)) - return -EINVAL; + for (tmp = if_address; tmp; tmp = tmp->ifa_next) { + if (tmp->ifa_addr && + !strncmp(tmp->ifa_name, if_name, IF_NAMESIZE) && + tmp->ifa_addr->sa_family == family) { - if (getifaddrs(&ifaddr) < 0) { - err = -errno; - fprintf(stderr, "Cannot get addresses err %d/%s", - err, strerror(-err)); - return err; - } - - for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) { - if (!ifa->ifa_addr) - continue; - - if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 && - ifa->ifa_addr->sa_family == family) { - if (family == AF_INET) { - struct sockaddr_in *in4 = (struct sockaddr_in *) - ifa->ifa_addr; + switch (family) { + case AF_INET: { + struct sockaddr_in *in4 = + (struct sockaddr_in *)tmp->ifa_addr; if (in4->sin_addr.s_addr == INADDR_ANY) continue; if ((in4->sin_addr.s_addr & IN_CLASSB_NET) == - ((in_addr_t) 0xa9fe0000)) + ((in_addr_t)0xa9fe0000)) continue; memcpy(address, &in4->sin_addr, - sizeof(struct in_addr)); - } else if (family == AF_INET6) { + sizeof(struct in_addr)); + error = 0; + goto out; + } + case AF_INET6: { struct sockaddr_in6 *in6 = - (struct sockaddr_in6 *)ifa->ifa_addr; - if (memcmp(&in6->sin6_addr, &in6addr_any, - sizeof(struct in6_addr)) == 0) + (struct sockaddr_in6 *)tmp->ifa_addr; + if (!memcmp(&in6->sin6_addr, &in6addr_any, + sizeof(struct in6_addr))) continue; if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr)) continue; memcpy(address, &in6->sin6_addr, - sizeof(struct in6_addr)); - } else { - err = -EINVAL; + sizeof(struct in6_addr)); + error = 0; + goto out; + } + default: + error = -EINVAL; goto out; } - - err = 0; - break; } } out: - freeifaddrs(ifaddr); + return error; +} + +static int get_address(const char *if_name, int family, void *address) +{ + struct ifaddrs *if_address; + int err; + + if (getifaddrs(&if_address) < 0) { + err = -errno; + fprintf(stderr, "Cannot get interface addresses for " + "interface %s error %d/%s", + if_name, err, strerror(-err)); + return err; + } + + err = find_address(family, if_address, if_name, address); + + freeifaddrs(if_address); + return err; } @@ -480,7 +492,12 @@ int main(int argc, char**argv) exit(-EINVAL); } - get_address(ifindex, family, address); + ret = get_address(interface, family, address); + if (ret < 0) { + printf("Cannot find suitable source address " + "for interface %s [%d/%s]\n", + interface, ret, strerror(-ret)); + } printf("Binding to %s\n", inet_ntop(family, address, addr_buf, sizeof(addr_buf))); diff --git a/net/ip/tools/echo-server.c b/net/ip/tools/echo-server.c index 379bfd59be1..2a9add30cff 100644 --- a/net/ip/tools/echo-server.c +++ b/net/ip/tools/echo-server.c @@ -204,61 +204,73 @@ static int join_mc_group(int sock, int ifindex, int family, void *addr, return ret; } -static int get_address(int ifindex, int family, void *address) +static int find_address(int family, struct ifaddrs *if_address, + const char *if_name, void *address) { - struct ifaddrs *ifaddr, *ifa; - int err = -ENOENT; - char name[IF_NAMESIZE]; + struct ifaddrs *tmp; + int error = -ENOENT; - if (!if_indextoname(ifindex, name)) - return -EINVAL; + for (tmp = if_address; tmp; tmp = tmp->ifa_next) { + if (tmp->ifa_addr && + !strncmp(tmp->ifa_name, if_name, IF_NAMESIZE) && + tmp->ifa_addr->sa_family == family) { - if (getifaddrs(&ifaddr) < 0) { - err = -errno; - fprintf(stderr, "Cannot get addresses err %d/%s", - err, strerror(-err)); - return err; - } - - for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) { - if (!ifa->ifa_addr) - continue; - - if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 && - ifa->ifa_addr->sa_family == family) { - if (family == AF_INET) { - struct sockaddr_in *in4 = (struct sockaddr_in *) - ifa->ifa_addr; + switch (family) { + case AF_INET: { + struct sockaddr_in *in4 = + (struct sockaddr_in *)tmp->ifa_addr; if (in4->sin_addr.s_addr == INADDR_ANY) continue; if ((in4->sin_addr.s_addr & IN_CLASSB_NET) == - ((in_addr_t) 0xa9fe0000)) + ((in_addr_t)0xa9fe0000)) continue; memcpy(address, &in4->sin_addr, - sizeof(struct in_addr)); - } else if (family == AF_INET6) { + sizeof(struct in_addr)); + error = 0; + goto out; + } + case AF_INET6: { struct sockaddr_in6 *in6 = - (struct sockaddr_in6 *)ifa->ifa_addr; - if (memcmp(&in6->sin6_addr, &in6addr_any, - sizeof(struct in6_addr)) == 0) + (struct sockaddr_in6 *)tmp->ifa_addr; + if (!memcmp(&in6->sin6_addr, &in6addr_any, + sizeof(struct in6_addr))) continue; if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr)) continue; memcpy(address, &in6->sin6_addr, - sizeof(struct in6_addr)); - } else { - err = -EINVAL; + sizeof(struct in6_addr)); + error = 0; + goto out; + } + default: + error = -EINVAL; goto out; } - - err = 0; - break; } } out: - freeifaddrs(ifaddr); + return error; +} + +static int get_address(const char *if_name, int family, void *address) +{ + struct ifaddrs *if_address; + int err; + + if (getifaddrs(&if_address) < 0) { + err = -errno; + fprintf(stderr, "Cannot get interface addresses for " + "interface %s error %d/%s", + if_name, err, strerror(-err)); + return err; + } + + err = find_address(family, if_address, if_name, address); + + freeifaddrs(if_address); + return err; } @@ -315,7 +327,7 @@ int main(int argc, char**argv) * we can listen correct addresses. We do not want to listen * link local addresses in this test. */ - get_address(ifindex, AF_INET, &addr4_recv.sin_addr); + get_address(interface, AF_INET, &addr4_recv.sin_addr); printf("IPv4: binding to %s\n", inet_ntop(AF_INET, &addr4_recv.sin_addr, addr_buf, sizeof(addr_buf))); @@ -324,7 +336,7 @@ int main(int argc, char**argv) addr6_recv.sin6_port = htons(SERVER_PORT); /* Bind to global unicast address instead of ll address */ - get_address(ifindex, AF_INET6, &addr6_recv.sin6_addr); + get_address(interface, AF_INET6, &addr6_recv.sin6_addr); printf("IPv6: binding to %s\n", inet_ntop(AF_INET6, &addr6_recv.sin6_addr, addr_buf, sizeof(addr_buf)));