OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [net/] [ipv6/] [netfilter/] [ip6t_LOG.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * This is a module which is used for logging packets.
3
 */
4
 
5
/* (C) 2001 Jan Rekorajski <baggins@pld.org.pl>
6
 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License version 2 as
10
 * published by the Free Software Foundation.
11
 */
12
 
13
#include <linux/module.h>
14
#include <linux/moduleparam.h>
15
#include <linux/skbuff.h>
16
#include <linux/if_arp.h>
17
#include <linux/ip.h>
18
#include <linux/spinlock.h>
19
#include <linux/icmpv6.h>
20
#include <net/udp.h>
21
#include <net/tcp.h>
22
#include <net/ipv6.h>
23
#include <linux/netfilter.h>
24
#include <linux/netfilter/x_tables.h>
25
#include <linux/netfilter_ipv6/ip6_tables.h>
26
 
27
MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
28
MODULE_DESCRIPTION("IP6 tables LOG target module");
29
MODULE_LICENSE("GPL");
30
 
31
struct in_device;
32
#include <net/route.h>
33
#include <linux/netfilter_ipv6/ip6t_LOG.h>
34
 
35
/* Use lock to serialize, so printks don't overlap */
36
static DEFINE_SPINLOCK(log_lock);
37
 
38
/* One level of recursion won't kill us */
39
static void dump_packet(const struct nf_loginfo *info,
40
                        const struct sk_buff *skb, unsigned int ip6hoff,
41
                        int recurse)
42
{
43
        u_int8_t currenthdr;
44
        int fragment;
45
        struct ipv6hdr _ip6h;
46
        const struct ipv6hdr *ih;
47
        unsigned int ptr;
48
        unsigned int hdrlen = 0;
49
        unsigned int logflags;
50
 
51
        if (info->type == NF_LOG_TYPE_LOG)
52
                logflags = info->u.log.logflags;
53
        else
54
                logflags = NF_LOG_MASK;
55
 
56
        ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h);
57
        if (ih == NULL) {
58
                printk("TRUNCATED");
59
                return;
60
        }
61
 
62
        /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */
63
        printk("SRC=" NIP6_FMT " DST=" NIP6_FMT " ", NIP6(ih->saddr), NIP6(ih->daddr));
64
 
65
        /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
66
        printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
67
               ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
68
               (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
69
               ih->hop_limit,
70
               (ntohl(*(__be32 *)ih) & 0x000fffff));
71
 
72
        fragment = 0;
73
        ptr = ip6hoff + sizeof(struct ipv6hdr);
74
        currenthdr = ih->nexthdr;
75
        while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) {
76
                struct ipv6_opt_hdr _hdr;
77
                const struct ipv6_opt_hdr *hp;
78
 
79
                hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
80
                if (hp == NULL) {
81
                        printk("TRUNCATED");
82
                        return;
83
                }
84
 
85
                /* Max length: 48 "OPT (...) " */
86
                if (logflags & IP6T_LOG_IPOPT)
87
                        printk("OPT ( ");
88
 
89
                switch (currenthdr) {
90
                case IPPROTO_FRAGMENT: {
91
                        struct frag_hdr _fhdr;
92
                        const struct frag_hdr *fh;
93
 
94
                        printk("FRAG:");
95
                        fh = skb_header_pointer(skb, ptr, sizeof(_fhdr),
96
                                                &_fhdr);
97
                        if (fh == NULL) {
98
                                printk("TRUNCATED ");
99
                                return;
100
                        }
101
 
102
                        /* Max length: 6 "65535 " */
103
                        printk("%u ", ntohs(fh->frag_off) & 0xFFF8);
104
 
105
                        /* Max length: 11 "INCOMPLETE " */
106
                        if (fh->frag_off & htons(0x0001))
107
                                printk("INCOMPLETE ");
108
 
109
                        printk("ID:%08x ", ntohl(fh->identification));
110
 
111
                        if (ntohs(fh->frag_off) & 0xFFF8)
112
                                fragment = 1;
113
 
114
                        hdrlen = 8;
115
 
116
                        break;
117
                }
118
                case IPPROTO_DSTOPTS:
119
                case IPPROTO_ROUTING:
120
                case IPPROTO_HOPOPTS:
121
                        if (fragment) {
122
                                if (logflags & IP6T_LOG_IPOPT)
123
                                        printk(")");
124
                                return;
125
                        }
126
                        hdrlen = ipv6_optlen(hp);
127
                        break;
128
                /* Max Length */
129
                case IPPROTO_AH:
130
                        if (logflags & IP6T_LOG_IPOPT) {
131
                                struct ip_auth_hdr _ahdr;
132
                                const struct ip_auth_hdr *ah;
133
 
134
                                /* Max length: 3 "AH " */
135
                                printk("AH ");
136
 
137
                                if (fragment) {
138
                                        printk(")");
139
                                        return;
140
                                }
141
 
142
                                ah = skb_header_pointer(skb, ptr, sizeof(_ahdr),
143
                                                        &_ahdr);
144
                                if (ah == NULL) {
145
                                        /*
146
                                         * Max length: 26 "INCOMPLETE [65535
147
                                         *  bytes] )"
148
                                         */
149
                                        printk("INCOMPLETE [%u bytes] )",
150
                                               skb->len - ptr);
151
                                        return;
152
                                }
153
 
154
                                /* Length: 15 "SPI=0xF1234567 */
155
                                printk("SPI=0x%x ", ntohl(ah->spi));
156
 
157
                        }
158
 
159
                        hdrlen = (hp->hdrlen+2)<<2;
160
                        break;
161
                case IPPROTO_ESP:
162
                        if (logflags & IP6T_LOG_IPOPT) {
163
                                struct ip_esp_hdr _esph;
164
                                const struct ip_esp_hdr *eh;
165
 
166
                                /* Max length: 4 "ESP " */
167
                                printk("ESP ");
168
 
169
                                if (fragment) {
170
                                        printk(")");
171
                                        return;
172
                                }
173
 
174
                                /*
175
                                 * Max length: 26 "INCOMPLETE [65535 bytes] )"
176
                                 */
177
                                eh = skb_header_pointer(skb, ptr, sizeof(_esph),
178
                                                        &_esph);
179
                                if (eh == NULL) {
180
                                        printk("INCOMPLETE [%u bytes] )",
181
                                               skb->len - ptr);
182
                                        return;
183
                                }
184
 
185
                                /* Length: 16 "SPI=0xF1234567 )" */
186
                                printk("SPI=0x%x )", ntohl(eh->spi) );
187
 
188
                        }
189
                        return;
190
                default:
191
                        /* Max length: 20 "Unknown Ext Hdr 255" */
192
                        printk("Unknown Ext Hdr %u", currenthdr);
193
                        return;
194
                }
195
                if (logflags & IP6T_LOG_IPOPT)
196
                        printk(") ");
197
 
198
                currenthdr = hp->nexthdr;
199
                ptr += hdrlen;
200
        }
