Skip to content

Commit 40883e8

Browse files
kaberDavid S. Miller
authored andcommitted
[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>
1 parent 9d5b8ba commit 40883e8

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

include/linux/netfilter_ipv4/ip_conntrack_sip.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ extern int ct_sip_get_info(const char *dptr, size_t dlen,
3131
enum sip_header_pos pos);
3232
extern int ct_sip_lnlen(const char *line, const char *limit);
3333
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);
3536
#endif /* __KERNEL__ */
3637
#endif /* __IP_CONNTRACK_SIP_H__ */

net/ipv4/netfilter/ip_conntrack_sip.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct sip_header_nfo {
6464
size_t lnlen;
6565
size_t snlen;
6666
size_t ln_strlen;
67+
int case_sensitive;
6768
int (*match_len)(const char *, const char *, int *);
6869
};
6970

@@ -105,6 +106,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = {
105106
.match_len = skp_digits_len
106107
},
107108
[POS_MEDIA] = { /* SDP media info */
109+
.case_sensitive = 1,
108110
.lname = "\nm=",
109111
.lnlen = sizeof("\nm=") - 1,
110112
.sname = "\rm=",
@@ -114,6 +116,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = {
114116
.match_len = digits_len
115117
},
116118
[POS_OWNER] = { /* SDP owner address*/
119+
.case_sensitive = 1,
117120
.lname = "\no=",
118121
.lnlen = sizeof("\no=") - 1,
119122
.sname = "\ro=",
@@ -123,6 +126,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = {
123126
.match_len = epaddr_len
124127
},
125128
[POS_CONNECTION] = { /* SDP connection info */
129+
.case_sensitive = 1,
126130
.lname = "\nc=",
127131
.lnlen = sizeof("\nc=") - 1,
128132
.sname = "\rc=",
@@ -132,6 +136,7 @@ static struct sip_header_nfo ct_sip_hdrs[] = {
132136
.match_len = epaddr_len
133137
},
134138
[POS_SDP_HEADER] = { /* SDP version header */
139+
.case_sensitive = 1,
135140
.lname = "\nv=",
136141
.lnlen = sizeof("\nv=") - 1,
137142
.sname = "\rv=",
@@ -161,13 +166,19 @@ EXPORT_SYMBOL_GPL(ct_sip_lnlen);
161166

162167
/* Linear string search, case sensitive. */
163168
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)
165171
{
166172
const char *limit = haystack + (haystack_len - needle_len);
167173

168174
while (haystack <= limit) {
169-
if (memcmp(haystack, needle, needle_len) == 0)
170-
return haystack;
175+
if (case_sensitive) {
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+
}
171182
haystack++;
172183
}
173184
return NULL;
@@ -280,7 +291,8 @@ int ct_sip_get_info(const char *dptr, size_t dlen,
280291
continue;
281292
}
282293
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);
284296
if (!aux) {
285297
DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str,
286298
hnfo->lname);

net/ipv4/netfilter/ip_nat_sip.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,15 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb,
8787
buffer, bufflen, POS_VIA))
8888
return 0;
8989

90-
/* This search should ignore case, but later.. */
9190
aux = ct_sip_search("CSeq:", *dptr, sizeof("CSeq:") - 1,
92-
(*pskb)->len - dataoff);
91+
(*pskb)->len - dataoff, 0);
9392
if (!aux)
9493
return 0;
9594

9695
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))
9899
return 1;
99100

100101
return mangle_sip_packet(pskb, ctinfo, ct, dptr,

0 commit comments

Comments
 (0)