pypcapkit 1.3.3.post1__cp313-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pcapkit/__init__.py +126 -0
- pcapkit/__main__.py +138 -0
- pcapkit/all.py +136 -0
- pcapkit/const/__init__.py +81 -0
- pcapkit/const/arp/__init__.py +25 -0
- pcapkit/const/arp/hardware.py +181 -0
- pcapkit/const/arp/operation.py +131 -0
- pcapkit/const/ftp/__init__.py +25 -0
- pcapkit/const/ftp/command.py +309 -0
- pcapkit/const/ftp/return_code.py +304 -0
- pcapkit/const/hip/__init__.py +94 -0
- pcapkit/const/hip/certificate.py +77 -0
- pcapkit/const/hip/cipher.py +65 -0
- pcapkit/const/hip/di.py +59 -0
- pcapkit/const/hip/ecdsa_curve.py +59 -0
- pcapkit/const/hip/ecdsa_low_curve.py +56 -0
- pcapkit/const/hip/eddsa_curve.py +65 -0
- pcapkit/const/hip/esp_transform_suite.py +98 -0
- pcapkit/const/hip/group.py +86 -0
- pcapkit/const/hip/hi_algorithm.py +86 -0
- pcapkit/const/hip/hit_suite.py +68 -0
- pcapkit/const/hip/nat_traversal.py +62 -0
- pcapkit/const/hip/notify_message.py +200 -0
- pcapkit/const/hip/packet.py +89 -0
- pcapkit/const/hip/parameter.py +377 -0
- pcapkit/const/hip/registration.py +68 -0
- pcapkit/const/hip/registration_failure.py +84 -0
- pcapkit/const/hip/suite.py +71 -0
- pcapkit/const/hip/transport.py +59 -0
- pcapkit/const/http/__init__.py +39 -0
- pcapkit/const/http/error_code.py +95 -0
- pcapkit/const/http/frame.py +95 -0
- pcapkit/const/http/method.py +184 -0
- pcapkit/const/http/setting.py +96 -0
- pcapkit/const/http/status_code.py +294 -0
- pcapkit/const/ipv4/__init__.py +57 -0
- pcapkit/const/ipv4/classification_level.py +64 -0
- pcapkit/const/ipv4/option_class.py +55 -0
- pcapkit/const/ipv4/option_number.py +137 -0
- pcapkit/const/ipv4/protection_authority.py +63 -0
- pcapkit/const/ipv4/qs_function.py +51 -0
- pcapkit/const/ipv4/router_alert.py +251 -0
- pcapkit/const/ipv4/tos_del.py +51 -0
- pcapkit/const/ipv4/tos_ecn.py +55 -0
- pcapkit/const/ipv4/tos_pre.py +63 -0
- pcapkit/const/ipv4/tos_rel.py +51 -0
- pcapkit/const/ipv4/tos_thr.py +51 -0
- pcapkit/const/ipv4/ts_flag.py +53 -0
- pcapkit/const/ipv6/__init__.py +53 -0
- pcapkit/const/ipv6/extension_header.py +66 -0
- pcapkit/const/ipv6/option.py +137 -0
- pcapkit/const/ipv6/option_action.py +55 -0
- pcapkit/const/ipv6/qs_function.py +51 -0
- pcapkit/const/ipv6/router_alert.py +266 -0
- pcapkit/const/ipv6/routing.py +80 -0
- pcapkit/const/ipv6/seed_id.py +55 -0
- pcapkit/const/ipv6/smf_dpd_mode.py +51 -0
- pcapkit/const/ipv6/tagger_id.py +62 -0
- pcapkit/const/ipx/__init__.py +27 -0
- pcapkit/const/ipx/packet.py +72 -0
- pcapkit/const/ipx/socket.py +104 -0
- pcapkit/const/l2tp/__init__.py +21 -0
- pcapkit/const/l2tp/type.py +51 -0
- pcapkit/const/mh/__init__.py +204 -0
- pcapkit/const/mh/access_type.py +92 -0
- pcapkit/const/mh/ack_status_code.py +71 -0
- pcapkit/const/mh/ani_suboption.py +74 -0
- pcapkit/const/mh/auth_subtype.py +53 -0
- pcapkit/const/mh/binding_ack_flag.py +66 -0
- pcapkit/const/mh/binding_error.py +51 -0
- pcapkit/const/mh/binding_revocation.py +59 -0
- pcapkit/const/mh/binding_update_flag.py +81 -0
- pcapkit/const/mh/cga_extension.py +66 -0
- pcapkit/const/mh/cga_sec.py +57 -0
- pcapkit/const/mh/cga_type.py +68 -0
- pcapkit/const/mh/dhcp_support_mode.py +53 -0
- pcapkit/const/mh/dns_status_code.py +65 -0
- pcapkit/const/mh/dsmip6_tls_packet.py +62 -0
- pcapkit/const/mh/dsmipv6_home_address.py +74 -0
- pcapkit/const/mh/enumerating_algorithm.py +56 -0
- pcapkit/const/mh/fb_ack_status.py +62 -0
- pcapkit/const/mh/fb_action.py +71 -0
- pcapkit/const/mh/fb_indication_trigger.py +65 -0
- pcapkit/const/mh/fb_type.py +59 -0
- pcapkit/const/mh/flow_id_status.py +77 -0
- pcapkit/const/mh/flow_id_suboption.py +71 -0
- pcapkit/const/mh/handoff_type.py +71 -0
- pcapkit/const/mh/handover_ack_flag.py +54 -0
- pcapkit/const/mh/handover_ack_status.py +92 -0
- pcapkit/const/mh/handover_initiate_flag.py +57 -0
- pcapkit/const/mh/handover_initiate_status.py +62 -0
- pcapkit/const/mh/home_address_reply.py +71 -0
- pcapkit/const/mh/lla_code.py +63 -0
- pcapkit/const/mh/lma_mag_suboption.py +59 -0
- pcapkit/const/mh/mn_group_id.py +59 -0
- pcapkit/const/mh/mn_id_subtype.py +77 -0
- pcapkit/const/mh/operator_id.py +63 -0
- pcapkit/const/mh/option.py +260 -0
- pcapkit/const/mh/packet.py +119 -0
- pcapkit/const/mh/qos_attribute.py +89 -0
- pcapkit/const/mh/revocation_status_code.py +83 -0
- pcapkit/const/mh/revocation_trigger.py +86 -0
- pcapkit/const/mh/status_code.py +232 -0
- pcapkit/const/mh/traffic_selector.py +62 -0
- pcapkit/const/mh/upa_status.py +71 -0
- pcapkit/const/mh/upn_reason.py +80 -0
- pcapkit/const/ospf/__init__.py +27 -0
- pcapkit/const/ospf/authentication.py +65 -0
- pcapkit/const/ospf/packet.py +71 -0
- pcapkit/const/pcapng/__init__.py +51 -0
- pcapkit/const/pcapng/block_type.py +152 -0
- pcapkit/const/pcapng/filter_type.py +48 -0
- pcapkit/const/pcapng/hash_algorithm.py +59 -0
- pcapkit/const/pcapng/option_type.py +233 -0
- pcapkit/const/pcapng/record_type.py +57 -0
- pcapkit/const/pcapng/secrets_type.py +56 -0
- pcapkit/const/pcapng/verdict_type.py +53 -0
- pcapkit/const/reg/__init__.py +34 -0
- pcapkit/const/reg/apptype.py +32702 -0
- pcapkit/const/reg/ethertype.py +714 -0
- pcapkit/const/reg/linktype.py +902 -0
- pcapkit/const/reg/transtype.py +523 -0
- pcapkit/const/tcp/__init__.py +35 -0
- pcapkit/const/tcp/checksum.py +55 -0
- pcapkit/const/tcp/flags.py +73 -0
- pcapkit/const/tcp/mp_tcp_option.py +80 -0
- pcapkit/const/tcp/option.py +198 -0
- pcapkit/const/vlan/__init__.py +23 -0
- pcapkit/const/vlan/priority_level.py +71 -0
- pcapkit/corekit/__init__.py +59 -0
- pcapkit/corekit/fields/__init__.py +45 -0
- pcapkit/corekit/fields/collections.py +282 -0
- pcapkit/corekit/fields/field.py +269 -0
- pcapkit/corekit/fields/ipaddress.py +274 -0
- pcapkit/corekit/fields/misc.py +722 -0
- pcapkit/corekit/fields/numbers.py +375 -0
- pcapkit/corekit/fields/strings.py +245 -0
- pcapkit/corekit/infoclass.py +394 -0
- pcapkit/corekit/io.py +506 -0
- pcapkit/corekit/module.py +39 -0
- pcapkit/corekit/multidict.py +626 -0
- pcapkit/corekit/protochain.py +263 -0
- pcapkit/corekit/version.py +33 -0
- pcapkit/dumpkit/__init__.py +15 -0
- pcapkit/dumpkit/common.py +199 -0
- pcapkit/dumpkit/null.py +77 -0
- pcapkit/dumpkit/pcap.py +144 -0
- pcapkit/foundation/__init__.py +45 -0
- pcapkit/foundation/engines/__init__.py +36 -0
- pcapkit/foundation/engines/dpkt.py +230 -0
- pcapkit/foundation/engines/engine.py +194 -0
- pcapkit/foundation/engines/pcap.py +188 -0
- pcapkit/foundation/engines/pcapng.py +310 -0
- pcapkit/foundation/engines/pyshark.py +166 -0
- pcapkit/foundation/engines/scapy.py +161 -0
- pcapkit/foundation/extraction.py +915 -0
- pcapkit/foundation/reassembly/__init__.py +49 -0
- pcapkit/foundation/reassembly/data/__init__.py +48 -0
- pcapkit/foundation/reassembly/data/ip.py +117 -0
- pcapkit/foundation/reassembly/data/tcp.py +145 -0
- pcapkit/foundation/reassembly/ip.py +192 -0
- pcapkit/foundation/reassembly/ipv4.py +50 -0
- pcapkit/foundation/reassembly/ipv6.py +50 -0
- pcapkit/foundation/reassembly/reassembly.py +389 -0
- pcapkit/foundation/reassembly/tcp.py +249 -0
- pcapkit/foundation/registry/__init__.py +41 -0
- pcapkit/foundation/registry/foundation.py +327 -0
- pcapkit/foundation/registry/protocols.py +885 -0
- pcapkit/foundation/traceflow/__init__.py +44 -0
- pcapkit/foundation/traceflow/data/__init__.py +30 -0
- pcapkit/foundation/traceflow/data/tcp.py +105 -0
- pcapkit/foundation/traceflow/tcp.py +159 -0
- pcapkit/foundation/traceflow/traceflow.py +390 -0
- pcapkit/interface/__init__.py +22 -0
- pcapkit/interface/core.py +185 -0
- pcapkit/interface/misc.py +120 -0
- pcapkit/protocols/__init__.py +85 -0
- pcapkit/protocols/application/NotImplemented/bgp.py +0 -0
- pcapkit/protocols/application/NotImplemented/dhcp.py +0 -0
- pcapkit/protocols/application/NotImplemented/dhcpv6.py +0 -0
- pcapkit/protocols/application/NotImplemented/dns.py +0 -0
- pcapkit/protocols/application/NotImplemented/imap.py +0 -0
- pcapkit/protocols/application/NotImplemented/ldap.py +0 -0
- pcapkit/protocols/application/NotImplemented/mqtt.py +0 -0
- pcapkit/protocols/application/NotImplemented/nntp.py +0 -0
- pcapkit/protocols/application/NotImplemented/ntp.py +0 -0
- pcapkit/protocols/application/NotImplemented/onc_rpc.py +0 -0
- pcapkit/protocols/application/NotImplemented/pop.py +0 -0
- pcapkit/protocols/application/NotImplemented/rip.py +0 -0
- pcapkit/protocols/application/NotImplemented/rtp.py +0 -0
- pcapkit/protocols/application/NotImplemented/sip.py +0 -0
- pcapkit/protocols/application/NotImplemented/smtp.py +0 -0
- pcapkit/protocols/application/NotImplemented/snmp.py +0 -0
- pcapkit/protocols/application/NotImplemented/ssh.py +0 -0
- pcapkit/protocols/application/NotImplemented/telnet.py +0 -0
- pcapkit/protocols/application/NotImplemented/tls.py +0 -0
- pcapkit/protocols/application/NotImplemented/xmpp.py +0 -0
- pcapkit/protocols/application/__init__.py +34 -0
- pcapkit/protocols/application/application.py +114 -0
- pcapkit/protocols/application/ftp.py +206 -0
- pcapkit/protocols/application/http.py +176 -0
- pcapkit/protocols/application/httpv1.py +320 -0
- pcapkit/protocols/application/httpv2.py +1255 -0
- pcapkit/protocols/data/__init__.py +192 -0
- pcapkit/protocols/data/application/__init__.py +57 -0
- pcapkit/protocols/data/application/ftp.py +59 -0
- pcapkit/protocols/data/application/httpv1.py +79 -0
- pcapkit/protocols/data/application/httpv2.py +293 -0
- pcapkit/protocols/data/data.py +25 -0
- pcapkit/protocols/data/internet/__init__.py +298 -0
- pcapkit/protocols/data/internet/ah.py +31 -0
- pcapkit/protocols/data/internet/hip.py +804 -0
- pcapkit/protocols/data/internet/hopopt.py +351 -0
- pcapkit/protocols/data/internet/ipv4.py +369 -0
- pcapkit/protocols/data/internet/ipv6.py +67 -0
- pcapkit/protocols/data/internet/ipv6_frag.py +29 -0
- pcapkit/protocols/data/internet/ipv6_opts.py +368 -0
- pcapkit/protocols/data/internet/ipv6_route.py +86 -0
- pcapkit/protocols/data/internet/ipx.py +56 -0
- pcapkit/protocols/data/internet/mh.py +509 -0
- pcapkit/protocols/data/link/__init__.py +33 -0
- pcapkit/protocols/data/link/arp.py +74 -0
- pcapkit/protocols/data/link/ethernet.py +28 -0
- pcapkit/protocols/data/link/l2tp.py +63 -0
- pcapkit/protocols/data/link/ospf.py +58 -0
- pcapkit/protocols/data/link/vlan.py +42 -0
- pcapkit/protocols/data/misc/__init__.py +109 -0
- pcapkit/protocols/data/misc/null.py +18 -0
- pcapkit/protocols/data/misc/pcap/__init__.py +18 -0
- pcapkit/protocols/data/misc/pcap/frame.py +56 -0
- pcapkit/protocols/data/misc/pcap/header.py +53 -0
- pcapkit/protocols/data/misc/pcapng.py +925 -0
- pcapkit/protocols/data/misc/raw.py +25 -0
- pcapkit/protocols/data/protocol.py +32 -0
- pcapkit/protocols/data/transport/__init__.py +71 -0
- pcapkit/protocols/data/transport/tcp.py +555 -0
- pcapkit/protocols/data/transport/udp.py +29 -0
- pcapkit/protocols/internet/NotImplemented/ecn.py +0 -0
- pcapkit/protocols/internet/NotImplemented/esp.py +97 -0
- pcapkit/protocols/internet/NotImplemented/icmp.py +0 -0
- pcapkit/protocols/internet/NotImplemented/icmpv6.py +0 -0
- pcapkit/protocols/internet/NotImplemented/igmp.py +0 -0
- pcapkit/protocols/internet/NotImplemented/shim6.py +0 -0
- pcapkit/protocols/internet/__init__.py +43 -0
- pcapkit/protocols/internet/ah.py +275 -0
- pcapkit/protocols/internet/hip.py +4727 -0
- pcapkit/protocols/internet/hopopt.py +1879 -0
- pcapkit/protocols/internet/internet.py +240 -0
- pcapkit/protocols/internet/ip.py +51 -0
- pcapkit/protocols/internet/ipsec.py +50 -0
- pcapkit/protocols/internet/ipv4.py +1782 -0
- pcapkit/protocols/internet/ipv6.py +361 -0
- pcapkit/protocols/internet/ipv6_frag.py +258 -0
- pcapkit/protocols/internet/ipv6_opts.py +1890 -0
- pcapkit/protocols/internet/ipv6_route.py +710 -0
- pcapkit/protocols/internet/ipx.py +230 -0
- pcapkit/protocols/internet/mh.py +2764 -0
- pcapkit/protocols/link/NotImplemented/dsl.py +0 -0
- pcapkit/protocols/link/NotImplemented/eapol.py +1 -0
- pcapkit/protocols/link/NotImplemented/fddi.py +0 -0
- pcapkit/protocols/link/NotImplemented/isdn.py +0 -0
- pcapkit/protocols/link/NotImplemented/ndp.py +0 -0
- pcapkit/protocols/link/NotImplemented/ppp.py +0 -0
- pcapkit/protocols/link/__init__.py +35 -0
- pcapkit/protocols/link/arp.py +421 -0
- pcapkit/protocols/link/ethernet.py +248 -0
- pcapkit/protocols/link/l2tp.py +267 -0
- pcapkit/protocols/link/link.py +140 -0
- pcapkit/protocols/link/ospf.py +342 -0
- pcapkit/protocols/link/rarp.py +82 -0
- pcapkit/protocols/link/vlan.py +225 -0
- pcapkit/protocols/misc/__init__.py +37 -0
- pcapkit/protocols/misc/null.py +129 -0
- pcapkit/protocols/misc/pcap/__init__.py +17 -0
- pcapkit/protocols/misc/pcap/frame.py +478 -0
- pcapkit/protocols/misc/pcap/header.py +358 -0
- pcapkit/protocols/misc/pcapng.py +5520 -0
- pcapkit/protocols/misc/raw.py +180 -0
- pcapkit/protocols/protocol.py +1216 -0
- pcapkit/protocols/schema/__init__.py +140 -0
- pcapkit/protocols/schema/application/__init__.py +40 -0
- pcapkit/protocols/schema/application/ftp.py +21 -0
- pcapkit/protocols/schema/application/httpv1.py +21 -0
- pcapkit/protocols/schema/application/httpv2.py +384 -0
- pcapkit/protocols/schema/internet/__init__.py +294 -0
- pcapkit/protocols/schema/internet/ah.py +40 -0
- pcapkit/protocols/schema/internet/hip.py +1184 -0
- pcapkit/protocols/schema/internet/hopopt.py +679 -0
- pcapkit/protocols/schema/internet/ipv4.py +576 -0
- pcapkit/protocols/schema/internet/ipv6.py +63 -0
- pcapkit/protocols/schema/internet/ipv6_frag.py +48 -0
- pcapkit/protocols/schema/internet/ipv6_opts.py +680 -0
- pcapkit/protocols/schema/internet/ipv6_route.py +198 -0
- pcapkit/protocols/schema/internet/ipx.py +40 -0
- pcapkit/protocols/schema/internet/mh.py +718 -0
- pcapkit/protocols/schema/link/__init__.py +19 -0
- pcapkit/protocols/schema/link/arp.py +39 -0
- pcapkit/protocols/schema/link/ethernet.py +51 -0
- pcapkit/protocols/schema/link/l2tp.py +88 -0
- pcapkit/protocols/schema/link/ospf.py +90 -0
- pcapkit/protocols/schema/link/vlan.py +69 -0
- pcapkit/protocols/schema/misc/__init__.py +108 -0
- pcapkit/protocols/schema/misc/null.py +18 -0
- pcapkit/protocols/schema/misc/pcap/__init__.py +10 -0
- pcapkit/protocols/schema/misc/pcap/frame.py +51 -0
- pcapkit/protocols/schema/misc/pcap/header.py +63 -0
- pcapkit/protocols/schema/misc/pcapng.py +1689 -0
- pcapkit/protocols/schema/misc/raw.py +24 -0
- pcapkit/protocols/schema/schema.py +809 -0
- pcapkit/protocols/schema/transport/__init__.py +69 -0
- pcapkit/protocols/schema/transport/tcp.py +928 -0
- pcapkit/protocols/schema/transport/udp.py +90 -0
- pcapkit/protocols/transport/NotImplemented/dccp.py +0 -0
- pcapkit/protocols/transport/NotImplemented/rsvp.py +0 -0
- pcapkit/protocols/transport/NotImplemented/sctp.py +0 -0
- pcapkit/protocols/transport/__init__.py +27 -0
- pcapkit/protocols/transport/tcp.py +3025 -0
- pcapkit/protocols/transport/transport.py +158 -0
- pcapkit/protocols/transport/udp.py +214 -0
- pcapkit/py.typed +0 -0
- pcapkit/toolkit/__init__.py +57 -0
- pcapkit/toolkit/dpkt.py +306 -0
- pcapkit/toolkit/pcap.py +212 -0
- pcapkit/toolkit/pcapng.py +251 -0
- pcapkit/toolkit/pyshark.py +99 -0
- pcapkit/toolkit/scapy.py +297 -0
- pcapkit/utilities/__init__.py +20 -0
- pcapkit/utilities/compat.py +196 -0
- pcapkit/utilities/decorators.py +192 -0
- pcapkit/utilities/exceptions.py +365 -0
- pcapkit/utilities/logging.py +55 -0
- pcapkit/utilities/warnings.py +185 -0
- pcapkit/vendor/__init__.py +105 -0
- pcapkit/vendor/__main__.py +92 -0
- pcapkit/vendor/arp/__init__.py +27 -0
- pcapkit/vendor/arp/hardware.py +29 -0
- pcapkit/vendor/arp/operation.py +29 -0
- pcapkit/vendor/default.py +474 -0
- pcapkit/vendor/ftp/__init__.py +27 -0
- pcapkit/vendor/ftp/command.py +244 -0
- pcapkit/vendor/ftp/return_code.py +256 -0
- pcapkit/vendor/hip/__init__.py +94 -0
- pcapkit/vendor/hip/certificate.py +29 -0
- pcapkit/vendor/hip/cipher.py +29 -0
- pcapkit/vendor/hip/di.py +29 -0
- pcapkit/vendor/hip/ecdsa_curve.py +29 -0
- pcapkit/vendor/hip/ecdsa_low_curve.py +29 -0
- pcapkit/vendor/hip/eddsa_curve.py +85 -0
- pcapkit/vendor/hip/esp_transform_suite.py +29 -0
- pcapkit/vendor/hip/group.py +87 -0
- pcapkit/vendor/hip/hi_algorithm.py +29 -0
- pcapkit/vendor/hip/hit_suite.py +29 -0
- pcapkit/vendor/hip/nat_traversal.py +29 -0
- pcapkit/vendor/hip/notify_message.py +29 -0
- pcapkit/vendor/hip/packet.py +88 -0
- pcapkit/vendor/hip/parameter.py +88 -0
- pcapkit/vendor/hip/registration.py +29 -0
- pcapkit/vendor/hip/registration_failure.py +29 -0
- pcapkit/vendor/hip/suite.py +29 -0
- pcapkit/vendor/hip/transport.py +29 -0
- pcapkit/vendor/http/__init__.py +39 -0
- pcapkit/vendor/http/error_code.py +95 -0
- pcapkit/vendor/http/frame.py +91 -0
- pcapkit/vendor/http/method.py +167 -0
- pcapkit/vendor/http/setting.py +93 -0
- pcapkit/vendor/http/status_code.py +185 -0
- pcapkit/vendor/ipv4/__init__.py +57 -0
- pcapkit/vendor/ipv4/classification_level.py +91 -0
- pcapkit/vendor/ipv4/option_class.py +80 -0
- pcapkit/vendor/ipv4/option_number.py +105 -0
- pcapkit/vendor/ipv4/protection_authority.py +84 -0
- pcapkit/vendor/ipv4/qs_function.py +78 -0
- pcapkit/vendor/ipv4/router_alert.py +93 -0
- pcapkit/vendor/ipv4/tos_del.py +78 -0
- pcapkit/vendor/ipv4/tos_ecn.py +95 -0
- pcapkit/vendor/ipv4/tos_pre.py +84 -0
- pcapkit/vendor/ipv4/tos_rel.py +78 -0
- pcapkit/vendor/ipv4/tos_thr.py +77 -0
- pcapkit/vendor/ipv4/ts_flag.py +79 -0
- pcapkit/vendor/ipv6/__init__.py +53 -0
- pcapkit/vendor/ipv6/extension_header.py +171 -0
- pcapkit/vendor/ipv6/option.py +104 -0
- pcapkit/vendor/ipv6/option_action.py +90 -0
- pcapkit/vendor/ipv6/qs_function.py +78 -0
- pcapkit/vendor/ipv6/router_alert.py +93 -0
- pcapkit/vendor/ipv6/routing.py +87 -0
- pcapkit/vendor/ipv6/seed_id.py +81 -0
- pcapkit/vendor/ipv6/smf_dpd_mode.py +78 -0
- pcapkit/vendor/ipv6/tagger_id.py +81 -0
- pcapkit/vendor/ipx/__init__.py +37 -0
- pcapkit/vendor/ipx/packet.py +123 -0
- pcapkit/vendor/ipx/socket.py +125 -0
- pcapkit/vendor/l2tp/__init__.py +21 -0
- pcapkit/vendor/l2tp/type.py +78 -0
- pcapkit/vendor/mh/__init__.py +204 -0
- pcapkit/vendor/mh/access_type.py +87 -0
- pcapkit/vendor/mh/ack_status_code.py +88 -0
- pcapkit/vendor/mh/ani_suboption.py +88 -0
- pcapkit/vendor/mh/auth_subtype.py +83 -0
- pcapkit/vendor/mh/binding_ack_flag.py +148 -0
- pcapkit/vendor/mh/binding_error.py +78 -0
- pcapkit/vendor/mh/binding_revocation.py +87 -0
- pcapkit/vendor/mh/binding_update_flag.py +147 -0
- pcapkit/vendor/mh/cga_extension.py +91 -0
- pcapkit/vendor/mh/cga_sec.py +91 -0
- pcapkit/vendor/mh/cga_type.py +74 -0
- pcapkit/vendor/mh/dhcp_support_mode.py +77 -0
- pcapkit/vendor/mh/dns_status_code.py +87 -0
- pcapkit/vendor/mh/dsmip6_tls_packet.py +87 -0
- pcapkit/vendor/mh/dsmipv6_home_address.py +87 -0
- pcapkit/vendor/mh/enumerating_algorithm.py +82 -0
- pcapkit/vendor/mh/fb_ack_status.py +87 -0
- pcapkit/vendor/mh/fb_action.py +88 -0
- pcapkit/vendor/mh/fb_indication_trigger.py +87 -0
- pcapkit/vendor/mh/fb_type.py +88 -0
- pcapkit/vendor/mh/flow_id_status.py +87 -0
- pcapkit/vendor/mh/flow_id_suboption.py +87 -0
- pcapkit/vendor/mh/handoff_type.py +87 -0
- pcapkit/vendor/mh/handover_ack_flag.py +143 -0
- pcapkit/vendor/mh/handover_ack_status.py +87 -0
- pcapkit/vendor/mh/handover_initiate_flag.py +143 -0
- pcapkit/vendor/mh/handover_initiate_status.py +87 -0
- pcapkit/vendor/mh/home_address_reply.py +87 -0
- pcapkit/vendor/mh/lla_code.py +97 -0
- pcapkit/vendor/mh/lma_mag_suboption.py +88 -0
- pcapkit/vendor/mh/mn_group_id.py +87 -0
- pcapkit/vendor/mh/mn_id_subtype.py +87 -0
- pcapkit/vendor/mh/operator_id.py +87 -0
- pcapkit/vendor/mh/option.py +83 -0
- pcapkit/vendor/mh/packet.py +82 -0
- pcapkit/vendor/mh/qos_attribute.py +87 -0
- pcapkit/vendor/mh/revocation_status_code.py +87 -0
- pcapkit/vendor/mh/revocation_trigger.py +87 -0
- pcapkit/vendor/mh/status_code.py +91 -0
- pcapkit/vendor/mh/traffic_selector.py +87 -0
- pcapkit/vendor/mh/upa_status.py +87 -0
- pcapkit/vendor/mh/upn_reason.py +87 -0
- pcapkit/vendor/ospf/__init__.py +27 -0
- pcapkit/vendor/ospf/authentication.py +29 -0
- pcapkit/vendor/ospf/packet.py +29 -0
- pcapkit/vendor/pcapng/__init__.py +51 -0
- pcapkit/vendor/pcapng/block_type.py +94 -0
- pcapkit/vendor/pcapng/filter_type.py +77 -0
- pcapkit/vendor/pcapng/hash_algorithm.py +82 -0
- pcapkit/vendor/pcapng/option_type.py +287 -0
- pcapkit/vendor/pcapng/record_type.py +81 -0
- pcapkit/vendor/pcapng/secrets_type.py +81 -0
- pcapkit/vendor/pcapng/verdict_type.py +79 -0
- pcapkit/vendor/reg/__init__.py +34 -0
- pcapkit/vendor/reg/apptype.py +338 -0
- pcapkit/vendor/reg/ethertype.py +121 -0
- pcapkit/vendor/reg/linktype.py +110 -0
- pcapkit/vendor/reg/transtype.py +111 -0
- pcapkit/vendor/tcp/__init__.py +35 -0
- pcapkit/vendor/tcp/checksum.py +80 -0
- pcapkit/vendor/tcp/flags.py +149 -0
- pcapkit/vendor/tcp/mp_tcp_option.py +90 -0
- pcapkit/vendor/tcp/option.py +103 -0
- pcapkit/vendor/vlan/__init__.py +23 -0
- pcapkit/vendor/vlan/priority_level.py +97 -0
- pypcapkit-1.3.3.post1.dist-info/LICENSE +29 -0
- pypcapkit-1.3.3.post1.dist-info/METADATA +236 -0
- pypcapkit-1.3.3.post1.dist-info/RECORD +466 -0
- pypcapkit-1.3.3.post1.dist-info/WHEEL +5 -0
- pypcapkit-1.3.3.post1.dist-info/entry_points.txt +3 -0
- pypcapkit-1.3.3.post1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,251 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""PCAP-NG-NG Tools
|
3
|
+
===================
|
4
|
+
|
5
|
+
.. module:: pcapkit.toolkit.pcapng
|
6
|
+
|
7
|
+
:mod:`pcapkit.toolkit.pcapng` contains all you need
|
8
|
+
for :mod:`pcapkit` handy usage of PCAP-NG-NG file format.
|
9
|
+
All functions returns with a flag to indicate if
|
10
|
+
usable for its caller.
|
11
|
+
|
12
|
+
"""
|
13
|
+
from typing import TYPE_CHECKING, cast
|
14
|
+
|
15
|
+
from pcapkit.const.ipv6.extension_header import ExtensionHeader as Enum_ExtensionHeader
|
16
|
+
from pcapkit.foundation.reassembly.data.ip import Packet as IP_Packet
|
17
|
+
from pcapkit.foundation.reassembly.data.tcp import Packet as TCP_Packet
|
18
|
+
from pcapkit.foundation.traceflow.data.tcp import Packet as TF_TCP_Packet
|
19
|
+
from pcapkit.protocols.data.misc.pcap.frame import Frame as Data_Frame
|
20
|
+
from pcapkit.protocols.data.misc.pcap.frame import FrameInfo as Data_FrameInfo
|
21
|
+
|
22
|
+
if TYPE_CHECKING:
|
23
|
+
from ipaddress import IPv4Address, IPv6Address
|
24
|
+
|
25
|
+
from pcapkit.protocols.internet.ipv4 import IPv4
|
26
|
+
from pcapkit.protocols.internet.ipv6 import IPv6
|
27
|
+
from pcapkit.protocols.internet.ipv6_frag import IPv6_Frag
|
28
|
+
from pcapkit.protocols.misc.pcapng import PCAPNG, Packet
|
29
|
+
from pcapkit.protocols.transport.tcp import TCP
|
30
|
+
|
31
|
+
__all__ = ['ipv4_reassembly', 'ipv6_reassembly', 'tcp_reassembly',
|
32
|
+
'tcp_traceflow', 'block2frame']
|
33
|
+
|
34
|
+
|
35
|
+
def ipv4_reassembly(frame: 'PCAPNG') -> 'IP_Packet[IPv4Address] | None':
|
36
|
+
"""Make data for IPv4 reassembly.
|
37
|
+
|
38
|
+
Args:
|
39
|
+
frame: PCAP-NG frame.
|
40
|
+
|
41
|
+
Returns:
|
42
|
+
Data for IPv4 reassembly.
|
43
|
+
|
44
|
+
* If the ``frame`` can be used for IPv4 reassembly. A frame can be reassembled
|
45
|
+
if it contains IPv4 layer (:class:`~pcapkit.protocols.internet.ipv4.IPv4`) and
|
46
|
+
the **DF** (:attr:`IPv4.flags.df <pcapkit.protocols.data.internet.ipv4.Flags.df>`)
|
47
|
+
flag is :data:`False`.
|
48
|
+
* If the ``frame`` can be reassembled, then the :obj:`dict` mapping of data for IPv4
|
49
|
+
reassembly (c.f. :term:`reasm.ipv4.packet`) will be returned; otherwise, returns :data:`None`.
|
50
|
+
|
51
|
+
See Also:
|
52
|
+
:class:`pcapkit.foundation.reassembly.ipv4.IPv4`
|
53
|
+
|
54
|
+
"""
|
55
|
+
if 'IPv4' in frame:
|
56
|
+
ipv4 = cast('IPv4', frame['IPv4'])
|
57
|
+
ipv4_info = ipv4.info
|
58
|
+
if ipv4_info.flags.df: # dismiss not fragmented frame
|
59
|
+
return None
|
60
|
+
|
61
|
+
frame_info = cast('Packet', frame.info)
|
62
|
+
data = IP_Packet(
|
63
|
+
bufid=(
|
64
|
+
ipv4_info.src, # source IP address
|
65
|
+
ipv4_info.dst, # destination IP address
|
66
|
+
ipv4_info.id, # identification
|
67
|
+
ipv4_info.protocol, # payload protocol type
|
68
|
+
),
|
69
|
+
num=frame_info.number, # original packet range number
|
70
|
+
fo=ipv4_info.offset, # fragment offset
|
71
|
+
ihl=ipv4_info.hdr_len, # internet header length
|
72
|
+
mf=ipv4_info.flags.mf, # more fragment flag
|
73
|
+
tl=ipv4_info.len, # total length, header includes
|
74
|
+
header=ipv4.packet.header, # raw bytes type header
|
75
|
+
payload=bytearray(ipv4.packet.payload), # raw bytearray type payload
|
76
|
+
)
|
77
|
+
return data
|
78
|
+
return None
|
79
|
+
|
80
|
+
|
81
|
+
def ipv6_reassembly(frame: 'PCAPNG') -> 'IP_Packet[IPv6Address] | None':
|
82
|
+
"""Make data for IPv6 reassembly.
|
83
|
+
|
84
|
+
Args:
|
85
|
+
frame: PCAP-NG frame.
|
86
|
+
|
87
|
+
Returns:
|
88
|
+
A tuple of data for IPv6 reassembly.
|
89
|
+
|
90
|
+
* If the ``frame`` can be used for IPv6 reassembly. A frame can be reassembled
|
91
|
+
if it contains IPv6 layer (:class:`~pcapkit.protocols.internet.ipv6.IPv6`) and
|
92
|
+
IPv6 Fragment header (:rfc:`2460#section-4.5`, i.e.,
|
93
|
+
:class:`~pcapkit.protocols.internet.ipv6_frag.IPv6_Frag`).
|
94
|
+
* If the ``frame`` can be reassembled, then the :obj:`dict` mapping of data for IPv6
|
95
|
+
reassembly (:term:`reasm.ipv6.packet`) will be returned; otherwise, returns :data:`None`.
|
96
|
+
|
97
|
+
See Also:
|
98
|
+
:class:`pcapkit.foundation.reassembly.ipv6.IPv6`
|
99
|
+
|
100
|
+
"""
|
101
|
+
if 'IPv6' in frame:
|
102
|
+
ipv6 = cast('IPv6', frame['IPv6'])
|
103
|
+
ipv6_info = ipv6.info
|
104
|
+
if (ipv6_frag := ipv6.extension_headers.get( # type: ignore[call-overload]
|
105
|
+
Enum_ExtensionHeader.IPv6_Frag
|
106
|
+
)) is None: # dismiss not fragmented frame
|
107
|
+
return None
|
108
|
+
ipv6_frag_info = cast('IPv6_Frag', ipv6_frag).info
|
109
|
+
|
110
|
+
frame_info = cast('Packet', frame.info)
|
111
|
+
data = IP_Packet(
|
112
|
+
bufid=(
|
113
|
+
ipv6_info.src, # source IP address
|
114
|
+
ipv6_info.dst, # destination IP address
|
115
|
+
ipv6_info.label, # label
|
116
|
+
ipv6_frag_info.next, # next header field in IPv6 Fragment Header
|
117
|
+
),
|
118
|
+
num=frame_info.number, # original packet range number
|
119
|
+
fo=ipv6_frag_info.offset, # fragment offset
|
120
|
+
ihl=ipv6_info.hdr_len, # header length, only headers before IPv6-Frag
|
121
|
+
mf=ipv6_frag_info.mf, # more fragment flag
|
122
|
+
tl=ipv6_info.hdr_len + ipv6_info.raw_len, # total length, header includes
|
123
|
+
header=ipv6_info.fragment.header, # raw bytearray type header before IPv6-Frag
|
124
|
+
payload=bytearray(ipv6_info.fragment.payload), # raw bytearray type payload after IPv6-Frag
|
125
|
+
)
|
126
|
+
return data
|
127
|
+
return None
|
128
|
+
|
129
|
+
|
130
|
+
def tcp_reassembly(frame: 'PCAPNG') -> 'TCP_Packet | None':
|
131
|
+
"""Make data for TCP reassembly.
|
132
|
+
|
133
|
+
Args:
|
134
|
+
frame: PCAP-NG frame.
|
135
|
+
|
136
|
+
Returns:
|
137
|
+
A tuple of data for TCP reassembly.
|
138
|
+
|
139
|
+
* If the ``frame`` can be used for TCP reassembly. A frame can be reassembled
|
140
|
+
if it contains TCP layer (:class:`~pcapkit.protocols.transport.tcp.TCP`).
|
141
|
+
* If the ``frame`` can be reassembled, then the :obj:`dict` mapping of data for TCP
|
142
|
+
reassembly (:term:`reasm.tcp.packet`) will be returned; otherwise, returns :data:`None`.
|
143
|
+
|
144
|
+
See Also:
|
145
|
+
:class:`pcapkit.foundation.reassembly.tcp.TCP`
|
146
|
+
|
147
|
+
"""
|
148
|
+
if 'TCP' in frame:
|
149
|
+
ip = cast('IPv4 | IPv6', frame['IP'])
|
150
|
+
ip_info = ip.info
|
151
|
+
tcp = cast('TCP', frame['TCP'])
|
152
|
+
tcp_info = tcp.info
|
153
|
+
|
154
|
+
raw_len = len(tcp.packet.payload)
|
155
|
+
frame_info = cast('Packet', frame.info)
|
156
|
+
|
157
|
+
data = TCP_Packet(
|
158
|
+
bufid=(
|
159
|
+
ip_info.src, # source IP address
|
160
|
+
tcp_info.srcport.port, # source port
|
161
|
+
ip_info.dst, # destination IP address
|
162
|
+
tcp_info.dstport.port, # destination port
|
163
|
+
),
|
164
|
+
num=frame_info.number, # original packet range number
|
165
|
+
ack=tcp_info.ack, # acknowledgement
|
166
|
+
dsn=tcp_info.seq, # data sequence number
|
167
|
+
syn=tcp_info.flags.syn, # synchronise flag
|
168
|
+
fin=tcp_info.flags.fin, # finish flag
|
169
|
+
rst=tcp_info.flags.rst, # reset connection flag
|
170
|
+
header=tcp.packet.header, # raw bytes type header
|
171
|
+
payload=bytearray(tcp.packet.payload), # raw bytearray type payload
|
172
|
+
first=tcp_info.seq, # this sequence number
|
173
|
+
last=tcp_info.seq + raw_len, # next (wanted) sequence number
|
174
|
+
len=raw_len, # payload length, header excludes
|
175
|
+
)
|
176
|
+
return data
|
177
|
+
return None
|
178
|
+
|
179
|
+
|
180
|
+
def tcp_traceflow(frame: 'PCAPNG', *, nanosecond: 'bool' = False) -> 'TF_TCP_Packet | None':
|
181
|
+
"""Trace packet flow for TCP.
|
182
|
+
|
183
|
+
Args:
|
184
|
+
frame: PCAP-NG frame.
|
185
|
+
nanosecond: Whether to use nanosecond precision.
|
186
|
+
|
187
|
+
Returns:
|
188
|
+
Data for TCP reassembly.
|
189
|
+
|
190
|
+
* If the ``packet`` can be used for TCP flow tracing. A frame can be reassembled
|
191
|
+
if it contains TCP layer (:class:`~pcapkit.protocols.transport.tcp.TCP`).
|
192
|
+
* If the ``frame`` can be reassembled, then the :obj:`dict` mapping of data for TCP
|
193
|
+
flow tracing (:term:`trace.tcp.packet`) will be returned; otherwise, returns :data:`None`.
|
194
|
+
|
195
|
+
See Also:
|
196
|
+
:class:`pcapkit.foundation.traceflow.tcp.TCP`
|
197
|
+
|
198
|
+
"""
|
199
|
+
if 'TCP' in frame:
|
200
|
+
ip = cast('IPv4 | IPv6', frame['IP'])
|
201
|
+
ip_info = ip.info
|
202
|
+
tcp = cast('TCP', frame['TCP'])
|
203
|
+
tcp_info = tcp.info
|
204
|
+
|
205
|
+
frame_info = cast('Packet', frame.info)
|
206
|
+
data = TF_TCP_Packet( # type: ignore[type-var]
|
207
|
+
protocol=frame.linktype, # data link type from global header
|
208
|
+
index=frame_info.number, # frame number
|
209
|
+
frame=block2frame(frame_info, nanosecond=nanosecond),
|
210
|
+
# extracted frame info
|
211
|
+
syn=tcp_info.flags.syn, # TCP synchronise (SYN) flag
|
212
|
+
fin=tcp_info.flags.fin, # TCP finish (FIN) flag
|
213
|
+
src=ip_info.src, # source IP
|
214
|
+
dst=ip_info.dst, # destination IP
|
215
|
+
srcport=tcp_info.srcport.port, # TCP source port
|
216
|
+
dstport=tcp_info.dstport.port, # TCP destination port
|
217
|
+
timestamp=float(frame_info.timestamp_epoch), # frame timestamp
|
218
|
+
)
|
219
|
+
return data
|
220
|
+
return None
|
221
|
+
|
222
|
+
|
223
|
+
def block2frame(block: 'Packet', *, nanosecond: 'bool' = False) -> 'Data_Frame':
|
224
|
+
"""Convert PCAP-NG block to PCAP frame.
|
225
|
+
|
226
|
+
Args:
|
227
|
+
block: PCAP-NG block.
|
228
|
+
nanosecond: Whether to use nanosecond precision.
|
229
|
+
|
230
|
+
Returns:
|
231
|
+
PCAP frame.
|
232
|
+
|
233
|
+
"""
|
234
|
+
ts_sec = int(block.timestamp_epoch)
|
235
|
+
ts_usec = int(block.timestamp_epoch - ts_sec) * (1_000_000_000 if nanosecond else 1_000_000)
|
236
|
+
|
237
|
+
frame = Data_Frame(
|
238
|
+
frame_info=Data_FrameInfo(
|
239
|
+
ts_sec=ts_sec,
|
240
|
+
ts_usec=ts_usec,
|
241
|
+
incl_len=block.captured_len,
|
242
|
+
orig_len=block.original_len,
|
243
|
+
),
|
244
|
+
time=block.timestamp,
|
245
|
+
number=block.number,
|
246
|
+
time_epoch=block.timestamp_epoch,
|
247
|
+
len=block.original_len,
|
248
|
+
cap_len=block.captured_len,
|
249
|
+
)
|
250
|
+
frame.__update__(packet=block.packet)
|
251
|
+
return frame
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""PyShark Tools
|
3
|
+
===================
|
4
|
+
|
5
|
+
:mod:`pcapkit.toolkit.pyshark` contains all you need for
|
6
|
+
:mod:`pcapkit` handy usage with `PyShark`_ engine. All
|
7
|
+
reforming functions returns with a flag to indicate if
|
8
|
+
usable for its caller.
|
9
|
+
|
10
|
+
.. _PyShark: https://kiminewt.github.io/pyshark
|
11
|
+
|
12
|
+
.. note::
|
13
|
+
|
14
|
+
Due to the lack of functionality of `PyShark`_, some
|
15
|
+
functions of :mod:`pcapkit` may not be available with
|
16
|
+
the `PyShark`_ engine.
|
17
|
+
|
18
|
+
"""
|
19
|
+
import ipaddress
|
20
|
+
from typing import TYPE_CHECKING, cast
|
21
|
+
|
22
|
+
from pcapkit.const.reg.linktype import LinkType as Enum_LinkType
|
23
|
+
from pcapkit.foundation.traceflow.data.tcp import Packet as TF_TCP_Packet
|
24
|
+
|
25
|
+
if TYPE_CHECKING:
|
26
|
+
from typing import Any
|
27
|
+
|
28
|
+
from pyshark.packet.packet import Packet
|
29
|
+
|
30
|
+
__all__ = ['packet2dict', 'tcp_traceflow']
|
31
|
+
|
32
|
+
|
33
|
+
def packet2dict(packet: 'Packet') -> 'dict[str, Any]':
|
34
|
+
"""Convert PyShark packet into :obj:`dict`.
|
35
|
+
|
36
|
+
Args:
|
37
|
+
packet: Scapy packet.
|
38
|
+
|
39
|
+
Returns:
|
40
|
+
A :obj:`dict` mapping of packet data.
|
41
|
+
|
42
|
+
"""
|
43
|
+
dict_ = {} # type: dict[str, Any]
|
44
|
+
frame = packet.frame_info
|
45
|
+
for field in frame.field_names:
|
46
|
+
dict_[field] = getattr(frame, field)
|
47
|
+
|
48
|
+
tempdict = dict_
|
49
|
+
for layer in packet.layers:
|
50
|
+
tempdict[layer.layer_name.upper()] = {}
|
51
|
+
tempdict = tempdict[layer.layer_name.upper()]
|
52
|
+
for field in layer.field_names:
|
53
|
+
tempdict[field] = getattr(layer, field)
|
54
|
+
|
55
|
+
return dict_
|
56
|
+
|
57
|
+
|
58
|
+
def tcp_traceflow(packet: 'Packet') -> 'TF_TCP_Packet | None':
|
59
|
+
"""Trace packet flow for TCP.
|
60
|
+
|
61
|
+
Args:
|
62
|
+
packet: Scapy packet.
|
63
|
+
|
64
|
+
Returns:
|
65
|
+
Tuple[bool, Dict[str, Any]]: A tuple of data for TCP reassembly.
|
66
|
+
|
67
|
+
* If the ``packet`` can be used for TCP flow tracing. A packet can be reassembled
|
68
|
+
if it contains TCP layer.
|
69
|
+
* If the ``packet`` can be reassembled, then the :obj:`dict` mapping of data for TCP
|
70
|
+
flow tracing (:term:`trace.tcp.packet`) will be returned; otherwise, returns :data:`None`.
|
71
|
+
|
72
|
+
See Also:
|
73
|
+
:class:`pcapkit.foundation.traceflow.tcp.TCP`
|
74
|
+
|
75
|
+
"""
|
76
|
+
if 'IP' in packet:
|
77
|
+
ip = cast('Packet', packet.ip)
|
78
|
+
elif 'IPv6' in packet:
|
79
|
+
ip = cast('Packet', packet.ipv6)
|
80
|
+
else:
|
81
|
+
return None
|
82
|
+
|
83
|
+
if 'TCP' in packet:
|
84
|
+
tcp = cast('Packet', packet.tcp)
|
85
|
+
|
86
|
+
data = TF_TCP_Packet( # type: ignore[type-var]
|
87
|
+
protocol=Enum_LinkType.get(packet.layers[0].layer_name.upper()), # data link type from global header
|
88
|
+
index=int(packet.number), # frame number
|
89
|
+
frame=packet2dict(packet), # extracted packet
|
90
|
+
syn=bool(int(tcp.flags_syn)), # TCP synchronise (SYN) flag
|
91
|
+
fin=bool(int(tcp.flags_fin)), # TCP finish (FIN) flag
|
92
|
+
src=ipaddress.ip_address(ip.src), # source IP
|
93
|
+
dst=ipaddress.ip_address(ip.dst), # destination IP
|
94
|
+
srcport=int(tcp.srcport), # TCP source port
|
95
|
+
dstport=int(tcp.dstport), # TCP destination port
|
96
|
+
timestamp=packet.frame_info.time_epoch, # timestamp
|
97
|
+
)
|
98
|
+
return data
|
99
|
+
return None
|
pcapkit/toolkit/scapy.py
ADDED
@@ -0,0 +1,297 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""Scapy Tools
|
3
|
+
=================
|
4
|
+
|
5
|
+
.. module:: pcapkit.toolkit.scapy
|
6
|
+
|
7
|
+
:mod:`pcapkit.toolkit.scapy` contains all you need for
|
8
|
+
:mod:`pcapkit` handy usage with `Scapy`_ engine. All reforming
|
9
|
+
functions returns with a flag to indicate if usable for
|
10
|
+
its caller.
|
11
|
+
|
12
|
+
.. _Scapy: https://scapy.net
|
13
|
+
|
14
|
+
.. warning::
|
15
|
+
|
16
|
+
This module requires installed `Scapy`_ engine.
|
17
|
+
|
18
|
+
"""
|
19
|
+
import ipaddress
|
20
|
+
import time
|
21
|
+
from typing import TYPE_CHECKING, cast
|
22
|
+
|
23
|
+
from pcapkit.const.reg.linktype import LinkType as Enum_LinkType
|
24
|
+
from pcapkit.const.reg.transtype import TransType as Enum_TransType
|
25
|
+
from pcapkit.foundation.reassembly.data.ip import Packet as IP_Packet
|
26
|
+
from pcapkit.foundation.reassembly.data.tcp import Packet as TCP_Packet
|
27
|
+
from pcapkit.foundation.traceflow.data.tcp import Packet as TF_TCP_Packet
|
28
|
+
from pcapkit.utilities.compat import ModuleNotFoundError # pylint: disable=redefined-builtin
|
29
|
+
from pcapkit.utilities.exceptions import ModuleNotFound, stacklevel
|
30
|
+
from pcapkit.utilities.warnings import ScapyWarning, warn
|
31
|
+
|
32
|
+
try:
|
33
|
+
import scapy
|
34
|
+
except ModuleNotFoundError:
|
35
|
+
scapy = None
|
36
|
+
warn("dependency package 'Scapy' not found",
|
37
|
+
ScapyWarning, stacklevel=stacklevel())
|
38
|
+
|
39
|
+
if TYPE_CHECKING:
|
40
|
+
from ipaddress import IPv4Address, IPv6Address
|
41
|
+
from typing import Any
|
42
|
+
|
43
|
+
from scapy.layers.inet import IP, TCP
|
44
|
+
from scapy.layers.inet6 import IPv6
|
45
|
+
from scapy.packet import Packet
|
46
|
+
|
47
|
+
__all__ = [
|
48
|
+
'packet2chain', 'packet2dict',
|
49
|
+
'ipv4_reassembly', 'ipv6_reassembly', 'tcp_reassembly', 'tcp_traceflow'
|
50
|
+
]
|
51
|
+
|
52
|
+
|
53
|
+
def packet2chain(packet: 'Packet') -> 'str':
|
54
|
+
"""Fetch Scapy packet protocol chain.
|
55
|
+
|
56
|
+
Args:
|
57
|
+
packet: Scapy packet.
|
58
|
+
|
59
|
+
Returns:
|
60
|
+
Colon (``:``) seperated list of protocol chain.
|
61
|
+
|
62
|
+
Raises:
|
63
|
+
ModuleNotFound: If `Scapy`_ is not installed.
|
64
|
+
|
65
|
+
"""
|
66
|
+
if scapy is None:
|
67
|
+
raise ModuleNotFound("No module named 'scapy'", name='scapy')
|
68
|
+
from scapy.packet import NoPayload
|
69
|
+
|
70
|
+
chain = [packet.name]
|
71
|
+
payload = packet.payload
|
72
|
+
while not isinstance(payload, NoPayload):
|
73
|
+
chain.append(payload.name)
|
74
|
+
payload = payload.payload
|
75
|
+
return ':'.join(chain)
|
76
|
+
|
77
|
+
|
78
|
+
def packet2dict(packet: 'Packet') -> 'dict[str, Any]':
|
79
|
+
"""Convert Scapy packet into :obj:`dict`.
|
80
|
+
|
81
|
+
Args:
|
82
|
+
packet: Scapy packet.
|
83
|
+
|
84
|
+
Returns:
|
85
|
+
A :obj:`dict` mapping of packet data.
|
86
|
+
|
87
|
+
Raises:
|
88
|
+
ModuleNotFound: If `Scapy`_ is not installed.
|
89
|
+
|
90
|
+
"""
|
91
|
+
if scapy is None:
|
92
|
+
raise ModuleNotFound("No module named 'scapy'", name='scapy')
|
93
|
+
from scapy.packet import NoPayload
|
94
|
+
|
95
|
+
def wrapper(packet: 'Packet') -> 'dict[str, Any]':
|
96
|
+
dict_ = packet.fields
|
97
|
+
payload = packet.payload
|
98
|
+
if not isinstance(payload, NoPayload):
|
99
|
+
dict_[payload.name] = wrapper(payload)
|
100
|
+
return dict_
|
101
|
+
|
102
|
+
return {
|
103
|
+
'packet': bytes(packet),
|
104
|
+
packet.name: wrapper(packet),
|
105
|
+
}
|
106
|
+
|
107
|
+
|
108
|
+
def ipv4_reassembly(packet: 'Packet', *, count: 'int' = -1) -> 'IP_Packet[IPv4Address] | None':
|
109
|
+
"""Make data for IPv4 reassembly.
|
110
|
+
|
111
|
+
Args:
|
112
|
+
packet: Scapy packet.
|
113
|
+
count: Packet index. If not provided, default to ``-1``.
|
114
|
+
|
115
|
+
Returns:
|
116
|
+
Data for IPv4 reassembly.
|
117
|
+
|
118
|
+
* If the ``packet`` can be used for IPv4 reassembly. A packet can be reassembled
|
119
|
+
if it contains IPv4 layer (:class:`scapy.layers.inet.IP`) and the **DF**
|
120
|
+
(:attr:`scapy.layers.inet.IP.flags.DF`) flag is :data:`False`.
|
121
|
+
* If the ``packet`` can be reassembled, then the :obj:`dict` mapping of data for IPv4
|
122
|
+
reassembly (:term:`reasm.ipv4.packet`) will be returned; otherwise, returns :data:`None`.
|
123
|
+
|
124
|
+
See Also:
|
125
|
+
:class:`pcapkit.foundation.reassembly.ipv4.IPv4`
|
126
|
+
|
127
|
+
"""
|
128
|
+
if 'IP' in packet:
|
129
|
+
ipv4 = cast('IP', packet['IP'])
|
130
|
+
if ipv4.flags.DF: # dismiss not fragmented packet
|
131
|
+
return None
|
132
|
+
|
133
|
+
data = IP_Packet(
|
134
|
+
bufid=(
|
135
|
+
cast('IPv4Address',
|
136
|
+
ipaddress.ip_address(ipv4.src)), # source IP address
|
137
|
+
cast('IPv4Address',
|
138
|
+
ipaddress.ip_address(ipv4.dst)), # destination IP address
|
139
|
+
ipv4.id, # identification
|
140
|
+
Enum_TransType.get(ipv4.proto), # payload protocol type
|
141
|
+
),
|
142
|
+
num=count, # original packet range number
|
143
|
+
fo=ipv4.frag, # fragment offset
|
144
|
+
ihl=ipv4.ihl, # internet header length
|
145
|
+
mf=bool(ipv4.flags.MF), # more fragment flag
|
146
|
+
tl=ipv4.len, # total length, header includes
|
147
|
+
header=ipv4.raw_packet_cache, # raw bytes type header
|
148
|
+
payload=bytearray(bytes(ipv4.payload)), # raw bytearray type payload
|
149
|
+
)
|
150
|
+
return data
|
151
|
+
return None
|
152
|
+
|
153
|
+
|
154
|
+
def ipv6_reassembly(packet: 'Packet', *, count: 'int' = -1) -> 'IP_Packet[IPv6Address] | None':
|
155
|
+
"""Make data for IPv6 reassembly.
|
156
|
+
|
157
|
+
Args:
|
158
|
+
packet: Scapy packet.
|
159
|
+
count: Packet index. If not provided, default to ``-1``.
|
160
|
+
|
161
|
+
Returns:
|
162
|
+
Data for IPv6 reassembly.
|
163
|
+
|
164
|
+
* If the ``packet`` can be used for IPv6 reassembly. A packet can be reassembled
|
165
|
+
if it contains IPv6 layer (:class:`scapy.layers.inet6.IPv6`) and IPv6 Fragment
|
166
|
+
header (:rfc:`2460#section-4.5`, i.e., :class:`scapy.layers.inet6.IPv6ExtHdrFragment`).
|
167
|
+
* If the ``packet`` can be reassembled, then the :obj:`dict` mapping of data for IPv6
|
168
|
+
reassembly (:term:`reasm.ipv6.packet`) will be returned; otherwise, returns :data:`None`.
|
169
|
+
|
170
|
+
Raises:
|
171
|
+
ModuleNotFound: If `Scapy`_ is not installed.
|
172
|
+
|
173
|
+
See Also:
|
174
|
+
:class:`pcapkit.foundation.reassembly.ipv6.IPv6`
|
175
|
+
|
176
|
+
"""
|
177
|
+
if scapy is None:
|
178
|
+
raise ModuleNotFound("No module named 'scapy'", name='scapy')
|
179
|
+
from scapy.layers.inet6 import IPv6ExtHdrFragment
|
180
|
+
|
181
|
+
if 'IPv6' in packet:
|
182
|
+
ipv6 = cast('IPv6', packet['IPv6'])
|
183
|
+
if IPv6ExtHdrFragment not in ipv6: # pylint: disable=E1101
|
184
|
+
return None # dismiss not fragmented packet
|
185
|
+
ipv6_frag = cast('IPv6ExtHdrFragment', ipv6['IPv6ExtHdrFragment'])
|
186
|
+
|
187
|
+
data = IP_Packet(
|
188
|
+
bufid=(
|
189
|
+
cast('IPv6Address',
|
190
|
+
ipaddress.ip_address(ipv6.src)), # source IP address
|
191
|
+
cast('IPv6Address',
|
192
|
+
ipaddress.ip_address(ipv6.dst)), # destination IP address
|
193
|
+
ipv6.fl, # label
|
194
|
+
Enum_TransType.get(ipv6_frag.nh), # next header field in IPv6 Fragment Header
|
195
|
+
),
|
196
|
+
num=count, # original packet range number
|
197
|
+
fo=ipv6_frag.offset, # fragment offset
|
198
|
+
ihl=len(ipv6) - len(ipv6_frag), # header length, only headers before IPv6-Frag
|
199
|
+
mf=bool(ipv6_frag.m), # more fragment flag
|
200
|
+
tl=len(ipv6), # total length, header includes
|
201
|
+
header=bytes(ipv6)[:-len(ipv6_frag)], # raw bytes type header before IPv6-Frag
|
202
|
+
payload=bytearray(bytes(ipv6_frag.payload)), # raw bytearray type payload after IPv6-Frag
|
203
|
+
)
|
204
|
+
return data
|
205
|
+
return None
|
206
|
+
|
207
|
+
|
208
|
+
def tcp_reassembly(packet: 'Packet', *, count: 'int' = -1) -> 'TCP_Packet | None':
|
209
|
+
"""Store data for TCP reassembly.
|
210
|
+
|
211
|
+
Args:
|
212
|
+
packet: Scapy packet.
|
213
|
+
count: Packet index. If not provided, default to ``-1``.
|
214
|
+
|
215
|
+
Returns:
|
216
|
+
Data for TCP reassembly.
|
217
|
+
|
218
|
+
* If the ``packet`` can be used for TCP reassembly. A packet can be reassembled
|
219
|
+
if it contains TCP layer (:class:`scapy.layers.inet.TCP`).
|
220
|
+
* If the ``packet`` can be reassembled, then the :obj:`dict` mapping of data for TCP
|
221
|
+
reassembly (:term:`reasm.tcp.packet`) will be returned; otherwise, returns :data:`None`.
|
222
|
+
|
223
|
+
See Also:
|
224
|
+
:class:`pcapkit.foundation.reassembly.tcp.TCP`
|
225
|
+
|
226
|
+
"""
|
227
|
+
if 'IP' in packet:
|
228
|
+
ip = cast('IP', packet['IP'])
|
229
|
+
elif 'IPv6' in packet:
|
230
|
+
ip = cast('IPv6', packet['IPv6'])
|
231
|
+
else:
|
232
|
+
return None
|
233
|
+
|
234
|
+
if 'TCP' in packet:
|
235
|
+
tcp = cast('TCP', packet['TCP'])
|
236
|
+
|
237
|
+
raw_len = len(tcp.payload) # payload length, header excludes
|
238
|
+
data = TCP_Packet(
|
239
|
+
bufid=(
|
240
|
+
ipaddress.ip_address(ip.src), # source IP address
|
241
|
+
tcp.sport, # source port
|
242
|
+
ipaddress.ip_address(ip.dst), # destination IP address
|
243
|
+
tcp.dport, # destination port
|
244
|
+
),
|
245
|
+
num=count, # original packet range number
|
246
|
+
ack=tcp.ack, # acknowledgement
|
247
|
+
dsn=tcp.seq, # data sequence number
|
248
|
+
syn=bool(tcp.flags.S), # synchronise flag
|
249
|
+
fin=bool(tcp.flags.F), # finish flag
|
250
|
+
rst=bool(tcp.flags.R), # reset connection flag
|
251
|
+
header=tcp.raw_packet_cache, # raw bytes type header
|
252
|
+
payload=bytearray(bytes(tcp.payload)), # raw bytearray type payload
|
253
|
+
first=tcp.seq, # this sequence number
|
254
|
+
last=tcp.seq + raw_len, # next (wanted) sequence number
|
255
|
+
len=raw_len, # payload length, header excludes
|
256
|
+
)
|
257
|
+
return data
|
258
|
+
return None
|
259
|
+
|
260
|
+
|
261
|
+
def tcp_traceflow(packet: 'Packet', *, count: 'int' = -1) -> 'TF_TCP_Packet | None':
|
262
|
+
"""Trace packet flow for TCP.
|
263
|
+
|
264
|
+
Args:
|
265
|
+
packet: Scapy packet.
|
266
|
+
count: Packet index. If not provided, default to ``-1``.
|
267
|
+
|
268
|
+
Returns:
|
269
|
+
Data for TCP reassembly.
|
270
|
+
|
271
|
+
* If the ``packet`` can be used for TCP flow tracing. A packet can be reassembled
|
272
|
+
if it contains TCP layer (:class:`scapy.layers.inet.TCP`).
|
273
|
+
* If the ``packet`` can be reassembled, then the :obj:`dict` mapping of data for TCP
|
274
|
+
flow tracing (:term:`trace.tcp.packet`) will be returned; otherwise, returns :data:`None`.
|
275
|
+
|
276
|
+
See Also:
|
277
|
+
:class:`pcapkit.foundation.traceflow.tcp.TCP`
|
278
|
+
|
279
|
+
"""
|
280
|
+
if 'TCP' in packet:
|
281
|
+
ip = cast('IP', packet['IP']) if 'IP' in packet else cast('IPv6', packet['IPv6'])
|
282
|
+
tcp = cast('TCP', packet['TCP'])
|
283
|
+
|
284
|
+
data = TF_TCP_Packet( # type: ignore[type-var]
|
285
|
+
protocol=Enum_LinkType.get(packet.name.upper()), # data link type from global header
|
286
|
+
index=count, # frame number
|
287
|
+
frame=packet2dict(packet), # extracted packet
|
288
|
+
syn=bool(tcp.flags.S), # TCP synchronise (SYN) flag
|
289
|
+
fin=bool(tcp.flags.F), # TCP finish (FIN) flag
|
290
|
+
src=ipaddress.ip_address(ip.src), # source IP
|
291
|
+
dst=ipaddress.ip_address(ip.dst), # destination IP
|
292
|
+
srcport=tcp.sport, # TCP source port
|
293
|
+
dstport=tcp.dport, # TCP destination port
|
294
|
+
timestamp=time.time(), # timestamp
|
295
|
+
)
|
296
|
+
return data
|
297
|
+
return None
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# pylint: disable=unused-wildcard-import
|
3
|
+
"""Module Utilities
|
4
|
+
======================
|
5
|
+
|
6
|
+
.. module:: pcapkit.utilities
|
7
|
+
|
8
|
+
:mod:`pcapkit.utilities` contains several useful functions
|
9
|
+
and classes which are fundations of :mod:`pcapkit`, including
|
10
|
+
decorater function :func:`~pcapkit.utilities.decorators.seekset`
|
11
|
+
and :func:`~pcapkit.utilities.decorators.beholder`, etc., and
|
12
|
+
several user-refined exceptions and warnings.
|
13
|
+
|
14
|
+
"""
|
15
|
+
from pcapkit.utilities.decorators import beholder, prepare, seekset
|
16
|
+
from pcapkit.utilities.exceptions import stacklevel
|
17
|
+
from pcapkit.utilities.logging import logger
|
18
|
+
from pcapkit.utilities.warnings import warn
|
19
|
+
|
20
|
+
__all__ = ['logger', 'warn', 'stacklevel']
|