201
 
202
        switch (currenthdr) {
203
        case IPPROTO_TCP: {
204
                struct tcphdr _tcph;
205
                const struct tcphdr *th;
206
 
207
                /* Max length: 10 "PROTO=TCP " */
208
                printk("PROTO=TCP ");
209
 
210
                if (fragment)
211
                        break;
212
 
213
                /* Max length: 25 "INCOMPLETE [65535 bytes] " */
214
                th = skb_header_pointer(skb, ptr, sizeof(_tcph), &_tcph);
215
                if (th == NULL) {
216
                        printk("INCOMPLETE [%u bytes] ", skb->len - ptr);
217
                        return;
218
                }
219
 
220
                /* Max length: 20 "SPT=65535 DPT=65535 " */
221
                printk("SPT=%u DPT=%u ",
222
                       ntohs(th->source), ntohs(th->dest));
223
                /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
224
                if (logflags & IP6T_LOG_TCPSEQ)
225
                        printk("SEQ=%u ACK=%u ",
226
                               ntohl(th->seq), ntohl(th->ack_seq));
227
                /* Max length: 13 "WINDOW=65535 " */
228
                printk("WINDOW=%u ", ntohs(th->window));
229
                /* Max length: 9 "RES=0x3C " */
230
                printk("RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22));
231
                /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
232
                if (th->cwr)
233
                        printk("CWR ");
234
                if (th->ece)
235
                        printk("ECE ");
236
                if (th->urg)
237
                        printk("URG ");
238
                if (th->ack)
239
                        printk("ACK ");
240
                if (th->psh)
241
                        printk("PSH ");
242
                if (th->rst)
243
                        printk("RST ");
244
                if (th->syn)
245
                        printk("SYN ");
246
                if (th->fin)
247
                        printk("FIN ");
248
                /* Max length: 11 "URGP=65535 " */
249
                printk("URGP=%u ", ntohs(th->urg_ptr));
250
 
251
                if ((logflags & IP6T_LOG_TCPOPT)
252
                    && th->doff * 4 > sizeof(struct tcphdr)) {
253
                        u_int8_t _opt[60 - sizeof(struct tcphdr)];
254
                        const u_int8_t *op;
255
                        unsigned int i;
256
                        unsigned int optsize = th->doff * 4
257
                                               - sizeof(struct tcphdr);
258
 
259
                        op = skb_header_pointer(skb,
260
                                                ptr + sizeof(struct tcphdr),
261
                                                optsize, _opt);
262
                        if (op == NULL) {
263
                                printk("OPT (TRUNCATED)");
264
                                return;
265
                        }
266
 
267
                        /* Max length: 127 "OPT (" 15*4*2chars ") " */
268
                        printk("OPT (");
269
                        for (i =0; i < optsize; i++)
270
                                printk("%02X", op[i]);
271
                        printk(") ");
272
                }
273
                break;
274
        }
275
        case IPPROTO_UDP:
276
        case IPPROTO_UDPLITE: {
277
                struct udphdr _udph;
278
                const struct udphdr *uh;
279
 
280
                if (currenthdr == IPPROTO_UDP)
281
                        /* Max length: 10 "PROTO=UDP "     */
282
                        printk("PROTO=UDP " );
283
                else    /* Max length: 14 "PROTO=UDPLITE " */
284
                        printk("PROTO=UDPLITE ");
285
 
286
                if (fragment)
287
                        break;
288
 
289
                /* Max length: 25 "INCOMPLETE [65535 bytes] " */
290
                uh = skb_header_pointer(skb, ptr, sizeof(_udph), &_udph);
291
                if (uh == NULL) {
292
                        printk("INCOMPLETE [%u bytes] ", skb->len - ptr);
293
                        return;
294
                }
295
 
296
                /* Max length: 20 "SPT=65535 DPT=65535 " */
297
                printk("SPT=%u DPT=%u LEN=%u ",
298
                       ntohs(uh->source), ntohs(uh->dest),
299
                       ntohs(uh->len));
300
                break;
301
        }
302
        case IPPROTO_ICMPV6: {
303
                struct icmp6hdr _icmp6h;
304
                const struct icmp6hdr *ic;
305
 
306
                /* Max length: 13 "PROTO=ICMPv6 " */
307
                printk("PROTO=ICMPv6 ");
308
 
309
                if (fragment)
310
                        break;
311
 
312
                /* Max length: 25 "INCOMPLETE [65535 bytes] " */
313
                ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h);
314
                if (ic == NULL) {
315
                        printk("INCOMPLETE [%u bytes] ", skb->len - ptr);
316
                        return;
317
                }
318
 
319
                /* Max length: 18 "TYPE=255 CODE=255 " */
320
                printk("TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code);
321
 
322
                switch (ic->icmp6_type) {
323
                case ICMPV6_ECHO_REQUEST:
324
                case ICMPV6_ECHO_REPLY:
325
                        /* Max length: 19 "ID=65535 SEQ=65535 " */
326
                        printk("ID=%u SEQ=%u ",
327
                                ntohs(ic->icmp6_identifier),
328
                                ntohs(ic->icmp6_sequence));
329
                        break;
330
                case ICMPV6_MGM_QUERY:
331
                case ICMPV6_MGM_REPORT:
332
                case ICMPV6_MGM_REDUCTION:
333
                        break;
334
 
335
                case ICMPV6_PARAMPROB:
336
                        /* Max length: 17 "POINTER=ffffffff " */
337
                        printk("POINTER=%08x ", ntohl(ic->icmp6_pointer));
338
                        /* Fall through */
339
                case ICMPV6_DEST_UNREACH:
340
                case ICMPV6_PKT_TOOBIG:
341
                case ICMPV6_TIME_EXCEED:
342
                        /* Max length: 3+maxlen */
343
                        if (recurse) {
344
                                printk("[");
345
                                dump_packet(info, skb, ptr + sizeof(_icmp6h),
346
                                            0);
347
                                printk("] ");
348
                        }
349
 
350
                        /* Max length: 10 "MTU=65535 " */
351
                        if (ic->icmp6_type == ICMPV6_PKT_TOOBIG)
352
                                printk("MTU=%u ", ntohl(ic->icmp6_mtu));
353
                }
354
                break;
355
        }
356
        /* Max length: 10 "PROTO=255 " */
357
        default:
358
                printk("PROTO=%u ", currenthdr);
359
        }
360
 
361
        /* Max length: 15 "UID=4294967295 " */
362
        if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) {
363
                read_lock_bh(&skb->sk->sk_callback_lock);
364
                if (skb->sk->sk_socket && skb->sk->sk_socket->file)
365
                        printk("UID=%u ", skb->sk->sk_socket->file->f_uid);
366
                read_unlock_bh(&skb->sk->sk_callback_lock);
367
        }
368
}
369
 
370
static struct nf_loginfo default_loginfo = {
371
        .type   = NF_LOG_TYPE_LOG,
372
        .u = {
373
                .log = {
374
                        .level    = 0,
375
                        .logflags = NF_LOG_MASK,
376
                },
377
        },
378
};
379
 
380
static void
381
ip6t_log_packet(unsigned int pf,
382
                unsigned int hooknum,
383
                const struct sk_buff *skb,
384
                const struct net_device *in,
385
                const struct net_device *out,
386
                const struct nf_loginfo *loginfo,
387
                const char *prefix)
388
{
389
        if (!loginfo)
390
                loginfo = &default_loginfo;
391
 
392
        spin_lock_bh(&log_lock);
393
        printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
394
                prefix,
395
                in ? in->name : "",
396
                out ? out->name : "");
397
        if (in && !out) {
398
                unsigned int len;
399
                /* MAC logging for input chain only. */
400
                printk("MAC=");
401
                if (skb->dev && (len = skb->dev->hard_header_len) &&
402
                    skb->mac_header != skb->network_header) {
403
                        const unsigned char *p = skb_mac_header(skb);
404
                        int i;
405
 
406
                        if (skb->dev->type == ARPHRD_SIT &&
407
                            (p -= ETH_HLEN) < skb->head)
408
                                p = NULL;
409
 
410
                        if (p != NULL) {
411
                                for (i = 0; i < len; i++)
412
                                        printk("%02x%s", p[i],
413
                                               i == len - 1 ? "" : ":");
414
                        }
415
                        printk(" ");
416
 
417
                        if (skb->dev->type == ARPHRD_SIT) {
418
                                const struct iphdr *iph =
419
                                        (struct iphdr *)skb_mac_header(skb);
420
                                printk("TUNNEL=%u.%u.%u.%u->%u.%u.%u.%u ",
421
                                       NIPQUAD(iph->saddr),
422
                                       NIPQUAD(iph->daddr));
423
                        }
424
                } else
425
                        printk(" ");
426
        }
427
 
428
        dump_packet(loginfo, skb, skb_network_offset(skb), 1);
429
        printk("\n");
430
        spin_unlock_bh(&log_lock);
431
}
432
 
433
static unsigned int
434
ip6t_log_target(struct sk_buff *skb,
435
                const struct net_device *in,
436
                const struct net_device *out,
437
                unsigned int hooknum,
438
                const struct xt_target *target,
439
                const void *targinfo)
440
{
441
        const struct ip6t_log_info *loginfo = targinfo;
442
        struct nf_loginfo li;
443
 
444
        li.type = NF_LOG_TYPE_LOG;
445
        li.u.log.level = loginfo->level;
446
        li.u.log.logflags = loginfo->logflags;
447
 
448
        ip6t_log_packet(PF_INET6, hooknum, skb, in, out, &li, loginfo->prefix);
449
        return XT_CONTINUE;
450
}
451
 
452
 
453
static bool ip6t_log_checkentry(const char *tablename,
454
                                const void *entry,
455
                                const struct xt_target *target,
456
                                void *targinfo,
457
                                unsigned int hook_mask)
458
{
459
        const struct ip6t_log_info *loginfo = targinfo;
460
 
461
        if (loginfo->level >= 8) {
462
                pr_debug("LOG: level %u >= 8\n", loginfo->level);
463
                return false;
464
        }
465
        if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
466
                pr_debug("LOG: prefix term %i\n",
467
                         loginfo->prefix[sizeof(loginfo->prefix)-1]);
468
                return false;
469
        }
470
        return true;
471
}
472
 
473
static struct xt_target ip6t_log_reg __read_mostly = {
474
        .name           = "LOG",
475
        .family         = AF_INET6,
476
        .target         = ip6t_log_target,
477
        .targetsize     = sizeof(struct ip6t_log_info),
478
        .checkentry     = ip6t_log_checkentry,
479
        .me             = THIS_MODULE,
480
};
481
 
482
static struct nf_logger ip6t_logger = {
483
        .name           = "ip6t_LOG",
484
        .logfn          = &ip6t_log_packet,
485
        .me             = THIS_MODULE,
486
};
487
 
488
static int __init ip6t_log_init(void)
489
{
490
        int ret;
491
 
492
        ret = xt_register_target(&ip6t_log_reg);
493
        if (ret < 0)
494
                return ret;
495
        nf_log_register(PF_INET6, &ip6t_logger);
496
        return 0;
497
}
498
 
499
static void __exit ip6t_log_fini(void)
500
{
501
        nf_log_unregister(&ip6t_logger);
502
        xt_unregister_target(&ip6t_log_reg);
503
}
504
 
505
module_init(ip6t_log_init);
506
module_exit(ip6t_log_fini);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.