diff --git a/busybox/22-ifconfig-ipv6.patch b/busybox/22-ifconfig-ipv6.patch new file mode 100644 index 0000000..fc215d3 --- /dev/null +++ b/busybox/22-ifconfig-ipv6.patch @@ -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 ++#include + #include + #include + #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 + #include + #include + #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)