Checking if a UDP message is sent in C - c

I want to check why a program is not receiving UDP messages. A client program is sending 4 integers every time sample. I have a server program that is using "recvfrom()" to get the UDP messages on a port but the program does not seem to be receiving the messages on the port number and is stuck in the "recvfrom" function. I was wondering if there are debugging techniques I can use to debug this issue?
Thanks!

There are many possibilities, common case could be,
Firewall on your machine or in transit, for example, your another endpoint is behind a firewall that disallow UDP inbound traffic from this address.
Routing, make sure the ping works
Your code bug, make sure loopback address works
To debug, you could install Wireshark to inspect specific interface's traffic.

Related

Can a RAW socket be bound to an ip:port instead of an interface?

I need to write a proxy server in C language on Linux (Ubuntu 20.04). The purpose of this proxy server is as follows. There're illogical governmental barriers in accessing the free internet. Some are:
Name resolution: I ping telegram.org and many other sites which the government doesn't want me to access. I ask 8.8.8.8 to resolve the name, but they response of behalf of the server that the IP may be resolved to 10.10.34.35!
Let's concentrate on this one, because when this is solved many other problems will be solved too. For this, I need to setup such a configuration:
A server outside of my country is required. I prepared it. It's a VPS. Let's call it RS (Remote Server).
A local proxy server is required. Let's call it PS. PS runs on the local machine (client) and knows RS's IP. I need it to gather all requests going to be sent through the only NIC available on client, process them, scramble them, and send them to RS in a way to be hidden from the government.
The server-side program should be running on RS on a specific port to get the packet, unscramble it, and send it to the internet on behalf of the client. After receiving the response from the internet, it should send it back to the client via the PS.
PS will deliver the response to the client application which originates the request. Of course this happens after it will unscramble and will find the original response from the internet.
This is the design and some parts is remained gloomy for me. Since I'm not an expert in network programming context, I'm going to ask my questions in the parts I'm getting into trouble or are not clear for me.
Now, I'm in part 2. See whether I'm right. There're two types of sockets, a RAW socket and a stream socket. A RAW socket is opened this way:
socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
And a stream socket is opened this way:
socket(AF_INET, SOCK_STREAM, 0);
For RAW sockets, we use sockaddr_ll and for stream sockets we use sockaddr_in. May I use stream sockets between client applications and PS? I think not, because I need the whole RAW packet. I should know the protocol and maybe some other info of the packet, because the whole packet should be retrieved transparently in RS. For example, I should know whether it has been a ping packet (ICMP) or a web request (TCP). For this, I need to have packet header in PS. So I can't use a stream socket, because it doesn't contain the packet header. But until now, I've used RAW sockets for interfaces and have not written a proxy server to receive RAW packets. Is it possible? In another words, I've the following questions to go to next step:
Can a RAW socket be bound to localhost:port instead of an interface so that it may receive all low-level packets containing packet headers (RAW packets)?
I may define a proxy server for browser. But can I put the whole system behind the proxy server so that packets of other apps like PING may route automatically via it?
Do I really need RAW sockets in PS? Can't I change the design to suffice the data I got from the packets payload?
Maybe I'm wrong in some of the concepts and will appreciate your guidance.
Thank you
Can a RAW socket be bound to localhost:port instead of an interface so that it may receive all low-level packets containing packet headers (RAW packets)?
No, it doesn't make sense. Raw packets don't have port numbers so how would it know which socket to go to?
It looks like you are trying to write a VPN. You can do this on Linux by creating a fake network interface called a "tun interface". You create a tun interface, and whenever Linux tries to send a packet through the interface, instead of going to a network cable, it goes to your program! Then you can do whatever you like with the packet. Of course, it works both ways - you can send packets from your program back to Linux through the tun interface, and Linux will act like they just arrived on a network cable.
Then, you can set up your routing table so that all traffic goes to the tun interface, except for traffic to the VPN server ("RS"), which goes to your real ethernet/wifi interface. Otherwise you'd have an endless loop where your VPN program PS tried to send packets to RS but they just went back to PS.

Deny a client's TCP connect request before accept()

I'm trying code TCP server in C language. I just noticed accept() function returns when connection is already established.
Some clients are flooding with random data some clients are just sending random data for one time, after that I want to close their's current connection and future connections for few minutes (or more, depends about how much load program have).
I can save bad client IP addresses in a array, can save timings too but I cant find any function for abort current connection or deny future connections from bad clients.
I found a function for windows OS called WSAAccept that allows you deny connections by user choice, but I don't use windows OS.
I tried code raw TCP server which allows you access TCP packet from begin including all TCP header and it doesn't accept connections automatically. I tried handle connections by program side including SYN ACK and other TCP signals. It worked but then I noticed raw TCP server receiving all packets in my network interface, when other programs using high traffic it makes my program laggy too.
I tried use libnetfilter which allows you filter whole traffic in your network interface. It works too but like raw TCP server it also receiving whole network interface's packets which is making it slow when there is lot of traffic. Also I tried compare libnetfilter with iptables. libnetfilter is slower than iptables.
So in summary how I can abort client's current and future connection without hurt other client connections?
I have linux with debian 10.
Once you do blacklisting on packet level you could get very fast vulnerable to very trivial attacks based on IP spoofing. For a very basic implementation an attacker could use your packet level blacklisting to blacklist anyone he wants by just sending you many packets with a fake source IP address. Usually you don't want to touch these filtering (except you really know what you are doing) and you just trust your firewall etc. .
So I recommend really just to close the file descriptor immediately after getting it from accept.

