This source file includes following definitions.
- port_match
- ip_fw_chk
- masq_expire
- alloc_masq_entry
- revamp
- recalc_check
- ip_fw_masquerade
- ip_fw_demasquerade
- zero_fw_chain
- free_fw_chain
- add_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_blk_procinfo
- ip_fw_fwd_procinfo
- ip_msqhst_procinfo
- ipfw_input_check
- ipfw_forward_check
- 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 #include <linux/config.h>
66 #include <asm/segment.h>
67 #include <asm/system.h>
68 #include <linux/types.h>
69 #include <linux/kernel.h>
70 #include <linux/sched.h>
71 #include <linux/string.h>
72 #include <linux/errno.h>
73 #include <linux/config.h>
74
75 #include <linux/socket.h>
76 #include <linux/sockios.h>
77 #include <linux/in.h>
78 #include <linux/inet.h>
79 #include <linux/netdevice.h>
80 #include <linux/icmp.h>
81 #include <linux/udp.h>
82 #include <net/ip.h>
83 #include <net/protocol.h>
84 #include <net/route.h>
85 #include <net/tcp.h>
86 #include <net/udp.h>
87 #include <linux/skbuff.h>
88 #include <net/sock.h>
89 #include <net/icmp.h>
90 #include <linux/firewall.h>
91 #include <linux/ip_fw.h>
92 #include <net/checksum.h>
93 #include <linux/proc_fs.h>
94 #include <linux/stat.h>
95
96
97
98
99
100 #ifdef CONFIG_IPFIREWALL_DEBUG
101 #define dprintf1(a) printk(a)
102 #define dprintf2(a1,a2) printk(a1,a2)
103 #define dprintf3(a1,a2,a3) printk(a1,a2,a3)
104 #define dprintf4(a1,a2,a3,a4) printk(a1,a2,a3,a4)
105 #else
106 #define dprintf1(a)
107 #define dprintf2(a1,a2)
108 #define dprintf3(a1,a2,a3)
109 #define dprintf4(a1,a2,a3,a4)
110 #endif
111
112 #define print_ip(a) printk("%ld.%ld.%ld.%ld",(ntohl(a)>>24)&0xFF,\
113 (ntohl(a)>>16)&0xFF,\
114 (ntohl(a)>>8)&0xFF,\
115 (ntohl(a))&0xFF);
116
117 #ifdef IPFIREWALL_DEBUG
118 #define dprint_ip(a) print_ip(a)
119 #else
120 #define dprint_ip(a)
121 #endif
122
123 #ifdef CONFIG_IP_FIREWALL
124 struct ip_fw *ip_fw_fwd_chain;
125 struct ip_fw *ip_fw_blk_chain;
126 int ip_fw_blk_policy=IP_FW_F_ACCEPT;
127 int ip_fw_fwd_policy=IP_FW_F_ACCEPT;
128 #endif
129 #ifdef CONFIG_IP_ACCT
130 struct ip_fw *ip_acct_chain;
131 #endif
132
133 #define IP_INFO_BLK 0
134 #define IP_INFO_FWD 1
135 #define IP_INFO_ACCT 2
136
137 #ifdef CONFIG_IP_MASQUERADE
138
139
140
141
142 static unsigned short masq_port = PORT_MASQ_BEGIN;
143 static const char *strProt[] = {"UDP","TCP"};
144 struct ip_masq *ip_msq_hosts;
145
146 #endif
147
148
149
150
151
152 extern inline int port_match(unsigned short *portptr,int nports,unsigned short port,int range_flag)
153 {
154 if (!nports)
155 return 1;
156 if ( range_flag )
157 {
158 if ( portptr[0] <= port && port <= portptr[1] )
159 {
160 return( 1 );
161 }
162 nports -= 2;
163 portptr += 2;
164 }
165 while ( nports-- > 0 )
166 {
167 if ( *portptr++ == port )
168 {
169 return( 1 );
170 }
171 }
172 return(0);
173 }
174
175 #if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
176
177
178
179
180
181
182
183
184
185
186
187
188
189 int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int policy, int opt)
190 {
191 struct ip_fw *f;
192 struct tcphdr *tcp=(struct tcphdr *)((unsigned long *)ip+ip->ihl);
193 struct udphdr *udp=(struct udphdr *)((unsigned long *)ip+ip->ihl);
194 struct icmphdr *icmp=(struct icmphdr *)((unsigned long *)ip+ip->ihl);
195 __u32 src, dst;
196 __u16 src_port=0, dst_port=0, icmp_type=0;
197 unsigned short f_prt=0, prt;
198 char notcpsyn=1, notcpack=1, match;
199 unsigned short f_flag;
200 unsigned short offset;
201
202
203
204
205
206
207
208 src = ip->saddr;
209 dst = ip->daddr;
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225 offset = ntohs(ip->frag_off) & IP_OFFSET;
226
227
228
229
230
231
232
233
234 if (offset == 1 && ip->protocol == IPPROTO_TCP)
235 return FW_BLOCK;
236
237 if (offset!=0 && (opt != 1) && (ip->protocol == IPPROTO_TCP ||
238 ip->protocol == IPPROTO_UDP))
239 return FW_ACCEPT;
240
241
242
243
244
245 if(ip->protocol==IPPROTO_TCP && (ip->ihl<<2)+16 > ntohs(ip->tot_len))
246 return FW_BLOCK;
247
248
249
250
251
252 else if(ntohs(ip->tot_len)<8+(ip->ihl<<2))
253 return FW_BLOCK;
254
255 src = ip->saddr;
256 dst = ip->daddr;
257
258
259
260
261
262
263
264
265
266 dprintf1("Packet ");
267 switch(ip->protocol)
268 {
269 case IPPROTO_TCP:
270 dprintf1("TCP ");
271
272 if (!offset) {
273 src_port=ntohs(tcp->source);
274 dst_port=ntohs(tcp->dest);
275 if(tcp->ack)
276
277 notcpack=0;
278 if(tcp->syn && notcpack)
279
280 notcpsyn=0;
281 }
282 prt=IP_FW_F_TCP;
283 break;
284 case IPPROTO_UDP:
285 dprintf1("UDP ");
286
287 if (!offset) {
288 src_port=ntohs(udp->source);
289 dst_port=ntohs(udp->dest);
290 }
291 prt=IP_FW_F_UDP;
292 break;
293 case IPPROTO_ICMP:
294 icmp_type=(__u16)(icmp->type);
295 dprintf2("ICMP:%d ",icmp_type);
296 prt=IP_FW_F_ICMP;
297 break;
298 default:
299 dprintf2("p=%d ",ip->protocol);
300 prt=IP_FW_F_ALL;
301 break;
302 }
303 #ifdef CONFIG_IP_FIREWALL_DEBUG
304 dprint_ip(ip->saddr);
305
306 if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP)
307
308 dprintf2(":%d ", src_port);
309 dprint_ip(ip->daddr);
310 if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP)
311
312 dprintf2(":%d ",dst_port);
313 dprintf1("\n");
314 #endif
315
316 for (f=chain;f;f=f->fw_next)
317 {
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335 match = 0x00;
336
337 if ((src&f->fw_smsk.s_addr)==f->fw_src.s_addr
338 && (dst&f->fw_dmsk.s_addr)==f->fw_dst.s_addr)
339
340 match |= 0x01;
341
342 if ((f->fw_flg & IP_FW_F_BIDIR) &&
343 (dst&f->fw_smsk.s_addr)==f->fw_src.s_addr
344 && (src&f->fw_dmsk.s_addr)==f->fw_dst.s_addr)
345
346 match |= 0x02;
347
348 if (match)
349 {
350
351
352
353 if(f->fw_via.s_addr && rif)
354 {
355 if(rif->pa_addr!=f->fw_via.s_addr)
356 continue;
357 }
358
359
360
361 }
362 else
363 continue;
364
365
366
367
368
369 f_prt=f->fw_flg&IP_FW_F_KIND;
370 if (f_prt!=IP_FW_F_ALL)
371 {
372
373
374
375
376
377
378
379 if((f->fw_flg&IP_FW_F_TCPSYN) && notcpsyn)
380 continue;
381
382
383
384
385
386
387
388
389 if((f->fw_flg&IP_FW_F_TCPACK) && notcpack)
390 if(f->fw_flg&IP_FW_F_BIDIR) {
391 if(match & 0x02)
392 continue;
393 } else
394 continue;
395
396
397
398
399
400
401 if(prt!=f_prt)
402 continue;
403
404 if((prt==IP_FW_F_ICMP &&
405 ! port_match(&f->fw_pts[0], f->fw_nsp,
406 icmp_type,f->fw_flg&IP_FW_F_SRNG)) ||
407 !(prt==IP_FW_F_ICMP || ((match & 0x01) &&
408 port_match(&f->fw_pts[0], f->fw_nsp, src_port,
409 f->fw_flg&IP_FW_F_SRNG) &&
410 port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, dst_port,
411 f->fw_flg&IP_FW_F_DRNG)) || ((match & 0x02) &&
412 port_match(&f->fw_pts[0], f->fw_nsp, dst_port,
413 f->fw_flg&IP_FW_F_SRNG) &&
414 port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, src_port,
415 f->fw_flg&IP_FW_F_DRNG))))
416 {
417 continue;
418 }
419 }
420 #ifdef CONFIG_IP_FIREWALL_VERBOSE
421
422
423
424
425
426 if (f->fw_flg & IP_FW_F_PRN)
427 {
428 if(opt != 1) {
429 if(f->fw_flg&IP_FW_F_ACCEPT)
430 printk("Accept ");
431 else if(f->fw_flg&IP_FW_F_ICMPRPL)
432 printk("Reject ");
433 else
434 printk("Deny ");
435 }
436 switch(ip->protocol)
437 {
438 case IPPROTO_TCP:
439 printk("TCP ");
440 break;
441 case IPPROTO_UDP:
442 printk("UDP ");
443 case IPPROTO_ICMP:
444 printk("ICMP ");
445 break;
446 default:
447 printk("p=%d ",ip->protocol);
448 break;
449 }
450 print_ip(ip->saddr);
451 if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
452 printk(":%d", src_port);
453 printk(" ");
454 print_ip(ip->daddr);
455 if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
456 printk(":%d",dst_port);
457 printk("\n");
458 }
459 #endif
460 if (opt != 2) {
461 f->fw_bcnt+=ntohs(ip->tot_len);
462 f->fw_pcnt++;
463 }
464 if (opt != 1)
465 break;
466 }
467
468 if(opt == 1)
469 return 0;
470
471
472
473
474
475
476
477 if(f!=NULL)
478 f_flag=f->fw_flg;
479 else
480 f_flag=policy;
481 if(f_flag&IP_FW_F_ACCEPT)
482 return ((f_flag&IP_FW_F_MASQ)?FW_MASQUERADE:FW_ACCEPT);
483 if(f_flag&IP_FW_F_ICMPRPL)
484 return FW_REJECT;
485 return FW_BLOCK;
486 }
487
488 #ifdef CONFIG_IP_MASQUERADE
489
490 static void masq_expire(unsigned long data)
491 {
492 struct ip_masq *ms = (struct ip_masq *)data;
493 struct ip_masq *old,*cur;
494 unsigned long flags;
495
496 #ifdef DEBUG_MASQ
497 printk("Masqueraded %s %lX:%X expired\n",
498 strProt[ms->protocol==IPPROTO_TCP],
499 ntohl(ms->src),ntohs(ms->sport));
500 #endif
501
502 save_flags(flags);
503 cli();
504
505
506 old = NULL;
507 cur = ip_msq_hosts;
508 while (cur!=NULL) {
509 if (cur==ms) {
510 if (old==NULL) ip_msq_hosts = ms->next;
511 else old->next = ms->next;
512 kfree_s(ms,sizeof(*ms));
513 break;
514 }
515 old = cur;
516 cur=cur->next;
517 }
518 restore_flags(flags);
519 }
520
521
522
523
524
525
526
527
528 static struct ip_masq *alloc_masq_entry(void)
529 {
530 struct ip_masq *ms, *mst;
531 unsigned long flags;
532
533 ms = (struct ip_masq *) kmalloc(sizeof(struct ip_masq), GFP_ATOMIC);
534 if (ms==NULL)
535 return NULL;
536
537 memset(ms,0,sizeof(*ms));
538 init_timer(&ms->timer);
539 ms->timer.data = (unsigned long)ms;
540 ms->timer.function = masq_expire;
541
542 save_flags(flags);
543 cli();
544 do
545 {
546
547 ms->mport = htons(masq_port++);
548 if (masq_port==PORT_MASQ_END)
549 masq_port = PORT_MASQ_BEGIN;
550
551
552
553 mst = ip_msq_hosts;
554 while (mst && mst->mport!=ms->mport)
555 mst = mst->next;
556 }
557 while (mst!=NULL);
558
559
560 ms->next = ip_msq_hosts;
561 ip_msq_hosts = ms;
562 restore_flags(flags);
563
564 return ms;
565 }
566
567
568
569
570
571
572
573
574
575
576
577
578
579 static struct sk_buff *revamp(struct sk_buff *skb, struct device *dev, struct ip_masq *ftp)
580 {
581 struct iphdr *iph = skb->h.iph;
582 struct tcphdr *th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
583 struct sk_buff *skb2;
584 char *p, *data = (char *)&th[1];
585 unsigned char p1,p2,p3,p4,p5,p6;
586 unsigned long from;
587 unsigned short port;
588 struct ip_masq *ms;
589 char buf[24];
590 int diff;
591 __u32 seq;
592
593
594
595
596
597
598
599
600
601 seq=ntohl(th->seq);
602 if (ftp->delta || ftp->previous_delta)
603 {
604 if(after(seq,ftp->init_seq) )
605 {
606 th->seq = htonl(seq + ftp->delta);
607 #ifdef DEBUG_MASQ
608 printk("masq_revamp : added delta (%d) to seq\n",ftp->delta);
609 #endif
610 }
611 else
612 {
613 th->seq = htonl(seq + ftp->previous_delta);
614 #ifdef DEBUG_MASQ
615 printk("masq_revamp : added previous_delta (%d) to seq\n",ftp->previous_delta);
616 #endif
617 }
618 }
619
620 while (skb->len - ((unsigned char *)data - skb->h.raw) > 18)
621 {
622 if (memcmp(data,"PORT ",5) && memcmp(data,"port ",5))
623 {
624 data ++;
625 continue;
626 }
627 p = data+5;
628 p1 = simple_strtoul(data+5,&data,10);
629 if (*data!=',')
630 continue;
631 p2 = simple_strtoul(data+1,&data,10);
632 if (*data!=',')
633 continue;
634 p3 = simple_strtoul(data+1,&data,10);
635 if (*data!=',')
636 continue;
637 p4 = simple_strtoul(data+1,&data,10);
638 if (*data!=',')
639 continue;
640 p5 = simple_strtoul(data+1,&data,10);
641 if (*data!=',')
642 continue;
643 p6 = simple_strtoul(data+1,&data,10);
644 if (*data!='\r' && *data!='\n')
645 continue;
646
647 from = (p1<<24) | (p2<<16) | (p3<<8) | p4;
648 port = (p5<<8) | p6;
649 #ifdef MASQ_DEBUG
650 printk("PORT %lX:%X detected\n",from,port);
651 #endif
652
653
654
655 ms = alloc_masq_entry();
656 if (ms==NULL)
657 return skb;
658 ms->protocol = IPPROTO_TCP;
659 ms->src = htonl(from);
660 ms->sport = htons(port);
661 ms->dst = iph->daddr;
662
663
664
665
666
667 ms->dport = htons(FTP_DPORT_TBD);
668 ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP_FIN;
669 add_timer(&ms->timer);
670
671
672
673
674 from = ntohl(dev->pa_addr);
675 port = ntohs(ms->mport);
676 sprintf(buf,"%ld,%ld,%ld,%ld,%d,%d",
677 from>>24&255,from>>16&255,from>>8&255,from&255,
678 port>>8&255,port&255);
679
680
681
682
683
684 diff = strlen(buf) - (data-p);
685
686
687
688
689
690 if (diff==0)
691 {
692
693
694
695 memcpy(p,buf,strlen(buf));
696 return skb;
697 }
698
699
700
701
702
703
704
705
706
707
708
709 if(!ftp->init_seq || after(seq,ftp->init_seq) )
710 {
711 ftp->previous_delta=ftp->delta;
712 ftp->delta+=diff;
713 ftp->init_seq = seq;
714 }
715
716
717
718
719 #ifdef DEBUG_MASQ
720 printk("MASQUERADE: resizing needed for %d bytes (%ld)\n",diff, skb->len);
721 #endif
722 skb2 = alloc_skb(MAX_HEADER + skb->len+diff, GFP_ATOMIC);
723 if (skb2 == NULL) {
724 printk("MASQUERADE: No memory available\n");
725 return skb;
726 }
727 skb2->free = skb->free;
728 skb_reserve(skb2,MAX_HEADER);
729 skb_put(skb2,skb->len + diff);
730 skb2->h.raw = skb2->data + (skb->h.raw - skb->data);
731 iph=skb2->h.iph;
732
733
734
735 iph->tot_len = htons(diff+ntohs(iph->tot_len));
736 iph->check = 0;
737 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
738
739
740
741
742
743 memcpy(skb2->data, skb->data, (p - (char *)skb->data));
744 memcpy(&skb2->data[(p - (char *)skb->data)], buf, strlen(buf));
745 memcpy(&skb2->data[(p - (char *)skb->data) + strlen(buf)], data,
746 skb->len - (data-(char *)skb->data));
747
748
749
750
751
752 iph->tot_len = htons(skb->len + diff);
753
754
755
756
757
758
759 kfree_skb(skb, FREE_WRITE);
760 return skb2;
761 }
762 return skb;
763 }
764
765 static void recalc_check(struct udphdr *uh, unsigned long saddr,
766 unsigned long daddr, int len)
767 {
768 uh->check=0;
769 uh->check=csum_tcpudp_magic(saddr,daddr,len,
770 IPPROTO_UDP, csum_partial((char *)uh,len,0));
771 if(uh->check==0)
772 uh->check=0xFFFF;
773 }
774
775 void ip_fw_masquerade(struct sk_buff **skb_ptr, struct device *dev)
776 {
777 struct sk_buff *skb=*skb_ptr;
778 struct iphdr *iph = skb->h.iph;
779 unsigned short *portptr;
780 struct ip_masq *ms;
781 int size;
782
783
784
785
786
787 if (iph->protocol!=IPPROTO_UDP && iph->protocol!=IPPROTO_TCP)
788 return;
789
790
791
792
793
794 portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
795 ms = ip_msq_hosts;
796
797 #ifdef DEBUG_MASQ
798 printk("Outgoing %s %lX:%X -> %lX:%X\n",
799 strProt[iph->protocol==IPPROTO_TCP],
800 ntohl(iph->saddr), ntohs(portptr[0]),
801 ntohl(iph->daddr), ntohs(portptr[1]));
802 #endif
803 while (ms!=NULL)
804 {
805 if (iph->protocol == ms->protocol &&
806 iph->saddr == ms->src && iph->daddr == ms->dst &&
807 portptr[0] == ms->sport && portptr[1] == ms->dport)
808 {
809 del_timer(&ms->timer);
810 break;
811 }
812 ms = ms->next;
813 }
814
815
816
817
818
819 if (ms==NULL)
820 {
821 ms = alloc_masq_entry();
822 if (ms==NULL)
823 {
824 printk("MASQUERADE: no memory left !\n");
825 return;
826 }
827 ms->protocol = iph->protocol;
828 ms->src = iph->saddr;
829 ms->dst = iph->daddr;
830 ms->sport = portptr[0];
831 ms->dport = portptr[1];
832 }
833
834
835
836
837
838 size = skb->len - ((unsigned char *)portptr - skb->h.raw);
839 iph->saddr = dev->pa_addr;
840 portptr[0] = ms->mport;
841
842
843
844
845
846 if (iph->protocol==IPPROTO_UDP)
847 {
848 ms->timer.expires = jiffies+MASQUERADE_EXPIRE_UDP;
849 recalc_check((struct udphdr *)portptr,iph->saddr,iph->daddr,size);
850 }
851 else
852 {
853 struct tcphdr *th;
854 if (portptr[1]==htons(21))
855 {
856 skb = revamp(*skb_ptr, dev, ms);
857 *skb_ptr = skb;
858 iph = skb->h.iph;
859 portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
860 size = skb->len - ((unsigned char *)portptr-skb->h.raw);
861 }
862 th = (struct tcphdr *)portptr;
863
864
865
866
867 if (ms->sawfin || th->fin)
868 {
869 ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP_FIN;
870 ms->sawfin = 1;
871 }
872 else ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP;
873
874 tcp_send_check(th,iph->saddr,iph->daddr,size,skb->sk);
875 }
876 add_timer(&ms->timer);
877 ip_send_check(iph);
878
879 #ifdef DEBUG_MASQ
880 printk("O-routed from %lX:%X over %s\n",ntohl(dev->pa_addr),ntohs(ms->mport),dev->name);
881 #endif
882 }
883
884
885
886
887
888
889
890
891
892
893 int ip_fw_demasquerade(struct sk_buff *skb_ptr)
894 {
895 struct iphdr *iph = skb_ptr->h.iph;
896 unsigned short *portptr;
897 struct ip_masq *ms;
898 struct tcphdr *th = (struct tcphdr *)(skb_ptr->h.raw+(iph->ihl<<2));
899
900 if (iph->protocol!=IPPROTO_UDP && iph->protocol!=IPPROTO_TCP)
901 return 0;
902
903 portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
904 if (ntohs(portptr[1]) < PORT_MASQ_BEGIN ||
905 ntohs(portptr[1]) > PORT_MASQ_END)
906 return 0;
907
908 #ifdef DEBUG_MASQ
909 printk("Incoming %s %lX:%X -> %lX:%X\n",
910 strProt[iph->protocol==IPPROTO_TCP],
911 ntohl(iph->saddr), ntohs(portptr[0]),
912 ntohl(iph->daddr), ntohs(portptr[1]));
913 #endif
914
915
916
917
918
919
920
921
922
923
924 ms = ip_msq_hosts;
925 while (ms!=NULL)
926 {
927 if (iph->protocol==ms->protocol &&
928 (iph->saddr==ms->dst || iph->protocol==IPPROTO_UDP) &&
929 (ms->dport==htons(FTP_DPORT_TBD) || portptr[0]==ms->dport) &&
930 portptr[1]==ms->mport)
931 {
932
933 int size = skb_ptr->len - ((unsigned char *)portptr - skb_ptr->h.raw);
934 iph->daddr = ms->src;
935 portptr[1] = ms->sport;
936
937 if(ms->dport==htons(FTP_DPORT_TBD))
938 {
939 ms->dport=portptr[0];
940 #ifdef DEBUG_MASQ
941 printk("demasq : Filled out dport entry (%d) based on initial connect attempt from FTP deamon\n",ntohs(ms->dport));
942 #endif
943 }
944
945
946
947
948 if (iph->protocol==IPPROTO_UDP)
949 recalc_check((struct udphdr *)portptr,iph->saddr,iph->daddr,size);
950 else
951 {
952 __u32 ack_seq;
953
954
955
956
957
958 #ifdef DEBUG_MASQ
959 printk("demasq : delta=%d ; previous_delta=%d ; init_seq=%lX ; ack_seq=%lX ; after=%d\n",ms->delta,ms->previous_delta,ntohl(ms->init_seq),ntohl(th->ack_seq),after(ntohl(th->ack_seq),ntohl(ms->init_seq)));
960 #endif
961 ack_seq=ntohl(th->ack_seq);
962 if (ms->delta || ms->previous_delta)
963 {
964 if(after(ack_seq,ms->init_seq))
965 {
966 th->ack_seq = htonl(ack_seq-ms->delta);
967 #ifdef DEBUG_MASQ
968 printk("demasq : substracted delta (%d) from ack_seq\n",ms->delta);
969 #endif
970 }
971 else
972 {
973 th->ack_seq = htonl(ack_seq-ms->previous_delta);
974 #ifdef DEBUG_MASQ
975 printk("demasq : substracted previous_delta (%d) from ack_seq\n",ms->previous_delta);
976 #endif
977 }
978 }
979 tcp_send_check((struct tcphdr *)portptr,iph->saddr,iph->daddr,size,skb_ptr->sk);
980 }
981 ip_send_check(iph);
982 #ifdef DEBUG_MASQ
983 printk("I-routed to %lX:%X\n",ntohl(iph->daddr),ntohs(portptr[1]));
984 #endif
985 return 1;
986 }
987 ms = ms->next;
988 }
989
990
991 return 0;
992 }
993 #endif
994
995
996
997 static void zero_fw_chain(struct ip_fw *chainptr)
998 {
999 struct ip_fw *ctmp=chainptr;
1000 while(ctmp)
1001 {
1002 ctmp->fw_pcnt=0L;
1003 ctmp->fw_bcnt=0L;
1004 ctmp=ctmp->fw_next;
1005 }
1006 }
1007
1008 static void free_fw_chain(struct ip_fw *volatile* chainptr)
1009 {
1010 unsigned long flags;
1011 save_flags(flags);
1012 cli();
1013 while ( *chainptr != NULL )
1014 {
1015 struct ip_fw *ftmp;
1016 ftmp = *chainptr;
1017 *chainptr = ftmp->fw_next;
1018 kfree_s(ftmp,sizeof(*ftmp));
1019 }
1020 restore_flags(flags);
1021 }
1022
1023
1024
1025 static int add_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl)
1026 {
1027 struct ip_fw *ftmp;
1028 struct ip_fw *chtmp=NULL;
1029 struct ip_fw *volatile chtmp_prev=NULL;
1030 unsigned long flags;
1031 unsigned long m_src_mask,m_dst_mask;
1032 unsigned long n_sa,n_da,o_sa,o_da,o_sm,o_dm,n_sm,n_dm;
1033 unsigned short n_sr,n_dr,o_sr,o_dr;
1034 unsigned short oldkind,newkind;
1035 int addb4=0;
1036 int n_o,n_n;
1037
1038 save_flags(flags);
1039
1040 ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
1041 if ( ftmp == NULL )
1042 {
1043 #ifdef DEBUG_CONFIG_IP_FIREWALL
1044 printk("ip_fw_ctl: malloc said no\n");
1045 #endif
1046 return( ENOMEM );
1047 }
1048
1049 memcpy(ftmp, frwl, sizeof( struct ip_fw ) );
1050
1051 ftmp->fw_pcnt=0L;
1052 ftmp->fw_bcnt=0L;
1053
1054 ftmp->fw_next = NULL;
1055
1056 cli();
1057
1058 if (*chainptr==NULL)
1059 {
1060 *chainptr=ftmp;
1061 }
1062 else
1063 {
1064 chtmp_prev=NULL;
1065 for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->fw_next)
1066 {
1067 addb4=0;
1068 newkind=ftmp->fw_flg & IP_FW_F_KIND;
1069 oldkind=chtmp->fw_flg & IP_FW_F_KIND;
1070
1071 if (newkind!=IP_FW_F_ALL
1072 && oldkind!=IP_FW_F_ALL
1073 && oldkind!=newkind)
1074 {
1075 chtmp_prev=chtmp;
1076 continue;
1077 }
1078
1079
1080
1081
1082
1083
1084 n_sa=ntohl(ftmp->fw_src.s_addr);
1085 n_da=ntohl(ftmp->fw_dst.s_addr);
1086 n_sm=ntohl(ftmp->fw_smsk.s_addr);
1087 n_dm=ntohl(ftmp->fw_dmsk.s_addr);
1088
1089 o_sa=ntohl(chtmp->fw_src.s_addr);
1090 o_da=ntohl(chtmp->fw_dst.s_addr);
1091 o_sm=ntohl(chtmp->fw_smsk.s_addr);
1092 o_dm=ntohl(chtmp->fw_dmsk.s_addr);
1093
1094 m_src_mask = o_sm & n_sm;
1095 m_dst_mask = o_dm & n_dm;
1096
1097 if ((o_sa & m_src_mask) == (n_sa & m_src_mask))
1098 {
1099 if (n_sm > o_sm)
1100 addb4++;
1101 if (n_sm < o_sm)
1102 addb4--;
1103 }
1104
1105 if ((o_da & m_dst_mask) == (n_da & m_dst_mask))
1106 {
1107 if (n_dm > o_dm)
1108 addb4++;
1109 if (n_dm < o_dm)
1110 addb4--;
1111 }
1112
1113 if (((o_da & o_dm) == (n_da & n_dm))
1114 &&((o_sa & o_sm) == (n_sa & n_sm)))
1115 {
1116 if (newkind!=IP_FW_F_ALL &&
1117 oldkind==IP_FW_F_ALL)
1118 addb4++;
1119 if (newkind==oldkind && (oldkind==IP_FW_F_TCP
1120 || oldkind==IP_FW_F_UDP))
1121 {
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134 if (ftmp->fw_flg & IP_FW_F_SRNG)
1135 n_sr=ftmp->fw_pts[1]-ftmp->fw_pts[0];
1136 else
1137 n_sr=(ftmp->fw_nsp)?
1138 ftmp->fw_nsp : 0xFFFF;
1139
1140 if (chtmp->fw_flg & IP_FW_F_SRNG)
1141 o_sr=chtmp->fw_pts[1]-chtmp->fw_pts[0];
1142 else
1143 o_sr=(chtmp->fw_nsp)?chtmp->fw_nsp : 0xFFFF;
1144
1145 if (n_sr<o_sr)
1146 addb4++;
1147 if (n_sr>o_sr)
1148 addb4--;
1149
1150 n_n=ftmp->fw_nsp;
1151 n_o=chtmp->fw_nsp;
1152
1153
1154
1155
1156
1157
1158
1159 if ((n_n>(IP_FW_MAX_PORTS-2)) ||
1160 (n_o>(IP_FW_MAX_PORTS-2)))
1161 goto skip_check;
1162
1163 if (ftmp->fw_flg & IP_FW_F_DRNG)
1164 n_dr=ftmp->fw_pts[n_n+1]-ftmp->fw_pts[n_n];
1165 else
1166 n_dr=(ftmp->fw_ndp)? ftmp->fw_ndp : 0xFFFF;
1167
1168 if (chtmp->fw_flg & IP_FW_F_DRNG)
1169 o_dr=chtmp->fw_pts[n_o+1]-chtmp->fw_pts[n_o];
1170 else
1171 o_dr=(chtmp->fw_ndp)? chtmp->fw_ndp : 0xFFFF;
1172 if (n_dr<o_dr)
1173 addb4++;
1174 if (n_dr>o_dr)
1175 addb4--;
1176 skip_check:
1177 }
1178
1179 if ((addb4 == 0) && ftmp->fw_via.s_addr &&
1180 !(chtmp->fw_via.s_addr))
1181 addb4++;
1182 }
1183 if (addb4>0)
1184 {
1185 if (chtmp_prev)
1186 {
1187 chtmp_prev->fw_next=ftmp;
1188 ftmp->fw_next=chtmp;
1189 }
1190 else
1191 {
1192 *chainptr=ftmp;
1193 ftmp->fw_next=chtmp;
1194 }
1195 restore_flags(flags);
1196 return 0;
1197 }
1198 chtmp_prev=chtmp;
1199 }
1200 }
1201
1202 if (chtmp_prev)
1203 chtmp_prev->fw_next=ftmp;
1204 else
1205 *chainptr=ftmp;
1206 restore_flags(flags);
1207 return(0);
1208 }
1209
1210 static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
1211 {
1212 struct ip_fw *ftmp,*ltmp;
1213 unsigned short tport1,tport2,tmpnum;
1214 char matches,was_found;
1215 unsigned long flags;
1216
1217 save_flags(flags);
1218 cli();
1219
1220 ftmp=*chainptr;
1221
1222 if ( ftmp == NULL )
1223 {
1224 #ifdef DEBUG_CONFIG_IP_FIREWALL
1225 printk("ip_fw_ctl: chain is empty\n");
1226 #endif
1227 restore_flags(flags);
1228 return( EINVAL );
1229 }
1230
1231 ltmp=NULL;
1232 was_found=0;
1233
1234 while( ftmp != NULL )
1235 {
1236 matches=1;
1237 if (ftmp->fw_src.s_addr!=frwl->fw_src.s_addr
1238 || ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr
1239 || ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr
1240 || ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr
1241 || ftmp->fw_via.s_addr!=frwl->fw_via.s_addr
1242 || ftmp->fw_flg!=frwl->fw_flg)
1243 matches=0;
1244
1245 tport1=ftmp->fw_nsp+ftmp->fw_ndp;
1246 tport2=frwl->fw_nsp+frwl->fw_ndp;
1247 if (tport1!=tport2)
1248 matches=0;
1249 else if (tport1!=0)
1250 {
1251 for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
1252 if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum])
1253 matches=0;
1254 }
1255 if(matches)
1256 {
1257 was_found=1;
1258 if (ltmp)
1259 {
1260 ltmp->fw_next=ftmp->fw_next;
1261 kfree_s(ftmp,sizeof(*ftmp));
1262 ftmp=ltmp->fw_next;
1263 }
1264 else
1265 {
1266 *chainptr=ftmp->fw_next;
1267 kfree_s(ftmp,sizeof(*ftmp));
1268 ftmp=*chainptr;
1269 }
1270 }
1271 else
1272 {
1273 ltmp = ftmp;
1274 ftmp = ftmp->fw_next;
1275 }
1276 }
1277 restore_flags(flags);
1278 if (was_found)
1279 return 0;
1280 else
1281 return(EINVAL);
1282 }
1283
1284 #endif
1285
1286 struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
1287 {
1288
1289 if ( len != sizeof(struct ip_fw) )
1290 {
1291 #ifdef DEBUG_CONFIG_IP_FIREWALL
1292 printk("ip_fw_ctl: len=%d, want %d\n",len, sizeof(struct ip_fw));
1293 #endif
1294 return(NULL);
1295 }
1296
1297 if ( (frwl->fw_flg & ~IP_FW_F_MASK) != 0 )
1298 {
1299 #ifdef DEBUG_CONFIG_IP_FIREWALL
1300 printk("ip_fw_ctl: undefined flag bits set (flags=%x)\n",
1301 frwl->fw_flg);
1302 #endif
1303 return(NULL);
1304 }
1305
1306 if ( (frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2 )
1307 {
1308 #ifdef DEBUG_CONFIG_IP_FIREWALL
1309 printk("ip_fw_ctl: src range set but fw_nsp=%d\n",
1310 frwl->fw_nsp);
1311 #endif
1312 return(NULL);
1313 }
1314
1315 if ( (frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2 )
1316 {
1317 #ifdef DEBUG_CONFIG_IP_FIREWALL
1318 printk("ip_fw_ctl: dst range set but fw_ndp=%d\n",
1319 frwl->fw_ndp);
1320 #endif
1321 return(NULL);
1322 }
1323
1324 if ( frwl->fw_nsp + frwl->fw_ndp > IP_FW_MAX_PORTS )
1325 {
1326 #ifdef DEBUG_CONFIG_IP_FIREWALL
1327 printk("ip_fw_ctl: too many ports (%d+%d)\n",
1328 frwl->fw_nsp,frwl->fw_ndp);
1329 #endif
1330 return(NULL);
1331 }
1332
1333 return frwl;
1334 }
1335
1336
1337
1338
1339 #ifdef CONFIG_IP_ACCT
1340
1341 #if 0
1342 void ip_acct_cnt(struct iphdr *iph, struct device *dev, struct ip_fw *f)
1343 {
1344 (void) ip_fw_chk(iph, dev, f, 0, 1);
1345 return;
1346 }
1347 #endif
1348
1349 int ip_acct_ctl(int stage, void *m, int len)
1350 {
1351 if ( stage == IP_ACCT_FLUSH )
1352 {
1353 free_fw_chain(&ip_acct_chain);
1354 return(0);
1355 }
1356 if ( stage == IP_ACCT_ZERO )
1357 {
1358 zero_fw_chain(ip_acct_chain);
1359 return(0);
1360 }
1361 if ( stage == IP_ACCT_ADD
1362 || stage == IP_ACCT_DEL
1363 )
1364 {
1365 struct ip_fw *frwl;
1366
1367 if (!(frwl=check_ipfw_struct(m,len)))
1368 return (EINVAL);
1369
1370 switch (stage)
1371 {
1372 case IP_ACCT_ADD:
1373 return( add_to_chain(&ip_acct_chain,frwl));
1374 case IP_ACCT_DEL:
1375 return( del_from_chain(&ip_acct_chain,frwl));
1376 default:
1377
1378
1379
1380 #ifdef DEBUG_CONFIG_IP_FIREWALL
1381 printk("ip_acct_ctl: unknown request %d\n",stage);
1382 #endif
1383 return(EINVAL);
1384 }
1385 }
1386 #ifdef DEBUG_CONFIG_IP_FIREWALL
1387 printk("ip_acct_ctl: unknown request %d\n",stage);
1388 #endif
1389 return(EINVAL);
1390 }
1391 #endif
1392
1393 #ifdef CONFIG_IP_FIREWALL
1394 int ip_fw_ctl(int stage, void *m, int len)
1395 {
1396 int ret;
1397
1398 if ( stage == IP_FW_FLUSH_BLK )
1399 {
1400 free_fw_chain(&ip_fw_blk_chain);
1401 return(0);
1402 }
1403
1404 if ( stage == IP_FW_FLUSH_FWD )
1405 {
1406 free_fw_chain(&ip_fw_fwd_chain);
1407 return(0);
1408 }
1409
1410 if ( stage == IP_FW_ZERO_BLK )
1411 {
1412 zero_fw_chain(ip_fw_blk_chain);
1413 return(0);
1414 }
1415
1416 if ( stage == IP_FW_ZERO_FWD )
1417 {
1418 zero_fw_chain(ip_fw_fwd_chain);
1419 return(0);
1420 }
1421
1422 if ( stage == IP_FW_POLICY_BLK || stage == IP_FW_POLICY_FWD )
1423 {
1424 int *tmp_policy_ptr;
1425 tmp_policy_ptr=(int *)m;
1426 if ( stage == IP_FW_POLICY_BLK )
1427 ip_fw_blk_policy=*tmp_policy_ptr;
1428 else
1429 ip_fw_fwd_policy=*tmp_policy_ptr;
1430 return 0;
1431 }
1432
1433 if ( stage == IP_FW_CHK_BLK || stage == IP_FW_CHK_FWD )
1434 {
1435 struct device viadev;
1436 struct ip_fwpkt *ipfwp;
1437 struct iphdr *ip;
1438
1439 if ( len < sizeof(struct ip_fwpkt) )
1440 {
1441 #ifdef DEBUG_CONFIG_IP_FIREWALL
1442 printk("ip_fw_ctl: length=%d, expected %d\n",
1443 len, sizeof(struct ip_fwpkt));
1444 #endif
1445 return( EINVAL );
1446 }
1447
1448 ipfwp = (struct ip_fwpkt *)m;
1449 ip = &(ipfwp->fwp_iph);
1450
1451 if ( ip->ihl != sizeof(struct iphdr) / sizeof(int))
1452 {
1453 #ifdef DEBUG_CONFIG_IP_FIREWALL
1454 printk("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
1455 sizeof(struct iphdr)/sizeof(int));
1456 #endif
1457 return(EINVAL);
1458 }
1459
1460 viadev.pa_addr = ipfwp->fwp_via.s_addr;
1461
1462 if ((ret = ip_fw_chk(ip, &viadev,
1463 stage == IP_FW_CHK_BLK ?
1464 ip_fw_blk_chain : ip_fw_fwd_chain,
1465 stage == IP_FW_CHK_BLK ?
1466 ip_fw_blk_policy : ip_fw_fwd_policy, 2 )) > 0
1467 )
1468 return(0);
1469 else if (ret == -1)
1470 return(ECONNREFUSED);
1471 else
1472 return(ETIMEDOUT);
1473 }
1474
1475
1476
1477
1478
1479
1480 if ( stage == IP_FW_ADD_BLK || stage == IP_FW_ADD_FWD
1481 || stage == IP_FW_DEL_BLK || stage == IP_FW_DEL_FWD
1482 )
1483 {
1484 struct ip_fw *frwl;
1485 frwl=check_ipfw_struct(m,len);
1486 if (frwl==NULL)
1487 return (EINVAL);
1488
1489 switch (stage)
1490 {
1491 case IP_FW_ADD_BLK:
1492 return(add_to_chain(&ip_fw_blk_chain,frwl));
1493 case IP_FW_ADD_FWD:
1494 return(add_to_chain(&ip_fw_fwd_chain,frwl));
1495 case IP_FW_DEL_BLK:
1496 return(del_from_chain(&ip_fw_blk_chain,frwl));
1497 case IP_FW_DEL_FWD:
1498 return(del_from_chain(&ip_fw_fwd_chain,frwl));
1499 default:
1500
1501
1502
1503 #ifdef DEBUG_CONFIG_IP_FIREWALL
1504 printk("ip_fw_ctl: unknown request %d\n",stage);
1505 #endif
1506 return(EINVAL);
1507 }
1508 }
1509
1510 #ifdef DEBUG_CONFIG_IP_FIREWALL
1511 printk("ip_fw_ctl: unknown request %d\n",stage);
1512 #endif
1513 return(EINVAL);
1514 }
1515 #endif
1516
1517 #if defined(CONFIG_IP_FIREWALL) || defined(CONFIG_IP_ACCT)
1518
1519 static int ip_chain_procinfo(int stage, char *buffer, char **start,
1520 off_t offset, int length, int reset)
1521 {
1522 off_t pos=0, begin=0;
1523 struct ip_fw *i;
1524 unsigned long flags;
1525 int len, p;
1526
1527
1528 switch(stage)
1529 {
1530 #ifdef CONFIG_IP_FIREWALL
1531 case IP_INFO_BLK:
1532 i = ip_fw_blk_chain;
1533 len=sprintf(buffer, "IP firewall block rules, default %d\n",
1534 ip_fw_blk_policy);
1535 break;
1536 case IP_INFO_FWD:
1537 i = ip_fw_fwd_chain;
1538 len=sprintf(buffer, "IP firewall forward rules, default %d\n",
1539 ip_fw_fwd_policy);
1540 break;
1541 #endif
1542 #ifdef CONFIG_IP_ACCT
1543 case IP_INFO_ACCT:
1544 i = ip_acct_chain;
1545 len=sprintf(buffer,"IP accounting rules\n");
1546 break;
1547 #endif
1548 default:
1549
1550 i = NULL;
1551 len=0;
1552 break;
1553 }
1554
1555 save_flags(flags);
1556 cli();
1557
1558 while(i!=NULL)
1559 {
1560 len+=sprintf(buffer+len,"%08lX/%08lX->%08lX/%08lX %08lX %X ",
1561 ntohl(i->fw_src.s_addr),ntohl(i->fw_smsk.s_addr),
1562 ntohl(i->fw_dst.s_addr),ntohl(i->fw_dmsk.s_addr),
1563 ntohl(i->fw_via.s_addr),i->fw_flg);
1564 len+=sprintf(buffer+len,"%u %u %-9lu %-9lu",
1565 i->fw_nsp,i->fw_ndp, i->fw_pcnt,i->fw_bcnt);
1566 for (p = 0; p < IP_FW_MAX_PORTS; p++)
1567 len+=sprintf(buffer+len, " %u", i->fw_pts[p]);
1568 buffer[len++]='\n';
1569 buffer[len]='\0';
1570 pos=begin+len;
1571 if(pos<offset)
1572 {
1573 len=0;
1574 begin=pos;
1575 }
1576 else if(reset)
1577 {
1578
1579 i->fw_pcnt=0L;
1580 i->fw_bcnt=0L;
1581 }
1582 if(pos>offset+length)
1583 break;
1584 i=i->fw_next;
1585 }
1586 restore_flags(flags);
1587 *start=buffer+(offset-begin);
1588 len-=(offset-begin);
1589 if(len>length)
1590 len=length;
1591 return len;
1592 }
1593 #endif
1594
1595 #ifdef CONFIG_IP_ACCT
1596
1597 static int ip_acct_procinfo(char *buffer, char **start, off_t offset,
1598 int length, int reset)
1599 {
1600 return ip_chain_procinfo(IP_INFO_ACCT, buffer,start, offset,length,
1601 reset);
1602 }
1603
1604 #endif
1605
1606 #ifdef CONFIG_IP_FIREWALL
1607
1608 static int ip_fw_blk_procinfo(char *buffer, char **start, off_t offset,
1609 int length, int reset)
1610 {
1611 return ip_chain_procinfo(IP_INFO_BLK, buffer,start,offset,length,
1612 reset);
1613 }
1614
1615 static int ip_fw_fwd_procinfo(char *buffer, char **start, off_t offset,
1616 int length, int reset)
1617 {
1618 return ip_chain_procinfo(IP_INFO_FWD, buffer,start,offset,length,
1619 reset);
1620 }
1621 #endif
1622
1623 #ifdef CONFIG_IP_MASQUERADE
1624
1625 static int ip_msqhst_procinfo(char *buffer, char **start, off_t offset,
1626 int length, int unused)
1627 {
1628 off_t pos=0, begin=0;
1629 struct ip_masq *ms;
1630 unsigned long flags;
1631 int len=0;
1632
1633 len=sprintf(buffer,"Prc FromIP FPrt ToIP TPrt Masq Init-seq Delta PDelta Expires\n");
1634 save_flags(flags);
1635 cli();
1636
1637 ms=ip_msq_hosts;
1638 while (ms!=NULL)
1639 {
1640 int timer_active = del_timer(&ms->timer);
1641 if (!timer_active)
1642 ms->timer.expires = jiffies;
1643 len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08X %5d %5d %lu\n",
1644 strProt[ms->protocol==IPPROTO_TCP],
1645 ntohl(ms->src),ntohs(ms->sport),
1646 ntohl(ms->dst),ntohs(ms->dport),
1647 ntohs(ms->mport),
1648 ms->init_seq,ms->delta,ms->previous_delta,ms->timer.expires-jiffies);
1649 if (timer_active)
1650 add_timer(&ms->timer);
1651
1652 pos=begin+len;
1653 if(pos<offset)
1654 {
1655 len=0;
1656 begin=pos;
1657 }
1658 if(pos>offset+length)
1659 break;
1660 ms=ms->next;
1661 }
1662 restore_flags(flags);
1663 *start=buffer+(offset-begin);
1664 len-=(offset-begin);
1665 if(len>length)
1666 len=length;
1667 return len;
1668 }
1669
1670 #endif
1671
1672 #ifdef CONFIG_IP_FIREWALL
1673
1674
1675
1676
1677 int ipfw_input_check(struct firewall_ops *this, int pf, struct sk_buff *skb, void *phdr)
1678 {
1679 return ip_fw_chk(phdr, skb->dev, ip_fw_blk_chain, ip_fw_blk_policy, 0);
1680 }
1681
1682 int ipfw_forward_check(struct firewall_ops *this, int pf, struct sk_buff *skb, void *phdr)
1683 {
1684 return ip_fw_chk(phdr, skb->dev, ip_fw_fwd_chain, ip_fw_fwd_policy, 0);
1685 }
1686
1687 struct firewall_ops ipfw_ops=
1688 {
1689 NULL,
1690 ipfw_forward_check,
1691 ipfw_input_check,
1692 ipfw_input_check,
1693 PF_INET,
1694 0
1695 };
1696
1697 #endif
1698
1699 void ip_fw_init(void)
1700 {
1701 #ifdef CONFIG_IP_ACCT
1702 proc_net_register(&(struct proc_dir_entry) {
1703 PROC_NET_IPACCT, 7, "ip_acct",
1704 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1705 0, &proc_net_inode_operations,
1706 ip_acct_procinfo
1707 });
1708 #endif
1709 #ifdef CONFIG_IP_FIREWALL
1710
1711 if(register_firewall(PF_INET,&ipfw_ops)<0)
1712 panic("Unable to register IP firewall.\n");
1713
1714 proc_net_register(&(struct proc_dir_entry) {
1715 PROC_NET_IPFWBLK, 8, "ip_block",
1716 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1717 0, &proc_net_inode_operations,
1718 ip_fw_blk_procinfo
1719 });
1720 proc_net_register(&(struct proc_dir_entry) {
1721 PROC_NET_IPFWFWD, 10, "ip_forward",
1722 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1723 0, &proc_net_inode_operations,
1724 ip_fw_fwd_procinfo
1725 });
1726 #endif
1727 #ifdef CONFIG_IP_MASQUERADE
1728 proc_net_register(&(struct proc_dir_entry) {
1729 PROC_NET_IPMSQHST, 13, "ip_masquerade",
1730 S_IFREG | S_IRUGO, 1, 0, 0,
1731 0, &proc_net_inode_operations,
1732 ip_msqhst_procinfo
1733 });
1734 #endif
1735 }