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 **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 #endif
454
455 #ifdef CONFIG_IP_FIREWALL
456
457 static int add_to_chain(struct ip_fw **chainptr, struct ip_fw *frwl)
458 {
459 struct ip_fw *ftmp;
460 struct ip_fw *chtmp=NULL;
461 struct ip_fw *chtmp_prev=NULL;
462 unsigned long flags;
463 unsigned long m_src_mask,m_dst_mask;
464 unsigned long n_sa,n_da,o_sa,o_da,o_sm,o_dm,n_sm,n_dm;
465 unsigned short n_sr,n_dr,o_sr,o_dr;
466 unsigned short oldkind,newkind;
467 int addb4=0;
468 int n_o,n_n;
469
470 save_flags(flags);
471
472 ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
473 if ( ftmp == NULL )
474 {
475 #ifdef DEBUG_CONFIG_IP_FIREWALL
476 printf("ip_fw_ctl: malloc said no\n");
477 #endif
478 return( ENOSPC );
479 }
480
481 memcpy(ftmp, frwl, sizeof( struct ip_fw ) );
482 ftmp->p_cnt=0L;
483 ftmp->b_cnt=0L;
484
485 ftmp->next = NULL;
486
487 cli();
488
489 if (*chainptr==NULL)
490 {
491 *chainptr=ftmp;
492 }
493 else
494 {
495 chtmp_prev=NULL;
496 for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->next)
497 {
498 addb4=0;
499 newkind=ftmp->flags & IP_FW_F_KIND;
500 oldkind=chtmp->flags & IP_FW_F_KIND;
501
502 if (newkind!=IP_FW_F_ALL
503 && oldkind!=IP_FW_F_ALL
504 && oldkind!=newkind)
505 {
506 chtmp_prev=chtmp;
507 continue;
508 }
509
510
511
512
513
514
515 n_sa=ntohl(ftmp->src.s_addr);
516 n_da=ntohl(ftmp->dst.s_addr);
517 n_sm=ntohl(ftmp->src_mask.s_addr);
518 n_dm=ntohl(ftmp->dst_mask.s_addr);
519
520 o_sa=ntohl(chtmp->src.s_addr);
521 o_da=ntohl(chtmp->dst.s_addr);
522 o_sm=ntohl(chtmp->src_mask.s_addr);
523 o_dm=ntohl(chtmp->dst_mask.s_addr);
524
525 m_src_mask = o_sm & n_sm;
526 m_dst_mask = o_dm & n_dm;
527
528 if ((o_sa & m_src_mask) == (n_sa & m_src_mask))
529 {
530 if (n_sm > o_sm)
531 addb4++;
532 if (n_sm < o_sm)
533 addb4--;
534 }
535
536 if ((o_da & m_dst_mask) == (n_da & m_dst_mask))
537 {
538 if (n_dm > o_dm)
539 addb4++;
540 if (n_dm < o_dm)
541 addb4--;
542 }
543
544 if (((o_da & o_dm) == (n_da & n_dm))
545 &&((o_sa & o_sm) == (n_sa & n_sm)))
546 {
547 if (newkind!=IP_FW_F_ALL &&
548 oldkind==IP_FW_F_ALL)
549 addb4++;
550 if (newkind==oldkind && (oldkind==IP_FW_F_TCP
551 || oldkind==IP_FW_F_UDP))
552 {
553
554
555
556
557
558
559
560
561
562
563
564
565 if (ftmp->flags & IP_FW_F_SRNG)
566 n_sr=ftmp->ports[1]-ftmp->ports[0];
567 else
568 n_sr=(ftmp->n_src_p)?ftmp->n_src_p : 0xFFFF;
569
570 if (chtmp->flags & IP_FW_F_SRNG)
571 o_sr=chtmp->ports[1]-chtmp->ports[0];
572 else
573 o_sr=(chtmp->n_src_p)?chtmp->n_src_p : 0xFFFF;
574
575 if (n_sr<o_sr)
576 addb4++;
577 if (n_sr>o_sr)
578 addb4--;
579
580 n_n=ftmp->n_src_p;
581 n_o=chtmp->n_src_p;
582
583
584
585
586
587
588
589 if ((n_n>(IP_FW_MAX_PORTS-2)) ||
590 (n_o>(IP_FW_MAX_PORTS-2)))
591 goto skip_check;
592
593 if (ftmp->flags & IP_FW_F_DRNG)
594 n_dr=ftmp->ports[n_n+1]-ftmp->ports[n_n];
595 else
596 n_dr=(ftmp->n_dst_p)? ftmp->n_dst_p : 0xFFFF;
597
598 if (chtmp->flags & IP_FW_F_DRNG)
599 o_dr=chtmp->ports[n_o+1]-chtmp->ports[n_o];
600 else
601 o_dr=(chtmp->n_dst_p)? chtmp->n_dst_p : 0xFFFF;
602 if (n_dr<o_dr)
603 addb4++;
604 if (n_dr>o_dr)
605 addb4--;
606 skip_check:
607 }
608 }
609 if (addb4>0)
610 {
611 if (chtmp_prev)
612 {
613 chtmp_prev->next=ftmp;
614 ftmp->next=chtmp;
615 }
616 else
617 {
618 *chainptr=ftmp;
619 ftmp->next=chtmp;
620 }
621 restore_flags(flags);
622 return 0;
623 }
624 chtmp_prev=chtmp;
625 }
626 }
627
628 if (chtmp_prev)
629 chtmp_prev->next=ftmp;
630 else
631 *chainptr=ftmp;
632 restore_flags(flags);
633 return(0);
634 }
635
636 static int del_from_chain(struct ip_fw **chainptr, struct ip_fw *frwl)
637 {
638 struct ip_fw *ftmp,*ltmp;
639 unsigned short tport1,tport2,tmpnum;
640 char matches,was_found;
641 unsigned long flags;
642
643 save_flags(flags);
644 cli();
645
646 ftmp=*chainptr;
647
648 if ( ftmp == NULL )
649 {
650 #ifdef DEBUG_CONFIG_IP_FIREWALL
651 printf("ip_fw_ctl: chain is empty\n");
652 #endif
653 restore_flags(flags);
654 return( EINVAL );
655 }
656
657 ltmp=NULL;
658 was_found=0;
659
660 while( ftmp != NULL )
661 {
662 matches=1;
663 if ((memcmp(&ftmp->src,&frwl->src,sizeof(struct in_addr)))
664 || (memcmp(&ftmp->src_mask,&frwl->src_mask,sizeof(struct in_addr)))
665 || (memcmp(&ftmp->dst,&frwl->dst,sizeof(struct in_addr)))
666 || (memcmp(&ftmp->dst_mask,&frwl->dst_mask,sizeof(struct in_addr)))
667 || (ftmp->flags!=frwl->flags))
668 matches=0;
669
670 tport1=ftmp->n_src_p+ftmp->n_dst_p;
671 tport2=frwl->n_src_p+frwl->n_dst_p;
672 if (tport1!=tport2)
673 matches=0;
674 else if (tport1!=0)
675 {
676 for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
677 if (ftmp->ports[tmpnum]!=frwl->ports[tmpnum])
678 matches=0;
679 }
680 if(matches)
681 {
682 was_found=1;
683 if (ltmp)
684 {
685 ltmp->next=ftmp->next;
686 kfree_s(ftmp,sizeof(*ftmp));
687 ftmp=ltmp->next;
688 }
689 else
690 {
691 *chainptr=ftmp->next;
692 kfree_s(ftmp,sizeof(*ftmp));
693 ftmp=*chainptr;
694 }
695 }
696 else
697 {
698 ltmp = ftmp;
699 ftmp = ftmp->next;
700 }
701 }
702 restore_flags(flags);
703 if (was_found)
704 return 0;
705 else
706 return(EINVAL);
707 }
708
709 #endif
710
711 struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
712 {
713
714 if ( len != sizeof(struct ip_fw) )
715 {
716 #ifdef DEBUG_CONFIG_IP_FIREWALL
717 printf("ip_fw_ctl: len=%d, want %d\n",m->m_len,
718 sizeof(struct ip_fw));
719 #endif
720 return(NULL);
721 }
722
723 if ( (frwl->flags & ~IP_FW_F_MASK) != 0 )
724 {
725 #ifdef DEBUG_CONFIG_IP_FIREWALL
726 printf("ip_fw_ctl: undefined flag bits set (flags=%x)\n",
727 frwl->flags);
728 #endif
729 return(NULL);
730 }
731
732 if ( (frwl->flags & IP_FW_F_SRNG) && frwl->n_src_p < 2 )
733 {
734 #ifdef DEBUG_CONFIG_IP_FIREWALL
735 printf("ip_fw_ctl: src range set but n_src_p=%d\n",
736 frwl->n_src_p);
737 #endif
738 return(NULL);
739 }
740
741 if ( (frwl->flags & IP_FW_F_DRNG) && frwl->n_dst_p < 2 )
742 {
743 #ifdef DEBUG_CONFIG_IP_FIREWALL
744 printf("ip_fw_ctl: dst range set but n_dst_p=%d\n",
745 frwl->n_dst_p);
746 #endif
747 return(NULL);
748 }
749
750 if ( frwl->n_src_p + frwl->n_dst_p > IP_FW_MAX_PORTS )
751 {
752 #ifdef DEBUG_CONFIG_IP_FIREWALL
753 printf("ip_fw_ctl: too many ports (%d+%d)\n",
754 frwl->n_src_p,frwl->n_dst_p);
755 #endif
756 return(NULL);
757 }
758
759 return frwl;
760 }
761
762
763
764
765 #ifdef CONFIG_IP_ACCT
766 int ip_acct_ctl(int stage, void *m, int len)
767 {
768 if ( stage == IP_ACCT_FLUSH )
769 {
770 free_fw_chain(&ip_acct_chain);
771 return(0);
772 }
773 if ( stage == IP_ACCT_ZERO )
774 {
775 zero_fw_chain(ip_acct_chain);
776 return(0);
777 }
778 if ( stage == IP_ACCT_ADD
779 || stage == IP_ACCT_DEL
780 )
781 {
782 struct ip_fw *frwl;
783
784 if (!(frwl=check_ipfw_struct(m,len)))
785 return (EINVAL);
786
787 switch (stage)
788 {
789 case IP_ACCT_ADD:
790 return( add_to_chain(&ip_acct_chain,frwl));
791 case IP_ACCT_DEL:
792 return( del_from_chain(&ip_acct_chain,frwl));
793 default:
794
795
796
797 #ifdef DEBUG_CONFIG_IP_FIREWALL
798 printf("ip_acct_ctl: unknown request %d\n",stage);
799 #endif
800 return(EINVAL);
801 }
802 }
803 #ifdef DEBUG_CONFIG_IP_FIREWALL
804 printf("ip_acct_ctl: unknown request %d\n",stage);
805 #endif
806 return(EINVAL);
807 }
808 #endif
809
810 #ifdef CONFIG_IP_FIREWALL
811 int ip_fw_ctl(int stage, void *m, int len)
812 {
813 if ( stage == IP_FW_FLUSH )
814 {
815 free_fw_chain(&ip_fw_blk_chain);
816 free_fw_chain(&ip_fw_fwd_chain);
817 return(0);
818 }
819
820 if ( stage == IP_FW_POLICY )
821 {
822 int *tmp_policy_ptr;
823 tmp_policy_ptr=(int *)m;
824 if ((*tmp_policy_ptr)!=1 && (*tmp_policy_ptr)!=0)
825 return (EINVAL);
826 ip_fw_policy=*tmp_policy_ptr;
827 return 0;
828 }
829
830 if ( stage == IP_FW_CHK_BLK
831 || stage == IP_FW_CHK_FWD )
832 {
833 struct iphdr *ip;
834
835 if ( len < sizeof(struct iphdr) + 2 * sizeof(unsigned short) )
836 {
837 #ifdef DEBUG_CONFIG_IP_FIREWALL
838 printf("ip_fw_ctl: len=%d, want at least %d\n",
839 len,sizeof(struct ip) + 2 * sizeof(unsigned short));
840 #endif
841 return( EINVAL );
842 }
843
844 ip = (struct iphdr *)m;
845
846 if ( ip->ihl != sizeof(struct iphdr) / sizeof(int))
847 {
848 #ifdef DEBUG_CONFIG_IP_FIREWALL
849 printf("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
850 sizeof(struct ip)/sizeof(int));
851 #endif
852 return(EINVAL);
853 }
854
855 if ( ip_fw_chk(ip,
856 stage == IP_FW_CHK_BLK ?
857 ip_fw_blk_chain : ip_fw_fwd_chain )
858 )
859 return(0);
860 else
861 return(EACCES);
862 }
863
864
865
866
867
868
869 if ( stage == IP_FW_ADD_BLK || stage == IP_FW_ADD_FWD
870 || stage == IP_FW_DEL_BLK || stage == IP_FW_DEL_FWD
871 )
872 {
873 struct ip_fw *frwl;
874 frwl=check_ipfw_struct(m,len);
875 if (frwl==NULL)
876 return (EINVAL);
877
878 switch (stage)
879 {
880 case IP_FW_ADD_BLK:
881 return(add_to_chain(&ip_fw_blk_chain,frwl));
882 case IP_FW_ADD_FWD:
883 return(add_to_chain(&ip_fw_fwd_chain,frwl));
884 case IP_FW_DEL_BLK:
885 return(del_from_chain(&ip_fw_blk_chain,frwl));
886 case IP_FW_DEL_FWD:
887 return(del_from_chain(&ip_fw_fwd_chain,frwl));
888 default:
889
890
891
892 #ifdef DEBUG_CONFIG_IP_FIREWALL
893 printf("ip_fw_ctl: unknown request %d\n",stage);
894 #endif
895 return(EINVAL);
896 }
897 }
898
899 #ifdef DEBUG_CONFIG_IP_FIREWALL
900 printf("ip_fw_ctl: unknown request %d\n",stage);
901 #endif
902 return(EINVAL);
903 }
904 #endif
905
906 #if defined(CONFIG_IP_FIREWALL) || defined(CONFIG_IP_ACCT)
907
908 static int ip_chain_procinfo(struct ip_fw *chain, char *buffer, char **start, off_t offset, int length)
909 {
910 off_t pos=0, begin=0;
911 struct ip_fw *i;
912 unsigned long flags;
913 int len=0;
914
915
916 len=sprintf(buffer,"Firewall Rules\n");
917 save_flags(flags);
918 cli();
919
920 i=chain;
921
922 while(i!=NULL)
923 {
924 len+=sprintf(buffer+len,"%08lX/%08lX->%08lX/%08lX %X ",
925 ntohl(i->src.s_addr),ntohl(i->src_mask.s_addr),
926 ntohl(i->dst.s_addr),ntohl(i->dst_mask.s_addr),
927 i->flags);
928 len+=sprintf(buffer+len,"%u %u %lu %lu ",
929 i->n_src_p,i->n_dst_p, i->p_cnt,i->b_cnt);
930 len+=sprintf(buffer+len,"%u %u %u %u %u %u %u %u %u %u\n",
931 i->ports[0],i->ports[1],i->ports[2],i->ports[3],
932 i->ports[4],i->ports[5],i->ports[6],i->ports[7],
933 i->ports[8],i->ports[9]);
934 pos=begin+len;
935 if(pos<offset)
936 {
937 len=0;
938 begin=pos;
939 }
940 if(pos>offset+length)
941 break;
942 i=i->next;
943 }
944 restore_flags(flags);
945 *start=buffer+(offset-begin);
946 len-=(offset-begin);
947 if(len>length)
948 len=length;
949 return len;
950 }
951 #endif
952
953 #ifdef CONFIG_IP_ACCT
954
955 int ip_acct_procinfo(char *buffer, char **start, off_t offset, int length)
956 {
957 return ip_chain_procinfo(ip_acct_chain, buffer,start,offset,length);
958 }
959
960 #endif
961
962 #ifdef CONFIG_IP_FIREWALL
963
964 int ip_fw_blk_procinfo(char *buffer, char **start, off_t offset, int length)
965 {
966 return ip_chain_procinfo(ip_fw_blk_chain, buffer,start,offset,length);
967 }
968
969 int ip_fw_fwd_procinfo(char *buffer, char **start, off_t offset, int length)
970 {
971 return ip_chain_procinfo(ip_fw_fwd_chain, buffer,start,offset,length);
972 }
973
974 #endif