2014-01-14 226 views
1

我需要澄清在計算校驗和時正確使用TCP報頭和僞報頭。僞首標是否需要在IP標題之後和實際的TCP標題之前立即出現?以下是我有:TCP報頭和校驗和

IPHeader *iph = (IPHeader *)(packet + ETHER_SIZE); //ETHER_SIZE == 14 
ipLen = ntohs(iph->totLen) * 4; 
TCPPseudo *tcps = (TCPPseudo *)(packet + ETHER_SIZE + ipLen); 
TCPHeader *tcp = (TCPHeader *)(tcps + sizeof(TCPPseudo)); 

這裏是我的頭:

typedef struct __attribute__((__packed__)) IPHeader { 
    #if __BYTE_ORDER__ == __LITTLE_ENDIAN__ 
    uint8_t hdrLen:4; 
    uint8_t version:4; 
    #else 
    uint8_t version:4; 
    uint8_t hdrLen:4; 
    #endif 
    uint8_t TOS; 
    uint16_t totLen; 
    uint16_t id; 
    uint16_t offset; 
    #define DF 0x4    
    #define MF 0x2   
    #define OFF 0 
    uint8_t TTL; 
    uint8_t protocol; 
    uint16_t checksum; 
    struct in_addr srcIP; 
    struct in_addr destIP; 
}IPHeader; 

typedef struct __attribute__((__packed__)) TCPHeader { 
    uint16_t srcPort; 
    uint16_t destPort; 
    uint32_t seqNum; 
    uint32_t ackNum; 
    uint8_t offset:4; 
    uint8_t res:4; 
    uint8_t flags; 
    uint16_t window; 
    uint16_t checksum; 
    uint16_t urg; 
}TCPHeader; 

typedef struct __attribute__((__packed__)) TCPPseudo { 
    struct in_addr srcAddr; 
    struct in_addr destAddr; 
    uint8_t zeroes; 
    uint8_t protocol; 
    uint16_t len; 
}TCPPseudo; 

是否校驗涉及服用僞首和「真正的」頭兩者的長度,以及兩者的地址他們?

+0

來自http://tools.ietf.org/html/rfc793校驗和字段是頭文件和文本中所有16位字的補碼總和的16位補碼。如果 段包含校驗和的奇數個頭和文本八位組,則最後一個八位位組在右側填充0,形成一個16位字,用於校驗和。該墊不是 作爲該部分的一部分傳輸。在計算校驗和 時,校驗和字段本身被替換爲零。 校驗和概念上也覆蓋了96位的僞頭文件 – lulyon

回答

1

僞頭不物理存在。它不是通過網絡發送的數據包的一部分。它只是幫助解釋IP報頭的哪些部分包含在TCP報頭校驗和計算中。

+0

因此,爲了計算TCP校驗和,我會使用僞頭文件中的長度字段以及其他一些算法來獲得正確的長度嗎?另外,我會通過校驗和功能的實際標題的地址,不包括pseudoheader? – PacSan

+0

您將使用數據包的數據(有效負載),TCP標頭和僞首部中描述的IP標頭部分。 – Marian