mirror of
https://github.com/zaphar/icmp-socket.git
synced 2025-07-21 19:29:47 -04:00
More unit tests and a bugfix for echo packet construction
This commit is contained in:
parent
f49a16c2f6
commit
8971625151
@ -19,7 +19,15 @@ pub fn main() {
|
|||||||
let mut socket6 = IcmpSocket6::new().unwrap();
|
let mut socket6 = IcmpSocket6::new().unwrap();
|
||||||
socket6.bind("::1".parse::<Ipv6Addr>().unwrap()).unwrap();
|
socket6.bind("::1".parse::<Ipv6Addr>().unwrap()).unwrap();
|
||||||
let mut echo_socket = echo::EchoSocket6::new(socket6);
|
let mut echo_socket = echo::EchoSocket6::new(socket6);
|
||||||
echo_socket.send_ping("::1".parse::<Ipv6Addr>().unwrap(), 42, &[]).unwrap();
|
echo_socket.send_ping("::1".parse::<Ipv6Addr>().unwrap(), 42, &[
|
||||||
|
0x20, 0x20, 0x75, 0x73, 0x74, 0x20, 0x61, 0x20,
|
||||||
|
0x66, 0x6c, 0x65, 0x73, 0x68, 0x20, 0x77, 0x6f,
|
||||||
|
0x75, 0x6e, 0x64, 0x20, 0x20, 0x74, 0x69, 0x73,
|
||||||
|
0x20, 0x62, 0x75, 0x74, 0x20, 0x61, 0x20, 0x73,
|
||||||
|
0x63, 0x72, 0x61, 0x74, 0x63, 0x68, 0x20, 0x20,
|
||||||
|
0x6b, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20,
|
||||||
|
0x6f, 0x66, 0x20, 0x6e, 0x69, 0x20, 0x20, 0x20]).unwrap();
|
||||||
|
let _ = echo_socket.recv_ping();
|
||||||
let resp = echo_socket.recv_ping().unwrap();
|
let resp = echo_socket.recv_ping().unwrap();
|
||||||
println!("seq: {}, identifier: {} payload: {}", resp.sequence, resp.identifier, resp.payload.len());
|
println!("seq: {}, identifier: {} payload: {}", resp.sequence, resp.identifier, resp.payload.len());
|
||||||
}
|
}
|
@ -105,6 +105,7 @@ pub struct EchoSocket6 {
|
|||||||
impl EchoSocket6 {
|
impl EchoSocket6 {
|
||||||
|
|
||||||
pub fn new(sock: IcmpSocket6) -> Self {
|
pub fn new(sock: IcmpSocket6) -> Self {
|
||||||
|
// TODO(jwall): How to set ICMPv6 filters.
|
||||||
EchoSocket6{inner:sock, sequence: 0, buf: Vec::with_capacity(512)}
|
EchoSocket6{inner:sock, sequence: 0, buf: Vec::with_capacity(512)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ fn sum_big_endian_words(bs: &[u8]) -> u32 {
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Icmpv6Message {
|
pub enum Icmpv6Message {
|
||||||
// NOTE(JWALL): All of the below integers should be parsed as big endian on the
|
// NOTE(JWALL): All of the below integers should be parsed as big endian on the
|
||||||
// wire.
|
// wire.
|
||||||
@ -300,7 +300,7 @@ impl Icmpv6Packet {
|
|||||||
/// Construct a packet for Echo Request messages.
|
/// Construct a packet for Echo Request messages.
|
||||||
pub fn with_echo_request(identifier: u16, sequence: u16, payload: Vec<u8>) -> Result<Self, Icmpv6PacketBuildError> {
|
pub fn with_echo_request(identifier: u16, sequence: u16, payload: Vec<u8>) -> Result<Self, Icmpv6PacketBuildError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
typ: 4,
|
typ: 128,
|
||||||
code: 0,
|
code: 0,
|
||||||
checksum: 0,
|
checksum: 0,
|
||||||
message: EchoRequest{
|
message: EchoRequest{
|
||||||
@ -314,7 +314,7 @@ impl Icmpv6Packet {
|
|||||||
/// Construct a packet for Echo Reply messages.
|
/// Construct a packet for Echo Reply messages.
|
||||||
pub fn with_echo_reply(identifier: u16, sequence: u16, payload: Vec<u8>) -> Result<Self, Icmpv6PacketBuildError> {
|
pub fn with_echo_reply(identifier: u16, sequence: u16, payload: Vec<u8>) -> Result<Self, Icmpv6PacketBuildError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
typ: 4,
|
typ: 129,
|
||||||
code: 0,
|
code: 0,
|
||||||
checksum: 0,
|
checksum: 0,
|
||||||
message: EchoReply{
|
message: EchoReply{
|
||||||
@ -326,6 +326,7 @@ impl Icmpv6Packet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Icmpv6PacketBuildError {
|
pub enum Icmpv6PacketBuildError {
|
||||||
InvalidCode(u8),
|
InvalidCode(u8),
|
||||||
}
|
}
|
||||||
@ -349,6 +350,72 @@ impl From<Icmpv6PacketBuildError> for std::io::Error {
|
|||||||
mod checksum_tests {
|
mod checksum_tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn packet_construction_echo_request_test() {
|
||||||
|
let pkt = Icmpv6Packet::with_echo_request(42, 1, vec![1,2,3,4]).unwrap();
|
||||||
|
assert_eq!(pkt.typ, 128);
|
||||||
|
assert_eq!(pkt.code, 0);
|
||||||
|
assert_eq!(pkt.message, EchoRequest{
|
||||||
|
identifier: 42, sequence: 1, payload: vec![1,2,3,4],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn packet_construction_echo_reply_test() {
|
||||||
|
let pkt = Icmpv6Packet::with_echo_reply(42, 1, vec![1,2,3,4]).unwrap();
|
||||||
|
assert_eq!(pkt.typ, 129);
|
||||||
|
assert_eq!(pkt.code, 0);
|
||||||
|
assert_eq!(pkt.message, EchoReply{
|
||||||
|
identifier: 42, sequence: 1, payload: vec![1,2,3,4],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn packet_construction_too_big_test() {
|
||||||
|
let pkt = Icmpv6Packet::with_packet_too_big(3, vec![1,2,3,4]).unwrap();
|
||||||
|
assert_eq!(pkt.typ, 2);
|
||||||
|
assert_eq!(pkt.code, 0);
|
||||||
|
assert_eq!(pkt.message, PacketTooBig{
|
||||||
|
mtu: 3, invoking_packet: vec![1,2,3,4],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn packet_construction_time_exceeded() {
|
||||||
|
let pkt = Icmpv6Packet::with_time_exceeded(0, vec![1,2,3,4]).unwrap();
|
||||||
|
assert_eq!(pkt.typ, 3);
|
||||||
|
assert_eq!(pkt.code, 0);
|
||||||
|
assert_eq!(pkt.message, TimeExceeded{
|
||||||
|
_unused: 0, invoking_packet: vec![1,2,3,4],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn packet_construction_time_exceeded_invalid_code() {
|
||||||
|
let pkt = Icmpv6Packet::with_time_exceeded(2, vec![1,2,3,4]);
|
||||||
|
assert!(pkt.is_err());
|
||||||
|
let e = pkt.unwrap_err();
|
||||||
|
assert_eq!(e, Icmpv6PacketBuildError::InvalidCode(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn packet_construction_parameter_problem() {
|
||||||
|
let pkt = Icmpv6Packet::with_parameter_problem(0, 30, vec![1,2,3,4,5,6,7,8,9,10]).unwrap();
|
||||||
|
assert_eq!(pkt.typ, 4);
|
||||||
|
assert_eq!(pkt.code, 0);
|
||||||
|
assert_eq!(pkt.message, ParameterProblem{
|
||||||
|
pointer: 30, invoking_packet: vec![1,2,3,4,5,6,7,8,9,10],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn packet_construction_parameter_problem_invalid_code() {
|
||||||
|
let pkt = Icmpv6Packet::with_parameter_problem(3, 30, vec![1,2,3,4]);
|
||||||
|
assert!(pkt.is_err());
|
||||||
|
let e = pkt.unwrap_err();
|
||||||
|
assert_eq!(e, Icmpv6PacketBuildError::InvalidCode(3));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn echo_packet_parse_test() {
|
fn echo_packet_parse_test() {
|
||||||
// NOTE(jwall): I am shamelessly ripping ff the cases for this from libpnet
|
// NOTE(jwall): I am shamelessly ripping ff the cases for this from libpnet
|
||||||
|
@ -103,7 +103,8 @@ impl IcmpSocket6 {
|
|||||||
packet = packet.with_checksum(source, &dest);
|
packet = packet.with_checksum(source, &dest);
|
||||||
let dest = ip_to_socket(&IpAddr::V6(dest));
|
let dest = ip_to_socket(&IpAddr::V6(dest));
|
||||||
self.inner.set_unicast_hops_v6(self.opts.hops)?;
|
self.inner.set_unicast_hops_v6(self.opts.hops)?;
|
||||||
self.inner.send_to(&packet.get_bytes(true), &(dest.into()))?;
|
let pkt = packet.get_bytes(true);
|
||||||
|
self.inner.send_to(&pkt, &(dest.into()))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user