/* include main1 */
#include	"udpcksum.h"

			/* DefinE global variables */
struct sockaddr	*dest, *local;
socklen_t		destlen, locallen;

int		datalink;		/* from pcap_datalink(), in <net/bpf.h> */
char   *device;			/* pcap device */
int		fddipad;		/* HACK; for libpcap if FDDI defined */
pcap_t *pd;				/* packet capture struct pointer */
int		rawfd;			/* raw socket to write on */
int		snaplen = 200;	/* amount of data to capture */
int		verbose;
int		zerosum;		/* send UDP query with no checksum */

static void	usage(const char *);

int
main(int argc, char *argv[])
{
	int				c, on=1;
	char			*ptr, localname[1024], *localport;
	struct addrinfo	*aip;

	if (argc < 2)
		usage("");

	/*
	 * Need local IP address for source IP address for UDP datagrams.
	 * Can't specify 0 and let IP choose, as we need to know it for
	 * the pseudo-header to calculate the UDP checksum.
	 * Both localname and localport can be overridden by -l option.
	 */

	if (gethostname(localname, sizeof(localname)) < 0)
		err_sys("gethostname error");
	localport = LOCALPORT;
/* end main1 */

/* include main2 */
	opterr = 0;		/* don't want getopt() writing to stderr */
	while ( (c = getopt(argc, argv, "0i:l:v")) != -1) {
		switch (c) {

		case '0':
			zerosum = 1;
			break;

		case 'i':
			device = optarg;			/* pcap device */
			break;

		case 'l':			/* local IP address and port#: a.b.c.d.p */
			if ( (ptr = strrchr(optarg, '.')) == NULL)
				usage("invalid -l option");

			*ptr++ = 0;					/* null replaces final period */
			localport = ptr;			/* service name or port number */
			strncpy(localname, optarg, sizeof(localname));
			break;

		case 'v':
			verbose = 1;
			break;

		case '?':
			usage("unrecognized option");
		}
	}
/* end main2 */
/* include main3 */
	if (optind != argc-2)
		usage("missing <host> and/or <serv>");

		/* 4convert destination name and service */
	aip = host_serv(argv[optind], argv[optind+1], AF_INET, SOCK_DGRAM);
	dest = aip->ai_addr;		/* don't freeaddrinfo() */
	destlen = aip->ai_addrlen;

		/* 4convert local name and service */
	aip = host_serv(localname, localport, AF_INET, SOCK_DGRAM);
	local = aip->ai_addr;		/* don't freeaddrinfo() */
	locallen = aip->ai_addrlen;

	/*
	 * Need a raw socket to write our own IP datagrams to.
	 * Process must have superuser privileges to create this socket.
	 * Also must set IP_HDRINCL so we can write our own IP headers.
	 */

	rawfd = Socket(dest->sa_family, SOCK_RAW, 0);

	Setsockopt(rawfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));

	open_pcap();		/* open packet capture device */

	setuid(getuid());	/* don't need superuser privileges any more */

	Signal(SIGTERM, cleanup);
	Signal(SIGINT, cleanup);
	Signal(SIGHUP, cleanup);

	test_udp();

	cleanup(0);
}
/* end main3 */

static void
usage(const char *msg)
{
	err_msg(
"usage: testudp [ options ] <host> <serv>\n"
"options: -0    send UDP datagram with checksum set to 0"
"         -i s  packet capture device\n"
"         -l a.b.c.d.p  local IP=a.b.c.d, local port=p\n"
"         -v    verbose output"
);

	if (msg[0] != 0)
		err_quit("%s", msg);
	exit(1);
}


syntax highlighted by Code2HTML, v. 0.9.1