[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_PORT 5060
#define SIP_TIMEOUT 3600 #define SIP_TIMEOUT 3600
#define POS_VIA 0 enum sip_header_pos {
#define POS_CONTACT 1 POS_REQ_HEADER,
#define POS_CONTENT 2 POS_VIA,
#define POS_MEDIA 3 POS_CONTACT,
#define POS_OWNER 4 POS_CONTENT,
#define POS_CONNECTION 5 POS_MEDIA,
#define POS_REQ_HEADER 6 POS_OWNER,
#define POS_SDP_HEADER 7 POS_CONNECTION,
POS_SDP_HEADER,
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 *);
}; };
extern unsigned int (*ip_nat_sip_hook)(struct sk_buff **pskb, 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, extern int ct_sip_get_info(const char *dptr, size_t dlen,
unsigned int *matchoff, unsigned int *matchoff,
unsigned int *matchlen, 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 int ct_sip_lnlen(const char *line, const char *limit);
extern const char *ct_sip_search(const char *needle, const char *haystack, extern const char *ct_sip_search(const char *needle, const char *haystack,
size_t needle_len, size_t haystack_len); 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); const char *dptr);
EXPORT_SYMBOL_GPL(ip_nat_sdp_hook); 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 digits_len(const char *dptr, const char *limit, int *shift);
static int epaddr_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_digits_len(const char *dptr, const char *limit, int *shift);
static int skp_epaddr_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[] = { struct sip_header_nfo {
{ /* Via header */ const char *lname;
.lname = "Via:", const char *sname;
.lnlen = sizeof("Via:") - 1, const char *ln_str;
.sname = "\r\nv:", size_t lnlen;
.snlen = sizeof("\r\nv:") - 1, /* rfc3261 "\r\n" */ size_t snlen;
.ln_str = "UDP ", size_t ln_strlen;
.ln_strlen = sizeof("UDP ") - 1, int (*match_len)(const char *, const char *, int *);
.match_len = epaddr_len, };
},
{ /* Contact header */ static struct sip_header_nfo ct_sip_hdrs[] = {
.lname = "Contact:", [POS_REQ_HEADER] = { /* SIP Requests headers */
.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 */
.lname = "sip:", .lname = "sip:",
.lnlen = sizeof("sip:") - 1, .lnlen = sizeof("sip:") - 1,
.sname = "sip:", .sname = "sip:",
@ -128,7 +77,61 @@ struct sip_header_nfo ct_sip_hdrs[] = {
.ln_strlen = sizeof("@") - 1, .ln_strlen = sizeof("@") - 1,
.match_len = epaddr_len .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=", .lname = "\nv=",
.lnlen = sizeof("\nv=") - 1, .lnlen = sizeof("\nv=") - 1,
.sname = "\rv=", .sname = "\rv=",
@ -138,7 +141,6 @@ struct sip_header_nfo ct_sip_hdrs[] = {
.match_len = digits_len .match_len = digits_len
} }
}; };
EXPORT_SYMBOL_GPL(ct_sip_hdrs);
/* get line lenght until first CR or LF seen. */ /* get line lenght until first CR or LF seen. */
int ct_sip_lnlen(const char *line, const char *limit) 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, int ct_sip_get_info(const char *dptr, size_t dlen,
unsigned int *matchoff, unsigned int *matchoff,
unsigned int *matchlen, 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; const char *limit, *aux, *k = dptr;
int shift = 0; 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); DEBUGP("%s header not found.\n", hnfo->lname);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ct_sip_get_info);
static int set_expected_rtp(struct sk_buff **pskb, static int set_expected_rtp(struct sk_buff **pskb,
struct ip_conntrack *ct, struct ip_conntrack *ct,
@ -393,7 +397,7 @@ static int sip_help(struct sk_buff **pskb,
} }
/* Get ip and port address from SDP packet. */ /* Get ip and port address from SDP packet. */
if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen, 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. */ /* We'll drop only if there are parse problems. */
if (parse_ipaddr(dptr + matchoff, NULL, &ipaddr, if (parse_ipaddr(dptr + matchoff, NULL, &ipaddr,
@ -402,7 +406,7 @@ static int sip_help(struct sk_buff **pskb,
goto out; goto out;
} }
if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen, 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); port = simple_strtoul(dptr + matchoff, NULL, 10);
if (port < 1024) { if (port < 1024) {

View file

@ -29,18 +29,16 @@ MODULE_DESCRIPTION("SIP NAT helper");
#define DEBUGP(format, args...) #define DEBUGP(format, args...)
#endif #endif
extern struct sip_header_nfo ct_sip_hdrs[];
static unsigned int mangle_sip_packet(struct sk_buff **pskb, static unsigned int mangle_sip_packet(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
struct ip_conntrack *ct, struct ip_conntrack *ct,
const char **dptr, size_t dlen, const char **dptr, size_t dlen,
char *buffer, int bufflen, char *buffer, int bufflen,
struct sip_header_nfo *hnfo) enum sip_header_pos pos)
{ {
unsigned int matchlen, matchoff; 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; return 0;
if (!ip_nat_mangle_udp_packet(pskb, ct, ctinfo, 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) { if ((ctinfo) < IP_CT_IS_REPLY) {
mangle_sip_packet(pskb, ctinfo, ct, dptr, mangle_sip_packet(pskb, ctinfo, ct, dptr,
(*pskb)->len - dataoff, (*pskb)->len - dataoff,
buffer, bufflen, buffer, bufflen, POS_CONTACT);
&ct_sip_hdrs[POS_CONTACT]);
return 1; return 1;
} }
if (!mangle_sip_packet(pskb, ctinfo, ct, dptr, if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
(*pskb)->len - dataoff, (*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_VIA])) buffer, bufflen, POS_VIA))
return 0; return 0;
/* This search should ignore case, but later.. */ /* 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, return mangle_sip_packet(pskb, ctinfo, ct, dptr,
(*pskb)->len - dataoff, (*pskb)->len - dataoff,
buffer, bufflen, buffer, bufflen, POS_CONTACT);
&ct_sip_hdrs[POS_CONTACT]);
} }
if ((ctinfo) < IP_CT_IS_REPLY) { if ((ctinfo) < IP_CT_IS_REPLY) {
if (!mangle_sip_packet(pskb, ctinfo, ct, dptr, if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
(*pskb)->len - dataoff, (*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_VIA])) buffer, bufflen, POS_VIA))
return 0; return 0;
/* Mangle Contact if exists only. - watch udp_nat_mangle()! */ /* Mangle Contact if exists only. - watch udp_nat_mangle()! */
mangle_sip_packet(pskb, ctinfo, ct, dptr, (*pskb)->len - dataoff, mangle_sip_packet(pskb, ctinfo, ct, dptr, (*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_CONTACT]); buffer, bufflen, POS_CONTACT);
return 1; return 1;
} }
/* This mangle requests headers. */ /* This mangle requests headers. */
return mangle_sip_packet(pskb, ctinfo, ct, dptr, return mangle_sip_packet(pskb, ctinfo, ct, dptr,
ct_sip_lnlen(*dptr, ct_sip_lnlen(*dptr,
*dptr + (*pskb)->len - dataoff), *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, 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 */ /* Get actual SDP lenght */
if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff, 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=' /* since ct_sip_get_info() give us a pointer passing 'v='
we need to add 2 bytes in this count. */ 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 */ /* Now, update SDP lenght */
if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff, 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); bufflen = sprintf(buffer, "%u", c_len);
@ -170,17 +166,17 @@ static unsigned int mangle_sdp(struct sk_buff **pskb,
/* Mangle owner and contact info. */ /* Mangle owner and contact info. */
bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip)); bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip));
if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff, if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_OWNER])) buffer, bufflen, POS_OWNER))
return 0; return 0;
if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff, if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_CONNECTION])) buffer, bufflen, POS_CONNECTION))
return 0; return 0;
/* Mangle media port. */ /* Mangle media port. */
bufflen = sprintf(buffer, "%u", port); bufflen = sprintf(buffer, "%u", port);
if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff, 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 0;
return mangle_content_len(pskb, ctinfo, ct, dptr); return mangle_content_len(pskb, ctinfo, ct, dptr);