国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
ping源代碼完全解析
--------------------------------------------------
author:    Zero1,lingyi.pro#163.com
date:        2008-04-27
--------------------------------------------------
目錄
-------------
1.相關(guān)知識(shí)
2.相關(guān)數(shù)據(jù)結(jié)構(gòu)
3.相關(guān)函數(shù)
4.代碼分析
5.小結(jié)
1.相關(guān)知識(shí)
-----------
ping命令可以查看一個(gè)系統(tǒng)到另一個(gè)系統(tǒng)是否可達(dá),即判斷網(wǎng)絡(luò)連接是否正常。它的工作原理是:向網(wǎng)絡(luò)上的另一臺(tái)主機(jī)發(fā)送ICMP報(bào)文,并等待ICMP回顯應(yīng)答(ECHO_REPLY);如果目標(biāo)系統(tǒng)接收到ICMP報(bào)文,它將返回給發(fā)送者一樣的報(bào)文;同時(shí)ping可以計(jì)算這兩臺(tái)主機(jī)間的往返時(shí)間,以表明兩主機(jī)間的距離。
ps:當(dāng)然現(xiàn)在有些主機(jī)為了隱藏自己,對(duì)于ping發(fā)送來ICMP報(bào)文不返回回顯信息。
想要深入了解ping的工作原理,還得了解ping命令所使用的TCP/IP協(xié)議。
ICMP(Internet Control Message Protocol,網(wǎng)際控制報(bào)文協(xié)議)是為網(wǎng)關(guān)和目標(biāo)主機(jī)提供的一種差錯(cuò)控制機(jī)制,使它們?cè)诎l(fā)生差錯(cuò)是把錯(cuò)誤信息報(bào)告給源發(fā)送方(source sender)。ICMP協(xié)議是IP層的一個(gè)協(xié)議,但是由于差錯(cuò)報(bào)告發(fā)送會(huì)源發(fā)送方的過程中可能要經(jīng)過若干子網(wǎng),因此牽扯到路由選擇問題,所以ICMP報(bào)文通常有IP協(xié)議來發(fā)送。于是ICMP數(shù)據(jù)報(bào)發(fā)送前需要進(jìn)行兩次封裝:首先添加ICMP報(bào)頭形成ICMP報(bào)文,再添加IP報(bào)頭形成IP數(shù)據(jù)報(bào),如下圖所示
----------------
|       IP報(bào)頭       |
|---------------------|
|  |----------------| |
| |    ICMP報(bào)頭   ||
| |-----------------| |
| |  |------------| | |
| | | ICMP數(shù)據(jù)報(bào) | | |
| |  |------------| | |
| |-----------------| |
|---------------------|
由于IP協(xié)議是一種點(diǎn)對(duì)點(diǎn)的協(xié)議,而不是端對(duì)端的協(xié)議,它提供無連接的數(shù)據(jù)包服務(wù)(通常使用UDP協(xié)議),所以不需要bind()和connect()函數(shù)來綁定和連接端口。用sendto()函數(shù)來發(fā)送數(shù)據(jù)報(bào),接收數(shù)據(jù)使用recvfrom()函數(shù)。(更多信息參看socket編程相關(guān)資料)
2.相關(guān)數(shù)據(jù)結(jié)構(gòu)
----------------
2.1 IP報(bào)頭格式
IP報(bào)頭格式:版本號(hào)(4bit),IP報(bào)頭長度(4),服務(wù)類型(8),數(shù)據(jù)報(bào)長度(16),報(bào)文標(biāo)志ID(16),報(bào)文標(biāo)志F(3),分段偏移量(13),生存時(shí)間(8),協(xié)議號(hào)(8),報(bào)頭校驗(yàn)和(16),源地址(32),目的地址(32),任選項(xiàng)和填充位(若干)。示意圖如下:
--------------------------------------------------------------------------
| 版本號(hào)VER(4) | IP報(bào)頭長度IHL(4) | 服務(wù)類型TOS(8) | 數(shù)據(jù)報(bào)長度TL(16) |
|------------------------------------------------------------------------|
|     報(bào)文標(biāo)志ID(16)   |   報(bào)文標(biāo)志F(3)   |    分段偏移量 F0(13)      |
|------------------------------------------------------------------------|
|     生存時(shí)間(8)    |     協(xié)議號(hào)PORT(8)    |     報(bào)頭校驗(yàn)和(16)         |
|------------------------------------------------------------------------|
|                           源地址(32)                                    |
|------------------------------------------------------------------------|
|                           目的地址(32)                                |
|------------------------------------------------------------------------|
|                        任選項(xiàng)和填充位(若干)                              |
--------------------------------------------------------------------------
根據(jù)IP報(bào)頭格式信息,可定義IP報(bào)頭格式數(shù)據(jù)結(jié)構(gòu)如下(更詳細(xì)請(qǐng)閱讀<netinet/ip.h>):
/****************************
*  計(jì)算icmp校驗(yàn)和算法
*  2008-05-02
* **************************/
unsigned short chksum(addr,len)
    unsigned short *addr;  /* 校驗(yàn)數(shù)據(jù)開始地址(注意是以2字節(jié)為單位) */
    int len;                /* 校驗(yàn)數(shù)據(jù)的長度大小,以字節(jié)為單位 */
{
    int sum = 0;        /* 校驗(yàn)和 */
    int nleft = len;    /* 未累加的數(shù)據(jù)長度 */
    unsigned short *p;  /* 走動(dòng)的臨時(shí)指針,2字節(jié)為單位 */
    unsigned short tmp = 0; /* 奇數(shù)字節(jié)長度時(shí)用到 */
   while( nleft > 1)
   {
       sum += *p++;    /* 累加 */
       nleft -= 2;
    }
   if(nleft == 1)      /* 奇數(shù)字節(jié)長度 */
   {
       *(unsigned char *)&tmp = *(&(unsigned char *)p); /* 將最后字節(jié)壓如2字節(jié)的高位 */
       sum += tmp;
   }
    sum += (sum >> 16) + (sum & 0xffff);    /* 高位低位相加 */
    sum += sum >> 16;                       /* 上一步溢出時(shí),將溢出位也加到sum中 */
    tmp = ~sum;     /* 注意類型轉(zhuǎn)換,現(xiàn)在的校驗(yàn)和為16位 */
    return tmp;
}
ping程序只用到以下數(shù)據(jù)段:
ip_hl:IP報(bào)頭長度(Internet Header Length),以4字節(jié)為一單位來記錄IP報(bào)頭長度。
ip_ttl:Time to Live,生存期,以秒為單位,指明此IP數(shù)據(jù)包在網(wǎng)絡(luò)上停留的最長時(shí)間,其值由發(fā)送端設(shè)定,每經(jīng)過一個(gè)路由,其值自減1,當(dāng)值為0時(shí),該IP數(shù)據(jù)包將被丟棄。
2.2 ICMP報(bào)頭格式
ICMP分為錯(cuò)誤報(bào)告報(bào)文和查詢報(bào)文兩種。每個(gè)ICMP報(bào)頭均包含類型、編碼和校驗(yàn)和三項(xiàng),長度分別為8位、8位和16位,其他選項(xiàng)隨ICMP功能的不同而不同(詳見《TCP/IP協(xié)議詳解-卷1:協(xié)議》p59)。
ICMP報(bào)頭格式示意圖如下:
----------------------------------------------
|   類型(8)  |  代碼(8)  |  校驗(yàn)和(16)  |
|--------------------------------------------|
|          (不同類型代碼有不同的內(nèi)容)          |
----------------------------------------------
ping命令中只用到"回顯應(yīng)答"(ICMP_ECHO)和"回顯請(qǐng)求"(ICMP_ECHOREPLY)兩種。Linux下定義為:
#define ICMP_ECHO    0
#define ICMP_ECHOREPLY    8
這兩種ICMP類型的報(bào)頭格式示意圖如下:
--------------------------------------------------------------
| 類型TYPE(0或8) | 編碼CODE(沒有使用) | 校驗(yàn)和SHECKSUM(16) |
|-------------------------------------------------------------|
|        標(biāo)志符Identifier      |     序列號(hào)Sequence       |
---------------------------------------------------------------
Linux下ICMP數(shù)據(jù)結(jié)構(gòu)的定義如下(詳見<netinet/ip_icmp.h>):
struct icmp
{
    u_int8_t icmp_type;        /* 消息類型 */
    u_int8_t icmp_code;        /* 編碼 */
    u_int16_t icmp_cksum;    /* 校驗(yàn)和 */
    union
    {
        u_char ih_pptr;        /* ICMP_PARAMPROB */
        struct in_addr ih_gwaddr;    /* 網(wǎng)關(guān)地址 */
        struct ih_idseq        /* 顯示數(shù)據(jù)報(bào) */
        {
            u_int16_t icd_id;    /*  */
            u_int16_t icd_seq;    /*  */
        }ih_idseq;
        u_int32_t ih_void;        /*  */
        /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery(rffc1191) */
        struct ih_pmtu
        {
            u_int16_t ipm_void;        /*  */
            u_int16_t ipm_nextmtu;    /*  */
        }ih_pmtu;
        struct ih_rtradv
        {
            u_int8_t irt_num_addr;    /*  */
            u_int8_t irt_wpa;        /*  */
            u_int16_t irt_lifetime;    /*  */
        }ih_rtradv;
    }icmp_hun;
    #define icmp_pptr    icmp_hun.ih_pptr
    #define icmp_gwaddr    icmp_hun.ih_gwaddr
    #define icmp_id    icmp_hun.ih_idseq.icd_id
    #define icmp_seq    icmp_hun.ih_idseq.icd_seq
    #define icmp_void    icmp_hun.ih_void
    #define icmp_pmvoid    icmp_hun.ih_pmtu.ipm_void
    #define icmp_nextmtu    icmp_hun.ih_pmtu.ipm_nextmtu
    #define icmp_num_addrs    icmp_hun.ih_rtradv.irt_num_addrs
    #define icmp_wpa    icmp_hun.ih_rtradv.irt_wpa
    #define icmp_lifetime    icmp_hun.ih_rtradv.irt_lifetime
    union
    {
        struct
        {
            u_int32_t its_otime;
            u_int32_t its_rtime;
            u_int32_t its_ttime;
        }id_ts;
        struct
        {
            struct ip idi_ip;
            /* 選項(xiàng)及64位數(shù)據(jù) */
        }id_ip;
        struct icmp_ra_addr id_radv;
        u_int32_t id_mask;    /**/
        u_int8_t id_data[1];
    }icmp_dun;
    #define icmp_otime    icmp_dun.id_ts.its_otime
    #define icmp_rtime    icmp_dun.id_ts.its_rtime
    #edfine icmp_ttime    icmp_dun.id_ts.its_ttime
    #define icmp_ip    icmp_dun.id_ip.idi_ip
    #edfine icmp_radv    icmp_dun.id_radv
    #define icmp_mask    icmp_dun.id_mask
    #define icmp_data    icmp_dun.id_data
};
/****************************
*  計(jì)算icmp校驗(yàn)和算法
*  2008-05-02
* **************************/
unsigned short chksum(addr,len)
unsigned short *addr;  /* 校驗(yàn)數(shù)據(jù)開始地址(注意是以2字節(jié)為單位) */
int len;                /* 校驗(yàn)數(shù)據(jù)的長度大小,以字節(jié)為單位 */
{
int sum = 0;        /* 校驗(yàn)和 */
int nleft = len;    /* 未累加的數(shù)據(jù)長度 */
unsigned short *p;  /* 走動(dòng)的臨時(shí)指針,2字節(jié)為單位 */
unsigned short tmp = 0; /* 奇數(shù)字節(jié)長度時(shí)用到 */
while( nleft > 1)
{
sum += *p++;    /* 累加 */
nleft -= 2;
}
if(nleft == 1)      /* 奇數(shù)字節(jié)長度 */
{
*(unsigned char *)&tmp = *(&(unsigned char *)p); /* 將最后字節(jié)壓如2字節(jié)的高位 */
sum += tmp;
}
sum += (sum >> 16) + (sum & 0xffff);    /* 高位低位相加 */
sum += sum >> 16;                       /* 上一步溢出時(shí),將溢出位也加到sum中 */
tmp = ~sum;     /* 注意類型轉(zhuǎn)換,現(xiàn)在的校驗(yàn)和為16位 */
return tmp;
}
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
用C語言實(shí)現(xiàn)Ping程序功能
IP報(bào)文頭結(jié)構(gòu)體
94
Linux網(wǎng)絡(luò)編程:原始套接字的魔力【上】
網(wǎng)際層
天天使用Ping 你真的了解嗎?
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服