網(wǎng)絡(luò)通信編程 原始套接字程序設(shè)計_第1頁
網(wǎng)絡(luò)通信編程 原始套接字程序設(shè)計_第2頁
網(wǎng)絡(luò)通信編程 原始套接字程序設(shè)計_第3頁
網(wǎng)絡(luò)通信編程 原始套接字程序設(shè)計_第4頁
網(wǎng)絡(luò)通信編程 原始套接字程序設(shè)計_第5頁
已閱讀5頁,還剩90頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、1第四章 原始套接字 2內(nèi)容提要 1.使用原始套接字 2.套接字選項 3.ICMP編程 4.使用IP頭包含選項 5.網(wǎng)絡(luò)嗅探器實例31.使用原始套接字 利用原始套接字(Raw Socket),可訪問底層傳輸協(xié)議。 原始套接字(Raw Socket)與標(biāo)準(zhǔn)套接字區(qū)別4 使用原始套接字可以做什么?實現(xiàn)一些實用工具(ping,traceroute)。可對IP頭,TCP頭,UDP頭,ICMP頭等進行操作。 原始套接字使用SOCK_RAW套接字類型來創(chuàng)建的,目前只有Winsock2提供了對它的支持。 無論Microsoft Windows CE 還是老版本的Windows 95 (無Winsock 2升

2、級)均不能利用原始套接字。5創(chuàng)建原始套接字 原始套接字類型在IP頭中使用預(yù)定義的協(xié)議(如ICMP)在IP頭中使用自定義的協(xié)議(使用IP頭包含選項)協(xié)議地址族套接字類型套接字類型使用的值協(xié)議字段互聯(lián)網(wǎng)協(xié)議(IP)AF_INETTCPSOCK_STREAMIPPROTO_TCPUDPSOCK_DGRAMIPPROTO_UDPRawSOCK_RAWIPPROTO_RAWIPPROTO_ICMP6創(chuàng)建原始套接字 使用socket()或WSASocket()創(chuàng)建原始套接字。例:創(chuàng)建原始套接字使用預(yù)定義協(xié)議: SOCKET s;S=socket(AF_INET,SOCK_RAM,IPPROTO_ICMP)

3、;/ORS=WSAsocket(AF_INEF,SOCK_RAM,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);7使用自定義協(xié)議使用IGMP、UDP、IP或者原始IP,只需分別設(shè)置IPPROTO_IGMP、IPPROTO_UDP、IPPROTO_IP或IPPROTO_RAW即可。注意:在Windows NT 4、Windows 98以及Windows 95(安裝Winsock 2)操作系統(tǒng)中,創(chuàng)建原始套接字時,只能使用ICMP。協(xié)議標(biāo)志IPPROTO_UDP、IPPROTO_IP以及IPPROTO_RAW均要求使用套接字選項IP_HDRINCL,而該選項在上

