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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* Amanda extension for IP connection tracking, Version 0.2
2
 * (C) 2002 by Brian J. Murrell <netfilter@interlinx.bc.ca>
3
 * based on HW's ip_conntrack_irc.c as well as other modules
4
 *
5
 *      This program is free software; you can redistribute it and/or
6
 *      modify it under the terms of the GNU General Public License
7
 *      as published by the Free Software Foundation; either version
8
 *      2 of the License, or (at your option) any later version.
9
 *
10
 *      Module load syntax:
11
 *      insmod ip_conntrack_amanda.o [master_timeout=n]
12
 *
13
 *      Where master_timeout is the timeout (in seconds) of the master
14
 *      connection (port 10080).  This defaults to 5 minutes but if
15
 *      your clients take longer than 5 minutes to do their work
16
 *      before getting back to the Amanda server, you can increase
17
 *      this value.
18
 *
19
 */
20
 
21
#include <linux/kernel.h>
22
#include <linux/module.h>
23
#include <linux/netfilter.h>
24
#include <linux/ip.h>
25
#include <net/checksum.h>
26
#include <net/udp.h>
27
 
28
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
29
#include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
30
 
31
static unsigned int master_timeout = 300;
32
 
33
MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
34
MODULE_DESCRIPTION("Amanda connection tracking module");
35
MODULE_LICENSE("GPL");
36
MODULE_PARM(master_timeout, "i");
37
MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
38
 
39
static struct { char *match; int len; } conns[] = {
40
        { "DATA ", 5},
41
        { "MESG ", 5},
42
        { "INDEX ", 6},
43
};
44
 
45
#define NUM_MSGS 3
46
 
47
 
48
static int help(const struct iphdr *iph, size_t len,
49
                struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
50
{
51
        struct ip_conntrack_expect exp;
52
        struct ip_ct_amanda_expect *exp_amanda_info;
53
        struct udphdr *udph = (void *)iph + iph->ihl * 4;
54
        u_int32_t udplen = len - iph->ihl * 4;
55
        u_int32_t datalen = udplen - sizeof(struct udphdr);
56
        char *data = (char *)udph + sizeof(struct udphdr);
57
        char *data_limit = data + datalen;
58
        char *start = data, *tmp;
59
        int i;
60
 
61
        /* Only look at packets from the Amanda server */
62
        if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
63
                return NF_ACCEPT;
64
 
65
        if (udplen < sizeof(struct udphdr)) {
66
                if (net_ratelimit())
67
                        printk("amanda_help: udplen = %u\n", udplen);
68
                return NF_ACCEPT;
69
        }
70
 
71
        if (udph->check &&
72
            csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP,
73
                              csum_partial((char *)udph, udplen, 0)))
74
                return NF_ACCEPT;
75
 
76
        /* increase the UDP timeout of the master connection as replies from
77
         * Amanda clients to the server can be quite delayed */
78
        ip_ct_refresh(ct, master_timeout * HZ);
79
 
80
        /* Search for "CONNECT " string */
81
        do {
82
                if (data + 8 >= data_limit)
83
                        return NF_ACCEPT;
84
                if (!memcmp(data, "CONNECT ", 8)) {
85
                        data += 8;
86
                        break;
87
                }
88
                data++;
89
        } while(1);
90
 
91
        memset(&exp, 0, sizeof(exp));
92
        exp.tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
93
        exp.tuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
94
        exp.tuple.dst.protonum = IPPROTO_TCP;
95
        exp.mask.src.ip = 0xFFFFFFFF;
96
        exp.mask.dst.ip = 0xFFFFFFFF;
97
        exp.mask.dst.protonum = 0xFFFF;
98
        exp.mask.dst.u.tcp.port = 0xFFFF;
99
 
100
        exp_amanda_info = &exp.help.exp_amanda_info;
101
        for (i = 0; data + conns[i].len < data_limit && *data != '\n'; data++) {
102
                if (memcmp(data, conns[i].match, conns[i].len))
103
                        continue;
104
                tmp = data += conns[i].len;
105
                exp_amanda_info->offset = data - start;
106
                exp_amanda_info->port   = simple_strtoul(data, &data, 10);
107
                exp_amanda_info->len    = data - tmp;
108
                if (exp_amanda_info->port == 0 || exp_amanda_info->len > 5)
109
                        break;
110
 
111
                exp.tuple.dst.u.tcp.port = htons(exp_amanda_info->port);
112
                ip_conntrack_expect_related(ct, &exp);
113
                if (++i == NUM_MSGS)
114
                        break;
115
        }
116
 
117
        return NF_ACCEPT;
118
}
119
 
120
static struct ip_conntrack_helper amanda_helper;
121
 
122
static void __exit fini(void)
123
{
124
        ip_conntrack_helper_unregister(&amanda_helper);
125
}
126
 
127
static int __init init(void)
128
{
129
        amanda_helper.tuple.src.u.udp.port = htons(10080);
130
        amanda_helper.tuple.dst.protonum = IPPROTO_UDP;
131
        amanda_helper.mask.src.u.udp.port = 0xFFFF;
132
        amanda_helper.mask.dst.protonum = 0xFFFF;
133
        amanda_helper.max_expected = NUM_MSGS;
134
        amanda_helper.timeout = 180;
135
        amanda_helper.flags = IP_CT_HELPER_F_REUSE_EXPECT;
136
        amanda_helper.me = THIS_MODULE;
137
        amanda_helper.help = help;
138
        amanda_helper.name = "amanda";
139
 
140
        return ip_conntrack_helper_register(&amanda_helper);
141
}
142
 
143
module_init(init);
144
module_exit(fini);

powered by: WebSVN 2.1.0

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