diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-10-04 14:56:05 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-10-04 14:56:05 -0400 |
commit | a8defca048fd11eb2d1a17ab61a60a856292dd4e (patch) | |
tree | b486460fd1f2310cd4572bd36c126a3fa8b3a5c5 /net/ipv4 | |
parent | 0c200d935346fe0ebde9b6dffbb683dddd166fb9 (diff) |
netfilter: ipt_LOG: add bufferisation to call printk() once
ipt_LOG & ip6t_LOG use lot of calls to printk() and use a lock in a hope
several cpus wont mix their output in syslog.
printk() being very expensive [1], its better to call it once, on a
prebuilt and complete line. Also, with mixed IPv4 and IPv6 trafic,
separate IPv4/IPv6 locks dont avoid garbage.
I used an allocation of a 1024 bytes structure, sort of seq_printf() but
with a fixed size limit.
Use a static buffer if dynamic allocation failed.
Emit a once time alert if buffer size happens to be too short.
[1]: printk() has various features like printk_delay()...
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/ipt_LOG.c | 145 |
1 files changed, 73 insertions, 72 deletions
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 915fc17d7ce2..72ffc8fda2e9 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c | |||
@@ -24,16 +24,15 @@ | |||
24 | #include <linux/netfilter/x_tables.h> | 24 | #include <linux/netfilter/x_tables.h> |
25 | #include <linux/netfilter_ipv4/ipt_LOG.h> | 25 | #include <linux/netfilter_ipv4/ipt_LOG.h> |
26 | #include <net/netfilter/nf_log.h> | 26 | #include <net/netfilter/nf_log.h> |
27 | #include <net/netfilter/xt_log.h> | ||
27 | 28 | ||
28 | MODULE_LICENSE("GPL"); | 29 | MODULE_LICENSE("GPL"); |
29 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | 30 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); |
30 | MODULE_DESCRIPTION("Xtables: IPv4 packet logging to syslog"); | 31 | MODULE_DESCRIPTION("Xtables: IPv4 packet logging to syslog"); |
31 | 32 | ||
32 | /* Use lock to serialize, so printks don't overlap */ | ||
33 | static DEFINE_SPINLOCK(log_lock); | ||
34 | |||
35 | /* One level of recursion won't kill us */ | 33 | /* One level of recursion won't kill us */ |
36 | static void dump_packet(const struct nf_loginfo *info, | 34 | static void dump_packet(struct sbuff *m, |
35 | const struct nf_loginfo *info, | ||
37 | const struct sk_buff *skb, | 36 | const struct sk_buff *skb, |
38 | unsigned int iphoff) | 37 | unsigned int iphoff) |
39 | { | 38 | { |
@@ -48,32 +47,32 @@ static void dump_packet(const struct nf_loginfo *info, | |||
48 | 47 | ||
49 | ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph); | 48 | ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph); |
50 | if (ih == NULL) { | 49 | if (ih == NULL) { |
51 | printk("TRUNCATED"); | 50 | sb_add(m, "TRUNCATED"); |
52 | return; | 51 | return; |
53 | } | 52 | } |
54 | 53 | ||
55 | /* Important fields: | 54 | /* Important fields: |
56 | * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */ | 55 | * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */ |
57 | /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */ | 56 | /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */ |
58 | printk("SRC=%pI4 DST=%pI4 ", | 57 | sb_add(m, "SRC=%pI4 DST=%pI4 ", |
59 | &ih->saddr, &ih->daddr); | 58 | &ih->saddr, &ih->daddr); |
60 | 59 | ||
61 | /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */ | 60 | /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */ |
62 | printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ", | 61 | sb_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ", |
63 | ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK, | 62 | ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK, |
64 | ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id)); | 63 | ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id)); |
65 | 64 | ||
66 | /* Max length: 6 "CE DF MF " */ | 65 | /* Max length: 6 "CE DF MF " */ |
67 | if (ntohs(ih->frag_off) & IP_CE) | 66 | if (ntohs(ih->frag_off) & IP_CE) |
68 | printk("CE "); | 67 | sb_add(m, "CE "); |
69 | if (ntohs(ih->frag_off) & IP_DF) | 68 | if (ntohs(ih->frag_off) & IP_DF) |
70 | printk("DF "); | 69 | sb_add(m, "DF "); |
71 | if (ntohs(ih->frag_off) & IP_MF) | 70 | if (ntohs(ih->frag_off) & IP_MF) |
72 | printk("MF "); | 71 | sb_add(m, "MF "); |
73 | 72 | ||
74 | /* Max length: 11 "FRAG:65535 " */ | 73 | /* Max length: 11 "FRAG:65535 " */ |
75 | if (ntohs(ih->frag_off) & IP_OFFSET) | 74 | if (ntohs(ih->frag_off) & IP_OFFSET) |
76 | printk("FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET); | 75 | sb_add(m, "FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET); |
77 | 76 | ||
78 | if ((logflags & IPT_LOG_IPOPT) && | 77 | if ((logflags & IPT_LOG_IPOPT) && |
79 | ih->ihl * 4 > sizeof(struct iphdr)) { | 78 | ih->ihl * 4 > sizeof(struct iphdr)) { |
@@ -85,15 +84,15 @@ static void dump_packet(const struct nf_loginfo *info, | |||
85 | op = skb_header_pointer(skb, iphoff+sizeof(_iph), | 84 | op = skb_header_pointer(skb, iphoff+sizeof(_iph), |
86 | optsize, _opt); | 85 | optsize, _opt); |
87 | if (op == NULL) { | 86 | if (op == NULL) { |
88 | printk("TRUNCATED"); | 87 | sb_add(m, "TRUNCATED"); |
89 | return; | 88 | return; |
90 | } | 89 | } |
91 | 90 | ||
92 | /* Max length: 127 "OPT (" 15*4*2chars ") " */ | 91 | /* Max length: 127 "OPT (" 15*4*2chars ") " */ |
93 | printk("OPT ("); | 92 | sb_add(m, "OPT ("); |
94 | for (i = 0; i < optsize; i++) | 93 | for (i = 0; i < optsize; i++) |
95 | printk("%02X", op[i]); | 94 | sb_add(m, "%02X", op[i]); |
96 | printk(") "); | 95 | sb_add(m, ") "); |
97 | } | 96 | } |
98 | 97 | ||
99 | switch (ih->protocol) { | 98 | switch (ih->protocol) { |
@@ -102,7 +101,7 @@ static void dump_packet(const struct nf_loginfo *info, | |||
102 | const struct tcphdr *th; | 101 | const struct tcphdr *th; |
103 | 102 | ||
104 | /* Max length: 10 "PROTO=TCP " */ | 103 | /* Max length: 10 "PROTO=TCP " */ |
105 | printk("PROTO=TCP "); | 104 | sb_add(m, "PROTO=TCP "); |
106 | 105 | ||
107 | if (ntohs(ih->frag_off) & IP_OFFSET) | 106 | if (ntohs(ih->frag_off) & IP_OFFSET) |
108 | break; | 107 | break; |
@@ -111,41 +110,41 @@ static void dump_packet(const struct nf_loginfo *info, | |||
111 | th = skb_header_pointer(skb, iphoff + ih->ihl * 4, | 110 | th = skb_header_pointer(skb, iphoff + ih->ihl * 4, |
112 | sizeof(_tcph), &_tcph); | 111 | sizeof(_tcph), &_tcph); |
113 | if (th == NULL) { | 112 | if (th == NULL) { |
114 | printk("INCOMPLETE [%u bytes] ", | 113 | sb_add(m, "INCOMPLETE [%u bytes] ", |
115 | skb->len - iphoff - ih->ihl*4); | 114 | skb->len - iphoff - ih->ihl*4); |
116 | break; | 115 | break; |
117 | } | 116 | } |
118 | 117 | ||
119 | /* Max length: 20 "SPT=65535 DPT=65535 " */ | 118 | /* Max length: 20 "SPT=65535 DPT=65535 " */ |
120 | printk("SPT=%u DPT=%u ", | 119 | sb_add(m, "SPT=%u DPT=%u ", |
121 | ntohs(th->source), ntohs(th->dest)); | 120 | ntohs(th->source), ntohs(th->dest)); |
122 | /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ | 121 | /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ |
123 | if (logflags & IPT_LOG_TCPSEQ) | 122 | if (logflags & IPT_LOG_TCPSEQ) |
124 | printk("SEQ=%u ACK=%u ", | 123 | sb_add(m, "SEQ=%u ACK=%u ", |
125 | ntohl(th->seq), ntohl(th->ack_seq)); | 124 | ntohl(th->seq), ntohl(th->ack_seq)); |
126 | /* Max length: 13 "WINDOW=65535 " */ | 125 | /* Max length: 13 "WINDOW=65535 " */ |
127 | printk("WINDOW=%u ", ntohs(th->window)); | 126 | sb_add(m, "WINDOW=%u ", ntohs(th->window)); |
128 | /* Max length: 9 "RES=0x3F " */ | 127 | /* Max length: 9 "RES=0x3F " */ |
129 | printk("RES=0x%02x ", (u8)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); | 128 | sb_add(m, "RES=0x%02x ", (u8)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); |
130 | /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */ | 129 | /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */ |
131 | if (th->cwr) | 130 | if (th->cwr) |
132 | printk("CWR "); | 131 | sb_add(m, "CWR "); |
133 | if (th->ece) | 132 | if (th->ece) |
134 | printk("ECE "); | 133 | sb_add(m, "ECE "); |
135 | if (th->urg) | 134 | if (th->urg) |
136 | printk("URG "); | 135 | sb_add(m, "URG "); |
137 | if (th->ack) | 136 | if (th->ack) |
138 | printk("ACK "); | 137 | sb_add(m, "ACK "); |
139 | if (th->psh) | 138 | if (th->psh) |
140 | printk("PSH "); | 139 | sb_add(m, "PSH "); |
141 | if (th->rst) | 140 | if (th->rst) |
142 | printk("RST "); | 141 | sb_add(m, "RST "); |
143 | if (th->syn) | 142 | if (th->syn) |
144 | printk("SYN "); | 143 | sb_add(m, "SYN "); |
145 | if (th->fin) | 144 | if (th->fin) |
146 | printk("FIN "); | 145 | sb_add(m, "FIN "); |
147 | /* Max length: 11 "URGP=65535 " */ | 146 | /* Max length: 11 "URGP=65535 " */ |
148 | printk("URGP=%u ", ntohs(th->urg_ptr)); | 147 | sb_add(m, "URGP=%u ", ntohs(th->urg_ptr)); |
149 | 148 | ||
150 | if ((logflags & IPT_LOG_TCPOPT) && | 149 | if ((logflags & IPT_LOG_TCPOPT) && |
151 | th->doff * 4 > sizeof(struct tcphdr)) { | 150 | th->doff * 4 > sizeof(struct tcphdr)) { |
@@ -158,15 +157,15 @@ static void dump_packet(const struct nf_loginfo *info, | |||
158 | iphoff+ih->ihl*4+sizeof(_tcph), | 157 | iphoff+ih->ihl*4+sizeof(_tcph), |
159 | optsize, _opt); | 158 | optsize, _opt); |
160 | if (op == NULL) { | 159 | if (op == NULL) { |
161 | printk("TRUNCATED"); | 160 | sb_add(m, "TRUNCATED"); |
162 | return; | 161 | return; |
163 | } | 162 | } |
164 | 163 | ||
165 | /* Max length: 127 "OPT (" 15*4*2chars ") " */ | 164 | /* Max length: 127 "OPT (" 15*4*2chars ") " */ |
166 | printk("OPT ("); | 165 | sb_add(m, "OPT ("); |
167 | for (i = 0; i < optsize; i++) | 166 | for (i = 0; i < optsize; i++) |
168 | printk("%02X", op[i]); | 167 | sb_add(m, "%02X", op[i]); |
169 | printk(") "); | 168 | sb_add(m, ") "); |
170 | } | 169 | } |
171 | break; | 170 | break; |
172 | } | 171 | } |
@@ -177,9 +176,9 @@ static void dump_packet(const struct nf_loginfo *info, | |||
177 | 176 | ||
178 | if (ih->protocol == IPPROTO_UDP) | 177 | if (ih->protocol == IPPROTO_UDP) |
179 | /* Max length: 10 "PROTO=UDP " */ | 178 | /* Max length: 10 "PROTO=UDP " */ |
180 | printk("PROTO=UDP " ); | 179 | sb_add(m, "PROTO=UDP " ); |
181 | else /* Max length: 14 "PROTO=UDPLITE " */ | 180 | else /* Max length: 14 "PROTO=UDPLITE " */ |
182 | printk("PROTO=UDPLITE "); | 181 | sb_add(m, "PROTO=UDPLITE "); |
183 | 182 | ||
184 | if (ntohs(ih->frag_off) & IP_OFFSET) | 183 | if (ntohs(ih->frag_off) & IP_OFFSET) |
185 | break; | 184 | break; |
@@ -188,13 +187,13 @@ static void dump_packet(const struct nf_loginfo *info, | |||
188 | uh = skb_header_pointer(skb, iphoff+ih->ihl*4, | 187 | uh = skb_header_pointer(skb, iphoff+ih->ihl*4, |
189 | sizeof(_udph), &_udph); | 188 | sizeof(_udph), &_udph); |
190 | if (uh == NULL) { | 189 | if (uh == NULL) { |
191 | printk("INCOMPLETE [%u bytes] ", | 190 | sb_add(m, "INCOMPLETE [%u bytes] ", |
192 | skb->len - iphoff - ih->ihl*4); | 191 | skb->len - iphoff - ih->ihl*4); |
193 | break; | 192 | break; |
194 | } | 193 | } |
195 | 194 | ||
196 | /* Max length: 20 "SPT=65535 DPT=65535 " */ | 195 | /* Max length: 20 "SPT=65535 DPT=65535 " */ |
197 | printk("SPT=%u DPT=%u LEN=%u ", | 196 | sb_add(m, "SPT=%u DPT=%u LEN=%u ", |
198 | ntohs(uh->source), ntohs(uh->dest), | 197 | ntohs(uh->source), ntohs(uh->dest), |
199 | ntohs(uh->len)); | 198 | ntohs(uh->len)); |
200 | break; | 199 | break; |
@@ -221,7 +220,7 @@ static void dump_packet(const struct nf_loginfo *info, | |||
221 | [ICMP_ADDRESSREPLY] = 12 }; | 220 | [ICMP_ADDRESSREPLY] = 12 }; |
222 | 221 | ||
223 | /* Max length: 11 "PROTO=ICMP " */ | 222 | /* Max length: 11 "PROTO=ICMP " */ |
224 | printk("PROTO=ICMP "); | 223 | sb_add(m, "PROTO=ICMP "); |
225 | 224 | ||
226 | if (ntohs(ih->frag_off) & IP_OFFSET) | 225 | if (ntohs(ih->frag_off) & IP_OFFSET) |
227 | break; | 226 | break; |
@@ -230,19 +229,19 @@ static void dump_packet(const struct nf_loginfo *info, | |||
230 | ich = skb_header_pointer(skb, iphoff + ih->ihl * 4, | 229 | ich = skb_header_pointer(skb, iphoff + ih->ihl * 4, |
231 | sizeof(_icmph), &_icmph); | 230 | sizeof(_icmph), &_icmph); |
232 | if (ich == NULL) { | 231 | if (ich == NULL) { |
233 | printk("INCOMPLETE [%u bytes] ", | 232 | sb_add(m, "INCOMPLETE [%u bytes] ", |
234 | skb->len - iphoff - ih->ihl*4); | 233 | skb->len - iphoff - ih->ihl*4); |
235 | break; | 234 | break; |
236 | } | 235 | } |
237 | 236 | ||
238 | /* Max length: 18 "TYPE=255 CODE=255 " */ | 237 | /* Max length: 18 "TYPE=255 CODE=255 " */ |
239 | printk("TYPE=%u CODE=%u ", ich->type, ich->code); | 238 | sb_add(m, "TYPE=%u CODE=%u ", ich->type, ich->code); |
240 | 239 | ||
241 | /* Max length: 25 "INCOMPLETE [65535 bytes] " */ | 240 | /* Max length: 25 "INCOMPLETE [65535 bytes] " */ |
242 | if (ich->type <= NR_ICMP_TYPES && | 241 | if (ich->type <= NR_ICMP_TYPES && |
243 | required_len[ich->type] && | 242 | required_len[ich->type] && |
244 | skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) { | 243 | skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) { |
245 | printk("INCOMPLETE [%u bytes] ", | 244 | sb_add(m, "INCOMPLETE [%u bytes] ", |
246 | skb->len - iphoff - ih->ihl*4); | 245 | skb->len - iphoff - ih->ihl*4); |
247 | break; | 246 | break; |
248 | } | 247 | } |
@@ -251,35 +250,35 @@ static void dump_packet(const struct nf_loginfo *info, | |||
251 | case ICMP_ECHOREPLY: | 250 | case ICMP_ECHOREPLY: |
252 | case ICMP_ECHO: | 251 | case ICMP_ECHO: |
253 | /* Max length: 19 "ID=65535 SEQ=65535 " */ | 252 | /* Max length: 19 "ID=65535 SEQ=65535 " */ |
254 | printk("ID=%u SEQ=%u ", | 253 | sb_add(m, "ID=%u SEQ=%u ", |
255 | ntohs(ich->un.echo.id), | 254 | ntohs(ich->un.echo.id), |
256 | ntohs(ich->un.echo.sequence)); | 255 | ntohs(ich->un.echo.sequence)); |
257 | break; | 256 | break; |
258 | 257 | ||
259 | case ICMP_PARAMETERPROB: | 258 | case ICMP_PARAMETERPROB: |
260 | /* Max length: 14 "PARAMETER=255 " */ | 259 | /* Max length: 14 "PARAMETER=255 " */ |
261 | printk("PARAMETER=%u ", | 260 | sb_add(m, "PARAMETER=%u ", |
262 | ntohl(ich->un.gateway) >> 24); | 261 | ntohl(ich->un.gateway) >> 24); |
263 | break; | 262 | break; |
264 | case ICMP_REDIRECT: | 263 | case ICMP_REDIRECT: |
265 | /* Max length: 24 "GATEWAY=255.255.255.255 " */ | 264 | /* Max length: 24 "GATEWAY=255.255.255.255 " */ |
266 | printk("GATEWAY=%pI4 ", &ich->un.gateway); | 265 | sb_add(m, "GATEWAY=%pI4 ", &ich->un.gateway); |
267 | /* Fall through */ | 266 | /* Fall through */ |
268 | case ICMP_DEST_UNREACH: | 267 | case ICMP_DEST_UNREACH: |
269 | case ICMP_SOURCE_QUENCH: | 268 | case ICMP_SOURCE_QUENCH: |
270 | case ICMP_TIME_EXCEEDED: | 269 | case ICMP_TIME_EXCEEDED: |
271 | /* Max length: 3+maxlen */ | 270 | /* Max length: 3+maxlen */ |
272 | if (!iphoff) { /* Only recurse once. */ | 271 | if (!iphoff) { /* Only recurse once. */ |
273 | printk("["); | 272 | sb_add(m, "["); |
274 | dump_packet(info, skb, | 273 | dump_packet(m, info, skb, |
275 | iphoff + ih->ihl*4+sizeof(_icmph)); | 274 | iphoff + ih->ihl*4+sizeof(_icmph)); |
276 | printk("] "); | 275 | sb_add(m, "] "); |
277 | } | 276 | } |
278 | 277 | ||
279 | /* Max length: 10 "MTU=65535 " */ | 278 | /* Max length: 10 "MTU=65535 " */ |
280 | if (ich->type == ICMP_DEST_UNREACH && | 279 | if (ich->type == ICMP_DEST_UNREACH && |
281 | ich->code == ICMP_FRAG_NEEDED) | 280 | ich->code == ICMP_FRAG_NEEDED) |
282 | printk("MTU=%u ", ntohs(ich->un.frag.mtu)); | 281 | sb_add(m, "MTU=%u ", ntohs(ich->un.frag.mtu)); |
283 | } | 282 | } |
284 | break; | 283 | break; |
285 | } | 284 | } |
@@ -292,19 +291,19 @@ static void dump_packet(const struct nf_loginfo *info, | |||
292 | break; | 291 | break; |
293 | 292 | ||
294 | /* Max length: 9 "PROTO=AH " */ | 293 | /* Max length: 9 "PROTO=AH " */ |
295 | printk("PROTO=AH "); | 294 | sb_add(m, "PROTO=AH "); |
296 | 295 | ||
297 | /* Max length: 25 "INCOMPLETE [65535 bytes] " */ | 296 | /* Max length: 25 "INCOMPLETE [65535 bytes] " */ |
298 | ah = skb_header_pointer(skb, iphoff+ih->ihl*4, | 297 | ah = skb_header_pointer(skb, iphoff+ih->ihl*4, |
299 | sizeof(_ahdr), &_ahdr); | 298 | sizeof(_ahdr), &_ahdr); |
300 | if (ah == NULL) { | 299 | if (ah == NULL) { |
301 | printk("INCOMPLETE [%u bytes] ", | 300 | sb_add(m, "INCOMPLETE [%u bytes] ", |
302 | skb->len - iphoff - ih->ihl*4); | 301 | skb->len - iphoff - ih->ihl*4); |
303 | break; | 302 | break; |
304 | } | 303 | } |
305 | 304 | ||
306 | /* Length: 15 "SPI=0xF1234567 " */ | 305 | /* Length: 15 "SPI=0xF1234567 " */ |
307 | printk("SPI=0x%x ", ntohl(ah->spi)); | 306 | sb_add(m, "SPI=0x%x ", ntohl(ah->spi)); |
308 | break; | 307 | break; |
309 | } | 308 | } |
310 | case IPPROTO_ESP: { | 309 | case IPPROTO_ESP: { |
@@ -312,7 +311,7 @@ static void dump_packet(const struct nf_loginfo *info, | |||
312 | const struct ip_esp_hdr *eh; | 311 | const struct ip_esp_hdr *eh; |
313 | 312 | ||
314 | /* Max length: 10 "PROTO=ESP " */ | 313 | /* Max length: 10 "PROTO=ESP " */ |
315 | printk("PROTO=ESP "); | 314 | sb_add(m, "PROTO=ESP "); |
316 | 315 | ||
317 | if (ntohs(ih->frag_off) & IP_OFFSET) | 316 | if (ntohs(ih->frag_off) & IP_OFFSET) |
318 | break; | 317 | break; |
@@ -321,25 +320,25 @@ static void dump_packet(const struct nf_loginfo *info, | |||
321 | eh = skb_header_pointer(skb, iphoff+ih->ihl*4, | 320 | eh = skb_header_pointer(skb, iphoff+ih->ihl*4, |
322 | sizeof(_esph), &_esph); | 321 | sizeof(_esph), &_esph); |
323 | if (eh == NULL) { | 322 | if (eh == NULL) { |
324 | printk("INCOMPLETE [%u bytes] ", | 323 | sb_add(m, "INCOMPLETE [%u bytes] ", |
325 | skb->len - iphoff - ih->ihl*4); | 324 | skb->len - iphoff - ih->ihl*4); |
326 | break; | 325 | break; |
327 | } | 326 | } |
328 | 327 | ||
329 | /* Length: 15 "SPI=0xF1234567 " */ | 328 | /* Length: 15 "SPI=0xF1234567 " */ |
330 | printk("SPI=0x%x ", ntohl(eh->spi)); | 329 | sb_add(m, "SPI=0x%x ", ntohl(eh->spi)); |
331 | break; | 330 | break; |
332 | } | 331 | } |
333 | /* Max length: 10 "PROTO 255 " */ | 332 | /* Max length: 10 "PROTO 255 " */ |
334 | default: | 333 | default: |
335 | printk("PROTO=%u ", ih->protocol); | 334 | sb_add(m, "PROTO=%u ", ih->protocol); |
336 | } | 335 | } |
337 | 336 | ||
338 | /* Max length: 15 "UID=4294967295 " */ | 337 | /* Max length: 15 "UID=4294967295 " */ |
339 | if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) { | 338 | if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) { |
340 | read_lock_bh(&skb->sk->sk_callback_lock); | 339 | read_lock_bh(&skb->sk->sk_callback_lock); |
341 | if (skb->sk->sk_socket && skb->sk->sk_socket->file) | 340 | if (skb->sk->sk_socket && skb->sk->sk_socket->file) |
342 | printk("UID=%u GID=%u ", | 341 | sb_add(m, "UID=%u GID=%u ", |
343 | skb->sk->sk_socket->file->f_cred->fsuid, | 342 | skb->sk->sk_socket->file->f_cred->fsuid, |
344 | skb->sk->sk_socket->file->f_cred->fsgid); | 343 | skb->sk->sk_socket->file->f_cred->fsgid); |
345 | read_unlock_bh(&skb->sk->sk_callback_lock); | 344 | read_unlock_bh(&skb->sk->sk_callback_lock); |
@@ -347,7 +346,7 @@ static void dump_packet(const struct nf_loginfo *info, | |||
347 | 346 | ||
348 | /* Max length: 16 "MARK=0xFFFFFFFF " */ | 347 | /* Max length: 16 "MARK=0xFFFFFFFF " */ |
349 | if (!iphoff && skb->mark) | 348 | if (!iphoff && skb->mark) |
350 | printk("MARK=0x%x ", skb->mark); | 349 | sb_add(m, "MARK=0x%x ", skb->mark); |
351 | 350 | ||
352 | /* Proto Max log string length */ | 351 | /* Proto Max log string length */ |
353 | /* IP: 40+46+6+11+127 = 230 */ | 352 | /* IP: 40+46+6+11+127 = 230 */ |
@@ -364,7 +363,8 @@ static void dump_packet(const struct nf_loginfo *info, | |||
364 | /* maxlen = 230+ 91 + 230 + 252 = 803 */ | 363 | /* maxlen = 230+ 91 + 230 + 252 = 803 */ |
365 | } | 364 | } |
366 | 365 | ||
367 | static void dump_mac_header(const struct nf_loginfo *info, | 366 | static void dump_mac_header(struct sbuff *m, |
367 | const struct nf_loginfo *info, | ||
368 | const struct sk_buff *skb) | 368 | const struct sk_buff *skb) |
369 | { | 369 | { |
370 | struct net_device *dev = skb->dev; | 370 | struct net_device *dev = skb->dev; |
@@ -378,7 +378,7 @@ static void dump_mac_header(const struct nf_loginfo *info, | |||
378 | 378 | ||
379 | switch (dev->type) { | 379 | switch (dev->type) { |
380 | case ARPHRD_ETHER: | 380 | case ARPHRD_ETHER: |
381 | printk("MACSRC=%pM MACDST=%pM MACPROTO=%04x ", | 381 | sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ", |
382 | eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, | 382 | eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, |
383 | ntohs(eth_hdr(skb)->h_proto)); | 383 | ntohs(eth_hdr(skb)->h_proto)); |
384 | return; | 384 | return; |
@@ -387,17 +387,17 @@ static void dump_mac_header(const struct nf_loginfo *info, | |||
387 | } | 387 | } |
388 | 388 | ||
389 | fallback: | 389 | fallback: |
390 | printk("MAC="); | 390 | sb_add(m, "MAC="); |
391 | if (dev->hard_header_len && | 391 | if (dev->hard_header_len && |
392 | skb->mac_header != skb->network_header) { | 392 | skb->mac_header != skb->network_header) { |
393 | const unsigned char *p = skb_mac_header(skb); | 393 | const unsigned char *p = skb_mac_header(skb); |
394 | unsigned int i; | 394 | unsigned int i; |
395 | 395 | ||
396 | printk("%02x", *p++); | 396 | sb_add(m, "%02x", *p++); |
397 | for (i = 1; i < dev->hard_header_len; i++, p++) | 397 | for (i = 1; i < dev->hard_header_len; i++, p++) |
398 | printk(":%02x", *p); | 398 | sb_add(m, ":%02x", *p); |
399 | } | 399 | } |
400 | printk(" "); | 400 | sb_add(m, " "); |
401 | } | 401 | } |
402 | 402 | ||
403 | static struct nf_loginfo default_loginfo = { | 403 | static struct nf_loginfo default_loginfo = { |
@@ -419,11 +419,12 @@ ipt_log_packet(u_int8_t pf, | |||
419 | const struct nf_loginfo *loginfo, | 419 | const struct nf_loginfo *loginfo, |
420 | const char *prefix) | 420 | const char *prefix) |
421 | { | 421 | { |
422 | struct sbuff *m = sb_open(); | ||
423 | |||
422 | if (!loginfo) | 424 | if (!loginfo) |
423 | loginfo = &default_loginfo; | 425 | loginfo = &default_loginfo; |
424 | 426 | ||
425 | spin_lock_bh(&log_lock); | 427 | sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, |
426 | printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, | ||
427 | prefix, | 428 | prefix, |
428 | in ? in->name : "", | 429 | in ? in->name : "", |
429 | out ? out->name : ""); | 430 | out ? out->name : ""); |
@@ -434,20 +435,20 @@ ipt_log_packet(u_int8_t pf, | |||
434 | 435 | ||
435 | physindev = skb->nf_bridge->physindev; | 436 | physindev = skb->nf_bridge->physindev; |
436 | if (physindev && in != physindev) | 437 | if (physindev && in != physindev) |
437 | printk("PHYSIN=%s ", physindev->name); | 438 | sb_add(m, "PHYSIN=%s ", physindev->name); |
438 | physoutdev = skb->nf_bridge->physoutdev; | 439 | physoutdev = skb->nf_bridge->physoutdev; |
439 | if (physoutdev && out != physoutdev) | 440 | if (physoutdev && out != physoutdev) |
440 | printk("PHYSOUT=%s ", physoutdev->name); | 441 | sb_add(m, "PHYSOUT=%s ", physoutdev->name); |
441 | } | 442 | } |
442 | #endif | 443 | #endif |
443 | 444 | ||
444 | /* MAC logging for input path only. */ | 445 | /* MAC logging for input path only. */ |
445 | if (in && !out) | 446 | if (in && !out) |
446 | dump_mac_header(loginfo, skb); | 447 | dump_mac_header(m, loginfo, skb); |
448 | |||
449 | dump_packet(m, loginfo, skb, 0); | ||
447 | 450 | ||
448 | dump_packet(loginfo, skb, 0); | 451 | sb_close(m); |
449 | printk("\n"); | ||
450 | spin_unlock_bh(&log_lock); | ||
451 | } | 452 | } |
452 | 453 | ||
453 | static unsigned int | 454 | static unsigned int |