This source file includes following definitions.
- port_match
- ip_fw_chk
- masq_expire
- alloc_masq_entry
- revamp
- recalc_check
- ip_fw_masquerade
- ip_fw_demasquerade
- zero_fw_chain
- free_fw_chain
- add_to_chain
- del_from_chain
- check_ipfw_struct
- ip_acct_cnt
- ip_acct_ctl
- ip_fw_ctl
- ip_chain_procinfo
- ip_acct_procinfo
- ip_fw_blk_procinfo
- ip_fw_fwd_procinfo
- ip_msqhst_procinfo
- ip_fw_init
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 #include <linux/config.h>
65 #include <asm/segment.h>
66 #include <asm/system.h>
67 #include <linux/types.h>
68 #include <linux/kernel.h>
69 #include <linux/sched.h>
70 #include <linux/string.h>
71 #include <linux/errno.h>
72 #include <linux/config.h>
73
74 #include <linux/socket.h>
75 #include <linux/sockios.h>
76 #include <linux/in.h>
77 #include <linux/inet.h>
78 #include <linux/netdevice.h>
79 #include <linux/icmp.h>
80 #include <linux/udp.h>
81 #include <net/ip.h>
82 #include <net/protocol.h>
83 #include <net/route.h>
84 #include <net/tcp.h>
85 #include <net/udp.h>
86 #include <linux/skbuff.h>
87 #include <net/sock.h>
88 #include <net/icmp.h>
89 #include <linux/ip_fw.h>
90 #include <net/checksum.h>
91 #include <linux/proc_fs.h>
92 #include <linux/stat.h>
93
94
95
96
97
98 #ifdef CONFIG_IPFIREWALL_DEBUG
99 #define dprintf1(a) printk(a)
100 #define dprintf2(a1,a2) printk(a1,a2)
101 #define dprintf3(a1,a2,a3) printk(a1,a2,a3)
102 #define dprintf4(a1,a2,a3,a4) printk(a1,a2,a3,a4)
103 #else
104 #define dprintf1(a)
105 #define dprintf2(a1,a2)
106 #define dprintf3(a1,a2,a3)
107 #define dprintf4(a1,a2,a3,a4)
108 #endif
109
110 #define print_ip(a) printk("%ld.%ld.%ld.%ld",(ntohl(a)>>24)&0xFF,\
111 (ntohl(a)>>16)&0xFF,\
112 (ntohl(a)>>8)&0xFF,\
113 (ntohl(a))&0xFF);
114
115 #ifdef IPFIREWALL_DEBUG
116 #define dprint_ip(a) print_ip(a)
117 #else
118 #define dprint_ip(a)
119 #endif
120
121 #ifdef CONFIG_IP_FIREWALL
122 struct ip_fw *ip_fw_fwd_chain;
123 struct ip_fw *ip_fw_blk_chain;
124 int ip_fw_blk_policy=IP_FW_F_ACCEPT;
125 int ip_fw_fwd_policy=IP_FW_F_ACCEPT;
126 #endif
127 #ifdef CONFIG_IP_ACCT
128 struct ip_fw *ip_acct_chain;
129 #endif
130
131 #define IP_INFO_BLK 0
132 #define IP_INFO_FWD 1
133 #define IP_INFO_ACCT 2
134
135 #ifdef CONFIG_IP_MASQUERADE
136
137
138
139
140 static unsigned short masq_port = PORT_MASQ_BEGIN;
141 static const char *strProt[] = {"UDP","TCP"};
142 struct ip_masq *ip_msq_hosts;
143
144 #endif
145
146
147
148
149
150 extern inline int port_match(unsigned short *portptr,int nports,unsigned short port,int range_flag)
151 {
152 if (!nports)
153 return 1;
154 if ( range_flag )
155 {
156 if ( portptr[0] <= port && port <= portptr[1] )
157 {
158 return( 1 );
159 }
160 nports -= 2;
161 portptr += 2;
162 }
163 while ( nports-- > 0 )
164 {
165 if ( *portptr++ == port )
166 {
167 return( 1 );
168 }
169 }
170 return(0);
171 }
172
173 #if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
174
175
176
177
178
179
180
181
182
183
184
185
186
187 int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int policy, int opt)
188 {
189 struct ip_fw *f;
190 struct tcphdr *tcp=(struct tcphdr *)((unsigned long *)ip+ip->ihl);
191 struct udphdr *udp=(struct udphdr *)((unsigned long *)ip+ip->ihl);
192 struct icmphdr *icmp=(struct icmphdr *)((unsigned long *)ip+ip->ihl);
193 __u32 src, dst;
194 __u16 src_port=0, dst_port=0, icmp_type=0;
195 unsigned short f_prt=0, prt;
196 char notcpsyn=1, notcpack=1, match;
197 unsigned short f_flag;
198 unsigned short offset;
199
200
201
202
203
204
205
206 src = ip->saddr;
207 dst = ip->daddr;
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223 offset = ntohs(ip->frag_off) & IP_OFFSET;
224
225
226
227
228
229
230
231
232 if (offset == 1 && ip->protocol == IPPROTO_TCP)
233 return FW_BLOCK;
234
235 if (offset!=0 && (opt != 1) && (ip->protocol == IPPROTO_TCP ||
236 ip->protocol == IPPROTO_UDP))
237 return FW_ACCEPT;
238
239
240
241
242
243 if(ip->protocol==IPPROTO_TCP && (ip->ihl<<2)+16 > ntohs(ip->tot_len))
244 return FW_BLOCK;
245
246
247
248
249
250 else if(ntohs(ip->tot_len)<8+(ip->ihl<<2))
251 return FW_BLOCK;
252
253 src = ip->saddr;
254 dst = ip->daddr;
255
256
257
258
259
260
261
262
263
264 dprintf1("Packet ");
265 switch(ip->protocol)
266 {
267 case IPPROTO_TCP:
268 dprintf1("TCP ");
269
270 if (!offset) {
271 src_port=ntohs(tcp->source);
272 dst_port=ntohs(tcp->dest);
273 if(tcp->ack)
274
275 notcpack=0;
276 if(tcp->syn && notcpack)
277
278 notcpsyn=0;
279 }
280 prt=IP_FW_F_TCP;
281 break;
282 case IPPROTO_UDP:
283 dprintf1("UDP ");
284
285 if (!offset) {
286 src_port=ntohs(udp->source);
287 dst_port=ntohs(udp->dest);
288 }
289 prt=IP_FW_F_UDP;
290 break;
291 case IPPROTO_ICMP:
292 icmp_type=(__u16)(icmp->type);
293 dprintf2("ICMP:%d ",icmp_type);
294 prt=IP_FW_F_ICMP;
295 break;
296 default:
297 dprintf2("p=%d ",ip->protocol);
298 prt=IP_FW_F_ALL;
299 break;
300 }
301 #ifdef CONFIG_IP_FIREWALL_DEBUG
302 dprint_ip(ip->saddr);
303
304 if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP)
305
306 dprintf2(":%d ", src_port);
307 dprint_ip(ip->daddr);
308 if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP)
309
310 dprintf2(":%d ",dst_port);
311 dprintf1("\n");
312 #endif
313
314 for (f=chain;f;f=f->fw_next)
315 {
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333 match = 0x00;
334
335 if ((src&f->fw_smsk.s_addr)==f->fw_src.s_addr
336 && (dst&f->fw_dmsk.s_addr)==f->fw_dst.s_addr)
337
338 match |= 0x01;
339
340 if ((f->fw_flg & IP_FW_F_BIDIR) &&
341 (dst&f->fw_smsk.s_addr)==f->fw_src.s_addr
342 && (src&f->fw_dmsk.s_addr)==f->fw_dst.s_addr)
343
344 match |= 0x02;
345
346 if (match)
347 {
348
349
350
351 if(f->fw_via.s_addr && rif)
352 {
353 if(rif->pa_addr!=f->fw_via.s_addr)
354 continue;
355 }
356
357
358
359 }
360 else
361 continue;
362
363
364
365
366
367 f_prt=f->fw_flg&IP_FW_F_KIND;
368 if (f_prt!=IP_FW_F_ALL)
369 {
370
371
372
373
374
375
376
377 if((f->fw_flg&IP_FW_F_TCPSYN) && notcpsyn)
378 continue;
379
380
381
382
383
384
385
386
387 if((f->fw_flg&IP_FW_F_TCPACK) && notcpack)
388 if(f->fw_flg&IP_FW_F_BIDIR) {
389 if(match & 0x02)
390 continue;
391 } else
392 continue;
393
394
395
396
397
398
399 if(prt!=f_prt)
400 continue;
401
402 if((prt==IP_FW_F_ICMP &&
403 ! port_match(&f->fw_pts[0], f->fw_nsp,
404 icmp_type,f->fw_flg&IP_FW_F_SRNG)) ||
405 !(prt==IP_FW_F_ICMP || ((match & 0x01) &&
406 port_match(&f->fw_pts[0], f->fw_nsp, src_port,
407 f->fw_flg&IP_FW_F_SRNG) &&
408 port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, dst_port,
409 f->fw_flg&IP_FW_F_DRNG)) || ((match & 0x02) &&
410 port_match(&f->fw_pts[0], f->fw_nsp, dst_port,
411 f->fw_flg&IP_FW_F_SRNG) &&
412 port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, src_port,
413 f->fw_flg&IP_FW_F_DRNG))))
414 {
415 continue;
416 }
417 }
418 #ifdef CONFIG_IP_FIREWALL_VERBOSE
419
420
421
422
423
424 if (f->fw_flg & IP_FW_F_PRN)
425 {
426 if(opt != 1) {
427 if(f->fw_flg&IP_FW_F_ACCEPT)
428 printk("Accept ");
429 else if(f->fw_flg&IP_FW_F_ICMPRPL)
430 printk("Reject ");
431 else
432 printk("Deny ");
433 }
434 switch(ip->protocol)
435 {
436 case IPPROTO_TCP:
437 printk("TCP ");
438 break;
439 case IPPROTO_UDP:
440 printk("UDP ");
441 case IPPROTO_ICMP:
442 printk("ICMP ");
443 break;
444 default:
445 printk("p=%d ",ip->protocol);
446 break;
447 }
448 print_ip(ip->saddr);
449 if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
450 printk(":%d", src_port);
451 printk(" ");
452 print_ip(ip->daddr);
453 if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
454 printk(":%d",dst_port);
455 printk("\n");
456 }
457 #endif
458 if (opt != 2) {
459 f->fw_bcnt+=ntohs(ip->tot_len);
460 f->fw_pcnt++;
461 }
462 if (opt != 1)
463 break;
464 }
465
466 if(opt == 1)
467 return 0;
468
469
470
471
472
473
474
475 if(f!=NULL)
476 f_flag=f->fw_flg;
477 else
478 f_flag=policy;
479 if(f_flag&IP_FW_F_ACCEPT)
480 return ((f_flag&IP_FW_F_MASQ)?FW_MASQUERADE:FW_ACCEPT);
481 if(f_flag&IP_FW_F_ICMPRPL)
482 return FW_REJECT;
483 return FW_BLOCK;
484 }
485
486 #ifdef CONFIG_IP_MASQUERADE
487
488 static void masq_expire(unsigned long data)
489 {
490 struct ip_masq *ms = (struct ip_masq *)data;
491 struct ip_masq *old,*cur;
492 unsigned long flags;
493
494 #ifdef DEBUG_MASQ
495 printk("Masqueraded %s %lX:%X expired\n",
496 strProt[ms->protocol==IPPROTO_TCP],
497 ntohl(ms->src),ntohs(ms->sport));
498 #endif
499
500 save_flags(flags);
501 cli();
502
503
504 old = NULL;
505 cur = ip_msq_hosts;
506 while (cur!=NULL) {
507 if (cur==ms) {
508 if (old==NULL) ip_msq_hosts = ms->next;
509 else old->next = ms->next;
510 kfree_s(ms,sizeof(*ms));
511 break;
512 }
513 old = cur;
514 cur=cur->next;
515 }
516 restore_flags(flags);
517 }
518
519
520
521
522
523
524
525
526 static struct ip_masq *alloc_masq_entry(void)
527 {
528 struct ip_masq *ms, *mst;
529 unsigned long flags;
530
531 ms = (struct ip_masq *) kmalloc(sizeof(struct ip_masq), GFP_ATOMIC);
532 if (ms==NULL)
533 return NULL;
534
535 memset(ms,0,sizeof(*ms));
536 init_timer(&ms->timer);
537 ms->timer.data = (unsigned long)ms;
538 ms->timer.function = masq_expire;
539
540 save_flags(flags);
541 cli();
542 do
543 {
544
545 ms->mport = htons(masq_port++);
546 if (masq_port==PORT_MASQ_END)
547 masq_port = PORT_MASQ_BEGIN;
548
549
550
551 mst = ip_msq_hosts;
552 while (mst && mst->mport!=ms->mport)
553 mst = mst->next;
554 }
555 while (mst!=NULL);
556
557
558 ms->next = ip_msq_hosts;
559 ip_msq_hosts = ms;
560 restore_flags(flags);
561
562 return ms;
563 }
564
565
566
567
568
569
570
571
572
573
574
575
576
577 static struct sk_buff *revamp(struct sk_buff *skb, struct device *dev, struct ip_masq *ftp)
578 {
579 struct iphdr *iph = skb->h.iph;
580 struct tcphdr *th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
581 struct sk_buff *skb2;
582 char *p, *data = (char *)&th[1];
583 unsigned char p1,p2,p3,p4,p5,p6;
584 unsigned long from;
585 unsigned short port;
586 struct ip_masq *ms;
587 char buf[24];
588 int diff;
589
590
591
592
593
594 if (ftp->delta && after(ftp->init_seq,th->seq))
595 {
596 th->seq += ftp->delta;
597
598 }
599
600 while (skb->len - ((unsigned char *)data - skb->h.raw) > 18)
601 {
602 if (memcmp(data,"PORT ",5) && memcmp(data,"port ",5))
603 {
604 data ++;
605 continue;
606 }
607 p = data+5;
608 p1 = simple_strtoul(data+5,&data,10);
609 if (*data!=',')
610 continue;
611 p2 = simple_strtoul(data+1,&data,10);
612 if (*data!=',')
613 continue;
614 p3 = simple_strtoul(data+1,&data,10);
615 if (*data!=',')
616 continue;
617 p4 = simple_strtoul(data+1,&data,10);
618 if (*data!=',')
619 continue;
620 p5 = simple_strtoul(data+1,&data,10);
621 if (*data!=',')
622 continue;
623 p6 = simple_strtoul(data+1,&data,10);
624 if (*data!='\r' && *data!='\n')
625 continue;
626
627 from = (p1<<24) | (p2<<16) | (p3<<8) | p4;
628 port = (p5<<8) | p6;
629 printk("PORT %lX:%X detected\n",from,port);
630
631
632
633
634 ms = alloc_masq_entry();
635 if (ms==NULL)
636 return skb;
637 ms->protocol = IPPROTO_TCP;
638 ms->src = htonl(from);
639 ms->sport = htons(port);
640 ms->dst = iph->daddr;
641 ms->dport = htons(20);
642 ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP_FIN;
643 add_timer(&ms->timer);
644
645
646
647
648 from = ntohl(dev->pa_addr);
649 port = ntohs(ms->mport);
650 sprintf(buf,"%ld,%ld,%ld,%ld,%d,%d",
651 from>>24&255,from>>16&255,from>>8&255,from&255,
652 port>>8&255,port&255);
653
654
655
656
657
658 diff = strlen(buf) - (data-p);
659
660
661
662
663
664 if (diff==0)
665 {
666
667
668
669 ftp->init_seq = 0;
670 memcpy(p,buf,strlen(buf));
671 return skb;
672 }
673
674
675
676
677
678
679
680
681
682
683
684 if(!ftp->init_seq || after(ftp->init_seq,th->seq))
685 ftp->delta+=diff;
686
687
688
689 printk("MASQUERADE: resizing needed for %d bytes (%ld)\n",ftp->delta, skb->len);
690 if (!ftp->init_seq)
691 ftp->init_seq = th->seq;
692
693 skb2 = alloc_skb(MAX_HEADER + skb->len+ftp->delta, GFP_ATOMIC);
694 if (skb2 == NULL) {
695 printk("MASQUERADE: No memory available\n");
696 return skb;
697 }
698 skb2->free = skb->free;
699 skb_reserve(skb2,MAX_HEADER);
700 skb_put(skb2,skb->len + ftp->delta);
701
702 skb2->h.raw = skb2->data + (skb->h.raw - skb->data);
703 iph=skb2->h.iph;
704
705
706
707 iph->tot_len = htons(diff+ntohs(iph->tot_len));
708 iph->check = 0;
709 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
710
711
712
713
714
715 memcpy(skb2->data, skb->data, (p - (char *)skb->data));
716 memcpy(&skb2->data[(p - (char *)skb->data)], buf, strlen(buf));
717 memcpy(&skb2->data[(p - (char *)skb->data) + strlen(buf)], data,
718 skb->len - (data-(char *)skb->data));
719
720
721
722
723
724
725 kfree_skb(skb, FREE_WRITE);
726 return skb2;
727 }
728 return skb;
729 }
730
731 static void recalc_check(struct udphdr *uh, unsigned long saddr,
732 unsigned long daddr, int len)
733 {
734 uh->check=0;
735 uh->check=csum_tcpudp_magic(saddr,daddr,len,
736 IPPROTO_UDP, csum_partial((char *)uh,len,0));
737 if(uh->check==0)
738 uh->check=0xFFFF;
739 }
740
741 void ip_fw_masquerade(struct sk_buff **skb_ptr, struct device *dev)
742 {
743 struct sk_buff *skb=*skb_ptr;
744 struct iphdr *iph = skb->h.iph;
745 unsigned short *portptr;
746 struct ip_masq *ms;
747 int size;
748
749
750
751
752
753 if (iph->protocol!=IPPROTO_UDP && iph->protocol!=IPPROTO_TCP)
754 return;
755
756
757
758
759
760 portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
761 ms = ip_msq_hosts;
762
763 #ifdef DEBUG_MASQ
764 printk("Outgoing %s %lX:%X -> %lX:%X\n",
765 strProt[iph->protocol==IPPROTO_TCP],
766 ntohl(iph->saddr), ntohs(portptr[0]),
767 ntohl(iph->daddr), ntohs(portptr[1]));
768 #endif
769 while (ms!=NULL)
770 {
771 if (iph->protocol == ms->protocol &&
772 iph->saddr == ms->src && iph->daddr == ms->dst &&
773 portptr[0] == ms->sport && portptr[1] == ms->dport)
774 {
775 del_timer(&ms->timer);
776 break;
777 }
778 ms = ms->next;
779 }
780
781
782
783
784
785 if (ms==NULL)
786 {
787 ms = alloc_masq_entry();
788 if (ms==NULL)
789 {
790 printk("MASQUERADE: no memory left !\n");
791 return;
792 }
793 ms->protocol = iph->protocol;
794 ms->src = iph->saddr;
795 ms->dst = iph->daddr;
796 ms->sport = portptr[0];
797 ms->dport = portptr[1];
798 }
799
800
801
802
803
804 size = skb->len - ((unsigned char *)portptr - skb->h.raw);
805 iph->saddr = dev->pa_addr;
806 portptr[0] = ms->mport;
807
808
809
810
811
812 if (iph->protocol==IPPROTO_UDP)
813 {
814 ms->timer.expires = jiffies+MASQUERADE_EXPIRE_UDP;
815 recalc_check((struct udphdr *)portptr,iph->saddr,iph->daddr,size);
816 }
817 else
818 {
819 struct tcphdr *th;
820 if (portptr[1]==htons(21))
821 {
822 skb = revamp(*skb_ptr, dev, ms);
823 *skb_ptr = skb;
824 iph = skb->h.iph;
825 portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
826 size = skb->len - ((unsigned char *)portptr-skb->h.raw);
827 }
828 th = (struct tcphdr *)portptr;
829
830
831
832
833 if (ms->sawfin || th->fin)
834 {
835 ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP_FIN;
836 ms->sawfin = 1;
837 }
838 else ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP;
839
840 tcp_send_check(th,iph->saddr,iph->daddr,size,skb->sk);
841 }
842 add_timer(&ms->timer);
843 ip_send_check(iph);
844
845 #ifdef DEBUG_MASQ
846 printk("O-routed from %lX:%X over %s\n",ntohl(dev->pa_addr),ntohs(ms->mport),dev->name);
847 #endif
848 }
849
850
851
852
853
854
855
856
857
858
859 int ip_fw_demasquerade(struct sk_buff *skb_ptr)
860 {
861 struct iphdr *iph = skb_ptr->h.iph;
862 unsigned short *portptr;
863 struct ip_masq *ms;
864 struct tcphdr *th = (struct tcphdr *)(skb_ptr->h.raw+(iph->ihl<<2));
865
866 if (iph->protocol!=IPPROTO_UDP && iph->protocol!=IPPROTO_TCP)
867 return 0;
868
869 portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
870 if (ntohs(portptr[1]) < PORT_MASQ_BEGIN ||
871 ntohs(portptr[1]) > PORT_MASQ_END)
872 return 0;
873
874 #ifdef DEBUG_MASQ
875 printk("Incoming %s %lX:%X -> %lX:%X\n",
876 strProt[iph->protocol==IPPROTO_TCP],
877 ntohl(iph->saddr), ntohs(portptr[0]),
878 ntohl(iph->daddr), ntohs(portptr[1]));
879 #endif
880
881
882
883
884
885
886
887
888
889 ms = ip_msq_hosts;
890 while (ms!=NULL)
891 {
892 if (iph->protocol==ms->protocol &&
893 (iph->saddr==ms->dst || iph->protocol==IPPROTO_UDP) &&
894 portptr[0]==ms->dport &&
895 portptr[1]==ms->mport)
896 {
897 int size = skb_ptr->len - ((unsigned char *)portptr - skb_ptr->h.raw);
898 iph->daddr = ms->src;
899 portptr[1] = ms->sport;
900
901
902
903
904 if (iph->protocol==IPPROTO_UDP)
905 recalc_check((struct udphdr *)portptr,iph->saddr,iph->daddr,size);
906 else
907 {
908
909
910
911
912 if (ms->delta && after(ms->init_seq,th->ack_seq))
913 {
914
915 th->ack_seq -= ms->delta;
916 }
917 tcp_send_check((struct tcphdr *)portptr,iph->saddr,iph->daddr,size,skb_ptr->sk);
918 }
919 ip_send_check(iph);
920 #ifdef DEBUG_MASQ
921 printk("I-routed to %lX:%X\n",ntohl(iph->daddr),ntohs(portptr[1]));
922 #endif
923 return 1;
924 }
925 ms = ms->next;
926 }
927
928
929 return 0;
930 }
931 #endif
932
933
934
935 static void zero_fw_chain(struct ip_fw *chainptr)
936 {
937 struct ip_fw *ctmp=chainptr;
938 while(ctmp)
939 {
940 ctmp->fw_pcnt=0L;
941 ctmp->fw_bcnt=0L;
942 ctmp=ctmp->fw_next;
943 }
944 }
945
946 static void free_fw_chain(struct ip_fw *volatile* chainptr)
947 {
948 unsigned long flags;
949 save_flags(flags);
950 cli();
951 while ( *chainptr != NULL )
952 {
953 struct ip_fw *ftmp;
954 ftmp = *chainptr;
955 *chainptr = ftmp->fw_next;
956 kfree_s(ftmp,sizeof(*ftmp));
957 }
958 restore_flags(flags);
959 }
960
961
962
963 static int add_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl)
964 {
965 struct ip_fw *ftmp;
966 struct ip_fw *chtmp=NULL;
967 struct ip_fw *volatile chtmp_prev=NULL;
968 unsigned long flags;
969 unsigned long m_src_mask,m_dst_mask;
970 unsigned long n_sa,n_da,o_sa,o_da,o_sm,o_dm,n_sm,n_dm;
971 unsigned short n_sr,n_dr,o_sr,o_dr;
972 unsigned short oldkind,newkind;
973 int addb4=0;
974 int n_o,n_n;
975
976 save_flags(flags);
977
978 ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
979 if ( ftmp == NULL )
980 {
981 #ifdef DEBUG_CONFIG_IP_FIREWALL
982 printk("ip_fw_ctl: malloc said no\n");
983 #endif
984 return( ENOMEM );
985 }
986
987 memcpy(ftmp, frwl, sizeof( struct ip_fw ) );
988
989 ftmp->fw_pcnt=0L;
990 ftmp->fw_bcnt=0L;
991
992 ftmp->fw_next = NULL;
993
994 cli();
995
996 if (*chainptr==NULL)
997 {
998 *chainptr=ftmp;
999 }
1000 else
1001 {
1002 chtmp_prev=NULL;
1003 for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->fw_next)
1004 {
1005 addb4=0;
1006 newkind=ftmp->fw_flg & IP_FW_F_KIND;
1007 oldkind=chtmp->fw_flg & IP_FW_F_KIND;
1008
1009 if (newkind!=IP_FW_F_ALL
1010 && oldkind!=IP_FW_F_ALL
1011 && oldkind!=newkind)
1012 {
1013 chtmp_prev=chtmp;
1014 continue;
1015 }
1016
1017
1018
1019
1020
1021
1022 n_sa=ntohl(ftmp->fw_src.s_addr);
1023 n_da=ntohl(ftmp->fw_dst.s_addr);
1024 n_sm=ntohl(ftmp->fw_smsk.s_addr);
1025 n_dm=ntohl(ftmp->fw_dmsk.s_addr);
1026
1027 o_sa=ntohl(chtmp->fw_src.s_addr);
1028 o_da=ntohl(chtmp->fw_dst.s_addr);
1029 o_sm=ntohl(chtmp->fw_smsk.s_addr);
1030 o_dm=ntohl(chtmp->fw_dmsk.s_addr);
1031
1032 m_src_mask = o_sm & n_sm;
1033 m_dst_mask = o_dm & n_dm;
1034
1035 if ((o_sa & m_src_mask) == (n_sa & m_src_mask))
1036 {
1037 if (n_sm > o_sm)
1038 addb4++;
1039 if (n_sm < o_sm)
1040 addb4--;
1041 }
1042
1043 if ((o_da & m_dst_mask) == (n_da & m_dst_mask))
1044 {
1045 if (n_dm > o_dm)
1046 addb4++;
1047 if (n_dm < o_dm)
1048 addb4--;
1049 }
1050
1051 if (((o_da & o_dm) == (n_da & n_dm))
1052 &&((o_sa & o_sm) == (n_sa & n_sm)))
1053 {
1054 if (newkind!=IP_FW_F_ALL &&
1055 oldkind==IP_FW_F_ALL)
1056 addb4++;
1057 if (newkind==oldkind && (oldkind==IP_FW_F_TCP
1058 || oldkind==IP_FW_F_UDP))
1059 {
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072 if (ftmp->fw_flg & IP_FW_F_SRNG)
1073 n_sr=ftmp->fw_pts[1]-ftmp->fw_pts[0];
1074 else
1075 n_sr=(ftmp->fw_nsp)?
1076 ftmp->fw_nsp : 0xFFFF;
1077
1078 if (chtmp->fw_flg & IP_FW_F_SRNG)
1079 o_sr=chtmp->fw_pts[1]-chtmp->fw_pts[0];
1080 else
1081 o_sr=(chtmp->fw_nsp)?chtmp->fw_nsp : 0xFFFF;
1082
1083 if (n_sr<o_sr)
1084 addb4++;
1085 if (n_sr>o_sr)
1086 addb4--;
1087
1088 n_n=ftmp->fw_nsp;
1089 n_o=chtmp->fw_nsp;
1090
1091
1092
1093
1094
1095
1096
1097 if ((n_n>(IP_FW_MAX_PORTS-2)) ||
1098 (n_o>(IP_FW_MAX_PORTS-2)))
1099 goto skip_check;
1100
1101 if (ftmp->fw_flg & IP_FW_F_DRNG)
1102 n_dr=ftmp->fw_pts[n_n+1]-ftmp->fw_pts[n_n];
1103 else
1104 n_dr=(ftmp->fw_ndp)? ftmp->fw_ndp : 0xFFFF;
1105
1106 if (chtmp->fw_flg & IP_FW_F_DRNG)
1107 o_dr=chtmp->fw_pts[n_o+1]-chtmp->fw_pts[n_o];
1108 else
1109 o_dr=(chtmp->fw_ndp)? chtmp->fw_ndp : 0xFFFF;
1110 if (n_dr<o_dr)
1111 addb4++;
1112 if (n_dr>o_dr)
1113 addb4--;
1114 skip_check:
1115 }
1116
1117 if ((addb4 == 0) && ftmp->fw_via.s_addr &&
1118 !(chtmp->fw_via.s_addr))
1119 addb4++;
1120 }
1121 if (addb4>0)
1122 {
1123 if (chtmp_prev)
1124 {
1125 chtmp_prev->fw_next=ftmp;
1126 ftmp->fw_next=chtmp;
1127 }
1128 else
1129 {
1130 *chainptr=ftmp;
1131 ftmp->fw_next=chtmp;
1132 }
1133 restore_flags(flags);
1134 return 0;
1135 }
1136 chtmp_prev=chtmp;
1137 }
1138 }
1139
1140 if (chtmp_prev)
1141 chtmp_prev->fw_next=ftmp;
1142 else
1143 *chainptr=ftmp;
1144 restore_flags(flags);
1145 return(0);
1146 }
1147
1148 static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
1149 {
1150 struct ip_fw *ftmp,*ltmp;
1151 unsigned short tport1,tport2,tmpnum;
1152 char matches,was_found;
1153 unsigned long flags;
1154
1155 save_flags(flags);
1156 cli();
1157
1158 ftmp=*chainptr;
1159
1160 if ( ftmp == NULL )
1161 {
1162 #ifdef DEBUG_CONFIG_IP_FIREWALL
1163 printk("ip_fw_ctl: chain is empty\n");
1164 #endif
1165 restore_flags(flags);
1166 return( EINVAL );
1167 }
1168
1169 ltmp=NULL;
1170 was_found=0;
1171
1172 while( ftmp != NULL )
1173 {
1174 matches=1;
1175 if (ftmp->fw_src.s_addr!=frwl->fw_src.s_addr
1176 || ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr
1177 || ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr
1178 || ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr
1179 || ftmp->fw_via.s_addr!=frwl->fw_via.s_addr
1180 || ftmp->fw_flg!=frwl->fw_flg)
1181 matches=0;
1182
1183 tport1=ftmp->fw_nsp+ftmp->fw_ndp;
1184 tport2=frwl->fw_nsp+frwl->fw_ndp;
1185 if (tport1!=tport2)
1186 matches=0;
1187 else if (tport1!=0)
1188 {
1189 for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
1190 if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum])
1191 matches=0;
1192 }
1193 if(matches)
1194 {
1195 was_found=1;
1196 if (ltmp)
1197 {
1198 ltmp->fw_next=ftmp->fw_next;
1199 kfree_s(ftmp,sizeof(*ftmp));
1200 ftmp=ltmp->fw_next;
1201 }
1202 else
1203 {
1204 *chainptr=ftmp->fw_next;
1205 kfree_s(ftmp,sizeof(*ftmp));
1206 ftmp=*chainptr;
1207 }
1208 }
1209 else
1210 {
1211 ltmp = ftmp;
1212 ftmp = ftmp->fw_next;
1213 }
1214 }
1215 restore_flags(flags);
1216 if (was_found)
1217 return 0;
1218 else
1219 return(EINVAL);
1220 }
1221
1222 #endif
1223
1224 struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
1225 {
1226
1227 if ( len != sizeof(struct ip_fw) )
1228 {
1229 #ifdef DEBUG_CONFIG_IP_FIREWALL
1230 printk("ip_fw_ctl: len=%d, want %d\n",len, sizeof(struct ip_fw));
1231 #endif
1232 return(NULL);
1233 }
1234
1235 if ( (frwl->fw_flg & ~IP_FW_F_MASK) != 0 )
1236 {
1237 #ifdef DEBUG_CONFIG_IP_FIREWALL
1238 printk("ip_fw_ctl: undefined flag bits set (flags=%x)\n",
1239 frwl->fw_flg);
1240 #endif
1241 return(NULL);
1242 }
1243
1244 if ( (frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2 )
1245 {
1246 #ifdef DEBUG_CONFIG_IP_FIREWALL
1247 printk("ip_fw_ctl: src range set but fw_nsp=%d\n",
1248 frwl->fw_nsp);
1249 #endif
1250 return(NULL);
1251 }
1252
1253 if ( (frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2 )
1254 {
1255 #ifdef DEBUG_CONFIG_IP_FIREWALL
1256 printk("ip_fw_ctl: dst range set but fw_ndp=%d\n",
1257 frwl->fw_ndp);
1258 #endif
1259 return(NULL);
1260 }
1261
1262 if ( frwl->fw_nsp + frwl->fw_ndp > IP_FW_MAX_PORTS )
1263 {
1264 #ifdef DEBUG_CONFIG_IP_FIREWALL
1265 printk("ip_fw_ctl: too many ports (%d+%d)\n",
1266 frwl->fw_nsp,frwl->fw_ndp);
1267 #endif
1268 return(NULL);
1269 }
1270
1271 return frwl;
1272 }
1273
1274
1275
1276
1277 #ifdef CONFIG_IP_ACCT
1278
1279 #if 0
1280 void ip_acct_cnt(struct iphdr *iph, struct device *dev, struct ip_fw *f)
1281 {
1282 (void) ip_fw_chk(iph, dev, f, 0, 1);
1283 return;
1284 }
1285 #endif
1286
1287 int ip_acct_ctl(int stage, void *m, int len)
1288 {
1289 if ( stage == IP_ACCT_FLUSH )
1290 {
1291 free_fw_chain(&ip_acct_chain);
1292 return(0);
1293 }
1294 if ( stage == IP_ACCT_ZERO )
1295 {
1296 zero_fw_chain(ip_acct_chain);
1297 return(0);
1298 }
1299 if ( stage == IP_ACCT_ADD
1300 || stage == IP_ACCT_DEL
1301 )
1302 {
1303 struct ip_fw *frwl;
1304
1305 if (!(frwl=check_ipfw_struct(m,len)))
1306 return (EINVAL);
1307
1308 switch (stage)
1309 {
1310 case IP_ACCT_ADD:
1311 return( add_to_chain(&ip_acct_chain,frwl));
1312 case IP_ACCT_DEL:
1313 return( del_from_chain(&ip_acct_chain,frwl));
1314 default:
1315
1316
1317
1318 #ifdef DEBUG_CONFIG_IP_FIREWALL
1319 printk("ip_acct_ctl: unknown request %d\n",stage);
1320 #endif
1321 return(EINVAL);
1322 }
1323 }
1324 #ifdef DEBUG_CONFIG_IP_FIREWALL
1325 printk("ip_acct_ctl: unknown request %d\n",stage);
1326 #endif
1327 return(EINVAL);
1328 }
1329 #endif
1330
1331 #ifdef CONFIG_IP_FIREWALL
1332 int ip_fw_ctl(int stage, void *m, int len)
1333 {
1334 int ret;
1335
1336 if ( stage == IP_FW_FLUSH_BLK )
1337 {
1338 free_fw_chain(&ip_fw_blk_chain);
1339 return(0);
1340 }
1341
1342 if ( stage == IP_FW_FLUSH_FWD )
1343 {
1344 free_fw_chain(&ip_fw_fwd_chain);
1345 return(0);
1346 }
1347
1348 if ( stage == IP_FW_ZERO_BLK )
1349 {
1350 zero_fw_chain(ip_fw_blk_chain);
1351 return(0);
1352 }
1353
1354 if ( stage == IP_FW_ZERO_FWD )
1355 {
1356 zero_fw_chain(ip_fw_fwd_chain);
1357 return(0);
1358 }
1359
1360 if ( stage == IP_FW_POLICY_BLK || stage == IP_FW_POLICY_FWD )
1361 {
1362 int *tmp_policy_ptr;
1363 tmp_policy_ptr=(int *)m;
1364 if ( stage == IP_FW_POLICY_BLK )
1365 ip_fw_blk_policy=*tmp_policy_ptr;
1366 else
1367 ip_fw_fwd_policy=*tmp_policy_ptr;
1368 return 0;
1369 }
1370
1371 if ( stage == IP_FW_CHK_BLK || stage == IP_FW_CHK_FWD )
1372 {
1373 struct device viadev;
1374 struct ip_fwpkt *ipfwp;
1375 struct iphdr *ip;
1376
1377 if ( len < sizeof(struct ip_fwpkt) )
1378 {
1379 #ifdef DEBUG_CONFIG_IP_FIREWALL
1380 printk("ip_fw_ctl: length=%d, expected %d\n",
1381 len, sizeof(struct ip_fwpkt));
1382 #endif
1383 return( EINVAL );
1384 }
1385
1386 ipfwp = (struct ip_fwpkt *)m;
1387 ip = &(ipfwp->fwp_iph);
1388
1389 if ( ip->ihl != sizeof(struct iphdr) / sizeof(int))
1390 {
1391 #ifdef DEBUG_CONFIG_IP_FIREWALL
1392 printk("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
1393 sizeof(struct iphdr)/sizeof(int));
1394 #endif
1395 return(EINVAL);
1396 }
1397
1398 viadev.pa_addr = ipfwp->fwp_via.s_addr;
1399
1400 if ((ret = ip_fw_chk(ip, &viadev,
1401 stage == IP_FW_CHK_BLK ?
1402 ip_fw_blk_chain : ip_fw_fwd_chain,
1403 stage == IP_FW_CHK_BLK ?
1404 ip_fw_blk_policy : ip_fw_fwd_policy, 2 )) > 0
1405 )
1406 return(0);
1407 else if (ret == -1)
1408 return(ECONNREFUSED);
1409 else
1410 return(ETIMEDOUT);
1411 }
1412
1413
1414
1415
1416
1417
1418 if ( stage == IP_FW_ADD_BLK || stage == IP_FW_ADD_FWD
1419 || stage == IP_FW_DEL_BLK || stage == IP_FW_DEL_FWD
1420 )
1421 {
1422 struct ip_fw *frwl;
1423 frwl=check_ipfw_struct(m,len);
1424 if (frwl==NULL)
1425 return (EINVAL);
1426
1427 switch (stage)
1428 {
1429 case IP_FW_ADD_BLK:
1430 return(add_to_chain(&ip_fw_blk_chain,frwl));
1431 case IP_FW_ADD_FWD:
1432 return(add_to_chain(&ip_fw_fwd_chain,frwl));
1433 case IP_FW_DEL_BLK:
1434 return(del_from_chain(&ip_fw_blk_chain,frwl));
1435 case IP_FW_DEL_FWD:
1436 return(del_from_chain(&ip_fw_fwd_chain,frwl));
1437 default:
1438
1439
1440
1441 #ifdef DEBUG_CONFIG_IP_FIREWALL
1442 printk("ip_fw_ctl: unknown request %d\n",stage);
1443 #endif
1444 return(EINVAL);
1445 }
1446 }
1447
1448 #ifdef DEBUG_CONFIG_IP_FIREWALL
1449 printk("ip_fw_ctl: unknown request %d\n",stage);
1450 #endif
1451 return(EINVAL);
1452 }
1453 #endif
1454
1455 #if defined(CONFIG_IP_FIREWALL) || defined(CONFIG_IP_ACCT)
1456
1457 static int ip_chain_procinfo(int stage, char *buffer, char **start,
1458 off_t offset, int length, int reset)
1459 {
1460 off_t pos=0, begin=0;
1461 struct ip_fw *i;
1462 unsigned long flags;
1463 int len, p;
1464
1465
1466 switch(stage)
1467 {
1468 #ifdef CONFIG_IP_FIREWALL
1469 case IP_INFO_BLK:
1470 i = ip_fw_blk_chain;
1471 len=sprintf(buffer, "IP firewall block rules, default %d\n",
1472 ip_fw_blk_policy);
1473 break;
1474 case IP_INFO_FWD:
1475 i = ip_fw_fwd_chain;
1476 len=sprintf(buffer, "IP firewall forward rules, default %d\n",
1477 ip_fw_fwd_policy);
1478 break;
1479 #endif
1480 #ifdef CONFIG_IP_ACCT
1481 case IP_INFO_ACCT:
1482 i = ip_acct_chain;
1483 len=sprintf(buffer,"IP accounting rules\n");
1484 break;
1485 #endif
1486 default:
1487
1488 i = NULL;
1489 len=0;
1490 break;
1491 }
1492
1493 save_flags(flags);
1494 cli();
1495
1496 while(i!=NULL)
1497 {
1498 len+=sprintf(buffer+len,"%08lX/%08lX->%08lX/%08lX %08lX %X ",
1499 ntohl(i->fw_src.s_addr),ntohl(i->fw_smsk.s_addr),
1500 ntohl(i->fw_dst.s_addr),ntohl(i->fw_dmsk.s_addr),
1501 ntohl(i->fw_via.s_addr),i->fw_flg);
1502 len+=sprintf(buffer+len,"%u %u %-9lu %-9lu",
1503 i->fw_nsp,i->fw_ndp, i->fw_pcnt,i->fw_bcnt);
1504 for (p = 0; p < IP_FW_MAX_PORTS; p++)
1505 len+=sprintf(buffer+len, " %u", i->fw_pts[p]);
1506 buffer[len++]='\n';
1507 buffer[len]='\0';
1508 pos=begin+len;
1509 if(pos<offset)
1510 {
1511 len=0;
1512 begin=pos;
1513 }
1514 else if(reset)
1515 {
1516
1517 i->fw_pcnt=0L;
1518 i->fw_bcnt=0L;
1519 }
1520 if(pos>offset+length)
1521 break;
1522 i=i->fw_next;
1523 }
1524 restore_flags(flags);
1525 *start=buffer+(offset-begin);
1526 len-=(offset-begin);
1527 if(len>length)
1528 len=length;
1529 return len;
1530 }
1531 #endif
1532
1533 #ifdef CONFIG_IP_ACCT
1534
1535 static int ip_acct_procinfo(char *buffer, char **start, off_t offset,
1536 int length, int reset)
1537 {
1538 return ip_chain_procinfo(IP_INFO_ACCT, buffer,start, offset,length,
1539 reset);
1540 }
1541
1542 #endif
1543
1544 #ifdef CONFIG_IP_FIREWALL
1545
1546 static int ip_fw_blk_procinfo(char *buffer, char **start, off_t offset,
1547 int length, int reset)
1548 {
1549 return ip_chain_procinfo(IP_INFO_BLK, buffer,start,offset,length,
1550 reset);
1551 }
1552
1553 static int ip_fw_fwd_procinfo(char *buffer, char **start, off_t offset,
1554 int length, int reset)
1555 {
1556 return ip_chain_procinfo(IP_INFO_FWD, buffer,start,offset,length,
1557 reset);
1558 }
1559 #endif
1560
1561 #ifdef CONFIG_IP_MASQUERADE
1562
1563 static int ip_msqhst_procinfo(char *buffer, char **start, off_t offset,
1564 int length, int unused)
1565 {
1566 off_t pos=0, begin=0;
1567 struct ip_masq *ms;
1568 unsigned long flags;
1569 int len=0;
1570
1571 len=sprintf(buffer,"Prc FromIP FPrt ToIP TPrt Masq Init-seq Delta Expires\n");
1572 save_flags(flags);
1573 cli();
1574
1575 ms=ip_msq_hosts;
1576 while (ms!=NULL)
1577 {
1578 int timer_active = del_timer(&ms->timer);
1579 if (!timer_active)
1580 ms->timer.expires = jiffies;
1581 len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08X %5d %lu\n",
1582 strProt[ms->protocol==IPPROTO_TCP],
1583 ntohl(ms->src),ntohs(ms->sport),
1584 ntohl(ms->dst),ntohs(ms->dport),
1585 ntohs(ms->mport),
1586 ms->init_seq,ms->delta,ms->timer.expires-jiffies);
1587 if (timer_active)
1588 add_timer(&ms->timer);
1589
1590 pos=begin+len;
1591 if(pos<offset)
1592 {
1593 len=0;
1594 begin=pos;
1595 }
1596 if(pos>offset+length)
1597 break;
1598 ms=ms->next;
1599 }
1600 restore_flags(flags);
1601 *start=buffer+(offset-begin);
1602 len-=(offset-begin);
1603 if(len>length)
1604 len=length;
1605 return len;
1606 }
1607
1608 #endif
1609
1610 void ip_fw_init(void)
1611 {
1612 #ifdef CONFIG_IP_ACCT
1613 proc_net_register(&(struct proc_dir_entry) {
1614 PROC_NET_IPACCT, 7, "ip_acct",
1615 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1616 0, &proc_net_inode_operations,
1617 ip_acct_procinfo
1618 });
1619 #endif
1620 #ifdef CONFIG_IP_FIREWALL
1621 proc_net_register(&(struct proc_dir_entry) {
1622 PROC_NET_IPFWBLK, 8, "ip_block",
1623 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1624 0, &proc_net_inode_operations,
1625 ip_fw_blk_procinfo
1626 });
1627 proc_net_register(&(struct proc_dir_entry) {
1628 PROC_NET_IPFWFWD, 10, "ip_forward",
1629 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1630 0, &proc_net_inode_operations,
1631 ip_fw_fwd_procinfo
1632 });
1633 #endif
1634 #ifdef CONFIG_IP_MASQUERADE
1635 proc_net_register(&(struct proc_dir_entry) {
1636 PROC_NET_IPMSQHST, 13, "ip_masquerade",
1637 S_IFREG | S_IRUGO, 1, 0, 0,
1638 0, &proc_net_inode_operations,
1639 ip_msqhst_procinfo
1640 });
1641 #endif
1642 }