root/net/ipv4/ip_masq_ftp.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. masq_ftp_init_1
  2. masq_ftp_done_1
  3. masq_ftp_out
  4. ip_masq_ftp_init
  5. ip_masq_ftp_done
  6. init_module
  7. cleanup_module

   1 /*
   2  *              IP_MASQ_FTP ftp masquerading module
   3  *
   4  *
   5  * Version:     @(#)ip_masq_ftp.c 0.01   02/05/96
   6  *
   7  * Author:      Wouter Gadeyne
   8  *              
   9  *
  10  * Fixes:
  11  *      Wouter Gadeyne          :       Fixed masquerading support of ftp PORT commands
  12  *      Juan Jose Ciarlante     :       Code moved and adapted from ip_fw.c
  13  *      
  14  *
  15  *
  16  *      This program is free software; you can redistribute it and/or
  17  *      modify it under the terms of the GNU General Public License
  18  *      as published by the Free Software Foundation; either version
  19  *      2 of the License, or (at your option) any later version.
  20  *      
  21  */
  22 
  23 #include <linux/module.h>
  24 #include <asm/system.h>
  25 #include <linux/types.h>
  26 #include <linux/kernel.h>
  27 #include <linux/skbuff.h>
  28 #include <linux/in.h>
  29 #include <linux/ip.h>
  30 #include <net/protocol.h>
  31 #include <net/tcp.h>
  32 #include <net/ip_masq.h>
  33 
  34 #define DEBUG_CONFIG_IP_MASQ_FTP 0
  35 
  36 static int
  37 masq_ftp_init_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
     /* [previous][next][first][last][top][bottom][index][help] */
  38 {
  39         MOD_INC_USE_COUNT;
  40         return 0;
  41 }
  42 
  43 static int
  44 masq_ftp_done_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
     /* [previous][next][first][last][top][bottom][index][help] */
  45 {
  46         MOD_DEC_USE_COUNT;
  47         return 0;
  48 }
  49 
  50 int
  51 masq_ftp_out (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  52 {
  53         struct sk_buff *skb;
  54         struct iphdr *iph;
  55         struct tcphdr *th;
  56         char *p, *data, *data_limit;
  57         unsigned char p1,p2,p3,p4,p5,p6;
  58         __u32 from;
  59         __u16 port;
  60         struct ip_masq *n_ms;
  61         char buf[24];           /* xxx.xxx.xxx.xxx,ppp,ppp\000 */
  62         unsigned buf_len;
  63         int diff;
  64 
  65         skb = *skb_p;
  66         iph = skb->h.iph;
  67         th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
  68         data = (char *)&th[1];
  69         
  70         data_limit = skb->h.raw + skb->len - 18;
  71 
  72         while (data < data_limit)
  73         {
  74                 if (memcmp(data,"PORT ",5) && memcmp(data,"port ",5)) 
  75                 {
  76                         data ++;
  77                         continue;
  78                 }
  79                 p = data+5;
  80                 p1 = simple_strtoul(data+5,&data,10);
  81                 if (*data!=',')
  82                         continue;
  83                 p2 = simple_strtoul(data+1,&data,10);
  84                 if (*data!=',')
  85                         continue;
  86                 p3 = simple_strtoul(data+1,&data,10);
  87                 if (*data!=',')
  88                         continue;
  89                 p4 = simple_strtoul(data+1,&data,10);
  90                 if (*data!=',')
  91                         continue;
  92                 p5 = simple_strtoul(data+1,&data,10);
  93                 if (*data!=',')
  94                         continue;
  95                 p6 = simple_strtoul(data+1,&data,10);
  96                 if (*data!='\r' && *data!='\n')
  97                         continue;
  98 
  99                 from = (p1<<24) | (p2<<16) | (p3<<8) | p4;
 100                 port = (p5<<8) | p6;
 101 #if DEBUG_CONFIG_IP_MASQ_FTP
 102                 printk("PORT %lX:%X detected\n",from,port);
 103 #endif  
 104                 /*
 105                  * Now create an masquerade entry for it
 106                  */
 107                 n_ms = ip_masq_new(dev, IPPROTO_TCP,
 108                                    htonl(from), htons(port),
 109                                    iph->daddr, 0,
 110                                    IP_MASQ_F_NO_DPORT);
 111                                    
 112                 if (n_ms==NULL)
 113                         return 0;
 114 
 115                 ip_masq_set_expire(n_ms, ip_masq_expire->tcp_fin_timeout);
 116                 
 117                 /*
 118                  * Replace the old PORT with the new one
 119                  */
 120                 from = ntohl(n_ms->maddr);
 121                 port = ntohs(n_ms->mport);
 122                 sprintf(buf,"%d,%d,%d,%d,%d,%d",
 123                         from>>24&255,from>>16&255,from>>8&255,from&255,
 124                         port>>8&255,port&255);
 125                 buf_len = strlen(buf);
 126  
 127                 /*
 128                  * Calculate required delta-offset to keep TCP happy
 129                  */
 130                 
 131                 diff = buf_len - (data-p);
 132                 
 133                 /*
 134                  *      No shift.
 135                  */
 136                  
 137                 if (diff==0) 
 138                 {
 139                         /*
 140                          * simple case, just replace the old PORT cmd
 141                          */
 142                         memcpy(p,buf,buf_len);
 143                         return 0;
 144                 }
 145 
 146                 *skb_p = ip_masq_skb_replace(skb, GFP_ATOMIC, p, data-p, buf, buf_len);
 147                 return diff;
 148 
 149         }
 150         return 0;
 151 
 152 }
 153 
 154 struct ip_masq_app ip_masq_ftp = {
 155         NULL,                   /* next */
 156         0,                      /* type */
 157         0,                      /* n_attach */
 158         masq_ftp_init_1,        /* ip_masq_init_1 */
 159         masq_ftp_done_1,        /* ip_masq_done_1 */
 160         masq_ftp_out,           /* pkt_out */
 161         NULL                    /* pkt_in */
 162 };
 163 
 164 /*
 165  *      ip_masq_ftp initialization
 166  */
 167 
 168 int ip_masq_ftp_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 169 {
 170         return register_ip_masq_app(&ip_masq_ftp, IPPROTO_TCP, 21);
 171 }
 172 
 173 /*
 174  *      ip_masq_ftp fin.
 175  */
 176 
 177 int ip_masq_ftp_done(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 178 {
 179         return unregister_ip_masq_app(&ip_masq_ftp);
 180 }
 181 
 182 #ifdef MODULE
 183 
 184 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 185 {
 186         if (ip_masq_ftp_init() != 0)
 187                 return -EIO;
 188         register_symtab(0);
 189         return 0;
 190 }
 191 
 192 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 193 {
 194         if (ip_masq_ftp_done() != 0)
 195                 printk("ip_masq_ftp: can't remove module");
 196 }
 197 
 198 #endif /* MODULE */

/* [previous][next][first][last][top][bottom][index][help] */