class IPv6TrafficSelector(TrafficSelector): name = "IKEv2 IPv6 Traffic Selector" fields_desc = [ ByteEnumField("TS_type", 8, IKEv2TrafficSelectorTypes), ByteEnumField("IP_protocol_ID", None, IPProtocolIDs), ShortField("length", 20), ShortField("start_port", 0), ShortField("end_port", 65535), IP6Field("starting_address_v6", "2001::"), IP6Field("ending_address_v6", "2001::"), ]
class OSPFv3_AS_External_LSA(OSPF_BaseLSA): name = "OSPFv3 AS External LSA" fields_desc = [ ShortField("age", 1), ShortEnumField("type", 0x4005, _OSPFv3_LStypes), IPField("id", "0.0.0.0"), IPField("adrouter", "1.1.1.1"), XIntField("seq", 0x80000001), XShortField("chksum", None), ShortField("len", None), FlagsField("flags", 0, 8, ["T", "F", "E"]), X3BytesField("metric", 20), FieldLenField("prefixlen", None, length_of="prefix", fmt="B"), # noqa: E501 OSPFv3PrefixOptionsField(), ShortEnumField("reflstype", 0, _OSPFv3_LStypes), IP6PrefixField("prefix", "2001:db8:0:42::/64", wordbytes=4, length_from=lambda pkt: pkt.prefixlen), # noqa: E501 ConditionalField(IP6Field("fwaddr", "::"), lambda pkt: pkt.flags & 0x02 == 0x02), # noqa: E501 ConditionalField(IntField("tag", 0), lambda pkt: pkt.flags & 0x01 == 0x01), # noqa: E501 ConditionalField(IPField("reflsid", 0), lambda pkt: pkt.reflstype != 0) ] # noqa: E501
class EIGRPv6ExtRoute(EIGRPGeneric): name = "EIGRP for IPv6 External Route" fields_desc = [ XShortField("type", 0x0403), FieldLenField("len", None, "dst", "!H", adjust=lambda pkt, x: x + 57), # noqa: E501 IP6Field("nexthop", "::"), IPField("originrouter", "192.168.0.1"), IntField("originasn", 0), IntField("tag", 0), IntField("externalmetric", 0), ShortField("reserved", 0), ByteEnumField("extprotocolid", 3, _EIGRP_EXTERNAL_PROTOCOL_ID), # noqa: E501 FlagsField("flags", 0, 8, _EIGRP_EXTROUTE_FLAGS), IntField("delay", 0), IntField("bandwidth", 256000), ThreeBytesField("mtu", 1500), ByteField("hopcount", 1), ByteField("reliability", 0), ByteField("load", 1), XShortField("reserved2", 0), ByteField("prefixlen", 8), EigrpIP6Field("dst", "::", length_from=lambda pkt: pkt.prefixlen) # noqa: E501 ]
class CDPAddrRecordIPv6(CDPAddrRecord): name = "CDP Address IPv6" fields_desc = [ByteEnumField("ptype", 0x02, _cdp_addr_record_ptype), FieldLenField("plen", 8, "proto", "B"), StrLenField("proto", _cdp_addrrecord_proto_ipv6, length_from=lambda x:x.plen, max_length=255), ShortField("addrlen", 16), IP6Field("addr", "::1")]
class RIPngEntry(Packet): name = "RIPng entry" fields_desc = [ IP6Field("prefix_or_nh", "::"), ShortField("routetag", 0), ByteField("prefixlen", 0), ByteEnumField("metric", 1, {16: "Unreach", 255: "next-hop entry"}) ]
class RPLDCOACK(_RPLGuessMsgType, _RPLGuessOption): """ Control Message: Destination Cleanup Object Acknowledgement (DCOACK) """ name = "Destination Cleanup Object Acknowledgement" fields_desc = [ ByteField("RPLInstanceID", 50), BitField("D", 0, 1), BitField("flags", 0, 7), ByteField("dcoseq", 1), ByteField("status", 0), ConditionalField(IP6Field("dodagid", None), lambda pkt: pkt.D == 1) ]
class RPLDAO(_RPLGuessMsgType, _RPLGuessOption): """ Control Message: Destination Advertisement Object (DAO) """ name = "Destination Advertisement Object" fields_desc = [ ByteField("RPLInstanceID", 50), BitField("K", 0, 1), BitField("D", 0, 1), BitField("flags", 0, 6), ByteField("reserved", 0), ByteField("daoseq", 1), ConditionalField(IP6Field("dodagid", None), lambda pkt: pkt.D == 1) ]
class OSPFv3_Link_LSA(OSPF_BaseLSA): name = "OSPFv3 Link LSA" fields_desc = [ShortField("age", 1), ShortEnumField("type", 0x0008, _OSPFv3_LStypes), IPField("id", "0.0.0.0"), IPField("adrouter", "1.1.1.1"), XIntField("seq", 0x80000001), XShortField("chksum", None), ShortField("len", None), ByteField("prio", 1), OSPFv3OptionsField(), IP6Field("lladdr", "fe80::"), FieldLenField("prefixes", None, count_of="prefixlist", fmt="I"), # noqa: E501 PacketListField("prefixlist", None, OSPFv3_Prefix_Item, count_from=lambda pkt: pkt.prefixes)]
class EIGRPv6IntRoute(EIGRPGeneric): name = "EIGRP for IPv6 Internal Route" fields_desc = [XShortField("type", 0x0402), FieldLenField("len", None, "dst", "!H", adjust=lambda pkt, x: x + 37), # noqa: E501 IP6Field("nexthop", "::"), IntField("delay", 128000), IntField("bandwidth", 256000), ThreeBytesField("mtu", 1500), ByteField("hopcount", 1), ByteField("reliability", 255), ByteField("load", 0), XShortField("reserved", 0), ByteField("prefixlen", 16), EigrpIP6Field("dst", "2001::", length_from=lambda pkt: pkt.prefixlen) # noqa: E501 ]
class RPLOptSolInfo(_RPLGuessOption): """ Control Option: Solicited Information """ name = "Solicited Information" fields_desc = [ ByteEnumField("otype", 7, RPLOPTSSTR), ByteField("len", 19), ByteField("RPLInstanceID", 0), BitField("V", 0, 1), BitField("I", 0, 1), BitField("D", 0, 1), BitField("flags", 0, 5), IP6Field("dodagid", "::1"), ByteField("ver", 0) ]
class RPLDIO(_RPLGuessMsgType, _RPLGuessOption): """ Control Message: DODAG Information Object (DIO) """ name = "DODAG Information Object" fields_desc = [ ByteField("RPLInstanceID", 50), ByteField("ver", 0), ShortField("rank", 1), BitField("G", 1, 1), BitField("unused1", 0, 1), BitEnumField("mop", 1, 3, RPLMOP), BitField("prf", 0, 3), ByteField("dtsn", 240), ByteField("flags", 0), ByteField("reserved", 0), IP6Field("dodagid", "::1") ]
class RPLOptPIO(_RPLGuessOption): """ Control Option: Prefix Information Option (PIO) """ name = "Prefix Information" fields_desc = [ ByteEnumField("otype", 8, RPLOPTSSTR), ByteField("len", 30), ByteField("plen", 64), BitField("L", 0, 1), BitField("A", 0, 1), BitField("R", 0, 1), BitField("reserved1", 0, 5), IntField("validlifetime", 0xffffffff), IntField("preflifetime", 0xffffffff), IntField("reserved2", 0), IP6Field("prefix", "::1") ]
class VRRPv3(Packet): fields_desc = [ BitField("version", 3, 4), BitField("type", 1, 4), ByteField("vrid", 1), ByteField("priority", 100), FieldLenField("ipcount", None, count_of="addrlist", fmt="B"), BitField("res", 0, 4), BitField("adv", 100, 12), XShortField("chksum", None), MultipleTypeField([ (FieldListField("addrlist", [], IPField("", "0.0.0.0"), count_from=lambda pkt: pkt.ipcount), lambda p: isinstance(p.underlayer, IP)), (FieldListField("addrlist", [], IP6Field("", "::"), count_from=lambda pkt: pkt.ipcount), lambda p: isinstance(p.underlayer, IPv6)), ], StrField("addrlist", "")) ] def post_build(self, p, pay): if self.chksum is None: if isinstance(self.underlayer, IP): ck = in4_chksum(112, self.underlayer, p) elif isinstance(self.underlayer, IPv6): ck = in6_chksum(112, self.underlayer, p) else: warning( "No IP(v6) layer to compute checksum on VRRP. Leaving null" ) # noqa: E501 ck = 0 p = p[:6] + chb(ck >> 8) + chb(ck & 0xff) + p[8:] return p @classmethod def dispatch_hook(cls, _pkt=None, *args, **kargs): if _pkt and len(_pkt) >= 16: ver_n_type = orb(_pkt[0]) if ver_n_type < 48 or ver_n_type > 57: # Version != 3 return VRRP return VRRPv3
class EIGRPSeq(EIGRPGeneric): name = "EIGRP Sequence" fields_desc = [XShortField("type", 0x0003), ShortField("len", None), ByteField("addrlen", 4), ConditionalField(IPField("ipaddr", "192.168.0.1"), lambda pkt:pkt.addrlen == 4), ConditionalField(IP6Field("ip6addr", "2001::"), lambda pkt:pkt.addrlen == 16) ] def post_build(self, p, pay): p += pay if self.len is None: tmp_len = len(p) tmp_p = p[:2] + chb((tmp_len >> 8) & 0xff) p = tmp_p + chb(tmp_len & 0xff) + p[4:] return p
class RTRIPv6Prefix(Packet): ''' IPv6 Prefix packet from section 5.7 https://tools.ietf.org/html/rfc6810#section-5.7 ''' name = 'IPv6 Prefix' fields_desc = [ ByteEnumField('rtr_version', 0, RTR_VERSION), ByteEnumField('pdu_type', 6, PDU_TYPE), ShortField('reserved', 0), IntField('length', STATIC_IPV6_PREFIX_LENGTH), ByteField('flags', 0), ByteField('shortest_length', 0), ByteField('longest_length', 0), ByteField('zeros', 0), IP6Field("prefix", "::"), IntField('asn', 0) ] def guess_payload_class(self, payload): return RTR
def i2repr(self, pkt, x): return IP6Field.i2repr(self, pkt, x)
def any2i(self, pkt, x): return IP6Field.any2i(self, pkt, x)
class PFLog(Packet): """ Class for handling PFLog headers """ name = "PFLog" # from OpenBSD src/sys/net/pfvar.h # and src/sys/net/if_pflog.h (struct pfloghdr) fields_desc = [ ByteField("hdrlen", PFLOG_HDRLEN), ByteEnumField("addrfamily", 2, { OPENBSD_AF_INET: "IPv4", OPENBSD_AF_INET6: "IPv6" }), ByteEnumField( "action", 1, { 0: "pass", 1: "drop", 2: "scrub", 3: "no-scrub", 4: "nat", 5: "no-nat", 6: "binat", 7: "no-binat", 8: "rdr", 9: "no-rdr", 10: "syn-proxy-drop" }), ByteEnumField( "reason", 0, { 0: "match", 1: "bad-offset", 2: "fragment", 3: "short", 4: "normalize", 5: "memory", 6: "bad-timestamp", 7: "congestion", 8: "ip-options", 9: "proto-cksum", 10: "state-mismatch", 11: "state-insert", 12: "state-limit", 13: "src-limit", 14: "syn-proxy" }), StrFixedLenField("iface", "", 16), StrFixedLenField("ruleset", "", 16), SignedIntField("rulenumber", 0), SignedIntField("subrulenumber", 0), SignedIntField("uid", 0), IntField("pid", 0), SignedIntField("ruleuid", 0), IntField("rulepid", 0), ByteEnumField("direction", 255, { 0: "inout", 1: "in", 2: "out", 255: "unknown" }), YesNoByteField("rewritten", 0), ByteEnumField("naddrfamily", 2, { OPENBSD_AF_INET: "IPv4", OPENBSD_AF_INET6: "IPv6" }), StrFixedLenField("pad", b"\x00", 1), MultipleTypeField( [ (PadField(IPField("saddr", "127.0.0.1"), 16, padwith=b"\x00"), lambda pkt: pkt.addrfamily == OPENBSD_AF_INET), (IP6Field("saddr", "::1"), lambda pkt: pkt.addrfamily == OPENBSD_AF_INET6), ], PadField(IPField("saddr", "127.0.0.1"), 16, padwith=b"\x00"), ), MultipleTypeField( [ (PadField(IPField("daddr", "127.0.0.1"), 16, padwith=b"\x00"), lambda pkt: pkt.addrfamily == OPENBSD_AF_INET), (IP6Field("daddr", "::1"), lambda pkt: pkt.addrfamily == OPENBSD_AF_INET6), ], PadField(IPField("daddr", "127.0.0.1"), 16, padwith=b"\x00"), ), ShortField("sport", 0), ShortField("dport", 0), ] def mysummary(self): return self.sprintf( "%PFLog.addrfamily% %PFLog.action% on %PFLog.iface% by rule %PFLog.rulenumber%" ) # noqa: E501
def randval(self): return IP6Field.randval(self)
def h2i(self, pkt, x): return IP6Field.h2i(self, pkt, x)
class ARP(Packet): name = "ARP" fields_desc = [ XShortField("hwtype", 0x0001), XShortEnumField("ptype", 0x0800, ETHER_TYPES), FieldLenField("hwlen", None, fmt="B", length_of="hwsrc"), FieldLenField("plen", None, fmt="B", length_of="psrc"), ShortEnumField("op", 1, { "who-has": 1, "is-at": 2, "RARP-req": 3, "RARP-rep": 4, "Dyn-RARP-req": 5, "Dyn-RAR-rep": 6, "Dyn-RARP-err": 7, "InARP-req": 8, "InARP-rep": 9 }), MultipleTypeField( [ (SourceMACField("hwsrc"), (lambda pkt: pkt.hwtype == 1 and pkt.hwlen == 6, lambda pkt, val: pkt.hwtype == 1 and ( pkt.hwlen == 6 or (pkt.hwlen is None and (val is None or len(val) == 6 or valid_mac(val))) ))), ], StrFixedLenField("hwsrc", None, length_from=lambda pkt: pkt.hwlen), ), MultipleTypeField( [ (SourceIPField("psrc", "pdst"), (lambda pkt: pkt.ptype == 0x0800 and pkt.plen == 4, lambda pkt, val: pkt.ptype == 0x0800 and ( pkt.plen == 4 or (pkt.plen is None and (val is None or valid_net(val))) ))), (SourceIP6Field("psrc", "pdst"), (lambda pkt: pkt.ptype == 0x86dd and pkt.plen == 16, lambda pkt, val: pkt.ptype == 0x86dd and ( pkt.plen == 16 or (pkt.plen is None and (val is None or valid_net6(val))) ))), ], StrFixedLenField("psrc", None, length_from=lambda pkt: pkt.plen), ), MultipleTypeField( [ (MACField("hwdst", ETHER_ANY), (lambda pkt: pkt.hwtype == 1 and pkt.hwlen == 6, lambda pkt, val: pkt.hwtype == 1 and ( pkt.hwlen == 6 or (pkt.hwlen is None and (val is None or len(val) == 6 or valid_mac(val))) ))), ], StrFixedLenField("hwdst", None, length_from=lambda pkt: pkt.hwlen), ), MultipleTypeField( [ (IPField("pdst", "0.0.0.0"), (lambda pkt: pkt.ptype == 0x0800 and pkt.plen == 4, lambda pkt, val: pkt.ptype == 0x0800 and ( pkt.plen == 4 or (pkt.plen is None and (val is None or valid_net(val))) ))), (IP6Field("pdst", "::"), (lambda pkt: pkt.ptype == 0x86dd and pkt.plen == 16, lambda pkt, val: pkt.ptype == 0x86dd and ( pkt.plen == 16 or (pkt.plen is None and (val is None or valid_net6(val))) ))), ], StrFixedLenField("pdst", None, length_from=lambda pkt: pkt.plen), ), ] def hashret(self): return struct.pack(">HHH", self.hwtype, self.ptype, ((self.op + 1) // 2)) + self.payload.hashret() def answers(self, other): if not isinstance(other, ARP): return False if self.op != other.op + 1: return False # We use a loose comparison on psrc vs pdst to catch answers # with ARP leaks self_psrc = self.get_field('psrc').i2m(self, self.psrc) other_pdst = other.get_field('pdst').i2m(other, other.pdst) return self_psrc[:len(other_pdst)] == other_pdst[:len(self_psrc)] def route(self): fld, dst = self.getfield_and_val("pdst") fld, dst = fld._find_fld_pkt_val(self, dst) if isinstance(dst, Gen): dst = next(iter(dst)) if isinstance(fld, IP6Field): return conf.route6.route(dst) elif isinstance(fld, IPField): return conf.route.route(dst) else: return None, None, None def extract_padding(self, s): return "", s def mysummary(self): if self.op == 1: return self.sprintf("ARP who has %pdst% says %psrc%") if self.op == 2: return self.sprintf("ARP is at %hwsrc% says %psrc%") return self.sprintf("ARP %op% %psrc% > %pdst%")