1 /*
2  * arping.c
3  *
4  *		This program is free software; you can redistribute it and/or
5  *		modify it under the terms of the GNU General Public License
6  *		as published by the Free Software Foundation; either version
7  *		2 of the License, or (at your option) any later version.
8  *
9  * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10  * 		YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
11  */
12 
13 /* Andrew Beekhof, Lars Ellenberg:
14  * Based on arping from iputils,
15  * adapted to the command line conventions established by the libnet based
16  * send_arp tool as used by the IPaddr and IPaddr2 resource agents.
17  * The libnet based send_arp, and its command line argument convention,
18  * was first added to the heartbeat project by Matt Soffen.
19  *
20  * Latest "resync" with iputils as of:
21  *   git://git.linux-ipv6.org/gitroot/iputils.git
22  *   511f8356e22615479c3cc16bca64d72d204f6df3
23  *   Fri Jul 24 10:48:47 2015
24  * To get various bugfixes and support for infiniband and other link layer
25  * addresses which do not fit into plain "sockaddr_ll", and broadcast addresses
26  * that may be different from memset(,0xff,).
27  */
28 
29 #include <stdlib.h>
30 #include <sys/param.h>
31 #include <sys/socket.h>
32 #include <linux/sockios.h>
33 #include <sys/file.h>
34 #include <sys/time.h>
35 #include <sys/signal.h>
36 #include <signal.h>
37 #include <sys/ioctl.h>
38 #include <net/if.h>
39 #include <linux/if_packet.h>
40 #include <linux/if_ether.h>
41 #include <net/if_arp.h>
42 #include <sys/uio.h>
43 #ifdef CAPABILITIES
44 #include <sys/prctl.h>
45 #include <sys/capability.h>
46 #endif
47 
48 #include <netdb.h>
49 #include <unistd.h>
50 #include <stdio.h>
51 #include <ctype.h>
52 #include <errno.h>
53 #include <string.h>
54 #include <netinet/in.h>
55 #include <arpa/inet.h>
56 
57 #ifdef USE_SYSFS
58 #include <sysfs/libsysfs.h>
59 struct sysfs_devattr_values;
60 #endif
61 
62 #ifndef WITHOUT_IFADDRS
63 #include <ifaddrs.h>
64 #endif
65 
66 #ifdef USE_IDN
67 #include <idna.h>
68 #include <locale.h>
69 #endif
70 
71 static char SNAPSHOT[] = "s20121221";
72 
73 static void usage(void) __attribute__((noreturn));
74 
75 #ifndef DEFAULT_DEVICE
76 #define DEFAULT_DEVICE "eth0"
77 #endif
78 #ifdef DEFAULT_DEVICE
79 # define DEFAULT_DEVICE_STR	DEFAULT_DEVICE
80 #else
81 # define DEFAULT_DEVICE		NULL
82 #endif
83 
84 struct device {
85 	const char *name;
86 	int ifindex;
87 #ifndef WITHOUT_IFADDRS
88 	struct ifaddrs *ifa;
89 #endif
90 #ifdef USE_SYSFS
91 	struct sysfs_devattr_values *sysfs;
92 #endif
93 };
94 
95 int quit_on_reply=0;
96 struct device device = {
97 	.name = DEFAULT_DEVICE,
98 };
99 char *source;
100 struct in_addr src, dst;
101 char *target;
102 int dad, unsolicited, advert;
103 int quiet;
104 int count=-1;
105 int timeout;
106 int unicasting;
107 int s;
108 int broadcast_only;
109 
110 struct sockaddr_storage me;
111 struct sockaddr_storage he;
112 
113 struct timeval start, last;
114 
115 int sent, brd_sent;
116 int received, brd_recv, req_recv;
117 
118 #ifndef CAPABILITIES
119 static uid_t euid;
120 #endif
121 
122 #define MS_TDIFF(tv1,tv2) ( ((tv1).tv_sec-(tv2).tv_sec)*1000 + \
123 			   ((tv1).tv_usec-(tv2).tv_usec)/1000 )
124 
125 #define OFFSET_OF(name,ele)	((size_t)&((name *)0)->ele)
126 
sll_len(size_t halen)127 static socklen_t sll_len(size_t halen)
128 {
129 	socklen_t len = OFFSET_OF(struct sockaddr_ll, sll_addr) + halen;
130 	if (len < sizeof(struct sockaddr_ll))
131 		len = sizeof(struct sockaddr_ll);
132 	return len;
133 }
134 
135 #define SLL_LEN(hln)		sll_len(hln)
136 
137 #if 1 /* hb_mode: always print hb_mode usage in this binary */
138 static char print_usage[]={
139 "send_arp: sends out custom ARP packet.\n"
140 "  usage: send_arp [-i repeatinterval-ms] [-r repeatcount] [-p pidfile] \\\n"
141 "              device src_ip_addr src_hw_addr broadcast_ip_addr netmask\n"
142 "\n"
143 "  where:\n"
144 "    repeatinterval-ms: ignored\n"
145 "\n"
146 "    repeatcount: how many ARP packets to send.\n"
147 "\n"
148 "    pidfile: pid file to use\n"
149 "\n"
150 "    device: network interface to use\n"
151 "\n"
152 "    src_ip_addr: source ip address\n"
153 "\n"
154 "    src_hw_addr: only \"auto\" is supported.\n"
155 "                 If other specified, it will exit without sending any ARP packets.\n"
156 "\n"
157 "    broadcast_ip_addr: ignored\n"
158 "\n"
159 "    netmask: ignored\n"
160 "\n"
161 "  Notes: Other options of iputils-arping may be accepted but it's not\n"
162 "         intended to be supported in this binary.\n"
163 "\n"
164 };
165 
usage(void)166 void usage(void)
167 {
168 	fprintf(stderr, "%s\n", print_usage);
169 	exit(2);
170 }
171 
172 #else /* hb_mode */
173 
usage(void)174 void usage(void)
175 {
176 	fprintf(stderr,
177 		"Usage: arping [-fqbDUAV] [-c count] [-w timeout] [-I device] [-s source] destination\n"
178 		"  -f : quit on first reply\n"
179 		"  -q : be quiet\n"
180 		"  -b : keep broadcasting, don't go unicast\n"
181 		"  -D : duplicate address detection mode\n"
182 		"  -U : Unsolicited ARP mode, update your neighbours\n"
183 		"  -A : ARP answer mode, update your neighbours\n"
184 		"  -V : print version and exit\n"
185 		"  -c count : how many packets to send\n"
186 		"  -w timeout : how long to wait for a reply\n"
187 		"  -I device : which ethernet device to use"
188 #ifdef DEFAULT_DEVICE_STR
189 			" (" DEFAULT_DEVICE_STR ")"
190 #endif
191 			"\n"
192 		"  -s source : source ip address\n"
193 		"  destination : ask for what ip address\n"
194 		);
195 	exit(2);
196 }
197 #endif /* hb_mode */
198 
set_signal(int signo,void (* handler)(void))199 static void set_signal(int signo, void (*handler)(void))
200 {
201 	struct sigaction sa;
202 
203 	memset(&sa, 0, sizeof(sa));
204 	sa.sa_handler = (void (*)(int))handler;
205 	sa.sa_flags = SA_RESTART;
206 	sigaction(signo, &sa, NULL);
207 }
208 
209 #ifdef CAPABILITIES
210 static const cap_value_t caps[] = { CAP_NET_RAW, };
211 static cap_flag_value_t cap_raw = CAP_CLEAR;
212 #endif
213 
limit_capabilities(void)214 static void limit_capabilities(void)
215 {
216 #ifdef CAPABILITIES
217 	cap_t cap_p;
218 
219 	cap_p = cap_get_proc();
220 	if (!cap_p) {
221 		perror("arping: cap_get_proc");
222 		exit(-1);
223 	}
224 
225 	cap_get_flag(cap_p, CAP_NET_RAW, CAP_PERMITTED, &cap_raw);
226 
227 	if (cap_raw != CAP_CLEAR) {
228 		if (cap_clear(cap_p) < 0) {
229 			perror("arping: cap_clear");
230 			exit(-1);
231 		}
232 
233 		cap_set_flag(cap_p, CAP_PERMITTED, 1, caps, CAP_SET);
234 
235 		if (cap_set_proc(cap_p) < 0) {
236 			perror("arping: cap_set_proc");
237 			if (errno != EPERM)
238 				exit(-1);
239 		}
240 	}
241 
242 	if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
243 		perror("arping: prctl");
244 		exit(-1);
245 	}
246 
247 	if (setuid(getuid()) < 0) {
248 		perror("arping: setuid");
249 		exit(-1);
250 	}
251 
252 	if (prctl(PR_SET_KEEPCAPS, 0) < 0) {
253 		perror("arping: prctl");
254 		exit(-1);
255 	}
256 
257 	cap_free(cap_p);
258 #else
259 	euid = geteuid();
260 #endif
261 }
262 
modify_capability_raw(int on)263 static int modify_capability_raw(int on)
264 {
265 #ifdef CAPABILITIES
266 	cap_t cap_p;
267 
268 	if (cap_raw != CAP_SET)
269 		return on ? -1 : 0;
270 
271 	cap_p = cap_get_proc();
272 	if (!cap_p) {
273 		perror("arping: cap_get_proc");
274 		return -1;
275 	}
276 
277 	cap_set_flag(cap_p, CAP_EFFECTIVE, 1, caps, on ? CAP_SET : CAP_CLEAR);
278 
279 	if (cap_set_proc(cap_p) < 0) {
280 		perror("arping: cap_set_proc");
281 		return -1;
282 	}
283 
284 	cap_free(cap_p);
285 #else
286 	if (setuid(on ? euid : getuid())) {
287 		perror("arping: setuid");
288 		return -1;
289 	}
290 #endif
291 	return 0;
292 }
293 
enable_capability_raw(void)294 static int enable_capability_raw(void)
295 {
296 	return modify_capability_raw(1);
297 }
298 
disable_capability_raw(void)299 static int disable_capability_raw(void)
300 {
301 	return modify_capability_raw(0);
302 }
303 
drop_capabilities(void)304 static void drop_capabilities(void)
305 {
306 #ifdef CAPABILITIES
307 	cap_t cap_p = cap_init();
308 
309 	if (!cap_p) {
310 		perror("arping: cap_init");
311 		exit(-1);
312 	}
313 
314 	if (cap_set_proc(cap_p) < 0) {
315 		perror("arping: cap_set_proc");
316 		exit(-1);
317 	}
318 
319 	cap_free(cap_p);
320 #else
321 	if (setuid(getuid()) < 0) {
322 		perror("arping: setuid");
323 		exit(-1);
324 	}
325 #endif
326 }
327 
send_pack(int s,struct in_addr src,struct in_addr dst,struct sockaddr_ll * ME,struct sockaddr_ll * HE)328 static int send_pack(int s, struct in_addr src, struct in_addr dst,
329 	      struct sockaddr_ll *ME, struct sockaddr_ll *HE)
330 {
331 	int err;
332 	struct timeval now;
333 	unsigned char buf[256];
334 	struct arphdr *ah = (struct arphdr*)buf;
335 	unsigned char *p = (unsigned char *)(ah+1);
336 
337 	ah->ar_hrd = htons(ME->sll_hatype);
338 	if (ah->ar_hrd == htons(ARPHRD_FDDI))
339 		ah->ar_hrd = htons(ARPHRD_ETHER);
340 	ah->ar_pro = htons(ETH_P_IP);
341 	ah->ar_hln = ME->sll_halen;
342 	ah->ar_pln = 4;
343 	ah->ar_op  = advert ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST);
344 
345 	memcpy(p, &ME->sll_addr, ah->ar_hln);
346 	p+=ME->sll_halen;
347 
348 	memcpy(p, &src, 4);
349 	p+=4;
350 
351 	if (advert)
352 		memcpy(p, &ME->sll_addr, ah->ar_hln);
353 	else
354 		memcpy(p, &HE->sll_addr, ah->ar_hln);
355 	p+=ah->ar_hln;
356 
357 	memcpy(p, &dst, 4);
358 	p+=4;
359 
360 	gettimeofday(&now, NULL);
361 	err = sendto(s, buf, p-buf, 0, (struct sockaddr*)HE, SLL_LEN(ah->ar_hln));
362 	if (err == p-buf) {
363 		last = now;
364 		sent++;
365 		if (!unicasting)
366 			brd_sent++;
367 	}
368 	return err;
369 }
370 
finish(void)371 static void finish(void)
372 {
373 	if (!quiet) {
374 		printf("Sent %d probes (%d broadcast(s))\n", sent, brd_sent);
375 		printf("Received %d response(s)", received);
376 		if (brd_recv || req_recv) {
377 			printf(" (");
378 			if (req_recv)
379 				printf("%d request(s)", req_recv);
380 			if (brd_recv)
381 				printf("%s%d broadcast(s)",
382 				       req_recv ? ", " : "",
383 				       brd_recv);
384 			printf(")");
385 		}
386 		printf("\n");
387 		fflush(stdout);
388 	}
389 	fflush(stdout);
390 	if (dad)
391 		exit(!!received);
392 	if (unsolicited)
393 		exit(0);
394 	exit(!received);
395 }
396 
catcher(void)397 static void catcher(void)
398 {
399 	struct timeval tv, tv_s, tv_o;
400 
401 	gettimeofday(&tv, NULL);
402 
403 	if (start.tv_sec==0)
404 		start = tv;
405 
406 	timersub(&tv, &start, &tv_s);
407 	tv_o.tv_sec = timeout;
408 	tv_o.tv_usec = 500 * 1000;
409 
410 	if (count-- == 0 || (timeout && timercmp(&tv_s, &tv_o, >)))
411 		finish();
412 
413 	timersub(&tv, &last, &tv_s);
414 	tv_o.tv_sec = 0;
415 
416 	if (last.tv_sec==0 || timercmp(&tv_s, &tv_o, >)) {
417 		send_pack(s, src, dst,
418 			  (struct sockaddr_ll *)&me, (struct sockaddr_ll *)&he);
419 		if (count == 0 && unsolicited)
420 			finish();
421 	}
422 	alarm(1);
423 }
424 
print_hex(unsigned char * p,int len)425 static void print_hex(unsigned char *p, int len)
426 {
427 	int i;
428 	for (i=0; i<len; i++) {
429 		printf("%02X", p[i]);
430 		if (i != len-1)
431 			printf(":");
432 	}
433 }
434 
recv_pack(unsigned char * buf,int len,struct sockaddr_ll * FROM)435 static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
436 {
437 	struct timeval tv;
438 	struct arphdr *ah = (struct arphdr*)buf;
439 	unsigned char *p = (unsigned char *)(ah+1);
440 	struct in_addr src_ip, dst_ip;
441 
442 	gettimeofday(&tv, NULL);
443 
444 	/* Filter out wild packets */
445 	if (FROM->sll_pkttype != PACKET_HOST &&
446 	    FROM->sll_pkttype != PACKET_BROADCAST &&
447 	    FROM->sll_pkttype != PACKET_MULTICAST)
448 		return 0;
449 
450 	/* Only these types are recognised */
451 	if (ah->ar_op != htons(ARPOP_REQUEST) &&
452 	    ah->ar_op != htons(ARPOP_REPLY))
453 		return 0;
454 
455 	/* ARPHRD check and this darned FDDI hack here :-( */
456 	if (ah->ar_hrd != htons(FROM->sll_hatype) &&
457 	    (FROM->sll_hatype != ARPHRD_FDDI || ah->ar_hrd != htons(ARPHRD_ETHER)))
458 		return 0;
459 
460 	/* Protocol must be IP. */
461 	if (ah->ar_pro != htons(ETH_P_IP))
462 		return 0;
463 	if (ah->ar_pln != 4)
464 		return 0;
465 	if (ah->ar_hln != ((struct sockaddr_ll *)&me)->sll_halen)
466 		return 0;
467 	if (len < sizeof(*ah) + 2*(4 + ah->ar_hln))
468 		return 0;
469 	memcpy(&src_ip, p+ah->ar_hln, 4);
470 	memcpy(&dst_ip, p+ah->ar_hln+4+ah->ar_hln, 4);
471 	if (!dad) {
472 		if (src_ip.s_addr != dst.s_addr)
473 			return 0;
474 		if (src.s_addr != dst_ip.s_addr)
475 			return 0;
476 		if (memcmp(p+ah->ar_hln+4, ((struct sockaddr_ll *)&me)->sll_addr, ah->ar_hln))
477 			return 0;
478 	} else {
479 		/* DAD packet was:
480 		   src_ip = 0 (or some src)
481 		   src_hw = ME
482 		   dst_ip = tested address
483 		   dst_hw = <unspec>
484 
485 		   We fail, if receive request/reply with:
486 		   src_ip = tested_address
487 		   src_hw != ME
488 		   if src_ip in request was not zero, check
489 		   also that it matches to dst_ip, otherwise
490 		   dst_ip/dst_hw do not matter.
491 		 */
492 		if (src_ip.s_addr != dst.s_addr)
493 			return 0;
494 		if (memcmp(p, ((struct sockaddr_ll *)&me)->sll_addr, ((struct sockaddr_ll *)&me)->sll_halen) == 0)
495 			return 0;
496 		if (src.s_addr && src.s_addr != dst_ip.s_addr)
497 			return 0;
498 	}
499 	if (!quiet) {
500 		int s_printed = 0;
501 		printf("%s ", FROM->sll_pkttype==PACKET_HOST ? "Unicast" : "Broadcast");
502 		printf("%s from ", ah->ar_op == htons(ARPOP_REPLY) ? "reply" : "request");
503 		printf("%s [", inet_ntoa(src_ip));
504 		print_hex(p, ah->ar_hln);
505 		printf("] ");
506 		if (dst_ip.s_addr != src.s_addr) {
507 			printf("for %s ", inet_ntoa(dst_ip));
508 			s_printed = 1;
509 		}
510 		if (memcmp(p+ah->ar_hln+4, ((struct sockaddr_ll *)&me)->sll_addr, ah->ar_hln)) {
511 			if (!s_printed)
512 				printf("for ");
513 			printf("[");
514 			print_hex(p+ah->ar_hln+4, ah->ar_hln);
515 			printf("]");
516 		}
517 		if (last.tv_sec) {
518 			long usecs = (tv.tv_sec-last.tv_sec) * 1000000 +
519 				tv.tv_usec-last.tv_usec;
520 			long msecs = (usecs+500)/1000;
521 			usecs -= msecs*1000 - 500;
522 			printf(" %ld.%03ldms\n", msecs, usecs);
523 		} else {
524 			printf(" UNSOLICITED?\n");
525 		}
526 		fflush(stdout);
527 	}
528 	received++;
529 	if (FROM->sll_pkttype != PACKET_HOST)
530 		brd_recv++;
531 	if (ah->ar_op == htons(ARPOP_REQUEST))
532 		req_recv++;
533 	if (quit_on_reply || (count == 0 && received == sent))
534 		finish();
535 	if(!broadcast_only) {
536 		memcpy(((struct sockaddr_ll *)&he)->sll_addr, p, ((struct sockaddr_ll *)&me)->sll_halen);
537 		unicasting=1;
538 	}
539 	return 1;
540 }
541 
542 #ifdef USE_SYSFS
543 union sysfs_devattr_value {
544 	unsigned long	ulong;
545 	void		*ptr;
546 };
547 
548 enum {
549 	SYSFS_DEVATTR_IFINDEX,
550 	SYSFS_DEVATTR_FLAGS,
551 	SYSFS_DEVATTR_ADDR_LEN,
552 #if 0
553 	SYSFS_DEVATTR_TYPE,
554 	SYSFS_DEVATTR_ADDRESS,
555 #endif
556 	SYSFS_DEVATTR_BROADCAST,
557 	SYSFS_DEVATTR_NUM
558 };
559 
560 struct sysfs_devattr_values
561 {
562 	char *ifname;
563 	union sysfs_devattr_value	value[SYSFS_DEVATTR_NUM];
564 };
565 
566 static int sysfs_devattr_ulong_dec(char *ptr, struct sysfs_devattr_values *v, unsigned idx);
567 static int sysfs_devattr_ulong_hex(char *ptr, struct sysfs_devattr_values *v, unsigned idx);
568 static int sysfs_devattr_macaddr(char *ptr, struct sysfs_devattr_values *v, unsigned idx);
569 
570 struct sysfs_devattrs {
571 	const char *name;
572 	int (*handler)(char *ptr, struct sysfs_devattr_values *v, unsigned int idx);
573 	int free;
574 } sysfs_devattrs[SYSFS_DEVATTR_NUM] = {
575 	[SYSFS_DEVATTR_IFINDEX] = {
576 		.name		= "ifindex",
577 		.handler	= sysfs_devattr_ulong_dec,
578 	},
579 	[SYSFS_DEVATTR_ADDR_LEN] = {
580 		.name		= "addr_len",
581 		.handler	= sysfs_devattr_ulong_dec,
582 	},
583 	[SYSFS_DEVATTR_FLAGS] = {
584 		.name		= "flags",
585 		.handler	= sysfs_devattr_ulong_hex,
586 	},
587 #if 0
588 	[SYSFS_DEVATTR_TYPE] = {
589 		.name		= "type",
590 		.handler	= sysfs_devattr_ulong_dec,
591 	},
592 	[SYSFS_DEVATTR_ADDRESS] = {
593 		.name		= "address",
594 		.handler	= sysfs_devattr_macaddr,
595 		.free		= 1,
596 	},
597 #endif
598 	[SYSFS_DEVATTR_BROADCAST] = {
599 		.name		= "broadcast",
600 		.handler	= sysfs_devattr_macaddr,
601 		.free		= 1,
602 	},
603 };
604 #endif
605 
byebye(int nsig)606 static void byebye(int nsig)
607 {
608     /* Avoid an "error exit" log message if we're killed */
609     nsig = 0;
610     exit(nsig);
611 }
612 
613 /*
614  * find_device()
615  *
616  * This function checks 1) if the device (if given) is okay for ARP,
617  * or 2) find fist appropriate device on the system.
618  *
619  * Return value:
620  *	>0	: Succeeded, and appropriate device not found.
621  *		  device.ifindex remains 0.
622  *	0	: Succeeded, and approptiate device found.
623  *		  device.ifindex is set.
624  *	<0	: Failed.  Support not found, or other
625  *		: system error.  Try other method.
626  *
627  * If an appropriate device found, it is recorded inside the
628  * "device" variable for later reference.
629  *
630  * We have several implementations for this.
631  *	by_ifaddrs():	requires getifaddr() in glibc, and rtnetlink in
632  *			kernel. default and recommended for recent systems.
633  *	by_sysfs():	requires libsysfs , and sysfs in kernel.
634  *	by_ioctl():	unable to list devices without ipv4 address; this
635  *			means, you need to supply the device name for
636  *			DAD purpose.
637  */
638 /* Common check for ifa->ifa_flags */
check_ifflags(unsigned int ifflags,int fatal)639 static int check_ifflags(unsigned int ifflags, int fatal)
640 {
641 	if (!(ifflags & IFF_UP)) {
642 		if (fatal) {
643 			if (!quiet)
644 				printf("Interface \"%s\" is down\n", device.name);
645 			exit(2);
646 		}
647 		return -1;
648 	}
649 	if (ifflags & (IFF_NOARP | IFF_LOOPBACK)) {
650 		if (fatal) {
651 			if (!quiet)
652 				printf("Interface \"%s\" is not ARPable\n", device.name);
653 			exit(dad ? 0 : 2);
654 		}
655 		return -1;
656 	}
657 	return 0;
658 }
659 
find_device_by_ifaddrs(void)660 static int find_device_by_ifaddrs(void)
661 {
662 #ifndef WITHOUT_IFADDRS
663 	int rc;
664 	struct ifaddrs *ifa0, *ifa;
665 	int count = 0;
666 
667 	rc = getifaddrs(&ifa0);
668 	if (rc) {
669 		perror("getifaddrs");
670 		return -1;
671 	}
672 
673 	for (ifa = ifa0; ifa; ifa = ifa->ifa_next) {
674 		if (!ifa->ifa_addr)
675 			continue;
676 		if (ifa->ifa_addr->sa_family != AF_PACKET)
677 			continue;
678 		if (device.name && ifa->ifa_name && strcmp(ifa->ifa_name, device.name))
679 			continue;
680 
681 		if (check_ifflags(ifa->ifa_flags, device.name != NULL) < 0)
682 			continue;
683 
684 		if (!((struct sockaddr_ll *)ifa->ifa_addr)->sll_halen)
685 			continue;
686 		if (!ifa->ifa_broadaddr)
687 			continue;
688 
689 		device.ifa = ifa;
690 
691 		if (count++)
692 			break;
693 	}
694 
695 	if (count == 1 && device.ifa) {
696 		device.ifindex = if_nametoindex(device.ifa->ifa_name);
697 		if (!device.ifindex) {
698 			perror("arping: if_nametoindex");
699 			freeifaddrs(ifa0);
700 			return -1;
701 		}
702 		device.name  = device.ifa->ifa_name;
703 		return 0;
704 	}
705 	return 1;
706 #else
707 	return -1;
708 #endif
709 }
710 
711 #ifdef USE_SYSFS
sysfs_devattr_values_init(struct sysfs_devattr_values * v,int do_free)712 static void sysfs_devattr_values_init(struct sysfs_devattr_values *v, int do_free)
713 {
714 	int i;
715 	if (do_free) {
716 		free(v->ifname);
717 		for (i = 0; i < SYSFS_DEVATTR_NUM; i++) {
718 			if (sysfs_devattrs[i].free)
719 				free(v->value[i].ptr);
720 		}
721 	}
722 	memset(v, 0, sizeof(*v));
723 }
724 
sysfs_devattr_ulong(char * ptr,struct sysfs_devattr_values * v,unsigned int idx,unsigned int base)725 static int sysfs_devattr_ulong(char *ptr, struct sysfs_devattr_values *v, unsigned int idx,
726 				     unsigned int base)
727 {
728 	unsigned long *p;
729 	char *ep;
730 
731 	if (!ptr || !v)
732 		return -1;
733 
734 	p = &v->value[idx].ulong;
735 	errno = 0;
736 	*p = strtoul(ptr, &ep, base);
737 	if ((*ptr && isspace(*ptr & 0xff)) || errno || (*ep != '\0' && *ep != '\n'))
738 		goto out;
739 
740 	return 0;
741 out:
742 	return -1;
743 }
744 
sysfs_devattr_ulong_dec(char * ptr,struct sysfs_devattr_values * v,unsigned int idx)745 static int sysfs_devattr_ulong_dec(char *ptr, struct sysfs_devattr_values *v, unsigned int idx)
746 {
747 	int rc = sysfs_devattr_ulong(ptr, v, idx, 10);
748 	return rc;
749 }
750 
sysfs_devattr_ulong_hex(char * ptr,struct sysfs_devattr_values * v,unsigned int idx)751 static int sysfs_devattr_ulong_hex(char *ptr, struct sysfs_devattr_values *v, unsigned int idx)
752 {
753 	int rc = sysfs_devattr_ulong(ptr, v, idx, 16);
754 	return rc;
755 }
756 
sysfs_devattr_macaddr(char * ptr,struct sysfs_devattr_values * v,unsigned int idx)757 static int sysfs_devattr_macaddr(char *ptr, struct sysfs_devattr_values *v, unsigned int idx)
758 {
759 	unsigned char *m;
760 	int i;
761 	unsigned int addrlen;
762 
763 	if (!ptr || !v)
764 		return -1;
765 
766 	addrlen = v->value[SYSFS_DEVATTR_ADDR_LEN].ulong;
767 	m = malloc(addrlen);
768 
769 	for (i = 0; i < addrlen; i++) {
770 		if (i && *(ptr + i * 3 - 1) != ':')
771 			goto out;
772 		if (sscanf(ptr + i * 3, "%02hhx", &m[i]) != 1)
773 			goto out;
774 	}
775 
776 	v->value[idx].ptr = m;
777 	return 0;
778 out:
779 	free(m);
780 	return -1;
781 }
782 #endif
783 
find_device_by_sysfs(void)784 static int find_device_by_sysfs(void)
785 {
786 	int rc = -1;
787 #ifdef USE_SYSFS
788 	struct sysfs_class *cls_net;
789 	struct dlist *dev_list;
790 	struct sysfs_class_device *dev;
791 	struct sysfs_attribute *dev_attr;
792 	struct sysfs_devattr_values sysfs_devattr_values;
793 	int count = 0;
794 
795 	if (!device.sysfs) {
796 		device.sysfs = malloc(sizeof(*device.sysfs));
797 		sysfs_devattr_values_init(device.sysfs, 0);
798 	}
799 
800 	cls_net = sysfs_open_class("net");
801 	if (!cls_net) {
802 		perror("sysfs_open_class");
803 		return -1;
804 	}
805 
806 	dev_list = sysfs_get_class_devices(cls_net);
807 	if (!dev_list) {
808 		perror("sysfs_get_class_devices");
809 		goto out;
810 	}
811 
812 	sysfs_devattr_values_init(&sysfs_devattr_values, 0);
813 
814 	dlist_for_each_data(dev_list, dev, struct sysfs_class_device) {
815 		int i;
816 		int rc = -1;
817 
818 		if (device.name && strcmp(dev->name, device.name))
819 			goto do_next;
820 
821 		sysfs_devattr_values_init(&sysfs_devattr_values, 1);
822 
823 		for (i = 0; i < SYSFS_DEVATTR_NUM; i++) {
824 
825 			dev_attr = sysfs_get_classdev_attr(dev, sysfs_devattrs[i].name);
826 			if (!dev_attr) {
827 				perror("sysfs_get_classdev_attr");
828 				rc = -1;
829 				break;
830 			}
831 			if (sysfs_read_attribute(dev_attr)) {
832 				perror("sysfs_read_attribute");
833 				rc = -1;
834 				break;
835 			}
836 			rc = sysfs_devattrs[i].handler(dev_attr->value, &sysfs_devattr_values, i);
837 
838 			if (rc < 0)
839 				break;
840 		}
841 
842 		if (rc < 0)
843 			goto do_next;
844 
845 		if (check_ifflags(sysfs_devattr_values.value[SYSFS_DEVATTR_FLAGS].ulong,
846 				  device.name != NULL) < 0)
847 			goto do_next;
848 
849 		if (!sysfs_devattr_values.value[SYSFS_DEVATTR_ADDR_LEN].ulong)
850 			goto do_next;
851 
852 		if (device.sysfs->value[SYSFS_DEVATTR_IFINDEX].ulong) {
853 			if (device.sysfs->value[SYSFS_DEVATTR_FLAGS].ulong & IFF_RUNNING)
854 				goto do_next;
855 		}
856 
857 		sysfs_devattr_values.ifname = strdup(dev->name);
858 		if (!sysfs_devattr_values.ifname) {
859 			perror("malloc");
860 			goto out;
861 		}
862 
863 		sysfs_devattr_values_init(device.sysfs, 1);
864 		memcpy(device.sysfs, &sysfs_devattr_values, sizeof(*device.sysfs));
865 		sysfs_devattr_values_init(&sysfs_devattr_values, 0);
866 
867 		if (count++)
868 			break;
869 
870 		continue;
871 do_next:
872 		sysfs_devattr_values_init(&sysfs_devattr_values, 1);
873 	}
874 
875 	if (count == 1) {
876 		device.ifindex = device.sysfs->value[SYSFS_DEVATTR_IFINDEX].ulong;
877 		device.name = device.sysfs->ifname;
878 	}
879 	rc = !device.ifindex;
880 out:
881 	sysfs_close_class(cls_net);
882 #endif
883 	return rc;
884 }
885 
check_device_by_ioctl(int s,struct ifreq * ifr)886 static int check_device_by_ioctl(int s, struct ifreq *ifr)
887 {
888 	if (ioctl(s, SIOCGIFFLAGS, ifr) < 0) {
889 		perror("ioctl(SIOCGIFINDEX");
890 		return -1;
891 	}
892 
893 	if (check_ifflags(ifr->ifr_flags, device.name != NULL) < 0)
894 		return 1;
895 
896 	if (ioctl(s, SIOCGIFINDEX, ifr) < 0) {
897 		perror("ioctl(SIOCGIFINDEX");
898 		return -1;
899 	}
900 
901 	return 0;
902 }
903 
find_device_by_ioctl(void)904 static int find_device_by_ioctl(void)
905 {
906 	int s;
907 	struct ifreq *ifr0, *ifr, *ifr_end;
908 	size_t ifrsize = sizeof(*ifr);
909 	struct ifconf ifc;
910 	static struct ifreq ifrbuf;
911 	int count = 0;
912 
913 	s = socket(AF_INET, SOCK_DGRAM, 0);
914 	if (s < 0) {
915 		perror("socket");
916 		return -1;
917 	}
918 
919 	memset(&ifrbuf, 0, sizeof(ifrbuf));
920 
921 	if (device.name) {
922 		strncpy(ifrbuf.ifr_name, device.name, sizeof(ifrbuf.ifr_name) - 1);
923 		if (check_device_by_ioctl(s, &ifrbuf))
924 			goto out;
925 		count++;
926 	} else {
927 		do {
928 			int rc;
929 			ifr0 = malloc(ifrsize);
930 			if (!ifr0) {
931 				perror("malloc");
932 				goto out;
933 			}
934 
935 			ifc.ifc_buf = (char *)ifr0;
936 			ifc.ifc_len = ifrsize;
937 
938 			rc = ioctl(s, SIOCGIFCONF, &ifc);
939 			if (rc < 0) {
940 				perror("ioctl(SIOCFIFCONF");
941 				goto out;
942 			}
943 
944 			if (ifc.ifc_len + sizeof(*ifr0) + sizeof(struct sockaddr_storage) - sizeof(struct sockaddr) <= ifrsize)
945 				break;
946 			ifrsize *= 2;
947 			free(ifr0);
948 			ifr0 = NULL;
949 		} while(ifrsize < INT_MAX / 2);
950 
951 		if (!ifr0) {
952 			fprintf(stderr, "arping: too many interfaces!?\n");
953 			goto out;
954 		}
955 
956 		ifr_end = (struct ifreq *)(((char *)ifr0) + ifc.ifc_len - sizeof(*ifr0));
957 		for (ifr = ifr0; ifr <= ifr_end; ifr++) {
958 			if (check_device_by_ioctl(s, &ifrbuf))
959 				continue;
960 			memcpy(&ifrbuf.ifr_name, ifr->ifr_name, sizeof(ifrbuf.ifr_name));
961 			if (count++)
962 				break;
963 		}
964 	}
965 
966 	close(s);
967 
968 	if (count == 1) {
969 		device.ifindex = ifrbuf.ifr_ifindex;
970 		device.name = ifrbuf.ifr_name;
971 	}
972 	return !device.ifindex;
973 out:
974 	close(s);
975 	return -1;
976 }
977 
find_device(void)978 static int find_device(void)
979 {
980 	int rc;
981 	rc = find_device_by_ifaddrs();
982 	if (rc >= 0)
983 		goto out;
984 	rc = find_device_by_sysfs();
985 	if (rc >= 0)
986 		goto out;
987 	rc = find_device_by_ioctl();
988 out:
989 	return rc;
990 }
991 
992 /*
993  * set_device_broadcast()
994  *
995  * This fills the device "broadcast address"
996  * based on information found by find_device() funcion.
997  */
set_device_broadcast_ifaddrs_one(struct device * device,unsigned char * ba,size_t balen,int fatal)998 static int set_device_broadcast_ifaddrs_one(struct device *device, unsigned char *ba, size_t balen, int fatal)
999 {
1000 #ifndef WITHOUT_IFADDRS
1001 	struct ifaddrs *ifa;
1002 	struct sockaddr_ll *sll;
1003 
1004 	if (!device)
1005 		return -1;
1006 
1007 	ifa = device->ifa;
1008 	if (!ifa)
1009 		return -1;
1010 
1011 	sll = (struct sockaddr_ll *)ifa->ifa_broadaddr;
1012 
1013 	if (sll->sll_halen != balen) {
1014 		if (fatal) {
1015 			if (!quiet)
1016 				printf("Address length does not match...\n");
1017 			exit(2);
1018 		}
1019 		return -1;
1020 	}
1021 	memcpy(ba, sll->sll_addr, sll->sll_halen);
1022 	return 0;
1023 #else
1024 	return -1;
1025 #endif
1026 }
set_device_broadcast_sysfs(struct device * device,unsigned char * ba,size_t balen)1027 static int set_device_broadcast_sysfs(struct device *device, unsigned char *ba, size_t balen)
1028 {
1029 #ifdef USE_SYSFS
1030 	struct sysfs_devattr_values *v;
1031 	if (!device)
1032 		return -1;
1033 	v = device->sysfs;
1034 	if (!v)
1035 		return -1;
1036 	if (v->value[SYSFS_DEVATTR_ADDR_LEN].ulong != balen)
1037 		return -1;
1038 	memcpy(ba, v->value[SYSFS_DEVATTR_BROADCAST].ptr, balen);
1039 	return 0;
1040 #else
1041 	return -1;
1042 #endif
1043 }
1044 
set_device_broadcast_fallback(struct device * device,unsigned char * ba,size_t balen)1045 static int set_device_broadcast_fallback(struct device *device, unsigned char *ba, size_t balen)
1046 {
1047 	if (!quiet)
1048 		fprintf(stderr, "WARNING: using default broadcast address.\n");
1049 	memset(ba, -1, balen);
1050 	return 0;
1051 }
1052 
set_device_broadcast(struct device * dev,unsigned char * ba,size_t balen)1053 static void set_device_broadcast(struct device *dev, unsigned char *ba, size_t balen)
1054 {
1055 	if (!set_device_broadcast_ifaddrs_one(dev, ba, balen, 0))
1056 		return;
1057 	if (!set_device_broadcast_sysfs(dev, ba, balen))
1058 		return;
1059 	set_device_broadcast_fallback(dev, ba, balen);
1060 }
1061 
1062 int
main(int argc,char ** argv)1063 main(int argc, char **argv)
1064 {
1065 	int socket_errno;
1066 	int ch;
1067 	int hb_mode = 0;
1068 
1069 	signal(SIGTERM, byebye);
1070 	signal(SIGPIPE, byebye);
1071 
1072 	limit_capabilities();
1073 
1074 #ifdef USE_IDN
1075 	setlocale(LC_ALL, "");
1076 #endif
1077 
1078 	enable_capability_raw();
1079 
1080 	s = socket(PF_PACKET, SOCK_DGRAM, 0);
1081 	socket_errno = errno;
1082 
1083 	disable_capability_raw();
1084 
1085 	while ((ch = getopt(argc, argv, "h?bfDUAqc:w:s:I:Vr:i:p:")) != EOF) {
1086 		switch(ch) {
1087 		case 'b':
1088 			broadcast_only=1;
1089 			break;
1090 		case 'D':
1091 			dad++;
1092 			quit_on_reply=1;
1093 			break;
1094 		case 'U':
1095 			unsolicited++;
1096 			break;
1097 		case 'A':
1098 			advert++;
1099 			unsolicited++;
1100 			break;
1101 		case 'q':
1102 			quiet++;
1103 			break;
1104 		case 'r': /* send_arp.libnet compatibility option */
1105 			hb_mode = 1;
1106 			/* fall-through */
1107 		case 'c':
1108 			count = atoi(optarg);
1109 			break;
1110 		case 'w':
1111 			timeout = atoi(optarg);
1112 			break;
1113 		case 'I':
1114 			device.name = optarg;
1115 			break;
1116 		case 'f':
1117 			quit_on_reply=1;
1118 			break;
1119 		case 's':
1120 			source = optarg;
1121 			break;
1122 		case 'V':
1123 			printf("send_arp utility, based on arping from iputils-%s\n", SNAPSHOT);
1124 			exit(0);
1125 		case 'p':
1126 		case 'i':
1127 		    hb_mode = 1;
1128 		    /* send_arp.libnet compatibility options, ignore */
1129 		    break;
1130 		case 'h':
1131 		case '?':
1132 		default:
1133 			usage();
1134 		}
1135 	}
1136 
1137 	if(hb_mode) {
1138 	    /* send_arp.libnet compatibility mode */
1139 	    if (argc - optind != 5) {
1140 		usage();
1141 		return 1;
1142 	    }
1143 	    /*
1144 	     *	argv[optind+1] DEVICE		dc0,eth0:0,hme0:0,
1145 	     *	argv[optind+2] IP		192.168.195.186
1146 	     *	argv[optind+3] MAC ADDR		00a0cc34a878
1147 	     *	argv[optind+4] BROADCAST	192.168.195.186
1148 	     *	argv[optind+5] NETMASK		ffffffffffff
1149 	     */
1150 
1151 	    unsolicited = 1;
1152 	    device.name = argv[optind];
1153 	    target = argv[optind+1];
1154             if (strcmp(argv[optind+2], "auto")) {
1155 		fprintf(stderr, "send_arp.linux: Gratuitous ARPs are not sent in the Cluster IP configuration\n");
1156                 /* return success to suppress an error log by the RA */
1157 		exit(0);
1158             }
1159 
1160 	} else {
1161 	    argc -= optind;
1162 	    argv += optind;
1163 	    if (argc != 1)
1164 		usage();
1165 
1166 	    target = *argv;
1167 	}
1168 
1169 	if (device.name && !*device.name)
1170 		device.name = NULL;
1171 
1172 	if (s < 0) {
1173 		errno = socket_errno;
1174 		perror("arping: socket");
1175 		exit(2);
1176 	}
1177 
1178 	if (find_device() < 0)
1179 		exit(2);
1180 
1181 	if (!device.ifindex) {
1182 		if (device.name) {
1183 			fprintf(stderr, "arping: Device %s not available.\n", device.name);
1184 			exit(2);
1185 		}
1186 		fprintf(stderr, "arping: device (option -I) is required.\n");
1187 		usage();
1188 	}
1189 
1190 	if (inet_aton(target, &dst) != 1) {
1191 		struct hostent *hp;
1192 		char *idn = target;
1193 #ifdef USE_IDN
1194 		int rc;
1195 
1196 		rc = idna_to_ascii_lz(target, &idn, 0);
1197 
1198 		if (rc != IDNA_SUCCESS) {
1199 			fprintf(stderr, "arping: IDN encoding failed: %s\n", idna_strerror(rc));
1200 			exit(2);
1201 		}
1202 #endif
1203 
1204 		hp = gethostbyname2(idn, AF_INET);
1205 		if (!hp) {
1206 			fprintf(stderr, "arping: unknown host %s\n", target);
1207 			exit(2);
1208 		}
1209 
1210 #ifdef USE_IDN
1211 		free(idn);
1212 #endif
1213 
1214 		memcpy(&dst, hp->h_addr, 4);
1215 	}
1216 
1217 	if (source && inet_aton(source, &src) != 1) {
1218 		fprintf(stderr, "arping: invalid source %s\n", source);
1219 		exit(2);
1220 	}
1221 
1222 	if (!dad && unsolicited && src.s_addr == 0)
1223 		src = dst;
1224 
1225 	if (!dad || src.s_addr) {
1226 		struct sockaddr_in saddr;
1227 		int probe_fd = socket(AF_INET, SOCK_DGRAM, 0);
1228 
1229 		if (probe_fd < 0) {
1230 			perror("socket");
1231 			exit(2);
1232 		}
1233 		if (device.name) {
1234 			enable_capability_raw();
1235 
1236 			if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device.name, strlen(device.name)+1) == -1)
1237 				perror("WARNING: interface is ignored");
1238 
1239 			disable_capability_raw();
1240 		}
1241 		memset(&saddr, 0, sizeof(saddr));
1242 		saddr.sin_family = AF_INET;
1243 		if (src.s_addr) {
1244 			saddr.sin_addr = src;
1245 			if (bind(probe_fd, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) {
1246 				perror("bind");
1247 				exit(2);
1248 			}
1249 		} else if (!dad) {
1250 			int on = 1;
1251 			socklen_t alen = sizeof(saddr);
1252 
1253 			saddr.sin_port = htons(1025);
1254 			saddr.sin_addr = dst;
1255 
1256 			if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, (char*)&on, sizeof(on)) == -1)
1257 				perror("WARNING: setsockopt(SO_DONTROUTE)");
1258 			if (connect(probe_fd, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) {
1259 				perror("connect");
1260 				exit(2);
1261 			}
1262 			if (getsockname(probe_fd, (struct sockaddr*)&saddr, &alen) == -1) {
1263 				perror("getsockname");
1264 				exit(2);
1265 			}
1266 			src = saddr.sin_addr;
1267 		}
1268 		close(probe_fd);
1269 	};
1270 
1271 	((struct sockaddr_ll *)&me)->sll_family = AF_PACKET;
1272 	((struct sockaddr_ll *)&me)->sll_ifindex = device.ifindex;
1273 	((struct sockaddr_ll *)&me)->sll_protocol = htons(ETH_P_ARP);
1274 	if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) {
1275 		perror("bind");
1276 		exit(2);
1277 	}
1278 
1279 	if (1) {
1280 		socklen_t alen = sizeof(me);
1281 		if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) {
1282 			perror("getsockname");
1283 			exit(2);
1284 		}
1285 	}
1286 	if (((struct sockaddr_ll *)&me)->sll_halen == 0) {
1287 		if (!quiet)
1288 			printf("Interface \"%s\" is not ARPable (no ll address)\n", device.name);
1289 		exit(dad?0:2);
1290 	}
1291 
1292 	he = me;
1293 
1294 	set_device_broadcast(&device, ((struct sockaddr_ll *)&he)->sll_addr,
1295 			     ((struct sockaddr_ll *)&he)->sll_halen);
1296 
1297 	if (!quiet) {
1298 		printf("ARPING %s ", inet_ntoa(dst));
1299 		printf("from %s %s\n",  inet_ntoa(src), device.name ? : "");
1300 	}
1301 
1302 	if (!src.s_addr && !dad) {
1303 		fprintf(stderr, "arping: no source address in not-DAD mode\n");
1304 		exit(2);
1305 	}
1306 
1307 	drop_capabilities();
1308 
1309 	set_signal(SIGINT, finish);
1310 	set_signal(SIGALRM, catcher);
1311 
1312 	catcher();
1313 
1314 	while(1) {
1315 		sigset_t sset, osset;
1316 		unsigned char packet[4096];
1317 		struct sockaddr_storage from;
1318 		socklen_t alen = sizeof(from);
1319 		int cc;
1320 
1321 		if ((cc = recvfrom(s, packet, sizeof(packet), 0,
1322 				   (struct sockaddr *)&from, &alen)) < 0) {
1323 			perror("arping: recvfrom");
1324 			continue;
1325 		}
1326 
1327 		sigemptyset(&sset);
1328 		sigaddset(&sset, SIGALRM);
1329 		sigaddset(&sset, SIGINT);
1330 		sigprocmask(SIG_BLOCK, &sset, &osset);
1331 		recv_pack(packet, cc, (struct sockaddr_ll *)&from);
1332 		sigprocmask(SIG_SETMASK, &osset, NULL);
1333 	}
1334 }
1335 
1336 
1337