[NETFILTER]: nf_conntrack_sip: introduce URI and header parameter parsing helpers
authorPatrick McHardy <kaber@trash.net>
Wed, 26 Mar 2008 03:24:24 +0000 (20:24 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 26 Mar 2008 03:24:24 +0000 (20:24 -0700)
Introduce URI and header parameter parsing helpers. These are needed
by the conntrack helper to parse expiration values in Contact: header
parameters and by the NAT helper to properly update the Via-header
rport=, received= and maddr= parameters.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/netfilter/nf_conntrack_sip.h
net/netfilter/nf_conntrack_sip.c

index da93e80804c2cd7bfab1001cf22e9b975dd6de75..87e402825dba356a8456bd6bca2b0cdba8887c81 100644 (file)
@@ -93,6 +93,16 @@ extern int ct_sip_parse_header_uri(const struct nf_conn *ct, const char *dptr,
                                   enum sip_header_types type, int *in_header,
                                   unsigned int *matchoff, unsigned int *matchlen,
                                   union nf_inet_addr *addr, __be16 *port);
+extern int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr,
+                                     unsigned int dataoff, unsigned int datalen,
+                                     const char *name,
+                                     unsigned int *matchoff, unsigned int *matchlen,
+                                     union nf_inet_addr *addr);
+extern int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr,
+                                       unsigned int off, unsigned int datalen,
+                                       const char *name,
+                                       unsigned int *matchoff, unsigned int *matchen,
+                                       unsigned int *val);
 
 extern int ct_sip_get_sdp_header(const struct nf_conn *ct, const char *dptr,
                                 unsigned int dataoff, unsigned int datalen,
index 8e7e5b465ffb4b41cb0106129bc34e42490fb525..126f30842d6055e5a117dee433d3372b89d05450 100644 (file)
@@ -448,6 +448,64 @@ int ct_sip_parse_header_uri(const struct nf_conn *ct, const char *dptr,
 }
 EXPORT_SYMBOL_GPL(ct_sip_parse_header_uri);
 
+/* Parse address from header parameter and return address, offset and length */
+int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr,
+                              unsigned int dataoff, unsigned int datalen,
+                              const char *name,
+                              unsigned int *matchoff, unsigned int *matchlen,
+                              union nf_inet_addr *addr)
+{
+       const char *limit = dptr + datalen;
+       const char *start, *end;
+
+       limit = ct_sip_header_search(dptr + dataoff, limit, ",", strlen(","));
+       if (!limit)
+               limit = dptr + datalen;
+
+       start = ct_sip_header_search(dptr + dataoff, limit, name, strlen(name));
+       if (!start)
+               return 0;
+
+       start += strlen(name);
+       if (!parse_addr(ct, start, &end, addr, limit))
+               return 0;
+       *matchoff = start - dptr;
+       *matchlen = end - start;
+       return 1;
+}
+EXPORT_SYMBOL_GPL(ct_sip_parse_address_param);
+
+/* Parse numerical header parameter and return value, offset and length */
+int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr,
+                                unsigned int dataoff, unsigned int datalen,
+                                const char *name,
+                                unsigned int *matchoff, unsigned int *matchlen,
+                                unsigned int *val)
+{
+       const char *limit = dptr + datalen;
+       const char *start;
+       char *end;
+
+       limit = ct_sip_header_search(dptr + dataoff, limit, ",", strlen(","));
+       if (!limit)
+               limit = dptr + datalen;
+
+       start = ct_sip_header_search(dptr + dataoff, limit, name, strlen(name));
+       if (!start)
+               return 0;
+
+       start += strlen(name);
+       *val = simple_strtoul(start, &end, 0);
+       if (start == end)
+               return 0;
+       if (matchoff && matchlen) {
+               *matchoff = start - dptr;
+               *matchlen = end - start;
+       }
+       return 1;
+}
+EXPORT_SYMBOL_GPL(ct_sip_parse_numerical_param);
+
 /* SDP header parsing: a SDP session description contains an ordered set of
  * headers, starting with a section containing general session parameters,
  * optionally followed by multiple media descriptions.