From: Philip Homburg Date: Tue, 8 Nov 2005 12:09:00 +0000 (+0000) Subject: ARP command. X-Git-Tag: v3.1.2a~514 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/named.html?a=commitdiff_plain;h=3a0af50c80e8e82efcc28f4d4b0cd034469db512;p=minix.git ARP command. --- diff --git a/commands/simple/Makefile b/commands/simple/Makefile index d59761e91..4b5da6a6e 100755 --- a/commands/simple/Makefile +++ b/commands/simple/Makefile @@ -40,6 +40,7 @@ CC = exec cc ALL = \ add_route \ + arp \ at \ backup \ badblocks \ @@ -210,6 +211,10 @@ add_route: add_route.c $(CCLD) -o $@ add_route.c @install -S 4kw $@ +arp: arp.c + $(CCLD) -o $@ arp.c + @install -S 4kw $@ + at: at.c $(CCLD) -o $@ $? @install -S 4kw $@ @@ -859,6 +864,7 @@ yes: yes.c install: \ /usr/bin/add_route \ /usr/bin/del_route \ + /usr/bin/arp \ /usr/bin/at \ /usr/bin/backup \ /usr/bin/restore \ @@ -1067,6 +1073,9 @@ install: \ /usr/bin/del_route: /usr/bin/add_route install -l $? $@ +/usr/bin/arp: arp + install -cs -o root -m 4755 $? $@ + /usr/bin/at: at install -cs -o root -m 4755 $? $@ diff --git a/commands/simple/arp.c b/commands/simple/arp.c new file mode 100644 index 000000000..aef07c26f --- /dev/null +++ b/commands/simple/arp.c @@ -0,0 +1,473 @@ +/* +arp.c + +Created: Jan 2001 by Philip Homburg + +Manipulate ARP table +*/ + +#define _POSIX_C_SOURCE 2 +#define _MINIX_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +char *progname; +static int ipfd= -1; +static int do_setuid= 0; + +static void do_open(char *devname); +static void show_one(char *hostname, int do_num); +static void show_all(int do_num); +static void print_one(ipaddr_t ipaddr, nwio_arp_t *arpp, int do_num); +static void delete_all(void); +static void delete(char *hostname); +static void do_set(char *hostname, char *ethername, int temp, int pub, + int optdelete); +static ipaddr_t nametoipaddr(char *hostname); +static void fatal(char *fmt, ...); +static void usage(void); + +int main(int argc, char *argv[]) +{ + int c; + char *hostname, *ethername; + int do_temp, do_pub; + int a_flag, d_flag, n_flag, s_flag, S_flag; + char *I_arg; + + (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]); + + a_flag= d_flag= n_flag= s_flag= S_flag= 0; + I_arg= NULL; + while(c= getopt(argc, argv, "adnsS?I:"), c != -1) + { + switch(c) + { + case '?': usage(); + case 'a': a_flag= 1; break; + case 'd': d_flag= 1; break; + case 'n': n_flag= 1; break; + case 's': s_flag= 1; break; + case 'S': S_flag= 1; break; + case 'I': I_arg= optarg; break; + default: fatal("getopt failed: '%c'", c); + } + } + + hostname= NULL; /* lint */ + ethername= NULL; /* lint */ + do_temp= do_pub= 0; /* lint */ + + if (n_flag + d_flag + s_flag + S_flag > 1) + usage(); + if (s_flag || S_flag) + { + if (optind >= argc) usage(); + hostname= argv[optind++]; + + if (optind >= argc) usage(); + ethername= argv[optind++]; + + do_temp= do_pub= 0; + while (optind < argc) + { + if (strcasecmp(argv[optind], "temp") == 0) + { + do_temp= 1; + optind++; + continue; + } + if (strcasecmp(argv[optind], "pub") == 0) + { + do_pub= 1; + optind++; + continue; + } + usage(); + } + } + else if (d_flag) + { + if (!a_flag) + { + if (optind >= argc) + usage(); + hostname= argv[optind++]; + if (optind != argc) + usage(); + } + } + else if (a_flag) + { + if (optind != argc) + usage(); + do_setuid= 1; + } + else + { + if (optind >= argc) + usage(); + hostname= argv[optind++]; + if (optind != argc) + usage(); + do_setuid= 1; + } + + do_open(I_arg); + if (d_flag) + { + if (a_flag) + delete_all(); + else + delete(hostname); + } + else if (s_flag || S_flag) + do_set(hostname, ethername, do_temp, do_pub, S_flag); + else if (a_flag) + show_all(n_flag); + else + show_one(hostname, n_flag); + exit(0); +} + +static void do_open(char *devname) +{ + size_t l; + char *check; + + if (do_setuid && devname) + { + /* Only strings that consist of IP_DEVICE optionally + * followed by a number are allowed. + */ + l= strlen(IP_DEVICE); + if (strncmp(devname, IP_DEVICE, l) != 0) + do_setuid= 0; + else if (strlen(devname) == l) + ; /* OK */ + else + { + strtoul(devname+l, &check, 10); + if (check[0] != '\0') + do_setuid= 0; + } + } + if (!devname) + devname= IP_DEVICE; + if (!do_setuid) + { + setuid(getuid()); + setgid(getgid()); + } + ipfd= open(devname, O_RDWR); + if (ipfd == -1) + fatal("unable to open '%s': %s", devname, strerror(errno)); +} + +static void show_one(char *hostname, int do_num) +{ + int r; + ipaddr_t ipaddr; + nwio_arp_t arp; + + ipaddr= nametoipaddr(hostname); + + arp.nwa_ipaddr= ipaddr; + r= ioctl(ipfd, NWIOARPGIP, &arp); + if (r == -1 && errno == ENOENT) + { + print_one(ipaddr, NULL, do_num); + exit(1); + } + if (r == -1) + fatal("NWIOARPGIP failed: %s", strerror(errno)); + print_one(ipaddr, &arp, do_num); +} + +static void show_all(int do_num) +{ + int ind, max, i, r; + nwio_arp_t *arptab; + nwio_arp_t arp; + + /* First get all entries */ + max= 10; + ind= 0; + arptab= malloc(max * sizeof(*arptab)); + if (arptab == NULL) + { + fatal("out of memory, can't get %d bytes", + max*sizeof(*arptab)); + } + arp.nwa_entno= 0; + for (;;) + { + if (ind == max) + { + max *= 2; + arptab= realloc(arptab, max * sizeof(*arptab)); + if (!arptab) + { + fatal("out of memory, can't get %d bytes", + max*sizeof(*arptab)); + } + } + r= ioctl(ipfd, NWIOARPGNEXT, &arp); + if (r == -1 && errno == ENOENT) + break; + if (r == -1) + fatal("NWIOARPGNEXT failed: %s", strerror(errno)); + arptab[ind]= arp; + ind++; + } + + for (i= 0; inwa_ipaddr; + if (!do_num) + he= gethostbyaddr((char *)&ipaddr, sizeof(ipaddr), AF_INET); + else + he= NULL; + if (he) + printf("%s (%s)", he->h_name, inet_ntoa(ipaddr)); + else + printf("%s", inet_ntoa(ipaddr)); + if (!arpp) + { + printf(" -- no entry\n"); + return; + } + flags= arpp->nwa_flags; + if (flags & NWAF_INCOMPLETE) + printf(" is incomplete"); + else if (flags & NWAF_DEAD) + printf(" is dead"); + else + { + printf(" is at %s", ether_ntoa(&arpp->nwa_ethaddr)); + if (flags & NWAF_PERM) + printf(" permanent"); + if (flags & NWAF_PUB) + printf(" published"); + } + printf("\n"); +} + +static void delete_all(void) +{ + int ind, max, i, r; + nwio_arp_t *arptab; + nwio_arp_t arp; + + /* First get all entries */ + max= 10; + ind= 0; + arptab= malloc(max * sizeof(*arptab)); + if (arptab == NULL) + { + fatal("out of memory, can't get %d bytes", + max*sizeof(*arptab)); + } + arp.nwa_entno= 0; + for (;;) + { + if (ind == max) + { + max *= 2; + arptab= realloc(arptab, max * sizeof(*arptab)); + if (arptab == NULL) + { + fatal("out of memory, can't get %d bytes", + max*sizeof(*arptab)); + } + } + r= ioctl(ipfd, NWIOARPGNEXT, &arp); + if (r == -1 && errno == ENOENT) + break; + if (r == -1) + fatal("NWIOARPGNEXT failed: %s", strerror(errno)); + arptab[ind]= arp; + ind++; + } + + for (i= 0; ih_addrtype != AF_INET || + he->h_length != sizeof(ipaddr)) + { + fatal("strange host '%s': addrtype %d, length %d", + he->h_addrtype, he->h_length); + } + memcpy(&ipaddr, he->h_addr, sizeof(ipaddr)); + } + return ipaddr; +} + +#if 0 +static char *ether_ntoa(struct ether_addr *eap) +{ + static char buf[]= "xx:xx:xx:xx:xx:xx"; + + sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", + eap->ea_addr[0], eap->ea_addr[1], + eap->ea_addr[2], eap->ea_addr[3], + eap->ea_addr[4], eap->ea_addr[5]); + return buf; +} +#endif + +static void fatal(char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprintf(stderr, "%s: ", progname); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + + exit(1); +} + +static void usage(void) +{ + fprintf(stderr, "Usage:\tarp [-I ip-dev] [-n] hostname\n" + "\tarp [-I ip-dev] [-n] -a\n" + "\tarp [-I ip-dev] -d hostname\n" + "\tarp [-I ip-dev] -d -a\n" + "\tarp [-I ip-dev] -s hostname ether-addr [temp] [pub]\n" + "\tarp [-I ip-dev] -S hostname ether-addr [temp] [pub]\n"); + exit(1); +} + +/* + * $PchId: arp.c,v 1.3 2005/01/31 22:31:45 philip Exp $ + */