/* 7/29/91 Corrected placement of ifdef NETROM in arpadd() */ /* 11/14/93 Added support for an IP only address - K5JB */ #include "config.h" #if defined(ETHER) || defined(AX25) #include #include "global.h" #include "mbuf.h" #include "timer.h" #ifdef ETHER #include "enet.h" #endif #include "iface.h" #include "ax25.h" #include "arp.h" #include "cmdparse.h" #ifdef VCIP_SSID extern struct ax25_addr ip_call; #endif extern char badhost[]; extern char nospace[]; int doarpadd(),doarpdrop(); struct cmds arpcmds[] = { "add", doarpadd, 4, #ifdef NETROM #ifdef ETHER "arp add ether|ax25|vax25|netrom ", #else "arp add ax25|vax25|netrom ", #endif /* ETHER */ #else /* NETROM */ "arp add ax25|vax25 ", #endif /* NETROM */ "arp add failed", "drop", doarpdrop, 3, #ifdef NETROM #ifdef ETHER "arp drop ether|ax25|netrom|vax25", #else "arp drop ax25|netrom|vax25", #endif /* ETHER */ #else /* NETROM */ "arp drop ax25|vax25", #endif /* NETROM */ "not in table", "publish", doarpadd, 4, #ifdef NETROM #ifdef ETHER "arp publish ether|ax25|netrom|vax25 ", #else "arp publish ax25|netrom|vax25 ", #endif /* ETHER */ #else /* NETROM */ "arp publish ax25|vax25 ", #endif /* NETROM */ "arp publish failed", NULLCHAR, NULLFP, 0, "arp subcommands: add, drop, publish", NULLCHAR }; char *arptypes[] = { /* little bit of wasted space here - K5JB */ "NET/ROM", /* but arp.h would have to be also modified */ "10 Mb Ethernet", "3 Mb Ethernet", "AX.25", "Pronet", "Chaos", "Blank", "Arcnet", "Appletalk", "VAX.25" }; int doarp(argc,argv) int argc; char *argv[]; { int subcmd(),dumparp(); if(argc < 2){ dumparp(); return 0; } return subcmd(arpcmds,argc,argv); } #include static doarpadd(argc,argv) int argc; char *argv[]; { int16 hwalen,hardware,naddr; int32 addr,resolve(); void free(); int stop_timer(); char *hwaddr; struct arp_tab *ap; struct arp_type *at; void arp_drop(); int pub = 0; if(argv[0][0] == 'p') /* Is this entry published? */ pub = 1; if((addr = resolve(argv[1])) == 0){ printf(badhost,argv[1]); return 1; } /* This is a kludge. It really ought to be table driven */ switch(tolower(argv[2][0])){ #ifdef NETROM case 'n': /* Net/Rom pseudo-type */ hardware = ARP_NETROM; naddr = argc - 3 ; if (naddr != 1) { printf( "No digipeaters in NET/ROM arp entries - Use netrom route add\n") ; return 1 ; } break; #endif #ifdef ETHER case 'e': /* "ether" */ hardware = ARP_ETHER; naddr = 1; break; #endif case 'a': /* "ax25" */ hardware = ARP_AX25; naddr = argc - 3; break; case 'v': /* VC AX.25 */ #ifdef VCIP_SSID if(ip_call.call[0] == '\0'){ printf("Set vcipcall first\n"); return -1; } #endif hardware = ARP_VAX25; naddr = argc - 3; break; default: printf("unknown hardware type \"%s\"\n",argv[2]); return -1; } /* If an entry already exists, clear it */ if((ap = arp_lookup(hardware,addr)) != NULLARP) arp_drop(ap); if(hardware == ARP_VAX25) at = &arp_type[ARP_AX25]; else at = &arp_type[hardware]; if(at->scan == NULLFP){ printf("Attach device first\n"); return 1; } /* Allocate buffer for hardware address and fill with remaining args */ hwalen = at->hwalen * naddr; if((hwaddr = malloc(hwalen)) == NULLCHAR){ printf(nospace); return 0; } /* Destination address */ (*at->scan)(hwaddr,&argv[3],argc - 3); ap = arp_add(addr,hardware,hwaddr,hwalen,pub); /* Put in table */ free(hwaddr); /* Clean up */ stop_timer(&ap->timer); /* Make entry permanent */ ap->timer.count = ap->timer.start = 0; return 0; } /* Remove an ARP entry */ static doarpdrop(argc,argv) int argc; char *argv[]; { int16 hardware; int32 addr,resolve(); struct arp_tab *ap; void arp_drop(); if((addr = resolve(argv[1])) == 0){ printf(badhost,argv[1]); return 1; } /* This is a kludge. It really ought to be table driven */ switch(tolower(argv[2][0])){ #ifdef NETROM case 'n': hardware = ARP_NETROM; break; #endif #ifdef ETHER case 'e': /* "ether" */ hardware = ARP_ETHER; break; #endif case 'a': /* "ax25" */ hardware = ARP_AX25; break; case 'v': /* VC AX.25 */ hardware = ARP_VAX25; break; #ifdef APPLETALK case 'm': /* "mac appletalk" */ hardware = ARP_APPLETALK; break; #endif default: hardware = 0; break; } if((ap = arp_lookup(hardware,addr)) == NULLARP) return -1; arp_drop(ap); return 0; } /* Dump ARP table */ static int dumparp() { register int i; extern struct arp_stat arp_stat; register struct arp_tab *ap; char e[128]; char *inet_ntoa(); printf( "received %u badtype %u bogus addr %u reqst in %u replies %u reqst out %u\n", arp_stat.recv,arp_stat.badtype,arp_stat.badaddr,arp_stat.inreq, arp_stat.replies,arp_stat.outreq); printf("IP addr Type Time Q Addr\n"); for(i=0;inext){ printf("%-16s%-15s%-5ld",inet_ntoa(ap->ip_addr), arptypes[ap->hardware],ap->timer.count*(long)MSPTICK/1000); if(ap->state == ARP_PENDING) printf("%-2u",len_q(ap->pending)); else printf(" "); if(ap->state == ARP_VALID){ if(ap->hardware == ARP_VAX25){ if(arp_type[ARP_AX25].format != NULLFP) (*arp_type[ARP_AX25].format)(e,ap->hw_addr); }else if(arp_type[ap->hardware].format != NULLFP){ (*arp_type[ap->hardware].format)(e,ap->hw_addr); } else { e[0] = '\0'; } printf("%s",e); } else { printf("[unknown]"); } if(ap->pub) printf(" (published)"); printf("\n"); } } return 0; } #endif /* ETHER || AX25 */