2

I have an IP packet stored in a char buffer:

char packet[] = "450000CC68C4000001114C4F0A0A0A0AEFFFFFFADEA9076C00B832074D2D534541524348202A20485454502F312E310D0A484F53543A203233392E3235352E3235352E3235303A313930300D0A4D414E3A2022737364703A646973636F766572220D0A4D583A20310D0A53543A2075726E3A6469616C2D6D756C746973637265656E2D6F72673A736572766963653A6469616C3A310D0A555345522D4147454E543A20476F6F676C65204368726F6D652F3130372E302E353330342E313130204D6163204F5320580D0A0D0A"

I am try to parse this IP header using netinet/ip.h ip definition.

But when i try to print the ip packet details like ip header length, it is printing garbage:

#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

What am i doing wrong here?

2
  • Have you tried converting the characters to their hexadecimal equivalents before assigning to ipHdr? Can you also update your question with what you have tried? Commented Nov 22, 2022 at 19:52
  • I tried below code to convert into hex, but still the output is not correct: const char hexstring[] = "450000....."; const char pos = hexstring; int hexStrLen = strlen(hexstring); unsigned char hex[hexStrLen/2]; for (size_t count = 0; count < sizeof hex/sizeof *hex; count++) { sscanf(pos, "%2hhx", &hex[count]); pos += 2; } ip_header_t ip_header = *(ip_header_t)(hex); // + sizeof(ether_header_t)); cout << "total_length: " << ip_header.total_length << endl; o/p: total_length: 62720 Commented Nov 23, 2022 at 5:42

1 Answer 1

3

Every character in your string represent a nybble in hexadecimal. You need to convert every 2 char from ASCII to hexadecimal as a byte.

#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: %d\n", (unsigned int)iph->version);
    printf("IP Header Length: %d Bytes\n", ((unsigned int)(iph->ihl)) * 4);
    printf("Type Of Service: %d\n", (unsigned int)iph->tos);
    printf("IP Total Length: %d  Bytes(Size of Packet)\n",
           ntohs(iph->tot_len));
    printf("Identification: %d\n", ntohs(iph->id));
    printf("TTL: %d\n", (unsigned int)iph->ttl);
    printf("Protocol: %d\n", (unsigned int)iph->protocol);
    printf("Checksum: %d\n", ntohs(iph->check));
    printf("Source Adddress: %.4x\n", source.sin_addr);
}

Output:

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.