/* 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 */ setsockopt(LISTENSOCKET, IPPROTO_IP, IP_PKTINFO, &true, sizeof(1L)); 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); struct msghdr msg; char buf[512]; union { struct cmsghdr cm; u_char data[ sizeof(struct cmsghdr) + sizeof(int) + sizeof(struct in_addr) ]; } ip_msg; struct in_addr interface; /* Zero out the structures before we use them */ /* This sets several key values to NULL */ bzero(&msg,sizeof(msg)); bzero(&ip_msg,sizeof(ip_msg)); /* Initialize the message structure */ msg.msg_control = ip_msg.data; 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); bcopy(ip_msg.data + sizeof(struct cmsghdr) + sizeof(int),&interface,sizeof(struct in_addr)); /* */ fprintf(stderr,"Client: %s, port %d\r\n",inet_ntoa(cliAddress.sin_addr),ntohs(cliAddress.sin_port)); fprintf(stderr,"Server: %s, port %d\r\n", inet_ntoa(interface),TEST_UDP_PORT); /* If this were a real application, we'd probably want to do something intelligent with buf here */ } }