* 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, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
"@(#) Copyright (c) 1984 Regents of the University of California.\n\
static char sccsid
[] = "@(#)arp.c 5.11.1.1 (Berkeley) 7/22/91";
* 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] : _PATH_UNIX
, 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
));
* Dump the entire arp table
int bynumber
, mf
, arptab_size
, sz
;
if (kvm_openfiles(kernel
, mem
, NULL
) == -1) {
fprintf(stderr
, "arp: kvm_openfiles: %s\n", kvm_geterr());
if (kvm_nlist(nl
) < 0 || nl
[X_ARPTAB_SIZE
].n_type
== 0) {
fprintf(stderr
, "arp: %s: bad namelist\n", kernel
);
if (kvm_read((void *)(nl
[X_ARPTAB_SIZE
].n_value
),
&arptab_size
, sizeof arptab_size
) == -1 ||
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
);
if (kvm_read((void *)(nl
[X_ARPTAB
].n_value
), (char *)at
, sz
) == -1) {
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
)
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 [kernel] [kernel_memory]\n");
printf(" arp -d hostname\n");
printf(" arp -s hostname ether_addr [temp] [pub] [trail]\n");
printf(" arp -f filename\n");