#define _XOPEN_SOURCE 500 #define __EXTENSIONS__ #include #include #include #include #include #include #include /* #include */ int main(int argc, char **argv) { int echo_s; struct sockaddr_in laddr; int ret; struct msghdr mhdr; struct iovec iov; char data[8192]; char cdata[sizeof (struct sockaddr_in) + sizeof (struct cmsghdr)]; struct cmsghdr *cmsg; struct sockaddr_in from; struct sockaddr_in toaddr; socklen_t fromlen = sizeof (struct sockaddr_in); fd_set rset; int i; struct in_addr ip_addr; char str[32]; struct cmsghdr *cmptr; if (argc < 2) { printf("usage: udpServerDaddr \n"); exit(0); } echo_s = socket(AF_INET, SOCK_DGRAM, 0); bzero(&laddr, sizeof (laddr)); laddr.sin_family = AF_INET; laddr.sin_port = htons(atoi(argv[1])); if (bind(echo_s, (struct sockaddr *)&laddr, sizeof (laddr)) < 0) { perror("bind error"); exit(1); } i = 1; setsockopt(echo_s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof (i)); i = 1; if (setsockopt(echo_s, IPPROTO_IP, IP_RECVDSTADDR, (char *) &i, sizeof(i)) < 0) perror("IP_RECVDSTADDR setsockopt error"); FD_ZERO(&rset); while (1) { FD_SET(echo_s, &rset); select(5, &rset, NULL, NULL, NULL); if (FD_ISSET(echo_s, &rset) ) { bzero(cdata, sizeof (cdata)); bzero(&mhdr, sizeof (mhdr)); mhdr.msg_name = &from; mhdr.msg_namelen = fromlen; mhdr.msg_iov = &iov; mhdr.msg_iovlen = 1; mhdr.msg_control = cdata; mhdr.msg_controllen = sizeof (cdata); iov.iov_base = data; iov.iov_len = sizeof (data); cmsg = (struct cmsghdr *)cdata; if ((ret = recvmsg(echo_s, &mhdr, MSG_DONTWAIT)) < 0) { perror("recvmsg()"); } /* recv address info */ for (cmptr = CMSG_FIRSTHDR(&mhdr); cmptr != NULL; cmptr = CMSG_NXTHDR(&mhdr, cmptr)) { if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR) { memcpy(&ip_addr, CMSG_DATA(cmptr), sizeof(struct in_addr)); printf("udp message sent to: %s\n", inet_ntop(AF_INET, &ip_addr, str, sizeof(str))); } } /* end of recv adddress info */ /* echo back */ iov.iov_len = ret; toaddr.sin_family = AF_INET; toaddr.sin_addr = ip_addr; toaddr.sin_port = laddr.sin_port; mhdr.msg_name = &toaddr; if (sendmsg(echo_s, &mhdr, MSG_DONTWAIT) < 0) { perror("sendmsg()"); } printf("received:"); fflush(stdout); write(1, data, ret); } } }