Permalink
Browse files

Add an NIF interface to ioctl()

Add an Erlang interface to ioctl() using an NIF. For example, to retrieve
the interface index for the "eth0" interface to use for sending out
raw packets:

-define(SIOCGIFINDEX, 16#8933).
{ok, <<_Ifname:16/bytes, Ifr:8, _/binary>>} = procket:ioctl(S,
        ?SIOCGIFINDEX,
        <<"eth0", 0:224>>).

The value "Ifr" will contain the index that can be used to set the
sll_ifindex member of struct sockaddr_ll.
  • Loading branch information...
1 parent 74a854e commit 65a61dc7bc17ba8742f19250735a28bd3ae90868 @msantos committed Jun 13, 2010
Showing with 41 additions and 1 deletion.
  1. +34 −0 c_src/procket.c
  2. +2 −0 c_src/procket.h
  3. +5 −1 src/procket.erl
View
@@ -232,6 +232,39 @@ nif_bind(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
return atom_ok;
}
+/* 0: (int)socket descriptor, 1: (int)device dependent request,
+ * 2: (char *)argp, pointer to structure
+ */
+ static ERL_NIF_TERM
+nif_ioctl(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
+{
+ int s = -1;
+ int req = 0;
+ ErlNifBinary ifr;
+
+
+ if (!enif_get_int(env, argv[0], &s))
+ return enif_make_badarg(env);
+
+ if (!enif_get_int(env, argv[1], &req))
+ return enif_make_badarg(env);
+
+ if (!enif_inspect_binary(env, argv[2], &ifr))
+ return enif_make_badarg(env);
+
+ if (!enif_realloc_binary(env, &ifr, ifr.size))
+ return enif_make_badarg(env);
+
+ (void)fprintf(stderr, "interface = %s\n", ifr.data);
+
+ if (ioctl(s, req, ifr.data) < 0)
+ return error_tuple(env, strerror(errno));
+
+ return enif_make_tuple(env, 2,
+ atom_ok,
+ enif_make_binary(env, &ifr));
+}
+
static ERL_NIF_TERM
error_tuple(ErlNifEnv *env, char *err)
@@ -259,6 +292,7 @@ static ErlNifFunc nif_funcs[] = {
{"close", 2, nif_close},
{"bind", 2, nif_bind},
{"recvfrom", 2, nif_recvfrom},
+ {"ioctl", 3, nif_ioctl},
{"sendto", 4, nif_sendto}
};
View
@@ -47,6 +47,8 @@
#include <sys/errno.h>
+#include <sys/ioctl.h>
+
#define PROCKET_VERSION "0.01"
#define MAXBUFLEN 4096 /* Largest message accepted on stdin */
View
@@ -32,7 +32,8 @@
-export([
init/0,open/1,poll/1,close/2,listen/1,listen/2,
- recvfrom/2,sendto/4,bind/2
+ recvfrom/2,sendto/4,bind/2,
+ ioctl/3
]).
-export([make_args/2,progname/0]).
@@ -60,6 +61,9 @@ bind(_,_) ->
recvfrom(_,_) ->
erlang:error(not_implemented).
+ioctl(_,_,_) ->
+ erlang:error(not_implemented).
+
sendto(_,_,_,_) ->
erlang:error(not_implemented).

0 comments on commit 65a61dc

Please sign in to comment.