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_ADJTIMEX(APPLET(adjtimex, _BB_DIR_SBIN, _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_ASH(APPLET_NOUSAGE(ash, ash, _BB_DIR_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!) */
#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 */
#undef FALSE
#define FALSE ((int) 0)
@ -426,8 +458,13 @@ extern int bb_test(int argc, char** argv);
int create_icmp_socket(void);
int create_icmp6_socket(void);
/* interface.c */
struct aftype;
struct hwtype;
extern int interface_opt_a;
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

View File

@ -55,6 +55,26 @@
" -x Extract\n" \
" -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 \
"[-fqbDUA] [-c count] [-w timeout] [-i device] [-s sender] target"
#define arping_full_usage \

View File

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

View File

@ -5,6 +5,7 @@
# Licensed under the GPL v2, see the file LICENSE in this tarball.
lib-y:=
lib-$(CONFIG_ARP) += arp.o interface.o
lib-$(CONFIG_ARPING) += arping.o
lib-$(CONFIG_DNSD) += dnsd.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 */
#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. */
static char *INET_sprint(struct sockaddr *sap, int numeric)
{
@ -126,12 +106,66 @@ static char *INET_sprint(struct sockaddr *sap, int numeric)
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 = {
.name = "inet",
.title = "DARPA Internet",
.af = AF_INET,
.alen = 4,
.sprint = INET_sprint,
.input = INET_input,
.fd = -1
};
@ -151,12 +185,37 @@ static char *INET6_sprint(struct sockaddr *sap, int numeric)
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 = {
.name = "inet6",
.title = "IPv6",
.af = AF_INET6,
.alen = sizeof(struct in6_addr),
.sprint = INET6_sprint,
.input = INET6_input,
.fd = -1
};
@ -205,6 +264,20 @@ static struct aftype * const aftypes[] = {
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. */
static struct aftype *get_afntype(int af)
{
@ -714,18 +787,6 @@ static int do_if_fetch(struct interface *ife)
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 = {
.name = "unspec",
.title = "UNSPEC",
@ -759,14 +820,69 @@ static char *pr_ether(unsigned char *ptr)
return buff;
}
static const struct hwtype ether_hwtype = {
static int in_ether(char *bufp, struct sockaddr *sap);
static struct hwtype ether_hwtype = {
.name = "ether",
.title = "Ethernet",
.type = ARPHRD_ETHER,
.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>
static const struct hwtype ppp_hwtype = {
@ -811,7 +927,21 @@ static const char * const if_port_text[] = {
#endif
/* 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;