/* vi: set sw=4 ts=4: */
/*
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 *
 * Author: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
 * Busybox port: Nick Fedchik <nick@fedchik.org.ua>
 */
//config:config ARPING
//config:	bool "arping (9 kb)"
//config:	default y
//config:	help
//config:	Ping hosts by ARP packets.

//applet:IF_ARPING(APPLET(arping, BB_DIR_USR_SBIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_ARPING) += arping.o

//usage:#define arping_trivial_usage
//usage:       "[-fqbDUA] [-c CNT] [-w TIMEOUT] [-I IFACE] [-s SRC_IP] DST_IP"
//usage:#define arping_full_usage "\n\n"
//usage:       "Send ARP requests/replies\n"
//usage:     "\n	-f		Quit on first ARP reply"
//usage:     "\n	-q		Quiet"
//usage:     "\n	-b		Keep broadcasting, don't go unicast"
//usage:     "\n	-D		Exit with 1 if DST_IP replies"
//usage:     "\n	-U		Unsolicited ARP mode, update your neighbors"
//usage:     "\n	-A		ARP answer mode, update your neighbors"
//usage:     "\n	-c N		Stop after sending N ARP requests"
//usage:     "\n	-w TIMEOUT	Seconds to wait for ARP reply"
//NB: in iputils-s20160308, iface is mandatory, no default
//usage:     "\n	-I IFACE	Interface to use (default eth0)"
//usage:     "\n	-s SRC_IP	Sender IP address"
//usage:     "\n	DST_IP		Target IP address"

#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <netpacket/packet.h>

#include "libbb.h"
#include "common_bufsiz.h"

/* We don't expect to see 1000+ seconds delay, unsigned is enough */
#define MONOTONIC_US() ((unsigned)monotonic_us())

enum {
	UNSOLICITED   = 1 << 0,
	DAD           = 1 << 1,
	ADVERT        = 1 << 2,
	QUIET         = 1 << 3,
	QUIT_ON_REPLY = 1 << 4,
	BCAST_ONLY    = 1 << 5,
	UNICASTING    = 1 << 6,
	TIMEOUT       = 1 << 7,
};
#define GETOPT32(str_timeout, device, source) \
	getopt32(argv, "^" \
		"UDAqfbc:+w:I:s:" \
		/* DAD also sets quit_on_reply, */ \
		/* advert also sets unsolicited: */ \
		"\0" "=1:Df:AU", \
		&count, &str_timeout, &device, &source \
	);

struct globals {
	struct in_addr src;
	struct in_addr dst;
	struct sockaddr_ll me;
	struct sockaddr_ll he;

	int count; // = -1;
	unsigned last;
	unsigned timeout_us;
	unsigned start;

	unsigned sent;
	unsigned brd_sent;
	unsigned received;
	unsigned brd_recv;
	unsigned req_recv;

	/* should be in main(), but are here to reduce stack use: */
	struct ifreq ifr;
	struct sockaddr_in probe_saddr;
	sigset_t sset;
	unsigned char packet[4096];
} FIX_ALIASING;
#define src        (G.src       )
#define dst        (G.dst       )
#define me         (G.me        )
#define he         (G.he        )
#define count      (G.count     )
#define last       (G.last      )
#define timeout_us (G.timeout_us)
#define start      (G.start     )
#define sent       (G.sent      )
#define brd_sent   (G.brd_sent  )
#define received   (G.received  )
#define brd_recv   (G.brd_recv  )
#define req_recv   (G.req_recv  )
//#define G (*(struct globals*)bb_common_bufsiz1)
#define G (*ptr_to_globals)
#define INIT_G() do { \
	/*setup_common_bufsiz();*/ \
	SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
	count = -1; \
} while (0)

#define sock_fd 3

static int send_pack(struct in_addr *src_addr,
			struct in_addr *dst_addr,
			struct sockaddr_ll *ME,
			struct sockaddr_ll *HE)
{
	int err;
	unsigned char buf[256];
	struct arphdr *ah = (struct arphdr *) buf;
	unsigned char *p;

