Are there any viable alternatives to Winsock for C++? The reason I need of is because Winsock's raw sockets are not behaving properly (no, this is not fixable, don't waste your time asking) and WinPCAP can only monitor network traffic, not actually receive packets. I need something that can receive complete packets including any IP, UDP, TCP headers, etc. Does such a thing exist, and if not, why not?
WinPCAP can only monitor network traffic, not actually receive packets
Monitoring network traffic is equivalent to receiving packets. That's exactly what tools such as Wireshark do: read off your network card and reconstruct packet boundaries.
I need something that can receive complete packets including any IP, UDP, TCP headers, etc.
This is very much possible using the Winsock API. Have a look at the WSAIoctl function, specifically the SIO_RCVALL option - enabling this option will deliver ALL packets received on an interface to your socket. And these are raw IP packets starting with the IP header.
You could look at Boost.Asio. C++ cross-platform IO library. Support for UDP, TCP and ICMP.
Related
I'm using a Linux (Debian based) system on which IP forwarding is enabled (/proc/sys/net/ipv4/ip_forward is set to 1). I can read the incoming packets using a C++ raw sockets program, but I want to modify their content before they are forwarded (using BSD sockets only). This link mentions that I can use an "iptables REDIRECT rule" to send the incoming packets to a port my program is listening on, but I didn't find any information on how exactly this should be done. Mainly, I want to know:
How I should forward the packets after modifying them. Do I have to send them manually from the program to their destination address after they are received and modified?
What I should do in case the program isn't listening on a particular port (e.g. a program concerned with only the IP headers of the packets).
In case it matters receiving and forwarding are done on the same wireless interface. I have to forward packets to, and receive packets from devices on the same WLAN.
I'm developing a peer-to-peer communications network for use over a LAN in an industrial environment. Some messages are are just asynchronous, and don't require a response. Others are request-response. The request messages (and the async messages) are sent to a multicast group, and the replies to requests are sent unicast. Each endpoint, therefore, receives UDP packets that are sent to the multicast group, and also receives messages that are just sent to it using plain unicast.
So far it's working fine, but there doesn't seem to be any way in boost::asio to find out the destination address of a received UDP packet (using socket.async_receive_from) - whether it was sent to the multicast group or the actual interface. I can use the contents of the message to infer whether it was sent multicast or unicast, but it would be nice to be able to also check the destination address.
We are currently using Windows 7, but will be transitioning to Linux in the future.
Is there a way to find the destination address of a UDP packet received using boost::asio?
Unfortunately this is not possible with boost::asio, and usually is not "the way to do" it, as you try to access Transport Layer information at the Application Layer.
So you basically have two options:
a) Write non-portable system code with for example IP_PKTINFO or SO_BINDTODEVICE on Linux. Example Code can be found on the boost asio mailing list here
b) use two distinct sockets, one for the multicast and one for the unicast. You therefore need to specify a listen_address other than "0.0.0.0" on each socket.
udp::endpoint(address_v4::from_string("239.192.152.143"), 6771)
This Question on SO might also be helpful: Using a specific network interface for a socket in windows
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.)
I have to develop a software to send same packets to multiple destination.
But i must not use multicast scheme.!!!! ( because my boss is a stupid man )
so, any way, the problem is that:
i have same packets and multiple IP address ( clients) and i can not use multicast
how can i do that in the best way?
i must use c++ as a language and Linux as a platform.
so please help me
Thanx
If your boss said you can't use multicast, maybe he/she has his/her reason. I guess broadcasting is out of the game too?
If these are the requisites, your only chance is to establish a TCP connection with every remote host you want to send packet to.
EDIT
UDP, conversely, would not provide much benefit over multicasting if your application will run over a LAN you are in charge for configuration of, that's the reason I specified TCP.
Maybe you have to describe your scenario a little better.
This could be done with either TCP or UDP depending on your reliability requirements. Can you tolerate lost or reordered packets? Are you prepared to handle timeouts and retransmission? If both answers are "yes", pick UDP. Otherwise stay with TCP. Then:
TCP case. Instead of single multicast UDP socket you would have a number of TCP sockets, one per destination. You will have to figure out the best scheme for connection establishment. Regular listening and accepting connecting clients works as usual. Then you just iterate over connected sockets and send your data to each one.
UDP case. This could be done with single UDP socket on the server side. If you know the IPs and ports of the clients (data receivers) use sendto(2) on the same data for each address/port. The clients would have to be recv(2)-ing at that time. If you don't know your clients upfront you'd need to devise a scheme for clients to request the data, or just register with the server. That's where recvfrom(2) is usefull - it gives you the address of the client.
You have restricted yourself by saying no to multicast. I guess sending packets to multiple clients is just a part of your requirement and unless you throw more light, it will be difficult to provide a complete solution.
Are you expecting two way communication between the client and the server ? in that case choosing multicast may prove complex. please clarify
You have to iterate through the clients and send packets one after another. You may want to persist the sessions if you are expecting response from the clients back.
Choice of UDP or TCP again depends on the nature of data being sent. with UDP you would need to handle out of sequence packets and also need to implement re-transmission.
You'll have to create a TCP Listerner on your server running at a particular port listening for incoming Tcp Client connections (Sockets).
Every time a client connects, you'll have to cache it in some kind of datastructre like a Name value pair (name being a unique name for the client amd value being the Network Stream of that client obtained as a result of the TCP socket).
Then when you are finally ready to transmit the data you could either iterate through this collection of name value pair connections and send them data as byte array one by one to each client or spawm off one thread per connected client and have it send the data concurrently.
TCP is a bulky protocol (due to its connection-oriented nature) and transmission of large data (like videos/images) can be quite slow.
UDP is definitely the choice for streaming large data packets but you'll have to trade-off with the delivery gurantee.
How do I write a C++/MFC program to make a server as a bridge for clients to stream their audio? I have been told to use UDP and RTP protocol but due to my lack knowledge of media streaming, I couldn't make it work. What is relationship between UDP and RTP and steps needed for server to listen, accept and handle packet transfer between client to client.
As unwind said, generally RTP runs on top of UDP. It's called a conectionless protocol.
This is the specification of UDP: http://www.ietf.org/rfc/rfc768.txt
An this is the specification of RTP: http://www.ietf.org/rfc/rfc1889.txt
You can find very useful information about RTP on this site. There are different libraries and docs.
It's possible to write a "RTP forwarder" application.
RTP generally runs on top of UDP, to get away from TCP's streaming behavior, TCP always delivers data in-order, which is not optimal for real-time applications.
It might be possible to do a "dumb" forwarder that is not RTP-aware, but instead is configured to e.g. accept UDP packets to port X, and forward all traffic to host:Y, packet by packet. Not sure if that works in practice, though.