smoltcp-rs / smoltcp

a smol tcp/ip stack
BSD Zero Clause License
3.73k stars 414 forks source link

Support for layer 3 mediums (IP only, non-Ethernet) #334

Closed Dirbaio closed 3 years ago

Dirbaio commented 4 years ago

It would be useful to have support for non-ethernet interfaces, that send/receive raw IP packets without ethernet headers and don't do ARP/NDISC.

There are several use cases for this:

I'm willing to take a look at implementing it. Is this something you would be interested in?

If so, how do you think it'd be the best way to implement it?

From a quick look at the code IMO the cleanest way would be to separate all the IP stuff into an "IP interface" struct, and have the Ethernet interface embed it. Socket handling, IP handling would go in the IP interface, ARP, NDISC and Ethernet header stuff would go in the Ethernet interface. I'm not sure how to handle some details though, such as NDISC handling which is deep in the ipv6 handling code.

whitequark commented 4 years ago

Is this something you would be interested in?

This is something that is definitely useful, see #326 for example.

If so, how do you think it'd be the best way to implement it?

I'm not entirely sure, either. I suspect the most practical way to do this is to have a completely separate IPInterface, because there are many concepts that won't apply at all to a pure-IP interface, like ARP, NDISC, broadcast/multicast, and so on.

Personally, I would be fine with a significant amount of code duplication between IPInterface and EthernetInterface because I strongly suspect that embedding the former into the latter wouldn't really work (or would be so complex as to outweigh the benefits of sharing code between them), but if you experiment with it and it turns out I'm wrong, we can do that too.

lattice0 commented 4 years ago

I was about to open an issue on this. I'm working on making a OpenVPN3 library. That is, I want to send/receive through OpenVPN as a library, not using the OS's tun/tap devices. Since OpenVPN3 client has only support for IP packet transmission (no ethernet packets transmission) my idea was to use this library to process the IP packets, without even touching ethernet. But it looks like it's not possible?

Or at least I need to make a fake ethernet device? Anyone could explain me better what am I supposed to do?

OpenVPN C++ IP packet transmission is already working, I just need to plug an IP stack into it

whitequark commented 4 years ago

PR #336 is handling this exact problem, and is pretty far in review, though it still needs some minor changes to proceed.

lattice0 commented 4 years ago

Nice @whitequark, I hope it merges.

I searched for IP stacks in C, C++, Rust and OCaml and only this one was: easy to read, easy to interface with C++, easy to compile as a library used by C++, all at same time. MirageOS's OCaml IP stack is easy to read but hard to compile as a library. C has only linux and freebsd ports of IP stacks that are huge and unsafe due to C's nature. C++ has no good libraries (aipstack is a mess)

This one is the chosen one for my project, https://github.com/lucaszanella/libopenvpn3

Thanks for writing this awesome library.

whitequark commented 4 years ago

I'm glad you like it!

Dirbaio commented 3 years ago

Done in #401