Skip to content
Snippets Groups Projects
Commit 75e2ad5c authored by Guillaume Valadon's avatar Guillaume Valadon Committed by GitHub
Browse files

Merge pull request #589 from thmsaurel/docs

add internal doc & reform binding layers
parents 194df89e c82fa7f5
No related branches found
No related tags found
No related merge requests found
...@@ -387,7 +387,14 @@ Binding layers ...@@ -387,7 +387,14 @@ Binding layers
One of the cool features with Scapy when dissecting layers is that is One of the cool features with Scapy when dissecting layers is that is
try to guess for us what the next layer is. The official way to link 2 try to guess for us what the next layer is. The official way to link 2
layers is using ``bind_layers()``: layers is using ``bind_layers()`` function.
Available inside the ``packet`` module, this function can be used as following::
bind_layers(ProtoA, ProtoB, FieldToBind=Value)
Each time a packet ``ProtoA()/ProtoB()`` will be created, the ``FieldToBind`` of
``ProtoA`` will be equal to ``Value``.
For instance, if you have a class ``HTTP``, you may expect that all the For instance, if you have a class ``HTTP``, you may expect that all the
packets coming from or going to port 80 will be decoded as such. This packets coming from or going to port 80 will be decoded as such. This
......
...@@ -131,9 +131,15 @@ class Packet(BasePacket): ...@@ -131,9 +131,15 @@ class Packet(BasePacket):
self.post_transforms = [post_transform] self.post_transforms = [post_transform]
def init_fields(self): def init_fields(self):
"""
Initialize each fields of the fields_desc dict
"""
self.do_init_fields(self.fields_desc) self.do_init_fields(self.fields_desc)
def do_init_fields(self, flist): def do_init_fields(self, flist):
"""
Initialize each fields of the fields_desc dict
"""
for f in flist: for f in flist:
self.default_fields[f.name] = copy.deepcopy(f.default) self.default_fields[f.name] = copy.deepcopy(f.default)
self.fieldtype[f.name] = f self.fieldtype[f.name] = f
...@@ -340,6 +346,11 @@ class Packet(BasePacket): ...@@ -340,6 +346,11 @@ class Packet(BasePacket):
return {fname: self.copy_field_value(fname, fval) return {fname: self.copy_field_value(fname, fval)
for fname, fval in fields.iteritems()} for fname, fval in fields.iteritems()}
def self_build(self, field_pos_list=None): def self_build(self, field_pos_list=None):
"""
Create the default layer regarding fields_desc dict
:param field_pos_list:
"""
if self.raw_packet_cache is not None: if self.raw_packet_cache is not None:
for fname, fval in self.raw_packet_cache_fields.iteritems(): for fname, fval in self.raw_packet_cache_fields.iteritems():
if self.getfieldval(fname) != fval: if self.getfieldval(fname) != fval:
...@@ -361,9 +372,19 @@ class Packet(BasePacket): ...@@ -361,9 +372,19 @@ class Packet(BasePacket):
return p return p
def do_build_payload(self): def do_build_payload(self):
"""
Create the default version of the payload layer
:return: a string of payload layer
"""
return self.payload.do_build() return self.payload.do_build()
def do_build(self): def do_build(self):
"""
Create the default version of the layer
:return: a string of the packet with the payload
"""
if not self.explicit: if not self.explicit:
self = self.__iter__().next() self = self.__iter__().next()
pkt = self.self_build() pkt = self.self_build()
...@@ -379,13 +400,24 @@ class Packet(BasePacket): ...@@ -379,13 +400,24 @@ class Packet(BasePacket):
return self.payload.build_padding() return self.payload.build_padding()
def build(self): def build(self):
"""
Create the current layer
:return: string of the packet with the payload
"""
p = self.do_build() p = self.do_build()
p += self.build_padding() p += self.build_padding()
p = self.build_done(p) p = self.build_done(p)
return p return p
def post_build(self, pkt, pay): def post_build(self, pkt, pay):
"""DEV: called right after the current layer is build.""" """
DEV: called right after the current layer is build.
:param str pkt: the current packet (build by self_buil function)
:param str pay: the packet payload (build by do_build_payload function)
:return: a string of the packet with the payload
"""
return pkt+pay return pkt+pay
def build_done(self, p): def build_done(self, p):
...@@ -425,8 +457,14 @@ class Packet(BasePacket): ...@@ -425,8 +457,14 @@ class Packet(BasePacket):
def psdump(self, filename=None, **kargs): def psdump(self, filename=None, **kargs):
"""psdump(filename=None, layer_shift=0, rebuild=1) """
Creates an EPS file describing a packet. If filename is not provided a temporary file is created and gs is called.""" psdump(filename=None, layer_shift=0, rebuild=1)
Creates an EPS file describing a packet. If filename is not provided a
temporary file is created and gs is called.
:param filename: the file's filename
"""
canvas = self.canvas_dump(**kargs) canvas = self.canvas_dump(**kargs)
if filename is None: if filename is None:
fname = get_temp_file(autoext=".eps") fname = get_temp_file(autoext=".eps")
...@@ -436,8 +474,14 @@ Creates an EPS file describing a packet. If filename is not provided a temporary ...@@ -436,8 +474,14 @@ Creates an EPS file describing a packet. If filename is not provided a temporary
canvas.writeEPSfile(filename) canvas.writeEPSfile(filename)
def pdfdump(self, filename=None, **kargs): def pdfdump(self, filename=None, **kargs):
"""pdfdump(filename=None, layer_shift=0, rebuild=1) """
Creates a PDF file describing a packet. If filename is not provided a temporary file is created and xpdf is called.""" pdfdump(filename=None, layer_shift=0, rebuild=1)
Creates a PDF file describing a packet. If filename is not provided a
temporary file is created and xpdf is called.
:param filename: the file's filename
"""
canvas = self.canvas_dump(**kargs) canvas = self.canvas_dump(**kargs)
if filename is None: if filename is None:
fname = get_temp_file(autoext=".pdf") fname = get_temp_file(autoext=".pdf")
...@@ -597,7 +641,12 @@ Creates an EPS file describing a packet. If filename is not provided a temporary ...@@ -597,7 +641,12 @@ Creates an EPS file describing a packet. If filename is not provided a temporary
def extract_padding(self, s): def extract_padding(self, s):
"""DEV: to be overloaded to extract current layer's padding. Return a couple of strings (actual layer, padding)""" """
DEV: to be overloaded to extract current layer's padding.
:param str s: the current layer
:return: a couple of strings (actual layer, padding)
"""
return s,None return s,None
def post_dissect(self, s): def post_dissect(self, s):
...@@ -626,6 +675,11 @@ Creates an EPS file describing a packet. If filename is not provided a temporary ...@@ -626,6 +675,11 @@ Creates an EPS file describing a packet. If filename is not provided a temporary
return s return s
def do_dissect_payload(self, s): def do_dissect_payload(self, s):
"""
Perform the dissection of the layer's payload
:param str s: the raw layer
"""
if s: if s:
cls = self.guess_payload_class(s) cls = self.guess_payload_class(s)
try: try:
...@@ -657,7 +711,13 @@ Creates an EPS file describing a packet. If filename is not provided a temporary ...@@ -657,7 +711,13 @@ Creates an EPS file describing a packet. If filename is not provided a temporary
def guess_payload_class(self, payload): def guess_payload_class(self, payload):
"""DEV: Guesses the next payload class from layer bonds. Can be overloaded to use a different mechanism.""" """
DEV: Guesses the next payload class from layer bonds.
Can be overloaded to use a different mechanism.
:param str payload: the layer's payload
:return: the payload class
"""
for t in self.aliastypes: for t in self.aliastypes:
for fval, cls in t.payload_guess: for fval, cls in t.payload_guess:
ok = 1 ok = 1
...@@ -670,7 +730,13 @@ Creates an EPS file describing a packet. If filename is not provided a temporary ...@@ -670,7 +730,13 @@ Creates an EPS file describing a packet. If filename is not provided a temporary
return self.default_payload_class(payload) return self.default_payload_class(payload)
def default_payload_class(self, payload): def default_payload_class(self, payload):
"""DEV: Returns the default payload class if nothing has been found by the guess_payload_class() method.""" """
DEV: Returns the default payload class if nothing has been found by the
guess_payload_class() method.
:param str payload: the layer's payload
:return: the default payload class define inside the configuration file
"""
return conf.raw_layer return conf.raw_layer
def hide_defaults(self): def hide_defaults(self):
...@@ -873,6 +939,13 @@ Creates an EPS file describing a packet. If filename is not provided a temporary ...@@ -873,6 +939,13 @@ Creates an EPS file describing a packet. If filename is not provided a temporary
""" """
Internal method that shows or dumps a hierarchical view of a packet. Internal method that shows or dumps a hierarchical view of a packet.
Called by show. Called by show.
:param dump: determine if it prints or returns the string value
:param int indent: the size of indentation for each layer
:param str lvl: additional information about the layer lvl
:param str label_lvl: additional information about the layer fields
:param first_call: determine if the current function is the first
:return: return a hierarchical view if dump, else print it
""" """
if dump: if dump:
...@@ -919,11 +992,30 @@ Creates an EPS file describing a packet. If filename is not provided a temporary ...@@ -919,11 +992,30 @@ Creates an EPS file describing a packet. If filename is not provided a temporary
return s return s
def show(self, dump=False, indent=3, lvl="", label_lvl=""): def show(self, dump=False, indent=3, lvl="", label_lvl=""):
"""Prints or returns (when "dump" is true) a hierarchical view of the packet. "indent" gives the size of indentation for each layer.""" """
Prints or returns (when "dump" is true) a hierarchical view of the
packet.
:param dump: determine if it prints or returns the string value
:param int indent: the size of indentation for each layer
:param str lvl: additional information about the layer lvl
:param str label_lvl: additional information about the layer fields
:return: return a hierarchical view if dump, else print it
"""
return self._show_or_dump(dump, indent, lvl, label_lvl) return self._show_or_dump(dump, indent, lvl, label_lvl)
def show2(self, dump=False, indent=3, lvl="", label_lvl=""): def show2(self, dump=False, indent=3, lvl="", label_lvl=""):
"""Prints or returns (when "dump" is true) a hierarchical view of an assembled version of the packet, so that automatic fields are calculated (checksums, etc.)""" """
Prints or returns (when "dump" is true) a hierarchical view of an
assembled version of the packet, so that automatic fields are
calculated (checksums, etc.)
:param dump: determine if it prints or returns the string value
:param int indent: the size of indentation for each layer
:param str lvl: additional information about the layer lvl
:param str label_lvl: additional information about the layer fields
:return: return a hierarchical view if dump, else print it
"""
return self.__class__(str(self)).show(dump, indent, lvl, label_lvl) return self.__class__(str(self)).show(dump, indent, lvl, label_lvl)
def sprintf(self, fmt, relax=1): def sprintf(self, fmt, relax=1):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment