Import 2.3.10pre5
[davej-history.git] / net / ipv4 / ip_masq_quake.c
blob17b11a799072f1416810f727af7699bd403b5597
1 /*
2 * IP_MASQ_QUAKE quake masquerading module
5 * Version: @(#)ip_masq_quake.c 0.02 22/02/97
7 * Author: Harald Hoyer mailto:HarryH@Royal.Net
8 *
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 * Juan Jose Ciarlante : litl bits for 2.1
15 * Horst von Brand : Add #include <linux/string.h>
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.
25 #include <linux/module.h>
26 #include <asm/system.h>
27 #include <linux/types.h>
28 #include <linux/string.h>
29 #include <linux/kernel.h>
30 #include <linux/skbuff.h>
31 #include <linux/in.h>
32 #include <linux/ip.h>
33 #include <linux/init.h>
34 #include <net/protocol.h>
35 #include <net/udp.h>
36 #include <net/ip_masq.h>
38 #define DEBUG_CONFIG_IP_MASQ_QUAKE 0
40 typedef struct
42 __u16 type; // (Little Endian) Type of message.
43 __u16 length; // (Little Endian) Length of message, header included.
44 char message[0]; // The contents of the message.
45 } QUAKEHEADER;
47 struct quake_priv_data {
48 /* Have we seen a client connect message */
49 signed char cl_connect;
52 static int
53 masq_quake_init_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
55 MOD_INC_USE_COUNT;
56 if ((ms->app_data = kmalloc(sizeof(struct quake_priv_data),
57 GFP_ATOMIC)) == NULL)
58 printk(KERN_INFO "Quake: No memory for application data\n");
59 else
61 struct quake_priv_data *priv =
62 (struct quake_priv_data *)ms->app_data;
63 priv->cl_connect = 0;
65 return 0;
68 static int
69 masq_quake_done_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
71 MOD_DEC_USE_COUNT;
72 if (ms->app_data)
73 kfree_s(ms->app_data, sizeof(struct quake_priv_data));
74 return 0;
77 int
78 masq_quake_in (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr)
80 struct sk_buff *skb;
81 struct iphdr *iph;
82 struct udphdr *uh;
83 QUAKEHEADER *qh;
84 __u16 udp_port;
85 char *data;
86 unsigned char code;
87 struct quake_priv_data *priv = (struct quake_priv_data *)ms->app_data;
89 if(priv->cl_connect == -1)
90 return 0;
92 skb = *skb_p;
94 iph = skb->nh.iph;
95 uh = (struct udphdr *)&(((char *)iph)[iph->ihl*4]);
97 /* Check for lenght */
98 if(ntohs(uh->len) < 5)
99 return 0;
101 qh = (QUAKEHEADER *)&uh[1];
103 if(qh->type != 0x0080)
104 return 0;
107 code = qh->message[0];
109 #if DEBUG_CONFIG_IP_MASQ_QUAKE
110 printk("Quake_in: code = %d \n", (int)code);
111 #endif
113 switch(code) {
114 case 0x01:
115 /* Connection Request */
117 if(ntohs(qh->length) < 0x0c) {
118 #if DEBUG_CONFIG_IP_MASQ_QUAKE
119 printk("Quake_in: length < 0xc \n");
120 #endif
121 return 0;
124 data = &qh->message[1];
126 /* Check for stomping string */
127 if(memcmp(data,"QUAKE\0\3",7)) {
128 #if DEBUG_CONFIG_IP_MASQ_QUAKE
129 printk("Quake_out: memcmp failed \n");
130 #endif
131 return 0;
133 else {
134 priv->cl_connect = 1;
135 #if DEBUG_CONFIG_IP_MASQ_QUAKE
136 printk("Quake_out: memcmp ok \n");
137 #endif
139 break;
141 case 0x81:
142 /* Accept Connection */
143 if((ntohs(qh->length) < 0x09) || (priv->cl_connect == 0))
144 return 0;
145 data = &qh->message[1];
147 memcpy(&udp_port, data, 2);
149 ms->dport = htons(udp_port);
151 #if DEBUG_CONFIG_IP_MASQ_QUAKE
152 printk("Quake_in: in_rewrote UDP port %d \n", udp_port);
153 #endif
154 priv->cl_connect = -1;
156 break;
159 return 0;
163 masq_quake_out (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr)
165 struct sk_buff *skb;
166 struct iphdr *iph;
167 struct udphdr *uh;
168 QUAKEHEADER *qh;
169 __u16 udp_port;
170 char *data;
171 unsigned char code;
172 struct ip_masq *n_ms;
173 struct quake_priv_data *priv = (struct quake_priv_data *)ms->app_data;
175 if(priv->cl_connect == -1)
176 return 0;
178 skb = *skb_p;
180 iph = skb->nh.iph;
181 uh = (struct udphdr *)&(((char *)iph)[iph->ihl*4]);
183 /* Check for lenght */
184 if(ntohs(uh->len) < 5)
185 return 0;
187 qh = (QUAKEHEADER *)&uh[1];
189 #if DEBUG_CONFIG_IP_MASQ_QUAKE
190 printk("Quake_out: qh->type = %d \n", (int)qh->type);
191 #endif
193 if(qh->type != 0x0080)
194 return 0;
196 code = qh->message[0];
198 #if DEBUG_CONFIG_IP_MASQ_QUAKE
199 printk("Quake_out: code = %d \n", (int)code);
200 #endif
202 switch(code) {
203 case 0x01:
204 /* Connection Request */
206 if(ntohs(qh->length) < 0x0c) {
207 #if DEBUG_CONFIG_IP_MASQ_QUAKE
208 printk("Quake_out: length < 0xc \n");
209 #endif
210 return 0;
213 data = &qh->message[1];
215 /* Check for stomping string */
216 if(memcmp(data,"QUAKE\0\3",7)) {
217 #if DEBUG_CONFIG_IP_MASQ_QUAKE
218 printk("Quake_out: memcmp failed \n");
219 #endif
220 return 0;
222 else {
223 priv->cl_connect = 1;
224 #if DEBUG_CONFIG_IP_MASQ_QUAKE
225 printk("Quake_out: memcmp ok \n");
226 #endif
228 break;
230 case 0x81:
231 /* Accept Connection */
232 if((ntohs(qh->length) < 0x09) || (priv->cl_connect == 0))
233 return 0;
235 data = &qh->message[1];
237 memcpy(&udp_port, data, 2);
239 n_ms = ip_masq_new(IPPROTO_UDP,
240 maddr, 0,
241 ms->saddr, htons(udp_port),
242 ms->daddr, ms->dport,
245 if (n_ms==NULL)
246 return 0;
248 #if DEBUG_CONFIG_IP_MASQ_QUAKE
249 printk("Quake_out: out_rewrote UDP port %d -> %d\n",
250 udp_port, ntohs(n_ms->mport));
251 #endif
252 udp_port = ntohs(n_ms->mport);
253 memcpy(data, &udp_port, 2);
255 ip_masq_listen(n_ms);
256 ip_masq_control_add(n_ms, ms);
257 ip_masq_put(n_ms);
259 break;
262 return 0;
265 struct ip_masq_app ip_masq_quake = {
266 NULL, /* next */
267 "Quake_26", /* name */
268 0, /* type */
269 0, /* n_attach */
270 masq_quake_init_1, /* ip_masq_init_1 */
271 masq_quake_done_1, /* ip_masq_done_1 */
272 masq_quake_out, /* pkt_out */
273 masq_quake_in /* pkt_in */
275 struct ip_masq_app ip_masq_quakenew = {
276 NULL, /* next */
277 "Quake_27", /* name */
278 0, /* type */
279 0, /* n_attach */
280 masq_quake_init_1, /* ip_masq_init_1 */
281 masq_quake_done_1, /* ip_masq_done_1 */
282 masq_quake_out, /* pkt_out */
283 masq_quake_in /* pkt_in */
287 * ip_masq_quake initialization
290 __initfunc(int ip_masq_quake_init(void))
292 return (register_ip_masq_app(&ip_masq_quake, IPPROTO_UDP, 26000) +
293 register_ip_masq_app(&ip_masq_quakenew, IPPROTO_UDP, 27000));
297 * ip_masq_quake fin.
300 int ip_masq_quake_done(void)
302 return (unregister_ip_masq_app(&ip_masq_quake) +
303 unregister_ip_masq_app(&ip_masq_quakenew));
306 #ifdef MODULE
307 EXPORT_NO_SYMBOLS;
309 int init_module(void)
311 if (ip_masq_quake_init() != 0)
312 return -EIO;
313 return 0;
316 void cleanup_module(void)
318 if (ip_masq_quake_done() != 0)
319 printk("ip_masq_quake: can't remove module");
322 #endif /* MODULE */