static char *sccsid
= "@(#)arp.c 1.1 (Berkeley) %G%";
* arp - display, set, and delete arp table entries
#include <netinet/if_ether.h>
if (argc
>= 2 && strcmp(argv
[1], "-a") == 0) {
char *kernel
= "/vmunix", *mem
= "/dev/kmem";
if (argc
>= 4 && strcmp(argv
[1], "-s") == 0) {
if (argc
== 3 && strcmp(argv
[1], "-d") == 0) {
if (argc
== 3 && strcmp(argv
[1], "-f") == 0) {
* Process a file to set standard arp entries
char line
[100], arg
[4][50], *args
[4];
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", arg
[0], arg
[1], arg
[2], arg
[3]);
fprintf(stderr
, "arp: bad line: %s\n", line
);
* Set an individual arp entry
char *host
= argv
[0], *eaddr
= argv
[1];
hp
= gethostbyname(host
);
fprintf(stderr
, "arp: %s: unknown host\n", host
);
bzero((caddr_t
)&ar
, sizeof ar
);
ar
.arp_pa
.sa_family
= AF_INET
;
sin
= (struct sockaddr_in
*)&ar
.arp_pa
;
sin
->sin_addr
= *(struct in_addr
*)hp
->h_addr
;
ea
= (struct ether_addr
*)ar
.arp_ha
.sa_data
;
if (ether_aton(eaddr
, ea
))
if (strncmp(argv
[0], "temp", 4) == 0)
ar
.arp_flags
&= ~ATF_PERM
;
if (strncmp(argv
[0], "pub", 3) == 0)
ar
.arp_flags
|= ATF_PUBL
;
s
= socket(AF_INET
, SOCK_DGRAM
, 0);
if (ioctl(s
, SIOCSARP
, (caddr_t
)&ar
) < 0) {
* Display an individual arp entry
hp
= gethostbyname(host
);
fprintf(stderr
, "arp: %s: unknown host\n", host
);
bzero((caddr_t
)&ar
, sizeof ar
);
ar
.arp_pa
.sa_family
= AF_INET
;
sin
= (struct sockaddr_in
*)&ar
.arp_pa
;
sin
->sin_addr
= *(struct in_addr
*)hp
->h_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
= (struct ether_addr
*)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
)) printf(" temporary");
if (ar
.arp_flags
& ATF_PUBL
) printf(" published");
hp
= gethostbyname(host
);
fprintf(stderr
, "arp: %s: unknown host\n", host
);
bzero((caddr_t
)&ar
, sizeof ar
);
ar
.arp_pa
.sa_family
= AF_INET
;
sin
= (struct sockaddr_in
*)&ar
.arp_pa
;
sin
->sin_addr
= *(struct in_addr
*)hp
->h_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
));
* Dump the entire arp table
if(nl
[X_ARPTAB_SIZE
].n_type
== 0) {
fprintf(stderr
, "arp: %s: bad namelist\n", kernel
);
fprintf(fprintf
, "arp: cannot open %s\n", mem
);
lseek(mf
, (long)nl
[X_ARPTAB_SIZE
].n_value
, 0);
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(sz
);
fprintf(stderr
, "arp: can't get memory for arptab\n");
lseek(mf
, (long)nl
[X_ARPTAB
].n_value
, 0);
if (read(mf
, (char *)at
, sz
) != sz
) {
perror("arp: error reading arptab");
for (; 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
,
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
)) printf(" temporary");
if (at
->at_flags
& ATF_PUBL
) printf(" published");
u_char
*cp
= &ea
->ether_addr_octet
[0];
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
);
n
->ether_addr_octet
[i
] = o
[i
];
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]\n");
printf(" arp -f filename\n");