]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
bittorrent-dht: parse and log node6 lists
authorJason Ish <jason.ish@oisf.net>
Thu, 8 Sep 2022 17:15:38 +0000 (11:15 -0600)
committerVictor Julien <vjulien@oisf.net>
Fri, 28 Oct 2022 09:48:13 +0000 (11:48 +0200)
Node6 lists are just like node lists, but for IPv6 addresses.

rust/src/bittorrent_dht/logger.rs
rust/src/bittorrent_dht/parser.rs

index 3145a956a36f8ebe85dd29fca9314a8e3c106ec5..2cfb9270ef673e1997f6ecc1a365bdae32e3f481 100644 (file)
@@ -97,6 +97,19 @@ fn log_bittorrent_dht(
                 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.into())?;
+                    js.close()?;
+                }
+                js.close()?;
+            }
+        }
         if let Some(values) = &response.values {
             js.open_array("values")?;
             for value in values {
index 7a6ce32434796735ca296fab98c77d076db67110..ffc31ac52b07667b3b50953ff03feb95db515c15 100644 (file)
@@ -23,9 +23,9 @@
 
 use crate::bittorrent_dht::bittorrent_dht::BitTorrentDHTTransaction;
 use bendy::decoding::{Decoder, Error, FromBencode, Object, ResultExt};
-use nom7::IResult;
 use nom7::bytes::complete::take;
 use nom7::number::complete::be_u16;
+use nom7::IResult;
 
 #[derive(Debug, Eq, PartialEq)]
 pub struct BitTorrentDHTRequest {
@@ -51,6 +51,7 @@ pub struct BitTorrentDHTResponse {
     /// q = find_node/get_peers - compact node info for target node or
     ///                           K(8) closest good nodes in routing table
     pub nodes: Option<Vec<Node>>,
+    pub nodes6: Option<Vec<Node>>,
     /// q = get_peers - list of compact peer infos
     pub values: Option<Vec<Peer>>,
     /// q = get_peers - token key required for sender's future
@@ -94,6 +95,21 @@ pub fn parse_node(i: &[u8]) -> IResult<&[u8], Node> {
     ))
 }
 
+/// Parse IPv6 node structures.
+pub fn parse_node6(i: &[u8]) -> IResult<&[u8], Node> {
+    let (i, id) = take(20usize)(i)?;
+    let (i, ip) = take(16usize)(i)?;
+    let (i, port) = be_u16(i)?;
+    Ok((
+        i,
+        Node {
+            id: id.to_vec(),
+            ip: ip.to_vec(),
+            port,
+        },
+    ))
+}
+
 fn parse_peer(i: &[u8]) -> IResult<&[u8], Peer> {
     let (i, ip) = if i.len() < 18 {
         take(4usize)(i)
@@ -213,6 +229,7 @@ impl FromBencode for BitTorrentDHTResponse {
     {
         let mut id = None;
         let mut nodes = None;
+        let mut nodes6 = None;
         let mut values = vec![];
         let mut token = None;
 
@@ -231,6 +248,14 @@ impl FromBencode for BitTorrentDHTResponse {
                         nodes = Some(decoded_nodes);
                     }
                 }
+                (b"nodes6", value) => {
+                    let (_, decoded_nodes) =
+                        nom7::multi::many0(parse_node6)(value.try_into_bytes().context("nodes6")?)
+                            .map_err(|_| Error::malformed_content("nodes6.nodes6"))?;
+                    if !decoded_nodes.is_empty() {
+                        nodes6 = Some(decoded_nodes);
+                    }
+                }
                 (b"values", value) => {
                     if let Object::List(mut list) = value {
                         while let Some(entry) = list.next_object()? {
@@ -256,6 +281,7 @@ impl FromBencode for BitTorrentDHTResponse {
         Ok(BitTorrentDHTResponse {
             id: id.to_vec(),
             nodes,
+            nodes6,
             values: if values.is_empty() {
                 None
             } else {