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
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>
33 #include <linux/init.h>
34 #include <net/protocol.h>
36 #include <net/ip_masq.h>
38 #define DEBUG_CONFIG_IP_MASQ_QUAKE 0
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.
47 struct quake_priv_data
{
48 /* Have we seen a client connect message */
49 signed char cl_connect
;
53 masq_quake_init_1 (struct ip_masq_app
*mapp
, struct ip_masq
*ms
)
56 if ((ms
->app_data
= kmalloc(sizeof(struct quake_priv_data
),
58 printk(KERN_INFO
"Quake: No memory for application data\n");
61 struct quake_priv_data
*priv
=
62 (struct quake_priv_data
*)ms
->app_data
;
69 masq_quake_done_1 (struct ip_masq_app
*mapp
, struct ip_masq
*ms
)
73 kfree_s(ms
->app_data
, sizeof(struct quake_priv_data
));
78 masq_quake_in (struct ip_masq_app
*mapp
, struct ip_masq
*ms
, struct sk_buff
**skb_p
, __u32 maddr
)
87 struct quake_priv_data
*priv
= (struct quake_priv_data
*)ms
->app_data
;
89 if(priv
->cl_connect
== -1)
95 uh
= (struct udphdr
*)&(((char *)iph
)[iph
->ihl
*4]);
97 /* Check for lenght */
98 if(ntohs(uh
->len
) < 5)
101 qh
= (QUAKEHEADER
*)&uh
[1];
103 if(qh
->type
!= 0x0080)
107 code
= qh
->message
[0];
109 #if DEBUG_CONFIG_IP_MASQ_QUAKE
110 printk("Quake_in: code = %d \n", (int)code
);
115 /* Connection Request */
117 if(ntohs(qh
->length
) < 0x0c) {
118 #if DEBUG_CONFIG_IP_MASQ_QUAKE
119 printk("Quake_in: length < 0xc \n");
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");
134 priv
->cl_connect
= 1;
135 #if DEBUG_CONFIG_IP_MASQ_QUAKE
136 printk("Quake_out: memcmp ok \n");
142 /* Accept Connection */
143 if((ntohs(qh
->length
) < 0x09) || (priv
->cl_connect
== 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
);
154 priv
->cl_connect
= -1;
163 masq_quake_out (struct ip_masq_app
*mapp
, struct ip_masq
*ms
, struct sk_buff
**skb_p
, __u32 maddr
)
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)
181 uh
= (struct udphdr
*)&(((char *)iph
)[iph
->ihl
*4]);
183 /* Check for lenght */
184 if(ntohs(uh
->len
) < 5)
187 qh
= (QUAKEHEADER
*)&uh
[1];
189 #if DEBUG_CONFIG_IP_MASQ_QUAKE
190 printk("Quake_out: qh->type = %d \n", (int)qh
->type
);
193 if(qh
->type
!= 0x0080)
196 code
= qh
->message
[0];
198 #if DEBUG_CONFIG_IP_MASQ_QUAKE
199 printk("Quake_out: code = %d \n", (int)code
);
204 /* Connection Request */
206 if(ntohs(qh
->length
) < 0x0c) {
207 #if DEBUG_CONFIG_IP_MASQ_QUAKE
208 printk("Quake_out: length < 0xc \n");
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");
223 priv
->cl_connect
= 1;
224 #if DEBUG_CONFIG_IP_MASQ_QUAKE
225 printk("Quake_out: memcmp ok \n");
231 /* Accept Connection */
232 if((ntohs(qh
->length
) < 0x09) || (priv
->cl_connect
== 0))
235 data
= &qh
->message
[1];
237 memcpy(&udp_port
, data
, 2);
239 n_ms
= ip_masq_new(IPPROTO_UDP
,
241 ms
->saddr
, htons(udp_port
),
242 ms
->daddr
, ms
->dport
,
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
));
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
);
265 struct ip_masq_app ip_masq_quake
= {
267 "Quake_26", /* name */
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
= {
277 "Quake_27", /* name */
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));
300 int ip_masq_quake_done(void)
302 return (unregister_ip_masq_app(&ip_masq_quake
) +
303 unregister_ip_masq_app(&ip_masq_quakenew
));
309 int init_module(void)
311 if (ip_masq_quake_init() != 0)
316 void cleanup_module(void)
318 if (ip_masq_quake_done() != 0)
319 printk("ip_masq_quake: can't remove module");