IP_RECVDSTADDR undefined

IP_RECVDSTADDR undefined


刺猬@http://blog.csdn.net/littlehedgehog





今天写一个unp上面的例子程序,被IP_RECVDSTADDR undefined难倒了,gcc老是报错说该宏未定义,最后还是在老外的一个“开源苹果”网站查到原来linux修改了相关的函数定义,包括cmsghdr及setsockopt都采用了linux系统自己的定义。顺便说一下,这个貌似并不是linux故意另辟蹊径,在solari和bsd上面也是各不相同的。这里把代码贴出来,方便后面的同学。

 

 

#include "./unix.h" #include <sys/param.h> ssize_t recvmsg_flags(int sockfd, void *buff, size_t nbytes, int *pflags, struct sockaddr *praddr, socklen_t *psocklen, struct in_addr *plocaladdr) { ssize_t ret; struct msghdr msg; struct cmsghdr *cmsgptr; struct iovec iov[1]; union{ struct cmsghdr cmsg; char control[CMSG_SPACE(sizeof(struct in_pktinfo))]; }cmsg_un; msg.msg_name = praddr; msg.msg_namelen = *psocklen; iov[0].iov_base = buff; iov[0].iov_len = nbytes; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_control = cmsg_un.control; msg.msg_controllen = sizeof(cmsg_un.control); msg.msg_flags = 0; /*这个flags设置问题*/ if ((ret = recvmsg(sockfd, &msg, 0)) < 0) { perror("recvmsg"); return ret; } *psocklen = msg.msg_namelen; *pflags = msg.msg_flags; if ((msg.msg_controllen < sizeof(struct cmsghdr)) || (msg.msg_flags & MSG_CTRUNC) || !plocaladdr) { return ret; } for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { #if defined(IP_RECVDSTADDR) if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_RECVDSTADDR) { memcpy(plocaladdr, CMSG_DATA(cmsgptr), sizeof(struct in_addr)); } #elif defined(IP_PKTINFO) if (cmsgptr->cmsg_level == SOL_IP && cmsgptr->cmsg_type == IP_PKTINFO) { struct in_pktinfo *in = (struct in_pktinfo *)CMSG_DATA(cmsgptr); memcpy(plocaladdr, &(in->ipi_addr), sizeof(struct in_addr)); } #endif } return ret; } void echo(int sockfd, const struct sockaddr *pservaddr, socklen_t len, struct FILE *fp) { int ret; int flags = 0; const int on = 1; struct in_addr localaddr; char sendline[MAXLINE], recvline[MAXLINE]; #if defined(IP_RECVDSTADDR) if (setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(int)) < 0) { perror("setsockopt"); return; } #elif defined(IP_PKTINFO) if (setsockopt(sockfd, IPPROTO_IP, IP_PKTINFO, &on, sizeof(int)) < 0) { perror("setsockopt"); return; } #endif memset(&localaddr, 0x00, sizeof(struct in_addr)); while (fgets(sendline, MAXLINE, fp) != NULL) { if (sendto(sockfd, sendline, strlen(sendline), 0x00, pservaddr, len) < 0) { perror("sendto"); return; } if ((ret = recvmsg_flags(sockfd, recvline, MAXLINE, &flags, pservaddr, &len, &localaddr)) < 0) { return; } printf("recvmsg %d-byte datagram through %s/n", ret, inet_ntoa(localaddr)); } } int main(int argc, char *argv[]) { int connfd; struct sockaddr_in servaddr; if ((connfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(-1); } memset(&servaddr, 0x00, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(1988); servaddr.sin_addr.s_addr = inet_addr("192.168.149.95"); echo(connfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in), stdin); close(connfd); return 0; } 

你可能感兴趣的:(linux,struct,socket,gcc,null,FP)