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