views:

116

answers:

3

How can I create a client UDP socket in C++ so that it can listen on a port which is being listened to by another application? In other words, how can I apply port multiplexing in C++?

+1  A: 

This is not multiplexing - that term is reserved for handling I/O on multiple channels in the same process and where things like select(2) and poll(2) are most useful.

What you are asking for is multicast. Here is the basic example.

Note that IP reserves a special range of addresses (a.k.a. groups) for multicasting. These get mapped to special ethernet addresses. The listener(s) would have to join the multicast group, while sender does not have to, it just sends as usual.

Hope this helps.

Nikolai N Fetissov
I have a software app running on port 5000, and I cannot modify that application so that it joins any multicast group or likewise. I want to listen on the same port so that my code can parse all the packets received by that application. I had a notion that this was called 'port multiplexing', but I am unable to find a proper example for the same.
SkypeMeSM
Then get the Wireshark (http://www.wireshark.org/), sniff the packets, dump into a file, and have a go at it.
Nikolai N Fetissov
I am using wireshark to look at the packets offline, but I have to write a C++ program which sniffs or listens on a particular port and not on all the ports, and it cannot be offline. I can use libpcap library, but like I said I want to listen on only one port, and I might need to stop it from sending out some particular packets, because my program will send it instead of the original application!! I am not sure if I am confusing you a lot :)
SkypeMeSM
pcap allows you to filter what you listen to, see here http://www.tcpdump.org/pcap.htm
Nikolai N Fetissov
+1  A: 

This is just packet sniffing like tcpdump or snoop, open up a raw socket and pull everything from the wire and filter as you require. You will probably want to use libpcap to make things a little easier.

Without administrator or super-user privileges you will need the target application to open ports with SO_REUSEADDR and SO_REUSEPORT as appropriate for the platform. The caveat being you can only receive broadcast and multicast packets, unicast packets are delivered to the first open socket.

Steve-o
Ok. So, in your opinion, the only other alternative is using libpcap to sniff every packet on a network interface and then filter out the packets for that particular port. I was thinking that since these are UDP packets (connection-less), it should not have been a problem to passively/actively send/receive the packet on the same port.
SkypeMeSM
I've tried, Linux only delivers to the first socket, it does not multiplex unicast packets. Other platforms may but are unlikely to be different for performance reasons.
Steve-o
+1  A: 

I want to listen on only one port

You can do that with a sniffer. Just ignore the packets from different ports.

I might need to stop it from sending out some particular packets, because my program will send it instead of the original application

Okay, here I suggest you to discard sniffers, and use a MITM technique.

You'll need to rely on a PREROUTING firewall rule to divert the packets to a "proxy" application. Assuming UDP, Linux, iptables, and the "proxy" running on the same host, here's what the "proxy" actually needs to do:

1. Add the firewall rule to divert the packets (do it manually, if you prefer):

iptables -t nat -A PREROUTING -i <iface> -p <proto> --dport <dport>
    -j REDIRECT --to-port <newport>

2. Bind and listen on <newport>.

3. Relay all the traffic between the 2 endpoints (client, and original destination). If you're running the "proxy" on a different host, use getsockopt with SO_ORIGINAL_DST to retrieve the original destination address.

It might sound tricky, but... yeah, that's because it's a bit tricky :-) Consult your firewall documentation if my assumption diverges.

jweyrich
I guess this is exactly what I need. :) Thanks a lot.
SkypeMeSM