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: 20348a6cb8df
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: 00c311a5b8ad
Choose a head ref
  • 2 commits
  • 13 files changed
  • 1 contributor

Commits on Dec 20, 2016

  1. Copy the full SHA
    268a552 View commit details
  2. Copy the full SHA
    00c311a View commit details
Showing with 158 additions and 156 deletions.
  1. +4 −1 README.md
  2. +4 −4 examples/smoltcpserver.rs
  3. +14 −14 src/iface/arp_cache.rs
  4. +19 −19 src/iface/ethernet.rs
  5. +6 −6 src/socket/mod.rs
  6. +18 −19 src/socket/udp.rs
  7. +16 −16 src/wire/arp.rs
  8. +24 −24 src/wire/icmpv4.rs
  9. +10 −10 src/wire/ip.rs
  10. +11 −11 src/wire/ipv4.rs
  11. +6 −6 src/wire/mod.rs
  12. +16 −16 src/wire/tcp.rs
  13. +10 −10 src/wire/udp.rs
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -43,7 +43,10 @@ The UDP protocol is supported over IPv4.

### TCP layer

TCP is **not** supported yet.
The TCP protocol is supported over IPv4.

* TCP header checksum is supported.
* TCP options are **not** supported.

Installation
------------
8 changes: 4 additions & 4 deletions examples/smoltcpserver.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ extern crate smoltcp;
use std::env;
use smoltcp::Error;
use smoltcp::phy::{Tracer, TapInterface};
use smoltcp::wire::{EthernetFrame, EthernetAddress, InternetAddress, InternetEndpoint};
use smoltcp::wire::{EthernetFrame, EthernetAddress, IpAddress, IpEndpoint};
use smoltcp::iface::{SliceArpCache, EthernetInterface};
use smoltcp::socket::{UdpSocket, AsSocket, UdpBuffer, UdpPacket};