How do apps like LogMeIn and TeamViewer work?

There's already a question How exactly does a remote program like team viewer work which gives a basic description, but I'm interested in how the comms works once the client has registered with the server. If the client is behind a NAT then it won't have its own IP address so how can the server (or another client) send a message to it? Or does the client just keep polling the server to see if its got any requests?
Are there any open source equivalents of LogMeIn or TeamViewer?
The simplest and most reliable way (although not always the most efficient) is to have each client make an outgoing TCP connection to a well-known server somewhere and keep that connection open. As long as the TCP connection is open, data can pass over that TCP connection in either direction at any time. It appears that both LogMeIn and TeamViewer use this method, at least as a fall-back. The main drawbacks for this technique are that all data has to pass through a TeamViewer/LogMeIn company server (which can become a bottleneck), and that TCP doesn't handle dropped packets very well -- it will stall and wait for the dropped packets to be resent, rather than giving up on them and sending newer data instead.
The other technique that they can sometimes use (in order to get better performance) is UDP hole-punching. That technique relies on the fact that many firewalls will accept incoming UDP packets from remote hosts that the firewalled-host has recently sent an outgoing UDP packet to. Given that, the TeamViewer/LogMeIn company's server can tell both clients to send an outgoing packet to the IP address of the other client's firewall, and after that (hopefully) each firewall will accept UDP packets from the other client's Internet-facing IP address. This doesn't always work, though, since different firewalls work in different ways and may not include the aforementioned UDP-allowing logic.

Read from UDP multicast raspberry pi

I've already started a question here (link) about this project I'm doing, and I keep having lots of problems with this.
In my earlier question I wanted to read from a same machine udp multicast and I find out how to do it, but not with ipmidi.(If you didn't read the previous question linked above, ipmidi is a tool for mac/win which allows me to send midi events through an UDP multicast).
I've been working around with wireshark and managed to see that ipmidi is sending datagrams to the ip 225.0.0.37, port 21928, wich tells me that is, in fact, a multicast.
Then I used this code (the listener) to try to echo the datagrams sent by ipmidi with no success (I changed the multicast ip and the port).
After this I decided to try to run this code from the raspberry pi, since I only wanted it to run in my mac for testing purposes, I went to the real thing.
In my raspi I compiled the code again and gcc claimed that setsockopt() had an invalid argument. perror() was useful enough to tell me that the problem was here:
setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq))
So I removed the part where it asks for a multicast address to the kernel and made it a simple listening socket at port 21928, but it still won't work.
I have my mac sending midi through ethernet to the raspi.
Now, the actual questions:
I'm now doubting my multicast, so called, knowledge: if my mac is multicasting ipmidi's datagrams, it means the datagrams are being sended through all the possible places in my mac, right? I mean, the ip 225.0.0.37 means multicast through wifi and ethernet or I have to route it to the network interface of my choice?
Since my raspi is, allegedly, receiving the datagrams through the ethernet, making my program listen at the ipmidi's datagram destination port would be enough or do I have to tell it explicitly 'where' those datagrams came from?
Is there an easier way to make a multicast receiving app, like an api for C/C++? I'm currently using C style sockets, as you could see in the code I linked, but this is not the main purpose for the program I'm doing and I find myself spending lots of time just learning about networking instead of focusing on the real thing.
Sorry for the long question, lots of doubts and I wanted to be in context.
Thanks for the help!
Just listening on the port isn't enough - you need to join the multicast group if you want to see datagrams sent to that group.
The "Invalid Argument" error from your setsockopt() call probably means that your mreq argument was bad. For the multicast address you've given, you should be doing:
struct ip_mreqn mreq;
inet_aton("225.0.0.37", &mreq.imr_multiaddr);
mreq.imr_address.s_addr = htonl(INADDR_ANY);
mreq.imr_ifindex = 0;
So, after some research and trial/error my problem was the raspberry pi being hidden behind my mac.
Since my mac was giving internet to the raspberry pi, the multicast wasn't being caught by the raspi, hence the reason why it failed to join it.
About the setsockopt, I made the same mistake has I had originally in the question: 255 instead of 225 in the multicast ip. Because of this, the options IPPROTO_IP and IP_ADD_MEMBERSHIP were wrong, and the program would block there.
Is working now and I already started to code the midi specification.
Thanks for the help, specially to #caf.

UDP client and server not able to communicate across different machines

I'm trying to run the UDP client-server example given here: http://www.abc.se/~m6695/udp.html.
When run on same machine by changing #define SRV_IP "999.999.999.999" to #define SRV_IP "127.0.0.1" the program works fine.
However, the same program, where server is placed on one system and the client on the other, and changing #define SRV_IP "999.999.999.999" to #define SRV_IP "10.60.5.94"(this is my server ip) doesn't work. That is Even-though the client sends the the packets to the server's IP, the server is unable to receive it.
Please suggest changes that are required to be performed for the code to run over different machines. Thanks in advance.
You should learn to debug this a step at a time.
First use a sniffer on the client machine to make sure that the UDP packet is in fact going out. While you are at it, check the destination address in the packet.
Then use a sniffer on the server machine to see of the packet is in fact coming in. The sniffer will catch the packets before they hit the kernel. This will tell you if something on the network or even a firewall on the server is eating the packet.
Good luck.

Resources