Using this thing I can obtain original destination IP address of socket(PF_INET, SOCK_DGRAM, 0)
socket.
How to get original destination port?
Try parsing /proc/net/nf_conntrack
Depends on the redirection mechanism. If you are using REDIRECT (which is NAT under the hood), then you need to use SO_ORIGINAL_DST, or libnetfilter_conntrack to query the original destination of the connection before NAT was applied. However since you can serve several connections with the same listener socket, this lookup has to be done for every packet.
You can experiment with libnetfilter_conntrack and the services it provides using the conntrack command line tool.
An alterntive is to use TPROXY for the redirection, which was meant to be used in cases like this. There you can get the original destination of the packet using an ancillirary message using recvmsg(). The key to look for is the IP_RECVORIGDST setsockopt.
More information on TPROXY can be found in the kernel Documentation directory, in a file called tproxy.txt. It is a bit difficult to use, but works more reliably as it is implemented by the stack, rather than the packet filtering subsystem.
Edited: to add how to query UDP destination addresses with TProxy.
Edited: SO_ORIGINAL_DST vs. udp
SO_ORIGINAL_DST should work with udp sockets, however the kernel doesn't let you specify the connection endpoints, it'll use the socket that you call SO_ORIGINAL_DST on to get this address information.
This means that it'll only work, if the UDP socket is properly bound (to the redirected-to address/port) and connected (to the client in question). Your listener socket is probably bound to 0.0.0.0 and is servicing not just a single, but mulitple clients.
However, you don't need to use your actual listener socket to query the destination address. Since since UDP doesn't transmit datagrams on connection establishment, you can create a new UDP socket, bind it to the redirect address and connect it to the client (whose address you know since it sent the first packet to your listener anyway). Then you could use this socket to run SO_ORIGINAL_DST on, however there are culprits:
The TProxy based method is clearly better.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With