我正在使用Windows和ANSI-c,我有一个应用程序从网卡嗅探数据然后解码它并通过UDP发送到其他应用程序。问题是我的应用程序从精细工作开始,但一段时间后它的所有变量int,浮点数和字符串都已损坏我已经多次检查它但无法解决问题。当我直接将数据直接发送到我的IP而不从网络中嗅探数据时,这个应用程序工作得很好。
任何人都可以建议我如何解决这个问题,任何测试工具或其他可以帮助吗?
//method for start sniffing the raw port
void StartSniffing(SOCKET sniffer)
{
unsigned char *Buffer = ( unsigned char *)malloc(65536);
int iPacketLength;
if (Buffer == NULL)
{
printf("malloc() failed.\n");
return;
}//end if
iPacketLength = recvfrom(sniffer,(char *)Buffer,65536,0,0,0);
if(iPacketLength > 0 && iPacketLength <50)
ProcessPacket(Buffer, iPacketLength);
else
printf( "recvfrom() failed.\n");
free(Buffer);
}//end method
//*****************************************************************************************
// method for pecket processing filters udp
void ProcessPacket(unsigned char* Buffer, int Size)
{
char srtPacketSourceIp[16]={'\0'};
char strPacketDestinationIp[16] ={'\0'} ;
strcpy_s(srtPacketSourceIp,inet_ntoa(source.sin_addr));
strcpy_s(strPacketDestinationIp,inet_ntoa(dest.sin_addr));
int a=strcmp(srtPacketSourceIp, strSourceIp );
int b=strcmp(strPacketDestinationIp,strDestinationIp);
iphdr = (IPV4_HDR *)Buffer;
switch (iphdr->ip_protocol) //Check the Protocol and do accordingly...
{
case 1: //ICMP Protocol
//PrintIcmpPacket(Buffer,Size);
break;
case 2: //IGMP Protocol
break;
case 6: //TCP Protocol
//PrintTcpPacket(Buffer,Size);
break;
case 17: //UDP Protocol
++udp;
if(!strcmp(srtPacketSourceIp, strSourceIp )&& !strcmp(strPacketDestinationIp,strDestinationIp))
PrintUdpPacket(Buffer,Size);
break;
default: //Some Other Protocol like ARP etc.
break;
}//end switch
}//end method
//*****************************************************************************************
//method to print ip header for displaing data
void PrintIpHeader (unsigned char* Buffer, int Size)
{
unsigned short iphdrlen;
iphdr = (IPV4_HDR *)Buffer;
iphdrlen = iphdr->ip_header_len*4;
memset(&source, 0, sizeof(source));
source.sin_addr.s_addr = iphdr->ip_srcaddr;
memset(&dest, 0, sizeof(dest));
dest.sin_addr.s_addr = iphdr->ip_destaddr;
/*printf("\n");
printf("IP Header\n");
printf(" |-IP Version : %d\n",(unsigned int)iphdr->ip_version);
printf(" |-IP Header Length : %d DWORDS or %d Bytes\n",(unsigned int)iphdr->ip_header_len);
printf(" |-Type Of Service : %d\n",(unsigned int)iphdr->ip_tos);
printf(" |-IP Total Length : %d Bytes(Size of Packet)\n",ntohs(iphdr->ip_total_length));
printf(" |-Identification : %d\n",ntohs(iphdr->ip_id));
printf(" |-Reserved ZERO Field : %d\n",(unsigned int)iphdr->ip_reserved_zero);
printf(" |-Dont Fragment Field : %d\n",(unsigned int)iphdr->ip_dont_fragment);
printf(" |-More Fragment Field : %d\n",(unsigned int)iphdr->ip_more_fragment);
printf(" |-TTL : %d\n",(unsigned int)iphdr->ip_ttl);
printf(" |-Protocol : %d\n",(unsigned int)iphdr->ip_protocol);
printf(" |-Checksum : %d\n",ntohs(iphdr->ip_checksum));
printf(" |-Source IP : %s\n",inet_ntoa(source.sin_addr));
printf(" |-Destination IP : %s\n",inet_ntoa(dest.sin_addr));*/
}//end method
//*****************************************************************************************
//method to print udp packet for displaying data
void PrintUdpPacket(unsigned char *Buffer,int Size)
{
unsigned short iphdrlen;
iphdr = (IPV4_HDR *)Buffer;
iphdrlen = iphdr->ip_header_len*4;
udpheader = (UDP_HDR *)(Buffer + iphdrlen);
/*printf("\n\n***********************UDP Packet*************************\n");
PrintIpHeader(Buffer,Size);
printf("\nUDP Header\n");
printf(" |-Source Port : %d\n",ntohs(udpheader->source_port));
printf(" |-Destination Port : %d\n",ntohs(udpheader->dest_port));
printf(" |-UDP Length : %d\n",ntohs(udpheader->udp_length));
printf(" |-UDP Checksum : %d\n",ntohs(udpheader->udp_checksum));
printf("\n");
printf("IP Header\n");
PrintData(Buffer,iphdrlen);
printf("UDP Header\n");
PrintData(Buffer+iphdrlen,sizeof(UDP_HDR));
printf("Data Payload\n");
PrintData(Buffer+iphdrlen+sizeof(UDP_HDR),(Size - sizeof(UDP_HDR) - iphdr->ip_header_len*4));*/
memcpy(strRecievedDump,Buffer+iphdrlen+sizeof(UDP_HDR),(Size - sizeof(UDP_HDR) - iphdr->ip_header_len*4));
DumpDecoderAndSender();//this just decodes and sends the data
//printf("\n###########################################################");
}//end method
//*****************************************************************************************
//method to print data
void PrintData (unsigned char* data , int Size)
{
for(int i=0 ; i < Size ; i++)
{
if( i!=0 && i%16==0) //if one line of hex printing is complete...
{
printf(" ");
for(int j=i-16 ; j<i ; j++)
{
if(data[j]>=32 && data[j]<=128)
printf("%c",(unsigned char)data[j]); //if its a number or alphabet
else
printf("."); //otherwise print a dot
}//end for
printf("\n");
}//end if
if(i%16==0)
printf(" ");
printf(" %02X",(unsigned int)data[i]);
if( i==Size-1) //print the last spaces
{
for(int j=0;j<15-i%16;j++)
(" "); //extra spaces
printf(" ");
for(int j=i-i%16 ; j<=i ; j++)
{
if(data[j]>=32 && data[j]<=128)
printf("%c",(unsigned char)data[j]);
else
printf(".");
}//end if
printf("\n");
}//end if
}//end for loop
}//end method
答案 0 :(得分:1)
另一个建议是在内存检查程序下运行程序,例如:的valgrind。
答案 1 :(得分:1)
只需2或3分
你的StartSniffing
函数没有循环,所以我认为每个收到的数据包都会调用它,在这种情况下,为每个调用分配/释放都是浪费。使用堆栈数组或让调用者分配缓冲区一次并将其传递给被调用者。由于锁定,分配可能会很昂贵。
在ProcessPacket
中,您声明了2个初始化的数组,然后填充strcpy
。删除不必要的初始化程序(隐藏memset
次调用)。
然后使用Ip地址比较的结果声明2变量a
和b
,到目前为止一直很好,但是在case 17
中你不使用它们并重新检查strcmp
这不太好。因此,要么重复使用a
和b
vars,要么完全删除它们。
在PrintIpHeader
和其他地方避免这些printf
通话费用。 printf是昂贵的,所以最好只有一个大呼叫而不是10个小呼叫。这是我的意思的一个例子。
printf("IP Header\n"
" |-IP Version : %u\n"
" |-IP Header Length : %u DWORDS or %u Bytes\n" /* 2 %u but only 1 parameter??? */
" |-Type Of Service : %u\n"
" |-IP Total Length : %u Bytes(Size of Packet)\n"
" |-Identification : %u\n"
" |-Reserved ZERO Field : %u\n"
" |-Dont Fragment Field : %u\n"
" |-More Fragment Field : %u\n"
" |-TTL : %d\n"
" |-Protocol : %d\n"
" |-Checksum : %d\n"
" |-Source IP : %s\n"
" |-Destination IP : %s\n", (unsigned int)iphdr->ip_version
, (unsigned int)iphdr->ip_header_len, 9999 /* Added 9999 because the original code was buggy */
, (unsigned int)iphdr->ip_tos
, ntohs(iphdr->ip_total_length)
, ntohs(iphdr->ip_id)
, (unsigned int)iphdr->ip_reserved_zero
, (unsigned int)iphdr->ip_dont_fragment
, (unsigned int)iphdr->ip_more_fragment
, (unsigned int)iphdr->ip_ttl
, (unsigned int)iphdr->ip_protocol
, ntohs(iphdr->ip_checksum)
, inet_ntoa(source.sin_addr)
, inet_ntoa(dest.sin_addr));
请注意,%u
是unsigned int
而不是%d
的格式,而第二个printf中的格式为false。你应该在启用警告的情况下进行编译,gcc会对此发出警告。