// SPDX-License-Identifier: GPL-2.0
/* nettest - used for functional tests of networking APIs
 *
 * Copyright (c) 2013-2019 David Ahern <dsahern@gmail.com>. All rights reserved.
 */

#define _GNU_SOURCE
#include <features.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <linux/tcp.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <libgen.h>
#include <limits.h>
#include <sched.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>

#ifndef IPV6_UNICAST_IF
#define IPV6_UNICAST_IF         76
#endif
#ifndef IPV6_MULTICAST_IF
#define IPV6_MULTICAST_IF       17
#endif

#define DEFAULT_PORT 12345

#define NS_PREFIX "/run/netns/"

#ifndef MAX
#define MAX(a, b)  ((a) > (b) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a, b)  ((a) < (b) ? (a) : (b))
#endif

struct sock_args {
	/* local address */
	const char *local_addr_str;
	const char *client_local_addr_str;
	union {
		struct in_addr  in;
		struct in6_addr in6;
	} local_addr;

	/* remote address */
	const char *remote_addr_str;
	union {
		struct in_addr  in;
		struct in6_addr in6;
	} remote_addr;
	int scope_id;  /* remote scope; v6 send only */

	struct in_addr grp;     /* multicast group */

	unsigned int has_local_ip:1,
		     has_remote_ip:1,
		     has_grp:1,
		     has_expected_laddr:1,
		     has_expected_raddr:1,
		     bind_test_only:1;

	unsigned short port;

	int type;      /* DGRAM, STREAM, RAW */
	int protocol;
	int version;   /* AF_INET/AF_INET6 */

	int use_setsockopt;
	int use_cmsg;
	const char *dev;
	const char *server_dev;
	int ifindex;

	const char *clientns;
	const char *serverns;

	const char *password;
	const char *client_pw;
	/* prefix for MD5 password */
	const char *md5_prefix_str;
	union {
		struct sockaddr_in v4;
		struct sockaddr_in6 v6;
	} md5_prefix;
	unsigned int prefix_len;

	/* expected addresses and device index for connection */
	const char *expected_dev;
	const char *expected_server_dev;
	int expected_ifindex;

	/* local address */
	const char *expected_laddr_str;
	union {
		struct in_addr  in;
		struct in6_addr in6;
	} expected_laddr;

	/* remote address */
	const char *expected_raddr_str;
	union {
		struct in_addr  in;
		struct in6_addr in6;
	} expected_raddr;
};

static int server_mode;
static unsigned int prog_timeout = 5;
static unsigned int interactive;
static int iter = 1;
static char *msg = "Hello world!";
static int msglen;
static int quiet;
static int try_broadcast = 1;

static char *timestamp(char *timebuf, int buflen)
{
	time_t now;

	now = time(NULL);
	if (strftime(timebuf, buflen, "%T", localtime(&now)) == 0) {
		memset(timebuf, 0, buflen);
		strncpy(timebuf, "00:00:00", buflen-1);
	}

	return timebuf;
}

static void log_msg(const char *format, ...)
{
	char timebuf[64];
	va_list args;

	if (quiet)
		return;

	fprintf(stdout, "%s %s:",
		timestamp(timebuf, sizeof(timebuf)),
		server_mode ? "server" : "client");
	va_start(args, format);
	vfprintf(stdout, format, args);
	va_end(args);

	fflush(stdout);
}

static void log_error(const char *format, ...)
{
	char timebuf[64];
	va_list args;

	if (quiet)
		return;

	fprintf(stderr, "%s %s:",
		timestamp(timebuf, sizeof(timebuf)),
		server_mode ? "server" : "client");
	va_start(args, format);
	vfprintf(stderr, format, args);
	va_end(args);

	fflush(stderr);
}

static void log_err_errno(const char *fmt, ...)
{
	char timebuf[64];
	va_list args;

	if (quiet)
		return;

	fprintf(stderr, "%s %s: ",
		timestamp(timebuf, sizeof(timebuf)),
		server_mode ? "server" : "client");
	va_start(args, fmt);
	vfprintf(stderr, fmt, args);
	va_end(args);

	fprintf(stderr, ": %d: %s\n", errno, strerror(errno));
	fflush(stderr);
}

static void log_address(const char *desc, struct sockaddr *sa)
{
	char addrstr[64];

	if (quiet)
		return;

	if (sa->sa_family == AF_INET) {
		struct sockaddr_in *s = (struct sockaddr_in *) sa;

		log_msg("%s %s:%d\n",
			desc,
			inet_ntop(AF_INET, &s->sin_addr, addrstr,
				  sizeof(addrstr)),
			ntohs(s->sin_port));

	} else if (sa->sa_family == AF_INET6) {
		struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa;

		log_msg("%s [%s]:%d\n",
			desc,
			inet_ntop(AF_INET6, &s6->sin6_addr, addrstr,
				  sizeof(addrstr)),
			ntohs(s6->sin6_port));
	}

	fflush(stdout);
}

static int switch_ns(const char *ns)
{
	char path[PATH_MAX];
	int fd, ret;

	if (geteuid())
		log_error("warning: likely need root to set netns %s!\n", ns);

	snprintf(path, sizeof(path), "%s%s", NS_PREFIX, ns);
	fd = open(path, 0);
	if (fd < 0) {
		log_err_errno("Failed to open netns path; can not switch netns");
		return 1;
	}

	ret = setns(fd, CLONE_NEWNET);
	close(fd);

	return ret;
}

static int tcp_md5sig(int sd, void *addr, socklen_t alen, struct sock_args *args)
{
	int keylen = strlen(args->password);
	struct tcp_md5sig md5sig = {};
	int opt = TCP_MD5SIG;
	int rc;

	md5sig.tcpm_keylen = keylen;
	memcpy(md5sig.tcpm_key, args->password, keylen);

	if (args->prefix_len) {
		opt = TCP_MD5SIG_EXT;
		md5sig.tcpm_flags |= TCP_MD5SIG_FLAG_PREFIX;

		md5sig.tcpm_prefixlen = args->prefix_len;
		addr = &args->md5_prefix;
	}
	memcpy(&md5sig.tcpm_addr, addr, alen);

	if (args->ifindex) {
		opt = TCP_MD5SIG_EXT;
		md5sig.tcpm_flags |= TCP_MD5SIG_FLAG_IFINDEX;

		md5sig.tcpm_ifindex = args->ifindex;
	}

	rc = setsockopt(sd, IPPROTO_TCP, opt, &md5sig, sizeof(md5sig));
	if (rc < 0) {
		/* ENOENT is harmless. Returned when a password is cleared */
		if (errno == ENOENT)
			rc = 0;
		else
			log_err_errno("setsockopt(TCP_MD5SIG)");
	}

	return rc;
}

