[NETFILTER]: sip conntrack: minor cleanup

- Use enum for header field enumeration
- Use numerical value instead of pointer to header info structure to
  identify headers, unexport ct_sip_hdrs
- group SIP and SDP entries in header info structure
- remove double forward declaration of ct_sip_get_info

Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
Patrick McHardy 2006-11-29 02:35:26 +01:00 committed by David S. Miller
parent 337fbc4166
commit 9d5b8baa4e
3 changed files with 95 additions and 103 deletions

View File

@ -5,23 +5,15 @@
#define SIP_PORT 5060
#define SIP_TIMEOUT 3600
#define POS_VIA 0
#define POS_CONTACT 1
#define POS_CONTENT 2
#define POS_MEDIA 3
#define POS_OWNER 4
#define POS_CONNECTION 5
#define POS_REQ_HEADER 6
#define POS_SDP_HEADER 7
struct sip_header_nfo {
const char *lname;
const char *sname;
const char *ln_str;
size_t lnlen;
size_t snlen;
size_t ln_strlen;
int (*match_len)(const char *, const char *, int *);
enum sip_header_pos {
POS_REQ_HEADER,
POS_VIA,
POS_CONTACT,
POS_CONTENT,
POS_MEDIA,
POS_OWNER,
POS_CONNECTION,
POS_SDP_HEADER,
};
extern unsigned int (*ip_nat_sip_hook)(struct sk_buff **pskb,
@ -36,7 +28,7 @@ extern unsigned int (*ip_nat_sdp_hook)(struct sk_buff **pskb,
extern int ct_sip_get_info(const char *dptr, size_t dlen,
unsigned int *matchoff,
unsigned int *matchlen,
struct sip_header_nfo *hnfo);
enum sip_header_pos pos);
extern int ct_sip_lnlen(const char *line, const char *limit);
extern const char *ct_sip_search(const char *needle, const char *haystack,
size_t needle_len, size_t haystack_len);

View File

@ -52,74 +52,23 @@ unsigned int (*ip_nat_sdp_hook)(struct sk_buff **pskb,
const char *dptr);
EXPORT_SYMBOL_GPL(ip_nat_sdp_hook);
int ct_sip_get_info(const char *dptr, size_t dlen,
unsigned int *matchoff,
unsigned int *matchlen,
struct sip_header_nfo *hnfo);
EXPORT_SYMBOL_GPL(ct_sip_get_info);
static int digits_len(const char *dptr, const char *limit, int *shift);
static int epaddr_len(const char *dptr, const char *limit, int *shift);
static int skp_digits_len(const char *dptr, const char *limit, int *shift);
static int skp_epaddr_len(const char *dptr, const char *limit, int *shift);
struct sip_header_nfo ct_sip_hdrs[] = {
{ /* Via header */
.lname = "Via:",
.lnlen = sizeof("Via:") - 1,
.sname = "\r\nv:",
.snlen = sizeof("\r\nv:") - 1, /* rfc3261 "\r\n" */
.ln_str = "UDP ",
.ln_strlen = sizeof("UDP ") - 1,
.match_len = epaddr_len,
},
{ /* Contact header */
.lname = "Contact:",
.lnlen = sizeof("Contact:") - 1,
.sname = "\r\nm:",
.snlen = sizeof("\r\nm:") - 1,
.ln_str = "sip:",
.ln_strlen = sizeof("sip:") - 1,
.match_len = skp_epaddr_len
},
{ /* Content length header */
.lname = "Content-Length:",
.lnlen = sizeof("Content-Length:") - 1,
.sname = "\r\nl:",
.snlen = sizeof("\r\nl:") - 1,
.ln_str = ":",
.ln_strlen = sizeof(":") - 1,
.match_len = skp_digits_len
},
{ /* SDP media info */
.lname = "\nm=",
.lnlen = sizeof("\nm=") - 1,
.sname = "\rm=",
.snlen = sizeof("\rm=") - 1,
.ln_str = "audio ",
.ln_strlen = sizeof("audio ") - 1,
.match_len = digits_len
},
{ /* SDP owner address*/
.lname = "\no=",
.lnlen = sizeof("\no=") - 1,
.sname = "\ro=",
.snlen = sizeof("\ro=") - 1,
.ln_str = "IN IP4 ",
.ln_strlen = sizeof("IN IP4 ") - 1,
.match_len = epaddr_len
},
{ /* SDP connection info */
.lname = "\nc=",
.lnlen = sizeof("\nc=") - 1,
.sname = "\rc=",
.snlen = sizeof("\rc=") - 1,
.ln_str = "IN IP4 ",
.ln_strlen = sizeof("IN IP4 ") - 1,
.match_len = epaddr_len
},
{ /* Requests headers */
struct sip_header_nfo {
const char *lname;
const char *sname;
const char *ln_str;
size_t lnlen;
size_t snlen;
size_t ln_strlen;
int (*match_len)(const char *, const char *, int *);
};
static struct sip_header_nfo ct_sip_hdrs[] = {
[POS_REQ_HEADER] = { /* SIP Requests headers */
.lname = "sip:",
.lnlen = sizeof("sip:") - 1,
.sname = "sip:",
@ -128,7 +77,61 @@ struct sip_header_nfo ct_sip_hdrs[] = {
.ln_strlen = sizeof("@") - 1,
.match_len = epaddr_len
},
{ /* SDP version header */
[POS_VIA] = { /* SIP Via header */
.lname = "Via:",
.lnlen = sizeof("Via:") - 1,
.sname = "\r\nv:",
.snlen = sizeof("\r\nv:") - 1, /* rfc3261 "\r\n" */
.ln_str = "UDP ",
.ln_strlen = sizeof("UDP ") - 1,
.match_len = epaddr_len,
},
[POS_CONTACT] = { /* SIP Contact header */
.lname = "Contact:",
.lnlen = sizeof("Contact:") - 1,
.sname = "\r\nm:",
.snlen = sizeof("\r\nm:") - 1,
.ln_str = "sip:",
.ln_strlen = sizeof("sip:") - 1,
.match_len = skp_epaddr_len
},
[POS_CONTENT] = { /* SIP Content length header */
.lname = "Content-Length:",
.lnlen = sizeof("Content-Length:") - 1,
.sname = "\r\nl:",
.snlen = sizeof("\r\nl:") - 1,
.ln_str = ":",
.ln_strlen = sizeof(":") - 1,
.match_len = skp_digits_len
},
[POS_MEDIA] = { /* SDP media info */
.lname = "\nm=",
.lnlen = sizeof("\nm=") - 1,
.sname = "\rm=",
.snlen = sizeof("\rm=") - 1,
.ln_str = "audio ",
.ln_strlen = sizeof("audio ") - 1,
.match_len = digits_len
},
[POS_OWNER] = { /* SDP owner address*/
.lname = "\no=",
.lnlen = sizeof("\no=") - 1,
.sname = "\ro=",
.snlen = sizeof("\ro=") - 1,
.ln_str = "IN IP4 ",
.ln_strlen = sizeof("IN IP4 ") - 1,
.match_len = epaddr_len
},
[POS_CONNECTION] = { /* SDP connection info */
.lname = "\nc=",
.lnlen = sizeof("\nc=") - 1,
.sname = "\rc=",
.snlen = sizeof("\rc=") - 1,
.ln_str = "IN IP4 ",
.ln_strlen = sizeof("IN IP4 ") - 1,
.match_len = epaddr_len
},
[POS_SDP_HEADER] = { /* SDP version header */
.lname = "\nv=",
.lnlen = sizeof("\nv=") - 1,
.sname = "\rv=",
@ -138,7 +141,6 @@ struct sip_header_nfo ct_sip_hdrs[] = {
.match_len = digits_len
}
};
EXPORT_SYMBOL_GPL(ct_sip_hdrs);
/* get line lenght until first CR or LF seen. */
int ct_sip_lnlen(const char *line, const char *limit)
@ -263,8 +265,9 @@ static int skp_epaddr_len(const char *dptr, const char *limit, int *shift)
int ct_sip_get_info(const char *dptr, size_t dlen,
unsigned int *matchoff,
unsigned int *matchlen,
struct sip_header_nfo *hnfo)
enum sip_header_pos pos)
{
struct sip_header_nfo *hnfo = &ct_sip_hdrs[pos];
const char *limit, *aux, *k = dptr;
int shift = 0;
@ -298,6 +301,7 @@ int ct_sip_get_info(const char *dptr, size_t dlen,
DEBUGP("%s header not found.\n", hnfo->lname);
return 0;
}
EXPORT_SYMBOL_GPL(ct_sip_get_info);
static int set_expected_rtp(struct sk_buff **pskb,
struct ip_conntrack *ct,
@ -393,7 +397,7 @@ static int sip_help(struct sk_buff **pskb,
}
/* Get ip and port address from SDP packet. */
if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen,
&ct_sip_hdrs[POS_CONNECTION]) > 0) {
POS_CONNECTION) > 0) {
/* We'll drop only if there are parse problems. */
if (parse_ipaddr(dptr + matchoff, NULL, &ipaddr,
@ -402,7 +406,7 @@ static int sip_help(struct sk_buff **pskb,
goto out;
}
if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen,
&ct_sip_hdrs[POS_MEDIA]) > 0) {
POS_MEDIA) > 0) {
port = simple_strtoul(dptr + matchoff, NULL, 10);
if (port < 1024) {

View File

@ -29,18 +29,16 @@ MODULE_DESCRIPTION("SIP NAT helper");
#define DEBUGP(format, args...)
#endif
extern struct sip_header_nfo ct_sip_hdrs[];
static unsigned int mangle_sip_packet(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
struct ip_conntrack *ct,
const char **dptr, size_t dlen,
char *buffer, int bufflen,
struct sip_header_nfo *hnfo)
enum sip_header_pos pos)
{
unsigned int matchlen, matchoff;
if (ct_sip_get_info(*dptr, dlen, &matchoff, &matchlen, hnfo) <= 0)
if (ct_sip_get_info(*dptr, dlen, &matchoff, &matchlen, pos) <= 0)
return 0;
if (!ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
@ -80,14 +78,13 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb,
if ((ctinfo) < IP_CT_IS_REPLY) {
mangle_sip_packet(pskb, ctinfo, ct, dptr,
(*pskb)->len - dataoff,
buffer, bufflen,
&ct_sip_hdrs[POS_CONTACT]);
buffer, bufflen, POS_CONTACT);
return 1;
}
if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
(*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
buffer, bufflen, POS_VIA))
return 0;
/* This search should ignore case, but later.. */
@ -102,25 +99,24 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb,
return mangle_sip_packet(pskb, ctinfo, ct, dptr,
(*pskb)->len - dataoff,
buffer, bufflen,
&ct_sip_hdrs[POS_CONTACT]);
buffer, bufflen, POS_CONTACT);
}
if ((ctinfo) < IP_CT_IS_REPLY) {
if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
(*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
buffer, bufflen, POS_VIA))
return 0;
/* Mangle Contact if exists only. - watch udp_nat_mangle()! */
mangle_sip_packet(pskb, ctinfo, ct, dptr, (*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_CONTACT]);
buffer, bufflen, POS_CONTACT);
return 1;
}
/* This mangle requests headers. */
return mangle_sip_packet(pskb, ctinfo, ct, dptr,
ct_sip_lnlen(*dptr,
*dptr + (*pskb)->len - dataoff),
buffer, bufflen, &ct_sip_hdrs[POS_REQ_HEADER]);
buffer, bufflen, POS_REQ_HEADER);
}
static int mangle_content_len(struct sk_buff **pskb,
@ -136,7 +132,7 @@ static int mangle_content_len(struct sk_buff **pskb,
/* Get actual SDP lenght */
if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff,
&matchlen, &ct_sip_hdrs[POS_SDP_HEADER]) > 0) {
&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. */
@ -144,7 +140,7 @@ static int mangle_content_len(struct sk_buff **pskb,
/* Now, update SDP lenght */
if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff,
&matchlen, &ct_sip_hdrs[POS_CONTENT]) > 0) {
&matchlen, POS_CONTENT) > 0) {
bufflen = sprintf(buffer, "%u", c_len);
@ -170,17 +166,17 @@ static unsigned int mangle_sdp(struct sk_buff **pskb,
/* Mangle owner and contact info. */
bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip));
if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_OWNER]))
buffer, bufflen, POS_OWNER))
return 0;
if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_CONNECTION]))
buffer, bufflen, POS_CONNECTION))
return 0;
/* Mangle media port. */
bufflen = sprintf(buffer, "%u", port);
if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_MEDIA]))
buffer, bufflen, POS_MEDIA))
return 0;
return mangle_content_len(pskb, ctinfo, ct, dptr);