// SPDX-License-Identifier: GPL-2.0
/*
 * Inject packets with all sorts of encapsulation into the kernel.
 *
 * IPv4/IPv6	outer layer 3
 * GRE/GUE/BARE outer layer 4, where bare is IPIP/SIT/IPv4-in-IPv6/..
 * IPv4/IPv6    inner layer 3
 */

#define _GNU_SOURCE

#include <stddef.h>
#include <arpa/inet.h>
#include <asm/byteorder.h>
#include <error.h>
#include <errno.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/ipv6.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <poll.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#define CFG_PORT_INNER	8000

/* Add some protocol definitions that do not exist in userspace */

struct grehdr {
	uint16_t unused;
	uint16_t protocol;
} __attribute__((packed));

struct guehdr {
	union {
		struct {
#if defined(__LITTLE_ENDIAN_BITFIELD)
			__u8	hlen:5,
				control:1,
				version:2;
#elif defined (__BIG_ENDIAN_BITFIELD)
			__u8	version:2,
				control:1,
				hlen:5;
#else
#error  "Please fix <asm/byteorder.h>"
#endif
			__u8	proto_ctype;
			__be16	flags;
		};
		__be32	word;
	};
};

static uint8_t	cfg_dsfield_inner;
static uint8_t	cfg_dsfield_outer;
static uint8_t	cfg_encap_proto;
static bool	cfg_expect_failure = false;
static int	cfg_l3_extra = AF_UNSPEC;	/* optional SIT prefix */
static int	cfg_l3_inner = AF_UNSPEC;
static int	cfg_l3_outer = AF_UNSPEC;
static int	cfg_num_pkt = 10;
static int	cfg_num_secs = 0;
static char	cfg_payload_char = 'a';
static int	cfg_payload_len = 100;
static int	cfg_port_gue = 6080;
static bool	cfg_only_rx;
static bool	cfg_only_tx;
static int	cfg_src_port = 9;

static char	buf[ETH_DATA_LEN];

#define INIT_ADDR4(name, addr4, port)				\
	static struct sockaddr_in name = {			\
		.sin_family = AF_INET,				\
		.sin_port = __constant_htons(port),		\
		.sin_addr.s_addr = __constant_htonl(addr4),	\
	};

#define INIT_ADDR6(name, addr6, port)				\
	static struct sockaddr_in6 name = {			\
		.sin6_family = AF_INET6,			\
		.sin6_port = __constant_htons(port),		\
		.sin6_addr = addr6,				\
	};

INIT_ADDR4(in_daddr4, INADDR_LOOPBACK, CFG_PORT_INNER)
INIT_ADDR4(in_saddr4, INADDR_LOOPBACK + 2, 0)
INIT_ADDR4(out_daddr4, INADDR_LOOPBACK, 0)
INIT_ADDR4(out_saddr4, INADDR_LOOPBACK + 1, 0)
INIT_ADDR4(extra_daddr4, INADDR_LOOPBACK, 0)
INIT_ADDR4(extra_saddr4, INADDR_LOOPBACK + 1, 0)

INIT_ADDR6(in_daddr6, IN6ADDR_LOOPBACK_INIT, CFG_PORT_INNER)
INIT_ADDR6(in_saddr6, IN6ADDR_LOOPBACK_INIT, 0)
INIT_ADDR6(out_daddr6, IN6ADDR_LOOPBACK_INIT, 0)
INIT_ADDR6(out_saddr6, IN6ADDR_LOOPBACK_INIT, 0)
INIT_ADDR6(extra_daddr6, IN6ADDR_LOOPBACK_INIT, 0)
INIT_ADDR6(extra_saddr6, IN6ADDR_LOOPBACK_INIT, 0)

static unsigned long util_gettime(void)
{
	struct timeval tv;

	gettimeofday(&tv, NULL);
	return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
}

static void util_printaddr(const char *msg, struct sockaddr *addr)
{
	unsigned long off = 0;
	char nbuf[INET6_ADDRSTRLEN];

	switch (addr->sa_family) {
	case PF_INET:
		off = __builtin_offsetof(struct sockaddr_in, sin_addr);
		break;
	case PF_INET6:
		off = __builtin_offsetof(struct sockaddr_in6, sin6_addr);
		break;
	default:
		error(1, 0, "printaddr: unsupported family %u\n",
		      addr->sa_family);
	}

	if (!inet_ntop(addr->sa_family, ((void *) addr) + off, nbuf,
		       sizeof(nbuf)))
		error(1, errno, "inet_ntop");

	fprintf(stderr, "%s: %s\n", msg, nbuf);
}

