Skip to content

Commit

Permalink
Introduction of sending ARP pakcets.
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul-weqe committed Jun 29, 2024
1 parent 76f62ea commit 808255b
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 18 deletions.
55 changes: 37 additions & 18 deletions holo-vrrp/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// SPDX-License-Identifier: MIT
//

use std::net::IpAddr;
use std::net::{IpAddr, SocketAddrV4, Ipv4Addr};
use std::sync::Arc;

use holo_utils::socket::{AsyncFd, Socket};
Expand All @@ -14,16 +14,20 @@ use socket2::{Domain, Protocol, Type};
use tokio::sync::mpsc::error::SendError;

use crate::error::IoError;
use crate::packet::VrrpPacket;
use crate::packet::{VrrpPacket, ArpPacket};
use crate::tasks::messages::input::NetRxPacketMsg;
use crate::tasks::messages::output::NetTxPacketMsg;

pub fn socket_vrrp(_ifname: &str) -> Result<Socket, std::io::Error> {
pub(crate) fn socket_vrrp(ifname: &str) -> Result<Socket, std::io::Error> {
#[cfg(not(feature = "testing"))]
{
let socket = capabilities::raise(|| {
Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::from(112)))
})?;

capabilities::raise(|| {
socket.bind_device(Some(ifname.as_bytes()))
})?;
socket.set_broadcast(true)?;
Ok(socket)
}
Expand All @@ -33,14 +37,15 @@ pub fn socket_vrrp(_ifname: &str) -> Result<Socket, std::io::Error> {
}
}

pub(crate) fn socket_arp(_ifname: &str) -> Result<Socket, std::io::Error> {
pub(crate) fn socket_arp(ifname: &str) -> Result<Socket, std::io::Error> {
#[cfg(not(feature = "testing"))]
{
// TODO
let eth_p_all = 0x0003;
let socket = capabilities::raise(|| {
Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::from(112)))
Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::from(eth_p_all)))
})?;
socket.set_broadcast(true)?;
socket.bind_device(Some(ifname.as_bytes()));
Ok(socket)
}
#[cfg(feature = "testing")]
Expand All @@ -50,33 +55,45 @@ pub(crate) fn socket_arp(_ifname: &str) -> Result<Socket, std::io::Error> {
}

#[cfg(not(feature = "testing"))]
pub async fn send_packet_vrrp(
pub(crate) async fn send_packet_vrrp(
socket: &AsyncFd<Socket>,
_src: IpAddr,
_dst: IpAddr,
packet: VrrpPacket,
) -> Result<usize, IoError> {
use std::net::{Ipv4Addr, SocketAddrV4};

let buf: &[u8] = &packet.encode();
let saddr = SocketAddrV4::new(Ipv4Addr::new(224, 0, 0, 8), 0);

socket
.async_io(tokio::io::Interest::WRITABLE, |sock| {
sock.send_to(&buf, &saddr.into())
sock.send_to(buf, &saddr.into())
.map_err(|errno| errno.into())
})
.await
.map_err(IoError::SendError)
}

#[cfg(not(feature = "testing"))]
async fn send_packet_arp(
_socket: &AsyncFd<Socket>,
// TODO: add other params
) -> Result<(), IoError> {
// TODO
Ok(())
pub(crate) async fn send_packet_arp(
socket: &AsyncFd<Socket>,
packet: ArpPacket
) -> Result<usize, IoError> {

let buf: &[u8]= &packet.encode();
let target = Ipv4Addr::from(packet.clone().target_proto_address);
let saddr = SocketAddrV4::new(target, 0);

socket
.async_io(tokio::io::Interest::WRITABLE, |sock| {
sock.send_to(&buf, &saddr.into())
.map_err(|errno| {
println!("error...{:#?}", errno);
errno.into()
})
})
.await
.map_err(IoError::SendError)
}

#[cfg(not(feature = "testing"))]
Expand All @@ -95,9 +112,11 @@ pub(crate) async fn write_loop(
}
}
NetTxPacketMsg::Arp {} => {
if let Err(error) = send_packet_arp(&socket_arp).await {
error.log();
}

// if let Err(error) = send_packet_arp(&socket_arp).await {
// error.log();
// }

}
}
}
Expand Down
70 changes: 70 additions & 0 deletions holo-vrrp/src/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,21 @@ pub struct Ipv4Packet {
pub padding: Option<u8>,
}