static int tcp_md5_remote(int sd, struct sock_args *args)
{
	struct sockaddr_in sin = {
		.sin_family = AF_INET,
	};
	struct sockaddr_in6 sin6 = {
		.sin6_family = AF_INET6,
	};
	void *addr;
	int alen;

	switch (args->version) {
	case AF_INET:
		sin.sin_port = htons(args->port);
		sin.sin_addr = args->md5_prefix.v4.sin_addr;
		addr = &sin;
		alen = sizeof(sin);
		break;
	case AF_INET6:
		sin6.sin6_port = htons(args->port);
		sin6.sin6_addr = args->md5_prefix.v6.sin6_addr;
		addr = &sin6;
		alen = sizeof(sin6);
		break;
	default:
		log_error("unknown address family\n");
		exit(1);
	}

	if (tcp_md5sig(sd, addr, alen, args))
		return -1;

	return 0;
}

static int get_ifidx(const char *ifname)
{
	struct ifreq ifdata;
	int sd, rc;

	if (!ifname || *ifname == '\0')
		return -1;

	memset(&ifdata, 0, sizeof(ifdata));

	strcpy(ifdata.ifr_name, ifname);

	sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
	if (sd < 0) {
		log_err_errno("socket failed");
		return -1;
	}

	rc = ioctl(sd, SIOCGIFINDEX, (char *)&ifdata);
	close(sd);
	if (rc != 0) {
		log_err_errno("ioctl(SIOCGIFINDEX) failed");
		return -1;
	}

	return ifdata.ifr_ifindex;
}

static int bind_to_device(int sd, const char *name)
{
	int rc;

	rc = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name)+1);
	if (rc < 0)
		log_err_errno("setsockopt(SO_BINDTODEVICE)");

	return rc;
}

static int get_bind_to_device(int sd, char *name, size_t len)
{
	int rc;
	socklen_t optlen = len;

	name[0] = '\0';
	rc = getsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, &optlen);
	if (rc < 0)
		log_err_errno("setsockopt(SO_BINDTODEVICE)");

	return rc;
}

static int check_device(int sd, struct sock_args *args)
{
	int ifindex = 0;
	char name[32];

	if (get_bind_to_device(sd, name, sizeof(name)))
		*name = '\0';
	else
		ifindex = get_ifidx(name);

	log_msg("    bound to device %s/%d\n",
		*name ? name : "<none>", ifindex);

	if (!args->expected_ifindex)
		return 0;

	if (args->expected_ifindex != ifindex) {
		log_error("Device index mismatch: expected %d have %d\n",
			  args->expected_ifindex, ifindex);
		return 1;
	}

	log_msg("Device index matches: expected %d have %d\n",
		args->expected_ifindex, ifindex);

	return 0;
}

static int set_pktinfo_v4(int sd)
{
	int one = 1;
	int rc;

	rc = setsockopt(sd, SOL_IP, IP_PKTINFO, &one, sizeof(one));
	if (rc < 0 && rc != -ENOTSUP)
		log_err_errno("setsockopt(IP_PKTINFO)");

	return rc;
}

static int set_recvpktinfo_v6(int sd)
{
	int one = 1;
	int rc;

	rc = setsockopt(sd, SOL_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
	if (rc < 0 && rc != -ENOTSUP)
		log_err_errno("setsockopt(IPV6_RECVPKTINFO)");

	return rc;
}

static int set_recverr_v4(int sd)
{
	int one = 1;
	int rc;

	rc = setsockopt(sd, SOL_IP, IP_RECVERR, &one, sizeof(one));
	if (rc < 0 && rc != -ENOTSUP)
		log_err_errno("setsockopt(IP_RECVERR)");

	return rc;
}

static int set_recverr_v6(int sd)
{
	int one = 1;
	int rc;

	rc = setsockopt(sd, SOL_IPV6, IPV6_RECVERR, &one, sizeof(one));
	if (rc < 0 && rc != -ENOTSUP)
		log_err_errno("setsockopt(IPV6_RECVERR)");

	return rc;
}

static int set_unicast_if(int sd, int ifindex, int version)
{
	int opt = IP_UNICAST_IF;
	int level = SOL_IP;
	int rc;

	ifindex = htonl(ifindex);

	if (version == AF_INET6) {
		opt = IPV6_UNICAST_IF;
		level = SOL_IPV6;
	}
	rc = setsockopt(sd, level, opt, &ifindex, sizeof(ifindex));
	if (rc < 0)
		log_err_errno("setsockopt(IP_UNICAST_IF)");

	return rc;
}

static int set_multicast_if(int sd, int ifindex)
{
	struct ip_mreqn mreq = { .imr_ifindex = ifindex };
	int rc;

	rc = setsockopt(sd, SOL_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq));
	if (rc < 0)
		log_err_errno("setsockopt(IP_MULTICAST_IF)");

	return rc;
}

static int set_membership(int sd, uint32_t grp, uint32_t addr, int ifindex)
{
	uint32_t if_addr = addr;
	struct ip_mreqn mreq;
	int rc;

	if (addr == htonl(INADDR_ANY) && !ifindex) {
		log_error("Either local address or device needs to be given for multicast membership\n");
		return -1;
	}

	mreq.imr_multiaddr.s_addr = grp;
	mreq.imr_address.s_addr = if_addr;
	mreq.imr_ifindex = ifindex;

	rc = setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
	if (rc < 0) {
		log_err_errno("setsockopt(IP_ADD_MEMBERSHIP)");
		return -1;
	}

	return 0;
}

static int set_broadcast(int sd)
{
	unsigned int one = 1;
	int rc = 0;

	if (setsockopt(sd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) != 0) {
		log_err_errno("setsockopt(SO_BROADCAST)");
		rc = -1;
	}

	return rc;
}

static int set_reuseport(int sd)
{
	unsigned int one = 1;
	int rc = 0;

	if (setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) != 0) {
		log_err_errno("setsockopt(SO_REUSEPORT)");
		rc = -1;
	}

	return rc;
}

static int set_reuseaddr(int sd)
{
	unsigned int one = 1;
	int rc = 0;

	if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) != 0) {
		log_err_errno("setsockopt(SO_REUSEADDR)");
		rc = -1;
	}

	return rc;
}

