* SIP/RTP support coming?
@ 2005-02-12 11:52 Steve Davies
2005-02-12 12:08 ` Max Kellermann
0 siblings, 1 reply; 9+ messages in thread
From: Steve Davies @ 2005-02-12 11:52 UTC (permalink / raw)
To: netfilter-devel
>From the FAQ on the netfilter site, I see the comment:
"The netfilter/iptables team has currently no resources to implement
SIP conntrack/NAT support, but we're always open for sponsors :)"
I have also noticed that Linksys have implemented some basic support
for SIP/SDP/RTP conntrack/NAT. I believe that due to the complexity of
the SIP protocol, there are one or two small problems with certain
message types - mentioned in
https://lists.netfilter.org/pipermail/netfilter/2004-December/057518.html
(A patch taken from the linksys code was offered in
https://lists.netfilter.org/pipermail/netfilter-devel/2005-January/018252.html)
Are there plans to integrate this officially? Should I take time to
(try to) update the patch to the 2.6.x kernel? Am I missing something?
Thanks,
Steve
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: SIP/RTP support coming?
2005-02-12 11:52 SIP/RTP support coming? Steve Davies
@ 2005-02-12 12:08 ` Max Kellermann
2005-02-12 16:30 ` Kevin P. Fleming
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Max Kellermann @ 2005-02-12 12:08 UTC (permalink / raw)
To: netfilter-devel
On 2005/02/12 12:52, Steve Davies <davies147@gmail.com> wrote:
> Are there plans to integrate this officially? Should I take time to
> (try to) update the patch to the 2.6.x kernel? Am I missing
> something?
I believe nobody is working on that yet; I planned to look at the code
when I'm done with the H.323 module, but that will take some time.
A lot people would be thankful if you hacked the source, and ported
that to Linux 2.6.11-rc3 (the API has changed very much since 2.6.10;
don't use the old API).
You should start with providing a patch-o-matic module (see netfilter
home page) of the original code, and then send patches with your
changes.
Max
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: SIP/RTP support coming?
2005-02-12 12:08 ` Max Kellermann
@ 2005-02-12 16:30 ` Kevin P. Fleming
2005-02-12 16:55 ` Steve Davies
2005-02-12 19:56 ` Christian Hentschel
2 siblings, 0 replies; 9+ messages in thread
From: Kevin P. Fleming @ 2005-02-12 16:30 UTC (permalink / raw)
Cc: netfilter-devel
Max Kellermann wrote:
> A lot people would be thankful if you hacked the source, and ported
> that to Linux 2.6.11-rc3 (the API has changed very much since 2.6.10;
> don't use the old API).
Agreed! There are lots of us out here would be thrilled to help test a
SIP/SDP ALG for netfilter.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: SIP/RTP support coming?
2005-02-12 12:08 ` Max Kellermann
2005-02-12 16:30 ` Kevin P. Fleming
@ 2005-02-12 16:55 ` Steve Davies
2005-02-12 19:56 ` Christian Hentschel
2 siblings, 0 replies; 9+ messages in thread
From: Steve Davies @ 2005-02-12 16:55 UTC (permalink / raw)
To: netfilter-devel
On Sat, 12 Feb 2005 13:08:47 +0100, Max Kellermann <max@duempel.org> wrote:
> On 2005/02/12 12:52, Steve Davies <davies147@gmail.com> wrote:
> > Are there plans to integrate this officially? Should I take time to
> > (try to) update the patch to the 2.6.x kernel? Am I missing
> > something?
>
> I believe nobody is working on that yet; I planned to look at the code
> when I'm done with the H.323 module, but that will take some time.
>
> A lot people would be thankful if you hacked the source, and ported
> that to Linux 2.6.11-rc3 (the API has changed very much since 2.6.10;
> don't use the old API).
>
> You should start with providing a patch-o-matic module (see netfilter
> home page) of the original code, and then send patches with your
> changes.
>
Thanks for the pointers... I just started a new job, so I am HUGELY
busy, but given the potential benefit of this for me personally, I
think I'll try and make the time :)
Regards,
Steve
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: SIP/RTP support coming?
2005-02-12 12:08 ` Max Kellermann
2005-02-12 16:30 ` Kevin P. Fleming
2005-02-12 16:55 ` Steve Davies
@ 2005-02-12 19:56 ` Christian Hentschel
2005-04-15 8:44 ` Steve Davies
2 siblings, 1 reply; 9+ messages in thread
From: Christian Hentschel @ 2005-02-12 19:56 UTC (permalink / raw)
To: Max Kellermann; +Cc: netfilter-devel
[-- Attachment #1: Type: text/plain, Size: 935 bytes --]
Hi, i'm very interesting in a conntrack/nat helper for sip.
Currently i'm working on this and help with testing will be great.
i've used kernel 2.6.10 for this.
Christian.
On Sat, 2005-02-12 at 13:08 +0100, Max Kellermann wrote:
> On 2005/02/12 12:52, Steve Davies <davies147@gmail.com> wrote:
> > Are there plans to integrate this officially? Should I take time to
> > (try to) update the patch to the 2.6.x kernel? Am I missing
> > something?
>
> I believe nobody is working on that yet; I planned to look at the code
> when I'm done with the H.323 module, but that will take some time.
>
> A lot people would be thankful if you hacked the source, and ported
> that to Linux 2.6.11-rc3 (the API has changed very much since 2.6.10;
> don't use the old API).
>
> You should start with providing a patch-o-matic module (see netfilter
> home page) of the original code, and then send patches with your
> changes.
>
> Max
>
>
--
[-- Attachment #2: Makefile --]
[-- Type: text/x-makefile, Size: 200 bytes --]
obj-m := ip_conntrack_sip.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -f *.ko *.o *mod.c
[-- Attachment #3: ip_conntrack_sip.c --]
[-- Type: text/x-csrc, Size: 5632 bytes --]
/* SIP extension for IP connection tracking.
*
* (C) 2005 Christian Hentschel
* based on RR's ip_conntrack_ftp.c and other modules.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/ip.h>
#include <linux/ctype.h>
#include <net/checksum.h>
#include <net/udp.h>
#include <linux/netfilter_ipv4/lockhelp.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com>");
MODULE_DESCRIPTION("SIP connection tracking helper");
#define SIP_PORT 5060
#define RTP_TIMEOUT 180
static char sip_buffer[65536];
static DECLARE_LOCK(sipbf_lock);
struct module *ip_conntrack_sip = THIS_MODULE;
#define MAX_PORTS 8
static int ports[MAX_PORTS];
static int ports_c;
module_param_array(ports, int, &ports_c, 0400);
MODULE_PARM_DESC(ports, " port numbers of sip servers");
//#if 0
#define DEBUGP printk
//#else
//#define DEBUGP(format, args...)
//#endif
struct ip_ct_sip_expect {
u_int32_t ip_offset;
u_int32_t ip_len;
u_int32_t port_offset;
u_int32_t port_len;
u_int16_t port;
};
static int rtp_expectfn(struct ip_conntrack *new)
{
DEBUGP("ct_sip: Got RTP..\n");
return 0;
}
static int skip_atoi(const char **str)
{
unsigned int result = 0;
while (isdigit(**str))
result = result*10 + *((*str)++) - '0';
return result;
}
static int get_ep_addr(const char *dptr,
u_int32_t *ip, struct ip_ct_sip_expect *exp)
{
int i;
const char *aux = dptr;
dptr = strstr(dptr, "c=IN IP4 ");
if (!dptr) {
DEBUGP("ct_sip: 'c=' not found.\n");
return -1;
}
dptr += 9;
// exp->ip_offset = (dptr - aux);
for (i = 3; i >= 0; i--){
((unsigned char *)ip)[i] = skip_atoi(&dptr);
dptr++;
}
// exp->ip_len = (dptr - exp->ip_offset);
dptr = strstr(dptr, "m=audio ");
if (!dptr) {
DEBUGP("ct_sip: 'm=' not found.\n");
return -1;
}
dptr += 8;
// exp->port_offset = (dptr - aux);
exp->port = skip_atoi(&dptr);
// exp->port_len = (dptr - exp->port_offset);
if (exp->port < 1024)
return -1;
return 0;
}
static int sip_help(struct sk_buff *skb,
struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
{
struct ip_ct_sip_expect *exp_sip_info, exp_tmp;
struct ip_conntrack_expect *exp;
unsigned int dataoff, datalen;
char *dptr;
u_int32_t rtp_ip;
if (ctinfo >= IP_CT_IS_REPLY)
return NF_ACCEPT;
/* No Data ? */
dataoff = skb->nh.iph->ihl * 4 + sizeof(struct udphdr);
if (dataoff >= skb->len){
DEBUGP("ct_sip: skb->len = %u\n", skb->len);
return NF_ACCEPT;
}
datalen = skb->len - dataoff;
LOCK_BH(&sipbf_lock);
dptr = skb_header_pointer(skb, dataoff, datalen, sip_buffer);
BUG_ON(dptr == NULL);
DEBUGP("ct_sip: datalen %u\n", datalen);
if (memcmp(dptr, "INVITE", 6) != 0 && memcmp(dptr, "SIP/2.0 200", 11) != 0) {
DEBUGP("ct_sip: Not interesting pkt.\n");
goto out;
}
*(dptr + datalen) = '\0';
if (get_ep_addr(dptr, &rtp_ip, &exp_tmp) < 0)
goto out;
DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
exp = ip_conntrack_expect_alloc();
if (exp == NULL)
goto out;
/* exp_sip_info = &exp->help.exp_sip_info;
exp_sip_info->port_offset = exp_tmp->port_offset;
exp_sip_info->ip_offset = exp_tmp->ip_offset;
exp_sip_info->port_len = exp_tmp->port_len;
exp_sip_info->ip_len = exp_tmp->ip_len;
exp_sip_info->port = exp_tmp->port;
*/
exp->tuple = ((struct ip_conntrack_tuple)
{ { ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip, { 0 } },
{ htonl(rtp_ip), { .udp = { htons(exp_tmp.port) } },
IPPROTO_UDP }});
exp->mask = ((struct ip_conntrack_tuple)
{ { 0xFFFFFFFF, { 0 } },
{ 0xFFFFFFFF, { .udp = { 0xFFFF } }, 0xFFFF }});
exp->expectfn = rtp_expectfn; //NULL;
DUMP_TUPLE(&exp->tuple);
DUMP_TUPLE(&exp->mask);
ip_conntrack_expect_related(exp, ct);
out:
UNLOCK_BH(&sipbf_lock);
return NF_ACCEPT;
}
static struct ip_conntrack_helper sip[MAX_PORTS];
static char sip_names[MAX_PORTS][10];
static void fini(void)
{
int i=0;
for (; i < ports_c; i++) {
DEBUGP("ip_ct_sip: unregistering helper for port %d\n", ports[i]);
ip_conntrack_helper_unregister(&sip[i]);
}
}
static int __init init(void)
{
int i, ret;
char *tmpname;
if (ports_c == 0)
ports[ports_c++] = SIP_PORT;
for (i=0; i < ports_c; i++) {
sip[i].tuple.src.u.udp.port = htons(ports[i]);
sip[i].tuple.dst.protonum = IPPROTO_UDP;
sip[i].mask.src.u.udp.port = 0xFFFF;
sip[i].mask.dst.protonum = 0xFFFF;
sip[i].max_expected = 1;
sip[i].timeout = RTP_TIMEOUT;
sip[i].flags = IP_CT_HELPER_F_REUSE_EXPECT;
sip[i].me = ip_conntrack_sip;
sip[i].help = sip_help;
tmpname = &sip_names[i][0];
if (ports[i] == SIP_PORT)
sprintf(tmpname, "sip");
else
sprintf(tmpname, "sip-%d", ports[i]);
sip[i].name = tmpname;
DEBUGP("ip_ct_sip: registering helper for port %d\n", ports[i]);
ret = ip_conntrack_helper_register(&sip[i]);
if (ret) {
DEBUGP("ip_ct_sip: error registering "
"helper for port %d\n", ports[i]);
fini();
return ret;
}
}
return 0;
}
PROVIDES_CONNTRACK(sip);
module_init(init);
module_exit(fini);
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: SIP/RTP support coming?
2005-02-12 19:56 ` Christian Hentschel
@ 2005-04-15 8:44 ` Steve Davies
2005-04-15 15:48 ` Harald Welte
0 siblings, 1 reply; 9+ messages in thread
From: Steve Davies @ 2005-04-15 8:44 UTC (permalink / raw)
To: Christian Hentschel, netfilter-devel
Christian,
Sorry about taking so long to get back to you - I have been using your
SIP conntrack helper for a little while now, and it seems to work very
well for me, also with kernel 2.6.10.
Many thanks for providing it.
One small problem I do have is the netfilter API change in kernel
2.6.11 - Is this change documented anywhere? Is there a
porting/updating guide anywhere?
Thanks,
Steve
On 2/12/05, Christian Hentschel <chentschel2@arnet.com.ar> wrote:
> Hi, i'm very interesting in a conntrack/nat helper for sip.
> Currently i'm working on this and help with testing will be great.
> i've used kernel 2.6.10 for this.
>
> Christian.
>
> On Sat, 2005-02-12 at 13:08 +0100, Max Kellermann wrote:
> > On 2005/02/12 12:52, Steve Davies <davies147@gmail.com> wrote:
> > > Are there plans to integrate this officially? Should I take time to
> > > (try to) update the patch to the 2.6.x kernel? Am I missing
> > > something?
> >
> > I believe nobody is working on that yet; I planned to look at the code
> > when I'm done with the H.323 module, but that will take some time.
> >
> > A lot people would be thankful if you hacked the source, and ported
> > that to Linux 2.6.11-rc3 (the API has changed very much since 2.6.10;
> > don't use the old API).
> >
> > You should start with providing a patch-o-matic module (see netfilter
> > home page) of the original code, and then send patches with your
> > changes.
> >
> > Max
> >
> >
> --
>
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: SIP/RTP support coming?
2005-04-15 8:44 ` Steve Davies
@ 2005-04-15 15:48 ` Harald Welte
2005-04-15 22:46 ` [patch] " Christian Hentschel
2005-04-15 22:54 ` Christian Hentschel
0 siblings, 2 replies; 9+ messages in thread
From: Harald Welte @ 2005-04-15 15:48 UTC (permalink / raw)
To: Steve Davies; +Cc: Christian Hentschel, netfilter-devel
[-- Attachment #1: Type: text/plain, Size: 975 bytes --]
On Fri, Apr 15, 2005 at 09:44:03AM +0100, Steve Davies wrote:
> Christian,
>
> Sorry about taking so long to get back to you - I have been using your
> SIP conntrack helper for a little while now, and it seems to work very
> well for me, also with kernel 2.6.10.
>
> Many thanks for providing it.
>
> One small problem I do have is the netfilter API change in kernel
> 2.6.11 - Is this change documented anywhere? Is there a
> porting/updating guide anywhere?
unfortunately not. I suggest looking at a diff between 2.6.10 and
2.6.11 version of a helper (e.g. within patch-o-matic).
--
- Harald Welte <laforge@netfilter.org> http://netfilter.org/
============================================================================
"Fragmentation is like classful addressing -- an interesting early
architectural error that shows how much experimentation was going
on while IP was being designed." -- Paul Vixie
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* [patch] Re: SIP/RTP support coming?
2005-04-15 15:48 ` Harald Welte
@ 2005-04-15 22:46 ` Christian Hentschel
2005-04-15 22:54 ` Christian Hentschel
1 sibling, 0 replies; 9+ messages in thread
From: Christian Hentschel @ 2005-04-15 22:46 UTC (permalink / raw)
To: Harald Welte; +Cc: netfilter-devel
[-- Attachment #1: Type: text/plain, Size: 926 bytes --]
Ok, here goes 2.6.11 patch.
I'm still working on nat SIP/SDP content mangling. But u should try this
patch meanwhile. It'd be great some help with it.
Let me know later.
Herald? Would it be possible to add it to pom if this works realiable?
On Fri, 2005-04-15 at 17:48 +0200, Harald Welte wrote:
> On Fri, Apr 15, 2005 at 09:44:03AM +0100, Steve Davies wrote:
> > Christian,
> >
> > Sorry about taking so long to get back to you - I have been using your
> > SIP conntrack helper for a little while now, and it seems to work very
> > well for me, also with kernel 2.6.10.
> >
> > Many thanks for providing it.
> >
> > One small problem I do have is the netfilter API change in kernel
> > 2.6.11 - Is this change documented anywhere? Is there a
> > porting/updating guide anywhere?
>
> unfortunately not. I suggest looking at a diff between 2.6.10 and
> 2.6.11 version of a helper (e.g. within patch-o-matic).
>
--
[-- Attachment #2: sip_conntrack.patch --]
[-- Type: text/x-patch, Size: 11151 bytes --]
Index: sip-conntrack-nat/include/linux/netfilter_ipv4/ip_conntrack_sip.h
===================================================================
--- sip-conntrack-nat/include/linux/netfilter_ipv4/ip_conntrack_sip.h (revision 0)
+++ sip-conntrack-nat/include/linux/netfilter_ipv4/ip_conntrack_sip.h (revision 0)
@@ -0,0 +1,24 @@
+#ifndef __IP_CONNTRACK_SIP_H__
+#define __IP_CONNTRACK_SIP_H__
+/* SIP tracking. */
+
+#ifdef __KERNEL__
+
+#define SIP_PORT 5060
+
+#endif /* __KERNEL__ */
+
+/* This structure exists only once per master */
+struct ip_ct_sip_master {
+ int dummy;
+};
+
+struct ip_conntrack_expect;
+
+/* For NAT to hook in when we find a packet which describes what other
+ * connection we should expect. */
+extern unsigned int (*ip_nat_sip_hook)(struct sk_buff **pskb,
+ enum ip_conntrack_info ctinfo,
+ struct ip_conntrack_expect *exp);
+
+#endif /* __IP_CONNTRACK_SIP_H__ */
Index: sip-conntrack-nat/net/ipv4/netfilter/Makefile.ladd
===================================================================
--- sip-conntrack-nat/net/ipv4/netfilter/Makefile.ladd (revision 0)
+++ sip-conntrack-nat/net/ipv4/netfilter/Makefile.ladd (revision 0)
@@ -0,0 +1,6 @@
+obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
+
+# SIP support
+obj-$(CONFIG_IP_NF_SIP) += ip_conntrack_sip.o
+obj-$(CONFIG_IP_NF_NAT_SIP) += ip_nat_sip.o
+
Index: sip-conntrack-nat/net/ipv4/netfilter/ip_conntrack_sip.c
===================================================================
--- sip-conntrack-nat/net/ipv4/netfilter/ip_conntrack_sip.c (revision 0)
+++ sip-conntrack-nat/net/ipv4/netfilter/ip_conntrack_sip.c (revision 0)
@@ -0,0 +1,269 @@
+/* SIP extension for IP connection tracking.
+ *
+ * (C) 2005 Christian Hentschel
+ * based on RR's ip_conntrack_ftp.c and other modules.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/ip.h>
+#include <linux/ctype.h>
+#include <net/checksum.h>
+#include <net/udp.h>
+
+#include <linux/netfilter_ipv4/lockhelp.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+
+//FIXME
+#include "ip_conntrack_sip.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com>");
+MODULE_DESCRIPTION("SIP connection tracking helper");
+
+/* This is slow, but it's simple. --RR */
+static char sip_buffer[65536];
+
+static DECLARE_LOCK(sipbf_lock);
+
+struct module *ip_conntrack_sip = THIS_MODULE;
+
+#define MAX_PORTS 8
+static int ports[MAX_PORTS];
+static int ports_c;
+module_param_array(ports, int, &ports_c, 0400);
+MODULE_PARM_DESC(ports, " port numbers of sip servers");
+
+unsigned int (*ip_nat_sip_hook)(struct sk_buff **pskb,
+ enum ip_conntrack_info ctinfo,
+ struct ip_conntrack_expect *exp);
+EXPORT_SYMBOL_GPL(ip_nat_sip_hook);
+
+
+//#if 0
+#define DEBUGP printk
+//#else
+//#define DEBUGP(format, args...)
+//#endif
+
+static int rtp_expectfn(struct ip_conntrack *new)
+{
+ DEBUGP("ct_sip: Got expected RTP\n");
+
+ return 0;
+}
+
+static unsigned int skip_atoi(const char **str)
+{
+ unsigned int result = 0;
+
+ while (isdigit(**str))
+ result = result*10 + *((*str)++) - '0';
+
+ return result;
+}
+
+/*
+ * Simple IPaddr parser..
+ */
+static int has_ip(const char **str, uint32_t *ipaddr)
+{
+ int i, digit;
+ uint32_t val;
+
+ for (i = 0, *ipaddr = 0; i < 4; i++) {
+ digit = 0;
+ if (!isdigit(**str))
+ break;
+ if ((val = skip_atoi(str)) > 0xFF)
+ return -1;
+
+ ((uint8_t *)ipaddr)[i] = val;
+ digit = 1;
+
+ if (*(*str) != '.')
+ break;
+ (*str)++;
+ }
+ if (!digit)
+ return -1;
+
+ return 0;
+}
+
+static int get_rtpaddr(const char *data, uint32_t *ipaddr, uint16_t *port)
+{
+ const char *aux, *dptr;
+
+ dptr = strstr(data, "c=IN IP4 ");
+ if (!dptr) {
+ DEBUGP("'c=IN IP4 ' not found\n");
+ return -1;
+ }
+ dptr += 9;
+
+ /* Get ipaddr */
+ aux = dptr;
+ if (has_ip(&dptr, ipaddr) < 0) {
+ DEBUGP("has_ip() failed\n");
+ return -1;
+ }
+
+ dptr = strstr(data, "m=audio ");
+ if (!dptr) {
+ DEBUGP("'m=audio ' not found\n");
+ return -1;
+ }
+
+ dptr += 8;
+ aux = dptr;
+
+ *port = skip_atoi(&dptr);
+
+ if (*port < 1024)
+ return -1;
+
+ return 0;
+}
+
+static int set_expected_rtp(struct sk_buff **pskb, struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo, u_int32_t ipaddr, u_int16_t port)
+{
+ struct ip_conntrack_expect *exp;
+
+ exp = ip_conntrack_expect_alloc();
+ if (exp == NULL)
+ return NF_DROP;
+
+ exp->tuple = ((struct ip_conntrack_tuple)
+ { { ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip, { 0 } },
+ { ipaddr, { .udp = { htons(port) } }, IPPROTO_UDP }});
+
+ exp->mask = ((struct ip_conntrack_tuple)
+ { { 0xFFFFFFFF, { 0 } },
+ { 0xFFFFFFFF, { .udp = { 0xFFFF } }, 0xFF }});
+
+ exp->expectfn = NULL; //rtp_expectfn;
+ exp->master = ct;
+
+ DEBUGP("expect: ");
+ DUMP_TUPLE(&exp->tuple);
+ DUMP_TUPLE(&exp->mask);
+
+ if (ip_nat_sip_hook)
+ return ip_nat_sip_hook(pskb, ctinfo, exp);
+ else if (ip_conntrack_expect_related(exp) != 0) {
+ ip_conntrack_expect_free(exp);
+ return NF_DROP;
+ }
+ return NF_ACCEPT;
+}
+
+
+static int sip_help(struct sk_buff **pskb,
+ struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
+{
+ unsigned int dataoff, datalen;
+ char *dptr;
+
+ int ret = NF_ACCEPT;
+
+ uint32_t ipaddr = 0;
+ uint16_t port;
+
+ if ((ctinfo) >= IP_CT_IS_REPLY)
+ return NF_ACCEPT;
+
+ /* No Data ? */
+ dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
+ if (dataoff >= (*pskb)->len) {
+ DEBUGP("skb->len = %u\n", (*pskb)->len);
+ return NF_ACCEPT;
+ }
+
+ datalen = (*pskb)->len - dataoff;
+
+ LOCK_BH(&sipbf_lock);
+
+ dptr = skb_header_pointer(*pskb, dataoff, datalen, sip_buffer);
+ BUG_ON(dptr == NULL);
+
+ DEBUGP("datalen %u\n", datalen);
+
+ /* RTP info only in SDP interestin packets */
+ if (memcmp(dptr, "INVITE", 6) != 0 && memcmp(dptr, "SIP/2.0 200", 11) != 0) {
+ DEBUGP("Not interesting pkt.\n");
+ goto out;
+ }
+
+ *(dptr + datalen) = '\0';
+
+ if (get_rtpaddr(dptr, &ipaddr, &port) < 0)
+ goto out;
+
+ ret = set_expected_rtp(pskb, ct, ctinfo, ipaddr, port);
+
+out: UNLOCK_BH(&sipbf_lock);
+ return ret;
+}
+
+static struct ip_conntrack_helper sip[MAX_PORTS];
+static char sip_names[MAX_PORTS][10];
+
+static void fini(void)
+{
+ int i = 0;
+ for (; i < ports_c; i++) {
+ DEBUGP("unregistering helper for port %d\n", ports[i]);
+ ip_conntrack_helper_unregister(&sip[i]);
+ }
+}
+
+static int __init init(void)
+{
+ int i, ret;
+ char *tmpname;
+
+ if (ports_c == 0)
+ ports[ports_c++] = SIP_PORT;
+
+ for (i = 0; i < ports_c; i++) {
+ /* Create helper structure */
+ memset(&sip[i], 0, sizeof(struct ip_conntrack_helper));
+
+ sip[i].tuple.dst.protonum = IPPROTO_UDP;
+ sip[i].tuple.src.u.udp.port = htons(ports[i]);
+ sip[i].mask.src.u.udp.port = 0xFFFF;
+ sip[i].mask.dst.protonum = 0xFF;
+ sip[i].max_expected = 2;
+ sip[i].timeout = 3 * 60; /* 3 minutes */
+ sip[i].me = THIS_MODULE;
+ sip[i].help = sip_help;
+
+ tmpname = &sip_names[i][0];
+ if (ports[i] == SIP_PORT)
+ sprintf(tmpname, "sip");
+ else
+ sprintf(tmpname, "sip-%d", i);
+ sip[i].name = tmpname;
+
+ DEBUGP("port #%d: %d\n", i, ports[i]);
+
+ ret=ip_conntrack_helper_register(&sip[i]);
+ if (ret) {
+ printk("ERROR registering helper for port %d\n",
+ ports[i]);
+ fini();
+ return(ret);
+ }
+ }
+ return(0);
+}
+
+module_init(init);
+module_exit(fini);
Index: sip-conntrack-nat/net/ipv4/netfilter/ip_nat_sip.c
===================================================================
--- sip-conntrack-nat/net/ipv4/netfilter/ip_nat_sip.c (revision 0)
+++ sip-conntrack-nat/net/ipv4/netfilter/ip_nat_sip.c (revision 0)
@@ -0,0 +1,97 @@
+/* SIP extension for SIP NAT alteration.
+ *
+ * (C) 2005 Christian Hentschel
+ * based on RR's ip_nat_ftp.c and other modules.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <linux/moduleparam.h>
+#include <net/udp.h>
+#include <linux/netfilter_ipv4/ip_nat.h>
+#include <linux/netfilter_ipv4/ip_nat_helper.h>
+#include <linux/netfilter_ipv4/ip_nat_rule.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+
+//FIXME
+#include "ip_conntrack_sip.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com>");
+MODULE_DESCRIPTION("SIP NAT helper");
+
+//#if 0
+#define DEBUGP printk
+//#else
+//#define DEBUGP(format, args...)
+//#endif
+
+
+/* So, this packet has hit the connection tracking matching code.
+ Mangle it, and change the expectation to match the new version. */
+static unsigned int ip_nat_sip(struct sk_buff **pskb,
+ enum ip_conntrack_info ctinfo, struct ip_conntrack_expect *exp)
+{
+ u_int32_t newip;
+ u_int16_t port;
+ int dir = CTINFO2DIR(ctinfo);
+ struct ip_conntrack *ct = exp->master;
+
+ DEBUGP("SIP_NAT: ");
+
+ /* Connection will come from wherever this packet goes, hence !dir */
+ newip = ct->tuplehash[!dir].tuple.dst.ip;
+ exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
+ exp->dir = !dir;
+
+ /* When you see the packet, we need to NAT it the same as the
+ * this one. */
+ exp->expectfn = ip_nat_follow_master;
+
+ /* Try to get same port: if not, try to change it. */
+ for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
+ exp->tuple.dst.u.tcp.port = htons(port);
+ if (ip_conntrack_expect_related(exp) == 0)
+ break;
+ }
+
+ if (port == 0) {
+ ip_conntrack_expect_free(exp);
+ return NF_DROP;
+ }
+
+/*
+ * Hard stuff, mangle data inside the packet..
+
+ if () {
+ ip_conntrack_unexpect_related(exp);
+ return NF_DROP;
+ }
+*/
+ DEBUGP("new addr: %u.%u.%u.%u:%u\n", NIPQUAD(newip), port);
+
+ return NF_ACCEPT;
+}
+
+static void __exit fini(void)
+{
+ ip_nat_sip_hook = NULL;
+ /* Make sure noone calls it, meanwhile. */
+ synchronize_net();
+}
+
+static int __init init(void)
+{
+ BUG_ON(ip_nat_sip_hook);
+ ip_nat_sip_hook = ip_nat_sip;
+ return 0;
+}
+
+module_init(init);
+module_exit(fini);
Index: sip-conntrack-nat/info
===================================================================
--- sip-conntrack-nat/info (revision 0)
+++ sip-conntrack-nat/info (revision 0)
@@ -0,0 +1,5 @@
+Title: h323 connection tracking and NAT helper
+Author: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>, Max Kellermann <max@duempel.org>
+Status: Alpha
+Repository: extra
+Requires: linux-2.6 >= 2.6.11
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: SIP/RTP support coming?
2005-04-15 15:48 ` Harald Welte
2005-04-15 22:46 ` [patch] " Christian Hentschel
@ 2005-04-15 22:54 ` Christian Hentschel
1 sibling, 0 replies; 9+ messages in thread
From: Christian Hentschel @ 2005-04-15 22:54 UTC (permalink / raw)
To: Harald Welte; +Cc: netfilter-devel
[-- Attachment #1: Type: text/plain, Size: 733 bytes --]
Ups, sorry here goes again with "info" file fixed.
On Fri, 2005-04-15 at 17:48 +0200, Harald Welte wrote:
> On Fri, Apr 15, 2005 at 09:44:03AM +0100, Steve Davies wrote:
> > Christian,
> >
> > Sorry about taking so long to get back to you - I have been using your
> > SIP conntrack helper for a little while now, and it seems to work very
> > well for me, also with kernel 2.6.10.
> >
> > Many thanks for providing it.
> >
> > One small problem I do have is the netfilter API change in kernel
> > 2.6.11 - Is this change documented anywhere? Is there a
> > porting/updating guide anywhere?
>
> unfortunately not. I suggest looking at a diff between 2.6.10 and
> 2.6.11 version of a helper (e.g. within patch-o-matic).
>
--
[-- Attachment #2: sip_conntrack.patch --]
[-- Type: text/x-patch, Size: 11118 bytes --]
Index: sip-conntrack-nat/include/linux/netfilter_ipv4/ip_conntrack_sip.h
===================================================================
--- sip-conntrack-nat/include/linux/netfilter_ipv4/ip_conntrack_sip.h (revision 0)
+++ sip-conntrack-nat/include/linux/netfilter_ipv4/ip_conntrack_sip.h (revision 0)
@@ -0,0 +1,24 @@
+#ifndef __IP_CONNTRACK_SIP_H__
+#define __IP_CONNTRACK_SIP_H__
+/* SIP tracking. */
+
+#ifdef __KERNEL__
+
+#define SIP_PORT 5060
+
+#endif /* __KERNEL__ */
+
+/* This structure exists only once per master */
+struct ip_ct_sip_master {
+ int dummy;
+};
+
+struct ip_conntrack_expect;
+
+/* For NAT to hook in when we find a packet which describes what other
+ * connection we should expect. */
+extern unsigned int (*ip_nat_sip_hook)(struct sk_buff **pskb,
+ enum ip_conntrack_info ctinfo,
+ struct ip_conntrack_expect *exp);
+
+#endif /* __IP_CONNTRACK_SIP_H__ */
Index: sip-conntrack-nat/net/ipv4/netfilter/Makefile.ladd
===================================================================
--- sip-conntrack-nat/net/ipv4/netfilter/Makefile.ladd (revision 0)
+++ sip-conntrack-nat/net/ipv4/netfilter/Makefile.ladd (revision 0)
@@ -0,0 +1,6 @@
+obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
+
+# SIP support
+obj-$(CONFIG_IP_NF_SIP) += ip_conntrack_sip.o
+obj-$(CONFIG_IP_NF_NAT_SIP) += ip_nat_sip.o
+
Index: sip-conntrack-nat/net/ipv4/netfilter/ip_conntrack_sip.c
===================================================================
--- sip-conntrack-nat/net/ipv4/netfilter/ip_conntrack_sip.c (revision 0)
+++ sip-conntrack-nat/net/ipv4/netfilter/ip_conntrack_sip.c (revision 0)
@@ -0,0 +1,269 @@
+/* SIP extension for IP connection tracking.
+ *
+ * (C) 2005 Christian Hentschel
+ * based on RR's ip_conntrack_ftp.c and other modules.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/ip.h>
+#include <linux/ctype.h>
+#include <net/checksum.h>
+#include <net/udp.h>
+
+#include <linux/netfilter_ipv4/lockhelp.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+
+//FIXME
+#include "ip_conntrack_sip.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com>");
+MODULE_DESCRIPTION("SIP connection tracking helper");
+
+/* This is slow, but it's simple. --RR */
+static char sip_buffer[65536];
+
+static DECLARE_LOCK(sipbf_lock);
+
+struct module *ip_conntrack_sip = THIS_MODULE;
+
+#define MAX_PORTS 8
+static int ports[MAX_PORTS];
+static int ports_c;
+module_param_array(ports, int, &ports_c, 0400);
+MODULE_PARM_DESC(ports, " port numbers of sip servers");
+
+unsigned int (*ip_nat_sip_hook)(struct sk_buff **pskb,
+ enum ip_conntrack_info ctinfo,
+ struct ip_conntrack_expect *exp);
+EXPORT_SYMBOL_GPL(ip_nat_sip_hook);
+
+
+//#if 0
+#define DEBUGP printk
+//#else
+//#define DEBUGP(format, args...)
+//#endif
+
+static int rtp_expectfn(struct ip_conntrack *new)
+{
+ DEBUGP("ct_sip: Got expected RTP\n");
+
+ return 0;
+}
+
+static unsigned int skip_atoi(const char **str)
+{
+ unsigned int result = 0;
+
+ while (isdigit(**str))
+ result = result*10 + *((*str)++) - '0';
+
+ return result;
+}
+
+/*
+ * Simple IPaddr parser..
+ */
+static int has_ip(const char **str, uint32_t *ipaddr)
+{
+ int i, digit;
+ uint32_t val;
+
+ for (i = 0, *ipaddr = 0; i < 4; i++) {
+ digit = 0;
+ if (!isdigit(**str))
+ break;
+ if ((val = skip_atoi(str)) > 0xFF)
+ return -1;
+
+ ((uint8_t *)ipaddr)[i] = val;
+ digit = 1;
+
+ if (*(*str) != '.')
+ break;
+ (*str)++;
+ }
+ if (!digit)
+ return -1;
+
+ return 0;
+}
+
+static int get_rtpaddr(const char *data, uint32_t *ipaddr, uint16_t *port)
+{
+ const char *aux, *dptr;
+
+ dptr = strstr(data, "c=IN IP4 ");
+ if (!dptr) {
+ DEBUGP("'c=IN IP4 ' not found\n");
+ return -1;
+ }
+ dptr += 9;
+
+ /* Get ipaddr */
+ aux = dptr;
+ if (has_ip(&dptr, ipaddr) < 0) {
+ DEBUGP("has_ip() failed\n");
+ return -1;
+ }
+
+ dptr = strstr(data, "m=audio ");
+ if (!dptr) {
+ DEBUGP("'m=audio ' not found\n");
+ return -1;
+ }
+
+ dptr += 8;
+ aux = dptr;
+
+ *port = skip_atoi(&dptr);
+
+ if (*port < 1024)
+ return -1;
+
+ return 0;
+}
+
+static int set_expected_rtp(struct sk_buff **pskb, struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo, u_int32_t ipaddr, u_int16_t port)
+{
+ struct ip_conntrack_expect *exp;
+
+ exp = ip_conntrack_expect_alloc();
+ if (exp == NULL)
+ return NF_DROP;
+
+ exp->tuple = ((struct ip_conntrack_tuple)
+ { { ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip, { 0 } },
+ { ipaddr, { .udp = { htons(port) } }, IPPROTO_UDP }});
+
+ exp->mask = ((struct ip_conntrack_tuple)
+ { { 0xFFFFFFFF, { 0 } },
+ { 0xFFFFFFFF, { .udp = { 0xFFFF } }, 0xFF }});
+
+ exp->expectfn = NULL; //rtp_expectfn;
+ exp->master = ct;
+
+ DEBUGP("expect: ");
+ DUMP_TUPLE(&exp->tuple);
+ DUMP_TUPLE(&exp->mask);
+
+ if (ip_nat_sip_hook)
+ return ip_nat_sip_hook(pskb, ctinfo, exp);
+ else if (ip_conntrack_expect_related(exp) != 0) {
+ ip_conntrack_expect_free(exp);
+ return NF_DROP;
+ }
+ return NF_ACCEPT;
+}
+
+
+static int sip_help(struct sk_buff **pskb,
+ struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
+{
+ unsigned int dataoff, datalen;
+ char *dptr;
+
+ int ret = NF_ACCEPT;
+
+ uint32_t ipaddr = 0;
+ uint16_t port;
+
+ if ((ctinfo) >= IP_CT_IS_REPLY)
+ return NF_ACCEPT;
+
+ /* No Data ? */
+ dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
+ if (dataoff >= (*pskb)->len) {
+ DEBUGP("skb->len = %u\n", (*pskb)->len);
+ return NF_ACCEPT;
+ }
+
+ datalen = (*pskb)->len - dataoff;
+
+ LOCK_BH(&sipbf_lock);
+
+ dptr = skb_header_pointer(*pskb, dataoff, datalen, sip_buffer);
+ BUG_ON(dptr == NULL);
+
+ DEBUGP("datalen %u\n", datalen);
+
+ /* RTP info only in SDP interestin packets */
+ if (memcmp(dptr, "INVITE", 6) != 0 && memcmp(dptr, "SIP/2.0 200", 11) != 0) {
+ DEBUGP("Not interesting pkt.\n");
+ goto out;
+ }
+
+ *(dptr + datalen) = '\0';
+
+ if (get_rtpaddr(dptr, &ipaddr, &port) < 0)
+ goto out;
+
+ ret = set_expected_rtp(pskb, ct, ctinfo, ipaddr, port);
+
+out: UNLOCK_BH(&sipbf_lock);
+ return ret;
+}
+
+static struct ip_conntrack_helper sip[MAX_PORTS];
+static char sip_names[MAX_PORTS][10];
+
+static void fini(void)
+{
+ int i = 0;
+ for (; i < ports_c; i++) {
+ DEBUGP("unregistering helper for port %d\n", ports[i]);
+ ip_conntrack_helper_unregister(&sip[i]);
+ }
+}
+
+static int __init init(void)
+{
+ int i, ret;
+ char *tmpname;
+
+ if (ports_c == 0)
+ ports[ports_c++] = SIP_PORT;
+
+ for (i = 0; i < ports_c; i++) {
+ /* Create helper structure */
+ memset(&sip[i], 0, sizeof(struct ip_conntrack_helper));
+
+ sip[i].tuple.dst.protonum = IPPROTO_UDP;
+ sip[i].tuple.src.u.udp.port = htons(ports[i]);
+ sip[i].mask.src.u.udp.port = 0xFFFF;
+ sip[i].mask.dst.protonum = 0xFF;
+ sip[i].max_expected = 2;
+ sip[i].timeout = 3 * 60; /* 3 minutes */
+ sip[i].me = THIS_MODULE;
+ sip[i].help = sip_help;
+
+ tmpname = &sip_names[i][0];
+ if (ports[i] == SIP_PORT)
+ sprintf(tmpname, "sip");
+ else
+ sprintf(tmpname, "sip-%d", i);
+ sip[i].name = tmpname;
+
+ DEBUGP("port #%d: %d\n", i, ports[i]);
+
+ ret=ip_conntrack_helper_register(&sip[i]);
+ if (ret) {
+ printk("ERROR registering helper for port %d\n",
+ ports[i]);
+ fini();
+ return(ret);
+ }
+ }
+ return(0);
+}
+
+module_init(init);
+module_exit(fini);
Index: sip-conntrack-nat/net/ipv4/netfilter/ip_nat_sip.c
===================================================================
--- sip-conntrack-nat/net/ipv4/netfilter/ip_nat_sip.c (revision 0)
+++ sip-conntrack-nat/net/ipv4/netfilter/ip_nat_sip.c (revision 0)
@@ -0,0 +1,97 @@
+/* SIP extension for SIP NAT alteration.
+ *
+ * (C) 2005 Christian Hentschel
+ * based on RR's ip_nat_ftp.c and other modules.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <linux/moduleparam.h>
+#include <net/udp.h>
+#include <linux/netfilter_ipv4/ip_nat.h>
+#include <linux/netfilter_ipv4/ip_nat_helper.h>
+#include <linux/netfilter_ipv4/ip_nat_rule.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+
+//FIXME
+#include "ip_conntrack_sip.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com>");
+MODULE_DESCRIPTION("SIP NAT helper");
+
+//#if 0
+#define DEBUGP printk
+//#else
+//#define DEBUGP(format, args...)
+//#endif
+
+
+/* So, this packet has hit the connection tracking matching code.
+ Mangle it, and change the expectation to match the new version. */
+static unsigned int ip_nat_sip(struct sk_buff **pskb,
+ enum ip_conntrack_info ctinfo, struct ip_conntrack_expect *exp)
+{
+ u_int32_t newip;
+ u_int16_t port;
+ int dir = CTINFO2DIR(ctinfo);
+ struct ip_conntrack *ct = exp->master;
+
+ DEBUGP("SIP_NAT: ");
+
+ /* Connection will come from wherever this packet goes, hence !dir */
+ newip = ct->tuplehash[!dir].tuple.dst.ip;
+ exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
+ exp->dir = !dir;
+
+ /* When you see the packet, we need to NAT it the same as the
+ * this one. */
+ exp->expectfn = ip_nat_follow_master;
+
+ /* Try to get same port: if not, try to change it. */
+ for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
+ exp->tuple.dst.u.tcp.port = htons(port);
+ if (ip_conntrack_expect_related(exp) == 0)
+ break;
+ }
+
+ if (port == 0) {
+ ip_conntrack_expect_free(exp);
+ return NF_DROP;
+ }
+
+/*
+ * Hard stuff, mangle data inside the packet..
+
+ if () {
+ ip_conntrack_unexpect_related(exp);
+ return NF_DROP;
+ }
+*/
+ DEBUGP("new addr: %u.%u.%u.%u:%u\n", NIPQUAD(newip), port);
+
+ return NF_ACCEPT;
+}
+
+static void __exit fini(void)
+{
+ ip_nat_sip_hook = NULL;
+ /* Make sure noone calls it, meanwhile. */
+ synchronize_net();
+}
+
+static int __init init(void)
+{
+ BUG_ON(ip_nat_sip_hook);
+ ip_nat_sip_hook = ip_nat_sip;
+ return 0;
+}
+
+module_init(init);
+module_exit(fini);
Index: sip-conntrack-nat/info
===================================================================
--- sip-conntrack-nat/info (revision 0)
+++ sip-conntrack-nat/info (revision 0)
@@ -0,0 +1,5 @@
+Title: SIP connection tracking and NAT helper
+Author: Christian Hentschel <chentschel@arnet.com.ar>
+Status: Alpha
+Repository: extra
+Requires: linux-2.6 >= 2.6.11
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2005-04-15 22:54 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-12 11:52 SIP/RTP support coming? Steve Davies
2005-02-12 12:08 ` Max Kellermann
2005-02-12 16:30 ` Kevin P. Fleming
2005-02-12 16:55 ` Steve Davies
2005-02-12 19:56 ` Christian Hentschel
2005-04-15 8:44 ` Steve Davies
2005-04-15 15:48 ` Harald Welte
2005-04-15 22:46 ` [patch] " Christian Hentschel
2005-04-15 22:54 ` Christian Hentschel
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.