V10/ipc/internet/arp.c
#include <values.h>
#include <stdio.h>
#include <sys/param.h>
#include <sys/filio.h>
#include <sys/inio.h>
#include <sys/enio.h>
#include <sys/inet/in.h>
#include <sys/inet/ip_var.h>
#include <nlist.h>
extern errno;
extern char *optarg;
extern int optind;
extern int ip_ld;
struct nlist nl[] = {
{"_ip_arps", 0},
{"_arpcnt", 0},
{0, 0}
};
#define NL_ARP 0
#define NL_NARP 1
#define MAXARP 512
struct x{
unsigned int inaddr;
unsigned char enaddr[6];
} goo;
struct ip_arp arp[MAXARP];
int kern_fd;
usage()
{
fprintf(stderr, "usage:\tarp hostname\n");
fprintf(stderr, "\tarp -a [unix] [kmem]\n");
fprintf(stderr, "\tarp -d hostname\n");
fprintf(stderr, "\tarp -s hostname ether_addr\n");
exit(1);
}
main(argc, argv)
char *argv[];
{
int c, narp;
int allf;
int deletef;
int setf;
char *xinu;
char *kmem;
allf = deletef = setf = 0;
xinu = "/unix";
kmem = "/dev/kmem";
while((c = getopt(argc, argv, "ads")) != -1) {
switch(c){
case 'a':
allf = 1;
break;
case 'd':
deletef = 1;
break;
case 's':
setf = 1;
break;
default:
usage();
}
}
if(allf+setf+deletef > 1)
usage();
if(allf){
if (argc > optind+1)
xinu = argv[optind++];
if (argc > optind)
kmem = argv[optind];
kern_init(xinu, kmem);
displayall();
} else if(setf){
if(optind != argc-2)
usage();
set(argv[optind], argv[optind+1]);
} else if(deletef){
if(optind != argc-1)
usage();
delete(argv[optind]);
} else {
if(optind >= argc)
usage();
kern_init(xinu, kmem);
narp = readarps();
for(; optind < argc; optind++)
display(narp, argv[optind]);
}
}
etherparse(to, from)
unsigned char *to;
char *from;
{
int tdig;
int fdig;
int i;
if(strlen(from) != 12){
fprintf(stderr, "illegal ether address %s\n", from);
exit(1);
}
for(i = 0; i < 6; i++){
fdig = *from++;
tdig = fdig > 'a' ? (fdig - 'a' + 10)
: (fdig > 'A' ? (fdig - 'A' + 10) : (fdig - '0'));
fdig = *from++;
tdig <<= 4;
tdig |= fdig > 'a' ? (fdig - 'a' + 10)
: (fdig > 'A' ? (fdig - 'A' + 10) : (fdig - '0'));
*to++ = tdig;
}
}
set(host, address)
char* host;
char *address;
{
int pfd[2];
int i;
goo.inaddr = in_address(host);
if(goo.inaddr == 0){
fprintf(stderr, "can't find ip address for %s\n", host);
return;
}
etherparse(goo.enaddr, address);
if(pipe(pfd) < 0){
perror("setting");
exit(1);
}
if(ioctl(pfd[0], FIOPUSHLD, &ip_ld) < 0){
perror("setting");
exit(1);
}
if(ioctl(pfd[0], IPIORESOLVE, &goo) < 0)
perror("can't set ether address");
close(pfd[0]);
close(pfd[1]);
}
delete(host)
char *host;
{
int i;
int pfd[2];
goo.inaddr = in_address(host);
if(goo.inaddr == 0){
fprintf(stderr, "can't find ip address for %s\n", host);
return;
}
if(pipe(pfd) < 0){
perror("setting");
exit(1);
}
if(ioctl(pfd[0], FIOPUSHLD, &ip_ld) < 0){
perror("setting");
exit(1);
}
/*
* this assumes the hashing algorithm is the same as that of
* the system
*/
for(i = 0; i < 256; i++){
goo.inaddr = i;
if(ioctl(pfd[0], IPIORESOLVE, &goo) < 0){
fprintf(stderr, "can't delete ether address for %s\n", host);
break;
}
}
close(pfd[0]);
close(pfd[1]);
}
kern_init(xinu, kmem)
char *xinu, *kmem;
{
int i;
nlist(xinu, nl);
if((long)nl[0].n_value == 0){
fprintf(stderr, "nlist %s failed\n", xinu);
exit(1);
}
if(strcmp(kmem, "/dev/kmem") != 0){
for(i = 0; nl[i].n_name; i++){
nl[i].n_value &= 0xffffff;
}
}
kern_fd = open(kmem, 0);
if(kern_fd < 0){
perror(kmem);
exit(1);
}
}
doseek(nlitem)
unsigned int nlitem;
{
if (nl[nlitem].n_value == 0)
return -1;
if(lseek(kern_fd, (long)nl[nlitem].n_value, 0) == -1){
perror("seek");
exit(1);
}
return 0;
}
void
doseekoff(nlitem, offset)
unsigned int nlitem;
unsigned int offset;
{
if(lseek(kern_fd, (long)(nl[nlitem].n_value+offset), 0) == -1){
perror("seek");
exit(1);
}
}
void
doread(addr, size)
char *addr;
unsigned int size;
{
if(read(kern_fd, addr, size) < 0){
perror("read");
exit(1);
}
}
readarps()
{
int narp;
if (doseek(NL_NARP) < 0) {
fprintf(stderr, "Arp not compiled into this kernel\n");
exit(1);
}
doread((char *)&narp, sizeof narp);
if (narp > MAXARP){
fprintf(stderr, "more arps than I can handle\n");
narp = MAXARP;
}
doseek(NL_ARP);
doread((char *)arp, narp*sizeof(struct ip_arp));
return narp;
}
displayall()
{
int narp, i, j;
narp = readarps();
for(i = 0; i < narp; i++){
if(arp[i].inaddr >= MAXARP){
printf("%s %28.28s ", in_ntoa(arp[i].inaddr), in_host(arp[i].inaddr));
for(j = 0; j < 6; j++){
printf("%02x", arp[i].enaddr[j]);
}
printf("\n");
}
}
}
display(narp, host)
int narp;
char *host;
{
int i, j;
goo.inaddr = in_address(host);
if(goo.inaddr == 0){
fprintf(stderr, "can't find ip address for %s\n", host);
return;
}
for(i = 0; i < narp; i++){
if(arp[i].inaddr == goo.inaddr){
printf("%.15s %.28s ", in_ntoa(arp[i].inaddr), in_host(arp[i].inaddr));
for(j = 0; j < 6; j++){
printf("%02x", arp[i].enaddr[j]);
}
printf("\n");
}
}
}