msantos / gen_icmp

Erlang interface to ICMP sockets
http://listincomprehension.com/2010/12/icmp-ping-in-erlang-part-2.html
BSD 3-Clause "New" or "Revised" License
101 stars 33 forks source link

Sending packets via specific network interfaces #15

Open mszmurlo opened 6 years ago

mszmurlo commented 6 years ago

Hi,

This is not an issue but a feature inquiry (unless it already exists and I've missed it).

I need to send packets (mainly for ping and traceroute) through different interfaces and I couldn't find the way do do it. On the command line with the linux ping, you can set the option -I <interface> or -I <address> and the packets are sent through the interface with the proper source address regardless of the routing table.

  1. Is there a way to do this
  2. Is there a way to set the source address
  3. If not, do you have plans to integrate it ?

Thanks for the great work anyway : this lib is very useful. Cheers Maurycy

msantos commented 6 years ago

Hey @mszmurlo !

Use the interface socket option to gen_icmp:open/1:

% ping -I lo 127.0.0.1
{ok, S} = gen_icmp:open([{interface, "lo"}]),
gen_icmp:ping(S, ["127.0.0.1", "8.8.8.8"], []).

[{error,timeout,"8.8.8.8",{8,8,8,8}},
 {ok,"127.0.0.1",
     {127,0,0,1},
     {127,0,0,1},
     {50250,0,64,0},
     <<" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO">>}]

These options are documented here: https://github.com/msantos/procket/blob/master/README.md

Setting the source IP address using the ip option should work but doesn't:

% ping -I 127.0.0.1
{ok, S} = gen_icmp:open([{ip, "127.0.0.1"}]),
gen_icmp:ping(S, ["127.0.0.1", "8.8.8.8"], []).

It seems procket will not attempt to bind() an ICMP socket. Should be simple to fix, I'll take a look at it.

Thank you for opening the issue! And if you have any questions, please let me know!

mszmurlo commented 6 years ago

Thanks for the quick reply! I didn't think about reading procket doc; just read gen_icmp... Grrr! I'll give it a try shortly and send back some feedback Thanks again Maurycy

msantos commented 6 years ago

No problem! The readme should have documented those options.

BTW, if you don't want to manage the socket yourself, gen_icmp:ping/2 accepts socket options:

gen_icmp:ping(["127.0.0.1", "8.8.8.8"], [{interface, "lo"}]).
mszmurlo commented 6 years ago

All works fine on my RPi with 2 modems and a wifi connection. Thanks for the reactivity Maurycy