zond_engine/protocols/
ip.rs1use std::net::{Ipv4Addr, Ipv6Addr};
8
9use crate::protocols::utils::IP_V6_HDR_LEN;
10use anyhow::Context;
11use pnet::packet::Packet;
12use pnet::packet::ethernet::EthernetPacket;
13use pnet::packet::ip::IpNextHeaderProtocol;
14use pnet::packet::ipv4::Ipv4Packet;
15use pnet::packet::ipv6::{Ipv6Packet, MutableIpv6Packet};
16
17pub fn create_ipv6_header(
52 src_addr: Ipv6Addr,
53 dst_addr: Ipv6Addr,
54 payload_length: u16,
55 next_protocol: IpNextHeaderProtocol,
56) -> anyhow::Result<Vec<u8>> {
57 let mut buffer: [u8; IP_V6_HDR_LEN] = [0; IP_V6_HDR_LEN];
58 {
59 let mut ipv6: MutableIpv6Packet =
60 MutableIpv6Packet::new(&mut buffer[..]).context("creating ipv6 packet")?;
61 ipv6.set_version(6);
62 ipv6.set_traffic_class(0);
63 ipv6.set_flow_label(rand::random());
64 ipv6.set_payload_length(payload_length);
65 ipv6.set_next_header(next_protocol);
66 ipv6.set_hop_limit(1);
67 ipv6.set_source(src_addr);
68 ipv6.set_destination(dst_addr);
69 }
70 Ok(buffer.to_vec())
71}
72
73pub fn get_ipv6_src_addr_from_eth(frame: &EthernetPacket) -> anyhow::Result<Ipv6Addr> {
74 let ipv6_packet: Ipv6Packet = Ipv6Packet::new(frame.payload()).context(format!(
75 "truncated or invalid ipv6 packet (payload len {})",
76 frame.payload().len()
77 ))?;
78 Ok(ipv6_packet.get_source())
79}
80
81pub fn get_ipv6_dst_addr_from_eth(frame: &EthernetPacket) -> anyhow::Result<Ipv6Addr> {
82 let ipv6_packet: Ipv6Packet = Ipv6Packet::new(frame.payload()).context(format!(
83 "truncated or invalid ipv6 packet (payload len {})",
84 frame.payload().len()
85 ))?;
86 Ok(ipv6_packet.get_destination())
87}
88
89pub fn get_ipv4_addr_from_eth(frame: &EthernetPacket) -> anyhow::Result<Ipv4Addr> {
90 let ipv4_packet: Ipv4Packet = Ipv4Packet::new(frame.payload()).context(format!(
91 "truncated or invalid ipv4 packet (payload len {})",
92 frame.payload().len()
93 ))?;
94 Ok(ipv4_packet.get_source())
95}