static unsigned long add_csum_hword(const uint16_t *start, int num_u16)
{
	unsigned long sum = 0;
	int i;

	for (i = 0; i < num_u16; i++)
		sum += start[i];

	return sum;
}

static uint16_t build_ip_csum(const uint16_t *start, int num_u16,
			      unsigned long sum)
{
	sum += add_csum_hword(start, num_u16);

	while (sum >> 16)
		sum = (sum & 0xffff) + (sum >> 16);

	return ~sum;
}

static void build_ipv4_header(void *header, uint8_t proto,
			      uint32_t src, uint32_t dst,
			      int payload_len, uint8_t tos)
{
	struct iphdr *iph = header;

	iph->ihl = 5;
	iph->version = 4;
	iph->tos = tos;
	iph->ttl = 8;
	iph->tot_len = htons(sizeof(*iph) + payload_len);
	iph->id = htons(1337);
	iph->protocol = proto;
	iph->saddr = src;
	iph->daddr = dst;
	iph->check = build_ip_csum((void *) iph, iph->ihl << 1, 0);
}

static void ipv6_set_dsfield(struct ipv6hdr *ip6h, uint8_t dsfield)
{
	uint16_t val, *ptr = (uint16_t *)ip6h;

	val = ntohs(*ptr);
	val &= 0xF00F;
	val |= ((uint16_t) dsfield) << 4;
	*ptr = htons(val);
}

static void build_ipv6_header(void *header, uint8_t proto,
			      struct sockaddr_in6 *src,
			      struct sockaddr_in6 *dst,
			      int payload_len, uint8_t dsfield)
{
	struct ipv6hdr *ip6h = header;

	ip6h->version = 6;
	ip6h->payload_len = htons(payload_len);
	ip6h->nexthdr = proto;
	ip6h->hop_limit = 8;
	ipv6_set_dsfield(ip6h, dsfield);

	memcpy(&ip6h->saddr, &src->sin6_addr, sizeof(ip6h->saddr));
	memcpy(&ip6h->daddr, &dst->sin6_addr, sizeof(ip6h->daddr));
}

static uint16_t build_udp_v4_csum(const struct iphdr *iph,
				  const struct udphdr *udph,
				  int num_words)
{
	unsigned long pseudo_sum;
	int num_u16 = sizeof(iph->saddr);	/* halfwords: twice byte len */

	pseudo_sum = add_csum_hword((void *) &iph->saddr, num_u16);
	pseudo_sum += htons(IPPROTO_UDP);
	pseudo_sum += udph->len;
	return build_ip_csum((void *) udph, num_words, pseudo_sum);
}

static uint16_t build_udp_v6_csum(const struct ipv6hdr *ip6h,
				  const struct udphdr *udph,
				  int num_words)
{
	unsigned long pseudo_sum;
	int num_u16 = sizeof(ip6h->saddr);	/* halfwords: twice byte len */

	pseudo_sum = add_csum_hword((void *) &ip6h->saddr, num_u16);
	pseudo_sum += htons(ip6h->nexthdr);
	pseudo_sum += ip6h->payload_len;
	return build_ip_csum((void *) udph, num_words, pseudo_sum);
}

static void build_udp_header(void *header, int payload_len,
			     uint16_t dport, int family)
{
	struct udphdr *udph = header;
	int len = sizeof(*udph) + payload_len;

	udph->source = htons(cfg_src_port);
	udph->dest = htons(dport);
	udph->len = htons(len);
	udph->check = 0;
	if (family == AF_INET)
		udph->check = build_udp_v4_csum(header - sizeof(struct iphdr),
						udph, len >> 1);
	else
		udph->check = build_udp_v6_csum(header - sizeof(struct ipv6hdr),
						udph, len >> 1);
}

static void build_gue_header(void *header, uint8_t proto)
{
	struct guehdr *gueh = header;

	gueh->proto_ctype = proto;
}

