Home | History | Annotate | Download | only in layers
      1 """
      2     CLNS Extension
      3     ~~~~~~~~~~~~~~~~~~~~~
      4 
      5     :copyright: 2014, 2015 BENOCS GmbH, Berlin (Germany)
      6     :author:    Marcel Patzlaff, mpatzlaff (at] benocs.com
      7     :license:   GPLv2
      8 
      9         This module is free software; you can redistribute it and/or
     10         modify it under the terms of the GNU General Public License
     11         as published by the Free Software Foundation; either version 2
     12         of the License, or (at your option) any later version.
     13 
     14         This module is distributed in the hope that it will be useful,
     15         but WITHOUT ANY WARRANTY; without even the implied warranty of
     16         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17         GNU General Public License for more details.
     18 
     19     :description:
     20 
     21         This module provides a registration function and a generic PDU
     22         for OSI Connectionless-mode Network Services (such as IS-IS).
     23 """
     24 import struct
     25 
     26 from scapy.config import conf
     27 from scapy.fields import ByteEnumField, PacketField
     28 from scapy.layers.l2 import LLC
     29 from scapy.packet import Packet, bind_top_down, bind_bottom_up
     30 from scapy.compat import orb
     31 
     32 network_layer_protocol_ids = {
     33     0x00: "Null",
     34     0x08: "Q.933",
     35     0x80: "IEEE SNAP",
     36     0x81: "ISO 8438 CLNP",
     37     0x82: "ISO 9542 ES-IS",
     38     0x83: "ISO 10589 IS-IS",
     39     0x8E: "IPv6",
     40     0xB0: "FRF.9",
     41     0xB1: "FRF.12",
     42     0xC0: "TRILL",
     43     0xC1: "IEEE 802.aq",
     44     0xCC: "IPv4",
     45     0xCF: "PPP"
     46 }
     47 
     48 
     49 _cln_protocols = {}
     50 
     51 
     52 class _GenericClnsPdu(Packet):
     53     name = "Generic CLNS PDU"
     54     fields_desc = [
     55         ByteEnumField("nlpid", 0x00, network_layer_protocol_ids),
     56         PacketField("rawdata", None, conf.raw_layer)
     57     ]
     58 
     59 
     60 def _create_cln_pdu(s, **kwargs):
     61     pdu_cls = conf.raw_layer
     62 
     63     if len(s) >= 1:
     64         nlpid = orb(s[0])
     65         pdu_cls = _cln_protocols.get(nlpid, _GenericClnsPdu)
     66 
     67     return pdu_cls(s, **kwargs)
     68 
     69 
     70 @conf.commands.register
     71 def register_cln_protocol(nlpid, cln_protocol_class):
     72     if nlpid is None or cln_protocol_class is None:
     73         return
     74 
     75     chk = _cln_protocols.get(nlpid, None)
     76     if chk is not None and chk != cln_protocol_class:
     77         raise ValueError("different protocol already registered!")
     78 
     79     _cln_protocols[nlpid] = cln_protocol_class
     80     bind_top_down(LLC, cln_protocol_class, dsap=0xfe, ssap=0xfe, ctrl=3)
     81 
     82 
     83 bind_top_down(LLC, _GenericClnsPdu, dsap=0xfe, ssap=0xfe, ctrl=3)
     84 bind_bottom_up(LLC, _create_cln_pdu, dsap=0xfe, ssap=0xfe, ctrl=3)
     85