Forwarding packets from NIC to WiFi using raw sockets in kernel space - sockets

For a project, I have 2 laptops with 2 wireless interfaces (wlan0 and wlan1) and one NIC, let's call the laptops Sender and Receiver. What I would like to do is to send the odd packets that arrive to Sender through its Ethernet interface through wlan0 and even packets through wlan1 to the Receiver laptop. I want to do so by any means that allow me to inspect every packet by code so that I can modify anything if needed or change the sending policy and I want to do it in kernel space because for this particular task low latency is very important.
Assuming all interfaces are correctly set up (wlan0 from Sender connected to wlan0 from Receiver and the same for wlan1) would Raw Sockets be the fastest choice?
Is there any "easy" way to change 802.3 headers to 802.11 headers?
The steps I am going to try are roughly:
Open a Receiving Raw Socket and a Sending Raw Socket
Receive the Ethernet packet, and extract the upper layers
Encapsulate it with 802.11 headers
Send the modified packet over the Raw Socket
The only step I am not clear on is the 3rd one, I would appreciate any help in this regard.

Is there any "easy" way to change 802.3 headers to 802.11 headers?
Yes. And this is the only right way to deal with them. Do not change them! Both 802.3 and 802.11 are part of the Data Link layer of the OSI model. Processing these headers is the business of the NIC driver but not your business, at least until you are interested in programming a specific NIC device. According to your project description, you need to capture every frame pushed out from the RX queue of the NIC driver of the Ethernet card and forward them to the TX queue of either driver of one WLAN NIC or another WLAN NIC. You need just a policy that will replace the MAC address of the recipient appropriately in the middle -- bridging.
Would Raw Sockets be the fastest choice?
Sockets is a userspace process-oriented interface to networking facilities implemented in the kernel. You mentioned that you care about latency and thus plan to implement bridging in the kernel -- therefore, below the sockets interface. In the kernel mode, you have to deal with socket buffer descriptors (struct sk_buff) that encapsulate frames with respective metadata and rely on the so-called New API (NAPI). You can look at struct net_device and field rx_handler, which seems to be implemented primarily for bridging purposes.

Related

Is there an ethernet link layer protocol to get remote IPv4 settings?

Given one or more embedded devices of the same type with some unknown IPv4 addresses or maybe no IPv4 addresses set at all: is there any Ethernet based network protocol to ”find“ those devices in the local net (LAN) from remote (PC) and get their IPv4 settings?
What not works for me:
ARP: IP address must be known or only finds device I communicated with before (or ugly ARP floods …)
LLDP: point to point only (?), so I would only see the switch between device and me. Also, just announces, no response on request (because there are no requests). Further: asking the switch (which supports LLDP) through SNMP is no option when using dumb switches
IP based protocols: I played with UDP and broadcasts (both as request and response), but that does not work reliably if device and me are on different subnets, and it does not work at all if device has no IPv4 set.
DHCP: does not work in networks without DHCP server, maybe no DHCP client on the embedded device
I assume others had the same problem before, take manufactures of network equipment like access points which should be configured remotely, powerline adapters, switches … all those where the vendor gives you some proprietary tool, the device shows up like magic in a list and you can assign some IPv4 then.
Of course the device must have some daemon listening and responding to certain requests, but what would be a standard protocol for such a task? Or do I have to make up some new protocol for that? May some of the above mentioned is possible, but I overlooked something?
Ethernet only provides a layer 2 connection, so anything Ethernet-based can't ever work across a router (ARP, LLDP - LLDP doesn't even cross a decent switch as it's link layer only).
Depending on the network, routed multicasts or directed broadcasts could work - normally they don't. All vendor tools I've seen just use (Ethernet) broadcasts and don't work across routers.
Most often, simple DNS is used for this purpose - the device registers with the DNS server or is preregistered and you just resolve the name.
Edit: without the router problem, the simplest way is to use a UDP broadcast to some unused port. With DHCP unavailable, the device could fall back to zeroconf (169.254.0.0/16) and broadcast from there.
Without IP, you'd need a "raw" Ethernet socket and use an Ethertype that doesn't interfere with normal network operations.

Issues converting communication from serial port to UDP packets

