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_vdolive.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1629 jcastillo
/*
2
 *              IP_MASQ_VDOLIVE  - VDO Live masquerading module
3
 *
4
 *
5
 * Version:     @(#)$Id: ip_masq_vdolive.c,v 1.1 2005-12-20 10:41:09 jcastillo Exp $
6
 *
7
 * Author:      Nigel Metheringham <Nigel.Metheringham@ThePLAnet.net>
8
 *              PLAnet Online Ltd
9
 *
10
 *      This program is free software; you can redistribute it and/or
11
 *      modify it under the terms of the GNU General Public License
12
 *      as published by the Free Software Foundation; either version
13
 *      2 of the License, or (at your option) any later version.
14
 *
15
 * Thanks:
16
 *      Thank you to VDOnet Corporation for allowing me access to
17
 *      a protocol description without an NDA.  This means that
18
 *      this module can be distributed as source - a great help!
19
 *
20
 */
21
 
22
#include <linux/module.h>
23
#include <asm/system.h>
24
#include <linux/types.h>
25
#include <linux/kernel.h>
26
#include <linux/skbuff.h>
27
#include <linux/in.h>
28
#include <linux/ip.h>
29
#include <net/protocol.h>
30
#include <net/tcp.h>
31
#include <net/ip_masq.h>
32
 
33
#ifndef DEBUG_CONFIG_IP_MASQ_VDOLIVE
34
#define DEBUG_CONFIG_IP_MASQ_VDOLIVE 0
35
#endif
36
 
37
struct vdolive_priv_data {
38
        /* Ports used */
39
        unsigned short  origport;
40
        unsigned short  masqport;
41
        /* State of decode */
42
        unsigned short  state;
43
};
44
 
45
#ifdef MODULE
46
#define STATIC
47
#else
48
#define STATIC  static
49
#endif
50
 
51
/*
52
 * List of ports (up to MAX_MASQ_APP_PORTS) to be handled by helper
53
 * First port is set to the default port.
54
 */
55
STATIC int ports[MAX_MASQ_APP_PORTS] = {7000}; /* I rely on the trailing items being set to zero */
56
struct ip_masq_app *masq_incarnations[MAX_MASQ_APP_PORTS];
57
 
58
static int
59
masq_vdolive_init_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
60
{
61
        MOD_INC_USE_COUNT;
62
        if ((ms->app_data = kmalloc(sizeof(struct vdolive_priv_data),
63
                                    GFP_ATOMIC)) == NULL)
64
                printk(KERN_INFO "VDOlive: No memory for application data\n");
65
        else
66
        {
67
                struct vdolive_priv_data *priv =
68
                        (struct vdolive_priv_data *)ms->app_data;
69
                priv->origport = 0;
70
                priv->masqport = 0;
71
                priv->state = 0;
72
        }
73
        return 0;
74
}
75
 
76
static int
77
masq_vdolive_done_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
78
{
79
        MOD_DEC_USE_COUNT;
80
        if (ms->app_data)
81
                kfree_s(ms->app_data, sizeof(struct vdolive_priv_data));
82
        return 0;
83
}
84
 
