--- a/package/busybox/0007-brcma9-sendarp.patch 2017-03-06 08:59:36.451053116 +0100 +++ b/package/busybox/0007-brcma9-sendarp.patch 2017-03-08 11:18:46.508543709 +0100 @@ -0,0 +1,224 @@ +diff -Naur busybox_original/include/applets.src.h busybox_sendarp/include/applets.src.h +--- busybox_original/include/applets.src.h 2010-08-23 02:44:35.000000000 +0200 ++++ busybox_sendarp/include/applets.src.h 2016-02-08 18:55:44.830331585 +0100 +@@ -80,6 +80,9 @@ + IF_ADDUSER(APPLET(adduser, BB_DIR_USR_SBIN, BB_SUID_DROP)) + IF_ADJTIMEX(APPLET(adjtimex, BB_DIR_SBIN, BB_SUID_DROP)) + IF_ARP(APPLET(arp, BB_DIR_SBIN, BB_SUID_DROP)) ++// brcm begin ++IF_SENDARP(APPLET(sendarp, BB_DIR_USR_SBIN, BB_SUID_DROP)) ++// brcm end + IF_ARPING(APPLET(arping, BB_DIR_USR_SBIN, BB_SUID_DROP)) + IF_BASENAME(APPLET_NOFORK(basename, basename, BB_DIR_USR_BIN, BB_SUID_DROP, basename)) + IF_BBCONFIG(APPLET(bbconfig, BB_DIR_BIN, BB_SUID_DROP)) +diff -Naur busybox_original/networking/Config.src busybox_sendarp/networking/Config.src +--- busybox_original/networking/Config.src 2010-08-23 02:44:35.000000000 +0200 ++++ busybox_sendarp/networking/Config.src 2016-02-08 18:58:20.138330504 +0100 +@@ -60,6 +60,14 @@ + help + Ping hosts by ARP packets. + ++# brcm begin ++config SENDARP ++ bool "sendarp" ++ default y ++ help ++ Ping hosts by ARP packets. ++# brcm end ++ + config BRCTL + bool "brctl" + default y +diff -Naur busybox_original/networking/Kbuild.src busybox_sendarp/networking/Kbuild.src +--- busybox_original/networking/Kbuild.src 2010-08-23 02:44:35.000000000 +0200 ++++ busybox_sendarp/networking/Kbuild.src 2016-02-08 18:58:27.298330454 +0100 +@@ -9,6 +9,9 @@ + INSERT + lib-$(CONFIG_ARP) += arp.o interface.o + lib-$(CONFIG_ARPING) += arping.o ++# brcm begin ++lib-$(CONFIG_SENDARP) += sendarp.o ++# brcm end + lib-$(CONFIG_BRCTL) += brctl.o + lib-$(CONFIG_DNSD) += dnsd.o + lib-$(CONFIG_ETHER_WAKE) += ether-wake.o +diff -Naur busybox_original/networking/sendarp.c busybox_sendarp/networking/sendarp.c +--- busybox_original/networking/sendarp.c 1970-01-01 01:00:00.000000000 +0100 ++++ busybox_sendarp/networking/sendarp.c 2015-11-05 11:54:35.178421000 +0100 +@@ -0,0 +1,176 @@ ++#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) { ++ 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 */ ++//brcm start ++ bcopy((u_char *)&sInaddr, &msg->sInaddr[0], 4); /* source IP address */ ++ bcopy(sHaddr, msg->sHaddr, 6); /* source hardware address */ ++ bcopy((u_char *)&tInaddr, &msg->tInaddr[0], 4); /* target IP address */ ++//brcm end ++ 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; ++} ++ ++//usage:#define sendarp_trivial_usage ++//usage: "-s -d " ++//usage:#define sendarp_full_usage "\n\n" ++//usage: "Send ARP packet with src device's IP and Hardware address to dst device.\n" ++//usage: "\nOptions:" ++//usage: "\n -s DEVNAME src device name." ++//usage: "\n -d DEVNAME dst device name." ++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); ++ } ++}