天天看點

IP封包及ICMP封包結構原理

在一個不可以稱之為學校的學校上學,沒啥項目可練手,也沒老師指導,隻能自己給自己找點事情做了,目前打算寫個掃描器,現在也在惡補網絡知識中(雖然以前學過點,但是不夠用啊······呵呵····)

IP報頭結構:

//定義IP首部

typedef struct _iphdr{

unsigned char h_lenver; //4 位IP版本号+4位首部長度

unsigned char tos; //8位服務類型TOS

unsigned short total_len; //16位IP包總長度(位元組)

unsigned short ident; //1 6位辨別, 用于輔助IP包的拆裝

unsigned short frag_and_flags; //3位标志位+13位偏移位, 也是用于IP包的拆裝

unsigned char ttl; //8位IP包生存時間 TTL

unsigned char proto; //8位協定 (TCP, UDP 或其他)

unsigned short checksum; //16位IP首部校驗和,最初置零,等所有標頭都填寫正确後,計算并替換.

unsigned int sourceIP; //32位源IP位址

unsigned int destIP; //32位目的IP位址

}IP_HEADER;  

在給張圖檔看下ip報頭的結構:

IP封包及ICMP封包結構原理

計算校驗和的經典函數: 

SHORT checksum(USHORT* buffer, int size)

{

    unsigned long cksum = 0;

    while(size>1)

    {

        cksum += *buffer++;

        size -= sizeof(USHORT);

    }

    if(size)

    {

        cksum += *(UCHAR*)buffer;

    }

    cksum = (cksum>>16) + (cksum&0xffff); 

    cksum += (cksum>>16); 

    return (USHORT)(~cksum);

ICMP報頭結構: 

//定義ICMP首部

typedef struct _icmphdr{

unsigned char i_type; //8位類型

unsigned char i_code; //8位代碼

unsigned short i_cksum; //16位校驗和, 從TYPE開始,直到最後一位使用者資料,如果為位元組數為奇數則補充一位

unsigned short i_id ; //識别号(一般用程序号作為識别号), 用于比對ECHO和ECHO REPLY包

unsigned short i_seq ; //封包序列号, 用于标記ECHO封包順序

unsigned int timestamp; //時間戳

}ICMP_HEADER; 

在上一張圖看看: 

IP封包及ICMP封包結構原理

ICMP封包的各種狀态: 

目的不可達封包

類型:3 代碼:0至15 檢驗和
未使用(全0)
收到的IP資料報的一部分,包括IP首部以及資料報資料的前8個位元組

源端抑制封包

類型:4 代碼:0 檢驗和
未使用(全0)
收到的IP資料報的一部分,包括IP首部以及資料報資料的前8個位元組

逾時封包

類型:11 代碼:0或1 檢驗和
未使用(全0)
收到的IP資料報的一部分,包括IP首部以及資料報資料的前8個位元組

參數問題

類型:12 代碼:0或1 檢驗和
指針 未使用(全0)
收到的IP資料報的一部分,包括IP首部以及資料報資料的前8個位元組

改變路由

類型:5 代碼:0到3 檢驗和
目标路由器IP位址
收到的IP資料報的一部分,包括IP首部以及資料報資料的前8個位元組

回送請求和回答

類型:8或0 代碼:0 檢驗和
辨別符 序号
由請求封包發送;由回答封包重複

時間戳請求和回答

類型:13或14 代碼:0 檢驗和
辨別符 序号
原始時間戳
接收時間戳
發送時間戳

位址掩碼請求和回答

類型:17或18 代碼:0 檢驗和
辨別符 序号
位址掩碼

路由詢問和通告

類型:10 代碼:0 檢驗和
辨別符 序号
類型:9 代碼:0 檢驗和
位址數 位址項目長度 壽命
路由器位址1
位址參考1
路由器位址2
位址參考2
...

........本文的内容收集與網絡········算是東湊西湊的,也不知道作者是誰?把自己要的都收集來了是以作者看到·····别怪啦····

IP封包及ICMP封包結構原理