* [H.323 Helper 5/5]: Add support for Call Forwarding
@ 2006-06-09 4:28 Jing Min Zhao
2006-06-09 13:22 ` Jing Min Zhao
2006-06-17 15:20 ` Patrick McHardy
0 siblings, 2 replies; 3+ messages in thread
From: Jing Min Zhao @ 2006-06-09 4:28 UTC (permalink / raw)
To: Netfilter Development Mailinglist; +Cc: Patrick McHardy
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="GB18030", Size: 102 bytes --]
Add support for Call Forwarding.
Signed-off-by: Jing Min Zhao <zhaojingmin@users.sourceforge.net>
[-- Attachment #2: patch5-call-forwarding --]
[-- Type: application/octet-stream, Size: 16867 bytes --]
diff -pruN linux-2.6.17.orig/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.17/include/linux/netfilter_ipv4/ip_conntrack.h
--- linux-2.6.17.orig/include/linux/netfilter_ipv4/ip_conntrack.h 2006-06-08 14:19:47.000000000 -0400
+++ linux-2.6.17/include/linux/netfilter_ipv4/ip_conntrack.h 2006-06-08 21:10:38.000000000 -0400
@@ -154,6 +154,7 @@ struct ip_conntrack_expect
unsigned int flags;
#ifdef CONFIG_IP_NF_NAT_NEEDED
+ u_int32_t saved_ip;
/* This is the original per-proto part, used to map the
* expected connection the way the recipient expects. */
union ip_conntrack_manip_proto saved_proto;
diff -pruN linux-2.6.17.orig/include/linux/netfilter_ipv4/ip_conntrack_h323.h linux-2.6.17/include/linux/netfilter_ipv4/ip_conntrack_h323.h
--- linux-2.6.17.orig/include/linux/netfilter_ipv4/ip_conntrack_h323.h 2006-06-08 14:19:47.000000000 -0400
+++ linux-2.6.17/include/linux/netfilter_ipv4/ip_conntrack_h323.h 2006-06-08 21:11:31.000000000 -0400
@@ -29,6 +29,7 @@ struct ip_ct_h323_master {
struct ip_conntrack_expect;
+extern int have_direct_route(u_int32_t src, u_int32_t dst);
extern int get_h225_addr(unsigned char *data, TransportAddress * addr,
u_int32_t * ip, u_int16_t * port);
extern void ip_conntrack_h245_expect(struct ip_conntrack *new,
@@ -71,6 +72,13 @@ extern int (*nat_h245_hook) (struct sk_b
unsigned char **data, int dataoff,
TransportAddress * addr, u_int16_t port,
struct ip_conntrack_expect * exp);
+extern int (*nat_callforwarding_hook) (struct sk_buff ** pskb,
+ struct ip_conntrack * ct,
+ enum ip_conntrack_info ctinfo,
+ unsigned char **data, int dataoff,
+ TransportAddress * addr,
+ u_int16_t port,
+ struct ip_conntrack_expect * exp);
extern int (*nat_q931_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, TransportAddress * addr,
diff -pruN linux-2.6.17.orig/include/linux/netfilter_ipv4/ip_conntrack_helper_h323_types.h linux-2.6.17/include/linux/netfilter_ipv4/ip_conntrack_helper_h323_types.h
--- linux-2.6.17.orig/include/linux/netfilter_ipv4/ip_conntrack_helper_h323_types.h 2006-06-08 20:59:43.000000000 -0400
+++ linux-2.6.17/include/linux/netfilter_ipv4/ip_conntrack_helper_h323_types.h 2006-06-08 21:12:14.000000000 -0400
@@ -412,6 +412,7 @@ typedef struct Facility_UUIE { /* SEQUEN
eFacility_UUIE_destinationInfo = (1 << 14),
eFacility_UUIE_h245SecurityMode = (1 << 13),
} options;
+ TransportAddress alternativeAddress;
FacilityReason reason;
TransportAddress h245Address;
Facility_UUIE_fastStart fastStart;
diff -pruN linux-2.6.17.orig/net/ipv4/netfilter/ip_conntrack_helper_h323.c linux-2.6.17/net/ipv4/netfilter/ip_conntrack_helper_h323.c
--- linux-2.6.17.orig/net/ipv4/netfilter/ip_conntrack_helper_h323.c 2006-06-08 21:08:53.000000000 -0400
+++ linux-2.6.17/net/ipv4/netfilter/ip_conntrack_helper_h323.c 2006-06-08 21:20:13.000000000 -0400
@@ -22,6 +22,8 @@
#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
#include <linux/moduleparam.h>
+#include <linux/ctype.h>
+#include <linux/inet.h>
#if 0
#define DEBUGP printk
@@ -38,6 +40,13 @@ static int gkrouted_only = 1;
module_param(gkrouted_only, int, 0600);
MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper");
+static char *internal_net = NULL;
+static u_int32_t internal_net_addr = 0;
+static u_int32_t internal_net_mask = 0;
+module_param(internal_net, charp, 0600);
+MODULE_PARM_DESC(internal_net, "specify your internal network using format "
+ "address/mask");
+
/* Hooks for NAT */
int (*set_h245_addr_hook) (struct sk_buff ** pskb,
unsigned char **data, int dataoff,
@@ -77,6 +86,12 @@ int (*nat_h245_hook) (struct sk_buff **
unsigned char **data, int dataoff,
TransportAddress * addr, u_int16_t port,
struct ip_conntrack_expect * exp);
+int (*nat_callforwarding_hook) (struct sk_buff ** pskb,
+ struct ip_conntrack * ct,
+ enum ip_conntrack_info ctinfo,
+ unsigned char **data, int dataoff,
+ TransportAddress * addr, u_int16_t port,
+ struct ip_conntrack_expect * exp);
int (*nat_q931_hook) (struct sk_buff ** pskb,
struct ip_conntrack * ct,
enum ip_conntrack_info ctinfo,
@@ -88,6 +103,44 @@ static DEFINE_SPINLOCK(ip_h323_lock);
static char *h323_buffer;
/****************************************************************************/
+int have_direct_route(u_int32_t src, u_int32_t dst)
+{
+ struct flowi fl_src = {.fl4_dst = src };
+ struct flowi fl_dst = {.fl4_dst = dst };
+ struct rtable *rt_src, *rt_dst;
+ int ret = 0;
+
+ if (internal_net) {
+ if (((src & internal_net_mask) == internal_net_addr) ==
+ ((dst & internal_net_mask) == internal_net_addr))
+ return 1;
+ return 0;
+ }
+
+ if (ip_route_output_key(&rt_dst, &fl_dst) != 0)
+ goto out;
+
+ if (ip_route_output_key(&rt_src, &fl_src) != 0)
+ goto out1;
+
+ if (rt_dst->u.dst.dev == rt_src->u.dst.dev &&
+ rt_dst->rt_src == rt_src->rt_src) {
+ if ((rt_dst->u.dst.flags & DST_HOST) ||
+ (rt_src->u.dst.flags & DST_HOST) ||
+ (rt_dst->rt_gateway == rt_src->rt_gateway)) {
+ DEBUGP("ip_ct_h323: dst has direct route to src\n");
+ ret = 1;
+ }
+ }
+
+ dst_release(&rt_src->u.dst);
+ out1:
+ dst_release(&rt_dst->u.dst);
+ out:
+ return ret;
+}
+
+/****************************************************************************/
static int get_tpkt_data(struct sk_buff **pskb, struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int *datalen, int *dataoff)
@@ -693,6 +746,73 @@ static int expect_h245(struct sk_buff **
return ret;
}
+/* Forwarding declaration */
+void ip_conntrack_q931_expect(struct ip_conntrack *new,
+ struct ip_conntrack_expect *this);
+
+/****************************************************************************/
+static int expect_callforwarding(struct sk_buff **pskb,
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ unsigned char **data, int dataoff,
+ TransportAddress * addr)
+{
+ int dir = CTINFO2DIR(ctinfo);
+ int ret = 0;
+ u_int32_t ip;
+ u_int16_t port;
+ struct ip_conntrack_expect *exp = NULL;
+
+ /* Read alternativeAddress */
+ if (!get_h225_addr(*data, addr, &ip, &port) || port == 0)
+ return 0;
+
+ /* If the calling party has direct route to the forward-to party,
+ * we don't need to track the second call */
+ if (have_direct_route(ct->tuplehash[!dir].tuple.src.ip, ip)) {
+ DEBUGP("ip_ct_q931: Call Forwarding not tracked\n");
+ return 0;
+ }
+
+ /* Create expect for the second call leg */
+ if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
+ return -1;
+ exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
+ exp->tuple.src.u.tcp.port = 0;
+ exp->tuple.dst.ip = ip;
+ exp->tuple.dst.u.tcp.port = htons(port);
+ exp->tuple.dst.protonum = IPPROTO_TCP;
+ exp->mask.src.ip = 0xFFFFFFFF;
+ exp->mask.src.u.tcp.port = 0;
+ exp->mask.dst.ip = 0xFFFFFFFF;
+ exp->mask.dst.u.tcp.port = 0xFFFF;
+ exp->mask.dst.protonum = 0xFF;
+ exp->flags = 0;
+
+ if (ct->tuplehash[dir].tuple.src.ip !=
+ ct->tuplehash[!dir].tuple.dst.ip && nat_callforwarding_hook) {
+ /* Need NAT */
+ ret = nat_callforwarding_hook(pskb, ct, ctinfo, data, dataoff,
+ addr, port, exp);
+ } else { /* Conntrack only */
+ exp->expectfn = ip_conntrack_q931_expect;
+
+ if (ip_conntrack_expect_related(exp) == 0) {
+ DEBUGP("ip_ct_q931: expect Call Forwarding "
+ "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+ NIPQUAD(exp->tuple.src.ip),
+ ntohs(exp->tuple.src.u.tcp.port),
+ NIPQUAD(exp->tuple.dst.ip),
+ ntohs(exp->tuple.dst.u.tcp.port));
+ } else
+ ret = -1;
+ }
+
+ ip_conntrack_expect_put(exp);
+
+ return ret;
+}
+
/****************************************************************************/
static int process_setup(struct sk_buff **pskb, struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
@@ -888,6 +1008,15 @@ static int process_facility(struct sk_bu
DEBUGP("ip_ct_q931: Facility\n");
+ if (facility->reason.choice == eFacilityReason_callForwarded) {
+ if (facility->options & eFacility_UUIE_alternativeAddress)
+ return expect_callforwarding(pskb, ct, ctinfo, data,
+ dataoff,
+ &facility->
+ alternativeAddress);
+ return 0;
+ }
+
if (facility->options & eFacility_UUIE_h245Address) {
ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
&facility->h245Address);
@@ -1680,6 +1809,7 @@ static void fini(void)
static int __init init(void)
{
int ret;
+ char *p;
h323_buffer = kmalloc(65536, GFP_KERNEL);
if (!h323_buffer)
@@ -1690,6 +1820,22 @@ static int __init init(void)
return ret;
}
+ if (internal_net) {
+ if ((p = strchr(internal_net, '/')))
+ *p++ = 0;
+ if (isdigit(internal_net[0])) {
+ internal_net_addr = in_aton(internal_net);
+ if (p && isdigit(p[0]))
+ internal_net_mask = in_aton(p);
+ else
+ internal_net_mask = 0xffffffff;
+ internal_net_addr &= internal_net_mask;
+ }
+ DEBUGP("ip_ct_h323: internal_net = %u.%u.%u.%u/%u.%u.%u.%u\n",
+ NIPQUAD(internal_net_addr),
+ NIPQUAD(internal_net_mask));
+ }
+
DEBUGP("ip_ct_h323: init success\n");
return 0;
}
@@ -1698,6 +1844,7 @@ static int __init init(void)
module_init(init);
module_exit(fini);
+EXPORT_SYMBOL_GPL(have_direct_route);
EXPORT_SYMBOL_GPL(get_h225_addr);
EXPORT_SYMBOL_GPL(ip_conntrack_h245_expect);
EXPORT_SYMBOL_GPL(ip_conntrack_q931_expect);
@@ -1708,6 +1855,7 @@ EXPORT_SYMBOL_GPL(set_ras_addr_hook);
EXPORT_SYMBOL_GPL(nat_rtp_rtcp_hook);
EXPORT_SYMBOL_GPL(nat_t120_hook);
EXPORT_SYMBOL_GPL(nat_h245_hook);
+EXPORT_SYMBOL_GPL(nat_callforwarding_hook);
EXPORT_SYMBOL_GPL(nat_q931_hook);
MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>");
diff -pruN linux-2.6.17.orig/net/ipv4/netfilter/ip_conntrack_helper_h323_types.c linux-2.6.17/net/ipv4/netfilter/ip_conntrack_helper_h323_types.c
--- linux-2.6.17.orig/net/ipv4/netfilter/ip_conntrack_helper_h323_types.c 2006-06-08 20:59:43.000000000 -0400
+++ linux-2.6.17/net/ipv4/netfilter/ip_conntrack_helper_h323_types.c 2006-06-08 21:13:42.000000000 -0400
@@ -1069,8 +1069,8 @@ static field_t _Facility_UUIE_fastStart[
static field_t _Facility_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
- {FNAME("alternativeAddress") CHOICE, 3, 7, 7, SKIP | EXT | OPT, 0,
- _TransportAddress},
+ {FNAME("alternativeAddress") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
+ offsetof(Facility_UUIE, alternativeAddress), _TransportAddress},
{FNAME("alternativeAliasAddress") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
_Facility_UUIE_alternativeAliasAddress},
{FNAME("conferenceID") OCTSTR, FIXD, 16, 0, SKIP | OPT, 0, NULL},
diff -pruN linux-2.6.17.orig/net/ipv4/netfilter/ip_nat_helper_h323.c linux-2.6.17/net/ipv4/netfilter/ip_nat_helper_h323.c
--- linux-2.6.17.orig/net/ipv4/netfilter/ip_nat_helper_h323.c 2006-06-08 14:19:49.000000000 -0400
+++ linux-2.6.17/net/ipv4/netfilter/ip_nat_helper_h323.c 2006-06-08 21:25:13.000000000 -0400
@@ -30,6 +30,24 @@
#endif
/****************************************************************************/
+static u_int32_t get_source_ip(u_int32_t dst)
+{
+ struct rtable *rt;
+ struct flowi fl;
+ u_int32_t src;
+
+ memset(&fl, 0, sizeof(fl));
+ fl.fl4_dst = dst;
+ if (ip_route_output_key(&rt, &fl) != 0)
+ return 0;
+
+ src = rt->rt_src;
+
+ dst_release(&rt->u.dst);
+ return src;
+}
+
+/****************************************************************************/
static int set_addr(struct sk_buff **pskb,
unsigned char **data, int dataoff,
unsigned int addroff, u_int32_t ip, u_int16_t port)
@@ -487,6 +505,87 @@ static int nat_q931(struct sk_buff **psk
}
/****************************************************************************/
+static void ip_nat_callforwarding_expect(struct ip_conntrack *new,
+ struct ip_conntrack_expect *this)
+{
+ struct ip_nat_range range;
+ u_int32_t src_ip;
+
+ /* This must be a fresh one. */
+ BUG_ON(new->status & IPS_NAT_DONE_MASK);
+
+ /* Change src to where master sends to */
+ range.flags = IP_NAT_RANGE_MAP_IPS;
+ if (!have_direct_route(new->master->tuplehash[!this->dir].tuple.src.ip,
+ this->saved_ip) &&
+ (src_ip = get_source_ip(this->saved_ip)))
+ range.min_ip = range.max_ip = src_ip;
+ else
+ range.min_ip = range.max_ip =
+ new->tuplehash[this->dir].tuple.src.ip;
+
+ /* hook doesn't matter, but it has to do source manip */
+ ip_nat_setup_info(new, &range, NF_IP_POST_ROUTING);
+
+ /* For DST manip, map port here to where it's expected. */
+ range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
+ range.min = range.max = this->saved_proto;
+ range.min_ip = range.max_ip = this->saved_ip;
+
+ /* hook doesn't matter, but it has to do destination manip */
+ ip_nat_setup_info(new, &range, NF_IP_PRE_ROUTING);
+
+ ip_conntrack_q931_expect(new, this);
+}
+
+/****************************************************************************/
+static int nat_callforwarding(struct sk_buff **pskb, struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ unsigned char **data, int dataoff,
+ TransportAddress * addr, u_int16_t port,
+ struct ip_conntrack_expect *exp)
+{
+ int dir = CTINFO2DIR(ctinfo);
+ u_int16_t nated_port;
+
+ /* Set expectations for NAT */
+ exp->saved_ip = exp->tuple.dst.ip;
+ exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
+ exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
+ exp->expectfn = ip_nat_callforwarding_expect;
+ exp->dir = !dir;
+
+ /* Try to get same port: if not, try to change it. */
+ for (nated_port = port; nated_port != 0; nated_port++) {
+ exp->tuple.dst.u.tcp.port = htons(nated_port);
+ if (ip_conntrack_expect_related(exp) == 0)
+ break;
+ }
+
+ if (nated_port == 0) { /* No port available */
+ if (net_ratelimit())
+ printk("ip_nat_q931: out of TCP ports\n");
+ return 0;
+ }
+
+ /* Modify signal */
+ if (!set_h225_addr(pskb, data, dataoff, addr,
+ ct->tuplehash[!dir].tuple.dst.ip,
+ nated_port) == 0) {
+ ip_conntrack_unexpect_related(exp);
+ return -1;
+ }
+
+ /* Success */
+ DEBUGP("ip_nat_q931: expect Call Forwarding "
+ "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+ NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
+ NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
+
+ return 0;
+}
+
+/****************************************************************************/
static int __init init(void)
{
BUG_ON(set_h245_addr_hook != NULL);
@@ -496,6 +595,7 @@ static int __init init(void)
BUG_ON(nat_rtp_rtcp_hook != NULL);
BUG_ON(nat_t120_hook != NULL);
BUG_ON(nat_h245_hook != NULL);
+ BUG_ON(nat_callforwarding_hook != NULL);
BUG_ON(nat_q931_hook != NULL);
set_h245_addr_hook = set_h245_addr;
@@ -505,6 +605,7 @@ static int __init init(void)
nat_rtp_rtcp_hook = nat_rtp_rtcp;
nat_t120_hook = nat_t120;
nat_h245_hook = nat_h245;
+ nat_callforwarding_hook = nat_callforwarding;
nat_q931_hook = nat_q931;
DEBUGP("ip_nat_h323: init success\n");
@@ -521,6 +622,7 @@ static void __exit fini(void)
nat_rtp_rtcp_hook = NULL;
nat_t120_hook = NULL;
nat_h245_hook = NULL;
+ nat_callforwarding_hook = NULL;
nat_q931_hook = NULL;
synchronize_net();
}
diff -pruN linux-2.6.17.orig/net/ipv4/netfilter/Kconfig linux-2.6.17/net/ipv4/netfilter/Kconfig
--- linux-2.6.17.orig/net/ipv4/netfilter/Kconfig 2006-06-08 14:19:49.000000000 -0400
+++ linux-2.6.17/net/ipv4/netfilter/Kconfig 2006-06-08 21:27:13.000000000 -0400
@@ -181,10 +181,10 @@ config IP_NF_H323
With this module you can support H.323 on a connection tracking/NAT
firewall.
- This module supports RAS, Fast-start, H.245 tunnelling, RTP/RTCP
- and T.120 based data and applications including audio, video, FAX,
- chat, whiteboard, file transfer, etc. For more information, please
- see http://nath323.sourceforge.net/.
+ This module supports RAS, Fast Start, H.245 Tunnelling, Call
+ Forwarding, RTP/RTCP and T.120 based audio, video, fax, chat,
+ whiteboard, file transfer, etc. For more information, please
+ visit http://nath323.sourceforge.net/.
If you want to compile it as a module, say 'M' here and read
Documentation/modules.txt. If unsure, say 'N'.
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [H.323 Helper 5/5]: Add support for Call Forwarding
2006-06-09 4:28 [H.323 Helper 5/5]: Add support for Call Forwarding Jing Min Zhao
@ 2006-06-09 13:22 ` Jing Min Zhao
2006-06-17 15:20 ` Patrick McHardy
1 sibling, 0 replies; 3+ messages in thread
From: Jing Min Zhao @ 2006-06-09 13:22 UTC (permalink / raw)
To: Jing Min Zhao, Netfilter Development Mailinglist; +Cc: Patrick McHardy
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="GB18030", Size: 1227 bytes --]
The new function "have_direct_route" is based on Patrick's patch,
but there are some changes. This function is used to guess
whether two endpoints have direct route between them, if they do,
firewall won't track future connection between them. But when a system
is using Policy Routing and/or Multipath Routing, this function
may guess wrong. This is why we still need the parameter "internal_net".
In case we guess wrong but user still need a correct result, this is
the last resort, although its limitation is supporting only
one internal subnet.
The reason there is no parameter to turn on/off the guessing is
it make things worse. When we don't guess, this module doesn't
work at all in some scenarios. So we always guess unless user
specify "internal_net".
Thanks,
Jing Min Zhao
----- Original Message -----
From: "Jing Min Zhao" <zhaojingmin@hotmail.com>
To: "Netfilter Development Mailinglist" <netfilter-devel@lists.netfilter.org>
Cc: "Patrick McHardy" <kaber@trash.net>
Sent: Friday, June 09, 2006 12:28 AM
Subject: [H.323 Helper 5/5]: Add support for Call Forwarding
> Add support for Call Forwarding.
>
> Signed-off-by: Jing Min Zhao <zhaojingmin@users.sourceforge.net>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [H.323 Helper 5/5]: Add support for Call Forwarding
2006-06-09 4:28 [H.323 Helper 5/5]: Add support for Call Forwarding Jing Min Zhao
2006-06-09 13:22 ` Jing Min Zhao
@ 2006-06-17 15:20 ` Patrick McHardy
1 sibling, 0 replies; 3+ messages in thread
From: Patrick McHardy @ 2006-06-17 15:20 UTC (permalink / raw)
To: Jing Min Zhao; +Cc: Netfilter Development Mailinglist
Jing Min Zhao wrote:
> Add support for Call Forwarding.
>
> Signed-off-by: Jing Min Zhao <zhaojingmin@users.sourceforge.net>
That patch is already queued in Dave's net-2.6.18 tree, so I guess
these patches are against Linus' current tree. Please rebase
your patchset against the net-2.6.18 tree and resend. Thanks.
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.18.git
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2006-06-17 15:20 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-09 4:28 [H.323 Helper 5/5]: Add support for Call Forwarding Jing Min Zhao
2006-06-09 13:22 ` Jing Min Zhao
2006-06-17 15:20 ` Patrick McHardy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.