view net-traffic/udp-test-sink.c @ 10:e686bc92c7d8

revamp for new subdir structure and configure script
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 15 May 2024 01:44:46 +0000
parents udp-test-sink.c@c00510e1ae8b
children
line wrap: on
line source

/*
 * This program is a simple sink for UDP: it binds to a UDP port and sinks
 * (reads and discards) all packets that arrive at it.  Upon receiving a
 * burst or stream of packets followed by a prolonged pause, it prints
 * the number of packets that were received.
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>

static void
parse_ip_port(arg, sin)
	char *arg;
	struct sockaddr_in *sin;
{
	char *cp;
	int rc;

	cp = index(arg, ':');
	if (!cp) {
		fprintf(stderr, "error: missing ':' in IP:port argument\n");
		exit(1);
	}
	*cp++ = '\0';
	sin->sin_family = AF_INET;
	rc = inet_aton(arg, &sin->sin_addr);
	if (!rc) {
		fprintf(stderr, "error: invalid IP address argument\n");
		exit(1);
	}
	sin->sin_port = htons(atoi(cp));
}

main(argc, argv)
	char **argv;
{
	struct sockaddr_in bindsin;
	int udp_fd, rc;
	unsigned idle_sec, rx_count;
	fd_set fds;
	struct timeval tv;
	u_char dummybuf[256];

	if (argc < 2 || argc > 3) {
		fprintf(stderr, "usage: bind-IP:port [idle-sec]\n", argv[0]);
		exit(1);
	}
	parse_ip_port(argv[1], &bindsin);
	if (argc >= 3)
		idle_sec = atoi(argv[2]);
	else
		idle_sec = 0;
	udp_fd = socket(AF_INET, SOCK_DGRAM, 0);
	if (udp_fd < 0) {
		perror("socket(AF_INET, SOCK_DGRAM, 0)");
		exit(1);
	}
	rc = bind(udp_fd, (struct sockaddr *) &bindsin, sizeof bindsin);
	if (rc < 0) {
		perror("bind");
		exit(1);
	}
	for (rx_count = 0; ; ) {
		FD_ZERO(&fds);
		FD_SET(udp_fd, &fds);
		if (rx_count && idle_sec) {
			tv.tv_sec = idle_sec;
			tv.tv_usec = 0;
			rc = select(udp_fd+1, &fds, 0, 0, &tv);
		} else
			rc = select(udp_fd+1, &fds, 0, 0, 0);
		if (rc < 0) {
			if (errno == EINTR)
				continue;
			perror("select");
			exit(1);
		}
		if (FD_ISSET(udp_fd, &fds)) {
			recv(udp_fd, dummybuf, sizeof dummybuf, 0);
			rx_count++;
		} else {
			printf("Received %u packet%s\n", rx_count,
				rx_count != 1 ? "s" : "");
			rx_count = 0;
		}
	}
}