Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 90344
b: refs/heads/master
c: 2a6cfb2
h: refs/heads/master
v: v3
  • Loading branch information
Patrick McHardy authored and David S. Miller committed Mar 26, 2008
1 parent ae7d949 commit e5f834a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 52 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b1ec488b1fb3c7a8819857e3506787516ca1ed4d
refs/heads/master: 2a6cfb22ae002330d445f734668d9158db9e90de
6 changes: 4 additions & 2 deletions trunk/include/linux/netfilter/nf_conntrack_sip.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ enum sip_header_pos {
extern unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conn *ct,
const char **dptr);
const char **dptr,
unsigned int *datalen);
extern unsigned int (*nf_nat_sdp_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conntrack_expect *exp,
const char *dptr);
const char **dptr,
unsigned int *datalen);

extern int ct_sip_get_info(const struct nf_conn *ct, const char *dptr,
size_t dlen, unsigned int *matchoff,
Expand Down
91 changes: 48 additions & 43 deletions trunk/net/ipv4/netfilter/nf_nat_sip.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,35 @@ static void addr_map_init(const struct nf_conn *ct, struct addr_map *map)
}
}

static unsigned int mangle_packet(struct sk_buff *skb,
const char **dptr, unsigned int *datalen,
unsigned int matchoff, unsigned int matchlen,
const char *buffer, unsigned int buflen)
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);

if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo, matchoff, matchlen,
buffer, buflen))
return 0;

/* Reload data pointer and adjust datalen value */
*dptr = skb->data + ip_hdrlen(skb) + sizeof(struct udphdr);
*datalen += buflen - matchlen;
return 1;
}

static int map_sip_addr(struct sk_buff *skb, enum ip_conntrack_info ctinfo,
struct nf_conn *ct, const char **dptr, size_t dlen,
struct nf_conn *ct,
const char **dptr, unsigned int *datalen,
enum sip_header_pos pos, struct addr_map *map)
{
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
unsigned int matchlen, matchoff, addrlen;
char *addr;

if (ct_sip_get_info(ct, *dptr, dlen, &matchoff, &matchlen, pos) <= 0)
if (ct_sip_get_info(ct, *dptr, *datalen, &matchoff, &matchlen,
pos) <= 0)
return 1;

if ((matchlen == map->addr[dir].srciplen ||
Expand All @@ -84,26 +104,19 @@ static int map_sip_addr(struct sk_buff *skb, enum ip_conntrack_info ctinfo,
} else
return 1;

if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo,
matchoff, matchlen, addr, addrlen))
return 0;
*dptr = skb->data + ip_hdrlen(skb) + sizeof(struct udphdr);
return 1;

return mangle_packet(skb, dptr, datalen, matchoff, matchlen,
addr, addrlen);
}

static unsigned int ip_nat_sip(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conn *ct,
const char **dptr)
const char **dptr, unsigned int *datalen)
{
enum sip_header_pos pos;
struct addr_map map;
int dataoff, datalen;

dataoff = ip_hdrlen(skb) + sizeof(struct udphdr);
datalen = skb->len - dataoff;
if (datalen < sizeof("SIP/2.0") - 1)
if (*datalen < sizeof("SIP/2.0") - 1)
return NF_ACCEPT;

addr_map_init(ct, &map);
Expand All @@ -115,7 +128,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
* The "userinfo" and "@" components of the SIP URI MUST NOT
* be present.
*/
if (datalen >= sizeof("REGISTER") - 1 &&
if (*datalen >= sizeof("REGISTER") - 1 &&
strncmp(*dptr, "REGISTER", sizeof("REGISTER") - 1) == 0)
pos = POS_REG_REQ_URI;
else
Expand All @@ -136,51 +149,45 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
static unsigned int mangle_sip_packet(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conn *ct,
const char **dptr, size_t dlen,
const char **dptr, unsigned int *datalen,
char *buffer, int bufflen,
enum sip_header_pos pos)
{
unsigned int matchlen, matchoff;

if (ct_sip_get_info(ct, *dptr, dlen, &matchoff, &matchlen, pos) <= 0)
return 0;

if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo,
matchoff, matchlen, buffer, bufflen))
if (ct_sip_get_info(ct, *dptr, *datalen, &matchoff, &matchlen,
pos) <= 0)
return 0;

/* We need to reload this. Thanks Patrick. */
*dptr = skb->data + ip_hdrlen(skb) + sizeof(struct udphdr);
return 1;
return mangle_packet(skb, dptr, datalen, matchoff, matchlen,
buffer, bufflen);
}

