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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [net/] [ipv4/] [ip_masq_irc.c] - Blame information for rev 1629

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

Line No. Rev Author Line
1 1629 jcastillo
/*
2
 *              IP_MASQ_IRC irc masquerading module
3
 *
4
 *
5
 * Version:     @(#)ip_masq_irc.c 0.01   03/20/96
6
 *
7
 * Author:      Juan Jose Ciarlante
8
 *
9
 *
10
 * Fixes:
11
 *      - set NO_DADDR flag in ip_masq_new().
12
 *      - Added multiple port support (Nigel Metheringham)
13
 *
14
 * FIXME:
15
 *      - detect also previous "PRIVMSG" string ?.
16
 *
17
 *      This program is free software; you can redistribute it and/or
18
 *      modify it under the terms of the GNU General Public License
19
 *      as published by the Free Software Foundation; either version
20
 *      2 of the License, or (at your option) any later version.
21
 *
22
 * Multiple Port Support
23
 *      The helper can be made to handle up to MAX_MASQ_APP_PORTS (normally 12)
24
 *      with the port numbers being defined at module load time.  The module
25
 *      uses the symbol "ports" to define a list of monitored ports, which can
26
 *      be specified on the insmod command line as
27
 *              ports=x1,x2,x3...
28
 *      where x[n] are integer port numbers.  This option can be put into
29
 *      /etc/conf.modules (or /etc/modules.conf depending on your config)
30
 *      where modload will pick it up should you use modload to load your
31
 *      modules.
32
 *
33
 */
34
 
35
#include <linux/module.h>
36
 
37
#include <linux/types.h>
38
#include <linux/kernel.h>
39
#include <asm/system.h>
40
#include <linux/skbuff.h>
41
#include <linux/in.h>
42
#include <linux/ip.h>
43
#include <net/protocol.h>
44
#include <net/tcp.h>
45
#include <net/ip_masq.h>
46
 
47
#ifndef DEBUG_CONFIG_IP_MASQ_IRC
48
#define DEBUG_CONFIG_IP_MASQ_IRC 0
49
#endif
50
 
51
#ifdef MODULE
52
#define STATIC
53
#else
54
#define STATIC  static
55
#endif
56
 
57
/*
58
 * List of ports (up to MAX_MASQ_APP_PORTS) to be handled by helper
59
 * First port is set to the default port.
60
 */
61
STATIC int ports[MAX_MASQ_APP_PORTS] = {6667}; /* I rely on the trailing items being set to zero */
62
struct ip_masq_app *masq_incarnations[MAX_MASQ_APP_PORTS];
63
 
64
static int
65
masq_irc_init_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
66
{
67
        MOD_INC_USE_COUNT;
68
        return 0;
69
}
70
 
71
static int
72
masq_irc_done_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
73
{
74
        MOD_DEC_USE_COUNT;
75
        return 0;
76
}
77
 
78
int
79
masq_irc_out (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, struct device *dev)
80
{
81
        struct sk_buff *skb;
82
        struct iphdr *iph;
83
        struct tcphdr *th;
84
        char *data, *data_limit;
85
        __u32 s_addr;
86
        __u16 s_port;
87
        struct ip_masq *n_ms;
88
        char buf[20];           /* "m_addr m_port" (dec base)*/
89
        unsigned buf_len;
90
        int diff;
91
        int xtra_args = 0;      /* extra int args wanted after addr */
92
        char *dcc_p, *addr_beg_p, *addr_end_p;
93
 
94
        skb = *skb_p;
95
        iph = skb->h.iph;
96
        th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
97
        data = (char *)&th[1];
98
 
99
        /*
100
         *      Hunt irc DCC string, the _shortest_:
101
         *
102
         *      strlen("DCC CHAT chat AAAAAAAA P\x01\n")=26
103
         *      strlen("DCC SEND F AAAAAAAA P S\x01\n")=25
104
         *              AAAAAAAAA: bound addr (1.0.0.0==16777216, min 8 digits)
105
         *              P:         bound port (min 1 d )
106
         *              F:         filename   (min 1 d )
107
         *              S:         size       (min 1 d )
108
         *              0x01, \n:  terminators
109
         */
110
 
111
        data_limit = skb->h.raw + skb->len;
112
 
113
        while (data < (data_limit - 25) )
114
        {
115
                if (memcmp(data,"DCC ",4))  {
116
                        data ++;
117
                        continue;
118
                }
119
 
120
                dcc_p = data;
121
                data += 4;     /* point to DCC cmd */
122
 
123
                if (memcmp(data, "CHAT ", 5) == 0 ||
124
                    memcmp(data, "SEND ", 5) == 0)
125
                {
126
                        /*
127
                         *      extra arg (file_size) req. for "SEND"
128
                         */
129
 
130
                        if (*data == 'S') xtra_args++;
131
                        data += 5;
132
                }
133
                else
134
                        continue;
135
 
136
                /*
137
                 *      skip next string.
138
                 */
139
 
140
                while( *data++ != ' ')
141
 
142
                        /*
143
                         *      must still parse, at least, "AAAAAAAA P\x01\n",
144
                         *      12 bytes left.
145
                         */
146
                        if (data > (data_limit-12)) return 0;
147
 
148
 
149
                addr_beg_p = data;
150
 
151
                /*
152
                 *      client bound address in dec base
153
                 */
154
 
155
                s_addr = simple_strtoul(data,&data,10);
156
                if (*data++ !=' ')
157
                        continue;
158
 
159
                /*
160
                 *      client bound port in dec base
161
                 */
162
 
163
                s_port = simple_strtoul(data,&data,10);
164
                addr_end_p = data;
165
 
166
                /*
167
                 *      should check args consistency?
168
                 */
169
 
170
                while(xtra_args) {
171
                        if (*data != ' ')
172
                                break;
173
                        data++;
174
                        simple_strtoul(data,&data,10);
175
                        xtra_args--;
176
                }
177
 
178
                if (xtra_args != 0) continue;
179
 
180
                /*
181
                 *      terminators.
182
                 */
183
 
184
                if (data[0] != 0x01)
185
                        continue;
186
                if (data[1]!='\r' && data[1]!='\n')
187
                        continue;
188
 
189
                /*
190
                 *      Now create an masquerade entry for it
191
                 *      must set NO_DPORT and NO_DADDR because
192
                 *      connection is requested by another client.
193
                 */
194
 
195
                n_ms = ip_masq_new(dev, IPPROTO_TCP,
196
                                   htonl(s_addr),htons(s_port),
197
                                   0, 0,
198
                                   IP_MASQ_F_NO_DPORT|IP_MASQ_F_NO_DADDR
199
                                   );
200
                if (n_ms==NULL)
201
                        return 0;
202
 
203
                ip_masq_set_expire(n_ms, ip_masq_expire->tcp_fin_timeout);
204
 
205
                /*
206
                 * Replace the old "address port" with the new one
207
                 */
208
 
209
                buf_len = sprintf(buf,"%lu %u",
210
                        ntohl(n_ms->maddr),ntohs(n_ms->mport));
211
 
212
                /*
213
                 * Calculate required delta-offset to keep TCP happy
214
                 */
215
 
216
                diff = buf_len - (addr_end_p-addr_beg_p);
217
 
218
#if DEBUG_CONFIG_IP_MASQ_IRC
219
                *addr_beg_p = '\0';
220
                printk("masq_irc_out(): '%s' %X:%X detected (diff=%d)\n", dcc_p, s_addr,s_port, diff);
221
#endif  
222
                /*
223
                 *      No shift.
224
                 */
225
 
226
                if (diff==0)
227
                {
228
                        /*
229
                         * simple case, just copy.
230
                         */
231
                        memcpy(addr_beg_p,buf,buf_len);
232
                        return 0;
233
                }
234
 
235
                *skb_p = ip_masq_skb_replace(skb, GFP_ATOMIC,
236
                                             addr_beg_p, addr_end_p-addr_beg_p,
237
                                             buf, buf_len);
238
                return diff;
239
        }
240
        return 0;
241
 
242
}
243
 
