This source file includes following definitions.
- port_match
- ip_fw_chk
- 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
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 #include <linux/config.h>
41 #include <asm/segment.h>
42 #include <asm/system.h>
43 #include <linux/types.h>
44 #include <linux/kernel.h>
45 #include <linux/sched.h>
46 #include <linux/string.h>
47 #include <linux/errno.h>
48 #include <linux/config.h>
49
50 #include <linux/socket.h>
51 #include <linux/sockios.h>
52 #include <linux/in.h>
53 #include <linux/inet.h>
54 #include <linux/netdevice.h>
55 #include <linux/icmp.h>
56 #include <linux/udp.h>
57 #include "ip.h"
58 #include "protocol.h"
59 #include "route.h"
60 #include "tcp.h"
61 #include <linux/skbuff.h>
62 #include "sock.h"
63 #include "icmp.h"
64 #include <linux/ip_fw.h>
65
66
67
68
69
70 #ifdef CONFIG_IPFIREWALL_DEBUG
71 #define dprintf1(a) printk(a)
72 #define dprintf2(a1,a2) printk(a1,a2)
73 #define dprintf3(a1,a2,a3) printk(a1,a2,a3)
74 #define dprintf4(a1,a2,a3,a4) printk(a1,a2,a3,a4)
75 #else
76 #define dprintf1(a)
77 #define dprintf2(a1,a2)
78 #define dprintf3(a1,a2,a3)
79 #define dprintf4(a1,a2,a3,a4)
80 #endif
81
82 #define print_ip(a) printf("%d.%d.%d.%d",(ntohl(a.s_addr)>>24)&0xFF,\
83 (ntohl(a.s_addr)>>16)&0xFF,\
84 (ntohl(a.s_addr)>>8)&0xFF,\
85 (ntohl(a.s_addr))&0xFF);
86
87 #ifdef IPFIREWALL_DEBUG
88 #define dprint_ip(a) print_ip(a)
89 #else
90 #define dprint_ip(a)
91 #endif
92
93 #ifdef CONFIG_IP_FIREWALL
94 struct ip_fw *ip_fw_fwd_chain;
95 struct ip_fw *ip_fw_blk_chain;
96 int ip_fw_blk_policy=IP_FW_F_ACCEPT;
97 int ip_fw_fwd_policy=IP_FW_F_ACCEPT;
98 #endif
99 #ifdef CONFIG_IP_ACCT
100 struct ip_fw *ip_acct_chain;
101 #endif
102
103 #define IP_INFO_BLK 0
104 #define IP_INFO_FWD 1
105 #define IP_INFO_ACCT 2
106
107
108
109
110
111
112 extern inline int port_match(unsigned short *portptr,int nports,unsigned short port,int range_flag)
113 {
114 if (!nports)
115 return 1;
116 if ( range_flag )
117 {
118 if ( portptr[0] <= port && port <= portptr[1] )
119 {
120 return( 1 );
121 }
122 nports -= 2;
123 portptr += 2;
124 }
125 while ( nports-- > 0 )
126 {
127 if ( *portptr++ == port )
128 {
129 return( 1 );
130 }
131 }
132 return(0);
133 }
134
135 #if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
136
137
138
139
140
141
142
143
144
145
146
147
148
149 int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int policy, int opt)
150 {
151 struct ip_fw *f;
152 struct tcphdr *tcp=(struct tcphdr *)((unsigned long *)ip+ip->ihl);
153 struct udphdr *udp=(struct udphdr *)((unsigned long *)ip+ip->ihl);
154 __u32 src, dst;
155 __u16 src_port=0, dst_port=0;
156 unsigned short f_prt=0, prt;
157 char notcpsyn=1, frag1, match;
158 unsigned short f_flag;
159
160
161
162
163
164
165
166 src = ip->saddr;
167 dst = ip->daddr;
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183 frag1 = ((ntohs(ip->frag_off) & IP_OFFSET) == 0);
184 if (!frag1 && (opt != 1) && (ip->protocol == IPPROTO_TCP ||
185 ip->protocol == IPPROTO_UDP))
186 return(1);
187
188 src = ip->saddr;
189 dst = ip->daddr;
190
191
192
193
194
195
196
197
198
199 dprintf1("Packet ");
200 switch(ip->protocol)
201 {
202 case IPPROTO_TCP:
203 dprintf1("TCP ");
204
205 if (frag1) {
206 src_port=ntohs(tcp->source);
207 dst_port=ntohs(tcp->dest);
208 if(tcp->syn && !tcp->ack)
209
210 notcpsyn=0;
211 }
212 prt=IP_FW_F_TCP;
213 break;
214 case IPPROTO_UDP:
215 dprintf1("UDP ");
216
217 if (frag1) {
218 src_port=ntohs(udp->source);
219 dst_port=ntohs(udp->dest);
220 }
221 prt=IP_FW_F_UDP;
222 break;
223 case IPPROTO_ICMP:
224 dprintf2("ICMP:%d ",((char *)portptr)[0]&0xff);
225 prt=IP_FW_F_ICMP;
226 break;
227 default:
228 dprintf2("p=%d ",ip->protocol);
229 prt=IP_FW_F_ALL;
230 break;
231 }
232 dprint_ip(ip->saddr);
233
234 if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP)
235
236 dprintf2(":%d ", src_port);
237 dprint_ip(ip->daddr);
238 if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP)
239
240 dprintf2(":%d ",dst_port);
241 dprintf1("\n");
242
243 for (f=chain;f;f=f->fw_next)
244 {
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262 match = 0x00;
263
264 if ((src&f->fw_smsk.s_addr)==f->fw_src.s_addr
265 && (dst&f->fw_dmsk.s_addr)==f->fw_dst.s_addr)
266
267 match |= 0x01;
268
269 if ((f->fw_flg & IP_FW_F_BIDIR) &&
270 (dst&f->fw_smsk.s_addr)==f->fw_src.s_addr
271 && (src&f->fw_dmsk.s_addr)==f->fw_dst.s_addr)
272
273 match |= 0x02;
274
275 if (match)
276 {
277
278
279
280 if(f->fw_via.s_addr && rif)
281 {
282 if(rif->pa_addr!=f->fw_via.s_addr)
283 continue;
284 }
285
286
287
288 }
289 else
290 continue;
291
292
293
294
295
296 f_prt=f->fw_flg&IP_FW_F_KIND;
297 if (f_prt!=IP_FW_F_ALL)
298 {
299
300
301
302
303
304
305
306 if((f->fw_flg&IP_FW_F_TCPSYN) && notcpsyn)
307 continue;
308
309
310
311
312
313 if(prt!=f_prt)
314 continue;
315
316 if(!(prt==IP_FW_F_ICMP || ((match & 0x01) &&
317 port_match(&f->fw_pts[0], f->fw_nsp, src_port,
318 f->fw_flg&IP_FW_F_SRNG) &&
319 port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, dst_port,
320 f->fw_flg&IP_FW_F_DRNG)) || ((match & 0x02) &&
321 port_match(&f->fw_pts[0], f->fw_nsp, dst_port,
322 f->fw_flg&IP_FW_F_SRNG) &&
323 port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, src_port,
324 f->fw_flg&IP_FW_F_DRNG))))
325 {
326 continue;
327 }
328 }
329 #ifdef CONFIG_IP_FIREWALL_VERBOSE
330
331
332
333
334
335 if (f->fw_flg & IP_FW_F_PRN)
336 {
337 if(opt != 1) {
338 if(f->fw_flg&IP_FW_F_ACCEPT)
339 printk("Accept ");
340 else if(f->fw_flg&IP_FW_F_ICMPRPL)
341 printk("Reject ");
342 else
343 printk("Deny ");
344 }
345 switch(ip->protocol)
346 {
347 case IPPROTO_TCP:
348 printk("TCP ");
349 break;
350 case IPPROTO_UDP:
351 printk("UDP ");
352 case IPPROTO_ICMP:
353 printk("ICMP ");
354 break;
355 default:
356 printk("p=%d ",ip->protocol);
357 break;
358 }
359 print_ip(ip->saddr);
360 if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
361 printk(":%d", src_port);
362 printk(" ");
363 print_ip(ip->daddr);
364 if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
365 printk(":%d",dst_port);
366 printk("\n");
367 }
368 #endif
369 if (opt != 2) {
370 f->fw_bcnt+=ntohs(ip->tot_len);
371 f->fw_pcnt++;
372 }
373 if (opt != 1)
374 break;
375 }
376
377 if(opt == 1)
378 return 0;
379
380
381
382
383
384
385
386 if(f!=NULL)
387 f_flag=f->fw_flg;
388 else
389 f_flag=policy;
390 if(f_flag&IP_FW_F_ACCEPT)
391 return 1;
392 if(f_flag&IP_FW_F_ICMPRPL)
393 return -1;
394 return 0;
395 }
396
397
398 static void zero_fw_chain(struct ip_fw *chainptr)
399 {
400 struct ip_fw *ctmp=chainptr;
401 while(ctmp)
402 {
403 ctmp->fw_pcnt=0L;
404 ctmp->fw_bcnt=0L;
405 ctmp=ctmp->fw_next;
406 }
407 }
408
409 static void free_fw_chain(struct ip_fw *volatile* chainptr)
410 {
411 unsigned long flags;
412 save_flags(flags);
413 cli();
414 while ( *chainptr != NULL )
415 {
416 struct ip_fw *ftmp;
417 ftmp = *chainptr;
418 *chainptr = ftmp->fw_next;
419 kfree_s(ftmp,sizeof(*ftmp));
420 }
421 restore_flags(flags);
422 }
423
424
425
426 static int add_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl)
427 {
428 struct ip_fw *ftmp;
429 struct ip_fw *chtmp=NULL;
430 struct ip_fw *volatile chtmp_prev=NULL;
431 unsigned long flags;
432 unsigned long m_src_mask,m_dst_mask;
433 unsigned long n_sa,n_da,o_sa,o_da,o_sm,o_dm,n_sm,n_dm;
434 unsigned short n_sr,n_dr,o_sr,o_dr;
435 unsigned short oldkind,newkind;
436 int addb4=0;
437 int n_o,n_n;
438
439 save_flags(flags);
440
441 ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
442 if ( ftmp == NULL )
443 {
444 #ifdef DEBUG_CONFIG_IP_FIREWALL
445 printf("ip_fw_ctl: malloc said no\n");
446 #endif
447 return( ENOMEM );
448 }
449
450 memcpy(ftmp, frwl, sizeof( struct ip_fw ) );
451
452 ftmp->fw_pcnt=0L;
453 ftmp->fw_bcnt=0L;
454
455 ftmp->fw_next = NULL;
456
457 cli();
458
459 if (*chainptr==NULL)
460 {
461 *chainptr=ftmp;
462 }
463 else
464 {
465 chtmp_prev=NULL;
466 for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->fw_next)
467 {
468 addb4=0;
469 newkind=ftmp->fw_flg & IP_FW_F_KIND;
470 oldkind=chtmp->fw_flg & IP_FW_F_KIND;
471
472 if (newkind!=IP_FW_F_ALL
473 && oldkind!=IP_FW_F_ALL
474 && oldkind!=newkind)
475 {
476 chtmp_prev=chtmp;
477 continue;
478 }
479
480
481
482
483
484
485 n_sa=ntohl(ftmp->fw_src.s_addr);
486 n_da=ntohl(ftmp->fw_dst.s_addr);
487 n_sm=ntohl(ftmp->fw_smsk.s_addr);
488 n_dm=ntohl(ftmp->fw_dmsk.s_addr);
489
490 o_sa=ntohl(chtmp->fw_src.s_addr);
491 o_da=ntohl(chtmp->fw_dst.s_addr);
492 o_sm=ntohl(chtmp->fw_smsk.s_addr);
493 o_dm=ntohl(chtmp->fw_dmsk.s_addr);
494
495 m_src_mask = o_sm & n_sm;
496 m_dst_mask = o_dm & n_dm;
497
498 if ((o_sa & m_src_mask) == (n_sa & m_src_mask))
499 {
500 if (n_sm > o_sm)
501 addb4++;
502 if (n_sm < o_sm)
503 addb4--;
504 }
505
506 if ((o_da & m_dst_mask) == (n_da & m_dst_mask))
507 {
508 if (n_dm > o_dm)
509 addb4++;
510 if (n_dm < o_dm)
511 addb4--;
512 }
513
514 if (((o_da & o_dm) == (n_da & n_dm))
515 &&((o_sa & o_sm) == (n_sa & n_sm)))
516 {
517 if (newkind!=IP_FW_F_ALL &&
518 oldkind==IP_FW_F_ALL)
519 addb4++;
520 if (newkind==oldkind && (oldkind==IP_FW_F_TCP
521 || oldkind==IP_FW_F_UDP))
522 {
523
524
525
526
527
528
529
530
531
532
533
534
535 if (ftmp->fw_flg & IP_FW_F_SRNG)
536 n_sr=ftmp->fw_pts[1]-ftmp->fw_pts[0];
537 else
538 n_sr=(ftmp->fw_nsp)?
539 ftmp->fw_nsp : 0xFFFF;
540
541 if (chtmp->fw_flg & IP_FW_F_SRNG)
542 o_sr=chtmp->fw_pts[1]-chtmp->fw_pts[0];
543 else
544 o_sr=(chtmp->fw_nsp)?chtmp->fw_nsp : 0xFFFF;
545
546 if (n_sr<o_sr)
547 addb4++;
548 if (n_sr>o_sr)
549 addb4--;
550
551 n_n=ftmp->fw_nsp;
552 n_o=chtmp->fw_nsp;
553
554
555
556
557
558
559
560 if ((n_n>(IP_FW_MAX_PORTS-2)) ||
561 (n_o>(IP_FW_MAX_PORTS-2)))
562 goto skip_check;
563
564 if (ftmp->fw_flg & IP_FW_F_DRNG)
565 n_dr=ftmp->fw_pts[n_n+1]-ftmp->fw_pts[n_n];
566 else
567 n_dr=(ftmp->fw_ndp)? ftmp->fw_ndp : 0xFFFF;
568
569 if (chtmp->fw_flg & IP_FW_F_DRNG)
570 o_dr=chtmp->fw_pts[n_o+1]-chtmp->fw_pts[n_o];
571 else
572 o_dr=(chtmp->fw_ndp)? chtmp->fw_ndp : 0xFFFF;
573 if (n_dr<o_dr)
574 addb4++;
575 if (n_dr>o_dr)
576 addb4--;
577 skip_check:
578 }
579
580 if ((addb4 == 0) && ftmp->fw_via.s_addr &&
581 !(chtmp->fw_via.s_addr))
582 addb4++;
583 }
584 if (addb4>0)
585 {
586 if (chtmp_prev)
587 {
588 chtmp_prev->fw_next=ftmp;
589 ftmp->fw_next=chtmp;
590 }
591 else
592 {
593 *chainptr=ftmp;
594 ftmp->fw_next=chtmp;
595 }
596 restore_flags(flags);
597 return 0;
598 }
599 chtmp_prev=chtmp;
600 }
601 }
602
603 if (chtmp_prev)
604 chtmp_prev->fw_next=ftmp;
605 else
606 *chainptr=ftmp;
607 restore_flags(flags);
608 return(0);
609 }
610
611 static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
612 {
613 struct ip_fw *ftmp,*ltmp;
614 unsigned short tport1,tport2,tmpnum;
615 char matches,was_found;
616 unsigned long flags;
617
618 save_flags(flags);
619 cli();
620
621 ftmp=*chainptr;
622
623 if ( ftmp == NULL )
624 {
625 #ifdef DEBUG_CONFIG_IP_FIREWALL
626 printk("ip_fw_ctl: chain is empty\n");
627 #endif
628 restore_flags(flags);
629 return( EINVAL );
630 }
631
632 ltmp=NULL;
633 was_found=0;
634
635 while( ftmp != NULL )
636 {
637 matches=1;
638 if (ftmp->fw_src.s_addr!=frwl->fw_src.s_addr
639 || ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr
640 || ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr
641 || ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr
642 || ftmp->fw_via.s_addr!=frwl->fw_via.s_addr
643 || ftmp->fw_flg!=frwl->fw_flg)
644 matches=0;
645
646 tport1=ftmp->fw_nsp+ftmp->fw_ndp;
647 tport2=frwl->fw_nsp+frwl->fw_ndp;
648 if (tport1!=tport2)
649 matches=0;
650 else if (tport1!=0)
651 {
652 for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
653 if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum])
654 matches=0;
655 }
656 if(matches)
657 {
658 was_found=1;
659 if (ltmp)
660 {
661 ltmp->fw_next=ftmp->fw_next;
662 kfree_s(ftmp,sizeof(*ftmp));
663 ftmp=ltmp->fw_next;
664 }
665 else
666 {
667 *chainptr=ftmp->fw_next;
668 kfree_s(ftmp,sizeof(*ftmp));
669 ftmp=*chainptr;
670 }
671 }
672 else
673 {
674 ltmp = ftmp;
675 ftmp = ftmp->fw_next;
676 }
677 }
678 restore_flags(flags);
679 if (was_found)
680 return 0;
681 else
682 return(EINVAL);
683 }
684
685 #endif
686
687 struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
688 {
689
690 if ( len != sizeof(struct ip_fw) )
691 {
692 #ifdef DEBUG_CONFIG_IP_FIREWALL
693 printk("ip_fw_ctl: len=%d, want %d\n",m->m_len,
694 sizeof(struct ip_fw));
695 #endif
696 return(NULL);
697 }
698
699 if ( (frwl->fw_flg & ~IP_FW_F_MASK) != 0 )
700 {
701 #ifdef DEBUG_CONFIG_IP_FIREWALL
702 printk("ip_fw_ctl: undefined flag bits set (flags=%x)\n",
703 frwl->fw_flg);
704 #endif
705 return(NULL);
706 }
707
708 if ( (frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2 )
709 {
710 #ifdef DEBUG_CONFIG_IP_FIREWALL
711 printk("ip_fw_ctl: src range set but n_src_p=%d\n",
712 frwl->fw_nsp);
713 #endif
714 return(NULL);
715 }
716
717 if ( (frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2 )
718 {
719 #ifdef DEBUG_CONFIG_IP_FIREWALL
720 printk("ip_fw_ctl: dst range set but n_dst_p=%d\n",
721 frwl->fw_ndp);
722 #endif
723 return(NULL);
724 }
725
726 if ( frwl->fw_nsp + frwl->fw_ndp > IP_FW_MAX_PORTS )
727 {
728 #ifdef DEBUG_CONFIG_IP_FIREWALL
729 printk("ip_fw_ctl: too many ports (%d+%d)\n",
730 frwl->fw_nsp,frwl->fw_ndp);
731 #endif
732 return(NULL);
733 }
734
735 return frwl;
736 }
737
738
739
740
741 #ifdef CONFIG_IP_ACCT
742
743 void ip_acct_cnt(struct iphdr *iph, struct device *dev, struct ip_fw *f)
744 {
745 (void) ip_fw_chk(iph, dev, f, 0, 1);
746 return;
747 }
748
749 int ip_acct_ctl(int stage, void *m, int len)
750 {
751 if ( stage == IP_ACCT_FLUSH )
752 {
753 free_fw_chain(&ip_acct_chain);
754 return(0);
755 }
756 if ( stage == IP_ACCT_ZERO )
757 {
758 zero_fw_chain(ip_acct_chain);
759 return(0);
760 }
761 if ( stage == IP_ACCT_ADD
762 || stage == IP_ACCT_DEL
763 )
764 {
765 struct ip_fw *frwl;
766
767 if (!(frwl=check_ipfw_struct(m,len)))
768 return (EINVAL);
769
770 switch (stage)
771 {
772 case IP_ACCT_ADD:
773 return( add_to_chain(&ip_acct_chain,frwl));
774 case IP_ACCT_DEL:
775 return( del_from_chain(&ip_acct_chain,frwl));
776 default:
777
778
779
780 #ifdef DEBUG_CONFIG_IP_FIREWALL
781 printf("ip_acct_ctl: unknown request %d\n",stage);
782 #endif
783 return(EINVAL);
784 }
785 }
786 #ifdef DEBUG_CONFIG_IP_FIREWALL
787 printf("ip_acct_ctl: unknown request %d\n",stage);
788 #endif
789 return(EINVAL);
790 }
791 #endif
792
793 #ifdef CONFIG_IP_FIREWALL
794 int ip_fw_ctl(int stage, void *m, int len)
795 {
796 int ret;
797
798 if ( stage == IP_FW_FLUSH_BLK )
799 {
800 free_fw_chain(&ip_fw_blk_chain);
801 return(0);
802 }
803
804 if ( stage == IP_FW_FLUSH_FWD )
805 {
806 free_fw_chain(&ip_fw_fwd_chain);
807 return(0);
808 }
809
810 if ( stage == IP_FW_ZERO_BLK )
811 {
812 zero_fw_chain(ip_fw_blk_chain);
813 return(0);
814 }
815
816 if ( stage == IP_FW_ZERO_FWD )
817 {
818 zero_fw_chain(ip_fw_fwd_chain);
819 return(0);
820 }
821
822 if ( stage == IP_FW_POLICY_BLK || stage == IP_FW_POLICY_FWD )
823 {
824 int *tmp_policy_ptr;
825 tmp_policy_ptr=(int *)m;
826 if ( stage == IP_FW_POLICY_BLK )
827 ip_fw_blk_policy=*tmp_policy_ptr;
828 else
829 ip_fw_fwd_policy=*tmp_policy_ptr;
830 return 0;
831 }
832
833 if ( stage == IP_FW_CHK_BLK || stage == IP_FW_CHK_FWD )
834 {
835 struct device viadev;
836 struct ip_fwpkt *ipfwp;
837 struct iphdr *ip;
838
839 if ( len < sizeof(struct ip_fwpkt) )
840 {
841 #ifdef DEBUG_CONFIG_IP_FIREWALL
842 printf("ip_fw_ctl: length=%d, expected %d\n",
843 len, sizeof(struct ip_fwpkt));
844 #endif
845 return( EINVAL );
846 }
847
848 ipfwp = (struct ip_fwpkt *)m;
849 ip = &(ipfwp->fwp_iph);
850
851 if ( ip->ihl != sizeof(struct iphdr) / sizeof(int))
852 {
853 #ifdef DEBUG_CONFIG_IP_FIREWALL
854 printf("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
855 sizeof(struct ip)/sizeof(int));
856 #endif
857 return(EINVAL);
858 }
859
860 viadev.pa_addr = ipfwp->fwp_via.s_addr;
861
862 if ((ret = ip_fw_chk(ip, &viadev,
863 stage == IP_FW_CHK_BLK ?
864 ip_fw_blk_chain : ip_fw_fwd_chain,
865 stage == IP_FW_CHK_BLK ?
866 ip_fw_blk_policy : ip_fw_fwd_policy, 2 )) > 0
867 )
868 return(0);
869 else if (ret == -1)
870 return(ECONNREFUSED);
871 else
872 return(ETIMEDOUT);
873 }
874
875
876
877
878
879
880 if ( stage == IP_FW_ADD_BLK || stage == IP_FW_ADD_FWD
881 || stage == IP_FW_DEL_BLK || stage == IP_FW_DEL_FWD
882 )
883 {
884 struct ip_fw *frwl;
885 frwl=check_ipfw_struct(m,len);
886 if (frwl==NULL)
887 return (EINVAL);
888
889 switch (stage)
890 {
891 case IP_FW_ADD_BLK:
892 return(add_to_chain(&ip_fw_blk_chain,frwl));
893 case IP_FW_ADD_FWD:
894 return(add_to_chain(&ip_fw_fwd_chain,frwl));
895 case IP_FW_DEL_BLK:
896 return(del_from_chain(&ip_fw_blk_chain,frwl));
897 case IP_FW_DEL_FWD:
898 return(del_from_chain(&ip_fw_fwd_chain,frwl));
899 default:
900
901
902
903 #ifdef DEBUG_CONFIG_IP_FIREWALL
904 printk("ip_fw_ctl: unknown request %d\n",stage);
905 #endif
906 return(EINVAL);
907 }
908 }
909
910 #ifdef DEBUG_CONFIG_IP_FIREWALL
911 printf("ip_fw_ctl: unknown request %d\n",stage);
912 #endif
913 return(EINVAL);
914 }
915 #endif
916
917 #if defined(CONFIG_IP_FIREWALL) || defined(CONFIG_IP_ACCT)
918
919 static int ip_chain_procinfo(int stage, char *buffer, char **start,
920 off_t offset, int length, int reset)
921 {
922 off_t pos=0, begin=0;
923 struct ip_fw *i;
924 unsigned long flags;
925 int len, p;
926
927
928 switch(stage)
929 {
930 #ifdef CONFIG_IP_FIREWALL
931 case IP_INFO_BLK:
932 i = ip_fw_blk_chain;
933 len=sprintf(buffer, "IP firewall block rules, default %d\n",
934 ip_fw_blk_policy);
935 break;
936 case IP_INFO_FWD:
937 i = ip_fw_fwd_chain;
938 len=sprintf(buffer, "IP firewall forward rules, default %d\n",
939 ip_fw_fwd_policy);
940 break;
941 #endif
942 #ifdef CONFIG_IP_ACCT
943 case IP_INFO_ACCT:
944 i = ip_acct_chain;
945 len=sprintf(buffer,"IP accounting rules\n");
946 break;
947 #endif
948 default:
949
950 i = NULL;
951 len=0;
952 break;
953 }
954
955 save_flags(flags);
956 cli();
957
958 while(i!=NULL)
959 {
960 len+=sprintf(buffer+len,"%08lX/%08lX->%08lX/%08lX %08lX %X ",
961 ntohl(i->fw_src.s_addr),ntohl(i->fw_smsk.s_addr),
962 ntohl(i->fw_dst.s_addr),ntohl(i->fw_dmsk.s_addr),
963 ntohl(i->fw_via.s_addr),i->fw_flg);
964 len+=sprintf(buffer+len,"%u %u %lu %lu",
965 i->fw_nsp,i->fw_ndp, i->fw_pcnt,i->fw_bcnt);
966 for (p = 0; p < IP_FW_MAX_PORTS; p++)
967 len+=sprintf(buffer+len, " %u", i->fw_pts[p]);
968 buffer[len++]='\n';
969 buffer[len]='\0';
970 pos=begin+len;
971 if(pos<offset)
972 {
973 len=0;
974 begin=pos;
975 }
976 else if(reset)
977 {
978
979 i->fw_pcnt=0L;
980 i->fw_bcnt=0L;
981 }
982 if(pos>offset+length)
983 break;
984 i=i->fw_next;
985 }
986 restore_flags(flags);
987 *start=buffer+(offset-begin);
988 len-=(offset-begin);
989 if(len>length)
990 len=length;
991 return len;
992 }
993 #endif
994
995 #ifdef CONFIG_IP_ACCT
996
997 int ip_acct_procinfo(char *buffer, char **start, off_t offset, int length, int reset)
998 {
999 return ip_chain_procinfo(IP_INFO_ACCT, buffer,start,offset,length,reset);
1000 }
1001
1002 #endif
1003
1004 #ifdef CONFIG_IP_FIREWALL
1005
1006 int ip_fw_blk_procinfo(char *buffer, char **start, off_t offset, int length, int reset)
1007 {
1008 return ip_chain_procinfo(IP_INFO_BLK, buffer,start,offset,length,reset);
1009 }
1010
1011 int ip_fw_fwd_procinfo(char *buffer, char **start, off_t offset, int length, int reset)
1012 {
1013 return ip_chain_procinfo(IP_INFO_FWD, buffer,start,offset,length,reset);
1014 }
1015
1016 #endif