diff options
author | Patrick McHardy <kaber@trash.net> | 2006-11-28 20:35:27 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:31:24 -0500 |
commit | 40883e8184947879f135605a05c0764c60656cc5 (patch) | |
tree | f45133bd4b1a33a9dd94ddad3f78ba442d1f2bea | |
parent | 9d5b8baa4e9ace9be113c6151aaeeb3c07a26fc8 (diff) |
[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>
-rw-r--r-- | include/linux/netfilter_ipv4/ip_conntrack_sip.h | 3 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_sip.c | 20 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_sip.c | 7 |
3 files changed, 22 insertions, 8 deletions
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_sip.h b/include/linux/netfilter_ipv4/ip_conntrack_sip.h index 2a15eb51fd6b..51c65ac18c57 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_sip.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_sip.h | |||
@@ -31,6 +31,7 @@ extern int ct_sip_get_info(const char *dptr, size_t dlen, | |||
31 | enum sip_header_pos pos); | 31 | enum sip_header_pos pos); |
32 | extern int ct_sip_lnlen(const char *line, const char *limit); | 32 | extern int ct_sip_lnlen(const char *line, const char *limit); |
33 | extern const char *ct_sip_search(const char *needle, const char *haystack, | 33 | extern const char *ct_sip_search(const char *needle, const char *haystack, |
34 | size_t needle_len, size_t haystack_len); | 34 | size_t needle_len, size_t haystack_len, |
35 | int case_sensitive); | ||
35 | #endif /* __KERNEL__ */ | 36 | #endif /* __KERNEL__ */ |
36 | #endif /* __IP_CONNTRACK_SIP_H__ */ | 37 | #endif /* __IP_CONNTRACK_SIP_H__ */ |
diff --git a/net/ipv4/netfilter/ip_conntrack_sip.c b/net/ipv4/netfilter/ip_conntrack_sip.c index cc3176581667..a9c0d1d3e56f 100644 --- a/net/ipv4/netfilter/ip_conntrack_sip.c +++ b/net/ipv4/netfilter/ip_conntrack_sip.c | |||
@@ -64,6 +64,7 @@ struct sip_header_nfo { | |||
64 | size_t lnlen; | 64 | size_t lnlen; |
65 | size_t snlen; | 65 | size_t snlen; |
66 | size_t ln_strlen; | 66 | size_t ln_strlen; |
67 | int case_sensitive; | ||
67 | int (*match_len)(const char *, const char *, int *); | 68 | int (*match_len)(const char *, const char *, int *); |
68 | }; | 69 | }; |
69 | 70 | ||
@@ -105,6 +106,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = { | |||
105 | .match_len = skp_digits_len | 106 | .match_len = skp_digits_len |
106 | }, | 107 | }, |
107 | [POS_MEDIA] = { /* SDP media info */ | 108 | [POS_MEDIA] = { /* SDP media info */ |
109 | .case_sensitive = 1, | ||
108 | .lname = "\nm=", | 110 | .lname = "\nm=", |
109 | .lnlen = sizeof("\nm=") - 1, | 111 | .lnlen = sizeof("\nm=") - 1, |
110 | .sname = "\rm=", | 112 | .sname = "\rm=", |
@@ -114,6 +116,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = { | |||
114 | .match_len = digits_len | 116 | .match_len = digits_len |
115 | }, | 117 | }, |
116 | [POS_OWNER] = { /* SDP owner address*/ | 118 | [POS_OWNER] = { /* SDP owner address*/ |
119 | .case_sensitive = 1, | ||
117 | .lname = "\no=", | 120 | .lname = "\no=", |
118 | .lnlen = sizeof("\no=") - 1, | 121 | .lnlen = sizeof("\no=") - 1, |
119 | .sname = "\ro=", | 122 | .sname = "\ro=", |
@@ -123,6 +126,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = { | |||
123 | .match_len = epaddr_len | 126 | .match_len = epaddr_len |
124 | }, | 127 | }, |
125 | [POS_CONNECTION] = { /* SDP connection info */ | 128 | [POS_CONNECTION] = { /* SDP connection info */ |
129 | .case_sensitive = 1, | ||
126 | .lname = "\nc=", | 130 | .lname = "\nc=", |
127 | .lnlen = sizeof("\nc=") - 1, | 131 | .lnlen = sizeof("\nc=") - 1, |
128 | .sname = "\rc=", | 132 | .sname = "\rc=", |
@@ -132,6 +136,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = { | |||
132 | .match_len = epaddr_len | 136 | .match_len = epaddr_len |
133 | }, | 137 | }, |
134 | [POS_SDP_HEADER] = { /* SDP version header */ | 138 | [POS_SDP_HEADER] = { /* SDP version header */ |
139 | .case_sensitive = 1, | ||
135 | .lname = "\nv=", | 140 | .lname = "\nv=", |
136 | .lnlen = sizeof("\nv=") - 1, | 141 | .lnlen = sizeof("\nv=") - 1, |
137 | .sname = "\rv=", | 142 | .sname = "\rv=", |
@@ -161,13 +166,19 @@ EXPORT_SYMBOL_GPL(ct_sip_lnlen); | |||
161 | 166 | ||
162 | /* Linear string search, case sensitive. */ | 167 | /* Linear string search, case sensitive. */ |
163 | const char *ct_sip_search(const char *needle, const char *haystack, | 168 | const char *ct_sip_search(const char *needle, const char *haystack, |
164 | size_t needle_len, size_t haystack_len) | 169 | size_t needle_len, size_t haystack_len, |
170 | int case_sensitive) | ||
165 | { | 171 | { |
166 | const char *limit = haystack + (haystack_len - needle_len); | 172 | const char *limit = haystack + (haystack_len - needle_len); |
167 | 173 | ||
168 | while (haystack <= limit) { | 174 | while (haystack <= limit) { |
169 | if (memcmp(haystack, needle, needle_len) == 0) | 175 | if (case_sensitive) { |
170 | return haystack; | 176 | if (strncmp(haystack, needle, needle_len) == 0) |
177 | return haystack; | ||
178 | } else { | ||
179 | if (strnicmp(haystack, needle, needle_len) == 0) | ||
180 | return haystack; | ||
181 | } | ||
171 | haystack++; | 182 | haystack++; |
172 | } | 183 | } |
173 | return NULL; | 184 | return NULL; |
@@ -280,7 +291,8 @@ int ct_sip_get_info(const char *dptr, size_t dlen, | |||
280 | continue; | 291 | continue; |
281 | } | 292 | } |
282 | aux = ct_sip_search(hnfo->ln_str, dptr, hnfo->ln_strlen, | 293 | aux = ct_sip_search(hnfo->ln_str, dptr, hnfo->ln_strlen, |
283 | ct_sip_lnlen(dptr, limit)); | 294 | ct_sip_lnlen(dptr, limit), |
295 | hnfo->case_sensitive); | ||
284 | if (!aux) { | 296 | if (!aux) { |
285 | DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str, | 297 | DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str, |
286 | hnfo->lname); | 298 | hnfo->lname); |
diff --git a/net/ipv4/netfilter/ip_nat_sip.c b/net/ipv4/netfilter/ip_nat_sip.c index 47097aac63d8..e16604c4339d 100644 --- a/net/ipv4/netfilter/ip_nat_sip.c +++ b/net/ipv4/netfilter/ip_nat_sip.c | |||
@@ -87,14 +87,15 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb, | |||
87 | buffer, bufflen, POS_VIA)) | 87 | buffer, bufflen, POS_VIA)) |
88 | return 0; | 88 | return 0; |
89 | 89 | ||
90 | /* This search should ignore case, but later.. */ | ||
91 | aux = ct_sip_search("CSeq:", *dptr, sizeof("CSeq:") - 1, | 90 | aux = ct_sip_search("CSeq:", *dptr, sizeof("CSeq:") - 1, |
92 | (*pskb)->len - dataoff); | 91 | (*pskb)->len - dataoff, 0); |
93 | if (!aux) | 92 | if (!aux) |
94 | return 0; | 93 | return 0; |
95 | 94 | ||
96 | if (!ct_sip_search("REGISTER", aux, sizeof("REGISTER"), | 95 | if (!ct_sip_search("REGISTER", aux, sizeof("REGISTER"), |
97 | ct_sip_lnlen(aux, *dptr + (*pskb)->len - dataoff))) | 96 | ct_sip_lnlen(aux, |
97 | *dptr + (*pskb)->len - dataoff), | ||
98 | 1)) | ||
98 | return 1; | 99 | return 1; |
99 | 100 | ||
100 | return mangle_sip_packet(pskb, ctinfo, ct, dptr, | 101 | return mangle_sip_packet(pskb, ctinfo, ct, dptr, |