PING(Packet InterNet Groper)中文名為因特網(wǎng)包探索器,是用來查看網(wǎng)絡(luò)上另一個(gè)主機(jī)系統(tǒng)的網(wǎng)絡(luò)連接是否正常的一個(gè)工具。ping命令的工作原理是:向網(wǎng)絡(luò)上的另一個(gè)主機(jī)系統(tǒng)發(fā)送ICMP報(bào)文,如果指定系統(tǒng)得到了報(bào)文,它將把回復(fù)報(bào)文傳回給發(fā)送者,這有點(diǎn)象潛水艇聲納系統(tǒng)中使用的發(fā)聲裝置。所以,我們想知道我這臺(tái)主機(jī)能不能和另一臺(tái)進(jìn)行通信,我們首先需要確認(rèn)的是我們兩臺(tái)主機(jī)間的網(wǎng)絡(luò)是不是通的,也就是我說的話能不能傳到你那里,這是雙方進(jìn)行通信的前提。在Linux下使用指令ping的方法和現(xiàn)象如下:

PING的實(shí)現(xiàn)看起來并不復(fù)雜,我想自己寫代碼實(shí)現(xiàn)這個(gè)功能,需要些什么知識(shí)儲(chǔ)備?我簡單羅列了一下:
?ICMP協(xié)議的理解
?RAW套接字
?網(wǎng)絡(luò)封包和解包技能
搭建這么一個(gè)ping程序的步驟如下:
1、ICMP包的封裝和解封
2、創(chuàng)建一個(gè)線程用于ICMP包的發(fā)送
3、創(chuàng)建一個(gè)線程用于ICMP包的接收
4、原始套接字編程
PING的流程如下:

一、ICMP包的封裝和解封
(1) ICMP協(xié)議理解要進(jìn)行PING的開發(fā),我們首先需要知道PING的實(shí)現(xiàn)是基于ICMP協(xié)議來開發(fā)的。要進(jìn)行ICMP包的封裝和解封,我們首先需要理解ICMP協(xié)議。ICMP位于網(wǎng)絡(luò)層,允許主機(jī)或者路由器報(bào)告差錯(cuò)情況和提供有關(guān)異常情況的報(bào)告。ICMP報(bào)文是封裝在IP數(shù)據(jù)報(bào)中,作為其中的數(shù)據(jù)部分。ICMP報(bào)文作為IP層數(shù)據(jù)報(bào)的數(shù)據(jù),加上數(shù)據(jù)報(bào)頭,組成IP數(shù)據(jù)報(bào)發(fā)送出去。ICMP報(bào)文格式如下:

ICMP報(bào)文的種類有兩種,即ICMP差錯(cuò)報(bào)告報(bào)文和ICMP詢問報(bào)文。PING程序使用的ICMP報(bào)文種類為ICMP詢問報(bào)文。注意一下上面說到的ICMP報(bào)文格式中的“類型”字段,我們在組包的時(shí)候可以向該字段填寫不同的值來標(biāo)定該ICMP報(bào)文的類型。下面列出的是幾種常用的ICMP報(bào)文類型。

我們的PING程序需要用到的ICMP的類型是回送請求(8)。
因?yàn)镮CMP報(bào)文的具體格式會(huì)因?yàn)镮CMP報(bào)文的類型而各不相同,我們ping包的格式是這樣的:

(2) ICMP包的組裝
對照上面的ping包格式,我們封裝ping包的代碼可以這么寫:
void icmp_pack(struct icmp* icmphdr, int seq, int length){ int i = 0; icmphdr->icmp_type = ICMP_ECHO; //類型填回送請求 icmphdr->icmp_code = 0; icmphdr->icmp_cksum = 0; //注意,這里先填寫0,很重要! icmphdr->icmp_seq = seq; //這里的序列號(hào)我們填1,2,3,4.... icmphdr->icmp_id = pid & 0xffff; //我們使用pid作為icmp_id,icmp_id只是2字節(jié),而pid有4字節(jié) for(i=0;i<length;i++) { icmphdr->icmp_data[i] = i; //填充數(shù)據(jù)段,使ICMP報(bào)文大于64B } icmphdr->icmp_cksum = cal_chksum((unsigned short*)icmphdr, length); //校驗(yàn)和計(jì)算}這里再三提醒一下,icmp_cksum 必須先填寫為0再執(zhí)行校驗(yàn)和算法計(jì)算,否則ping時(shí)對方主機(jī)會(huì)因?yàn)樾r?yàn)和計(jì)算錯(cuò)誤而丟棄請求包,導(dǎo)致ping的失敗。我一個(gè)同事曾經(jīng)就因?yàn)檫@么一個(gè)錯(cuò)誤而排查許久,血的教訓(xùn)請銘記。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注