/* * IP_MASQ_H323, H.323 masquerading module * * * Version: 1.0 beta, Feb 25 2000 * * Author: Rajkumar. S * Archana V. S. * Sheenarani I. * * ____Modified on 28 Mar 2000 by CoRiTeL (www.coritel.it)___ * Luca Veltri (veltri@coritel.it) * Stefano Giacometti * * to work on kernel 2.2.12 and NetMeeting 3.01 * * official site: http://www.coritel.it/projects/sofia/nat.html * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * */ #include #include #include #include #include #include #include #include #include #include #ifndef DEBUG_CONFIG_IP_MASQ_H323 #define DEBUG_CONFIG_IP_MASQ_H323 1 #endif /* * port_h323 is set to the default h.323 port (1720) */ int port_h323 = 1720; struct ip_masq_app *masq_incarnation; /*@@@@@ private comments (CoRiTeL)... some notes: 1) every h.323 session regists a new 'h245 application' to handle with a new h.245 session, this 'h245 appl.' is always registered with the same ip_masq_h245 structure (see point (1)); for this reason only one h245 session can be handled in the same time; 2) for this reason, when a new h245 session is needed, the old one is deregistrated and the 'attach' value is set to zero; */ int h245registered=0; /********** Start of H.245 masq app functions ******************/ static int masq_h245_init_1 (struct ip_masq_app *mapp, struct ip_masq *ms) { MOD_INC_USE_COUNT; printk("masq_h245_init_1: IP masq app 245 init\n"); return 0; } static int masq_h245_done_1 (struct ip_masq_app *mapp, struct ip_masq *ms) { MOD_DEC_USE_COUNT; printk("masq_h245_done_1: IP masq app 245 done\n"); return 0; } int masq_h245_in (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr) { // printk("masq_h245_in\n"); return 0; } int masq_h245_out (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr) { //@@@@@ (CoRiTeL): private comments // 'mapp' punta all'info sul protocollo da mascherare (in pratica h245) // 'ms' punta la tabella di masheramento // 'sk_buff' punta una struttura che contiene anche il pacchetto IP completo // 'maddr' e' una copia del masq IP address (mi sembra nelle prove identico a 'ms->maddr') struct sk_buff *skb; struct iphdr *iph; struct tcphdr *th; unsigned char *data, *data_limit; unsigned char *skbuff_p; __u16 port, *rtp_port; __u32 ip,temp_ip, *rtp_ip; struct ip_masq * n_ms_rtp; unsigned char p1,p2; skb = *skb_p; iph = skb->h.ipiph; //'skbuff_p' points the IP header of the packet to be processed th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]); data = skb->data; data_limit = skb->tail; skbuff_p = data+12; printk("masq_h245_out: tcp/ip_packet: h245_data: "); data+=iph->ihl*4+th->doff*4; while(datadata; //@@@@@ CoRiTeL: start of IP pkt data+=iph->ihl*4+th->doff*4; //@@@@@ CoRiTeL: jumps headres ip=ntohl(ms->saddr); //@@@@@ CoRiTeL: to find=source IP address while((data+5)n_attach (before 'ip_masq_new') = %d\n",mapp->n_attach); n_ms_rtp = ip_masq_new( IPPROTO_UDP, maddr,0, //@@@@@ CoRiTeL: masq addr htonl(ip), htons(port), //@@@@@ CoRiTeL: pck source iph->daddr, 0, //@@@@@ CoRiTeL: pck dest IP_MASQ_F_NO_DPORT); if(n_ms_rtp==NULL) printk("masq_h245_out: RTCP/RTP masq entry not made\n"); else { rtp_ip=data; rtp_port=data+4; *rtp_ip=n_ms_rtp->maddr; //@@@@@ CoRiTeL: change IP *rtp_port=n_ms_rtp->mport; //@@@@@ CoRiTeL: change port printk("masq_h245_out: RTCP/RTP masquerated: maddr=%08x , mport=%u\n", n_ms_rtp->maddr,n_ms_rtp->mport); //printk("masq_h245_out: mapp->n_attach (after 'ip_masq_new') = %d\n",mapp->n_attach); } } data++; } return 0; } /***********End of H.245 app functions *******************/ struct ip_masq_app ip_masq_h245_template = { NULL, /* next */ "h245", /* name */ 0, /* type */ 0, /* n_attach */ masq_h245_init_1, /* ip_masq_init_1 */ masq_h245_done_1, /* ip_masq_done_1 */ masq_h245_out, /* pkt_out */ masq_h245_in, /* pkt_in */ }; struct ip_masq_app * ip_masq_h245; static int masq_h323_init_1 (struct ip_masq_app *mapp, struct ip_masq *ms) { printk("masq_h323_init_1\n"); MOD_INC_USE_COUNT; if (h245registered) { //printk("masq_h323_init_1: found an old ip_masq_app entry for h245, I'm trying to delete it....\n"); //@@@@@ CoRiTeL: set n_attach to zero to unregister the old h245 app ip_masq_h245->n_attach=0; printk("masq_h323_init_1: found an old h245 app; n_attach forced to 0\n"); if(unregister_ip_masq_app(ip_masq_h245)) { //kfree(ip_masq_h245); //@@@@@ CoRiTeL: otherwise it frees mem not to be malloced before being reused printk("masq_h323_init_1: error unregistering the old h245 app!\n"); } else printk("masq_h323_init_1: the old h245 app is successfully unregistered.\n"); h245registered=0; } return 0; } static int masq_h323_done_1 (struct ip_masq_app *mapp, struct ip_masq *ms) { printk("masq_h323_done_1\n"); printk("masq_h323: h245 status (0=unregistered, 1=registered) = %d\n",h245registered); //@@@@@ CoRiTeL: debug MOD_DEC_USE_COUNT; return 0; } int masq_h323_out (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr) { // printk("masq_h323_out: does do nothing!!!\n"); return 0; } int masq_h323_in (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr) { struct sk_buff *skb; struct iphdr *iph; struct tcphdr *th; unsigned char *data, *data_limit; __u32 ip; __u16 port; __u32 temp_ip; unsigned char * skbuff_p; unsigned char p1,p2; int j; skb = *skb_p; iph = skb->h.ipiph; th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]); data = skb->data; data_limit = skb->tail; skbuff_p = data+12; ip= (((*skbuff_p) << 24) + (*(skbuff_p+1)<< 16) + (*(skbuff_p+2) << 8) + (*(skbuff_p+3))); skbuff_p=skbuff_p+4; temp_ip= (((*skbuff_p) << 24) + (*(skbuff_p+1)<< 16) + (*(skbuff_p+2) << 8) + (*(skbuff_p+3))); while(((skbuff_p+6)< data_limit) && (temp_ip !=ip)){ skbuff_p++; temp_ip= (((*skbuff_p) << 24) + (*(skbuff_p+1)<< 16) + (*(skbuff_p+2) << 8) + (*(skbuff_p+3))); } if(temp_ip==ip){ p1=*(skbuff_p+4); p2=*(skbuff_p+5); port=(p1<<8)+p2; if (h245registered==1) { printk("masq_h323_in: ATTENTION!!! found a previous ip_masq_app entry, deleting....\n"); unregister_ip_masq_app(ip_masq_h245); h245registered=0; } printk("masq_h323_in: H.245 Port is at: %u\n",port); if (!(j = register_ip_masq_app(ip_masq_h245, IPPROTO_TCP, port))) { h245registered = 1; } else printk("masq_h323_in: ATTENTION: H245 messages will not be captured!!!\n"); } return 0; } struct ip_masq_app ip_masq_h323 = { NULL, /* next */ "h323", /* name */ 0, /* type */ 0, /* n_attach */ // masq_h323_init_1, /* ip_masq_init_1 */ masq_h323_done_1, /* ip_masq_done_1 */ masq_h323_out, /* pkt_out */ masq_h323_in, /* pkt_in */ }; /* * ip_masq_h323 initialization */ int ip_masq_h323_init(void) { int j; // printk("ip_masq_h323_init\n"); ip_masq_h245 = NULL; if ((masq_incarnation = kmalloc(sizeof(struct ip_masq_app), GFP_KERNEL)) == NULL) return -ENOMEM; memcpy(masq_incarnation, &ip_masq_h323, sizeof(struct ip_masq_app)); if ((ip_masq_h245 = kmalloc(sizeof(struct ip_masq_app),GFP_KERNEL)) == NULL) return -ENOMEM; memcpy(ip_masq_h245, &ip_masq_h245_template, sizeof(struct ip_masq_app)); if ((j = register_ip_masq_app(masq_incarnation, IPPROTO_TCP, port_h323))) return j; #if DEBUG_CONF_IG_IP_MASQ_H323 printk("ip_masq_h323_init: H323: loaded support on port = %d\n", port_h323); #endif return 0; } /* * ip_masq_h323 fin. */ int ip_masq_h323_done(void) { int k; k=0; printk("ip_masq_h323_done\n"); if (masq_incarnation) { if ((k = unregister_ip_masq_app(masq_incarnation))) { } else { kfree(masq_incarnation); masq_incarnation = NULL; #if DEBUG_CONFIG_IP_MASQ_H323 printk("ip_masq_h323_done: H323: unloaded support on port = %d\n", port_h323); #endif } } if (h245registered) { printk("ip_masq_h323_done: removing the masq app entry\n"); if(unregister_ip_masq_app(ip_masq_h245)) kfree(ip_masq_h245); h245registered=0; } return k; } #ifdef MODULE int init_module(void) { printk("Init module\n"); if (ip_masq_h323_init() != 0) return -EIO; return 0; } void cleanup_module(void) { if (ip_masq_h323_done() != 0) printk("ip_masq_h323: can't remove module\n"); } #endif /* MODULE */