Does a router broadcast the packet or an arp request when receiving a packet with unknown destination mac? - router

When a router receives a packet with unknown destination MAC (perhaps due to arp time out), how does the router respond? Will it broadcast the packet or broadcast an arp request instead? I find it a little confusing when I see these two solutions in different articles. Thanks.

ARP (Address Resolution Protocol) is used to convert an IP address into a MAC address. If the router has an unknown MAC address, ARP won't fix it.
It could try RARP (Reverse ARP), but it's easier to simply broadcast it. That's exactly what an unmanaged switch does, until it 'learns' where a MAC address is by receiving it as a source address.
More sophisticated routers can be configured to do a number of things - including dropping the frame.

As far as I know, the router sends out an ARP request if said MAC address is not on the ARP table. If no one answers, it gets dropped.

Related

Could I get other host's TCP packets on my computer?

I use wireshark to capture the packets of my computer. I want to get the packets of 219.231.143.116(source ip) ,and my ip is 219.231.143.220(destination ip).
In fact,I got what i wanted, but to my surprise,I got some others' packets.Those packets' source IP and destination IP were not 219.231.143.116 or 219.231.143.220.
As I know,tcp is a 3rd layer in TCP/IP protocol,the switch would not send those packets that don't belong to me. So,the problem is why could i capture them on my computer? Is this the issue of wireshark or the switch?
(Due to my level is too low,so the image is here,i'm sorry!)
http://mysource.lofter.com/post/1cfd51e8_55d5972
The switch decides which packets to send you. You can't change this. You can only filter out (in Wireshark) the packets you don't want to work with.
Wireshark will show you all the packets you actually receive (in promiscuous mode).
All the additional packets you highlight in your image are TCP Retransmission packets. The switch may be casting the packets wider because retransmissions are occuring, so something is timing out. Or, there may be a broadcast or multicast flag set in the packet, as the source attempts to get it's retransmissions heard.
You won't get a lot of packets destined for other computers, and you won't get a complete sequence of sent & received packets belonging to another device (unless you configure the switch to do so with port mirror)
If you really really don't want to see or leak those packets to a particular device, you could use a physical firewall like pfsense or a router between you and the switch, to absolutely filter out multicast traffic originating in your network. This would be an usual use case.

Why do we need SocketOptions.SO_BROADCAST to enable broadcast?

If we want to broadcast information from a socket, we need to enable SocketOptions.SO_BROADCAST. However, I don't understand why that is necessary.
My understanding is we set the packet with a broadcast address, just the same way as set a unicast address. Then we just need to send it through a regular socket. If its a UDP socket, then a UDP header will be added to that packet, and then an IP header containing the receiver's IP address (in this case is the broadcast address in the form of 192.168.255.255), and then a MAC address (FF:FF:FF:FF) is added.
I think the router will get the packet and perform the broadcast. I don't understand why we need to set the socket attribute to SO_BROADCAST.
"Socket semantics require that an application set the SO_BROADCAST option on before attempting to send a datagram to a base or broadcast address. This protects the application from accidentally sending a datagram to many systems."
Source
In most cases these calls just call the same thing in the OS. This is likely to be a restriction of your OS, not Java.
To complement Jeremy Friesner's answer, here is a good wording I found about this: https://notes.shichao.io/unp/ch7/
Since an application must set this socket option before sending a broadcast datagram, it prevents a process from sending a broadcast when the application was never designed to broadcast. For example, a UDP application might take the destination IP address as a command-line argument, but the application never intended for a user to type in a broadcast address. Rather than forcing the application to try to determine if a given address is a broadcast address or not, the test is in the kernel: If the destination address is a broadcast address and this socket option is not set, EACCES is returned.
In other words, by setting this option, the application is saying that it is designed to support the broadcast use-case and is ready to handle broadcast IP addresses provided by user.
Since not all apps were designed for broadcast, the option is disable by default.

Coordinating peer-to-peer messages using multicast, how to get receiving IP?

I have been working on a local LAN service which uses a multicast port to coordinate several machines. Each machine listens on the multicast port for instructions, and when a certain instruction is received, will send messages directly to other machines.
In other words the multicast port is used to coordinate peer-to-peer UDP messaging.
In practice this works quite well but there is a lingering issue related to correctly setting up these peer-to-peer transmissions. Basically, each machine needs to announce on the multicast port its own IP address, so that other machines know where to send messages when they wish to start a P2P transmission.
I realize that in general the idea of identifying the local IP is not necessarily sensible, but I don't see any other way-- the local receiving IP must be announced one way or another. At least I am not working on the internet, so in general I won't need to worry about NATs, just need to identify the local LAN IP. (No more than 1 hop for the multicast packets is allowed.)
I wanted to, if possible, determine the IP passively, i.e., without sending any messages.
I have been using code that calls getifaddrs(), which returns a linked list of NICs on the machine, and I scan this list for non-zero IP addresses and choose the first one.
In general this has worked okay, but we have had issues where for example a machine with both a wired and wifi connection are active, it will identify the wrong one, and the only work-around we found was to turn off the wifi.
Now, I imagine that a more reliable solution would be to send a message to the multicast telling other machines to report back with the source address of the message; that might allow to identify which IP is actually visible to the other machines on the net. Alternatively maybe even just looking at the multicast loopback message would work.
What do you think, are there any passive solutions to identify which address to use? If not, what's the best active solution?
I'm using POSIX socket API from C. Must work on Linux, OS X, Windows. (For Windows I have been using GetAdapterAddresses().)
Your question about how to get the address so you can advertise it right is looking at it from the wrong side. It's a losing proposition to try to guess what your address is. Better for the other side to detect it itself.
When a listening machine receives a message, it is probably doing do using recvfrom(2). The fifth argument is a buffer into which the kernel will store the address of the peer, if the underlying protocol offers it. Since you are using IP/UDP, the buffer should get filled in with a sockaddr_in showing the IP address of the sender.
I'd use the address on the interface I use to send the announcement multicast message -- on the wired interface announce the wired address and on the wireless interface announce the wireless address.
When all the receivers live on the wired side, they will never see the message on the wireless network.
When there is a bridge between the wired and the wireless network, add a second step in discovery for round-trip time estimation, and include a unique host ID in the announcement packet, so multiple routes to the same host can be detected and the best one chosen.
Also, it may be a good idea to add a configuration option to limit the service to certain interfaces.

Broadcasting ip:port by socket server

I'm trying to find a way for client to know socket server ip:port, without explicitly defining it. Generally I have a socket server running on portable device that's connect to network over DHCP (via WiFi), and ideally clients should be able to find it automaticaly.
So I guess a question is whether socket server can somehow broadcast it's address over local network? I think UPnP can do this, but I'd rather not get into it.
I'm quite sure that this question was asked on Stack lot's of times, but I could find proper keywords to search for it.
One method of doing this is via UDP broadcast packets. See beej's guide if you're using BSD sockets. And here is Microsoft's version of the same.
Assuming all the clients of the application are on the same side of a router then a broadcast address of 255.255.255.255 (or ff02::1 for IPv6) should be more than adequate.
Multicast is another option, but if this is a LAN-only thing I don't think that's necessary.
Suggestion
Pick a UDP port number (say for the sake of an example we pick 1667). The client should listen to UDP messages on 255.255.255.255:1667 (or whatever the equivalent is. e.g.: IPEndPoint(IPAddress.Any, 1667)). The server should broadcast messages on the same address.
Format Suggestion
UDP Packet: First four bytes as a magic number, next four bytes an IPv4 address (and you might want to add other things like a server name).
The magic number is just in case there is a collision with another application using the same port. Check both the length of the packet and the magic number.
Server would broadcast the packet at something like 30 second time intervals. (Alternatively you could have the server send a response only when a client sends a request via broadcast.)
Some options are:
DNS-SD (which seems to translate to "Apple Bonjour"): it has libraries on macOS, but it needs to install the Bonjour service on Windows. I don't know the Linux situation for this. So, it's multi-platform but you need external libraries.
UDP broadcast or multicast
Some other fancy things like Ethernet broadcast, raw sockets, ...
For your case (clients on a WiFi network), a UDP broadcast packet would suffice, it's multi-platform, and not too difficult to implement from the ground up.
Choosing this option, the two main algorithms are:
The server(s) send an "announce" broadcast packet, with clients listening to the broadcast address. Once clients receive the "announce" packet, they know about the server address. Now they can send UDP packets to the server (which will discover their addresses for sending a reply), or connect using TCP.
The client(s) send a "discover" broadcast packet, with the server(s) listening to the broadcast address. Once the server(s) receive the "discover" packet, it can reply directly to it with an "announce" UDP packet.
One or the other could be better for your application, it depends.
Please consider these arguments:
Servers usually listen to requests and send replies
A server that sends regular "announce" broadcast packets over a WiFi network, for a client that may arrive or not, wastes the network bandwidth, while a client knows exactly when it needs to poll for available servers, and stop once it's done.
As a mix of the two options, a server could send a "gratuitous announce" broadcast packet once it comes up, and then it can listen for "discover" broadcast requests from clients, replying directly to one of them using a regular UDP packet.
From here, the client can proceed as needed: send direct requests with UDP to the server, connect to a TCP address:port provided in the "announce" packet, ...
(this is the scheme I used in an application I am working on)

Winsock Join MAC ADDRESS Multicast group

Is there a way to join an Ethernet multicast group? All documentation I found is about adding an IP group.
I just want to receive the Cisco CDP packet that is sent to the MAC address 01:00:0c:cc:cc:cc.
The OID part of the MAC address you give (01:00:0C) isn't the same as the one used for IPv4 multicast (01:00:5E), so you can't use anything in Winsock to send this packet. Even raw sockets won't work, because that doesn't let you dig down to the Ethernet layer.
What you need is WinPCap or something like it, with which you can construct raw Ethernet frames and receive answering packets at that same level.