1*cf5a6c84SAndroid Build Coastguard Worker /* arp.c - manipulate the system ARP cache
2*cf5a6c84SAndroid Build Coastguard Worker *
3*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2014 Sandeep Sharma <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2014 Kyungwan Han <[email protected]>
5*cf5a6c84SAndroid Build Coastguard Worker * No Standard
6*cf5a6c84SAndroid Build Coastguard Worker
7*cf5a6c84SAndroid Build Coastguard Worker USE_ARP(NEWTOY(arp, "vi:nDsdap:A:H:[+Ap][!sd]", TOYFLAG_USR|TOYFLAG_BIN))
8*cf5a6c84SAndroid Build Coastguard Worker
9*cf5a6c84SAndroid Build Coastguard Worker config ARP
10*cf5a6c84SAndroid Build Coastguard Worker bool "arp"
11*cf5a6c84SAndroid Build Coastguard Worker default n
12*cf5a6c84SAndroid Build Coastguard Worker help
13*cf5a6c84SAndroid Build Coastguard Worker usage: arp
14*cf5a6c84SAndroid Build Coastguard Worker [-vn] [-H HWTYPE] [-i IF] -a [HOSTNAME]
15*cf5a6c84SAndroid Build Coastguard Worker [-v] [-i IF] -d HOSTNAME [pub]
16*cf5a6c84SAndroid Build Coastguard Worker [-v] [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [temp]
17*cf5a6c84SAndroid Build Coastguard Worker [-v] [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [netmask MASK] pub
18*cf5a6c84SAndroid Build Coastguard Worker [-v] [-H HWTYPE] [-i IF] -Ds HOSTNAME IFACE [netmask MASK] pub
19*cf5a6c84SAndroid Build Coastguard Worker
20*cf5a6c84SAndroid Build Coastguard Worker Manipulate ARP cache.
21*cf5a6c84SAndroid Build Coastguard Worker
22*cf5a6c84SAndroid Build Coastguard Worker -a Display (all) hosts
23*cf5a6c84SAndroid Build Coastguard Worker -s Set new ARP entry
24*cf5a6c84SAndroid Build Coastguard Worker -d Delete a specified entry
25*cf5a6c84SAndroid Build Coastguard Worker -v Verbose
26*cf5a6c84SAndroid Build Coastguard Worker -n Don't resolve names
27*cf5a6c84SAndroid Build Coastguard Worker -i IFACE Network interface
28*cf5a6c84SAndroid Build Coastguard Worker -D Read <hwaddr> from given device
29*cf5a6c84SAndroid Build Coastguard Worker -A,-p AF Protocol family
30*cf5a6c84SAndroid Build Coastguard Worker -H HWTYPE Hardware address type
31*cf5a6c84SAndroid Build Coastguard Worker
32*cf5a6c84SAndroid Build Coastguard Worker */
33*cf5a6c84SAndroid Build Coastguard Worker
34*cf5a6c84SAndroid Build Coastguard Worker #define FOR_arp
35*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
36*cf5a6c84SAndroid Build Coastguard Worker #include <net/if_arp.h>
37*cf5a6c84SAndroid Build Coastguard Worker
38*cf5a6c84SAndroid Build Coastguard Worker GLOBALS(
39*cf5a6c84SAndroid Build Coastguard Worker char *hw_type;
40*cf5a6c84SAndroid Build Coastguard Worker char *af_type_A;
41*cf5a6c84SAndroid Build Coastguard Worker char *af_type_p;
42*cf5a6c84SAndroid Build Coastguard Worker char *interface;
43*cf5a6c84SAndroid Build Coastguard Worker
44*cf5a6c84SAndroid Build Coastguard Worker int sockfd;
45*cf5a6c84SAndroid Build Coastguard Worker char *device;
46*cf5a6c84SAndroid Build Coastguard Worker )
47*cf5a6c84SAndroid Build Coastguard Worker
48*cf5a6c84SAndroid Build Coastguard Worker struct arpreq req;
49*cf5a6c84SAndroid Build Coastguard Worker
50*cf5a6c84SAndroid Build Coastguard Worker struct type {
51*cf5a6c84SAndroid Build Coastguard Worker char *name;
52*cf5a6c84SAndroid Build Coastguard Worker int val;
53*cf5a6c84SAndroid Build Coastguard Worker };
54*cf5a6c84SAndroid Build Coastguard Worker
55*cf5a6c84SAndroid Build Coastguard Worker struct type hwtype[] = {
56*cf5a6c84SAndroid Build Coastguard Worker {"ether", ARPHRD_ETHER },
57*cf5a6c84SAndroid Build Coastguard Worker {"loop" ,ARPHRD_LOOPBACK},
58*cf5a6c84SAndroid Build Coastguard Worker {"ppp" ,ARPHRD_PPP},
59*cf5a6c84SAndroid Build Coastguard Worker {"infiniband" ,ARPHRD_INFINIBAND},
60*cf5a6c84SAndroid Build Coastguard Worker {NULL, -1},
61*cf5a6c84SAndroid Build Coastguard Worker };
62*cf5a6c84SAndroid Build Coastguard Worker
63*cf5a6c84SAndroid Build Coastguard Worker struct type aftype[] = {
64*cf5a6c84SAndroid Build Coastguard Worker {"inet", AF_INET },
65*cf5a6c84SAndroid Build Coastguard Worker {"inet6" ,AF_INET6},
66*cf5a6c84SAndroid Build Coastguard Worker {"unspec" ,AF_UNSPEC},
67*cf5a6c84SAndroid Build Coastguard Worker {NULL, -1},
68*cf5a6c84SAndroid Build Coastguard Worker };
69*cf5a6c84SAndroid Build Coastguard Worker
70*cf5a6c84SAndroid Build Coastguard Worker struct type flag_type[] = {
71*cf5a6c84SAndroid Build Coastguard Worker {"PERM", ATF_PERM },
72*cf5a6c84SAndroid Build Coastguard Worker {"PUB" ,ATF_PUBL},
73*cf5a6c84SAndroid Build Coastguard Worker {"DONTPUB" ,ATF_DONTPUB},
74*cf5a6c84SAndroid Build Coastguard Worker {"TRAIL" ,ATF_USETRAILERS},
75*cf5a6c84SAndroid Build Coastguard Worker {NULL, -1},
76*cf5a6c84SAndroid Build Coastguard Worker };
77*cf5a6c84SAndroid Build Coastguard Worker
get_index(struct type arr[],char * name)78*cf5a6c84SAndroid Build Coastguard Worker static int get_index(struct type arr[], char *name)
79*cf5a6c84SAndroid Build Coastguard Worker {
80*cf5a6c84SAndroid Build Coastguard Worker int i;
81*cf5a6c84SAndroid Build Coastguard Worker
82*cf5a6c84SAndroid Build Coastguard Worker for (i = 0; arr[i].name; i++)
83*cf5a6c84SAndroid Build Coastguard Worker if (!strcmp(arr[i].name, name)) break;
84*cf5a6c84SAndroid Build Coastguard Worker return arr[i].val;
85*cf5a6c84SAndroid Build Coastguard Worker }
86*cf5a6c84SAndroid Build Coastguard Worker
resolve_host(char * host,struct sockaddr * sa)87*cf5a6c84SAndroid Build Coastguard Worker static void resolve_host(char *host, struct sockaddr *sa)
88*cf5a6c84SAndroid Build Coastguard Worker {
89*cf5a6c84SAndroid Build Coastguard Worker struct addrinfo *ai = xgetaddrinfo(host, NULL, AF_INET, SOCK_STREAM, 0, 0);
90*cf5a6c84SAndroid Build Coastguard Worker
91*cf5a6c84SAndroid Build Coastguard Worker memcpy(sa, ai->ai_addr, ai->ai_addrlen);
92*cf5a6c84SAndroid Build Coastguard Worker freeaddrinfo(ai);
93*cf5a6c84SAndroid Build Coastguard Worker }
94*cf5a6c84SAndroid Build Coastguard Worker
check_flags(int * i,char ** argv)95*cf5a6c84SAndroid Build Coastguard Worker static void check_flags(int *i, char** argv)
96*cf5a6c84SAndroid Build Coastguard Worker {
97*cf5a6c84SAndroid Build Coastguard Worker struct sockaddr sa;
98*cf5a6c84SAndroid Build Coastguard Worker int flag = *i, j;
99*cf5a6c84SAndroid Build Coastguard Worker struct flags {
100*cf5a6c84SAndroid Build Coastguard Worker char *name;
101*cf5a6c84SAndroid Build Coastguard Worker int or, flag;
102*cf5a6c84SAndroid Build Coastguard Worker } f[] = {
103*cf5a6c84SAndroid Build Coastguard Worker {"pub", 1 ,ATF_PUBL},
104*cf5a6c84SAndroid Build Coastguard Worker {"priv", 0 ,~ATF_PUBL},
105*cf5a6c84SAndroid Build Coastguard Worker {"trail", 1, ATF_USETRAILERS},
106*cf5a6c84SAndroid Build Coastguard Worker {"temp", 0, ~ATF_PERM},
107*cf5a6c84SAndroid Build Coastguard Worker {"dontpub",1, ATF_DONTPUB},
108*cf5a6c84SAndroid Build Coastguard Worker };
109*cf5a6c84SAndroid Build Coastguard Worker
110*cf5a6c84SAndroid Build Coastguard Worker for (;*argv; argv++) {
111*cf5a6c84SAndroid Build Coastguard Worker for (j = 0; j < ARRAY_LEN(f); j++) {
112*cf5a6c84SAndroid Build Coastguard Worker if (!strcmp(*argv, f[j].name)) {
113*cf5a6c84SAndroid Build Coastguard Worker (f[j].or) ?(flag |= f[j].flag):(flag &= f[j].flag);
114*cf5a6c84SAndroid Build Coastguard Worker break;
115*cf5a6c84SAndroid Build Coastguard Worker }
116*cf5a6c84SAndroid Build Coastguard Worker }
117*cf5a6c84SAndroid Build Coastguard Worker if (j > 4 && !strcmp(*argv, "netmask")) {
118*cf5a6c84SAndroid Build Coastguard Worker if (!*++argv) error_exit("NULL netmask");
119*cf5a6c84SAndroid Build Coastguard Worker if (strcmp(*argv, "255.255.255.255")) {
120*cf5a6c84SAndroid Build Coastguard Worker resolve_host(toys.optargs[0], &sa);
121*cf5a6c84SAndroid Build Coastguard Worker memcpy(&req.arp_netmask, &sa, sizeof(sa));
122*cf5a6c84SAndroid Build Coastguard Worker flag |= ATF_NETMASK;
123*cf5a6c84SAndroid Build Coastguard Worker } else argv++;
124*cf5a6c84SAndroid Build Coastguard Worker } else if (j > 4 && !strcmp(*argv, "dev")) {
125*cf5a6c84SAndroid Build Coastguard Worker if (!*++argv) error_exit("NULL dev");
126*cf5a6c84SAndroid Build Coastguard Worker TT.device = *argv;
127*cf5a6c84SAndroid Build Coastguard Worker } else if (j > 4) error_exit("invalid arg");
128*cf5a6c84SAndroid Build Coastguard Worker }
129*cf5a6c84SAndroid Build Coastguard Worker *i = flag;
130*cf5a6c84SAndroid Build Coastguard Worker }
131*cf5a6c84SAndroid Build Coastguard Worker
set_entry(void)132*cf5a6c84SAndroid Build Coastguard Worker static int set_entry(void)
133*cf5a6c84SAndroid Build Coastguard Worker {
134*cf5a6c84SAndroid Build Coastguard Worker int flags = 0;
135*cf5a6c84SAndroid Build Coastguard Worker
136*cf5a6c84SAndroid Build Coastguard Worker if (!toys.optargs[1]) error_exit("bad syntax");
137*cf5a6c84SAndroid Build Coastguard Worker
138*cf5a6c84SAndroid Build Coastguard Worker if (!FLAG(D)) {
139*cf5a6c84SAndroid Build Coastguard Worker char *ptr = toys.optargs[1];
140*cf5a6c84SAndroid Build Coastguard Worker char *p = ptr, *hw_addr = req.arp_ha.sa_data;
141*cf5a6c84SAndroid Build Coastguard Worker
142*cf5a6c84SAndroid Build Coastguard Worker while (*hw_addr && (p-ptr) < 6) {
143*cf5a6c84SAndroid Build Coastguard Worker int val, len;
144*cf5a6c84SAndroid Build Coastguard Worker
145*cf5a6c84SAndroid Build Coastguard Worker if (*hw_addr == ':') hw_addr++;
146*cf5a6c84SAndroid Build Coastguard Worker if (!sscanf(hw_addr, "%2x%n", &val, &len)) break;
147*cf5a6c84SAndroid Build Coastguard Worker hw_addr += len;
148*cf5a6c84SAndroid Build Coastguard Worker *p++ = val;
149*cf5a6c84SAndroid Build Coastguard Worker }
150*cf5a6c84SAndroid Build Coastguard Worker
151*cf5a6c84SAndroid Build Coastguard Worker if ((p-ptr) != 6 || *hw_addr)
152*cf5a6c84SAndroid Build Coastguard Worker error_exit("bad hw addr '%s'", req.arp_ha.sa_data);
153*cf5a6c84SAndroid Build Coastguard Worker } else {
154*cf5a6c84SAndroid Build Coastguard Worker struct ifreq ifre;
155*cf5a6c84SAndroid Build Coastguard Worker
156*cf5a6c84SAndroid Build Coastguard Worker xstrncpy(ifre.ifr_name, toys.optargs[1], IFNAMSIZ);
157*cf5a6c84SAndroid Build Coastguard Worker xioctl(TT.sockfd, SIOCGIFHWADDR, &ifre);
158*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(H) && ifre.ifr_hwaddr.sa_family != ARPHRD_ETHER)
159*cf5a6c84SAndroid Build Coastguard Worker error_exit("protocol type mismatch");
160*cf5a6c84SAndroid Build Coastguard Worker memcpy(&req.arp_ha, &(ifre.ifr_hwaddr), sizeof(req.arp_ha));
161*cf5a6c84SAndroid Build Coastguard Worker }
162*cf5a6c84SAndroid Build Coastguard Worker
163*cf5a6c84SAndroid Build Coastguard Worker flags = ATF_PERM | ATF_COM;
164*cf5a6c84SAndroid Build Coastguard Worker if (toys.optargs[2]) check_flags(&flags, (toys.optargs+2));
165*cf5a6c84SAndroid Build Coastguard Worker req.arp_flags = flags;
166*cf5a6c84SAndroid Build Coastguard Worker xstrncpy(req.arp_dev, TT.device, sizeof(req.arp_dev));
167*cf5a6c84SAndroid Build Coastguard Worker xioctl(TT.sockfd, SIOCSARP, &req);
168*cf5a6c84SAndroid Build Coastguard Worker
169*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(v)) xprintf("Entry set for %s\n", toys.optargs[0]);
170*cf5a6c84SAndroid Build Coastguard Worker return 0;
171*cf5a6c84SAndroid Build Coastguard Worker }
172*cf5a6c84SAndroid Build Coastguard Worker
ip_to_host(struct sockaddr * sa,int flag)173*cf5a6c84SAndroid Build Coastguard Worker static int ip_to_host(struct sockaddr *sa, int flag)
174*cf5a6c84SAndroid Build Coastguard Worker {
175*cf5a6c84SAndroid Build Coastguard Worker int status = 0;
176*cf5a6c84SAndroid Build Coastguard Worker char hbuf[NI_MAXHOST] = {0,}, sbuf[NI_MAXSERV] = {0,};
177*cf5a6c84SAndroid Build Coastguard Worker socklen_t len = sizeof(struct sockaddr_in6);
178*cf5a6c84SAndroid Build Coastguard Worker
179*cf5a6c84SAndroid Build Coastguard Worker *toybuf = 0;
180*cf5a6c84SAndroid Build Coastguard Worker if (!(status = getnameinfo(sa, len, hbuf, sizeof(hbuf), sbuf,
181*cf5a6c84SAndroid Build Coastguard Worker sizeof(sbuf), flag))) {
182*cf5a6c84SAndroid Build Coastguard Worker strcpy(toybuf, hbuf);
183*cf5a6c84SAndroid Build Coastguard Worker return 0;
184*cf5a6c84SAndroid Build Coastguard Worker }
185*cf5a6c84SAndroid Build Coastguard Worker return 1;
186*cf5a6c84SAndroid Build Coastguard Worker }
187*cf5a6c84SAndroid Build Coastguard Worker
delete_entry(void)188*cf5a6c84SAndroid Build Coastguard Worker static int delete_entry(void)
189*cf5a6c84SAndroid Build Coastguard Worker {
190*cf5a6c84SAndroid Build Coastguard Worker int flags = ATF_PERM;
191*cf5a6c84SAndroid Build Coastguard Worker
192*cf5a6c84SAndroid Build Coastguard Worker if (toys.optargs[1]) check_flags(&flags, (toys.optargs+1));
193*cf5a6c84SAndroid Build Coastguard Worker req.arp_flags = flags;
194*cf5a6c84SAndroid Build Coastguard Worker xstrncpy(req.arp_dev, TT.device, sizeof(req.arp_dev));
195*cf5a6c84SAndroid Build Coastguard Worker xioctl(TT.sockfd, SIOCDARP, &req);
196*cf5a6c84SAndroid Build Coastguard Worker
197*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(v)) xprintf("Delete entry for %s\n", toys.optargs[0]);
198*cf5a6c84SAndroid Build Coastguard Worker return 0;
199*cf5a6c84SAndroid Build Coastguard Worker }
200*cf5a6c84SAndroid Build Coastguard Worker
arp_main(void)201*cf5a6c84SAndroid Build Coastguard Worker void arp_main(void)
202*cf5a6c84SAndroid Build Coastguard Worker {
203*cf5a6c84SAndroid Build Coastguard Worker struct sockaddr sa;
204*cf5a6c84SAndroid Build Coastguard Worker char ip[16], hw_addr[30], mask[16], dev[16], *host_ip = NULL;
205*cf5a6c84SAndroid Build Coastguard Worker FILE *fp;
206*cf5a6c84SAndroid Build Coastguard Worker int h_type, type, flag, i, entries = 0, disp = 0;
207*cf5a6c84SAndroid Build Coastguard Worker
208*cf5a6c84SAndroid Build Coastguard Worker TT.device = "";
209*cf5a6c84SAndroid Build Coastguard Worker memset(&sa, 0, sizeof(sa));
210*cf5a6c84SAndroid Build Coastguard Worker TT.sockfd = xsocket(AF_INET, SOCK_STREAM, 0);
211*cf5a6c84SAndroid Build Coastguard Worker
212*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(A) || FLAG(p)) {
213*cf5a6c84SAndroid Build Coastguard Worker if ((type = get_index(aftype,
214*cf5a6c84SAndroid Build Coastguard Worker (TT.af_type_A)?TT.af_type_A:TT.af_type_p)) != AF_INET)
215*cf5a6c84SAndroid Build Coastguard Worker error_exit((type != -1)?"only inet supported by kernel":"unknown family");
216*cf5a6c84SAndroid Build Coastguard Worker }
217*cf5a6c84SAndroid Build Coastguard Worker
218*cf5a6c84SAndroid Build Coastguard Worker req.arp_ha.sa_family = ARPHRD_ETHER;
219*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(H)) {
220*cf5a6c84SAndroid Build Coastguard Worker if ((type = get_index(hwtype, TT.hw_type)) != ARPHRD_ETHER)
221*cf5a6c84SAndroid Build Coastguard Worker error_exit((type != -1)?"h/w type not supported":"unknown h/w type");
222*cf5a6c84SAndroid Build Coastguard Worker req.arp_ha.sa_family = type;
223*cf5a6c84SAndroid Build Coastguard Worker }
224*cf5a6c84SAndroid Build Coastguard Worker
225*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(s) || FLAG(d)) {
226*cf5a6c84SAndroid Build Coastguard Worker if (!toys.optargs[0]) error_exit("-%c needs a host name", FLAG(d)?'d':'s');
227*cf5a6c84SAndroid Build Coastguard Worker resolve_host(toys.optargs[0], &sa);
228*cf5a6c84SAndroid Build Coastguard Worker memcpy(&req.arp_pa, &sa, sizeof(struct sockaddr));
229*cf5a6c84SAndroid Build Coastguard Worker
230*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(s) && !set_entry()) return;
231*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(d) && !delete_entry()) return;
232*cf5a6c84SAndroid Build Coastguard Worker }
233*cf5a6c84SAndroid Build Coastguard Worker
234*cf5a6c84SAndroid Build Coastguard Worker // Show arp cache.
235*cf5a6c84SAndroid Build Coastguard Worker
236*cf5a6c84SAndroid Build Coastguard Worker if (toys.optargs[0]) {
237*cf5a6c84SAndroid Build Coastguard Worker resolve_host(toys.optargs[0], &sa);
238*cf5a6c84SAndroid Build Coastguard Worker ip_to_host(&sa, NI_NUMERICHOST);
239*cf5a6c84SAndroid Build Coastguard Worker host_ip = xstrdup(toybuf);
240*cf5a6c84SAndroid Build Coastguard Worker }
241*cf5a6c84SAndroid Build Coastguard Worker
242*cf5a6c84SAndroid Build Coastguard Worker fp = xfopen("/proc/net/arp", "r");
243*cf5a6c84SAndroid Build Coastguard Worker fgets(toybuf, sizeof(toybuf), fp); // Skip header.
244*cf5a6c84SAndroid Build Coastguard Worker while (fscanf(fp, "%15s 0x%x 0x%x %29s %15s %15s",
245*cf5a6c84SAndroid Build Coastguard Worker ip, &h_type, &flag, hw_addr, mask, dev) == 6) {
246*cf5a6c84SAndroid Build Coastguard Worker char *host_name = "?";
247*cf5a6c84SAndroid Build Coastguard Worker
248*cf5a6c84SAndroid Build Coastguard Worker entries++;
249*cf5a6c84SAndroid Build Coastguard Worker if ((FLAG(H) && get_index(hwtype, TT.hw_type) != h_type) ||
250*cf5a6c84SAndroid Build Coastguard Worker (FLAG(i) && strcmp(TT.interface, dev)) ||
251*cf5a6c84SAndroid Build Coastguard Worker (toys.optargs[0] && strcmp(host_ip, ip))) {
252*cf5a6c84SAndroid Build Coastguard Worker continue;
253*cf5a6c84SAndroid Build Coastguard Worker }
254*cf5a6c84SAndroid Build Coastguard Worker
255*cf5a6c84SAndroid Build Coastguard Worker resolve_host(ip, &sa);
256*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(n)) ip_to_host(&sa, NI_NUMERICHOST);
257*cf5a6c84SAndroid Build Coastguard Worker else if (!ip_to_host(&sa, NI_NAMEREQD)) host_name = toybuf;
258*cf5a6c84SAndroid Build Coastguard Worker
259*cf5a6c84SAndroid Build Coastguard Worker disp++;
260*cf5a6c84SAndroid Build Coastguard Worker printf("%s (%s) at" , host_name, ip);
261*cf5a6c84SAndroid Build Coastguard Worker
262*cf5a6c84SAndroid Build Coastguard Worker for (i = 0; hwtype[i].name; i++)
263*cf5a6c84SAndroid Build Coastguard Worker if (hwtype[i].val & h_type) break;
264*cf5a6c84SAndroid Build Coastguard Worker if (!hwtype[i].name) error_exit("unknown h/w type");
265*cf5a6c84SAndroid Build Coastguard Worker
266*cf5a6c84SAndroid Build Coastguard Worker if (!(flag & ATF_COM)) {
267*cf5a6c84SAndroid Build Coastguard Worker if ((flag & ATF_PUBL)) printf(" *");
268*cf5a6c84SAndroid Build Coastguard Worker else printf(" <incomplete>");
269*cf5a6c84SAndroid Build Coastguard Worker } else printf(" %s [%s]", hw_addr, hwtype[i].name);
270*cf5a6c84SAndroid Build Coastguard Worker
271*cf5a6c84SAndroid Build Coastguard Worker if (flag & ATF_NETMASK) printf("netmask %s ", mask);
272*cf5a6c84SAndroid Build Coastguard Worker
273*cf5a6c84SAndroid Build Coastguard Worker for (i = 0; flag_type[i].name; i++)
274*cf5a6c84SAndroid Build Coastguard Worker if (flag_type[i].val & flag) printf(" %s", flag_type[i].name);
275*cf5a6c84SAndroid Build Coastguard Worker
276*cf5a6c84SAndroid Build Coastguard Worker printf(" on %s\n", dev);
277*cf5a6c84SAndroid Build Coastguard Worker }
278*cf5a6c84SAndroid Build Coastguard Worker
279*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(v))
280*cf5a6c84SAndroid Build Coastguard Worker xprintf("Entries: %d\tSkipped: %d\tFound: %d\n",
281*cf5a6c84SAndroid Build Coastguard Worker entries, entries - disp, disp);
282*cf5a6c84SAndroid Build Coastguard Worker if (toys.optargs[0] && !disp)
283*cf5a6c84SAndroid Build Coastguard Worker xprintf("%s (%s) -- no entry\n", toys.optargs[0], host_ip);
284*cf5a6c84SAndroid Build Coastguard Worker
285*cf5a6c84SAndroid Build Coastguard Worker if (CFG_TOYBOX_FREE) {
286*cf5a6c84SAndroid Build Coastguard Worker free(host_ip);
287*cf5a6c84SAndroid Build Coastguard Worker fclose(fp);
288*cf5a6c84SAndroid Build Coastguard Worker }
289*cf5a6c84SAndroid Build Coastguard Worker }
290