如何解析C/ c++中存储在char buffer中的IP数据包



我有一个存储在字符缓冲区中的IP数据包:

char packet[] = "450000CC68C4000001114C4F0A0A0A0AEFFFFFFADEA9076C00B832074D2D534541524348202A20485454502F312E310D0A484F53543A203233392E3235352E3235352E3235303A313930300D0A4D414E3A2022737364703A646973636F766572220D0A4D583A20310D0A53543A2075726E3A6469616C2D6D756C746973637265656E2D6F72673A736572766963653A6469616C3A310D0A555345522D4147454E543A20476F6F676C65204368726F6D652F3130372E302E353330342E313130204D6163204F5320580D0A0D0A"

我尝试使用netinet/IP .h IP定义解析这个IP头。

但是当我尝试打印ip包的细节,如ip报头长度,它是打印垃圾:

#include <netinet/ip.h>
void decodeIPPacket(const char *packet)
{
struct ip *ipHdr = (struct ip*)(long)packet;

printf("decodeIPPacket:: IP Len: %d", ipHdr->ip_len);
printf("decodeIPPacket:: srcip: %u", ipHdr->ip_src.s_addr);
printf("decodeIPPacket:: dstip: %u", ipHdr->ip_dst.s_addr);
}

decodeIPPacket:: IP Len:12336

decodeIPPacket:: srcip: 808464432

decodeIPPacket:: dstip: 825307440

我做错了什么?

字符串中的每个字符以十六进制表示一个nybble。您需要将每2个char从ASCII转换为十六进制作为字节。

#include <netinet/ip.h>
#include <stdio.h>
#include <string.h>
char string[] =
"450000CC68C4000001114C4F0A0A0A0AEFFFFFFADEA9076C00B832074D2D53454152434820"
"2A20485454502F312E310D0A484F53543A203233392E3235352E3235352E3235303A313930"
"300D0A4D414E3A2022737364703A646973636F766572220D0A4D583A20310D0A53543A2075"
"726E3A6469616C2D6D756C746973637265656E2D6F72673A736572766963653A6469616C3A"
"310D0A555345522D4147454E543A20476F6F676C65204368726F6D652F3130372E302E3533"
"30342E313130204D6163204F5320580D0A0D0A";
int main() {
char *pos = string;
int packetLen = strlen(string) / 2;
unsigned char packet[packetLen];
struct sockaddr_in source, dest;
/* Read only 20 bytes (40 nybbles) 
* to store only IPv4 header.
* NOTE: IPv4 header is not always 
* 20 bytes. Can contain 'options' field.
* You have to extract ihl value first.
*/
for (size_t i = 0; i < 40; ++i) {
sscanf(pos, "%2hhx", &packet[i]);
pos += 2;
}
struct iphdr *iph = (struct iphdr *)packet;
memset(&source, 0, sizeof(source));
source.sin_addr.s_addr = iph->saddr;
memset(&dest, 0, sizeof(dest));
dest.sin_addr.s_addr = iph->daddr;
printf("IP Version: %dn", (unsigned int)iph->version);
printf("IP Header Length: %d Bytesn", ((unsigned int)(iph->ihl)) * 4);
printf("Type Of Service: %dn", (unsigned int)iph->tos);
printf("IP Total Length: %d  Bytes(Size of Packet)n",
ntohs(iph->tot_len));
printf("Identification: %dn", ntohs(iph->id));
printf("TTL: %dn", (unsigned int)iph->ttl);
printf("Protocol: %dn", (unsigned int)iph->protocol);
printf("Checksum: %dn", ntohs(iph->check));
printf("Source Adddress: %.4xn", source.sin_addr);
}

输出:

IP Version: 4
IP Header Length: 20 Bytes
Type Of Service: 0
IP Total Length: 204  Bytes(Size of Packet)
Identification: 26820
TTL: 1
Protocol: 17
Checksum: 19535
Source Adddress: a0a0a0a
Destination Adddress: faffffef

最新更新