xenet_packet_builder/
ethernet.rs

1use xenet_core::mac::MacAddr;
2use xenet_packet::ethernet::{EtherType, MutableEthernetPacket, ETHERNET_HEADER_LEN};
3use xenet_packet::ipv4::Ipv4Packet;
4use xenet_packet::Packet;
5
6/// Build Ethernet packet.
7pub(crate) fn build_ethernet_packet(
8    eth_packet: &mut MutableEthernetPacket,
9    src_mac: MacAddr,
10    dst_mac: MacAddr,
11    ether_type: EtherType,
12) {
13    eth_packet.set_source(src_mac);
14    eth_packet.set_destination(dst_mac);
15    match ether_type {
16        EtherType::Arp => {
17            eth_packet.set_ethertype(EtherType::Arp);
18        }
19        EtherType::Ipv4 => {
20            eth_packet.set_ethertype(EtherType::Ipv4);
21        }
22        EtherType::Ipv6 => {
23            eth_packet.set_ethertype(EtherType::Ipv6);
24        }
25        _ => {
26            // TODO
27        }
28    }
29}
30
31/// Build Ethernet ARP packet.
32pub(crate) fn build_ethernet_arp_packet(eth_packet: &mut MutableEthernetPacket, src_mac: MacAddr) {
33    eth_packet.set_source(src_mac);
34    eth_packet.set_destination(MacAddr::broadcast());
35    eth_packet.set_ethertype(EtherType::Arp);
36}
37
38/// Ethernet Packet Builder.
39#[derive(Clone, Debug)]
40pub struct EthernetPacketBuilder {
41    /// Source MAC address.
42    pub src_mac: MacAddr,
43    /// Destination MAC address.
44    pub dst_mac: MacAddr,
45    /// EtherType.
46    pub ether_type: EtherType,
47}
48
49impl EthernetPacketBuilder {
50    /// Constructs a new EthernetPacketBuilder.
51    pub fn new() -> EthernetPacketBuilder {
52        EthernetPacketBuilder {
53            src_mac: MacAddr::zero(),
54            dst_mac: MacAddr::zero(),
55            ether_type: EtherType::Ipv4,
56        }
57    }
58    /// Build Ethernet packet and return bytes.
59    pub fn build(&self) -> Vec<u8> {
60        let mut buffer: Vec<u8> = vec![0; ETHERNET_HEADER_LEN];
61        let mut eth_packet = MutableEthernetPacket::new(&mut buffer).unwrap();
62        build_ethernet_packet(
63            &mut eth_packet,
64            self.src_mac.clone(),
65            self.dst_mac.clone(),
66            self.ether_type,
67        );
68        eth_packet.to_immutable().packet().to_vec()
69    }
70}
71
72/// Create Dummy Ethernet Frame.
73#[allow(dead_code)]
74pub(crate) fn create_dummy_ethernet_frame(payload_offset: usize, packet: &[u8]) -> Vec<u8> {
75    if packet.len() <= payload_offset {
76        return packet.to_vec();
77    }
78    let buffer_size: usize = packet.len() + ETHERNET_HEADER_LEN - payload_offset;
79    let mut buffer: Vec<u8> = vec![0; buffer_size];
80    let src_mac: MacAddr = MacAddr::zero();
81    let dst_mac: MacAddr = MacAddr::zero();
82    let mut ether_type: EtherType = EtherType::Unknown(0);
83    let mut eth_packet = MutableEthernetPacket::new(&mut buffer).unwrap();
84    if let Some(ip_packet) = Ipv4Packet::new(&packet[payload_offset..]) {
85        let version = ip_packet.get_version();
86        if version == 4 {
87            ether_type = EtherType::Ipv4;
88        } else if version == 6 {
89            ether_type = EtherType::Ipv6;
90        }
91    }
92    build_ethernet_packet(&mut eth_packet, src_mac, dst_mac, ether_type);
93    eth_packet.set_payload(&packet[payload_offset..]);
94    eth_packet.to_immutable().packet().to_vec()
95}