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 %X:%X detected\n",from,port);
 103 #endif  
 104                 /*
 105                  * Now update or create an masquerade entry for it
 106                  */
 107 #if DEBUG_CONFIG_IP_MASQ_FTP
 108                 printk("protocol %d %lX:%X %X:%X\n", iph->protocol, htonl(from), htons(port), iph->daddr, 0);
 109 
 110 #endif  
 111                 n_ms = ip_masq_out_get_2(iph->protocol,
 112                                          htonl(from), htons(port),
 113                                          iph->daddr, 0);
 114                 if (n_ms) {
 115                         /* existing masquerade, clear timer */
 116                         ip_masq_set_expire(n_ms,0);
 117                 }
 118                 else {
 119                         n_ms = ip_masq_new(dev, IPPROTO_TCP,
 120                                            htonl(from), htons(port),
 121                                            iph->daddr, 0,
 122                                            IP_MASQ_F_NO_DPORT);
 123                                         
 124                         if (n_ms==NULL)
 125                                 return 0;
 126                 }
 127 
 128                 /*
 129                  * keep for a bit longer than tcp_fin, caller may not reissue
 130                  * PORT before tcp_fin_timeout.
 131                  */
 132                 ip_masq_set_expire(n_ms, ip_masq_expire->tcp_fin_timeout*3);
 133 
 134                 /*
 135                  * Replace the old PORT with the new one
 136                  */
 137                 from = ntohl(n_ms->maddr);
 138                 port = ntohs(n_ms->mport);
 139                 sprintf(buf,"%d,%d,%d,%d,%d,%d",
 140                         from>>24&255,from>>16&255,from>>8&255,from&255,
 141                         port>>8&255,port&255);
 142                 buf_len = strlen(buf);
 143 #if DEBUG_CONFIG_IP_MASQ_FTP
 144                 printk("new PORT %X:%X\n",from,port);
 145 #endif  
 146 
 147                 /*
 148                  * Calculate required delta-offset to keep TCP happy
 149                  */
 150                 
 151                 diff = buf_len - (data-p);
 152                 
 153                 /*
 154                  *      No shift.
 155                  */
 156                 
 157                 if (diff==0)
 158                 {
 159                         /*
 160                          * simple case, just replace the old PORT cmd
 161                          */
 162                         memcpy(p,buf,buf_len);
 163                         return 0;
 164                 }
 165 
 166                 *skb_p = ip_masq_skb_replace(skb, GFP_ATOMIC, p, data-p, buf, buf_len);
 167                 return diff;
 168 
 169         }
 170         return 0;
 171 
 172 }
 173 
 174 struct ip_masq_app ip_masq_ftp = {
 175         NULL,                   /* next */
 176         "ftp",                  /* name */
 177         0,                      /* type */
 178         0,                      /* n_attach */
 179         masq_ftp_init_1,        /* ip_masq_init_1 */
 180         masq_ftp_done_1,        /* ip_masq_done_1 */
 181         masq_ftp_out,           /* pkt_out */
 182         NULL                    /* pkt_in */
 183 };
 184 
 185 /*
 186  *      ip_masq_ftp initialization
 187  */
 188 
 189 int ip_masq_ftp_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 190 {
 191         return register_ip_masq_app(&ip_masq_ftp, IPPROTO_TCP, 21);
 192 }
 193 
 194 /*
 195  *      ip_masq_ftp fin.
 196  */
 197 
 198 int ip_masq_ftp_done(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 199 {
 200         return unregister_ip_masq_app(&ip_masq_ftp);
 201 }
 202 
 203 #ifdef MODULE
 204 
 205 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 206 {
 207         if (ip_masq_ftp_init() != 0)
 208                 return -EIO;
 209         register_symtab(0);
 210         return 0;
 211 }
 212 
 213 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 214 {
 215         if (ip_masq_ftp_done() != 0)
 216                 printk("ip_masq_ftp: can't remove module");
 217 }
 218 
 219 #endif /* MODULE */

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