`IpRepr::lower` replaces unspecified src_addr in Ipv4Repr as well.
This commit is contained in:
parent
c1c4ed68c5
commit
e927b09ba8
114
src/wire/ip.rs
114
src/wire/ip.rs
|
@ -123,7 +123,7 @@ impl<T: Into<Address>> From<(T, u16)> for Endpoint {
|
||||||
/// This enum abstracts the various versions of IP packets. It either contains a concrete
|
/// This enum abstracts the various versions of IP packets. It either contains a concrete
|
||||||
/// high-level representation for some IP protocol version, or an unspecified representation,
|
/// high-level representation for some IP protocol version, or an unspecified representation,
|
||||||
/// which permits the `IpAddress::Unspecified` addresses.
|
/// which permits the `IpAddress::Unspecified` addresses.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum IpRepr {
|
pub enum IpRepr {
|
||||||
Unspecified {
|
Unspecified {
|
||||||
src_addr: Address,
|
src_addr: Address,
|
||||||
|
@ -219,10 +219,27 @@ impl IpRepr {
|
||||||
|
|
||||||
&IpRepr::Unspecified { dst_addr: Address::Unspecified, .. } =>
|
&IpRepr::Unspecified { dst_addr: Address::Unspecified, .. } =>
|
||||||
panic!("unspecified destination IP address"),
|
panic!("unspecified destination IP address"),
|
||||||
|
|
||||||
// &IpRepr::Unspecified { .. } =>
|
// &IpRepr::Unspecified { .. } =>
|
||||||
// panic!("source and destination IP address families do not match"),
|
// panic!("source and destination IP address families do not match"),
|
||||||
|
|
||||||
repr @ &IpRepr::Ipv4(_) => Ok(repr.clone()),
|
&IpRepr::Ipv4(mut repr) => {
|
||||||
|
if repr.src_addr.is_unspecified() {
|
||||||
|
for addr in fallback_src_addrs {
|
||||||
|
match addr {
|
||||||
|
&Address::Ipv4(addr) => {
|
||||||
|
repr.src_addr = addr;
|
||||||
|
return Ok(IpRepr::Ipv4(repr));
|
||||||
|
}
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(Error::Unaddressable)
|
||||||
|
} else {
|
||||||
|
Ok(IpRepr::Ipv4(repr))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
&IpRepr::__Nonexhaustive => unreachable!()
|
&IpRepr::__Nonexhaustive => unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,3 +328,96 @@ pub mod checksum {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use wire::{Ipv4Address, IpProtocol, IpAddress, Ipv4Repr};
|
||||||
|
#[test]
|
||||||
|
fn ip_repr_lower() {
|
||||||
|
let ip_addr_a = Ipv4Address::new(1, 2, 3, 4);
|
||||||
|
let ip_addr_b = Ipv4Address::new(5, 6, 7, 8);
|
||||||
|
let proto = IpProtocol::Icmp;
|
||||||
|
let payload_len = 10;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
IpRepr::Unspecified{
|
||||||
|
src_addr: IpAddress::Ipv4(ip_addr_a),
|
||||||
|
dst_addr: IpAddress::Ipv4(ip_addr_b),
|
||||||
|
protocol: proto,
|
||||||
|
payload_len
|
||||||
|
}.lower(&[]),
|
||||||
|
Ok(IpRepr::Ipv4(Ipv4Repr{
|
||||||
|
src_addr: ip_addr_a,
|
||||||
|
dst_addr: ip_addr_b,
|
||||||
|
protocol: proto,
|
||||||
|
payload_len
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
IpRepr::Unspecified{
|
||||||
|
src_addr: IpAddress::Unspecified,
|
||||||
|
dst_addr: IpAddress::Ipv4(ip_addr_b),
|
||||||
|
protocol: proto,
|
||||||
|
payload_len
|
||||||
|
}.lower(&[]),
|
||||||
|
Err(Error::Unaddressable)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
IpRepr::Unspecified{
|
||||||
|
src_addr: IpAddress::Unspecified,
|
||||||
|
dst_addr: IpAddress::Ipv4(ip_addr_b),
|
||||||
|
protocol: proto,
|
||||||
|
payload_len
|
||||||
|
}.lower(&[IpAddress::Ipv4(ip_addr_a)]),
|
||||||
|
Ok(IpRepr::Ipv4(Ipv4Repr{
|
||||||
|
src_addr: ip_addr_a,
|
||||||
|
dst_addr: ip_addr_b,
|
||||||
|
protocol: proto,
|
||||||
|
payload_len
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
IpRepr::Ipv4(Ipv4Repr{
|
||||||
|
src_addr: ip_addr_a,
|
||||||
|
dst_addr: ip_addr_b,
|
||||||
|
protocol: proto,
|
||||||
|
payload_len
|
||||||
|
}).lower(&[]),
|
||||||
|
Ok(IpRepr::Ipv4(Ipv4Repr{
|
||||||
|
src_addr: ip_addr_a,
|
||||||
|
dst_addr: ip_addr_b,
|
||||||
|
protocol: proto,
|
||||||
|
payload_len
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
IpRepr::Ipv4(Ipv4Repr{
|
||||||
|
src_addr: Ipv4Address::new(0, 0, 0, 0),
|
||||||
|
dst_addr: ip_addr_b,
|
||||||
|
protocol: proto,
|
||||||
|
payload_len
|
||||||
|
}).lower(&[]),
|
||||||
|
Err(Error::Unaddressable)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
IpRepr::Ipv4(Ipv4Repr{
|
||||||
|
src_addr: Ipv4Address::new(0, 0, 0, 0),
|
||||||
|
dst_addr: ip_addr_b,
|
||||||
|
protocol: proto,
|
||||||
|
payload_len
|
||||||
|
}).lower(&[IpAddress::Ipv4(ip_addr_a)]),
|
||||||
|
Ok(IpRepr::Ipv4(Ipv4Repr{
|
||||||
|
src_addr: ip_addr_a,
|
||||||
|
dst_addr: ip_addr_b,
|
||||||
|
protocol: proto,
|
||||||
|
payload_len
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue