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;} 

           
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值