understanding link layer multicasting - c

I am fairly new to network programming especially L2.
I am working on an implementation of LLDP(Link Layer Discovery Protocol) in C. I understand that multicasting over link layer works on directly connected LAN devices. My aim is to have it work across VLAN's (Eg: a device in 10.1.1.0 pool should be able to receive L2 multicast packets sent by a device in 192.168.1.0).
Is there a possible way to achieve this ..or am I missing something vital here?
Wireshark wiki on LLDP says:
LLDP Data Units (LLDPDUs) are sent to the destination MAC address 01:80:c2:00:00:0e. This address is defined as the "LLDP_Multicast" address. This address is defined within a range of addresses reserved by the IEEE for protocols that are to be constrained to an individual LAN. AN LLDPDU will not be forwarded by MAC bridges (e.g. switches) that conform to IEEE Std 802.1D-2004.
so does that mean that a switch or a router just ignores link layer multicast packets coming from another device in another subnet?
does multicast over link layer work only on directly connected devices?
what is the scope of a data link layer multicast address?

From your question, it seems you are mixing L2 and L3 technologies. If you are dealing L2 multicast, IP addresses have no meaning there.
As for the questions:
1) When talking about switches, you have to consider if a switch is 802.1D compliant or not. A dumb switch (a. la Generic $5 from a store next door) will treat your LLDP PDU as a broadcast frame and will distribute it to all other ports except for the one it received it from. This is because MAC address starts with 01 which indicates that the group address bit is set.
A switch which is 802.1D compliant will not forward this frame anywhere. It might process it locally to learn about a device sending it. This will happen if the switch has LLDP protocol support enabled.
A router will act in the same way as a 802.1D compliant switch. It will not forward the LLDP frame and might process it if the LLDP is enabled.
A PC will act the same was as a router.
2) Scope will depend on the endpoints of a link. Any smart device will terminate the journey of the LLDP frame. A dumb switch will treat it as a broadcast frame.

Link-local multicasts will not be propagated off a link. Because of that, the question of ignoring, or not, a link-local multicast from another link will never come up.
You will not be successful in creating an LLDP implementation which originates on one link and is received on a different link. You will need to create a completely different protocol to do what you want, and you will need to change the software on the network devices to recognize this new protocol. This will not be possible with network devices which run proprietary software.

Related

Send a ping through a specific next hop in linux userspace C

How can I send icmp requests and control the next hop from a Linux C user space application I'm writing.
I have a single NIC (192.168.1.10/24) which is connected to 2 routers on the same subnet (192.168.1.1 and 192.168.1.2).
I would like to reach the internet (8.8.8.8) through 192.168.1.1 and 192.168.1.2 and decide what is my default route according to the latency results.
Is there a way I could control the immediate next hop in user space C ? I'm using raw sockets.
You can use source-routing:
In computer networking, source routing, also called path addressing, allows a sender of a packet to partially or completely specify the route the packet takes through the network.[1] In contrast, in conventional routing, routers in the network determine the path incrementally based on the packet's destination.
Note, though, it's quite common for source-routed packets to be summarily and silently dropped as there's no way for the receiver to trust that they came from where they seem to have come from without alteration.
Sonicwall has this to say about their firewall configuration:
Drop Source Routed IP Packets - (Enabled by default.) Clear this checkbox if you are testing traffic between two specific hosts and you are using source routing.
IP Source Routing is a standard option in IP that allows the sender of a packet to specify some or all of the routers that should be used to get the packet to its destination.
This IP option is typically blocked from use as it can be used by an eavesdropper to receive packets by inserting an option to send packets from A to B via router C. The routing table should control the path that a packet takes, so that it is not overridden by the sender or a downstream router.

Send Packets to another subnet/network using Sockets

