[erlang-questions] bpf port driver
mighty
mighty.fine@REDACTED
Thu Feb 22 17:47:44 CET 2007
i'm very new to erlang and was looking for some help putting together a
reasonable driver around bpf. using the tuntap driver in jungerl as a
starting point, i have a driver through with which i can successfully write
to the bpf... but i'm running into troubles attempting to read from the bpf
-- i can't get anything read in from the bpf, and calling driver_select()
crashes. i've attached what i've put together so far (it's pretty rough and
minimal) minus my attempts to read() from the bpf -- any and all advice
would be greatly appreciated (i've looked around at a number of example
drivers, but am having a hard time distilling the minimum essence of getting
input from a driver into erlang). thanks!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20070222/eb98e384/attachment.htm>
-------------- next part --------------
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <net/bpf.h>
#include <errno.h>
#include <string.h>
#include <erl_driver.h>
struct bpf_data
{
ErlDrvPort port;
int fd;
char dev[sizeof("/dev/bpf0")];
};
static int bpf_dev(struct bpf_data *data)
{
int i;
for (i=0; i<10; i++)
{
snprintf(data->dev, sizeof(data->dev), "/dev/bpf%u", i);
if ((data->fd = open(data->dev, O_RDWR)) != -1)
return 0;
}
return -1;
}
static int bpf_ifc(struct bpf_data *data, char *ifc)
{
struct ifreq ifr;
int on =1;
strncpy(ifr.ifr_name, ifc, sizeof(ifr.ifr_name));
if (ioctl(data->fd, BIOCSETIF, &ifr) != -1)
if (ioctl(data->fd, BIOCPROMISC, &on) != -1)
if (ioctl(data->fd, BIOCIMMEDIATE, &on) != -1)
return 0;
return -1;
}
static ErlDrvData bpf_open(ErlDrvPort port, char *buf)
{
struct bpf_data *data;
while (*buf++ != ' ');
if ((data = (struct bpf_data *)driver_alloc(sizeof(struct bpf_data))))
{
if (bpf_dev(data) != -1)
{
if (bpf_ifc(data, buf) != -1)
return (ErlDrvData)data;
close(data->fd);
}
driver_free((void *)data);
}
return ERL_DRV_ERROR_GENERAL;
}
static void bpf_close(ErlDrvData handle)
{
struct bpf_data *data;
if ((data = (struct bpf_data *)handle))
{
close(data->fd);
driver_free((void *)data);
}
}
static void bpf_output(ErlDrvData handle, char *buf, int len)
{
struct bpf_data *data;
if ((data = (struct bpf_data *)handle))
if (write(data->fd, buf, len) < 0)
driver_failure_posix(data->port, errno);
}
ErlDrvEntry bpf_driver_entry =
{
0,
bpf_open,
bpf_close,
bpf_output,
0,
0,
"bpf_drv",
0,
0,
0,
0
};
DRIVER_INIT(bpf)
{
return &bpf_driver_entry;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bpf.erl
Type: application/octet-stream
Size: 277 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20070222/eb98e384/attachment.obj>
More information about the erlang-questions
mailing list