static int str_to_uint(const char *str, int min, int max, unsigned int *value)
{
	int number;
	char *end;

	errno = 0;
	number = (unsigned int) strtoul(str, &end, 0);

	/* entire string should be consumed by conversion
	 * and value should be between min and max
	 */
	if (((*end == '\0') || (*end == '\n')) && (end != str) &&
	    (errno != ERANGE) && (min <= number) && (number <= max)) {
		*value = number;
		return 0;
	}

	return -1;
}

static int resolve_devices(struct sock_args *args)
{
	if (args->dev) {
		args->ifindex = get_ifidx(args->dev);
		if (args->ifindex < 0) {
			log_error("Invalid device name\n");
			return 1;
		}
	}

	if (args->expected_dev) {
		unsigned int tmp;

		if (str_to_uint(args->expected_dev, 0, INT_MAX, &tmp) == 0) {
			args->expected_ifindex = (int)tmp;
		} else {
			args->expected_ifindex = get_ifidx(args->expected_dev);
			if (args->expected_ifindex < 0) {
				fprintf(stderr, "Invalid expected device\n");
				return 1;
			}
		}
	}

	return 0;
}

static int expected_addr_match(struct sockaddr *sa, void *expected,
			       const char *desc)
{
	char addrstr[64];
	int rc = 0;

	if (sa->sa_family == AF_INET) {
		struct sockaddr_in *s = (struct sockaddr_in *) sa;
		struct in_addr *exp_in = (struct in_addr *) expected;

		if (s->sin_addr.s_addr != exp_in->s_addr) {
			log_error("%s address does not match expected %s\n",
				  desc,
				  inet_ntop(AF_INET, exp_in,
					    addrstr, sizeof(addrstr)));
			rc = 1;
		}
	} else if (sa->sa_family == AF_INET6) {
		struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa;
		struct in6_addr *exp_in = (struct in6_addr *) expected;

		if (memcmp(&s6->sin6_addr, exp_in, sizeof(*exp_in))) {
			log_error("%s address does not match expected %s\n",
				  desc,
				  inet_ntop(AF_INET6, exp_in,
					    addrstr, sizeof(addrstr)));
			rc = 1;
		}
	} else {
		log_error("%s address does not match expected - unknown family\n",
			  desc);
		rc = 1;
	}

	if (!rc)
		log_msg("%s address matches expected\n", desc);

	return rc;
}

static int show_sockstat(int sd, struct sock_args *args)
{
	struct sockaddr_in6 local_addr, remote_addr;
	socklen_t alen = sizeof(local_addr);
	struct sockaddr *sa;
	const char *desc;
	int rc = 0;

	desc = server_mode ? "server local:" : "client local:";
	sa = (struct sockaddr *) &local_addr;
	if (getsockname(sd, sa, &alen) == 0) {
		log_address(desc, sa);

		if (args->has_expected_laddr) {
			rc = expected_addr_match(sa, &args->expected_laddr,
						 "local");
		}
	} else {
		log_err_errno("getsockname failed");
	}

	sa = (struct sockaddr *) &remote_addr;
	desc = server_mode ? "server peer:" : "client peer:";
	if (getpeername(sd, sa, &alen) == 0) {
		log_address(desc, sa);

		if (args->has_expected_raddr) {
			rc |= expected_addr_match(sa, &args->expected_raddr,
						 "remote");
		}
	} else {
		log_err_errno("getpeername failed");
	}

	return rc;
}

enum addr_type {
	ADDR_TYPE_LOCAL,
	ADDR_TYPE_REMOTE,
	ADDR_TYPE_MCAST,
	ADDR_TYPE_EXPECTED_LOCAL,
	ADDR_TYPE_EXPECTED_REMOTE,
	ADDR_TYPE_MD5_PREFIX,
};

static int convert_addr(struct sock_args *args, const char *_str,
			enum addr_type atype)
{
	int pfx_len_max = args->version == AF_INET6 ? 128 : 32;
	int family = args->version;
	char *str, *dev, *sep;
	struct in6_addr *in6;
	struct in_addr  *in;
	const char *desc;
	void *addr;
	int rc = 0;

	str = strdup(_str);
	if (!str)
		return -ENOMEM;

	switch (atype) {
	case ADDR_TYPE_LOCAL:
		desc = "local";
		addr = &args->local_addr;
		break;
	case ADDR_TYPE_REMOTE:
		desc = "remote";
		addr = &args->remote_addr;
		break;
	case ADDR_TYPE_MCAST:
		desc = "mcast grp";
		addr = &args->grp;
		break;
	case ADDR_TYPE_EXPECTED_LOCAL:
		desc = "expected local";
		addr = &args->expected_laddr;
		break;
	case ADDR_TYPE_EXPECTED_REMOTE:
		desc = "expected remote";
		addr = &args->expected_raddr;
		break;
	case ADDR_TYPE_MD5_PREFIX:
		desc = "md5 prefix";
		if (family == AF_INET) {
			args->md5_prefix.v4.sin_family = AF_INET;
			addr = &args->md5_prefix.v4.sin_addr;
		} else if (family == AF_INET6) {
			args->md5_prefix.v6.sin6_family = AF_INET6;
			addr = &args->md5_prefix.v6.sin6_addr;
		} else
			return 1;

		sep = strchr(str, '/');
		if (sep) {
			*sep = '\0';
			sep++;
			if (str_to_uint(sep, 1, pfx_len_max,
					&args->prefix_len) != 0) {
				fprintf(stderr, "Invalid port\n");
				return 1;
			}
		} else {
			args->prefix_len = 0;
		}
		break;
	default:
		log_error("unknown address type\n");
		exit(1);
	}

	switch (family) {
	case AF_INET:
		in  = (struct in_addr *) addr;
		if (str) {
			if (inet_pton(AF_INET, str, in) == 0) {
				log_error("Invalid %s IP address\n", desc);
				rc = -1;
				goto out;
			}
		} else {
			in->s_addr = htonl(INADDR_ANY);
		}
		break;

	case AF_INET6:
		dev = strchr(str, '%');
		if (dev) {
			*dev = '\0';
			dev++;
		}

		in6 = (struct in6_addr *) addr;
		if (str) {
			if (inet_pton(AF_INET6, str, in6) == 0) {
				log_error("Invalid %s IPv6 address\n", desc);
				rc = -1;
				goto out;
			}
		} else {
			*in6 = in6addr_any;
		}
		if (dev) {
			args->scope_id = get_ifidx(dev);
			if (args->scope_id < 0) {
				log_error("Invalid scope on %s IPv6 address\n",
					  desc);
				rc = -1;
				goto out;
			}
		}
		break;

	default:
		log_error("Invalid address family\n");
	}

out:
	free(str);
	return rc;
}

