Question

I have a C++ code that generates an IP Packet Header. The code use a struct representing each field in the packet:

struct cip {
   uint8_t        ip_hl:4, /* both fields are 4 bytes */
                  ip_v:4;
   uint8_t        ip_tos;
   uint16_t       ip_len;
   uint16_t       ip_id;
   uint16_t       ip_off;
   uint8_t        ip_ttl;
   uint8_t        ip_p;
   uint16_t       ip_sum;
   struct in_addr ip_src;
   struct in_addr ip_dst;
   char       head[100];
};

The user is prompt an input message to enter the values for each variable in the struct:

Enter the filename to save the packet: packet

Enter IP version(0-15): 4

Enter Header Length(5-15): 5

Enter type of service(0-255): 55

Enter packet total size(bytes, 20, 200): 25

The packet is created and saved in a file:

FILE* f = fopen(file, "w");
int success = fwrite(&packet, sizeof(char), ((unsigned int)packet.ip_hl)*4,f);
if(success <= 0) {
    printf("Error writing packet header");
}
success = fwrite(&data, sizeof(char),ntohs(packet.ip_len)-(4*packet.ip_hl),f);
if(success < 0) {
    printf("Error writing packet data");
}
fflush(f);
fclose(f);
printf("\nPacket Written.\n");

I didn't create this code, someone gave me the code so I can create other program in Python that will validate the packet created by the program above. The validation includes verifying the checksum generated for the packet, the version of the Ip Packet, protocol, length of header and so on.

So I will like to know if someone can help me figuring out how can I read the file and parse the frame. I tried to read the line in the file as a string, but the problem I'm having is that the file looks like this after the creation: (it is unreadable)

O È ,@ šÀ¨À¨ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxDATA_______________________DATA____________ ô·

I don't understand why: (I'm guessing that this is because the variables bigger than 1 byte are converted to big endian by the function "htons":

printf("\nEnter ip ID number(0-65535):\n");
scanf("%d", &input);
packet.ip_id = htons(input);

I tried to search for another option as dealing this with socket.makefile(), but this will help me the socket in my program as a file, but what I need to do is parse the frame gave to me in this file.

Any ideas?

Thanks.

P.S.: Also can someone give me a link where I can find how to convert integer from big endian to small endian and vicerversa in Python. Thanks!

Was it helpful?

Solution

You should read file as usual (specifying "binary" mode for Windows):

with open("test.txt", 'br') as f:
    for line in f.readlines():
        # process lines

To unpack binary data you should use struct package, which can also handle big and little endian and so on. Example for your struct:

print struct.unpack('BBHHHBBH100s', line)

I omitted ip_src and ip_dst unpacking since you didn't specify the contents of their struct. The least possible value to read is one byte, so to split first field into two parts you can use:

(ip_hl, ip_v) = (value >> 4, value & 15)

Of course, the order of 8-bit component depends on your struct endianess.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top