0

I have a binary file where a IP Packet was written. I have to create a Python program that has to validate each field in the IP Packet, so I'm trying to parse each field form the file (Ip Packet). The problem that I have is there are two fields that are 4 bits long (the first 2 fields of the packet), but the smallest data I can unpack (struct.pack) is 1 byte. So I was trying to bit-mask the bits to extract them form the packet, but I have an error indicating that the flow of bits that are have is considered as a string and the AND operation that I'm doing with the bitmask is with integer. Does someone has a clue of how two extract the first and second 4-bits words from a long string of bits?

This is my code so far:

while True:
        try:
            filename=raw_input('Enter the name of the file where the packet is: ')
            break
        except EOFError as e:
            pass
            print "You didn't enter a valid file name"
    #Reading packet from file and converting to little endian accordingly
     with open(filename, 'rb') as f:
        for line in f.readlines():
            mask1=0b1111
            mask2=0b00001111
            bit_hl=line & mask1
            bit_v= line & mask2

            pk_hl= struct.unpack('@B', bit_hl) #ip_hl
            print('\n',pk_hl)
            pk_v = struct.unpack('@B', bit_v)  #ip_v
            print('\n',pk_v)

....

The packet is generated from a C++ program and the structure of the packet is:

struct cip {
   uint8_t        ip_hl:4, /* both fields are 4 bits */
                  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];
};

Thank you.

rocco
  • 25
  • 7

1 Answers1

0

You might try a bytearray:

mask1=0b11110000
mask2=0b00001111
with open(filename, 'rb') as fh:
    ba = bytearray(fh.readline())
    byte=ba[0]
    print byte & mask1    # might be 'print ord(byte & mask1)'...
    print byte & mask2

Also, you your mask1=0b1111 and mask2=0b00001111 are really the same value. I think you meant to use mask1=0b11110000 and mask2=0b00001111

dawg
  • 98,345
  • 23
  • 131
  • 206
  • Thanks drewk. But the file has already binary information if I convert it to binary (strings to bytes) wouldn't be converting the characters 1's or 0's in binary and my data w0n't be accurate. It's what bytearray() I understand does, "If it is a string, you must also give the encoding (and optionally, errors) parameters; bytearray() then converts the string to bytes using str.encode()." – rocco May 07 '13 at 03:05
  • Drewk. I'm testing your code, but I'm getting other data that is not accurate. I suppose to have he number 4 for the first AND and I'm having 64 or '6' and '4'. Any ideas?...pk_ver=byte & mask1 print 'Ver:',pk_ver pk_hl=byte & mask2 print 'HL:',pk_hl................Ver: 64 – rocco May 07 '13 at 03:43
  • Your IP HV might then be `(byte & 0b11110000) >> 4` to turn the high nibble into the low nibble. – dawg May 07 '13 at 17:00