static int validate_addresses(struct sock_args *args)
{
	if (args->local_addr_str &&
	    convert_addr(args, args->local_addr_str, ADDR_TYPE_LOCAL) < 0)
		return 1;

	if (args->remote_addr_str &&
	    convert_addr(args, args->remote_addr_str, ADDR_TYPE_REMOTE) < 0)
		return 1;

	if (args->md5_prefix_str &&
	    convert_addr(args, args->md5_prefix_str,
			 ADDR_TYPE_MD5_PREFIX) < 0)
		return 1;

	if (args->expected_laddr_str &&
	    convert_addr(args, args->expected_laddr_str,
			 ADDR_TYPE_EXPECTED_LOCAL))
		return 1;

	if (args->expected_raddr_str &&
	    convert_addr(args, args->expected_raddr_str,
			 ADDR_TYPE_EXPECTED_REMOTE))
		return 1;

	return 0;
}

static int get_index_from_cmsg(struct msghdr *m)
{
	struct cmsghdr *cm;
	int ifindex = 0;
	char buf[64];

	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(m);
	     m->msg_controllen != 0 && cm;
	     cm = (struct cmsghdr *)CMSG_NXTHDR(m, cm)) {

		if (cm->cmsg_level == SOL_IP &&
		    cm->cmsg_type == IP_PKTINFO) {
			struct in_pktinfo *pi;

			pi = (struct in_pktinfo *)(CMSG_DATA(cm));
			inet_ntop(AF_INET, &pi->ipi_addr, buf, sizeof(buf));
			ifindex = pi->ipi_ifindex;
		} else if (cm->cmsg_level == SOL_IPV6 &&
			   cm->cmsg_type == IPV6_PKTINFO) {
			struct in6_pktinfo *pi6;

			pi6 = (struct in6_pktinfo *)(CMSG_DATA(cm));
			inet_ntop(AF_INET6, &pi6->ipi6_addr, buf, sizeof(buf));
			ifindex = pi6->ipi6_ifindex;
		}
	}

	if (ifindex) {
		log_msg("    pktinfo: ifindex %d dest addr %s\n",
			ifindex, buf);
	}
	return ifindex;
}

static int send_msg_no_cmsg(int sd, void *addr, socklen_t alen)
{
	int err;

again:
	err = sendto(sd, msg, msglen, 0, addr, alen);
	if (err < 0) {
		if (errno == EACCES && try_broadcast) {
			try_broadcast = 0;
			if (!set_broadcast(sd))
				goto again;
			errno = EACCES;
		}

		log_err_errno("sendto failed");
		return 1;
	}

	return 0;
}

static int send_msg_cmsg(int sd, void *addr, socklen_t alen,
			 int ifindex, int version)
{
	unsigned char cmsgbuf[64];
	struct iovec iov[2];
	struct cmsghdr *cm;
	struct msghdr m;
	int err;

	iov[0].iov_base = msg;
	iov[0].iov_len = msglen;
	m.msg_iov = iov;
	m.msg_iovlen = 1;
	m.msg_name = (caddr_t)addr;
	m.msg_namelen = alen;

	memset(cmsgbuf, 0, sizeof(cmsgbuf));
	cm = (struct cmsghdr *)cmsgbuf;
	m.msg_control = (caddr_t)cm;

	if (version == AF_INET) {
		struct in_pktinfo *pi;

		cm->cmsg_level = SOL_IP;
		cm->cmsg_type = IP_PKTINFO;
		cm->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
		pi = (struct in_pktinfo *)(CMSG_DATA(cm));
		pi->ipi_ifindex = ifindex;

		m.msg_controllen = cm->cmsg_len;

	} else if (version == AF_INET6) {
		struct in6_pktinfo *pi6;

		cm->cmsg_level = SOL_IPV6;
		cm->cmsg_type = IPV6_PKTINFO;
		cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));

		pi6 = (struct in6_pktinfo *)(CMSG_DATA(cm));
		pi6->ipi6_ifindex = ifindex;

		m.msg_controllen = cm->cmsg_len;
	}

again:
	err = sendmsg(sd, &m, 0);
	if (err < 0) {
		if (errno == EACCES && try_broadcast) {
			try_broadcast = 0;
			if (!set_broadcast(sd))
				goto again;
			errno = EACCES;
		}

		log_err_errno("sendmsg failed");
		return 1;
	}

	return 0;
}


static int send_msg(int sd, void *addr, socklen_t alen, struct sock_args *args)
{
	if (args->type == SOCK_STREAM) {
		if (write(sd, msg, msglen) < 0) {
			log_err_errno("write failed sending msg to peer");
			return 1;
		}
	} else if (args->ifindex && args->use_cmsg) {
		if (send_msg_cmsg(sd, addr, alen, args->ifindex, args->version))
			return 1;
	} else {
		if (send_msg_no_cmsg(sd, addr, alen))
			return 1;
	}

	log_msg("Sent message:\n");
	log_msg("    %.24s%s\n", msg, msglen > 24 ? " ..." : "");

	return 0;
}