244
/*
245
 *      Main irc object
246
 *      You need 1 object per port in case you need
247
 *      to offer also other used irc ports (6665,6666,etc),
248
 *      they will share methods but they need own space for
249
 *      data.
250
 */
251
 
252
struct ip_masq_app ip_masq_irc = {
253
        NULL,                   /* next */
254
        "irc",                  /* name */
255
        0,                      /* type */
256
        0,                      /* n_attach */
257
        masq_irc_init_1,        /* init_1 */
258
        masq_irc_done_1,        /* done_1 */
259
        masq_irc_out,           /* pkt_out */
260
        NULL                    /* pkt_in */
261
};
262
 
263
/*
264
 *      ip_masq_irc initialization
265
 */
266
 
267
int ip_masq_irc_init(void)
268
{
269
        int i, j;
270
 
271
        for (i=0; (i<MAX_MASQ_APP_PORTS); i++) {
272
                if (ports[i]) {
273
                        if ((masq_incarnations[i] = kmalloc(sizeof(struct ip_masq_app),
274
                                                            GFP_KERNEL)) == NULL)
275
                                return -ENOMEM;
276
                        memcpy(masq_incarnations[i], &ip_masq_irc, sizeof(struct ip_masq_app));
277
                        if ((j = register_ip_masq_app(masq_incarnations[i],
278
                                                      IPPROTO_TCP,
279
                                                      ports[i]))) {
280
                                return j;
281
                        }
282
#if DEBUG_CONFIG_IP_MASQ_IRC
283
                        printk("Irc: loaded support on port[%d] = %d\n",
284
                               i, ports[i]);
285
#endif
286
                } else {
287
                        /* To be safe, force the incarnation table entry to NULL */
288
                        masq_incarnations[i] = NULL;
289
                }
290
        }
291
        return 0;
292
}
293
 
294
/*
295
 *      ip_masq_irc fin.
296
 */
297
 
298
int ip_masq_irc_done(void)
299
{
300
        int i, j, k;
301
 
302
        k=0;
303
        for (i=0; (i<MAX_MASQ_APP_PORTS); i++) {
304
                if (masq_incarnations[i]) {
305
                        if ((j = unregister_ip_masq_app(masq_incarnations[i]))) {
306
                                k = j;
307
                        } else {
308
                                kfree(masq_incarnations[i]);
309
                                masq_incarnations[i] = NULL;
310
#if DEBUG_CONFIG_IP_MASQ_IRC
311
                                printk("Irc: unloaded support on port[%d] = %d\n",
312
                                       i, ports[i]);
313
#endif
314
                        }
315
                }
316
        }
317
        return k;
318
}
319
 
320
 
321
#ifdef MODULE
322
 
323
int init_module(void)
324
{
325
        if (ip_masq_irc_init() != 0)
326
                return -EIO;
327
        register_symtab(NULL);
328
        return 0;
329
}
330
 
331
void cleanup_module(void)
332
{
333
        if (ip_masq_irc_done() != 0)
334
                printk("ip_masq_irc: can't remove module");
335
}
336
 
337
#endif /* MODULE */

powered by: WebSVN 2.1.0

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