	ah->ar_hrd = htons(ARPHRD_ETHER);
	ah->ar_pro = htons(ETH_P_IP);
	ah->ar_hln = ME->sll_halen;
	ah->ar_pln = 4;
	ah->ar_op = option_mask32 & ADVERT ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST);

	p = (unsigned char *) (ah + 1);
	p = mempcpy(p, &ME->sll_addr, ah->ar_hln);
	p = mempcpy(p, src_addr, 4);

	if (option_mask32 & ADVERT)
		p = mempcpy(p, &ME->sll_addr, ah->ar_hln);
	else
		p = mempcpy(p, &HE->sll_addr, ah->ar_hln);

	p = mempcpy(p, dst_addr, 4);

	err = sendto(sock_fd, buf, p - buf, 0, (struct sockaddr *) HE, sizeof(*HE));
	if (err == p - buf) {
		last = MONOTONIC_US();
		sent++;
		if (!(option_mask32 & UNICASTING))
			brd_sent++;
	}
	return err;
}

static void finish(void) NORETURN;
static void finish(void)
{
	if (!(option_mask32 & QUIET)) {
		printf("Sent %u probe(s) (%u broadcast(s))\n"
			"Received %u response(s)"
			" (%u request(s), %u broadcast(s))\n",
			sent, brd_sent,
			received,
			req_recv, brd_recv);
	}
	if (option_mask32 & DAD)
		exit(!!received);
	if (option_mask32 & UNSOLICITED)
		exit(EXIT_SUCCESS);
	exit(!received);
}

static void catcher(void)
{
	unsigned now;

	now = MONOTONIC_US();
	if (start == 0)
		start = now;

	if (count == 0 || (timeout_us && (now - start) > timeout_us))
		finish();

	/* count < 0 means "infinite count" */
	if (count > 0)
		count--;

	if (last == 0 || (now - last) > 500000) {
		send_pack(&src, &dst, &me, &he);
		if (count == 0 && (option_mask32 & UNSOLICITED))
			finish();
	}
	alarm(1);
}