static int socket_read_dgram(int sd, struct sock_args *args)
{
	unsigned char addr[sizeof(struct sockaddr_in6)];
	struct sockaddr *sa = (struct sockaddr *) addr;
	socklen_t alen = sizeof(addr);
	struct iovec iov[2];
	struct msghdr m = {
		.msg_name = (caddr_t)addr,
		.msg_namelen = alen,
		.msg_iov = iov,
		.msg_iovlen = 1,
	};
	unsigned char cmsgbuf[256];
	struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf;
	char buf[16*1024];
	int ifindex;
	int len;

	iov[0].iov_base = (caddr_t)buf;
	iov[0].iov_len = sizeof(buf);

	memset(cmsgbuf, 0, sizeof(cmsgbuf));
	m.msg_control = (caddr_t)cm;
	m.msg_controllen = sizeof(cmsgbuf);

	len = recvmsg(sd, &m, 0);
	if (len == 0) {
		log_msg("peer closed connection.\n");
		return 0;
	} else if (len < 0) {
		log_msg("failed to read message: %d: %s\n",
			errno, strerror(errno));
		return -1;
	}

	buf[len] = '\0';

	log_address("Message from:", sa);
	log_msg("    %.24s%s\n", buf, len > 24 ? " ..." : "");

	ifindex = get_index_from_cmsg(&m);
	if (args->expected_ifindex) {
		if (args->expected_ifindex != ifindex) {
			log_error("Device index mismatch: expected %d have %d\n",
				  args->expected_ifindex, ifindex);
			return -1;
		}
		log_msg("Device index matches: expected %d have %d\n",
			args->expected_ifindex, ifindex);
	}

	if (!interactive && server_mode) {
		if (sa->sa_family == AF_INET6) {
			struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa;
			struct in6_addr *in6 = &s6->sin6_addr;

			if (IN6_IS_ADDR_V4MAPPED(in6)) {
				const uint32_t *pa = (uint32_t *) &in6->s6_addr;
				struct in_addr in4;
				struct sockaddr_in *sin;

				sin = (struct sockaddr_in *) addr;
				pa += 3;
				in4.s_addr = *pa;
				sin->sin_addr = in4;
				sin->sin_family = AF_INET;
				if (send_msg_cmsg(sd, addr, alen,
						  ifindex, AF_INET) < 0)
					goto out_err;
			}
		}
again:
		iov[0].iov_len = len;

		if (args->version == AF_INET6) {
			struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa;

			if (args->dev) {
				/* avoid PKTINFO conflicts with bindtodev */
				if (sendto(sd, buf, len, 0,
					   (void *) addr, alen) < 0)
					goto out_err;
			} else {
				/* kernel is allowing scope_id to be set to VRF
				 * index for LLA. for sends to global address
				 * reset scope id
				 */
				s6->sin6_scope_id = ifindex;
				if (sendmsg(sd, &m, 0) < 0)
					goto out_err;
			}
		} else {
			int err;

			err = sendmsg(sd, &m, 0);
			if (err < 0) {
				if (errno == EACCES && try_broadcast) {
					try_broadcast = 0;
					if (!set_broadcast(sd))
						goto again;
					errno = EACCES;
				}
				goto out_err;
			}
		}
		log_msg("Sent message:\n");
		log_msg("    %.24s%s\n", buf, len > 24 ? " ..." : "");
	}

	return 1;
out_err:
	log_err_errno("failed to send msg to peer");
	return -1;
}

static int socket_read_stream(int sd)
{
	char buf[1024];
	int len;

	len = read(sd, buf, sizeof(buf)-1);
	if (len == 0) {
		log_msg("client closed connection.\n");
		return 0;
	} else if (len < 0) {
		log_msg("failed to read message\n");
		return -1;
	}

	buf[len] = '\0';
	log_msg("Incoming message:\n");
	log_msg("    %.24s%s\n", buf, len > 24 ? " ..." : "");

	if (!interactive && server_mode) {
		if (write(sd, buf, len) < 0) {
			log_err_errno("failed to send buf");
			return -1;
		}
		log_msg("Sent message:\n");
		log_msg("     %.24s%s\n", buf, len > 24 ? " ..." : "");
	}

	return 1;
}

static int socket_read(int sd, struct sock_args *args)
{
	if (args->type == SOCK_STREAM)
		return socket_read_stream(sd);

	return socket_read_dgram(sd, args);
}

static int stdin_to_socket(int sd, int type, void *addr, socklen_t alen)
{
	char buf[1024];
	int len;

	if (fgets(buf, sizeof(buf), stdin) == NULL)
		return 0;

	len = strlen(buf);
	if (type == SOCK_STREAM) {
		if (write(sd, buf, len) < 0) {
			log_err_errno("failed to send buf");
			return -1;
		}
	} else {
		int err;

again:
		err = sendto(sd, buf, len, 0, addr, alen);
		if (err < 0) {
			if (errno == EACCES && try_broadcast) {
				try_broadcast = 0;
				if (!set_broadcast(sd))
					goto again;
				errno = EACCES;
			}
			log_err_errno("failed to send msg to peer");
			return -1;
		}
	}
	log_msg("Sent message:\n");
	log_msg("    %.24s%s\n", buf, len > 24 ? " ..." : "");

	return 1;
}

static void set_recv_attr(int sd, int version)
{
	if (version == AF_INET6) {
		set_recvpktinfo_v6(sd);
		set_recverr_v6(sd);
	} else {
		set_pktinfo_v4(sd);
		set_recverr_v4(sd);
	}
}

static int msg_loop(int client, int sd, void *addr, socklen_t alen,
		    struct sock_args *args)
{
	struct timeval timeout = { .tv_sec = prog_timeout }, *ptval = NULL;
	fd_set rfds;
	int nfds;
	int rc;

	if (args->type != SOCK_STREAM)
		set_recv_attr(sd, args->version);

	if (msg) {
		msglen = strlen(msg);

		/* client sends first message */
		if (client) {
			if (send_msg(sd, addr, alen, args))
				return 1;
		}
		if (!interactive) {
			ptval = &timeout;
			if (!prog_timeout)
				timeout.tv_sec = 5;
		}
	}

	nfds = interactive ? MAX(fileno(stdin), sd)  + 1 : sd + 1;
	while (1) {
		FD_ZERO(&rfds);
		FD_SET(sd, &rfds);
		if (interactive)
			FD_SET(fileno(stdin), &rfds);

		rc = select(nfds, &rfds, NULL, NULL, ptval);
		if (rc < 0) {
			if (errno == EINTR)
				continue;

			rc = 1;
			log_err_errno("select failed");
			break;
		} else if (rc == 0) {
			log_error("Timed out waiting for response\n");
			rc = 2;
			break;
		}

		if (FD_ISSET(sd, &rfds)) {
			rc = socket_read(sd, args);
			if (rc < 0) {
				rc = 1;
				break;
			}
			if (rc == 0)
				break;
		}

		rc = 0;

		if (FD_ISSET(fileno(stdin), &rfds)) {
			if (stdin_to_socket(sd, args->type, addr, alen) <= 0)
				break;
		}

		if (interactive)
			continue;

		if (iter != -1) {
			--iter;
			if (iter == 0)
				break;
		}

		log_msg("Going into quiet mode\n");
		quiet = 1;

		if (client) {
			if (send_msg(sd, addr, alen, args)) {
				rc = 1;
				break;
			}
		}
	}

	return rc;
}

