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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [net/] [ipv4/] [ip_masq_quake.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1629 jcastillo
/*
2
 *              IP_MASQ_QUAKE quake masquerading module
3
 *
4
 *
5
 * Version:     @(#)ip_masq_quake.c 1.00   22/02/97
6
 *
7
 * Author:      Harald Hoyer mailto:HarryH@Royal.Net
8
 *
9
 *
10
 * Fixes:
11
 *      Harald Hoyer            :       Unofficial Quake Specs found at
12
 *                                 http://www.gamers.org/dEngine/quake/spec/
13
 *      Harald Hoyer            :       Check for QUAKE-STRING
14
 *
15
 *      This program is free software; you can redistribute it and/or
16
 *      modify it under the terms of the GNU General Public License
17
 *      as published by the Free Software Foundation; either version
18
 *      2 of the License, or (at your option) any later version.
19
 *
20
 *
21
 */
22
 
23
#include <linux/module.h>
24
 
25
#include <linux/types.h>
26
#include <linux/kernel.h>
27
#include <asm/system.h>
28
#include <linux/skbuff.h>
29
#include <linux/in.h>
30
#include <linux/ip.h>
31
#include <net/protocol.h>
32
#include <net/udp.h>
33
#include <net/ip_masq.h>
34
 
35
#ifndef DEBUG_CONFIG_IP_MASQ_QUAKE
36
#define DEBUG_CONFIG_IP_MASQ_QUAKE 0
37
#endif
38
 
39
#ifdef MODULE
40
#define STATIC
41
#else
42
#define STATIC  static
43
#endif
44
 
45
/*
46
 * List of ports (up to MAX_MASQ_APP_PORTS) to be handled by helper
47
 * First ports are set to the default port.
48
 */
49
STATIC int ports[MAX_MASQ_APP_PORTS] = { 26000,   /* I rely on the trailing items */
50
                                  27000 }; /* being set to zero */
51
struct ip_masq_app *masq_incarnations[MAX_MASQ_APP_PORTS];
52
 
53
 
54
typedef struct
55
{
56
        __u16 type;     /* (Little Endian) Type of message. */
57
        __u16 length;   /* (Little Endian) Length of message, header included. */
58
        char  message[0];  /* The contents of the message. */
59
} QUAKEHEADER;
60
 
61
struct quake_priv_data {
62
        /* Have we seen a client connect message */
63
        char    cl_connect;
64
};
65
 
66
static int
67
masq_quake_init_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
68
{
69
        MOD_INC_USE_COUNT;
70
        if ((ms->app_data = kmalloc(sizeof(struct quake_priv_data),
71
                                    GFP_ATOMIC)) == NULL)
72
                printk(KERN_INFO "Quake: No memory for application data\n");
73
        else
74
        {
75
                struct quake_priv_data *priv =
76
                        (struct quake_priv_data *)ms->app_data;
77
                priv->cl_connect = 0;
78
        }
79
        return 0;
80
}
81
 
82
static int
83
masq_quake_done_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
84
{
85
        MOD_DEC_USE_COUNT;
86
        if (ms->app_data)
87
                kfree_s(ms->app_data, sizeof(struct quake_priv_data));
88
        return 0;
89
}
90
 
91
int
92
masq_quake_in (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, struct device *dev)
93
{
94
        struct sk_buff *skb;
95
        struct iphdr *iph;
96
        struct udphdr *uh;
97
        QUAKEHEADER *qh;
98
        __u16 udp_port;
99
        char *data;
100
        unsigned char code;
101
        struct quake_priv_data *priv = (struct quake_priv_data *)ms->app_data;
102
 
103
        if(priv->cl_connect == -1)
104
          return 0;
105
 
106
        skb = *skb_p;
107
        iph = skb->h.iph;
108
/*      iph = skb->nh.iph; */
109
 
110
        uh = (struct udphdr *)&(((char *)iph)[iph->ihl*4]);
111
 
112
        /* Check for lenght */
113
        if(ntohs(uh->len) < 5)
114
          return 0;
115
 
116
        qh = (QUAKEHEADER *)&uh[1];
117
 
118
        if(qh->type != 0x0080)
119
          return 0;
120
 
121
 
122
        code = qh->message[0];
123
 
124
#if DEBUG_CONFIG_IP_MASQ_QUAKE
125
          printk("Quake_in: code = %d \n", (int)code);
126
#endif
127
 
128
        switch(code) {
129
        case 0x01:
130
          /* Connection Request */
131
 
132
          if(ntohs(qh->length) < 0x0c) {
133
#if DEBUG_CONFIG_IP_MASQ_QUAKE
134
            printk("Quake_in: length < 0xc \n");
135
#endif
136
            return 0;
137
          }
138
 
139
          data = &qh->message[1];
140
 
141
          /* Check for stomping string */
142
          if(memcmp(data,"QUAKE\0\3",7)) {
143
#if DEBUG_CONFIG_IP_MASQ_QUAKE
144
            printk("Quake_out: memcmp failed \n");
145
#endif
146
            return 0;
147
          }
148
          else {
149
            priv->cl_connect = 1;
150
#if DEBUG_CONFIG_IP_MASQ_QUAKE
151
            printk("Quake_out: memcmp ok \n");
152
#endif
153
          }
154
          break;
155
 
156
        case 0x81:
157
          /* Accept Connection */
158
          if((ntohs(qh->length) < 0x09) || (priv->cl_connect == 0))
159
            return 0;
160
          data = &qh->message[1];
161
 
162
          memcpy(&udp_port, data, 2);
163
 
164
          ms->dport = htons(udp_port);
165
 
166
#if DEBUG_CONFIG_IP_MASQ_QUAKE
167
          printk("Quake_in: in_rewrote UDP port %d \n", udp_port);
168
#endif
169
          priv->cl_connect = -1;
170
 
171
          break;
172
        }
173
 
174
        return 0;
175
}
176
 
177
int
178
masq_quake_out (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, struct device *dev)
179
{
180
        struct sk_buff *skb;
181
        struct iphdr *iph;
182
        struct udphdr *uh;
183
        QUAKEHEADER *qh;
184
        __u16 udp_port;
185
        char *data;
186
        unsigned char code;
187
        struct ip_masq *n_ms;
188
        struct quake_priv_data *priv = (struct quake_priv_data *)ms->app_data;
189
 
190
        if(priv->cl_connect == -1)
191
          return 0;
192
 
193
        skb = *skb_p;
194
        iph = skb->h.iph;
195
/*      iph = skb->nh.iph; */
196
 
197
        uh = (struct udphdr *)&(((char *)iph)[iph->ihl*4]);
198
 
199
        /* Check for lenght */
200
        if(ntohs(uh->len) < 5)
201
          return 0;
202
 
203
        qh = (QUAKEHEADER *)&uh[1];
204
 
205
#if DEBUG_CONFIG_IP_MASQ_QUAKE
206
          printk("Quake_out: qh->type = %d \n", (int)qh->type);
207
#endif
208
 
209
        if(qh->type != 0x0080)
210
          return 0;
211
 
212
        code = qh->message[0];
213
 
214
#if DEBUG_CONFIG_IP_MASQ_QUAKE
215
          printk("Quake_out: code = %d \n", (int)code);
216
#endif
217
 
218
        switch(code) {
219
        case 0x01:
220
          /* Connection Request */
221
 
222
          if(ntohs(qh->length) < 0x0c) {
223
#if DEBUG_CONFIG_IP_MASQ_QUAKE
224
            printk("Quake_out: length < 0xc \n");
225
#endif
226
            return 0;
227
          }
228
 
229
          data = &qh->message[1];
230
 
231
          /* Check for stomping string */
232
          if(memcmp(data,"QUAKE\0\3",7)) {
233
#if DEBUG_CONFIG_IP_MASQ_QUAKE
234
            printk("Quake_out: memcmp failed \n");
235
#endif
236
            return 0;
237
          }
238
          else {
239
            priv->cl_connect = 1;
240
#if DEBUG_CONFIG_IP_MASQ_QUAKE
241
            printk("Quake_out: memcmp ok \n");
242
#endif
243
          }
244
          break;
245
 
246
        case 0x81:
247
          /* Maybe a redirection of a quake-server at the inner side works in
248
             the future? */
249
 
250
          /* Accept Connection */
251
          if((ntohs(qh->length) < 0x09) || (priv->cl_connect == 0))
252
            return 0;
253
 
254
          data = &qh->message[1];
255
 
256
          memcpy(&udp_port, data, 2);
257
 
258
          n_ms = ip_masq_new(dev, IPPROTO_UDP,
259
                             ms->saddr, htons(udp_port),
260
                             ms->daddr, ms->dport,
261
                             0);
262
 
263
          if (n_ms==NULL)
264
            return 0;
265
 
266
#if DEBUG_CONFIG_IP_MASQ_QUAKE
267
          printk("Quake_out: out_rewrote UDP port %d -> %d\n",
268
                 udp_port, ntohs(n_ms->mport));
269
#endif
270
          udp_port = ntohs(n_ms->mport);
271
          memcpy(data, &udp_port, 2);
272
 
273
          break;
274
        }
275
 
276
        return 0;
277
}
278
 
279
struct ip_masq_app ip_masq_quake = {
280
        NULL,                   /* next */
281
        "Quake",                /* name */
282
        0,                      /* type */
283
        0,                      /* n_attach */
284
        masq_quake_init_1,      /* ip_masq_init_1 */
285
        masq_quake_done_1,      /* ip_masq_done_1 */
286
        masq_quake_out,         /* pkt_out */
287
        masq_quake_in           /* pkt_in */
288
};
289
 
290
/*
291
 *      ip_masq_quake initialization
292
 */
293
 
294
int ip_masq_quake_init(void)
295
{
296
        int i, j;
297
 
298
        for (i=0; (i<MAX_MASQ_APP_PORTS); i++) {
299
                if (ports[i]) {
300
                        if ((masq_incarnations[i] = kmalloc(sizeof(struct ip_masq_app),
301
                                                            GFP_KERNEL)) == NULL)
302
                                return -ENOMEM;
303
                        memcpy(masq_incarnations[i], &ip_masq_quake, sizeof(struct ip_masq_app));
304
                        if ((j = register_ip_masq_app(masq_incarnations[i],
305
                                                      IPPROTO_UDP,
306
                                                      ports[i]))) {
307
                                return j;
308
                        }
309
#if DEBUG_CONFIG_IP_MASQ_QUAKE
310
                        printk("Quake: loaded support on port[%d] = %d\n",
311
                               i, ports[i]);
312
#endif
313
                } else {
314
                        /* To be safe, force the incarnation table entry to NULL */
315
                        masq_incarnations[i] = NULL;
316
                }
317
        }
318
        return 0;
319
}
320
 
321
/*
322
 *      ip_masq_quake fin.
323
 */
324
 
325
int ip_masq_quake_done(void)
326
{
327
        int i, j, k;
328
 
329
        k=0;
330
        for (i=0; (i<MAX_MASQ_APP_PORTS); i++) {
331
                if (masq_incarnations[i]) {
332
                        if ((j = unregister_ip_masq_app(masq_incarnations[i]))) {
333
                                k = j;
334
                        } else {
335
                                kfree(masq_incarnations[i]);
336
                                masq_incarnations[i] = NULL;
337
#if DEBUG_CONFIG_IP_MASQ_QUAKE
338
                                printk("Quake: unloaded support on port[%d] = %d\n",
339
                                       i, ports[i]);
340
#endif
341
                        }
342
                }
343
        }
344
        return k;
345
}
346
 
347
#ifdef MODULE
348
 
349
int init_module(void)
350
{
351
        if (ip_masq_quake_init() != 0)
352
                return -EIO;
353
        register_symtab(0);
354
        return 0;
355
}
356
 
357
void cleanup_module(void)
358
{
359
        if (ip_masq_quake_done() != 0)
360
                printk("ip_masq_quake: can't remove module");
361
}
362
 
363
#endif /* MODULE */

powered by: WebSVN 2.1.0

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