|
@@ -496,75 +496,88 @@ impl Repr {
|
|
|
match self {
|
|
|
#[cfg(feature = "proto-ipv4")]
|
|
|
&Repr::Unspecified {
|
|
|
- src_addr: Address::Ipv4(src_addr),
|
|
|
+ src_addr: src_addr @ Address::Unspecified,
|
|
|
dst_addr: Address::Ipv4(dst_addr),
|
|
|
protocol, payload_len, hop_limit
|
|
|
- } => {
|
|
|
+ } |
|
|
|
+ &Repr::Unspecified {
|
|
|
+ src_addr: src_addr @ Address::Ipv4(_),
|
|
|
+ dst_addr: Address::Ipv4(dst_addr),
|
|
|
+ protocol, payload_len, hop_limit
|
|
|
+ } if src_addr.is_unspecified() => {
|
|
|
+ let mut src_addr = if let Address::Ipv4(src_ipv4_addr) = src_addr {
|
|
|
+ Some(src_ipv4_addr)
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ };
|
|
|
+ for cidr in fallback_src_addrs {
|
|
|
+ if let Address::Ipv4(addr) = cidr.address() {
|
|
|
+ src_addr = Some(addr);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
Ok(Repr::Ipv4(Ipv4Repr {
|
|
|
- src_addr: src_addr,
|
|
|
- dst_addr: dst_addr,
|
|
|
- protocol: protocol,
|
|
|
- payload_len: payload_len, hop_limit
|
|
|
+ src_addr: src_addr.ok_or(Error::Unaddressable)?,
|
|
|
+ dst_addr, protocol, payload_len, hop_limit
|
|
|
}))
|
|
|
}
|
|
|
|
|
|
#[cfg(feature = "proto-ipv6")]
|
|
|
&Repr::Unspecified {
|
|
|
- src_addr: Address::Ipv6(src_addr),
|
|
|
+ src_addr: src_addr @ Address::Unspecified,
|
|
|
dst_addr: Address::Ipv6(dst_addr),
|
|
|
protocol, payload_len, hop_limit
|
|
|
- } => {
|
|
|
+ } |
|
|
|
+ &Repr::Unspecified {
|
|
|
+ src_addr: src_addr @ Address::Ipv6(_),
|
|
|
+ dst_addr: Address::Ipv6(dst_addr),
|
|
|
+ protocol, payload_len, hop_limit
|
|
|
+ } if src_addr.is_unspecified() => {
|
|
|
+ let mut src_addr = if let Address::Ipv6(src_ipv6_addr) = src_addr {
|
|
|
+ Some(src_ipv6_addr)
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ };
|
|
|
+ for cidr in fallback_src_addrs {
|
|
|
+ if let Address::Ipv6(addr) = cidr.address() {
|
|
|
+ src_addr = Some(addr);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
Ok(Repr::Ipv6(Ipv6Repr {
|
|
|
- src_addr: src_addr,
|
|
|
- dst_addr: dst_addr,
|
|
|
+ src_addr: src_addr.ok_or(Error::Unaddressable)?,
|
|
|
next_header: protocol,
|
|
|
- payload_len: payload_len,
|
|
|
- hop_limit: hop_limit
|
|
|
+ dst_addr, payload_len, hop_limit
|
|
|
}))
|
|
|
}
|
|
|
|
|
|
#[cfg(feature = "proto-ipv4")]
|
|
|
&Repr::Unspecified {
|
|
|
- src_addr: Address::Unspecified,
|
|
|
+ src_addr: Address::Ipv4(src_addr),
|
|
|
dst_addr: Address::Ipv4(dst_addr),
|
|
|
protocol, payload_len, hop_limit
|
|
|
} => {
|
|
|
- let mut src_addr = None;
|
|
|
- for cidr in fallback_src_addrs {
|
|
|
- match cidr.address() {
|
|
|
- Address::Ipv4(addr) => {
|
|
|
- src_addr = Some(addr);
|
|
|
- break
|
|
|
- }
|
|
|
- _ => ()
|
|
|
- }
|
|
|
- }
|
|
|
Ok(Repr::Ipv4(Ipv4Repr {
|
|
|
- src_addr: src_addr.ok_or(Error::Unaddressable)?,
|
|
|
- dst_addr, protocol, payload_len, hop_limit
|
|
|
+ src_addr: src_addr,
|
|
|
+ dst_addr: dst_addr,
|
|
|
+ protocol: protocol,
|
|
|
+ payload_len: payload_len, hop_limit
|
|
|
}))
|
|
|
}
|
|
|
|
|
|
#[cfg(feature = "proto-ipv6")]
|
|
|
&Repr::Unspecified {
|
|
|
- src_addr: Address::Unspecified,
|
|
|
+ src_addr: Address::Ipv6(src_addr),
|
|
|
dst_addr: Address::Ipv6(dst_addr),
|
|
|
protocol, payload_len, hop_limit
|
|
|
} => {
|
|
|
- // Find a fallback address to use
|
|
|
- match fallback_src_addrs.iter().filter_map(|cidr| match cidr.address() {
|
|
|
- Address::Ipv6(addr) => Some(addr),
|
|
|
- _ => None
|
|
|
- }).next() {
|
|
|
- Some(addr) =>
|
|
|
- Ok(Repr::Ipv6(Ipv6Repr {
|
|
|
- src_addr: addr,
|
|
|
- next_header: protocol,
|
|
|
- hop_limit: hop_limit,
|
|
|
- dst_addr, payload_len
|
|
|
- })),
|
|
|
- None => Err(Error::Unaddressable)
|
|
|
- }
|
|
|
+ Ok(Repr::Ipv6(Ipv6Repr {
|
|
|
+ src_addr: src_addr,
|
|
|
+ dst_addr: dst_addr,
|
|
|
+ next_header: protocol,
|
|
|
+ payload_len: payload_len,
|
|
|
+ hop_limit: hop_limit
|
|
|
+ }))
|
|
|
}
|
|
|
|
|
|
#[cfg(feature = "proto-ipv4")]
|
|
@@ -875,6 +888,40 @@ pub(crate) mod test {
|
|
|
}))
|
|
|
);
|
|
|
|
|
|
+ assert_eq!(
|
|
|
+ Repr::Unspecified{
|
|
|
+ src_addr: IpAddress::Ipv4(Ipv4Address::UNSPECIFIED),
|
|
|
+ dst_addr: IpAddress::Ipv4(ip_addr_b),
|
|
|
+ protocol: proto,
|
|
|
+ hop_limit: 64,
|
|
|
+ payload_len
|
|
|
+ }.lower(&[IpCidr::new(IpAddress::Ipv4(ip_addr_a), 24)]),
|
|
|
+ Ok(Repr::Ipv4(Ipv4Repr{
|
|
|
+ src_addr: ip_addr_a,
|
|
|
+ dst_addr: ip_addr_b,
|
|
|
+ protocol: proto,
|
|
|
+ hop_limit: 64,
|
|
|
+ payload_len
|
|
|
+ }))
|
|
|
+ );
|
|
|
+
|
|
|
+ assert_eq!(
|
|
|
+ Repr::Unspecified{
|
|
|
+ src_addr: IpAddress::Ipv4(Ipv4Address::UNSPECIFIED),
|
|
|
+ dst_addr: IpAddress::Ipv4(ip_addr_b),
|
|
|
+ protocol: proto,
|
|
|
+ hop_limit: 64,
|
|
|
+ payload_len
|
|
|
+ }.lower(&[]),
|
|
|
+ Ok(Repr::Ipv4(Ipv4Repr{
|
|
|
+ src_addr: Ipv4Address::UNSPECIFIED,
|
|
|
+ dst_addr: ip_addr_b,
|
|
|
+ protocol: proto,
|
|
|
+ hop_limit: 64,
|
|
|
+ payload_len
|
|
|
+ }))
|
|
|
+ );
|
|
|
+
|
|
|
assert_eq!(
|
|
|
Repr::Ipv4(Ipv4Repr{
|
|
|
src_addr: ip_addr_a,
|