[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:
parent
337fbc4166
commit
9d5b8baa4e
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue