1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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>
48#include <linux/in.h>
49#include <linux/ip.h>
50#include <linux/init.h>
51#include <net/protocol.h>
52#include <net/udp.h>
53
54
55#include <net/ip_masq.h>
56
57#pragma pack(1)
58
59typedef struct {
60 u_short dest_family;
61 u_short dest_port;
62 u_long dest_addr;
63 short family;
64 u_short port;
65 u_long addr;
66 u_long seq;
67 u_short msg;
68 u_short data_type;
69 u_short packet_len;
70} cu_header;
71
72
73typedef struct {
74 cu_header cu_head;
75 u_short client_count;
76 u_long seq_no;
77 char user_name[20];
78 char stuff[4];
79}oc_header;
80
81
82typedef struct {
83 u_long address;
84 char stuff[8];
85} client_info;
86#pragma pack()
87
88
89
90
91
92static int ports[MAX_MASQ_APP_PORTS] = {7648};
93struct ip_masq_app *masq_incarnations[MAX_MASQ_APP_PORTS];
94
95
96
97
98#ifdef CONFIG_IP_MASQ_DEBUG
99static int debug=0;
100MODULE_PARM(debug, "i");
101#endif
102
103MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_MASQ_APP_PORTS) "i");
104
105static int
106masq_cuseeme_init_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
107{
108 MOD_INC_USE_COUNT;
109 return 0;
110}
111
112static int
113masq_cuseeme_done_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
114{
115 MOD_DEC_USE_COUNT;
116 return 0;
117}
118
119int
120masq_cuseeme_out (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr)
121{
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]);
125 cu_header *cu_head;
126 char *data=(char *)&uh[1];
127
128 if (skb->len - ((unsigned char *) data - skb->h.raw) >= sizeof(cu_header))
129 {
130 cu_head = (cu_header *) data;
131
132 if( cu_head->addr )
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");
136 }
137 return 0;
138}
139
140int
141masq_cuseeme_in (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr)
142{
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]);
146 cu_header *cu_head;
147 oc_header *oc;
148 client_info *ci;
149 char *data=(char *)&uh[1];
150 u_short len = skb->len - ((unsigned char *) data - skb->h.raw);
151 int i, off;
152
153 if (len >= sizeof(cu_header))
154 {
155 cu_head = (cu_header *) data;
156 if(cu_head->dest_addr)
157 cu_head->dest_addr = (u_long) ms->saddr;
158 if(ntohs(cu_head->data_type)==101 && len > sizeof(oc_header))
159 {
160 oc = (oc_header * ) data;
161
162 off=sizeof(oc_header);
163 for(i=0;
164 (i < oc->client_count && off+sizeof(client_info) <= len);
165 i++)
166 {
167 ci=(client_info *)(data+off);
168 if(ci->address==(u_long) maddr)
169 {
170
171 ci->address = (u_long) ms->saddr;
172 break;
173 }
174 else
175 off+=sizeof(client_info);
176 }
177 }
178 }
179 return 0;
180}
181
182struct ip_masq_app ip_masq_cuseeme = {
183 NULL,
184 "cuseeme",
185 0,
186 0,
187 masq_cuseeme_init_1,
188 masq_cuseeme_done_1,
189 masq_cuseeme_out,
190 masq_cuseeme_in
191};
192
193
194
195
196
197
198__initfunc(int ip_masq_cuseeme_init(void))
199{
200 int i, j;
201
202 for (i=0; (i<MAX_MASQ_APP_PORTS); i++) {
203 if (ports[i]) {
204 if ((masq_incarnations[i] = kmalloc(sizeof(struct ip_masq_app),
205 GFP_KERNEL)) == NULL)
206 return -ENOMEM;
207 memcpy(masq_incarnations[i], &ip_masq_cuseeme, sizeof(struct ip_masq_app));
208 if ((j = register_ip_masq_app(masq_incarnations[i],
209 IPPROTO_UDP,
210 ports[i]))) {
211 return j;
212 }
213#if DEBUG_CONFIG_IP_MASQ_CUSEEME
214 IP_MASQ_DEBUG(1-debug, "CuSeeMe: loaded support on port[%d] = %d\n",
215 i, ports[i]);
216#endif
217 } else {
218
219 masq_incarnations[i] = NULL;
220 }
221 }
222 return 0;
223}
224
225
226
227
228
229int ip_masq_cuseeme_done(void)
230{
231 int i, j, k;
232
233 k=0;
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]))) {
237 k = j;
238 } else {
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]);
242 }
243 }
244 }
245 return k;
246}
247
248#ifdef MODULE
249EXPORT_NO_SYMBOLS;
250
251int init_module(void)
252{
253 if (ip_masq_cuseeme_init() != 0)
254 return -EIO;
255 return 0;
256}
257
258void cleanup_module(void)
259{
260 if (ip_masq_cuseeme_done() != 0)
261 IP_MASQ_DEBUG(1-debug, "ip_masq_cuseeme: can't remove module");
262}
263
264#endif
265