From 27b3c2c20195b48e2be96d261339747f30f3d997 Mon Sep 17 00:00:00 2001 From: Johnny Mnemonic Date: Fri, 7 Feb 2025 13:58:45 +0100 Subject: [PATCH 1/3] src/netdev.c: switch from PF_INET to AF_PACKET --- src/netdev.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/netdev.c b/src/netdev.c index 3b67392..436b805 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -125,10 +126,10 @@ typedef struct _eth_dev_t { struct _eth_dev_t *eth_next; /* linked list of devices */ char eth_name[IFNAMSIZ]; /* real name */ - unsigned int eth_ipaddr; /* current ipaddress */ - int eth_fd; /* current fiel descriptor */ + unsigned int eth_ipaddr; /* current IP address */ + int eth_fd; /* current field descriptor */ int eth_flags; /* attached|detached */ - struct sockaddr eth_sa; /* save extra copies on send */ + struct sockaddr_ll eth_sa_ll; /* save extra copies on send */ } eth_dev_t; @@ -153,7 +154,11 @@ find_eth (int fd) int netdev_open (char *name, unsigned char *macaddr) { - struct sockaddr sa; + struct sockaddr_ll sa_ll = { + .sll_family = AF_PACKET, + .sll_protocol = htons(ETH_P_ALL), + .sll_ifindex = if_nametoindex(name), + }; struct sockaddr_in *sin; struct ifreq ifr; eth_dev_t *eth; @@ -167,10 +172,8 @@ netdev_open (char *name, unsigned char *macaddr) * Open a RAW/PACKET socket (just like tcpdump) * * See 'man 7 packet' on Linux. - * - * TODO: switch obsolete PF_INET to AF_PACKET. */ - fd = socket (PF_INET, SOCK_PACKET, htons(ETH_P_ALL)); + fd = socket (AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (fd == -1) { if (errno == EPERM) @@ -180,12 +183,7 @@ netdev_open (char *name, unsigned char *macaddr) return -1; } - memset (&sa, 0, sizeof (sa)); - - sa.sa_family = AF_INET; - strncpy (sa.sa_data, name, sizeof (sa.sa_data)); - - r = bind (fd, &sa, sizeof (sa)); + r = bind (fd, (struct sockaddr *)&sa_ll, sizeof (sa_ll)); if (r) { cmdwPrint("Cannot bind (disabling network): make sure %s exists\n", name); close(fd); @@ -215,7 +213,7 @@ netdev_open (char *name, unsigned char *macaddr) eth->eth_flags = ETH_DETACHED; eth_list = eth; /* we're at the head of the list now */ - eth->eth_sa = sa; /* we're fine because sa_data is an array */ + eth->eth_sa_ll = sa_ll; r = ioctl (fd, SIOCGIFHWADDR, &ifr); if (r) @@ -377,7 +375,7 @@ long netdev_send (int fd, char *fbuf, int len) { int r; - struct sockaddr sa; + struct sockaddr_ll sa_ll; eth_dev_t *eth = find_eth (fd); if ((unsigned long) fbuf & 0x3) @@ -386,7 +384,7 @@ netdev_send (int fd, char *fbuf, int len) if (eth == NULL) progExit ("netdev_send: can't find %d\n", fd); - r = sendto (fd, fbuf, len, 0, ð->eth_sa, sizeof (sa)); + r = sendto (fd, fbuf, len, 0, (struct sockaddr *)ð->eth_sa_ll, sizeof (sa_ll)); if (r == -1) progExit ("netdev_send: error on sendto %d\n", errno); From c754a11194a334e0084ea8d6a7955ca3c2a553dc Mon Sep 17 00:00:00 2001 From: Johnny Mnemonic Date: Fri, 7 Feb 2025 14:12:34 +0100 Subject: [PATCH 2/3] src/netdev.c: fix typos and remove unneeded whitespaces --- src/netdev.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/netdev.c b/src/netdev.c index 436b805..04183f2 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -57,9 +57,9 @@ #define MAX_FD 256 -BOOL ski_nonet; /* when true network is disable, ie no interface is found */ +BOOL ski_nonet; /* when true network is disabled, i.e. no interface is found */ -/* +/* * thanks to tcpdump for the program dump * * /usr/sbin/tcpdump -dd dst xx.xx.xx.xx or ether broadcast @@ -134,7 +134,7 @@ typedef struct _eth_dev_t eth_dev_t; /* - * list od currently detected devices + * list of currently detected devices */ static eth_dev_t *eth_list; @@ -176,7 +176,7 @@ netdev_open (char *name, unsigned char *macaddr) fd = socket (AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (fd == -1) { - if (errno == EPERM) + if (errno == EPERM) cmdwPrint("No network support: must be run as root\n"); else cmdwPrint("No network support: make sure SOCK_PACKET is configured\n"); @@ -217,7 +217,7 @@ netdev_open (char *name, unsigned char *macaddr) r = ioctl (fd, SIOCGIFHWADDR, &ifr); if (r) - progExit ("netdev_open: get can't HW addr\n"); + progExit ("netdev_open: can't get HW addr\n"); memcpy (macaddr, (char *) ifr.ifr_hwaddr.sa_data, IFHWADDRLEN); @@ -229,7 +229,7 @@ netdev_open (char *name, unsigned char *macaddr) } static inline -void +void filter_patch (struct sock_filter *filter, unsigned int ipaddr) { filter[BPF_INS1].k = ipaddr; @@ -238,8 +238,8 @@ filter_patch (struct sock_filter *filter, unsigned int ipaddr) /* - * Put the device is promiscuous mode - * and enable packet filtering on the ipaddress + * Put the device in promiscuous mode + * and enable packet filtering on the IP address */ int netdev_attach (int fd, unsigned int ipaddr) @@ -285,7 +285,7 @@ netdev_attach (int fd, unsigned int ipaddr) ifr.ifr_flags |= IFF_PROMISC; /* - * promiscuous mode enabled now + * promiscuous mode enabled now */ r = ioctl (fd, SIOCSIFFLAGS, &ifr); if (r) @@ -324,7 +324,7 @@ netdev_detach (int fd) */ r = setsockopt (fd, SOL_SOCKET, SO_DETACH_FILTER, &dummy, sizeof (dummy)); if (r) - progExit ("netdev_attach: can't detach filter %d\n", errno); + progExit ("netdev_detach: can't detach filter %d\n", errno); memset (&ifr, 0, sizeof (ifr)); @@ -332,7 +332,7 @@ netdev_detach (int fd) r = ioctl (fd, SIOCGIFFLAGS, &ifr); if (r) - progExit ("net_detach: ioctl getflags"); + progExit ("netdev_detach: ioctl getflags"); ifr.ifr_flags &= ~IFF_PROMISC; @@ -362,7 +362,7 @@ netdev_recv (int fd, char *fbuf, int len) r = recv (fd, fbuf, len, 0); if (r == -1 && errno != EAGAIN) - progExit ("netdev_recv: error on read %d\n", errno); + progExit ("netdev_recv: error on recv %d\n", errno); return (long) (r > 0 ? r : 0); } @@ -379,7 +379,7 @@ netdev_send (int fd, char *fbuf, int len) eth_dev_t *eth = find_eth (fd); if ((unsigned long) fbuf & 0x3) - progExit ("trasmit frame not aligned"); + progExit ("transmit frame not aligned"); if (eth == NULL) progExit ("netdev_send: can't find %d\n", fd); @@ -392,7 +392,7 @@ netdev_send (int fd, char *fbuf, int len) } /* - * check is SIGIO was because of network I/O + * check if SIGIO was because of network I/O * the other possible reason is keyboard input * * This is kind of heavy weight but we need to demultiplex somewhow ! From c19b7f59f3508668e55fc1332e61bb98b84174ef Mon Sep 17 00:00:00 2001 From: Johnny Mnemonic Date: Wed, 12 Feb 2025 21:55:22 +0100 Subject: [PATCH 3/3] src/netdev.c: bring up network interface for Ski before use * otherwise Ski crashes on first console input (w/PF_INET) or * the selected interface cannot be used inside Ski (w/AF_PACKET). --- src/netdev.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/netdev.c b/src/netdev.c index 04183f2..f7cd89d 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -151,6 +151,47 @@ find_eth (int fd) return NULL; } +/* + * taken and adapted from + * https://github.com/torvalds/linux/blob/v3.10/Documentation/networking/ifenslave.c + */ +static +int +set_if_up (char *ifname) +{ + int skfd = -1; /* AF_INET socket for ioctl() calls.*/ + int saved_errno; + + struct ifreq ifr; + int res = 0; + + ifr.ifr_flags = IFF_UP; + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + + /* Open a basic socket */ + if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("set_if_up: socket() failed\n"); + res = 1; + goto out; + } + + res = ioctl(skfd, SIOCSIFFLAGS, &ifr); + if (res < 0) { + saved_errno = errno; + cmdwPrint("Host interface '%s': Error: SIOCSIFFLAGS failed: %s\n", + ifname, strerror(saved_errno)); + } else { + cmdwPrint("Host interface '%s': flags set to %04X.\n", ifname, IFF_UP); + } + + out: + if (skfd >= 0) { + close(skfd); + } + + return res; +} + int netdev_open (char *name, unsigned char *macaddr) { @@ -183,6 +224,11 @@ netdev_open (char *name, unsigned char *macaddr) return -1; } + /* + * Make sure the selected interface is up, before using it. + */ + set_if_up (name); + r = bind (fd, (struct sockaddr *)&sa_ll, sizeof (sa_ll)); if (r) { cmdwPrint("Cannot bind (disabling network): make sure %s exists\n", name);