static int msock_init(struct sock_args *args, int server)
{
	uint32_t if_addr = htonl(INADDR_ANY);
	struct sockaddr_in laddr = {
		.sin_family = AF_INET,
		.sin_port = htons(args->port),
	};
	int one = 1;
	int sd;

	if (!server && args->has_local_ip)
		if_addr = args->local_addr.in.s_addr;

	sd = socket(PF_INET, SOCK_DGRAM, 0);
	if (sd < 0) {
		log_err_errno("socket");
		return -1;
	}

	if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
		       (char *)&one, sizeof(one)) < 0) {
		log_err_errno("Setting SO_REUSEADDR error");
		goto out_err;
	}

	if (setsockopt(sd, SOL_SOCKET, SO_BROADCAST,
		       (char *)&one, sizeof(one)) < 0)
		log_err_errno("Setting SO_BROADCAST error");

	if (args->dev && bind_to_device(sd, args->dev) != 0)
		goto out_err;
	else if (args->use_setsockopt &&
		 set_multicast_if(sd, args->ifindex))
		goto out_err;

	laddr.sin_addr.s_addr = if_addr;

	if (bind(sd, (struct sockaddr *) &laddr, sizeof(laddr)) < 0) {
		log_err_errno("bind failed");
		goto out_err;
	}

	if (server &&
	    set_membership(sd, args->grp.s_addr,
			   args->local_addr.in.s_addr, args->ifindex))
		goto out_err;

	return sd;
out_err:
	close(sd);
	return -1;
}

static int msock_server(struct sock_args *args)
{
	return msock_init(args, 1);
}

static int msock_client(struct sock_args *args)
{
	return msock_init(args, 0);
}

static int bind_socket(int sd, struct sock_args *args)
{
	struct sockaddr_in serv_addr = {
		.sin_family = AF_INET,
	};
	struct sockaddr_in6 serv6_addr = {
		.sin6_family = AF_INET6,
	};
	void *addr;
	socklen_t alen;

	if (!args->has_local_ip && args->type == SOCK_RAW)
		return 0;

	switch (args->version) {
	case AF_INET:
		serv_addr.sin_port = htons(args->port);
		serv_addr.sin_addr = args->local_addr.in;
		addr = &serv_addr;
		alen = sizeof(serv_addr);
		break;

	case AF_INET6:
		serv6_addr.sin6_port = htons(args->port);
		serv6_addr.sin6_addr = args->local_addr.in6;
		addr = &serv6_addr;
		alen = sizeof(serv6_addr);
		break;

	default:
		log_error("Invalid address family\n");
		return -1;
	}

	if (bind(sd, addr, alen) < 0) {
		log_err_errno("error binding socket");
		return -1;
	}

	return 0;
}

static int lsock_init(struct sock_args *args)
{
	long flags;
	int sd;

	sd = socket(args->version, args->type, args->protocol);
	if (sd < 0) {
		log_err_errno("Error opening socket");
		return  -1;
	}

	if (set_reuseaddr(sd) != 0)
		goto err;

	if (set_reuseport(sd) != 0)
		goto err;

	if (args->dev && bind_to_device(sd, args->dev) != 0)
		goto err;
	else if (args->use_setsockopt &&
		 set_unicast_if(sd, args->ifindex, args->version))
		goto err;

	if (bind_socket(sd, args))
		goto err;

	if (args->bind_test_only)
		goto out;

	if (args->type == SOCK_STREAM && listen(sd, 1) < 0) {
		log_err_errno("listen failed");
		goto err;
	}

	flags = fcntl(sd, F_GETFL);
	if ((flags < 0) || (fcntl(sd, F_SETFL, flags|O_NONBLOCK) < 0)) {
		log_err_errno("Failed to set non-blocking option");
		goto err;
	}

	if (fcntl(sd, F_SETFD, FD_CLOEXEC) < 0)
		log_err_errno("Failed to set close-on-exec flag");

out:
	return sd;

err:
	close(sd);
	return -1;
}

static void ipc_write(int fd, int message)
{
	/* Not in both_mode, so there's no process to signal */
	if (fd < 0)
		return;

	if (write(fd, &message, sizeof(message)) < 0)
		log_err_errno("Failed to send client status");
}

static int do_server(struct sock_args *args, int ipc_fd)
{
	/* ipc_fd = -1 if no parent process to signal */
	struct timeval timeout = { .tv_sec = prog_timeout }, *ptval = NULL;
	unsigned char addr[sizeof(struct sockaddr_in6)] = {};
	socklen_t alen = sizeof(addr);
	int lsd, csd = -1;

	fd_set rfds;
	int rc;

	if (args->serverns) {
		if (switch_ns(args->serverns)) {
			log_error("Could not set server netns to %s\n",
				  args->serverns);
			goto err_exit;
		}
		log_msg("Switched server netns\n");
	}

	args->dev = args->server_dev;
	args->expected_dev = args->expected_server_dev;
	if (resolve_devices(args) || validate_addresses(args))
		goto err_exit;

	if (prog_timeout)
		ptval = &timeout;

	if (args->has_grp)
		lsd = msock_server(args);
	else
		lsd = lsock_init(args);

	if (lsd < 0)
		goto err_exit;

	if (args->bind_test_only) {
		close(lsd);
		ipc_write(ipc_fd, 1);
		return 0;
	}

	if (args->type != SOCK_STREAM) {
		ipc_write(ipc_fd, 1);
		rc = msg_loop(0, lsd, (void *) addr, alen, args);
		close(lsd);
		return rc;
	}

	if (args->password && tcp_md5_remote(lsd, args)) {
		close(lsd);
		goto err_exit;
	}

	ipc_write(ipc_fd, 1);
	while (1) {
		log_msg("waiting for client connection.\n");
		FD_ZERO(&rfds);
		FD_SET(lsd, &rfds);

		rc = select(lsd+1, &rfds, NULL, NULL, ptval);
		if (rc == 0) {
			rc = 2;
			break;
		}

		if (rc < 0) {
			if (errno == EINTR)
				continue;

			log_err_errno("select failed");
			break;
		}

		if (FD_ISSET(lsd, &rfds)) {

			csd = accept(lsd, (void *) addr, &alen);
			if (csd < 0) {
				log_err_errno("accept failed");
				break;
			}

			rc = show_sockstat(csd, args);
			if (rc)
				break;

			rc = check_device(csd, args);
			if (rc)
				break;
		}

		rc = msg_loop(0, csd, (void *) addr, alen, args);
		close(csd);

		if (!interactive)
			break;
	}

	close(lsd);

	return rc;
err_exit:
	ipc_write(ipc_fd, 0);
	return 1;
}

static int wait_for_connect(int sd)
{
	struct timeval _tv = { .tv_sec = prog_timeout }, *tv = NULL;
	fd_set wfd;
	int val = 0, sz = sizeof(val);
	int rc;

	FD_ZERO(&wfd);
	FD_SET(sd, &wfd);

	if (prog_timeout)
		tv = &_tv;

	rc = select(FD_SETSIZE, NULL, &wfd, NULL, tv);
	if (rc == 0) {
		log_error("connect timed out\n");
		return -2;
	} else if (rc < 0) {
		log_err_errno("select failed");
		return -3;
	}

	if (getsockopt(sd, SOL_SOCKET, SO_ERROR, &val, (socklen_t *)&sz) < 0) {
		log_err_errno("getsockopt(SO_ERROR) failed");
		return -4;
	}

	if (val != 0) {
		log_error("connect failed: %d: %s\n", val, strerror(val));
		return -1;
	}

	return 0;
}

