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