0

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=0
    arch= open('packet.out', 'w')
    arch.write( struct.pack('B',frstb) )
    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: 0
TOS: 0
LEN: 50
ID= 456
OFF: 16384
TTL: 4
PROT: 6
CHSUM: 0
SRC: 3232235777
DST: 2818640397
data: ['@', '\x00', '\x00', '2', '\x01', '\xc8', '@', '\x00', '\x04', '\x06', '\x00', '\x00', '\x01', '\x01', '\xa8', '\xc0', '\r', '\n', '\x01', '\xa8', '\xc0', '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', 'A']

As you see, some of the variables have another value and I don't know why.

Can someone tell me what I'm doing wrong?

Thanks

2
  • 1
    the compiler says its wrong isn't a very good description of your problem. What did you expect it to do? What is it currently doing? (Also not that python is not compiled) Commented May 9, 2013 at 0:52
  • Do you mean bit-order or byte-order. "endianess" is usually used to describe the latter. If the field lengths vary, you can just use a different format string calculated on-the-fly. An optional first letter of the format string can be used to specify the byte endianess desired, the default is native (see the docs). Commented May 9, 2013 at 1:04

1 Answer 1

1

You can control the endianess by prefixing the format string with "<"(little) or ">"(big)

Sign up to request clarification or add additional context in comments.

8 Comments

Compiler error: new_packet=struct.pack('B!H!H!HBB!H!I!I',frstb,pk_tos,pk_len,pk_id,pk_off,pk_ttl,pk_p,pk_cksum,pk_src,pk_dst,pk_head, pk_data ) struct.error: bad char in struct format
martineau I need to covert the fields greater than 1 byte from little endian to big endian and then pack them. Could you explain what is on-the-fly for variable length fields?
gnibble, yes I know the "<"(little) or ">"(big), but where should I put them? before the type of data of each variable as I put the "!"? Because only some variables mas be converted to big endian, not the whole stream.
@rocco, "prefixing" means the first character. You can't change endian midway. You'll have to break it up in to multiple chunks. What type of sadist switches endian part way through?
@gnibber... answering your question, the one that created the packet in the beginning. I have to reassemble a packet generated in C. This person used htons() function in some variables before packing. To create the new packet (after some validations) I have to do the same thing he did in Python.
|

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.