Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

busybox: add IPv6 support #75

Merged
merged 3 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions busybox/09-ping-signal.patch
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
networking/ping.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
networking/ping.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/networking/ping.c b/networking/ping.c
index 94fb007..dc45f94 100644
index 94fb007..179d9e6 100644
--- a/networking/ping.c
+++ b/networking/ping.c
@@ -25,6 +25,7 @@
Expand Down Expand Up @@ -45,3 +45,34 @@ index 94fb007..dc45f94 100644
if (c < 0) {
if (errno != EINTR)
bb_perror_msg("recvfrom");
@@ -743,6 +750,7 @@ static void ping4(len_and_sockaddr *lsa)
static void ping6(len_and_sockaddr *lsa)
{
int sockopt;
+ int flags;
struct msghdr msg;
struct sockaddr_in6 from;
struct iovec iov;
@@ -775,6 +783,9 @@ static void ping6(len_and_sockaddr *lsa)
sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */
setsockopt_SOL_SOCKET_int(pingsock, SO_RCVBUF, sockopt);

+ flags = fcntl(pingsock,F_GETFL,0);
+ fcntl(pingsock, F_SETFL, flags | O_NONBLOCK);
+
sockopt = offsetof(struct icmp6_hdr, icmp6_cksum);
BUILD_BUG_ON(offsetof(struct icmp6_hdr, icmp6_cksum) != 2);
setsockopt_int(pingsock, SOL_RAW, IPV6_CHECKSUM, sockopt);
@@ -803,8 +814,10 @@ static void ping6(len_and_sockaddr *lsa)
struct cmsghdr *mp;
int hoplimit = -1;
msg.msg_controllen = sizeof(control_buf);
-
- c = recvmsg(pingsock, &msg, 0);
+ do {
+ usleep(500);
+ c = recvmsg(pingsock, &msg, 0);
+ } while(c < 0 && errno == EAGAIN);
if (c < 0) {
if (errno != EINTR)
bb_perror_msg("recvfrom");
15 changes: 15 additions & 0 deletions busybox/21-route-include-ip6_route.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
networking/route.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/networking/route.c b/networking/route.c
index 811886c..8572b7d 100644
--- a/networking/route.c
+++ b/networking/route.c
@@ -45,6 +45,7 @@

#include <sys/socket.h>
#include <net/route.h>
+#include <net/ip6_route.h>
#include <net/if.h>

#include "libbb.h"
151 changes: 151 additions & 0 deletions busybox/22-ifconfig-ipv6.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
networking/ifconfig.c | 25 ++++++++--------------
networking/interface.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 63 insertions(+), 18 deletions(-)

diff --git a/networking/ifconfig.c b/networking/ifconfig.c
index 0a91e71..9c22c61 100644
--- a/networking/ifconfig.c
+++ b/networking/ifconfig.c
@@ -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 @@ static const struct arg1opt Arg1Opt[] = {
{ "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 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv)
}
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;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This break -Wunused-but-set-variable on prefix_len which is part of -Wall

- 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 --git a/networking/interface.c b/networking/interface.c
index 228ccf7..535c741 100644
--- a/networking/interface.c
+++ b/networking/interface.c
@@ -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,6 +841,7 @@ static void print_bytes_scaled(unsigned long long ull, const char *end)


#ifdef HAVE_AFINET6
+#if !defined(__phoenix__)
#define IPV6_ADDR_ANY 0x0000U

#define IPV6_ADDR_UNICAST 0x0001U
@@ -913,6 +914,59 @@ static void ife_print6(struct interface *ptr)
fclose(f);
}
#else
+static void ife_print6(struct interface *ptr)
+{
+ 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;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks: -Wdeclaration-after-statement declared in Makefile.flags of busybox. For some reason on GCC 9.5 warn is not issued but on gcc 14.2 it is.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update its also triggered on 9.50 my bad

+ 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;
+ }
+}
+#endif
+#else
#define ife_print6(a) ((void)0)
#endif

Loading