在接受到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>