Skip to content

Commit

Permalink
busybox: Add IPv6 support for ifconfig
Browse files Browse the repository at this point in the history
Change the way ifconfig obtains the IPv6 addresses
  • Loading branch information
mateuszkobak committed Apr 17, 2024
1 parent 0caa417 commit a14f4d7
Showing 1 changed file with 199 additions and 0 deletions.
199 changes: 199 additions & 0 deletions busybox/22-ifconfig-ipv6.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
diff -ru busybox_clean/networking/ifconfig.c busybox-1.27.2/networking/ifconfig.c
--- busybox_clean/networking/ifconfig.c 2024-04-17 09:27:37.247725657 +0200
+++ busybox-1.27.2/networking/ifconfig.c 2024-04-17 09:34:13.348243876 +0200
@@ -100,6 +100,7 @@
#include "libbb.h"
#include "inet_common.h"
#include <net/if.h>
+#include <net/if6.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#ifdef HAVE_NET_ETHERNET_H
@@ -129,14 +130,6 @@
# define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses */
#endif

-#if ENABLE_FEATURE_IPV6
-struct in6_ifreq {
- struct in6_addr ifr6_addr;
- uint32_t ifr6_prefixlen;
- int ifr6_ifindex;
-};
-#endif
-
/*
* Here are the bit masks for the "flags" member of struct options below.
* N_ signifies no arg prefix; M_ signifies arg prefixed by '-'.
@@ -272,8 +265,8 @@
{ "SIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.irq) },
#endif
#if ENABLE_FEATURE_IPV6
- { "SIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */
- { "DIFADDR", SIOCDIFADDR, ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */
+ { "SIFADDR", SIOCAIFADDR_IN6, ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */
+ { "DIFADDR", SIOCDIFADDR_IN6, ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */
#endif
/* Last entry is for unmatched (assumed to be hostname/address) arg. */
{ "SIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr) },
@@ -453,15 +446,13 @@
}
if (lsa->u.sa.sa_family == AF_INET6) {
int sockfd6;
- struct in6_ifreq ifr6;
+ struct in6_aliasreq ifr6;

sockfd6 = xsocket(AF_INET6, SOCK_DGRAM, 0);
- xioctl(sockfd6, SIOCGIFINDEX, &ifr);
- ifr6.ifr6_ifindex = ifr.ifr_ifindex;
- ifr6.ifr6_prefixlen = prefix_len;
- memcpy(&ifr6.ifr6_addr,
- &lsa->u.sin6.sin6_addr,
- sizeof(struct in6_addr));
+ strncpy_IFNAMSIZ(ifr6.ifra_name, ifr.ifr_name);
+ memcpy(&ifr6.ifrau_addr,
+ &lsa->u.sin6,
+ sizeof(struct sockaddr_in6));
ioctl_or_perror_and_die(sockfd6, a1op->selector, &ifr6, "SIOC%s", a1op->name);
if (ENABLE_FEATURE_CLEAN_UP)
free(lsa);
diff -ru busybox_clean/networking/interface.c busybox-1.27.2/networking/interface.c
--- busybox_clean/networking/interface.c 2024-04-17 09:27:37.283725693 +0200
+++ busybox-1.27.2/networking/interface.c 2024-04-17 09:34:13.348243876 +0200
@@ -33,6 +33,7 @@

#include "libbb.h"
#include "inet_common.h"
+#include <ifaddrs.h>
#include <net/if.h>
#include <net/if_arp.h>
#ifdef HAVE_NET_ETHERNET_H
@@ -52,7 +53,6 @@
#endif

#define _PATH_PROCNET_DEV "/proc/net/dev"
-#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"

#ifdef HAVE_AFINET6
# ifndef _LINUX_IN6_H
@@ -841,76 +841,57 @@


#ifdef HAVE_AFINET6
-#define IPV6_ADDR_ANY 0x0000U
-
-#define IPV6_ADDR_UNICAST 0x0001U
-#define IPV6_ADDR_MULTICAST 0x0002U
-#define IPV6_ADDR_ANYCAST 0x0004U
-
-#define IPV6_ADDR_LOOPBACK 0x0010U
-#define IPV6_ADDR_LINKLOCAL 0x0020U
-#define IPV6_ADDR_SITELOCAL 0x0040U
-
-#define IPV6_ADDR_COMPATv4 0x0080U
-
-#define IPV6_ADDR_SCOPE_MASK 0x00f0U
-
-#define IPV6_ADDR_MAPPED 0x1000U
-#define IPV6_ADDR_RESERVED 0x2000U /* reserved address space */
-

static void ife_print6(struct interface *ptr)
{
- FILE *f;
- char addr6[40], devname[21];
- struct sockaddr_in6 sap;
- int plen, scope, dad_status, if_idx;
- char addr6p[8][5];
-
- f = fopen_for_read(_PATH_PROCNET_IFINET6);
- if (f == NULL)
- return;
-
- while (fscanf
- (f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
- addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4],
- addr6p[5], addr6p[6], addr6p[7], &if_idx, &plen, &scope,
- &dad_status, devname) != EOF
- ) {
- if (strcmp(devname, ptr->name) == 0) {
- sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
- addr6p[0], addr6p[1], addr6p[2], addr6p[3],
- addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
- memset(&sap, 0, sizeof(sap));
- inet_pton(AF_INET6, addr6,
- (struct sockaddr *) &sap.sin6_addr);
- sap.sin6_family = AF_INET6;
- printf(" inet6 addr: %s/%d",
- INET6_sprint((struct sockaddr *) &sap, 1),
- plen);
- printf(" Scope:");
- switch (scope & IPV6_ADDR_SCOPE_MASK) {
- case 0:
- puts("Global");
- break;
- case IPV6_ADDR_LINKLOCAL:
- puts("Link");
- break;
- case IPV6_ADDR_SITELOCAL:
- puts("Site");
- break;
- case IPV6_ADDR_COMPATv4:
- puts("Compat");
- break;
- case IPV6_ADDR_LOOPBACK:
- puts("Host");
- break;
- default:
- puts("Unknown");
+ char addr6[50];
+
+ struct ifaddrs *ifap;
+ getifaddrs(&ifap);
+
+ while (ifap != NULL) {
+ if (strcmp(ifap->ifa_name, ptr->name) == 0) {
+ struct sockaddr_in6 *addr;
+ addr = ifap->ifa_addr;
+
+ if (addr->sin6_family == AF_INET6) {
+ inet_ntop(AF_INET6, &addr->sin6_addr, addr6, 50);
+
+ /* Get the prefix length */
+ unsigned char *c = ((struct sockaddr_in6 *)ifap->ifa_netmask)->sin6_addr.s6_addr;
+ int i = 0, j = 0;
+ unsigned char n = 0;
+ while (i < 16) {
+ n = c[i];
+ while (n > 0) {
+ if (n & 1) j++;
+ n = n/2;
+ }
+ i++;
+ }
+
+ printf(" inet6 addr: %s/%d", addr6, j);
+ printf(" Scope:");
+
+ if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
+ puts ("link-local");
+ } else if (IN6_IS_ADDR_SITELOCAL(&addr->sin6_addr)) {
+ puts ("site-local");
+ } else if (IN6_IS_ADDR_V4MAPPED(&addr->sin6_addr)) {
+ puts ("v4mapped");
+ } else if (IN6_IS_ADDR_V4COMPAT(&addr->sin6_addr)) {
+ puts ("v4compat");
+ } else if (IN6_IS_ADDR_LOOPBACK(&addr->sin6_addr)) {
+ puts ("host");
+ } else if (IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr)) {
+ puts ("unspecified");
+ } else {
+ puts ("global");
+ }
}
}
+ ifap = ifap->ifa_next;
}
- fclose(f);
}
#else
#define ife_print6(a) ((void)0)

0 comments on commit a14f4d7

Please sign in to comment.