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.
Related
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.
I've setup a UDP server, and joined a multicast group on both localhost interface and the physical ethernet, to be able to receive multicasts from 127.0.0.1 and 192.168.78.* (example).
According to docs, the destination interface for a multicast message is determined through the source address, and I have a client sending messages, but sometimes localhost interface is chosen, and sometimes the ethernet interface. I.e. in the former case the source address is 127.0.0.1.
Question: How can I force a datagram socket to always send multicast messages to the physical interface ? (i.e. having a source address of 192.168.78.xx)
According to docs, the destination interface for a multicast message is determined through the source address
No. It is determined by the route to the multicast address given by looking up the IP routing tables, unless you use the IP_MULTICAST_IF option, which sets the default interface for outgoing multicasts.
I have a client sending messages, but sometimes localhost interface is chosen, and sometimes the ethernet interface. I.e. in the former case the source address is 127.0.0.1.
Question: How can I force a datagram socket to always send multicast messages to the physical interface ? (i.e. having a source address of 192.168.78.xx)
With the option mentioned above.
Source: Stevens et al., Unix Network Programming, 3rd edition, §21.6.
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.
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)
I have been unable to receive UDP multicast under VxWorks 5.5. I've joined the multicast group:
setsockopt(soc, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &ipMreq, sizeof (ipMreq));
Similar code on an adjacent Windows machine does receive multicast.
I am able to send multicast from VxWorks; ifShow() indicates the interface is multicast capable; MCAST_ROUTING is enabled in the kernel config, but still unable to receive multicast.
Edit: I needed to set a bit in the RealTek Ethernet drive RX configuration register to enable multicast to be passed on to the application layer.
#define RTL_RXCG_AM 0x04 /* Accept Multicast */
Are you checking the return value on the Join setsockopt() call to be sure it's actually succeeding? I had a specific problem with VxWorks 5.5 in the past where my multicast joins were failing when they shouldn't be. I believe we had to get new libraries from WindRiver to fix the issue.
Edit: There is no specific trick that I'm aware of to getting multicast to work with VxWorks. It should use the standard BSD sockets operations. If the interface can receive unicast traffic properly, and a network analyzer (Wireshark, for instance) shows that the multicast JOINs are being sent and the inbound multicast packets are correctly formed, I would suspect a driver issue. WindRiver support has been very helpful for us in the past with these sorts of problems; I don't know if you have a support contract with them to get that level of assistance.