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