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