學習 原始套接字

2021-04-15 13:10:20 字數 1604 閱讀 3336

原始套接字可以訪問icmp和icmp等協議包,可以讀寫核心不處理的ip資料報。可以建立自定義的ip資料報首部。一句話,使用原始套接字可以

編寫基於ip協議的通訊程式。

1.建立原始套接字

具體格式如下:

int sockfd;

sockfd = socktet(af_inet, sock_raw, ipproto_icmp);

第乙個引數:協議族 af_inet 代表tcp/ip協議

第二個引數:socket型別

第三個引數:協議型別

注意:@如果指定協議為0時,原始套接字可以接收核心傳遞給原始套接字的任何ip資料報,且只有超級使用者才可以建立原始套接字。

@當需要編寫自己的ip資料報首部時,可以在原始套接字上設定套接字選項ip_hdrincl。在不設定這個選項的情況下,ip協議自動填充ip資料報的首部。

int on = 1;

if(setsockopt(sockfd, ipproto_ip, ip_hdrincl, &on, sizeof(on)) < 0)

原始套接字直接使用ip協議的套接字,所以是非面向連線的。在這個套接字上可以呼叫connect和bind函式,分別執行繫結對方和本地位址。

說明:bind函式:呼叫bind函式後,傳送資料報的源ip位址將是bind函式指定的位址。如是不呼叫bind,則核心將以發介面的主ip位址填充。如果設定了ip_hdrincl,那麼必須手工填充每個傳送資料報的源ip位址。

connetc函式:呼叫connect函式後,可以用write和send傳送資料報。核心將用這個繫結的位址填充ip資料報的目的ip位址。

傳送資料報

使用原始套接字傳送資料報必須遵循以下規則:

1.如果沒有用connect函式繫結對方位址時,則應使用sendto或sendmsg函式傳送資料報,在函式引數中指定對方位址。如果呼叫了connect函式,則可以直接使用send,write或writev來傳送資料報。

2.如果沒有設定ip_hdrincl選項時,包內可寫的內容為資料部分,核心將自動建立ip首部。如果設定了ip_hdrincl選項,則包內要填充的內容為ip資料報和首部。核心只負責填充下面兩個域:

·如果將ip資料報的標識域設定為0,核心將設定這個域

·核心總是計算和填充ip資料報首部的校驗和。

注意:ip資料報首部各個域的內容都是網路位元組順序。

接收資料報

核心遵循以下規則接收資料報:

1.udp和tcp資料報從不傳送給乙個原始套接字。如果要檢視這兩類資料報,只能通過直接訪問資料鏈路層來實現。

2.大多數icmp資料報的乙個拷貝傳送給匹配的原始套接字。

3.核心處理的所有其它型別的資料報的乙個拷貝都傳給匹配的原始套接字。

4.所有核心不能識別的協議型別的ip資料報都傳送給匹配的原始套接字。對於這些ip資料報,核心只做必要的檢驗工作。

在將乙個ip資料報傳送給原始套接字之前,核心需要選擇匹配的原始套接字

1.資料報的協議域必須與接收原始套接字的協議型別匹配。

2.如果原始套接字呼叫了bind函式繫結了本地ip位址,那麼到達的ip資料報的源ip位址必須和對方的ip相匹配。

3.如果原始套接字呼叫connect函式指定了對方的ip位址,則到達的ip資料報的源ip位址秘須與這它相同。  

學習 原始套接字

原始套接字可以訪問icmp和icmp等協議包,可以讀寫核心不處理的ip資料報。可以建立自定義的ip資料報首部。一句話,使用原始套接字可以 編寫基於ip協議的通訊程式。1.建立原始套接字 具體格式如下 int sockfd sockfd socktet af inet,sock raw,ipproto...

原始套接字

資料出處 實際上,我們常用的網路程式設計都是在應用層的報文的收發操作,也就是大多數程式設計師接觸到的流式套接字 sock stream 和資料報式套接字 sock dgram 而這些資料報都是由系統提供的協議棧實現,使用者只需要填充應用層報文即可,由系統完成底層報文頭的填充並傳送。然而在某些情況下需...

原始套接字

參考1 原始套接字能幹什麼?參考2 原始套接字抓包實踐 參考3 各層頭結構 通過原始套接字,我們可以抓取所有傳送到本機的ip包 包括ip頭和tcp udp icmp包頭 也可以抓取所有本機收到的幀 包括資料鏈路層協議頭 普通的套接字無法處理icmp igmp等網路報文,而sock raw可以。利用原...