static int connectsock(void *addr, socklen_t alen, struct sock_args *args)
{
	int sd, rc = -1;
	long flags;

	sd = socket(args->version, args->type, args->protocol);
	if (sd < 0) {
		log_err_errno("Failed to create socket");
		return -1;
	}

	flags = fcntl(sd, F_GETFL);
	if ((flags < 0) || (fcntl(sd, F_SETFL, flags|O_NONBLOCK) < 0)) {
		log_err_errno("Failed to set non-blocking option");
		goto err;
	}

	if (set_reuseport(sd) != 0)
		goto err;

	if (args->dev && bind_to_device(sd, args->dev) != 0)
		goto err;
	else if (args->use_setsockopt &&
		 set_unicast_if(sd, args->ifindex, args->version))
		goto err;

	if (args->has_local_ip && bind_socket(sd, args))
		goto err;

	if (args->type != SOCK_STREAM)
		goto out;

	if (args->password && tcp_md5sig(sd, addr, alen, args))
		goto err;

	if (args->bind_test_only)
		goto out;

	if (connect(sd, addr, alen) < 0) {
		if (errno != EINPROGRESS) {
			log_err_errno("Failed to connect to remote host");
			rc = -1;
			goto err;
		}
		rc = wait_for_connect(sd);
		if (rc < 0)
			goto err;
	}
out:
	return sd;

err:
	close(sd);
	return rc;
}

static int do_client(struct sock_args *args)
{
	struct sockaddr_in sin = {
		.sin_family = AF_INET,
	};
	struct sockaddr_in6 sin6 = {
		.sin6_family = AF_INET6,
	};
	void *addr;
	int alen;
	int rc = 0;
	int sd;

	if (!args->has_remote_ip && !args->has_grp) {
		fprintf(stderr, "remote IP or multicast group not given\n");
		return 1;
	}

	if (args->clientns) {
		if (switch_ns(args->clientns)) {
			log_error("Could not set client netns to %s\n",
				  args->clientns);
			return 1;
		}
		log_msg("Switched client netns\n");
	}

	args->local_addr_str = args->client_local_addr_str;
	if (resolve_devices(args) || validate_addresses(args))
		return 1;

	if ((args->use_setsockopt || args->use_cmsg) && !args->ifindex) {
		fprintf(stderr, "Device binding not specified\n");
		return 1;
	}
	if (args->use_setsockopt || args->use_cmsg)
		args->dev = NULL;

	switch (args->version) {
	case AF_INET:
		sin.sin_port = htons(args->port);
		if (args->has_grp)
			sin.sin_addr = args->grp;
		else
			sin.sin_addr = args->remote_addr.in;
		addr = &sin;
		alen = sizeof(sin);
		break;
	case AF_INET6:
		sin6.sin6_port = htons(args->port);
		sin6.sin6_addr = args->remote_addr.in6;
		sin6.sin6_scope_id = args->scope_id;
		addr = &sin6;
		alen = sizeof(sin6);
		break;
	}

	args->password = args->client_pw;

	if (args->has_grp)
		sd = msock_client(args);
	else
		sd = connectsock(addr, alen, args);

	if (sd < 0)
		return -sd;

	if (args->bind_test_only)
		goto out;

	if (args->type == SOCK_STREAM) {
		rc = show_sockstat(sd, args);
		if (rc != 0)
			goto out;
	}

	rc = msg_loop(1, sd, addr, alen, args);

out:
	close(sd);

	return rc;
}

static char *random_msg(int len)
{
	int i, n = 0, olen = len + 1;
	char *m;

	if (len <= 0)
		return NULL;

	m = malloc(olen);
	if (!m)
		return NULL;

	while (len > 26) {
		i = snprintf(m + n, olen - n, "%.26s",
			     "abcdefghijklmnopqrstuvwxyz");
		n += i;
		len -= i;
	}
	i = snprintf(m + n, olen - n, "%.*s", len,
		     "abcdefghijklmnopqrstuvwxyz");
	return m;
}

static int ipc_child(int fd, struct sock_args *args)
{
	char *outbuf, *errbuf;
	int rc = 1;

	outbuf = malloc(4096);
	errbuf = malloc(4096);
	if (!outbuf || !errbuf) {
		fprintf(stderr, "server: Failed to allocate buffers for stdout and stderr\n");
		goto out;
	}

	setbuffer(stdout, outbuf, 4096);
	setbuffer(stderr, errbuf, 4096);

	server_mode = 1; /* to tell log_msg in case we are in both_mode */

	/* when running in both mode, address validation applies
	 * solely to client side
	 */
	args->has_expected_laddr = 0;
	args->has_expected_raddr = 0;

	rc = do_server(args, fd);

out:
	free(outbuf);
	free(errbuf);

	return rc;
}

static int ipc_parent(int cpid, int fd, struct sock_args *args)
{
	int client_status;
	int status;
	int buf;

	/* do the client-side function here in the parent process,
	 * waiting to be told when to continue
	 */
	if (read(fd, &buf, sizeof(buf)) <= 0) {
		log_err_errno("Failed to read IPC status from status");
		return 1;
	}
	if (!buf) {
		log_error("Server failed; can not continue\n");
		return 1;
	}
	log_msg("Server is ready\n");

	client_status = do_client(args);
	log_msg("parent is done!\n");

	if (kill(cpid, 0) == 0)
		kill(cpid, SIGKILL);

	wait(&status);
	return client_status;
}

#define GETOPT_STR  "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SCi6L:0:1:2:3:Fbq"