4、述平臺下都是不支持的。Windows 2000提供了對IP_HDRINCL選項的支持,所以能夠處理IP頭(IPPROTO_RAW)、TCP頭(IPPROTO_TCP)以及UDP頭(IPPROTO_UDP)。無論是否設(shè)置IP_HDRINCL選項,原始套接字上接收到的數(shù)據(jù)都會包含IP頭。8使用原始套接字可以對底層傳輸機制加以控制,所以有些人將其用于不法用途,9 套接字選項操作函數(shù) getsocketopt()獲取套接字選項信息。int getsocketopt( SOCKET s, /套接字描述符 int level, /選項級別 int optname, /選項名稱 char *optval,

5、/選項值 int *optlen/選項長度 );setsocketopt( ) 設(shè)置套接字選項。int setsocketopt(SOCKET s, int level, int optname, const char *optval, int optlen);2.套接字選項10n 選項級別:協(xié)議的層次對應(yīng)選項級別應(yīng)用層:SOL_SOCKET傳輸層:IPPROTO_TCP、IPPROTO_UDP網(wǎng)絡(luò)層:IPPROTO_IPn 不同級別屬性不同,同一級別的不同協(xié)議的屬性不同,因此必須指定level參數(shù)例:Int nTime=2*1000setsockopt(s,SOL_SOCKET,SO_RCV

6、TIMEO,(char*)&nTime,sizeof(nTime)11選項值類型獲取/設(shè)置Winsock版本說明bool獲取1 +返回值如果為TRUE,表明套接字處于監(jiān)聽模式SOL_SOCKET選項級別SO_ACCEPTCONN如果已調(diào)用Listen函數(shù),將套接字置為監(jiān)聽模式, 這個選項就會返回TRUE。SOCK_DGRAM類型的套接字不支持這一選項。選項值類型獲取/設(shè)置Winsock版本說明bool均可1 +如果指定的套接字已經(jīng)配置成收發(fā)廣播數(shù)據(jù),對這個套接字選項進行查詢,就會返回TRUE。隨SO_BROADCAST一起使用setsockopt,便可在這個套接字上啟用廣播通信功能。對

7、于非SOCK_STREAM類型的所有套接字來說,這個選項都是有效的。SO_BROADCAST12選項值類型獲取/設(shè)置Winsock版本說明int獲取1 +返回套接字建立連接的時間,以秒為單位SO_CONNECT_TIME該選項最常見的用法是和AcceptEx函數(shù)一道使用。選項值類型獲取/設(shè)置Winsock版本說明bool均可1 +如果是TRUE,便直接向網(wǎng)絡(luò)接口發(fā)送消息,毋需查詢路由表SO_DONTROUTE假定創(chuàng)建了一個UDP套接字,并將其與接口A綁定到一起,然后發(fā)送一個數(shù)據(jù)包,目的地址是網(wǎng)絡(luò)中使用接口B的另一個網(wǎng)絡(luò)上的某臺機器。此時,若采用默認(rèn)設(shè)置,該數(shù)據(jù)包會經(jīng)過一個路由過程,使其能通過接

8、口B傳入目標(biāo)網(wǎng)絡(luò)。但將這里的布爾值設(shè)為TRUE,再來調(diào)用setsockopt,便可禁止路由,數(shù)據(jù)包會從綁定的接口上直接發(fā)送出去。以后可調(diào)用getsockopt,判斷是否允許了路由。注意:在默認(rèn)情況下,路由是允許的。13選項值類型獲取/設(shè)置Winsock版本說明bool均可1 +如果是TRUE,套接字就可與一個正由其他套接字使用的地址綁定到一起,或與處在TIME_WAIT狀態(tài)的地址綁定到一起SO_REUSEADDR監(jiān)聽套接字例外。兩個獨立的套接字不可與同一個本地地址綁定到一起,以等待進入的連接通知。選項值類型獲取/設(shè)置Winsock版本說明bool均可2 +如果是TRUE,套接字綁定的本地地址就

9、不能重新被另一個進程使用SO_EXCLUSIVEADDRUSE例如,假定兩個單獨的進程都與同一個本地地址綁定到了一起(假定已設(shè)置例如,假定兩個單獨的進程都與同一個本地地址綁定到了一起(假定已設(shè)置了了SO_REUSEADDR),那么兩個套接字中到底由哪一個負(fù)責(zé)接收進入連接),那么兩個套接字中到底由哪一個負(fù)責(zé)接收進入連接請求通知呢?這一點并未定義!如果應(yīng)用程序的要求非常苛刻(用于關(guān)鍵性請求通知呢?這一點并未定義!如果應(yīng)用程序的要求非??量蹋ㄓ糜陉P(guān)鍵性任務(wù)的程序),這一點顯然是非常不幸的。任務(wù)的程序),這一點顯然是非常不幸的。SO_EXCLUSIVEADDRUSE選項選項的作用便是將一個本地地址牢牢

10、鎖定在與它綁定的那個套接字上。的作用便是將一個本地地址牢牢鎖定在與它綁定的那個套接字上。14選項值類型獲取/設(shè)置Winsock版本說明int均可1 +面向接收操作,為每個套接字分別獲取或設(shè)置緩沖區(qū)長度SO_RCVBUF改緩沖區(qū)的大小,一個可能的原因是需要根據(jù)應(yīng)用程序的行為,對緩沖區(qū)大小進行相應(yīng)地調(diào)整。選項值類型獲取/設(shè)置Winsock版本說明int均可1 +面向發(fā)送操作,為每個套接字分別獲取或設(shè)置緩沖區(qū)長度SO_SNDBUF15選項值類型獲取/設(shè)置Winsock版本說明int均可1 +獲取或設(shè)置套接字上接收數(shù)據(jù)的超時時間(以毫秒為單位)SO_RCVTIMEO選項值類型獲取/設(shè)置Winsock版

11、本說明int均可1 +獲取或設(shè)置套接字上發(fā)送數(shù)據(jù)的超時時間(以毫秒為單位)SO_SNDTIMEO主要用于設(shè)置阻塞套接字的收發(fā)超時時間,超時時間實際上指明了阻塞時間的長短。當(dāng)調(diào)用接收(發(fā)送)函數(shù)時,如果在SO _ RCVTIMEO( SO_ SNDTIMEO )指定的時間內(nèi)沒有數(shù)據(jù)到來,那么函數(shù)調(diào)用也會結(jié)束并且返回錯誤10060 ( WSAETIMEDOUT )。16 IPPROTO_IP級別IPPROTO_IP這一級的套接字選項與IP協(xié)議存在密切聯(lián)系,比如可用這些選項修改IP頭的特定字段以及向IP多播組增添一個套接字等等。選項值類型獲取/設(shè)置Winsock版本說明char兩者均可1 +設(shè)置或獲

