在接受到UDP包后,有时候我们需要根据所接收到得UDP包,获取它的路由目的IP地址和头标识目的地址。
在setsockopt中设置IP_PKTINFO,然后通过recvmsg来获取struct in_pktinfo(struct in_pktinfo是struct msghdr中msg_control的成员).in_pktinfo 结构体(如下所示),我们可以从in_pktinfo中获取路由目的地址(destination address of the packet)、头标识目的地址(source address of the packet)。这种方法只能用于UDP(数据报)传输中。
ipi_ifindex指的是接收包的接口的唯一索引,ipi_spec_dst指的是路由表记录中的目的地址,而ipi_addr 指的是包头中的目的地址。如果给setsockopt传递了IP_PKTINFO,那么外发的包会通过在ipi_ifindex中指定的接口发送出去,同时把ipi_spec_dst设置为目的地址。




1、开启虚拟机下面的例子程序
2、通过windows下面的网络调试助手向虚拟机发送数据
因为通过虚拟网卡的,所以我们看到目标IP地址并不是网络调试助手中设置的IP,而是虚拟网卡的地址,通过Linux下的tcpdump我们可以看到其中网卡转发的过程。
1、struct in_addr
in_addr_t 一般为 32位的unsigned long,其字节顺序为网络顺序(network byte ordered),即该无符号整数采用大端字节序
2、struct msghdr


struct msghdr看上去似乎是一个需要创建的巨大的结构。但是不要怕。其结构成员可分为四组:
套接口地址成员: msg_name与msg_namelen。 I/O向量引用:msg_iov与msg_iovlen。 附属数据缓冲区成员:msg_control与msg_controllen。 接收信息标记位:msg_flags。
在我们将这个结构分为上面的几类以后,结构看起来就不那样巨大了。
标记位
描述
MSG_EOR
当接收到记录结尾时会设置这一位。这通常对于SOCK_SEQPACKET套接口类型十分有用。
MSG_TRUNC
这个标记位表明数据的结尾被截短,因为接收缓冲区太小不足以接收全部的数据。
MSG_CTRUNC
这个标记位表明某些控制数据(附属数据)被截短,因为缓冲区太小。
MSG_OOB
这个标记位表明接收了带外数据。
MSG_ERRQUEUE
个标记位表明没有接收到数据,但是返回一个扩展错误。
3、struct cmsghdr结构
recvmsg与sendmsg函数允许程序发送或是接收附属数据。然而,这些额外的信息受限于一定的格式规则。下面将会介绍控制信息头与程序将会用来管理这些信息的宏。
属信息可以包括0,1,或是更多的单独附属数据对象。在每一个对象之前都有一个struct cmsghdr结构。头部之后是填充字节,然后是对象本身。最后,附属数据对象之后,下一个cmsghdr之前也许要有更多的填充字节。在这里,我们将要关注的附属数据对象是文件描述符与证书结构。
图1显示了一个包含附属数据的缓冲区是如何组织的。
图1 辅助数据结构是由各种子结构、数据区, 填充字节构成
我们需要注意以下几点:
cmsg_len与CMSG_LEN()宏值所显示的长度相同。
CMSG_SPACE()宏可以计算一个附属数据对象的所必需的空白。
msg_controllen是CMSG_SPACE()长度之后,并且为每一个附属数据对象进行计算。
其成员描述如下:
成员
描述
cmsg_len
附属数据的字节计数,这包含结构头的尺寸。这个值是由CMSG_LEN()宏计算的。
cmsg_level
这个值表明了原始的协议级别(例如,SOL_SOCKET)。
cmsg_type
这个值表明了控制信息类型(例如,SCM_RIGHTS)。
cmsg_data
这个成员并不实际存在。他用来指明实际的额外附属数据所在的位置。
这一章所用的例子程序只使用SOL_SOCKET的cmsg_level值。这一章我们感兴趣的控制信息类型如下(cmsg_level=SOL_SOCKET):
SCM_RIGHTS
附属数据对象是一个文件描述符
SCM_CREDENTIALS
附属数据对象是一个包含证书信息的结构


参考链接
<a href="http://hi.baidu.com/linux_kernel/item/c1f91d3fb0ffd5352e20c494">套接字选项(四)</a>
<a href="http://blog.chinaunix.net/uid-20583479-id-1919933.html">inet_pton & inet_ntop函数</a>
<a href="http://blog.csdn.net/wsllq334/article/details/6977039">关于struct msghdr和struct cmsghdr</a>
<a href="http://alas.matf.bg.ac.rs/manuals/lspe/mode=1.html">Linux Socket Programming by Example - Warren Gay</a>
<a href="http://blog.csdn.net/mylxiaoyi/article/category/304912">Linux Socket学习</a>
本文转自陈哈哈博客园博客,原文链接<b>http://www.cnblogs.com/kissazi2/p/3158603.html如需转载请自行联系原作者</b>
<b></b>
<b>kissazi2</b>