Reputation: 103
I am trying to change a number of integer parameters into bytes and putting them into a byte array. I have most of the required answer but the first 2 bytes in my byte array are different from the required answer. All the if statements in the code are for errors in integer format and the for loop decides how many bytes to allocate to the parameter depending on how big the integer is.
I have tried this on my mac and also Linux computers and I still get the same answer.
def composepacket (version, hdrlen, tosdscp, totallength, identification, flags, fragmentoffset, timetolive, protocoltype, headerchecksum, sourceaddress, destinationaddress):
if version != 4:
return 1
elif hdrlen < 0 or hdrlen > 15:
return 2
elif tosdscp < 0 or tosdscp > 63:
return 3
elif totallength < 0 or totallength > 65535:
return 4
elif identification < 0 or identification > 65535:
return 5
elif flags < 0 or flags > 7:
return 6
elif fragmentoffset < 0 or fragmentoffset > 8191:
return 7
elif timetolive < 0 or timetolive > 255:
return 8
elif protocoltype < 0 or protocoltype > 255:
return 9
elif headerchecksum < 0 or headerchecksum > 65535:
return 10
elif sourceaddress < 0 or sourceaddress > 4294967295:
return 11
elif destinationaddress < 0 or destinationaddress > 4294967295:
return 12
else:
list1 = [version,hdrlen,tosdscp,totallength,identification,flags,fragmentoffset,timetolive,protocoltype,headerchecksum,sourceaddress,destinationaddress]
final = bytearray()
for element in list1:
if element <= 255:
x = element.to_bytes(1,byteorder='big')
final += x
elif element <= 65535:
x = element.to_bytes(2,byteorder='big')
final += x
elif element <= 16777215:
x = element.to_bytes(3,byteorder='big')
final += x
elif element <= 4294967295:
x = element.to_bytes(4,byteorder='big')
final += x
return final
the test line is
print(composepacket(4,5,0,1500,24200,0,63,22,6,4711, 2190815565, 3232270145))
The expected answer is
bytearray(b'E\x00\x05\xdc^\x88\x00?\x16\x06\x12g\x82\x951M\xc0\xa8\x87A')
and the answer I get is
bytearray(b'\x04\x05\x00\x05\xdc^\x88\x00?\x16\x06\x12g\x82\x951M\xc0\xa8\x87A')
so the difference is the first two bytes where i get b'\x04\x05 where i should get b'E
Upvotes: 0
Views: 508
Reputation: 1378
It looks like you're working on building out a IPv4 packet header (you should've mentioned this in your question, assuming you know this to be the case).
Your logic currently takes the version
and appends it to your byte array as a whole byte (8 bits), but it should only occupy the first 4 bits (or 1 nibble).
You're likely expecting the first byte to be "E" because 0b0100_0101
(that is, 4 represented as 4 bits
followed by 5 represented as 4 bits
, as shown in the diagram below) is 69 in decimal, which is the ASCII character for "E". So, if you were to run strings
or hexdump
on a TCPv4 packet, you might see "E" as the first character. However, the first byte should actually be 0x45
, so you're confusing the representations of the initial byte.
Your code isn't quite right because it's treating the version
and hdrlen
as two separate bytes when they should be in the same byte as two separate nibbles.
So, you want something like:
first_byte = version << 4 | length
This should give you enough direction. Best of luck.
Upvotes: 2