12、取IP頭內(nèi)的IP選項IP_OPTIONS 通過該選項可在I P頭內(nèi)設(shè)置各種IP選項,可能出現(xiàn)的選項包括:n記錄路由:每個路由器都將自己的IP地址添加到IP頭內(nèi)。n時間標(biāo)志(時間戳):每個路由器都增添自己的IP地址及時間。17 源路由選擇:源主機指定一條通過互聯(lián)網(wǎng)的路徑。 注意:主機和路由器并不支持所有這些選項。 設(shè)置一個IP選項時,傳至setsockopt調(diào)用內(nèi)部的數(shù)據(jù)會遵照下圖所示的數(shù)據(jù)結(jié)構(gòu)。IP選項頭最長可達(dá)40字節(jié)。IP選項頭格式18選項值類型獲取/設(shè)置Winsock版本說明bool均可2 +如果是TRUE,IP頭就會隨即將發(fā)送的數(shù)據(jù)一起提交,并從讀取的數(shù)據(jù)中返回IP_HDRINCLn若

13、將IP_HDRINCL選項設(shè)為TRUE,發(fā)送函數(shù)會將IP頭包括在發(fā)送的數(shù)據(jù)前面,并會促使接收函數(shù)將IP頭作為數(shù)據(jù)的一部分。n在調(diào)用一個Winsock發(fā)送函數(shù)的時候,必須在數(shù)據(jù)前面包括完整的IP頭,并對IP頭的每個字段進行正確的填寫。n僅僅用于原始套接字n該選項僅適用于Windows 2000操作系統(tǒng)。19選項值類型獲取/設(shè)置Winsock版本說明int均可1 +IP協(xié)議的“存在時間”(TTL)參數(shù)IP_TTLnTTL字段需要在IP頭內(nèi)進行設(shè)置。n數(shù)據(jù)報利用TTL字段對數(shù)據(jù)報能夠通過的最大路由器數(shù)量加以限制,避免由于路由循環(huán),造成數(shù)據(jù)報永無休止地在網(wǎng)絡(luò)中“游蕩”。n數(shù)據(jù)報每經(jīng)過一個路由器,都會由

14、路由器解析出它的TTL值,并將其減去1。若發(fā)現(xiàn)這個值變成了0,數(shù)據(jù)報便會被“無情”地丟棄。n注意, Windows CE不支持這個選項。203. ICMP編程內(nèi)容提要 ICMP協(xié)議 PING程序分析 TRACEROUTE程序分析 為了提高 IP 數(shù)據(jù)報交付成功的機會,在網(wǎng)際層使用了因特網(wǎng)控制報文協(xié)議 ICMP (Internet Control Message Protocol)。 ICMP 允許主機或路由器報告差錯情況和提供有關(guān)異常情況的報告。 ICMP 不是高層協(xié)議,而是 IP 層的協(xié)議。 ICMP 報文作為 IP 層數(shù)據(jù)報的數(shù)據(jù),加上數(shù)據(jù)報的首部,組成 IP 數(shù)據(jù)報發(fā)送出去。ICMP協(xié)議

15、ICMP的位置及封裝的位置及封裝n ICMP 本身是一個網(wǎng)絡(luò)層協(xié)議本身是一個網(wǎng)絡(luò)層協(xié)議nICMP報文首先要封裝成報文首先要封裝成IP數(shù)據(jù)數(shù)據(jù)報,然后再傳送給下一層報,然后再傳送給下一層ICMP 報文的格式報文的格式 首 部ICMP 報文0數(shù) 據(jù) 部 分檢驗和類型代碼(這 4 個字節(jié)取決于 ICMP 報文的類型)81631IP 數(shù)據(jù)報前 4 個字節(jié)都是一樣的ICMP 的數(shù)據(jù)部分(長度取決于類型) ICMP報文中各字段的作用報文中各字段的作用 類型類型:8比特長字段,定義了報文的類型。比特長字段,定義了報文的類型。 代碼代碼:8比特長字段,指明了發(fā)送此特定報文類型的原因。比特長字段,指明了發(fā)送此特

16、定報文類型的原因。 檢驗和檢驗和:16比特長字段,進行差錯檢驗。比特長字段,進行差錯檢驗。 首部的其余部分首部的其余部分:對每一種報文類型都是特定的。:對每一種報文類型都是特定的。 數(shù)據(jù)部分?jǐn)?shù)據(jù)部分: 在在差錯報文差錯報文中:所攜帶的信息可找出引起差錯的原始分組;中:所攜帶的信息可找出引起差錯的原始分組; 在在查詢報文查詢報文中:攜帶了基于查詢類型的額外信息。中:攜帶了基于查詢類型的額外信息。 報文類型報文類型ICMP 報文報文差錯報告差錯報告查詢查詢幫助主機或網(wǎng)絡(luò)管理員從幫助主機或網(wǎng)絡(luò)管理員從一個路由器或另一個主機一個路由器或另一個主機得到特定的信息得到特定的信息它是成對出現(xiàn)的它是成對出現(xiàn)的

