Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Erlang interface to low level socket operations
Erlang C Other
tree: 74a854e59e

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
c_src
src
.gitignore
Emakefile
Makefile
README

README

procket is an Erlang interface for requesting socket features that
usually require superuser privileges.

procket uses the experimental NIF interface first introduced in Erlang
R13B03.


EXPORTS

listen(Port, Options) -> {ok, FD} | {error, Reason} | {error, {Reason, Description}}

    Types   Port = 0..65535
            Options = [Opts]
            Opts = {pipe, Path} | {protocol, Protocol} | {ip, IPAddress} |
                    {progname, string()}
            Protocol = tcp | udp
            IPAddress = string() | tuple()
            Reason = atom()
            Description = string()


COMPILING

Well, try running: make

Maybe it'll work. If not:

1. In the Makefile, adjust ERL_ROOT to point to your Erlang install if
   it isn't in the default location.

2. In the Makefile, check the proper flags are uncommented for your
   platform (tested on Mac OS X and Linux).

3. For Mac OS X, the Makefile is set up for a 32-bit Erlang. If
   you're running a 64-bit Erlang, change ARCH=-m64 in Makefile and
   c_src/Makefile.ancillary.


SETUID vs SUDO

The procket executable needs root privileges. Either allow your user to
run procket using sudo or copy procket to somewhere owned by root and
make it setuid.

* for sudo

    sudo visudo
    youruser ALL=NOPASSWD: /path/to/procket/priv/procket

* to make it setuid

    sudo cp priv/procket /usr/local/bin
    sudo chown root:yourgroup /usr/local/bin/procket
    sudo chmod 750 /usr/local/bin/procket
    sudo chmod u+s /usr/local/bin/procket


USING IT

$ erl -pa ebin
Erlang R13B03 (erts-5.7.4) [source] [rq:1] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4  (abort with ^G)
1> {ok, FD} = procket:listen(53, [{progname, "sudo priv/procket"},{protocol, udp}]).
{ok,9}
2> {ok, S} = gen_udp:open(53, [{fd,FD}]).
{ok,#Port<0.929>}
3> receive M -> M end.
{udp,#Port<0.929>,{127,0,0,1},47483,"hello\n"}
4> 

$ nc -u localhost 53
hello
^C


EXAMPLE

echo is a sample client using procket.

$ erl -pa ebin
1> echo:start(53, [{progname, "sudo priv/procket"}, {protocol, tcp}]).

ICMP Ping:

1> icmp:ping("www.yahoo.com").

Sniff the network:

1> {ok, S} = procket:listen(0, [{protocol, 16#0008}, {type, raw}, {family, packet}]).
{ok,12}
2> procket:recvfrom(S, 2048).   
{ok,<<0,21,175,89,8,38,0,3,82,3,39,36,8,0,69,0,0,52,242,
          0,0,0,52,6,188,81,209,...>>}
3> {ok, S1} = gen_udp:open(0, [binary, {fd, S}, {active, false}]).
4> gen_udp:recv(S1, 2048).

HOW IT WORKS

procket creates a local domain socket and spawns a small setuid binary
(or runs it under sudo). The executable opens a socket, drops privs and
passes the file descriptor back to Erlang over the Unix socket.

procket uses libanciallary for passing file descriptors between processes:

    http://www.normalesup.org/~george/comp/libancillary/


TODO

Something went wrong with that request. Please try again.