This source file includes following definitions.
- masq_proto_name
- ip_masq_hash_key
- ip_masq_hash
- ip_masq_unhash
- ip_masq_in_get
- ip_masq_out_get
- ip_masq_getbym
- masq_expire
- ip_masq_new
- ip_masq_set_expire
- recalc_check
- ip_fw_masquerade
- ip_fw_demasquerade
- ip_msqhst_procinfo
- ip_masq_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <linux/module.h>
20 #include <linux/types.h>
21 #include <linux/kernel.h>
22 #include <linux/errno.h>
23 #include <linux/skbuff.h>
24 #include <asm/system.h>
25 #include <linux/stat.h>
26 #include <linux/proc_fs.h>
27 #include <linux/in.h>
28 #include <linux/ip.h>
29 #include <net/protocol.h>
30 #include <net/tcp.h>
31 #include <net/udp.h>
32 #include <net/ip_masq.h>
33
34 #define IP_MASQ_TAB_SIZE 256
35
36
37
38
39
40 static const char *strProt[] = {"UDP","TCP"};
41
42 static __inline__ const char * masq_proto_name(unsigned proto)
43 {
44 return strProt[proto==IPPROTO_TCP];
45 }
46
47
48
49
50
51 static __u16 masq_port = PORT_MASQ_BEGIN;
52
53
54
55
56
57
58
59
60
61
62
63
64
65 int ip_masq_free_ports[2] = {
66 PORT_MASQ_END - PORT_MASQ_BEGIN,
67 PORT_MASQ_END - PORT_MASQ_BEGIN
68 };
69
70 static struct symbol_table ip_masq_syms = {
71 #include <linux/symtab_begin.h>
72 X(ip_masq_new),
73 X(ip_masq_set_expire),
74 X(ip_masq_free_ports),
75 #include <linux/symtab_end.h>
76 };
77
78
79
80
81
82 struct ip_masq *ip_masq_m_tab[IP_MASQ_TAB_SIZE];
83 struct ip_masq *ip_masq_s_tab[IP_MASQ_TAB_SIZE];
84
85
86
87
88
89 static __inline__ unsigned
90
91 ip_masq_hash_key(unsigned proto, __u32 addr, __u16 port)
92 {
93 return (proto^ntohl(addr)^ntohs(port)) & (IP_MASQ_TAB_SIZE-1);
94 }
95
96
97
98
99
100
101
102 static __inline__ int
103 ip_masq_hash(struct ip_masq *ms)
104 {
105 unsigned hash;
106
107 if (ms->flags & IP_MASQ_F_HASHED) {
108 printk("ip_masq_hash(): request for already hashed\n");
109 return 0;
110 }
111
112
113
114 hash = ip_masq_hash_key(ms->protocol, ms->maddr, ms->mport);
115 ms->m_link = ip_masq_m_tab[hash];
116 ip_masq_m_tab[hash] = ms;
117
118
119
120
121 hash = ip_masq_hash_key(ms->protocol, ms->saddr, ms->sport);
122 ms->s_link = ip_masq_s_tab[hash];
123 ip_masq_s_tab[hash] = ms;
124
125
126 ms->flags |= IP_MASQ_F_HASHED;
127 return 1;
128 }
129
130
131
132
133
134
135
136 static __inline__ int ip_masq_unhash(struct ip_masq *ms)
137 {
138 unsigned hash;
139 struct ip_masq ** ms_p;
140 if (!(ms->flags & IP_MASQ_F_HASHED)) {
141 printk("ip_masq_unhash(): request for unhash flagged\n");
142 return 0;
143 }
144
145
146
147 hash = ip_masq_hash_key(ms->protocol, ms->maddr, ms->mport);
148 for (ms_p = &ip_masq_m_tab[hash]; *ms_p ; ms_p = &(*ms_p)->m_link)
149 if (ms == (*ms_p)) {
150 *ms_p = ms->m_link;
151 break;
152 }
153
154
155
156 hash = ip_masq_hash_key(ms->protocol, ms->saddr, ms->sport);
157 for (ms_p = &ip_masq_s_tab[hash]; *ms_p ; ms_p = &(*ms_p)->s_link)
158 if (ms == (*ms_p)) {
159 *ms_p = ms->s_link;
160 break;
161 }
162
163 ms->flags &= ~IP_MASQ_F_HASHED;
164 return 1;
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178 struct ip_masq *
179 ip_masq_in_get(struct iphdr *iph)
180 {
181 unsigned hash;
182 struct ip_masq *ms;
183 __u16 *portptr;
184 int protocol;
185 __u32 s_addr, d_addr;
186 __u16 s_port, d_port;
187
188 portptr = (__u16 *)&(((char *)iph)[iph->ihl*4]);
189 protocol = iph->protocol;
190 s_addr = iph->saddr;
191 s_port = portptr[0];
192 d_addr = iph->daddr;
193 d_port = portptr[1];
194
195 hash = ip_masq_hash_key(protocol, d_addr, d_port);
196 for(ms = ip_masq_m_tab[hash]; ms ; ms = ms->m_link) {
197 if ( protocol==ms->protocol &&
198 (s_addr==ms->daddr || ms->flags & IP_MASQ_F_NO_DADDR) &&
199 (s_port==ms->dport || ms->flags & IP_MASQ_F_NO_DPORT) &&
200 (d_addr==ms->maddr && d_port==ms->mport))
201 return ms;
202 }
203 return NULL;
204 }
205
206
207
208
209
210
211 struct ip_masq *
212 ip_masq_out_get(struct iphdr *iph)
213 {
214 unsigned hash;
215 struct ip_masq *ms;
216 __u16 *portptr;
217 int protocol;
218 __u32 s_addr, d_addr;
219 __u16 s_port, d_port;
220
221 portptr = (__u16 *)&(((char *)iph)[iph->ihl*4]);
222 protocol = iph->protocol;
223 s_addr = iph->saddr;
224 s_port = portptr[0];
225 d_addr = iph->daddr;
226 d_port = portptr[1];
227
228 hash = ip_masq_hash_key(protocol, s_addr, s_port);
229 for(ms = ip_masq_s_tab[hash]; ms ; ms = ms->s_link) {
230 if (protocol == ms->protocol &&
231 s_addr == ms->saddr && s_port == ms->sport &&
232 d_addr == ms->daddr && d_port == ms->dport )
233 return ms;
234 }
235
236 return NULL;
237 }
238
239
240
241
242
243
244 struct ip_masq *
245 ip_masq_getbym(int protocol, __u32 m_addr, __u16 m_port)
246 {
247 unsigned hash;
248 struct ip_masq *ms;
249
250 hash = ip_masq_hash_key(protocol, m_addr, m_port);
251 for(ms = ip_masq_m_tab[hash]; ms ; ms = ms->m_link) {
252 if ( protocol==ms->protocol &&
253 (m_addr==ms->maddr && m_port==ms->mport))
254 return ms;
255 }
256 return NULL;
257 }
258
259 static void masq_expire(unsigned long data)
260 {
261 struct ip_masq *ms = (struct ip_masq *)data;
262 unsigned long flags;
263
264 #ifdef DEBUG_CONFIG_IP_MASQUERADE
265 printk("Masqueraded %s %lX:%X expired\n",
266 masq_proto_name(ms->protocol),
267 ntohl(ms->src),ntohs(ms->sport));
268 #endif
269
270 save_flags(flags);
271 cli();
272
273 if (ip_masq_unhash(ms)) {
274 ip_masq_free_ports[ms->protocol==IPPROTO_TCP]++;
275 ip_masq_unbind_app(ms);
276 kfree_s(ms,sizeof(*ms));
277 }
278
279 restore_flags(flags);
280 }
281
282
283
284
285
286
287
288 struct ip_masq * ip_masq_new(struct device *dev, int proto, __u32 saddr, __u16 sport, __u32 daddr, __u16 dport, unsigned mflags)
289 {
290 struct ip_masq *ms, *mst;
291 int ports_tried, *free_ports_p;
292 unsigned long flags;
293 static int n_fails = 0;
294
295 free_ports_p = &ip_masq_free_ports[proto==IPPROTO_TCP];
296
297 if (*free_ports_p == 0) {
298 if (++n_fails < 5)
299 printk("ip_masq_new(proto=%s): no free ports.\n",
300 masq_proto_name(proto));
301 return NULL;
302 }
303 ms = (struct ip_masq *) kmalloc(sizeof(struct ip_masq), GFP_ATOMIC);
304 if (ms == NULL) {
305 if (++n_fails < 5)
306 printk("ip_masq_new(proto=%s): no memory available.\n",
307 masq_proto_name(proto));
308 return NULL;
309 }
310 memset(ms, 0, sizeof(*ms));
311 init_timer(&ms->timer);
312 ms->timer.data = (unsigned long)ms;
313 ms->timer.function = masq_expire;
314 ms->protocol = proto;
315 ms->saddr = saddr;
316 ms->sport = sport;
317 ms->daddr = daddr;
318 ms->dport = dport;
319 ms->flags = mflags;
320
321 if (proto == IPPROTO_UDP)
322 ms->flags |= IP_MASQ_F_NO_DADDR;
323
324
325 ms->maddr = dev->pa_addr;
326
327 for (ports_tried = 0; ports_tried < *free_ports_p; ports_tried++){
328 save_flags(flags);
329 cli();
330
331
332
333
334
335 ms->mport = htons(masq_port++);
336 if (masq_port==PORT_MASQ_END) masq_port = PORT_MASQ_BEGIN;
337
338 restore_flags(flags);
339
340
341
342
343
344 mst = ip_masq_getbym(proto, ms->maddr, ms->mport);
345 if (mst == NULL) {
346 save_flags(flags);
347 cli();
348
349 if (*free_ports_p == 0) {
350 restore_flags(flags);
351 break;
352 }
353 (*free_ports_p)--;
354 ip_masq_hash(ms);
355
356 restore_flags(flags);
357
358 ip_masq_bind_app(ms);
359 n_fails = 0;
360 return ms;
361 }
362 }
363
364 if (++n_fails < 5)
365 printk("ip_masq_new(proto=%s): could not get free masq entry (free=%d).\n",
366 masq_proto_name(ms->protocol), *free_ports_p);
367 kfree_s(ms, sizeof(*ms));
368 return NULL;
369 }
370
371
372
373
374
375
376
377 void ip_masq_set_expire(struct ip_masq *ms, unsigned long tout)
378 {
379 if (tout) {
380 ms->timer.expires = jiffies+tout;
381 add_timer(&ms->timer);
382 } else {
383 del_timer(&ms->timer);
384 }
385 }
386
387 static void recalc_check(struct udphdr *uh, __u32 saddr,
388 __u32 daddr, int len)
389 {
390 uh->check=0;
391 uh->check=csum_tcpudp_magic(saddr,daddr,len,
392 IPPROTO_UDP, csum_partial((char *)uh,len,0));
393 if(uh->check==0)
394 uh->check=0xFFFF;
395 }
396
397 void ip_fw_masquerade(struct sk_buff **skb_ptr, struct device *dev)
398 {
399 struct sk_buff *skb=*skb_ptr;
400 struct iphdr *iph = skb->h.iph;
401 __u16 *portptr;
402 struct ip_masq *ms;
403 int size;
404 unsigned long timeout;
405
406
407
408
409
410 if (iph->protocol!=IPPROTO_UDP && iph->protocol!=IPPROTO_TCP)
411 return;
412
413
414
415
416
417 portptr = (__u16 *)&(((char *)iph)[iph->ihl*4]);
418 #ifdef DEBUG_CONFIG_IP_MASQUERADE
419 printk("Outgoing %s %lX:%X -> %lX:%X\n",
420 masq_proto_name(iph->protocol),
421 ntohl(iph->saddr), ntohs(portptr[0]),
422 ntohl(iph->daddr), ntohs(portptr[1]));
423 #endif
424
425 ms = ip_masq_out_get(iph);
426 if (ms!=NULL)
427 ip_masq_set_expire(ms,0);
428
429
430
431
432
433 if (ms==NULL)
434 {
435 ms = ip_masq_new(dev, iph->protocol,
436 iph->saddr, portptr[0],
437 iph->daddr, portptr[1],
438 0);
439 if (ms == NULL)
440 return;
441 }
442
443
444
445
446
447 size = skb->len - ((unsigned char *)portptr - skb->h.raw);
448
449
450
451 iph->saddr = ms->maddr;
452 portptr[0] = ms->mport;
453
454
455
456
457
458 if (ip_masq_app_pkt_out(ms, skb_ptr, dev) != 0)
459 {
460
461
462
463 skb = *skb_ptr;
464 iph = skb->h.iph;
465 portptr = (__u16 *)&(((char *)iph)[iph->ihl*4]);
466 size = skb->len - ((unsigned char *)portptr-skb->h.raw);
467 }
468
469
470
471
472
473 if (iph->protocol==IPPROTO_UDP)
474 {
475 timeout = MASQUERADE_EXPIRE_UDP;
476 recalc_check((struct udphdr *)portptr,iph->saddr,iph->daddr,size);
477 }
478 else
479 {
480 struct tcphdr *th;
481 th = (struct tcphdr *)portptr;
482
483
484
485
486 if (ms->flags & IP_MASQ_F_SAW_FIN || th->fin)
487 {
488 timeout = MASQUERADE_EXPIRE_TCP_FIN;
489 ms->flags |= IP_MASQ_F_SAW_FIN;
490 }
491 else timeout = MASQUERADE_EXPIRE_TCP;
492
493 skb->csum = csum_partial((void *)(th + 1), size - sizeof(*th), 0);
494 tcp_send_check(th,iph->saddr,iph->daddr,size,skb);
495 }
496 ip_masq_set_expire(ms, timeout);
497 ip_send_check(iph);
498
499 #ifdef DEBUG_CONFIG_IP_MASQUERADE
500 printk("O-routed from %lX:%X over %s\n",ntohl(ms->maddr),ntohs(ms->mport),dev->name);
501 #endif
502 }
503
504
505
506
507
508
509
510
511
512
513 int ip_fw_demasquerade(struct sk_buff **skb_p, struct device *dev)
514 {
515 struct sk_buff *skb = *skb_p;
516 struct iphdr *iph = skb->h.iph;
517 __u16 *portptr;
518 struct ip_masq *ms;
519
520 if (iph->protocol!=IPPROTO_UDP && iph->protocol!=IPPROTO_TCP)
521 return 0;
522
523 portptr = (__u16 *)&(((char *)iph)[iph->ihl*4]);
524 if (ntohs(portptr[1]) < PORT_MASQ_BEGIN ||
525 ntohs(portptr[1]) > PORT_MASQ_END)
526 return 0;
527
528 #ifdef DEBUG_CONFIG_IP_MASQUERADE
529 printk("Incoming %s %lX:%X -> %lX:%X\n",
530 masq_proto_name(iph->protocol),
531 ntohl(iph->saddr), ntohs(portptr[0]),
532 ntohl(iph->daddr), ntohs(portptr[1]));
533 #endif
534
535
536
537
538 ms = ip_masq_in_get(iph);
539
540 if (ms != NULL)
541 {
542 int size;
543
544
545
546
547
548 if ( ms->flags & IP_MASQ_F_NO_DPORT && ms->protocol == IPPROTO_TCP ) {
549 ms->flags &= ~IP_MASQ_F_NO_DPORT;
550 ms->dport = portptr[0];
551 #if DEBUG_CONFIG_IP_MASQUERADE
552 printk("ip_fw_demasquerade(): filled dport=%d\n",
553 ntohs(ms->dport));
554 #endif
555 }
556 if (ms->flags & IP_MASQ_F_NO_DADDR && ms->protocol == IPPROTO_TCP) {
557 ms->flags &= ~IP_MASQ_F_NO_DADDR;
558 ms->daddr = iph->saddr;
559 #if DEBUG_CONFIG_IP_MASQUERADE
560 printk("ip_fw_demasquerade(): filled daddr=%X\n",
561 ntohs(ms->daddr));
562 #endif
563 }
564 size = skb->len - ((unsigned char *)portptr - skb->h.raw);
565 iph->daddr = ms->saddr;
566 portptr[1] = ms->sport;
567
568
569
570
571
572
573 if (ip_masq_app_pkt_in(ms, skb_p, dev) != 0)
574 {
575
576
577
578
579 skb = *skb_p;
580 iph = skb->h.iph;
581 portptr = (__u16 *)&(((char *)iph)[iph->ihl*4]);
582 size = skb->len - ((unsigned char *)portptr-skb->h.raw);
583 }
584
585
586
587
588 if (iph->protocol==IPPROTO_UDP)
589 recalc_check((struct udphdr *)portptr,iph->saddr,iph->daddr,size);
590 else
591 {
592 skb->csum = csum_partial((void *)(((struct tcphdr *)portptr) + 1),
593 size - sizeof(struct tcphdr), 0);
594 tcp_send_check((struct tcphdr *)portptr,iph->saddr,iph->daddr,size,skb);
595 }
596 ip_send_check(iph);
597 #ifdef DEBUG_CONFIG_IP_MASQUERADE
598 printk("I-routed to %lX:%X\n",ntohl(iph->daddr),ntohs(portptr[1]));
599 #endif
600 return 1;
601 }
602
603
604 return 0;
605 }
606
607
608
609
610
611 static int ip_msqhst_procinfo(char *buffer, char **start, off_t offset,
612 int length, int unused)
613 {
614 off_t pos=0, begin=0;
615 struct ip_masq *ms;
616 unsigned long flags;
617 int idx = 0;
618 int len=0;
619
620 len=sprintf(buffer,"Prc FromIP FPrt ToIP TPrt Masq Init-seq Delta PDelta Expires (free=%d,%d)\n",
621 ip_masq_free_ports[0], ip_masq_free_ports[1]);
622 save_flags(flags);
623 cli();
624
625 for(idx = 0; idx < IP_MASQ_TAB_SIZE; idx++)
626 for(ms = ip_masq_m_tab[idx]; ms ; ms = ms->m_link)
627 {
628 int timer_active = del_timer(&ms->timer);
629 if (!timer_active)
630 ms->timer.expires = jiffies;
631 len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08X %6d %6d %lu\n",
632 masq_proto_name(ms->protocol),
633 ntohl(ms->saddr),ntohs(ms->sport),
634 ntohl(ms->daddr),ntohs(ms->dport),
635 ntohs(ms->mport),
636 ms->out_seq.init_seq,ms->out_seq.delta,ms->out_seq.previous_delta,ms->timer.expires-jiffies);
637 if (timer_active)
638 add_timer(&ms->timer);
639
640 pos=begin+len;
641 if(pos<offset)
642 {
643 len=0;
644 begin=pos;
645 }
646 if(pos>offset+length)
647 break;
648 }
649 restore_flags(flags);
650 *start=buffer+(offset-begin);
651 len-=(offset-begin);
652 if(len>length)
653 len=length;
654 return len;
655 }
656
657
658
659
660 int ip_masq_init(void)
661 {
662 register_symtab (&ip_masq_syms);
663 proc_net_register(&(struct proc_dir_entry) {
664 PROC_NET_IPMSQHST, 13, "ip_masquerade",
665 S_IFREG | S_IRUGO, 1, 0, 0,
666 0, &proc_net_inode_operations,
667 ip_msqhst_procinfo
668 });
669 ip_masq_app_init();
670
671 return 0;
672 }