SOCK RAW程式設計

2022-06-21 06:48:08 字數 1437 閱讀 1701

tcp(sock_stream)和udp套介面(sock_dgram)可以滿足大部分需求,但要獲取底層協議內容就需要原始套接字。相比前兩者,sock_raw具有如下優點:

1)使用原始套接字可以讀寫icmp及icmp6,如ping程式就是使用原始套接字傳送icmp應答請求。

2)使用原始套接字可以讀寫特殊的ip資料報,核心不處理這些資料報的ip協議字段,而出錯的診斷將依靠欄位的含義。

3)利用原始套介面設定ip_hdrincl套介面選項可以構造自己的ip頭部。

int sockfd=socket(af_inet, sock_raw, protocol);

af_inet:使用ipv4協議

sock_raw:原始套接字

protocol:協議名

建立原始套介面後,可以通過它向網路中寫自己的ip資料報,為了防止非法使用者破壞網路,規定只有超級使用者才有建立原始套介面的許可權。

核心如何將接收到的分組傳送給原始套接字,遵循如下原則:

》接收到的tcp和udp分組絕不會傳遞給任何原始套接子。

》當核心處理完icmp訊息之後,絕大部分icmp分組將傳遞給原始套介面。

》當核心處理完igmp訊息後,所有igmp分組將傳遞給某個原始套介面。

》所有帶有核心不能識別的協議欄位的ip資料報都將傳遞給某個原始套介面,而核心只是檢驗ip頭部中的某些字段。

如果資料報以分片形式到達,則該分組將在所有分片到達並重組後才傳給該套接字。

如果沒有設定ip_hdrincl選項,則核心寫的資料起始位址指ip頭部之後的第乙個位元組,此時核心構造ip頭部,並且核心將ip頭部的協議段設為使用者在呼叫socket()時指定的protocol引數。

如果設定ip_hdrincl選項,則核心寫的資料起始位址指向ip頭部的第乙個位元組,使用者所提供的資料的大小值必須包括頭部的位元組數,此時程序構造出以下兩項以外的整個ip頭部:ip標識字段可以設為0,要求核心設定該值,ip頭部的校驗由核心來計算和儲存。類似tcp協議超出外出介面的分組,核心將其分片。

當核心準備好乙個待傳輸的資料報之後,核心將對所有的程序的原始套介面進行尋找,每個匹配的套接字都將收到乙個該ip資料報的複製。匹配的過程分為3個測試步驟,只有3個測試步驟都滿足時,資料報才會傳遞給該套接字。

》在建立套接字時,如果protocol不為0,則接收到的資料報的協議字段應該與之匹配。

》如果在原始套介面上繫結乙個本地ip位址,那麼接收到的資料報的位址應該與之匹配。

》如果此原始套接字通過呼叫connect()指定乙個對方ip位址,那麼接收到的源ip位址應該與之相匹配。

技巧:如果乙個原始套接子建立引數protocol設定為0,並且沒有呼叫connect()和bind(),那麼對於核心傳遞給原始套接子的每個原始資料報,該套介面都會收到乙個複製資料報。

網上找到乙個判斷網路是否連通的程式,其通過傳送icmp包來實現。

參考:1. linux環境下c程式設計指南

2. linux下判斷網路是否連線

UNIX網路程式設計 原始套接字SOCK RAW

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

原始套接字SOCK RAW

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

原始套接字SOCK RAW

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