static void build_gre_header(void *header, uint16_t proto)
{
	struct grehdr *greh = header;

	greh->protocol = htons(proto);
}

static int l3_length(int family)
{
	if (family == AF_INET)
		return sizeof(struct iphdr);
	else
		return sizeof(struct ipv6hdr);
}

static int build_packet(void)
{
	int ol3_len = 0, ol4_len = 0, il3_len = 0, il4_len = 0;
	int el3_len = 0;

	if (cfg_l3_extra)
		el3_len = l3_length(cfg_l3_extra);

	/* calculate header offsets */
	if (cfg_encap_proto) {
		ol3_len = l3_length(cfg_l3_outer);

		if (cfg_encap_proto == IPPROTO_GRE)
			ol4_len = sizeof(struct grehdr);
		else if (cfg_encap_proto == IPPROTO_UDP)
			ol4_len = sizeof(struct udphdr) + sizeof(struct guehdr);
	}

	il3_len = l3_length(cfg_l3_inner);
	il4_len = sizeof(struct udphdr);

	if (el3_len + ol3_len + ol4_len + il3_len + il4_len + cfg_payload_len >=
	    sizeof(buf))
		error(1, 0, "packet too large\n");

	/*
	 * Fill packet from inside out, to calculate correct checksums.
	 * But create ip before udp headers, as udp uses ip for pseudo-sum.
	 */
	memset(buf + el3_len + ol3_len + ol4_len + il3_len + il4_len,
	       cfg_payload_char, cfg_payload_len);

	/* add zero byte for udp csum padding */
	buf[el3_len + ol3_len + ol4_len + il3_len + il4_len + cfg_payload_len] = 0;

	switch (cfg_l3_inner) {
	case PF_INET:
		build_ipv4_header(buf + el3_len + ol3_len + ol4_len,
				  IPPROTO_UDP,
				  in_saddr4.sin_addr.s_addr,
				  in_daddr4.sin_addr.s_addr,
				  il4_len + cfg_payload_len,
				  cfg_dsfield_inner);
		break;
	case PF_INET6:
		build_ipv6_header(buf + el3_len + ol3_len + ol4_len,
				  IPPROTO_UDP,
				  &in_saddr6, &in_daddr6,
				  il4_len + cfg_payload_len,
				  cfg_dsfield_inner);
		break;
	}

	build_udp_header(buf + el3_len + ol3_len + ol4_len + il3_len,
			 cfg_payload_len, CFG_PORT_INNER, cfg_l3_inner);

	if (!cfg_encap_proto)
		return il3_len + il4_len + cfg_payload_len;

	switch (cfg_l3_outer) {
	case PF_INET:
		build_ipv4_header(buf + el3_len, cfg_encap_proto,
				  out_saddr4.sin_addr.s_addr,
				  out_daddr4.sin_addr.s_addr,
				  ol4_len + il3_len + il4_len + cfg_payload_len,
				  cfg_dsfield_outer);
		break;
	case PF_INET6:
		build_ipv6_header(buf + el3_len, cfg_encap_proto,
				  &out_saddr6, &out_daddr6,
				  ol4_len + il3_len + il4_len + cfg_payload_len,
				  cfg_dsfield_outer);
		break;
	}

	switch (cfg_encap_proto) {
	case IPPROTO_UDP:
		build_gue_header(buf + el3_len + ol3_len + ol4_len -
				 sizeof(struct guehdr),
				 cfg_l3_inner == PF_INET ? IPPROTO_IPIP
							 : IPPROTO_IPV6);
		build_udp_header(buf + el3_len + ol3_len,
				 sizeof(struct guehdr) + il3_len + il4_len +
				 cfg_payload_len,
				 cfg_port_gue, cfg_l3_outer);
		break;
	case IPPROTO_GRE:
		build_gre_header(buf + el3_len + ol3_len,
				 cfg_l3_inner == PF_INET ? ETH_P_IP
							 : ETH_P_IPV6);
		break;
	}

	switch (cfg_l3_extra) {
	case PF_INET:
		build_ipv4_header(buf,
				  cfg_l3_outer == PF_INET ? IPPROTO_IPIP
							  : IPPROTO_IPV6,
				  extra_saddr4.sin_addr.s_addr,
				  extra_daddr4.sin_addr.s_addr,
				  ol3_len + ol4_len + il3_len + il4_len +
				  cfg_payload_len, 0);
		break;
	case PF_INET6:
		build_ipv6_header(buf,
				  cfg_l3_outer == PF_INET ? IPPROTO_IPIP
							  : IPPROTO_IPV6,
				  &extra_saddr6, &extra_daddr6,
				  ol3_len + ol4_len + il3_len + il4_len +
				  cfg_payload_len, 0);
		break;
	}

	return el3_len + ol3_len + ol4_len + il3_len + il4_len +
	       cfg_payload_len;
}

