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
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 {
632 *chainptr=ftmp;
633 printk("ip_fw: add_to_chain: Can't happen");
634 }
635 restore_flags(flags);
636 return(0);
637 }
638
639 static int del_from_chain(struct ip_fw **chainptr, struct ip_fw *frwl)
640 {
641 struct ip_fw *ftmp,*ltmp;
642 unsigned short tport1,tport2,tmpnum;
643 char matches,was_found;
644 unsigned long flags;
645
646 save_flags(flags);
647 cli();
648
649 ftmp=*chainptr;
650
651 if ( ftmp == NULL )
652 {
653 #ifdef DEBUG_CONFIG_IP_FIREWALL
654 printf("ip_fw_ctl: chain is empty\n");
655 #endif
656 restore_flags(flags);
657 return( EINVAL );
658 }
659
660 ltmp=NULL;
661 was_found=0;
662
663 while( ftmp != NULL )
664 {
665 matches=1;
666 if ((memcmp(&ftmp->src,&frwl->src,sizeof(struct in_addr)))
667 || (memcmp(&ftmp->src_mask,&frwl->src_mask,sizeof(struct in_addr)))
668 || (memcmp(&ftmp->dst,&frwl->dst,sizeof(struct in_addr)))
669 || (memcmp(&ftmp->dst_mask,&frwl->dst_mask,sizeof(struct in_addr)))
670 || (ftmp->flags!=frwl->flags))
671 matches=0;
672
673 tport1=ftmp->n_src_p+ftmp->n_dst_p;
674 tport2=frwl->n_src_p+frwl->n_dst_p;
675 if (tport1!=tport2)
676 matches=0;
677 else if (tport1!=0)
678 {
679 for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
680 if (ftmp->ports[tmpnum]!=frwl->ports[tmpnum])
681 matches=0;
682 }
683 if(matches)
684 {
685 was_found=1;
686 if (ltmp)
687 {
688 ltmp->next=ftmp->next;
689 kfree_s(ftmp,sizeof(*ftmp));
690 ftmp=ltmp->next;
691 }
692 else
693 {
694 *chainptr=ftmp->next;
695 kfree_s(ftmp,sizeof(*ftmp));
696 ftmp=*chainptr;
697 }
698 }
699 else
700 {
701 ltmp = ftmp;
702 ftmp = ftmp->next;
703 }
704 }
705 restore_flags(flags);
706 if (was_found)
707 return 0;
708 else
709 return(EINVAL);
710 }
711
712 #endif
713
714 struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
715 {
716
717 if ( len != sizeof(struct ip_fw) )
718 {
719 #ifdef DEBUG_CONFIG_IP_FIREWALL
720 printf("ip_fw_ctl: len=%d, want %d\n",m->m_len,
721 sizeof(struct ip_fw));
722 #endif
723 return(NULL);
724 }
725
726 if ( (frwl->flags & ~IP_FW_F_MASK) != 0 )
727 {
728 #ifdef DEBUG_CONFIG_IP_FIREWALL
729 printf("ip_fw_ctl: undefined flag bits set (flags=%x)\n",
730 frwl->flags);
731 #endif
732 return(NULL);
733 }
734
735 if ( (frwl->flags & IP_FW_F_SRNG) && frwl->n_src_p < 2 )
736 {
737 #ifdef DEBUG_CONFIG_IP_FIREWALL
738 printf("ip_fw_ctl: src range set but n_src_p=%d\n",
739 frwl->n_src_p);
740 #endif
741 return(NULL);
742 }
743
744 if ( (frwl->flags & IP_FW_F_DRNG) && frwl->n_dst_p < 2 )
745 {
746 #ifdef DEBUG_CONFIG_IP_FIREWALL
747 printf("ip_fw_ctl: dst range set but n_dst_p=%d\n",
748 frwl->n_dst_p);
749 #endif
750 return(NULL);
751 }
752
753 if ( frwl->n_src_p + frwl->n_dst_p > IP_FW_MAX_PORTS )
754 {
755 #ifdef DEBUG_CONFIG_IP_FIREWALL
756 printf("ip_fw_ctl: too many ports (%d+%d)\n",
757 frwl->n_src_p,frwl->n_dst_p);
758 #endif
759 return(NULL);
760 }
761
762 return frwl;
763 }
764
765
766
767
768 #ifdef CONFIG_IP_ACCT
769 int ip_acct_ctl(int stage, void *m, int len)
770 {
771 if ( stage == IP_ACCT_FLUSH )
772 {
773 free_fw_chain(&ip_acct_chain);
774 return(0);
775 }
776 if ( stage == IP_ACCT_ZERO )
777 {
778 zero_fw_chain(ip_acct_chain);
779 return(0);
780 }
781 if ( stage == IP_ACCT_ADD
782 || stage == IP_ACCT_DEL
783 )
784 {
785 struct ip_fw *frwl;
786
787 if (!(frwl=check_ipfw_struct(m,len)))
788 return (EINVAL);
789
790 switch (stage)
791 {
792 case IP_ACCT_ADD:
793 return( add_to_chain(&ip_acct_chain,frwl));
794 case IP_ACCT_DEL:
795 return( del_from_chain(&ip_acct_chain,frwl));
796 default:
797
798
799
800 #ifdef DEBUG_CONFIG_IP_FIREWALL
801 printf("ip_acct_ctl: unknown request %d\n",stage);
802 #endif
803 return(EINVAL);
804 }
805 }
806 #ifdef DEBUG_CONFIG_IP_FIREWALL
807 printf("ip_acct_ctl: unknown request %d\n",stage);
808 #endif
809 return(EINVAL);
810 }
811 #endif
812
813 #ifdef CONFIG_IP_FIREWALL
814 int ip_fw_ctl(int stage, void *m, int len)
815 {
816 if ( stage == IP_FW_FLUSH )
817 {
818 free_fw_chain(&ip_fw_blk_chain);
819 free_fw_chain(&ip_fw_fwd_chain);
820 return(0);
821 }
822
823 if ( stage == IP_FW_POLICY )
824 {
825 int *tmp_policy_ptr;
826 tmp_policy_ptr=(int *)m;
827 if ((*tmp_policy_ptr)!=1 && (*tmp_policy_ptr)!=0)
828 return (EINVAL);
829 ip_fw_policy=*tmp_policy_ptr;
830 return 0;
831 }
832
833 if ( stage == IP_FW_CHK_BLK
834 || stage == IP_FW_CHK_FWD )
835 {
836 struct iphdr *ip;
837
838 if ( len < sizeof(struct iphdr) + 2 * sizeof(unsigned short) )
839 {
840 #ifdef DEBUG_CONFIG_IP_FIREWALL
841 printf("ip_fw_ctl: len=%d, want at least %d\n",
842 len,sizeof(struct ip) + 2 * sizeof(unsigned short));
843 #endif
844 return( EINVAL );
845 }
846
847 ip = (struct iphdr *)m;
848
849 if ( ip->ihl != sizeof(struct iphdr) / sizeof(int))
850 {
851 #ifdef DEBUG_CONFIG_IP_FIREWALL
852 printf("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
853 sizeof(struct ip)/sizeof(int));
854 #endif
855 return(EINVAL);
856 }
857
858 if ( ip_fw_chk(ip,
859 stage == IP_FW_CHK_BLK ?
860 ip_fw_blk_chain : ip_fw_fwd_chain )
861 )
862 return(0);
863 else
864 return(EACCES);
865 }
866
867
868
869
870
871
872 if ( stage == IP_FW_ADD_BLK || stage == IP_FW_ADD_FWD
873 || stage == IP_FW_DEL_BLK || stage == IP_FW_DEL_FWD
874 )
875 {
876 struct ip_fw *frwl;
877 frwl=check_ipfw_struct(m,len);
878 if (frwl==NULL)
879 return (EINVAL);
880
881 switch (stage)
882 {
883 case IP_FW_ADD_BLK:
884 return(add_to_chain(&ip_fw_blk_chain,frwl));
885 case IP_FW_ADD_FWD:
886 return(add_to_chain(&ip_fw_fwd_chain,frwl));
887 case IP_FW_DEL_BLK:
888 return(del_from_chain(&ip_fw_blk_chain,frwl));
889 case IP_FW_DEL_FWD:
890 return(del_from_chain(&ip_fw_fwd_chain,frwl));
891 default:
892
893
894
895 #ifdef DEBUG_CONFIG_IP_FIREWALL
896 printf("ip_fw_ctl: unknown request %d\n",stage);
897 #endif
898 return(EINVAL);
899 }
900 }
901
902 #ifdef DEBUG_CONFIG_IP_FIREWALL
903 printf("ip_fw_ctl: unknown request %d\n",stage);
904 #endif
905 return(EINVAL);
906 }
907 #endif