| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 560 人关注过本帖
标题:有没有人用过sendmsg这个函数?
只看楼主 加入收藏
lezijia
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2010-6-8
收藏
 问题点数:0 回复次数:0 
有没有人用过sendmsg这个函数?
这是在freebsd系统的一端源代码,主要是计算机调用用sendmsg函数与OSPF路由器通信:
int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst,unsigned int *ifindex, struct iovec *message) {
int retval;
struct msghdr smsghdr;
struct cmsghdr *scmsgp;
u_char cmsgbuf[CMSG_SPACE(sizeof (struct in6_pktinfo))];
struct in6_pktinfo *pktinfo;
struct sockaddr_in6 dst_sin6;

assert(dst);
assert(*ifindex);

scmsgp = (struct cmsghdr *) cmsgbuf;
pktinfo = (struct in6_pktinfo *) (CMSG_DATA(scmsgp));
memset(&dst_sin6, 0, sizeof (struct sockaddr_in6));

/* source address */
pktinfo->ipi6_ifindex = *ifindex;
if (src)
memcpy(&pktinfo->ipi6_addr, src, sizeof (struct in6_addr));
else
memset(&pktinfo->ipi6_addr, 0, sizeof (struct in6_addr));

/* destination address */
dst_sin6.sin6_family = AF_INET6;
#ifdef SIN6_LEN
dst_sin6.sin6_len = sizeof (struct sockaddr_in6);
#endif /*SIN6_LEN*/
memcpy(&dst_sin6.sin6_addr, dst, sizeof (struct in6_addr));
#ifdef HAVE_SIN6_SCOPE_ID
dst_sin6.sin6_scope_id = *ifindex;
#endif

/* send control msg */
scmsgp->cmsg_level = IPPROTO_IPV6;
scmsgp->cmsg_type = IPV6_PKTINFO;
scmsgp->cmsg_len = CMSG_LEN(sizeof (struct in6_pktinfo));
/* scmsgp = CMSG_NXTHDR (&smsghdr, scmsgp); */

/* send msg hdr */
memset(&smsghdr, 0, sizeof (smsghdr));
smsghdr.msg_iov = message;
smsghdr.msg_iovlen = iov_count(message);
smsghdr.msg_name = (caddr_t) & dst_sin6;
smsghdr.msg_namelen = sizeof (struct sockaddr_in6);
smsghdr.msg_control = (caddr_t) cmsgbuf;
smsghdr.msg_controllen = sizeof (cmsgbuf);

printf("sendmsg: ospf6_sock: %d\n", ospf6_sock);
retval = sendmsg(ospf6_sock, &smsghdr, 0);
printf("reval is %d\n", retval);
if (retval != iov_totallen(message))
printf("sendmsg failed: ifindex: %d: (%d)", *ifindex, errno);
// printf ("sendmsg failed: ifindex: %d: %s (%d)",*ifindex, safe_strerror (errno), errno);
printf("ospf6_sendmsg(): finished. \n");
return retval;
}

在solaris以及red hat linux下测试均可成功调用,在Cent OS 5.4测试报错,提示“reval is -1
sendmsg failed: ifindex: 2: (22)ospf6_sendmsg(): finished. ”
上网查22号错误是Invaild Segment.
后来把 “smsghdr.msg_controllen = sizeof (cmsgbuf);”这行代码注释后不再报错,就是说问题出在smsghdr.msg_control上。奇怪的是,通过对比red hat 和centOS,结构体smsghdr的定义完全一样的。
在注释了此行的情况下,在Cent下使用该函数与OSPF路由器通信,正常的情况应该是计算机先组播一个OSPF HELLO(把HELLO包发去ff02::5),然后路由器回应一个OSPF HELLO,计算机从HELLO获取路由器网关IP 然后计算机向该地址发一个OSPF DB Descri.包,然后路由器也会回应一个OSPF DB Descri. 该过程在solaris和red hat下测试均无问题,可是在Cent下发了OSPF DB Descri.路由器就没有回应了。Cent是在虚拟机跑的,在WIN XP安装了WireShark进行抓包,发现DB Descri.包已成功发给路由器,不知道为什么路由器没有回应。
在red hat下进行抓包,发现前几个包各个字段与Cent下是一模一样的。但red hat下路由器有回应DB Descri. 本人做的改动仅仅在于上面所讲的注释 “smsghdr.msg_controllen = sizeof (cmsgbuf);”这行。因此怀疑是这里出了问题。本人猜测由于发OSPF HELLO包的时候并没有用到msg_control里面的内容,因此路由器就正常回应了一个OSPF HELLO回来,但可能DB Descri.是放在msg_control里面,由于注释了msg_controllen,因此路由器收到计算机随后发来的DB Descri.包后没有对msg_control进行检查,因此就不知道这是一个DB Descri.包 因此就没有回应。
请各位大侠帮小弟分析一下。

搜索更多相关主题的帖子: sendmsg 函数 
2010-06-08 15:15
快速回复:有没有人用过sendmsg这个函数?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020328 second(s), 9 queries.
Copyright©2004-2025, BCCN.NET, All Rights Reserved