17、種類種類類型類型報文報文Reason差錯報告報文差錯報告報文3目的站不可達(dá)目的站不可達(dá)4源站抑制源站抑制11時間超過時間超過Too long route12參數(shù)問題參數(shù)問題Format error5重定向(改變路由)重定向(改變路由)Route changed查詢報文查詢報文8 or 0回送請求或應(yīng)答回送請求或應(yīng)答Reachability13 or 14時間戳請求或應(yīng)答時間戳請求或應(yīng)答Synchronization17 or 18地址掩碼請求或應(yīng)答地址掩碼請求或應(yīng)答Mask maintenance10 or 9路由器懇求路由器懇求(solicitation)或通告或通告(advertiseme

18、nt)Coincidence between routersICMP 差錯報告報文的數(shù)據(jù)字段的內(nèi)容差錯報告報文的數(shù)據(jù)字段的內(nèi)容 首部IP 數(shù)據(jù)報ICMP 的前 8 字節(jié)裝入 ICMP 報文的 IP 數(shù)據(jù)報IP 數(shù)據(jù)報首部ICMP 差錯報告報文8字節(jié)收到的 IP 數(shù)據(jù)報IP 數(shù)據(jù)報首部8字節(jié)ICMP 差錯報告報文IP 數(shù)據(jù)報的數(shù)據(jù)字段(1)回送請求和回答:由主機/路由器向一特定主機發(fā)出ICMP詢問,特定主機收到后必須給出ICMP回答報文。ICMP查詢報文查詢報文說明:說明:(2)時間戳請求和回答)時間戳請求和回答說明:說明:發(fā)送時間發(fā)送時間戳戳:發(fā)送方填寫:發(fā)送方填寫接收時間接收時間戳:應(yīng)答主機

19、收到請求報文時填寫戳:應(yīng)答主機收到請求報文時填寫(3)地址掩碼請求和回答)地址掩碼請求和回答n 主機可能知道他的完整IP地址,但卻不知道地址中的哪一部分定義網(wǎng)絡(luò)地址和子網(wǎng)地址,哪一部分對應(yīng)于主機標(biāo)識符。這樣,主機就需要知道掩碼。n 要得到掩碼,主機應(yīng)發(fā)送地址掩碼請求報文給局域網(wǎng)上的路由器。n 若主機知道該路由器的地址,它就將這個請求直接發(fā)給該路由器;若不知道,則廣播此報文。n 路由器收到地址掩碼請求報文就響應(yīng)地址掩碼回答報文,向主機提供所需的掩碼。n 在請求報文中,地址掩碼字段填入全0,回答報文中,這個字段就包含真正的掩碼。說明:說明:檢驗和檢驗和發(fā)送端的檢驗和計算:發(fā)送端的檢驗和計算:v先將

20、首部的檢驗和字段置為先將首部的檢驗和字段置為0。v將分組劃分為將分組劃分為K部分,每部分都是部分,每部分都是16比特長。比特長。v用用反碼算術(shù)運算反碼算術(shù)運算將所有這些部分相加。將所有這些部分相加。v將最終結(jié)果取反碼就得出檢驗和。再將其填入檢驗和字段。將最終結(jié)果取反碼就得出檢驗和。再將其填入檢驗和字段。接收端的檢驗和計算:接收端的檢驗和計算:v將收到的分組劃分為將收到的分組劃分為K部分,每部分都是部分,每部分都是16比特長。比特長。v用用反碼算術(shù)運算反碼算術(shù)運算將所有這些部分相加。將所有這些部分相加。v將得到的結(jié)果取反碼。將得到的結(jié)果取反碼。v若結(jié)果為若結(jié)果為0,則接收此分組,否組就拒絕此分組

21、。,則接收此分組,否組就拒絕此分組。在在ICMP中,檢驗和的計算覆蓋了整個報文(首部和數(shù)據(jù))。中,檢驗和的計算覆蓋了整個報文(首部和數(shù)據(jù))。PING程序程序分析分析 使用原始套接字實現(xiàn)回送請求和回答使用原始套接字實現(xiàn)回送請求和回答 (PING程序的設(shè)計與實現(xiàn)程序的設(shè)計與實現(xiàn)) PING 用來測試兩個主機之間的連通性。用來測試兩個主機之間的連通性。 PING 使用了使用了 ICMP 回送請求與回送回答報文?;厮驼埱笈c回送回答報文。 PING 是應(yīng)用層直接使用網(wǎng)絡(luò)層是應(yīng)用層直接使用網(wǎng)絡(luò)層 ICMP 的例子,它沒有通的例子,它沒有通過運輸層的過運輸層的 TCP 或或UDP。 C:Documents

22、and Settingswy ping NoImagePING 使用了使用了 ICMP 回送請求與回送回答報文回送請求與回送回答報文原始套接字的創(chuàng)建原始套接字的創(chuàng)建函數(shù)格式:函數(shù)格式: / 創(chuàng)建原始套節(jié)字創(chuàng)建原始套節(jié)字 SOCKET sRaw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); IPPROTO_ICMP指定使用指定使用ICMP PING 程序執(zhí)行步驟程序執(zhí)行步驟1、創(chuàng)建協(xié)議類型為、創(chuàng)建協(xié)議類型為IPPROTO_ICMP的原始套接字,的原始套接字,設(shè)置套接字的屬性。設(shè)置套接字的屬性。2、創(chuàng)建并初始化、創(chuàng)建并初始化ICMP封包。封包。3、調(diào)用、調(diào)用

