DragonFlyBSD Kernel Audit
DF-0631 / udppkt.c
← back to finding ↓ download raw
/*
 * DF-0631 trigger helper: send UDP datagrams from a fixed source port to a
 * fixed destination, optionally in a burst.  Reusing the same source port
 * keeps the 5-tuple identical across invocations so the ipfw3 keep-state
 * entry is matched again.  Bursts help cover the per-CPU state tables.
 *
 *   ./udppkt [count]            (default count=1)
 *
 * compile: cc -o udppkt udppkt.c
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#define SPORT 11111
#define DPORT 1
#define DGW   "10.0.2.2"   /* QEMU user-net gateway: routes out vtnet0 */

int main(int argc, char **argv)
{
	int s, i, n = 1;
	struct sockaddr_in src, dst;
	const char *msg = "x";

	if (argc > 1) n = atoi(argv[1]);
	if (n < 1) n = 1;

	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("socket"); return 1;
	}
	memset(&src, 0, sizeof(src));
	src.sin_family = AF_INET;
	src.sin_port = htons(SPORT);
	src.sin_addr.s_addr = htonl(INADDR_ANY);
	if (bind(s, (struct sockaddr *)&src, sizeof(src)) < 0) {
		perror("bind"); return 1;
	}
	memset(&dst, 0, sizeof(dst));
	dst.sin_family = AF_INET;
	dst.sin_port = htons(DPORT);
	inet_pton(AF_INET, DGW, &dst.sin_addr);

	for (i = 0; i < n; i++) {
		if (sendto(s, msg, 1, 0,
			   (struct sockaddr *)&dst, sizeof(dst)) < 0) {
			perror("sendto"); return 1;
		}
	}
	printf("udppkt: sent %d UDP %s:%d -> %s:%d\n",
		n, "10.0.2.15", SPORT, DGW, DPORT);
	close(s);
	return 0;
}