use super::bittorrent_dht::BitTorrentDHTTransaction;
use crate::jsonbuilder::{JsonBuilder, JsonError};
fn print_ip_addr(addr: &[u8]) -> std::string::String {
if addr.len() == 4 {
return format!("{}.{}.{}.{}", addr[0], addr[1], addr[2], addr[3]);
} else if addr.len() == 16 {
return format!("{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}",
addr[0],
addr[1],
addr[2],
addr[3],
addr[4],
addr[5],
addr[6],
addr[7],
addr[8],
addr[9],
addr[10],
addr[11],
addr[12],
addr[13],
addr[14],
addr[15]);
} else {
return "".to_string();
}
}
fn log_bittorrent_dht(
tx: &BitTorrentDHTTransaction, js: &mut JsonBuilder,
) -> Result<(), JsonError> {
js.open_object("bittorrent_dht")?;
js.set_hex("transaction_id", &tx.transaction_id)?;
if let Some(client_version) = &tx.client_version {
js.set_hex("client_version", client_version)?;
}
if let Some(request_type) = &tx.request_type {
js.set_string("request_type", request_type)?;
}
if let Some(error) = &tx.error {
js.open_object("error")?;
js.set_uint("num", u64::from(error.num))?;
js.set_string("msg", &error.msg)?;
js.close()?;
};
if let Some(request) = &tx.request {
js.open_object("request")?;
js.set_hex("id", &request.id)?;
if let Some(target) = &request.target {
js.set_hex("target", target)?;
}
if let Some(info_hash) = &request.info_hash {
js.set_hex("info_hash", info_hash)?;
}
if let Some(token) = &request.token {
js.set_hex("token", token)?;
}
if let Some(implied_port) = request.implied_port {
js.set_uint("implied_port", u64::from(implied_port))?;
}
if let Some(port) = request.port {
js.set_uint("port", u64::from(port))?;
}
js.close()?;
};
if let Some(response) = &tx.response {
js.open_object("response")?;
js.set_hex("id", &response.id)?;
if let Some(nodes) = &response.nodes {
if !nodes.is_empty() {
js.open_array("nodes")?;
for node in nodes {
js.start_object()?;
js.set_hex("id", &node.id)?;
js.set_string("ip", &print_ip_addr(&node.ip))?;
js.set_uint("port", node.port)?;
js.close()?;
}
js.close()?;
}
}
if let Some(nodes) = &response.nodes6 {
if !nodes.is_empty() {
js.open_array("nodes6")?;
for node in nodes {
js.start_object()?;
js.set_hex("id", &node.id)?;
js.set_string("ip", &print_ip_addr(&node.ip))?;
js.set_uint("port", node.port)?;
js.close()?;
}
js.close()?;
}
}
if let Some(values) = &response.values {
js.open_array("values")?;
for value in values {
js.start_object()?;
js.set_string("ip", &print_ip_addr(&value.ip))?;
js.set_uint("port", value.port)?;
js.close()?;
}
js.close()?;
}
if let Some(token) = &response.token {
js.set_hex("token", token)?;
}
js.close()?;
};
js.close()?;
Ok(())
}
#[no_mangle]
pub unsafe extern "C" fn SCBittorrentDhtLogger(
tx: *mut std::os::raw::c_void, js: &mut JsonBuilder,
) -> bool {
let tx = cast_pointer!(tx, BitTorrentDHTTransaction);
log_bittorrent_dht(tx, js).is_ok()
}