Ok this is so new to me but does anyone have example code that decodes header fields in an IP datagram? or a link to something like the beej's guide....So i need to decode the header from the following example.

0000000 141724 120662 000002 000004 000000 000000 000000 000000
0000020 177777 000000 000001 000000 142167 045720 175323 000001
0000040 000146 000000 000146 000000 010000 177733 120040 006000
0000060 134051 122150 000010 010105 054000 153336 000100 003100
0000100 111425 022620 046250 125514 004701 013000 042602 044146
0000120 164312 036636 030340 014120 010070 161701 000000 025433
0000140 050532 067325 046066 000014 121441 144064 051477 073361
0000160 045065 020626 162237 062362 020070 067610 030756 074707
0000200 026372 140127 177576 051622 063626 106116 172414
0000216

I think this is way too complicated for an intro to networking class....
I was thinking of using a union but I don't know!!! help!!!

Recommended Answers

All 14 Replies

that was a bit helpful, but if anyone else has some other links or example code, please let me know.

if you think decoding an IP header in your intro to networking class is hard, you're in for a rough time.

you need to become intimate with RFC 791. pay special attention to section 3, "specification"

okay, i'm suspicious about this example IP header. for instance, the first octet is supposed to contain the IP version (either 4 or 6) and the IP header length (at least 5, but probably not more than 8 or 10 or so...)

i dont see what appears to be a valid first octet anywhere in this code. I dont see what looks to be a "typical" valid IP destination or IP source address either, although this could be made up to be something unusual. i would have to see more about the assignment to understand if your instructor has constructed this IP packet in some sort of unusual manner, because it doesn't make much sense to me.

if you want to see what i'm seeing compile this code to convert the octal packet to a hexadecimal packet. if anything this will get you started.

/* This code is 'quick and dirty' and performs ZERO error checking.
   It is not suitable for commercial or academic use.  
   it is only supplied here as a concept example  */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
    FILE *fp;
    char string[80], *ptr, *doubleOctet;
    int do_val;
       
    fp = fopen(argv[1], "r");
    
    while((fgets(string, sizeof(string), fp)) != NULL)
    {
        doubleOctet = strtok(string, " ");
        printf("0x0000");
        do {
            do_val = strtol(doubleOctet, &ptr, 8);
            printf("%04X ", do_val);
        } while ((doubleOctet = strtok(NULL, " ")) != NULL);
        printf("\n");
    }
    
    fclose(fp);
       
    return 0;    
}

I compile the code using gcc, then run the code by passing in the file name of your example ip packet as an argument:

jephthah$ gcc -o ipdecode ipdecode.c
jephthah$ ./ipdecode ipexample.txt
0x00000000 C3D4 A1B2 0002 0004 0000 0000 0000 0000 
0x00000010 FFFF 0000 0001 0000 C477 4BD0 FAD3 0001 
0x00000020 0066 0000 0066 0000 1000 FFDB A020 0C00 
0x00000030 B829 A468 0008 1045 5800 D6DE 0040 0640 
0x00000040 9315 2590 4CA8 AB4C 09C1 1600 4582 4866 
0x00000050 E8CA 3D9E 30E0 1850 1038 E3C1 0000 2B1B 
0x00000060 515A 6ED5 4C36 000C A321 C834 533F 76F1 
0x00000070 4A35 2196 E49F 64F2 2038 6F88 31EE 79C7 
0x00000080 2CFA C057 FF7E 5392 6796 8C4E F50C 
0x0000008E

K well think I got something down that kinda works...well it at least gives me the correct version number. I just need to
* display the IP source and destination addresses in dotted decimal format.
* display each integer header filed as a decimal value. Use ntohs or an equivalent function to convert the field from network byte order to the local byte order.
* identify individual bits of the FLAGS field.
* display the name of the protocol that was used to create the payload (e.g. TCP or ICMP, ...).
* Compute and display the size of the payload carried in the datagram.

Im sure I need to read the file into a buffer and then find the index where the header starts and do something to it...Please help. This is what the file contains
0000000 141724 120662 000002 000004 000000 000000 000000 000000
0000020 177777 000000 000001 000000 142167 045720 175323 000001
0000040 000146 000000 000146 000000 010000 177733 120040 006000
0000060 134051 122150 000010 010105 054000 153336 000100 003100
0000100 111425 022620 046250 125514 004701 013000 042602 044146
0000120 164312 036636 030340 014120 010070 161701 000000 025433
0000140 050532 067325 046066 000014 121441 144064 051477 073361
0000160 045065 020626 162237 062362 020070 067610 030756 074707
0000200 026372 140127 177576 051622 063626 106116 172414
0000216

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

typedef unsigned long UINT32;

