Commit Graph

203 Commits

Author SHA1 Message Date
Egor Karavaev f57de10625 Implement wire::{IpCidr/Ipv4Cidr}. 2017-10-03 14:27:17 +00:00
whitequark e4fb2b2997 Make sure IpAddress prohibits exhaustive matches.
I forgot to ensure this.
2017-10-03 13:22:09 +00:00
whitequark 3fa1d60be0 Only verify checksum in pretty printers, do not bail out if invalid.
This lets us e.g. deal with checksum offload on egress packets.
2017-10-03 07:09:53 +00:00
whitequark cf986bf20b Fix insufficient length validation in IPv4 packets.
Found via cargo-fuzz.
2017-10-02 23:03:41 +00:00
whitequark 30754efc4f Formatting. NFC. 2017-10-02 21:51:43 +00:00
Steffen Butzer 61cb64406d support hardware based checksum settings in during packet send/recv
- makes sure the checksum is zeroed when not emitted by software
  (This is required by some implementations such as STM32 to work properly)
2017-10-02 21:40:08 +00:00
whitequark ba93552ccd Fix many warnings. 2017-09-25 00:55:54 +00:00
whitequark 38f648affb Add some docs. 2017-09-24 23:29:42 +00:00
Egor Karavaev 0e88617b82 Uncomment associated constants. 2017-09-24 23:25:18 +00:00
whitequark 5aae15aaba Fix an issue where TCP packets would have zero IP payload length. 2017-09-22 10:14:26 +00:00
whitequark b6e4e23868 Clean up PSH flag handling. 2017-09-22 08:15:29 +00:00
whitequark 9281733209 Implement TCP timeouts. 2017-09-18 11:05:40 +00:00
whitequark 8876d71802 According to RFC 1122, unsupported IP options MUST be ignored. 2017-09-01 19:31:09 +00:00
whitequark d53bdab029 Fix Ipv4Packet::payload{,_mut}() returning overly long buffers.
These functions only skipped the header, but what they should have
done is cut the packet at its total length and skip the header.
Otherwise, if the buffer the IP packet is constructed from contains
padding, such as Ethernet packets, the payload would be too long.
2017-08-30 13:34:50 +00:00
whitequark 695c61fd05 Break up the EthernetInterface::dispatch macro atrocity into functions.
There wasn't any real reason for it to be a macro, it was ugly
and unreadable, and it resulted in combinatorial bloat when compiled.
2017-08-28 05:49:56 +00:00
whitequark afdf73ffef TcpRepr::push → TcpControl::Psh.
This is done for simplification. FIN implies PSH, RST doesn't have
any meaning with PSH, and SYN|PSH only makes sense in the context
of TCP Fast Open, in the context of which, any data in the original
SYN already implies PSH.
2017-08-25 06:05:17 +00:00
whitequark 5b2de544c8 Radically simplify and optimize TCP packet dispatch.
This commit completely reworks packet dispatch in TCP sockets,
and brings significant improvements to processing as well.

In particular:
  * Challenge ACKs now do not reset retransmit timer; instead,
    TcpSocket::process directly returns a TcpRepr without altering
    any internal state at all.
  * Retransmit and close (aka TIME-WAIT) timers are unified
    and restructured into a enum that actually matches semantics
    of the timers.
  * If a packet cannot be emitted, no internal state is changed.
  * The dispatch of RST packets in case of connection abort
    is brought in line with dispatch of all other packets.
  * Packet dispatch now follows a series of steps with clean
    separation of concerns, like packet processing:
      1. If we should retransmit, update state to assume that
         all in-flight packets are lost.
      2. Prepare the packet that would be sent next, considering
         the in-flight packets, if any.
      3. Check if the packet contains anything new, or it's the same
         as the one already in flight. If it is, bail.
      4. Finalize and try to actually transmit the packet.
         If we can't do that, bail.
      5. Update the internal state to reflect that the packet
         we've just sent is in flight.
