port and ip serialization tests

This commit is contained in:
debris 2016-09-19 17:56:32 +02:00
parent bf6dec9d5f
commit 2d2ee4a9dd
4 changed files with 142 additions and 88 deletions

View File

@ -1,94 +1,8 @@
use std::{net, str};
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
use ser::{
Stream, Serializable,
Reader, Deserializable, Error as ReaderError
};
use ServiceFlags;
#[derive(Debug, PartialEq)]
pub struct Port(u16);
impl From<u16> for Port {
fn from(port: u16) -> Self {
Port(port)
}
}
impl Serializable for Port {
fn serialize(&self, stream: &mut Stream) {
stream.write_u16::<BigEndian>(self.0).unwrap();
}
}
impl Deserializable for Port {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
Ok(try!(reader.read_u16::<BigEndian>().map(Port)))
}
}
#[derive(Debug, PartialEq)]
pub struct IpAddress(net::IpAddr);
impl From<net::IpAddr> for IpAddress {
fn from(ip: net::IpAddr) -> Self {
IpAddress(ip)
}
}
impl From<&'static str> for IpAddress {
fn from(s: &'static str) -> Self {
s.parse().unwrap()
}
}
impl str::FromStr for IpAddress {
type Err = <net::IpAddr as str::FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
s.parse().map(IpAddress)
}
}
impl Serializable for IpAddress {
fn serialize(&self, stream: &mut Stream) {
match self.0 {
net::IpAddr::V4(address) => {
stream
.append_slice(&[0u8; 12])
.append_slice(&address.octets());
},
net::IpAddr::V6(address) => {
for segment in &address.segments() {
stream.write_u16::<BigEndian>(*segment).unwrap();
}
},
}
}
}
impl Deserializable for IpAddress {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let mut bytes = try!(reader.read_slice(12));
if bytes == &[0u8; 12] {
let address = try!(reader.read_slice(4));
let address = net::Ipv4Addr::new(address[0], address[1], address[2], address[3]);
Ok(IpAddress(net::IpAddr::V4(address)))
} else {
let address = net::Ipv6Addr::new(
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(reader.read_u16::<BigEndian>()),
try!(reader.read_u16::<BigEndian>())
);
Ok(IpAddress(net::IpAddr::V6(address)))
}
}
}
use {Port, IpAddress, ServiceFlags};
#[derive(Debug, PartialEq)]
pub struct NetAddress {

89
net/src/ip.rs Normal file
View File

@ -0,0 +1,89 @@
use std::{str, net};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
#[derive(Debug, PartialEq)]
pub struct IpAddress(net::IpAddr);
impl From<net::IpAddr> for IpAddress {
fn from(ip: net::IpAddr) -> Self {
IpAddress(ip)
}
}
impl From<&'static str> for IpAddress {
fn from(s: &'static str) -> Self {
s.parse().unwrap()
}
}
impl str::FromStr for IpAddress {
type Err = <net::IpAddr as str::FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
s.parse().map(IpAddress)
}
}
impl Serializable for IpAddress {
fn serialize(&self, stream: &mut Stream) {
match self.0 {
net::IpAddr::V4(address) => {
stream
.append_slice(&[0u8; 12])
.append_slice(&address.octets());
},
net::IpAddr::V6(address) => {
for segment in &address.segments() {
stream.write_u16::<BigEndian>(*segment).unwrap();
}
},
}
}
}
impl Deserializable for IpAddress {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let mut bytes = try!(reader.read_slice(12));
if bytes == &[0u8; 12] {
let address = try!(reader.read_slice(4));
let address = net::Ipv4Addr::new(address[0], address[1], address[2], address[3]);
Ok(IpAddress(net::IpAddr::V4(address)))
} else {
let address = net::Ipv6Addr::new(
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(reader.read_u16::<BigEndian>()),
try!(reader.read_u16::<BigEndian>())
);
Ok(IpAddress(net::IpAddr::V6(address)))
}
}
}
#[cfg(test)]
mod test {
use std::net;
use ser::{serialize, deserialize};
use super::IpAddress;
#[test]
fn test_ip_serialize() {
let ip = IpAddress(net::IpAddr::V6("::ffff:a00:1".parse().unwrap()));
assert_eq!(serialize(&ip), vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x01]);
let ip = IpAddress(net::IpAddr::V4("10.0.0.1".parse().unwrap()));
assert_eq!(serialize(&ip), vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x01]);
}
#[test]
fn test_ip_deserialize() {
let ip: IpAddress = deserialize(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x01]).unwrap();
assert_eq!(ip, IpAddress(net::IpAddr::V6("::ffff:a00:1".parse().unwrap())));
let ip: IpAddress = deserialize(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x01]).unwrap();
assert_eq!(ip, IpAddress(net::IpAddr::V4("10.0.0.1".parse().unwrap())));
}
}

View File

@ -2,7 +2,11 @@ extern crate byteorder;
extern crate serialization as ser;
mod address;
mod ip;
mod port;
mod service;
pub use self::address::{Port, IpAddress, NetAddress};
pub use self::address::NetAddress;
pub use self::ip::IpAddress;
pub use self::port::Port;
pub use self::service::ServiceFlags;

47
net/src/port.rs Normal file
View File

@ -0,0 +1,47 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
#[derive(Debug, PartialEq)]
pub struct Port(u16);
impl From<u16> for Port {
fn from(port: u16) -> Self {
Port(port)
}
}
impl From<Port> for u16 {
fn from(port: Port) -> Self {
port.0
}
}
impl Serializable for Port {
fn serialize(&self, stream: &mut Stream) {
stream.write_u16::<BigEndian>(self.0).unwrap();
}
}
impl Deserializable for Port {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
Ok(try!(reader.read_u16::<BigEndian>().map(Port)))
}
}
#[cfg(test)]
mod tests {
use ser::{serialize, deserialize};
use super::Port;
#[test]
fn test_port_serialize() {
assert_eq!(serialize(&Port::from(1)), vec![0x00, 0x01]);
assert_eq!(serialize(&Port::from(0x1234)), vec![0x12, 0x34]);
}
#[test]
fn test_port_deserialize() {
assert_eq!(Port::from(1), deserialize(&[0x00, 0x01]).unwrap());
assert_eq!(Port::from(0x1234), deserialize(&[0x12, 0x34]).unwrap());
}
}