mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-24 03:24:55 +08:00
[NETFILTER]: sip conntrack: do case insensitive SIP header search
SIP headers are generally case-insensitive, only SDP headers are case sensitive. Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
parent
9d5b8baa4e
commit
40883e8184
@ -31,6 +31,7 @@ extern int ct_sip_get_info(const char *dptr, size_t dlen,
|
||||
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);
|
||||
size_t needle_len, size_t haystack_len,
|
||||
int case_sensitive);
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __IP_CONNTRACK_SIP_H__ */
|
||||
|
@ -64,6 +64,7 @@ struct sip_header_nfo {
|
||||
size_t lnlen;
|
||||
size_t snlen;
|
||||
size_t ln_strlen;
|
||||
int case_sensitive;
|
||||
int (*match_len)(const char *, const char *, int *);
|
||||
};
|
||||
|
||||
@ -105,6 +106,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = {
|
||||
.match_len = skp_digits_len
|
||||
},
|
||||
[POS_MEDIA] = { /* SDP media info */
|
||||
.case_sensitive = 1,
|
||||
.lname = "\nm=",
|
||||
.lnlen = sizeof("\nm=") - 1,
|
||||
.sname = "\rm=",
|
||||
@ -114,6 +116,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = {
|
||||
.match_len = digits_len
|
||||
},
|
||||
[POS_OWNER] = { /* SDP owner address*/
|
||||
.case_sensitive = 1,
|
||||
.lname = "\no=",
|
||||
.lnlen = sizeof("\no=") - 1,
|
||||
.sname = "\ro=",
|
||||
@ -123,6 +126,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = {
|
||||
.match_len = epaddr_len
|
||||
},
|
||||
[POS_CONNECTION] = { /* SDP connection info */
|
||||
.case_sensitive = 1,
|
||||
.lname = "\nc=",
|
||||
.lnlen = sizeof("\nc=") - 1,
|
||||
.sname = "\rc=",
|
||||
@ -132,6 +136,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = {
|
||||
.match_len = epaddr_len
|
||||
},
|
||||
[POS_SDP_HEADER] = { /* SDP version header */
|
||||
.case_sensitive = 1,
|
||||
.lname = "\nv=",
|
||||
.lnlen = sizeof("\nv=") - 1,
|
||||
.sname = "\rv=",
|
||||
@ -161,13 +166,19 @@ EXPORT_SYMBOL_GPL(ct_sip_lnlen);
|
||||
|
||||
/* Linear string search, case sensitive. */
|
||||
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);
|
||||
|
||||
while (haystack <= limit) {
|
||||
if (memcmp(haystack, needle, needle_len) == 0)
|
||||
return haystack;
|
||||
if (case_sensitive) {
|
||||
if (strncmp(haystack, needle, needle_len) == 0)
|
||||
return haystack;
|
||||
} else {
|
||||
if (strnicmp(haystack, needle, needle_len) == 0)
|
||||
return haystack;
|
||||
}
|
||||
haystack++;
|
||||
}
|
||||
return NULL;
|
||||
@ -280,7 +291,8 @@ int ct_sip_get_info(const char *dptr, size_t dlen,
|
||||
continue;
|
||||
}
|
||||
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) {
|
||||
DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str,
|
||||
hnfo->lname);
|
||||
|
@ -87,14 +87,15 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb,
|
||||
buffer, bufflen, POS_VIA))
|
||||
return 0;
|
||||
|
||||
/* This search should ignore case, but later.. */
|
||||
aux = ct_sip_search("CSeq:", *dptr, sizeof("CSeq:") - 1,
|
||||
(*pskb)->len - dataoff);
|
||||
(*pskb)->len - dataoff, 0);
|
||||
if (!aux)
|
||||
return 0;
|
||||
|
||||
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 mangle_sip_packet(pskb, ctinfo, ct, dptr,
|
||||
|
Loading…
Reference in New Issue
Block a user