2017-08-25 03:53:31 +00:00
whitequark 9d0084171f Rework responses to TCP packets and factor in RST replies to TcpSocket. 2017-08-22 22:32:05 +00:00
whitequark ffbb885586 Remove IpEndpoint::accepts.
Unclear purpose, one use, we don't need it.
2017-08-01 11:08:48 +00:00
whitequark a1f865f6d3 Rework and test raw sockets. 2017-07-30 02:02:41 +00:00
whitequark ad12573f62 Rework and test UDP sockets.
Before, errors such as packets not fitting into a buffer would have
resulted in panics, and errors such as unbound sockets were
simply ignored.
2017-07-27 22:30:01 +00:00
whitequark 8d8a4ea583 Get rid of Result<_, ()>.
The use of this type has several drawbacks:
  * It does not allow distinguishing between different error
    conditions. In fact, we wrongly conflated some of them
    before this commit.
  * It does not allow propagation via ? and requires manual use
    of map_err, which is especially tiresome for downstream code.
  * It prevents us from expanding the set of error conditions
    even if right now we have only one.
  * It prevents us from blanket using Result<T> everywhere
    (a nitpick at most).

Instead, use Result<T, Error> everywhere, and differentiate error
conditions where applicable.
2017-07-27 13:55:47 +00:00
whitequark 8a2432dcd7 Rework error handling in TcpSocket::connect. 2017-07-27 12:27:33 +00:00
whitequark a3423b35f4 as_unspecified → to_unspecified 2017-07-27 11:26:07 +00:00
whitequark 1c41f2d7fa Fix determination of local address from incoming packets.
We've advertised this capability before in examples, but it did not
actually work.
2017-07-23 23:07:55 +00:00
whitequark fe6fb087e5 Move macros into their own module.
This allows us to use `enum_with_unknown` in `phy`.
2017-07-23 07:54:36 +00:00
whitequark 6cd8cb4422 Transmit actual UDP checksum of all-zeroes as all-ones instead. 2017-06-26 16:57:21 +00:00
whitequark 2704a10dd8 Add missing #[derive]s on wire::IpVersion. 2017-06-26 06:06:18 +00:00
whitequark 0f0c545755 Make sure representation emission covers every octet of the buffer.
Also fix a bug where TcpRepr::emit would not clear the urgent
pointer.
2017-06-26 03:44:36 +00:00
whitequark b86d22701d Expose PSH flag in TcpRepr. 2017-06-25 08:20:25 +00:00
whitequark 0a9c5d52dd Remove an unnecessary length check. 2017-06-24 16:34:55 +00:00
whitequark 74823b0dff try! → ? 2017-06-24 16:34:32 +00:00
whitequark 023d8deea5 Disable checksum validation on wire level when fuzzing. 2017-06-24 15:26:15 +00:00
whitequark fce23593fc Fix insufficient length validation in TCP packets.
Found via cargo-fuzz.
2017-06-24 12:29:39 +00:00
whitequark c73af2b247 Fix insufficient length validation in UDP packets.
Found via cargo-fuzz.
2017-06-24 12:15:18 +00:00
whitequark 6790eac6d9 Fix a crash parsing a malformed IPv4 packet.
Found via cargo-fuzz.
2017-06-24 12:02:34 +00:00
whitequark 9f8db1d8f9 Factor out wire::tcp::field::OPTIONS. 2017-06-24 12:02:34 +00:00
whitequark 315b51d7da Fix a crash parsing a truncated TCP packet with options.
Found via cargo-fuzz.
2017-06-24 11:48:17 +00:00
whitequark 6842d7013d Fix a crash parsing malformed TCP options.
Found via cargo-fuzz.
2017-06-24 11:48:17 +00:00
whitequark c09e96a657 Fix a crash printing a malformed TCP packet.
Found via cargo-fuzz.
2017-06-24 11:48:13 +00:00
whitequark 8b27330c8b Do not attempt to validate length of packets being emitted.
This is a form of an uninitialized read bug; although safe it caused
panics. In short, transmit buffers received from the network stack
should be considered uninitialized (in practice they will often
contain previously transmitted packets or parts thereof). Wrapping
them with the only method we had (e.g. Ipv4Packet) treated the buffer
as if it contained a valid incoming packet, which can easily fail
with Error::Truncated.

