Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: smoltcp-rs/smoltcp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1746702f53a7
Choose a base ref
...
head repository: smoltcp-rs/smoltcp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 5c3fc4935eb0
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Jun 26, 2017

  1. Copy the full SHA
    e47e94e View commit details
  2. Discard packets with non-unicast source addresses at IP level.

    This is required by RFC 1122 and helps avoid "broadcast storms".
    whitequark committed Jun 26, 2017
    Copy the full SHA
    5c3fc49 View commit details
Showing with 22 additions and 2 deletions.
  1. +6 −1 src/iface/ethernet.rs
  2. +16 −1 src/wire/udp.rs
7 changes: 6 additions & 1 deletion src/iface/ethernet.rs
Original file line number Diff line number Diff line change
@@ -193,7 +193,12 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
let ipv4_packet = Ipv4Packet::new_checked(eth_frame.payload())?;
let ipv4_repr = Ipv4Repr::parse(&ipv4_packet)?;

if ipv4_repr.src_addr.is_unicast() && eth_frame.src_addr().is_unicast() {
if ipv4_repr.src_addr.is_unicast() {
// Discard packets with non-unicast source addresses.
return Err(Error::Malformed)
}

if eth_frame.src_addr().is_unicast() {
// Fill the ARP cache from IP header of unicast frames.
self.arp_cache.fill(&IpAddress::Ipv4(ipv4_repr.src_addr),
&eth_frame.src_addr());
17 changes: 16 additions & 1 deletion src/wire/udp.rs
Original file line number Diff line number Diff line change
@@ -173,7 +173,11 @@ impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
checksum::data(&data[..self.len() as usize])
])
};
self.set_checksum(checksum)
// UDP checksum value of 0 means no checksum; if the checksum really is zero,
// use all-ones, which indicates that the remote end must verify the checksum.
// Arithmetically, RFC 1071 checksums of all-zeroes and all-ones behave identically,
// so no action is necessary on the remote end.
self.set_checksum(if checksum == 0 { 0xffff } else { checksum })
}
}

@@ -317,6 +321,17 @@ mod test {
assert_eq!(packet.check_len(), Err(Error::Malformed));
}

#[test]
fn test_zero_checksum() {
let mut bytes = vec![0; 8];
let mut packet = Packet::new(&mut bytes);
packet.set_src_port(1);
packet.set_dst_port(31881);
packet.set_len(8);
packet.fill_checksum(&SRC_ADDR.into(), &DST_ADDR.into());
assert_eq!(packet.checksum(), 0xffff);
}

fn packet_repr() -> Repr<'static> {
Repr {
src_port: 48896,