summaryrefslogtreecommitdiffstats
path: root/input/packet/ulogd_inppkt_NFLOG.c
diff options
context:
space:
mode:
authorlaforge <laforge>2005-10-03 13:09:19 +0000
committerlaforge <laforge>2005-10-03 13:09:19 +0000
commitbf45c8d7bf623921410b26f33d071566bd1ebad8 (patch)
tree61a227e4dc4245da2d7090ec00f394ee54a6fa37 /input/packet/ulogd_inppkt_NFLOG.c
parent936e615424b0b77c112a1e5c5fab1045f569bbf1 (diff)
bring NFLOG input plugin into compiling state
Diffstat (limited to 'input/packet/ulogd_inppkt_NFLOG.c')
-rw-r--r--input/packet/ulogd_inppkt_NFLOG.c269
1 files changed, 159 insertions, 110 deletions
diff --git a/input/packet/ulogd_inppkt_NFLOG.c b/input/packet/ulogd_inppkt_NFLOG.c
index 8592ac2..3bc0a07 100644
--- a/input/packet/ulogd_inppkt_NFLOG.c
+++ b/input/packet/ulogd_inppkt_NFLOG.c
@@ -4,6 +4,7 @@
#include <unistd.h>
#include <stdlib.h>
+#include <netinet/in.h>
#include <ulogd/ulogd.h>
#include <libnfnetlink_log/libnfnetlink_log.h>
@@ -32,31 +33,46 @@ struct nful_input {
/* configuration entries */
static struct config_keyset libulog_kset = {
- .num_ces = 3,
+ .num_ces = 5,
.ces = {
- {
- .key = "bufsize",
- .type = CONFIG_TYPE_INT,
- .options = CONFIG_OPT_NONE,
- .u.value = NFLOG_BUFSIZE_DEFAULT,
- },
- {
- .key = "group",
- .type = CONFIG_TYPE_INT,
- .options = CONFIG_OPT_NONE,
- .u.value = NFLOG_GROUP_DEFAULT,
- },
- {
- .key = "rmem",
- .type = CONFIG_TYPE_INT,
- .options = CONFIG_OPT_NONE,
- .u.value = NFLOG_RMEM_DEFAULT,
- },
+ {
+ .key = "bufsize",
+ .type = CONFIG_TYPE_INT,
+ .options = CONFIG_OPT_NONE,
+ .u.value = NFLOG_BUFSIZE_DEFAULT,
+ },
+ {
+ .key = "group",
+ .type = CONFIG_TYPE_INT,
+ .options = CONFIG_OPT_NONE,
+ .u.value = NFLOG_GROUP_DEFAULT,
+ },
+ {
+ .key = "rmem",
+ .type = CONFIG_TYPE_INT,
+ .options = CONFIG_OPT_NONE,
+ .u.value = NFLOG_RMEM_DEFAULT,
+ },
+ {
+ .key = "addressfamily",
+ .type = CONFIG_TYPE_INT,
+ .options = CONFIG_OPT_NONE,
+ .u.value = AF_INET,
+ },
+ {
+ .key = "unbind",
+ .type = CONFIG_TYPE_INT,
+ .options = CONFIG_OPT_NONE,
+ .u.value = 1,
+ },
+ }
};
-#define bufsiz_ce(x) (x[0])
-#define group_ce(x) (x[1])
-#define rmem_ce(x) (x[2])
+#define bufsiz_ce(x) (x->ces[0])
+#define group_ce(x) (x->ces[1])
+#define rmem_ce(x) (x->ces[2])
+#define af_ce(x) (x->ces[3])
+#define unbind_ce(x) (x->ces[4])
static struct ulogd_key output_keys[] = {
@@ -127,63 +143,99 @@ static struct ulogd_key output_keys[] = {
},
};
-static int interp_packet(struct ulogd_pluginstance *ip, ulog_packet_msg_t *pkt)
+static inline int
+interp_packet(struct ulogd_pluginstance *upi, struct nfattr *nfa[])
{
unsigned char *p;
int i;
char *buf, *oldbuf = NULL;
- struct ulogd_key *ret = ip->output;
+ struct ulogd_key *ret = upi->output;
+
+ if (nfa[NFULA_PACKET_HDR-1]) {
+ struct nfulnl_msg_packet_hdr *ph =
+ NFA_DATA(nfa[NFULA_PACKET_HDR-1]);
+ /* FIXME */
+ }
- if (pkt->mac_len) {
- buf = (char *) malloc(3 * pkt->mac_len + 1);
- if (!buf) {
+ if (nfa[NFULA_HWADDR-1]) {
+ struct nfulnl_msg_packet_hw *hw =
+ NFA_DATA(nfa[NFULA_HWADDR-1]);
+ int addr_len = ntohs(hw->hw_addrlen);
+
+ buf = (char *) malloc(3 * addr_len + 1);
+ if (!buf)
ulogd_log(ULOGD_ERROR, "OOM!!!\n");
- return -1;
+ else {
+ *buf = '\0';
+
+ p = hw->hw_addr;
+ oldbuf = buf;
+ for (i = 0; i < addr_len; i++, p++)
+ sprintf(buf, "%s%02x%c", oldbuf, *p,
+ i==addr_len-1 ? ' ':':');
+ ret[0].u.value.ptr = buf;
+ ret[0].flags |= ULOGD_RETF_VALID;
}
- *buf = '\0';
-
- p = pkt->mac;
- oldbuf = buf;
- for (i = 0; i < pkt->mac_len; i++, p++)
- sprintf(buf, "%s%02x%c", oldbuf, *p, i==pkt->mac_len-1 ? ' ':':');
- ret[0].u.value.ptr = buf;
- ret[0].flags |= ULOGD_RETF_VALID;
}
- /* include pointer to raw ipv4 packet */
- ret[1].u.value.ptr = pkt->payload;
- ret[1].flags |= ULOGD_RETF_VALID;
- ret[2].u.value.ui32 = pkt->data_len;
- ret[2].flags |= ULOGD_RETF_VALID;
+ if (nfa[NFULA_PAYLOAD-1]) {
+ /* include pointer to raw packet */
+ ret[1].u.value.ptr = NFA_DATA(nfa[NFULA_PAYLOAD-1]);
+ ret[1].flags |= ULOGD_RETF_VALID;
+
+ ret[2].u.value.ui32 = NFA_PAYLOAD(nfa[NFULA_PAYLOAD-1]);
+ ret[2].flags |= ULOGD_RETF_VALID;
+ }
+
+ /* number of packets */
ret[3].u.value.ui32 = 1;
ret[3].flags |= ULOGD_RETF_VALID;
- ret[4].u.value.ptr = pkt->prefix;
- ret[4].flags |= ULOGD_RETF_VALID;
-
- /* god knows why timestamp_usec contains crap if timestamp_sec == 0
- * if (pkt->timestamp_sec || pkt->timestamp_usec) { */
- if (pkt->timestamp_sec) {
- ret[5].u.value.ui32 = pkt->timestamp_sec;
- ret[5].flags |= ULOGD_RETF_VALID;
- ret[6].u.value.ui32 = pkt->timestamp_usec;
- ret[6].flags |= ULOGD_RETF_VALID;
- } else {
- ret[5].flags &= ~ULOGD_RETF_VALID;
- ret[6].flags &= ~ULOGD_RETF_VALID;
+ if (nfa[NFULA_PREFIX-1]) {
+ ret[4].u.value.ptr = NFA_DATA(nfa[NFULA_PREFIX-1]);
+ ret[4].flags |= ULOGD_RETF_VALID;
+ }
+
+ if (nfa[NFULA_TIMESTAMP-1]) {
+ struct nfulnl_msg_packet_timestamp *ts =
+ NFA_DATA(nfa[NFULA_TIMESTAMP-1]);
+ /* FIXME: convert endianness */
+
+ /* god knows why timestamp_usec contains crap if timestamp_sec
+ * == 0 if (pkt->timestamp_sec || pkt->timestamp_usec) { */
+ if (ts->sec) {
+ ret[5].u.value.ui32 = ts->sec;
+ ret[5].flags |= ULOGD_RETF_VALID;
+ ret[6].u.value.ui32 = ts->usec;
+ ret[6].flags |= ULOGD_RETF_VALID;
+ } else {
+ ret[5].flags &= ~ULOGD_RETF_VALID;
+ ret[6].flags &= ~ULOGD_RETF_VALID;
+ }
+ }
+
+ if (nfa[NFULA_MARK-1]) {
+ ret[7].u.value.ui32 =
+ ntohl(*(u_int32_t *)NFA_DATA(nfa[NFULA_MARK-1]));
+ ret[7].flags |= ULOGD_RETF_VALID;
+ }
+
+ if (nfa[NFULA_IFINDEX_INDEV-1]) {
+ ret[8].u.value.ui32 =
+ ntohl(*(u_int32_t *)NFA_DATA(nfa[NFULA_IFINDEX_INDEV]));
+ ret[8].flags |= ULOGD_RETF_VALID;
}
- ret[7].u.value.ui32 = pkt->mark;
- ret[7].flags |= ULOGD_RETF_VALID;
- ret[8].u.value.ptr = pkt->indev_name;
- ret[8].flags |= ULOGD_RETF_VALID;
- ret[9].u.value.ptr = pkt->outdev_name;
- ret[9].flags |= ULOGD_RETF_VALID;
+ if (nfa[NFULA_IFINDEX_OUTDEV-1]) {
+ ret[9].u.value.ui32 =
+ ntohl(*(u_int32_t *)NFA_DATA(nfa[NFULA_IFINDEX_OUTDEV]));
+ ret[9].flags |= ULOGD_RETF_VALID;
+ }
return 0;
}
-/* callback called when fd is readable */
+/* callback called from ulogd core when fd is readable */
static int nful_read_cb(int fd, unsigned int what, void *param)
{
struct ulogd_pluginstance *upi = (struct ulogd_pluginstance *)param;
@@ -193,25 +245,15 @@ static int nful_read_cb(int fd, unsigned int what, void *param)
if (!(what & ULOGD_FD_READ))
return 0;
- /* FIXME: read */
- nfulnl_handle_packet(ui->nful_h, buf, len);
-#if 0
- while (len = ipulog_read(u->libulog_h, u->libulog_buf,
- bufsiz_ce(upi->configs).u.value, 1)) {
- if (len <= 0) {
- /* this is not supposed to happen */
- ulogd_log(ULOGD_ERROR, "ipulog_read = %d! "
- "ipulog_errno = %d, errno = %d\n",
- len, ipulog_errno, errno);
- break;
- }
- while ((upkt = ipulog_get_packet(u->libulog_h,
- u->libulog_buf, len))) {
- ulogd_log(ULOGD_DEBUG, "==> ulog packet received\n");
- interp_packet(upi, upkt);
- }
- }
-#endif
+ /* we don't have a while loop here, since we don't want to
+ * grab all the processing time just for us. there might be other
+ * sockets that have pending work */
+ len = recv(fd, ui->nfulog_buf, bufsiz_ce(upi->config_kset).u.value, 0);
+ if (len < 0)
+ return len;
+
+ nfulnl_handle_packet(ui->nful_h, ui->nfulog_buf, len);
+
return 0;
}
@@ -219,23 +261,22 @@ static int nful_read_cb(int fd, unsigned int what, void *param)
static int msg_cb(struct nfulnl_g_handle *gh, struct nfgenmsg *nfmsg,
struct nfattr *nfa[], void *data)
{
- /* FIXME: interp_packet() */
+ struct ulogd_pluginstance *upi = data;
+
+ return interp_packet(upi, nfa);
}
-static struct ulogd_pluginstance *init(struct ulogd_plugin *pl)
+static int configure(struct ulogd_pluginstance *upi,
+ struct ulogd_pluginstance_stack *stack)
{
- struct nful_input *ui;
- struct ulogd_pluginstance *upi = malloc(sizeof(*upi)+sizeof(*ui));
-
- if (!upi)
- return NULL;
+ return 0;
+}
- ui = (struct nful_input *) upi->private;
- upi->plugin = pl;
- upi->input = NULL;
- /* FIXME: upi->output = */
+static int start(struct ulogd_pluginstance *upi)
+{
+ struct nful_input *ui = (struct nful_input *) upi->private;
- ui->nfulog_buf = malloc(bufsiz_ce(upi->configs).u.value);
+ ui->nfulog_buf = malloc(bufsiz_ce(upi->config_kset).u.value);
if (!ui->nfulog_buf)
goto out_buf;
@@ -243,35 +284,41 @@ static struct ulogd_pluginstance *init(struct ulogd_plugin *pl)
if (!ui->nful_h)
goto out_handle;
- /* FIXME: config entry for af's */
- /* FIXME: forced unbind of existing handler */
- if (nfulnl_bind_pf(ui->nful_h, AF_INET) < 0)
+ if (unbind_ce(upi->config_kset).u.value > 0)
+ nfulnl_unbind_pf(ui->nful_h, af_ce(upi->config_kset).u.value);
+
+ if (nfulnl_bind_pf(ui->nful_h, af_ce(upi->config_kset).u.value) < 0)
goto out_bind_pf;
- ui->nful_gh = nfulnl_bind_group(&ui->nful_h,
- group_ce(upi->configs).u.value,
- &msg_cb, NULL);
+ ui->nful_gh = nfulnl_bind_group(ui->nful_h,
+ group_ce(upi->config_kset).u.value);
if (!ui->nful_gh)
goto out_bind;
+ nfulnl_set_mode(ui->nful_gh, NFULNL_COPY_PACKET, 0xffff);
+
//nfulnl_set_nlbufsiz(&ui->nful_gh, );
//nfnl_set_rcvbuf();
+
+ nfulnl_callback_register(ui->nful_gh, &msg_cb, upi);
- ui->ulog_fd.fd = nfulnl_fd(ui->nfulnl_h);
- ui->ulog_fd.cb = &nfulnl_read_cb;
- ui->ulog_fd.data = upi;
+ ui->nful_fd.fd = nfulnl_fd(ui->nful_h);
+ ui->nful_fd.cb = &nful_read_cb;
+ ui->nful_fd.data = upi;
+ ui->nful_fd.flags = ULOGD_FD_READ;
ulogd_register_fd(&ui->nful_fd);
- return upi;
+ return 0;
out_bind:
- nfulnl_close(&ui->nful_h);
+ nfulnl_close(ui->nful_h);
+out_bind_pf:
+ nfulnl_unbind_pf(ui->nful_h, af_ce(upi->config_kset).u.value);
out_handle:
- free(ui->libulog_buf);
+ free(ui->nfulog_buf);
out_buf:
- free(upi);
- return NULL;
+ return -1;
}
static int fini(struct ulogd_pluginstance *pi)
@@ -294,12 +341,14 @@ struct ulogd_plugin libulog_plugin = {
},
.output = {
.type = ULOGD_DTYPE_RAW,
- .keys = &output_keys,
+ .keys = output_keys,
.num_keys = sizeof(output_keys)/sizeof(struct ulogd_key),
},
- .constructor = &init,
- .destructor = &fini,
- .config_kset = &libulog_kset,
+ .priv_size = sizeof(struct nful_input),
+ .configure = &configure,
+ .start = &start,
+ .stop = &fini,
+ .config_kset = &libulog_kset,
};
void _init(void)