pmlag

Poor man's link aggregation
git clone git://git.finwo.net/app/pmlag
Log | Files | Refs | README | LICENSE

commit a40b06a0e24b54bdec276dc2bbcefc0605d1cb80
parent 88008ab347a73d7352757566931d6971ff2fdc38
Author: Yersa Nordman <yersa@finwo.nl>
Date:   Sun, 12 Mar 2023 23:37:03 +0100

Set iface to promiscuous mode for sockraw

Diffstat:
Msrc/util/socket.c | 133+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
1 file changed, 76 insertions(+), 57 deletions(-)

diff --git a/src/util/socket.c b/src/util/socket.c @@ -42,9 +42,21 @@ int iface_idx(int sockfd, char * ifname) { return ifr.ifr_ifindex; } +int if_ioctl(int cmd, struct ifreq* req) { + int ret, sock; + sock = socket(AF_INET, SOCK_PACKET, 0); + if (sock < 0) { + return -1; + } + ret = ioctl(sock, cmd, req); + close(sock); + return ret; +} + int sockraw_open(char * ifname) { + struct ifreq ifr; - // Open socket + // Open socket (P_ALL, due to custom ethertype field) int sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (sockfd < 0) { perror("Error opening socket"); @@ -52,7 +64,12 @@ int sockraw_open(char * ifname) { return -1; } - // Bind socket to interface + /* // Bind socket to interface */ + /* if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)) < 0) { */ + /* perror("Error binding raw socket to interface"); */ + /* } */ + + // Old bind to socket struct sockaddr_ll sll; bzero(&sll, sizeof(sll)); sll.sll_family = AF_PACKET; @@ -68,72 +85,74 @@ int sockraw_open(char * ifname) { return -1; } + // Get current iface configuration + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, ifname); + if (if_ioctl(SIOCGIFFLAGS, &ifr) < 0) { + perror("Get interface flags"); + } + + // Set iface to promiscuous mode + ifr.ifr_flags |= IFF_PROMISC; + if (if_ioctl(SIOCSIFFLAGS, &ifr) < 0) { + perror("Configure interface promiscuous mode"); + } + // Return the prepared socket return sockfd; } -static int if_ioctl(int cmd, struct ifreq* req) { - int ret, sock; - sock = socket(AF_INET, SOCK_PACKET, 0); - if (sock < 0) { - return -1; - } - ret = ioctl(sock, cmd, req); - close(sock); - return ret; -} - int tap_alloc(char * ifname, unsigned char * mac) { - struct ifreq ifr; - int fd, err; + struct ifreq ifr; + int fd, err; - if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) { - perror("Open tun"); - return -1; - } + if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) { + perror("Open tun"); + return -1; + } - // Bring up the interface - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TAP | IFF_MULTI_QUEUE | IFF_NO_PI; - if( *ifname ) { - strncpy(ifr.ifr_name, ifname, IFNAMSIZ); - } - /* if ( mac ) { */ - /* // TODO: random, copied or specific mac address pulled from ini */ - /* printf("MAC: %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]); */ - /* memset(&ifr, 0, sizeof(ifr)); */ - /* strcpy(ifr.ifr_name, ifname); */ - /* ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; */ - /* memcpy(ifr.ifr_hwaddr.sa_data, mac, ETH_ALEN); */ - /* if ((err = if_ioctl(SIOCSIFHWADDR, &ifr)) < 0) { */ - /* perror("Set if hwaddr"); */ - /* close(fd); */ - /* return err; */ - /* } */ - /* } */ - if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){ - perror("Open tun"); - close(fd); - return err; - } - strcpy(ifname, ifr.ifr_name); + // Bring up the interface + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_MULTI_QUEUE | IFF_NO_PI; + if( *ifname ) { + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + } + /* if ( mac ) { */ + /* // TODO: random, copied or specific mac address pulled from ini */ + /* printf("MAC: %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]); */ + /* memset(&ifr, 0, sizeof(ifr)); */ + /* strcpy(ifr.ifr_name, ifname); */ + /* ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; */ + /* memcpy(ifr.ifr_hwaddr.sa_data, mac, ETH_ALEN); */ + /* if ((err = if_ioctl(SIOCSIFHWADDR, &ifr)) < 0) { */ + /* perror("Set if hwaddr"); */ + /* close(fd); */ + /* return err; */ + /* } */ + /* } */ + if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){ + perror("Open tun"); + close(fd); + return err; + } + strcpy(ifname, ifr.ifr_name); - // Set interface to multicast|broadcast - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, ifname); - if (if_ioctl(SIOCGIFFLAGS, &ifr) < 0) { + // Set interface to multicast|broadcast + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, ifname); + if (if_ioctl(SIOCGIFFLAGS, &ifr) < 0) { + perror("failed to get the interface flags"); + close(fd); + return err; + } + if (!(ifr.ifr_flags & IFF_UP)) { + ifr.ifr_flags |= IFF_UP; + if (if_ioctl(SIOCSIFFLAGS, &ifr) < 0) { perror("failed to get the interface flags"); close(fd); return err; } - if (!(ifr.ifr_flags & IFF_UP)) { - ifr.ifr_flags |= IFF_UP; - if (if_ioctl(SIOCSIFFLAGS, &ifr) < 0) { - perror("failed to get the interface flags"); - close(fd); - return err; - } - } + } - return fd; + return fd; }