/* sender transmits encapsulated over RAW or unencap'd over UDP */
static int setup_tx(void)
{
	int family, fd, ret;

	if (cfg_l3_extra)
		family = cfg_l3_extra;
	else if (cfg_l3_outer)
		family = cfg_l3_outer;
	else
		family = cfg_l3_inner;

	fd = socket(family, SOCK_RAW, IPPROTO_RAW);
	if (fd == -1)
		error(1, errno, "socket tx");

	if (cfg_l3_extra) {
		if (cfg_l3_extra == PF_INET)
			ret = connect(fd, (void *) &extra_daddr4,
				      sizeof(extra_daddr4));
		else
			ret = connect(fd, (void *) &extra_daddr6,
				      sizeof(extra_daddr6));
		if (ret)
			error(1, errno, "connect tx");
	} else if (cfg_l3_outer) {
		/* connect to destination if not encapsulated */
		if (cfg_l3_outer == PF_INET)
			ret = connect(fd, (void *) &out_daddr4,
				      sizeof(out_daddr4));
		else
			ret = connect(fd, (void *) &out_daddr6,
				      sizeof(out_daddr6));
		if (ret)
			error(1, errno, "connect tx");
	} else {
		/* otherwise using loopback */
		if (cfg_l3_inner == PF_INET)
			ret = connect(fd, (void *) &in_daddr4,
				      sizeof(in_daddr4));
		else
			ret = connect(fd, (void *) &in_daddr6,
				      sizeof(in_daddr6));
		if (ret)
			error(1, errno, "connect tx");
	}

	return fd;
}

/* receiver reads unencapsulated UDP */
static int setup_rx(void)
{
	int fd, ret;

	fd = socket(cfg_l3_inner, SOCK_DGRAM, 0);
	if (fd == -1)
		error(1, errno, "socket rx");

	if (cfg_l3_inner == PF_INET)
		ret = bind(fd, (void *) &in_daddr4, sizeof(in_daddr4));
	else
		ret = bind(fd, (void *) &in_daddr6, sizeof(in_daddr6));
	if (ret)
		error(1, errno, "bind rx");

	return fd;
}

static int do_tx(int fd, const char *pkt, int len)
{
	int ret;

	ret = write(fd, pkt, len);
	if (ret == -1)
		error(1, errno, "send");
	if (ret != len)
		error(1, errno, "send: len (%d < %d)\n", ret, len);

	return 1;
}

static int do_poll(int fd, short events, int timeout)
{
	struct pollfd pfd;
	int ret;

	pfd.fd = fd;
	pfd.events = events;

	ret = poll(&pfd, 1, timeout);
	if (ret == -1)
		error(1, errno, "poll");
	if (ret && !(pfd.revents & POLLIN))
		error(1, errno, "poll: unexpected event 0x%x\n", pfd.revents);

	return ret;
}

static int do_rx(int fd)
{
	char rbuf;
	int ret, num = 0;

	while (1) {
		ret = recv(fd, &rbuf, 1, MSG_DONTWAIT);
		if (ret == -1 && errno == EAGAIN)
			break;
		if (ret == -1)
			error(1, errno, "recv");
		if (rbuf != cfg_payload_char)
			error(1, 0, "recv: payload mismatch");
		num++;
	};

	return num;
}

