[NETFILTER]: sip conntrack: do case insensitive SIP header search
[deliverable/linux.git] / net / ipv4 / netfilter / ip_nat_sip.c
index 71fc2730a007d5ccdd9f4069c763d4b8bb8f748c..e16604c4339dd39626aaf4217002fab4fb8640ec 100644 (file)
@@ -29,18 +29,16 @@ MODULE_DESCRIPTION("SIP NAT helper");
 #define DEBUGP(format, args...)
 #endif
 
-extern struct sip_header_nfo ct_sip_hdrs[];
-
 static unsigned int mangle_sip_packet(struct sk_buff **pskb,
                                      enum ip_conntrack_info ctinfo,
                                      struct ip_conntrack *ct,
                                      const char **dptr, size_t dlen,
                                      char *buffer, int bufflen,
-                                     struct sip_header_nfo *hnfo)
+                                     enum sip_header_pos pos)
 {
        unsigned int matchlen, matchoff;
 
-       if (ct_sip_get_info(*dptr, dlen, &matchoff, &matchlen, hnfo) <= 0)
+       if (ct_sip_get_info(*dptr, dlen, &matchoff, &matchlen, pos) <= 0)
                return 0;
 
        if (!ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
@@ -80,47 +78,46 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb,
                if ((ctinfo) < IP_CT_IS_REPLY) {
                        mangle_sip_packet(pskb, ctinfo, ct, dptr,
                                          (*pskb)->len - dataoff,
-                                         buffer, bufflen,
-                                         &ct_sip_hdrs[POS_CONTACT]);
+                                         buffer, bufflen, POS_CONTACT);
                        return 1;
                }
 
                if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
                                       (*pskb)->len - dataoff,
-                                      buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
+                                      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,
                                         (*pskb)->len - dataoff,
-                                        buffer, bufflen,
-                                        &ct_sip_hdrs[POS_CONTACT]);
+                                        buffer, bufflen, POS_CONTACT);
        }
        if ((ctinfo) < IP_CT_IS_REPLY) {
                if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
                                       (*pskb)->len - dataoff,
-                                      buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
+                                      buffer, bufflen, POS_VIA))
                        return 0;
 
                /* Mangle Contact if exists only. - watch udp_nat_mangle()! */
                mangle_sip_packet(pskb, ctinfo, ct, dptr, (*pskb)->len - dataoff,
-                                 buffer, bufflen, &ct_sip_hdrs[POS_CONTACT]);
+                                 buffer, bufflen, POS_CONTACT);
                return 1;
        }
        /* This mangle requests headers. */
        return mangle_sip_packet(pskb, ctinfo, ct, dptr,
                                 ct_sip_lnlen(*dptr,
                                              *dptr + (*pskb)->len - dataoff),
-                                buffer, bufflen, &ct_sip_hdrs[POS_REQ_HEADER]);
+                                buffer, bufflen, POS_REQ_HEADER);
 }
 
 static int mangle_content_len(struct sk_buff **pskb,
@@ -136,7 +133,7 @@ static int mangle_content_len(struct sk_buff **pskb,
 
        /* Get actual SDP lenght */
        if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff,
-                           &matchlen, &ct_sip_hdrs[POS_SDP_HEADER]) > 0) {
+                           &matchlen, POS_SDP_HEADER) > 0) {
 
                /* since ct_sip_get_info() give us a pointer passing 'v='
                   we need to add 2 bytes in this count. */
@@ -144,7 +141,7 @@ static int mangle_content_len(struct sk_buff **pskb,
 
                /* Now, update SDP lenght */
                if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff,
-                                   &matchlen, &ct_sip_hdrs[POS_CONTENT]) > 0) {
+                                   &matchlen, POS_CONTENT) > 0) {
 
                        bufflen = sprintf(buffer, "%u", c_len);
 
@@ -170,17 +167,17 @@ static unsigned int mangle_sdp(struct sk_buff **pskb,
        /* Mangle owner and contact info. */
        bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip));
        if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
-                              buffer, bufflen, &ct_sip_hdrs[POS_OWNER]))
+                              buffer, bufflen, POS_OWNER))
                return 0;
 
        if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
-                              buffer, bufflen, &ct_sip_hdrs[POS_CONNECTION]))
+                              buffer, bufflen, POS_CONNECTION))
                return 0;
 
        /* Mangle media port. */
        bufflen = sprintf(buffer, "%u", port);
        if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
-                              buffer, bufflen, &ct_sip_hdrs[POS_MEDIA]))
+                              buffer, bufflen, POS_MEDIA))
                return 0;
 
        return mangle_content_len(pskb, ctinfo, ct, dptr);
@@ -230,18 +227,17 @@ static unsigned int ip_nat_sdp(struct sk_buff **pskb,
 
 static void __exit fini(void)
 {
-       ip_nat_sip_hook = NULL;
-       ip_nat_sdp_hook = NULL;
-       /* Make sure noone calls it, meanwhile. */
-       synchronize_net();
+       rcu_assign_pointer(ip_nat_sip_hook, NULL);
+       rcu_assign_pointer(ip_nat_sdp_hook, NULL);
+       synchronize_rcu();
 }
 
 static int __init init(void)
 {
-       BUG_ON(ip_nat_sip_hook);
-       BUG_ON(ip_nat_sdp_hook);
-       ip_nat_sip_hook = ip_nat_sip;
-       ip_nat_sdp_hook = ip_nat_sdp;
+       BUG_ON(rcu_dereference(ip_nat_sip_hook));
+       BUG_ON(rcu_dereference(ip_nat_sdp_hook));
+       rcu_assign_pointer(ip_nat_sip_hook, ip_nat_sip);
+       rcu_assign_pointer(ip_nat_sdp_hook, ip_nat_sdp);
        return 0;
 }
 
This page took 0.028371 seconds and 5 git commands to generate.