linux sock raw原始套接字程式設計

2021-05-27 23:49:58 字數 2407 閱讀 6481

sock_raw原始套接字程式設計可以接收到本機網絡卡上的資料幀或者資料報,對與監聽網路的流量和分析是很有作用的.

一共可以有3種方式建立這種socket

1.socket(af_inet, sock_raw, ipproto_tcp|ipproto_udp|ipproto_icmp)傳送接收ip資料報

2.socket(pf_packet, sock_raw, htons(eth_p_ip|eth_p_arp|eth_p_all))傳送接收乙太網資料幀

3.socket(af_inet, sock_packet, htons(eth_p_ip|eth_p_arp|eth_p_all))過時了,不要用啊

理解一下sock_raw的原理, 比如網絡卡收到了乙個 14+20+8+100+4 的udp的乙太網資料幀.

首先,網絡卡對該資料幀進行硬過濾(根據網絡卡的模式不同會有不同的動作,如果設定了promisc混雜模式的話,則不做任何過濾直接交給下一層輸入例程,否則非本機mac或者廣播mac會被直接丟棄).按照上面的例子,如果成功的話,會進入ip輸入例程.但是在進入ip輸入例程之前,系統會檢查系統中是否有通過socket(af_packet, sock_raw, ..)建立的套接字.如果有的話並且協議相符,在這個例子中就是需要eth_p_ip或者eth_p_all型別.系統就給每個這樣的socket接收緩衝區傳送乙個資料幀拷貝.然後進入下一步.

其次,進入了ip輸入例程(ip層會對該資料報進行軟過濾,就是檢查校驗或者丟棄非本機ip或者廣播ip的資料報等,具體要參考源**),例子中就是如果成功的話會進入udp輸入例程.但是在交給udp輸入例程之前,系統會檢查系統中是否有通過socket(af_inet, sock_raw, ..)建立的套接字.如果有的話並且協議相符,在這個例子中就是需要ipproto_udp型別.系統就給每個這樣的socket接收緩衝區傳送乙個資料幀拷貝.然後進入下一步.

最後,進入udp輸入例程 ...

ps:如果校驗和出錯的話,核心會直接丟棄該資料報的.而不會拷貝給sock_raw的套接字,因為校驗和都出錯了,資料肯定有問題的包括所有資訊都沒有意義了.

進一步分析他們的能力.

1. socket(af_inet, sock_raw, ipproto_udp);

能:該套接字可以接收協議型別為(tcp udp icmp等)發往本機的ip資料報,從上面看的就是20+8+100.

不能:不能收到非發往本地ip的資料報(ip軟過濾會丟棄這些不是發往本機ip的資料報).

不能:不能收到從本機傳送出去的資料報.

傳送的話需要自己組織tcp udp icmp等頭部.可以setsockopt來自己包裝ip頭部

這種套接字用來寫個ping程式比較適合

2. socket(pf_packet, sock_raw, htons(x));

這個套接字比較強大,建立這種套接字可以監聽網絡卡上的所有資料幀.從上面看就是20+20+8+100.最後乙個乙太網crc從來都不算進來的,因為核心已經判斷過了,對程式來說沒有任何意義了.

能: 接收發往本地mac的資料幀

能: 接收從本機傳送出去的資料幀(第3個引數需要設定為eth_p_all)

能: 接收非發往本地mac的資料幀(網絡卡需要設定為promisc混雜模式)

協議型別一共有四個

eth_p_ip 0x800      只接收發往本機mac的ip型別的資料幀

eth_p_arp 0x806      只接受發往本機mac的arp型別的資料幀

eth_p_arp 0x8035     只接受發往本機mac的rarp型別的資料幀

eth_p_all 0x3         接收發往本機mac的所有型別ip arp rarp的資料幀, 接收從本機發出的所有型別的資料幀.(混雜模式開啟的情況下,會接收到非發往本地mac的資料幀)

傳送的時候需要自己組織整個乙太網資料幀.所有相關的位址使用struct sockaddr_ll 而不是struct sockaddr_in(因為協議簇是pf_packet不是af_inet了),比如傳送給某個機器,對方的位址需要使用struct sockaddr_ll.

在使用sock_raw, sock_dgram和sock_packet的區別(詳請參考

在socket的第乙個引數使用pf_packet的時候,上述三種socket的型別都可以使用。但是有區別。

(1)使用sock_raw傳送的資料必須包含鏈路層的協議頭,接受得到的資料報,包含鏈路層協議頭。而使用sock_dgram則都不含鏈路層的協議頭。

(2)sock_packet也是可以使用的,但是已經廢棄,以後不保證還能支援,不推薦使用。

(3)在使用sock_raw或sock_dgram和sock_packet時,在sendto和recvfrom中使用的位址型別不同,前兩者使用sockaddr_ll型別的位址,而後者使用sockaddr型別的位址。

(4)如socket的第乙個引數使用pf_inet,第二個引數使用sock_raw,則可以得到原始的ip包。

UNIX網路程式設計讀書筆記 原始套介面

應用程式可以繞過傳輸層而直接使用ipv4和ipv6,這稱為原始套介面 raw socket 原始套介面是一種對原始網路報文進行處理的套介面。原始套介面主要應用在底層網路程式設計上,同時也是網路黑客的必備手段。例如sniffer 拒絕服務 dos ip位址欺騙等都需要在原始套接字的基礎上實現。與原始套...

UNPv1第二十五章 原始套介面

原始套介面提供以下三種tcp及udp套介面一般不提供的功能。1.使用原始套介面可以讀寫icmpv4,igmpv4,icmpv6分組。例如 ping程式,就使用原始套介面傳送icmp回射請求,並接受icmp回射應答。2.使用原始套介面可以讀寫特殊的ipv4資料報,核心不處理這些資料報的ipv4協議字段...

原始的抽象

由於排版原因,完整版本請看這裡 原始的抽象 本來預想的寫作計畫總是不斷的被一些新的念頭所打斷,然而這卻是乙個極好的事,人只能在他人的觸動下才更容易產生靈感,這次觸動我得是 cs 我非常贊同 只是不知能否進一步討論 抽象 對於人是什麼 對於計算機是什麼 您可以就以圍棋來談 當然也可以就 nlp來說 我...