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