linux中定義的幾個網絡報文的結構體

1、UDP協議


UDP協議是建立在IP協議基礎之上的,用在傳輸層的協議。
0                               16                              32
-------------------------------------------------------
|       UDP源端口     |      UDP目的端口   |
-------------------------------------------------------
|   UDP數據報長度 |   UDP數據報校驗 |
-------------------------------------------------------
|                              數據                             |
-------------------------------------------------------

UDP的頭格式爲:
struct udphdr
{
u_int16_t source; /*源地址端口*/
u_int16_t dest;    /*目的地址端口*/
u_int16_t len;     /*UDP長度*/
u_int16_t check;   /*UDP校驗和*/
};
頭文件:linux/udp.h


2、ICMP協議


ICMP是消息控制協議,也處於網絡層。在網絡上傳遞IP數據包時,如果發生了錯誤,那麼就會用ICMP協議來報告錯誤。
0               8             16                        32
----------------------------------------------------
|    類型    |    代碼    |       校驗和           |
----------------------------------------------------
|        識別號           |     報文序列號      |
----------------------------------------------------
ICMP的頭格式爲:
struct icmphdr
{
u_int8_t type;                /* 類型 */
u_int8_t code;                /* 代碼*/
u_int16_t checksum;   /*校驗和*/
union
{
    struct
    {
      u_int16_t id;
      u_int16_t sequence;
    } echo;                     /* echo datagram */
    u_int32_t   gateway;        /* gateway address */
    struct
    {
      u_int16_t __unused;
      u_int16_t mtu;
    } frag;                     /* path mtu discovery */
} un;
};
頭文件:linux /icmp.h


3、IP協議


IP協議是在網絡層的協議,它主要完成數據包的發送作用,下面這個表是IPv4的數據包格式:  

IP的頭格式爲:

struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD) /*小端*/
    __u8 ihl:4,              /*IP頭部長度*/
          version:4;              /*IP版本,值爲4*/
#elif defined (__BIG_ENDIAN_BITFIELD)/*大端*/
    __u8 version:4,          /*IP版本,值爲4*/
                 ihl:4;              /*IP頭部長度*/
#else
#error "Please fix <asm/byteorder.h>"
#endif
    __u8    tos;                /*服務類型*/
    __be16 tot_len;            /*總長度*/
    __be16 id;                 /*標識*/
    __be16 frag_off;           /*片偏移*/
    __u8    ttl;                /*生存時間*/
    __u8    protocol;           /*協議類型*/
    __u16   check;              /*頭部校驗和*/
    __be32 saddr;              /*源IP地址*/
    __be32 daddr;              /*目的IP地址*/
      /*IP選項*/
};
頭文件:linux/ip.h


4、TCP協議




TCP的頭格式爲:
struct tcphdr
{
    __u16   source;         /*源地址端口*/
    __u16   dest;           /*目的地址端口*/
    __u32   seq;            /*序列號*/
    __u32   ack_seq;        /*確認序列號*/
#if defined(__LITTLE_ENDIAN_BITFIELD)
    __u16 res1:4,         /*保留*/
         doff:4,            /*偏移*/
        fin:1,              /*關閉連接標誌*/
        syn:1,              /*請求連接標誌*/
        rst:1,              /*重置連接標誌*/
        psh:1,              /*接收方儘快將數據放到應用層標誌*/
        ack:1,              /*確認序號標誌*/
        urg:1,              /*緊急指針標誌*/
        ece:1,              /*擁塞標誌位*/
        cwr:1;              /*擁塞標誌位*/
#elif defined(__BIG_ENDIAN_BITFIELD)
    __u16 doff:4,         /*偏移*/
        res1:4,             /*保留*/
        cwr:1,              /*擁塞標誌位*/
        ece:1,              /*擁塞標誌位*/
        urg:1,              /*緊急指針標誌*/
        ack:1,              /*確認序號標誌*/
        psh:1,              /*接收方儘快將數據放到應用層標誌*/
        rst:1,              /*重置連接標誌*/
        syn:1,              /*請求連接標誌*/
        fin:1;              /*關閉連接標誌*/
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
    __u16   window;         /*滑動窗口大小*/
    __u16   check;          /*校驗和*/
    __u16   urg_ptr;        /*緊急字段指針*/
};
頭文件:linux/tcp.h

