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