From 99987584cdfd3c4d52432346b407818547e9e157 Mon Sep 17 00:00:00 2001 From: laforge Date: Mon, 31 Jul 2000 09:08:10 +0000 Subject: Initial revision --- iptables/libipt_ULOG.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++ kernel/ipt_ULOG.c | 138 +++++++++++++++++++++++++++++++++++++++ kernel/ipt_ULOG.h | 36 +++++++++++ 3 files changed, 345 insertions(+) create mode 100644 iptables/libipt_ULOG.c create mode 100644 kernel/ipt_ULOG.c create mode 100644 kernel/ipt_ULOG.h diff --git a/iptables/libipt_ULOG.c b/iptables/libipt_ULOG.c new file mode 100644 index 0000000..f079e5f --- /dev/null +++ b/iptables/libipt_ULOG.c @@ -0,0 +1,171 @@ +/* Shared library add-on to iptables to add ULOG support. + * + * (C) 2000 by Harald Welte + * + * This software is released under the terms of GNU GPL + * + * $Id$ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ULOG_DEFAULT_NLGROUP 1 + + +void print_groups(unsigned int gmask) +{ + int b; + unsigned int test; + + for (b = 31; b >= 0; b--) + { + test = (1 << b); + if (gmask & test) + printf("%d ", b + 1); + } +} + +/* Function which prints out usage message. */ +static void help(void) +{ + printf( +"ULOG v%s options:\n" +" --ulog-nlgroup nlgroup NETLINK grouo used for logging\n" +" --ulog-prefix prefix Prefix log messages with this prefix.\n\n", +NETFILTER_VERSION); +} + +static struct option opts[] = { + { "ulog-nlgroup", 1, 0, '!' }, + { "ulog-prefix", 1, 0, '#' }, + { 0 } +}; + +/* Initialize the target. */ +static void init(struct ipt_entry_target *t, unsigned int *nfcache) +{ + struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *)t->data; + + loginfo->nl_group = ULOG_DEFAULT_NLGROUP; + + /* Can't cache this */ + *nfcache |= NFC_UNKNOWN; +} + +#define IPT_LOG_OPT_NLGROUP 0x01 +#define IPT_LOG_OPT_PREFIX 0x02 + +/* Function which parses command options; returns true if it + ate an option */ +static int parse(int c, char **argv, int invert, unsigned int *flags, + const struct ipt_entry *entry, + struct ipt_entry_target **target) +{ + struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *)(*target)->data; + int group_d; + + switch (c) { + case '!': + if (*flags & IPT_LOG_OPT_NLGROUP) + exit_error(PARAMETER_PROBLEM, + "Can't specify --ulog-nlgroup twice"); + + if (check_inverse(optarg, &invert)) + exit_error(PARAMETER_PROBLEM, + "Unexpected `!' after --ulog-nlgroup"); + group_d = atoi(optarg); + if (group_d > 32 || group_d < 1) + exit_error(PARAMETER_PROBLEM, + "--ulog-nlgroup has to be between 1 and 32"); + + loginfo->nl_group = (1 << (group_d -1)); + + *flags |= IPT_LOG_OPT_NLGROUP; + break; + + case '#': + if (*flags & IPT_LOG_OPT_PREFIX) + exit_error(PARAMETER_PROBLEM, + "Can't specify --ulog-prefix twice"); + + if (check_inverse(optarg, &invert)) + exit_error(PARAMETER_PROBLEM, + "Unexpected `!' after --ulog-prefix"); + + if (strlen(optarg) > sizeof(loginfo->prefix) - 1) + exit_error(PARAMETER_PROBLEM, + "Maximum prefix length %u for --ulog-prefix", + sizeof(loginfo->prefix) - 1); + + strcpy(loginfo->prefix, optarg); + *flags |= IPT_LOG_OPT_PREFIX; + break; + } + return 1; +} + +/* Final check; nothing. */ +static void final_check(unsigned int flags) +{ +} + +/* Saves the union ipt_targinfo in parsable form to stdout. */ +static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target) +{ + const struct ipt_ulog_info *loginfo + = (const struct ipt_ulog_info *)target->data; + + if (strcmp(loginfo->prefix, "") != 0) + printf("--ulog-prefix %s ", loginfo->prefix); + + if (loginfo->nl_group != ULOG_DEFAULT_NLGROUP) + { + printf("--ulog-nlgroup "); + print_groups(loginfo->nl_group); + printf("\n"); + } +} + +/* Prints out the targinfo. */ +static void +print(const struct ipt_ip *ip, + const struct ipt_entry_target *target, + int numeric) +{ + const struct ipt_ulog_info *loginfo + = (const struct ipt_ulog_info *)target->data; + + printf("ULOG "); + printf("flags %u nlgroup ", + loginfo->logflags); + print_groups(loginfo->nl_group); + if (strcmp(loginfo->prefix, "") != 0) + printf("prefix `%s' ", loginfo->prefix); +} + +struct iptables_target ulog += { NULL, + "ULOG", + NETFILTER_VERSION, + IPT_ALIGN(sizeof(struct ipt_ulog_info)), + IPT_ALIGN(sizeof(struct ipt_ulog_info)), + &help, + &init, + &parse, + &final_check, + &print, + &save, + opts +}; + +void _init(void) +{ + register_target(&ulog); +} diff --git a/kernel/ipt_ULOG.c b/kernel/ipt_ULOG.c new file mode 100644 index 0000000..06a3578 --- /dev/null +++ b/kernel/ipt_ULOG.c @@ -0,0 +1,138 @@ +/* + * netfilter module for userspace packet logging daemons + * + * (C) 2000 by Harald Welte + * + * Released under the terms of the GPL + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NETLINK_NFLOG 25 +#define ULOG_NL_EVENT 111 + +#if 1 +#define DEBUGP printk +#else +#define DEBUGP(format, args ...) +#endif + +struct sock *nflognl; + +static void nflog_rcv(struct sock *sk, int len) +{ + printk("nflog_rcv: did receive netlink message ?!?\n"); +} + +static unsigned int ipt_ulog_target( + struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const void *targinfo, + void *userinfo) +{ + ulog_packet_msg_t *pm; + size_t size; + struct sk_buff *nlskb; + unsigned char *old_tail; + struct nlmsghdr *nlh; + struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *)targinfo; + + /* calculate the size of the skb needed */ + + size = NLMSG_SPACE(sizeof(*pm) + (*pskb)->len); + nlskb = alloc_skb(size, GFP_ATOMIC); + if (!nlskb) + goto nlmsg_failure; + + old_tail = nlskb->tail; + nlh = NLMSG_PUT(nlskb, 0, 0, ULOG_NL_EVENT, size - sizeof(*nlh)); + pm = NLMSG_DATA(nlh); + + /* copy hook, prefix, timestamp, payload, etc. */ + + pm->data_len = (*pskb)->len; + pm->timestamp_sec = (*pskb)->stamp.tv_sec; + pm->timestamp_usec = (*pskb)->stamp.tv_usec; + pm->mark = (*pskb)->nfmark; + pm->hook = hooknum; + if (loginfo->prefix) + strcpy(pm->prefix, loginfo->prefix); + + if (in && !out) + { + if ((*pskb)->dev && (*pskb)->dev->hard_header_len > 0 + && (*pskb)->dev->hard_header_len <= ULOG_MAC_LEN) + { + memcpy(pm->mac, (*pskb)->mac.raw, (*pskb)->dev->hard_header_len); + pm->mac_len = (*pskb)->dev->hard_header_len; + } + + } +/* + if (in) strcpy(pm->indev_name, in->name); + else pm->indev_name[0] = '\0'; +*/ + if ((*pskb)->len) + memcpy(pm->payload, (*pskb)->data, (*pskb)->len); + nlh->nlmsg_len = nlskb->tail - old_tail; + NETLINK_CB(nlskb).dst_groups = loginfo->nl_group; + DEBUGP("ipt_ULOG: going to throw out a packet to netlink groupmask %u\n", loginfo->nl_group); + netlink_broadcast(nflognl, nlskb, 0, loginfo->nl_group, GFP_ATOMIC); + + return IPT_CONTINUE; + +nlmsg_failure: + if (nlskb) + kfree(nlskb); + printk("ipt_ULOG: Error building netlink message\n"); + return IPT_CONTINUE; + +} + +static int ipt_ulog_checkentry( + const char *tablename, + const struct ipt_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hookmask) +{ + return 1; +} + + +static struct ipt_target ipt_ulog_reg = + { { NULL, NULL }, "ULOG", ipt_ulog_target, ipt_ulog_checkentry, NULL, + THIS_MODULE }; + +static int __init init(void) +{ + DEBUGP("ipt_ULOG: init module\n"); + nflognl = netlink_kernel_create(NETLINK_NFLOG, nflog_rcv); + if (ipt_register_target(&ipt_ulog_reg)) + return -EINVAL; + + return 0; +} + +static void __exit fini(void) +{ + DEBUGP("ipt_ULOG: cleanup_module\n"); + ipt_unregister_target(&ipt_ulog_reg); +} + +module_init(init); +module_exit(fini); diff --git a/kernel/ipt_ULOG.h b/kernel/ipt_ULOG.h new file mode 100644 index 0000000..78ff0df --- /dev/null +++ b/kernel/ipt_ULOG.h @@ -0,0 +1,36 @@ +#ifndef _IPT_ULOG_H +#define _IPT_ULOG_H + +#ifdef __KERNEL__ +#include +#endif + +#define ULOG_MAC_LEN 80 + + +/* just until this is in netfilter.h */ +#ifndef NETLINK_NFLOG +#define NETLINK_NFLOG 25 +#endif + +struct ipt_ulog_info { + unsigned char logflags; + unsigned int nl_group; + char prefix[30]; +}; + +typedef struct ulog_packet_msg { + unsigned long mark; + long timestamp_sec; + long timestamp_usec; + unsigned int hook; + char indev_name[IFNAMSIZ]; + char outdev_name[IFNAMSIZ]; + size_t data_len; + char prefix[30]; + unsigned char mac_len; + unsigned char mac[ULOG_MAC_LEN]; + unsigned char payload[0]; +} ulog_packet_msg_t; + +#endif /*_IPT_ULOG_H*/ -- cgit v1.2.3