How do I receive multicast packets? - c++

I'm trying to receive multicast packets from a media server. This is the wireshark capture of an example packet:
(source: memecode.com)
There doesn't seem to be any ports involved, just MAC address for source and destination. Most of the source code examples I've seen bind against a specific port when receiving multicast packets. e.g.
https://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=%2Frzab6%2Frzab6x2multicast.htm
I would like to be able to receive these packets on both Windows and MaxOSX (C++ apps in both cases, ie Win32 API and Carbon, although the Mac port is more important).
How can I do this?

You just create a UDP socket, bind it to the port, join the multicast group, and call recvfrom().
But the packet you captured doesn't look like a UDP multicast packet. Possibly something between the routers? It doesn't have an IP header let alone a UDP header, which is where the IP and port information is,

Related

My friend and I are receiving packets from a server in UDP, I am able to receive them but he can't

My friend and I are writing a game in sfml. We wrote both the client and the server in C++. The library we used to handle the networking is SFML. The clients send block update packets to the server and the server sends them to all connected players. This works fine, both my friend and I are able to receive the TCP packets. The problem is with the UDP player position packets. The server receives a UDP packet containing the players x y z (position coordinates) and pitch and yaw(direction the player is looking). Then it sends that information to all other connected clients.(This happens 10 times per second) We put a simple printf() statement to detect whether my friend is even receiving the udp packets but it turns out he was not. And I am obviously receiving the UDP packets since it I am able to see his position.
We thought this was because the server is sending UDP packets to the clients' router's IP but the packet does not contain the local ip of the computer the packet is meant for. Later, we learned that when the server sends a packet to the router, the packet gets sent containing a public ip address and a public port, the router then maps that port to a local ip address and a local port. However this is called port forwarding and requires the routers to be configured.
We just want to know why isn't this a problem with TCP connections?
Why am I able to receive the UDP packets without port forwarding?
Is port forwarding necessary for UDP communication?
We just want to know why isn't this a problem with TCP connections?
Because a connection is bidirectional.
Why am I able to receive the UDP packets without port forwarding?
There could be a lot of possibilities and there's no way we can know without looking much more closely. Here are a few possibilities:
You aren't behind a router that's doing NAT.
The router that does NAT for you isn't between your client and the server.
Your client sent a UDP datagram to the server and your router recognizes the response UDP datagram as a reply to that, creating the effect of having a "UDP connection".
Your client uses UPnP and your router supports UPnP to get port forwarding without special effort.
The server sets the source and destination UDP ports incorrectly and, by luck, it still works in your case. For example, the source and destination ports might happen to be the same or your router's NAT is especially permissive.
The server sets its source IP address incorrectly and this just happens to work in your case either because your router's NAT is more permissive or because the IP address you send to and the IP address the server sends from happen to be the same in your case.
You send a UDP datagram to the server and your friend didn't, thus your datagrams are seen as replies and your friend's aren't.
You can narrow things down if you can dump packets at the server. Seeing a UDP datagram from your friend as seen by the server followed by a UDP datagram from the server to your friend would help narrow things down a lot.
Is port forwarding necessary for UDP communication?
Generally no. If the client sends the first UDP datagram and the server correctly swaps the source and destination ports and the source and destination IP addresses, the UDP reply datagram will usually work.
The client must send UDP to the server first. The server must ensure that the UDP datagram is seen as a reply. That means the server looks at the UDP datagrams it gets from the client and ensures that it responds from the port the client sent UDP to and to the port the client sent UDP from. Similarly, it must send to the IP address the client sent from and send from the IP address the client send to.
Generally, servers offer TCP fallback or some other form of NAT penetration in case things don't "just work".

Getting the destination IP of incoming UDP packet in C++

