How do 2 devices communicate over an ethernet switch - ethernet

Before I proceed, I'd like to mention that I did try to research this topic on the internet, but I still need clarification.
Let's say I have two Linux machines connected to a switch (and only to a switch). Machine A has an IP address of 10.0.0.1 and machine B -- 10.0.0.2. I used nmcli command to set the IP address and create an ethernet interface for each machine. Everything works as expected.
Now, the confusing part is how machine A can find machine B and vice versa? I'm using the following command to connect from machine A to machine B:
ssh userB#10.0.0.2
And it works, even if this is the very first data transmission. This surely means that machine A somehow already knew the machine's B MAC address; otherwise, the frame wouldn't find its way to machine B. But how? Since the IP address is meaningless to the switch (Level2), why when I do ping 10.0.0.2 or ssh 10.0.0.2, it still works?

Probably the ARP cache was already populated. Maybe there was a grations ARP broadcast:
Every time an IP interface or link goes up, the driver for that interface will typically send a gratuitous ARP to preload the ARP tables of all other local hosts.
If not, most likely an ARP request/reply was happening right before the first ping. Check the arp command or ip neigh.
In general I suggest you use Wireshark to explore what's going on, or something like tcpdump -n -i eth0 not ssh if your are working remotely (note the -n to prevent name resolution). You can also record traffic with tcpdump -s 9999 -w output.pcap and view it later in Wireshark.
If you sniff network traffic on a third PC, keep in mind that switches will not send traffic to all ports when they have learned where the destination is. Some switches allow you to configure a mirror port to observe all traffic to or from a certain port. Either way you should always be able to observe ARP requests as they are broadcast.

