feat: add EtherType and IP Protocol enums for enhanced packet parsing and logging
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 9s
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 9s
This commit is contained in:
139
backend/src/Models/etherType.py
Normal file
139
backend/src/Models/etherType.py
Normal file
@@ -0,0 +1,139 @@
|
||||
from enum import Enum
|
||||
from typing import Dict
|
||||
|
||||
"""
|
||||
This module defines an enumeration for Ethernet frame types (EtherTypes) and provides a mapping
|
||||
from numeric EtherType values to their corresponding enum representation.
|
||||
Source: https://en.wikipedia.org/wiki/EtherType (01/12/2025)
|
||||
"""
|
||||
|
||||
|
||||
class EtherTypeEnum(str, Enum):
|
||||
IPv4 = "Internet Protocol version 4"
|
||||
CHAOSNET = "Chaosnet"
|
||||
ARP = "Address Resolution Protocol"
|
||||
WAKE_ON_LAN = "Wake-on-LAN"
|
||||
SRP = "Stream Reservation Protocol"
|
||||
AVTP = "Audio Video Transport Protocol"
|
||||
TRILL = "IETF TRILL Protocol"
|
||||
DEC_MOP_RC = "DEC MOP RC"
|
||||
DECNET_PHASE_IV = "DECnet Phase IV / DNA Routing"
|
||||
DEC_LAT = "DEC Local Area Transport"
|
||||
RARP = "Reverse Address Resolution Protocol"
|
||||
APPLETALK = "AppleTalk (EtherTalk)"
|
||||
IBM_SNA = "IBM SNA / LLC PDU"
|
||||
AARP = "AppleTalk Address Resolution Protocol"
|
||||
VLAN_8021Q = "VLAN-tagged (802.1Q)"
|
||||
SLPP = "Simple Loop Prevention Protocol"
|
||||
VLACP = "Virtual Link Aggregation Control Protocol"
|
||||
IPX = "IPX"
|
||||
QNX_QNET = "QNX Qnet"
|
||||
IPv6 = "Internet Protocol version 6"
|
||||
FLOW_CONTROL = "Ethernet Flow Control"
|
||||
SLOW_PROTOCOLS = "Ethernet Slow Protocols (LACP)"
|
||||
COBRANET = "CobraNet"
|
||||
MPLS_UNICAST = "MPLS Unicast"
|
||||
MPLS_MULTICAST = "MPLS Multicast"
|
||||
PPPoE_DISCOVERY = "PPPoE Discovery Stage"
|
||||
PPPoE_SESSION = "PPPoE Session Stage"
|
||||
HOMEPLUG = "HomePlug 1.0 MME"
|
||||
EAPOL = "EAP over LAN (802.1X)"
|
||||
PROFINET = "PROFINET Protocol"
|
||||
HYPERSCSI = "HyperSCSI"
|
||||
ATA_OVER_ETHERNET = "ATA over Ethernet"
|
||||
ETHERCAT = "EtherCAT Protocol"
|
||||
Q_IN_Q = "Service VLAN (Q-in-Q S-Tag)"
|
||||
ETH_POWERLINK = "Ethernet Powerlink"
|
||||
GOOSE = "Generic Substation Events (GOOSE)"
|
||||
GSE = "GSE Management Services"
|
||||
SV = "Sampled Value Transmission"
|
||||
MIKROTIK_ROMON = "MikroTik RoMON"
|
||||
LLDP = "Link Layer Discovery Protocol"
|
||||
SERCOS_III = "SERCOS III"
|
||||
HOMEPLUG_GREENPHY = "HomePlug Green PHY"
|
||||
MRP = "Media Redundancy Protocol"
|
||||
MACSEC = "MAC Security (MACsec)"
|
||||
PBB = "Provider Backbone Bridges (PBB)"
|
||||
PTP = "Precision Time Protocol over Ethernet"
|
||||
NC_SI = "NC-SI"
|
||||
PRP = "Parallel Redundancy Protocol"
|
||||
CFM = "Connectivity Fault Management (802.1ag / Y.1731)"
|
||||
FCoE = "Fibre Channel over Ethernet"
|
||||
FCoE_INIT = "FCoE Initialization Protocol"
|
||||
ROCE = "RDMA over Converged Ethernet (RoCE)"
|
||||
TTE = "TTEthernet Protocol Control Frame"
|
||||
IEEE_1905_1 = "1905.1 IEEE Protocol"
|
||||
HSR = "High-availability Seamless Redundancy"
|
||||
ETH_CONFIG_TEST = "Ethernet Configuration Testing Protocol"
|
||||
REDUNDANCY_TAG = "Redundancy Tag (802.1CB)"
|
||||
UNKNOWN = "Unknown EtherType"
|
||||
|
||||
|
||||
# Mapping from integer EtherType → enum
|
||||
ETHERTYPE_MAP: Dict[int, EtherTypeEnum] = {
|
||||
0x0800: EtherTypeEnum.IPv4,
|
||||
0x0804: EtherTypeEnum.CHAOSNET,
|
||||
0x0806: EtherTypeEnum.ARP,
|
||||
0x0842: EtherTypeEnum.WAKE_ON_LAN,
|
||||
0x22EA: EtherTypeEnum.SRP,
|
||||
0x22F0: EtherTypeEnum.AVTP,
|
||||
0x22F3: EtherTypeEnum.TRILL,
|
||||
0x6002: EtherTypeEnum.DEC_MOP_RC,
|
||||
0x6003: EtherTypeEnum.DECNET_PHASE_IV,
|
||||
0x6004: EtherTypeEnum.DEC_LAT,
|
||||
0x8035: EtherTypeEnum.RARP,
|
||||
0x809B: EtherTypeEnum.APPLETALK,
|
||||
0x80D5: EtherTypeEnum.IBM_SNA,
|
||||
0x80F3: EtherTypeEnum.AARP,
|
||||
0x8100: EtherTypeEnum.VLAN_8021Q,
|
||||
0x8102: EtherTypeEnum.SLPP,
|
||||
0x8103: EtherTypeEnum.VLACP,
|
||||
0x8137: EtherTypeEnum.IPX,
|
||||
0x8204: EtherTypeEnum.QNX_QNET,
|
||||
0x86DD: EtherTypeEnum.IPv6,
|
||||
0x8808: EtherTypeEnum.FLOW_CONTROL,
|
||||
0x8809: EtherTypeEnum.SLOW_PROTOCOLS,
|
||||
0x8819: EtherTypeEnum.COBRANET,
|
||||
0x8847: EtherTypeEnum.MPLS_UNICAST,
|
||||
0x8848: EtherTypeEnum.MPLS_MULTICAST,
|
||||
0x8863: EtherTypeEnum.PPPoE_DISCOVERY,
|
||||
0x8864: EtherTypeEnum.PPPoE_SESSION,
|
||||
0x887B: EtherTypeEnum.HOMEPLUG,
|
||||
0x888E: EtherTypeEnum.EAPOL,
|
||||
0x8892: EtherTypeEnum.PROFINET,
|
||||
0x889A: EtherTypeEnum.HYPERSCSI,
|
||||
0x88A2: EtherTypeEnum.ATA_OVER_ETHERNET,
|
||||
0x88A4: EtherTypeEnum.ETHERCAT,
|
||||
0x88A8: EtherTypeEnum.Q_IN_Q,
|
||||
0x88AB: EtherTypeEnum.ETH_POWERLINK,
|
||||
0x88B8: EtherTypeEnum.GOOSE,
|
||||
0x88B9: EtherTypeEnum.GSE,
|
||||
0x88BA: EtherTypeEnum.SV,
|
||||
0x88BF: EtherTypeEnum.MIKROTIK_ROMON,
|
||||
0x88CC: EtherTypeEnum.LLDP,
|
||||
0x88CD: EtherTypeEnum.SERCOS_III,
|
||||
0x88E1: EtherTypeEnum.HOMEPLUG_GREENPHY,
|
||||
0x88E3: EtherTypeEnum.MRP,
|
||||
0x88E5: EtherTypeEnum.MACSEC,
|
||||
0x88E7: EtherTypeEnum.PBB,
|
||||
0x88F7: EtherTypeEnum.PTP,
|
||||
0x88F8: EtherTypeEnum.NC_SI,
|
||||
0x88FB: EtherTypeEnum.PRP,
|
||||
0x8902: EtherTypeEnum.CFM,
|
||||
0x8906: EtherTypeEnum.FCoE,
|
||||
0x8914: EtherTypeEnum.FCoE_INIT,
|
||||
0x8915: EtherTypeEnum.ROCE,
|
||||
0x891D: EtherTypeEnum.TTE,
|
||||
0x893A: EtherTypeEnum.IEEE_1905_1,
|
||||
0x892F: EtherTypeEnum.HSR,
|
||||
0x9000: EtherTypeEnum.ETH_CONFIG_TEST,
|
||||
0xF1C1: EtherTypeEnum.REDUNDANCY_TAG,
|
||||
}
|
||||
|
||||
|
||||
def ethertype_from_int(value: int) -> EtherTypeEnum:
|
||||
"""
|
||||
Map a numeric EtherType value to the corresponding enum.
|
||||
Returns UNKNOWN if not found.
|
||||
"""
|
||||
return ETHERTYPE_MAP.get(value, EtherTypeEnum.UNKNOWN)
|
||||
315
backend/src/Models/ip_protocol.py
Normal file
315
backend/src/Models/ip_protocol.py
Normal file
@@ -0,0 +1,315 @@
|
||||
from enum import Enum
|
||||
|
||||
"""
|
||||
This module defines an enumeration for IP protocol types and provides a mapping
|
||||
from numeric IP protocol values to their corresponding enum representation.
|
||||
Source: https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers (01/12/2025)
|
||||
"""
|
||||
|
||||
|
||||
class IPProtocolEnum(str, Enum):
|
||||
HOPOPT = "IPv6 Hop-by-Hop Option"
|
||||
ICMP = "Internet Control Message Protocol"
|
||||
IGMP = "Internet Group Management Protocol"
|
||||
GGP = "Gateway-to-Gateway Protocol"
|
||||
IP_IN_IP = "IP in IP Encapsulation"
|
||||
ST = "Internet Stream Protocol"
|
||||
TCP = "Transmission Control Protocol"
|
||||
CBT = "Core-based Trees"
|
||||
EGP = "Exterior Gateway Protocol"
|
||||
IGP = "Interior Gateway Protocol"
|
||||
BBN_RCC_MON = "BBN RCC Monitoring"
|
||||
NVP_II = "Network Voice Protocol"
|
||||
PUP = "Xerox PUP"
|
||||
ARGUS = "ARGUS"
|
||||
EMCON = "EMCON"
|
||||
XNET = "Cross Net Debugger"
|
||||
CHAOS = "Chaos Protocol"
|
||||
UDP = "User Datagram Protocol"
|
||||
MUX = "Multiplexing"
|
||||
DCN_MEAS = "DCN Measurement Subsystems"
|
||||
HMP = "Host Monitoring Protocol"
|
||||
PRM = "Packet Radio Measurement"
|
||||
XNS_IDP = "XEROX NS IDP"
|
||||
TRUNK_1 = "Trunk 1"
|
||||
TRUNK_2 = "Trunk 2"
|
||||
LEAF_1 = "Leaf 1"
|
||||
LEAF_2 = "Leaf 2"
|
||||
RDP = "Reliable Data Protocol"
|
||||
IRTP = "Internet Reliable Transaction Protocol"
|
||||
ISO_TP4 = "ISO Transport Protocol Class 4"
|
||||
NETBLT = "Bulk Data Transfer Protocol"
|
||||
MFE_NSP = "MFE Network Services Protocol"
|
||||
MERIT_INP = "MERIT Internodal Protocol"
|
||||
DCCP = "Datagram Congestion Control Protocol"
|
||||
THREE_PC = "Third Party Connect Protocol"
|
||||
IDPR = "Inter-Domain Policy Routing"
|
||||
XTP = "Xpress Transport Protocol"
|
||||
DDP = "Datagram Delivery Protocol"
|
||||
IDPR_CMTP = "IDPR Control Message Transport Protocol"
|
||||
TP_PP = "TP++ Transport Protocol"
|
||||
IL = "IL Transport Protocol"
|
||||
IPV6 = "IPv6 Encapsulation"
|
||||
SDRP = "Source Demand Routing Protocol"
|
||||
IPV6_ROUTE = "IPv6 Routing Header"
|
||||
IPV6_FRAG = "IPv6 Fragment Header"
|
||||
IDRP = "Inter-Domain Routing Protocol"
|
||||
RSVP = "Resource Reservation Protocol"
|
||||
GRE = "Generic Routing Encapsulation"
|
||||
DSR = "Dynamic Source Routing"
|
||||
BNA = "Burroughs Network Architecture"
|
||||
ESP = "Encapsulating Security Payload"
|
||||
AH = "Authentication Header"
|
||||
I_NLSP = "Integrated Net Layer Security Protocol"
|
||||
SWIPE = "SwIPe"
|
||||
NARP = "NBMA Address Resolution Protocol"
|
||||
MOBILE = "IP Mobility"
|
||||
TLSP = "Transport Layer Security Protocol"
|
||||
SKIP = "Simple Key-Management for IP"
|
||||
IPV6_ICMP = "ICMP for IPv6"
|
||||
IPV6_NONXT = "No Next Header for IPv6"
|
||||
IPV6_OPTS = "Destination Options for IPv6"
|
||||
PROTO_61 = "Any host internal protocol"
|
||||
CFTP = "CFTP"
|
||||
PROTO_63 = "Any local network"
|
||||
SAT_EXPAK = "SATNET and Backroom EXPAK"
|
||||
KRYPTOLAN = "Kryptolan"
|
||||
RVD = "MIT Remote Virtual Disk Protocol"
|
||||
IPPC = "Internet Pluribus Packet Core"
|
||||
PROTO_68 = "Any distributed file system"
|
||||
SAT_MON = "SATNET Monitoring"
|
||||
VISA = "VISA Protocol"
|
||||
IPCU = "Internet Packet Core Utility"
|
||||
CPNX = "Computer Protocol Network Executive"
|
||||
CPHB = "Computer Protocol Heart Beat"
|
||||
WSN = "Wang Span Network"
|
||||
PVP = "Packet Video Protocol"
|
||||
BR_SAT_MON = "Backroom SATNET Monitoring"
|
||||
SUN_ND = "SUN ND Protocol (temporary)"
|
||||
WB_MON = "Wideband Monitoring"
|
||||
WB_EXPAK = "Wideband EXPAK"
|
||||
ISO_IP = "International Organization for Standardization Internet Protocol"
|
||||
VMTP = "Versatile Message Transaction Protocol"
|
||||
SECURE_VMTP = "Secure VMTP"
|
||||
VINES = "VINES"
|
||||
TTP = "TTP (Transaction Transport Protocol / IPTM)"
|
||||
NSFNET_IGP = "NSFNET-IGP"
|
||||
DGP = "Dissimilar Gateway Protocol"
|
||||
TCF = "TCF"
|
||||
EIGRP = "EIGRP"
|
||||
OSPF = "Open Shortest Path First"
|
||||
SPRITE_RPC = "Sprite RPC Protocol"
|
||||
LARP = "Locus Address Resolution Protocol"
|
||||
MTP = "Multicast Transport Protocol"
|
||||
AX25 = "AX.25 Packet Radio"
|
||||
OS = "KA9Q NOS compatible IP over IP tunneling"
|
||||
MICP = "Mobile Internetworking Control Protocol"
|
||||
SCC_SP = "Semaphore Communications Security Protocol"
|
||||
ETHERIP = "Ethernet-within-IP Encapsulation"
|
||||
ENCAP = "Encapsulation Header"
|
||||
PROTO_99 = "Any private encryption scheme"
|
||||
GMTP = "GMTP"
|
||||
IFMP = "Ipsilon Flow Management Protocol"
|
||||
PNNI = "PNNI over IP"
|
||||
PIM = "Protocol Independent Multicast"
|
||||
ARIS = "IBM ARIS"
|
||||
SCPS = "Space Communications Protocol Standards"
|
||||
QNX = "QNX"
|
||||
AN = "Active Networks"
|
||||
IPCOMP = "IP Payload Compression Protocol"
|
||||
SNP = "Sitara Networks Protocol"
|
||||
COMPAQ_PEER = "Compaq Peer Protocol"
|
||||
IPX_IN_IP = "IPX in IP"
|
||||
VRRP = "Virtual Router Redundancy Protocol"
|
||||
PGM = "PGM Reliable Transport Protocol"
|
||||
PROTO_114 = "Any 0-hop protocol"
|
||||
L2TP = "Layer Two Tunneling Protocol Version 3"
|
||||
DDX = "D-II Data Exchange"
|
||||
IATP = "Interactive Agent Transfer Protocol"
|
||||
STP = "Schedule Transfer Protocol"
|
||||
SRP = "SpectraLink Radio Protocol"
|
||||
UTI = "Universal Transport Interface Protocol"
|
||||
SMP = "Simple Message Protocol"
|
||||
SM = "Simple Multicast Protocol"
|
||||
PTP = "Performance Transparency Protocol"
|
||||
ISIS = "IS-IS over IPv4"
|
||||
FIRE = "Flexible Intra-AS Routing Environment"
|
||||
CRTP = "Combat Radio Transport Protocol"
|
||||
CRUDP = "Combat Radio User Datagram"
|
||||
SSCOPMCE = "Service-Specific Connection-Oriented Protocol"
|
||||
IPLT = "IPLT"
|
||||
SPS = "Secure Packet Shield"
|
||||
PIPE = "Private IP Encapsulation within IP"
|
||||
SCTP = "Stream Control Transmission Protocol"
|
||||
FC = "Fibre Channel"
|
||||
RSVP_E2E_IGNORE = "RSVP End-to-End Ignore"
|
||||
MOBILITY_HEADER = "Mobility Extension Header for IPv6"
|
||||
UDPLITE = "UDPLite"
|
||||
MPLS_IN_IP = "MPLS-in-IP"
|
||||
MANET = "MANET Protocols"
|
||||
HIP = "Host Identity Protocol"
|
||||
SHIM6 = "Shim6"
|
||||
WESP = "Wrapped Encapsulating Security Payload"
|
||||
ROHC = "Robust Header Compression"
|
||||
SRV6 = "Segment Routing over IPv6"
|
||||
AGGFRAG = "AGGFRAG Encapsulation Payload for ESP"
|
||||
NSH = "Network Service Header"
|
||||
HOMA = "Homa transport protocol"
|
||||
BIT_EMU = "Bit-stream Emulation"
|
||||
EXPERIMENTAL_253 = "Use for experimentation (RFC 3692)"
|
||||
EXPERIMENTAL_254 = "Use for experimentation (RFC 3692)"
|
||||
RESERVED = "Reserved"
|
||||
UNKNOWN = "Unknown"
|
||||
|
||||
IP_PROTOCOL_MAP = {
|
||||
0: IPProtocolEnum.HOPOPT,
|
||||
1: IPProtocolEnum.ICMP,
|
||||
2: IPProtocolEnum.IGMP,
|
||||
3: IPProtocolEnum.GGP,
|
||||
4: IPProtocolEnum.IP_IN_IP,
|
||||
5: IPProtocolEnum.ST,
|
||||
6: IPProtocolEnum.TCP,
|
||||
7: IPProtocolEnum.CBT,
|
||||
8: IPProtocolEnum.EGP,
|
||||
9: IPProtocolEnum.IGP,
|
||||
10: IPProtocolEnum.BBN_RCC_MON,
|
||||
11: IPProtocolEnum.NVP_II,
|
||||
12: IPProtocolEnum.PUP,
|
||||
13: IPProtocolEnum.ARGUS,
|
||||
14: IPProtocolEnum.EMCON,
|
||||
15: IPProtocolEnum.XNET,
|
||||
16: IPProtocolEnum.CHAOS,
|
||||
17: IPProtocolEnum.UDP,
|
||||
18: IPProtocolEnum.MUX,
|
||||
19: IPProtocolEnum.DCN_MEAS,
|
||||
20: IPProtocolEnum.HMP,
|
||||
21: IPProtocolEnum.PRM,
|
||||
22: IPProtocolEnum.XNS_IDP,
|
||||
23: IPProtocolEnum.TRUNK_1,
|
||||
24: IPProtocolEnum.TRUNK_2,
|
||||
25: IPProtocolEnum.LEAF_1,
|
||||
26: IPProtocolEnum.LEAF_2,
|
||||
27: IPProtocolEnum.RDP,
|
||||
28: IPProtocolEnum.IRTP,
|
||||
29: IPProtocolEnum.ISO_TP4,
|
||||
30: IPProtocolEnum.NETBLT,
|
||||
31: IPProtocolEnum.MFE_NSP,
|
||||
32: IPProtocolEnum.MERIT_INP,
|
||||
33: IPProtocolEnum.DCCP,
|
||||
34: IPProtocolEnum.THREE_PC,
|
||||
35: IPProtocolEnum.IDPR,
|
||||
36: IPProtocolEnum.XTP,
|
||||
37: IPProtocolEnum.DDP,
|
||||
38: IPProtocolEnum.IDPR_CMTP,
|
||||
39: IPProtocolEnum.TP_PP,
|
||||
40: IPProtocolEnum.IL,
|
||||
41: IPProtocolEnum.IPV6,
|
||||
42: IPProtocolEnum.SDRP,
|
||||
43: IPProtocolEnum.IPV6_ROUTE,
|
||||
44: IPProtocolEnum.IPV6_FRAG,
|
||||
45: IPProtocolEnum.IDRP,
|
||||
46: IPProtocolEnum.RSVP,
|
||||
47: IPProtocolEnum.GRE,
|
||||
48: IPProtocolEnum.DSR,
|
||||
49: IPProtocolEnum.BNA,
|
||||
50: IPProtocolEnum.ESP,
|
||||
51: IPProtocolEnum.AH,
|
||||
52: IPProtocolEnum.I_NLSP,
|
||||
53: IPProtocolEnum.SWIPE,
|
||||
54: IPProtocolEnum.NARP,
|
||||
55: IPProtocolEnum.MOBILE,
|
||||
56: IPProtocolEnum.TLSP,
|
||||
57: IPProtocolEnum.SKIP,
|
||||
58: IPProtocolEnum.IPV6_ICMP,
|
||||
59: IPProtocolEnum.IPV6_NONXT,
|
||||
60: IPProtocolEnum.IPV6_OPTS,
|
||||
62: IPProtocolEnum.CFTP,
|
||||
64: IPProtocolEnum.SAT_EXPAK,
|
||||
65: IPProtocolEnum.KRYPTOLAN,
|
||||
66: IPProtocolEnum.RVD,
|
||||
67: IPProtocolEnum.IPPC,
|
||||
69: IPProtocolEnum.SAT_MON,
|
||||
70: IPProtocolEnum.VISA,
|
||||
71: IPProtocolEnum.IPCU,
|
||||
72: IPProtocolEnum.CPNX,
|
||||
73: IPProtocolEnum.CPHB,
|
||||
74: IPProtocolEnum.WSN,
|
||||
75: IPProtocolEnum.PVP,
|
||||
76: IPProtocolEnum.BR_SAT_MON,
|
||||
77: IPProtocolEnum.SUN_ND,
|
||||
78: IPProtocolEnum.WB_MON,
|
||||
79: IPProtocolEnum.WB_EXPAK,
|
||||
80: IPProtocolEnum.ISO_IP,
|
||||
81: IPProtocolEnum.VMTP,
|
||||
82: IPProtocolEnum.SECURE_VMTP,
|
||||
83: IPProtocolEnum.VINES,
|
||||
84: IPProtocolEnum.TTP,
|
||||
85: IPProtocolEnum.NSFNET_IGP,
|
||||
86: IPProtocolEnum.DGP,
|
||||
87: IPProtocolEnum.TCF,
|
||||
88: IPProtocolEnum.EIGRP,
|
||||
89: IPProtocolEnum.OSPF,
|
||||
90: IPProtocolEnum.SPRITE_RPC,
|
||||
91: IPProtocolEnum.LARP,
|
||||
92: IPProtocolEnum.MTP,
|
||||
93: IPProtocolEnum.AX25,
|
||||
94: IPProtocolEnum.OS,
|
||||
95: IPProtocolEnum.MICP,
|
||||
96: IPProtocolEnum.SCC_SP,
|
||||
97: IPProtocolEnum.ETHERIP,
|
||||
98: IPProtocolEnum.ENCAP,
|
||||
100: IPProtocolEnum.GMTP,
|
||||
101: IPProtocolEnum.IFMP,
|
||||
102: IPProtocolEnum.PNNI,
|
||||
103: IPProtocolEnum.PIM,
|
||||
104: IPProtocolEnum.ARIS,
|
||||
105: IPProtocolEnum.SCPS,
|
||||
106: IPProtocolEnum.QNX,
|
||||
107: IPProtocolEnum.AN,
|
||||
108: IPProtocolEnum.IPCOMP,
|
||||
109: IPProtocolEnum.SNP,
|
||||
110: IPProtocolEnum.COMPAQ_PEER,
|
||||
111: IPProtocolEnum.IPX_IN_IP,
|
||||
112: IPProtocolEnum.VRRP,
|
||||
113: IPProtocolEnum.PGM,
|
||||
115: IPProtocolEnum.L2TP,
|
||||
116: IPProtocolEnum.DDX,
|
||||
117: IPProtocolEnum.IATP,
|
||||
118: IPProtocolEnum.STP,
|
||||
119: IPProtocolEnum.SRP,
|
||||
120: IPProtocolEnum.UTI,
|
||||
121: IPProtocolEnum.SMP,
|
||||
122: IPProtocolEnum.SM,
|
||||
123: IPProtocolEnum.PTP,
|
||||
124: IPProtocolEnum.ISIS,
|
||||
125: IPProtocolEnum.FIRE,
|
||||
126: IPProtocolEnum.CRTP,
|
||||
127: IPProtocolEnum.CRUDP,
|
||||
128: IPProtocolEnum.SSCOPMCE,
|
||||
129: IPProtocolEnum.IPLT,
|
||||
130: IPProtocolEnum.SPS,
|
||||
131: IPProtocolEnum.PIPE,
|
||||
132: IPProtocolEnum.SCTP,
|
||||
133: IPProtocolEnum.FC,
|
||||
134: IPProtocolEnum.RSVP_E2E_IGNORE,
|
||||
135: IPProtocolEnum.MOBILITY_HEADER,
|
||||
136: IPProtocolEnum.UDPLITE,
|
||||
137: IPProtocolEnum.MPLS_IN_IP,
|
||||
138: IPProtocolEnum.MANET,
|
||||
139: IPProtocolEnum.HIP,
|
||||
140: IPProtocolEnum.SHIM6,
|
||||
141: IPProtocolEnum.WESP,
|
||||
142: IPProtocolEnum.ROHC,
|
||||
143: IPProtocolEnum.SRV6,
|
||||
144: IPProtocolEnum.AGGFRAG,
|
||||
145: IPProtocolEnum.NSH,
|
||||
146: IPProtocolEnum.HOMA,
|
||||
147: IPProtocolEnum.BIT_EMU,
|
||||
253: IPProtocolEnum.EXPERIMENTAL_253,
|
||||
254: IPProtocolEnum.EXPERIMENTAL_254,
|
||||
255: IPProtocolEnum.RESERVED,
|
||||
}
|
||||
|
||||
def protocol_from_number(n: int) -> IPProtocolEnum:
|
||||
return IP_PROTOCOL_MAP.get(n, IPProtocolEnum.UNKNOWN)
|
||||
|
||||
@@ -4,7 +4,6 @@ import threading
|
||||
import os
|
||||
import time
|
||||
from typing import List, Dict, Optional
|
||||
|
||||
import asyncpg
|
||||
from scapy.all import (
|
||||
Ether,
|
||||
@@ -18,13 +17,15 @@ from scapy.all import (
|
||||
Dot1Q,
|
||||
Raw,
|
||||
)
|
||||
|
||||
# ---- New imports for AF_PACKET optimized reader ----------------------
|
||||
import socket
|
||||
import selectors
|
||||
import errno
|
||||
import struct
|
||||
|
||||
from src.Models.etherType import EtherTypeEnum, ethertype_from_int
|
||||
from src.Models.ip_protocol import IPProtocolEnum, protocol_from_number
|
||||
|
||||
|
||||
# ---- Logging ----------------------------------------------------------
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger("af_packet_sniffer")
|
||||
@@ -170,7 +171,7 @@ async def db_insert_packet(pkt_info: dict, bridge: str) -> None:
|
||||
pkt_info.get("vlan_id"),
|
||||
pkt_info.get("src_ip"),
|
||||
pkt_info.get("dst_ip"),
|
||||
pkt_info.get("protocol_name"),
|
||||
pkt_info.get("protocol"),
|
||||
pkt_info.get("src_port"),
|
||||
pkt_info.get("dst_port"),
|
||||
pkt_info["length"],
|
||||
@@ -192,13 +193,15 @@ def parse_packet(pkt, bridge: str) -> None:
|
||||
Parse a scapy packet object and collect a normalized dict of metadata
|
||||
which is then scheduled to be written to the database asynchronously.
|
||||
|
||||
The function expects that 'pkt' is a Scapy Packet and that we set
|
||||
'pkt.sniffed_on' before calling this function.
|
||||
Enhancements:
|
||||
- Uses EtherType and IP Protocol enums (human-readable) for API documentation.
|
||||
- Records both raw numeric values and enum descriptions.
|
||||
- Proper VLAN handling (Dot1Q inner ethertype).
|
||||
- Keeps `protocol_name` (string) for backward compatibility.
|
||||
"""
|
||||
pkt_iface = getattr(pkt, "sniffed_on", None)
|
||||
if not pkt_iface:
|
||||
# If sniffed_on is missing we cannot determine the interface context;
|
||||
# skip this packet.
|
||||
# If sniffed_on is missing we cannot determine the interface context; skip this packet.
|
||||
return
|
||||
|
||||
logger.debug("Packet captured on %s, bridge %s", pkt_iface, bridge)
|
||||
@@ -210,78 +213,163 @@ def parse_packet(pkt, bridge: str) -> None:
|
||||
"raw": bytes(pkt),
|
||||
"src_mac": None,
|
||||
"dst_mac": None,
|
||||
"eth_type": None,
|
||||
# eth types: both raw numeric and enum/description
|
||||
"eth_type_raw": None,
|
||||
"eth_type": EtherTypeEnum.UNKNOWN, # enum / human description
|
||||
"vlan_id": None,
|
||||
# IP protocol: raw numeric and enum/description
|
||||
"protocol_raw": None,
|
||||
"protocol": IPProtocolEnum.UNKNOWN,
|
||||
# backward-compatible string label (older code)
|
||||
"protocol_name": None,
|
||||
# L3/L4 fields
|
||||
"src_ip": None,
|
||||
"dst_ip": None,
|
||||
"protocol_name": None,
|
||||
"src_port": None,
|
||||
"dst_port": None,
|
||||
}
|
||||
|
||||
# --- Layer extraction ---
|
||||
# Ethernet layer
|
||||
# Ethernet layer + EtherType
|
||||
if Ether in pkt:
|
||||
pkt_info["src_mac"] = pkt[Ether].src
|
||||
pkt_info["dst_mac"] = pkt[Ether].dst
|
||||
pkt_info["eth_type"] = hex(pkt[Ether].type)
|
||||
try:
|
||||
pkt_info["src_mac"] = pkt[Ether].src
|
||||
except Exception:
|
||||
pkt_info["src_mac"] = None
|
||||
try:
|
||||
pkt_info["dst_mac"] = pkt[Ether].dst
|
||||
except Exception:
|
||||
pkt_info["dst_mac"] = None
|
||||
|
||||
# VLAN (802.1Q)
|
||||
if Dot1Q in pkt:
|
||||
pkt_info["vlan_id"] = pkt[Dot1Q].vlan
|
||||
# Base ethertype (may be 0x8100 for VLAN)
|
||||
eth_type_raw: Optional[int] = None
|
||||
try:
|
||||
eth_type_raw = int(pkt[Ether].type)
|
||||
except Exception:
|
||||
eth_type_raw = None
|
||||
|
||||
# ARP
|
||||
# VLAN (Dot1Q) may contain the inner ethertype
|
||||
if Dot1Q in pkt:
|
||||
try:
|
||||
# Dot1Q.type is the encapsulated ethertype
|
||||
inner = int(pkt[Dot1Q].type)
|
||||
if inner:
|
||||
eth_type_raw = inner
|
||||
except Exception:
|
||||
# ignore and keep whatever eth_type_raw was
|
||||
pass
|
||||
# capture vlan id if present
|
||||
try:
|
||||
pkt_info["vlan_id"] = int(pkt[Dot1Q].vlan)
|
||||
except Exception:
|
||||
pkt_info["vlan_id"] = None
|
||||
|
||||
# Fill eth_type fields (raw + enum)
|
||||
if eth_type_raw is not None:
|
||||
pkt_info["eth_type_raw"] = eth_type_raw
|
||||
try:
|
||||
pkt_info["eth_type"] = ethertype_from_int(eth_type_raw)
|
||||
except Exception:
|
||||
pkt_info["eth_type"] = EtherTypeEnum.UNKNOWN
|
||||
else:
|
||||
# Unknown / missing ethertype
|
||||
pkt_info["eth_type_raw"] = None
|
||||
pkt_info["eth_type"] = EtherTypeEnum.UNKNOWN
|
||||
|
||||
# ARP (layer 2/3)
|
||||
if ARP in pkt:
|
||||
pkt_info["protocol_name"] = "ARP"
|
||||
pkt_info["src_ip"] = pkt[ARP].psrc
|
||||
pkt_info["dst_ip"] = pkt[ARP].pdst
|
||||
pkt_info["src_ip"] = getattr(pkt[ARP], "psrc", None)
|
||||
pkt_info["dst_ip"] = getattr(pkt[ARP], "pdst", None)
|
||||
pkt_info["src_port"] = None
|
||||
pkt_info["dst_port"] = None
|
||||
# ARP is a L2 protocol — leave protocol_raw/protocol as UNKNOWN (or set to a sentinel if desired)
|
||||
|
||||
# IPv4
|
||||
if IP in pkt:
|
||||
pkt_info["src_ip"] = pkt[IP].src
|
||||
pkt_info["dst_ip"] = pkt[IP].dst
|
||||
proto = pkt[IP].proto
|
||||
if proto == 6 and TCP in pkt:
|
||||
try:
|
||||
pkt_info["src_ip"] = pkt[IP].src
|
||||
except Exception:
|
||||
pkt_info["src_ip"] = None
|
||||
try:
|
||||
pkt_info["dst_ip"] = pkt[IP].dst
|
||||
except Exception:
|
||||
pkt_info["dst_ip"] = None
|
||||
|
||||
# protocol number (IPv4 'protocol' field)
|
||||
try:
|
||||
proto_num = int(pkt[IP].proto)
|
||||
except Exception:
|
||||
proto_num = None
|
||||
|
||||
if proto_num is not None:
|
||||
pkt_info["protocol_raw"] = proto_num
|
||||
try:
|
||||
pkt_info["protocol"] = protocol_from_number(proto_num)
|
||||
except Exception:
|
||||
pkt_info["protocol"] = IPProtocolEnum.UNKNOWN
|
||||
|
||||
# Common transports
|
||||
if proto_num == 6 and TCP in pkt:
|
||||
pkt_info["protocol_name"] = "TCP"
|
||||
pkt_info["src_port"] = pkt[TCP].sport
|
||||
pkt_info["dst_port"] = pkt[TCP].dport
|
||||
elif proto == 17 and UDP in pkt:
|
||||
pkt_info["src_port"] = getattr(pkt[TCP], "sport", None)
|
||||
pkt_info["dst_port"] = getattr(pkt[TCP], "dport", None)
|
||||
elif proto_num == 17 and UDP in pkt:
|
||||
pkt_info["protocol_name"] = "UDP"
|
||||
pkt_info["src_port"] = pkt[UDP].sport
|
||||
pkt_info["dst_port"] = pkt[UDP].dport
|
||||
elif proto == 1 and ICMP in pkt:
|
||||
pkt_info["src_port"] = getattr(pkt[UDP], "sport", None)
|
||||
pkt_info["dst_port"] = getattr(pkt[UDP], "dport", None)
|
||||
elif proto_num == 1 and ICMP in pkt:
|
||||
pkt_info["protocol_name"] = "ICMP"
|
||||
else:
|
||||
pkt_info["protocol_name"] = f"IP_PROTO_{proto}"
|
||||
# leave protocol_name as numeric fallback if not matched
|
||||
if pkt_info["protocol_name"] is None:
|
||||
pkt_info["protocol_name"] = f"IP_PROTO_{proto_num}" if proto_num is not None else None
|
||||
|
||||
# IPv6
|
||||
if IPv6 in pkt:
|
||||
pkt_info["src_ip"] = pkt[IPv6].src
|
||||
pkt_info["dst_ip"] = pkt[IPv6].dst
|
||||
nh = pkt[IPv6].nh
|
||||
try:
|
||||
pkt_info["src_ip"] = pkt[IPv6].src
|
||||
except Exception:
|
||||
pkt_info["src_ip"] = None
|
||||
try:
|
||||
pkt_info["dst_ip"] = pkt[IPv6].dst
|
||||
except Exception:
|
||||
pkt_info["dst_ip"] = None
|
||||
|
||||
# next header / nh value
|
||||
try:
|
||||
nh = int(pkt[IPv6].nh)
|
||||
except Exception:
|
||||
nh = None
|
||||
|
||||
if nh is not None:
|
||||
pkt_info["protocol_raw"] = nh
|
||||
try:
|
||||
pkt_info["protocol"] = protocol_from_number(nh)
|
||||
except Exception:
|
||||
pkt_info["protocol"] = IPProtocolEnum.UNKNOWN
|
||||
|
||||
if nh == 6 and TCP in pkt:
|
||||
pkt_info["protocol_name"] = "TCP"
|
||||
pkt_info["src_port"] = pkt[TCP].sport
|
||||
pkt_info["dst_port"] = pkt[TCP].dport
|
||||
pkt_info["src_port"] = getattr(pkt[TCP], "sport", None)
|
||||
pkt_info["dst_port"] = getattr(pkt[TCP], "dport", None)
|
||||
elif nh == 17 and UDP in pkt:
|
||||
pkt_info["protocol_name"] = "UDP"
|
||||
pkt_info["src_port"] = pkt[UDP].sport
|
||||
pkt_info["dst_port"] = pkt[UDP].dport
|
||||
pkt_info["src_port"] = getattr(pkt[UDP], "sport", None)
|
||||
pkt_info["dst_port"] = getattr(pkt[UDP], "dport", None)
|
||||
elif ICMPv6Unknown in pkt:
|
||||
pkt_info["protocol_name"] = "ICMPv6"
|
||||
else:
|
||||
pkt_info["protocol_name"] = f"IPV6_PROTO_{nh}"
|
||||
if pkt_info["protocol_name"] is None:
|
||||
pkt_info["protocol_name"] = f"IPV6_PROTO_{nh}" if nh is not None else None
|
||||
|
||||
# Raw payload / fallback protocol label
|
||||
if Raw in pkt and not pkt_info["protocol_name"]:
|
||||
pkt_info["protocol_name"] = "RAW"
|
||||
|
||||
# Submit DB insert to background asyncio loop from this thread.
|
||||
# Submit DB insert to background asyncio loop from this thread
|
||||
asyncio.run_coroutine_threadsafe(db_insert_packet(pkt_info, bridge), async_loop)
|
||||
|
||||
|
||||
# -------------------------
|
||||
# AF_PACKET optimized reader
|
||||
# -------------------------
|
||||
|
||||
Reference in New Issue
Block a user