0

I've been more than a day trying to solve this one. I need to create a IP Packet in Python, but the length of the fields are different. Every time I have a field bigger than 1 byte I need to change the byte order to big endian. So what I did was to pack each variable separately and save everything in a file. I'm saving in a file because I need to do the checksum after packing and then pack all over again with the checksum (If someone has a better idea is more than welcome).

I'm having two problems:

1) The packet that I generate is bigger than the original one from were I parsed the information (the IP packet I generate only change in one field that is the TTL, but it should remain the same size)

2) When I parse my packet (stream of data in the file), some information has change (I didn't change it).

This is the original packet information:

Ver: 4
HL: 12
TOS: 0
LEN: 50
ID= 456
OFF: 16384
TTL: 5
PROT: 6
CHSUM: 30512
SRC: 16885952
DST: 167880896
rem_head: ['Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q']
data: ['A', 'A']

This result is from parsing the packet. Then I verify the check sum and decrease the TTL by one and reassemble the packet like this:

pk_cksum=0x0000
arch= open('packet.out', 'w')
arch.write( struct.pack('B',byte) )
arch.write( struct.pack('>B', pk_tos) )
arch.write( struct.pack('>H', pk_len) )
arch.write( struct.pack('>H', pk_id) )
arch.write( struct.pack('>H',pk_off) )
arch.write( struct.pack('B', pk_ttl) )
arch.write( struct.pack('B', pk_p) )
arch.write( struct.pack('>H', pk_cksum) )
arch.write( struct.pack('<I', pk_src) )
arch.write( struct.pack('<I', pk_dst) )
if (pk_hl>5):
    for i in range(len(pk_head)):
        arch.write(struct.pack('c', pk_head[i])[0])
if (pk_len>(pk_hl*4)):
    for j in range(len(pk_data)):
        arch.write(struct.pack('c', pk_data[j])[0])
arch.close()

To verify if the packing was successful I use my same code to parse this last packet and then I get this information:

Ver: 4
HL: 12
TOS: 0
LEN: 50
ID= 456
OFF: 16384
TTL: 4
PROT: 6
CHSUM: 0
SRC: 16885952
DST: 218212544  1101 0000 0001 1010 1000 1100 0000
rem_head: ['\n', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q']
data: ['Q', 'A']

As you see, the destination address changed and I have a '\n' in the head, but my original variable doesn't have And the data have a Q that not suppose to have.

Can someone tell me what I'm doing wrong?

Thanks

Dan Lecocq
  • 3,383
  • 25
  • 22
rocco
  • 25
  • 7
  • FWIW, consider getting in the habit of using files as a context manager (http://docs.python.org/release/2.5/whatsnew/pep-343.html) – Dan Lecocq May 09 '13 at 21:48
  • Although the details of your checksum aren't here, you can probably use `cStringIO` which implements a sort-of-file-like-in-memory buffer – Dan Lecocq May 09 '13 at 21:49
  • I think it will be important to see some of the details of how you're reading this packed data back in, but it _looks_ like you've got an offset issue (especially since on of the 'Q's has overflowed into data). – Dan Lecocq May 09 '13 at 22:24
  • @da.lecocq- I change the code as you suggested.... "with open('packet.out', 'w') as arch:".... but I still have the same problem. I have to use Python 2.4 so I'm using the checksum from this link....http://stackoverflow.com/questions/1767910/checksum-udp-calculation-python – rocco May 09 '13 at 22:27
  • Yeah, the `with` syntax isn't going to solve this problem, but it's a _good habit_ to get into :-) Looking at that checksum method, I don't think there's any reason that you have to write it all out to a file. If you want to hop on 'chat' we can probably get this solved more quickly – Dan Lecocq May 09 '13 at 22:30
  • I found the problem! I had to open the file as binary, that's why I was having an '\n' after some amount of data. Found the answer here http://stackoverflow.com/questions/9184107/python-file-write-new-line – rocco May 09 '13 at 22:39
  • Ah. I feel like I should have thought of that :-) Glad you found the issue, though! – Dan Lecocq May 09 '13 at 22:40
  • @da.lecocq-how can we chat? – rocco May 09 '13 at 22:51
  • There's a 'chat' feature to SO, but I guess there's a reputation limit. I'm about to head home, but maybe it would be easiest if you copied your code to a [gist](http://gist.github.com) or a [colaborative editing site](https://etherpad.mozilla.org/) so we can both take a look. – Dan Lecocq May 09 '13 at 22:54

0 Answers0