diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-07 01:24:12 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-07 01:24:12 +0000 |
commit | fa85b86f388fb037b67fa7fcc3b5502c8d0fa84a (patch) | |
tree | 0d2f47866709f0a555d28166b4aeca04dfb7808c /networking | |
parent | b05955e0a5aa5c16ef9460cf4bfed1ee589f5f64 (diff) | |
download | busybox-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>
Diffstat (limited to 'networking')
-rw-r--r-- | networking/Config.in | 6 | ||||
-rw-r--r-- | networking/Kbuild | 1 | ||||
-rw-r--r-- | networking/interface.c | 200 |
3 files changed, 172 insertions, 35 deletions
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 | ||
15 | config ARP | ||
16 | bool "arp" | ||
17 | default n | ||
18 | help | ||
19 | Manipulate the system ARP cache | ||
20 | |||
15 | config ARPING | 21 | config 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 | ||
7 | lib-y:= | 7 | lib-y:= |
8 | lib-$(CONFIG_ARP) += arp.o interface.o | ||
8 | lib-$(CONFIG_ARPING) += arping.o | 9 | lib-$(CONFIG_ARPING) += arping.o |
9 | lib-$(CONFIG_DNSD) += dnsd.o | 10 | lib-$(CONFIG_DNSD) += dnsd.o |
10 | lib-$(CONFIG_ETHER_WAKE) += ether-wake.o | 11 | lib-$(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. */ | ||
95 | struct 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. */ |
115 | static char *INET_sprint(struct sockaddr *sap, int numeric) | 95 | static 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 | ||
109 | static 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 | |||
150 | static 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 | |||
129 | static struct aftype inet_aftype = { | 162 | static 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 | ||
188 | static 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 | |||
202 | static 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 | |||
154 | static struct aftype inet6_aftype = { | 212 | static 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. */ |
268 | struct 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. */ | ||
209 | static struct aftype *get_afntype(int af) | 282 | static 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. */ | ||
718 | struct 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 | |||
729 | static const struct hwtype unspec_hwtype = { | 790 | static 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 | ||
762 | static const struct hwtype ether_hwtype = { | 823 | static int in_ether(char *bufp, struct sockaddr *sap); |
824 | |||
825 | static 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 | ||
834 | static 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. */ | ||
845 | static 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 | ||
772 | static const struct hwtype ppp_hwtype = { | 888 | static 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. */ |
814 | static const struct hwtype *get_hwntype(int type) | 930 | const 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. */ | ||
944 | const struct hwtype *get_hwntype(int type) | ||
815 | { | 945 | { |
816 | const struct hwtype * const *hwp; | 946 | const struct hwtype * const *hwp; |
817 | 947 | ||