I found the function: GetTcpTable in C++. In the header: iphlpapi.h. That gives me the destination IP of TCP packet and I was wondering if there's a function from the same header that would give me the destination IP of UDP packet... I tried the function: GetUdpTable but it gives only the local IP and port. I will be more than happy if that function has also code example in C++ of course. Thank you anyway!
EDIT:
I using pcap.h now and i still don't know how to catch UDP packets and take from them the ip. There is a code that i can use?
GetTcpTable() does not give you the destination IP of TCP packets. It merely gives you a list of currently listening TCP ports and active TCP connections.
GetUdpTable() can give you the list of currently listening UDP ports, where UDP packets can be sent to. There are no connections in UDP.
But, if you want to know the actual destination IP for each UDP packet received, and without having to use a low-level capture library like WinPCap, then you can use the WSARecvMsg() function to receive your UDP packets, rather than using the recvfrom() or even recv() function.
WSARecvMsg() can report metadata about each packet, most notably the IP_PKTINFO (IPv4) and IPV6_PKTINFO (IPv6) control blocks, which specify the destination IP of the packet and the index of the network interface that received the packet.
You need to use WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER) to obtain a pointer to the WSARecvMsg() function (see Why is the WSARecvMsg function implemented as a function pointer and can this pointer be reused? for the reason why), and use setsockopt() to enable the IP_PKTINFO/IPV6_PKTINFO socket option, before you start calling WSARecvMsg() to receive packets.
See Function to retrieve the header destination address from a packet in windows XP for an example.

Opening Boost.Asio UDP socket with ephemeral port

I am working on an application that will receive RTP packets from another local service over UDP. Early in the protocol, I receive a message with the IP address from which I'll be receiving these RTP packets, but the port number will be given as 0 (zero) ... I'm to open my UDP socket using an ephemeral port. My response to the given message will contain the actual port I've opened so the sender can know where to direct the packets.
My networking library is an implementation of sockets with boost::asio. Where can I find clear information on how to open such a socket without specifying a non-zero port i.e. use an ephemeral port? Searching the boost docs for "ephemeral" doesn't give me networking results.
Of course, I'm open to seeing an actual example, but finding good documentation would also be just fine.
Thanks.
I would question using ephemeral ports like that, but ... - you can bind your UDP socket to port 0, then use local_endpoint() to retrieve actual port assigned by the OS.

Receiving Multicast From Different Ports

Basically I have an application that creates say 5 multicast sockets on the same interface and within the same application, each socket binds to a different multicast IP address/port. When any one of those sockets sends a message, the other 4 sockets within the application end up reading that message. Is this normal behavior?
This is happening in Ubuntu 11.10 using boost.asio and gcc 4.6.
It's normal in some operating systems ;-) You can turn it off with setsockopt() and the IP_MULTICAST_LOOP option.
Sounds strange to me. If you are using UDP, then you should only receive messages associated with the port number of the UDP socket. Of course, if you using multicast at the IP level, then the port number would not matter.
It is quite true (as per EJP) that loopback will cause programs to receive their own messages if loopback isn't disabled. However, the UDP port numbers still apply. A multicast UDP message sent to port x, should not be received by a socket listening for port y.

Connecting to a multicast server using actual IP and port of the server

I have a multicast server which multicast on an IP 233.1.2.8 on some ports
I need to connect to that server directly using its actual IP do not want to use the broadcast. I want to get actual data it sends on a specific port let say
Multicast Ip 233.1.2.8 port 32334 and 35245
Actual IP 198.122.55.191 port 35366
so i want to read the data of 35366
I can see that data in CommView.exe but can not read it if i try to connect it connects but no data
Thanks
You may want to rethink your question. IP packets have a source and destination address and port, so lets summarise:
You are looking for multicast packets with source port 35366.
Multicast address 233.1.2.8.
Destination port 32334 or 32335.
You will have to open two sockets, one listening to port 32334 and one to 32335, for each socket you will have to the multicast address 233.1.2.8. That gets you a stream of packets from any host, now you have a choice:
Use connect() to restrict to packets from 198.122.55.191.
Use recvmsg() or recvfrom() to read each packet with the source IP address and filter the stream within your application.
Use Source-Specific-Multicast (SSM) and subscribe to multicast address 233.1.2.8 from 198.122.55.191.
The last option usually requires IGMPv3 enabled network and is limited to 232.0.0.0/8 addresses.
Multicast by definition is one-way street: the server sends data to a group, and you subscribe to it.
Connecting to a server cannot be done through UDP, it requires a TCP server actually being there and listening for incoming connections on that particular port. The fact that that port is used for sending out multicast packets doesn't suggest that there's anyone listening on it as well.
If you want to read the data sent from a particular port - then you need to subscribe to all the groups, and analyze the UDP packets (and the IP frame if you have several servers transmitting, to know the origin IP) to see where they're coming from, and filter out the ones that come from the origin you fancy.
You can have a look at this site. It has an example also
http://tack.ch/multicast/