23、sendto函數(shù)向遠(yuǎn)程主機發(fā)送函數(shù)向遠(yuǎn)程主機發(fā)送ICMP請求。請求。4、調(diào)用、調(diào)用recvfrom函數(shù)接收函數(shù)接收ICMP響應(yīng)。響應(yīng)。/ Ping.h/ 聲明聲明IP頭頭數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)結(jié)構(gòu)typedef struct _IPHeader / 20字節(jié)的字節(jié)的IP頭頭 UCHAR iphVerLen; / 版本號和頭長度(各占版本號和頭長度(各占4位)位) UCHAR ipTOS; / 服務(wù)類型服務(wù)類型 USHORT ipLength; / 封包總長度,即整個封包總長度,即整個IP報的長度報的長度 USHORT ipID; / 封包標(biāo)識,惟一標(biāo)識發(fā)送的每一個數(shù)據(jù)報封包標(biāo)識,惟一標(biāo)識發(fā)送的每一個數(shù)據(jù)

24、報 USHORT ipFlags; / 標(biāo)志和片偏移標(biāo)志和片偏移 UCHAR ipTTL; / 生存時間,就是生存時間,就是TTL UCHAR ipProtocol; / 協(xié)議,可能是協(xié)議,可能是TCP、UDP、ICMP等等 USHORT ipChecksum; / 校驗和校驗和 ULONG ipSource; / 源源IP地址地址 ULONG ipDestination; / 目標(biāo)目標(biāo)IP地址地址 IPHeader, *PIPHeader; PING 程序代碼程序代碼/ICMP頭數(shù)據(jù)結(jié)構(gòu)頭數(shù)據(jù)結(jié)構(gòu)typedef struct icmp_hdr unsigned char icmp_type;

25、/ 消息類型消息類型 unsigned char icmp_code;/ 代碼代碼 unsigned short icmp_checksum;/ 校驗和校驗和 unsigned short icmp_id; / 用來惟一標(biāo)識此請求的用來惟一標(biāo)識此請求的ID號,通常設(shè)置為進程號,通常設(shè)置為進程ID unsigned short icmp_sequence;/ 序號序號 unsigned long icmp_timestamp; / 數(shù)據(jù)傳輸時間數(shù)據(jù)傳輸時間 ICMP_HDR, *PICMP_HDR;/ICMP回送請求的數(shù)據(jù)結(jié)構(gòu)回送請求的數(shù)據(jù)結(jié)構(gòu)typedef struct _EchoReques

26、tICMP_HDR icmphdr;char cData32;ECHOREQUEST,*PECHOREQUEST; /ICMP回送應(yīng)答的數(shù)據(jù)結(jié)構(gòu)回送應(yīng)答的數(shù)據(jù)結(jié)構(gòu)#define REQ_DATASIZE 32typedef struct _EchoReplyIPHeader iphdr;ECHOREQUEST echoRequest;ECHOREPLAY,*PECHOREPLAY; / 校驗和的計算校驗和的計算/ 以以16位的字為單位將緩沖區(qū)的內(nèi)容相加,如果緩沖區(qū)長度為奇數(shù),位的字為單位將緩沖區(qū)的內(nèi)容相加,如果緩沖區(qū)長度為奇數(shù),/ 則再加上一個字節(jié)。它們的和存入一個則再加上一個字節(jié)。它們的和存

27、入一個32位的雙字中位的雙字中USHORT checksum(USHORT* buff, int size);/ Ping.cpp#include #include #pragma comment(lib, WS2_32)/ 鏈接到鏈接到WS2_32.lib#include #include ping.hUSHORT checksum(USHORT* buff, int size)u_long cksum = 0;while(size1) / 將數(shù)據(jù)以字為單位累加到將數(shù)據(jù)以字為單位累加到cksum 中中 cksum=cksum+ *buff; buff= buff +1;size= size-

28、 sizeof(USHORT); /等價于等價于size=size-2; if(size=1) / 共有奇數(shù)個字節(jié)將最后一個字節(jié)擴展為字,再累加共有奇數(shù)個字節(jié)將最后一個字節(jié)擴展為字,再累加 USHORT u=0;u=(USHORT)(*(UCHAR*)buff);cksum = cksum +u; / 校驗位計算校驗位計算/高高16位和低位和低16位相加位相加cksum = (cksum 16) + (cksum & 0 x0000ffff); cksum = cksum+(cksum 16);/本身再加上當(dāng)前的高本身再加上當(dāng)前的高16位位 u_short answer=(u_shor

29、t)(cksum);/取反并轉(zhuǎn)換為取反并轉(zhuǎn)換為16位數(shù)位數(shù)return (answer); 位位右移右移運算符運算符 右邊的值依次被移右邊的值依次被移出了,左邊的位置出了,左邊的位置依次放依次放0校驗位計算校驗位計算(1) 將將32位的位的chsum高高16位和低位和低16位相加位相加(2) 自加當(dāng)前數(shù)的高自加當(dāng)前數(shù)的高16位位(3) 取反并轉(zhuǎn)換為取反并轉(zhuǎn)換為16位位int main()WSADATA wsaData;WORD version = MAKEWORD(2, 2);int ret = WSAStartup(version, &wsaData); /載入載入Winsock庫庫

