Tuesday, January 25, 2011

Linux下的網絡編程6

轉:http://cyuyanbiancheng.blog.hexun.com.tw/57020855_d.html


7. TCP/IP協議
  你也許聽說過TCP/IP協議,那麽你知道到底什麽是TCP,什麽是IP?在這一章裏面,我們一 起來學習這個目前網絡上用最廣泛的協議

7.1 
網絡傳輸分層  

  如果你考過計算機等級考試,那麽你就應該已經知道了網絡傳輸分層這個概念.在網絡上,人們為了傳輸數據時的方便,把網絡的傳輸分為7個層次.分別是:應用層,表示層,會話層,傳輸層,網絡層,數據鏈路層和物理層.分好了層以後,傳輸數據時,上一層如果要數據的 ,就可以直接向下一層要了,而不必要管數據傳輸的細節.下一層也只向它的上一層提供 數據,而不要去管其它東西了.如果你不想考試,你沒有必要去記這些東西的.只要知道是 分層的,而且各層的作用不同

7.2 IP
協議
  IP協議是在網絡層的協議.它主要完成數據包的發送作用下面這個表是IP4的數據包格

      0 4 8 16 32
      --------------------------------------------------
      |版本 |首部長度|服務類型數據包總長 |
      --------------------------------------------------
      標識 |DF |MF| 碎片偏移 |
      --------------------------------------------------
      生存時間 | 協議 | 首部較驗和 |
      ------------------------------------------------
      IP地址 |
      ------------------------------------------------
      目的IP地址 |
      -------------------------------------------------
      選項 |       =================================================
      數據 |       ------------------------------------------------- 


下面我們看一看IP的結構定義<netinet/ip.h>;     struct ip {
      #if __BYTE_ORDER == __LITTLE_ENDIAN
      unsigned int ip_hl:4; /* header length */       unsigned int ip_v:4; /* version */
      #endif
      #if __BYTE_ORDER == __BIG_ENDIAN
      unsigned int ip_v:4; /* version */
      unsigned int ip_hl:4; /* header length */
      #endif
      u_int8_t ip_tos; /* type of service */
      u_short ip_len; /* total length */
      u_short ip_id; /* identification */
      u_short ip_off; /* fragment offset field */
      #define IP_RF 0x8000 /* reserved fragment flag */
      #define IP_DF 0x4000 /* dont fragment flag */
      #define IP_MF 0x2000 /* more fragments flag */
      #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
      u_int8_t ip_ttl; /* time to live */       u_int8_t ip_p; /* protocol */
      u_short ip_sum; /* checksum */
      struct in_addr ip_src, ip_dst; /* source and dest address */
    };
 

  ip_vIP協議的版本號,這裏是4,現在IPV6已經出來了
  ip_hlIP包首部長度,這個值以4字節為單位.IP協議首部的固定長度為20個字節,如果IP 沒有選項,那麽這個值為5.   ip_tos服務類型,說明提供的優先權
  ip_len說明IP數據的長度.以字節為單位
  ip_id標識這個IP數據包
  ip_off碎片偏移,這和上面ID一起用來重組碎片的
  ip_ttl生存時間.沒經過一個路由的時候減一,直到為0時被拋棄
  ip_p協議,表示創建這個IP數據包的高層協議.TCP,UDP協議
  ip_sum首部校驗和,提供對首部數據的校驗
  ip_src,ip_dst發送者和接收者的IP地址

關於IP協議的詳細情況,請參考 RFC791




