linux-old/net/ipv4/ip_masq_cuseeme.c
<<
>>
Prefs
   1/*
   2 *              IP_MASQ_FTP CUSeeMe masquerading module
   3 *
   4 *
   5 * Version:     @(#)$Id: ip_masq_cuseeme.c,v 1.4 1998/10/06 04:48:57 davem Exp $
   6 *
   7 * Author:      Richard Lynch
   8 *              
   9 *
  10 * Fixes:
  11 *      Richard Lynch           :       Updated patch to conform to new module
  12 *                                      specifications
  13 *      Nigel Metheringham      :       Multiple port support
  14 *      Michael Owings          :       Fixed broken init code
  15 *                                      Added code to update inbound
  16 *                                      packets with correct local addresses.
  17 *                                      Fixes audio and "chat" problems
  18 *                                      Thanx to the CU-SeeMe Consortium for
  19 *                                      technical docs
  20 *      Steven Clarke           :       Small changes for 2.1   
  21 *
  22 *
  23 *
  24 *      This program is free software; you can redistribute it and/or
  25 *      modify it under the terms of the GNU General Public License
  26 *      as published by the Free Software Foundation; either version
  27 *      2 of the License, or (at your option) any later version.
  28 *      
  29 * Multiple Port Support
  30 *      The helper can be made to handle up to MAX_MASQ_APP_PORTS (normally 12)
  31 *      with the port numbers being defined at module load time.  The module
  32 *      uses the symbol "ports" to define a list of monitored ports, which can
  33 *      be specified on the insmod command line as
  34 *              ports=x1,x2,x3...
  35 *      where x[n] are integer port numbers.  This option can be put into
  36 *      /etc/conf.modules (or /etc/modules.conf depending on your config)
  37 *      where modload will pick it up should you use modload to load your
  38 *      modules.
  39 *      
  40 */
  41
  42#include <linux/config.h>
  43#include <linux/module.h>
  44#include <asm/system.h>
  45#include <linux/types.h>
  46#include <linux/kernel.h>
  47#include <linux/skbuff.h>
  48#include <linux/in.h>
  49#include <linux/ip.h>
  50#include <linux/init.h>
  51#include <net/protocol.h>
  52#include <net/udp.h>
  53
  54/* #define IP_MASQ_NDEBUG */
  55#include <net/ip_masq.h>
  56
  57#pragma pack(1)
  58/* CU-SeeMe Data Header */
  59typedef struct {
  60        u_short         dest_family;
  61        u_short         dest_port;
  62        u_long          dest_addr;
  63        short           family;
  64        u_short         port;
  65        u_long          addr;
  66        u_long          seq;
  67        u_short         msg;
  68        u_short         data_type;
  69        u_short         packet_len;
  70} cu_header;
  71
  72/* Open Continue Header */
  73typedef struct  {
  74        cu_header       cu_head;
  75        u_short         client_count; /* Number of client info structs */
  76        u_long          seq_no;
  77        char            user_name[20];
  78        char            stuff[4]; /* flags,  version stuff,  etc */
  79}oc_header;
  80
  81/* client info structures */
  82typedef struct {
  83        u_long          address; /* Client address */
  84        char            stuff[8]; /* Flags, pruning bitfield,  packet counts etc */
  85} client_info;
  86#pragma pack()
  87
  88/*
  89 * List of ports (up to MAX_MASQ_APP_PORTS) to be handled by helper
  90 * First port is set to the default port.
  91 */
  92static int ports[MAX_MASQ_APP_PORTS] = {7648}; /* I rely on the trailing items being set to zero */
  93struct ip_masq_app *masq_incarnations[MAX_MASQ_APP_PORTS];
  94
  95/*
  96 *     Debug level
  97 */
  98#ifdef CONFIG_IP_MASQ_DEBUG
  99static int debug=0;
 100MODULE_PARM(debug, "i");
 101#endif
 102
 103MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_MASQ_APP_PORTS) "i");
 104
 105static int
 106masq_cuseeme_init_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
 107{
 108        MOD_INC_USE_COUNT;
 109        return 0;
 110}
 111
 112static int
 113masq_cuseeme_done_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
 114{
 115        MOD_DEC_USE_COUNT;
 116        return 0;
 117}
 118
 119int
 120masq_cuseeme_out (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr)
 121{
 122        struct sk_buff *skb = *skb_p;
 123        struct iphdr *iph = skb->nh.iph;
 124        struct udphdr *uh = (struct udphdr *)&(((char *)iph)[iph->ihl*4]);
 125        cu_header *cu_head;
 126        char *data=(char *)&uh[1];
 127
 128        if (skb->len - ((unsigned char *) data - skb->h.raw) >= sizeof(cu_header))
 129        {
 130                cu_head         = (cu_header *) data;
 131                /* cu_head->port   = ms->mport; */
 132                if( cu_head->addr )
 133                cu_head->addr = (u_long) maddr;
 134                if(ntohs(cu_head->data_type) == 257)
 135                        IP_MASQ_DEBUG(1-debug, "Sending talk packet!\n");
 136        }
 137        return 0;
 138}
 139
 140int
 141masq_cuseeme_in (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr)
 142{
 143        struct sk_buff *skb = *skb_p;
 144        struct iphdr *iph = skb->nh.iph;
 145        struct udphdr *uh = (struct udphdr *)&(((char *)iph)[iph->ihl*4]);
 146        cu_header *cu_head;
 147        oc_header       *oc;
 148        client_info     *ci;
 149        char *data=(char *)&uh[1];
 150        u_short len = skb->len - ((unsigned char *) data - skb->h.raw);
 151        int             i, off;
 152
 153        if (len >= sizeof(cu_header))
 154        {
 155                cu_head         = (cu_header *) data;
 156                if(cu_head->dest_addr) /* Correct destination address */
 157                        cu_head->dest_addr = (u_long) ms->saddr;
 158                if(ntohs(cu_head->data_type)==101 && len > sizeof(oc_header))
 159                {
 160                        oc = (oc_header * ) data;
 161                        /* Spin (grovel) thru client_info structs till we find our own */
 162                        off=sizeof(oc_header);
 163                        for(i=0;
 164                            (i < oc->client_count && off+sizeof(client_info) <= len);
 165                            i++)                    
 166                        {
 167                                ci=(client_info *)(data+off);
 168                                if(ci->address==(u_long) maddr)
 169                                {
 170                                        /* Update w/ our real ip address and exit */
 171                                        ci->address = (u_long) ms->saddr;
 172                                        break;
 173                                }
 174                                else
 175                                   off+=sizeof(client_info);
 176                        }
 177                }
 178        }
 179        return 0;
 180}
 181
 182struct ip_masq_app ip_masq_cuseeme = {
 183        NULL,                   /* next */
 184        "cuseeme",
 185        0,                      /* type */
 186        0,                      /* n_attach */
 187        masq_cuseeme_init_1,    /* ip_masq_init_1 */
 188        masq_cuseeme_done_1,    /* ip_masq_done_1 */
 189        masq_cuseeme_out,       /* pkt_out */
 190        masq_cuseeme_in         /* pkt_in */
 191};
 192
 193
 194/*
 195 *      ip_masq_cuseeme initialization
 196 */
 197
 198__initfunc(int ip_masq_cuseeme_init(void))
 199{
 200        int i, j;
 201
 202        for (i=0; (i<MAX_MASQ_APP_PORTS); i++) {
 203                if (ports[i]) {
 204                        if ((masq_incarnations[i] = kmalloc(sizeof(struct ip_masq_app),
 205                                                            GFP_KERNEL)) == NULL)
 206                                return -ENOMEM;
 207                        memcpy(masq_incarnations[i], &ip_masq_cuseeme, sizeof(struct ip_masq_app));
 208                        if ((j = register_ip_masq_app(masq_incarnations[i], 
 209                                                      IPPROTO_UDP,
 210                                                      ports[i]))) {
 211                                return j;
 212                        }
 213#if DEBUG_CONFIG_IP_MASQ_CUSEEME
 214                        IP_MASQ_DEBUG(1-debug, "CuSeeMe: loaded support on port[%d] = %d\n",
 215                               i, ports[i]);
 216#endif
 217                } else {
 218                        /* To be safe, force the incarnation table entry to NULL */
 219                        masq_incarnations[i] = NULL;
 220                }
 221        }
 222        return 0;
 223}
 224
 225/*
 226 *      ip_masq_cuseeme fin.
 227 */
 228
 229int ip_masq_cuseeme_done(void)
 230{
 231        int i, j, k;
 232
 233        k=0;
 234        for (i=0; (i<MAX_MASQ_APP_PORTS); i++) {
 235                if (masq_incarnations[i]) {
 236                        if ((j = unregister_ip_masq_app(masq_incarnations[i]))) {
 237                                k = j;
 238                        } else {
 239                                kfree(masq_incarnations[i]);
 240                                masq_incarnations[i] = NULL;
 241                                IP_MASQ_DEBUG(1-debug, "CuSeeMe: unloaded support on port[%d] = %d\n", i, ports[i]);
 242                        }
 243                }
 244        }
 245        return k;
 246}
 247
 248#ifdef MODULE
 249EXPORT_NO_SYMBOLS;
 250
 251int init_module(void)
 252{
 253        if (ip_masq_cuseeme_init() != 0)
 254                return -EIO;
 255        return 0;
 256}
 257
 258void cleanup_module(void)
 259{
 260        if (ip_masq_cuseeme_done() != 0)
 261                IP_MASQ_DEBUG(1-debug, "ip_masq_cuseeme: can't remove module");
 262}
 263
 264#endif /* MODULE */
 265
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.