#define _XOPEN_SOURCE 500 #define __EXTENSIONS__ #include #include #include #include #include #include #include #include "mcast.h" #define SA struct sockaddr void init_mhdr(); void display_addr(); 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; socklen_t fromlen = sizeof(struct sockaddr_in); struct in_addr ip_addr; struct cmsghdr *cmptr; char str[32]; int main(int argc, char **argv) { int echo_s; struct sockaddr_in laddr; int ret; int loop; if (argc < 2) { printf("usage: %s \n", argv[0]); exit(0); } echo_s = socket(AF_INET, SOCK_DGRAM, 0); reusePort(echo_s); bzero(&laddr, sizeof(laddr)); laddr.sin_family = AF_INET; laddr.sin_port = htons(atoi(argv[2])); if (bind(echo_s, (struct sockaddr *) & laddr, sizeof(laddr)) < 0) { perror("bind error"); exit(1); } displayDaddr(echo_s); joinGroup(echo_s, argv[1]); joinGroup(echo_s, "224.0.0.2"); joinGroup(echo_s, "224.0.0.3"); loop = 1; setLoopback(echo_s, loop); while (1) { /* using recvmsg & sendmsg */ printf("\n.... Using recvMSG & sendMSG ....\n"); init_mhdr(); if ((ret = recvmsg(echo_s, &mhdr, MSG_WAITALL)) < 0) { perror("recvmsg()"); } printf("received:"); fflush(stdout); write(1, data, ret); display_addr(); iov.iov_len = ret; if (sendmsg(echo_s, &mhdr, MSG_DONTWAIT) < 0) { perror("sendmsg()"); exit(-1); } /* using recvfrom & sendto */ /* printf("\n.... Using recvFROM & sendTO ....\n"); if ((ret = recvfrom(echo_s, data, sizeof(data), 0, (SA *) & from, &fromlen)) < 0) { perror("recvfrom"); } printf("received:"); fflush(stdout); write(1, data, ret); printf("udp message sent from: %s:%d\n", inet_ntop(AF_INET, &from.sin_addr, str, sizeof(str)), ntohs(from.sin_port)); if (sendto(echo_s, data, ret, 0, (SA *) & from, fromlen) < 0) { printf("error in sendto\n"); exit(-1); } */ } } void init_mhdr() { bzero(cdata, sizeof(cdata)); bzero(data, sizeof(data)); 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; } void display_addr() { 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))); printf("udp message sent from: %s:%d\n", inet_ntop(AF_INET, &from.sin_addr, str, sizeof(str)), ntohs(from.sin_port)); } } }