*
*/
-#include <linux/in.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_log.h>
#include <linux/netfilter.h>
#include <linux/in.h>
#include <linux/if_arp.h>
#include <linux/spinlock.h>
+#include <net/netfilter/nf_log.h>
+#include <linux/ipv6.h>
+#include <net/ipv6.h>
+#include <linux/in6.h>
static DEFINE_SPINLOCK(ebt_log_lock);
static int ebt_log_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_log_info *info = (struct ebt_log_info *)data;
+ struct ebt_log_info *info = data;
if (datalen != EBT_ALIGN(sizeof(struct ebt_log_info)))
return -EINVAL;
struct tcpudphdr
{
- uint16_t src;
- uint16_t dst;
+ __be16 src;
+ __be16 dst;
};
struct arppayload
unsigned char ip_dst[4];
};
-static void print_MAC(unsigned char *p)
+static void print_MAC(const unsigned char *p)
{
int i;
printk("%02x%c", *p, i == ETH_ALEN - 1 ? ' ':':');
}
+static void
+print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
+{
+ if (protocol == IPPROTO_TCP ||
+ protocol == IPPROTO_UDP ||
+ protocol == IPPROTO_UDPLITE ||
+ protocol == IPPROTO_SCTP ||
+ protocol == IPPROTO_DCCP) {
+ const struct tcpudphdr *pptr;
+ struct tcpudphdr _ports;
+
+ pptr = skb_header_pointer(skb, offset,
+ sizeof(_ports), &_ports);
+ if (pptr == NULL) {
+ printk(" INCOMPLETE TCP/UDP header");
+ return;
+ }
+ printk(" SPT=%u DPT=%u", ntohs(pptr->src), ntohs(pptr->dst));
+ }
+}
+
#define myNIPQUAD(a) a[0], a[1], a[2], a[3]
static void
ebt_log_packet(unsigned int pf, unsigned int hooknum,
if ((bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto ==
htons(ETH_P_IP)){
- struct iphdr _iph, *ih;
+ const struct iphdr *ih;
+ struct iphdr _iph;
ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
if (ih == NULL) {
printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP "
"tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr),
NIPQUAD(ih->daddr), ih->tos, ih->protocol);
- if (ih->protocol == IPPROTO_TCP ||
- ih->protocol == IPPROTO_UDP ||
- ih->protocol == IPPROTO_SCTP ||
- ih->protocol == IPPROTO_DCCP) {
- struct tcpudphdr _ports, *pptr;
-
- pptr = skb_header_pointer(skb, ih->ihl*4,
- sizeof(_ports), &_ports);
- if (pptr == NULL) {
- printk(" INCOMPLETE TCP/UDP header");
- goto out;
- }
- printk(" SPT=%u DPT=%u", ntohs(pptr->src),
- ntohs(pptr->dst));
+ print_ports(skb, ih->protocol, ih->ihl*4);
+ goto out;
+ }
+
+#if defined(CONFIG_BRIDGE_EBT_IP6) || defined(CONFIG_BRIDGE_EBT_IP6_MODULE)
+ if ((bitmask & EBT_LOG_IP6) && eth_hdr(skb)->h_proto ==
+ htons(ETH_P_IPV6)) {
+ const struct ipv6hdr *ih;
+ struct ipv6hdr _iph;
+ uint8_t nexthdr;
+ int offset_ph;
+
+ ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
+ if (ih == NULL) {
+ printk(" INCOMPLETE IPv6 header");
+ goto out;
}
+ printk(" IPv6 SRC=%x:%x:%x:%x:%x:%x:%x:%x "
+ "IPv6 DST=%x:%x:%x:%x:%x:%x:%x:%x, IPv6 "
+ "priority=0x%01X, Next Header=%d", NIP6(ih->saddr),
+ NIP6(ih->daddr), ih->priority, ih->nexthdr);
+ nexthdr = ih->nexthdr;
+ offset_ph = ipv6_skip_exthdr(skb, sizeof(_iph), &nexthdr);
+ if (offset_ph == -1)
+ goto out;
+ print_ports(skb, nexthdr, offset_ph);
goto out;
}
+#endif
if ((bitmask & EBT_LOG_ARP) &&
((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) ||
(eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) {
- struct arphdr _arph, *ah;
+ const struct arphdr *ah;
+ struct arphdr _arph;
ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
if (ah == NULL) {
* then log the ARP payload */
if (ah->ar_hrd == htons(1) &&
ah->ar_hln == ETH_ALEN &&
- ah->ar_pln == sizeof(uint32_t)) {
- struct arppayload _arpp, *ap;
+ ah->ar_pln == sizeof(__be32)) {
+ const struct arppayload *ap;
+ struct arppayload _arpp;
ap = skb_header_pointer(skb, sizeof(_arph),
sizeof(_arpp), &_arpp);
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
{
- struct ebt_log_info *info = (struct ebt_log_info *)data;
+ const struct ebt_log_info *info = data;
struct nf_loginfo li;
li.type = NF_LOG_TYPE_LOG;
if (info->bitmask & EBT_LOG_NFLOG)
nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li,
- "%s", info->prefix);
+ "%s", info->prefix);
else
ebt_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li,
- info->prefix);
+ info->prefix);
}
static struct ebt_watcher log =
.me = THIS_MODULE,
};
-static struct nf_logger ebt_log_logger = {
+static const struct nf_logger ebt_log_logger = {
.name = "ebt_log",
.logfn = &ebt_log_packet,
.me = THIS_MODULE,
ret = ebt_register_watcher(&log);
if (ret < 0)
return ret;
- if (nf_log_register(PF_BRIDGE, &ebt_log_logger) < 0) {
- printk(KERN_WARNING "ebt_log: not logging via system console "
- "since somebody else already registered for PF_INET\n");
- /* we cannot make module load fail here, since otherwise
- * ebtables userspace would abort */
- }
-
+ nf_log_register(PF_BRIDGE, &ebt_log_logger);
return 0;
}
static void __exit ebt_log_fini(void)
{
- nf_log_unregister_logger(&ebt_log_logger);
+ nf_log_unregister(&ebt_log_logger);
ebt_unregister_watcher(&log);
}
module_init(ebt_log_init);
module_exit(ebt_log_fini);
+MODULE_DESCRIPTION("Ebtables: Packet logging to syslog");
MODULE_LICENSE("GPL");