diff options
-rw-r--r-- | include/linux/netfilter/nf_conntrack_sip.h | 1 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_sip.c | 39 |
2 files changed, 40 insertions, 0 deletions
diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h index ff8cfbcf3b81..0ce91d56a5f2 100644 --- a/include/linux/netfilter/nf_conntrack_sip.h +++ b/include/linux/netfilter/nf_conntrack_sip.h | |||
@@ -89,6 +89,7 @@ enum sip_header_types { | |||
89 | SIP_HDR_VIA_TCP, | 89 | SIP_HDR_VIA_TCP, |
90 | SIP_HDR_EXPIRES, | 90 | SIP_HDR_EXPIRES, |
91 | SIP_HDR_CONTENT_LENGTH, | 91 | SIP_HDR_CONTENT_LENGTH, |
92 | SIP_HDR_CALL_ID, | ||
92 | }; | 93 | }; |
93 | 94 | ||
94 | enum sdp_header_types { | 95 | enum sdp_header_types { |
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 2fd1ea2c1bb3..715ce54d2fc4 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
@@ -130,6 +130,44 @@ static int digits_len(const struct nf_conn *ct, const char *dptr, | |||
130 | return len; | 130 | return len; |
131 | } | 131 | } |
132 | 132 | ||
133 | static int iswordc(const char c) | ||
134 | { | ||
135 | if (isalnum(c) || c == '!' || c == '"' || c == '%' || | ||
136 | (c >= '(' && c <= '/') || c == ':' || c == '<' || c == '>' || | ||
137 | c == '?' || (c >= '[' && c <= ']') || c == '_' || c == '`' || | ||
138 | c == '{' || c == '}' || c == '~') | ||
139 | return 1; | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static int word_len(const char *dptr, const char *limit) | ||
144 | { | ||
145 | int len = 0; | ||
146 | while (dptr < limit && iswordc(*dptr)) { | ||
147 | dptr++; | ||
148 | len++; | ||
149 | } | ||
150 | return len; | ||
151 | } | ||
152 | |||
153 | static int callid_len(const struct nf_conn *ct, const char *dptr, | ||
154 | const char *limit, int *shift) | ||
155 | { | ||
156 | int len, domain_len; | ||
157 | |||
158 | len = word_len(dptr, limit); | ||
159 | dptr += len; | ||
160 | if (!len || dptr == limit || *dptr != '@') | ||
161 | return len; | ||
162 | dptr++; | ||
163 | len++; | ||
164 | |||
165 | domain_len = word_len(dptr, limit); | ||
166 | if (!domain_len) | ||
167 | return 0; | ||
168 | return len + domain_len; | ||
169 | } | ||
170 | |||
133 | /* get media type + port length */ | 171 | /* get media type + port length */ |
134 | static int media_len(const struct nf_conn *ct, const char *dptr, | 172 | static int media_len(const struct nf_conn *ct, const char *dptr, |
135 | const char *limit, int *shift) | 173 | const char *limit, int *shift) |
@@ -299,6 +337,7 @@ static const struct sip_header ct_sip_hdrs[] = { | |||
299 | [SIP_HDR_VIA_TCP] = SIP_HDR("Via", "v", "TCP ", epaddr_len), | 337 | [SIP_HDR_VIA_TCP] = SIP_HDR("Via", "v", "TCP ", epaddr_len), |
300 | [SIP_HDR_EXPIRES] = SIP_HDR("Expires", NULL, NULL, digits_len), | 338 | [SIP_HDR_EXPIRES] = SIP_HDR("Expires", NULL, NULL, digits_len), |
301 | [SIP_HDR_CONTENT_LENGTH] = SIP_HDR("Content-Length", "l", NULL, digits_len), | 339 | [SIP_HDR_CONTENT_LENGTH] = SIP_HDR("Content-Length", "l", NULL, digits_len), |
340 | [SIP_HDR_CALL_ID] = SIP_HDR("Call-Id", "i", NULL, callid_len), | ||
302 | }; | 341 | }; |
303 | 342 | ||
304 | static const char *sip_follow_continuation(const char *dptr, const char *limit) | 343 | static const char *sip_follow_continuation(const char *dptr, const char *limit) |