@@ -16,10 +16,10 @@ fn main() {
let arp_cache = SliceArpCache::new(vec![Default::default(); 8]);

let hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
let mut protocol_addrs = [InternetAddress::ipv4([192, 168, 69, 1])];
let mut protocol_addrs = [IpAddress::v4(192, 168, 69, 1)];

let listen_address = InternetAddress::ipv4([0, 0, 0, 0]);
let endpoint = InternetEndpoint::new(listen_address, 6969);
let listen_address = IpAddress::v4(0, 0, 0, 0);
let endpoint = IpEndpoint::new(listen_address, 6969);

let udp_rx_buffer = UdpBuffer::new(vec![UdpPacket::new(vec![0; 2048])]);
let udp_tx_buffer = UdpBuffer::new(vec![UdpPacket::new(vec![0; 2048])]);
28 changes: 14 additions & 14 deletions src/iface/arp_cache.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use Managed;
use wire::{EthernetAddress, InternetAddress};
use wire::{EthernetAddress, IpAddress};

/// An Address Resolution Protocol cache.
///
/// This interface maps protocol addresses to hardware addresses.
pub trait Cache {
/// Update the cache to map given protocol address to given hardware address.
fn fill(&mut self, protocol_addr: InternetAddress, hardware_addr: EthernetAddress);
fn fill(&mut self, protocol_addr: IpAddress, hardware_addr: EthernetAddress);

/// Look up the hardware address corresponding for the given protocol address.
fn lookup(&mut self, protocol_addr: InternetAddress) -> Option<EthernetAddress>;
fn lookup(&mut self, protocol_addr: IpAddress) -> Option<EthernetAddress>;
}

/// An Address Resolution Protocol cache backed by a slice.
@@ -33,7 +33,7 @@ pub trait Cache {
/// ```
pub struct SliceCache<'a> {
storage: Managed<'a, [(InternetAddress, EthernetAddress, usize)]>,
storage: Managed<'a, [(IpAddress, EthernetAddress, usize)]>,
counter: usize
}

@@ -43,7 +43,7 @@ impl<'a> SliceCache<'a> {
/// # Panics
/// This function panics if `storage.len() == 0`.
pub fn new<T>(storage: T) -> SliceCache<'a>
where T: Into<Managed<'a, [(InternetAddress, EthernetAddress, usize)]>> {
where T: Into<Managed<'a, [(IpAddress, EthernetAddress, usize)]>> {
let mut storage = storage.into();
if storage.len() == 0 {
panic!("ARP slice cache created with empty storage")
@@ -59,9 +59,9 @@ impl<'a> SliceCache<'a> {
}

/// Find an entry for the given protocol address, if any.
fn find(&self, protocol_addr: InternetAddress) -> Option<usize> {
// The order of comparison is important: any valid InternetAddress should
// sort before InternetAddress::Invalid.
fn find(&self, protocol_addr: IpAddress) -> Option<usize> {
// The order of comparison is important: any valid IpAddress should
// sort before IpAddress::Invalid.
self.storage.binary_search_by_key(&protocol_addr, |&(key, _, _)| key).ok()
}

@@ -77,7 +77,7 @@ impl<'a> SliceCache<'a> {
}

impl<'a> Cache for SliceCache<'a> {
fn fill(&mut self, protocol_addr: InternetAddress, hardware_addr: EthernetAddress) {
fn fill(&mut self, protocol_addr: IpAddress, hardware_addr: EthernetAddress) {
if let None = self.find(protocol_addr) {
let lru_index = self.lru();
self.storage[lru_index] =
@@ -86,7 +86,7 @@ impl<'a> Cache for SliceCache<'a> {
}
}

fn lookup(&mut self, protocol_addr: InternetAddress) -> Option<EthernetAddress> {
fn lookup(&mut self, protocol_addr: IpAddress) -> Option<EthernetAddress> {
if let Some(index) = self.find(protocol_addr) {
let (_protocol_addr, hardware_addr, ref mut counter) =
self.storage[index];
@@ -108,10 +108,10 @@ mod test {
const HADDR_C: EthernetAddress = EthernetAddress([0, 0, 0, 0, 0, 3]);
const HADDR_D: EthernetAddress = EthernetAddress([0, 0, 0, 0, 0, 4]);

const PADDR_A: InternetAddress = InternetAddress::ipv4([0, 0, 0, 0]);
const PADDR_B: InternetAddress = InternetAddress::ipv4([0, 0, 0, 1]);
const PADDR_C: InternetAddress = InternetAddress::ipv4([0, 0, 0, 2]);
const PADDR_D: InternetAddress = InternetAddress::ipv4([0, 0, 0, 3]);
const PADDR_A: IpAddress = IpAddress::v4(0, 0, 0, 0);
const PADDR_B: IpAddress = IpAddress::v4(0, 0, 0, 1);
const PADDR_C: IpAddress = IpAddress::v4(0, 0, 0, 2);
const PADDR_D: IpAddress = IpAddress::v4(0, 0, 0, 3);

#[test]
fn test_slice_cache() {
38 changes: 19 additions & 19 deletions src/iface/ethernet.rs
Original file line number Diff line number Diff line change
@@ -3,9 +3,9 @@ use core::marker::PhantomData;

use Error;
use phy::Device;
use wire::{EthernetAddress, EthernetProtocolType, EthernetFrame};
use wire::{EthernetAddress, EthernetProtocol, EthernetFrame};
use wire::{ArpPacket, ArpRepr, ArpOperation};
use wire::{InternetAddress, InternetProtocolType};
use wire::{IpAddress, IpProtocol};
use wire::{Ipv4Packet, Ipv4Repr};
use wire::{Icmpv4Packet, Icmpv4Repr};
use socket::Socket;
@@ -20,7 +20,7 @@ use super::{ArpCache};
pub struct Interface<'a, 'b: 'a,
DeviceT: Device,
ArpCacheT: ArpCache,
ProtocolAddrsT: BorrowMut<[InternetAddress]>,
ProtocolAddrsT: BorrowMut<[IpAddress]>,
SocketsT: BorrowMut<[Socket<'a, 'b>]>
> {
device: DeviceT,
@@ -34,7 +34,7 @@ pub struct Interface<'a, 'b: 'a,
impl<'a, 'b: 'a,
DeviceT: Device,
ArpCacheT: ArpCache,
ProtocolAddrsT: BorrowMut<[InternetAddress]>,
ProtocolAddrsT: BorrowMut<[IpAddress]>,
SocketsT: BorrowMut<[Socket<'a, 'b>]>
> Interface<'a, 'b, DeviceT, ArpCacheT, ProtocolAddrsT, SocketsT> {
/// Create a network interface using the provided network device.
@@ -77,7 +77,7 @@ impl<'a, 'b: 'a,
Self::check_hardware_addr(&self.hardware_addr);
}

fn check_protocol_addrs(addrs: &[InternetAddress]) {
fn check_protocol_addrs(addrs: &[IpAddress]) {
for addr in addrs {
if !addr.is_unicast() {
panic!("protocol address {} is not unicast", addr)
@@ -86,21 +86,21 @@ impl<'a, 'b: 'a,
}

/// Get the protocol addresses of the interface.
pub fn protocol_addrs(&self) -> &[InternetAddress] {
pub fn protocol_addrs(&self) -> &[IpAddress] {
self.protocol_addrs.borrow()
}

/// Update the protocol addresses of the interface.
///
/// # Panics
/// This function panics if any of the addresses is not unicast.
pub fn update_protocol_addrs<F: FnOnce(&mut [InternetAddress])>(&mut self, f: F) {
pub fn update_protocol_addrs<F: FnOnce(&mut [IpAddress])>(&mut self, f: F) {
f(self.protocol_addrs.borrow_mut());
Self::check_protocol_addrs(self.protocol_addrs.borrow())
}

/// Check whether the interface has the given protocol address assigned.
pub fn has_protocol_addr<T: Into<InternetAddress>>(&self, addr: T) -> bool {
pub fn has_protocol_addr<T: Into<IpAddress>>(&self, addr: T) -> bool {
let addr = addr.into();
self.protocol_addrs.borrow().iter().any(|&probe| probe == addr)
}
@@ -130,7 +130,7 @@ impl<'a, 'b: 'a,
let mut response = Response::Nop;
match eth_frame.ethertype() {
// Snoop all ARP traffic, and respond to ARP packets directed at us.
EthernetProtocolType::Arp => {
EthernetProtocol::Arp => {
let arp_packet = try!(ArpPacket::new(eth_frame.payload()));
match try!(ArpRepr::parse(&arp_packet)) {
// Respond to ARP requests aimed at us, and fill the ARP cache
@@ -166,14 +166,14 @@ impl<'a, 'b: 'a,
},

// Handle IP packets directed at us.
EthernetProtocolType::Ipv4 => {
EthernetProtocol::Ipv4 => {
let ip_packet = try!(Ipv4Packet::new(eth_frame.payload()));
match try!(Ipv4Repr::parse(&ip_packet)) {
// Ignore IP packets not directed at us.
Ipv4Repr { dst_addr, .. } if !self.has_protocol_addr(dst_addr) => (),

// Respond to ICMP packets.
Ipv4Repr { protocol: InternetProtocolType::Icmp, src_addr, dst_addr } => {
Ipv4Repr { protocol: IpProtocol::Icmp, src_addr, dst_addr } => {
let icmp_packet = try!(Icmpv4Packet::new(ip_packet.payload()));
let icmp_repr = try!(Icmpv4Repr::parse(&icmp_packet));
match icmp_repr {
@@ -184,7 +184,7 @@ impl<'a, 'b: 'a,
let ip_reply_repr = Ipv4Repr {
src_addr: dst_addr,
dst_addr: src_addr,
protocol: InternetProtocolType::Icmp
protocol: IpProtocol::Icmp
};
let icmp_reply_repr = Icmpv4Repr::EchoReply {
ident: ident,
@@ -232,7 +232,7 @@ impl<'a, 'b: 'a,
ArpRepr::EthernetIpv4 { target_hardware_addr, .. } => target_hardware_addr,
_ => unreachable!()
});
frame.set_ethertype(EthernetProtocolType::Arp);
frame.set_ethertype(EthernetProtocol::Arp);

let mut packet = try!(ArpPacket::new(frame.payload_mut()));
repr.emit(&mut packet);
@@ -253,7 +253,7 @@ impl<'a, 'b: 'a,
let mut frame = try!(EthernetFrame::new(&mut tx_buffer));
frame.set_src_addr(self.hardware_addr);
frame.set_dst_addr(dst_hardware_addr);
frame.set_ethertype(EthernetProtocolType::Ipv4);
frame.set_ethertype(EthernetProtocol::Ipv4);

let mut ip_packet = try!(Ipv4Packet::new(frame.payload_mut()));
ip_repr.emit(&mut ip_packet, icmp_repr.buffer_len());
@@ -283,11 +283,11 @@ impl<'a, 'b: 'a,
let result = socket.dispatch(&mut |src_addr, dst_addr, protocol, payload| {
let src_addr =
match src_addr {
&InternetAddress::Ipv4(_) if src_addr.is_unspecified() => {
&IpAddress::Ipv4(_) if src_addr.is_unspecified() => {
let mut assigned_addr = None;
for addr in src_protocol_addrs {
match addr {
addr @ &InternetAddress::Ipv4(_) => {
addr @ &IpAddress::Ipv4(_) => {
assigned_addr = Some(addr);
break
}
@@ -304,8 +304,8 @@ impl<'a, 'b: 'a,

let ip_repr =
match (src_addr, dst_addr) {
(&InternetAddress::Ipv4(src_addr),
&InternetAddress::Ipv4(dst_addr)) => {
(&IpAddress::Ipv4(src_addr),
&IpAddress::Ipv4(dst_addr)) => {
Ipv4Repr {
src_addr: src_addr,
dst_addr: dst_addr,
@@ -327,7 +327,7 @@ impl<'a, 'b: 'a,
let mut frame = try!(EthernetFrame::new(&mut tx_buffer));
frame.set_src_addr(src_hardware_addr);
frame.set_dst_addr(dst_hardware_addr);
frame.set_ethertype(EthernetProtocolType::Ipv4);
frame.set_ethertype(EthernetProtocol::Ipv4);

let mut ip_packet = try!(Ipv4Packet::new(frame.payload_mut()));
ip_repr.emit(&mut ip_packet, payload.buffer_len());
12 changes: 6 additions & 6 deletions src/socket/mod.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
//! size for a buffer, allocate it, and let the networking stack use it.
use Error;
use wire::{InternetAddress as Address, InternetProtocolType as ProtocolType};
use wire::{IpAddress, IpProtocol};

mod udp;
mod tcp;
@@ -31,7 +31,7 @@ pub trait PacketRepr {
fn buffer_len(&self) -> usize;

/// Emit this high-level representation into a sequence of octets.
fn emit(&self, src_addr: &Address, dst_addr: &Address, payload: &mut [u8]);
fn emit(&self, src_addr: &IpAddress, dst_addr: &IpAddress, payload: &mut [u8]);
}

/// A network socket.
@@ -61,8 +61,8 @@ impl<'a, 'b> Socket<'a, 'b> {
/// is returned.
///
/// This function is used internally by the networking stack.
pub fn collect(&mut self, src_addr: &Address, dst_addr: &Address,
protocol: ProtocolType, payload: &[u8])
pub fn collect(&mut self, src_addr: &IpAddress, dst_addr: &IpAddress,
protocol: IpProtocol, payload: &[u8])
-> Result<(), Error> {
match self {
&mut Socket::Udp(ref mut socket) =>
@@ -78,8 +78,8 @@ impl<'a, 'b> Socket<'a, 'b> {
/// is returned.
///
/// This function is used internally by the networking stack.
pub fn dispatch(&mut self, f: &mut FnMut(&Address, &Address,
ProtocolType, &PacketRepr) -> Result<(), Error>)
pub fn dispatch(&mut self, f: &mut FnMut(&IpAddress, &IpAddress,
IpProtocol, &PacketRepr) -> Result<(), Error>)
-> Result<(), Error> {
match self {
&mut Socket::Udp(ref mut socket) =>
Loading