Bit Fields
So far we saw how to pack/unpack bytes. It is time to go one level deeper and work with bits:
>>> from bisturi.packet import Packet
>>> from bisturi.field import Bits, Int
>>>
>>> class BitsExample(Packet):
... fragment_offset = Bits(12)
... flags = Bits(4)
The Bits
field, as its name suggests, handles a fixed amount of bits
and see them as integers.
In this example, 16 bits are required: 12 bits for fragment_offset
and 4 more bits for flags
.
>>> s = b'\x00\x12' # which in binary is 0000 0000 0001 0002
>>> p = BitsExample.unpack(s)
>>>
>>> p.fragment_offset # 'Bits' work with integers like 'Int'
1
>>> p.flags
2
>>> q = BitsExample(fragment_offset=1) # you can set a default as usual
>>> q.flags = 2
>>> q.pack() == s
True
The bytes under the bits
The use of Bits
has an extra requirement: you can use 1 or more Bits
fields
but they must be consecutive and the sum of the bits must be
multiple of 8.
This is because under the hood bisturi
works at the byte level and
Bits
are a front end, an abstraction on top of them.
The following are some bad examples that should illustrate the possible errors:
>>> # this is wrong because the sum is not multiple of 8
>>> class WrongUse(Packet):
... fragment_offset = Bits(12)
... flags = Bits(1) # 12 + 1 = 13 (not a multiple of 8)
<...>
<...>ByteBoundaryError: Wrong sequence of bits: [12, 1] with total sum of 13 (not a multiple of 8).
>>> # this is wrong because the fields are not consecutive
>>> class WrongUse(Packet):
... fragment_offset = Bits(9)
... flags1 = Bits(4) # bad, because 9 + 4 is not a multiple of 8
... i = Int()
... flags3 = Bits(3) # yes, 12 + 1 + 3 is multiple of 8, but they are not contiguous.
<...>
<...>ByteBoundaryError: Wrong sequence of bits: [9, 4] with total sum of 13 (not a multiple of 8).
This however is a good example:
>>> # this is fine, consecutive bits sum a multiple of 8
>>> class GoodUse(Packet):
... fragment_offset = Bits(12)
... flags1 = Bits(4) # good because 12 + 4 is a multiple of 8
... i = Int()
... flags3 = Bits(4)
... flags4 = Bits(4) # good because 4 + 4 is a multiple of 8