/* Show how to get the remote and local IPs from a UDP socket connection */ /* For sockets */ #include #include #include /* For INET sockets */ #include #include /* Printing info about connections */ #include #include #include #include #define TEST_UDP_PORT 6667 int main(void) { int LISTENSOCKET; struct sockaddr_in bindsockaddr; const long true = 1L; LISTENSOCKET = socket(AF_INET, SOCK_DGRAM, 0); /* Get information about each incoming packet */ #ifdef Linux setsockopt(LISTENSOCKET, IPPROTO_IP, IP_PKTINFO, &true, sizeof(true)); #else setsockopt(LISTENSOCKET, IPPROTO_IP, IP_RECVDSTADDR, &true, sizeof(true)); #endif bindsockaddr.sin_family = AF_INET; bindsockaddr.sin_addr.s_addr = htonl(INADDR_ANY); bindsockaddr.sin_port = htons(TEST_UDP_PORT); bind(LISTENSOCKET, (struct sockaddr *)&bindsockaddr, sizeof(bindsockaddr)); fprintf(stderr, "Now listening on udp port %d\n", TEST_UDP_PORT); while (1) { struct sockaddr_in cliAddress; int templen = sizeof(struct sockaddr_in), i; struct msghdr msg; char buf[512]; struct { struct cmsghdr cm; #ifdef Linux int foo; #endif struct in_addr dest[10]; } ip_msg; /* Zero out the structures before we use them */ /* This sets several key values to NULL */ memset(&msg, 0, sizeof(msg)); memset(&ip_msg, 0, sizeof(ip_msg)); /* Initialize the message structure */ msg.msg_control = (caddr_t)&ip_msg; msg.msg_controllen = sizeof(ip_msg); /* Get info about the incoming packet */ recvmsg(LISTENSOCKET, &msg, MSG_PEEK); /* Receive the incoming packet */ recvfrom(LISTENSOCKET, buf, sizeof(buf), 0, (struct sockaddr *)&cliAddress, &templen); fprintf(stderr, "Client: %s, port %d\r\n", inet_ntoa(cliAddress.sin_addr), ntohs(cliAddress.sin_port)); for (i = 0; i < 10; i++) fprintf(stderr, "Server: %s, port %d\r\n", inet_ntoa(ip_msg.dest[i]), TEST_UDP_PORT); /* If this were a real application, we'd probably want to do something intelligent with buf here */ } }