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