Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 184167
b: refs/heads/master
c: 3b6b9fa
h: refs/heads/master
i:
  184165: ac4ea24
  184163: 8e86918
  184159: 7f190ee
v: v3
  • Loading branch information
Patrick McHardy committed Feb 11, 2010
1 parent 41ef58a commit 7a9e24a
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 93 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: 54101f4f3bed87fa968b57f77f8ff3b09fd88bcf
refs/heads/master: 3b6b9fab42fe98358d70735cf98d43fc18dc79c9
14 changes: 10 additions & 4 deletions trunk/include/linux/netfilter/nf_conntrack_sip.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ struct sdp_media_type {
struct sip_handler {
const char *method;
unsigned int len;
int (*request)(struct sk_buff *skb,
int (*request)(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen,
unsigned int cseq);
int (*response)(struct sk_buff *skb,
int (*response)(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen,
unsigned int cseq, unsigned int code);
};
Expand Down Expand Up @@ -100,33 +100,39 @@ enum sdp_header_types {
};

extern unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb,
unsigned int dataoff,
const char **dptr,
unsigned int *datalen);
extern unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb,
unsigned int dataoff,
const char **dptr,
unsigned int *datalen,
struct nf_conntrack_expect *exp,
unsigned int matchoff,
unsigned int matchlen);
extern unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb,
const char **dptr,
unsigned int dataoff,
const char **dptr,
unsigned int *datalen,
unsigned int sdpoff,
enum sdp_header_types type,
enum sdp_header_types term,
const union nf_inet_addr *addr);
extern unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb,
unsigned int dataoff,
const char **dptr,
unsigned int *datalen,
unsigned int matchoff,
unsigned int matchlen,
u_int16_t port);
extern unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb,
const char **dptr,
unsigned int dataoff,
const char **dptr,
unsigned int *datalen,
unsigned int sdpoff,
const union nf_inet_addr *addr);
extern unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb,
unsigned int dataoff,
const char **dptr,
unsigned int *datalen,
struct nf_conntrack_expect *rtp_exp,
Expand Down
101 changes: 51 additions & 50 deletions trunk/net/ipv4/netfilter/nf_nat_sip.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ MODULE_DESCRIPTION("SIP NAT helper");
MODULE_ALIAS("ip_nat_sip");


static unsigned int mangle_packet(struct sk_buff *skb,
static unsigned int mangle_packet(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen,
unsigned int matchoff, unsigned int matchlen,
const char *buffer, unsigned int buflen)
Expand All @@ -42,12 +42,12 @@ static unsigned int mangle_packet(struct sk_buff *skb,
return 0;

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

static int map_addr(struct sk_buff *skb,
static int map_addr(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen,
unsigned int matchoff, unsigned int matchlen,
union nf_inet_addr *addr, __be16 port)
Expand Down Expand Up @@ -76,11 +76,11 @@ static int map_addr(struct sk_buff *skb,

buflen = sprintf(buffer, "%pI4:%u", &newaddr, ntohs(newport));

return mangle_packet(skb, dptr, datalen, matchoff, matchlen,
return mangle_packet(skb, dataoff, dptr, datalen, matchoff, matchlen,
buffer, buflen);
}

static int map_sip_addr(struct sk_buff *skb,
static int map_sip_addr(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen,
enum sip_header_types type)
{
Expand All @@ -93,16 +93,17 @@ static int map_sip_addr(struct sk_buff *skb,
if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, type, NULL,
&matchoff, &matchlen, &addr, &port) <= 0)
return 1;
return map_addr(skb, dptr, datalen, matchoff, matchlen, &addr, port);
return map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen,
&addr, port);
}

static unsigned int ip_nat_sip(struct sk_buff *skb,
static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen)
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
unsigned int dataoff, matchoff, matchlen;
unsigned int coff, matchoff, matchlen;
union nf_inet_addr addr;
__be16 port;
int request, in_header;
Expand All @@ -112,7 +113,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
if (ct_sip_parse_request(ct, *dptr, *datalen,
&matchoff, &matchlen,
&addr, &port) > 0 &&
!map_addr(skb, dptr, datalen, matchoff, matchlen,
!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen,
&addr, port))
return NF_DROP;
request = 1;
Expand All @@ -138,7 +139,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
goto next;
}

if (!map_addr(skb, dptr, datalen, matchoff, matchlen,
if (!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen,
&addr, port))
return NF_DROP;

Expand All @@ -153,8 +154,8 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) {
buflen = sprintf(buffer, "%pI4",
&ct->tuplehash[!dir].tuple.dst.u3.ip);
if (!mangle_packet(skb, dptr, datalen, poff, plen,
buffer, buflen))
if (!mangle_packet(skb, dataoff, dptr, datalen,
poff, plen, buffer, buflen))
return NF_DROP;
}

Expand All @@ -167,8 +168,8 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) {
buflen = sprintf(buffer, "%pI4",
&ct->tuplehash[!dir].tuple.src.u3.ip);
if (!mangle_packet(skb, dptr, datalen, poff, plen,
buffer, buflen))
if (!mangle_packet(skb, dataoff, dptr, datalen,
poff, plen, buffer, buflen))
return NF_DROP;
}

Expand All @@ -181,27 +182,27 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
htons(n) != ct->tuplehash[!dir].tuple.src.u.udp.port) {
__be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port;
buflen = sprintf(buffer, "%u", ntohs(p));
if (!mangle_packet(skb, dptr, datalen, poff, plen,
buffer, buflen))
if (!mangle_packet(skb, dataoff, dptr, datalen,
poff, plen, buffer, buflen))
return NF_DROP;
}
}

