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

int
udpsocket (int port)
{
  int fd;
  struct sockaddr_in sin;

  if (port < 1 || port > 0xffff) {
    fprintf (stderr, "bad port number\n");
    exit (1);
  }

  fd = socket (AF_INET, SOCK_DGRAM, 0);
  if (fd < 0) {
    perror ("socket");
    exit (1);
  }

  bzero (&sin, sizeof (sin));
  sin.sin_family = AF_INET;
  sin.sin_port = htons (port);
  sin.sin_addr.s_addr = htonl (INADDR_ANY);
  if (bind (fd, (struct sockaddr *) &sin, sizeof (sin)) < 0) {
    perror ("bind");
    exit (1);
  }

  return fd;
}

int
main (int argc, char **argv)
{
  int fd;
  struct sockaddr_in sin;
  socklen_t sinlen;
  char buf[512];
  int n;

  if (argc != 2) {
    fprintf (stderr, "usage: %s port\n", argv[0]);
    exit (1);
  }

  fd = udpsocket (atoi (argv[1]));
  for (;;) {
    bzero (&sin, sizeof (sin));
    sinlen = sizeof (sin);
    n = recvfrom (fd, buf, sizeof (buf), 0, (struct sockaddr *) &sin, &sinlen);
    if (n < 0) {
      perror ("recvfrom");
      exit (1);
    }
    fprintf (stderr, "got %d bytes from IP address %s, UDP port %d\n",
	     n, inet_ntoa (sin.sin_addr), ntohs (sin.sin_port));
    sendto (fd, buf, n, 0, (struct sockaddr *) &sin, sizeof (sin));
  }
}

