From f49a16c2f6ca80ae6508420637a86a36c0b7e310 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Sat, 16 Jan 2021 13:45:12 -0500 Subject: [PATCH] Example and some debugging --- examples/ping6.rs | 25 +++++++++++++++++++++++++ src/echo.rs | 6 ++++-- src/packet.rs | 5 ++++- 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 examples/ping6.rs diff --git a/examples/ping6.rs b/examples/ping6.rs new file mode 100644 index 0000000..c5b73ff --- /dev/null +++ b/examples/ping6.rs @@ -0,0 +1,25 @@ +// Copyright 2021 Jeremy Wall +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +use std::net::Ipv6Addr; + +use icmp_socket::*; + +pub fn main() { + let mut socket6 = IcmpSocket6::new().unwrap(); + socket6.bind("::1".parse::().unwrap()).unwrap(); + let mut echo_socket = echo::EchoSocket6::new(socket6); + echo_socket.send_ping("::1".parse::().unwrap(), 42, &[]).unwrap(); + let resp = echo_socket.recv_ping().unwrap(); + println!("seq: {}, identifier: {} payload: {}", resp.sequence, resp.identifier, resp.payload.len()); +} \ No newline at end of file diff --git a/src/echo.rs b/src/echo.rs index 8e6220a..07f5dd9 100644 --- a/src/echo.rs +++ b/src/echo.rs @@ -17,13 +17,14 @@ use std::net::{Ipv4Addr, Ipv6Addr}; use packet::{Builder, Packet as P}; use packet::icmp::echo::Packet; -use crate::packet::{Icmpv6Packet, Icmpv6Message::{EchoReply, EchoRequest}}; +use crate::packet::{Icmpv6Packet, Icmpv6Message::EchoReply}; // TODO(jwall): It turns out that the ICMPv6 packets are sufficiently // different from the ICMPv4 packets. In order to handle them appropriately // It is going to take some consideration. use crate::{IcmpSocket4, IcmpSocket6}; +#[derive(Debug)] pub struct EchoResponse { pub identifier: u16, pub sequence: u16, @@ -45,7 +46,7 @@ impl TryFrom for EchoResponse { payload, }) } else { - Err(std::io::Error::new(std::io::ErrorKind::Other, "Incorrect icmpv6 message")) + Err(std::io::Error::new(std::io::ErrorKind::Other, format!("Incorrect icmpv6 message: {:?}, code: {}", pkt.message, pkt.code))) } } } @@ -119,6 +120,7 @@ impl EchoSocket6 { } pub fn recv_ping(&mut self) -> std::io::Result { + self.buf.resize(512, 0); let bytes_read = self.inner.rcv_from(&mut self.buf)?; match Icmpv6Packet::parse(&self.buf[0..bytes_read]) { Ok(p) => return Ok(p.try_into()?), diff --git a/src/packet.rs b/src/packet.rs index b8bedea..4fe215a 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -369,7 +369,7 @@ mod checksum_tests { 0x6b, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x6e, 0x69, 0x20, 0x20, 0x20 ]; - let pkt = Icmpv6Packet::parse(&data).unwrap(); + let mut pkt = Icmpv6Packet::parse(&data).unwrap(); assert_eq!(pkt.typ, 128); assert_eq!(pkt.code, 0x00); if let EchoRequest{ @@ -393,6 +393,8 @@ mod checksum_tests { } assert_eq!(pkt.get_bytes(true), data); assert_eq!(pkt.calculate_checksum(lo, lo), 0x1d2e); + pkt = pkt.with_checksum(lo, lo); + assert_eq!(pkt.checksum, 0x1d2e); // Check echo response as well data[0] = 0x81; @@ -418,6 +420,7 @@ mod checksum_tests { } else { assert!(false, "Packet did not parse as an EchoReply {:?}", pkt.message); } + assert_eq!(pkt.get_bytes(true), data); assert_eq!(pkt.calculate_checksum(lo, lo), 0x1c2e); } } \ No newline at end of file