* Copyright (c) 1984 Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1984 Regents of the University of California.\n\
static char sccsid
[] = "@(#)arp.c 5.8 (Berkeley) 10/10/88";
* arp - display, set, and delete arp table entries
#include <netinet/if_ether.h>
while ((ch
= getopt(argc
, argv
, "adsf")) != EOF
)
dump((argc
>= 3) ? argv
[2] : "/vmunix", mem
);
if (argc
< 4 || argc
> 7)
exit(set(argc
-2, &argv
[2]) ? 1 : 0);
exit (file(argv
[2]) ? 1 : 0);
* Process a file to set standard arp entries
char line
[100], arg
[5][50], *args
[5];
if ((fp
= fopen(name
, "r")) == NULL
) {
fprintf(stderr
, "arp: cannot open %s\n", name
);
while(fgets(line
, 100, fp
) != NULL
) {
i
= sscanf(line
, "%s %s %s %s %s", arg
[0], arg
[1], arg
[2],
fprintf(stderr
, "arp: bad line: %s\n", line
);
* Set an individual arp entry
char *host
= argv
[0], *eaddr
= argv
[1];
bzero((caddr_t
)&ar
, sizeof ar
);
sin
= (struct sockaddr_in
*)&ar
.arp_pa
;
sin
->sin_family
= AF_INET
;
sin
->sin_addr
.s_addr
= inet_addr(host
);
if (sin
->sin_addr
.s_addr
== -1) {
if (!(hp
= gethostbyname(host
))) {
fprintf(stderr
, "arp: %s: ", host
);
bcopy((char *)hp
->h_addr
, (char *)&sin
->sin_addr
,
ea
= (u_char
*)ar
.arp_ha
.sa_data
;
if (ether_aton(eaddr
, ea
))
if (strncmp(argv
[0], "temp", 4) == 0)
ar
.arp_flags
&= ~ATF_PERM
;
else if (strncmp(argv
[0], "pub", 3) == 0)
ar
.arp_flags
|= ATF_PUBL
;
else if (strncmp(argv
[0], "trail", 5) == 0)
ar
.arp_flags
|= ATF_USETRAILERS
;
s
= socket(AF_INET
, SOCK_DGRAM
, 0);
if (ioctl(s
, SIOCSARP
, (caddr_t
)&ar
) < 0) {
* Display an individual arp entry
bzero((caddr_t
)&ar
, sizeof ar
);
ar
.arp_pa
.sa_family
= AF_INET
;
sin
= (struct sockaddr_in
*)&ar
.arp_pa
;
sin
->sin_family
= AF_INET
;
sin
->sin_addr
.s_addr
= inet_addr(host
);
if (sin
->sin_addr
.s_addr
== -1) {
if (!(hp
= gethostbyname(host
))) {
fprintf(stderr
, "arp: %s: ", host
);
bcopy((char *)hp
->h_addr
, (char *)&sin
->sin_addr
,
s
= socket(AF_INET
, SOCK_DGRAM
, 0);
if (ioctl(s
, SIOCGARP
, (caddr_t
)&ar
) < 0) {
printf("%s (%s) -- no entry\n",
host
, inet_ntoa(sin
->sin_addr
));
ea
= (u_char
*)ar
.arp_ha
.sa_data
;
printf("%s (%s) at ", host
, inet_ntoa(sin
->sin_addr
));
if (ar
.arp_flags
& ATF_COM
)
if (ar
.arp_flags
& ATF_PERM
)
if (ar
.arp_flags
& ATF_PUBL
)
if (ar
.arp_flags
& ATF_USETRAILERS
)
bzero((caddr_t
)&ar
, sizeof ar
);
ar
.arp_pa
.sa_family
= AF_INET
;
sin
= (struct sockaddr_in
*)&ar
.arp_pa
;
sin
->sin_family
= AF_INET
;
sin
->sin_addr
.s_addr
= inet_addr(host
);
if (sin
->sin_addr
.s_addr
== -1) {
if (!(hp
= gethostbyname(host
))) {
fprintf(stderr
, "arp: %s: ", host
);
bcopy((char *)hp
->h_addr
, (char *)&sin
->sin_addr
,
s
= socket(AF_INET
, SOCK_DGRAM
, 0);
if (ioctl(s
, SIOCDARP
, (caddr_t
)&ar
) < 0) {
printf("%s (%s) -- no entry\n",
host
, inet_ntoa(sin
->sin_addr
));
printf("%s (%s) deleted\n", host
, inet_ntoa(sin
->sin_addr
));
static struct pte
*Sysmap
;
* Dump the entire arp table
int bynumber
, mf
, arptab_size
, sz
;
if (nlist(kernel
, nl
) < 0 || nl
[X_ARPTAB_SIZE
].n_type
== 0) {
fprintf(stderr
, "arp: %s: bad namelist\n", kernel
);
mf
= open(mem
, O_RDONLY
);
fprintf(stderr
, "arp: cannot open %s\n", mem
);
malloc((u_int
)(nl
[N_SYSSIZE
].n_value
* sizeof(struct pte
)));
fputs("arp: can't get memory for Sysmap.\n", stderr
);
off
= nl
[N_SYSMAP
].n_value
& ~KERNBASE
;
(void)lseek(mf
, off
, L_SET
);
(void)read(mf
, (char *)Sysmap
,
(int)(nl
[N_SYSSIZE
].n_value
* sizeof(struct pte
)));
klseek(mf
, (long)nl
[X_ARPTAB_SIZE
].n_value
, L_SET
);
read(mf
, &arptab_size
, sizeof arptab_size
);
if (arptab_size
<= 0 || arptab_size
> 1000) {
fprintf(stderr
, "arp: %s: namelist wrong\n", kernel
);
sz
= arptab_size
* sizeof (struct arptab
);
at
= (struct arptab
*)malloc((u_int
)sz
);
fputs("arp: can't get memory for arptab.\n", stderr
);
klseek(mf
, (long)nl
[X_ARPTAB
].n_value
, L_SET
);
if (read(mf
, (char *)at
, sz
) != sz
) {
perror("arp: error reading arptab");
for (bynumber
= 0; arptab_size
-- > 0; at
++) {
if (at
->at_iaddr
.s_addr
== 0 || at
->at_flags
== 0)
hp
= gethostbyaddr((caddr_t
)&at
->at_iaddr
,
sizeof at
->at_iaddr
, AF_INET
);
if (h_errno
== TRY_AGAIN
)
printf("%s (%s) at ", host
, inet_ntoa(at
->at_iaddr
));
if (at
->at_flags
& ATF_COM
)
ether_print(at
->at_enaddr
);
if (at
->at_flags
& ATF_PERM
)
if (at
->at_flags
& ATF_PUBL
)
if (at
->at_flags
& ATF_USETRAILERS
)
* Seek into the kernel for a value.
if (kflag
) { /* get kernel pte */
base
= ctob(Sysmap
[btop(base
)].pg_pfnum
) + (base
& PGOFSET
);
(void)lseek(fd
, base
, off
);
printf("%x:%x:%x:%x:%x:%x", cp
[0], cp
[1], cp
[2], cp
[3], cp
[4], cp
[5]);
i
= sscanf(a
, "%x:%x:%x:%x:%x:%x", &o
[0], &o
[1], &o
[2],
fprintf(stderr
, "arp: invalid Ethernet address '%s'\n", a
);
printf("usage: arp hostname\n");
printf(" arp -a [/vmunix] [/dev/kmem]\n");
printf(" arp -d hostname\n");
printf(" arp -s hostname ether_addr [temp] [pub] [trail]\n");
printf(" arp -f filename\n");