mirror of
https://github.com/GyulyVGC/sniffnet.git
synced 2026-10-20 22:21:15 +00:00
feat(dns): capture and parse DNS traffic in the packet pipeline
Detect DNS traffic (UDP/TCP port 53) in the capture loop and parse the message from the transport payload, extracted from `headers.payload` before `analyze_headers` consumes the headers (the slice borrows `packet.data`, so it outlives the move). DNS over TCP's 2-byte length prefix is stripped before parsing. Parsed messages are pushed to a new `InfoTraffic::dns_events` vector, carried to the GUI on each tick and reset by `take_but_leave_something`; `refresh` intentionally ignores it (events are drained GUI-side). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2d5431a970
commit
4695544de5
2 changed files with 39 additions and 1 deletions
|
|
@ -5,6 +5,8 @@ use crate::location;
|
|||
use crate::mmdb::asn::get_asn;
|
||||
use crate::mmdb::country::get_country;
|
||||
use crate::mmdb::types::mmdb_reader::MmdbReaders;
|
||||
use crate::networking::dns::parser::parse_dns;
|
||||
use crate::networking::dns::types::DnsEvent;
|
||||
use crate::networking::manage_packets::{
|
||||
analyze_headers, get_address_to_lookup, get_traffic_type, is_local_connection,
|
||||
modify_or_insert_in_map,
|
||||
|
|
@ -20,13 +22,14 @@ use crate::networking::types::icmp_type::IcmpType;
|
|||
use crate::networking::types::info_traffic::InfoTraffic;
|
||||
use crate::networking::types::ip_blacklist::IpBlacklist;
|
||||
use crate::networking::types::my_link_type::MyLinkType;
|
||||
use crate::networking::types::protocol::Protocol;
|
||||
use crate::networking::types::traffic_direction::TrafficDirection;
|
||||
use crate::utils::error_logger::{ErrorLogger, Location};
|
||||
use crate::utils::formatted_strings::get_domain_from_r_dns;
|
||||
use crate::utils::types::timestamp::Timestamp;
|
||||
use async_channel::Sender;
|
||||
use dns_lookup::lookup_addr;
|
||||
use etherparse::{EtherType, LaxPacketHeaders};
|
||||
use etherparse::{EtherType, LaxPacketHeaders, LaxPayloadSlice};
|
||||
use pcap::{Address, Packet, PacketHeader};
|
||||
use std::collections::HashMap;
|
||||
use std::net::IpAddr;
|
||||
|
|
@ -155,6 +158,15 @@ pub fn parse_packets(
|
|||
let mut icmp_type = IcmpType::default();
|
||||
let mut arp_type = ArpType::default();
|
||||
|
||||
// Capture the UDP/TCP payload before `analyze_headers` consumes
|
||||
// `headers`. The returned slice borrows `packet.data`, not
|
||||
// `headers`, so it remains valid after the move.
|
||||
let transport_payload: Option<&[u8]> = match &headers.payload {
|
||||
LaxPayloadSlice::Udp { payload, .. }
|
||||
| LaxPayloadSlice::Tcp { payload, .. } => Some(payload),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let key_option = analyze_headers(
|
||||
headers,
|
||||
&mut mac_addresses,
|
||||
|
|
@ -167,6 +179,28 @@ pub fn parse_packets(
|
|||
continue;
|
||||
};
|
||||
|
||||
// If this is DNS traffic (port 53), parse the message from the
|
||||
// transport payload and record it as a DNS event.
|
||||
if key.sport == Some(53) || key.dport == Some(53) {
|
||||
if let Some(payload) = transport_payload {
|
||||
// DNS over TCP is prefixed by a 2-byte length field.
|
||||
let dns_bytes = if key.protocol == Protocol::TCP {
|
||||
payload.get(2..)
|
||||
} else {
|
||||
Some(payload)
|
||||
};
|
||||
if let Some(message) = dns_bytes.and_then(parse_dns) {
|
||||
info_traffic_msg.dns_events.push(DnsEvent {
|
||||
timestamp: next_packet_timestamp,
|
||||
src: key.source,
|
||||
dst: key.dest,
|
||||
transport: key.protocol,
|
||||
message,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save this packet to PCAP file
|
||||
if let Some(file) = savefile.as_mut() {
|
||||
file.write(&Packet {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::Service;
|
||||
use crate::networking::dns::types::DnsEvent;
|
||||
use crate::networking::manage_packets::get_local_port;
|
||||
use crate::networking::types::address_port_pair::AddressPortPair;
|
||||
use crate::networking::types::data_info::DataInfo;
|
||||
|
|
@ -26,6 +27,9 @@ pub struct InfoTraffic {
|
|||
pub services: HashMap<Service, DataInfo>,
|
||||
/// Map of the hosts with their data info
|
||||
pub hosts: HashMap<Host, DataInfoHost>,
|
||||
/// DNS messages parsed during the current interval (drained by the GUI each
|
||||
/// tick; not accumulated in the global `InfoTraffic`).
|
||||
pub dns_events: Vec<DnsEvent>,
|
||||
}
|
||||
|
||||
impl InfoTraffic {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue