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