static void recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
{
	struct arphdr *ah = (struct arphdr *) buf;
	unsigned char *p = (unsigned char *) (ah + 1);
	struct in_addr src_ip, dst_ip;

	/* moves below assume in_addr is 4 bytes big, ensure that */
	BUILD_BUG_ON(sizeof(struct in_addr) != 4);
	BUILD_BUG_ON(sizeof(src_ip.s_addr) != 4);

	/* Filter out wild packets */
	if (FROM->sll_pkttype != PACKET_HOST
	 && FROM->sll_pkttype != PACKET_BROADCAST
	 && FROM->sll_pkttype != PACKET_MULTICAST)
		return;

	/* Only these types are recognized */
	if (ah->ar_op != htons(ARPOP_REQUEST) && ah->ar_op != htons(ARPOP_REPLY))
		return;

	/* ARPHRD check and this darned FDDI hack here :-( */
	if (ah->ar_hrd != htons(FROM->sll_hatype)
	 && (FROM->sll_hatype != ARPHRD_FDDI || ah->ar_hrd != htons(ARPHRD_ETHER)))
		return;

	/* Protocol must be IP. */
	if (ah->ar_pro != htons(ETH_P_IP)
	 || (ah->ar_pln != 4)
	 || (ah->ar_hln != me.sll_halen)
	 || (len < (int)(sizeof(*ah) + 2 * (4 + ah->ar_hln)))
	) {
		return;
	}

	move_from_unaligned32(src_ip.s_addr, p + ah->ar_hln);
	move_from_unaligned32(dst_ip.s_addr, p + ah->ar_hln + 4 + ah->ar_hln);

	if (dst.s_addr != src_ip.s_addr)
		return;
	if (!(option_mask32 & DAD)) {
		if ((src.s_addr != dst_ip.s_addr)
		 || (memcmp(p + ah->ar_hln + 4, &me.sll_addr, ah->ar_hln)))
			return;
	} else {
		/* DAD packet was:
		   src_ip = 0 (or some src)
		   src_hw = ME
		   dst_ip = tested address
		   dst_hw = <unspec>

		   We fail, if receive request/reply with:
		   src_ip = tested_address
		   src_hw != ME
		   if src_ip in request was not zero, check
		   also that it matches to dst_ip, otherwise
		   dst_ip/dst_hw do not matter.
		 */
		if ((memcmp(p, &me.sll_addr, me.sll_halen) == 0)
		 || (src.s_addr && src.s_addr != dst_ip.s_addr))
			return;
	}
	if (!(option_mask32 & QUIET)) {
		int s_printed = 0;

//TODO: arping from iputils-s20160308 print upprcase hex in MAC, follow them?
		printf("%scast re%s from %s [%02x:%02x:%02x:%02x:%02x:%02x]",
			FROM->sll_pkttype == PACKET_HOST ? "Uni" : "Broad",
			ah->ar_op == htons(ARPOP_REPLY) ? "ply" : "quest",
			inet_ntoa(src_ip),
			p[0], p[1], p[2], p[3], p[4], p[5]
		);
		if (dst_ip.s_addr != src.s_addr) {
			printf("for %s", inet_ntoa(dst_ip));
			s_printed = 1;
		}
		if (memcmp(p + ah->ar_hln + 4, me.sll_addr, ah->ar_hln)) {
			unsigned char *pp = p + ah->ar_hln + 4;
			if (!s_printed)
				printf(" for");
			printf(" [%02x:%02x:%02x:%02x:%02x:%02x]",
				pp[0], pp[1], pp[2], pp[3], pp[4], pp[5]
			);
		}

		if (last) {
			unsigned diff = MONOTONIC_US() - last;
			printf(" %u.%03ums\n", diff / 1000, diff % 1000);
		} else {
			puts(" UNSOLICITED?");
		}
		fflush_all();
	}
	received++;
	if (FROM->sll_pkttype != PACKET_HOST)
		brd_recv++;
	if (ah->ar_op == htons(ARPOP_REQUEST))
		req_recv++;
	if (option_mask32 & QUIT_ON_REPLY)
		finish();
	if (!(option_mask32 & BCAST_ONLY)) {
		memcpy(he.sll_addr, p, me.sll_halen);
		option_mask32 |= UNICASTING;
	}
}

