Submitted by: Archie@Whistle.com (Archie Cobbs)

allow teh -a option to work with the  -d option
thus:
arp -d -a now flushes your arp cache.
also fix the -n option so that -an now works correctly.
This commit is contained in:
julian 1997-11-13 01:16:57 +00:00
parent 857944f486
commit fec9363bc4
3 changed files with 154 additions and 66 deletions

View File

@ -3,5 +3,6 @@
PROG= arp
MAN8= arp.8
MAN4= arp.4
COPTS+= -Wall
.include <bsd.prog.mk>

View File

@ -46,6 +46,10 @@
.Fl a
.Nm arp
.Fl d Ar hostname
.Op Ar proxy
.Nm arp
.Fl d
.Fl a
.Nm arp
.Fl s Ar hostname ether_addr
.Op Ar temp
@ -72,7 +76,7 @@ using Internet dot notation.
Available options:
.Bl -tag -width Ds
.It Fl a
The program displays all of the current
The program displays or deletes all of the current
.Tn ARP
entries.
.It Fl d
@ -80,7 +84,9 @@ A super-user may delete an entry for the host called
.Ar hostname
with the
.Fl d
flag.
flag. May be combined with the
.Fl a
flag to delete all entries.
.It Fl n
Show network addresses as numbers (normally
.Nm

View File

@ -45,7 +45,7 @@ static char const copyright[] =
static char const sccsid[] = "@(#)from: arp.c 8.2 (Berkeley) 1/2/94";
#endif
static const char rcsid[] =
"$Id$";
"$Id: arp.c,v 1.12 1997/09/03 06:32:31 charnier Exp $";
#endif /* not lint */
/*
@ -82,12 +82,17 @@ static const char rcsid[] =
#include <strings.h>
#include <unistd.h>
void dump(u_long addr);
void search(u_long addr, void (*action)(struct sockaddr_dl *sdl,
struct sockaddr_inarp *sin, struct rt_msghdr *rtm));
void print_entry(struct sockaddr_dl *sdl,
struct sockaddr_inarp *sin, struct rt_msghdr *rtm);
void nuke_entry(struct sockaddr_dl *sdl,
struct sockaddr_inarp *sin, struct rt_msghdr *rtm);
int delete(char *host, char *info);
void ether_print(u_char *cp);
void usage(void);
int set(int argc, char **argv);
void get(char *host);
int get(char *host);
int file(char *name);
void getsocket(void);
int my_ether_aton(char *a, u_char *n);
@ -95,49 +100,96 @@ int rtmsg(int cmd);
int get_ether_addr(u_long ipaddr, u_char *hwaddr);
static int pid;
static int nflag;
static int nflag; /* no reverse dns lookups */
static int aflag; /* do it for all entries */
static int s = -1;
/* which function we're supposed to do */
#define F_GET 1
#define F_SET 2
#define F_FILESET 3
#define F_REPLACE 4
#define F_DELETE 5
#define SETFUNC(f) { if (func) usage(); func = (f); }
int
main(argc, argv)
int argc;
char **argv;
{
int ch;
int ch, func = 0;
int rtn = 0;
pid = getpid();
while ((ch = getopt(argc, argv, "andfsS")) != -1)
switch((char)ch) {
case 'a':
dump(0);
exit(0);
aflag = 1;
break;
case 'd':
if (argc < 3 || argc > 4)
usage();
delete(argv[2], argv[3]);
exit(0);
SETFUNC(F_DELETE);
break;
case 'n':
nflag = 1;
continue;
break;
case 'S':
delete(argv[2], NULL);
/* FALL THROUGH */
SETFUNC(F_REPLACE);
break;
case 's':
if (argc < 4 || argc > 7)
usage();
exit(set(argc-2, &argv[2]) ? 1 : 0);
SETFUNC(F_SET);
break;
case 'f' :
if (argc != 3)
usage();
return (file(argv[2]));
SETFUNC(F_FILESET);
break;
case '?':
default:
usage();
}
if (argc != 2)
usage();
get(argv[1]);
exit(0);
argc -= optind;
argv += optind;
if (!func)
func = F_GET;
switch (func) {
case F_GET:
if (aflag) {
if (argc != 0)
usage();
search(0, print_entry);
} else {
if (argc != 1)
usage();
get(argv[0]);
}
break;
case F_SET:
case F_REPLACE:
if (argc < 2 || argc > 5)
usage();
if (func == F_REPLACE)
(void) delete(argv[0], NULL);
rtn = set(argc, argv) ? 1 : 0;
break;
case F_DELETE:
if (aflag) {
if (argc != 0)
usage();
search(0, nuke_entry);
} else {
if (argc < 1 || argc > 2)
usage();
rtn = delete(argv[0], argv[1]);
}
break;
case F_FILESET:
if (argc != 1)
usage();
rtn = file(argv[0]);
break;
}
return(rtn);
}
/*
@ -285,7 +337,7 @@ set(int argc, char **argv)
/*
* Display an individual arp entry
*/
void
int
get(char *host)
{
struct hostent *hp;
@ -299,12 +351,13 @@ get(char *host)
bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
sizeof sin->sin_addr);
}
dump(sin->sin_addr.s_addr);
search(sin->sin_addr.s_addr, print_entry);
if (found_entry == 0) {
printf("%s (%s) -- no entry\n",
host, inet_ntoa(sin->sin_addr));
exit(1);
return(1);
}
return(0);
}
/*
@ -367,19 +420,19 @@ delete(char *host, char *info)
}
/*
* Dump the entire arp table
* Search the arp table and do some action on matching entries
*/
void
dump(u_long addr)
search(u_long addr, void (*action)(struct sockaddr_dl *sdl,
struct sockaddr_inarp *sin, struct rt_msghdr *rtm))
{
int mib[6];
size_t needed;
char *host, *lim, *buf, *next;
char *lim, *buf, *next;
struct rt_msghdr *rtm;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
extern int h_errno;
struct hostent *hp;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
@ -403,39 +456,66 @@ dump(u_long addr)
continue;
found_entry = 1;
}
if (nflag == 0)
hp = gethostbyaddr((caddr_t)&(sin->sin_addr),
sizeof sin->sin_addr, AF_INET);
else
hp = 0;
if (hp)
host = hp->h_name;
else {
host = "?";
if (h_errno == TRY_AGAIN)
nflag = 1;
}
printf("%s (%s) at ", host, inet_ntoa(sin->sin_addr));
if (sdl->sdl_alen)
ether_print(LLADDR(sdl));
else
printf("(incomplete)");
if (rtm->rtm_rmx.rmx_expire == 0)
printf(" permanent");
if (sin->sin_other & SIN_PROXY)
printf(" published (proxy only)");
if (rtm->rtm_addrs & RTA_NETMASK) {
sin = (struct sockaddr_inarp *)
(sdl->sdl_len + (char *)sdl);
if (sin->sin_addr.s_addr == 0xffffffff)
printf(" published");
if (sin->sin_len != 8)
printf("(wierd)");
}
printf("\n");
(*action)(sdl, sin, rtm);
}
}
/*
* Display an arp entry
*/
void
print_entry(struct sockaddr_dl *sdl,
struct sockaddr_inarp *sin, struct rt_msghdr *rtm)
{
char *host;
extern int h_errno;
struct hostent *hp;
if (nflag == 0)
hp = gethostbyaddr((caddr_t)&(sin->sin_addr),
sizeof sin->sin_addr, AF_INET);
else
hp = 0;
if (hp)
host = hp->h_name;
else {
host = "?";
if (h_errno == TRY_AGAIN)
nflag = 1;
}
printf("%s (%s) at ", host, inet_ntoa(sin->sin_addr));
if (sdl->sdl_alen)
ether_print(LLADDR(sdl));
else
printf("(incomplete)");
if (rtm->rtm_rmx.rmx_expire == 0)
printf(" permanent");
if (sin->sin_other & SIN_PROXY)
printf(" published (proxy only)");
if (rtm->rtm_addrs & RTA_NETMASK) {
sin = (struct sockaddr_inarp *)
(sdl->sdl_len + (char *)sdl);
if (sin->sin_addr.s_addr == 0xffffffff)
printf(" published");
if (sin->sin_len != 8)
printf("(wierd)");
}
printf("\n");
}
/*
* Nuke an arp entry
*/
void
nuke_entry(struct sockaddr_dl *sdl,
struct sockaddr_inarp *sin, struct rt_msghdr *rtm)
{
char ip[20];
snprintf(ip, sizeof(ip), "%s", inet_ntoa(sin->sin_addr));
delete(ip, NULL);
}
void
ether_print(u_char *cp)
{
@ -461,10 +541,11 @@ my_ether_aton(char *a, u_char *n)
void
usage(void)
{
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n",
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
"usage: arp [-n] hostname",
" arp [-n] -a [kernel] [kernel_memory]",
" arp -d hostname",
" arp [-n] -a",
" arp -d hostname [proxy]",
" arp -d -a",
" arp -s hostname ether_addr [temp] [pub]",
" arp -S hostname ether_addr [temp] [pub]",
" arp -f filename");