experimental tcp snmp handling

This commit is contained in:
Graham McIntire 2026-02-04 17:25:39 -06:00
parent df334e4db8
commit f454a1f7ea
No known key found for this signature in database
3 changed files with 24 additions and 1 deletions

View file

@ -26,6 +26,7 @@ message SnmpConfig {
string version = 2;
string community = 3;
uint32 port = 4;
string transport = 5;
}
message Sensor {
@ -148,6 +149,7 @@ message SnmpDevice {
string v3_auth_password = 8; // Decrypted before sending
string v3_priv_protocol = 9; // "DES" | "AES" | "AES-256" | etc.
string v3_priv_password = 10; // Decrypted before sending
string transport = 11; // "udp" | "tcp"
}
message SnmpQuery {

View file

@ -30,6 +30,7 @@ pub struct DeviceConfig {
pub version: String,
pub community: SecretString,
pub v3_config: Option<V3Config>,
pub transport: String,
}
impl std::fmt::Debug for DeviceConfig {
@ -38,6 +39,7 @@ impl std::fmt::Debug for DeviceConfig {
.field("ip", &self.ip)
.field("port", &self.port)
.field("version", &self.version)
.field("transport", &self.transport)
.field("community", &"[REDACTED]")
.field("v3_config", &self.v3_config)
.finish()
@ -185,11 +187,25 @@ fn run_poller_thread(
Ok(())
}
/// Create an SNMP session based on version
/// Create an SNMP session based on version and transport
fn create_session(addr: &str, config: &DeviceConfig) -> Result<SyncSession, String> {
let timeout = Some(Duration::from_secs(SNMP_TIMEOUT_SECS));
let version_num = parse_snmp_version(&config.version)?;
let transport = config.transport.to_lowercase();
// TCP transport warning - not yet implemented
// TODO: Implement SNMP-over-TCP (RFC 3430) - requires low-level PDU handling
// since snmp2 crate doesn't expose internal types needed for TCP framing
if transport == "tcp" {
tracing::warn!(
"TCP transport requested for {} but not yet implemented. \
Falling back to UDP. TCP support requires custom PDU encoder/decoder \
since snmp2 crate doesn't expose necessary internal types.",
addr
);
}
// UDP transport (default, also used as fallback for TCP)
if config.version == "3" {
let v3_config = config
.v3_config

View file

@ -576,6 +576,11 @@ async fn execute_snmp_job(
version: snmp_device.version.clone(),
community: SecretString::new(snmp_device.community.clone()),
v3_config,
transport: if snmp_device.transport.is_empty() {
"udp".to_string()
} else {
snmp_device.transport.clone()
},
};
// Zeroize credentials in protobuf message after extraction