[erlang-questions] how: destination address of receiving connection

jm <>
Fri Nov 23 06:38:49 CET 2007


Per Hedeland wrote:

> For TCP, it's effectively from the packet - i.e. it's actually from the
> socket data structures, but you can be assured that it is the same as
> the destination address in the packet(s).
> 
> The original destination address after REDIRECT/DNAT is not in the
> packet or in the receiving socket's data, but you can get it from
> iptables *on the host where the DNAT happened* (which is OK in your
> case) by using getsockopt() with SO_ORIGINAL_DST (it's in
> <linux/netfilter_ipv4.h>) - don't know if it's documented anywhere, but
> there's always Google... I.e. an opportunity to use the RawOptReq
> functionality of inet:getopts/2!:-)


Thanks Per. Your a fountain of information on this stuff and Erlang. I 
was going nuts trying to workout how to avoid using libpcap and libnet 
or raw sockets in promiscuous for a proof of concept. I'd spent the last 
couple of days reading doco on all three, RFCs, and going mad. Looking 
at this it may be good enough to do a prototype to test with real traffic.

For anyone who has a similar problem this is what I've ended up with,

original_destination(Socket) ->
     %% /usr/include/linux/socket.h SOL_IP = 0,
     %% /usr/include/linux/netfilter_ipv4.h SO_ORIGINAL_DST = 80,
     %% sizeof(struct sockaddr_in) = 16 bytes
     {ok,[{raw, _, _, Info}]} = inet:getopts(Socket, [{raw, 0, 80, 16}]),
     <<_J:16, DPort:16/big, A:8, B:8, C:8, D:8, _Rest/binary>> = Info,
     DAddr = {A, B, C, D},
     error_logger:info_msg("getopts return ~p ~p ~p~n",
                           [Info, DAddr, DPort]),
     {DAddr, DPort}.

For the one machine test I was talking about: The machine is set up with 
  two ip adrresses

  eth0   192.168.1.66
  eth0:0 192.168.1.67

and added these two iptable rule

  iptables -t nat -A OUTPUT -s 192.168.1.66 -j ACCEPT
  iptables -t nat -A OUTPUT -p tcp -m multiport --source-ports 
30000:60000 -j REDIRECT --to-port 5002

where port 5002 is the port this program is listening on. These rules 
aren't great but should be good enough with a little tuning. This seems 
to work at least with

   telnet -b 192.168.1.67 someserver 80

so all that needs to be done is to bind the client to 192.168.1.67, 
luckily the client being used supports this. Testing a simple pass 
through proxy I managed to sustain about 240 connection using 3% or less 
of the cpu on a 2.66GHz P4. Still not a proof of concept but looking 
good so far.

Jeff.





More information about the erlang-questions mailing list