views:

71

answers:

1

I have all traffic from port 50 redirected to 5050 using

iptables -t nat -A POSTROUTING -p udp --dport 50 -j REDIRECT --to-port 5050

I listen using a RAW Socket on 5050, and I see IP packets from 0.0.0.0:50 to 0.0.0.0:5050. The original destination address is obviously not present, since this seems to be a separate redirection packet from port 50 to port 5050.

If the original packet was supposed to go to a.b.c.d:50, how do I get that ip address? How can I figure out the destination address where the message was supposed to be sent to, so that I can forward it there?

I appreciate your help.

P.S.: I do not want to use libipq, since for some reason it didn't work and I wish not to waste more time getting it to work.

+3  A: 

Linux netfilter defines a socket option called SO_ORIGINAL_DST in <linux/netfilter_ipv4.h>.

First you need to enable port forwarding in your system, using one of these commands:

sysctl net.ipv4.ip_forward=1
echo 1 > /proc/sys/net/ipv4/ip_forward

Then you can use this:

struct sockaddr_in addr;
socklen_t addr_sz = sizeof(addr);
getsockopt(fd, IPPROTO_IP, SO_ORIGINAL_DST, &addr, &addr_sz);

I cannot find SO_ORIGINAL_DST in any Linux manpage. You may have luck finding formal documentation on the netfilter site.

camh
Thanks for replying. No it doesn't work either. It gives my_ip_address:0 . Can we get this done any other way?
SkypeMeSM
@SkypeMeSM: `SO_ORIGINAL_DST` requires you to enable port forwarding. It should fix your problem.
jweyrich
@jweyrich: Thank you for replying. I have done it. system("sysctl net.ipv4.ip_forward=1");addr_len = sizeof(struct sockaddr);getsockopt(sip_socket, IPPROTO_IP_IP, SO_ORIGINAL_DST, cout << inet_ntoa(sender_addr.sin_addr) << ":" << ntohs(sender_addr.sin_port) << endl;
SkypeMeSM
Sorry about that unaligned code in the comment. Basically I am setting the options properly. When a packet is received from a.b.c.d:50 to my_ip:50, it is redirected as a separate packet from my_ip:50 to my_ip:5050. Using SO_ORIGINAL_DST gives me my_ip:0, while I need a.b.c.d:50.
SkypeMeSM
@SkypeMeSM: try passing `SOL_IP` instead of `IPPROTO_IP`.
jweyrich
did that earlier.. same result...
SkypeMeSM
@SkypeMeSM: another important thing is that you must use PREROUTING instead of POSTROUTING because destination NAT only works before routing.
jweyrich
@jweyrich: I am using PREROUTING to forward the incoming packets and POSTROUTING to forward the outgoing packets to the new port 5050. Is that the correct thing to do?
SkypeMeSM
@SkypeMeSM: want to discuss it in the Networking chat room?
jweyrich
If I'm wrong, I hope someone correct me. I think this solution doesn't work for connectionless sockets because it's part of the conntrack module. See our conversation here: http://chat.stackoverflow.com/transcript/message/10324#10324
jweyrich
@SkypeMeSM: just found a project that might interest you. Read this specific topic: http://zorp-unoff.sourceforge.net/faq-4.html#ss4.5
jweyrich
@jweyrich: Thanks for the link. 'tproxy' seems to be an iptable patch, which requires that after installation, the linux kernel must be compiled again. This is not very feasible for my application, unfortunately.
SkypeMeSM
Can we use ip routes or a tunnel interface in some way??
SkypeMeSM