Index: busybox-1.31.1/include/usage.src.h =================================================================== --- busybox-1.31.1.orig/include/usage.src.h 2019-06-10 18:50:53.000000000 +0800 +++ busybox-1.31.1/include/usage.src.h 2021-03-16 14:29:48.169776648 +0800 @@ -28,6 +28,22 @@ INSERT #define busybox_notes_usage \ - "Hello world!\n" + "Hello world!\n" + +#define sendarp_trivial_usage \ + "-s -d " +#define sendarp_full_usage "\n\n" \ + "Send ARP packet with src device's IP and Hardware address to dst device.\n" \ + "\nOptions:" \ + "\n -s DEVNAME src device name." \ + "\n -d DEVNAME dst device name." \ + +#define sysinfo_trivial_usage \ + "System status report" +#define sysinfo_full_usage \ + "System status report\n\n" +#define sysinfo_example_usage \ + "$ sysinfo\n" + #endif Index: busybox-1.31.1/networking/Kbuild.src =================================================================== --- busybox-1.31.1.orig/networking/Kbuild.src 2019-06-10 18:50:53.000000000 +0800 +++ busybox-1.31.1/networking/Kbuild.src 2021-03-16 14:29:48.169776648 +0800 @@ -7,3 +7,4 @@ lib-y:= INSERT +lib-$(CONFIG_SENDARP) += sendarp.o Index: busybox-1.31.1/networking/sendarp.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ busybox-1.31.1/networking/sendarp.c 2021-03-16 14:35:55.865778425 +0800 @@ -0,0 +1,176 @@ + +//applet:IF_SENDARP(APPLET(sendarp, BB_DIR_USR_BIN, BB_SUID_DROP)) + +#include +#include +#include +#include +#include +#include +#include +#include +#include "busybox.h" + +#define MAC_BCAST_ADDR "\xff\xff\xff\xff\xff\xff" + +#define IFIPADDR 1 +#define IFHWADDR 2 + +struct arpMsg { + struct ethhdr ethhdr; /* Ethernet header */ + u_short htype; /* hardware type (must be ARPHRD_ETHER) */ + u_short ptype; /* protocol type (must be ETH_P_IP) */ + u_char hlen; /* hardware address length (must be 6) */ + u_char plen; /* protocol address length (must be 4) */ + u_short operation; /* ARP opcode */ + u_char sHaddr[6]; /* sender's hardware address */ + u_char sInaddr[4]; /* sender's IP address */ + u_char tHaddr[6]; /* target's hardware address */ + u_char tInaddr[4]; /* target's IP address */ + u_char pad[18]; /* pad for min. Ethernet payload (60 bytes) */ +}; + +/* local prototypes */ +static void sendArp(char *srcDev, char *destDev); +static void mkArpMsg(int opcode, u_long tInaddr, u_char *tHaddr, u_long sInaddr, u_char *sHaddr, struct arpMsg *msg); +static int getDevInfo (char *devname, int infotype, char *data); + +int sendarp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int sendarp_main(int argc, char **argv) +{ + char *srcdev = NULL; + char *dstdev = NULL; + int opt; + + while ((opt = getopt(argc, argv, "s:d:")) != -1) { + switch (opt) { + case 's': + srcdev = xstrdup(optarg); + break; + case 'd': + dstdev = xstrdup(optarg); + break; + } + } + + if ((srcdev == NULL) || (dstdev == NULL)) { + bb_show_usage(); + return 0; + } + + /* send gratutious ARP packet with srcdev's IP and hardware address to dstdev */ + sendArp(srcdev, dstdev); + + return EXIT_SUCCESS; +} + +static void mkArpMsg(int opcode, u_long tInaddr, u_char *tHaddr, + u_long sInaddr, u_char *sHaddr, struct arpMsg *msg) { + u_long *msgsAddr, *msgtAddr; + // tHaddr, sHaddr, msg ? + bzero(msg, sizeof(*msg)); + bcopy(MAC_BCAST_ADDR, msg->ethhdr.h_dest, 6); /* MAC DA */ + bcopy(sHaddr, msg->ethhdr.h_source, 6); /* MAC SA */ + msg->ethhdr.h_proto = htons(ETH_P_ARP); /* protocol type (Ethernet) */ + msg->htype = htons(ARPHRD_ETHER); /* hardware type */ + msg->ptype = htons(ETH_P_IP); /* protocol type (ARP message) */ + msg->hlen = 6; /* hardware address length */ + msg->plen = 4; /* protocol address length */ + msg->operation = htons(opcode); /* ARP op code */ + msgsAddr = (u_long *)msg->sInaddr; + msgtAddr = (u_long *)msg->tInaddr; + //*((u_long *)(msg->sInaddr)) = sInaddr; /* source IP address */ + *msgsAddr = sInaddr; + bcopy(sHaddr, msg->sHaddr, 6); /* source hardware address */ + //*((u_long *)(msg->tInaddr)) = tInaddr; /* target IP address */ + *msgtAddr = tInaddr; + if ( opcode == ARPOP_REPLY ) + bcopy(tHaddr, msg->tHaddr, 6); /* target hardware address */ +} + +static int getDevInfo (char *devname, int infotype, char *data) { + int sock; + struct ifreq ifr; + int rc = 0; + + /* create device level socket */ + if ((sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) + { + perror("cannot open socket "); + return -1; + } + + memset(&ifr, 0, sizeof(struct ifreq)); + strcpy(ifr.ifr_name, devname); + switch(infotype) { + case IFIPADDR: + /* get IP address */ + if (ioctl(sock, SIOCGIFADDR, &ifr) == -1) { + rc = -1; + } else { + memcpy(data, &((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr, sizeof(struct in_addr)); + } + break; + case IFHWADDR: + /* get hardware address */ + if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) { + rc = -1; + } else { + memcpy(data, ifr.ifr_hwaddr.sa_data, ETH_ALEN); + } + break; + default: + rc = -1; + break; + } + close (sock); + return rc; +} + +static void sendArp(char *srcDev, char *destDev) { + int sock; + struct arpMsg arp; + unsigned char br_macaddr[ETH_ALEN]; + unsigned char eth_macaddr[ETH_ALEN]; + unsigned int br_ipAddr; + struct sockaddr_ll sll; + struct ifreq ifr; + int flag; + + if ((getDevInfo(srcDev, IFIPADDR, (char *)&br_ipAddr) == 0) && + (getDevInfo(srcDev, IFHWADDR, (char *)br_macaddr) == 0) && + (getDevInfo(destDev, IFHWADDR, (char *)eth_macaddr) == 0)) { + /* create device level socket */ + if ((sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { + perror("cannot open socket "); + return; + } + + memset(&sll, 0, sizeof(sll)); + sll.sll_family = AF_PACKET; + sll.sll_protocol = htons(ETH_P_ALL); + + /* get interface index number */ + memset(&ifr, 0, sizeof(struct ifreq)); + strcpy(ifr.ifr_name, destDev); + if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) { + perror("SIOCGIFINDEX(): "); + close(sock); + return; + } + sll.sll_ifindex = ifr.ifr_ifindex; + /* bind the socket to the interface */ + if (bind(sock, (struct sockaddr *)&sll, sizeof(sll)) == -1) { + perror("bind(): "); + close(sock); + return; + } + /* set socket to non-blocking operation */ + if ((flag = fcntl(sock, F_GETFL, 0)) >= 0) { + fcntl(sock, F_SETFL, flag | O_NONBLOCK); + } + mkArpMsg(ARPOP_REQUEST, br_ipAddr, NULL, br_ipAddr, br_macaddr, &arp); + sendto(sock, &arp, sizeof(arp), 0, (struct sockaddr *)&sll, sizeof(sll)); + close(sock); + } +} Index: busybox-1.31.1/networking/Config.src =================================================================== --- busybox-1.31.1.orig/networking/Config.src 2021-03-16 14:29:48.125776648 +0800 +++ busybox-1.31.1/networking/Config.src 2021-03-16 14:29:48.169776648 +0800 @@ -55,6 +55,13 @@ config FEATURE_TLS_SHA1 bool "In TLS code, support ciphers which use deprecated SHA1" depends on TLS + +config SENDARP + bool "sendarp" + default y + help + Ping hosts by ARP packets. + default n help Selecting this option increases interoperability with very old