7.3 ICMP協議   ICMP是消息控制協議,也處於網絡層.在網絡上傳遞IP數據包時,如果發生了錯誤,那麽就 會用ICMP協議來報告錯誤.   ICMP包的結構如下:
      0 8 16 32
      ---------------------------------------------------------------------
      類型 | 代碼 | 校驗和 |
      --------------------------------------------------------------------
      數據 | 數據 |
      -------------------------------------------------------------------- 
  
  ICMP<netinet/ip_icmp.h>;中的定義是
    struct icmphdr {
      u_int8_t type; /* message type */
      u_int8_t code; /* type sub-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;
    };


關於ICMP協議的詳細情況可以查看 RFC792

7.4 UDP協議

      0 16 32
      ---------------------------------------------------
      | UDP源端口 | UDP目的端口 |
      ---------------------------------------------------
      | UDP數據報長度 | UDP數據報校驗 |
      ---------------------------------------------------


      UDP結構在<netinet/udp.h>;中的定義為:

      struct udphdr {         u_int16_t source;
        u_int16_t dest;
        u_int16_t len;
        u_int16_t check;
      };  


關於UDP協議的詳細情況,請參考 RFC768

7.5 TCP
  TCP協議也是建立在IP協議之上的,不過TCP協議是可靠的.按照順序發送的.TCP的數據結 構比前面的結構都要復雜.

      0 4 8 10 16 24 32
      -------------------------------------------------------------------

      源端口 | 目的端口 |
      -------------------------------------------------------------------
      序列號 |
      ------------------------------------------------------------------
      確認號 |
      ------------------------------------------------------------------
      | | |U|A|P|S|F| |
      |首部長度保留 |R|C|S|Y|I| 窗口 |
      | | |G|K|H|N|N| |
      -----------------------------------------------------------------
      校驗和 | 緊急指針 |
      -----------------------------------------------------------------
      選項 | 填充字節 |
      -----------------------------------------------------------------  


  TCP的結構在<netinet/tcp.h>;中定義為:

      struct tcphdr {
        u_int16_t source;
        u_int16_t dest;
        u_int32_t seq;
        u_int32_t ack_seq;
        #if __BYTE_ORDER == __LITTLE_ENDIAN
        u_int16_t res1:4;
        u_int16_t doff:4;
        u_int16_t fin:1;
        u_int16_t syn:1;
        u_int16_t rst:1;
        u_int16_t psh:1;
        u_int16_t ack:1;
        u_int16_t urg:1;
        u_int16_t res2:2;
        #elif __BYTE_ORDER == __BIG_ENDIAN
        u_int16_t doff:4;
        u_int16_t res1:4;
        u_int16_t res2:2;
        u_int16_t urg:1;
        u_int16_t ack:1;
        u_int16_t psh:1;
        u_int16_t rst:1;
        u_int16_t syn:1;
        u_int16_t fin:1;
        #endif
        u_int16_t window;
        u_int16_t check;
        u_int16_t urg_prt;
      };
 

   source發送TCP數據的源端口
   dest接受TCP數據的目的端口
   seq標識該TCP所包含的數據字節的開始序列號
   ack_seq確認序列號,表示接受方下一次接受的數據序列號
   doff數據首部長度.IP協議一樣,4字節為單位.一般的時候為
   urg如果設置緊急數據指針,則該位為
   ack如果確認號正確,那麽為
   psh如果設置為1,那麽接收方收到數據後,立即交給上一層程序    rst1的時候,表示請求重新連接
   syn1的時候,表示請求建立連接
   fin1的時候,表示親戚關閉連接
   window窗口,告訴接收者可以接收的大小
   checkTCP數據進行較核
   urg_ptr如果urg=1,那麽指出緊急數據對於歷史數據開始的序列號的偏移值

關於TCP協議的詳細情況,查看 RFC793


7.6 TCP


      Step 1: Client向Server送一個TCP數據包,表示請求建立連接為此,Client將數據包的SYN位設置為1,並且設置序列號seq=1000(我們假設為1000). 


      Step 2: Server收到了數據包,並從SYN位為1知道這是一個建立請求的連接.於是Server Client發送一個TCP數據包.因為是響應Client的請求,於是Server設置ACK1,sak_seq=1001(1000+1)同時設置自己的序列號.seq=2000(我們假設為2000). 


      Step 3:Client收到了ServerTCP,並從ACK1ack_seq=1001知道是從Server來的確認 信息.於是Client也向Server發送確認信息.Client設置ACK=1,ack_seq=2001,seq=1001,發送給Server.至此Client完成連接.  


      Step 4: Server受到確認信息,也完成連接. 通過上面幾個步驟,一個TCP連接就建立了.


  當然在建立過程中可能出現錯誤,不過TCP協議 可以保證自己去處理錯誤的. 說一說其中的一種錯誤. 聽說過DOS?(可不是操作系統啊).今年春節的時候,美國的五大網站一起受到攻擊. 擊者用的就是DOS(拒絕式服務)方式.概括的說一下原理.  


        Client先進行Step 1.Server收到後,進行第Step 2.按照正常的TCP連接,Client 應該進行Step 3. 不過攻擊者實際上並不進行Step 3.因為Client在進行Step 1的時候,修改了自 己的IP地址,就是說將一個實際上不存在的IP填充在自己IP數據包的發送者的IP一欄. 樣因為Server發的IP地址沒有人接收,所以Server會收不到Step 3的確認信號,這樣 Server會在那邊一直等待,直到超時. 這樣當有大量的Client發出請求後,Server會有大量等待,直到所有的資源被用光,而不能再 接收Server的請求.
連接的建立
  TCP協議是一種可靠的連接,為了保證連接的可靠性,TCP的連接要分為幾個步驟.我們把這 個連接過程稱為"三次握手". 下面我們從一個實例來分析建立連接的過程:
  UDP協議是建立在IP協議基礎之上的,用在傳輸層的協議.UDPIP協議一樣是不可靠的數 據報服務.UDP的頭格式為:

No comments:

Post a Comment