next:
/* Translate Contact headers */
dataoff = 0;
coff = 0;
in_header = 0;
while (ct_sip_parse_header_uri(ct, *dptr, &dataoff, *datalen,
while (ct_sip_parse_header_uri(ct, *dptr, &coff, *datalen,
SIP_HDR_CONTACT, &in_header,
&matchoff, &matchlen,
&addr, &port) > 0) {
if (!map_addr(skb, dptr, datalen, matchoff, matchlen,
if (!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen,
&addr, port))
return NF_DROP;
}

if (!map_sip_addr(skb, dptr, datalen, SIP_HDR_FROM) ||
!map_sip_addr(skb, dptr, datalen, SIP_HDR_TO))
if (!map_sip_addr(skb, dataoff, dptr, datalen, SIP_HDR_FROM) ||
!map_sip_addr(skb, dataoff, dptr, datalen, SIP_HDR_TO))
return NF_DROP;
return NF_ACCEPT;
}
Expand Down Expand Up @@ -232,7 +233,7 @@ static void ip_nat_sip_expected(struct nf_conn *ct,
}
}

static unsigned int ip_nat_sip_expect(struct sk_buff *skb,
static unsigned int ip_nat_sip_expect(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen,
struct nf_conntrack_expect *exp,
unsigned int matchoff,
Expand Down Expand Up @@ -279,8 +280,8 @@ static unsigned int ip_nat_sip_expect(struct sk_buff *skb,
if (exp->tuple.dst.u3.ip != exp->saved_ip ||
exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) {
buflen = sprintf(buffer, "%pI4:%u", &newip, port);
if (!mangle_packet(skb, dptr, datalen, matchoff, matchlen,
buffer, buflen))
if (!mangle_packet(skb, dataoff, dptr, datalen,
matchoff, matchlen, buffer, buflen))
goto err;
}
return NF_ACCEPT;
Expand All @@ -290,7 +291,7 @@ static unsigned int ip_nat_sip_expect(struct sk_buff *skb,
return NF_DROP;
}

static int mangle_content_len(struct sk_buff *skb,
static int mangle_content_len(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen)
{
enum ip_conntrack_info ctinfo;
Expand All @@ -312,12 +313,13 @@ static int mangle_content_len(struct sk_buff *skb,
return 0;

buflen = sprintf(buffer, "%u", c_len);
return mangle_packet(skb, dptr, datalen, matchoff, matchlen,
return mangle_packet(skb, dataoff, dptr, datalen, matchoff, matchlen,
buffer, buflen);
}

static int mangle_sdp_packet(struct sk_buff *skb, const char **dptr,
unsigned int dataoff, unsigned int *datalen,
static int mangle_sdp_packet(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen,
unsigned int sdpoff,
enum sdp_header_types type,
enum sdp_header_types term,
char *buffer, int buflen)
Expand All @@ -326,16 +328,16 @@ static int mangle_sdp_packet(struct sk_buff *skb, const char **dptr,
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
unsigned int matchlen, matchoff;

if (ct_sip_get_sdp_header(ct, *dptr, dataoff, *datalen, type, term,
if (ct_sip_get_sdp_header(ct, *dptr, sdpoff, *datalen, type, term,
&matchoff, &matchlen) <= 0)
return -ENOENT;
return mangle_packet(skb, dptr, datalen, matchoff, matchlen,
return mangle_packet(skb, dataoff, dptr, datalen, matchoff, matchlen,
buffer, buflen) ? 0 : -EINVAL;
}

static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr,
unsigned int dataoff,
unsigned int *datalen,
static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen,
unsigned int sdpoff,
enum sdp_header_types type,
enum sdp_header_types term,
const union nf_inet_addr *addr)
Expand All @@ -344,16 +346,15 @@ static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr,
unsigned int buflen;

buflen = sprintf(buffer, "%pI4", &addr->ip);
if (mangle_sdp_packet(skb, dptr, dataoff, datalen, type, term,
if (mangle_sdp_packet(skb, dataoff, dptr, datalen, sdpoff, type, term,
buffer, buflen))
return 0;

return mangle_content_len(skb, dptr, datalen);
return mangle_content_len(skb, dataoff, dptr, datalen);
}

static unsigned int ip_nat_sdp_port(struct sk_buff *skb,
const char **dptr,
unsigned int *datalen,
static unsigned int ip_nat_sdp_port(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen,
unsigned int matchoff,
unsigned int matchlen,
u_int16_t port)
Expand All @@ -362,29 +363,29 @@ static unsigned int ip_nat_sdp_port(struct sk_buff *skb,
unsigned int buflen;

buflen = sprintf(buffer, "%u", port);
if (!mangle_packet(skb, dptr, datalen, matchoff, matchlen,
if (!mangle_packet(skb, dataoff, dptr, datalen, matchoff, matchlen,
buffer, buflen))
return 0;

return mangle_content_len(skb, dptr, datalen);
return mangle_content_len(skb, dataoff, dptr, datalen);
}

static unsigned int ip_nat_sdp_session(struct sk_buff *skb, const char **dptr,
unsigned int dataoff,
unsigned int *datalen,
static unsigned int ip_nat_sdp_session(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen,
unsigned int sdpoff,
const union nf_inet_addr *addr)
{
char buffer[sizeof("nnn.nnn.nnn.nnn")];
unsigned int buflen;

/* Mangle session description owner and contact addresses */
buflen = sprintf(buffer, "%pI4", &addr->ip);
if (mangle_sdp_packet(skb, dptr, dataoff, datalen,
if (mangle_sdp_packet(skb, dataoff, dptr, datalen, sdpoff,
SDP_HDR_OWNER_IP4, SDP_HDR_MEDIA,
buffer, buflen))
return 0;

switch (mangle_sdp_packet(skb, dptr, dataoff, datalen,
switch (mangle_sdp_packet(skb, dataoff, dptr, datalen, sdpoff,
SDP_HDR_CONNECTION_IP4, SDP_HDR_MEDIA,
buffer, buflen)) {
case 0:
Expand All @@ -401,14 +402,13 @@ static unsigned int ip_nat_sdp_session(struct sk_buff *skb, const char **dptr,
return 0;
}

return mangle_content_len(skb, dptr, datalen);
return mangle_content_len(skb, dataoff, dptr, datalen);
}

/* 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_sdp_media(struct sk_buff *skb,
const char **dptr,
unsigned int *datalen,
static unsigned int ip_nat_sdp_media(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen,
struct nf_conntrack_expect *rtp_exp,
struct nf_conntrack_expect *rtcp_exp,
unsigned int mediaoff,
Expand Down Expand Up @@ -456,7 +456,8 @@ static unsigned int ip_nat_sdp_media(struct sk_buff *skb,

/* Update media port. */
if (rtp_exp->tuple.dst.u.udp.port != rtp_exp->saved_proto.udp.port &&
!ip_nat_sdp_port(skb, dptr, datalen, mediaoff, medialen, port))
!ip_nat_sdp_port(skb, dataoff, dptr, datalen,
mediaoff, medialen, port))
goto err2;

return NF_ACCEPT;
Expand Down
Loading

0 comments on commit 7a9e24a

Please sign in to comment.