#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Deserialize, Serialize)]
pub struct ArpPacket {
pub hw_type: u16,
pub proto_type: u16,
pub hw_length: u8,
pub proto_length: u8,
pub operation: u16,
pub sender_hw_address: [u8; 6], // src mac
pub sender_proto_address: [u8; 4], // src ip
pub target_hw_address: [u8; 6], // src mac
pub target_proto_address: [u8; 4] // src ip
}

#[derive(Debug, Eq, PartialEq)]
#[derive(Deserialize, Serialize)]
pub enum DecodeError {
Expand Down Expand Up @@ -306,6 +321,61 @@ impl Ipv4Packet {
}
}


impl ArpPacket {
pub fn encode(&self) -> BytesMut {
let mut buf = BytesMut::with_capacity(28);
buf.put_u16(self.hw_type);
buf.put_u16(self.proto_type);
buf.put_u8(self.hw_length);
buf.put_u8(self.proto_length);
buf.put_u16(self.operation);

for x in self.sender_hw_address { buf.put_u8(x); }
for x in self.sender_proto_address { buf.put_u8(x); }
for x in self.target_hw_address { buf.put_u8(x) }
for x in self.target_proto_address { buf.put_u8(x) }
buf
}

pub fn decode(data: &[u8]) ->DecodeResult<Self> {
if data.len() != 28 {
return Err(DecodeError::PacketLengthError)
}
let mut buf = Bytes::copy_from_slice(data);

let hw_type = buf.get_u16();
let proto_type = buf.get_u16();
let hw_length = buf.get_u8();
let proto_length = buf.get_u8();
let operation = buf.get_u16();
let mut sender_hw_address: [u8; 6] = [0_u8; 6];
for x in 0..6 { sender_hw_address[x] = buf.get_u8(); }

let mut sender_proto_address: [u8; 4] = [0_u8; 4];
for x in 0..4 { sender_proto_address[x] = buf.get_u8(); }

let mut target_hw_address: [u8; 6] = [0_u8; 6];
for x in 0..6 { target_hw_address[x] = buf.get_u8(); }

let mut target_proto_address: [u8; 4] = [0_u8; 4];
for x in 0..4 { target_hw_address[x] = buf.get_u8(); }

Ok(Self {
hw_type,
proto_type,
hw_length,
proto_length,
operation,
sender_hw_address,
sender_proto_address,
target_hw_address,
target_proto_address,
})

}
}

pub mod checksum {
pub fn calculate(data: &[u8], checksum_position: usize) -> u16 {
let mut result: u16 = 0;
Expand Down
44 changes: 44 additions & 0 deletions holo-vrrp/tests/packet/arp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// Copyright (c) The Holo Core Contributors
//
// SPDX-License-Identifier: MIT
//

use holo_vrrp::packet::{ArpPacket, DecodeError};


/*
ARP packet =>
hw_type: 1,
proto_type: 0x0800,
hw_length: 6,
proto_length: 4,
operation: 1,
sender_hw_address: [0xd4, 0xb1, 0x08, 0x4c, 0xbb, 0xf9], // src mac
sender_proto_address: [192, 168, 100, 1], // src ip
pub target_hw_address: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // src mac
pub target_proto_address: [192, 168, 100, 16] // src ip
*/
fn valid_pkt_data() -> [u8; 28] {
[

0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xd4, 0xb1, 0x08, 0x4c, 0xbb, 0xf9,
0xc0, 0xa8, 0x64, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x64, 0x10
]
}


#[test]
fn encode_valid_pkt(){
let pkt_wrapped = ArpPacket::decode(&valid_pkt_data());
assert!(pkt_wrapped.is_ok());
}

#[test]
fn test_pkt_invalid_length() {
let pkt = ArpPacket::decode(&[0x01]);
assert_eq!(pkt, Err(DecodeError::PacketLengthError));
}
1 change: 1 addition & 0 deletions holo-vrrp/tests/packet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@

mod ipv4;
mod vrrp;
mod arp;

0 comments on commit 808255b

Please sign in to comment.