basically, when the first packet reach to the switch ( virtual or physical switch ), the switch will populate arp broadcast packet for the sake of getting all devices mac and ip addresses. so even though ip addresses seem meaningless to switches ( cause they're layer 3 concept but switch is for layer 2 ), switches still need those data to process the packets. because this is how we, as human beings, interact with computers for transmitting data by using ip addresses.
when you ping a device, like 10.0.0.2, the switch will search in it's arp table and find the corresponding mac address and also the interface for reaching to the destination.
the best way to comprehend the whole process is to capture the data using wireshark or even implementing a simple topology in softwares like cisco packet tracer.

Related

How to intercept IP packets going to the kernel Linux

I need to create a TCP session "manually", without using the connect() function. I have tried to use RAW sockets. But in this case, I only get copies of the incoming IP packets. The original incoming packets slip through to the kernel and it generates an ACK response packet that damages my protocol.
Next, variant 2, I can write a virtual eth interface driver (kernel module) and route incoming traffic to it using iptables. But there is a patched non-original (non vanila) kernel on the machine. Normal linking of the module with the kernel is not possible.
Variant 3. I also tried not to assign an IP address to the NIC interface. In this case, the network TCP/IP layer module in the kernel is not activated and it is possible to generate and receive arbitrary IP packets on the link (ethernet) layer using the PF_PACKET socket domain type in the socket() function. But at this time, any other applications using the TCP/IP protocol can’t work.
How can this problem be solved in other ways?
It would be nice if it were possible to intercept packets going from the network interface to the kernel, that is, intercept the SKBuf buffer. But I don't know how to realize it.
Apparently you are trying to create a tunnel. Instead of trying to hijack an existing interface, the proper way to create a tunnel is to create a new interface, using a kernel module or TUN/TAP. However, tunnels are normally intended to receive traffic generated on the machine which runs the tunnel software, or at least routed through it. That means you will also have to set up the kernel to route the traffic to your tunnel.
You can create a new interface as a TUN/TAP interface. It is like a virtual ethernet driver except you don't need to write a new kernel module. It is designed for tunnels (hence the name).
The difference between TUN and TAP is that a TUN interface is an IP interface that receives IP packets from the kernel's IP routing system, and a TAP interface receives Ethernet packets (which may contain IP packets) so it can alternatively be part of a bridge (a virtual Ethernet switch - which only looks at the Ethernet header, not the IP header).
I think for your scenario, you will find it easiest to create a TAP interface, then create a bridge (virtual Ethernet switch) between the TAP interface, and the interface which the other host is connected to. Neither one needs an IP address - the kernel will happily pass Ethernet-layer traffic without attempting to process the IP information in the packet. Your tunnel software can then emulate a host - or tunnel to an actual host - or whatever you want it to do.
Or in visual form:
If you want the host to also be able to talk to the machine running the tunnel software - without going through the tunnel software - then you may choose to put an IP address on the bridge.

Windows 7 temporarily routes UDP packets for local network to default gateway

I have a Windows service running on a multi-homed Windows 7 machine communicating via UDP to a machine on the local network. This works fine, except sometimes during Windows startup the network traffic is temporarily (30 seconds) being routed to the default gateway, resulting in UDP packet loss. This packet loss is not necessarily a problem, but leads to an unnecessarily long startup time of the application.
The service binds to the socket using INADDR_ANY. Now when I change this to bind to the IP address of the control network NIC (192.168.32.1) I don't observe the problem. However I don't understand why the binding matters in this situation, and also I don't understand why the problem is there only temporarily. Do any of you have an explanation for this?
Besides my curiosity to find the root cause of this issue, I would also like to get an answer to this question so I can remove the bind to the specific IP address from my code. This decouples my application code from the network layout.
Network details:
Machine A, Windows 7, two NICs:
NIC #1 (ext network): 192.168.116.x/23 (DHCP), gateway 192.168.117.1
NIC #2 (int network): 192.168.32.1/26 (fixed)
Machine B, VxWorks, one NIC:
NIC #1 (int network): 192.168.32.16/26 (DHCP, assigned by Machine A)
When using INADDR_ANY, you bind your socket to the default IP address - the one with the lowest interface address. From the symptomps you are describing, it seems like this interface is not yet configured during startup, which makes sense.
The question is, why do you bind sending socket to any address at all. Implicit binding during send should be OK for you, I imagine?

ZeroMQ (0MQ) basic issue re connecting or binding to sockets

I'm using ZeroMQ on Windows, using C#, and am confused by a very basic networking question. I set up simplistic sample programs, one to PUBlish messages, the others use a SUB socket to receive them (the SUBscriber programs).
Works fine when both are on the same box. I used endpoint tcp://127.0.0.1:5000
As the next step, I put the SUBscriber program on a separate virtual machine (VM), to simulate using separate computers. I ran ipconfig to get it's IP address (on the guest os), 192.168.92.136
The host os has several network interfaces, one of which is the VMware Network Adapter VMnet1, with IP 192.168.92.1
On the host os, I ran the PUB program and connected the socket to 192.168.92.136, the IP address of the guest os.
On the guest os, I ran the SUB program and connected the socket to the IP of the host os. Did not work.
Then I changed the SUB program on the guest os to make it connect it to it's own IP address, ie that of the guest os - 192.168.92.136. Now it works!
Question: Why? I'm confused. But in a way it sort of makes sense: if that socket is for a service that attends to various clients that dynamically come and go, it doesn't know the IP address of each client. Therefore what the heck do you specify as the IP address for the SUB socket?! So connecting it to it's own host IP address does solve that concern. But the ZeroMQ Guide doesn't say this anywhere!
A related question is: if your host has multiple network interfaces, and each has it's own IP address, then if you connect your socket to some other host using the IP address of that other host - do you not need to specify which of those network interfaces you want to connect through? If so, how?
Incidentally, only one subscriber program seems to be able to connect at a time. The 2nd program to attempt to connect to it's SUB socket to the local IP address always gets a "Address is in use" error-message. I'm trying to make progress in small steps and learn this as I go.
Thanks for any help or advice.
James Hurst, JamesH at Designforge dot com

Sniffing data on uClinux local loopback

I am looking for a way to monitor/sniff local loopback traffic inside a uClinux embedded device. I have several processes that communicate via the local loopback and want to capture this traffic on an outside machine. So I want to direct a copy of all local loopback traffic out the "real" Ethernet to a specific IP address, namely that of my Windows PC running a sniffer.
Is this possible, maybe with iptables or something? The traffic is all UDP, between a few dozen ports. If not, I was thinking about writing some code to open a raw socket, read in the packets in question and forward them to my fixed IP address. Would it work to capture local loopback traffic with a raw socket?

How to communicate between two embedded devices over ethernet?

I am not expert on this subject, need your suggestions. I have a few devices on ethernet/LAN. I wanted to have these devices communicate over LAN without going into their network configurations. Below is my plan, please let me know if this can be achievable:
1) I install TCP/IP stack on these devices
2) I give them their hostnames like device1, device 2 etc....
3) I configure these devices for local-link networking, so that they can configure themselves and get their IPs.
4) I use socket programming and access each device by using hostnames.
Please let me know if this can be done without much hassle, and let me know if I have missed out something in above mentioned points.
Thanks in advance.
This is basically a good approach.
If your embedded devices have a good IPv6 stack, I recommend using it instead of IPv4. link local addresses work better with IPv6. Most IPv4 stacks are configured to try to obtain an address from a DHCP server first, and only fall back to link local addresses if they can't get one. The link local address and DHCP address might be mutually exclusive, so the link local address doesn't become operational until after DHCP has been tried and timed out. The link local address might even be disrupted if DHCP periodically retries. Although the devices will normally be connected to each other and there won't be a DHCP server, you don't want to disable DHCP, because the devices probably should obtain a DHCP address if they are ever connected to a wider network. With IPv6 on the other hand, the link local addresses come up immediately when the interface comes up, and stay up continuously while other IP addresses (from autoconf or from DHCPv6) may come and go.
Link local addresses alone won't let the devices contact each other by hostname, but dns-sd (mDNS, zeroconf) will. If you are using Linux then you can use avahi as a dns-sd stack.
Better than using hostnames, consider having the devices probe for each other by dns-sd service type. If you are using a custom protocol between your devices, make up a unique service tpe name and have the devices advertise themselves it and probe for it with dns-sd.