int arping_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int arping_main(int argc UNUSED_PARAM, char **argv)
{
	const char *device = "eth0";
	char *source = NULL;
	char *target;
	char *err_str;

	INIT_G();

	xmove_fd(xsocket(AF_PACKET, SOCK_DGRAM, 0), sock_fd);

	// If you ever change BB_SUID_DROP to BB_SUID_REQUIRE,
	// drop suid root privileges here:
	//xsetuid(getuid());

	{
		unsigned opt;
		char *str_timeout;

		opt = GETOPT32(str_timeout, device, source);
		if (opt & TIMEOUT)
			timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000;
	}

	target = argv[optind];
	err_str = xasprintf("interface %s %%s", device);
	xfunc_error_retval = 2;

	/*memset(&G.ifr, 0, sizeof(G.ifr)); - zeroed by INIT_G */
	strncpy_IFNAMSIZ(G.ifr.ifr_name, device);
	ioctl_or_perror_and_die(sock_fd, SIOCGIFINDEX, &G.ifr, err_str, "not found");
	me.sll_ifindex = G.ifr.ifr_ifindex;

	xioctl(sock_fd, SIOCGIFFLAGS, (char *) &G.ifr);

	if (!(G.ifr.ifr_flags & IFF_UP)) {
		bb_error_msg_and_die(err_str, "is down");
	}
	if (G.ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) {
		bb_error_msg(err_str, "is not ARPable");
		BUILD_BUG_ON(DAD != 2);
		/* exit 0 if DAD, else exit 2 */
		return (~option_mask32 & DAD);
	}

	/* if (!inet_aton(target, &dst)) - not needed */ {
		len_and_sockaddr *lsa;
		lsa = xhost_and_af2sockaddr(target, 0, AF_INET);
		dst = lsa->u.sin.sin_addr;
		if (ENABLE_FEATURE_CLEAN_UP)
			free(lsa);
	}

	if (source && !inet_aton(source, &src)) {
		bb_error_msg_and_die("invalid source address %s", source);
	}

	if ((option_mask32 & (DAD|UNSOLICITED)) == UNSOLICITED && src.s_addr == 0)
		src = dst;

	if (!(option_mask32 & DAD) || src.s_addr) {
		/*struct sockaddr_in probe_saddr;*/
		int probe_fd = xsocket(AF_INET, SOCK_DGRAM, 0);

		setsockopt_bindtodevice(probe_fd, device);

		/*memset(&G.probe_saddr, 0, sizeof(G.probe_saddr)); - zeroed by INIT_G */
		G.probe_saddr.sin_family = AF_INET;
		if (src.s_addr) {
			/* Check that this is indeed our IP */
			G.probe_saddr.sin_addr = src;
			xbind(probe_fd, (struct sockaddr *) &G.probe_saddr, sizeof(G.probe_saddr));
		} else { /* !(option_mask32 & DAD) case */
			/* Find IP address on this iface */
			G.probe_saddr.sin_port = htons(1025);
			G.probe_saddr.sin_addr = dst;

			if (setsockopt_SOL_SOCKET_1(probe_fd, SO_DONTROUTE) != 0)
				bb_perror_msg("setsockopt(%s)", "SO_DONTROUTE");
			xconnect(probe_fd, (struct sockaddr *) &G.probe_saddr, sizeof(G.probe_saddr));
			bb_getsockname(probe_fd, (struct sockaddr *) &G.probe_saddr, sizeof(G.probe_saddr));
			if (G.probe_saddr.sin_family != AF_INET)
				bb_simple_error_msg_and_die("no IP address configured");
			src = G.probe_saddr.sin_addr;
		}
		close(probe_fd);
	}

	me.sll_family = AF_PACKET;
	//me.sll_ifindex = ifindex; - done before
	me.sll_protocol = htons(ETH_P_ARP);
	xbind(sock_fd, (struct sockaddr *) &me, sizeof(me));

	bb_getsockname(sock_fd, (struct sockaddr *) &me, sizeof(me));
	//never happens:
	//if (getsockname(sock_fd, (struct sockaddr *) &me, &alen) == -1)
	//	bb_perror_msg_and_die("getsockname");
	if (me.sll_halen == 0) {
		bb_error_msg(err_str, "is not ARPable (no ll address)");
		BUILD_BUG_ON(DAD != 2);
		/* exit 0 if DAD, else exit 2 */
		return (~option_mask32 & DAD);
	}
	he = me;
	memset(he.sll_addr, -1, he.sll_halen);

	if (!(option_mask32 & QUIET)) {
		/* inet_ntoa uses static storage, can't use in same printf */
		printf("ARPING %s", inet_ntoa(dst));
		printf(" from %s %s\n", inet_ntoa(src), device);
	}

	/*sigemptyset(&G.sset); - zeroed by INIT_G */
	sigaddset(&G.sset, SIGALRM);
	sigaddset(&G.sset, SIGINT);
	signal_SA_RESTART_empty_mask(SIGINT,  (void (*)(int))finish);
	signal_SA_RESTART_empty_mask(SIGALRM, (void (*)(int))catcher);

	/* Send the first packet, arm ALRM */
	catcher();

	while (1) {
		struct sockaddr_ll from;
		socklen_t alen = sizeof(from);
		int cc;

		/* Unblock SIGALRM so that the previously called alarm()
		 * can prevent recvfrom from blocking forever in case the
		 * inherited procmask is blocking SIGALRM.
		 */
		sigprocmask(SIG_UNBLOCK, &G.sset, NULL);

		cc = recvfrom(sock_fd, G.packet, sizeof(G.packet), 0, (struct sockaddr *) &from, &alen);

		/* Don't allow SIGALRMs while we process the reply */
		sigprocmask(SIG_BLOCK, &G.sset, NULL);
		if (cc < 0) {
			bb_simple_perror_msg("recvfrom");
			continue;
		}
		recv_pack(G.packet, cc, &from);
	}
}