static int mangle_content_len(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conn *ct,
const char *dptr)
const char **dptr, unsigned int *datalen)
{
unsigned int dataoff, matchoff, matchlen;
unsigned int matchoff, matchlen;
char buffer[sizeof("65536")];
int bufflen;

dataoff = ip_hdrlen(skb) + sizeof(struct udphdr);

/* Get actual SDP length */
if (ct_sip_get_info(ct, dptr, skb->len - dataoff, &matchoff,
if (ct_sip_get_info(ct, *dptr, *datalen, &matchoff,
&matchlen, POS_SDP_HEADER) > 0) {

/* since ct_sip_get_info() give us a pointer passing 'v='
we need to add 2 bytes in this count. */
int c_len = skb->len - dataoff - matchoff + 2;
int c_len = *datalen - matchoff + 2;

/* Now, update SDP length */
if (ct_sip_get_info(ct, dptr, skb->len - dataoff, &matchoff,
if (ct_sip_get_info(ct, *dptr, *datalen, &matchoff,
&matchlen, POS_CONTENT) > 0) {

bufflen = sprintf(buffer, "%u", c_len);
return nf_nat_mangle_udp_packet(skb, ct, ctinfo,
matchoff, matchlen,
buffer, bufflen);
return mangle_packet(skb, dptr, datalen,
matchoff, matchlen,
buffer, bufflen);
}
}
return 0;
Expand All @@ -190,30 +197,28 @@ static unsigned int mangle_sdp(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conn *ct,
__be32 newip, u_int16_t port,
const char *dptr)
const char **dptr, unsigned int *datalen)
{
char buffer[sizeof("nnn.nnn.nnn.nnn")];
unsigned int dataoff, bufflen;

dataoff = ip_hdrlen(skb) + sizeof(struct udphdr);
unsigned int bufflen;

/* Mangle owner and contact info. */
bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip));
if (!mangle_sip_packet(skb, ctinfo, ct, &dptr, skb->len - dataoff,
if (!mangle_sip_packet(skb, ctinfo, ct, dptr, datalen,
buffer, bufflen, POS_OWNER_IP4))
return 0;

if (!mangle_sip_packet(skb, ctinfo, ct, &dptr, skb->len - dataoff,
if (!mangle_sip_packet(skb, ctinfo, ct, dptr, datalen,
buffer, bufflen, POS_CONNECTION_IP4))
return 0;

/* Mangle media port. */
bufflen = sprintf(buffer, "%u", port);
if (!mangle_sip_packet(skb, ctinfo, ct, &dptr, skb->len - dataoff,
if (!mangle_sip_packet(skb, ctinfo, ct, dptr, datalen,
buffer, bufflen, POS_MEDIA))
return 0;

return mangle_content_len(skb, ctinfo, ct, dptr);
return mangle_content_len(skb, ctinfo, ct, dptr, datalen);
}

static void ip_nat_sdp_expect(struct nf_conn *ct,
Expand Down Expand Up @@ -242,7 +247,7 @@ static void ip_nat_sdp_expect(struct nf_conn *ct,
static unsigned int ip_nat_sdp(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conntrack_expect *exp,
const char *dptr)
const char **dptr, unsigned int *datalen)
{
struct nf_conn *ct = exp->master;
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
Expand Down Expand Up @@ -275,7 +280,7 @@ static unsigned int ip_nat_sdp(struct sk_buff *skb,
if (port == 0)
return NF_DROP;

if (!mangle_sdp(skb, ctinfo, ct, newip, port, dptr)) {
if (!mangle_sdp(skb, ctinfo, ct, newip, port, dptr, datalen)) {
nf_ct_unexpect_related(exp);
return NF_DROP;
}
Expand Down
14 changes: 8 additions & 6 deletions trunk/net/netfilter/nf_conntrack_sip.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ MODULE_PARM_DESC(sip_timeout, "timeout for the master SIP session");
unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conn *ct,
const char **dptr) __read_mostly;
const char **dptr,
unsigned int *datalen) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_sip_hook);

unsigned int (*nf_nat_sdp_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conntrack_expect *exp,
const char *dptr) __read_mostly;
const char **dptr,
unsigned int *datalen) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_sdp_hook);

static int digits_len(const struct nf_conn *, const char *, const char *, int *);
Expand Down Expand Up @@ -369,7 +371,7 @@ static int set_expected_rtp(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
union nf_inet_addr *addr,
__be16 port,
const char *dptr)
const char **dptr, unsigned int *datalen)
{
struct nf_conntrack_expect *exp;
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
Expand All @@ -386,7 +388,7 @@ static int set_expected_rtp(struct sk_buff *skb,

nf_nat_sdp = rcu_dereference(nf_nat_sdp_hook);
if (nf_nat_sdp && ct->status & IPS_NAT_MASK)
ret = nf_nat_sdp(skb, ctinfo, exp, dptr);
ret = nf_nat_sdp(skb, ctinfo, exp, dptr, datalen);
else {
if (nf_ct_expect_related(exp) != 0)
ret = NF_DROP;
Expand Down Expand Up @@ -429,7 +431,7 @@ static int sip_help(struct sk_buff *skb,

nf_nat_sip = rcu_dereference(nf_nat_sip_hook);
if (nf_nat_sip && ct->status & IPS_NAT_MASK) {
if (!nf_nat_sip(skb, ctinfo, ct, &dptr)) {
if (!nf_nat_sip(skb, ctinfo, ct, &dptr, &datalen)) {
ret = NF_DROP;
goto out;
}
Expand Down Expand Up @@ -466,7 +468,7 @@ static int sip_help(struct sk_buff *skb,
goto out;
}
ret = set_expected_rtp(skb, ct, ctinfo, &addr,
htons(port), dptr);
htons(port), &dptr, &datalen);
}
}
out:
Expand Down

0 comments on commit e5f834a

Please sign in to comment.