home *** CD-ROM | disk | FTP | other *** search
/ Hacks & Cracks / Hacks_and_Cracks.iso / hackersclub / km / downloads / c_scripts / ip_masq.c < prev    next >
C/C++ Source or Header  |  1998-03-25  |  33KB  |  1,271 lines

  1. From nik@netaxs.comTue Jul 18 09:26:08 1995
  2. Date: Mon, 17 Jul 1995 17:25:26 -0400 (EDT)
  3. From: Nik Weidenbacher <nik@netaxs.com>
  4. To: masq@eves.com
  5. Subject: The 1.2 patch.
  6.  
  7. I have heard many requests for this, so here it is.  I also posted it to
  8. c.o.l.networking.  
  9.  
  10. nik
  11.  
  12. diff -rc linux/arch/i386/config.in linux+masq/arch/i386/config.in
  13. *** linux/arch/i386/config.in    Tue Mar  7 15:25:26 1995
  14. --- linux+masq/arch/i386/config.in    Thu Mar  9 10:00:25 1995
  15. ***************
  16. *** 46,51 ****
  17. --- 46,54 ----
  18.   bool 'IP multicasting' CONFIG_IP_MULTICAST n
  19.   bool 'IP firewalling' CONFIG_IP_FIREWALL n
  20.   bool 'IP accounting' CONFIG_IP_ACCT n
  21. + if [ "$CONFIG_IP_FORWARD" = "y" -a "$CONFIG_IP_FIREWALL" = "y" ]; then
  22. +   bool 'IP masquerading (ALPHA)' CONFIG_IP_MASQUERADE n
  23. + fi
  24.   comment '(it is safe to leave these untouched)'
  25.   bool 'PC/TCP compatibility mode' CONFIG_INET_PCTCP n
  26.   bool 'Reverse ARP' CONFIG_INET_RARP n
  27. diff -rc linux/include/linux/ip_fw.h linux+masq/include/linux/ip_fw.h
  28. *** linux/include/linux/ip_fw.h    Thu Mar  9 19:33:55 1995
  29. --- linux+masq/include/linux/ip_fw.h    Sat Mar 18 10:46:39 1995
  30. ***************
  31. *** 15,20 ****
  32. --- 15,23 ----
  33.    *        Alan.
  34.    *
  35.    *    All the real work was done by .....
  36. +  *
  37. +  * Fixes:
  38. +  *    Pauline Middelink    :    Added masquerading.
  39.    */
  40.   
  41.   /*
  42. ***************
  43. *** 83,89 ****
  44.   #define IP_FW_F_BIDIR    0x040    /* For bidirectional firewalls        */
  45.   #define IP_FW_F_TCPSYN    0x080    /* For tcp packets-check SYN only     */
  46.   #define IP_FW_F_ICMPRPL 0x100    /* Send back icmp unreachable packet  */
  47. ! #define IP_FW_F_MASK    0x1FF    /* All possible flag bits mask        */
  48.   
  49.   /*    
  50.    *    New IP firewall options for [gs]etsockopt at the RAW IP level.
  51. --- 86,93 ----
  52.   #define IP_FW_F_BIDIR    0x040    /* For bidirectional firewalls        */
  53.   #define IP_FW_F_TCPSYN    0x080    /* For tcp packets-check SYN only     */
  54.   #define IP_FW_F_ICMPRPL 0x100    /* Send back icmp unreachable packet  */
  55. ! #define IP_FW_F_MASQ    0x200    /* Masquerading                  */
  56. ! #define IP_FW_F_MASK    0x3FF    /* All possible flag bits mask        */
  57.   
  58.   /*    
  59.    *    New IP firewall options for [gs]etsockopt at the RAW IP level.
  60. ***************
  61. *** 134,147 ****
  62.   extern struct ip_fw *ip_fw_fwd_chain;
  63.   extern int ip_fw_blk_policy;
  64.   extern int ip_fw_fwd_policy;
  65.   extern int ip_fw_ctl(int, void *, int);
  66.   #endif
  67.   #ifdef CONFIG_IP_ACCT
  68.   extern struct ip_fw *ip_acct_chain;
  69. - extern void ip_acct_cnt(struct iphdr *, struct device *, struct ip_fw *);
  70.   extern int ip_acct_ctl(int, void *, int);
  71.   #endif
  72. ! extern int ip_fw_chk(struct iphdr *, struct device *rif,struct ip_fw *, int, int);
  73.   #endif /* KERNEL */
  74.   
  75.   #endif /* _IP_FW_H */
  76. --- 138,166 ----
  77.   extern struct ip_fw *ip_fw_fwd_chain;
  78.   extern int ip_fw_blk_policy;
  79.   extern int ip_fw_fwd_policy;
  80. + extern int ip_fw_chk(struct iphdr *, struct device *rif,struct ip_fw *, int, int);
  81.   extern int ip_fw_ctl(int, void *, int);
  82.   #endif
  83.   #ifdef CONFIG_IP_ACCT
  84.   extern struct ip_fw *ip_acct_chain;
  85.   extern int ip_acct_ctl(int, void *, int);
  86.   #endif
  87. ! #ifdef CONFIG_IP_MASQUERADE
  88. ! struct ip_masq {
  89. !     struct ip_masq    *next;        /* next member in list */
  90. !     struct timer_list timer;    /* Expiration timer */
  91. !     __u16         protocol;    /* Which protocol are we talking? */
  92. !     __u32         src, dst;    /* Source and destination IP addresses */
  93. !     __u16        sport,dport;    /* Source and destoination ports */
  94. !     __u16        mport;        /* Masquaraded port */
  95. !     __u32        init_seq;    /* Add delta from this seq. on */
  96. !     short        delta;        /* Delta in sequence numbers */
  97. !     char        sawfin;        /* Did we saw an FIN packet? */
  98. ! };
  99. ! extern struct ip_masq *ip_msq_hosts;
  100. ! extern void ip_fw_masquerade(struct sk_buff *, struct device *);
  101. ! extern int ip_fw_demasquerade(struct sk_buff *);
  102. ! #endif
  103.   #endif /* KERNEL */
  104.   
  105.   #endif /* _IP_FW_H */
  106. diff -rc linux/include/linux/proc_fs.h linux+masq/include/linux/proc_fs.h
  107. *** linux/include/linux/proc_fs.h    Sun Feb 12 20:11:02 1995
  108. --- linux+masq/include/linux/proc_fs.h    Thu Mar  9 10:00:26 1995
  109. ***************
  110. *** 74,79 ****
  111. --- 74,82 ----
  112.   #ifdef CONFIG_IP_ACCT
  113.       PROC_NET_IPACCT,
  114.   #endif
  115. + #ifdef CONFIG_IP_MASQUERADE
  116. +     PROC_NET_IPMSQHST,
  117. + #endif
  118.   #if    defined(CONFIG_WAVELAN)
  119.       PROC_NET_WAVELAN,
  120.   #endif    /* defined(CONFIG_WAVELAN) */
  121. diff -rc linux/net/inet/ip.c linux+masq/net/inet/ip.c
  122. *** linux/net/inet/ip.c    Thu Mar  9 19:33:55 1995
  123. --- linux+masq/net/inet/ip.c    Sat Mar 18 10:44:03 1995
  124. ***************
  125. *** 62,67 ****
  126. --- 62,69 ----
  127.    *        Alan Cox    :    RAW sockets demultiplex in the BSD style.
  128.    *        Gunther Mayer    :    Fix the SNMP reporting typo
  129.    *        Alan Cox    :    Always in group 224.0.0.1
  130. +  *    Pauline Middelink    :    Fast ip_checksum update when forwarding
  131. +  *                    Masquerading support.
  132.    *        Alan Cox    :    Multicast loopback error for 224.0.0.1
  133.    *        Alan Cox    :    IP_MULTICAST_LOOP option.
  134.    *        Alan Cox    :    Use notifiers.
  135. ***************
  136. *** 1263,1280 ****
  137.       struct rtable *rt;    /* Route we use */
  138.       unsigned char *ptr;    /* Data pointer */
  139.       unsigned long raddr;    /* Router IP address */
  140. !     
  141.       /* 
  142.        *    See if we are allowed to forward this.
  143.        */
  144.   
  145. ! #ifdef CONFIG_IP_FIREWALL
  146. !     int err;
  147. !     
  148. !     if((err=ip_fw_chk(skb->h.iph, dev, ip_fw_fwd_chain, ip_fw_fwd_policy, 0))!=1)
  149. !     {
  150. !         if(err==-1)
  151. !             icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev);
  152.           return;
  153.       }
  154.   #endif
  155. --- 1265,1282 ----
  156.       struct rtable *rt;    /* Route we use */
  157.       unsigned char *ptr;    /* Data pointer */
  158.       unsigned long raddr;    /* Router IP address */
  159. ! #ifdef CONFIG_IP_FIREWALL
  160. !     int fw_res = 0;        /* Forwarding Result */
  161.       /* 
  162.        *    See if we are allowed to forward this.
  163. +      *    Note: demasqueraded fragments are always 'back'warded.
  164.        */
  165.   
  166. !      if( !(is_frag&4) && (fw_res=ip_fw_chk(skb->h.iph, dev, ip_fw_fwd_chain, ip_fw_fwd_policy, 0))<1)
  167. !       {
  168. !          if(fw_res==-1)
  169. !              icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev);
  170.           return;
  171.       }
  172.   #endif
  173. ***************
  174. *** 1291,1302 ****
  175.   
  176.       iph = skb->h.iph;
  177.       iph->ttl--;
  178. -     if (iph->ttl <= 0)
  179. -     {
  180. -         /* Tell the sender its packet died... */
  181. -         icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, dev);
  182. -         return;
  183. -     }
  184.   
  185.       /*
  186.        *    Re-compute the IP header checksum.
  187. --- 1293,1298 ----
  188. ***************
  189. *** 1304,1310 ****
  190. --- 1300,1324 ----
  191.        *    and could thus adjust the checksum as Phil Karn does in KA9Q
  192.        */
  193.   
  194. + #if 0
  195.       ip_send_check(iph);
  196. + #else
  197. +     /*
  198. +      * Like this?
  199. +      *     Notice we must do the additions in HOST format!
  200. +      */
  201. +     iph->check = ntohs(iph->check) + 0x0100;
  202. +     if ((iph->check & 0xFF00) == 0)
  203. +         iph->check++;        /* carry overflow */
  204. +     iph->check = htons(iph->check);
  205. + #endif
  206. +     if (iph->ttl <= 0)
  207. +     {
  208. +         /* Tell the sender its packet died... */
  209. +         icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, dev);
  210. +         return;
  211. +     }
  212.   
  213.       /*
  214.        * OK, the packet is still valid.  Fetch its destination address,
  215. ***************
  216. *** 1380,1385 ****
  217. --- 1394,1407 ----
  218.   
  219.       if (dev2->flags & IFF_UP)
  220.       {
  221. + #ifdef CONFIG_IP_MASQUERADE
  222. +         /*
  223. +          * If this fragment needs masquerading, make it so...
  224. +          * (Dont masquerade de-masqueraded fragments)
  225. +          */
  226. +         if (!(is_frag&4) && fw_res==2)
  227. +             ip_fw_masquerade(skb, dev2);
  228. + #endif
  229.   
  230.           /*
  231.            *    Current design decrees we copy the packet. For identical header
  232. ***************
  233. *** 1430,1436 ****
  234.                *    Count mapping we shortcut
  235.                */
  236.                
  237. !             ip_acct_cnt(iph,dev,ip_acct_chain);
  238.   #endif            
  239.               
  240.               /*
  241. --- 1452,1458 ----
  242.                *    Count mapping we shortcut
  243.                */
  244.                
  245. !             ip_fw_chk(iph,dev,ip_acct_chain,0,1);
  246.   #endif            
  247.               
  248.               /*
  249. ***************
  250. *** 1501,1507 ****
  251.   
  252.   #ifdef    CONFIG_IP_FIREWALL
  253.       
  254. !     if ((err=ip_fw_chk(iph,dev,ip_fw_blk_chain,ip_fw_blk_policy, 0))!=1)
  255.       {
  256.           if(err==-1)
  257.               icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0, dev);
  258. --- 1523,1529 ----
  259.   
  260.   #ifdef    CONFIG_IP_FIREWALL
  261.       
  262. !     if ((err=ip_fw_chk(iph,dev,ip_fw_blk_chain,ip_fw_blk_policy,0))<1)
  263.       {
  264.           if(err==-1)
  265.               icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0, dev);
  266. ***************
  267. *** 1613,1624 ****
  268.           while(1);
  269.       }
  270.   #endif
  271.       /*
  272.        *    Account for the packet
  273.        */
  274. !      
  275.   #ifdef CONFIG_IP_ACCT
  276. !     ip_acct_cnt(iph,dev, ip_acct_chain);
  277.   #endif    
  278.   
  279.       /*
  280. --- 1635,1658 ----
  281.           while(1);
  282.       }
  283.   #endif
  284. + #ifdef CONFIG_IP_MASQUERADE
  285. +     /*
  286. +      * Do we need to de-masquerade this fragment?
  287. +      */
  288. +     if (ip_fw_demasquerade(skb)) {
  289. +         ip_forward(skb, dev, is_frag|4);
  290. +         kfree_skb(skb, FREE_WRITE);
  291. +         return(0);
  292. +     }
  293. + #endif
  294.       /*
  295.        *    Account for the packet
  296.        */
  297. !  
  298.   #ifdef CONFIG_IP_ACCT
  299. !     ip_fw_chk(iph,dev,ip_acct_chain,0,1);
  300.   #endif    
  301.   
  302.       /*
  303. ***************
  304. *** 1634,1641 ****
  305.           skb->dev = dev;
  306.           iph=skb->h.iph;
  307.       }
  308. -     
  309. -          
  310.   
  311.       /*
  312.        *    Point into the IP datagram, just past the header.
  313. --- 1668,1673 ----
  314. ***************
  315. *** 1643,1655 ****
  316.   
  317.       skb->ip_hdr = iph;
  318.       skb->h.raw += iph->ihl*4;
  319. !     
  320.       /*
  321.        *    Deliver to raw sockets. This is fun as to avoid copies we want to make no surplus copies.
  322.        */
  323. !      
  324.       hash = iph->protocol & (SOCK_ARRAY_SIZE-1);
  325. !     
  326.       /* If there maybe a raw socket we must check - if not we don't care less */
  327.       if((raw_sk=raw_prot.sock_array[hash])!=NULL)
  328.       {
  329. --- 1675,1687 ----
  330.   
  331.       skb->ip_hdr = iph;
  332.       skb->h.raw += iph->ihl*4;
  333.       /*
  334.        *    Deliver to raw sockets. This is fun as to avoid copies we want to make no surplus copies.
  335.        */
  336. !  
  337.       hash = iph->protocol & (SOCK_ARRAY_SIZE-1);
  338.       /* If there maybe a raw socket we must check - if not we don't care less */
  339.       if((raw_sk=raw_prot.sock_array[hash])!=NULL)
  340.       {
  341. ***************
  342. *** 1921,1927 ****
  343.        
  344.       ip_statistics.IpOutRequests++;
  345.   #ifdef CONFIG_IP_ACCT
  346. !     ip_acct_cnt(iph,dev, ip_acct_chain);
  347.   #endif    
  348.       
  349.   #ifdef CONFIG_IP_MULTICAST    
  350. --- 1953,1959 ----
  351.        
  352.       ip_statistics.IpOutRequests++;
  353.   #ifdef CONFIG_IP_ACCT
  354. !     ip_fw_chk(iph,dev,ip_acct_chain,0,1);
  355.   #endif    
  356.       
  357.   #ifdef CONFIG_IP_MULTICAST    
  358. diff -rc linux/net/inet/ip_fw.c linux+masq/net/inet/ip_fw.c
  359. *** linux/net/inet/ip_fw.c    Fri Mar 10 09:07:14 1995
  360. --- linux+masq/net/inet/ip_fw.c    Sat Mar 18 11:15:41 1995
  361. ***************
  362. *** 21,26 ****
  363. --- 21,41 ----
  364.    *        Jos Vos 5/Mar/1995.
  365.    *
  366.    *    All the real work was done by .....
  367. +  *
  368. +  * Fixes:
  369. +  *    Pauline Middelink    :    Added masquerading.
  370. +  */
  371. + /*
  372. +  * Masquerading functionality
  373. +  *
  374. +  * Copyright (c) 1994 Pauline Middelink
  375. +  *
  376. +  * The pieces which added masquerading functionality are totaly
  377. +  * my responsibility and have nothing to with the original authors
  378. +  * copyright or doing.
  379. +  *
  380. +  * Parts distributed under GPL.
  381.    */
  382.   
  383.   /*
  384. ***************
  385. *** 58,63 ****
  386. --- 73,79 ----
  387.   #include "protocol.h"
  388.   #include "route.h"
  389.   #include "tcp.h"
  390. + #include "udp.h"
  391.   #include <linux/skbuff.h>
  392.   #include "sock.h"
  393.   #include "icmp.h"
  394. ***************
  395. *** 104,109 ****
  396. --- 120,148 ----
  397.   #define IP_INFO_FWD    1
  398.   #define IP_INFO_ACCT    2
  399.   
  400. + /*
  401. +  *    Implement IP packet masquerading
  402. +  */
  403. + #ifdef CONFIG_IP_MASQUERADE
  404. + #undef DEBUG_MASQ
  405. + #define MASQUERADE_EXPIRE_TCP     15*60*HZ
  406. + #define MASQUERADE_EXPIRE_TCP_FIN  2*60*HZ
  407. + #define MASQUERADE_EXPIRE_UDP      5*60*HZ
  408. + /*
  409. +  * Linux ports don't get allocated above 32K. I used a extra 4K port-space
  410. +  */
  411. + #define PORT_MASQ_BEGIN    32768
  412. + #define PORT_MASQ_END    (PORT_MASQ_BEGIN+4096)
  413. + static unsigned short masq_port = PORT_MASQ_BEGIN;
  414. + static char *strProt[] = {"UDP","TCP"};
  415. + struct ip_masq *ip_msq_hosts;
  416. + #endif
  417.   
  418.   /*
  419.    *    Returns 1 if the port is matched by the vector, 0 otherwise
  420. ***************
  421. *** 136,143 ****
  422.   
  423.   
  424.   /*
  425. !  *    Returns 0 if packet should be dropped, 1 if it should be accepted,
  426. !  *    and -1 if an ICMP host unreachable packet should be sent.
  427.    *    Also does accounting so you can feed it the accounting chain.
  428.    *    If opt is set to 1, it means that we do this for accounting
  429.    *    purposes (searches all entries and handles fragments different).
  430. --- 175,184 ----
  431.   
  432.   
  433.   /*
  434. !  *    Returns 0 if packet should be dropped, 1 if it should be
  435. !  *    accepted and -1 if an ICMP host unreachable packet should
  436. !  *    be sent. Returns 2 to indicate it as matched by a masquerading rule.
  437. !  *
  438.    *    Also does accounting so you can feed it the accounting chain.
  439.    *    If opt is set to 1, it means that we do this for accounting
  440.    *    purposes (searches all entries and handles fragments different).
  441. ***************
  442. *** 149,173 ****
  443.   int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int policy, int opt)
  444.   {
  445.       struct ip_fw *f;
  446. !     struct tcphdr        *tcp=(struct tcphdr *)((unsigned long *)ip+ip->ihl);
  447. !     struct udphdr        *udp=(struct udphdr *)((unsigned long *)ip+ip->ihl);
  448.       __u32            src, dst;
  449.       __u16            src_port=0, dst_port=0;
  450.       unsigned short        f_prt=0, prt;
  451.       char            notcpsyn=1, frag1, match;
  452.       unsigned short        f_flag;
  453.   
  454. -     /*
  455. -      *    If the chain is empty follow policy. The BSD one
  456. -      *    accepts anything giving you a time window while
  457. -      *    flushing and rebuilding the tables.
  458. -      */
  459. -      
  460. -     src = ip->saddr;
  461. -     dst = ip->daddr;
  462.       /* 
  463. !      *    This way we handle fragmented packets.
  464.        *    we ignore all fragments but the first one
  465.        *    so the whole packet can't be reassembled.
  466.        *    This way we relay on the full info which
  467. --- 190,205 ----
  468.   int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int policy, int opt)
  469.   {
  470.       struct ip_fw *f;
  471. !     struct tcphdr        *tcp=(struct tcphdr *)((unsigned char *)ip+ip->ihl*4);
  472. !     struct udphdr        *udp=(struct udphdr *)((unsigned char *)ip+ip->ihl*4);
  473.       __u32            src, dst;
  474.       __u16            src_port=0, dst_port=0;
  475.       unsigned short        f_prt=0, prt;
  476.       char            notcpsyn=1, frag1, match;
  477.       unsigned short        f_flag;
  478.   
  479.       /* 
  480. !      *    This way we handle fragmented packets:
  481.        *    we ignore all fragments but the first one
  482.        *    so the whole packet can't be reassembled.
  483.        *    This way we relay on the full info which
  484. ***************
  485. *** 195,201 ****
  486.        *    per device. We have a device per address with dummy
  487.        *    devices instead.
  488.        */
  489. !      
  490.       dprintf1("Packet ");
  491.       switch(ip->protocol) 
  492.       {
  493. --- 227,233 ----
  494.        *    per device. We have a device per address with dummy
  495.        *    devices instead.
  496.        */
  497.       dprintf1("Packet ");
  498.       switch(ip->protocol) 
  499.       {
  500. ***************
  501. *** 388,399 ****
  502.       else
  503.           f_flag=policy;
  504.       if(f_flag&IP_FW_F_ACCEPT)
  505. !         return 1;
  506.       if(f_flag&IP_FW_F_ICMPRPL)
  507.           return -1;
  508.       return 0;
  509.   }
  510.   
  511.   
  512.   static void zero_fw_chain(struct ip_fw *chainptr)
  513.   {
  514. --- 420,811 ----
  515.       else
  516.           f_flag=policy;
  517.       if(f_flag&IP_FW_F_ACCEPT)
  518. !         return (f_flag&IP_FW_F_MASQ) ? 2 : 1;
  519.       if(f_flag&IP_FW_F_ICMPRPL)
  520.           return -1;
  521.       return 0;
  522.   }
  523.   
  524. + #ifdef CONFIG_IP_MASQUERADE
  525. + static
  526. + void masq_expire(unsigned long data)
  527. + {
  528. +     struct ip_masq *ms = (struct ip_masq *)data;
  529. +     struct ip_masq *old,*cur;
  530. +     unsigned long flags;
  531. + #ifdef DEBUG_MASQ
  532. +     printk("Masqueraded %s %lX:%X expired\n",
  533. +             strProt[ms->protocol==IPPROTO_TCP],
  534. +             ntohl(ms->src),ntohs(ms->sport));
  535. + #endif
  536. +     
  537. +     save_flags(flags);
  538. +     cli();
  539. +     /* delete from list of hosts */
  540. +     old = NULL;
  541. +     cur = ip_msq_hosts;
  542. +     while (cur!=NULL) {
  543. +         if (cur==ms) {
  544. +             if (old==NULL) ip_msq_hosts = ms->next;
  545. +             else old->next = ms->next;
  546. +             kfree_s(ms,sizeof(*ms));
  547. +             break;
  548. +         }
  549. +         old = cur;
  550. +         cur=cur->next;
  551. +     }
  552. +     restore_flags(flags);
  553. + }
  554. + /*
  555. +  * Create a new masquerade list entry, also allocate an
  556. +  * unused mport, keeping the portnumber between the
  557. +  * given boundaries MASQ_BEGIN and MASQ_END.
  558. +  *
  559. +  * FIXME: possible deadlock if all free ports are exhausted! 
  560. +  */
  561. + static
  562. + struct ip_masq *alloc_masq_entry(void)
  563. + {
  564. +     struct ip_masq *ms, *mst;
  565. +     unsigned long flags;
  566. +     ms = (struct ip_masq *) kmalloc(sizeof(struct ip_masq), GFP_ATOMIC);
  567. +     if (ms==NULL) 
  568. +         return NULL;
  569. +     memset(ms,0,sizeof(*ms));
  570. +     init_timer(&ms->timer);
  571. +     ms->timer.data     = (unsigned long)ms;
  572. +     ms->timer.function = masq_expire;
  573. +     save_flags(flags);
  574. +     cli();
  575. +     do {
  576. +         /* Try the next available port number */
  577. +         ms->mport = htons(masq_port++);
  578. +         if (masq_port==PORT_MASQ_END)
  579. +             masq_port = PORT_MASQ_BEGIN;
  580. +         /* Now hunt through the used ports to see if
  581. +          * this port is in use... */
  582. +         mst = ip_msq_hosts;
  583. +         while (mst && mst->mport!=ms->mport)
  584. +             mst = mst->next;
  585. +     }
  586. +     while (mst!=NULL); 
  587. +     /* add new entry in front of list to minimize lookup-time */
  588. +     ms->next  = ip_msq_hosts;
  589. +     ip_msq_hosts = ms;
  590. +     restore_flags(flags);
  591. +     return ms;
  592. + }
  593. + #ifdef notdef
  594. + /*
  595. +  * When passing an FTP 'PORT' command, try to replace the IP
  596. +  * address with an newly assigned (masquereded) port on this
  597. +  * host, so the ftp-data connect FROM the site will succeed...
  598. +  *
  599. +  * Also, when the size of the packet changes, create an delta
  600. +  * offset, which will be added to every th->seq (and subtracted for
  601. +  * (th->acqseq) whose seq > init_seq.
  602. +  *
  603. +  * Not for the faint of heart!
  604. +  */
  605. + static
  606. + struct sk_buff *revamp(struct sk_buff *skb, struct device *dev, struct ip_masq *ftp)
  607. + {
  608. +     struct iphdr *iph = skb->h.iph;
  609. +     struct tcphdr *th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
  610. +     struct sk_buff *skb2;
  611. +     char *p, *data = (char *)&th[1];
  612. +     unsigned char p1,p2,p3,p4,p5,p6;
  613. +     unsigned long from;
  614. +     unsigned short port;
  615. +     struct ip_masq *ms;
  616. +     char buf[20];        /* xxx.xxx.xxx.xxx\r\n */
  617. +     
  618. +     /*
  619. +      * Adjust seq and ack_seq with delta-offset for
  620. +      * the packets AFTER this one...
  621. +      */
  622. +     if (ftp->delta && after(ftp->init_seq,th->seq)) {
  623. +         th->seq += ftp->delta;
  624. +         th->ack_seq += ftp->delta;
  625. +     }
  626. +     while (skb->len - ((unsigned char *)data - skb->h.raw) > 18)
  627. +     {
  628. +         if (memcmp(data,"PORT ",5)!=0 && memcmp(data,"port ",5)!=0) {
  629. +             data += 5;
  630. +             continue;
  631. +         }
  632. +         p = data+5;
  633. +         p1 = simple_strtoul(data+5,&data,10);
  634. +         if (*data!=',')
  635. +             continue;
  636. +         p2 = simple_strtoul(data+1,&data,10);
  637. +         if (*data!=',')
  638. +             continue;
  639. +         p3 = simple_strtoul(data+1,&data,10);
  640. +         if (*data!=',')
  641. +             continue;
  642. +         p4 = simple_strtoul(data+1,&data,10);
  643. +         if (*data!=',')
  644. +             continue;
  645. +         p5 = simple_strtoul(data+1,&data,10);
  646. +         if (*data!=',')
  647. +             continue;
  648. +         p6 = simple_strtoul(data+1,&data,10);
  649. +         if (*data!='\r' && *data!='\n')
  650. +             continue;
  651. +         from = (p1<<24) | (p2<<16) | (p3<<8) | p4;
  652. +         port = (p5<<8) | p6;
  653. + printk("PORT %lX:%X detected\n",from,port);
  654. +     
  655. +         /*
  656. +          * Now create an masquerade entry for it
  657. +          */
  658. +         ms = alloc_masq_entry();
  659. +         if (ms==NULL)
  660. +             return skb;
  661. +         ms->protocol = IPPROTO_TCP;
  662. +         ms->src      = htonl(from);    /* derived from PORT cmd */
  663. +         ms->sport    = htons(port);    /* derived from PORT cmd */
  664. +         ms->dst      = iph->daddr;
  665. +         ms->dport    = htons(20);    /* ftp-data */
  666. +         ms->timer.expires = MASQUERADE_EXPIRE_TCP_FIN;
  667. +         add_timer(&ms->timer);
  668. +         /*
  669. +          * Replace the old PORT with the new one
  670. +          */
  671. +         from = ntohl(dev->pa_addr);
  672. +         port = ntohs(ms->mport);
  673. +         sprintf(buf,"%ld,%ld,%ld,%ld,%d,%d",
  674. +             from>>24&255,from>>16&255,from>>8&255,from&255,
  675. +             port>>8&255,port&255);
  676. +         /*
  677. +          * Calculate required delta-offset to keep TCP happy
  678. +          */
  679. +         ftp->delta += strlen(buf) - (data-p);
  680. +         if (ftp->delta==0) {
  681. +             /*
  682. +              * simple case, just replace the old PORT cmd
  683. +              */
  684. +             ftp->init_seq = 0;
  685. +             memcpy(p,buf,strlen(buf));
  686. +             return skb;
  687. +         }
  688. +         /*
  689. +          * Sizes differ, make a copy
  690. +          */
  691. + printk("MASQUERADE: resizing needed for %d bytes (%ld)\n",ftp->delta, skb->len);
  692. +         if (!ftp->init_seq)
  693. +             ftp->init_seq = th->seq;
  694. +         skb2 = alloc_skb(skb->mem_len-sizeof(struct sk_buff)+ftp->delta, GFP_ATOMIC);
  695. +         if (skb2 == NULL) {
  696. +             printk("MASQUERADE: No memory available\n");
  697. +             return skb;
  698. +         }
  699. +         skb2->free = skb->free;
  700. +         skb2->len = skb->len + ftp->delta;
  701. +         skb2->h.raw = &skb2->data[skb->h.raw - skb->data];
  702. +         /*
  703. +          *    Copy the packet data into the new buffer.
  704. +          *    Thereby replacing the PORT cmd.
  705. +          */
  706. +         memcpy(skb2->data, skb->data, (p - (char *)skb->data));
  707. +         memcpy(&skb2->data[(p - (char *)skb->data)], buf, strlen(buf));
  708. +         memcpy(&skb2->data[(p - (char *)skb->data) + strlen(buf)], data,
  709. +             skb->mem_len - sizeof(struct sk_buff) - ((char *)skb->h.raw - data));
  710. +         /*
  711. +          * Problem, how to replace the new skb with old one,
  712. +          * preferably inplace, so all the pointers in the
  713. +          * calling tree keep ok :(
  714. +          */
  715. +         kfree_skb(skb, FREE_WRITE);
  716. +         return skb2;
  717. +     }
  718. +     return skb;
  719. + }
  720. + #endif
  721. + void ip_fw_masquerade(struct sk_buff *skb, struct device *dev)
  722. + {
  723. +     struct iphdr    *iph = skb->h.iph;
  724. +     unsigned short    *portptr;
  725. +     struct ip_masq    *ms;
  726. +     int        size;
  727. +     /*
  728. +      * We can only masquerade protocols with ports...
  729. +      */
  730. +     if (iph->protocol!=IPPROTO_UDP && iph->protocol!=IPPROTO_TCP)
  731. +         return;
  732. +     /*
  733. +      * Now hunt the list to see if we have an old entry
  734. +      */
  735. +     portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
  736. +     ms = ip_msq_hosts;
  737. + #ifdef DEBUG_MASQ
  738. +     printk("Outgoing %s %lX:%X -> %lX:%X\n",
  739. +         strProt[iph->protocol==IPPROTO_TCP],
  740. +         ntohl(iph->saddr), ntohs(portptr[0]),
  741. +         ntohl(iph->daddr), ntohs(portptr[1]));
  742. + #endif
  743. +     while (ms!=NULL) {
  744. +         if (iph->protocol == ms->protocol &&
  745. +             iph->saddr == ms->src   && iph->daddr == ms->dst &&
  746. +             portptr[0] == ms->sport && portptr[1] == ms->dport) {
  747. +             del_timer(&ms->timer);
  748. +             break;
  749. +         }
  750. +         ms = ms->next;
  751. +     }
  752. +     /*
  753. +      * Nope, not found, create a new entry for it
  754. +      */
  755. +     if (ms==NULL) {
  756. +         ms = alloc_masq_entry();
  757. +         if (ms==NULL) {
  758. +             printk("MASQUERADE: no memory left !\n");
  759. +             return;
  760. +         }
  761. +         ms->protocol = iph->protocol;
  762. +         ms->src      = iph->saddr;
  763. +         ms->dst      = iph->daddr;
  764. +         ms->sport    = portptr[0];
  765. +         ms->dport    = portptr[1];
  766. +     }
  767. +     /*
  768. +      * Change the fragments origin
  769. +      */
  770. +     size = skb->len - ((unsigned char *)portptr - skb->h.raw);
  771. +     iph->saddr = dev->pa_addr; /* my own address */
  772. +     portptr[0] = ms->mport;
  773. +     /*
  774. +      * Adjust packet accordingly to protocol
  775. +      */
  776. +     if (iph->protocol==IPPROTO_UDP) {
  777. +         ms->timer.expires = MASQUERADE_EXPIRE_UDP;
  778. +         udp_send_check((struct udphdr *)portptr,iph->saddr,iph->daddr,size,skb->sk);
  779. +     }
  780. +     else {
  781. +         struct tcphdr *th;
  782. + #ifdef notdef
  783. +         if (portptr[1]==htons(21)) {
  784. +             skb = revamp(skb, dev, ms);
  785. +             iph = skb->h.iph;
  786. +             portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
  787. +         }
  788. + #endif
  789. +         th = (struct tcphdr *)portptr;
  790. +         /*
  791. +          * Timeout depends if FIN packet was seen
  792. +          */
  793. +         if (ms->sawfin || th->fin) {
  794. +             ms->timer.expires = MASQUERADE_EXPIRE_TCP_FIN;
  795. +             ms->sawfin = 1;
  796. +         }
  797. +         else ms->timer.expires = MASQUERADE_EXPIRE_TCP;
  798. +         tcp_send_check(th,iph->saddr,iph->daddr,size,skb->sk);
  799. +     }
  800. +     add_timer(&ms->timer);
  801. +     ip_send_check(iph);
  802. + #ifdef DEBUG_MASQ
  803. +     printk("O-routed from %lX:%X over %s\n",ntohl(dev->pa_addr),ntohs(ms->mport),dev->name);
  804. + #endif
  805. + }
  806. + /*
  807. +  *    Check if it's an masqueraded port, look it up,
  808. +  *    and send it on it's way...
  809. +  *
  810. +  *    Better not have many hosts using the designated portrange
  811. +  *    as 'normal' ports, or you'll be spending lots of time in
  812. +  *    this function.
  813. +  */
  814. + int ip_fw_demasquerade(struct sk_buff *skb)
  815. + {
  816. +     struct iphdr    *iph = skb->h.iph;
  817. +     unsigned short    *portptr;
  818. +     struct ip_masq    *ms;
  819. +     int        size;
  820. +     if (iph->protocol!=IPPROTO_UDP && iph->protocol!=IPPROTO_TCP)
  821. +         return 0;
  822. +     portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
  823. +     if (ntohs(portptr[1]) < PORT_MASQ_BEGIN ||
  824. +         ntohs(portptr[1]) > PORT_MASQ_END)
  825. +         return 0;
  826. + #ifdef DEBUG_MASQ
  827. +     printk("Incoming %s %lX:%X -> %lX:%X\n",
  828. +         strProt[iph->protocol==IPPROTO_TCP],
  829. +         ntohl(iph->saddr), ntohs(portptr[0]),
  830. +         ntohl(iph->daddr), ntohs(portptr[1]));
  831. + #endif
  832. +     /*
  833. +      * reroute to original host:port if found...
  834. +      *
  835. +      * NB. Cannot check destination address, just for the incoming port.
  836. +      * reason: archie.doc.ac.uk has 6 interfaces, you send to
  837. +      * phoenix and get a reply from any other interface(==dst)!
  838. +      */
  839. +     ms = ip_msq_hosts;
  840. +     while (ms!=NULL) {
  841. +         if (iph->protocol==ms->protocol &&
  842. + /*            iph->saddr==ms->dst && */
  843. +             portptr[0]==ms->dport &&
  844. +             portptr[1]==ms->mport)
  845. +         {
  846. +             size = skb->len - ((unsigned char *)portptr - skb->h.raw);
  847. +             iph->daddr = ms->src;
  848. +             portptr[1] = ms->sport;
  849. +             
  850. +             /*
  851. +              * Yug! adjust UDP/TCP and IP checksums
  852. +              */
  853. +             if (iph->protocol==IPPROTO_UDP)
  854. +                 udp_send_check((struct udphdr *)portptr,iph->saddr,iph->daddr,size,skb->sk);
  855. +             else
  856. +                 tcp_send_check((struct tcphdr *)portptr,iph->saddr,iph->daddr,size,skb->sk);
  857. +             ip_send_check(iph);
  858. + #ifdef DEBUG_MASQ
  859. +             printk("I-routed to %lX:%X\n",ntohl(iph->daddr),ntohs(portptr[1]));
  860. + #endif
  861. +             return 1;
  862. +         }
  863. +         ms = ms->next;
  864. +     }
  865. +     /* sorry, all this trouble for a no-hit :) */
  866. +     return 0;
  867. + }
  868. + #endif
  869.   
  870.   static void zero_fw_chain(struct ip_fw *chainptr)
  871.   {
  872. ***************
  873. *** 442,448 ****
  874.       if ( ftmp == NULL ) 
  875.       {
  876.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  877. !         printf("ip_fw_ctl:  malloc said no\n");
  878.   #endif
  879.           return( ENOMEM );
  880.       }
  881. --- 854,860 ----
  882.       if ( ftmp == NULL ) 
  883.       {
  884.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  885. !         printk("ip_fw_ctl:  malloc said no\n");
  886.   #endif
  887.           return( ENOMEM );
  888.       }
  889. ***************
  890. *** 511,518 ****
  891.                       addb4--;
  892.               }
  893.   
  894. !             if (((o_da & o_dm) == (n_da & n_dm))
  895. !                            &&((o_sa & o_sm) == (n_sa & n_sm)))
  896.               {
  897.                   if (newkind!=IP_FW_F_ALL &&
  898.                       oldkind==IP_FW_F_ALL)
  899. --- 923,930 ----
  900.                       addb4--;
  901.               }
  902.   
  903. !             if (((o_da & o_dm) == (n_da & n_dm)) &&
  904. !                 ((o_sa & o_sm) == (n_sa & n_sm)))
  905.               {
  906.                   if (newkind!=IP_FW_F_ALL &&
  907.                       oldkind==IP_FW_F_ALL)
  908. ***************
  909. *** 603,609 ****
  910.       if (chtmp_prev)
  911.           chtmp_prev->fw_next=ftmp;
  912.       else
  913. !             *chainptr=ftmp;
  914.       restore_flags(flags);
  915.       return(0);
  916.   }
  917. --- 1015,1021 ----
  918.       if (chtmp_prev)
  919.           chtmp_prev->fw_next=ftmp;
  920.       else
  921. !         *chainptr=ftmp;
  922.       restore_flags(flags);
  923.       return(0);
  924.   }
  925. ***************
  926. *** 635,647 ****
  927.       while( ftmp != NULL )
  928.       {
  929.           matches=1;
  930. !          if (ftmp->fw_src.s_addr!=frwl->fw_src.s_addr 
  931.                ||  ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr
  932.                ||  ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr
  933.                ||  ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr
  934.                ||  ftmp->fw_via.s_addr!=frwl->fw_via.s_addr
  935.                ||  ftmp->fw_flg!=frwl->fw_flg)
  936. !                 matches=0;
  937.   
  938.           tport1=ftmp->fw_nsp+ftmp->fw_ndp;
  939.           tport2=frwl->fw_nsp+frwl->fw_ndp;
  940. --- 1047,1059 ----
  941.       while( ftmp != NULL )
  942.       {
  943.           matches=1;
  944. !         if (ftmp->fw_src.s_addr!=frwl->fw_src.s_addr 
  945.                ||  ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr
  946.                ||  ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr
  947.                ||  ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr
  948.                ||  ftmp->fw_via.s_addr!=frwl->fw_via.s_addr
  949.                ||  ftmp->fw_flg!=frwl->fw_flg)
  950. !             matches=0;
  951.   
  952.           tport1=ftmp->fw_nsp+ftmp->fw_ndp;
  953.           tport2=frwl->fw_nsp+frwl->fw_ndp;
  954. ***************
  955. *** 650,657 ****
  956.           else if (tport1!=0)
  957.           {
  958.               for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
  959. !                 if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum])
  960. !                     matches=0;
  961.           }
  962.           if(matches)
  963.           {
  964. --- 1062,1069 ----
  965.           else if (tport1!=0)
  966.           {
  967.               for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
  968. !             if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum])
  969. !                 matches=0;
  970.           }
  971.           if(matches)
  972.           {
  973. ***************
  974. *** 661,671 ****
  975.                   ltmp->fw_next=ftmp->fw_next;
  976.                   kfree_s(ftmp,sizeof(*ftmp));
  977.                   ftmp=ltmp->fw_next;
  978. !                 }
  979. !                   else
  980. !                   {
  981. !                       *chainptr=ftmp->fw_next; 
  982. !                  kfree_s(ftmp,sizeof(*ftmp));
  983.                   ftmp=*chainptr;
  984.               }       
  985.           }
  986. --- 1073,1083 ----
  987.                   ltmp->fw_next=ftmp->fw_next;
  988.                   kfree_s(ftmp,sizeof(*ftmp));
  989.                   ftmp=ltmp->fw_next;
  990. !             }
  991. !             else
  992. !             {
  993. !                 *chainptr=ftmp->fw_next; 
  994. !                 kfree_s(ftmp,sizeof(*ftmp));
  995.                   ftmp=*chainptr;
  996.               }       
  997.           }
  998. ***************
  999. *** 708,714 ****
  1000.       if ( (frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2 ) 
  1001.       {
  1002.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1003. !         printk("ip_fw_ctl: src range set but n_src_p=%d\n",
  1004.               frwl->fw_nsp);
  1005.   #endif
  1006.           return(NULL);
  1007. --- 1120,1126 ----
  1008.       if ( (frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2 ) 
  1009.       {
  1010.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1011. !         printk("ip_fw_ctl: src range set but fw_nsp=%d\n",
  1012.               frwl->fw_nsp);
  1013.   #endif
  1014.           return(NULL);
  1015. ***************
  1016. *** 717,723 ****
  1017.       if ( (frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2 ) 
  1018.       {
  1019.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1020. !         printk("ip_fw_ctl: dst range set but n_dst_p=%d\n",
  1021.               frwl->fw_ndp);
  1022.   #endif
  1023.           return(NULL);
  1024. --- 1129,1135 ----
  1025.       if ( (frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2 ) 
  1026.       {
  1027.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1028. !         printk("ip_fw_ctl: dst range set but fw_ndp=%d\n",
  1029.               frwl->fw_ndp);
  1030.   #endif
  1031.           return(NULL);
  1032. ***************
  1033. *** 740,751 ****
  1034.   
  1035.   #ifdef CONFIG_IP_ACCT
  1036.   
  1037. - void ip_acct_cnt(struct iphdr *iph, struct device *dev, struct ip_fw *f)
  1038. - {
  1039. -     (void) ip_fw_chk(iph, dev, f, 0, 1);
  1040. -     return;
  1041. - }
  1042.   int ip_acct_ctl(int stage, void *m, int len)
  1043.   {
  1044.       if ( stage == IP_ACCT_FLUSH )
  1045. --- 1152,1157 ----
  1046. ***************
  1047. *** 775,790 ****
  1048.                   return( del_from_chain(&ip_acct_chain,frwl));
  1049.               default:
  1050.                   /*
  1051. !                   *    Should be panic but... (Why ??? - AC)
  1052.                    */
  1053.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1054. !                 printf("ip_acct_ctl:  unknown request %d\n",stage);
  1055.   #endif
  1056.                   return(EINVAL);
  1057.           }
  1058.       }
  1059.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1060. !     printf("ip_acct_ctl:  unknown request %d\n",stage);
  1061.   #endif
  1062.       return(EINVAL);
  1063.   }
  1064. --- 1181,1196 ----
  1065.                   return( del_from_chain(&ip_acct_chain,frwl));
  1066.               default:
  1067.                   /*
  1068. !                  *    Should be panic but... (Why ??? - AC)
  1069.                    */
  1070.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1071. !                 printk("ip_acct_ctl:  unknown request %d\n",stage);
  1072.   #endif
  1073.                   return(EINVAL);
  1074.           }
  1075.       }
  1076.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1077. !     printk("ip_acct_ctl:  unknown request %d\n",stage);
  1078.   #endif
  1079.       return(EINVAL);
  1080.   }
  1081. ***************
  1082. *** 839,845 ****
  1083.           if ( len < sizeof(struct ip_fwpkt) )
  1084.           {
  1085.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1086. !             printf("ip_fw_ctl: length=%d, expected %d\n",
  1087.                   len, sizeof(struct ip_fwpkt));
  1088.   #endif
  1089.               return( EINVAL );
  1090. --- 1245,1251 ----
  1091.           if ( len < sizeof(struct ip_fwpkt) )
  1092.           {
  1093.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1094. !             printk("ip_fw_ctl: length=%d, expected %d\n",
  1095.                   len, sizeof(struct ip_fwpkt));
  1096.   #endif
  1097.               return( EINVAL );
  1098. ***************
  1099. *** 851,857 ****
  1100.           if ( ip->ihl != sizeof(struct iphdr) / sizeof(int))
  1101.           {
  1102.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1103. !             printf("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
  1104.                       sizeof(struct ip)/sizeof(int));
  1105.   #endif
  1106.               return(EINVAL);
  1107. --- 1257,1263 ----
  1108.           if ( ip->ihl != sizeof(struct iphdr) / sizeof(int))
  1109.           {
  1110.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1111. !             printk("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
  1112.                       sizeof(struct ip)/sizeof(int));
  1113.   #endif
  1114.               return(EINVAL);
  1115. ***************
  1116. *** 908,914 ****
  1117.       } 
  1118.   
  1119.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1120. !     printf("ip_fw_ctl:  unknown request %d\n",stage);
  1121.   #endif
  1122.       return(EINVAL);
  1123.   }
  1124. --- 1314,1320 ----
  1125.       } 
  1126.   
  1127.   #ifdef DEBUG_CONFIG_IP_FIREWALL
  1128. !     printk("ip_fw_ctl:  unknown request %d\n",stage);
  1129.   #endif
  1130.       return(EINVAL);
  1131.   }
  1132. ***************
  1133. *** 1013,1016 ****
  1134. --- 1419,1467 ----
  1135.       return ip_chain_procinfo(IP_INFO_FWD, buffer,start,offset,length,reset);
  1136.   }
  1137.   
  1138. + #endif
  1139. + #ifdef CONFIG_IP_MASQUERADE
  1140. + int ip_msqhst_procinfo(char *buffer, char **start, off_t offset, int length)
  1141. + {
  1142. +     off_t pos=0, begin=0;
  1143. +     struct ip_masq *ms;
  1144. +     unsigned long flags;
  1145. +     int len=0;
  1146. +     len=sprintf(buffer,"Prc FromIP   FPrt ToIP     TPrt Masq Init-seq Delta Expires\n"); 
  1147. +     save_flags(flags);
  1148. +     cli();
  1149. +     ms=ip_msq_hosts;
  1150. +     while (ms!=NULL) {
  1151. +         int timer_active = del_timer(&ms->timer);
  1152. +         if (!timer_active)
  1153. +             ms->timer.expires = 0;
  1154. +         len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08lX %5d %lu\n",
  1155. +             strProt[ms->protocol==IPPROTO_TCP],
  1156. +             ntohl(ms->src),ntohs(ms->sport),
  1157. +             ntohl(ms->dst),ntohs(ms->dport),
  1158. +             ntohs(ms->mport),
  1159. +             ms->init_seq,ms->delta,ms->timer.expires);
  1160. +         if (timer_active)
  1161. +             add_timer(&ms->timer);
  1162. +         pos=begin+len;
  1163. +         if(pos<offset) {
  1164. +             len=0;
  1165. +             begin=pos;
  1166. +         }
  1167. +         if(pos>offset+length)
  1168. +             break;
  1169. +         ms=ms->next;
  1170. +     }
  1171. +     restore_flags(flags);
  1172. +     *start=buffer+(offset-begin);
  1173. +     len-=(offset-begin);
  1174. +     if(len>length)
  1175. +         len=length;
  1176. +     return len;
  1177. + }
  1178.   #endif
  1179. diff -rc linux/net/inet/udp.c linux+masq/net/inet/udp.c
  1180. *** linux/net/inet/udp.c    Thu Jan 26 06:25:54 1995
  1181. --- linux+masq/net/inet/udp.c    Thu Mar  9 10:00:27 1995
  1182. ***************
  1183. *** 230,236 ****
  1184.    *    doing or get burned...
  1185.    */
  1186.   
  1187. ! static void udp_send_check(struct udphdr *uh, unsigned long saddr, 
  1188.              unsigned long daddr, int len, struct sock *sk)
  1189.   {
  1190.       uh->check = 0;
  1191. --- 230,236 ----
  1192.    *    doing or get burned...
  1193.    */
  1194.   
  1195. ! void udp_send_check(struct udphdr *uh, unsigned long saddr, 
  1196.              unsigned long daddr, int len, struct sock *sk)
  1197.   {
  1198.       uh->check = 0;
  1199. diff -rc linux/net/inet/udp.h linux+masq/net/inet/udp.h
  1200. *** linux/net/inet/udp.h    Wed Dec  1 13:44:15 1993
  1201. --- linux+masq/net/inet/udp.h    Thu Mar  9 10:00:27 1995
  1202. ***************
  1203. *** 33,38 ****
  1204. --- 33,40 ----
  1205.   
  1206.   extern void    udp_err(int err, unsigned char *header, unsigned long daddr,
  1207.               unsigned long saddr, struct inet_protocol *protocol);
  1208. + extern void    udp_send_check(struct udphdr *uh, unsigned long saddr, 
  1209. +             unsigned long daddr, int len, struct sock *sk);
  1210.   extern int    udp_recvfrom(struct sock *sk, unsigned char *to,
  1211.                    int len, int noblock, unsigned flags,
  1212.                    struct sockaddr_in *sin, int *addr_len);
  1213.  
  1214.  
  1215.