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