2012-01-12 350 views
0

我試圖從包中提取TCP有效載荷,而這裏的捕捉回調的最低限度的情況下:TCP有效載荷提取和正確的IP地址

void capture_callback (u_char *hdr , const struct pcap_pkthdr* pkthdr , const u_char* buff) 
{ 
    struct ether_header *eptr = (struct ether_header *) buff; 
    buff += sizeof (ether_header); /* jump over ethernet header: 14 bytes */ 

    if (ntohs (eptr->ether_type) == ETHERTYPE_IP) 
    { 
     struct ip *iph; 
     struct tcphdr *tcp_header; 

     iph = (struct ip *) buff; 
     buff += sizeof (ip); /* jump over ip header */ 

     if (iph->ip_p == IPPROTO_TCP) 
     { 
      tcp_header = (struct tcphdr *) buff; 
      buff += sizeof (tcphdr); /* jump over tcp header */ 

      cout << inet_ntoa (iph->ip_src) << ":" << ntohs (tcp_header->th_sport) << 
         " --> " << inet_ntoa(iph->ip_dst) << ":" << ntohs (tcp_header->th_dport) << endl; 

     } 

    } 
} 
  1. 但出事了這裏,源和目的IP地址是一樣的。

  2. 此外,我怎樣才能打印出有效載荷?由於我不能將一個無符號的char數組明確地轉換爲一個char數組,該數組以「\ 0」結尾,可能會出錯。

    192.168.56.1:48065 - > 192.168.56.1:80

    192.168.56.80:80 - > 192.168.56.80:48065

EDIT

- --------------------

THanks to Celeda,我解決了ip地址問題,通過分離ine的調用t_ntoa:

cout << "IP: " << inet_ntoa (iph->ip_src) << ":" << ntohs (tcp_header->th_sport) << 
       " --> "; 
    cout << inet_ntoa(iph->ip_dst) << ":" << ntohs (tcp_header->th_dport) << endl; 

而現在的第二部分中,我使用:

cout << hex << buff << endl;

對於HTTP協議,我沒有看到類似 「GET /」,但有多個空白行什麼

編輯2

--------------------------

我現在不太確定TCP選項,我會檢查更多關於詳細信息的文檔, ,但現在這個功能很好。

if (iph->ip_p == IPPROTO_TCP) 
    { 
     tcp_header = (struct tcphdr *) buff; 
     buff += tcp_header->th_off * 4; 

     cout << "IP: " << inet_ntoa (iph->ip_src) << ":" << ntohs (tcp_header->th_sport) << 
        " --> "; 
     cout << inet_ntoa(iph->ip_dst) << ":" << ntohs (tcp_header->th_dport) << endl; 

     for (int i = 0 ; i < iph->ip_len - iph->ip_off * 4; i ++) 
     { 
      if (isascii (buff[i])) 
      { 
       cout << buff[i]; 
      } 
     } 
     cout << endl << "-----------" << endl; 

    } 
+0

對於第二部分,我不確定,也許'buff'不是指向正確的位置。我看你做了'buff + = sizeof(tcphdr)',但也許有TCP選項需要跳過。我也不知道C++,所以我不確定'hex << buff'實際上做了什麼。但我懷疑它期望一個NUL終止的字符串;我認爲你需要使用一些將長度作爲輸入的函數,因此它不會超出數據包的末尾。 – Celada 2012-01-12 15:50:20

+0

@Celada請參閱「編輯2」 – daisy 2012-01-12 16:07:04

回答

1
  1. inet_ntoa()使用靜態緩衝區。通過調用兩次來覆蓋緩衝區。改爲使用inet_ntop()

  2. 有效負載可能是二進制數據。你想如何打印出來?作爲一個十六進制轉儲或類似的東西?只需查看有效負載,並將這些字節以十六進制格式打印一次,以獲得簡單的十六進制轉儲。或者,如果您確定它是可打印的數據,則可以使用任何函數(如fwrite())將其直接轉儲到輸出,以便指定要寫入的字符串的長度。

編輯附加信息的問題

「額外的字符」你喜歡你試圖解釋爲有效載荷數據TCP選項的HTTP數據的聲音之前看到的。當您將指針跳過buff時,請務必正確計算TCP標頭的大小。它是4個字節* th_off。在使用ip_hl時,您應該對IP標頭執行相同的操作,因爲IP標頭並不總是20個字節。

之後,for循環中的結束條件是錯誤的。首先,ip_off(片段偏移量)不進入,其次,ip_hltcp_off都是以4個字節爲單位測量的,而不是以字節爲單位。

將您的代碼與Wireshark解碼相同數據包的方式進行比較,您將能夠輕鬆診斷出任何進一步的差異。

+0

請參閱我的更新,謝謝! – daisy 2012-01-12 15:33:39