I am trying to find out whether the machines in a network are running a certain app. More like, I am trying to resolve addresses of nodes in a network.
I built a small code based on ARP, but it works only on a local network(same subnet). What I want to do is resolve addresses out of the subnet i.e. all other nodes.
I read these answers: UDP broadcast packets across subnets
and Broadcast on different subnets
But they all talk about changing router setting or creating a multicast network.
From what I read for multicasting to work, I need to create a multitask network beforehand. Is it really necessary?
And for changing router setting, does it really have to be a "special" router?
This is all for a college assignment and would be demonstrating it probably on an ad-hoc network or something like that.
I am open to ideas to solve the original problem.
PS:
1. I am a beginner in networking so do excuse me for any fault or misinterpretation.
I am using sockets and C(No other option).
Edit 1:
I am well aware ARP is useless outside the subnet. I mentioned it because I used it and it helped explaining the problem.
Edit 2:
The original problem is:
Building a chat application, nothing fancy sending messages from one point to another, without using a central server of any kind. Not even a hybrid network with a central store is allowed.
i.e. if A and B are two clients, A should directly connect to B and vice versa.
I did some research and decided to use P2P architecture. And now I am stuck to how will A discover address of B. If I know the subnet of B, I can brute force and locate B but since I don't have such information what do I do?
ARP is not intended to be routed outside the local network, where in IPv4, the "local network" typically corresponds to a subnet. You should not expect ARP traffic to transit routers from inside to outside or vise versa.
Similarly, UDP broadcasts generally do not propagate outside the local network, and it's a good thing that they don't, for reasons related to both security and traffic volume.
From what I read for multicasting to work, I need to create a multitask network beforehand. Is it really necessary?
Basically, yes. Your routers need to be configured to support multicasting (which may be their default). All participants need to agree on and join the same multicast group. There might not be a need for any new networking hardware, but multicast communication has its own protocols and network requirements; it is not merely a broadcast that can traverse network boundaries.
And for changing router setting, does it really have to be a "special" router?
If you mean changing router settings so that UDP broadcasts are routed between networks, you do indeed need a router that exposes this capability. But I urge you not to do this, as it will let broadcasts from all other sources, for all other reasons transit the router, too. At minimum, this will significantly increase the noisiness of all networks involved, but it could produce bona fide misbehavior of applications and services other than yours.
The Limited Broadcast (255.255.255.255, which is used by ARP requests as the destination address, and ARP only works for IPv4 on the local LAN) cannot cross a router, and a Network Broadcast (last network address, where the host is all ones) by default cannot cross a router (Directed Broadcast) because it is a security risk (see RFC 2644, Changing the Default for Directed Broadcasts in Routers).
Some routers can be configured to forward directed broadcasts, but this can be dangerous.
Multicast is a form of broadcast. Multicast routing is very different than unicast routing, and every router in a path must be configured for multicast routing. Also, hosts must subscribe to a multicast group before they will even listen for packets from a multicast group. Additionally, there are some multicast groups that all hosts listen for, but those are link-local multicasts that cannot be forwarded off the local LAN.
Adding to what other answers have provided:
ARP is not useful for a system in another subnet. Even if you were able to send an ARP request to a system in the other subnet, and receive its response somehow -- providing you with that system's MAC address -- you could not use it to send a packet to that system because Ethernet does not provide a routing mechanism, and so the system will never see any Ethernet packet you address to it.
If you are simply trying to identify which systems within another IP subnet are live, you can probably do this by other means. Take a look at the nmap command, for example. It supports a wide variety of IP communications methods that will be routed to the other subnet and can often detect what machines are present and which services are available on the machines found.
And you can of course duplicate what nmap does yourself. For example, if you want to find out which systems in subnet 192.168.10.0/24 are listening on TCP port 80, one way is to simply attempt to connect to port 80 on each system in that subnet. In general, there are four answers you may receive back:
Connection success (No error: the machine is present and there is a program listening to that port)
Connection refused (errno ECONNREFUSED: the machine is present but there
is no program listening to that port)
No route to host (EHOSTUNREACH: there is no machine answering to
that IP address)
No response (ETIMEDOUT: several reasons why this can happen; for example, the system could have firewall settings causing it to simply ignore the request)
(And there are other less likely possibilities as well.) Using other IP access methods (ICMP/ping, UDP packets) will have a different matrix of possible results.
As others have explained, multicast mechanisms would only be helpful for discovering a set of cooperating machines that are pre-configured to join a multicast group.

Injecting an incoming packet to a network interface

