-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
busybox: Add IPv6 support for ifconfig
Change the way ifconfig obtains the IPv6 addresses
- Loading branch information
1 parent
0caa417
commit a14f4d7
Showing
1 changed file
with
199 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |