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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [ipv4/] [netfilter/] [ip_conntrack_proto_icmp.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
#include <linux/types.h>
2
#include <linux/sched.h>
3
#include <linux/timer.h>
4
#include <linux/netfilter.h>
5
#include <linux/in.h>
6
#include <linux/icmp.h>
7
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
8
 
9
unsigned long ip_ct_icmp_timeout = 30*HZ;
10
 
11
#if 0
12
#define DEBUGP printk
13
#else
14
#define DEBUGP(format, args...)
15
#endif
16
 
17
static int icmp_pkt_to_tuple(const void *datah, size_t datalen,
18
                             struct ip_conntrack_tuple *tuple)
19
{
20
        const struct icmphdr *hdr = datah;
21
 
22
        tuple->dst.u.icmp.type = hdr->type;
23
        tuple->src.u.icmp.id = hdr->un.echo.id;
24
        tuple->dst.u.icmp.code = hdr->code;
25
 
26
        return 1;
27
}
28
 
29
static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple,
30
                             const struct ip_conntrack_tuple *orig)
31
{
32
        /* Add 1; spaces filled with 0. */
33
        static u_int8_t invmap[]
34
                = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
35
                    [ICMP_ECHOREPLY] = ICMP_ECHO + 1,
36
                    [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
37
                    [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
38
                    [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
39
                    [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
40
                    [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
41
                    [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1};
42
 
43
        if (orig->dst.u.icmp.type >= sizeof(invmap)
44
            || !invmap[orig->dst.u.icmp.type])
45
                return 0;
46
 
47
        tuple->src.u.icmp.id = orig->src.u.icmp.id;
48
        tuple->dst.u.icmp.type = invmap[orig->dst.u.icmp.type] - 1;
49
        tuple->dst.u.icmp.code = orig->dst.u.icmp.code;
50
        return 1;
51
}
52
 
53
/* Print out the per-protocol part of the tuple. */
54
static unsigned int icmp_print_tuple(char *buffer,
55
                                     const struct ip_conntrack_tuple *tuple)
56
{
57
        return sprintf(buffer, "type=%u code=%u id=%u ",
58
                       tuple->dst.u.icmp.type,
59
                       tuple->dst.u.icmp.code,
60
                       ntohs(tuple->src.u.icmp.id));
61
}
62
 
63
/* Print out the private part of the conntrack. */
64
static unsigned int icmp_print_conntrack(char *buffer,
65
                                     const struct ip_conntrack *conntrack)
66
{
67
        return 0;
68
}
69
 
70
/* Returns verdict for packet, or -1 for invalid. */
71
static int icmp_packet(struct ip_conntrack *ct,
72
                       struct iphdr *iph, size_t len,
73
                       enum ip_conntrack_info ctinfo)
74
{
75
        /* Try to delete connection immediately after all replies:
76
           won't actually vanish as we still have skb, and del_timer
77
           means this will only run once even if count hits zero twice
78
           (theoretically possible with SMP) */
79
        if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
80
                if (atomic_dec_and_test(&ct->proto.icmp.count)
81
                    && del_timer(&ct->timeout))
82
                        ct->timeout.function((unsigned long)ct);
83
        } else {
84
                atomic_inc(&ct->proto.icmp.count);
85
                ip_ct_refresh(ct, ip_ct_icmp_timeout);
86
        }
87
 
88
        return NF_ACCEPT;
89
}
90
 
91
/* Called when a new connection for this protocol found. */
92
static int icmp_new(struct ip_conntrack *conntrack,
93
                    struct iphdr *iph, size_t len)
94
{
95
        static u_int8_t valid_new[]
96
                = { [ICMP_ECHO] = 1,
97
                    [ICMP_TIMESTAMP] = 1,
98
                    [ICMP_INFO_REQUEST] = 1,
99
                    [ICMP_ADDRESS] = 1 };
100
 
101
        if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
102
            || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
103
                /* Can't create a new ICMP `conn' with this. */
104
                DEBUGP("icmp: can't create new conn with type %u\n",
105
                       conntrack->tuplehash[0].tuple.dst.u.icmp.type);
106
                DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
107
                return 0;
108
        }
109
        atomic_set(&conntrack->proto.icmp.count, 0);
110
        return 1;
111
}
112
 
113
struct ip_conntrack_protocol ip_conntrack_protocol_icmp
114
= { { NULL, NULL }, IPPROTO_ICMP, "icmp",
115
    icmp_pkt_to_tuple, icmp_invert_tuple, icmp_print_tuple,
116
    icmp_print_conntrack, icmp_packet, icmp_new, NULL, NULL, NULL };

powered by: WebSVN 2.1.0

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