2013-11-23 50 views
0

我有一個分配在C.寫一個數據包嗅探器目前提供的示例代碼獲取原始數據包,並解析鏈路層(以太網)報頭,像這樣:印刷IP版本和IP報頭用C

struct ethernet_header { 
    unsigned char dest[6]; 
    unsigned char source[6]; 
    char proto; 
} 

... 



const struct ethernet_header *header; 
    header = (const struct ethernet_header *)data_packet; 

    printf("Source MAC: %02x", header->source[0]); 
    for (i = 1; i < 6; i++) printf(":%02x", header->source[i]); 
    printf("\n"); 

... 

現在我需要解析互聯網層。 對於網絡層我有以下結構:

struct ip_header { 
     unsigned char ip_vhl;   /* version << 4 | header length >> 2 */ 
     unsigned char ip_tos;     /* type of service */ 
     unsigned char ip_len;     /* total length */ 
... 
}; 

現在ip_vhl是8位長,我想前4位和printf它作爲一個版本,最後4位的printf它作爲一個頭的長度。你們能幫我在這裏嗎?

同樣在示例代碼中,他們使用%02x來printf header->source[i]%hu來printf header->proto。我真的很感激,如果有人可以解釋它,以及我應該用什麼樣的printf ip_vhl,ip_tos和ip_len %..

回答

0

你有兩個選擇:

  • 要麼使用位域來形容4位字段。謹防實現和平臺相關的位和字節順序:
struct foo { 
    int bar:4; 
    int baz:4; 
} 
  • 或使用邏輯運算來抽取位。
upper4bits = (bigvar >> 4) & 0xf; 
lower4bits = bigvar & 0xf; 
+0

感謝。這回答了問題的最後部分,但第二個呢? – maximilliano

+0

格式化字符串只是告訴printf作爲下一個參數的期望變量的類型以及如何顯示它。這取決於你決定你想看到什麼。有關格式字符串的詳細信息,請參閱http://linux.die.net/man/3/printf。 – ArtemB