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