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
- 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 #include <linux/config.h>
65 #include <asm/segment.h>
66 #include <asm/system.h>
67 #include <linux/types.h>
68 #include <linux/kernel.h>
69 #include <linux/sched.h>
70 #include <linux/string.h>
71 #include <linux/errno.h>
72 #include <linux/config.h>
73
74 #include <linux/socket.h>
75 #include <linux/sockios.h>
76 #include <linux/in.h>
77 #include <linux/inet.h>
78 #include <linux/netdevice.h>
79 #include <linux/icmp.h>
80 #include <linux/udp.h>
81 #include <net/ip.h>
82 #include <net/protocol.h>
83 #include <net/route.h>
84 #include <net/tcp.h>
85 #include <net/udp.h>
86 #include <linux/skbuff.h>
87 #include <net/sock.h>
88 #include <net/icmp.h>
89 #include <linux/ip_fw.h>
90 #include <net/checksum.h>
91 #include <linux/proc_fs.h>
92 #include <linux/stat.h>
93
94
95
96
97
98 #ifdef CONFIG_IPFIREWALL_DEBUG
99 #define dprintf1(a) printk(a)
100 #define dprintf2(a1,a2) printk(a1,a2)
101 #define dprintf3(a1,a2,a3) printk(a1,a2,a3)
102 #define dprintf4(a1,a2,a3,a4) printk(a1,a2,a3,a4)
103 #else
104 #define dprintf1(a)
105 #define dprintf2(a1,a2)
106 #define dprintf3(a1,a2,a3)
107 #define dprintf4(a1,a2,a3,a4)
108 #endif
109
110 #define print_ip(a) printk("%ld.%ld.%ld.%ld",(ntohl(a)>>24)&0xFF,\
111 (ntohl(a)>>16)&0xFF,\
112 (ntohl(a)>>8)&0xFF,\
113 (ntohl(a))&0xFF);
114
115 #ifdef IPFIREWALL_DEBUG
116 #define dprint_ip(a) print_ip(a)
117 #else
118 #define dprint_ip(a)
119 #endif
120
121 #ifdef CONFIG_IP_FIREWALL
122 struct ip_fw *ip_fw_fwd_chain;
123 struct ip_fw *ip_fw_blk_chain;
124 int ip_fw_blk_policy=IP_FW_F_ACCEPT;
125 int ip_fw_fwd_policy=IP_FW_F_ACCEPT;
126 #endif
127 #ifdef CONFIG_IP_ACCT
128 struct ip_fw *ip_acct_chain;
129 #endif
130
131 #define IP_INFO_BLK 0
132 #define IP_INFO_FWD 1
133 #define IP_INFO_ACCT 2
134
135 #ifdef CONFIG_IP_MASQUERADE
136
137
138
139
140 static unsigned short masq_port = PORT_MASQ_BEGIN;
141 static const char *strProt[] = {"UDP","TCP"};
142 struct ip_masq *ip_msq_hosts;
143
144 #endif
145
146
147
148
149
150 extern inline int port_match(unsigned short *portptr,int nports,unsigned short port,int range_flag)
151 {
152 if (!nports)
153 return 1;
154 if ( range_flag )
155 {
156 if ( portptr[0] <= port && port <= portptr[1] )
157 {
158 return( 1 );
159 }
160 nports -= 2;
161 portptr += 2;
162 }
163 while ( nports-- > 0 )
164 {
165 if ( *portptr++ == port )
166 {
167 return( 1 );
168 }
169 }
170 return(0);
171 }
172
173 #if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
174
175
176
177
178
179
180
181
182
183
184
185
186
187 int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int policy, int opt)
188 {
189 struct ip_fw *f;
190 struct tcphdr *tcp=(struct tcphdr *)((unsigned long *)ip+ip->ihl);
191 struct udphdr *udp=(struct udphdr *)((unsigned long *)ip+ip->ihl);
192 struct icmphdr *icmp=(struct icmphdr *)((unsigned long *)ip+ip->ihl);
193 __u32 src, dst;
194 __u16 src_port=0, dst_port=0, icmp_type=0;
195 unsigned short f_prt=0, prt;
196 char notcpsyn=1, notcpack=1, frag1, match;
197 unsigned short f_flag;
198 unsigned short offset;
199
200
201
202
203
204
205
206 src = ip->saddr;
207 dst = ip->daddr;
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223 offset = ntohs(ip->frag_off) & IP_OFFSET;
224
225 frag1 = (offset == 0);
226
227
228
229
230
231
232
233
234 if (offset == 1 && ip->protocol == IPPROTO_TCP)
235 return 0;
236
237 if (!frag1 && (opt != 1) && (ip->protocol == IPPROTO_TCP ||
238 ip->protocol == IPPROTO_UDP))
239 return(1);
240
241
242
243
244
245 if(ip->protocol==IPPROTO_TCP && (ip->ihl<<2)+16 > ntohs(ip->tot_len))
246 return 0;
247
248
249
250
251
252 else if(ntohs(ip->tot_len)<8+(ip->ihl<<2))
253 return 0;
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 (frag1) {
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 (frag1) {
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)?2:1);
483 if(f_flag&IP_FW_F_ICMPRPL)
484 return -1;
485 return 0;
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[20];
590
591
592
593
594
595 if (ftp->delta && after(ftp->init_seq,th->seq))
596 {
597 th->seq += ftp->delta;
598
599 }
600
601 while (skb->len - ((unsigned char *)data - skb->h.raw) > 18)
602 {
603 if (memcmp(data,"PORT ",5)!=0 && memcmp(data,"port ",5)!=0)
604 {
605 data += 5;
606 continue;
607 }
608 p = data+5;
609 p1 = simple_strtoul(data+5,&data,10);
610 if (*data!=',')
611 continue;
612 p2 = simple_strtoul(data+1,&data,10);
613 if (*data!=',')
614 continue;
615 p3 = simple_strtoul(data+1,&data,10);
616 if (*data!=',')
617 continue;
618 p4 = simple_strtoul(data+1,&data,10);
619 if (*data!=',')
620 continue;
621 p5 = simple_strtoul(data+1,&data,10);
622 if (*data!=',')
623 continue;
624 p6 = simple_strtoul(data+1,&data,10);
625 if (*data!='\r' && *data!='\n')
626 continue;
627
628 from = (p1<<24) | (p2<<16) | (p3<<8) | p4;
629 port = (p5<<8) | p6;
630 printk("PORT %lX:%X detected\n",from,port);
631
632
633
634
635 ms = alloc_masq_entry();
636 if (ms==NULL)
637 return skb;
638 ms->protocol = IPPROTO_TCP;
639 ms->src = htonl(from);
640 ms->sport = htons(port);
641 ms->dst = iph->daddr;
642 ms->dport = htons(20);
643 ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP_FIN;
644 add_timer(&ms->timer);
645
646
647
648
649 from = ntohl(dev->pa_addr);
650 port = ntohs(ms->mport);
651 sprintf(buf,"%ld,%ld,%ld,%ld,%d,%d",
652 from>>24&255,from>>16&255,from>>8&255,from&255,
653 port>>8&255,port&255);
654
655
656
657
658 ftp->delta += strlen(buf) - (data-p);
659 if (ftp->delta==0)
660 {
661
662
663
664 ftp->init_seq = 0;
665 memcpy(p,buf,strlen(buf));
666 return skb;
667 }
668
669
670
671
672 printk("MASQUERADE: resizing needed for %d bytes (%ld)\n",ftp->delta, skb->len);
673 if (!ftp->init_seq)
674 ftp->init_seq = th->seq;
675
676 skb2 = alloc_skb(MAX_HEADER + skb->len+ftp->delta, GFP_ATOMIC);
677 if (skb2 == NULL) {
678 printk("MASQUERADE: No memory available\n");
679 return skb;
680 }
681 skb2->free = skb->free;
682 skb_reserve(skb2,MAX_HEADER);
683 skb_put(skb2,skb->len + ftp->delta);
684 skb2->h.raw = &skb2->data[skb->h.raw - skb->data];
685
686
687
688
689
690 memcpy(skb2->data, skb->data, (p - (char *)skb->data));
691 memcpy(&skb2->data[(p - (char *)skb->data)], buf, strlen(buf));
692 memcpy(&skb2->data[(p - (char *)skb->data) + strlen(buf)], data,
693 skb->len - ((char *)skb->h.raw - data));
694
695
696
697
698
699
700 kfree_skb(skb, FREE_WRITE);
701 return skb2;
702 }
703 return skb;
704 }
705
706 static void recalc_check(struct udphdr *uh, unsigned long saddr,
707 unsigned long daddr, int len)
708 {
709 uh->check=0;
710 uh->check=csum_tcpudp_magic(saddr,daddr,len,
711 IPPROTO_UDP, csum_partial((char *)uh,len,0));
712 if(uh->check==0)
713 uh->check=0xFFFF;
714 }
715
716 void ip_fw_masquerade(struct sk_buff **skb_ptr, struct device *dev)
717 {
718 struct sk_buff *skb=*skb_ptr;
719 struct iphdr *iph = skb->h.iph;
720 unsigned short *portptr;
721 struct ip_masq *ms;
722 int size;
723
724
725
726
727
728 if (iph->protocol!=IPPROTO_UDP && iph->protocol!=IPPROTO_TCP)
729 return;
730
731
732
733
734
735 portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
736 ms = ip_msq_hosts;
737
738 #ifdef DEBUG_MASQ
739 printk("Outgoing %s %lX:%X -> %lX:%X\n",
740 strProt[iph->protocol==IPPROTO_TCP],
741 ntohl(iph->saddr), ntohs(portptr[0]),
742 ntohl(iph->daddr), ntohs(portptr[1]));
743 #endif
744 while (ms!=NULL)
745 {
746 if (iph->protocol == ms->protocol &&
747 iph->saddr == ms->src && iph->daddr == ms->dst &&
748 portptr[0] == ms->sport && portptr[1] == ms->dport)
749 {
750 del_timer(&ms->timer);
751 break;
752 }
753 ms = ms->next;
754 }
755
756
757
758
759
760 if (ms==NULL)
761 {
762 ms = alloc_masq_entry();
763 if (ms==NULL)
764 {
765 printk("MASQUERADE: no memory left !\n");
766 return;
767 }
768 ms->protocol = iph->protocol;
769 ms->src = iph->saddr;
770 ms->dst = iph->daddr;
771 ms->sport = portptr[0];
772 ms->dport = portptr[1];
773 }
774
775
776
777
778
779 size = skb->len - ((unsigned char *)portptr - skb->h.raw);
780 iph->saddr = dev->pa_addr;
781 portptr[0] = ms->mport;
782
783
784
785
786
787 if (iph->protocol==IPPROTO_UDP)
788 {
789 ms->timer.expires = jiffies+MASQUERADE_EXPIRE_UDP;
790 recalc_check((struct udphdr *)portptr,iph->saddr,iph->daddr,size);
791 }
792 else
793 {
794 struct tcphdr *th;
795 if (portptr[1]==htons(21))
796 {
797 skb = revamp(*skb_ptr, dev, ms);
798 *skb_ptr = skb;
799 iph = skb->h.iph;
800 portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
801 }
802 th = (struct tcphdr *)portptr;
803
804
805
806
807 if (ms->sawfin || th->fin)
808 {
809 ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP_FIN;
810 ms->sawfin = 1;
811 }
812 else ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP;
813
814 tcp_send_check(th,iph->saddr,iph->daddr,size,skb->sk);
815 }
816 add_timer(&ms->timer);
817 ip_send_check(iph);
818
819 #ifdef DEBUG_MASQ
820 printk("O-routed from %lX:%X over %s\n",ntohl(dev->pa_addr),ntohs(ms->mport),dev->name);
821 #endif
822 }
823
824
825
826
827
828
829
830
831
832
833 int ip_fw_demasquerade(struct sk_buff *skb_ptr)
834 {
835 struct iphdr *iph = skb_ptr->h.iph;
836 unsigned short *portptr;
837 struct ip_masq *ms;
838 struct tcphdr *th = (struct tcphdr *)(skb_ptr->h.raw+(iph->ihl<<2));
839
840 if (iph->protocol!=IPPROTO_UDP && iph->protocol!=IPPROTO_TCP)
841 return 0;
842
843 portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
844 if (ntohs(portptr[1]) < PORT_MASQ_BEGIN ||
845 ntohs(portptr[1]) > PORT_MASQ_END)
846 return 0;
847
848 #ifdef DEBUG_MASQ
849 printk("Incoming %s %lX:%X -> %lX:%X\n",
850 strProt[iph->protocol==IPPROTO_TCP],
851 ntohl(iph->saddr), ntohs(portptr[0]),
852 ntohl(iph->daddr), ntohs(portptr[1]));
853 #endif
854
855
856
857
858
859
860
861
862
863 ms = ip_msq_hosts;
864 while (ms!=NULL)
865 {
866 if (iph->protocol==ms->protocol &&
867 (iph->saddr==ms->dst || iph->protocol==IPPROTO_UDP) &&
868 portptr[0]==ms->dport &&
869 portptr[1]==ms->mport)
870 {
871 int size = skb_ptr->len - ((unsigned char *)portptr - skb_ptr->h.raw);
872 iph->daddr = ms->src;
873 portptr[1] = ms->sport;
874
875
876
877
878 if (iph->protocol==IPPROTO_UDP)
879 recalc_check((struct udphdr *)portptr,iph->saddr,iph->daddr,size);
880 else
881 {
882
883
884
885
886 if (ms->delta && after(ms->init_seq,th->ack_seq))
887 {
888
889 th->ack_seq -= ms->delta;
890 }
891 tcp_send_check((struct tcphdr *)portptr,iph->saddr,iph->daddr,size,skb_ptr->sk);
892 }
893 ip_send_check(iph);
894 #ifdef DEBUG_MASQ
895 printk("I-routed to %lX:%X\n",ntohl(iph->daddr),ntohs(portptr[1]));
896 #endif
897 return 1;
898 }
899 ms = ms->next;
900 }
901
902
903 return 0;
904 }
905 #endif
906
907
908
909 static void zero_fw_chain(struct ip_fw *chainptr)
910 {
911 struct ip_fw *ctmp=chainptr;
912 while(ctmp)
913 {
914 ctmp->fw_pcnt=0L;
915 ctmp->fw_bcnt=0L;
916 ctmp=ctmp->fw_next;
917 }
918 }
919
920 static void free_fw_chain(struct ip_fw *volatile* chainptr)
921 {
922 unsigned long flags;
923 save_flags(flags);
924 cli();
925 while ( *chainptr != NULL )
926 {
927 struct ip_fw *ftmp;
928 ftmp = *chainptr;
929 *chainptr = ftmp->fw_next;
930 kfree_s(ftmp,sizeof(*ftmp));
931 }
932 restore_flags(flags);
933 }
934
935
936
937 static int add_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl)
938 {
939 struct ip_fw *ftmp;
940 struct ip_fw *chtmp=NULL;
941 struct ip_fw *volatile chtmp_prev=NULL;
942 unsigned long flags;
943 unsigned long m_src_mask,m_dst_mask;
944 unsigned long n_sa,n_da,o_sa,o_da,o_sm,o_dm,n_sm,n_dm;
945 unsigned short n_sr,n_dr,o_sr,o_dr;
946 unsigned short oldkind,newkind;
947 int addb4=0;
948 int n_o,n_n;
949
950 save_flags(flags);
951
952 ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
953 if ( ftmp == NULL )
954 {
955 #ifdef DEBUG_CONFIG_IP_FIREWALL
956 printk("ip_fw_ctl: malloc said no\n");
957 #endif
958 return( ENOMEM );
959 }
960
961 memcpy(ftmp, frwl, sizeof( struct ip_fw ) );
962
963 ftmp->fw_pcnt=0L;
964 ftmp->fw_bcnt=0L;
965
966 ftmp->fw_next = NULL;
967
968 cli();
969
970 if (*chainptr==NULL)
971 {
972 *chainptr=ftmp;
973 }
974 else
975 {
976 chtmp_prev=NULL;
977 for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->fw_next)
978 {
979 addb4=0;
980 newkind=ftmp->fw_flg & IP_FW_F_KIND;
981 oldkind=chtmp->fw_flg & IP_FW_F_KIND;
982
983 if (newkind!=IP_FW_F_ALL
984 && oldkind!=IP_FW_F_ALL
985 && oldkind!=newkind)
986 {
987 chtmp_prev=chtmp;
988 continue;
989 }
990
991
992
993
994
995
996 n_sa=ntohl(ftmp->fw_src.s_addr);
997 n_da=ntohl(ftmp->fw_dst.s_addr);
998 n_sm=ntohl(ftmp->fw_smsk.s_addr);
999 n_dm=ntohl(ftmp->fw_dmsk.s_addr);
1000
1001 o_sa=ntohl(chtmp->fw_src.s_addr);
1002 o_da=ntohl(chtmp->fw_dst.s_addr);
1003 o_sm=ntohl(chtmp->fw_smsk.s_addr);
1004 o_dm=ntohl(chtmp->fw_dmsk.s_addr);
1005
1006 m_src_mask = o_sm & n_sm;
1007 m_dst_mask = o_dm & n_dm;
1008
1009 if ((o_sa & m_src_mask) == (n_sa & m_src_mask))
1010 {
1011 if (n_sm > o_sm)
1012 addb4++;
1013 if (n_sm < o_sm)
1014 addb4--;
1015 }
1016
1017 if ((o_da & m_dst_mask) == (n_da & m_dst_mask))
1018 {
1019 if (n_dm > o_dm)
1020 addb4++;
1021 if (n_dm < o_dm)
1022 addb4--;
1023 }
1024
1025 if (((o_da & o_dm) == (n_da & n_dm))
1026 &&((o_sa & o_sm) == (n_sa & n_sm)))
1027 {
1028 if (newkind!=IP_FW_F_ALL &&
1029 oldkind==IP_FW_F_ALL)
1030 addb4++;
1031 if (newkind==oldkind && (oldkind==IP_FW_F_TCP
1032 || oldkind==IP_FW_F_UDP))
1033 {
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046 if (ftmp->fw_flg & IP_FW_F_SRNG)
1047 n_sr=ftmp->fw_pts[1]-ftmp->fw_pts[0];
1048 else
1049 n_sr=(ftmp->fw_nsp)?
1050 ftmp->fw_nsp : 0xFFFF;
1051
1052 if (chtmp->fw_flg & IP_FW_F_SRNG)
1053 o_sr=chtmp->fw_pts[1]-chtmp->fw_pts[0];
1054 else
1055 o_sr=(chtmp->fw_nsp)?chtmp->fw_nsp : 0xFFFF;
1056
1057 if (n_sr<o_sr)
1058 addb4++;
1059 if (n_sr>o_sr)
1060 addb4--;
1061
1062 n_n=ftmp->fw_nsp;
1063 n_o=chtmp->fw_nsp;
1064
1065
1066
1067
1068
1069
1070
1071 if ((n_n>(IP_FW_MAX_PORTS-2)) ||
1072 (n_o>(IP_FW_MAX_PORTS-2)))
1073 goto skip_check;
1074
1075 if (ftmp->fw_flg & IP_FW_F_DRNG)
1076 n_dr=ftmp->fw_pts[n_n+1]-ftmp->fw_pts[n_n];
1077 else
1078 n_dr=(ftmp->fw_ndp)? ftmp->fw_ndp : 0xFFFF;
1079
1080 if (chtmp->fw_flg & IP_FW_F_DRNG)
1081 o_dr=chtmp->fw_pts[n_o+1]-chtmp->fw_pts[n_o];
1082 else
1083 o_dr=(chtmp->fw_ndp)? chtmp->fw_ndp : 0xFFFF;
1084 if (n_dr<o_dr)
1085 addb4++;
1086 if (n_dr>o_dr)
1087 addb4--;
1088 skip_check:
1089 }
1090
1091 if ((addb4 == 0) && ftmp->fw_via.s_addr &&
1092 !(chtmp->fw_via.s_addr))
1093 addb4++;
1094 }
1095 if (addb4>0)
1096 {
1097 if (chtmp_prev)
1098 {
1099 chtmp_prev->fw_next=ftmp;
1100 ftmp->fw_next=chtmp;
1101 }
1102 else
1103 {
1104 *chainptr=ftmp;
1105 ftmp->fw_next=chtmp;
1106 }
1107 restore_flags(flags);
1108 return 0;
1109 }
1110 chtmp_prev=chtmp;
1111 }
1112 }
1113
1114 if (chtmp_prev)
1115 chtmp_prev->fw_next=ftmp;
1116 else
1117 *chainptr=ftmp;
1118 restore_flags(flags);
1119 return(0);
1120 }
1121
1122 static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
1123 {
1124 struct ip_fw *ftmp,*ltmp;
1125 unsigned short tport1,tport2,tmpnum;
1126 char matches,was_found;
1127 unsigned long flags;
1128
1129 save_flags(flags);
1130 cli();
1131
1132 ftmp=*chainptr;
1133
1134 if ( ftmp == NULL )
1135 {
1136 #ifdef DEBUG_CONFIG_IP_FIREWALL
1137 printk("ip_fw_ctl: chain is empty\n");
1138 #endif
1139 restore_flags(flags);
1140 return( EINVAL );
1141 }
1142
1143 ltmp=NULL;
1144 was_found=0;
1145
1146 while( ftmp != NULL )
1147 {
1148 matches=1;
1149 if (ftmp->fw_src.s_addr!=frwl->fw_src.s_addr
1150 || ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr
1151 || ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr
1152 || ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr
1153 || ftmp->fw_via.s_addr!=frwl->fw_via.s_addr
1154 || ftmp->fw_flg!=frwl->fw_flg)
1155 matches=0;
1156
1157 tport1=ftmp->fw_nsp+ftmp->fw_ndp;
1158 tport2=frwl->fw_nsp+frwl->fw_ndp;
1159 if (tport1!=tport2)
1160 matches=0;
1161 else if (tport1!=0)
1162 {
1163 for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
1164 if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum])
1165 matches=0;
1166 }
1167 if(matches)
1168 {
1169 was_found=1;
1170 if (ltmp)
1171 {
1172 ltmp->fw_next=ftmp->fw_next;
1173 kfree_s(ftmp,sizeof(*ftmp));
1174 ftmp=ltmp->fw_next;
1175 }
1176 else
1177 {
1178 *chainptr=ftmp->fw_next;
1179 kfree_s(ftmp,sizeof(*ftmp));
1180 ftmp=*chainptr;
1181 }
1182 }
1183 else
1184 {
1185 ltmp = ftmp;
1186 ftmp = ftmp->fw_next;
1187 }
1188 }
1189 restore_flags(flags);
1190 if (was_found)
1191 return 0;
1192 else
1193 return(EINVAL);
1194 }
1195
1196 #endif
1197
1198 struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
1199 {
1200
1201 if ( len != sizeof(struct ip_fw) )
1202 {
1203 #ifdef DEBUG_CONFIG_IP_FIREWALL
1204 printk("ip_fw_ctl: len=%d, want %d\n",len, sizeof(struct ip_fw));
1205 #endif
1206 return(NULL);
1207 }
1208
1209 if ( (frwl->fw_flg & ~IP_FW_F_MASK) != 0 )
1210 {
1211 #ifdef DEBUG_CONFIG_IP_FIREWALL
1212 printk("ip_fw_ctl: undefined flag bits set (flags=%x)\n",
1213 frwl->fw_flg);
1214 #endif
1215 return(NULL);
1216 }
1217
1218 if ( (frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2 )
1219 {
1220 #ifdef DEBUG_CONFIG_IP_FIREWALL
1221 printk("ip_fw_ctl: src range set but fw_nsp=%d\n",
1222 frwl->fw_nsp);
1223 #endif
1224 return(NULL);
1225 }
1226
1227 if ( (frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2 )
1228 {
1229 #ifdef DEBUG_CONFIG_IP_FIREWALL
1230 printk("ip_fw_ctl: dst range set but fw_ndp=%d\n",
1231 frwl->fw_ndp);
1232 #endif
1233 return(NULL);
1234 }
1235
1236 if ( frwl->fw_nsp + frwl->fw_ndp > IP_FW_MAX_PORTS )
1237 {
1238 #ifdef DEBUG_CONFIG_IP_FIREWALL
1239 printk("ip_fw_ctl: too many ports (%d+%d)\n",
1240 frwl->fw_nsp,frwl->fw_ndp);
1241 #endif
1242 return(NULL);
1243 }
1244
1245 return frwl;
1246 }
1247
1248
1249
1250
1251 #ifdef CONFIG_IP_ACCT
1252
1253 #if 0
1254 void ip_acct_cnt(struct iphdr *iph, struct device *dev, struct ip_fw *f)
1255 {
1256 (void) ip_fw_chk(iph, dev, f, 0, 1);
1257 return;
1258 }
1259 #endif
1260
1261 int ip_acct_ctl(int stage, void *m, int len)
1262 {
1263 if ( stage == IP_ACCT_FLUSH )
1264 {
1265 free_fw_chain(&ip_acct_chain);
1266 return(0);
1267 }
1268 if ( stage == IP_ACCT_ZERO )
1269 {
1270 zero_fw_chain(ip_acct_chain);
1271 return(0);
1272 }
1273 if ( stage == IP_ACCT_ADD
1274 || stage == IP_ACCT_DEL
1275 )
1276 {
1277 struct ip_fw *frwl;
1278
1279 if (!(frwl=check_ipfw_struct(m,len)))
1280 return (EINVAL);
1281
1282 switch (stage)
1283 {
1284 case IP_ACCT_ADD:
1285 return( add_to_chain(&ip_acct_chain,frwl));
1286 case IP_ACCT_DEL:
1287 return( del_from_chain(&ip_acct_chain,frwl));
1288 default:
1289
1290
1291
1292 #ifdef DEBUG_CONFIG_IP_FIREWALL
1293 printk("ip_acct_ctl: unknown request %d\n",stage);
1294 #endif
1295 return(EINVAL);
1296 }
1297 }
1298 #ifdef DEBUG_CONFIG_IP_FIREWALL
1299 printk("ip_acct_ctl: unknown request %d\n",stage);
1300 #endif
1301 return(EINVAL);
1302 }
1303 #endif
1304
1305 #ifdef CONFIG_IP_FIREWALL
1306 int ip_fw_ctl(int stage, void *m, int len)
1307 {
1308 int ret;
1309
1310 if ( stage == IP_FW_FLUSH_BLK )
1311 {
1312 free_fw_chain(&ip_fw_blk_chain);
1313 return(0);
1314 }
1315
1316 if ( stage == IP_FW_FLUSH_FWD )
1317 {
1318 free_fw_chain(&ip_fw_fwd_chain);
1319 return(0);
1320 }
1321
1322 if ( stage == IP_FW_ZERO_BLK )
1323 {
1324 zero_fw_chain(ip_fw_blk_chain);
1325 return(0);
1326 }
1327
1328 if ( stage == IP_FW_ZERO_FWD )
1329 {
1330 zero_fw_chain(ip_fw_fwd_chain);
1331 return(0);
1332 }
1333
1334 if ( stage == IP_FW_POLICY_BLK || stage == IP_FW_POLICY_FWD )
1335 {
1336 int *tmp_policy_ptr;
1337 tmp_policy_ptr=(int *)m;
1338 if ( stage == IP_FW_POLICY_BLK )
1339 ip_fw_blk_policy=*tmp_policy_ptr;
1340 else
1341 ip_fw_fwd_policy=*tmp_policy_ptr;
1342 return 0;
1343 }
1344
1345 if ( stage == IP_FW_CHK_BLK || stage == IP_FW_CHK_FWD )
1346 {
1347 struct device viadev;
1348 struct ip_fwpkt *ipfwp;
1349 struct iphdr *ip;
1350
1351 if ( len < sizeof(struct ip_fwpkt) )
1352 {
1353 #ifdef DEBUG_CONFIG_IP_FIREWALL
1354 printk("ip_fw_ctl: length=%d, expected %d\n",
1355 len, sizeof(struct ip_fwpkt));
1356 #endif
1357 return( EINVAL );
1358 }
1359
1360 ipfwp = (struct ip_fwpkt *)m;
1361 ip = &(ipfwp->fwp_iph);
1362
1363 if ( ip->ihl != sizeof(struct iphdr) / sizeof(int))
1364 {
1365 #ifdef DEBUG_CONFIG_IP_FIREWALL
1366 printk("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
1367 sizeof(struct iphdr)/sizeof(int));
1368 #endif
1369 return(EINVAL);
1370 }
1371
1372 viadev.pa_addr = ipfwp->fwp_via.s_addr;
1373
1374 if ((ret = ip_fw_chk(ip, &viadev,
1375 stage == IP_FW_CHK_BLK ?
1376 ip_fw_blk_chain : ip_fw_fwd_chain,
1377 stage == IP_FW_CHK_BLK ?
1378 ip_fw_blk_policy : ip_fw_fwd_policy, 2 )) > 0
1379 )
1380 return(0);
1381 else if (ret == -1)
1382 return(ECONNREFUSED);
1383 else
1384 return(ETIMEDOUT);
1385 }
1386
1387
1388
1389
1390
1391
1392 if ( stage == IP_FW_ADD_BLK || stage == IP_FW_ADD_FWD
1393 || stage == IP_FW_DEL_BLK || stage == IP_FW_DEL_FWD
1394 )
1395 {
1396 struct ip_fw *frwl;
1397 frwl=check_ipfw_struct(m,len);
1398 if (frwl==NULL)
1399 return (EINVAL);
1400
1401 switch (stage)
1402 {
1403 case IP_FW_ADD_BLK:
1404 return(add_to_chain(&ip_fw_blk_chain,frwl));
1405 case IP_FW_ADD_FWD:
1406 return(add_to_chain(&ip_fw_fwd_chain,frwl));
1407 case IP_FW_DEL_BLK:
1408 return(del_from_chain(&ip_fw_blk_chain,frwl));
1409 case IP_FW_DEL_FWD:
1410 return(del_from_chain(&ip_fw_fwd_chain,frwl));
1411 default:
1412
1413
1414
1415 #ifdef DEBUG_CONFIG_IP_FIREWALL
1416 printk("ip_fw_ctl: unknown request %d\n",stage);
1417 #endif
1418 return(EINVAL);
1419 }
1420 }
1421
1422 #ifdef DEBUG_CONFIG_IP_FIREWALL
1423 printk("ip_fw_ctl: unknown request %d\n",stage);
1424 #endif
1425 return(EINVAL);
1426 }
1427 #endif
1428
1429 #if defined(CONFIG_IP_FIREWALL) || defined(CONFIG_IP_ACCT)
1430
1431 static int ip_chain_procinfo(int stage, char *buffer, char **start,
1432 off_t offset, int length, int reset)
1433 {
1434 off_t pos=0, begin=0;
1435 struct ip_fw *i;
1436 unsigned long flags;
1437 int len, p;
1438
1439
1440 switch(stage)
1441 {
1442 #ifdef CONFIG_IP_FIREWALL
1443 case IP_INFO_BLK:
1444 i = ip_fw_blk_chain;
1445 len=sprintf(buffer, "IP firewall block rules, default %d\n",
1446 ip_fw_blk_policy);
1447 break;
1448 case IP_INFO_FWD:
1449 i = ip_fw_fwd_chain;
1450 len=sprintf(buffer, "IP firewall forward rules, default %d\n",
1451 ip_fw_fwd_policy);
1452 break;
1453 #endif
1454 #ifdef CONFIG_IP_ACCT
1455 case IP_INFO_ACCT:
1456 i = ip_acct_chain;
1457 len=sprintf(buffer,"IP accounting rules\n");
1458 break;
1459 #endif
1460 default:
1461
1462 i = NULL;
1463 len=0;
1464 break;
1465 }
1466
1467 save_flags(flags);
1468 cli();
1469
1470 while(i!=NULL)
1471 {
1472 len+=sprintf(buffer+len,"%08lX/%08lX->%08lX/%08lX %08lX %X ",
1473 ntohl(i->fw_src.s_addr),ntohl(i->fw_smsk.s_addr),
1474 ntohl(i->fw_dst.s_addr),ntohl(i->fw_dmsk.s_addr),
1475 ntohl(i->fw_via.s_addr),i->fw_flg);
1476 len+=sprintf(buffer+len,"%u %u %-9lu %-9lu",
1477 i->fw_nsp,i->fw_ndp, i->fw_pcnt,i->fw_bcnt);
1478 for (p = 0; p < IP_FW_MAX_PORTS; p++)
1479 len+=sprintf(buffer+len, " %u", i->fw_pts[p]);
1480 buffer[len++]='\n';
1481 buffer[len]='\0';
1482 pos=begin+len;
1483 if(pos<offset)
1484 {
1485 len=0;
1486 begin=pos;
1487 }
1488 else if(reset)
1489 {
1490
1491 i->fw_pcnt=0L;
1492 i->fw_bcnt=0L;
1493 }
1494 if(pos>offset+length)
1495 break;
1496 i=i->fw_next;
1497 }
1498 restore_flags(flags);
1499 *start=buffer+(offset-begin);
1500 len-=(offset-begin);
1501 if(len>length)
1502 len=length;
1503 return len;
1504 }
1505 #endif
1506
1507 #ifdef CONFIG_IP_ACCT
1508
1509 static int ip_acct_procinfo(char *buffer, char **start, off_t offset,
1510 int length, int reset)
1511 {
1512 return ip_chain_procinfo(IP_INFO_ACCT, buffer,start, offset,length,
1513 reset);
1514 }
1515
1516 #endif
1517
1518 #ifdef CONFIG_IP_FIREWALL
1519
1520 static int ip_fw_blk_procinfo(char *buffer, char **start, off_t offset,
1521 int length, int reset)
1522 {
1523 return ip_chain_procinfo(IP_INFO_BLK, buffer,start,offset,length,
1524 reset);
1525 }
1526
1527 static int ip_fw_fwd_procinfo(char *buffer, char **start, off_t offset,
1528 int length, int reset)
1529 {
1530 return ip_chain_procinfo(IP_INFO_FWD, buffer,start,offset,length,
1531 reset);
1532 }
1533 #endif
1534
1535 #ifdef CONFIG_IP_MASQUERADE
1536
1537 static int ip_msqhst_procinfo(char *buffer, char **start, off_t offset,
1538 int length, int unused)
1539 {
1540 off_t pos=0, begin=0;
1541 struct ip_masq *ms;
1542 unsigned long flags;
1543 int len=0;
1544
1545 len=sprintf(buffer,"Prc FromIP FPrt ToIP TPrt Masq Init-seq Delta Expires\n");
1546 save_flags(flags);
1547 cli();
1548
1549 ms=ip_msq_hosts;
1550 while (ms!=NULL)
1551 {
1552 int timer_active = del_timer(&ms->timer);
1553 if (!timer_active)
1554 ms->timer.expires = jiffies;
1555 len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08X %5d %lu\n",
1556 strProt[ms->protocol==IPPROTO_TCP],
1557 ntohl(ms->src),ntohs(ms->sport),
1558 ntohl(ms->dst),ntohs(ms->dport),
1559 ntohs(ms->mport),
1560 ms->init_seq,ms->delta,ms->timer.expires-jiffies);
1561 if (timer_active)
1562 add_timer(&ms->timer);
1563
1564 pos=begin+len;
1565 if(pos<offset)
1566 {
1567 len=0;
1568 begin=pos;
1569 }
1570 if(pos>offset+length)
1571 break;
1572 ms=ms->next;
1573 }
1574 restore_flags(flags);
1575 *start=buffer+(offset-begin);
1576 len-=(offset-begin);
1577 if(len>length)
1578 len=length;
1579 return len;
1580 }
1581
1582 #endif
1583
1584 void ip_fw_init(void)
1585 {
1586 #ifdef CONFIG_IP_ACCT
1587 proc_net_register(&(struct proc_dir_entry) {
1588 PROC_NET_IPACCT, 7, "ip_acct",
1589 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1590 0, &proc_net_inode_operations,
1591 ip_acct_procinfo
1592 });
1593 #endif
1594 #ifdef CONFIG_IP_FIREWALL
1595 proc_net_register(&(struct proc_dir_entry) {
1596 PROC_NET_IPFWBLK, 8, "ip_block",
1597 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1598 0, &proc_net_inode_operations,
1599 ip_fw_blk_procinfo
1600 });
1601 proc_net_register(&(struct proc_dir_entry) {
1602 PROC_NET_IPFWFWD, 10, "ip_forward",
1603 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
1604 0, &proc_net_inode_operations,
1605 ip_fw_fwd_procinfo
1606 });
1607 #endif
1608 #ifdef CONFIG_IP_MASQUERADE
1609 proc_net_register(&(struct proc_dir_entry) {
1610 PROC_NET_IPMSQHST, 13, "ip_masquerade",
1611 S_IFREG | S_IRUGO, 1, 0, 0,
1612 0, &proc_net_inode_operations,
1613 ip_msqhst_procinfo
1614 });
1615 #endif
1616 }