static int do_main(void)
{
	unsigned long tstop, treport, tcur;
	int fdt = -1, fdr = -1, len, tx = 0, rx = 0;

	if (!cfg_only_tx)
		fdr = setup_rx();
	if (!cfg_only_rx)
		fdt = setup_tx();

	len = build_packet();

	tcur = util_gettime();
	treport = tcur + 1000;
	tstop = tcur + (cfg_num_secs * 1000);

	while (1) {
		if (!cfg_only_rx)
			tx += do_tx(fdt, buf, len);

		if (!cfg_only_tx)
			rx += do_rx(fdr);

		if (cfg_num_secs) {
			tcur = util_gettime();
			if (tcur >= tstop)
				break;
			if (tcur >= treport) {
				fprintf(stderr, "pkts: tx=%u rx=%u\n", tx, rx);
				tx = 0;
				rx = 0;
				treport = tcur + 1000;
			}
		} else {
			if (tx == cfg_num_pkt)
				break;
		}
	}

	/* read straggler packets, if any */
	if (rx < tx) {
		tstop = util_gettime() + 100;
		while (rx < tx) {
			tcur = util_gettime();
			if (tcur >= tstop)
				break;

			do_poll(fdr, POLLIN, tstop - tcur);
			rx += do_rx(fdr);
		}
	}

	fprintf(stderr, "pkts: tx=%u rx=%u\n", tx, rx);

	if (fdr != -1 && close(fdr))
		error(1, errno, "close rx");
	if (fdt != -1 && close(fdt))
		error(1, errno, "close tx");

	/*
	 * success (== 0) only if received all packets
	 * unless failure is expected, in which case none must arrive.
	 */
	if (cfg_expect_failure)
		return rx != 0;
	else
		return rx != tx;
}


static void __attribute__((noreturn)) usage(const char *filepath)
{
	fprintf(stderr, "Usage: %s [-e gre|gue|bare|none] [-i 4|6] [-l len] "
			"[-O 4|6] [-o 4|6] [-n num] [-t secs] [-R] [-T] "
			"[-s <osrc> [-d <odst>] [-S <isrc>] [-D <idst>] "
			"[-x <otos>] [-X <itos>] [-f <isport>] [-F]\n",
		filepath);
	exit(1);
}

static void parse_addr(int family, void *addr, const char *optarg)
{
	int ret;

	ret = inet_pton(family, optarg, addr);
	if (ret == -1)
		error(1, errno, "inet_pton");
	if (ret == 0)
		error(1, 0, "inet_pton: bad string");
}

static void parse_addr4(struct sockaddr_in *addr, const char *optarg)
{
	parse_addr(AF_INET, &addr->sin_addr, optarg);
}

static void parse_addr6(struct sockaddr_in6 *addr, const char *optarg)
{
	parse_addr(AF_INET6, &addr->sin6_addr, optarg);
}

static int parse_protocol_family(const char *filepath, const char *optarg)
{
	if (!strcmp(optarg, "4"))
		return PF_INET;
	if (!strcmp(optarg, "6"))
		return PF_INET6;

	usage(filepath);
}