This commit splits every `fn new(buffer: T) -> Result<Self, Error>`
method on a `Packet` into three smaller ones:
  * `fn check_len(&self) -> Result<(), Error>`, purely a validator;
  * `fn new(T) -> Self`, purely a wrapper;
  * `fn new_checked(T) -> Result<Self, Error>`, a validating wrapper.

This makes it easy to process ingress packets (using `new_checked`),
egress packets (using `new`), and, if needed, maintain the invariants
at any point during packet construction (using `check_len`).

Fixes #17.
2017-06-24 11:42:32 +00:00
whitequark cc5fb0e5ef Clean up a few doctests. 2017-06-24 09:02:12 +00:00
whitequark 83cf86f1d0 Unbreak parsing of ICMP unreachable messages.
Fixes #16.
2017-06-21 04:08:33 +00:00
Egor Karavaev ca56baca65 Add `RawSocket`. 2017-06-21 03:29:31 +00:00
Egor Karavaev e927b09ba8 `IpRepr::lower` replaces unspecified src_addr in Ipv4Repr as well. 2017-06-21 03:01:15 +00:00
whitequark 393ebbe682 Don't put non-unicast (IP or Ethernet) addresses into ARP cache.
Thanks @little-dude for pointing this out--it's probably a DoS bug.
2017-03-07 06:32:18 +00:00
whitequark 5137608aed Follow-up to b9e79d19; always process broadcast frames. 2017-03-06 04:00:13 +00:00
whitequark cd894460f5 Implement the TCP SYN-SENT state. 2017-03-05 03:53:04 +00:00
whitequark bc1d65ea89 Send the TCP MSS option. 2017-01-27 02:56:27 +00:00
whitequark 077513fda6 Add support for TCP MSS option in TCP representation. 2017-01-27 02:56:27 +00:00
whitequark 4c3f454902 Add support for TCP option parsing and emission. 2017-01-27 00:33:30 +00:00
whitequark ca1146995f Remove TcpControl::len(). 2017-01-26 21:20:48 +00:00
whitequark 62883a6e0b Don't display IP packet error twice when pretty-printing. 2017-01-14 12:09:30 +00:00
whitequark 578d7bce5f Calculate IP payload length from the total length field.
Before this commit, IP payload length was calculated by subtracting
the IP header length from the total underlying buffer length, which
fails if the underlying buffer has padding, e.g. like Ethernet
does.
2017-01-14 11:07:06 +00:00
whitequark 9b24627d69 Pretty-print TCP and UDP representations, and verify checksums. 2017-01-14 10:08:08 +00:00
whitequark 716a1cf7fe Fix silliness in docs. 2017-01-01 08:15:38 +00:00
whitequark bf3b62bb25 Examples for the phy layer! 2016-12-31 12:28:59 +00:00
whitequark 5bee008464 Examples for the wire layer! 2016-12-31 11:44:51 +00:00
whitequark 818e98f47a TCP: retransmit ACK when receiving duplicate SEQ. 2016-12-31 01:33:46 +00:00
whitequark be68066152 #[inline(always)] → #[inline] 2016-12-30 16:55:31 +00:00
whitequark 287affb447 Implement the TCP TIME-WAIT state. 2016-12-28 05:33:12 +00:00
whitequark 94963faf12 Implement the TCP CLOSING state. 2016-12-28 04:56:49 +00:00
whitequark 151b3ba07b Get rid of the #![feature(associated_consts)]. 2016-12-28 00:12:15 +00:00
whitequark 71268ace88 Get rid of the #![feature(const_fn)]. 2016-12-28 00:08:51 +00:00
whitequark e043e7c496 Get rid of the #![feature(step_by)]. 2016-12-28 00:08:51 +00:00
whitequark e6357ee79c Correctly propagate carries in the IP checksum. 2016-12-27 18:43:49 +00:00
whitequark 6b592742fd Use the correct wrapping operations on TCP sequence numbers. 2016-12-27 18:34:13 +00:00
whitequark ea78053dc1 Factor out IpRepr into the wire module. 2016-12-26 11:20:20 +00:00
whitequark 0ae27678a0 Implement TCP data reception. 2016-12-25 11:09:50 +00:00
whitequark fa1a51b90a Add tests for TCP state machine. 2016-12-24 23:06:42 +00:00
whitequark 6d8d3cb29d Use correct sequence numbers in TCP RST packets. 2016-12-23 07:34:10 +00:00
whitequark 3bd715e1bc Use signed integers to represent TCP sequence numbers. 2016-12-23 07:34:07 +00:00
whitequark bddb5f9127 Implement TCP server sockets. 2016-12-20 19:51:52 +00:00
whitequark 5a64a87dbe Reply with ICMP dest. unreachable or TCP RST from unused ports. 2016-12-20 19:18:35 +00:00
whitequark 0d9a8a417d Add some sanity into enumeration names (avoid "*Type"). 2016-12-20 13:54:11 +00:00
whitequark c562ea784d Fix TcpRepr field visibility. 2016-12-20 13:44:41 +00:00
whitequark 3d5f47b89f Implement TCP representation printing. 2016-12-20 13:16:29 +00:00
whitequark 513923725e Implement TCP representation parsing and emission. 2016-12-20 12:52:33 +00:00
whitequark 31040bf0fc In Repr::emit, do not assume that the packet is pre-zeroed. 2016-12-20 09:41:08 +00:00
whitequark 6d2c11fb61 Fix IP checksum calculation for odd-length packets. 2016-12-20 00:17:29 +00:00
whitequark f86fac2223 Sort out buffer lengths. 2016-12-19 23:50:04 +00:00
whitequark 9c922d0306 Implement TCP packet support. 2016-12-18 21:42:44 +00:00
whitequark 31e44445f5 Working UDP loopback. 2016-12-17 05:12:45 +00:00
whitequark d1d910b46d Significantly simplify buffering. 2016-12-15 17:27:17 +00:00
whitequark fb172ed1ed Implement UDP sockets. 2016-12-14 17:39:44 +00:00
whitequark 2b01a3dace Implement UDP representation parsing and emission. 2016-12-14 02:11:50 +00:00
whitequark 5a721a7b11 Implement UDP packet support. 2016-12-14 00:11:45 +00:00
whitequark 57e544cc8c Return interior pointers more uniformly. 2016-12-13 22:37:05 +00:00
whitequark 53309f8271 Simplify checksum computation. 2016-12-13 17:31:08 +00:00
whitequark 1c616218a1 Respond with ICMP echo request data in echo reply. 2016-12-13 17:02:50 +00:00
whitequark d587981ef5 Implement ICMPv4 echo replies. 2016-12-12 23:22:59 +00:00
whitequark 2482117682 Implement ICMPv4 echo request/reply representation parsing and emission. 2016-12-12 22:38:13 +00:00
whitequark 9fa0bffb7a Implement ICMPv4 echo request/reply packet support. 2016-12-12 22:11:59 +00:00
whitequark c5bdf30458 Implement IPv4 representation parsing and emission. 2016-12-12 20:09:37 +00:00
whitequark 921ca353b4 Implement IPv4 packet support. 2016-12-12 17:26:06 +00:00
whitequark 7f1b88ef45 Implement ARP snooping. 2016-12-12 12:30:35 +00:00
whitequark 4421b2fe27 Implement ARP replies. 2016-12-12 07:19:53 +00:00
whitequark d862512582 Implement an ARP LRU cache. 2016-12-12 02:39:46 +00:00
whitequark 2e80d69384 Naming consistency. 2016-12-11 00:50:34 +00:00
whitequark 2a438b6e8d Factor out pretty-printing of packets. 2016-12-11 00:48:44 +00:00
whitequark 77225b77a9 Fix tests. 2016-12-11 00:30:40 +00:00
whitequark b1149e746c Implement raw socket interface and tcpdump. 2016-12-10 16:58:30 +00:00
whitequark 32ff49a795 Move protocol-related data structures to smoltcp::wire. 2016-12-10 13:13:13 +00:00