FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+4), StrLenField("load","",length_from=lambda x:x.length-4), ] IKEv2_payload_type_overload = {} for i, payloadname in enumerate(IKEv2_payload_type): name = "IKEv2_payload_%s" % payloadname if name in globals(): IKEv2_payload_type_overload[globals()[name]] = {"next_payload": i} del i, payloadname, name IKEv2_class._overload_fields = IKEv2_payload_type_overload.copy() split_layers(UDP, ISAKMP, sport=500) split_layers(UDP, ISAKMP, dport=500) bind_layers( UDP, IKEv2, dport=500, sport=500) # TODO: distinguish IKEv1/IKEv2 bind_layers( UDP, IKEv2, dport=4500, sport=4500) def ikev2scan(ip): return sr(IP(dst=ip)/UDP()/IKEv2(init_SPI=RandString(8), exch_type=34)/IKEv2_payload_SA(prop=IKEv2_payload_Proposal())) # conf.debug_dissector = 1 if __name__ == "__main__": from scapy.main import interact interact(mydict=globals(), mybanner="IKEv2 alpha-level protocol implementation")
eg. https://tools.ietf.org/html/rfc6810#section-5.2 ''' name = 'RTR dissector' @classmethod def dispatch_hook(cls, _pkt=None, *args, **kargs): ''' Attribution of correct type depending on version and pdu_type ''' if _pkt and len(_pkt) >= 2: version = orb(_pkt[0]) pdu_type = orb(_pkt[1]) if version == 0: return PDU_CLASS_VERSION_0[pdu_type] elif version == 1: return PDU_CLASS_VERSION_1[pdu_type] return Raw bind_layers(TCP, RTR, dport=323) # real reserved port bind_layers(TCP, RTR, sport=323) # real reserved port bind_layers(TCP, RTR, dport=8282) # RIPE implementation default port bind_layers(TCP, RTR, sport=8282) # RIPE implementation default port bind_layers(TCP, RTR, dport=2222) # gortr implementation default port bind_layers(TCP, RTR, sport=2222) # gortr implementation default port if __name__ == '__main__': from scapy.main import interact interact(mydict=globals(), mybanner='RPKI to Router')
cls = conf.raw_layer if len(p) >= 2: t = struct.unpack("!H", p[:2])[0] clsname = _DTP_TLV_CLS.get(t, "DtpGenericTlv") cls = globals()[clsname] return cls(p, **kargs) class DTP(Packet): name = "DTP" fields_desc = [ ByteField("ver", 1), RepeatedTlvListField("tlvlist", [], _DTPGuessPayloadClass) ] bind_layers(SNAP, DTP, code=0x2004, OUI=0xc) def negotiate_trunk(iface=conf.iface, mymac=str(RandMAC())): print "Trying to negotiate a trunk on interface %s" % iface p = Dot3(src=mymac, dst="01:00:0c:cc:cc:cc")/LLC()/SNAP() / \ DTP(tlvlist=[ DTPDomain(), DTPStatus(), DTPType(), DTPNeighbor(neighbor=mymac)]) sendp(p) if __name__ == "__main__": from scapy.main import interact interact(mydict=globals(), mybanner="DTP")
print client_next_seq,"=>",server_next_seq nexts = possible_stream.filter( lambda p:p.seq in (client_next_seq,server_next_seq) and \ not p in tcp_stream and not p in fin ) if not nexts: break for some in nexts: tcp_stream.append(some) if some[L3].src == srcip: client_next_seq += _calc_tcp_pay_len(some) elif some[L3].src == dstip: server_next_seq += _calc_tcp_pay_len(some) tcp_stream += fin #<TCP Stream Between ?:? - ?:? : TCP:22 UDP:5 ICMP:0 Other:3> if resolv: tcp_stream = PacketList(tcp_stream, name="TCP Stream Between %s:%s - %s:%s" % (srchost, srcservice, dsthost, dstservice) ) else: tcp_stream = PacketList(tcp_stream, name="TCP Stream Between %s:%s - %s:%s" % (srcip, srcport, dstip, dstport) ) return tcp_stream if __name__ == "__main__": from scapy.main import interact interact(mydict=locals(),mybanner="***SYA-KE scapy!***")
FlagsField("flags", 0, 32, _EIGRP_FLAGS), IntField("seq", 0), IntField("ack", 0), IntField("asn", 100), RepeatedTlvListField( "tlvlist", [], _EIGRPGuessPayloadClass) ] def post_build(self, p, pay): p += pay if self.chksum is None: c = checksum(p) p = p[:2] + chr((c >> 8) & 0xff) + chr(c & 0xff) + p[4:] return p def mysummary(self): summarystr = "EIGRP (AS=%EIGRP.asn% Opcode=%EIGRP.opcode%" if self.opcode == 5 and self.ack != 0: summarystr += " (ACK)" if self.flags != 0: summarystr += " Flags=%EIGRP.flags%" return self.sprintf(summarystr + ")") bind_layers(IP, EIGRP, proto=88) bind_layers(IPv6, EIGRP, nh=88) if __name__ == "__main__": from scapy.main import interact interact(mydict=globals(), mybanner="EIGRP")
return '%s.dev%s' % (match.group(1), match.group(2)) else: # just remove the 'v' prefix return re.sub(r'^v', '', tag) else: raise subprocess.CalledProcessError(p.returncode, err) def _version(): version_file = os.path.join(_SCAPY_PKG_DIR, 'VERSION') try: tag = _version_from_git_describe() # successfully read the tag from git, write it in VERSION for # installation and/or archive generation. with open(version_file, 'w') as f: f.write(tag) return tag except: # failed to read the tag from git, try to read it from a VERSION file try: with open(version_file, 'r') as f: tag = f.read() return tag except: return 'unknown.version' VERSION = _version() if __name__ == "__main__": from scapy.main import interact interact()
p = p[:2+wl]+struct.pack("!H", l)+p[4+wl:] return p+pay class BGPNotification(Packet): name = "BGP Notification fields" fields_desc = [ ByteEnumField("ErrorCode",0,{1:"Message Header Error",2:"OPEN Message Error",3:"UPDATE Messsage Error",4:"Hold Timer Expired",5:"Finite State Machine",6:"Cease"}), ByteEnumField("ErrorSubCode",0,{1:"MessageHeader",2:"OPENMessage",3:"UPDATEMessage"}), LongField("Data", 0), ] class BGPErrorSubcodes(Packet): name = "BGP Error Subcodes" Fields_desc = [ ByteEnumField("MessageHeader",0,{1:"Connection Not Synchronized",2:"Bad Message Length",3:"Bad Messsage Type"}), ByteEnumField("OPENMessage",0,{1:"Unsupported Version Number",2:"Bad Peer AS",3:"Bad BGP Identifier",4:"Unsupported Optional Parameter",5:"Authentication Failure",6:"Unacceptable Hold Time"}), ByteEnumField("UPDATEMessage",0,{1:"Malformed Attribute List",2:"Unrecognized Well-Known Attribute",3:"Missing Well-Known Attribute",4:"Attribute Flags Error",5:"Attribute Length Error",6:"Invalid ORIGIN Attribute",7:"AS Routing Loop",8:"Invalid NEXT_HOP Attribute",9:"Optional Attribute Error",10:"Invalid Network Field",11:"Malformed AS_PATH"}), ] bind_layers( TCP, BGPHeader, dport=179) bind_layers( TCP, BGPHeader, sport=179) bind_layers( BGPHeader, BGPOpen, type=1) bind_layers( BGPHeader, BGPUpdate, type=2) bind_layers( BGPHeader, BGPHeader, type=4) if __name__ == "__main__": from scapy.main import interact interact(mydict=globals(), mybanner="BGP addon .05")
#!/usr/bin/python3 from scapy.main import interact from sys import exit exit(interact())
ByteEnumField("cert_type", 0, IKEv2CertificateEncodings), StrLenField("cert_data", "", length_from=lambda x:x.length - 5), ] IKEv2_payload_type_overload = {} for i, payloadname in enumerate(IKEv2_payload_type): name = "IKEv2_payload_%s" % payloadname if name in globals(): IKEv2_payload_type_overload[globals()[name]] = {"next_payload": i} del i, payloadname, name IKEv2_class._overload_fields = IKEv2_payload_type_overload.copy() split_layers(UDP, ISAKMP, sport=500) split_layers(UDP, ISAKMP, dport=500) bind_layers(UDP, IKEv2, dport=500, sport=500) # TODO: distinguish IKEv1/IKEv2 bind_layers(UDP, IKEv2, dport=4500, sport=4500) def ikev2scan(ip): return sr(IP(dst=ip) / UDP() / IKEv2(init_SPI=RandString(8), exch_type=34) / IKEv2_payload_SA(prop=IKEv2_payload_Proposal())) # conf.debug_dissector = 1 if __name__ == "__main__": from scapy.main import interact interact(mydict=globals(), mybanner="IKEv2 alpha-level protocol implementation")
# Setting length of packet to obfuscate if not filled by user if self.length is None and pay: p = p[:-4] + struct.pack('!I', len(pay)) if self.flags == 0: pay = obfuscate(pay, SECRET, self.session_id, self.version, self.seq) # noqa: E501 return p + pay return p def hashret(self): return struct.pack('I', self.session_id) def answers(self, other): return (isinstance(other, TacacsHeader) and self.seq == other.seq + 1 and self.type == other.type and self.session_id == other.session_id) bind_layers(TCP, TacacsHeader, dport=49) bind_layers(TCP, TacacsHeader, sport=49) bind_layers(TacacsHeader, TacacsAuthenticationStart, type=1, dport=49) bind_layers(TacacsHeader, TacacsAuthenticationReply, type=1, sport=49) if __name__ == '__main__': from scapy.main import interact interact(mydict=globals(), mybanner='tacacs+')
class OSPFv3_LSAck(Packet): name = "OSPFv3 Link State Acknowledgement" fields_desc = [ PacketListField("lsaheaders", None, OSPFv3_LSA_Hdr, count_from=lambda pkt: None, length_from=lambda pkt: pkt.underlayer.len - 16) ] bind_layers(IP, OSPF_Hdr, proto=89) bind_layers(OSPF_Hdr, OSPF_Hello, type=1) bind_layers(OSPF_Hdr, OSPF_DBDesc, type=2) bind_layers(OSPF_Hdr, OSPF_LSReq, type=3) bind_layers(OSPF_Hdr, OSPF_LSUpd, type=4) bind_layers(OSPF_Hdr, OSPF_LSAck, type=5) DestIPField.bind_addr(OSPF_Hdr, "224.0.0.5") bind_layers(IPv6, OSPFv3_Hdr, nh=89) bind_layers(OSPFv3_Hdr, OSPFv3_Hello, type=1) bind_layers(OSPFv3_Hdr, OSPFv3_DBDesc, type=2) bind_layers(OSPFv3_Hdr, OSPFv3_LSReq, type=3) bind_layers(OSPFv3_Hdr, OSPFv3_LSUpd, type=4) bind_layers(OSPFv3_Hdr, OSPFv3_LSAck, type=5) DestIP6Field.bind_addr(OSPFv3_Hdr, "ff02::5") if __name__ == "__main__": from scapy.main import interact interact(mydict=globals(), mybanner="OSPF extension %s" % EXT_VERSION)
return RTRResetQuery elif self.pdu_type == 3: return RTRCacheResponse elif self.pdu_type == 4: return RTRIPv4Prefix elif self.pdu_type == 6: return RTRIPv6Prefix elif self.pdu_type == 7: if self.rtr_version == 0: return RTREndofDatav0 elif self.rtr_version == 1: return RTREndofDatav1 elif self.pdu_type == 8: return RTRCacheReset elif self.pdu_type == 9: if self.rtr_version == 1: return RTRRouterKey elif self.pdu_type == 10: return RTRErrorReport bind_layers(TCP, RTRHeader, dport=323) # real reserved port bind_layers(TCP, RTRHeader, sport=323) # real reserved port bind_layers(TCP, RTRHeader, dport=8282) # RIPE implementation default port bind_layers(TCP, RTRHeader, sport=8282) # RIPE implementation default port bind_layers(RTRHeader, RTRCacheResponse, pdu_type=3, dport=8282) if __name__ == '__main__': from scapy.main import interact interact(mydict=globals(), mybanner='RPKI to Router')
@return p str パケットデータ。多くの場合pkt+payをreturnするだろう。 """ self.show() print "===pkt===" print pkt print "===pay===" print pay return Packet.post_build(self, pkt, pay) def build_padding(self): """ ペイロードに対してbuild_padding関数を呼び出す。 デフォルトでペイロードで連鎖する。 @return pad str 連鎖して完成した自レイヤ以降のパディング """ return Packet.build_padding(self) def build_done(self,pkt): """ ペイロードに対してbuild_done関数を呼び出す。 デフォルトでペイロードで連鎖する。 @return pkt str 最終的に完成した全パケットデータ """ return Packet.build_done(self,pkt) i=Example() i.code=0xFF i.show() from scapy.main import interact interact(mydict=locals())
LEIntField('callid', 0)] class Skinny(Packet): name="Skinny" fields_desc = [ LEIntField("len", None), LEIntField("res",0), LEIntEnumField("msg",0, skinny_messages_cls) ] def post_build(self, pkt, p): if self.len is None: l=len(p)+len(pkt)-8 # on compte pas les headers len et reserved pkt=struct.pack('@I', l)+pkt[4:] return pkt+p # An helper def get_cls(name, fallback_cls): return globals().get(name, fallback_cls) #return __builtin__.__dict__.get(name, fallback_cls) for msgid,strcls in skinny_messages_cls.items(): cls=get_cls(strcls, SkinnyMessageGeneric) bind_layers(Skinny, cls, {"msg": msgid}) bind_layers(TCP, Skinny, { "dport": 2000 } ) bind_layers(TCP, Skinny, { "sport": 2000 } ) if __name__ == "__main__": from scapy.main import interact interact(mydict=globals(),mybanner="Welcome to Skinny add-on")
FlagsField("flags", 0, 32, _EIGRP_FLAGS), IntField("seq", 0), IntField("ack", 0), IntField("asn", 100), RepeatedTlvListField("tlvlist", [], _EIGRPGuessPayloadClass) ] def post_build(self, p, pay): p += pay if self.chksum is None: c = checksum(p) p = p[:2] + chb((c >> 8) & 0xff) + chb(c & 0xff) + p[4:] return p def mysummary(self): summarystr = "EIGRP (AS=%EIGRP.asn% Opcode=%EIGRP.opcode%" if self.opcode == 5 and self.ack != 0: summarystr += " (ACK)" if self.flags != 0: summarystr += " Flags=%EIGRP.flags%" return self.sprintf(summarystr + ")") bind_layers(IP, EIGRP, proto=88) bind_layers(IPv6, EIGRP, nh=88) if __name__ == "__main__": from scapy.main import interact interact(mydict=globals(), mybanner="EIGRP")
length_from=lambda pkt:pkt.underlayer.len - 16)] # noqa: E501 class OSPFv3_LSAck(Packet): name = "OSPFv3 Link State Acknowledgement" fields_desc = [PacketListField("lsaheaders", None, OSPFv3_LSA_Hdr, count_from=lambda pkt:None, length_from=lambda pkt:pkt.underlayer.len - 16)] # noqa: E501 bind_layers(IP, OSPF_Hdr, proto=89) bind_layers(OSPF_Hdr, OSPF_Hello, type=1) bind_layers(OSPF_Hdr, OSPF_DBDesc, type=2) bind_layers(OSPF_Hdr, OSPF_LSReq, type=3) bind_layers(OSPF_Hdr, OSPF_LSUpd, type=4) bind_layers(OSPF_Hdr, OSPF_LSAck, type=5) DestIPField.bind_addr(OSPF_Hdr, "224.0.0.5") bind_layers(IPv6, OSPFv3_Hdr, nh=89) bind_layers(OSPFv3_Hdr, OSPFv3_Hello, type=1) bind_layers(OSPFv3_Hdr, OSPFv3_DBDesc, type=2) bind_layers(OSPFv3_Hdr, OSPFv3_LSReq, type=3) bind_layers(OSPFv3_Hdr, OSPFv3_LSUpd, type=4) bind_layers(OSPFv3_Hdr, OSPFv3_LSAck, type=5) DestIP6Field.bind_addr(OSPFv3_Hdr, "ff02::5") if __name__ == "__main__": from scapy.main import interact interact(mydict=globals(), mybanner="OSPF extension %s" % EXT_VERSION)
name = "PCP Peer" fields_desc = [StrFixedLenField("nonce", os.urandom(12), 12), ByteEnumField("protocol", ProtocolNumbers.TCP, PROTOCOL_NUMBERS), StrFixedLenField("reserved1", "\x00" * 3, 3), Emph(ShortField("int_port", 1234)), Emph(ShortField("ext_port", 5678)), Emph(IP6Field("ext_ip", "::ffff:127.0.0.1")), Emph(ShortField("peer_port", 9101)), StrFixedLenField("reserved2", "\x00" * 2, 2), Emph(IP6Field("peer_ip", "::ffff:127.0.0.1")), PacketListField("options", None, PCPOption)] def answers(self, other): return self.nonce == other.nonce bind_layers(UDP, PCPRequest, dport=5351) bind_layers(UDP, PCPResponse, sport=5351) bind_layers(PCPRequest, PCPMap, opcode=PCPOpcodes.MAP) bind_layers(PCPResponse, PCPMap, opcode=PCPOpcodes.MAP) bind_layers(PCPRequest, PCPPeer, opcode=PCPOpcodes.PEER) bind_layers(PCPResponse, PCPPeer, opcode=PCPOpcodes.PEER) bind_layers(PCPOption, PCPOptionThirdParty, code=PCPOptions.THIRD_PARTY) bind_layers(PCPOption, PCPOptionPreferFailure, code=PCPOptions.PREFER_FAILURE) bind_layers(PCPOption, PCPOptionFilter, code=PCPOptions.FILTER) bind_layers(PCPOption, PCPOptionUnknown) if __name__ == '__main__': from scapy.main import interact interact(mydict=globals(), mybanner="PCP Addon")
from scapy.packet import * from scapy.fields import * from scapy.layers.inet import UDP from scapy.layers.inet6 import * class RIPng(Packet): name = "RIPng header" fields_desc = [ByteEnumField("cmd", 1, {1: "req", 2: "resp"}), ByteField("ver", 1), ShortField("null", 0)] class RIPngEntry(Packet): name = "RIPng entry" fields_desc = [ ConditionalField(IP6Field("prefix", "::"), lambda pkt: pkt.metric != 255), ConditionalField(IP6Field("nexthop", "::"), lambda pkt: pkt.metric == 255), ShortField("routetag", 0), ByteField("prefixlen", 0), ByteEnumField("metric", 1, {16: "Unreach", 255: "next-hop entry"}), ] bind_layers(UDP, RIPng, sport=521, dport=521) bind_layers(RIPng, RIPngEntry) bind_layers(RIPngEntry, RIPngEntry) if __name__ == "__main__": from scapy.main import interact interact(mydict=globals(), mybanner="RIPng")
LEIntField("res", 0), LEIntEnumField("msg", 0, skinny_messages_cls) ] def post_build(self, pkt, p): if self.len is None: # on compte pas les headers len et reserved tmp_len = len(p) + len(pkt) - 8 pkt = struct.pack('@I', tmp_len) + pkt[4:] return pkt + p # An helper def get_cls(name, fallback_cls): return globals().get(name, fallback_cls) # return __builtin__.__dict__.get(name, fallback_cls) for msgid, strcls in skinny_messages_cls.items(): cls = get_cls(strcls, SkinnyMessageGeneric) bind_layers(Skinny, cls, {"msg": msgid}) bind_layers(TCP, Skinny, {"dport": 2000}) bind_layers(TCP, Skinny, {"sport": 2000}) if __name__ == "__main__": from scapy.main import interact interact(mydict=globals(), mybanner="Welcome to Skinny add-on")
2: "resp" }), ByteField("ver", 1), ShortField("null", 0), ] class RIPngEntry(Packet): name = "RIPng entry" fields_desc = [ ConditionalField(IP6Field("prefix", "::"), lambda pkt: pkt.metric != 255), ConditionalField(IP6Field("nexthop", "::"), lambda pkt: pkt.metric == 255), ShortField("routetag", 0), ByteField("prefixlen", 0), ByteEnumField("metric", 1, { 16: "Unreach", 255: "next-hop entry" }) ] bind_layers(UDP, RIPng, sport=521, dport=521) bind_layers(RIPng, RIPngEntry) bind_layers(RIPngEntry, RIPngEntry) if __name__ == "__main__": from scapy.main import interact interact(mydict=globals(), mybanner="RIPng")
#FieldLenField("length", None, "neighbor", adjust=lambda pkt,x:x + 4), ShortField("len", 10), MACField("neighbor", None) ] def _DTPGuessPayloadClass(p, **kargs): cls = conf.raw_layer if len(p) >= 2: t = struct.unpack("!H", p[:2])[0] clsname = _DTP_TLV_CLS.get(t, "DtpGenericTlv") cls = globals()[clsname] return cls(p, **kargs) class DTP(Packet): name = "DTP" fields_desc = [ ByteField("ver", 1), RepeatedTlvListField("tlvlist", [], _DTPGuessPayloadClass) ] bind_layers(SNAP, DTP, code=0x2004, OUI=0xc) def negotiate_trunk(iface=conf.iface, mymac=str(RandMAC())): print("Trying to negotiate a trunk on interface %s" % iface) p = Dot3(src=mymac, dst="01:00:0c:cc:cc:cc")/LLC()/SNAP()/DTP(tlvlist=[DTPDomain(),DTPStatus(),DTPType(),DTPNeighbor(neighbor=mymac)]) sendp(p) if __name__ == "__main__": from scapy.main import interact interact(mydict=globals(), mybanner="DTP")
fdesc.write(tag) return tag except Exception: # failed to read the tag from git, try to read it from a VERSION file try: with open(version_file, 'r') as fdsec: tag = fdsec.read() return tag except Exception: # Rely on git archive "export-subst" git attribute. # See 'man gitattributes' for more details. git_archive_id = 'c62f9013d3 (HEAD -> master)' sha1 = git_archive_id.strip().split()[0] match = re.search('tag:(\\S+)', git_archive_id) if match: return "git-archive.dev" + match.group(1) elif sha1: return "git-archive.dev" + sha1 else: return 'unknown.version' VERSION = __version__ = _version() _tmp = re.search(r"[0-9.]+", VERSION) VERSION_MAIN = _tmp.group() if _tmp is not None else VERSION if __name__ == "__main__": from scapy.main import interact interact()
# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. """Scapy Dissector for CIP messages at the Field Communications Network at the Tennesse Eastman Testbed at the National Institute of Standards and Technology """ from scapy.main import interact from te import * import filters banner = 'Add-on: Scapy Dissector for CIP messages at the' \ '\n Field Communications Network at the Tennesse Eastman Testbed' interact(mydict=globals(), mybanner=banner)
# Copyright (c) 2016 David I Urbina # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. """EtherCAT Dissector for the Manufactoring Robot Testbed at the National Institute of Standards and Technology """ from scapy.main import interact from ethercat import * import filters banner = 'Add-on: EtherCAT Dissector for the Manufactoring Robot Testbed' interact(mydict=globals(), mybanner=banner)