2009-11-25 112 views
1

那麼,我正在將數據包直接從網絡中取出並從中提取TCP流。簡而言之,這意味着剝離各種報頭(例如,eth-> IP-> TCP->流數據)。新的沒有分配足夠的內存?

在我終於獲得所有頭文件時調用的函數中,遇到了一個奇怪的錯誤。

/*Meta is a pointer to the IP header, pkt is a pointer to the TCP header*/ 
    virtual const u_char* processPacket(const u_char* pkt, const u_char* meta) { 
     //Extract IP info from meta. 
     iphdr* metaHdr = (iphdr*)meta; 
     //Form TCP header from the current offset, hdr. 
     const tcphdr* hdr = (const tcphdr*)pkt; 

     //Do pointer math to figure out the size of the stream data. 
     u_int32_t len = ntohs(metaHdr->tot_len) - metaHdr->ihl*4 - hdr->doff*4; 
     if(len > 0) 
     { 
      //Store TCP stream data in a queue, mapped to it's IP source. 
      TCPStream* stream = new TCPStream(); 
      stream->seqNumber = ntohl(hdr->seq); 
      stream->streamData = new u_char(len); 
      //memcpy(stream->streamData, offset(pkt), len); 
      for(u_int32_t i = 0; i < len; i++) 
      { 
       printf("k%i-%i",len, i); //Used to figure out when the segfault occurs. 
       stream->streamData[i] = offset(pkt)[i]; //Offset returns a pointer to the data under the TCP header 
      } 

      //streams[metaHdr->saddr].push(stream); 
     } 

     return offset(pkt); 
    }; 

TCP流是一個簡單的u_int32_tu_char*指向數據包的數據的副本。 因此,當我使用memcpy時,它會被隔離。
顯然,無論我的指針是無效的,還是我搞亂了我的長度。

在這個特定的數據包的情況下,數據的長度是1380字節(由Wireshark確認),所以len被正確計算。

好的,所以我必須把我的指針搞亂(但不是NULL)。我做了以下實驗:

stream->streamData[0] = offset(pkt)[0]; //Works 
stream->streamData[0] = offset(pkt)[len]; //Works, odd. 
stream->streamData[len] = offset(pkt)[0]; //Fails, scary 
stream->streamData[len] = offset(pkt)[len]; //Fails 

所以,我提領太遠streamData(指數1236是具體的),當段錯誤! 但streamData被實例化:

stream->streamData = new u_char(len); 

我開始通過streamData在I = 0迭代,所以我不會跳過一堆我的數據。 streamData是u_char*offset(pkt)u_char*所以我不搞亂我的類型。

在成功迭代3000+個其他數據包之後,在特定數據包上失敗。轉儲文件是27 megs,並且我有4個RAM的演出,所以我認爲我沒有耗盡或任何東西...所以我不得不得出結論,新的沒有分配足夠的內存,但爲什麼?

回答

11
stream->streamData = new u_char(len); 

這分配了一個字符,初始化爲len

要分配一個數組,使用:

stream->streamData = new u_char[len]; 

在哪裏,你永遠釋放它:

delete [] stream->streamData; 

編輯:

stream->streamData[len] = offset(pkt)[0]; //Fails, scary 

這將是不確定的行爲,甚至如果數組分配正確。有效索引訪問是0到len不包括

+0

呵呵,一定是學校裏所有的java編程;並且因爲不是len-1而失敗。 笨笨我。 – mamidon 2009-11-25 20:35:31

+0

它的工作原理是,所有數據包都可以成功迭代並在適當的位置剝離其頭部。 – mamidon 2009-11-25 20:36:13

相關問題