Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sending packets via specific network interfaces #15

Open
mszmurlo opened this issue Sep 3, 2018 · 4 comments
Open

Sending packets via specific network interfaces #15

mszmurlo opened this issue Sep 3, 2018 · 4 comments

Comments

@mszmurlo
Copy link

mszmurlo commented Sep 3, 2018

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
Copy link
Owner

msantos commented Sep 3, 2018

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
Copy link
Author

mszmurlo commented Sep 3, 2018

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
Copy link
Owner

msantos commented Sep 3, 2018

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
Copy link
Author

mszmurlo commented Sep 3, 2018

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

msantos added a commit to msantos/procket that referenced this issue Sep 10, 2018
Allow setting the source address of ICMP sockets by calling bind(2) in
the setuid helper. See:

msantos/gen_icmp#15

For SOCK_RAW sockets, getaddrinfo(3) on Linux expects:

* the service name (aka port) to be NULL
* the node name to be non-NULL

According to the Linux and FreeBSD man page, if the node name is NULL,
default values of INADDR_ANY for IPv4 and IN6ADDR_ANY_INIT for IPv6 will
be used. On Linux at least, passing NULL will result in an error. Set
defaults of either "0.0.0.0" or "::" to avoid the error. Portability
of these defaults still needs testing.

Alternatively, setting of these options could be moved to erlang code,
either in procket.erl or by the caller.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants