2 * IP_MASQ_FTP CUSeeMe masquerading module
5 * Version: @(#)$Id: ip_masq_cuseeme.c,v 1.4 1998/10/06 04:48:57 davem Exp $
7 * Author: Richard Lynch
11 * Richard Lynch : Updated patch to conform to new module
13 * Nigel Metheringham : Multiple port support
14 * Michael Owings : Fixed broken init code
15 * Added code to update inbound
16 * packets with correct local addresses.
17 * Fixes audio and "chat" problems
18 * Thanx to the CU-SeeMe Consortium for
20 * Steven Clarke : Small changes for 2.1
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * as published by the Free Software Foundation; either version
27 * 2 of the License, or (at your option) any later version.
29 * Multiple Port Support
30 * The helper can be made to handle up to MAX_MASQ_APP_PORTS (normally 12)
31 * with the port numbers being defined at module load time. The module
32 * uses the symbol "ports" to define a list of monitored ports, which can
33 * be specified on the insmod command line as
35 * where x[n] are integer port numbers. This option can be put into
36 * /etc/conf.modules (or /etc/modules.conf depending on your config)
37 * where modload will pick it up should you use modload to load your
42 #include <linux/config.h>
43 #include <linux/module.h>
44 #include <asm/system.h>
45 #include <linux/types.h>
46 #include <linux/kernel.h>
47 #include <linux/skbuff.h>
50 #include <linux/init.h>
51 #include <net/protocol.h>
54 /* #define IP_MASQ_NDEBUG */
55 #include <net/ip_masq.h>
58 /* CU-SeeMe Data Header */
72 /* Open Continue Header */
75 u_short client_count
; /* Number of client info structs */
78 char stuff
[4]; /* flags, version stuff, etc */
81 /* client info structures */
83 u_long address
; /* Client address */
84 char stuff
[8]; /* Flags, pruning bitfield, packet counts etc */
89 * List of ports (up to MAX_MASQ_APP_PORTS) to be handled by helper
90 * First port is set to the default port.
92 static int ports
[MAX_MASQ_APP_PORTS
] = {7648}; /* I rely on the trailing items being set to zero */
93 struct ip_masq_app
*masq_incarnations
[MAX_MASQ_APP_PORTS
];
98 #ifdef CONFIG_IP_MASQ_DEBUG
100 MODULE_PARM(debug
, "i");
103 MODULE_PARM(ports
, "1-" __MODULE_STRING(MAX_MASQ_APP_PORTS
) "i");
106 masq_cuseeme_init_1 (struct ip_masq_app
*mapp
, struct ip_masq
*ms
)
113 masq_cuseeme_done_1 (struct ip_masq_app
*mapp
, struct ip_masq
*ms
)
120 masq_cuseeme_out (struct ip_masq_app
*mapp
, struct ip_masq
*ms
, struct sk_buff
**skb_p
, __u32 maddr
)
122 struct sk_buff
*skb
= *skb_p
;
123 struct iphdr
*iph
= skb
->nh
.iph
;
124 struct udphdr
*uh
= (struct udphdr
*)&(((char *)iph
)[iph
->ihl
*4]);
126 char *data
=(char *)&uh
[1];
128 if (skb
->len
- ((unsigned char *) data
- skb
->h
.raw
) >= sizeof(cu_header
))
130 cu_head
= (cu_header
*) data
;
131 /* cu_head->port = ms->mport; */
133 cu_head
->addr
= (u_long
) maddr
;
134 if(ntohs(cu_head
->data_type
) == 257)
135 IP_MASQ_DEBUG(1-debug
, "Sending talk packet!\n");
141 masq_cuseeme_in (struct ip_masq_app
*mapp
, struct ip_masq
*ms
, struct sk_buff
**skb_p
, __u32 maddr
)
143 struct sk_buff
*skb
= *skb_p
;
144 struct iphdr
*iph
= skb
->nh
.iph
;
145 struct udphdr
*uh
= (struct udphdr
*)&(((char *)iph
)[iph
->ihl
*4]);
149 char *data
=(char *)&uh
[1];
150 u_short len
= skb
->len
- ((unsigned char *) data
- skb
->h
.raw
);
153 if (len
>= sizeof(cu_header
))
155 cu_head
= (cu_header
*) data
;
156 if(cu_head
->dest_addr
) /* Correct destination address */
157 cu_head
->dest_addr
= (u_long
) ms
->saddr
;
158 if(ntohs(cu_head
->data_type
)==101 && len
> sizeof(oc_header
))
160 oc
= (oc_header
* ) data
;
161 /* Spin (grovel) thru client_info structs till we find our own */
162 off
=sizeof(oc_header
);
164 (i
< oc
->client_count
&& off
+sizeof(client_info
) <= len
);
167 ci
=(client_info
*)(data
+off
);
168 if(ci
->address
==(u_long
) maddr
)
170 /* Update w/ our real ip address and exit */
171 ci
->address
= (u_long
) ms
->saddr
;
175 off
+=sizeof(client_info
);
182 struct ip_masq_app ip_masq_cuseeme
= {
187 masq_cuseeme_init_1
, /* ip_masq_init_1 */
188 masq_cuseeme_done_1
, /* ip_masq_done_1 */
189 masq_cuseeme_out
, /* pkt_out */
190 masq_cuseeme_in
/* pkt_in */
195 * ip_masq_cuseeme initialization
198 __initfunc(int ip_masq_cuseeme_init(void))
202 for (i
=0; (i
<MAX_MASQ_APP_PORTS
); i
++) {
204 if ((masq_incarnations
[i
] = kmalloc(sizeof(struct ip_masq_app
),
205 GFP_KERNEL
)) == NULL
)
207 memcpy(masq_incarnations
[i
], &ip_masq_cuseeme
, sizeof(struct ip_masq_app
));
208 if ((j
= register_ip_masq_app(masq_incarnations
[i
],
213 #if DEBUG_CONFIG_IP_MASQ_CUSEEME
214 IP_MASQ_DEBUG(1-debug
, "CuSeeMe: loaded support on port[%d] = %d\n",
218 /* To be safe, force the incarnation table entry to NULL */
219 masq_incarnations
[i
] = NULL
;
226 * ip_masq_cuseeme fin.
229 int ip_masq_cuseeme_done(void)
234 for (i
=0; (i
<MAX_MASQ_APP_PORTS
); i
++) {
235 if (masq_incarnations
[i
]) {
236 if ((j
= unregister_ip_masq_app(masq_incarnations
[i
]))) {
239 kfree(masq_incarnations
[i
]);
240 masq_incarnations
[i
] = NULL
;
241 IP_MASQ_DEBUG(1-debug
, "CuSeeMe: unloaded support on port[%d] = %d\n", i
, ports
[i
]);
251 int init_module(void)
253 if (ip_masq_cuseeme_init() != 0)
258 void cleanup_module(void)
260 if (ip_masq_cuseeme_done() != 0)
261 IP_MASQ_DEBUG(1-debug
, "ip_masq_cuseeme: can't remove module");