Commit 40883e81 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[NETFILTER]: sip conntrack: do case insensitive SIP header search

SIP headers are generally case-insensitive, only SDP headers are
case sensitive.
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent 9d5b8baa
...@@ -31,6 +31,7 @@ extern int ct_sip_get_info(const char *dptr, size_t dlen, ...@@ -31,6 +31,7 @@ extern int ct_sip_get_info(const char *dptr, size_t dlen,
enum sip_header_pos pos); 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,
int case_sensitive);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* __IP_CONNTRACK_SIP_H__ */ #endif /* __IP_CONNTRACK_SIP_H__ */
...@@ -64,6 +64,7 @@ struct sip_header_nfo { ...@@ -64,6 +64,7 @@ struct sip_header_nfo {
size_t lnlen; size_t lnlen;
size_t snlen; size_t snlen;
size_t ln_strlen; size_t ln_strlen;
int case_sensitive;
int (*match_len)(const char *, const char *, int *); int (*match_len)(const char *, const char *, int *);
}; };
...@@ -105,6 +106,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = { ...@@ -105,6 +106,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = {
.match_len = skp_digits_len .match_len = skp_digits_len
}, },
[POS_MEDIA] = { /* SDP media info */ [POS_MEDIA] = { /* SDP media info */
.case_sensitive = 1,
.lname = "\nm=", .lname = "\nm=",
.lnlen = sizeof("\nm=") - 1, .lnlen = sizeof("\nm=") - 1,
.sname = "\rm=", .sname = "\rm=",
...@@ -114,6 +116,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = { ...@@ -114,6 +116,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = {
.match_len = digits_len .match_len = digits_len
}, },
[POS_OWNER] = { /* SDP owner address*/ [POS_OWNER] = { /* SDP owner address*/
.case_sensitive = 1,
.lname = "\no=", .lname = "\no=",
.lnlen = sizeof("\no=") - 1, .lnlen = sizeof("\no=") - 1,
.sname = "\ro=", .sname = "\ro=",
...@@ -123,6 +126,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = { ...@@ -123,6 +126,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = {
.match_len = epaddr_len .match_len = epaddr_len
}, },
[POS_CONNECTION] = { /* SDP connection info */ [POS_CONNECTION] = { /* SDP connection info */
.case_sensitive = 1,
.lname = "\nc=", .lname = "\nc=",
.lnlen = sizeof("\nc=") - 1, .lnlen = sizeof("\nc=") - 1,
.sname = "\rc=", .sname = "\rc=",
...@@ -132,6 +136,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = { ...@@ -132,6 +136,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = {
.match_len = epaddr_len .match_len = epaddr_len
}, },
[POS_SDP_HEADER] = { /* SDP version header */ [POS_SDP_HEADER] = { /* SDP version header */
.case_sensitive = 1,
.lname = "\nv=", .lname = "\nv=",
.lnlen = sizeof("\nv=") - 1, .lnlen = sizeof("\nv=") - 1,
.sname = "\rv=", .sname = "\rv=",
...@@ -161,13 +166,19 @@ EXPORT_SYMBOL_GPL(ct_sip_lnlen); ...@@ -161,13 +166,19 @@ EXPORT_SYMBOL_GPL(ct_sip_lnlen);
/* Linear string search, case sensitive. */ /* Linear string search, case sensitive. */
const char *ct_sip_search(const char *needle, const char *haystack, 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,
int case_sensitive)
{ {
const char *limit = haystack + (haystack_len - needle_len); const char *limit = haystack + (haystack_len - needle_len);
while (haystack <= limit) { while (haystack <= limit) {
if (memcmp(haystack, needle, needle_len) == 0) if (case_sensitive) {
return haystack; if (strncmp(haystack, needle, needle_len) == 0)
return haystack;
} else {
if (strnicmp(haystack, needle, needle_len) == 0)
return haystack;
}
haystack++; haystack++;
} }
return NULL; return NULL;
...@@ -280,7 +291,8 @@ int ct_sip_get_info(const char *dptr, size_t dlen, ...@@ -280,7 +291,8 @@ int ct_sip_get_info(const char *dptr, size_t dlen,
continue; continue;
} }
aux = ct_sip_search(hnfo->ln_str, dptr, hnfo->ln_strlen, aux = ct_sip_search(hnfo->ln_str, dptr, hnfo->ln_strlen,
ct_sip_lnlen(dptr, limit)); ct_sip_lnlen(dptr, limit),
hnfo->case_sensitive);
if (!aux) { if (!aux) {
DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str, DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str,
hnfo->lname); hnfo->lname);
......
...@@ -87,14 +87,15 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb, ...@@ -87,14 +87,15 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb,
buffer, bufflen, POS_VIA)) buffer, bufflen, POS_VIA))
return 0; return 0;
/* This search should ignore case, but later.. */
aux = ct_sip_search("CSeq:", *dptr, sizeof("CSeq:") - 1, aux = ct_sip_search("CSeq:", *dptr, sizeof("CSeq:") - 1,
(*pskb)->len - dataoff); (*pskb)->len - dataoff, 0);
if (!aux) if (!aux)
return 0; return 0;
if (!ct_sip_search("REGISTER", aux, sizeof("REGISTER"), if (!ct_sip_search("REGISTER", aux, sizeof("REGISTER"),
ct_sip_lnlen(aux, *dptr + (*pskb)->len - dataoff))) ct_sip_lnlen(aux,
*dptr + (*pskb)->len - dataoff),
1))
return 1; return 1;
return mangle_sip_packet(pskb, ctinfo, ct, dptr, return mangle_sip_packet(pskb, ctinfo, ct, dptr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment