Date: Mon, 1 Jan 2001 17:47:19 +0100 From: Danny Pansters <danny@ricin.com> To: Brent Kearney <brent@kearneys.ca> Cc: freebsd-questions@freebsd.org Subject: Re: hope for H323/natd Message-ID: <01010117471902.25486@ricin.localnet> In-Reply-To: <20001230211532.A49774@kearneys.ca> References: <20001230211532.A49774@kearneys.ca>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --] On Sunday 31 December 2000 06:15, you wrote: > http://www.coritel.it/projects/sofia/nat.html > > Anyone up for porting this to *BSD? Trouble is, its a linux kernel module and therefore probably not that easily "ported" to BSD. The sad thing is that I've used it (with linux) in the past and it worked great (albeit very noisy as it threw any output to the console). It's limited to one video (h245) connection at a time. You could try gatekeeper instead but I didn't get it to properly work yet :-( AFAIK it's really a crazy protocol (from an IP angle) as it wants to connect to random ports > 1024. Not easy with firewalls either. Would be great though if someone more knowledgeable than me would write a module for it, maybe as an extension to natd or ipf, because - please don't flame me - gatekeeper didn't get me anything further to correctly NAT this type of traffic and I've given up on it for the time being. I know that my partner would like to be able to do netmeeting and currently this is still somewhat of an Achilles' heel in my defending switching my boxes from linux to fBSD... I am not a programmer, but I assume that the hard part would be to think up some notion of statefulness for h323 connections including the other protocols encapsulated by h323 so that its possible to, once identified as a valid h323 two way connection, have it bypass any filtering. Maybe the linux module source can be modified to use BSD kernel calls instead because the algorithm itself seems to work, but really I don't know sh*t about how to do that. For those readers who like to give it a try, the source is rather small, has lots of commented-out code, is GPL'ed and attached below. I'll be more than happy to test it. Danny [-- Attachment #2 --] /* * 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 <linux/module.h> #include <asm/system.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/skbuff.h> #include <linux/in.h> #include <linux/ip.h> #include <net/protocol.h> #include <net/tcp.h> #include <net/ip_masq.h> #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(data<data_limit){ printk("%02x ",*data); data++; } printk("\n"); //@@@@@ CoRiTeL: analisys of h245 msg data=skb->data; //@@@@@ 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)<data_limit) { temp_ip= (((*data) << 24) + (*(data+1)<< 16) + (*(data+2) << 8) + (*(data+3))); if (temp_ip==ip) { p1=*(data+4); p2=*(data+5); port=(p1<<8)+p2; printk("masq_h245_out: <-- RTCP/RTP_dest_addr: %08x\n",ip); printk("masq_h245_out: <-- RTCP/RTP_dest_port: %04x\n",port); //printk("masq_h245_out: mapp->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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?01010117471902.25486>
