Skip to content

Latest commit

 

History

History
104 lines (78 loc) · 4.72 KB

File metadata and controls

104 lines (78 loc) · 4.72 KB

TODO — Décapsulation des tunnels

Suivi du chantier « un paquet encapsulé → plusieurs niveaux de flux ». Tout passe par le module src/parse/tunnel/mod.rs.

Suivi GitHub : issue #15.

✅ Fait

  • Champ récursif PacketFlow.inner: Option<Box<PacketFlow>> + flatten().
  • Refactor parse_implparse_layers(data_link, depth) (réutilisable).
  • Garde-fou profondeur (MAX_TUNNEL_DEPTH = 4) + dégradation gracieuse (jamais d'erreur : None → seule la ligne externe est produite).
  • CAPWAP-Data (UDP 5247) → IEEE 802.11 (ToDS/FromDS/WDS/QoS, gestion du byte-swap Frame Control Cisco) → LLC/SNAP → L3.
  • Le tunnel est reporté comme protocole applicatif de la ligne externe (ex. "CAPWAP").
  • 2 tests de référence sur trames réelles (ToDS/HLEN 16 et FromDS/HLEN 8).

🧭 Rappel : comment brancher un nouveau tunnel

Dans detect_inner() : reconnaître le tunnel, peler ses en-têtes, obtenir la trame interne, puis appeler PacketFlow::parse_layers(inner_dl, depth + 1) et renvoyer Some(("NOM", inner)).

Deux formes de trame interne :

  • Interne = Ethernet (VXLAN, NVGRE, Geneve-transparent) : la trame interne commence par un en-tête Ethernet complet → PacketFlow::parse_layers(DataLink::try_from(inner_bytes)?, depth + 1).
  • Interne = IP brute (IP-in-IP, GTP-U, GRE-IP) : pas de L2 interne → synthétiser un DataLink à MAC vides (MacAddress([0u8; 6])), ethertype = IPv4 (0x0800) ou IPv6 (0x86DD), payload = octets IP internes, puis parse_layers.

⚠️ Point d'architecture à ne pas rater

detect_inner() n'est appelé aujourd'hui que si transport est Some (donc pour les tunnels au-dessus d'UDP/TCP). Les tunnels niveau IP (GRE = proto 47, IP-in-IP = 4/41) ne produisent pas de couche Transport → il faudra ajouter un point de détection dans parse_layers quand transport est None mais que internet.payload_protocol vaut Gre/Ipip. Prévoir de passer internet (ou son payload + payload_protocol) à la détection, pas seulement transport.


📋 À faire (un test de référence par tunnel = obligatoire)

Ne rien merger sans une trame réelle en fixture (golden test), comme pour CAPWAP. Fournir le hex complet depuis l'Ethernet.

Tunnels UDP (hook transport existant — le plus simple)

  • VXLAN — UDP 4789. En-tête 8 octets (flags 1, réservé 3, VNI 3, réservé 1). Interne = Ethernet. Fixture requise.
  • GTP-U — UDP 2152. En-tête variable (min 8 octets ; +4 si un des flags E/S/PN est posé ; puis extension headers). Interne = IP (pas de L2). Attention au champ « message type » = 255 (G-PDU) pour ne peler que les données. Fixture requise.
  • Geneve — UDP 6081. En-tête 8 octets + options variables (Opt Len en mots de 4). protocol type indique Ethernet (0x6558) ou IP. Fixture requise.

Tunnels niveau IP (nécessite le nouveau hook, cf. point d'archi)

  • IP-in-IP — IP proto 4 (IPv4) / 41 (IPv6). Interne = IP directe. Fixture requise.
  • GRE — IP proto 47. En-tête 4 octets min (+ champs optionnels selon les bits C/K/S) ; le champ protocol type (EtherType) dit si l'interne est IP (0x0800/0x86DD) ou Ethernet (0x6558, NVGRE/transparent bridging). Fixture requise.

Cas particuliers / hors périmètre immédiat

  • CAPWAP-DTLS (préambule type 1) : chiffré → non décapsulable. Déjà géré : on renvoie None (pas de récursion), la ligne externe reste. À documenter comme limite, rien à coder.
  • ESP (proto 50) : chiffré → idem, ne pas récurser.
  • MPLS (EtherType 0x8847/0x8848) : encapsulation niveau 2.5, à traiter au niveau DataLink si besoin un jour.

🔗 Intégration Sonar (fait côté Sonar par Cyprien)

  • Re-vendorer la crate dans Sonar (cargo vendor) après bump de version.
  • Dans le pipeline de capture, itérer flatten()N lignes de flux par paquet.
  • Attribution des octets par niveau pour ne pas doubler le volume : ligne externe = taille de la trame complète ; ligne interne = taille du segment interne (inner.data_link.payload.len() pour la couche L3 interne). Le count (paquets) à +1 par niveau est correct.

🧪 Rappel tests

  • Décoder la trame en amont (Python/Wireshark) pour figer les offsets et les adresses attendues, puis asserter externe et interne + flatten().len().
  • Couvrir les variantes qui changent le pelage (longueurs d'en-tête, sens du flux, présence d'options), comme les deux tests CAPWAP ToDS/FromDS.