17c478bd9Sstevel@tonic-gate /* 269bb4bb4Scarlsonj * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate /* 67c478bd9Sstevel@tonic-gate * Copyright (c) 1984 Regents of the University of California. 77c478bd9Sstevel@tonic-gate * All rights reserved. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * This code is derived from software contributed to Berkeley by 107c478bd9Sstevel@tonic-gate * Sun Microsystems, Inc. 117c478bd9Sstevel@tonic-gate * 127c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 137c478bd9Sstevel@tonic-gate * modification, are permitted provided that the following conditions 147c478bd9Sstevel@tonic-gate * are met: 157c478bd9Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 167c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 177c478bd9Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 187c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 197c478bd9Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 207c478bd9Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 217c478bd9Sstevel@tonic-gate * must display the following acknowledgement: 227c478bd9Sstevel@tonic-gate * This product includes software developed by the University of 237c478bd9Sstevel@tonic-gate * California, Berkeley and its contributors. 247c478bd9Sstevel@tonic-gate * 4. Neither the name of the University nor the names of its contributors 257c478bd9Sstevel@tonic-gate * may be used to endorse or promote products derived from this software 267c478bd9Sstevel@tonic-gate * without specific prior written permission. 277c478bd9Sstevel@tonic-gate * 287c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 297c478bd9Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 307c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 317c478bd9Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 327c478bd9Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 337c478bd9Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 347c478bd9Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 357c478bd9Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 367c478bd9Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 377c478bd9Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 387c478bd9Sstevel@tonic-gate * SUCH DAMAGE. 397c478bd9Sstevel@tonic-gate */ 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate /* 437c478bd9Sstevel@tonic-gate * arp - display, set, and delete arp table entries 447c478bd9Sstevel@tonic-gate */ 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate #include <stdio.h> 477c478bd9Sstevel@tonic-gate #include <sys/types.h> 487c478bd9Sstevel@tonic-gate #include <sys/socket.h> 497c478bd9Sstevel@tonic-gate #include <netinet/in.h> 507c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 517c478bd9Sstevel@tonic-gate #include <errno.h> 527c478bd9Sstevel@tonic-gate #include <netdb.h> 537c478bd9Sstevel@tonic-gate #include <net/if.h> 547c478bd9Sstevel@tonic-gate #include <net/if_arp.h> 557c478bd9Sstevel@tonic-gate #include <stdlib.h> 567c478bd9Sstevel@tonic-gate #include <unistd.h> 577c478bd9Sstevel@tonic-gate #include <string.h> 587c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 597c478bd9Sstevel@tonic-gate #include <net/if_types.h> 607c478bd9Sstevel@tonic-gate #include <net/if_dl.h> 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate static int file(char *); 637c478bd9Sstevel@tonic-gate static int set(int, char *[]); 647c478bd9Sstevel@tonic-gate static void get(char *); 657c478bd9Sstevel@tonic-gate static void delete(char *); 667c478bd9Sstevel@tonic-gate static void usage(void); 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate int 697c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 707c478bd9Sstevel@tonic-gate { 717c478bd9Sstevel@tonic-gate int c, nflags = 0, argsleft; 727c478bd9Sstevel@tonic-gate int n_flag, a_flag, d_flag, f_flag, s_flag; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate n_flag = a_flag = d_flag = f_flag = s_flag = 0; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate #define CASE(x, y) \ 777c478bd9Sstevel@tonic-gate case x: \ 787c478bd9Sstevel@tonic-gate if (nflags > 0) { \ 797c478bd9Sstevel@tonic-gate usage(); \ 807c478bd9Sstevel@tonic-gate exit(1); \ 817c478bd9Sstevel@tonic-gate } else \ 827c478bd9Sstevel@tonic-gate y##_flag = 1; \ 837c478bd9Sstevel@tonic-gate nflags++; \ 847c478bd9Sstevel@tonic-gate break 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "nadfs")) != EOF) { 877c478bd9Sstevel@tonic-gate switch (c) { 887c478bd9Sstevel@tonic-gate case '?': 897c478bd9Sstevel@tonic-gate usage(); 907c478bd9Sstevel@tonic-gate exit(1); 917c478bd9Sstevel@tonic-gate /* NOTREACHED */ 927c478bd9Sstevel@tonic-gate break; 937c478bd9Sstevel@tonic-gate case 'n': 947c478bd9Sstevel@tonic-gate n_flag = 1; 957c478bd9Sstevel@tonic-gate break; 967c478bd9Sstevel@tonic-gate CASE('a', a); 977c478bd9Sstevel@tonic-gate CASE('d', d); 987c478bd9Sstevel@tonic-gate CASE('f', f); 997c478bd9Sstevel@tonic-gate CASE('s', s); 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate #undef CASE 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate /* 1067c478bd9Sstevel@tonic-gate * -n only allowed with -a 1077c478bd9Sstevel@tonic-gate */ 1087c478bd9Sstevel@tonic-gate if (n_flag && !a_flag) { 1097c478bd9Sstevel@tonic-gate usage(); 1107c478bd9Sstevel@tonic-gate exit(1); 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate argsleft = argc - optind; 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate if (a_flag && (argsleft == 0)) { 1167c478bd9Sstevel@tonic-gate /* 1177c478bd9Sstevel@tonic-gate * the easiest way to get the complete arp table 1187c478bd9Sstevel@tonic-gate * is to let netstat, which prints it as part of 1197c478bd9Sstevel@tonic-gate * the MIB statistics, do it. 1207c478bd9Sstevel@tonic-gate */ 1217c478bd9Sstevel@tonic-gate (void) execl("/usr/bin/netstat", "netstat", 1227c478bd9Sstevel@tonic-gate (n_flag ? "-np" : "-p"), 1237c478bd9Sstevel@tonic-gate "-f", "inet", (char *)0); 124*2545d10dSRobert Mustacchi (void) fprintf(stderr, "failed to exec netstat: %s\n", 125*2545d10dSRobert Mustacchi strerror(errno)); 1267c478bd9Sstevel@tonic-gate exit(1); 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate } else if (s_flag && (argsleft >= 2)) { 1297c478bd9Sstevel@tonic-gate if (set(argsleft, &argv[optind]) != 0) 1307c478bd9Sstevel@tonic-gate exit(1); 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate } else if (d_flag && (argsleft == 1)) { 1337c478bd9Sstevel@tonic-gate delete(argv[optind]); 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate } else if (f_flag && (argsleft == 1)) { 1367c478bd9Sstevel@tonic-gate if (file(argv[optind]) != 0) 1377c478bd9Sstevel@tonic-gate exit(1); 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate } else if ((nflags == 0) && (argsleft == 1)) { 1407c478bd9Sstevel@tonic-gate get(argv[optind]); 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate } else { 1437c478bd9Sstevel@tonic-gate usage(); 1447c478bd9Sstevel@tonic-gate exit(1); 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate return (0); 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate /* 1507c478bd9Sstevel@tonic-gate * Process a file to set standard arp entries 1517c478bd9Sstevel@tonic-gate */ 15269bb4bb4Scarlsonj static int 15369bb4bb4Scarlsonj file(char *name) 1547c478bd9Sstevel@tonic-gate { 1557c478bd9Sstevel@tonic-gate /* 1567c478bd9Sstevel@tonic-gate * A line of input can be: 15769bb4bb4Scarlsonj * <hostname> <macaddr> ["temp"] ["pub"] ["trail"] ["permanent"] 1587c478bd9Sstevel@tonic-gate */ 1597c478bd9Sstevel@tonic-gate #define MAX_LINE_LEN (MAXHOSTNAMELEN + \ 16069bb4bb4Scarlsonj sizeof (" xx:xx:xx:xx:xx:xx temp pub trail permanent\n")) 1617c478bd9Sstevel@tonic-gate #define MIN_ARGS 2 1627c478bd9Sstevel@tonic-gate #define MAX_ARGS 5 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate FILE *fp; 1657c478bd9Sstevel@tonic-gate char line[MAX_LINE_LEN]; 1667c478bd9Sstevel@tonic-gate int retval; 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate if ((fp = fopen(name, "r")) == NULL) { 1697c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "arp: cannot open %s\n", name); 1707c478bd9Sstevel@tonic-gate exit(1); 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate retval = 0; 1747c478bd9Sstevel@tonic-gate while (fgets(line, MAX_LINE_LEN, fp) != NULL) { 1757c478bd9Sstevel@tonic-gate char line_copy[MAX_LINE_LEN]; 1767c478bd9Sstevel@tonic-gate char *args[MAX_ARGS]; 1777c478bd9Sstevel@tonic-gate char *start; 1787c478bd9Sstevel@tonic-gate int i; 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate /* 1817c478bd9Sstevel@tonic-gate * Keep a copy of the un-altered line for error 1827c478bd9Sstevel@tonic-gate * reporting. 1837c478bd9Sstevel@tonic-gate */ 1847c478bd9Sstevel@tonic-gate (void) strlcpy(line_copy, line, MAX_LINE_LEN); 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate start = line_copy; 1877c478bd9Sstevel@tonic-gate for (i = 0; i < MAX_ARGS; i++) { 1887c478bd9Sstevel@tonic-gate if ((args[i] = strtok(start, " \t\n")) == NULL) 1897c478bd9Sstevel@tonic-gate break; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate start = NULL; 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate if (i < MIN_ARGS) { 1957c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "arp: bad line: %s\n", 1967c478bd9Sstevel@tonic-gate line); 1977c478bd9Sstevel@tonic-gate retval = 1; 1987c478bd9Sstevel@tonic-gate continue; 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate if (set(i, args) != 0) 2027c478bd9Sstevel@tonic-gate retval = 1; 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate #undef MAX_LINE_LEN 2067c478bd9Sstevel@tonic-gate #undef MIN_ARGS 2077c478bd9Sstevel@tonic-gate #undef MAX_ARGS 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate (void) fclose(fp); 2107c478bd9Sstevel@tonic-gate return (retval); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate /* 2147c478bd9Sstevel@tonic-gate * Set an individual arp entry 2157c478bd9Sstevel@tonic-gate */ 21669bb4bb4Scarlsonj static int 21769bb4bb4Scarlsonj set(int argc, char *argv[]) 2187c478bd9Sstevel@tonic-gate { 2197c478bd9Sstevel@tonic-gate struct xarpreq ar; 2207c478bd9Sstevel@tonic-gate struct hostent *hp; 2217c478bd9Sstevel@tonic-gate struct sockaddr_in *sin; 2227c478bd9Sstevel@tonic-gate uchar_t *ea; 2237c478bd9Sstevel@tonic-gate int s; 2247c478bd9Sstevel@tonic-gate char *host = argv[0], *eaddr = argv[1]; 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate argc -= 2; 2277c478bd9Sstevel@tonic-gate argv += 2; 2287c478bd9Sstevel@tonic-gate (void) memset(&ar, 0, sizeof (ar)); 2297c478bd9Sstevel@tonic-gate sin = (struct sockaddr_in *)&ar.xarp_pa; 2307c478bd9Sstevel@tonic-gate sin->sin_family = AF_INET; 2317c478bd9Sstevel@tonic-gate sin->sin_addr.s_addr = inet_addr(host); 2327c478bd9Sstevel@tonic-gate if (sin->sin_addr.s_addr == (in_addr_t)-1) { 2337c478bd9Sstevel@tonic-gate hp = gethostbyname(host); 2347c478bd9Sstevel@tonic-gate if (hp == NULL) { 2357c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "arp: %s: unknown host\n", 2367c478bd9Sstevel@tonic-gate host); 2377c478bd9Sstevel@tonic-gate return (1); 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate (void) memcpy(&sin->sin_addr, hp->h_addr, 2407c478bd9Sstevel@tonic-gate sizeof (sin->sin_addr)); 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate ea = _link_aton(eaddr, &s); 2437c478bd9Sstevel@tonic-gate if (ea == NULL) { 2447c478bd9Sstevel@tonic-gate if (s == -1) { 2457c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2467c478bd9Sstevel@tonic-gate "arp: invalid link layer address '%s'\n", eaddr); 2477c478bd9Sstevel@tonic-gate return (1); 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate perror("arp: nomem"); 2507c478bd9Sstevel@tonic-gate exit(1); 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate ar.xarp_ha.sdl_alen = s; 2537c478bd9Sstevel@tonic-gate (void) memcpy(LLADDR(&ar.xarp_ha), ea, ar.xarp_ha.sdl_alen); 2547c478bd9Sstevel@tonic-gate free(ea); 2557c478bd9Sstevel@tonic-gate ar.xarp_ha.sdl_family = AF_LINK; 2567c478bd9Sstevel@tonic-gate ar.xarp_flags = ATF_PERM; 2577c478bd9Sstevel@tonic-gate while (argc-- > 0) { 25869bb4bb4Scarlsonj if (strncmp(argv[0], "temp", 4) == 0) { 2597c478bd9Sstevel@tonic-gate ar.xarp_flags &= ~ATF_PERM; 26069bb4bb4Scarlsonj } else if (strncmp(argv[0], "pub", 3) == 0) { 2617c478bd9Sstevel@tonic-gate ar.xarp_flags |= ATF_PUBL; 26269bb4bb4Scarlsonj } else if (strncmp(argv[0], "trail", 5) == 0) { 2637c478bd9Sstevel@tonic-gate ar.xarp_flags |= ATF_USETRAILERS; 26469bb4bb4Scarlsonj } else if (strcmp(argv[0], "permanent") == 0) { 26569bb4bb4Scarlsonj ar.xarp_flags |= ATF_AUTHORITY; 26669bb4bb4Scarlsonj } else { 26769bb4bb4Scarlsonj (void) fprintf(stderr, 26869bb4bb4Scarlsonj "arp: unknown keyword '%s'\n", argv[0]); 26969bb4bb4Scarlsonj return (1); 27069bb4bb4Scarlsonj } 2717c478bd9Sstevel@tonic-gate argv++; 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate 27469bb4bb4Scarlsonj if ((ar.xarp_flags & (ATF_PERM|ATF_AUTHORITY)) == ATF_AUTHORITY) { 27569bb4bb4Scarlsonj (void) fprintf(stderr, "arp: 'temp' and 'permanent' flags are " 27669bb4bb4Scarlsonj "not usable together.\n"); 27769bb4bb4Scarlsonj return (1); 27869bb4bb4Scarlsonj } 27969bb4bb4Scarlsonj 2807c478bd9Sstevel@tonic-gate s = socket(AF_INET, SOCK_DGRAM, 0); 2817c478bd9Sstevel@tonic-gate if (s < 0) { 2827c478bd9Sstevel@tonic-gate perror("arp: socket"); 2837c478bd9Sstevel@tonic-gate exit(1); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate if (ioctl(s, SIOCSXARP, (caddr_t)&ar) < 0) { 2867c478bd9Sstevel@tonic-gate perror(host); 2877c478bd9Sstevel@tonic-gate exit(1); 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate (void) close(s); 2907c478bd9Sstevel@tonic-gate return (0); 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate /* 2947c478bd9Sstevel@tonic-gate * Display an individual arp entry 2957c478bd9Sstevel@tonic-gate */ 29669bb4bb4Scarlsonj static void 29769bb4bb4Scarlsonj get(char *host) 2987c478bd9Sstevel@tonic-gate { 2997c478bd9Sstevel@tonic-gate struct xarpreq ar; 3007c478bd9Sstevel@tonic-gate struct hostent *hp; 3017c478bd9Sstevel@tonic-gate struct sockaddr_in *sin; 3027c478bd9Sstevel@tonic-gate uchar_t *ea; 3037c478bd9Sstevel@tonic-gate int s; 3047c478bd9Sstevel@tonic-gate char *str = NULL; 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate (void) memset(&ar, 0, sizeof (ar)); 3077c478bd9Sstevel@tonic-gate sin = (struct sockaddr_in *)&ar.xarp_pa; 3087c478bd9Sstevel@tonic-gate sin->sin_family = AF_INET; 3097c478bd9Sstevel@tonic-gate sin->sin_addr.s_addr = inet_addr(host); 3107c478bd9Sstevel@tonic-gate if (sin->sin_addr.s_addr == (in_addr_t)-1) { 3117c478bd9Sstevel@tonic-gate hp = gethostbyname(host); 3127c478bd9Sstevel@tonic-gate if (hp == NULL) { 3137c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "arp: %s: unknown host\n", 3147c478bd9Sstevel@tonic-gate host); 3157c478bd9Sstevel@tonic-gate exit(1); 3167c478bd9Sstevel@tonic-gate } 3177c478bd9Sstevel@tonic-gate (void) memcpy(&sin->sin_addr, hp->h_addr, 3187c478bd9Sstevel@tonic-gate sizeof (sin->sin_addr)); 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate s = socket(AF_INET, SOCK_DGRAM, 0); 3217c478bd9Sstevel@tonic-gate if (s < 0) { 3227c478bd9Sstevel@tonic-gate perror("arp: socket"); 3237c478bd9Sstevel@tonic-gate exit(1); 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate ar.xarp_ha.sdl_family = AF_LINK; 3267c478bd9Sstevel@tonic-gate if (ioctl(s, SIOCGXARP, (caddr_t)&ar) < 0) { 3277c478bd9Sstevel@tonic-gate if (errno == ENXIO) 3287c478bd9Sstevel@tonic-gate (void) printf("%s (%s) -- no entry\n", 3297c478bd9Sstevel@tonic-gate host, inet_ntoa(sin->sin_addr)); 3307c478bd9Sstevel@tonic-gate else 3317c478bd9Sstevel@tonic-gate perror("SIOCGXARP"); 3327c478bd9Sstevel@tonic-gate exit(1); 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate (void) close(s); 3357c478bd9Sstevel@tonic-gate ea = (uchar_t *)LLADDR(&ar.xarp_ha); 3367c478bd9Sstevel@tonic-gate if (ar.xarp_flags & ATF_COM) { 3377c478bd9Sstevel@tonic-gate str = _link_ntoa(ea, str, ar.xarp_ha.sdl_alen, IFT_OTHER); 3387c478bd9Sstevel@tonic-gate if (str != NULL) { 3397c478bd9Sstevel@tonic-gate (void) printf("%s (%s) at %s", host, 3407c478bd9Sstevel@tonic-gate inet_ntoa(sin->sin_addr), str); 3417c478bd9Sstevel@tonic-gate free(str); 3427c478bd9Sstevel@tonic-gate } else { 3437c478bd9Sstevel@tonic-gate perror("arp: nomem"); 3447c478bd9Sstevel@tonic-gate exit(1); 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate } else { 3477c478bd9Sstevel@tonic-gate (void) printf("%s (%s) at (incomplete)", host, 3487c478bd9Sstevel@tonic-gate inet_ntoa(sin->sin_addr)); 3497c478bd9Sstevel@tonic-gate } 35069bb4bb4Scarlsonj if (!(ar.xarp_flags & ATF_PERM)) 35169bb4bb4Scarlsonj (void) printf(" temp"); 3527c478bd9Sstevel@tonic-gate if (ar.xarp_flags & ATF_PUBL) 35369bb4bb4Scarlsonj (void) printf(" pub"); 3547c478bd9Sstevel@tonic-gate if (ar.xarp_flags & ATF_USETRAILERS) 35569bb4bb4Scarlsonj (void) printf(" trail"); 35669bb4bb4Scarlsonj if (ar.xarp_flags & ATF_AUTHORITY) 35769bb4bb4Scarlsonj (void) printf(" permanent"); 3587c478bd9Sstevel@tonic-gate (void) printf("\n"); 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate /* 3627c478bd9Sstevel@tonic-gate * Delete an arp entry 3637c478bd9Sstevel@tonic-gate */ 36469bb4bb4Scarlsonj static void 36569bb4bb4Scarlsonj delete(char *host) 3667c478bd9Sstevel@tonic-gate { 3677c478bd9Sstevel@tonic-gate struct xarpreq ar; 3687c478bd9Sstevel@tonic-gate struct hostent *hp; 3697c478bd9Sstevel@tonic-gate struct sockaddr_in *sin; 3707c478bd9Sstevel@tonic-gate int s; 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate (void) memset(&ar, 0, sizeof (ar)); 3737c478bd9Sstevel@tonic-gate sin = (struct sockaddr_in *)&ar.xarp_pa; 3747c478bd9Sstevel@tonic-gate sin->sin_family = AF_INET; 3757c478bd9Sstevel@tonic-gate sin->sin_addr.s_addr = inet_addr(host); 3767c478bd9Sstevel@tonic-gate if (sin->sin_addr.s_addr == (in_addr_t)-1) { 3777c478bd9Sstevel@tonic-gate hp = gethostbyname(host); 3787c478bd9Sstevel@tonic-gate if (hp == NULL) { 3797c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "arp: %s: unknown host\n", 3807c478bd9Sstevel@tonic-gate host); 3817c478bd9Sstevel@tonic-gate exit(1); 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate (void) memcpy(&sin->sin_addr, hp->h_addr, 3847c478bd9Sstevel@tonic-gate sizeof (sin->sin_addr)); 3857c478bd9Sstevel@tonic-gate } 3867c478bd9Sstevel@tonic-gate s = socket(AF_INET, SOCK_DGRAM, 0); 3877c478bd9Sstevel@tonic-gate if (s < 0) { 3887c478bd9Sstevel@tonic-gate perror("arp: socket"); 3897c478bd9Sstevel@tonic-gate exit(1); 3907c478bd9Sstevel@tonic-gate } 3917c478bd9Sstevel@tonic-gate ar.xarp_ha.sdl_family = AF_LINK; 3927c478bd9Sstevel@tonic-gate if (ioctl(s, SIOCDXARP, (caddr_t)&ar) < 0) { 3937c478bd9Sstevel@tonic-gate if (errno == ENXIO) 3947c478bd9Sstevel@tonic-gate (void) printf("%s (%s) -- no entry\n", 3957c478bd9Sstevel@tonic-gate host, inet_ntoa(sin->sin_addr)); 3967c478bd9Sstevel@tonic-gate else 3977c478bd9Sstevel@tonic-gate perror("SIOCDXARP"); 3987c478bd9Sstevel@tonic-gate exit(1); 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate (void) close(s); 4017c478bd9Sstevel@tonic-gate (void) printf("%s (%s) deleted\n", host, inet_ntoa(sin->sin_addr)); 4027c478bd9Sstevel@tonic-gate } 4037c478bd9Sstevel@tonic-gate 40469bb4bb4Scarlsonj static void 40569bb4bb4Scarlsonj usage(void) 4067c478bd9Sstevel@tonic-gate { 4077c478bd9Sstevel@tonic-gate (void) printf("Usage: arp hostname\n"); 4087c478bd9Sstevel@tonic-gate (void) printf(" arp -a [-n]\n"); 4097c478bd9Sstevel@tonic-gate (void) printf(" arp -d hostname\n"); 4107c478bd9Sstevel@tonic-gate (void) printf(" arp -s hostname ether_addr " 41169bb4bb4Scarlsonj "[temp] [pub] [trail] [permanent]\n"); 4127c478bd9Sstevel@tonic-gate (void) printf(" arp -f filename\n"); 4137c478bd9Sstevel@tonic-gate } 414