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