static void print_usage(char *prog)
{
	printf(
	"usage: %s OPTS\n"
	"Required:\n"
	"    -r addr       remote address to connect to (client mode only)\n"
	"    -p port       port to connect to (client mode)/listen on (server mode)\n"
	"                  (default: %d)\n"
	"    -s            server mode (default: client mode)\n"
	"    -t            timeout seconds (default: none)\n"
	"\n"
	"Optional:\n"
	"    -B            do both client and server via fork and IPC\n"
	"    -N ns         set client to network namespace ns (requires root)\n"
	"    -O ns         set server to network namespace ns (requires root)\n"
	"    -F            Restart server loop\n"
	"    -6            IPv6 (default is IPv4)\n"
	"    -P proto      protocol for socket: icmp, ospf (default: none)\n"
	"    -D|R          datagram (D) / raw (R) socket (default stream)\n"
	"    -l addr       local address to bind to in server mode\n"
	"    -c addr       local address to bind to in client mode\n"
	"\n"
	"    -d dev        bind socket to given device name\n"
	"    -I dev        bind socket to given device name - server mode\n"
	"    -S            use setsockopt (IP_UNICAST_IF or IP_MULTICAST_IF)\n"
	"                  to set device binding\n"
	"    -C            use cmsg and IP_PKTINFO to specify device binding\n"
	"\n"
	"    -L len        send random message of given length\n"
	"    -n num        number of times to send message\n"
	"\n"
	"    -M password   use MD5 sum protection\n"
	"    -X password   MD5 password for client mode\n"
	"    -m prefix/len prefix and length to use for MD5 key\n"
	"    -g grp        multicast group (e.g., 239.1.1.1)\n"
	"    -i            interactive mode (default is echo and terminate)\n"
	"\n"
	"    -0 addr       Expected local address\n"
	"    -1 addr       Expected remote address\n"
	"    -2 dev        Expected device name (or index) to receive packet\n"
	"    -3 dev        Expected device name (or index) to receive packets - server mode\n"
	"\n"
	"    -b            Bind test only.\n"
	"    -q            Be quiet. Run test without printing anything.\n"
	, prog, DEFAULT_PORT);
}

int main(int argc, char *argv[])
{
	struct sock_args args = {
		.version = AF_INET,
		.type    = SOCK_STREAM,
		.port    = DEFAULT_PORT,
	};
	struct protoent *pe;
	int both_mode = 0;
	unsigned int tmp;
	int forever = 0;
	int fd[2];
	int cpid;

	/* process inputs */
	extern char *optarg;
	int rc = 0;

	/*
	 * process input args
	 */

	while ((rc = getopt(argc, argv, GETOPT_STR)) != -1) {
		switch (rc) {
		case 'B':
			both_mode = 1;
			break;
		case 's':
			server_mode = 1;
			break;
		case 'F':
			forever = 1;
			break;
		case 'l':
			args.has_local_ip = 1;
			args.local_addr_str = optarg;
			break;
		case 'r':
			args.has_remote_ip = 1;
			args.remote_addr_str = optarg;
			break;
		case 'c':
			args.has_local_ip = 1;
			args.client_local_addr_str = optarg;
			break;
		case 'p':
			if (str_to_uint(optarg, 1, 65535, &tmp) != 0) {
				fprintf(stderr, "Invalid port\n");
				return 1;
			}
			args.port = (unsigned short) tmp;
			break;
		case 't':
			if (str_to_uint(optarg, 0, INT_MAX,
					&prog_timeout) != 0) {
				fprintf(stderr, "Invalid timeout\n");
				return 1;
			}
			break;
		case 'D':
			args.type = SOCK_DGRAM;
			break;
		case 'R':
			args.type = SOCK_RAW;
			args.port = 0;
			if (!args.protocol)
				args.protocol = IPPROTO_RAW;
			break;
		case 'P':
			pe = getprotobyname(optarg);
			if (pe) {
				args.protocol = pe->p_proto;
			} else {
				if (str_to_uint(optarg, 0, 0xffff, &tmp) != 0) {
					fprintf(stderr, "Invalid protocol\n");
					return 1;
				}
				args.protocol = tmp;
			}
			break;
		case 'n':
			iter = atoi(optarg);
			break;
		case 'N':
			args.clientns = optarg;
			break;
		case 'O':
			args.serverns = optarg;
			break;
		case 'L':
			msg = random_msg(atoi(optarg));
			break;
		case 'M':
			args.password = optarg;
			break;
		case 'X':
			args.client_pw = optarg;
			break;
		case 'm':
			args.md5_prefix_str = optarg;
			break;
		case 'S':
			args.use_setsockopt = 1;
			break;
		case 'C':
			args.use_cmsg = 1;
			break;
		case 'd':
			args.dev = optarg;
			break;
		case 'I':
			args.server_dev = optarg;
			break;
		case 'i':
			interactive = 1;
			break;
		case 'g':
			args.has_grp = 1;
			if (convert_addr(&args, optarg, ADDR_TYPE_MCAST) < 0)
				return 1;
			args.type = SOCK_DGRAM;
			break;
		case '6':
			args.version = AF_INET6;
			break;
		case 'b':
			args.bind_test_only = 1;
			break;
		case '0':
			args.has_expected_laddr = 1;
			args.expected_laddr_str = optarg;
			break;
		case '1':
			args.has_expected_raddr = 1;
			args.expected_raddr_str = optarg;
			break;
		case '2':
			args.expected_dev = optarg;
			break;
		case '3':
			args.expected_server_dev = optarg;
			break;
		case 'q':
			quiet = 1;
			break;
		default:
			print_usage(argv[0]);
			return 1;
		}
	}

	if (args.password &&
	    ((!args.has_remote_ip && !args.md5_prefix_str) ||
	      args.type != SOCK_STREAM)) {
		log_error("MD5 passwords apply to TCP only and require a remote ip for the password\n");
		return 1;
	}

	if (args.md5_prefix_str && !args.password) {
		log_error("Prefix range for MD5 protection specified without a password\n");
		return 1;
	}

	if (iter == 0) {
		fprintf(stderr, "Invalid number of messages to send\n");
		return 1;
	}

	if (args.type == SOCK_STREAM && !args.protocol)
		args.protocol = IPPROTO_TCP;
	if (args.type == SOCK_DGRAM && !args.protocol)
		args.protocol = IPPROTO_UDP;

	if ((args.type == SOCK_STREAM || args.type == SOCK_DGRAM) &&
	     args.port == 0) {
		fprintf(stderr, "Invalid port number\n");
		return 1;
	}

	if ((both_mode || !server_mode) && !args.has_grp &&
	    !args.has_remote_ip && !args.has_local_ip) {
		fprintf(stderr,
			"Local (server mode) or remote IP (client IP) required\n");
		return 1;
	}

	if (interactive) {
		prog_timeout = 0;
		msg = NULL;
	}

	if (both_mode) {
		if (pipe(fd) < 0) {
			perror("pipe");
			exit(1);
		}

		cpid = fork();
		if (cpid < 0) {
			perror("fork");
			exit(1);
		}
		if (cpid)
			return ipc_parent(cpid, fd[0], &args);

		return ipc_child(fd[1], &args);
	}

	if (server_mode) {
		do {
			rc = do_server(&args, -1);
		} while (forever);

		return rc;
	}
	return do_client(&args);
}
