aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-07 01:24:12 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-07 01:24:12 +0000
commitfa85b86f388fb037b67fa7fcc3b5502c8d0fa84a (patch)
tree0d2f47866709f0a555d28166b4aeca04dfb7808c
parentb05955e0a5aa5c16ef9460cf4bfed1ee589f5f64 (diff)
downloadbusybox-w32-fa85b86f388fb037b67fa7fcc3b5502c8d0fa84a.tar.gz
busybox-w32-fa85b86f388fb037b67fa7fcc3b5502c8d0fa84a.tar.bz2
busybox-w32-fa85b86f388fb037b67fa7fcc3b5502c8d0fa84a.zip
add arp applet - thanks to
"Eric Spakman" <E.Spakman@inter.nl.net>
-rw-r--r--include/applets.h1
-rw-r--r--include/libbb.h37
-rw-r--r--include/usage.h20
-rw-r--r--networking/Config.in6
-rw-r--r--networking/Kbuild1
-rw-r--r--networking/interface.c200
6 files changed, 230 insertions, 35 deletions
diff --git a/include/applets.h b/include/applets.h
index 8586ffc86..465ecdbdd 100644
--- a/include/applets.h
+++ b/include/applets.h
@@ -56,6 +56,7 @@ USE_ADDGROUP(APPLET(addgroup, _BB_DIR_BIN, _BB_SUID_NEVER))
56USE_ADDUSER(APPLET(adduser, _BB_DIR_BIN, _BB_SUID_NEVER)) 56USE_ADDUSER(APPLET(adduser, _BB_DIR_BIN, _BB_SUID_NEVER))
57USE_ADJTIMEX(APPLET(adjtimex, _BB_DIR_SBIN, _BB_SUID_NEVER)) 57USE_ADJTIMEX(APPLET(adjtimex, _BB_DIR_SBIN, _BB_SUID_NEVER))
58USE_AR(APPLET(ar, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) 58USE_AR(APPLET(ar, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
59USE_ARP(APPLET(arp, _BB_DIR_SBIN, _BB_SUID_NEVER))
59USE_ARPING(APPLET(arping, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) 60USE_ARPING(APPLET(arping, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
60USE_ASH(APPLET_NOUSAGE(ash, ash, _BB_DIR_BIN, _BB_SUID_NEVER)) 61USE_ASH(APPLET_NOUSAGE(ash, ash, _BB_DIR_BIN, _BB_SUID_NEVER))
61USE_AWK(APPLET(awk, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) 62USE_AWK(APPLET(awk, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
diff --git a/include/libbb.h b/include/libbb.h
index e92e4db1c..6f66c8545 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -121,6 +121,38 @@
121/* scary. better ideas? (but do *test* them first!) */ 121/* scary. better ideas? (but do *test* them first!) */
122#define OFF_T_MAX ((off_t)~((off_t)1 << (sizeof(off_t)*8-1))) 122#define OFF_T_MAX ((off_t)~((off_t)1 << (sizeof(off_t)*8-1)))
123 123
124/* This structure defines protocol families and their handlers. */
125struct aftype {
126 char *name;
127 char *title;
128 int af;
129 int alen;
130 char *(*print) (unsigned char *);
131 char *(*sprint) (struct sockaddr *, int numeric);
132 int (*input) (int type, char *bufp, struct sockaddr *);
133 void (*herror) (char *text);
134 int (*rprint) (int options);
135 int (*rinput) (int typ, int ext, char **argv);
136
137 /* may modify src */
138 int (*getmask) (char *src, struct sockaddr * mask, char *name);
139
140 int fd;
141 char *flag_file;
142};
143
144/* This structure defines hardware protocols and their handlers. */
145struct hwtype {
146 char *name;
147 char *title;
148 int type;
149 int alen;
150 char *(*print) (unsigned char *);
151 int (*input) (char *, struct sockaddr *);
152 int (*activate) (int fd);
153 int suppress_null_addr;
154};
155
124/* Some useful definitions */ 156/* Some useful definitions */
125#undef FALSE 157#undef FALSE
126#define FALSE ((int) 0) 158#define FALSE ((int) 0)
@@ -426,8 +458,13 @@ extern int bb_test(int argc, char** argv);
426int create_icmp_socket(void); 458int create_icmp_socket(void);
427int create_icmp6_socket(void); 459int create_icmp6_socket(void);
428/* interface.c */ 460/* interface.c */
461struct aftype;
462struct hwtype;
429extern int interface_opt_a; 463extern int interface_opt_a;
430int display_interfaces(char *ifname); 464int display_interfaces(char *ifname);
465struct aftype *get_aftype(const char *name);
466const struct hwtype *get_hwtype(const char *name);
467const struct hwtype *get_hwntype(int type);
431 468
432 469
433#ifndef BUILD_INDIVIDUAL 470#ifndef BUILD_INDIVIDUAL
diff --git a/include/usage.h b/include/usage.h
index ae03d5431..cfae4e1e1 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -55,6 +55,26 @@
55 " -x Extract\n" \ 55 " -x Extract\n" \
56 " -v Verbosely list files processed" 56 " -v Verbosely list files processed"
57 57
58#define arp_trivial_usage \
59 "\n" \
60 "[-vn] [-H type] [-i if] -a [hostname]\n" \
61 "[-v] [-i if] -d hostname [pub]\n" \
62 "[-v] [-H type] [-i if] -s hostname hw_addr [temp]\n" \
63 "[-v] [-H type] [-i if] -s hostname hw_addr [netmask nm] pub\n" \
64 "[-v] [-H type] [-i if] -Ds hostname ifa [netmask nm] pub\n"
65#define arp_full_usage \
66 "Manipulate the system ARP cache" \
67 "\n\nOptions:" \
68 "\n -a Display (all) hosts" \
69 "\n -s Set a new ARP entry" \
70 "\n -d Delete a specified entry" \
71 "\n -v Verbose" \
72 "\n -n Don't resolve names" \
73 "\n -i if Specify network interface (e.g. eth0)" \
74 "\n -D Read <hwaddr> from given device" \
75 "\n -A, -p Specify protocol family" \
76 "\n -H hwtype Specify hardware address type"
77
58#define arping_trivial_usage \ 78#define arping_trivial_usage \
59 "[-fqbDUA] [-c count] [-w timeout] [-i device] [-s sender] target" 79 "[-fqbDUA] [-c count] [-w timeout] [-i device] [-s sender] target"
60#define arping_full_usage \ 80#define arping_full_usage \
diff --git a/networking/Config.in b/networking/Config.in
index b2d973f0c..88ccb16ab 100644
--- a/networking/Config.in
+++ b/networking/Config.in
@@ -12,6 +12,12 @@ config FEATURE_IPV6
12 Enable IPv6 support in busybox. 12 Enable IPv6 support in busybox.
13 This adds IPv6 support in the networking applets. 13 This adds IPv6 support in the networking applets.
14 14
15config ARP
16 bool "arp"
17 default n
18 help
19 Manipulate the system ARP cache
20
15config ARPING 21config ARPING
16 bool "arping" 22 bool "arping"
17 default n 23 default n
diff --git a/networking/Kbuild b/networking/Kbuild
index a9a51fc2e..4c29e45a8 100644
--- a/networking/Kbuild
+++ b/networking/Kbuild
@@ -5,6 +5,7 @@
5# Licensed under the GPL v2, see the file LICENSE in this tarball. 5# Licensed under the GPL v2, see the file LICENSE in this tarball.
6 6
7lib-y:= 7lib-y:=
8lib-$(CONFIG_ARP) += arp.o interface.o
8lib-$(CONFIG_ARPING) += arping.o 9lib-$(CONFIG_ARPING) += arping.o
9lib-$(CONFIG_DNSD) += dnsd.o 10lib-$(CONFIG_DNSD) += dnsd.o
10lib-$(CONFIG_ETHER_WAKE) += ether-wake.o 11lib-$(CONFIG_ETHER_WAKE) += ether-wake.o
diff --git a/networking/interface.c b/networking/interface.c
index b39298cfe..6d23e9bfc 100644
--- a/networking/interface.c
+++ b/networking/interface.c
@@ -91,26 +91,6 @@ struct in6_ifreq {
91#define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses */ 91#define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses */
92#endif 92#endif
93 93
94/* This structure defines protocol families and their handlers. */
95struct aftype {
96 const char *name;
97 const char *title;
98 int af;
99 int alen;
100 char *(*print) (unsigned char *);
101 char *(*sprint) (struct sockaddr *, int numeric);
102 int (*input) (int type, char *bufp, struct sockaddr *);
103 void (*herror) (char *text);
104 int (*rprint) (int options);
105 int (*rinput) (int typ, int ext, char **argv);
106
107 /* may modify src */
108 int (*getmask) (char *src, struct sockaddr * mask, char *name);
109
110 int fd;
111 char *flag_file;
112};
113
114/* Display an Internet socket address. */ 94/* Display an Internet socket address. */
115static char *INET_sprint(struct sockaddr *sap, int numeric) 95static char *INET_sprint(struct sockaddr *sap, int numeric)
116{ 96{
@@ -126,12 +106,66 @@ static char *INET_sprint(struct sockaddr *sap, int numeric)
126 return buff; 106 return buff;
127} 107}
128 108
109static int INET_getsock(char *bufp, struct sockaddr *sap)
110{
111 char *sp = bufp, *bp;
112 unsigned int i;
113 unsigned val;
114 struct sockaddr_in *sock_in;
115
116 sock_in = (struct sockaddr_in *) sap;
117 sock_in->sin_family = AF_INET;
118 sock_in->sin_port = 0;
119
120 val = 0;
121 bp = (char *) &val;
122 for (i = 0; i < sizeof(sock_in->sin_addr.s_addr); i++) {
123 *sp = toupper(*sp);
124
125 if ((unsigned)(*sp - 'A') <= 5)
126 bp[i] |= (int) (*sp - ('A' - 10));
127 else if (isdigit(*sp))
128 bp[i] |= (int) (*sp - '0');
129 else
130 return -1;
131
132 bp[i] <<= 4;
133 sp++;
134 *sp = toupper(*sp);
135
136 if ((unsigned)(*sp - 'A') <= 5)
137 bp[i] |= (int) (*sp - ('A' - 10));
138 else if (isdigit(*sp))
139 bp[i] |= (int) (*sp - '0');
140 else
141 return -1;
142
143 sp++;
144 }
145 sock_in->sin_addr.s_addr = htonl(val);
146
147 return (sp - bufp);
148}
149
150static int INET_input(int type, char *bufp, struct sockaddr *sap)
151{
152 switch (type) {
153 case 1:
154 return (INET_getsock(bufp, sap));
155 case 256:
156 return (INET_resolve(bufp, (struct sockaddr_in *) sap, 1));
157 default:
158 return (INET_resolve(bufp, (struct sockaddr_in *) sap, 0));
159 }
160}
161
129static struct aftype inet_aftype = { 162static struct aftype inet_aftype = {
130 .name = "inet", 163 .name = "inet",
131 .title = "DARPA Internet", 164 .title = "DARPA Internet",
132 .af = AF_INET, 165 .af = AF_INET,
133 .alen = 4, 166 .alen = 4,
134 .sprint = INET_sprint, 167 .sprint = INET_sprint,
168 .input = INET_input,
135 .fd = -1 169 .fd = -1
136}; 170};
137 171
@@ -151,12 +185,37 @@ static char *INET6_sprint(struct sockaddr *sap, int numeric)
151 return buff; 185 return buff;
152} 186}
153 187
188static int INET6_getsock(char *bufp, struct sockaddr *sap)
189{
190 struct sockaddr_in6 *sin6;
191
192 sin6 = (struct sockaddr_in6 *) sap;
193 sin6->sin6_family = AF_INET6;
194 sin6->sin6_port = 0;
195
196 if (inet_pton(AF_INET6, bufp, sin6->sin6_addr.s6_addr) <= 0)
197 return -1;
198
199 return 16; /* ?;) */
200}
201
202static int INET6_input(int type, char *bufp, struct sockaddr *sap)
203{
204 switch (type) {
205 case 1:
206 return (INET6_getsock(bufp, sap));
207 default:
208 return (INET6_resolve(bufp, (struct sockaddr_in6 *) sap));
209 }
210}
211
154static struct aftype inet6_aftype = { 212static struct aftype inet6_aftype = {
155 .name = "inet6", 213 .name = "inet6",
156 .title = "IPv6", 214 .title = "IPv6",
157 .af = AF_INET6, 215 .af = AF_INET6,
158 .alen = sizeof(struct in6_addr), 216 .alen = sizeof(struct in6_addr),
159 .sprint = INET6_sprint, 217 .sprint = INET6_sprint,
218 .input = INET6_input,
160 .fd = -1 219 .fd = -1
161}; 220};
162 221
@@ -206,6 +265,20 @@ static struct aftype * const aftypes[] = {
206}; 265};
207 266
208/* Check our protocol family table for this family. */ 267/* Check our protocol family table for this family. */
268struct aftype *get_aftype(const char *name)
269{
270 struct aftype * const *afp;
271
272 afp = aftypes;
273 while (*afp != NULL) {
274 if (!strcmp((*afp)->name, name))
275 return (*afp);
276 afp++;
277 }
278 return NULL;
279}
280
281/* Check our protocol family table for this family. */
209static struct aftype *get_afntype(int af) 282static struct aftype *get_afntype(int af)
210{ 283{
211 struct aftype * const *afp; 284 struct aftype * const *afp;
@@ -714,18 +787,6 @@ static int do_if_fetch(struct interface *ife)
714 return 0; 787 return 0;
715} 788}
716 789
717/* This structure defines hardware protocols and their handlers. */
718struct hwtype {
719 const char * const name;
720 const char *title;
721 int type;
722 int alen;
723 char *(*print) (unsigned char *);
724 int (*input) (char *, struct sockaddr *);
725 int (*activate) (int fd);
726 int suppress_null_addr;
727};
728
729static const struct hwtype unspec_hwtype = { 790static const struct hwtype unspec_hwtype = {
730 .name = "unspec", 791 .name = "unspec",
731 .title = "UNSPEC", 792 .title = "UNSPEC",
@@ -759,14 +820,69 @@ static char *pr_ether(unsigned char *ptr)
759 return buff; 820 return buff;
760} 821}
761 822
762static const struct hwtype ether_hwtype = { 823static int in_ether(char *bufp, struct sockaddr *sap);
824
825static struct hwtype ether_hwtype = {
763 .name = "ether", 826 .name = "ether",
764 .title = "Ethernet", 827 .title = "Ethernet",
765 .type = ARPHRD_ETHER, 828 .type = ARPHRD_ETHER,
766 .alen = ETH_ALEN, 829 .alen = ETH_ALEN,
767 .print = pr_ether 830 .print = pr_ether,
831 .input = in_ether
768}; 832};
769 833
834static unsigned hexchar2int(char c)
835{
836 if (isdigit(c))
837 return c - '0';
838 c &= ~0x20; /* a -> A */
839 if ((unsigned)(c - 'A') <= 5)
840 return c - ('A' - 10);
841 return ~0U;
842}
843
844/* Input an Ethernet address and convert to binary. */
845static int in_ether(char *bufp, struct sockaddr *sap)
846{
847 unsigned char *ptr;
848 char c, *orig;
849 int i;
850 unsigned val;
851
852 sap->sa_family = ether_hwtype.type;
853 ptr = sap->sa_data;
854
855 i = 0;
856 orig = bufp;
857 while ((*bufp != '\0') && (i < ETH_ALEN)) {
858 val = hexchar2int(*bufp++) * 0x10;
859 if (val > 0xff) {
860 errno = EINVAL;
861 return -1;
862 }
863 c = *bufp;
864 if (c == ':' || c == 0)
865 val >>= 4;
866 else {
867 val |= hexchar2int(c);
868 if (val > 0xff) {
869 errno = EINVAL;
870 return -1;
871 }
872 }
873 if (c != 0)
874 bufp++;
875 *ptr++ = (unsigned char) val;
876 i++;
877
878 /* We might get a semicolon here - not required. */
879 if (*bufp == ':') {
880 bufp++;
881 }
882 }
883 return 0;
884}
885
770#include <net/if_arp.h> 886#include <net/if_arp.h>
771 887
772static const struct hwtype ppp_hwtype = { 888static const struct hwtype ppp_hwtype = {
@@ -811,7 +927,21 @@ static const char * const if_port_text[] = {
811#endif 927#endif
812 928
813/* Check our hardware type table for this type. */ 929/* Check our hardware type table for this type. */
814static const struct hwtype *get_hwntype(int type) 930const struct hwtype *get_hwtype(const char *name)
931{
932 const struct hwtype * const *hwp;
933
934 hwp = hwtypes;
935 while (*hwp != NULL) {
936 if (!strcmp((*hwp)->name, name))
937 return (*hwp);
938 hwp++;
939 }
940 return NULL;
941}
942
943/* Check our hardware type table for this type. */
944const struct hwtype *get_hwntype(int type)
815{ 945{
816 const struct hwtype * const *hwp; 946 const struct hwtype * const *hwp;
817 947