tcphdr->source
    16位源端口號
tcphdr->dest
    16位目的端口號
tcphdr->seq
    表示此次發送的數據在整個報文段中的起始字節數。序號是32 bit的無符號數。爲了安全起見,它的初始值是一個隨機生成的數,它到達32位最大值後,又從零開始。
tcphdr->ack_seq
    指定的是下一個期望接收的字節,而不是已經正確接收到的最後一個字節。
tcphdr->doff
    TCP頭長度,指明瞭在TCP頭部包含多少個32位的字。此信息是必須的,因爲options域的長度是可變的,所以整個TCP頭部的長度也是變化的。從技術上講,這個域實際上指明瞭數據部分在段內部的其起始地址(以32位字作爲單位進行計量),因爲這個數值正好是按字爲單位的TCP頭部的長度,所以,二者的效果是等同的
tcphdr->res1爲保留位
tcphdr->window
    是16位滑動窗口的大小,單位爲字節,起始於確認序列號字段指明的值,這個值是接收端正期望接收的字節數,其最大值是63353字節。
    TCP中的流量控制是通過一個可變大小的滑動窗口來完成的。window域指定了從被確認的字節算起可以接收的多少個字節。window = 0也是合法的,這相當於說,到現在爲止多達ack_seq-1個字節已經接收到了,但是接收方現在狀態不佳,需要休息一下,等一會兒再繼續接收更多的數據,謝謝。以後,接收方可以通過發送一個同樣ack_seq但是window不爲0的數據段,告訴發送方繼續發送數據段。
tcphdr->check
    是檢驗和,覆蓋了整個的TCP報文段,這是一個強制性的字段,一定是由發送端計算和存儲,並由接收端進行驗證。
tcphdr->urg_ptr
    這個域被用來指示緊急數據在當前數據段中的位置,它是一個相對於當前序列號的字節偏移值。這個設施可以代替中斷信息。
fin, syn, rst, psh, ack, urg爲6個標誌位
    這6個位域已經保留了超過四分之一個世紀的時間而仍然原封未動,這樣的事實正好也說明了TCP的設計者們考慮的是多麼的周到。它們的含義如下:
    tcphdr->fin fin位被用於釋放一個連接。它表示發送方已經沒有數據要傳輸了。
    tcphdr->syn 同步序號,用來發起一個連接。syn位被用於建立連接的過程。在連接請求中,syn=1; ack=0表示該數據段沒有使用捎帶的確認域。連接應答捎帶了一個確認,所以有syn=1; ack=1。本質上,syn位被用來表示connection request和connection accepted,然而進一步用ack位來區分這兩種情況。
    tcphdr->rst 該爲用於重置一個已經混亂的連接,之所以會混亂,可能是由於主機崩潰,或者其他的原因。該位也可以被用來拒絕一個無效的數據段,或者拒絕一個連接請求。一般而言,如果你得到的數據段設置了rst位,那說明你這一端有了問題。
    tcphdr->psh 接收方在收到數據後應立即請求將數據遞交給應用程序,而不是將它緩衝起來直到整個緩衝區接收滿爲止(這樣做的目的可能是爲了效率的原因)
    tcphdr->ack ack位被設置爲1表示tcphdr->ack_seq是有效的。如果ack爲0,則該數據段不包含確認信息,所以,tcphdr->ack_seq域應該被忽略。
    tcphdr->urg 緊急指針有效
    tcphdr->ece 用途暫時不明
    tcphdr->cwr 用途暫時不明

對於TCP協議,其IP頭部的protocol的值應該爲6,通過計算IP頭部的長度可以得到TCP頭部的地址,即TCP的頭部在IP頭部長度ihl*4之後。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章