add arp applet - thanks to

"Eric Spakman" <E.Spakman@inter.nl.net>
This commit is contained in:
Denis Vlasenko 2007-01-07 01:24:12 +00:00
parent b05955e0a5
commit fa85b86f38
6 changed files with 230 additions and 35 deletions

View File

@ -56,6 +56,7 @@ USE_ADDGROUP(APPLET(addgroup, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_ADDUSER(APPLET(adduser, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_ADDUSER(APPLET(adduser, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_ADJTIMEX(APPLET(adjtimex, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_ADJTIMEX(APPLET(adjtimex, _BB_DIR_SBIN, _BB_SUID_NEVER))
USE_AR(APPLET(ar, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) USE_AR(APPLET(ar, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
USE_ARP(APPLET(arp, _BB_DIR_SBIN, _BB_SUID_NEVER))
USE_ARPING(APPLET(arping, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) USE_ARPING(APPLET(arping, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
USE_ASH(APPLET_NOUSAGE(ash, ash, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_ASH(APPLET_NOUSAGE(ash, ash, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_AWK(APPLET(awk, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) USE_AWK(APPLET(awk, _BB_DIR_USR_BIN, _BB_SUID_NEVER))

View File

@ -121,6 +121,38 @@
/* scary. better ideas? (but do *test* them first!) */ /* scary. better ideas? (but do *test* them first!) */
#define OFF_T_MAX ((off_t)~((off_t)1 << (sizeof(off_t)*8-1))) #define OFF_T_MAX ((off_t)~((off_t)1 << (sizeof(off_t)*8-1)))
/* This structure defines protocol families and their handlers. */
struct aftype {
char *name;
char *title;
int af;
int alen;
char *(*print) (unsigned char *);
char *(*sprint) (struct sockaddr *, int numeric);
int (*input) (int type, char *bufp, struct sockaddr *);
void (*herror) (char *text);
int (*rprint) (int options);
int (*rinput) (int typ, int ext, char **argv);
/* may modify src */
int (*getmask) (char *src, struct sockaddr * mask, char *name);
int fd;
char *flag_file;
};
/* This structure defines hardware protocols and their handlers. */
struct hwtype {
char *name;
char *title;
int type;
int alen;
char *(*print) (unsigned char *);
int (*input) (char *, struct sockaddr *);
int (*activate) (int fd);
int suppress_null_addr;
};
/* Some useful definitions */ /* Some useful definitions */
#undef FALSE #undef FALSE
#define FALSE ((int) 0) #define FALSE ((int) 0)
@ -426,8 +458,13 @@ extern int bb_test(int argc, char** argv);
int create_icmp_socket(void); int create_icmp_socket(void);
int create_icmp6_socket(void); int create_icmp6_socket(void);
/* interface.c */ /* interface.c */
struct aftype;
struct hwtype;
extern int interface_opt_a; extern int interface_opt_a;
int display_interfaces(char *ifname); int display_interfaces(char *ifname);
struct aftype *get_aftype(const char *name);
const struct hwtype *get_hwtype(const char *name);
const struct hwtype *get_hwntype(int type);
#ifndef BUILD_INDIVIDUAL #ifndef BUILD_INDIVIDUAL

View File

@ -55,6 +55,26 @@
" -x Extract\n" \ " -x Extract\n" \
" -v Verbosely list files processed" " -v Verbosely list files processed"
#define arp_trivial_usage \
"\n" \
"[-vn] [-H type] [-i if] -a [hostname]\n" \
"[-v] [-i if] -d hostname [pub]\n" \
"[-v] [-H type] [-i if] -s hostname hw_addr [temp]\n" \
"[-v] [-H type] [-i if] -s hostname hw_addr [netmask nm] pub\n" \
"[-v] [-H type] [-i if] -Ds hostname ifa [netmask nm] pub\n"
#define arp_full_usage \
"Manipulate the system ARP cache" \
"\n\nOptions:" \
"\n -a Display (all) hosts" \
"\n -s Set a new ARP entry" \
"\n -d Delete a specified entry" \
"\n -v Verbose" \
"\n -n Don't resolve names" \
"\n -i if Specify network interface (e.g. eth0)" \
"\n -D Read <hwaddr> from given device" \
"\n -A, -p Specify protocol family" \
"\n -H hwtype Specify hardware address type"
#define arping_trivial_usage \ #define arping_trivial_usage \
"[-fqbDUA] [-c count] [-w timeout] [-i device] [-s sender] target" "[-fqbDUA] [-c count] [-w timeout] [-i device] [-s sender] target"
#define arping_full_usage \ #define arping_full_usage \

View File

@ -12,6 +12,12 @@ config FEATURE_IPV6
Enable IPv6 support in busybox. Enable IPv6 support in busybox.
This adds IPv6 support in the networking applets. This adds IPv6 support in the networking applets.
config ARP
bool "arp"
default n
help
Manipulate the system ARP cache
config ARPING config ARPING
bool "arping" bool "arping"
default n default n

View File

@ -5,6 +5,7 @@
# Licensed under the GPL v2, see the file LICENSE in this tarball. # Licensed under the GPL v2, see the file LICENSE in this tarball.
lib-y:= lib-y:=
lib-$(CONFIG_ARP) += arp.o interface.o
lib-$(CONFIG_ARPING) += arping.o lib-$(CONFIG_ARPING) += arping.o
lib-$(CONFIG_DNSD) += dnsd.o lib-$(CONFIG_DNSD) += dnsd.o
lib-$(CONFIG_ETHER_WAKE) += ether-wake.o lib-$(CONFIG_ETHER_WAKE) += ether-wake.o

View File

@ -91,26 +91,6 @@ struct in6_ifreq {
#define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses */ #define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses */
#endif #endif
/* This structure defines protocol families and their handlers. */
struct aftype {
const char *name;
const char *title;
int af;
int alen;
char *(*print) (unsigned char *);
char *(*sprint) (struct sockaddr *, int numeric);
int (*input) (int type, char *bufp, struct sockaddr *);
void (*herror) (char *text);
int (*rprint) (int options);
int (*rinput) (int typ, int ext, char **argv);
/* may modify src */
int (*getmask) (char *src, struct sockaddr * mask, char *name);
int fd;
char *flag_file;
};
/* Display an Internet socket address. */ /* Display an Internet socket address. */
static char *INET_sprint(struct sockaddr *sap, int numeric) static char *INET_sprint(struct sockaddr *sap, int numeric)
{ {
@ -126,12 +106,66 @@ static char *INET_sprint(struct sockaddr *sap, int numeric)
return buff; return buff;
} }
static int INET_getsock(char *bufp, struct sockaddr *sap)
{
char *sp = bufp, *bp;
unsigned int i;
unsigned val;
struct sockaddr_in *sock_in;
sock_in = (struct sockaddr_in *) sap;
sock_in->sin_family = AF_INET;
sock_in->sin_port = 0;
val = 0;
bp = (char *) &val;
for (i = 0; i < sizeof(sock_in->sin_addr.s_addr); i++) {
*sp = toupper(*sp);
if ((unsigned)(*sp - 'A') <= 5)
bp[i] |= (int) (*sp - ('A' - 10));
else if (isdigit(*sp))
bp[i] |= (int) (*sp - '0');
else
return -1;
bp[i] <<= 4;
sp++;
*sp = toupper(*sp);
if ((unsigned)(*sp - 'A') <= 5)
bp[i] |= (int) (*sp - ('A' - 10));
else if (isdigit(*sp))
bp[i] |= (int) (*sp - '0');
else
return -1;
sp++;
}
sock_in->sin_addr.s_addr = htonl(val);
return (sp - bufp);
}
static int INET_input(int type, char *bufp, struct sockaddr *sap)
{
switch (type) {
case 1:
return (INET_getsock(bufp, sap));
case 256:
return (INET_resolve(bufp, (struct sockaddr_in *) sap, 1));
default:
return (INET_resolve(bufp, (struct sockaddr_in *) sap, 0));
}
}
static struct aftype inet_aftype = { static struct aftype inet_aftype = {
.name = "inet", .name = "inet",
.title = "DARPA Internet", .title = "DARPA Internet",
.af = AF_INET, .af = AF_INET,
.alen = 4, .alen = 4,
.sprint = INET_sprint, .sprint = INET_sprint,
.input = INET_input,
.fd = -1 .fd = -1
}; };
@ -151,12 +185,37 @@ static char *INET6_sprint(struct sockaddr *sap, int numeric)
return buff; return buff;
} }
static int INET6_getsock(char *bufp, struct sockaddr *sap)
{
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *) sap;
sin6->sin6_family = AF_INET6;
sin6->sin6_port = 0;
if (inet_pton(AF_INET6, bufp, sin6->sin6_addr.s6_addr) <= 0)
return -1;
return 16; /* ?;) */
}
static int INET6_input(int type, char *bufp, struct sockaddr *sap)
{
switch (type) {
case 1:
return (INET6_getsock(bufp, sap));
default:
return (INET6_resolve(bufp, (struct sockaddr_in6 *) sap));
}
}
static struct aftype inet6_aftype = { static struct aftype inet6_aftype = {
.name = "inet6", .name = "inet6",
.title = "IPv6", .title = "IPv6",
.af = AF_INET6, .af = AF_INET6,
.alen = sizeof(struct in6_addr), .alen = sizeof(struct in6_addr),
.sprint = INET6_sprint, .sprint = INET6_sprint,
.input = INET6_input,
.fd = -1 .fd = -1
}; };
@ -205,6 +264,20 @@ static struct aftype * const aftypes[] = {
NULL NULL
}; };
/* Check our protocol family table for this family. */
struct aftype *get_aftype(const char *name)
{
struct aftype * const *afp;
afp = aftypes;
while (*afp != NULL) {
if (!strcmp((*afp)->name, name))
return (*afp);
afp++;
}
return NULL;
}
/* Check our protocol family table for this family. */ /* Check our protocol family table for this family. */
static struct aftype *get_afntype(int af) static struct aftype *get_afntype(int af)
{ {
@ -714,18 +787,6 @@ static int do_if_fetch(struct interface *ife)
return 0; return 0;
} }
/* This structure defines hardware protocols and their handlers. */
struct hwtype {
const char * const name;
const char *title;
int type;
int alen;
char *(*print) (unsigned char *);
int (*input) (char *, struct sockaddr *);
int (*activate) (int fd);
int suppress_null_addr;
};
static const struct hwtype unspec_hwtype = { static const struct hwtype unspec_hwtype = {
.name = "unspec", .name = "unspec",
.title = "UNSPEC", .title = "UNSPEC",
@ -759,14 +820,69 @@ static char *pr_ether(unsigned char *ptr)
return buff; return buff;
} }
static const struct hwtype ether_hwtype = { static int in_ether(char *bufp, struct sockaddr *sap);
static struct hwtype ether_hwtype = {
.name = "ether", .name = "ether",
.title = "Ethernet", .title = "Ethernet",
.type = ARPHRD_ETHER, .type = ARPHRD_ETHER,
.alen = ETH_ALEN, .alen = ETH_ALEN,
.print = pr_ether .print = pr_ether,
.input = in_ether
}; };
static unsigned hexchar2int(char c)
{
if (isdigit(c))
return c - '0';
c &= ~0x20; /* a -> A */
if ((unsigned)(c - 'A') <= 5)
return c - ('A' - 10);
return ~0U;
}
/* Input an Ethernet address and convert to binary. */
static int in_ether(char *bufp, struct sockaddr *sap)
{
unsigned char *ptr;
char c, *orig;
int i;
unsigned val;
sap->sa_family = ether_hwtype.type;
ptr = sap->sa_data;
i = 0;
orig = bufp;
while ((*bufp != '\0') && (i < ETH_ALEN)) {
val = hexchar2int(*bufp++) * 0x10;
if (val > 0xff) {
errno = EINVAL;
return -1;
}
c = *bufp;
if (c == ':' || c == 0)
val >>= 4;
else {
val |= hexchar2int(c);
if (val > 0xff) {
errno = EINVAL;
return -1;
}
}
if (c != 0)
bufp++;
*ptr++ = (unsigned char) val;
i++;
/* We might get a semicolon here - not required. */
if (*bufp == ':') {
bufp++;
}
}
return 0;
}
#include <net/if_arp.h> #include <net/if_arp.h>
static const struct hwtype ppp_hwtype = { static const struct hwtype ppp_hwtype = {
@ -811,7 +927,21 @@ static const char * const if_port_text[] = {
#endif #endif
/* Check our hardware type table for this type. */ /* Check our hardware type table for this type. */
static const struct hwtype *get_hwntype(int type) const struct hwtype *get_hwtype(const char *name)
{
const struct hwtype * const *hwp;
hwp = hwtypes;
while (*hwp != NULL) {
if (!strcmp((*hwp)->name, name))
return (*hwp);
hwp++;
}
return NULL;
}
/* Check our hardware type table for this type. */
const struct hwtype *get_hwntype(int type)
{ {
const struct hwtype * const *hwp; const struct hwtype * const *hwp;