30、if(ret != 0)printf( 加載加載Winsock庫錯誤庫錯誤! n);return 0;/ 目的目的IP地址,即要地址,即要Ping的的IP地址地址char szDestIp = “192.168.0.2;/ 創(chuàng)建原始套接字創(chuàng)建原始套接字SOCKET sRaw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);/ 設(shè)置目的地址設(shè)置目的地址SOCKADDR_IN dest;dest.sin_family = AF_INET;dest.sin_port = htons(0); / 0表示程序執(zhí)行時系統(tǒng)自動分配一個表示程序執(zhí)行時系統(tǒng)自動分配一個 /端口

31、給應(yīng)用程序端口給應(yīng)用程序dest.sin_addr.S_un.S_addr = inet_addr(szDestIp);/ 創(chuàng)建創(chuàng)建ICMP封包封包(回送請求回送請求)ECHOREQUEST echoReq;/ 填寫填寫ICMP封包數(shù)據(jù)封包數(shù)據(jù)echoReq.icmphdr.icmp_type = 8; / 請求一個請求一個ICMP回顯回顯 echoReq.icmphdr.icmp_code = 0;echoReq.icmphdr.icmp_id = (USHORT)GetCurrentProcessId();echoReq.icmphdr.icmp_checksum = 0;echoReq.

32、icmphdr.icmp_sequence = 0;/ 填充數(shù)據(jù)部分,可以為任意填充數(shù)據(jù)部分,可以為任意memset(&echoReq.cData, E, 32);/Sets buffers to a specified character./ 開始發(fā)送和接收開始發(fā)送和接收ICMP封包封包USHORT nSeq = 0; SOCKADDR_IN from;int nLen = sizeof(from);while(TRUE)static int nCount = 0; int nRet;if(nCount+ = 4) break;echoReq.icmphdr.icmp_checksu

33、m = 0;/ GetTickCount() 系統(tǒng)開始后,已經(jīng)經(jīng)過的毫秒數(shù)系統(tǒng)開始后,已經(jīng)經(jīng)過的毫秒數(shù)echoReq.icmphdr.icmp_timestamp = GetTickCount();echoReq.icmphdr.icmp_sequence = nSeq+;echoReq.icmphdr.icmp_checksum = checksum(USHORT*)&echoReq, sizeof(echoReq);nRet = sendto(sRaw, (char*)&echoReq, sizeof(echoReq), 0, (SOCKADDR *)&dest,

34、sizeof(dest);if(nRet = SOCKET_ERROR)printf( sendto() failed: %d n, WSAGetLastError();return -1;/接收回送應(yīng)答包接收回送應(yīng)答包ECHOREPLAY echoReply;nRet = recvfrom(sRaw, (char*)&echoReply,sizeof(ECHOREPLAY), 0, (sockaddr*)&from, &nLen);if(nRet = SOCKET_ERROR)if(WSAGetLastError() = WSAETIMEDOUT)printf( ti

35、med outn);continue;printf( recvfrom() failed: %dn, WSAGetLastError();return -1; / 下面開始解析接收到的封包下面開始解析接收到的封包if(nRet icmp_type != 11 & pICMPHdr-icmp_type != 3 & pICMPHdr-icmp_code != 3)printf( Unexpected Type: %d , code: %d n,pICMPHdr-icmp_type, pICMPHdr-icmp_code);elsechar *szIP = inet_ntoa(re

36、cvAddr.sin_addr);printf( 第%d個路由器,IP地址:%s n, nTTL, szIP);printf( 用時:%d毫秒 n, GetTickCount() - nTick);if(destAddr.sin_addr.S_un.S_addr = recvAddr.sin_addr.S_un.S_addr)printf(目標(biāo)可達(dá) n);break;printf(/-/ n); while(nTTL+ 20);closesocket(sRaw);closesocket(sSend); 604. 使用IP頭包含選項 創(chuàng)建原始套接字后使用IP_HDRINCL套接字選項可對IP頭進

37、行操作,同時也能操作TCP或UDP頭(或封裝在IP內(nèi)的其他任何協(xié)議)。 使用IP_HDRINCL選項時,必須針對每一次發(fā)送調(diào)用,向IP頭內(nèi)自行填充內(nèi)容。同時還需填寫封裝在其中的其他協(xié)議頭。 相關(guān)協(xié)議報文格式固定部分可變部分04816192431版 本標(biāo)志生 存 時 間協(xié) 議標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首 部 檢 驗 和源 地 址目 的 地 址可 選 字 段 (長 度 可 變)位首部長度數(shù) 據(jù) 部 分?jǐn)?shù) 據(jù) 部 分首 部傳送IP 數(shù)據(jù)報首部發(fā)送在前 IP 數(shù)據(jù)報格式可變部分首部04816192431版 本標(biāo)志生 存 時 間協(xié) 議標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首

38、部 檢 驗 和源 地 址目 的 地 址可 選 字 段 (長 度 可 變)位首部長度數(shù) 據(jù) 部 分?jǐn)?shù) 據(jù) 部 分首 部傳送IP 數(shù)據(jù)報固定部分首部04816192431版 本標(biāo)志生 存 時 間協(xié) 議標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首 部 檢 驗 和源 地 址目 的 地 址可 選 字 段 (長 度 可 變)位首部長度數(shù) 據(jù) 部 分?jǐn)?shù) 據(jù) 部 分首 部傳送IP 數(shù)據(jù)報固定部分可變部分首部04816192431版 本標(biāo)志生 存 時 間協(xié) 議標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首 部 檢 驗 和源 地 址目 的 地 址可 選 字 段 (長 度 可 變)位首部長度數(shù) 據(jù) 部 分固定

