#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <winsock2.h>
#include <Ws2tcpip.h>

#define PORT 46123
#define BUF_LENGTH 1024

static SOCKET sock;

static void
handle_error (const char *funcname)
{
    fprintf (stderr, "%s failed: %d\n", funcname, WSAGetLastError ());
    closesocket (sock);
    exit (EXIT_FAILURE);
}

int
main (void)
{
    WSADATA wsa;

    int result = WSAStartup (MAKEWORD (2, 2), &wsa);
    if (result != 0)
    {
        fprintf (stderr, "WSAStartup: %d\n", result);
        exit (EXIT_FAILURE);
    }

    if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
        handle_error ("socket");

    SOCKADDR_IN addr;
    memset (&addr, 0, sizeof (SOCKADDR_IN));
    addr.sin_family = AF_INET;
    addr.sin_port = htons (PORT);
    addr.sin_addr.s_addr = htonl (INADDR_ANY);

    if (bind (sock, (SOCKADDR *) &addr, sizeof (addr)) == SOCKET_ERROR)
        handle_error ("bind");

    while (true)
    {
        char buf[BUF_LENGTH];
        struct sockaddr_in src_addr;
        int addrlen = sizeof (SOCKADDR_IN);
        char str[INET_ADDRSTRLEN];

        int bytes = recvfrom (sock, buf, BUF_LENGTH, 0,
                              (SOCKADDR *) &src_addr, &addrlen);
        if (bytes == SOCKET_ERROR)
            handle_error ("recvfrom");

        if (InetNtop (AF_INET, &src_addr.sin_addr, str, INET_ADDRSTRLEN) == NULL)
        {
            fprintf (stderr, "Could not convert address to string\n");
            exit (EXIT_FAILURE);
        }

        printf ("Received %d bytes from %s\n", bytes, str);
    }

    return 0;
}