diff options
author | Harald Welte <laforge@netfilter.org> | 2005-08-09 22:58:27 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 18:38:07 -0400 |
commit | 608c8e4f7b6e61cc783283e9dff8a465a5ad59bb (patch) | |
tree | 55ca8bed99789cd6af07f6cc6ee99b0cf718a611 | |
parent | 838ab6364956d9bdcefe84712de1621cf20a40b3 (diff) |
[NETFILTER]: Extend netfilter logging API
This patch is in preparation to nfnetlink_log:
- loggers now have to register struct nf_logger instead of nf_logfn
- nf_log_unregister() replaced by nf_log_unregister_pf() and
nf_log_unregister_logger()
- add comment to ip[6]t_LOG.h to assure nobody redefines flags
- add /proc/net/netfilter/nf_log to tell user which logger is currently
registered for which address family
- if user has configured logging, but no logging backend (logger) is
available, always spit a message to syslog, not just the first time.
- split ip[6]t_LOG.c into two parts:
Backend: Always try to register as logger for the respective address family
Frontend: Always log via nf_log_packet() API
- modify all users of nf_log_packet() to accomodate additional argument
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/netfilter.h | 48 | ||||
-rw-r--r-- | include/linux/netfilter_ipv4/ipt_LOG.h | 1 | ||||
-rw-r--r-- | include/linux/netfilter_ipv6/ip6t_LOG.h | 1 | ||||
-rw-r--r-- | net/core/netfilter.c | 127 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_proto_icmp.c | 8 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_proto_tcp.c | 21 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_proto_udp.c | 6 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_LOG.c | 86 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_ULOG.c | 33 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_LOG.c | 93 |
10 files changed, 299 insertions, 125 deletions
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 711e05f33d68..815583af06c2 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h | |||
@@ -114,15 +114,51 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg); | |||
114 | 114 | ||
115 | extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS]; | 115 | extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS]; |
116 | 116 | ||
117 | typedef void nf_logfn(unsigned int hooknum, | 117 | /* those NF_LOG_* defines and struct nf_loginfo are legacy definitios that will |
118 | * disappear once iptables is replaced with pkttables. Please DO NOT use them | ||
119 | * for any new code! */ | ||
120 | #define NF_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */ | ||
121 | #define NF_LOG_TCPOPT 0x02 /* Log TCP options */ | ||
122 | #define NF_LOG_IPOPT 0x04 /* Log IP options */ | ||
123 | #define NF_LOG_UID 0x08 /* Log UID owning local socket */ | ||
124 | #define NF_LOG_MASK 0x0f | ||
125 | |||
126 | #define NF_LOG_TYPE_LOG 0x01 | ||
127 | #define NF_LOG_TYPE_ULOG 0x02 | ||
128 | |||
129 | struct nf_loginfo { | ||
130 | u_int8_t type; | ||
131 | union { | ||
132 | struct { | ||
133 | u_int32_t copy_len; | ||
134 | u_int16_t group; | ||
135 | u_int16_t qthreshold; | ||
136 | } ulog; | ||
137 | struct { | ||
138 | u_int8_t level; | ||
139 | u_int8_t logflags; | ||
140 | } log; | ||
141 | } u; | ||
142 | }; | ||
143 | |||
144 | typedef void nf_logfn(unsigned int pf, | ||
145 | unsigned int hooknum, | ||
118 | const struct sk_buff *skb, | 146 | const struct sk_buff *skb, |
119 | const struct net_device *in, | 147 | const struct net_device *in, |
120 | const struct net_device *out, | 148 | const struct net_device *out, |
149 | const struct nf_loginfo *li, | ||
121 | const char *prefix); | 150 | const char *prefix); |
122 | 151 | ||
152 | struct nf_logger { | ||
153 | struct module *me; | ||
154 | nf_logfn *logfn; | ||
155 | char *name; | ||
156 | }; | ||
157 | |||
123 | /* Function to register/unregister log function. */ | 158 | /* Function to register/unregister log function. */ |
124 | int nf_log_register(int pf, nf_logfn *logfn); | 159 | int nf_log_register(int pf, struct nf_logger *logger); |
125 | void nf_log_unregister(int pf, nf_logfn *logfn); | 160 | void nf_log_unregister_pf(int pf); |
161 | void nf_log_unregister_logger(struct nf_logger *logger); | ||
126 | 162 | ||
127 | /* Calls the registered backend logging function */ | 163 | /* Calls the registered backend logging function */ |
128 | void nf_log_packet(int pf, | 164 | void nf_log_packet(int pf, |
@@ -130,6 +166,7 @@ void nf_log_packet(int pf, | |||
130 | const struct sk_buff *skb, | 166 | const struct sk_buff *skb, |
131 | const struct net_device *in, | 167 | const struct net_device *in, |
132 | const struct net_device *out, | 168 | const struct net_device *out, |
169 | struct nf_loginfo *li, | ||
133 | const char *fmt, ...); | 170 | const char *fmt, ...); |
134 | 171 | ||
135 | /* Activate hook; either okfn or kfree_skb called, unless a hook | 172 | /* Activate hook; either okfn or kfree_skb called, unless a hook |
@@ -221,6 +258,11 @@ struct nf_queue_rerouter { | |||
221 | extern int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer); | 258 | extern int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer); |
222 | extern int nf_unregister_queue_rerouter(int pf); | 259 | extern int nf_unregister_queue_rerouter(int pf); |
223 | 260 | ||
261 | #ifdef CONFIG_PROC_FS | ||
262 | #include <linux/proc_fs.h> | ||
263 | extern struct proc_dir_entry *proc_net_netfilter; | ||
264 | #endif | ||
265 | |||
224 | #else /* !CONFIG_NETFILTER */ | 266 | #else /* !CONFIG_NETFILTER */ |
225 | #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) | 267 | #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) |
226 | static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} | 268 | static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} |
diff --git a/include/linux/netfilter_ipv4/ipt_LOG.h b/include/linux/netfilter_ipv4/ipt_LOG.h index d25f782e57d1..22d16177319b 100644 --- a/include/linux/netfilter_ipv4/ipt_LOG.h +++ b/include/linux/netfilter_ipv4/ipt_LOG.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef _IPT_LOG_H | 1 | #ifndef _IPT_LOG_H |
2 | #define _IPT_LOG_H | 2 | #define _IPT_LOG_H |
3 | 3 | ||
4 | /* make sure not to change this without changing netfilter.h:NF_LOG_* (!) */ | ||
4 | #define IPT_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */ | 5 | #define IPT_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */ |
5 | #define IPT_LOG_TCPOPT 0x02 /* Log TCP options */ | 6 | #define IPT_LOG_TCPOPT 0x02 /* Log TCP options */ |
6 | #define IPT_LOG_IPOPT 0x04 /* Log IP options */ | 7 | #define IPT_LOG_IPOPT 0x04 /* Log IP options */ |
diff --git a/include/linux/netfilter_ipv6/ip6t_LOG.h b/include/linux/netfilter_ipv6/ip6t_LOG.h index 42996a43bb39..9008ff5c40ae 100644 --- a/include/linux/netfilter_ipv6/ip6t_LOG.h +++ b/include/linux/netfilter_ipv6/ip6t_LOG.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef _IP6T_LOG_H | 1 | #ifndef _IP6T_LOG_H |
2 | #define _IP6T_LOG_H | 2 | #define _IP6T_LOG_H |
3 | 3 | ||
4 | /* make sure not to change this without changing netfilter.h:NF_LOG_* (!) */ | ||
4 | #define IP6T_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */ | 5 | #define IP6T_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */ |
5 | #define IP6T_LOG_TCPOPT 0x02 /* Log TCP options */ | 6 | #define IP6T_LOG_TCPOPT 0x02 /* Log TCP options */ |
6 | #define IP6T_LOG_IPOPT 0x04 /* Log IP options */ | 7 | #define IP6T_LOG_IPOPT 0x04 /* Log IP options */ |
diff --git a/net/core/netfilter.c b/net/core/netfilter.c index 3e38084ac2bd..98cc61e79fea 100644 --- a/net/core/netfilter.c +++ b/net/core/netfilter.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/if.h> | 22 | #include <linux/if.h> |
23 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
24 | #include <linux/inetdevice.h> | 24 | #include <linux/inetdevice.h> |
25 | #include <linux/proc_fs.h> | ||
25 | #include <net/sock.h> | 26 | #include <net/sock.h> |
26 | 27 | ||
27 | /* In this code, we can be waiting indefinitely for userspace to | 28 | /* In this code, we can be waiting indefinitely for userspace to |
@@ -535,11 +536,10 @@ EXPORT_SYMBOL(skb_make_writable); | |||
535 | 536 | ||
536 | #define NF_LOG_PREFIXLEN 128 | 537 | #define NF_LOG_PREFIXLEN 128 |
537 | 538 | ||
538 | static nf_logfn *nf_logging[NPROTO]; /* = NULL */ | 539 | static struct nf_logger *nf_logging[NPROTO]; /* = NULL */ |
539 | static int reported = 0; | ||
540 | static DEFINE_SPINLOCK(nf_log_lock); | 540 | static DEFINE_SPINLOCK(nf_log_lock); |
541 | 541 | ||
542 | int nf_log_register(int pf, nf_logfn *logfn) | 542 | int nf_log_register(int pf, struct nf_logger *logger) |
543 | { | 543 | { |
544 | int ret = -EBUSY; | 544 | int ret = -EBUSY; |
545 | 545 | ||
@@ -547,54 +547,134 @@ int nf_log_register(int pf, nf_logfn *logfn) | |||
547 | * substituting pointer. */ | 547 | * substituting pointer. */ |
548 | spin_lock(&nf_log_lock); | 548 | spin_lock(&nf_log_lock); |
549 | if (!nf_logging[pf]) { | 549 | if (!nf_logging[pf]) { |
550 | rcu_assign_pointer(nf_logging[pf], logfn); | 550 | rcu_assign_pointer(nf_logging[pf], logger); |
551 | ret = 0; | 551 | ret = 0; |
552 | } | 552 | } |
553 | spin_unlock(&nf_log_lock); | 553 | spin_unlock(&nf_log_lock); |
554 | return ret; | 554 | return ret; |
555 | } | 555 | } |
556 | 556 | ||
557 | void nf_log_unregister(int pf, nf_logfn *logfn) | 557 | void nf_log_unregister_pf(int pf) |
558 | { | 558 | { |
559 | spin_lock(&nf_log_lock); | 559 | spin_lock(&nf_log_lock); |
560 | if (nf_logging[pf] == logfn) | 560 | nf_logging[pf] = NULL; |
561 | nf_logging[pf] = NULL; | ||
562 | spin_unlock(&nf_log_lock); | 561 | spin_unlock(&nf_log_lock); |
563 | 562 | ||
564 | /* Give time to concurrent readers. */ | 563 | /* Give time to concurrent readers. */ |
565 | synchronize_net(); | 564 | synchronize_net(); |
566 | } | 565 | } |
566 | |||
567 | void nf_log_unregister_logger(struct nf_logger *logger) | ||
568 | { | ||
569 | int i; | ||
570 | |||
571 | spin_lock(&nf_log_lock); | ||
572 | for (i = 0; i < NPROTO; i++) { | ||
573 | if (nf_logging[i] == logger) | ||
574 | nf_logging[i] = NULL; | ||
575 | } | ||
576 | spin_unlock(&nf_log_lock); | ||
577 | |||
578 | synchronize_net(); | ||
579 | } | ||
567 | 580 | ||
568 | void nf_log_packet(int pf, | 581 | void nf_log_packet(int pf, |
569 | unsigned int hooknum, | 582 | unsigned int hooknum, |
570 | const struct sk_buff *skb, | 583 | const struct sk_buff *skb, |
571 | const struct net_device *in, | 584 | const struct net_device *in, |
572 | const struct net_device *out, | 585 | const struct net_device *out, |
586 | struct nf_loginfo *loginfo, | ||
573 | const char *fmt, ...) | 587 | const char *fmt, ...) |
574 | { | 588 | { |
575 | va_list args; | 589 | va_list args; |
576 | char prefix[NF_LOG_PREFIXLEN]; | 590 | char prefix[NF_LOG_PREFIXLEN]; |
577 | nf_logfn *logfn; | 591 | struct nf_logger *logger; |
578 | 592 | ||
579 | rcu_read_lock(); | 593 | rcu_read_lock(); |
580 | logfn = rcu_dereference(nf_logging[pf]); | 594 | logger = rcu_dereference(nf_logging[pf]); |
581 | if (logfn) { | 595 | if (logger) { |
582 | va_start(args, fmt); | 596 | va_start(args, fmt); |
583 | vsnprintf(prefix, sizeof(prefix), fmt, args); | 597 | vsnprintf(prefix, sizeof(prefix), fmt, args); |
584 | va_end(args); | 598 | va_end(args); |
585 | /* We must read logging before nf_logfn[pf] */ | 599 | /* We must read logging before nf_logfn[pf] */ |
586 | logfn(hooknum, skb, in, out, prefix); | 600 | logger->logfn(pf, hooknum, skb, in, out, loginfo, prefix); |
587 | } else if (!reported) { | 601 | } else if (net_ratelimit()) { |
588 | printk(KERN_WARNING "nf_log_packet: can\'t log yet, " | 602 | printk(KERN_WARNING "nf_log_packet: can\'t log since " |
589 | "no backend logging module loaded in!\n"); | 603 | "no backend logging module loaded in! Please either " |
590 | reported++; | 604 | "load one, or disable logging explicitly\n"); |
591 | } | 605 | } |
592 | rcu_read_unlock(); | 606 | rcu_read_unlock(); |
593 | } | 607 | } |
594 | EXPORT_SYMBOL(nf_log_register); | 608 | EXPORT_SYMBOL(nf_log_register); |
595 | EXPORT_SYMBOL(nf_log_unregister); | 609 | EXPORT_SYMBOL(nf_log_unregister_pf); |
610 | EXPORT_SYMBOL(nf_log_unregister_logger); | ||
596 | EXPORT_SYMBOL(nf_log_packet); | 611 | EXPORT_SYMBOL(nf_log_packet); |
597 | 612 | ||
613 | #ifdef CONFIG_PROC_FS | ||
614 | struct proc_dir_entry *proc_net_netfilter; | ||
615 | EXPORT_SYMBOL(proc_net_netfilter); | ||
616 | |||
617 | static void *seq_start(struct seq_file *seq, loff_t *pos) | ||
618 | { | ||
619 | rcu_read_lock(); | ||
620 | |||
621 | if (*pos >= NPROTO) | ||
622 | return NULL; | ||
623 | |||
624 | return pos; | ||
625 | } | ||
626 | |||
627 | static void *seq_next(struct seq_file *s, void *v, loff_t *pos) | ||
628 | { | ||
629 | (*pos)++; | ||
630 | |||
631 | if (*pos >= NPROTO) | ||
632 | return NULL; | ||
633 | |||
634 | return pos; | ||
635 | } | ||
636 | |||
637 | static void seq_stop(struct seq_file *s, void *v) | ||
638 | { | ||
639 | rcu_read_unlock(); | ||
640 | } | ||
641 | |||
642 | static int seq_show(struct seq_file *s, void *v) | ||
643 | { | ||
644 | loff_t *pos = v; | ||
645 | const struct nf_logger *logger; | ||
646 | |||
647 | logger = rcu_dereference(nf_logging[*pos]); | ||
648 | |||
649 | if (!logger) | ||
650 | return seq_printf(s, "%2lld NONE\n", *pos); | ||
651 | |||
652 | return seq_printf(s, "%2lld %s\n", *pos, logger->name); | ||
653 | } | ||
654 | |||
655 | static struct seq_operations nflog_seq_ops = { | ||
656 | .start = seq_start, | ||
657 | .next = seq_next, | ||
658 | .stop = seq_stop, | ||
659 | .show = seq_show, | ||
660 | }; | ||
661 | |||
662 | static int nflog_open(struct inode *inode, struct file *file) | ||
663 | { | ||
664 | return seq_open(file, &nflog_seq_ops); | ||
665 | } | ||
666 | |||
667 | static struct file_operations nflog_file_ops = { | ||
668 | .owner = THIS_MODULE, | ||
669 | .open = nflog_open, | ||
670 | .read = seq_read, | ||
671 | .llseek = seq_lseek, | ||
672 | .release = seq_release, | ||
673 | }; | ||
674 | |||
675 | #endif /* PROC_FS */ | ||
676 | |||
677 | |||
598 | /* This does not belong here, but locally generated errors need it if connection | 678 | /* This does not belong here, but locally generated errors need it if connection |
599 | tracking in use: without this, connection may not be in hash table, and hence | 679 | tracking in use: without this, connection may not be in hash table, and hence |
600 | manufactured ICMP or RST packets will not be associated with it. */ | 680 | manufactured ICMP or RST packets will not be associated with it. */ |
@@ -613,6 +693,9 @@ void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) | |||
613 | void __init netfilter_init(void) | 693 | void __init netfilter_init(void) |
614 | { | 694 | { |
615 | int i, h; | 695 | int i, h; |
696 | #ifdef CONFIG_PROC_FS | ||
697 | struct proc_dir_entry *pde; | ||
698 | #endif | ||
616 | 699 | ||
617 | queue_rerouter = kmalloc(NPROTO * sizeof(struct nf_queue_rerouter), | 700 | queue_rerouter = kmalloc(NPROTO * sizeof(struct nf_queue_rerouter), |
618 | GFP_KERNEL); | 701 | GFP_KERNEL); |
@@ -624,6 +707,16 @@ void __init netfilter_init(void) | |||
624 | for (h = 0; h < NF_MAX_HOOKS; h++) | 707 | for (h = 0; h < NF_MAX_HOOKS; h++) |
625 | INIT_LIST_HEAD(&nf_hooks[i][h]); | 708 | INIT_LIST_HEAD(&nf_hooks[i][h]); |
626 | } | 709 | } |
710 | |||
711 | #ifdef CONFIG_PROC_FS | ||
712 | proc_net_netfilter = proc_mkdir("netfilter", proc_net); | ||
713 | if (!proc_net_netfilter) | ||
714 | panic("cannot create netfilter proc entry"); | ||
715 | pde = create_proc_entry("nf_log", S_IRUGO, proc_net_netfilter); | ||
716 | if (!pde) | ||
717 | panic("cannot create /proc/net/netfilter/nf_log"); | ||
718 | pde->proc_fops = &nflog_file_ops; | ||
719 | #endif | ||
627 | } | 720 | } |
628 | 721 | ||
629 | EXPORT_SYMBOL(ip_ct_attach); | 722 | EXPORT_SYMBOL(ip_ct_attach); |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c index 3f90cb9979ac..838d1d69b36e 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c | |||
@@ -217,7 +217,7 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, | |||
217 | icmph = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_ih), &_ih); | 217 | icmph = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_ih), &_ih); |
218 | if (icmph == NULL) { | 218 | if (icmph == NULL) { |
219 | if (LOG_INVALID(IPPROTO_ICMP)) | 219 | if (LOG_INVALID(IPPROTO_ICMP)) |
220 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 220 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
221 | "ip_ct_icmp: short packet "); | 221 | "ip_ct_icmp: short packet "); |
222 | return -NF_ACCEPT; | 222 | return -NF_ACCEPT; |
223 | } | 223 | } |
@@ -231,13 +231,13 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, | |||
231 | if (!(u16)csum_fold(skb->csum)) | 231 | if (!(u16)csum_fold(skb->csum)) |
232 | break; | 232 | break; |
233 | if (LOG_INVALID(IPPROTO_ICMP)) | 233 | if (LOG_INVALID(IPPROTO_ICMP)) |
234 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 234 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
235 | "ip_ct_icmp: bad HW ICMP checksum "); | 235 | "ip_ct_icmp: bad HW ICMP checksum "); |
236 | return -NF_ACCEPT; | 236 | return -NF_ACCEPT; |
237 | case CHECKSUM_NONE: | 237 | case CHECKSUM_NONE: |
238 | if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) { | 238 | if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) { |
239 | if (LOG_INVALID(IPPROTO_ICMP)) | 239 | if (LOG_INVALID(IPPROTO_ICMP)) |
240 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 240 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
241 | "ip_ct_icmp: bad ICMP checksum "); | 241 | "ip_ct_icmp: bad ICMP checksum "); |
242 | return -NF_ACCEPT; | 242 | return -NF_ACCEPT; |
243 | } | 243 | } |
@@ -254,7 +254,7 @@ checksum_skipped: | |||
254 | */ | 254 | */ |
255 | if (icmph->type > NR_ICMP_TYPES) { | 255 | if (icmph->type > NR_ICMP_TYPES) { |
256 | if (LOG_INVALID(IPPROTO_ICMP)) | 256 | if (LOG_INVALID(IPPROTO_ICMP)) |
257 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 257 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
258 | "ip_ct_icmp: invalid ICMP type "); | 258 | "ip_ct_icmp: invalid ICMP type "); |
259 | return -NF_ACCEPT; | 259 | return -NF_ACCEPT; |
260 | } | 260 | } |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index c2bce22d4031..f23ef1f88c46 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c | |||
@@ -716,7 +716,7 @@ static int tcp_in_window(struct ip_ct_tcp *state, | |||
716 | res = 1; | 716 | res = 1; |
717 | } else { | 717 | } else { |
718 | if (LOG_INVALID(IPPROTO_TCP)) | 718 | if (LOG_INVALID(IPPROTO_TCP)) |
719 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 719 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
720 | "ip_ct_tcp: %s ", | 720 | "ip_ct_tcp: %s ", |
721 | before(seq, sender->td_maxend + 1) ? | 721 | before(seq, sender->td_maxend + 1) ? |
722 | after(end, sender->td_end - receiver->td_maxwin - 1) ? | 722 | after(end, sender->td_end - receiver->td_maxwin - 1) ? |
@@ -815,7 +815,7 @@ static int tcp_error(struct sk_buff *skb, | |||
815 | sizeof(_tcph), &_tcph); | 815 | sizeof(_tcph), &_tcph); |
816 | if (th == NULL) { | 816 | if (th == NULL) { |
817 | if (LOG_INVALID(IPPROTO_TCP)) | 817 | if (LOG_INVALID(IPPROTO_TCP)) |
818 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 818 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
819 | "ip_ct_tcp: short packet "); | 819 | "ip_ct_tcp: short packet "); |
820 | return -NF_ACCEPT; | 820 | return -NF_ACCEPT; |
821 | } | 821 | } |
@@ -823,7 +823,7 @@ static int tcp_error(struct sk_buff *skb, | |||
823 | /* Not whole TCP header or malformed packet */ | 823 | /* Not whole TCP header or malformed packet */ |
824 | if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) { | 824 | if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) { |
825 | if (LOG_INVALID(IPPROTO_TCP)) | 825 | if (LOG_INVALID(IPPROTO_TCP)) |
826 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 826 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
827 | "ip_ct_tcp: truncated/malformed packet "); | 827 | "ip_ct_tcp: truncated/malformed packet "); |
828 | return -NF_ACCEPT; | 828 | return -NF_ACCEPT; |
829 | } | 829 | } |
@@ -840,7 +840,7 @@ static int tcp_error(struct sk_buff *skb, | |||
840 | skb->ip_summed == CHECKSUM_HW ? skb->csum | 840 | skb->ip_summed == CHECKSUM_HW ? skb->csum |
841 | : skb_checksum(skb, iph->ihl*4, tcplen, 0))) { | 841 | : skb_checksum(skb, iph->ihl*4, tcplen, 0))) { |
842 | if (LOG_INVALID(IPPROTO_TCP)) | 842 | if (LOG_INVALID(IPPROTO_TCP)) |
843 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 843 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
844 | "ip_ct_tcp: bad TCP checksum "); | 844 | "ip_ct_tcp: bad TCP checksum "); |
845 | return -NF_ACCEPT; | 845 | return -NF_ACCEPT; |
846 | } | 846 | } |
@@ -849,7 +849,7 @@ static int tcp_error(struct sk_buff *skb, | |||
849 | tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR)); | 849 | tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR)); |
850 | if (!tcp_valid_flags[tcpflags]) { | 850 | if (!tcp_valid_flags[tcpflags]) { |
851 | if (LOG_INVALID(IPPROTO_TCP)) | 851 | if (LOG_INVALID(IPPROTO_TCP)) |
852 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 852 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
853 | "ip_ct_tcp: invalid TCP flag combination "); | 853 | "ip_ct_tcp: invalid TCP flag combination "); |
854 | return -NF_ACCEPT; | 854 | return -NF_ACCEPT; |
855 | } | 855 | } |
@@ -897,8 +897,9 @@ static int tcp_packet(struct ip_conntrack *conntrack, | |||
897 | */ | 897 | */ |
898 | write_unlock_bh(&tcp_lock); | 898 | write_unlock_bh(&tcp_lock); |
899 | if (LOG_INVALID(IPPROTO_TCP)) | 899 | if (LOG_INVALID(IPPROTO_TCP)) |
900 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 900 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, |
901 | "ip_ct_tcp: killing out of sync session "); | 901 | NULL, "ip_ct_tcp: " |
902 | "killing out of sync session "); | ||
902 | if (del_timer(&conntrack->timeout)) | 903 | if (del_timer(&conntrack->timeout)) |
903 | conntrack->timeout.function((unsigned long) | 904 | conntrack->timeout.function((unsigned long) |
904 | conntrack); | 905 | conntrack); |
@@ -912,7 +913,7 @@ static int tcp_packet(struct ip_conntrack *conntrack, | |||
912 | 913 | ||
913 | write_unlock_bh(&tcp_lock); | 914 | write_unlock_bh(&tcp_lock); |
914 | if (LOG_INVALID(IPPROTO_TCP)) | 915 | if (LOG_INVALID(IPPROTO_TCP)) |
915 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 916 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
916 | "ip_ct_tcp: invalid packet ignored "); | 917 | "ip_ct_tcp: invalid packet ignored "); |
917 | return NF_ACCEPT; | 918 | return NF_ACCEPT; |
918 | case TCP_CONNTRACK_MAX: | 919 | case TCP_CONNTRACK_MAX: |
@@ -922,7 +923,7 @@ static int tcp_packet(struct ip_conntrack *conntrack, | |||
922 | old_state); | 923 | old_state); |
923 | write_unlock_bh(&tcp_lock); | 924 | write_unlock_bh(&tcp_lock); |
924 | if (LOG_INVALID(IPPROTO_TCP)) | 925 | if (LOG_INVALID(IPPROTO_TCP)) |
925 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 926 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
926 | "ip_ct_tcp: invalid state "); | 927 | "ip_ct_tcp: invalid state "); |
927 | return -NF_ACCEPT; | 928 | return -NF_ACCEPT; |
928 | case TCP_CONNTRACK_SYN_SENT: | 929 | case TCP_CONNTRACK_SYN_SENT: |
@@ -943,7 +944,7 @@ static int tcp_packet(struct ip_conntrack *conntrack, | |||
943 | write_unlock_bh(&tcp_lock); | 944 | write_unlock_bh(&tcp_lock); |
944 | if (LOG_INVALID(IPPROTO_TCP)) | 945 | if (LOG_INVALID(IPPROTO_TCP)) |
945 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 946 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, |
946 | "ip_ct_tcp: invalid SYN"); | 947 | NULL, "ip_ct_tcp: invalid SYN"); |
947 | return -NF_ACCEPT; | 948 | return -NF_ACCEPT; |
948 | } | 949 | } |
949 | case TCP_CONNTRACK_CLOSE: | 950 | case TCP_CONNTRACK_CLOSE: |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c index 14130169cbfd..f2dcac7c7660 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c | |||
@@ -98,7 +98,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, | |||
98 | hdr = skb_header_pointer(skb, iph->ihl*4, sizeof(_hdr), &_hdr); | 98 | hdr = skb_header_pointer(skb, iph->ihl*4, sizeof(_hdr), &_hdr); |
99 | if (hdr == NULL) { | 99 | if (hdr == NULL) { |
100 | if (LOG_INVALID(IPPROTO_UDP)) | 100 | if (LOG_INVALID(IPPROTO_UDP)) |
101 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 101 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
102 | "ip_ct_udp: short packet "); | 102 | "ip_ct_udp: short packet "); |
103 | return -NF_ACCEPT; | 103 | return -NF_ACCEPT; |
104 | } | 104 | } |
@@ -106,7 +106,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, | |||
106 | /* Truncated/malformed packets */ | 106 | /* Truncated/malformed packets */ |
107 | if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) { | 107 | if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) { |
108 | if (LOG_INVALID(IPPROTO_UDP)) | 108 | if (LOG_INVALID(IPPROTO_UDP)) |
109 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 109 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
110 | "ip_ct_udp: truncated/malformed packet "); | 110 | "ip_ct_udp: truncated/malformed packet "); |
111 | return -NF_ACCEPT; | 111 | return -NF_ACCEPT; |
112 | } | 112 | } |
@@ -126,7 +126,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, | |||
126 | skb->ip_summed == CHECKSUM_HW ? skb->csum | 126 | skb->ip_summed == CHECKSUM_HW ? skb->csum |
127 | : skb_checksum(skb, iph->ihl*4, udplen, 0))) { | 127 | : skb_checksum(skb, iph->ihl*4, udplen, 0))) { |
128 | if (LOG_INVALID(IPPROTO_UDP)) | 128 | if (LOG_INVALID(IPPROTO_UDP)) |
129 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | 129 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
130 | "ip_ct_udp: bad UDP checksum "); | 130 | "ip_ct_udp: bad UDP checksum "); |
131 | return -NF_ACCEPT; | 131 | return -NF_ACCEPT; |
132 | } | 132 | } |
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index ef08733d26da..92ed050fac69 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c | |||
@@ -27,10 +27,6 @@ MODULE_LICENSE("GPL"); | |||
27 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | 27 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); |
28 | MODULE_DESCRIPTION("iptables syslog logging module"); | 28 | MODULE_DESCRIPTION("iptables syslog logging module"); |
29 | 29 | ||
30 | static unsigned int nflog = 1; | ||
31 | module_param(nflog, int, 0400); | ||
32 | MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); | ||
33 | |||
34 | #if 0 | 30 | #if 0 |
35 | #define DEBUGP printk | 31 | #define DEBUGP printk |
36 | #else | 32 | #else |
@@ -41,11 +37,17 @@ MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); | |||
41 | static DEFINE_SPINLOCK(log_lock); | 37 | static DEFINE_SPINLOCK(log_lock); |
42 | 38 | ||
43 | /* One level of recursion won't kill us */ | 39 | /* One level of recursion won't kill us */ |
44 | static void dump_packet(const struct ipt_log_info *info, | 40 | static void dump_packet(const struct nf_loginfo *info, |
45 | const struct sk_buff *skb, | 41 | const struct sk_buff *skb, |
46 | unsigned int iphoff) | 42 | unsigned int iphoff) |
47 | { | 43 | { |
48 | struct iphdr _iph, *ih; | 44 | struct iphdr _iph, *ih; |
45 | unsigned int logflags; | ||
46 | |||
47 | if (info->type == NF_LOG_TYPE_LOG) | ||
48 | logflags = info->u.log.logflags; | ||
49 | else | ||
50 | logflags = NF_LOG_MASK; | ||
49 | 51 | ||
50 | ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph); | 52 | ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph); |
51 | if (ih == NULL) { | 53 | if (ih == NULL) { |
@@ -76,7 +78,7 @@ static void dump_packet(const struct ipt_log_info *info, | |||
76 | if (ntohs(ih->frag_off) & IP_OFFSET) | 78 | if (ntohs(ih->frag_off) & IP_OFFSET) |
77 | printk("FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET); | 79 | printk("FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET); |
78 | 80 | ||
79 | if ((info->logflags & IPT_LOG_IPOPT) | 81 | if ((logflags & IPT_LOG_IPOPT) |
80 | && ih->ihl * 4 > sizeof(struct iphdr)) { | 82 | && ih->ihl * 4 > sizeof(struct iphdr)) { |
81 | unsigned char _opt[4 * 15 - sizeof(struct iphdr)], *op; | 83 | unsigned char _opt[4 * 15 - sizeof(struct iphdr)], *op; |
82 | unsigned int i, optsize; | 84 | unsigned int i, optsize; |
@@ -119,7 +121,7 @@ static void dump_packet(const struct ipt_log_info *info, | |||
119 | printk("SPT=%u DPT=%u ", | 121 | printk("SPT=%u DPT=%u ", |
120 | ntohs(th->source), ntohs(th->dest)); | 122 | ntohs(th->source), ntohs(th->dest)); |
121 | /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ | 123 | /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ |
122 | if (info->logflags & IPT_LOG_TCPSEQ) | 124 | if (logflags & IPT_LOG_TCPSEQ) |
123 | printk("SEQ=%u ACK=%u ", | 125 | printk("SEQ=%u ACK=%u ", |
124 | ntohl(th->seq), ntohl(th->ack_seq)); | 126 | ntohl(th->seq), ntohl(th->ack_seq)); |
125 | /* Max length: 13 "WINDOW=65535 " */ | 127 | /* Max length: 13 "WINDOW=65535 " */ |
@@ -146,7 +148,7 @@ static void dump_packet(const struct ipt_log_info *info, | |||
146 | /* Max length: 11 "URGP=65535 " */ | 148 | /* Max length: 11 "URGP=65535 " */ |
147 | printk("URGP=%u ", ntohs(th->urg_ptr)); | 149 | printk("URGP=%u ", ntohs(th->urg_ptr)); |
148 | 150 | ||
149 | if ((info->logflags & IPT_LOG_TCPOPT) | 151 | if ((logflags & IPT_LOG_TCPOPT) |
150 | && th->doff * 4 > sizeof(struct tcphdr)) { | 152 | && th->doff * 4 > sizeof(struct tcphdr)) { |
151 | unsigned char _opt[4 * 15 - sizeof(struct tcphdr)]; | 153 | unsigned char _opt[4 * 15 - sizeof(struct tcphdr)]; |
152 | unsigned char *op; | 154 | unsigned char *op; |
@@ -328,7 +330,7 @@ static void dump_packet(const struct ipt_log_info *info, | |||
328 | } | 330 | } |
329 | 331 | ||
330 | /* Max length: 15 "UID=4294967295 " */ | 332 | /* Max length: 15 "UID=4294967295 " */ |
331 | if ((info->logflags & IPT_LOG_UID) && !iphoff && skb->sk) { | 333 | if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) { |
332 | read_lock_bh(&skb->sk->sk_callback_lock); | 334 | read_lock_bh(&skb->sk->sk_callback_lock); |
333 | if (skb->sk->sk_socket && skb->sk->sk_socket->file) | 335 | if (skb->sk->sk_socket && skb->sk->sk_socket->file) |
334 | printk("UID=%u ", skb->sk->sk_socket->file->f_uid); | 336 | printk("UID=%u ", skb->sk->sk_socket->file->f_uid); |
@@ -349,19 +351,31 @@ static void dump_packet(const struct ipt_log_info *info, | |||
349 | /* maxlen = 230+ 91 + 230 + 252 = 803 */ | 351 | /* maxlen = 230+ 91 + 230 + 252 = 803 */ |
350 | } | 352 | } |
351 | 353 | ||
354 | struct nf_loginfo default_loginfo = { | ||
355 | .type = NF_LOG_TYPE_LOG, | ||
356 | .u = { | ||
357 | .log = { | ||
358 | .level = 0, | ||
359 | .logflags = NF_LOG_MASK, | ||
360 | }, | ||
361 | }, | ||
362 | }; | ||
363 | |||
352 | static void | 364 | static void |
353 | ipt_log_packet(unsigned int hooknum, | 365 | ipt_log_packet(unsigned int pf, |
366 | unsigned int hooknum, | ||
354 | const struct sk_buff *skb, | 367 | const struct sk_buff *skb, |
355 | const struct net_device *in, | 368 | const struct net_device *in, |
356 | const struct net_device *out, | 369 | const struct net_device *out, |
357 | const struct ipt_log_info *loginfo, | 370 | const struct nf_loginfo *loginfo, |
358 | const char *level_string, | ||
359 | const char *prefix) | 371 | const char *prefix) |
360 | { | 372 | { |
373 | if (!loginfo) | ||
374 | loginfo = &default_loginfo; | ||
375 | |||
361 | spin_lock_bh(&log_lock); | 376 | spin_lock_bh(&log_lock); |
362 | printk(level_string); | 377 | printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, |
363 | printk("%sIN=%s OUT=%s ", | 378 | prefix, |
364 | prefix == NULL ? loginfo->prefix : prefix, | ||
365 | in ? in->name : "", | 379 | in ? in->name : "", |
366 | out ? out->name : ""); | 380 | out ? out->name : ""); |
367 | #ifdef CONFIG_BRIDGE_NETFILTER | 381 | #ifdef CONFIG_BRIDGE_NETFILTER |
@@ -405,28 +419,15 @@ ipt_log_target(struct sk_buff **pskb, | |||
405 | void *userinfo) | 419 | void *userinfo) |
406 | { | 420 | { |
407 | const struct ipt_log_info *loginfo = targinfo; | 421 | const struct ipt_log_info *loginfo = targinfo; |
408 | char level_string[4] = "< >"; | 422 | struct nf_loginfo li; |
409 | 423 | ||
410 | level_string[1] = '0' + (loginfo->level % 8); | 424 | li.type = NF_LOG_TYPE_LOG; |
411 | ipt_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL); | 425 | li.u.log.level = loginfo->level; |
426 | li.u.log.logflags = loginfo->logflags; | ||
412 | 427 | ||
413 | return IPT_CONTINUE; | 428 | nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li, loginfo->prefix); |
414 | } | ||
415 | 429 | ||
416 | static void | 430 | return IPT_CONTINUE; |
417 | ipt_logfn(unsigned int hooknum, | ||
418 | const struct sk_buff *skb, | ||
419 | const struct net_device *in, | ||
420 | const struct net_device *out, | ||
421 | const char *prefix) | ||
422 | { | ||
423 | struct ipt_log_info loginfo = { | ||
424 | .level = 0, | ||
425 | .logflags = IPT_LOG_MASK, | ||
426 | .prefix = "" | ||
427 | }; | ||
428 | |||
429 | ipt_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix); | ||
430 | } | 431 | } |
431 | 432 | ||
432 | static int ipt_log_checkentry(const char *tablename, | 433 | static int ipt_log_checkentry(const char *tablename, |
@@ -464,20 +465,29 @@ static struct ipt_target ipt_log_reg = { | |||
464 | .me = THIS_MODULE, | 465 | .me = THIS_MODULE, |
465 | }; | 466 | }; |
466 | 467 | ||
468 | static struct nf_logger ipt_log_logger ={ | ||
469 | .name = "ipt_LOG", | ||
470 | .logfn = &ipt_log_packet, | ||
471 | .me = THIS_MODULE, | ||
472 | }; | ||
473 | |||
467 | static int __init init(void) | 474 | static int __init init(void) |
468 | { | 475 | { |
469 | if (ipt_register_target(&ipt_log_reg)) | 476 | if (ipt_register_target(&ipt_log_reg)) |
470 | return -EINVAL; | 477 | return -EINVAL; |
471 | if (nflog) | 478 | if (nf_log_register(PF_INET, &ipt_log_logger) < 0) { |
472 | nf_log_register(PF_INET, &ipt_logfn); | 479 | printk(KERN_WARNING "ipt_LOG: not logging via system console " |
480 | "since somebody else already registered for PF_INET\n"); | ||
481 | /* we cannot make module load fail here, since otherwise | ||
482 | * iptables userspace would abort */ | ||
483 | } | ||
473 | 484 | ||
474 | return 0; | 485 | return 0; |
475 | } | 486 | } |
476 | 487 | ||
477 | static void __exit fini(void) | 488 | static void __exit fini(void) |
478 | { | 489 | { |
479 | if (nflog) | 490 | nf_log_unregister_logger(&ipt_log_logger); |
480 | nf_log_unregister(PF_INET, &ipt_logfn); | ||
481 | ipt_unregister_target(&ipt_log_reg); | 491 | ipt_unregister_target(&ipt_log_reg); |
482 | } | 492 | } |
483 | 493 | ||
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 4ea8371ab270..b86f06ec9762 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
@@ -304,18 +304,27 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb, | |||
304 | return IPT_CONTINUE; | 304 | return IPT_CONTINUE; |
305 | } | 305 | } |
306 | 306 | ||
307 | static void ipt_logfn(unsigned int hooknum, | 307 | static void ipt_logfn(unsigned int pf, |
308 | unsigned int hooknum, | ||
308 | const struct sk_buff *skb, | 309 | const struct sk_buff *skb, |
309 | const struct net_device *in, | 310 | const struct net_device *in, |
310 | const struct net_device *out, | 311 | const struct net_device *out, |
312 | const struct nf_loginfo *li, | ||
311 | const char *prefix) | 313 | const char *prefix) |
312 | { | 314 | { |
313 | struct ipt_ulog_info loginfo = { | 315 | struct ipt_ulog_info loginfo; |
314 | .nl_group = ULOG_DEFAULT_NLGROUP, | 316 | |
315 | .copy_range = 0, | 317 | if (!li || li->type != NF_LOG_TYPE_ULOG) { |
316 | .qthreshold = ULOG_DEFAULT_QTHRESHOLD, | 318 | loginfo.nl_group = ULOG_DEFAULT_NLGROUP; |
317 | .prefix = "" | 319 | loginfo.copy_range = 0; |
318 | }; | 320 | loginfo.qthreshold = ULOG_DEFAULT_QTHRESHOLD; |
321 | loginfo.prefix[0] = '\0'; | ||
322 | } else { | ||
323 | loginfo.nl_group = li->u.ulog.group; | ||
324 | loginfo.copy_range = li->u.ulog.copy_len; | ||
325 | loginfo.qthreshold = li->u.ulog.qthreshold; | ||
326 | strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); | ||
327 | } | ||
319 | 328 | ||
320 | ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); | 329 | ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); |
321 | } | 330 | } |
@@ -355,6 +364,12 @@ static struct ipt_target ipt_ulog_reg = { | |||
355 | .me = THIS_MODULE, | 364 | .me = THIS_MODULE, |
356 | }; | 365 | }; |
357 | 366 | ||
367 | static struct nf_logger ipt_ulog_logger = { | ||
368 | .name = "ipt_ULOG", | ||
369 | .logfn = &ipt_logfn, | ||
370 | .me = THIS_MODULE, | ||
371 | }; | ||
372 | |||
358 | static int __init init(void) | 373 | static int __init init(void) |
359 | { | 374 | { |
360 | int i; | 375 | int i; |
@@ -382,7 +397,7 @@ static int __init init(void) | |||
382 | return -EINVAL; | 397 | return -EINVAL; |
383 | } | 398 | } |
384 | if (nflog) | 399 | if (nflog) |
385 | nf_log_register(PF_INET, &ipt_logfn); | 400 | nf_log_register(PF_INET, &ipt_ulog_logger); |
386 | 401 | ||
387 | return 0; | 402 | return 0; |
388 | } | 403 | } |
@@ -395,7 +410,7 @@ static void __exit fini(void) | |||
395 | DEBUGP("ipt_ULOG: cleanup_module\n"); | 410 | DEBUGP("ipt_ULOG: cleanup_module\n"); |
396 | 411 | ||
397 | if (nflog) | 412 | if (nflog) |
398 | nf_log_unregister(PF_INET, &ipt_logfn); | 413 | nf_log_unregister_logger(&ipt_ulog_logger); |
399 | ipt_unregister_target(&ipt_ulog_reg); | 414 | ipt_unregister_target(&ipt_ulog_reg); |
400 | sock_release(nflognl->sk_socket); | 415 | sock_release(nflognl->sk_socket); |
401 | 416 | ||
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index a692e26a4fa3..0cd1d1bd9033 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c | |||
@@ -26,10 +26,6 @@ MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>"); | |||
26 | MODULE_DESCRIPTION("IP6 tables LOG target module"); | 26 | MODULE_DESCRIPTION("IP6 tables LOG target module"); |
27 | MODULE_LICENSE("GPL"); | 27 | MODULE_LICENSE("GPL"); |
28 | 28 | ||
29 | static unsigned int nflog = 1; | ||
30 | module_param(nflog, int, 0400); | ||
31 | MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); | ||
32 | |||
33 | struct in_device; | 29 | struct in_device; |
34 | #include <net/route.h> | 30 | #include <net/route.h> |
35 | #include <linux/netfilter_ipv6/ip6t_LOG.h> | 31 | #include <linux/netfilter_ipv6/ip6t_LOG.h> |
@@ -44,7 +40,7 @@ struct in_device; | |||
44 | static DEFINE_SPINLOCK(log_lock); | 40 | static DEFINE_SPINLOCK(log_lock); |
45 | 41 | ||
46 | /* One level of recursion won't kill us */ | 42 | /* One level of recursion won't kill us */ |
47 | static void dump_packet(const struct ip6t_log_info *info, | 43 | static void dump_packet(const struct nf_loginfo *info, |
48 | const struct sk_buff *skb, unsigned int ip6hoff, | 44 | const struct sk_buff *skb, unsigned int ip6hoff, |
49 | int recurse) | 45 | int recurse) |
50 | { | 46 | { |
@@ -53,6 +49,12 @@ static void dump_packet(const struct ip6t_log_info *info, | |||
53 | struct ipv6hdr _ip6h, *ih; | 49 | struct ipv6hdr _ip6h, *ih; |
54 | unsigned int ptr; | 50 | unsigned int ptr; |
55 | unsigned int hdrlen = 0; | 51 | unsigned int hdrlen = 0; |
52 | unsigned int logflags; | ||
53 | |||
54 | if (info->type == NF_LOG_TYPE_LOG) | ||
55 | logflags = info->u.log.logflags; | ||
56 | else | ||
57 | logflags = NF_LOG_MASK; | ||
56 | 58 | ||
57 | ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h); | 59 | ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h); |
58 | if (ih == NULL) { | 60 | if (ih == NULL) { |
@@ -84,7 +86,7 @@ static void dump_packet(const struct ip6t_log_info *info, | |||
84 | } | 86 | } |
85 | 87 | ||
86 | /* Max length: 48 "OPT (...) " */ | 88 | /* Max length: 48 "OPT (...) " */ |
87 | if (info->logflags & IP6T_LOG_IPOPT) | 89 | if (logflags & IP6T_LOG_IPOPT) |
88 | printk("OPT ( "); | 90 | printk("OPT ( "); |
89 | 91 | ||
90 | switch (currenthdr) { | 92 | switch (currenthdr) { |
@@ -119,7 +121,7 @@ static void dump_packet(const struct ip6t_log_info *info, | |||
119 | case IPPROTO_ROUTING: | 121 | case IPPROTO_ROUTING: |
120 | case IPPROTO_HOPOPTS: | 122 | case IPPROTO_HOPOPTS: |
121 | if (fragment) { | 123 | if (fragment) { |
122 | if (info->logflags & IP6T_LOG_IPOPT) | 124 | if (logflags & IP6T_LOG_IPOPT) |
123 | printk(")"); | 125 | printk(")"); |
124 | return; | 126 | return; |
125 | } | 127 | } |
@@ -127,7 +129,7 @@ static void dump_packet(const struct ip6t_log_info *info, | |||
127 | break; | 129 | break; |
128 | /* Max Length */ | 130 | /* Max Length */ |
129 | case IPPROTO_AH: | 131 | case IPPROTO_AH: |
130 | if (info->logflags & IP6T_LOG_IPOPT) { | 132 | if (logflags & IP6T_LOG_IPOPT) { |
131 | struct ip_auth_hdr _ahdr, *ah; | 133 | struct ip_auth_hdr _ahdr, *ah; |
132 | 134 | ||
133 | /* Max length: 3 "AH " */ | 135 | /* Max length: 3 "AH " */ |
@@ -158,7 +160,7 @@ static void dump_packet(const struct ip6t_log_info *info, | |||
158 | hdrlen = (hp->hdrlen+2)<<2; | 160 | hdrlen = (hp->hdrlen+2)<<2; |
159 | break; | 161 | break; |
160 | case IPPROTO_ESP: | 162 | case IPPROTO_ESP: |
161 | if (info->logflags & IP6T_LOG_IPOPT) { | 163 | if (logflags & IP6T_LOG_IPOPT) { |
162 | struct ip_esp_hdr _esph, *eh; | 164 | struct ip_esp_hdr _esph, *eh; |
163 | 165 | ||
164 | /* Max length: 4 "ESP " */ | 166 | /* Max length: 4 "ESP " */ |
@@ -190,7 +192,7 @@ static void dump_packet(const struct ip6t_log_info *info, | |||
190 | printk("Unknown Ext Hdr %u", currenthdr); | 192 | printk("Unknown Ext Hdr %u", currenthdr); |
191 | return; | 193 | return; |
192 | } | 194 | } |
193 | if (info->logflags & IP6T_LOG_IPOPT) | 195 | if (logflags & IP6T_LOG_IPOPT) |
194 | printk(") "); | 196 | printk(") "); |
195 | 197 | ||
196 | currenthdr = hp->nexthdr; | 198 | currenthdr = hp->nexthdr; |
@@ -218,7 +220,7 @@ static void dump_packet(const struct ip6t_log_info *info, | |||
218 | printk("SPT=%u DPT=%u ", | 220 | printk("SPT=%u DPT=%u ", |
219 | ntohs(th->source), ntohs(th->dest)); | 221 | ntohs(th->source), ntohs(th->dest)); |
220 | /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ | 222 | /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ |
221 | if (info->logflags & IP6T_LOG_TCPSEQ) | 223 | if (logflags & IP6T_LOG_TCPSEQ) |
222 | printk("SEQ=%u ACK=%u ", | 224 | printk("SEQ=%u ACK=%u ", |
223 | ntohl(th->seq), ntohl(th->ack_seq)); | 225 | ntohl(th->seq), ntohl(th->ack_seq)); |
224 | /* Max length: 13 "WINDOW=65535 " */ | 226 | /* Max length: 13 "WINDOW=65535 " */ |
@@ -245,7 +247,7 @@ static void dump_packet(const struct ip6t_log_info *info, | |||
245 | /* Max length: 11 "URGP=65535 " */ | 247 | /* Max length: 11 "URGP=65535 " */ |
246 | printk("URGP=%u ", ntohs(th->urg_ptr)); | 248 | printk("URGP=%u ", ntohs(th->urg_ptr)); |
247 | 249 | ||
248 | if ((info->logflags & IP6T_LOG_TCPOPT) | 250 | if ((logflags & IP6T_LOG_TCPOPT) |
249 | && th->doff * 4 > sizeof(struct tcphdr)) { | 251 | && th->doff * 4 > sizeof(struct tcphdr)) { |
250 | u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; | 252 | u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; |
251 | unsigned int i; | 253 | unsigned int i; |
@@ -349,7 +351,7 @@ static void dump_packet(const struct ip6t_log_info *info, | |||
349 | } | 351 | } |
350 | 352 | ||
351 | /* Max length: 15 "UID=4294967295 " */ | 353 | /* Max length: 15 "UID=4294967295 " */ |
352 | if ((info->logflags & IP6T_LOG_UID) && recurse && skb->sk) { | 354 | if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) { |
353 | read_lock_bh(&skb->sk->sk_callback_lock); | 355 | read_lock_bh(&skb->sk->sk_callback_lock); |
354 | if (skb->sk->sk_socket && skb->sk->sk_socket->file) | 356 | if (skb->sk->sk_socket && skb->sk->sk_socket->file) |
355 | printk("UID=%u ", skb->sk->sk_socket->file->f_uid); | 357 | printk("UID=%u ", skb->sk->sk_socket->file->f_uid); |
@@ -357,19 +359,31 @@ static void dump_packet(const struct ip6t_log_info *info, | |||
357 | } | 359 | } |
358 | } | 360 | } |
359 | 361 | ||
362 | static struct nf_loginfo default_loginfo = { | ||
363 | .type = NF_LOG_TYPE_LOG, | ||
364 | .u = { | ||
365 | .log = { | ||
366 | .level = 0, | ||
367 | .logflags = NF_LOG_MASK, | ||
368 | }, | ||
369 | }, | ||
370 | }; | ||
371 | |||
360 | static void | 372 | static void |
361 | ip6t_log_packet(unsigned int hooknum, | 373 | ip6t_log_packet(unsigned int pf, |
374 | unsigned int hooknum, | ||
362 | const struct sk_buff *skb, | 375 | const struct sk_buff *skb, |
363 | const struct net_device *in, | 376 | const struct net_device *in, |
364 | const struct net_device *out, | 377 | const struct net_device *out, |
365 | const struct ip6t_log_info *loginfo, | 378 | const struct nf_loginfo *loginfo, |
366 | const char *level_string, | ||
367 | const char *prefix) | 379 | const char *prefix) |
368 | { | 380 | { |
381 | if (!loginfo) | ||
382 | loginfo = &default_loginfo; | ||
383 | |||
369 | spin_lock_bh(&log_lock); | 384 | spin_lock_bh(&log_lock); |
370 | printk(level_string); | 385 | printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, |
371 | printk("%sIN=%s OUT=%s ", | 386 | prefix, |
372 | prefix == NULL ? loginfo->prefix : prefix, | ||
373 | in ? in->name : "", | 387 | in ? in->name : "", |
374 | out ? out->name : ""); | 388 | out ? out->name : ""); |
375 | if (in && !out) { | 389 | if (in && !out) { |
@@ -416,29 +430,17 @@ ip6t_log_target(struct sk_buff **pskb, | |||
416 | void *userinfo) | 430 | void *userinfo) |
417 | { | 431 | { |
418 | const struct ip6t_log_info *loginfo = targinfo; | 432 | const struct ip6t_log_info *loginfo = targinfo; |
419 | char level_string[4] = "< >"; | 433 | struct nf_loginfo li; |
434 | |||
435 | li.type = NF_LOG_TYPE_LOG; | ||
436 | li.u.log.level = loginfo->level; | ||
437 | li.u.log.logflags = loginfo->logflags; | ||
420 | 438 | ||
421 | level_string[1] = '0' + (loginfo->level % 8); | 439 | nf_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, loginfo->prefix); |
422 | ip6t_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL); | ||
423 | 440 | ||
424 | return IP6T_CONTINUE; | 441 | return IP6T_CONTINUE; |
425 | } | 442 | } |
426 | 443 | ||
427 | static void | ||
428 | ip6t_logfn(unsigned int hooknum, | ||
429 | const struct sk_buff *skb, | ||
430 | const struct net_device *in, | ||
431 | const struct net_device *out, | ||
432 | const char *prefix) | ||
433 | { | ||
434 | struct ip6t_log_info loginfo = { | ||
435 | .level = 0, | ||
436 | .logflags = IP6T_LOG_MASK, | ||
437 | .prefix = "" | ||
438 | }; | ||
439 | |||
440 | ip6t_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix); | ||
441 | } | ||
442 | 444 | ||
443 | static int ip6t_log_checkentry(const char *tablename, | 445 | static int ip6t_log_checkentry(const char *tablename, |
444 | const struct ip6t_entry *e, | 446 | const struct ip6t_entry *e, |
@@ -475,20 +477,29 @@ static struct ip6t_target ip6t_log_reg = { | |||
475 | .me = THIS_MODULE, | 477 | .me = THIS_MODULE, |
476 | }; | 478 | }; |
477 | 479 | ||
480 | static struct nf_logger ip6t_logger = { | ||
481 | .name = "ip6t_LOG", | ||
482 | .logfn = &ip6t_log_packet, | ||
483 | .me = THIS_MODULE, | ||
484 | }; | ||
485 | |||
478 | static int __init init(void) | 486 | static int __init init(void) |
479 | { | 487 | { |
480 | if (ip6t_register_target(&ip6t_log_reg)) | 488 | if (ip6t_register_target(&ip6t_log_reg)) |
481 | return -EINVAL; | 489 | return -EINVAL; |
482 | if (nflog) | 490 | if (nf_log_register(PF_INET6, &ip6t_logger) < 0) { |
483 | nf_log_register(PF_INET6, &ip6t_logfn); | 491 | printk(KERN_WARNING "ip6t_LOG: not logging via system console " |
492 | "since somebody else already registered for PF_INET6\n"); | ||
493 | /* we cannot make module load fail here, since otherwise | ||
494 | * ip6tables userspace would abort */ | ||
495 | } | ||
484 | 496 | ||
485 | return 0; | 497 | return 0; |
486 | } | 498 | } |
487 | 499 | ||
488 | static void __exit fini(void) | 500 | static void __exit fini(void) |
489 | { | 501 | { |
490 | if (nflog) | 502 | nf_log_unregister_logger(&ip6t_logger); |
491 | nf_log_unregister(PF_INET6, &ip6t_logfn); | ||
492 | ip6t_unregister_target(&ip6t_log_reg); | 503 | ip6t_unregister_target(&ip6t_log_reg); |
493 | } | 504 | } |
494 | 505 | ||