85
int
86
masq_vdolive_out (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, struct device *dev)
87
{
88
        struct sk_buff *skb;
89
        struct iphdr *iph;
90
        struct tcphdr *th;
91
        char *data, *data_limit;
92
        unsigned int tagval;    /* This should be a 32 bit quantity */
93
        struct ip_masq *n_ms;
94
        struct vdolive_priv_data *priv =
95
                (struct vdolive_priv_data *)ms->app_data;
96
 
97
        /* This doesn't work at all if no priv data was allocated on startup */
98
        if (!priv)
99
                return 0;
100
 
101
        /* Everything running correctly already */
102
        if (priv->state == 3)
103
                return 0;
104
 
105
        skb = *skb_p;
106
        iph = skb->h.iph;
107
        th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
108
        data = (char *)&th[1];
109
 
110
        data_limit = skb->h.raw + skb->len;
111
 
112
        if (data+8 > data_limit) {
113
#if DEBUG_CONFIG_IP_MASQ_VDOLIVE
114
                printk("VDOlive: packet too short for ID %lx %lx\n",
115
                       data, data_limit);
116
#endif
117
                return 0;
118
        }
119
        memcpy(&tagval, data+4, 4);
120
#if DEBUG_CONFIG_IP_MASQ_VDOLIVE
121
        printk("VDOlive: packet seen, tag %ld, in initial state %d\n",
122
               ntohl(tagval), priv->state);
123
#endif
124
 
125
        /* Check for leading packet ID */
126
        if ((ntohl(tagval) != 6) && (ntohl(tagval) != 1)) {
127
#if DEBUG_CONFIG_IP_MASQ_VDOLIVE
128
                printk("VDOlive: unrecognised tag %ld, in initial state %d\n",
129
                       ntohl(tagval), priv->state);
130
#endif
131
                return 0;
132
        }
133
 
134
 
135
        /* Check packet is long enough for data - ignore if not */
136
        if ((ntohl(tagval) == 6) && (data+36 > data_limit)) {
137
#if DEBUG_CONFIG_IP_MASQ_VDOLIVE
138
                printk("VDOlive: initial packet too short %lx %lx\n",
139
                       data, data_limit);
140
#endif
141
                return 0;
142
        } else if ((ntohl(tagval) == 1) && (data+20 > data_limit)) {
143
#if DEBUG_CONFIG_IP_MASQ_VDOLIVE
144
                printk("VDOlive: secondary packet too short %lx %lx\n",
145
                       data, data_limit);
146
#endif
147
                return 0;
148
        }
149
 
150
        /* Adjust data pointers */
151
        /*
152
         * I could check the complete protocol version tag
153
         * in here however I am just going to look for the
154
         * "VDO Live" tag in the hope that this part will
155
         * remain constant even if the version changes
156
         */
157
        if (ntohl(tagval) == 6) {
158
                data += 24;
159
#if DEBUG_CONFIG_IP_MASQ_VDOLIVE
160
                printk("VDOlive: initial packet found\n");
161
#endif
162
        } else {
163
                data += 8;
164
#if DEBUG_CONFIG_IP_MASQ_VDOLIVE
165
                printk("VDOlive: secondary packet found\n");
166
#endif
167
        }
168
 
169
        if (memcmp(data, "VDO Live", 8) != 0) {
170
#if DEBUG_CONFIG_IP_MASQ_VDOLIVE
171
                printk("VDOlive: did not find tag\n");
172
#endif
173
                return 0;
174
        }
175
        /*
176
         * The port number is the next word after the tag.
177
         * VDOlive encodes all of these values
178
         * in 32 bit words, so in this case I am
179
         * skipping the first 2 bytes of the next
180
         * word to get to the relevant 16 bits
181
         */
182
        data += 10;
183
 
184
        /*
185
         * If we have not seen the port already,
186
         * set the masquerading tunnel up
187
         */
188
        if (!priv->origport) {
189
                memcpy(&priv->origport, data, 2);
190
 
191
#if DEBUG_CONFIG_IP_MASQ_VDOLIVE
192
                printk("VDOlive: found port %d\n",
193
                       ntohs(priv->origport));
194
#endif
195
 
196
                /* Open up a tunnel */
197
                n_ms = ip_masq_new(dev, IPPROTO_UDP,
198
                                   ms->saddr, priv->origport,
199
                                   ms->daddr, 0,
200
                                   IP_MASQ_F_NO_DPORT);
201
 
202
                if (n_ms==NULL) {
203
                        printk("VDOlive: unable to build UDP tunnel for %x:%x\n",
204
                               ms->saddr, priv->origport);
205
                        /* Leave state as unset */
206
                        priv->origport = 0;
207
                        return 0;
208
                }
209
 
210
                ip_masq_set_expire(n_ms, ip_masq_expire->udp_timeout);
211
                priv->masqport = n_ms->mport;
212
        } else if (memcmp(data, &(priv->origport), 2)) {
213
                printk("VDOlive: ports do not match\n");
214
                /* Write the port in anyhow!!! */
215
        }
216
 
217
        /*
218
         * Write masq port into packet
219
         */
220
        memcpy(data, &(priv->masqport), 2);
221
#if DEBUG_CONFIG_IP_MASQ_VDOLIVE
222
        printk("VDOlive: rewrote port %d to %d, server %s\n",
223
               ntohs(priv->origport), ntohs(priv->masqport), in_ntoa(ms->saddr));
224
#endif
225
 
226
        /*
227
         * Set state bit to make which bit has been done
228
         */
229
 
230
        priv->state |= (ntohl(tagval) == 6) ? 1 : 2;
231
 
232
        return 0;
233
}
234
 
235
 
236
struct ip_masq_app ip_masq_vdolive = {
237
        NULL,                   /* next */
238
        "VDOlive",              /* name */
239
        0,                      /* type */
240
        0,                      /* n_attach */
241
        masq_vdolive_init_1,    /* ip_masq_init_1 */
242
        masq_vdolive_done_1,    /* ip_masq_done_1 */
243
        masq_vdolive_out,       /* pkt_out */
244
        NULL                    /* pkt_in */
245
};
246
 
247
/*
248
 *      ip_masq_vdolive initialization
249
 */
250
 
251
int ip_masq_vdolive_init(void)
252
{
253
        int i, j;
254
 
255
        for (i=0; (i<MAX_MASQ_APP_PORTS); i++) {
256
                if (ports[i]) {
257
                        if ((masq_incarnations[i] = kmalloc(sizeof(struct ip_masq_app),
258
                                                            GFP_KERNEL)) == NULL)
259
                                return -ENOMEM;
260
                        memcpy(masq_incarnations[i], &ip_masq_vdolive, sizeof(struct ip_masq_app));
261
                        if ((j = register_ip_masq_app(masq_incarnations[i],
262
                                                      IPPROTO_TCP,
263
                                                      ports[i]))) {
264
                                return j;
265
                        }
266
#if DEBUG_CONFIG_IP_MASQ_VDOLIVE
267
                        printk("RealAudio: loaded support on port[%d] = %d\n",
268
                               i, ports[i]);
269
#endif
270
                } else {
271
                        /* To be safe, force the incarnation table entry to NULL */
272
                        masq_incarnations[i] = NULL;
273
                }
274
        }
275
        return 0;
276
}
277
 
278
/*
279
 *      ip_masq_vdolive fin.
280
 */
281
 
282
int ip_masq_vdolive_done(void)
283
{
284
        int i, j, k;
285
 
286
        k=0;
287
        for (i=0; (i<MAX_MASQ_APP_PORTS); i++) {
288
                if (masq_incarnations[i]) {
289
                        if ((j = unregister_ip_masq_app(masq_incarnations[i]))) {
290
                                k = j;
291
                        } else {
292
                                kfree(masq_incarnations[i]);
293
                                masq_incarnations[i] = NULL;
294
#if DEBUG_CONFIG_IP_MASQ_VDOLIVE
295
                                printk("VDOlive: unloaded support on port[%d] = %d\n",
296
                                       i, ports[i]);
297
#endif
298
                        }
299
                }
300
        }
301
        return k;
302
}
303
 
304
 
305
#ifdef MODULE
306
 
307
int init_module(void)
308
{
309
        if (ip_masq_vdolive_init() != 0)
310
                return -EIO;
311
        register_symtab(0);
312
        return 0;
313
}
314
 
315
void cleanup_module(void)
316
{
317
        if (ip_masq_vdolive_done() != 0)
318
                printk("ip_masq_vdolive: can't remove module");
319
}
320
 
321
#endif /* MODULE */

powered by: WebSVN 2.1.0

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