typedef struct ipv4_hdr_f1 {
    UINT32 ver   : 4; //Ip version
    UINT32 iphl  : 4; //Internet Header Length
    UINT32 tos   : 8; //Type Of Service
    UINT32 len   : 16; //Total Length
} IPV4_HDR_F1;

typedef struct ipv4_hdr_f2 {
    UINT32 ident : 16; //Identification
    UINT32 flags : 3; //Flags
    UINT32 offset: 13; //Fragment Offset:
} IPV4_HDR_F2; 

typedef struct ipv4_hdr_f3 {
    UINT32 ttl   : 8; //Time To Live
    UINT32 proto : 8; //Protocol
    UINT32 cksum : 16; //checksum
} IPV4_HDR_F3;

typedef struct ipv4_header {
    IPV4_HDR_F1	f1; 
    IPV4_HDR_F2	f2;
    IPV4_HDR_F3 f3;
    UINT32 src; //Source Address
    UINT32 dest; //Destination Address
} IPV4_HEADER;


int main(int argc, char *argv[])
{

    IPV4_HEADER  ipv4_hdr; //Declares a struct of type IPV4_HEADER

    int fd; //file name
    int  nbytes; //Count number of bytes 

    if (argc != 2) {
       printf("Usage: %s <filename> \n", argv[0]);
       exit(-1);
    }

    fd = open(argv[1], O_RDONLY, 0664);
    if (fd == -1) {
       perror("open error");
       exit(-1);
    }

    nbytes = read(fd, (void*)&ipv4_hdr, sizeof(IPV4_HEADER)); //will count the number of bytes in the file
    if (nbytes == -1) {
        perror("read error");
        exit(-1);
    }

/// The Following will print out the translated datagram 
    printf("Version          : %d \n", ipv4_hdr.f1.ver);
    printf("IP Header Length : %d \n", ipv4_hdr.f1.iphl);
    printf("Type of Service  : %d \n", ipv4_hdr.f1.tos);
    printf("Size             : %d \n", ipv4_hdr.f1.len);
    printf("Identification   : %d \n", ipv4_hdr.f2.ident);
    printf("Flags            : %x \n", ipv4_hdr.f2.flags);
    printf("Offset           : %d \n", ipv4_hdr.f2.offset);
    printf("TTL              : %d \n", ipv4_hdr.f3.ttl);
    printf("Protocol         : %d \n", ipv4_hdr.f3.proto);
    printf("Check Sum        : %x \n", ipv4_hdr.f3.cksum);
    printf("Source IP Addr   : %x \n", ipv4_hdr.src);
    printf("Dest IP Addr     : %x \n", ipv4_hdr.dest);

    return(0);

}

so am i missing something? it's been 2 1/2 years since i worked with network packets.

can you tell me how are the first two octets (0xC3D4) being read?


.

the file is in binary so im guessing binary

that's not what i mean. i mean, where are you getting the version 4 (IPv4) and the Header Length info that is supposed to be in the first octet, according to the specification? i'm not quite seeing where this info is contained.

okay, i think i missed somethign... you have to "Use ntohs or an equivalent function to convert the field from network byte order to the local byte order." this will probably solve my confusion. this will also be a key element of your assignment. you're expected to use the library functions not hand-crafted conversion routines.

.

well the log file is already in host to network order, so I need to read the binary file and parse it. Im not sure what you are asking, but I think there is another way of doing it. I can read the file then seek to 54 then read it into a buffer then do a bit shift like so

iphead.ip_ver=buffer>>28; // where iphead is a struct

but I dont know how to...and I need to by the end of today.

i dont think so.

Note that the first group of octal numbers converts to the hex value 0xC3D4. in other words, your first two octets (8-bit values) are 0xC3 and 0xD4

if it were in the proper order, the very first octet would correctly indicate that the IP Version is "4" (or "6") those are the only possibilites. your packet says the IP Version is "C" (ie, 12). furthermore, the minimum valid IHL is 5. in your example the IHL is "3". both of these are invalid.

now look at the IP specification, and see for yourself how this does not make sense:

Internet Protocol

                           3.  SPECIFICATION

3.1.  Internet Header Format

  A summary of the contents of the internet header follows:

    0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |Version|  IHL  |Type of Service|          Total Length         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Identification        |Flags|      Fragment Offset    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Time to Live |    Protocol   |         Header Checksum       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                       Source Address                          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Destination Address                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                    Example Internet Datagram Header

oh...according to the professors email since he used tcpdump on the same
host as where were running the program I don't need to use the
hton functions (host to network order). So, just read the binary file and parse as is.

yeah, a non sequiter,... but ok, wat ever

@R3Slick : your program was really helpful.
I have a doubt though. What does "UINT32 ver : 4" mean. Ok,it specifies the no. of bits.
But,can we actually write something like "int a : 4" ??

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.