I have some (very) old software written in C, that was used for two devices that communicate via serial cable (RS232) - both sending and receiving messages.
Now the old devices are to be replaced by new modern ones that do not have serial ports, but only Ethernet.
Hence, the request now is to convert the old serial communication to UDP communication (C++ is the choice for the moment).
So, I have some questions about this "conversion":
1) Suppose there are two peers A and B. Should I implement a server and a client for each peer, i.e.: serverA+clientA (for device A) and serverB+clientB (for device B)? Or is there some other/different approach?...
2) The old serial communication had some CRC, probably to ensure some reliability. Is it CRC necessary to be implemented (in my custom messages) also on UDP communication or not?
Thanks in advance for your time and patience.
1) UDP is a connectionless protocol so there's no rigid client and server roles here. You simply have some code that handles receiving and some code that facilitates sending.
2) You don't need CRC for UDP. First, there's a FCS (CRC32) in each Ethernet frame. Then, there's a header checksum in IP packets. After all, checksum is already included in UPD datagram!
Please also consider the following things:
In everyday life COM ports are long gone from the physical world, but they're still with us in the virtual form (even Android phones have COM ports). There are a lot of solutions for doing COM over USB/TCP/whatever. Some of them are PC apps, some of them are implemented in hardware (see Arduino's COM over USB),
When an UDP datagram fails checksum test, it is dropped (usually) silently. So in UDP you don't have built-in capabilities to distinguish between "nothing was received" and "we received something but that's not a valid thing". Check UDP-Lite if you want to handle these situations on the application level (it should simplify the porting process I believe).
Default choice for transferring data is TCP, because it provides reliable delivery. UDP is recommended for users that care about being realtime and for those who can tolerate some data loss. Or for those who care about the resources.
Choose TCP if you are going to send large amount of data or be ready to handle packet congestion on ports. Choose TCP if you plan to go wireless in future or be ready to handle periodical significant loss of packets.
If your devices are really tiny or filled with other stuff, it is possible to operate directly on Level 2 (Ethernet).

Do TCP Sockets require a wired connection?

I am reading about TCP sockets which require a connection to be set up between a client and a server. Is it possible to have TCP sockets working on a wireless connection?
Perhaps you are interpreting 'connection' to mean 'physical link' (as in, wires). This is incorrect.
'physical' in networking extends to all data transfer mediums. In the case of wireless, this is the radio waves. In terms of TCP a 'connection' is made when one computer is listening on a network and responds to a second computer who makes a request.
TCP doesn't care what physical medium it is travelling through.
With regards to your question it may help to think of the OSI model. In this model TCP sits at level 4. What this should mean is that it can be mostly oblivious to what happens above and below it.
The actual physical layer is level 1 of the OSI model, so TCP should not have to care what is happening there. Thus, whether you are using wires, wireless, fiber or pieces of paper to send the TCP packets is irrelevant, so long as the protocol is enacted as described.
Short answer - Yes.
Read more at wiki
I hope so - I am using mobile broadband. And web access uses TCP/Sockets.
The network technology is organized in so called layers.
Physical transmission of signals is responsibility of the first layer. It can be copper cable, optical fiber, radio signals, homing pigeons, whatever technology there is to get zeros and ones between the machines.
TCP is a fourth layer protocol. It relies on the bottom three layers to route packets of data from the source to the destination. It's responsibility is to make sure that the packets arrive in an orderly fashion.
The whole point of this layered structure is that when you program networking drivers, you don't need to worry what kind of data the user will send on the network. When you program web application you don't need to worry if the user is connected with an ethernet CAT-5 cable, or a cable TV modem.

Can I send non-IP packets using Winsock?

I'm trying to create a small PPPoE Access Concentrator to learn the inner workings of PPPoE.
This requires me to send non-IP packets, I need to be able to set the ETHER_TYPE and eventualy the destination mac fields in the ethernet frame header, but as far as I can tell, raw WinSock sockets give me the ability to supply my own IP header, but not the ethernet header.
Is this true? And if so, is there any way of circumventing this?
I am well aware of WinPcap, and will use it ONLY as a last resort.
I believe that you are correct. Winsock will allow a raw IP socket but does not allow you to get beneath layer 3 and send non-IP packets. For this I believe you would need to pursue the WinPcap / TDI option . More information.

Sockets VS WinPcap

Does anyone know why should I use Winpcap and not just .Net sockets to sniff packets on my local pc?
TY
Sockets (.NET, Winsock, etc.) normally collect at layer 7, the Application layer. That is, whatever is sent by the sender is what is received by the receiver. All of the various headers that are added automatically on the sending side are stripped off by the time the receiver reads the data from the socket.
It is possible to configure a socket to be a raw socket, in which case, you can see all of the headers down to layer 3, the Network layer. Further still, you can put the raw socket in promiscuous mode, which allows you to see all of the traffic on the network, not just the packets destined for your machine. But even this is limited. For example, when you configure the raw socket, you specify the protocol type to use, e.g., IP, ICMP, etc. This limits the socket to "seeing" packets that adhere to that protocol. I have been unable to figure out how to make the socket see all packets at layer 3 regardless of protocol.
Winpcap operates as a device driver at layer 2, the Data Link layer. In this case, you see literally all of the packets on the network with full headers down to layer 2. Winpcap also offers filtering capability so you can narrow down the packets that are reported to you based on whatever criteria you provide.
As far as choosing between them, it really boils down to the requirements of your specific task. If you are trying to implement any kind of realistic network analysis capability, you'll be hardpressed to do that with just sockets. Winpcap makes more sense in that case. However, if you are only interested in IP packets, for example, then sockets will work fine for that.
As far as I understanf .Net sockets are an IPC to communicate between 2 processes. While winpcap is a library that help you to access the data link layer an sniff pacquets going through your network hardware (or virtual) devices on your machine. Data link layer allow to get the data on any socket (.Net or not) created on your system.