39、部分可變部分版本占 4 位,指IP協(xié)議的版本目前的 IP 協(xié)議版本號為 4 (即 IPv4)首部04816192431版 本標(biāo)志生 存 時 間協(xié) 議標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首 部 檢 驗 和源 地 址目 的 地 址可 選 字 段 (長 度 可 變)位首部長度數(shù) 據(jù) 部 分固定部分可變部分首部長度占 4 位,可表示的最大數(shù)值是 15 個單位(一個單位為 4 字節(jié))因此 IP 的首部長度的最大值是60字節(jié)。首部04816192431版 本標(biāo)志生 存 時 間協(xié) 議標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首 部 檢 驗 和源 地 址目 的 地 址可 選 字 段 (長 度 可

40、 變)位首部長度數(shù) 據(jù) 部 分固定部分可變部分區(qū)分服務(wù)占 8 位,用來獲得更好的服務(wù)。在舊標(biāo)準(zhǔn)中叫做服務(wù)類型,但實際上并未被使用過。僅在使用區(qū)分服務(wù)(DiffServ)時,此字段才起作用。首部04816192431版 本標(biāo)志生 存 時 間協(xié) 議標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首 部 檢 驗 和源 地 址目 的 地 址可 選 字 段 (長 度 可 變)位首部長度數(shù) 據(jù) 部 分固定部分可變部分總長度占 16 位,指首部和數(shù)據(jù)之和的長度,單位為字節(jié),因此數(shù)據(jù)報的最大長度為 65535 字節(jié)??傞L度必須不超過最大傳送單元 MTU。 首部04816192431版 本標(biāo)志生 存 時 間協(xié) 議

41、標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首 部 檢 驗 和源 地 址目 的 地 址可 選 字 段 (長 度 可 變)位首部長度數(shù) 據(jù) 部 分固定部分可變部分標(biāo)識(identification)占 16 位,它是一個計數(shù)器,用來產(chǎn)生數(shù)據(jù)報的標(biāo)識。 首部04816192431版 本標(biāo)志生 存 時 間協(xié) 議標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首 部 檢 驗 和源 地 址目 的 地 址可 選 字 段 (長 度 可 變)位首部長度數(shù) 據(jù) 部 分固定部分可變部分標(biāo)志(flag)占 3 位,目前只有前兩位有意義。標(biāo)志字段的最低位是 MF (More Fragment)。MF 1 表示后面“還

42、有分片”。MF 0 表示最后一個分片。標(biāo)志字段中間的一位是 DF (Dont Fragment) 。只有當(dāng) DF 0 時才允許分片。 首部04816192431版 本標(biāo)志生 存 時 間協(xié) 議標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首 部 檢 驗 和源 地 址目 的 地 址可 選 字 段 (長 度 可 變)位首部長度數(shù) 據(jù) 部 分固定部分可變部分片偏移(12 位)指出:較長的分組在分片后某片在原分組中的相對位置。片偏移以 8 個字節(jié)為偏移單位。首部04816192431版 本標(biāo)志生 存 時 間協(xié) 議標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首 部 檢 驗 和源 地 址目 的 地 址可

43、選 字 段 (長 度 可 變)位首部長度數(shù) 據(jù) 部 分固定部分可變部分生存時間(8 位)記為 TTL (Time To Live),這是為了限制數(shù)據(jù)報在網(wǎng)絡(luò)中的生存時間,用“跳數(shù)”作為 TTL 的單位。數(shù)據(jù)報每經(jīng)過一個路由器,其 TTL 值就減 1。首部04816192431版 本標(biāo)志生 存 時 間協(xié) 議標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首 部 檢 驗 和源 地 址目 的 地 址可 選 字 段 (長 度 可 變)位首部長度數(shù) 據(jù) 部 分固定部分可變部分協(xié)議(8 位)字段指出此數(shù)據(jù)報攜帶的數(shù)據(jù)使用何種協(xié)議以便目的主機的 IP 層將數(shù)據(jù)部分向上正確交付運輸層網(wǎng)絡(luò)層首部TCPUDPICM

