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("masq ");
448 else
449 printk("acc ");
450 } else if(f->fw_flg&IP_FW_F_ICMPRPL)
451 printk("rej ");
452 else
453 printk("deny ");
454 }
455 if (rif)
456 printk("%s ", rif->name);
457 switch(ip->protocol)
458 {
459 case IPPROTO_TCP:
460 printk("TCP ");
461 break;
462 case IPPROTO_UDP:
463 printk("UDP ");
464 break;
465 case IPPROTO_ICMP:
466 printk("ICMP:%d ", icmp_type);
467 break;
468 default:
469 printk("p=%d ",ip->protocol);
470 break;
471 }
472 print_ip(ip->saddr);
473 if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
474 printk(":%d", src_port);
475 printk(" ");
476 print_ip(ip->daddr);
477 if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
478 printk(":%d",dst_port);
479 printk("\n");
480 }
481 #endif
482 if (opt != 2) {
483 f->fw_bcnt+=ntohs(ip->tot_len);
484 f->fw_pcnt++;
485 }
486 if (opt != 1)
487 break;
488 }
489
490 if (opt != 1) {
491
492
493
494
495
496
497
498 if (f!=NULL) {
499 policy=f->fw_flg;
500 tosand=f->fw_tosand;
501 tosxor=f->fw_tosxor;
502 } else {
503 tosand=0xFF;
504 tosxor=0x00;
505 }
506
507 if (policy&IP_FW_F_ACCEPT) {
508
509 __u8 old_tos = ip->tos;
510 ip->tos = (old_tos & tosand) ^ tosxor;
511 if (ip->tos != old_tos)
512 ip_send_check(ip);
513 answer=(policy&IP_FW_F_MASQ)?FW_MASQUERADE:FW_ACCEPT;
514 } else if(policy&IP_FW_F_ICMPRPL)
515 answer = FW_REJECT;
516 else
517 answer = FW_BLOCK;
518
519 return answer;
520 } else
521
522 return 0;
523 }
524
525 #ifdef CONFIG_IP_MASQUERADE
526
527 static void masq_expire(unsigned long data)
528 {
529 struct ip_masq *ms = (struct ip_masq *)data;
530 struct ip_masq *old,*cur;
531 unsigned long flags;
532
533 #ifdef DEBUG_MASQ
534 printk("Masqueraded %s %lX:%X expired\n",
535 strProt[ms->protocol==IPPROTO_TCP],
536 ntohl(ms->src),ntohs(ms->sport));
537 #endif
538
539 save_flags(flags);
540 cli();
541
542
543 old = NULL;
544 cur = ip_msq_hosts;
545 while (cur!=NULL) {
546 if (cur==ms) {
547 if (old==NULL) ip_msq_hosts = ms->next;
548 else old->next = ms->next;
549 kfree_s(ms,sizeof(*ms));
550 break;
551 }
552 old = cur;
553 cur=cur->next;
554 }
555 restore_flags(flags);
556 }
557
558
559
560
561
562
563
564
565 static struct ip_masq *alloc_masq_entry(void)
566 {
567 struct ip_masq *ms, *mst;
568 unsigned long flags;
569
570 ms = (struct ip_masq *) kmalloc(sizeof(struct ip_masq), GFP_ATOMIC);
571 if (ms==NULL)
572 return NULL;
573
574 memset(ms,0,sizeof(*ms));
575 init_timer(&ms->timer);
576 ms->timer.data = (unsigned long)ms;
577 ms->timer.function = masq_expire;
578
579 save_flags(flags);
580 cli();
581 do
582 {
583
584 ms->mport = htons(masq_port++);
585 if (masq_port==PORT_MASQ_END)
586 masq_port = PORT_MASQ_BEGIN;
587
588
589
590 mst = ip_msq_hosts;
591 while (mst && mst->mport!=ms->mport)
592 mst = mst->next;
593 }
594 while (mst!=NULL);
595
596
597 ms->next = ip_msq_hosts;
598 ip_msq_hosts = ms;
599 restore_flags(flags);
600
601 return ms;
602 }
603
604
605
606
607
608
609
610
611
612
613
614
615
616 static struct sk_buff *revamp(struct sk_buff *skb, struct device *dev, struct ip_masq *ftp)
617 {
618 struct iphdr *iph = skb->h.iph;
619 struct tcphdr *th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
620 struct sk_buff *skb2;
621 char *p, *data = (char *)&th[1];
622 unsigned char p1,p2,p3,p4,p5,p6;
623 unsigned long from;
624 unsigned short port;
625 struct ip_masq *ms;
626 char buf[24];
627 int diff;
628 __u32 seq;
629
630
631
632
633
634
635
636
637
638 seq=ntohl(th->seq);
639 if (ftp->delta || ftp->previous_delta)
640 {
641 if(after(seq,ftp->init_seq) )
642 {
643 th->seq = htonl(seq + ftp->delta);
644 #ifdef DEBUG_MASQ
645 printk("masq_revamp : added delta (%d) to seq\n",ftp->delta);
646 #endif
647 }
648 else
649 {
650 th->seq = htonl(seq + ftp->previous_delta);
651 #ifdef DEBUG_MASQ
652 printk("masq_revamp : added previous_delta (%d) to seq\n",ftp->previous_delta);
653 #endif
654 }
655 }
656
657 while (skb->len - ((unsigned char *)data - skb->h.raw) > 18)
658 {
659 if (memcmp(data,"PORT ",5) && memcmp(data,"port ",5))
660 {
661 data ++;
662 continue;
663 }
664 p = data+5;
665 p1 = simple_strtoul(data+5,&data,10);
666 if (*data!=',')
667 continue;
668 p2 = simple_strtoul(data+1,&data,10);
669 if (*data!=',')
670 continue;
671 p3 = simple_strtoul(data+1,&data,10);
672 if (*data!=',')
673 continue;
674 p4 = simple_strtoul(data+1,&data,10);
675 if (*data!=',')
676 continue;
677 p5 = simple_strtoul(data+1,&data,10);
678 if (*data!=',')
679 continue;
680 p6 = simple_strtoul(data+1,&data,10);
681 if (*data!='\r' && *data!='\n')
682 continue;
683
684 from = (p1<<24) | (p2<<16) | (p3<<8) | p4;
685 port = (p5<<8) | p6;
686 #ifdef MASQ_DEBUG
687 printk("PORT %lX:%X detected\n",from,port);
688 #endif
689
690
691
692 ms = alloc_masq_entry();
693 if (ms==NULL)
694 return skb;
695 ms->protocol = IPPROTO_TCP;
696 ms->src = htonl(from);
697 ms->sport = htons(port);
698 ms->dst = iph->daddr;
699
700
701
702
703
704 ms->dport = htons(FTP_DPORT_TBD);
705 ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP_FIN;
706 add_timer(&ms->timer);
707
708
709
710
711 from = ntohl(dev->pa_addr);
712 port = ntohs(ms->mport);
713 sprintf(buf,"%ld,%ld,%ld,%ld,%d,%d",
714 from>>24&255,from>>16&255,from>>8&255,from&255,
715 port>>8&255,port&255);
716
717
718
719
720
721 diff = strlen(buf) - (data-p);
722
723
724
725
726
727 if (diff==0)
728 {
729
730
731
732 memcpy(p,buf,strlen(buf));
733 return skb;
734 }
735
736
737
738
739
740
741
742
743
744
745
746 if(!ftp->init_seq || after(seq,ftp->init_seq) )
747 {
748 ftp->previous_delta=ftp->delta;
749 ftp->delta+=diff;
750 ftp->init_seq = seq;
751 }
752
753
754
755
756 #ifdef DEBUG_MASQ
757 printk("MASQUERADE: resizing needed for %d bytes (%ld)\n",diff, skb->len);
758 #endif
759 skb2 = alloc_skb(MAX_HEADER + skb->len+diff, GFP_ATOMIC);
760 if (skb2 == NULL) {
761 printk("MASQUERADE: No memory available\n");
762 return skb;
763 }
764 skb2->free = skb->free;
765 skb_reserve(skb2,MAX_HEADER);
766 skb_put(skb2,skb->len + diff);
767 skb2->h.raw = skb2->data + (skb->h.raw - skb->data);
768 iph=skb2->h.iph;
769
770
771
772 iph->tot_len = htons(diff+ntohs(iph->tot_len));
773 iph->check = 0;
774 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
775
776
777
778
779
780 memcpy(skb2->data, skb->data, (p - (char *)skb->data));
781 memcpy(&skb2->data[(p - (char *)skb->data)], buf, strlen(buf));
782 memcpy(&skb2->data[(p - (char *)skb->data) + strlen(buf)], data,
783 skb->len - (data-(char *)skb->data));
784
785
786
787
788
789 iph->tot_len = htons(skb->len + diff);
790
791
792
793
794
795
796 kfree_skb(skb, FREE_WRITE);
797 return skb2;
798 }
799 return skb;
800 }
801
802 static void recalc_check(struct udphdr *uh, unsigned long saddr,
803 unsigned long daddr, int len)
804 {
805 uh->check=0;
806 uh->check=csum_tcpudp_magic(saddr,daddr,len,
807 IPPROTO_UDP, csum_partial((char *)uh,len,0));
808 if(uh->check==0)
809 uh->check=0xFFFF;
810 }
811
812 void ip_fw_masquerade(struct sk_buff **skb_ptr, struct device *dev)
813 {
814 struct sk_buff *skb=*skb_ptr;
815 struct iphdr *iph = skb->h.iph;
816 unsigned short *portptr;
817 struct ip_masq *ms;
818 int size;
819
820
821
822
823
824 if (iph->protocol!=IPPROTO_UDP && iph->protocol!=IPPROTO_TCP)
825 return;
826
827
828
829
830
831 portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
832 ms = ip_msq_hosts;
833
834 #ifdef DEBUG_MASQ
835 printk("Outgoing %s %lX:%X -> %lX:%X\n",
836 strProt[iph->protocol==IPPROTO_TCP],
837 ntohl(iph->saddr), ntohs(portptr[0]),
838 ntohl(iph->daddr), ntohs(portptr[1]));
839 #endif
840 while (ms!=NULL)
841 {
842 if (iph->protocol == ms->protocol &&
843 iph->saddr == ms->src && iph->daddr == ms->dst &&
844 portptr[0] == ms->sport && portptr[1] == ms->dport)
845 {
846 del_timer(&ms->timer);
847 break;
848 }
849 ms = ms->next;
850 }
851
852
853
854
855
856 if (ms==NULL)
857 {
858 ms = alloc_masq_entry();
859 if (ms==NULL)
860 {
861 printk("MASQUERADE: no memory left !\n");
862 return;
863 }
864 ms->protocol = iph->protocol;
865 ms->src = iph->saddr;
866 ms->dst = iph->daddr;
867 ms->sport = portptr[0];
868 ms->dport = portptr[1];
869 }
870
871
872
873
874
875 size = skb->len - ((unsigned char *)portptr - skb->h.raw);
876 iph->saddr = dev->pa_addr;
877 portptr[0] = ms->mport;
878
879
880
881
882
883 if (iph->protocol==IPPROTO_UDP)
884 {
885 ms->timer.expires = jiffies+MASQUERADE_EXPIRE_UDP;
886 recalc_check((struct udphdr *)portptr,iph->saddr,iph->daddr,size);
887 }
888 else
889 {
890 struct tcphdr *th;
891 if (portptr[1]==htons(21))
892 {
893 skb = revamp(*skb_ptr, dev, ms);
894 *skb_ptr = skb;
895 iph = skb->h.iph;
896 portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
897 size = skb->len - ((unsigned char *)portptr-skb->h.raw);
898 }
899 th = (struct tcphdr *)portptr;
900
901
902
903
904 if (ms->sawfin || th->fin)
905 {
906 ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP_FIN;
907 ms->sawfin = 1;
908 }
909 else ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP;
910
911 skb->csum = csum_partial((void *)(th + 1), size - sizeof(*th), 0);
912 tcp_send_check(th,iph->saddr,iph->daddr,size,skb);
913 }
914 add_timer(&ms->timer);
915 ip_send_check(iph);
916
917 #ifdef DEBUG_MASQ
918 printk("O-routed from %lX:%X over %s\n",ntohl(dev->pa_addr),ntohs(ms->mport),dev->name);
919 #endif
920 }
921
922
923
924
925
926
927
928
929
930
931 int ip_fw_demasquerade(struct sk_buff *skb)
932 {
933 struct iphdr *iph = skb->h.iph;
934 unsigned short *portptr;
935 struct ip_masq *ms;
936 struct tcphdr *th = (struct tcphdr *)(skb->h.raw+(iph->ihl<<2));
937
938 if (iph->protocol!=IPPROTO_UDP && iph->protocol!=IPPROTO_TCP)
939 return 0;
940
941 portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
942 if (ntohs(portptr[1]) < PORT_MASQ_BEGIN ||
943 ntohs(portptr[1]) > PORT_MASQ_END)
944 return 0;
945
946 #ifdef DEBUG_MASQ
947 printk("Incoming %s %lX:%X -> %lX:%X\n",
948 strProt[iph->protocol==IPPROTO_TCP],
949 ntohl(iph->saddr), ntohs(portptr[0]),
950 ntohl(iph->daddr), ntohs(portptr[1]));
951 #endif
952
953
954
955
956
957
958
959
960
961
962 ms = ip_msq_hosts;
963 while (ms!=NULL)
964 {
965 if (iph->protocol==ms->protocol &&
966 (iph->saddr==ms->dst || iph->protocol==IPPROTO_UDP) &&
967 (ms->dport==htons(FTP_DPORT_TBD) || portptr[0]==ms->dport) &&
968 portptr[1]==ms->mport)
969 {
970
971 int size = skb->len - ((unsigned char *)portptr - skb->h.raw);
972 iph->daddr = ms->src;
973 portptr[1] = ms->sport;
974
975 if(ms->dport==htons(FTP_DPORT_TBD))
976 {
977 ms->dport=portptr[0];
978 #ifdef DEBUG_MASQ
979 printk("demasq : Filled out dport entry (%d) based on initial connect attempt from FTP deamon\n",ntohs(ms->dport));
980 #endif
981 }
982
983
984
985
986 if (iph->protocol==IPPROTO_UDP)
987 recalc_check((struct udphdr *)portptr,iph->saddr,iph->daddr,size);
988 else
989 {
990 __u32 ack_seq;
991
992
993
994
995
996 #ifdef DEBUG_MASQ
997 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)));
998 #endif
999 ack_seq=ntohl(th->ack_seq);
1000 if (ms->delta || ms->previous_delta)
1001 {
1002 if(after(ack_seq,ms->init_seq))
1003 {
1004 th->ack_seq = htonl(ack_seq-ms->delta);
1005 #ifdef DEBUG_MASQ
1006 printk("demasq : substracted delta (%d) from ack_seq\n",ms->delta);
1007 #endif
1008 }
1009 else
1010 {
1011 th->ack_seq = htonl(ack_seq-ms->previous_delta);
1012 #ifdef DEBUG_MASQ
1013 printk("demasq : substracted previous_delta (%d) from ack_seq\n",ms->previous_delta);
1014 #endif
1015 }
1016 }
1017 skb->csum = csum_partial((void *)(((struct tcphdr *)portptr) + 1),
1018 size - sizeof(struct tcphdr), 0);
1019 tcp_send_check((struct tcphdr *)portptr,iph->saddr,iph->daddr,size,skb);
1020 }
1021 ip_send_check(iph);
1022 #ifdef DEBUG_MASQ
1023 printk("I-routed to %lX:%X\n",ntohl(iph->daddr),ntohs(portptr[1]));
1024 #endif
1025 return 1;
1026 }
1027 ms = ms->next;
1028 }
1029
1030
1031 return 0;
1032 }
1033 #endif
1034
1035
1036
1037 static void zero_fw_chain(struct ip_fw *chainptr)
1038 {
1039 struct ip_fw *ctmp=chainptr;
1040 while(ctmp)
1041 {
1042 ctmp->fw_pcnt=0L;
1043 ctmp->fw_bcnt=0L;
1044 ctmp=ctmp->fw_next;
1045 }
1046 }
1047
1048 static void free_fw_chain(struct ip_fw *volatile* chainptr)
1049 {
1050 unsigned long flags;
1051 save_flags(flags);
1052 cli();
1053 while ( *chainptr != NULL )
1054 {
1055 struct ip_fw *ftmp;
1056 ftmp = *chainptr;
1057 *chainptr = ftmp->fw_next;
1058 kfree_s(ftmp,sizeof(*ftmp));
1059 }
1060 restore_flags(flags);
1061 }
1062
1063
1064
1065 static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,int len)
1066 {
1067 struct ip_fw *ftmp;
1068 unsigned long flags;
1069
1070 save_flags(flags);
1071
1072 ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
1073 if ( ftmp == NULL )
1074 {
1075 #ifdef DEBUG_CONFIG_IP_FIREWALL
1076 printk("ip_fw_ctl: malloc said no\n");
1077 #endif
1078 return( ENOMEM );
1079 }
1080
1081 memcpy(ftmp, frwl, len);
1082 ftmp->fw_tosand |= 0x03;
1083 ftmp->fw_tosxor &= 0xFC;
1084 ftmp->fw_pcnt=0L;
1085 ftmp->fw_bcnt=0L;
1086
1087 cli();
1088
1089 if ((ftmp->fw_vianame)[0]) {
1090 if (!(ftmp->fw_viadev = dev_get(ftmp->fw_vianame)))
1091 ftmp->fw_viadev = (struct device *) -1;
1092 } else
1093 ftmp->fw_viadev = NULL;
1094
1095 ftmp->fw_next = *chainptr;
1096 *chainptr=ftmp;
1097 restore_flags(flags);
1098 return(0);
1099 }
1100
1101 static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,int len)
1102 {
1103 struct ip_fw *ftmp;
1104 struct ip_fw *chtmp=NULL;
1105 struct ip_fw *volatile chtmp_prev=NULL;
1106 unsigned long flags;
1107
1108 save_flags(flags);
1109
1110 ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
1111 if ( ftmp == NULL )
1112 {
1113 #ifdef DEBUG_CONFIG_IP_FIREWALL
1114 printk("ip_fw_ctl: malloc said no\n");
1115 #endif
1116 return( ENOMEM );
1117 }
1118
1119 memcpy(ftmp, frwl, len);
1120 ftmp->fw_tosand |= 0x03;
1121 ftmp->fw_tosxor &= 0xFC;
1122 ftmp->fw_pcnt=0L;
1123 ftmp->fw_bcnt=0L;
1124
1125 ftmp->fw_next = NULL;
1126
1127 cli();
1128
1129 if ((ftmp->fw_vianame)[0]) {
1130 if (!(ftmp->fw_viadev = dev_get(ftmp->fw_vianame)))
1131 ftmp->fw_viadev = (struct device *) -1;
1132 } else
1133 ftmp->fw_viadev = NULL;
1134
1135 chtmp_prev=NULL;
1136 for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->fw_next)
1137 chtmp_prev=chtmp;
1138
1139 if (chtmp_prev)
1140 chtmp_prev->fw_next=ftmp;
1141 else
1142 *chainptr=ftmp;
1143 restore_flags(flags);
1144 return(0);
1145 }
1146
1147 static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
1148 {
1149 struct ip_fw *ftmp,*ltmp;
1150 unsigned short tport1,tport2,tmpnum;
1151 char matches,was_found;
1152 unsigned long flags;
1153
1154 save_flags(flags);
1155 cli();
1156
1157 ftmp=*chainptr;
1158
1159 if ( ftmp == NULL )
1160 {
1161 #ifdef DEBUG_CONFIG_IP_FIREWALL
1162 printk("ip_fw_ctl: chain is empty\n");
1163 #endif
1164 restore_flags(flags);
1165 return( EINVAL );
1166 }
1167
1168 ltmp=NULL;
1169 was_found=0;
1170
1171 while( !was_found && ftmp != NULL )
1172 {
1173 matches=1;
1174 if (ftmp->fw_src.s_addr!=frwl->fw_src.s_addr
1175 || ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr
1176 || ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr
1177 || ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr
1178 || ftmp->fw_via.s_addr!=frwl->fw_via.s_addr
1179 || ftmp->fw_flg!=frwl->fw_flg)
1180 matches=0;
1181
1182 tport1=ftmp->fw_nsp+ftmp->fw_ndp;
1183 tport2=frwl->fw_nsp+frwl->fw_ndp;
1184 if (tport1!=tport2)
1185 matches=0;
1186 else if (tport1!=0)
1187 {
1188 for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
1189 if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum])
1190 matches=0;
1191 }
1192 if (strncmp(ftmp->fw_vianame, frwl->fw_vianame, IFNAMSIZ))
1193 matches=0;
1194 if(matches)
1195 {
1196 was_found=1;
1197 if (ltmp)
1198 {
1199 ltmp->fw_next=ftmp->fw_next;
1200 kfree_s(ftmp,sizeof(*ftmp));
1201 ftmp=ltmp->fw_next;
1202 }
1203 else
1204 {
1205 *chainptr=ftmp->fw_next;
1206 kfree_s(ftmp,sizeof(*ftmp));
1207 ftmp=*chainptr;
1208 }
1209 }
1210 else
1211 {
1212 ltmp = ftmp;
1213 ftmp = ftmp->fw_next;
1214 }
1215 }
1216 restore_flags(flags);
1217 if (was_found)
1218 return 0;
1219 else
1220 return(EINVAL);
1221 }
1222
1223 #endif
1224
1225 struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
1226 {
1227
1228 if ( len != sizeof(struct ip_fw) )
1229 {
1230 #ifdef DEBUG_CONFIG_IP_FIREWALL
1231 printk("ip_fw_ctl: len=%d, want %d\n",len, sizeof(struct ip_fw));
1232 #endif
1233 return(NULL);
1234 }
1235
1236 if ( (frwl->fw_flg & ~IP_FW_F_MASK) != 0 )
1237 {
1238 #ifdef DEBUG_CONFIG_IP_FIREWALL
1239 printk("ip_fw_ctl: undefined flag bits set (flags=%x)\n",
1240 frwl->fw_flg);
1241 #endif
1242 return(NULL);
1243 }
1244
1245 if ( (frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2 )
1246 {
1247 #ifdef DEBUG_CONFIG_IP_FIREWALL
1248 printk("ip_fw_ctl: src range set but fw_nsp=%d\n",
1249 frwl->fw_nsp);
1250 #endif
1251 return(NULL);
1252 }
1253
1254 if ( (frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2 )
1255 {
1256 #ifdef DEBUG_CONFIG_IP_FIREWALL
1257 printk("ip_fw_ctl: dst range set but fw_ndp=%d\n",
1258 frwl->fw_ndp);
1259 #endif
1260 return(NULL);
1261 }
1262
1263 if ( frwl->fw_nsp + frwl->fw_ndp > IP_FW_MAX_PORTS )
1264 {
1265 #ifdef DEBUG_CONFIG_IP_FIREWALL
1266 printk("ip_fw_ctl: too many ports (%d+%d)\n",
1267 frwl->fw_nsp,frwl->fw_ndp);
1268 #endif
1269 return(NULL);
1270 }
1271
1272 return frwl;
1273 }
1274
1275
1276
1277
1278 #ifdef CONFIG_IP_ACCT
1279
1280 #if 0
1281 void ip_acct_cnt(struct iphdr *iph, struct device *dev, struct ip_fw *f)
1282 {
1283 (void) ip_fw_chk(iph, dev, f, 0, 1);
1284 return;
1285 }
1286 #endif
1287
1288 int ip_acct_ctl(int stage, void *m, int len)
1289 {
1290 if ( stage == IP_ACCT_FLUSH )
1291 {
1292 free_fw_chain(&ip_acct_chain);
1293 return(0);
1294 }
1295 if ( stage == IP_ACCT_ZERO )
1296 {
1297 zero_fw_chain(ip_acct_chain);
1298 return(0);
1299 }
1300 if ( stage == IP_ACCT_INSERT || stage == IP_ACCT_APPEND ||
1301 stage == IP_ACCT_DELETE )
1302 {
1303 struct ip_fw *frwl;
1304
1305 if (!(frwl=check_ipfw_struct(m,len)))
1306 return (EINVAL);
1307
1308 switch (stage)
1309 {
1310 case IP_ACCT_INSERT:
1311 return( insert_in_chain(&ip_acct_chain,frwl,len));
1312 case IP_ACCT_APPEND:
1313 return( append_to_chain(&ip_acct_chain,frwl,len));
1314 case IP_ACCT_DELETE:
1315 return( del_from_chain(&ip_acct_chain,frwl));
1316 default:
1317
1318
1319
1320 #ifdef DEBUG_CONFIG_IP_FIREWALL
1321 printk("ip_acct_ctl: unknown request %d\n",stage);
1322 #endif
1323 return(EINVAL);
1324 }
1325 }
1326 #ifdef DEBUG_CONFIG_IP_FIREWALL
1327 printk("ip_acct_ctl: unknown request %d\n",stage);
1328 #endif
1329 return(EINVAL);
1330 }
1331 #endif
1332
1333 #ifdef CONFIG_IP_FIREWALL
1334 int ip_fw_ctl(int stage, void *m, int len)
1335 {
1336 int ret, cmd, fwtype;
1337
1338 cmd = stage & IP_FW_COMMAND;
1339 fwtype = (stage & IP_FW_TYPE) >> IP_FW_SHIFT;
1340
1341 if ( cmd == IP_FW_FLUSH )
1342 {
1343 free_fw_chain(chains[fwtype]);
1344 return(0);
1345 }
1346
1347 if ( cmd == IP_FW_ZERO )
1348 {
1349 zero_fw_chain(*chains[fwtype]);
1350 return(0);
1351 }
1352
1353 if ( cmd == IP_FW_POLICY )
1354 {
1355 int *tmp_policy_ptr;
1356 tmp_policy_ptr=(int *)m;
1357 *policies[fwtype] = *tmp_policy_ptr;
1358 return 0;
1359 }
1360
1361 if ( cmd == IP_FW_CHECK )
1362 {
1363 struct device *viadev;
1364 struct ip_fwpkt *ipfwp;
1365 struct iphdr *ip;
1366
1367 if ( len != sizeof(struct ip_fwpkt) )
1368 {
1369 #ifdef DEBUG_CONFIG_IP_FIREWALL
1370 printk("ip_fw_ctl: length=%d, expected %d\n",
1371 len, sizeof(struct ip_fwpkt));
1372 #endif
1373 return( EINVAL );
1374 }
1375
1376 ipfwp = (struct ip_fwpkt *)m;
1377 ip = &(ipfwp->fwp_iph);
1378
1379 if ( !(viadev = dev_get(ipfwp->fwp_vianame)) ) {
1380 #ifdef DEBUG_CONFIG_IP_FIREWALL
1381 printk("ip_fw_ctl: invalid device \"%s\"\n", ipfwp->fwp_vianame);
1382 #endif
1383 return(EINVAL);
1384 } else if ( viadev->pa_addr != ipfwp->fwp_via.s_addr ) {
1385 #ifdef DEBUG_CONFIG_IP_FIREWALL
1386 printk("ip_fw_ctl: device \"%s\" has another IP address\n",
1387 ipfwp->fwp_vianame);
1388 #endif
1389 return(EINVAL);
1390 } else if ( ip->ihl != sizeof(struct iphdr) / sizeof(int)) {
1391 #ifdef DEBUG_CONFIG_IP_FIREWALL
1392 printk("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
1393 sizeof(struct iphdr)/sizeof(int));
1394 #endif
1395 return(EINVAL);
1396 }
1397
1398 if ((ret = ip_fw_chk(ip, viadev, *chains[fwtype],
1399 *policies[fwtype], 2)) == FW_ACCEPT)
1400 return(0);
1401 else if (ret == FW_MASQUERADE)
1402 return(ECONNRESET);
1403 else if (ret == FW_REJECT)
1404 return(ECONNREFUSED);
1405 else
1406 return(ETIMEDOUT);
1407 }
1408
1409
1410
1411
1412
1413
1414 if ( cmd == IP_FW_INSERT || cmd == IP_FW_APPEND || cmd == IP_FW_DELETE )
1415 {
1416 struct ip_fw *frwl;
1417 int fwtype;
1418
1419 frwl=check_ipfw_struct(m,len);
1420 if (frwl==NULL)
1421 return (EINVAL);
1422 fwtype = (stage & IP_FW_TYPE) >> IP_FW_SHIFT;
1423
1424 switch (cmd)
1425 {
1426 case IP_FW_INSERT:
1427 return(insert_in_chain(chains[fwtype],frwl,len));
1428 case IP_FW_APPEND:
1429 return(append_to_chain(chains[fwtype],frwl,len));
1430 case IP_FW_DELETE:
1431 return(del_from_chain(chains[fwtype],frwl));
1432 default:
1433
1434
1435
1436 #ifdef DEBUG_CONFIG_IP_FIREWALL
1437 printk("ip_fw_ctl: unknown request %d\n",stage);
1438 #endif
1439 return(EINVAL);
1440 }
1441 }
1442
1443 #ifdef DEBUG_CONFIG_IP_FIREWALL
1444 printk("ip_fw_ctl: unknown request %d\n",stage);
1445 #endif
1446 return(EINVAL);
1447 }
1448 #endif
1449
1450 #if defined(CONFIG_IP_FIREWALL) || defined(CONFIG_IP_ACCT)
1451
1452 static int ip_chain_procinfo(int stage, char *buffer, char **start,
1453 off_t offset, int length, int reset)
1454 {
1455 off_t pos=0, begin=0;
1456 struct ip_fw *i;
1457 unsigned long flags;
1458 int len, p;
1459
1460
1461 switch(stage)
1462 {
1463 #ifdef CONFIG_IP_FIREWALL
1464 case IP_FW_IN:
1465 i = ip_fw_in_chain;
1466 len=sprintf(buffer, "IP firewall input rules, default %d\n",
1467 ip_fw_in_policy);
1468 break;
1469 case IP_FW_OUT:
1470 i = ip_fw_out_chain;
1471 len=sprintf(buffer, "IP firewall output rules, default %d\n",
1472 ip_fw_out_policy);
1473 break;
1474 case IP_FW_FWD:
1475 i = ip_fw_fwd_chain;
1476 len=sprintf(buffer, "IP firewall forward rules, default %d\n",
1477 ip_fw_fwd_policy);
1478 break;
1479 #endif
1480 #ifdef CONFIG_IP_ACCT
1481 case IP_FW_ACCT:
1482 i = ip_acct_chain;
1483 len=sprintf(buffer,"IP accounting rules\n");
1484 break;
1485 #endif
1486 default:
1487
1488 i = NULL;
1489 len=0;
1490 break;
1491 }
1492
1493 save_flags(flags);
1494 cli();
1495
1496 while(i!=NULL)
1497 {
1498 len+=sprintf(buffer+len,"%08lX/%08lX->%08lX/%08lX %.16s %08lX %X ",
1499 ntohl(i->fw_src.s_addr),ntohl(i->fw_smsk.s_addr),
1500 ntohl(i->fw_dst.s_addr),ntohl(i->fw_dmsk.s_addr),
1501 (i->fw_vianame)[0] ? i->fw_vianame : "-",
1502 ntohl(i->fw_via.s_addr),i->fw_flg);
1503 len+=sprintf(buffer+len,"%u %u %-9lu %-9lu",
1504 i->fw_nsp,i->fw_ndp, i->fw_pcnt,i->fw_bcnt);
1505 for (p = 0; p < IP_FW_MAX_PORTS; p++)
1506 len+=sprintf(buffer+len, " %u", i->fw_pts[p]);
1507 len+=sprintf(buffer+len, " A%02X X%02X", i->fw_tosand, i->fw_tosxor);
1508 buffer[len++]='\n';
1509 buffer[len]='\0';
1510 pos=begin+len;
1511 if(pos<offset)
1512 {
1513 len=0;
1514 begin=pos;
1515 }
1516 else if(reset)
1517 {
1518
1519 i->fw_pcnt=0L;
1520 i->fw_bcnt=0L;
1521 }
1522 if(pos>offset+length)
1523 break;
1524 i=i->fw_next;
1525 }
1526 restore_flags(flags);
1527 *start=buffer+(offset-begin);
1528 len-=(offset-begin);
1529 if(len>length)
1530 len=length;
1531 return len;
1532 }
1533 #endif
1534
1535 #ifdef CONFIG_IP_ACCT
1536
1537 static int ip_acct_procinfo(char *buffer, char **start, off_t offset,
1538 int length, int reset)
1539 {
1540 return ip_chain_procinfo(IP_FW_ACCT, buffer,start, offset,length,
1541 reset);
1542 }
1543
1544 #endif
1545
1546 #ifdef CONFIG_IP_FIREWALL
1547
1548 static int ip_fw_in_procinfo(char *buffer, char **start, off_t offset,
1549 int length, int reset)
1550 {
1551 return ip_chain_procinfo(IP_FW_IN, buffer,start,offset,length,
1552 reset);
1553 }
1554
1555 static int ip_fw_out_procinfo(char *buffer, char **start, off_t offset,
1556 int length, int reset)
1557 {
1558 return ip_chain_procinfo(IP_FW_OUT, buffer,start,offset,length,
1559 reset);
1560 }
1561
1562 static int ip_fw_fwd_procinfo(char *buffer, char **start, off_t offset,
1563 int length, int reset)
1564 {
1565 return ip_chain_procinfo(IP_FW_FWD, buffer,start,offset,length,
1566 reset);
1567 }
1568 #endif
1569
1570 #ifdef CONFIG_IP_MASQUERADE
1571
1572 static int ip_msqhst_procinfo(char *buffer, char **start, off_t offset,
1573 int length, int unused)
1574 {
1575 off_t pos=0, begin=0;
1576 struct ip_masq *ms;
1577 unsigned long flags;
1578 int len=0;
1579
1580 len=sprintf(buffer,"Prc FromIP FPrt ToIP TPrt Masq Init-seq Delta PDelta Expires\n");
1581 save_flags(flags);
1582 cli();
1583
1584 ms=ip_msq_hosts;
1585 while (ms!=NULL)
1586 {
1587 int timer_active = del_timer(&ms->timer);
1588 if (!timer_active)
1589 ms->timer.expires = jiffies;
1590 len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08X %6d %6d %lu\n",
1591 strProt[ms->protocol==IPPROTO_TCP],
1592 ntohl(ms->src),ntohs(ms->sport),
1593 ntohl(ms->dst),ntohs(ms->dport),
1594 ntohs(ms->mport),
1595 ms->init_seq,ms->delta,ms->previous_delta,ms->timer.expires-jiffies);
1596 if (timer_active)
1597 add_timer(&ms->timer);
1598
1599 pos=begin+len;
1600 if(pos<offset)
1601 {
1602 len=0;
1603 begin=pos;
1604 }
1605 if(pos>offset+length)
1606 break;
1607 ms=ms->next;
1608 }
1609 restore_flags(flags);
1610 *start=buffer+(offset-begin);
1611 len-=(offset-begin);
1612 if(len>length)
1613 len=length;
1614 return len;
1615 }
1616
1617 #endif
1618
1619 #ifdef CONFIG_IP_FIREWALL
1620
1621
1622
1623
1624 int ipfw_input_check(struct firewall_ops *this, int pf, struct sk_buff *skb, void *phdr)
1625 {
1626 return ip_fw_chk(phdr, skb->dev, ip_fw_in_chain, ip_fw_in_policy, 0);
1627 }
1628
1629 int ipfw_output_check(struct firewall_ops *this, int pf, struct sk_buff *skb, void *phdr)
1630 {
1631 return ip_fw_chk(phdr, skb->dev, ip_fw_out_chain, ip_fw_out_policy, 0);
1632 }
1633
1634 int ipfw_forward_check(struct firewall_ops *this, int pf, struct sk_buff *skb, void *phdr)
1635 {
1636 return ip_fw_chk(phdr, skb->dev, ip_fw_fwd_chain, ip_fw_fwd_policy, 0);
1637 }
1638
1639 struct firewall_ops ipfw_ops=
1640 {
1641 NULL,
1642 ipfw_forward_check,
1643 ipfw_input_check,
1644 ipfw_output_check,
1645 PF_INET,
1646 0
1647 };
1648
1649 #endif
1650
1651 #if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
1652
1653 int ipfw_device_event(struct notifier_block *this, unsigned long event, void *ptr)
1654 {
1655 struct device *dev=ptr;
1656 char *devname = dev->name;
1657 unsigned long flags;
1658 struct ip_fw *fw;
1659 int chn;
1660
1661 save_flags(flags);
1662 cli();
1663
1664 if (event == NETDEV_UP) {
1665 for (chn = 0; chn < IP_FW_CHAINS; chn++)
1666 for (fw = *chains[chn]; fw; fw = fw->fw_next)
1667 if ((fw->fw_vianame)[0] && !strncmp(devname,
1668 fw->fw_vianame, IFNAMSIZ))
1669 fw->fw_viadev = dev;
1670 } else if (event == NETDEV_DOWN) {
1671 for (chn = 0; chn < IP_FW_CHAINS; chn++)
1672 for (fw = *chains[chn]; fw; fw = fw->fw_next)
1673
1674 if ((fw->fw_vianame)[0] && !strncmp(devname,
1675 fw->fw_vianame, IFNAMSIZ))
1676 fw->fw_viadev = (struct device *) -1;
1677 }
1678
1679 restore_flags(flags);
1680 return NOTIFY_DONE;
1681 }
1682
1683 static struct notifier_block ipfw_dev_notifier={
1684 ipfw_device_event,
1685 NULL,
1686 0
1687 };
1688
1689 #endif
1690
1691 void ip_fw_init(void)
1692 {
1693 #ifdef CONFIG_IP_ACCT
1694 proc_net_register(&(struct proc_dir_entry) {
1695 PROC_NET_IPACCT, 7, "ip_acct",
1696 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1697 0, &proc_net_inode_operations,
1698 ip_acct_procinfo
1699 });
1700 #endif
1701 #ifdef CONFIG_IP_FIREWALL
1702
1703 if(register_firewall(PF_INET,&ipfw_ops)<0)
1704 panic("Unable to register IP firewall.\n");
1705
1706 proc_net_register(&(struct proc_dir_entry) {
1707 PROC_NET_IPFWIN, 8, "ip_input",
1708 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1709 0, &proc_net_inode_operations,
1710 ip_fw_in_procinfo
1711 });
1712 proc_net_register(&(struct proc_dir_entry) {
1713 PROC_NET_IPFWOUT, 9, "ip_output",
1714 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1715 0, &proc_net_inode_operations,
1716 ip_fw_out_procinfo
1717 });
1718 proc_net_register(&(struct proc_dir_entry) {
1719 PROC_NET_IPFWFWD, 10, "ip_forward",
1720 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1721 0, &proc_net_inode_operations,
1722 ip_fw_fwd_procinfo
1723 });
1724 #endif
1725 #ifdef CONFIG_IP_MASQUERADE
1726 proc_net_register(&(struct proc_dir_entry) {
1727 PROC_NET_IPMSQHST, 13, "ip_masquerade",
1728 S_IFREG | S_IRUGO, 1, 0, 0,
1729 0, &proc_net_inode_operations,
1730 ip_msqhst_procinfo
1731 });
1732 #endif
1733 #if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
1734
1735 register_netdevice_notifier(&ipfw_dev_notifier);
1736 #endif
1737 }