From 436983fe412b9e764f6bec422317b8588d175a86 Mon Sep 17 00:00:00 2001 From: Toni Uhlig Date: Wed, 13 Jun 2018 01:18:53 +0200 Subject: POTD skeleton #103. Signed-off-by: Toni Uhlig --- src/socket.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 2 deletions(-) (limited to 'src/socket.c') diff --git a/src/socket.c b/src/socket.c index 6713d10..06abc93 100644 --- a/src/socket.c +++ b/src/socket.c @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include #include #include @@ -116,9 +119,8 @@ int socket_accept_in(const psocket *psock, psocket *client_psock) int fd; assert(psock && client_psock); - client_psock->fd = -1; - client_psock->addr_len = psock->addr_len; + *client_psock = *psock; fd = accept(psock->fd, &client_psock->addr, &client_psock->addr_len); if (fd < 0) @@ -246,3 +248,73 @@ void socket_clone(const psocket *src, psocket *dst) memcpy(dst, src, sizeof(*dst)); dst->fd = -1; } + +ssize_t socket_get_ifnames(const psocket *test_sock, char name[][IFNAMSIZ], + size_t siz, int loopback_only) +{ + struct ifreq ifr; + struct ifreq *it, *end; + struct ifconf ifc; + char buf[1024]; + int sock; + size_t rc = 0; + + assert(test_sock); + sock = socket(test_sock->family, test_sock->socktype, + test_sock->protocol); + if (sock <= 0) + return -1; + + ifc.ifc_len = sizeof buf; + ifc.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) + return -1; + it = ifc.ifc_req; + end = it + (ifc.ifc_len / sizeof(struct ifreq)); + + for (; it != end; ++it) { + strncpy(ifr.ifr_name, it->ifr_name, IFNAMSIZ); + + if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) { + if (loopback_only && !(ifr.ifr_flags & IFF_LOOPBACK)) + continue; + if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) { + strncpy(name[rc++], it->ifr_name, IFNAMSIZ); + if (siz == rc) + break; + } + } + } + + close(sock); + + return rc; +} + +int socket_set_ifaddr(const psocket *test_sock, + const char *ifname, const char *addr, const char *mask) +{ + struct ifreq ifr; + int sock; + + assert(test_sock); + sock = socket(test_sock->family, test_sock->socktype, + test_sock->protocol); + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + + ifr.ifr_addr.sa_family = AF_INET; + inet_pton(AF_INET, addr, ifr.ifr_addr.sa_data + 2); + ioctl(sock, SIOCSIFADDR, &ifr); + + inet_pton(AF_INET, mask, ifr.ifr_addr.sa_data + 2); + ioctl(sock, SIOCSIFNETMASK, &ifr); + + ioctl(sock, SIOCGIFFLAGS, &ifr); + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + + ioctl(sock, SIOCSIFFLAGS, &ifr); + close(sock); + + return 0; +} -- cgit v1.2.3