44、PIGMPOSPF數(shù) 據(jù) 部 分IP 數(shù)據(jù)報協(xié)議字段指出應(yīng)將數(shù)據(jù)部分交付到什么地方首部04816192431版 本標(biāo)志生 存 時 間協(xié) 議標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首 部 檢 驗 和源 地 址目 的 地 址可 選 字 段 (長 度 可 變)位首部長度數(shù) 據(jù) 部 分固定部分可變部分首部檢驗和(16 位)字段只檢驗數(shù)據(jù)報的首部不包括數(shù)據(jù)部分。這里不采用 CRC 檢驗碼而采用簡單的計算方法。 首部04816192431版 本標(biāo)志生 存 時 間協(xié) 議標(biāo) 識區(qū) 分 服 務(wù)總 長 度片 偏 移填 充首 部 檢 驗 和源 地 址目 的 地 址可 選 字 段 (長 度 可 變)位首部長度數(shù)

45、 據(jù) 部 分固定部分可變部分源地址和目的地址都各占 4 字節(jié)IP 數(shù)據(jù)報首部的可變部分IP IP 首部的可變部分就是一個選項字段,用來支持排錯、測量以首部的可變部分就是一個選項字段,用來支持排錯、測量以及安全等措施,內(nèi)容很豐富。及安全等措施,內(nèi)容很豐富。選項字段的長度可變,從選項字段的長度可變,從 1 1 個字節(jié)到個字節(jié)到 40 40 個字節(jié)不等,取決于個字節(jié)不等,取決于所選擇的項目。所選擇的項目。增加首部的可變部分是為了增加增加首部的可變部分是為了增加 IP IP 數(shù)據(jù)報的功能,但這同時也數(shù)據(jù)報的功能,但這同時也使得使得 IP IP 數(shù)據(jù)報的首部長度成為可變的。這就增加了每一個路由數(shù)據(jù)報的首

46、部長度成為可變的。這就增加了每一個路由器處理數(shù)據(jù)報的開銷。器處理數(shù)據(jù)報的開銷。 typedef struct _IPHeader / 20字節(jié)的IP頭 UCHAR iphVerLen; / 版本號和頭長度(各占4位) UCHAR ipTOS; / 服務(wù)類型 USHORT ipLength; / 整個IP報文長度 USHORT ipID; / 封包標(biāo)識 USHORT ipFlags;/ 標(biāo)志、片偏移量 UCHAR ipTTL;/ 生存時間TTL UCHAR ipProtocol; / 協(xié)議(TCP、UDP、ICMP等) USHORT ipChecksum; / 校驗和 ULONG ipSourc

47、e; / 源IP地址 ULONG ipDestination; / 目標(biāo)IP地址 IPHeader, *PIPHeader; 77 網(wǎng)絡(luò)編程中網(wǎng)絡(luò)編程中IP頭對應(yīng)結(jié)構(gòu)體聲明頭對應(yīng)結(jié)構(gòu)體聲明78 UDP頭簡單。長度僅為8個字節(jié),而且只包含了四個字段,格式如圖所示。源端口(16位)目標(biāo)端口(16位)UDP長度(16位)UDP校驗和(16位) 由于UDP是一種不能保證數(shù)據(jù)可靠傳輸?shù)膮f(xié)議,所以校驗和的計算是可選的。 UDP校驗和除覆蓋了UDP頭之外,還同時覆蓋了實際的數(shù)據(jù),此外還包括IP頭的一部分。 typedef struct _UDPHeader USHORTsourcePort;/ 源端口號US

48、HORTdestinationPort; / 目的端口號USHORTlen;/ 封包長度USHORTchecksum;/ 校驗和 UDPHeader, *PUDPHeader;7980 計算UDP校驗和的附加字段叫作“偽首部”。 UDP校驗和基于如下幾個域:32位源IP地址(IP頭)32位目標(biāo)IP地址(IP頭)8位字段(全零)8位協(xié)議16位UDP長度16位源端口號16位目標(biāo)端口號16位UDP長度16位UDP校驗和UDP數(shù)據(jù)81 發(fā)送原始UDP封包的步驟首先以IPPOTO_UDP為協(xié)議類型創(chuàng)建一個原始套接字,打開原始套接字上的IP_HDRINCL選項;然后構(gòu)建UDP封包(先設(shè)置IP頭,再設(shè)置UD

49、P頭,最后設(shè)置數(shù)據(jù));初始化完整的UDP封包之后,調(diào)用sendto函數(shù)即可將它發(fā)送。 例:發(fā)送原始UDP封包發(fā)送原始UDP封包int main()/ 輸入?yún)?shù)信息char szDestIp = 10.16.115.88; / = 填寫目的IP地址char szSourceIp = 127.0.0.1; / iphVerLen = (4ipLength = htons(sizeof(IPHeader) + sizeof(UDPHeader) + nMsgLen);pIphdr-ipTTL = 128;pIphdr-ipProtocol = IPPROTO_UDP;pIphdr-ipSource = inet_addr(szSourceIp);pIphdr-ipDestination = inet_addr(szDestIp);pIphdr-ipChecksum = checksum(USHORT*)pIphdr, sizeof(IPHeader);/ UDP頭UDPHeader *pUdphdr = (UDPHeader *)&buffsizeof(IPHeader);pUdphdr-sourcePort = htons(8888);pUdphdr-des

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論