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.
Related
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,
I run Ubuntu 12.04 and I am currently writing C++ code to create a UDP socket, which sends packets to various destinations with sendto. Now it happens that my laptop has both a wlan0 and a eth0 interface. If I bind it to either one of these, using the IP address, and the SO_BINDTODEVICE option, depending on the destination address, sendto will still decide to use the other interface if it suits him.
Specifically, if I bind a UDP socket to the eth0 interface, with its ip address and some port, and I send a packet to another laptop (locally, with only wifi access), it will decide to use my wlan0 interface.
I understand that this behaviour has pros, but I would like to be able to turn it off, i.e. I want to be able to say to the socket that it should only use the one interface I assigned it.
Suggestions?
EDIT:
struct sockaddr_storage sa = address;
fd = socket(address.get_family(), SOCK_DGRAM, 0);
char *devname = "wlan0";
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, devname, strlen(devname));
bind(fd, (sockaddr*)&sa, len);
Binding a socket to an interface with SO_BINDTODEVICE or bind defines a filter for received packets. When a packet has not been received using the specified interface it is not passed to the socket's receive queue. See: http://linux.die.net/man/7/socket
But binding a socket to an interface does not affect the normal IP routing process. When you send a packet it's the responsibility of the network IP stack to find the best route and to send the IP packet over a hardware adapter. This can be an Ethernet adpter but it's not controller with and bind operation.
When you want to send a packet at a specific interface you need raw sockets. You construct the complete packet content including IP and hardware layer (probably Ethernet) and send it using the raw socket.
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.
I am curious about raw sockets and and how to create them and would like to implement my own TCP mechanism. I have read some examples and have succeeded with sending both custom made TCP packets and UDP packets with my own written IP header (of course influenced by a lot of examples). I have checked with Wireshark that the packet is reaching its destination, so everything is fine so far.
But regarding TCP packets, to make the full handshake:
Client Server
syn --->
<--- syn ack
ack --->
What do I need from the serverĀ“s point of view to get the syn packet so I can send the syn ack back to the client?
To receive packets on a raw socket, just call recv or recvfrom on it. The OS will return you a copy of the next packet addressed to the machine, with headers and all, which should include address info. Watch the destination address, port, and transport protocol, and ignore any that aren't what you were expecting. (Since the point of a raw socket is that there's no built-in notion of ports or anything the OS could use to route packets to sockets, it doesn't know what program to send it to...so every raw socket should receive every packet addressed to the machine. Meaning you might receive lots of crap you have no interest in.)
Once you see a packet addressed to "you", just build a SYN/ACK packet and send it to the address and port listed as the source in the received packet.
Note, though: the OS will often do its own processing of TCP and UDP packets (including sending ICMP "port unreachable" or other responses for ports it doesn't have listeners for)...and doing your own processing on top of that is bound to cause wackiness. If you're going to implement your own flavor of TCP, you might want to use a different protocol number. (Of course, then most clients won't be able to connect to it...you'd have to make a client as well.)
For my Uni assignment I have to create a fast action paced networked game and so have chosen to use UDP as opposed to TCP. I am aware of a lot of the differences in programming both UDP and TCP and have read through most of the relevant parts of MSDN's documentation on winsock. On MSDN it states that creating a UDP socket via the connect() function should bind the socket to the address and port specified and as a result be able use the send() and recv() functions with the created socket.
For my application I create a client and use connect() using the loopback address which sends a number of packets via the send() function. The client, after calling select(), then receives the packets it sent out. However the result I get from the recv() function is SOCKET_ERROR and the error description using WSAGetLastError() is "An existing connection was forcibly closed by the remote host".
If i use the bind() function and use sendto() to send data over the loopback address, I recv() packets without any errors... Does anyone know why the connect() function is not doing what it is supposed to do, and has anyone been able to use UDP sockets with the connect() function?
You will need to call bind() if you want your program to receive UDP packets. connect() only sets the address that the socket will send packets to if you call send(); it does not associate the socket with a local UDP port to receive on; for that you must call bind().
"UNIX Network Programming" points out that a connect call made on a UDP client side socket figures out and stores all the state about the destination socket address in advance (masking, selecting interface, etc.), saving the cost of doing so on every ::sendto call. This book claims that ::send vs ::sendto can be up to 3x faster because of this reduced overhead - data can go straight to the NIC driver bypassing most IP stack processing. High performance game programmer's may want to consider this.
you should check Beej's Guide to Network Programming Using Internet Sockets, there are nice examples that address your question.
Keep in mind that the UDP protocol is a "connectionless" protocol meaning that you never ever connect to the host, you just send out data. So you can see that connect as an action is meaningless for UDP.
For UDP you should use sendto() and recvfrom() in these function you specify the address and the buffers and that's about it, everything else that is comfortably handled for you in TCP is gone you have to handle things on your own.
In the MSDN documentation its mentioned that you can in fact somehow use the normal send/recv functions with UDP but why would you when you have separate functions already? Like other commented already connect() for UDP does something else it's not essentially a "connect" operation but a sort of a filter to set up send()/recv() for UDP usage.