2012-11-18 30 views
1

所以我試圖解開以太網幀eth和ip頭。我有一個程序框架,它從文件中讀取輸入數據,併爲框架數據提供結構。反編組以太網幀和數據對齊

我已經GOOGLE和閱讀其他帖子的主題,但我無處可去。例如: Data Alignment with network programming http://en.wikipedia.org/wiki/Data_structure_alignment

我不確定是什麼問題。很顯然,即時通訊新的C.

如果我只是嘗試使用memcpy並將數據複製到我的結構的eth和ip標頭大部分數據出來很好,但不是我的ip結構中的IP地址。我也嘗試從輸入結構中讀取1byte,2byte和4byte塊,但它沒有給我正確的數據。

這裏是從輸入文件的輸入數據幀的一個示例:

200 0000 0002 0200 0000 0012 0800 4500 0026 17d4 81e7 ff01 0000 0a02 0002 0c0c 0c0c 0000 e802 c04b 0004 3e89 3325 0006 ddef 0809 

下面是使用

struct ethhdr{ 
    char  da[6]; 
    char  sa[6]; 
    uint16_t pt; 
}; 
typedef struct ethhdr ethhdr; 

struct iphdr{ 
#ifdef WORDS_BIGENDIAN 
    unsigned int ip_v:4;  /* version */ 
    unsigned int ip_hl:4;  /* header length */ 
#else 
    unsigned int ip_hl:4;  /* header length */ 
    unsigned int ip_v:4;  /* version */ 
#endif 
    uint8_t ip_tos;   /* type of service */ 
    uint16_t ip_len;   /* total length */ 
    uint16_t ip_id;   /* identification */ 
    uint16_t ip_off;   /* fragment offset field */ 
    uint8_t ip_ttl;   /* time to live */ 
    uint8_t ip_p;   /* protocol */ 
    uint16_t ip_sum;   /* checksum */ 
    uint32_t ip_src, ip_dst;   /* source and dest address */ 
}; 
typedef struct iphdr iphdr; 

,即時通訊被服務的輸入數據結構中的首標結構的IM。

struct fe_context{ 
    char *pkt;   /* Pointer to packet */ 
    size_t len;   /* Length of packet */ 
    void *if_in;  /* Incoming interface - handle */ 
}; 
typedef struct fe_context fe_context; 

我如何綁定以讀取數據的示例代碼。

int fe_process(fe_context *c) 
{ 
    printf("\n\nPacket received!\n"); 
    printf("memcpy to header structs:\n"); 
    ethhdr * ethh = (ethhdr *) malloc(sizeof(ethhdr)); 
    iphdr * iph = (iphdr *) malloc(sizeof(iphdr)); 
    memcpy(ethh, c->pkt, sizeof(ethhdr)); 
    memcpy(iph, c->pkt+sizeof(ethhdr), sizeof(ethhdr)); 

    printf("MAC SA: %02x:%02x:%02x:%02x:%02x:%02x\n", ethh->sa[0], ethh->sa[1], ethh->sa[2], 
     ethh->sa[3], ethh->sa[4], ethh->sa[5]); 
    printf("MAC P: %04x\n", ntohs(ethh->pt)); 

    printf("IP Ver: %x\n", ntohl(iph->ip_v)); 
    printf("IP IHL: %x\n", ntohl(iph->ip_hl)); 
    printf("IP TTL: %i\n", iph->ip_ttl); 
    printf("IP Checksum: %x\n", ntohl(iph->ip_sum)); 
    printf("IP SRC: %08x\n", ntohl(iph->ip_src)); 
    printf("IP DST: %08x\n", ntohl(iph->ip_dst)); 

    char * cp = c->pkt; 
    printf("\nPacket read by char:\n"); 
    char data; 
    int p; 
    for(p = 0; p < 52; p++) { 
    data = *cp; 
    cp++; 
    printf("%02x", data); 
    if(p%2==1) { 
     printf(" "); 
    } 
    } 
    printf("\n\n"); 
    cp = c->pkt; 
    printf("Packet read by uint16_t:\n"); 
    uint16_t data16; 
    for(p = 0; p < 52/2; p++) { 
    data16 = *cp; 
    cp+=2; 
    printf("%04x ", ntohs(data16)); 
    } 
    printf("\n\n"); 
    cp = c->pkt; 
    printf("Packet read by uint32_t:\n"); 
    uint32_t data32; 
    for(p = 0; p < 52/4; p++) { 
    data32 = *cp; 
    cp+=4; 
    printf("%08x ", ntohl(data32)); 
    } 
    printf("\n\n"); 

    return 0; 
} 

這裏是它的輸出與上述測試數據輸入。

Packet received! 
memcpy to header structs: 
MAC SA: 02:00:00:00:00:12 
MAC P: 0800 
IP Ver: 4000000 
IP IHL: 5000000 
IP TTL: 255 
IP Checksum: 0 
IP SRC: 0a020000 
IP DST: 00000000 // It looks good up until here. this should be 0c0c0c0c 

Packet read by char: 
0200 0000 0002 0200 0000 0012 0800 4500 0026 17ffffffd4 ffffff81ffffffe7 ffffffff01 0000 0a02 0002 0c0c 0c0c 0000 ffffffe802 ffffffc04b 0004 3effffff89 3325 0006 ffffffddffffffef 0809 

Packet read by uint16_t: 
0200 0000 0000 0200 0000 0000 0800 4500 0000 1700 81ff ffff 0000 0a00 0000 0c00 0c00 0000 e8ff c0ff 0000 3e00 3300 0000 ddff 0800 

Packet read by uint32_t: 
02000000 00000000 00000000 08000000 00000000 81ffffff 00000000 00000000 0c000000 e8ffffff 00000000 33000000 ddffffff 

正如你可以看到結構中的數據一直很好,直到DST IP。這可能是因爲填充/數據對齊?通過查看字符讀數,它會出現問題以某種方式發生在數據的IP頭部分中?當我通過char閱讀時,這些'f從哪裏來?

我試着檢查c-> pkt指針地址和它的偶數。我甚至不確定這是否重要?我認爲這將始終是因爲malloc爲我而來。閱讀這些數據以解析/解組的正確方式是什麼?我將會對這些數據進行修改,所以我寧願將數據轉換成整潔的結構。

在我的代碼中有一個簡單的錯誤還是我錯誤的方式?任何幫助深表感謝!

回答

1

我注意到你就行犯了一個錯誤:

memcpy(iph, c->pkt+sizeof(ethhdr), sizeof(ethhdr));

你複製sizeof(ethhdr)字節爲您的IP報頭,而不是sizeof(iphdr)這是你想要的這裏。好像你犯了一個錯字。

+0

謝謝!它似乎正在工作! – Robzet