Permalink
Browse files

Try to figure out the default interface

Use a dumb algorithm (whether an interface has a self-assigned IP address)
to determine the default network device. Really should check the routing
table instead for the interface associated with the default route.
  • Loading branch information...
msantos committed Sep 17, 2010
1 parent be109e2 commit a56fb0bdc6d914fa3d2ffb6cbad301f5215dff7a
Showing with 49 additions and 13 deletions.
  1. +17 −6 README
  2. +32 −7 src/perv.erl
View
23 README
@@ -25,11 +25,26 @@ HOW TO USE IT
perv:start() -> ok
perv:start(Options) -> ok
- Types Options = list()
+ Types Options = [EpcapArgs | Keyword]
+ EpcapArgs = list()
+ Keyword = [exclude]
See epcap documentation for options.
- Files are written to priv/files/<mime type>.
+ perv will try to find the default interface to snoop (and will
+ probably get it wrong if there is more than one network interface). To
+ exclude the local host from packet dumps, use:
+
+ > perv:start(exclude).
+
+ To override the defaults, manually specify the device using the
+ epcap options, e.g.:
+
+ > perv:start([
+ {interface, "eth0"},
+ {filter, "tcp and src port 80 and not host 10.11.11.11"}]).
+
+ Content is written to priv/files/<mime type>.
A trace file containing the HTTP response is written to priv/tmp. The
trace file can be unpacked by using pervon:content/3.
@@ -99,9 +114,5 @@ TODO
* pervon:content/3 should return a list of tuples containing the name,
file type and file contents, rather than writing them directly to disk
-* since the interface being snooped is known, grab the device's IP
- address using inet:ifget/2. Provide an option for including/excluding
- the user's address.
-
* add option to enable/disable debug messages and tracing
View
@@ -37,6 +37,8 @@
-define(SERVER, ?MODULE).
-export([start/0, start/1, stop/0]).
+-export([dev/0]).
+-export([getip/1]).
-export([start_link/0, start_link/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
@@ -46,27 +48,35 @@
}).
-define(EPCAP_DEFAULT_ARG, [{filter, "tcp and src port 80"},
- {interface, "wlan0"},
{promiscuous, true},
{chroot, "priv/tmp"}]).
start() ->
start_link().
-start(EpcapArg) ->
- start_link(EpcapArg).
+start(Options) ->
+ start_link(Options).
stop() ->
gen_server:call(?SERVER, [stop]).
start_link() ->
start_link([]).
-start_link(EpcapArg) ->
- gen_server:start_link({local, ?SERVER}, ?MODULE, [EpcapArg], []).
+start_link(Options) ->
+ gen_server:start_link({local, ?SERVER}, ?MODULE, [Options], []).
-init([EpcapArg]) ->
- epcap:start(EpcapArg ++ ?EPCAP_DEFAULT_ARG),
+init([Options]) ->
+ {Dev, Address} = dev(),
+
+ EpcapArgs = case Options of
+ exclude ->
+ [{filter, "tcp and src port 80 and not host " ++ inet_parse:ntoa(Address)}];
+ Opt when is_list(Opt) ->
+ Options
+ end,
+
+ epcap:start(EpcapArgs ++ [{interface, Dev}] ++ ?EPCAP_DEFAULT_ARG),
{ok, #state{c = dict:new()}}.
@@ -199,3 +209,18 @@ buf(Pid, SeqNo, Payload, PayloadSize) when PayloadSize < byte_size(Payload) ->
pervon:buf(Pid, SeqNo, <<Payload:PayloadSize/bytes>>).
+% Try to autostupidly figure out the local host's network device.
+% Guaranteed to annoy.
+dev() ->
+ {ok, Devs} = inet:getiflist(),
+ Ifs = [ {N, getip(N)} || N <- Devs ],
+ hd(lists:filter(
+ fun ({_, {127,_,_,_}}) -> false;
+ ({_, {169,_,_,_}}) -> false;
+ ({_, {_,_,_,_}}) -> true
+ end, Ifs)).
+
+getip(Dev) ->
+ {ok, Addr} = inet:ifget(Dev, [addr]),
+ proplists:get_value(addr, Addr).
+

0 comments on commit a56fb0b

Please sign in to comment.