Re: scapy - feedback
Sean Van Gorder <sean.van.gorder <at> gmail.com>
2010-11-09 22:45:55 GMT
I had time to really read through this today, so here's a more detailed
response.
> -> Offsets
>
> Actually I want to get Value_A and Value_B, but the 'value' of both is
> 'hidden' in "Data", at a specific offset with a length and there is
> even some padding data of unspecified length in there.
I just added OffsetPacketListField to the community repository, it takes a
list of tuples containing the name of the field with the offset and the data
structure (layer class) at that offset. Any data outside of the defined
packets is included in the list as Raw packets. It doesn't support a length
value yet, though.
You can pull the latest community-contributed code from
http://hg.secdev.org/scapy-com/
> -> Size ...
> Due to the liberal use of relative offsets as well as implicit and
> explicit padding, getting the length of a Field or Packet was required
> in many situations, I ended up adding Packet.size() and Field.size().
len(pkt) gives you the size of a packet, and fields have the i2len method.
Also, I came up with Packet.getfieldlen("field") for convenience, it uses
i2len on the value stored in the packet. That's in the community repository.
> For fields, I've had problems with Field definition consistency,
> class TestPacket(Packet):
> name="Test Packet"
> fields_desc= [
> BitField("Reserved",0x00,7),
> BitField("Length",0,17)
> ]
> length of this Packet should be 3 bytes, but I got 4 bytes initally,
> so now I count the bitlength, divide by 8, and round. As the total of
> all BitFields in a layer is likely a multiple of eight, this gives
> proper integers as a result.
I fixed that in the community repository, BitField.i2len now returns a float.
> It would have been great if there was a documented way to use h2i and
> friends to convert the input data to defined valid data types for
> i/m/h, to catch type & content errors in time.
Basically you want to separate them out like:
h = human = the clearest/easiest way for the user to input data
i = internal = the most convenient way to store the data for editing
m = machine = the data in byte string form (with minimal extra processing)
Usually i and h are the same thing and you can ignore h2i and i2h. Special
processing/encoding/etc. goes in the addfield/getfield, for example adding
the null byte at the end of StrNullField, or the way bits in consecutive
BitFields are combined. The line between those and i2m/m2i isn't really well-
defined, subclasses tend to inherit one and do their thing in the other based
on convenience.
> x.foobar = "special value"
> I forgot the \0, it is not a valid *NullField any longer.
> I could look for a \0 or \0\0 in case of unicode in addfield and add
> if not required, *but* then len(self.foobar) is off by one, as it
> misses the terminating \0, for unicode it would be off-by-two.
If you want the length of the field as it will appear over the wire, you need
to use Field.i2len(value) or Packet.getfieldlen("field"). When you access the
field value directly, you're getting the "h" or "i" form of the data, which
can't be guaranteed to be the same length as the final byte stream.
> Content error, the string is not null terminated in internal storage.
> Of course a proper h2i for StrNullField would have solved this, but
> obviously thats not 'the default'.
>
> I'm about to fix this for all basic Fields I use, once I got an
> overview which parts of the logic are affected by the changes - I got
> burned by this more than once.
This shouldn't be necessary, following what I said above.
---------------------------------------------------------------------
To unsubscribe, send a mail to scapy.ml-unsubscribe <at> secdev.org