Open UDP socket between source and destination, modify it and forward it to the original destination - c

I am running a simple network that contains 2 nodes and a gateway. My scenario is as follows: Node1 wants to send a UDP IPv6 socket to Node2 via the Gateway which has to open the sockets, verifies data and then forwarding it.
I configured an internal network between Node1 and Gateway having an address of aaaa::/20, and an other network between Gateway and Node2 having an address of aaab::/20. I modified Node1 routing table to send packets destined to aaab::/20 network via its aaaa::/20 interface connected to the Gateway, and configured the former to forward packets.
My problem is by doing so, the Gateway became completely transparent. I want my gateway to be able to catch sockets even if they are not destined to it, opening them, modifying them and forwarding them to their original destination. Googled this and I found suggestions to use iptables, but i'm not expert with them.
I'm using 3 virtual machines under linux and programming with c. Any help please?!!

Iptables is not something to be afraid of ;) it has its own defined C functions. Go through the interface library and apply it to your own case. That is to run a program in the gateway, to capture all packets passing through it. There is documentation.

Related

disabling TCP stack in kernel and creating Userspace TCP stack -- call it a server for something -- what may be the challenges

if I malfunctioned my computer TCP stack in kernel just commenting out single important line of code or compiling with excluding TCP stack and install. Then What are the steps in I need to take in coding. Do I need to Implement Ethernet (if creates layer 2 Socket in my stack implementation) then do I need to implement IP because that comes with if I am using layer 2 socket then implement TCP (this is what final code will be)
If that's so
Then what are the supported protocols I need to implement to cover ethernet layer, Ip layer and (TCP layer -- that I can know I may have used it in code)
Can anyone please tell the machining protocols with each layer
whats before?-->ethernet --> ip -- tcp --> http <--protocol names please that may be needed
the whole thing is just for as a research thing or learning for my self or just may be programming
I'll assume you want to be able to do something like request https://example.com from a web server.
For this the following procotols are diretly necessary:
HTTPS (i.e. HTTP and TLS), but that's usually already implemented in user space, no change here
DNS to resolve example.com to an IP address. Usually implemented in user space as well, based on UDP
UDP to run DNS on top of. Usually implemented in the kernel on top of IP.
TCP to run HTTPS on top of. Usually implemented in the kernel on top of IP.
IP to run both TCP and UDP on top of. Usually implemented in the kernel on top of Ethernet.
Ethernet to send/receive IP packages. Usually implemented in the kernel, with the help of hardware-specific NIC drivers.
But even if you had implemented those, you wouldn't be done. For example, you wouldn't know what your local IP address is.
To do this, you'd implement DHCP. You could get away without implementing this, if you just configured your IP address to a fixed value (as long as it's within the allowed range of your network and doesn't conflict with other devices, this is not a problem).
But when you try to send your first IP packet to the DNS server, you'd realize that you don't know what Ethernet address you should send that to. So you'd need to implement ARP as well. Again, you could theoretically have a static routing table and "fake" the ARP responses by your router this way, but this could be way trickier than just hard-coding the IP adress.
I may have missed some protocol (and I'm sure comments will pop up, if I did), but that should be roughly everything that you'd need to get going.

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.

How to know the various IP addresses of the server using C, Linux, Socket?

I know one IP address of the remote node via. traceroute. However, I want to know all the IP address in its interfaces. How can I do so? The node doesn't have hostname so I can't use the API to get various ifaddress using hostname API. I searched various places but couldn't find on how to get the various IP address of the remote node. Is it possible to get it? Basically, I am implementing traceroute and my aim here is to display the loopback address of the intermediate node and not the actual interface address. In case loopback address is not available, I would like to display the actual interface address. I am struggling here and have no clue on it. This is all implemented using C - linux, UDP socket.
I want to know all the IP address in its interfaces. How can I do so
Lookup DNS or login in and use the OS dependant tools/APIs to lookup the local interfaces' IP addresses, else you are lost.
Technically if you are on the same network you could use the macid, and sniffing network traffic, to find other IPs on that interface, but once you leave your local network, its near impossible to find out other ips that machine is listening to, this would be a security issue if they made this information available.
The way traceroute works is by sending packets with increasing IP TTL values towards a remote address and the routers along the way will generate back ICMP TTL time exceeded thus revealing their IP source address back to the sender and so you get to know the hops that your data might be traversing when attempting to communicate to a specific remote address. The icmp error message will contain the ip address of the hop's incoming interface and in your case you want to discover also all other ip addresses assigned to further outgoing interfaces (outgoing as seen from your sender perspective) but this is not possible by using the above mentioned technique or any other.

Retrieving local IP before a connection is made

I am trying to determine which local IP would be used on a socket for a TCP connection towards a given host on Linux, using C.
Let me make an example. I could connect my socket and use getsockname() on the file descriptor to get the local ip (and local TCP port); but can I do this without opening the connection?
I could read the routing table and make a decision based on that - but the networking subsystem must have that algorithm already, for when the connection is actually open. In short, I'd like to know if there is an API to access the routing algorithms without having to parse the rules myself or opening an actual connection. The solution - if any - will probably be Linux only but that's OK.
EDIT: someone on IRC suggested I create a UDP socket and use connect() on it. No network is used at that point but I should be able to use getsockname() on it
The only solution I know to this is what traceroute does. Send a packet with a TTL of 1 and see which interface the ICMP return comes in on. As I recall there are lots of incompatibilities between different hosts, so there's probably several different types of messages you might need to send/receive to get the data you need.

Network Discovery of Servers

Ok, so I understand that communication between a client computer and a server computer can be initiated in windows with the creation of a socket between the two computers, but every tutorial that I have seen depends on the End User knowing the IP address of the computer that they wish to connect to.
In local network LAN games, however, the clients somehow autodetect the server. How is this done? Does the client autocheck every possible IP, is there some sort of "GetDetectedIPs" api, etc?
Im looking for answers that can be implemented in standard WIN32 API in straight C. No MFC, .NET, or C++ please. Thank you.
The technique you need is called broadcasting. It's used, for example, in BOOTP and DHCP protocols.
Sending a packet with broadcast destination address results in it being received by all devices in LAN. Broadcast address is an IP address in which the host identification field is filled with ones:
bcast_addr = ~netmask | my_addr;
The discovery process is usually like follows:
The client sends a UDP datagram with broadcast destination address at specific port.
The server listens on this port and receives the datagram. Other computers discard it.
Server sends all the necessary info about itself to the client by a usual UDP datagram.
This is usually done with zero-conf. Microsoft version of it is Simple Service Discovery Protocol.
You could just let the client send an UDP packet to every IP in a specified range and let the server answer with another UDP packet.

Resources