I want to be able to simulate an incoming packet on a certain physical network interface.
Specifically, given an array of bytes and an interface name, I want to be able to make that interface think a packet containing those bytes arrived from another interface (most likely on another machine).
I've implemented the code that prepares the packet, but I'm unsure what the next step is.
I should point out that I actually need to feed the interface with my bytes, and not use a workaround that might produce a similar results in other machines (I've seen answers to other questions mentioning the loopback interface and external tools). This code is supposed to simulate traffic on a machine that's expecting to receive traffic from certain sources via specific interfaces. Anything else will be ignored by the machine.
I'm going to stick my neck out and say this is not possible without kernel modifications, and possibly driver modifications. Note that:
There are plenty of ways of generating egress packets through a particular interface, including libpcap. But you want to generate ingress packets.
There are plenty of ways of generating ingress packets that are not through a physical interface - this is what tap/tun devices are for.
If you modify the kernel to allow direct injection of packets into a device's receive queue, that may have unexpected effects, and is still not going to be an accurate simulation of the packets arriving in hardware (e.g. they will not be constrained to the same MTU etc). Perhaps you can build an iptables extension that fools the kernel into thinking the packet came from a different interface; I'm not sure that will do what you need though.
If all you need is simulation (and you are happy with a complete simulation), build a tap/tun driver, and rename the tap interface to eth0 or similar.
Depending on which network layer you're trying to simulate, there may be a work-around.
I have had success getting ip packets into the ingress queue with an ethernet 'hairpin'. That is, by setting the source and destination MAC address to the local interface, sending the packet results in it first appearing as an egress packet, then being 'hairpinned' and also appearing as an ingress packet.
This at least works under linux using pcapplusplus (libpcap under the hood), with my wireless interface. Your millage may vary.
This will obviously only suit your needs if you're OK with modifying the ethernet header, ie only simulating a higher layer.
Here is a snippet of c++ where I spoof a rst tcp packet for a local socket:
//always use the actual device source MAC, even if we're spoofing the remote rst
// this produces a 'hairpin' from the egress to the ingress on the interface so the tcp stack actually processes the packet
// required because the tcp stack doesn't process egress packets (at least on a linux wireless interface)
pcpp::EthLayer eth(localMAC,localMAC);
pcpp::IPv4Layer ip(remoteIP, localIP);
pcpp::TcpLayer tcp(remotePort, localPort);
pcpp::Packet pac(60);
ip.getIPv4Header()->timeToLive = 255;
tcp.getTcpHeader()->rstFlag = 1;
tcp.getTcpHeader()->ackFlag = 1;
tcp.getTcpHeader()->ackNumber = pcpp::hostToNet32(src.Ack);
tcp.getTcpHeader()->sequenceNumber = pcpp::hostToNet32(src.Seq);
pac.addLayer(&eth);
pac.addLayer(&ip);
pac.addLayer(&tcp);
pac.computeCalculateFields();
dev->sendPacket(&pac);
EDIT: the same code works on windows on an ethernet interface. It doesn't seem to do the same 'hairpin' judging from wireshark, but the tcp stack does process the packets.
Another solution is to create a new dummy network device driver, which will have the same functionality as the loopback interface (i.e. it will be dummy). After that you can wrap up a creation of simple tcp packet and specify in the source and destination addresses the addresses of the two network devices.
It sounds a little hard but it's worth trying - you'll learn a lot for the networking and tcp/ip stack in linux.

User-mode TCP stack for retransmits over lossy serial link

I believe that my question is:
Is there a simple user-mode TCP stack on PC operating systems that could be used to exchange data over a lossy serial link with a Linux-based device?
Here is more context:
I have a Linux-based device connected via a serial link to a PC. The serial link is lossy so data being sent between the two devices sometimes needs to be retransmitted. Currently the system uses a custom protocol that includes framing, addressing (for routing to different processes within the Linux device), and a not-so-robust retransmission algorithm.
On the Linux device side, it would be convenient to replace the custom protocol, implement SLIP over the serial link and use TCP for all communications. The problem is that on the PC-side, we're not sure how to use the host's TCP stack without pulling in general IP routing that we don't need. If there were a user-mode TCP stack available, it seems like I could integrate that in the PC app. The only TCP stacks that I've found so far are for microcontrollers. They could be ported, but it would be nice if there were something more ready-to-go. Or is there some special way to use the OS's built in TCP stack without needing administrative privileges or risking IP address conflicts with the real Ethernet interfaces.
Lastly, just to keep the solution focused on TCP, yes, there are other solutions to this problem such as using HDLC or just fixing our custom protocol. However, we wanted to explore the TCP route further in case it was an option.
It appears that the comments have already answered your question, but perhaps to clarify; No you can not use TCP without using IP. TCP is built on top of IP, and it isn't going to work any other way.
PPP is a good way of establishing an IP connection over a serial link, but if you do not have administrative access on both sides of the computer this could be difficult. 172.16.x, 10.x, and 192.168.x are defined as being open for local networks, so you should be able to find a set of IP addresses that does not interfere with the network operation of the local computer.
From the point of view of no configuration, no dependencies, comping up with your own framing / re-transmit protocol should not be too hard, and is probably your best choice if you don't need inter-operability. That being said kermit, {z,y,z}modem would provide both better performance and a standard to code against.
Lastly, you may be able to use something like socat to do protocol translation. I.e. connect a serial stream to a TCP port. That wouldn't address data reliability / re-transmission, but it may be the interface you are looking to program against.

UDP multicasting: how do I know which group to send to?

I've got a little program that needs to communicate between two computers on the same LAN. I'm rather new to networking, but from what I've read it sounds like I want UDP multicasting so that the two computers can discover each other, after which I can establish a TCP connection for actual data communication. I've found this little example for UDP multicasting which I can follow. However, I'm wondering about the multicast group (HELLO_GROUP in that example, which is 225.0.0.37).
How can I know the group I should use? This program will be running on various networks, so I can't hard code one (as far as I know). Do I get the group from the router, and if so, how do I do that?
You can choose any multicast address (224.0.0.0 to 239.255.255.255) that isn't listed as reserved by IANA.
Its possible (if unlikely) that another program will also be using the same address. You can minimise the chances of this causing any confusion by making the announcement messages your program sends out suitably specific. e.g.
CORNSTALKS-DISCOVERY
HOST: {address:port}
[newline]
This would inform your recipients of the address to use for their TCP connection but should find its first line rejected by any other recipients.
You understood wrong.
What are you talking about is broadcasting. A broadcast UDP datagram is sent to every computer in the subnet. (Technically you send a datagram to the address 255.255.255.255.)
UDP broadcast work inside a specific subnet, but don't cross the subnet boundaties. That is, most of the routers are configured not to route broadcast datagrams (reduce spamming).
OTOH multicast is something completely different. The purpose of multicast is to avoid using TCP (or any other unicast) for data transmission. It's good when you need to send something to many other recipients "at once". Those machine agree preliminary on a specific multicast address (like 225.0.0.37 in your example), and "join" this multicast group. Within a specific subnet everything works pretty similar to broadcast, however in contrast to broadcast the multicast may also cross the subnet boundaries. This is due to the fact that when machines join a multicast group the appropriate routers are notified, and they are capable to route multicast datagrams appropriately.
EDIT:
Conclusion (for clarification).
In order to use a multicast one has to pick a multicast address. This is like choosing a port for the application.
The main purpose of multicast is to deliver content (transmit data) to a number of recipients. It's more efficient than unicast in this case.
A "network discovery" is usually done via broadcast. A multicast can theoretically be used for this as well, but this is like killing a fly with a cannon (because routers should also track the lifetime of the multicast session).
I would suggest you don't use multicast directly.
Rather, use zero-configuration networking. This, in its mDNS/DNS-SD incarnation, is available through Apple's Bonjour library on OS X and Windows, and Avahi on unices (and possibly on OS X and Windows too, not sure).
With DNS-SD, you define a name for your service, then use the library to advertise its availability on a given host, or to browse for hosts where it's available. This is how Macs discover printers, file shares, etc - exactly your use case, i believe. It's a simple but very effective technology. And it's an open standard with a good open source implementation, so it's not some proprietary Apple scarytime.

Resources