static void parse_opts(int argc, char **argv)
{
	int c;

	while ((c = getopt(argc, argv, "d:D:e:f:Fhi:l:n:o:O:Rs:S:t:Tx:X:")) != -1) {
		switch (c) {
		case 'd':
			if (cfg_l3_outer == AF_UNSPEC)
				error(1, 0, "-d must be preceded by -o");
			if (cfg_l3_outer == AF_INET)
				parse_addr4(&out_daddr4, optarg);
			else
				parse_addr6(&out_daddr6, optarg);
			break;
		case 'D':
			if (cfg_l3_inner == AF_UNSPEC)
				error(1, 0, "-D must be preceded by -i");
			if (cfg_l3_inner == AF_INET)
				parse_addr4(&in_daddr4, optarg);
			else
				parse_addr6(&in_daddr6, optarg);
			break;
		case 'e':
			if (!strcmp(optarg, "gre"))
				cfg_encap_proto = IPPROTO_GRE;
			else if (!strcmp(optarg, "gue"))
				cfg_encap_proto = IPPROTO_UDP;
			else if (!strcmp(optarg, "bare"))
				cfg_encap_proto = IPPROTO_IPIP;
			else if (!strcmp(optarg, "none"))
				cfg_encap_proto = IPPROTO_IP;	/* == 0 */
			else
				usage(argv[0]);
			break;
		case 'f':
			cfg_src_port = strtol(optarg, NULL, 0);
			break;
		case 'F':
			cfg_expect_failure = true;
			break;
		case 'h':
			usage(argv[0]);
			break;
		case 'i':
			if (!strcmp(optarg, "4"))
				cfg_l3_inner = PF_INET;
			else if (!strcmp(optarg, "6"))
				cfg_l3_inner = PF_INET6;
			else
				usage(argv[0]);
			break;
		case 'l':
			cfg_payload_len = strtol(optarg, NULL, 0);
			break;
		case 'n':
			cfg_num_pkt = strtol(optarg, NULL, 0);
			break;
		case 'o':
			cfg_l3_outer = parse_protocol_family(argv[0], optarg);
			break;
		case 'O':
			cfg_l3_extra = parse_protocol_family(argv[0], optarg);
			break;
		case 'R':
			cfg_only_rx = true;
			break;
		case 's':
			if (cfg_l3_outer == AF_INET)
				parse_addr4(&out_saddr4, optarg);
			else
				parse_addr6(&out_saddr6, optarg);
			break;
		case 'S':
			if (cfg_l3_inner == AF_INET)
				parse_addr4(&in_saddr4, optarg);
			else
				parse_addr6(&in_saddr6, optarg);
			break;
		case 't':
			cfg_num_secs = strtol(optarg, NULL, 0);
			break;
		case 'T':
			cfg_only_tx = true;
			break;
		case 'x':
			cfg_dsfield_outer = strtol(optarg, NULL, 0);
			break;
		case 'X':
			cfg_dsfield_inner = strtol(optarg, NULL, 0);
			break;
		}
	}

	if (cfg_only_rx && cfg_only_tx)
		error(1, 0, "options: cannot combine rx-only and tx-only");

	if (cfg_encap_proto && cfg_l3_outer == AF_UNSPEC)
		error(1, 0, "options: must specify outer with encap");
	else if ((!cfg_encap_proto) && cfg_l3_outer != AF_UNSPEC)
		error(1, 0, "options: cannot combine no-encap and outer");
	else if ((!cfg_encap_proto) && cfg_l3_extra != AF_UNSPEC)
		error(1, 0, "options: cannot combine no-encap and extra");

	if (cfg_l3_inner == AF_UNSPEC)
		cfg_l3_inner = AF_INET6;
	if (cfg_l3_inner == AF_INET6 && cfg_encap_proto == IPPROTO_IPIP)
		cfg_encap_proto = IPPROTO_IPV6;

	/* RFC 6040 4.2:
	 *   on decap, if outer encountered congestion (CE == 0x3),
	 *   but inner cannot encode ECN (NoECT == 0x0), then drop packet.
	 */
	if (((cfg_dsfield_outer & 0x3) == 0x3) &&
	    ((cfg_dsfield_inner & 0x3) == 0x0))
		cfg_expect_failure = true;
}

static void print_opts(void)
{
	if (cfg_l3_inner == PF_INET6) {
		util_printaddr("inner.dest6", (void *) &in_daddr6);
		util_printaddr("inner.source6", (void *) &in_saddr6);
	} else {
		util_printaddr("inner.dest4", (void *) &in_daddr4);
		util_printaddr("inner.source4", (void *) &in_saddr4);
	}

	if (!cfg_l3_outer)
		return;

	fprintf(stderr, "encap proto:   %u\n", cfg_encap_proto);

	if (cfg_l3_outer == PF_INET6) {
		util_printaddr("outer.dest6", (void *) &out_daddr6);
		util_printaddr("outer.source6", (void *) &out_saddr6);
	} else {
		util_printaddr("outer.dest4", (void *) &out_daddr4);
		util_printaddr("outer.source4", (void *) &out_saddr4);
	}

	if (!cfg_l3_extra)
		return;

	if (cfg_l3_outer == PF_INET6) {
		util_printaddr("extra.dest6", (void *) &extra_daddr6);
		util_printaddr("extra.source6", (void *) &extra_saddr6);
	} else {
		util_printaddr("extra.dest4", (void *) &extra_daddr4);
		util_printaddr("extra.source4", (void *) &extra_saddr4);
	}

}

int main(int argc, char **argv)
{
	parse_opts(argc, argv);
	print_opts();
	return do_main();
}
