2009-11-25 3 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_t 패킷의 데이터의 복사본을 가리키는 u_char*이다. 그래서 memcpy를 사용할 때 segfault가 발생했습니다.
명백히 내 포인터가 유효하지 않거나 내 길이가 엉망이되었습니다.

이 특정 패킷의 경우 데이터의 길이는 1380 바이트 (Wireshark에 의해 확인 됨)이므로 len이 올바르게 계산됩니다.

그래, 내 포인터가 엉망이되어야하지만 (NULL은 아님). streamData (인덱스 1236 구체적하기 위해)에 너무 멀리 역 참조 때, 나는 세그 폴트

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는 다음과 같이 인스턴스화 : I는 I = 0 streamData을 반복 시작, 그래서 난 내 데이터의 무리를 건너 뛰는 아니에요

stream->streamData = new u_char(len); 

. streamData는 u_char*이고 offset(pkt)u_char*이므로 내 유형을 망칠 필요가 없습니다.

3000 + 다른 패킷을 성공적으로 반복 한 후 특정 패킷에서 실패합니다. 덤프 파일은 27 메가이고, 4 기가 바이트의 램이있어서, 나는 아무것도 빠지지 않는다고 생각하지 않는다. 그래서 나는 새로운 것이 충분한 메모리를 할당하지 않는다는 결론을 내릴 수밖에 없다. ?

답변

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

duh는 반드시 학교에서 자바 프로그래밍을해야합니다. 그리고 len-1''ll를 위해 나를 실패한다. 바보 같은 날. – mamidon

+0

그리고 작동합니다. 모든 패킷이 성공적으로 반복되고 헤더가 제거됩니다. – mamidon

관련 문제