diff options
author | laforge <laforge> | 2005-10-03 13:09:19 +0000 |
---|---|---|
committer | laforge <laforge> | 2005-10-03 13:09:19 +0000 |
commit | bf45c8d7bf623921410b26f33d071566bd1ebad8 (patch) | |
tree | 61a227e4dc4245da2d7090ec00f394ee54a6fa37 /input/packet/ulogd_inppkt_NFLOG.c | |
parent | 936e615424b0b77c112a1e5c5fab1045f569bbf1 (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.c | 269 |
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) |