net_trace/
packet.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Serialize, Deserialize, Clone)]
5pub struct NetworkPacket {
6    pub timestamp: DateTime<Utc>,
7    pub ethernet_layer: EthernetFrame,
8    pub ip_layer: IPv4Packet,
9    pub tcp_layer: TCPSegment,
10    pub application_layer: ApplicationData,
11}
12
13/// Ethernet (Layer 2) Frame
14#[derive(Debug, Serialize, Deserialize, Clone)]
15pub struct EthernetFrame {
16    pub source_mac: [u8; 6],
17    pub destination_mac: [u8; 6],
18    pub ethertype: u16,  // 0x0800 for IPv4
19    pub frame_check_sequence: u32,
20}
21
22/// IPv4 (Layer 3) Packet
23#[derive(Debug, Serialize, Deserialize, Clone)]
24pub struct IPv4Packet {
25    pub version: u8,          // 4 for IPv4
26    pub ihl: u8,             // Internet Header Length
27    pub dscp: u8,            // Differentiated Services Code Point
28    pub ecn: u8,             // Explicit Congestion Notification
29    pub total_length: u16,
30    pub identification: u16,
31    pub flags: IPv4Flags,
32    pub fragment_offset: u16,
33    pub ttl: u8,             // Time To Live
34    pub protocol: u8,        // 6 for TCP
35    pub header_checksum: u16,
36    pub source_ip: [u8; 4],
37    pub destination_ip: [u8; 4],
38    pub options: Vec<u8>,    // Optional IPv4 options
39}
40
41/// IPv4 Flags
42#[derive(Debug, Serialize, Deserialize, Clone)]
43pub struct IPv4Flags {
44    pub reserved: bool,      // Must be zero
45    pub dont_fragment: bool,
46    pub more_fragments: bool,
47}
48
49/// TCP (Layer 4) Segment
50#[derive(Debug, Serialize, Deserialize, Clone)]
51pub struct TCPSegment {
52    pub source_port: u16,
53    pub destination_port: u16,
54    pub sequence_number: u32,
55    pub acknowledgment_number: u32,
56    pub data_offset: u8,     // Header length in 32-bit words
57    pub flags: TCPFlags,
58    pub window_size: u16,
59    pub checksum: u16,
60    pub urgent_pointer: u16,
61    pub options: Vec<TCPOption>,
62}
63
64/// TCP Flags
65#[derive(Debug, Serialize, Deserialize, Clone)]
66pub struct TCPFlags {
67    pub fin: bool,          // Finish
68    pub syn: bool,          // Synchronize
69    pub rst: bool,          // Reset
70    pub psh: bool,          // Push
71    pub ack: bool,          // Acknowledgment
72    pub urg: bool,          // Urgent
73    pub ece: bool,          // ECN-Echo
74    pub cwr: bool,          // Congestion Window Reduced
75}
76
77/// TCP Option
78#[derive(Debug, Serialize, Deserialize, Clone)]
79pub struct TCPOption {
80    pub kind: u8,
81    pub length: u8,
82    pub data: Vec<u8>,
83}
84
85/// Application Layer Data
86#[derive(Debug, Serialize, Deserialize, Clone)]
87pub struct ApplicationData {
88    pub protocol: ApplicationProtocol,
89    pub payload: Vec<u8>,
90}
91
92/// Supported Application Protocols
93#[derive(Debug, Serialize, Deserialize, Clone)]
94pub enum ApplicationProtocol {
95    HTTP,
96    HTTPS,
97    FTP,
98    SSH,
99    SMTP,
100    DNS,
101    NTP,
102    NetBIOS,
103    IMAP,
104    SNMP,
105    LDAP,
106    SMB,
107    Kerberos,
108    Custom(String),
109}
110
111/// Implementation for NetworkPacket
112impl NetworkPacket {
113    /// Calculate the total size of the packet in bytes
114    pub fn total_size(&self) -> usize {
115        14 + // Ethernet header (without FCS)
116        20 + self.ip_layer.options.len() + // IPv4 header
117        20 + self.tcp_layer.options.iter().map(|opt| opt.length as usize).sum::<usize>() + // TCP header
118        self.application_layer.payload.len() // Application data
119    }
120    
121    /// Check if packet is part of a TCP handshake
122    pub fn is_handshake(&self) -> bool {
123        self.tcp_layer.flags.syn || self.tcp_layer.flags.fin
124    }
125    
126    /// Get the application protocol as a string
127    pub fn get_protocol_string(&self) -> String {
128        match &self.application_layer.protocol {
129            ApplicationProtocol::HTTP => "HTTP".to_string(),
130            ApplicationProtocol::HTTPS => "HTTPS".to_string(),
131            ApplicationProtocol::FTP => "FTP".to_string(),
132            ApplicationProtocol::SSH => "SSH".to_string(),
133            ApplicationProtocol::SMTP => "SMTP".to_string(),
134            ApplicationProtocol::DNS => "DNS".to_string(),
135            ApplicationProtocol::NTP => "NTP".to_string(),
136            ApplicationProtocol::NetBIOS => "NetBIOS".to_string(),
137            ApplicationProtocol::IMAP => "IMAP".to_string(),
138            ApplicationProtocol::SNMP => "SNMP".to_string(),
139            ApplicationProtocol::LDAP => "LDAP".to_string(),
140            ApplicationProtocol::SMB => "SMB".to_string(),
141            ApplicationProtocol::Kerberos => "Kerberos".to_string(),
142            ApplicationProtocol::Custom(proto) => proto.clone(),
143        }
144    }
145}