This source file includes following definitions.
- port_match
- ip_fw_chk
- zero_fw_chain
- free_fw_chain
- insert_in_chain
- append_to_chain
- del_from_chain
- check_ipfw_struct
- ip_acct_cnt
- ip_acct_ctl
- ip_fw_ctl
- ip_chain_procinfo
- ip_acct_procinfo
- ip_fw_in_procinfo
- ip_fw_out_procinfo
- ip_fw_fwd_procinfo
- ipfw_input_check
- ipfw_output_check
- ipfw_forward_check
- ipfw_device_event
- ip_fw_init
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 #include <linux/config.h>
78 #include <asm/segment.h>
79 #include <asm/system.h>
80 #include <linux/types.h>
81 #include <linux/kernel.h>
82 #include <linux/sched.h>
83 #include <linux/string.h>
84 #include <linux/errno.h>
85 #include <linux/config.h>
86
87 #include <linux/socket.h>
88 #include <linux/sockios.h>
89 #include <linux/in.h>
90 #include <linux/inet.h>
91 #include <linux/netdevice.h>
92 #include <linux/icmp.h>
93 #include <linux/udp.h>
94 #include <net/ip.h>
95 #include <net/protocol.h>
96 #include <net/route.h>
97 #include <net/tcp.h>
98 #include <net/udp.h>
99 #include <linux/skbuff.h>
100 #include <net/sock.h>
101 #include <net/icmp.h>
102 #include <linux/firewall.h>
103 #include <linux/ip_fw.h>
104
105 #ifdef CONFIG_IP_MASQUERADE
106 #include <net/ip_masq.h>
107 #endif
108
109 #include <net/checksum.h>
110 #include <linux/proc_fs.h>
111 #include <linux/stat.h>
112
113
114
115
116
117 #ifdef CONFIG_IP_FIREWALL_DEBUG
118 #define dprintf1(a) printk(a)
119 #define dprintf2(a1,a2) printk(a1,a2)
120 #define dprintf3(a1,a2,a3) printk(a1,a2,a3)
121 #define dprintf4(a1,a2,a3,a4) printk(a1,a2,a3,a4)
122 #else
123 #define dprintf1(a)
124 #define dprintf2(a1,a2)
125 #define dprintf3(a1,a2,a3)
126 #define dprintf4(a1,a2,a3,a4)
127 #endif
128
129 #define print_ip(a) printk("%ld.%ld.%ld.%ld",(ntohl(a)>>24)&0xFF,\
130 (ntohl(a)>>16)&0xFF,\
131 (ntohl(a)>>8)&0xFF,\
132 (ntohl(a))&0xFF);
133
134 #ifdef CONFIG_IP_FIREWALL_DEBUG
135 #define dprint_ip(a) print_ip(a)
136 #else
137 #define dprint_ip(a)
138 #endif
139
140 #if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
141
142 struct ip_fw *ip_fw_fwd_chain;
143 struct ip_fw *ip_fw_in_chain;
144 struct ip_fw *ip_fw_out_chain;
145 struct ip_fw *ip_acct_chain;
146
147 static struct ip_fw **chains[] =
148 {&ip_fw_fwd_chain, &ip_fw_in_chain, &ip_fw_out_chain, &ip_acct_chain};
149
150 int ip_fw_fwd_policy=IP_FW_F_ACCEPT;
151 int ip_fw_in_policy=IP_FW_F_ACCEPT;
152 int ip_fw_out_policy=IP_FW_F_ACCEPT;
153
154 static int *policies[] =
155 {&ip_fw_fwd_policy, &ip_fw_in_policy, &ip_fw_out_policy};
156
157 #endif
158
159
160
161
162
163 extern inline int port_match(unsigned short *portptr,int nports,unsigned short port,int range_flag)
164 {
165 if (!nports)
166 return 1;
167 if ( range_flag )
168 {
169 if ( portptr[0] <= port && port <= portptr[1] )
170 {
171 return( 1 );
172 }
173 nports -= 2;
174 portptr += 2;
175 }
176 while ( nports-- > 0 )
177 {
178 if ( *portptr++ == port )
179 {
180 return( 1 );
181 }
182 }
183 return(0);
184 }
185
186 #if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
187
188
189
190
191
192
193
194
195
196
197
198
199
200 int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int policy, int opt)
201 {
202 struct ip_fw *f;
203 struct tcphdr *tcp=(struct tcphdr *)((unsigned long *)ip+ip->ihl);
204 struct udphdr *udp=(struct udphdr *)((unsigned long *)ip+ip->ihl);
205 struct icmphdr *icmp=(struct icmphdr *)((unsigned long *)ip+ip->ihl);
206 __u32 src, dst;
207 __u16 src_port=0xFFFF, dst_port=0xFFFF, icmp_type=0xFF;
208 unsigned short f_prt=0, prt;
209 char notcpsyn=1, notcpack=1, match;
210 unsigned short offset;
211 int answer;
212 unsigned char tosand, tosxor;
213
214
215
216
217
218
219
220 src = ip->saddr;
221 dst = ip->daddr;
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237 offset = ntohs(ip->frag_off) & IP_OFFSET;
238
239
240
241
242
243
244
245
246 if (offset == 1 && ip->protocol == IPPROTO_TCP)
247 return FW_BLOCK;
248
249 if (offset!=0 && (opt != 1) && (ip->protocol == IPPROTO_TCP ||
250 ip->protocol == IPPROTO_UDP || ip->protocol == IPPROTO_ICMP))
251 return FW_ACCEPT;
252
253
254
255
256
257 if(ip->protocol==IPPROTO_TCP && (ip->ihl<<2)+16 > ntohs(ip->tot_len))
258 return FW_BLOCK;
259
260
261
262
263
264 else if(ntohs(ip->tot_len)<8+(ip->ihl<<2))
265 return FW_BLOCK;
266
267 src = ip->saddr;
268 dst = ip->daddr;
269
270
271
272
273
274
275
276
277
278 dprintf1("Packet ");
279 switch(ip->protocol)
280 {
281 case IPPROTO_TCP:
282 dprintf1("TCP ");
283
284 if (!offset) {
285 src_port=ntohs(tcp->source);
286 dst_port=ntohs(tcp->dest);
287 if(tcp->ack)
288
289 notcpack=0;
290 if(tcp->syn && notcpack)
291
292 notcpsyn=0;
293 }
294 prt=IP_FW_F_TCP;
295 break;
296 case IPPROTO_UDP:
297 dprintf1("UDP ");
298
299 if (!offset) {
300 src_port=ntohs(udp->source);
301 dst_port=ntohs(udp->dest);
302 }
303 prt=IP_FW_F_UDP;
304 break;
305 case IPPROTO_ICMP:
306
307 if (!offset)
308 icmp_type=(__u16)(icmp->type);
309 dprintf2("ICMP:%d ",icmp_type);
310 prt=IP_FW_F_ICMP;
311 break;
312 default:
313 dprintf2("p=%d ",ip->protocol);
314 prt=IP_FW_F_ALL;
315 break;
316 }
317 #ifdef CONFIG_IP_FIREWALL_DEBUG
318 dprint_ip(ip->saddr);
319
320 if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP)
321
322 dprintf2(":%d ", src_port);
323 dprint_ip(ip->daddr);
324 if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP)
325
326 dprintf2(":%d ",dst_port);
327 dprintf1("\n");
328 #endif
329
330 for (f=chain;f;f=f->fw_next)
331 {
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349 match = 0x00;
350
351 if ((src&f->fw_smsk.s_addr)==f->fw_src.s_addr
352 && (dst&f->fw_dmsk.s_addr)==f->fw_dst.s_addr)
353
354 match |= 0x01;
355
356 if ((f->fw_flg & IP_FW_F_BIDIR) &&
357 (dst&f->fw_smsk.s_addr)==f->fw_src.s_addr
358 && (src&f->fw_dmsk.s_addr)==f->fw_dst.s_addr)
359
360 match |= 0x02;
361
362 if (match)
363 {
364
365
366
367 if(f->fw_via.s_addr && rif)
368 {
369 if(rif->pa_addr!=f->fw_via.s_addr)
370 continue;
371 }
372
373
374
375
376 if(f->fw_viadev)
377 {
378 if(rif!=f->fw_viadev)
379 continue;
380 }
381
382
383
384
385 }
386 else
387 continue;
388
389
390
391
392
393 f_prt=f->fw_flg&IP_FW_F_KIND;
394 if (f_prt!=IP_FW_F_ALL)
395 {
396
397
398
399
400
401
402
403 if((f->fw_flg&IP_FW_F_TCPSYN) && notcpsyn)
404 continue;
405
406 if((f->fw_flg&IP_FW_F_TCPACK) && notcpack)
407 continue;
408
409
410
411
412
413
414 if(prt!=f_prt)
415 continue;
416
417 if((prt==IP_FW_F_ICMP &&
418 ! port_match(&f->fw_pts[0], f->fw_nsp,
419 icmp_type,f->fw_flg&IP_FW_F_SRNG)) ||
420 !(prt==IP_FW_F_ICMP || ((match & 0x01) &&
421 port_match(&f->fw_pts[0], f->fw_nsp, src_port,
422 f->fw_flg&IP_FW_F_SRNG) &&
423 port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, dst_port,
424 f->fw_flg&IP_FW_F_DRNG)) || ((match & 0x02) &&
425 port_match(&f->fw_pts[0], f->fw_nsp, dst_port,
426 f->fw_flg&IP_FW_F_SRNG) &&
427 port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, src_port,
428 f->fw_flg&IP_FW_F_DRNG))))
429 {
430 continue;
431 }
432 }
433 #ifdef CONFIG_IP_FIREWALL_VERBOSE
434
435
436
437
438
439 if (f->fw_flg & IP_FW_F_PRN)
440 {
441 if(opt != 1) {
442 if(f->fw_flg&IP_FW_F_ACCEPT) {
443 if(f->fw_flg&IP_FW_F_MASQ)
444 printk("masq ");
445 else
446 printk("acc ");
447 } else if(f->fw_flg&IP_FW_F_ICMPRPL)
448 printk("rej ");
449 else
450 printk("deny ");
451 }
452 if (rif)
453 printk("%s ", rif->name);
454 switch(ip->protocol)
455 {
456 case IPPROTO_TCP:
457 printk("TCP ");
458 break;
459 case IPPROTO_UDP:
460 printk("UDP ");
461 break;
462 case IPPROTO_ICMP:
463 printk("ICMP:%d ", icmp_type);
464 break;
465 default:
466 printk("p=%d ",ip->protocol);
467 break;
468 }
469 print_ip(ip->saddr);
470 if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
471 printk(":%d", src_port);
472 printk(" ");
473 print_ip(ip->daddr);
474 if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
475 printk(":%d",dst_port);
476 printk("\n");
477 }
478 #endif
479 if (opt != 2) {
480 f->fw_bcnt+=ntohs(ip->tot_len);
481 f->fw_pcnt++;
482 }
483 if (opt != 1)
484 break;
485 }
486
487 if (opt != 1) {
488
489
490
491
492
493
494
495 if (f!=NULL) {
496 policy=f->fw_flg;
497 tosand=f->fw_tosand;
498 tosxor=f->fw_tosxor;
499 } else {
500 tosand=0xFF;
501 tosxor=0x00;
502 }
503
504 if (policy&IP_FW_F_ACCEPT) {
505
506 __u8 old_tos = ip->tos;
507 ip->tos = (old_tos & tosand) ^ tosxor;
508 if (ip->tos != old_tos)
509 ip_send_check(ip);
510 answer=(policy&IP_FW_F_MASQ)?FW_MASQUERADE:FW_ACCEPT;
511 } else if(policy&IP_FW_F_ICMPRPL)
512 answer = FW_REJECT;
513 else
514 answer = FW_BLOCK;
515
516 return answer;
517 } else
518
519 return 0;
520 }
521
522
523 static void zero_fw_chain(struct ip_fw *chainptr)
524 {
525 struct ip_fw *ctmp=chainptr;
526 while(ctmp)
527 {
528 ctmp->fw_pcnt=0L;
529 ctmp->fw_bcnt=0L;
530 ctmp=ctmp->fw_next;
531 }
532 }
533
534 static void free_fw_chain(struct ip_fw *volatile* chainptr)
535 {
536 unsigned long flags;
537 save_flags(flags);
538 cli();
539 while ( *chainptr != NULL )
540 {
541 struct ip_fw *ftmp;
542 ftmp = *chainptr;
543 *chainptr = ftmp->fw_next;
544 kfree_s(ftmp,sizeof(*ftmp));
545 }
546 restore_flags(flags);
547 }
548
549
550
551 static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,int len)
552 {
553 struct ip_fw *ftmp;
554 unsigned long flags;
555
556 save_flags(flags);
557
558 ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
559 if ( ftmp == NULL )
560 {
561 #ifdef DEBUG_CONFIG_IP_FIREWALL
562 printk("ip_fw_ctl: malloc said no\n");
563 #endif
564 return( ENOMEM );
565 }
566
567 memcpy(ftmp, frwl, len);
568
569
570
571
572 ftmp->fw_tosand |= 0x01;
573 ftmp->fw_tosxor &= 0xFE;
574 ftmp->fw_pcnt=0L;
575 ftmp->fw_bcnt=0L;
576
577 cli();
578
579 if ((ftmp->fw_vianame)[0]) {
580 if (!(ftmp->fw_viadev = dev_get(ftmp->fw_vianame)))
581 ftmp->fw_viadev = (struct device *) -1;
582 } else
583 ftmp->fw_viadev = NULL;
584
585 ftmp->fw_next = *chainptr;
586 *chainptr=ftmp;
587 restore_flags(flags);
588 return(0);
589 }
590
591 static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,int len)
592 {
593 struct ip_fw *ftmp;
594 struct ip_fw *chtmp=NULL;
595 struct ip_fw *volatile chtmp_prev=NULL;
596 unsigned long flags;
597
598 save_flags(flags);
599
600 ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
601 if ( ftmp == NULL )
602 {
603 #ifdef DEBUG_CONFIG_IP_FIREWALL
604 printk("ip_fw_ctl: malloc said no\n");
605 #endif
606 return( ENOMEM );
607 }
608
609 memcpy(ftmp, frwl, len);
610 ftmp->fw_tosand |= 0x03;
611 ftmp->fw_tosxor &= 0xFC;
612 ftmp->fw_pcnt=0L;
613 ftmp->fw_bcnt=0L;
614
615 ftmp->fw_next = NULL;
616
617 cli();
618
619 if ((ftmp->fw_vianame)[0]) {
620 if (!(ftmp->fw_viadev = dev_get(ftmp->fw_vianame)))
621 ftmp->fw_viadev = (struct device *) -1;
622 } else
623 ftmp->fw_viadev = NULL;
624
625 chtmp_prev=NULL;
626 for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->fw_next)
627 chtmp_prev=chtmp;
628
629 if (chtmp_prev)
630 chtmp_prev->fw_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 printk("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( !was_found && ftmp != NULL )
662 {
663 matches=1;
664 if (ftmp->fw_src.s_addr!=frwl->fw_src.s_addr
665 || ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr
666 || ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr
667 || ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr
668 || ftmp->fw_via.s_addr!=frwl->fw_via.s_addr
669 || ftmp->fw_flg!=frwl->fw_flg)
670 matches=0;
671
672 tport1=ftmp->fw_nsp+ftmp->fw_ndp;
673 tport2=frwl->fw_nsp+frwl->fw_ndp;
674 if (tport1!=tport2)
675 matches=0;
676 else if (tport1!=0)
677 {
678 for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
679 if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum])
680 matches=0;
681 }
682 if (strncmp(ftmp->fw_vianame, frwl->fw_vianame, IFNAMSIZ))
683 matches=0;
684 if(matches)
685 {
686 was_found=1;
687 if (ltmp)
688 {
689 ltmp->fw_next=ftmp->fw_next;
690 kfree_s(ftmp,sizeof(*ftmp));
691 ftmp=ltmp->fw_next;
692 }
693 else
694 {
695 *chainptr=ftmp->fw_next;
696 kfree_s(ftmp,sizeof(*ftmp));
697 ftmp=*chainptr;
698 }
699 }
700 else
701 {
702 ltmp = ftmp;
703 ftmp = ftmp->fw_next;
704 }
705 }
706 restore_flags(flags);
707 if (was_found)
708 return 0;
709 else
710 return(EINVAL);
711 }
712
713 #endif
714
715 struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
716 {
717
718 if ( len != sizeof(struct ip_fw) )
719 {
720 #ifdef DEBUG_CONFIG_IP_FIREWALL
721 printk("ip_fw_ctl: len=%d, want %d\n",len, sizeof(struct ip_fw));
722 #endif
723 return(NULL);
724 }
725
726 if ( (frwl->fw_flg & ~IP_FW_F_MASK) != 0 )
727 {
728 #ifdef DEBUG_CONFIG_IP_FIREWALL
729 printk("ip_fw_ctl: undefined flag bits set (flags=%x)\n",
730 frwl->fw_flg);
731 #endif
732 return(NULL);
733 }
734
735 if ( (frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2 )
736 {
737 #ifdef DEBUG_CONFIG_IP_FIREWALL
738 printk("ip_fw_ctl: src range set but fw_nsp=%d\n",
739 frwl->fw_nsp);
740 #endif
741 return(NULL);
742 }
743
744 if ( (frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2 )
745 {
746 #ifdef DEBUG_CONFIG_IP_FIREWALL
747 printk("ip_fw_ctl: dst range set but fw_ndp=%d\n",
748 frwl->fw_ndp);
749 #endif
750 return(NULL);
751 }
752
753 if ( frwl->fw_nsp + frwl->fw_ndp > IP_FW_MAX_PORTS )
754 {
755 #ifdef DEBUG_CONFIG_IP_FIREWALL
756 printk("ip_fw_ctl: too many ports (%d+%d)\n",
757 frwl->fw_nsp,frwl->fw_ndp);
758 #endif
759 return(NULL);
760 }
761
762 return frwl;
763 }
764
765
766
767
768 #ifdef CONFIG_IP_ACCT
769
770 #if 0
771 void ip_acct_cnt(struct iphdr *iph, struct device *dev, struct ip_fw *f)
772 {
773 (void) ip_fw_chk(iph, dev, f, 0, 1);
774 return;
775 }
776 #endif
777
778 int ip_acct_ctl(int stage, void *m, int len)
779 {
780 if ( stage == IP_ACCT_FLUSH )
781 {
782 free_fw_chain(&ip_acct_chain);
783 return(0);
784 }
785 if ( stage == IP_ACCT_ZERO )
786 {
787 zero_fw_chain(ip_acct_chain);
788 return(0);
789 }
790 if ( stage == IP_ACCT_INSERT || stage == IP_ACCT_APPEND ||
791 stage == IP_ACCT_DELETE )
792 {
793 struct ip_fw *frwl;
794
795 if (!(frwl=check_ipfw_struct(m,len)))
796 return (EINVAL);
797
798 switch (stage)
799 {
800 case IP_ACCT_INSERT:
801 return( insert_in_chain(&ip_acct_chain,frwl,len));
802 case IP_ACCT_APPEND:
803 return( append_to_chain(&ip_acct_chain,frwl,len));
804 case IP_ACCT_DELETE:
805 return( del_from_chain(&ip_acct_chain,frwl));
806 default:
807
808
809
810 #ifdef DEBUG_CONFIG_IP_FIREWALL
811 printk("ip_acct_ctl: unknown request %d\n",stage);
812 #endif
813 return(EINVAL);
814 }
815 }
816 #ifdef DEBUG_CONFIG_IP_FIREWALL
817 printk("ip_acct_ctl: unknown request %d\n",stage);
818 #endif
819 return(EINVAL);
820 }
821 #endif
822
823 #ifdef CONFIG_IP_FIREWALL
824 int ip_fw_ctl(int stage, void *m, int len)
825 {
826 int ret, cmd, fwtype;
827
828 cmd = stage & IP_FW_COMMAND;
829 fwtype = (stage & IP_FW_TYPE) >> IP_FW_SHIFT;
830
831 if ( cmd == IP_FW_FLUSH )
832 {
833 free_fw_chain(chains[fwtype]);
834 return(0);
835 }
836
837 if ( cmd == IP_FW_ZERO )
838 {
839 zero_fw_chain(*chains[fwtype]);
840 return(0);
841 }
842
843 if ( cmd == IP_FW_POLICY )
844 {
845 int *tmp_policy_ptr;
846 tmp_policy_ptr=(int *)m;
847 *policies[fwtype] = *tmp_policy_ptr;
848 return 0;
849 }
850
851 if ( cmd == IP_FW_CHECK )
852 {
853 struct device *viadev;
854 struct ip_fwpkt *ipfwp;
855 struct iphdr *ip;
856
857 if ( len != sizeof(struct ip_fwpkt) )
858 {
859 #ifdef DEBUG_CONFIG_IP_FIREWALL
860 printk("ip_fw_ctl: length=%d, expected %d\n",
861 len, sizeof(struct ip_fwpkt));
862 #endif
863 return( EINVAL );
864 }
865
866 ipfwp = (struct ip_fwpkt *)m;
867 ip = &(ipfwp->fwp_iph);
868
869 if ( !(viadev = dev_get(ipfwp->fwp_vianame)) ) {
870 #ifdef DEBUG_CONFIG_IP_FIREWALL
871 printk("ip_fw_ctl: invalid device \"%s\"\n", ipfwp->fwp_vianame);
872 #endif
873 return(EINVAL);
874 } else if ( viadev->pa_addr != ipfwp->fwp_via.s_addr ) {
875 #ifdef DEBUG_CONFIG_IP_FIREWALL
876 printk("ip_fw_ctl: device \"%s\" has another IP address\n",
877 ipfwp->fwp_vianame);
878 #endif
879 return(EINVAL);
880 } else if ( ip->ihl != sizeof(struct iphdr) / sizeof(int)) {
881 #ifdef DEBUG_CONFIG_IP_FIREWALL
882 printk("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
883 sizeof(struct iphdr)/sizeof(int));
884 #endif
885 return(EINVAL);
886 }
887
888 if ((ret = ip_fw_chk(ip, viadev, *chains[fwtype],
889 *policies[fwtype], 2)) == FW_ACCEPT)
890 return(0);
891 else if (ret == FW_MASQUERADE)
892 return(ECONNRESET);
893 else if (ret == FW_REJECT)
894 return(ECONNREFUSED);
895 else
896 return(ETIMEDOUT);
897 }
898
899
900
901
902
903
904 if ( cmd == IP_FW_INSERT || cmd == IP_FW_APPEND || cmd == IP_FW_DELETE )
905 {
906 struct ip_fw *frwl;
907 int fwtype;
908
909 frwl=check_ipfw_struct(m,len);
910 if (frwl==NULL)
911 return (EINVAL);
912 fwtype = (stage & IP_FW_TYPE) >> IP_FW_SHIFT;
913
914 switch (cmd)
915 {
916 case IP_FW_INSERT:
917 return(insert_in_chain(chains[fwtype],frwl,len));
918 case IP_FW_APPEND:
919 return(append_to_chain(chains[fwtype],frwl,len));
920 case IP_FW_DELETE:
921 return(del_from_chain(chains[fwtype],frwl));
922 default:
923
924
925
926 #ifdef DEBUG_CONFIG_IP_FIREWALL
927 printk("ip_fw_ctl: unknown request %d\n",stage);
928 #endif
929 return(EINVAL);
930 }
931 }
932
933 #ifdef DEBUG_CONFIG_IP_FIREWALL
934 printk("ip_fw_ctl: unknown request %d\n",stage);
935 #endif
936 return(EINVAL);
937 }
938 #endif
939
940 #if defined(CONFIG_IP_FIREWALL) || defined(CONFIG_IP_ACCT)
941
942 static int ip_chain_procinfo(int stage, char *buffer, char **start,
943 off_t offset, int length, int reset)
944 {
945 off_t pos=0, begin=0;
946 struct ip_fw *i;
947 unsigned long flags;
948 int len, p;
949
950
951 switch(stage)
952 {
953 #ifdef CONFIG_IP_FIREWALL
954 case IP_FW_IN:
955 i = ip_fw_in_chain;
956 len=sprintf(buffer, "IP firewall input rules, default %d\n",
957 ip_fw_in_policy);
958 break;
959 case IP_FW_OUT:
960 i = ip_fw_out_chain;
961 len=sprintf(buffer, "IP firewall output rules, default %d\n",
962 ip_fw_out_policy);
963 break;
964 case IP_FW_FWD:
965 i = ip_fw_fwd_chain;
966 len=sprintf(buffer, "IP firewall forward rules, default %d\n",
967 ip_fw_fwd_policy);
968 break;
969 #endif
970 #ifdef CONFIG_IP_ACCT
971 case IP_FW_ACCT:
972 i = ip_acct_chain;
973 len=sprintf(buffer,"IP accounting rules\n");
974 break;
975 #endif
976 default:
977
978 i = NULL;
979 len=0;
980 break;
981 }
982
983 save_flags(flags);
984 cli();
985
986 while(i!=NULL)
987 {
988 len+=sprintf(buffer+len,"%08lX/%08lX->%08lX/%08lX %.16s %08lX %X ",
989 ntohl(i->fw_src.s_addr),ntohl(i->fw_smsk.s_addr),
990 ntohl(i->fw_dst.s_addr),ntohl(i->fw_dmsk.s_addr),
991 (i->fw_vianame)[0] ? i->fw_vianame : "-",
992 ntohl(i->fw_via.s_addr),i->fw_flg);
993 len+=sprintf(buffer+len,"%u %u %-9lu %-9lu",
994 i->fw_nsp,i->fw_ndp, i->fw_pcnt,i->fw_bcnt);
995 for (p = 0; p < IP_FW_MAX_PORTS; p++)
996 len+=sprintf(buffer+len, " %u", i->fw_pts[p]);
997 len+=sprintf(buffer+len, " A%02X X%02X", i->fw_tosand, i->fw_tosxor);
998 buffer[len++]='\n';
999 buffer[len]='\0';
1000 pos=begin+len;
1001 if(pos<offset)
1002 {
1003 len=0;
1004 begin=pos;
1005 }
1006 else if(reset)
1007 {
1008
1009 i->fw_pcnt=0L;
1010 i->fw_bcnt=0L;
1011 }
1012 if(pos>offset+length)
1013 break;
1014 i=i->fw_next;
1015 }
1016 restore_flags(flags);
1017 *start=buffer+(offset-begin);
1018 len-=(offset-begin);
1019 if(len>length)
1020 len=length;
1021 return len;
1022 }
1023 #endif
1024
1025 #ifdef CONFIG_IP_ACCT
1026
1027 static int ip_acct_procinfo(char *buffer, char **start, off_t offset,
1028 int length, int reset)
1029 {
1030 return ip_chain_procinfo(IP_FW_ACCT, buffer,start, offset,length,
1031 reset);
1032 }
1033
1034 #endif
1035
1036 #ifdef CONFIG_IP_FIREWALL
1037
1038 static int ip_fw_in_procinfo(char *buffer, char **start, off_t offset,
1039 int length, int reset)
1040 {
1041 return ip_chain_procinfo(IP_FW_IN, buffer,start,offset,length,
1042 reset);
1043 }
1044
1045 static int ip_fw_out_procinfo(char *buffer, char **start, off_t offset,
1046 int length, int reset)
1047 {
1048 return ip_chain_procinfo(IP_FW_OUT, buffer,start,offset,length,
1049 reset);
1050 }
1051
1052 static int ip_fw_fwd_procinfo(char *buffer, char **start, off_t offset,
1053 int length, int reset)
1054 {
1055 return ip_chain_procinfo(IP_FW_FWD, buffer,start,offset,length,
1056 reset);
1057 }
1058 #endif
1059
1060
1061 #ifdef CONFIG_IP_FIREWALL
1062
1063
1064
1065
1066 int ipfw_input_check(struct firewall_ops *this, int pf, struct sk_buff *skb, void *phdr)
1067 {
1068 return ip_fw_chk(phdr, skb->dev, ip_fw_in_chain, ip_fw_in_policy, 0);
1069 }
1070
1071 int ipfw_output_check(struct firewall_ops *this, int pf, struct sk_buff *skb, void *phdr)
1072 {
1073 return ip_fw_chk(phdr, skb->dev, ip_fw_out_chain, ip_fw_out_policy, 0);
1074 }
1075
1076 int ipfw_forward_check(struct firewall_ops *this, int pf, struct sk_buff *skb, void *phdr)
1077 {
1078 return ip_fw_chk(phdr, skb->dev, ip_fw_fwd_chain, ip_fw_fwd_policy, 0);
1079 }
1080
1081 struct firewall_ops ipfw_ops=
1082 {
1083 NULL,
1084 ipfw_forward_check,
1085 ipfw_input_check,
1086 ipfw_output_check,
1087 PF_INET,
1088 0
1089 };
1090
1091 #endif
1092
1093 #if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
1094
1095 int ipfw_device_event(struct notifier_block *this, unsigned long event, void *ptr)
1096 {
1097 struct device *dev=ptr;
1098 char *devname = dev->name;
1099 unsigned long flags;
1100 struct ip_fw *fw;
1101 int chn;
1102
1103 save_flags(flags);
1104 cli();
1105
1106 if (event == NETDEV_UP) {
1107 for (chn = 0; chn < IP_FW_CHAINS; chn++)
1108 for (fw = *chains[chn]; fw; fw = fw->fw_next)
1109 if ((fw->fw_vianame)[0] && !strncmp(devname,
1110 fw->fw_vianame, IFNAMSIZ))
1111 fw->fw_viadev = dev;
1112 } else if (event == NETDEV_DOWN) {
1113 for (chn = 0; chn < IP_FW_CHAINS; chn++)
1114 for (fw = *chains[chn]; fw; fw = fw->fw_next)
1115
1116 if ((fw->fw_vianame)[0] && !strncmp(devname,
1117 fw->fw_vianame, IFNAMSIZ))
1118 fw->fw_viadev = (struct device *) -1;
1119 }
1120
1121 restore_flags(flags);
1122 return NOTIFY_DONE;
1123 }
1124
1125 static struct notifier_block ipfw_dev_notifier={
1126 ipfw_device_event,
1127 NULL,
1128 0
1129 };
1130
1131 #endif
1132
1133 void ip_fw_init(void)
1134 {
1135 #ifdef CONFIG_IP_ACCT
1136 proc_net_register(&(struct proc_dir_entry) {
1137 PROC_NET_IPACCT, 7, "ip_acct",
1138 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1139 0, &proc_net_inode_operations,
1140 ip_acct_procinfo
1141 });
1142 #endif
1143 #ifdef CONFIG_IP_FIREWALL
1144
1145 if(register_firewall(PF_INET,&ipfw_ops)<0)
1146 panic("Unable to register IP firewall.\n");
1147
1148 proc_net_register(&(struct proc_dir_entry) {
1149 PROC_NET_IPFWIN, 8, "ip_input",
1150 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1151 0, &proc_net_inode_operations,
1152 ip_fw_in_procinfo
1153 });
1154 proc_net_register(&(struct proc_dir_entry) {
1155 PROC_NET_IPFWOUT, 9, "ip_output",
1156 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1157 0, &proc_net_inode_operations,
1158 ip_fw_out_procinfo
1159 });
1160 proc_net_register(&(struct proc_dir_entry) {
1161 PROC_NET_IPFWFWD, 10, "ip_forward",
1162 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1163 0, &proc_net_inode_operations,
1164 ip_fw_fwd_procinfo
1165 });
1166 #endif
1167
1168 #ifdef CONFIG_IP_MASQUERADE
1169
1170
1171
1172
1173
1174 ip_masq_init();
1175 #endif
1176
1177 #if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
1178
1179 register_netdevice_notifier(&ipfw_dev_notifier);
1180 #endif
1181 }