[sr-dev] git:master: ipops: new cfg function dns_nc_match_ip(hostname, ipaddr)

Daniel-Constantin Mierla miconda at gmail.com
Mon Jul 15 16:13:50 CEST 2013


Hello,

On 7/15/13 10:35 AM, Klaus Darilion wrote:
> Hi Daniel!
>
> Does it both, A and AAAA lookups and can it handle multiple answer RRs?

surely it gets the IPv4 and IPv6 addresses. It is using getaddrinfo() 
for dns query, but I didn't have time to dig in/test all scenarios.

Cheers,
Daniel
>
> regards
> Klaus
>
> On 12.07.2013 13:34, Daniel-Constantin Mierla wrote:
>> Module: sip-router
>> Branch: master
>> Commit: ccebf9e536d7d5ea8fc824ea089d501e888b37c8
>> URL: 
>> http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ccebf9e536d7d5ea8fc824ea089d501e888b37c8
>>
>> Author: Daniel-Constantin Mierla <miconda at gmail.com>
>> Committer: Daniel-Constantin Mierla <miconda at gmail.com>
>> Date:   Fri Jul 12 13:31:12 2013 +0200
>>
>> ipops: new cfg function dns_nc_match_ip(hostname, ipaddr)
>>
>> - do dns query for the hostname and compare the result to see if is a
>>    match with ipaddr
>>
>> ---
>>
>>   modules/ipops/README              |   24 ++++++++++
>>   modules/ipops/doc/ipops_admin.xml |   45 ++++++++++++++++++++
>>   modules/ipops/ipops_mod.c         |   84 
>> +++++++++++++++++++++++++++++++++++++
>>   3 files changed, 153 insertions(+), 0 deletions(-)
>>
>> diff --git a/modules/ipops/README b/modules/ipops/README
>> index bd79553..901535a 100644
>> --- a/modules/ipops/README
>> +++ b/modules/ipops/README
>> @@ -36,6 +36,7 @@ I
>>                 4.8. compare_pure_ips (ip1, ip2)
>>                 4.9. is_ip_rfc1918 (ip)
>>                 4.10. is_in_subnet (ip, subnet)
>> +              4.11. dns_nc_match_ip(hostname, ipaddr)
>>
>>      List of Examples
>>
>> @@ -49,6 +50,7 @@ I
>>      1.8. compare_pure_ips usage
>>      1.9. is_ip_rfc1918 usage
>>      1.10. is_in_subnet usage
>> +   1.11. dns_nc_match_ip usage
>>
>>   Chapter 1. Admin Guide
>>
>> @@ -73,6 +75,7 @@ Chapter 1. Admin Guide
>>           4.8. compare_pure_ips (ip1, ip2)
>>           4.9. is_ip_rfc1918 (ip)
>>           4.10. is_in_subnet (ip, subnet)
>> +        4.11. dns_nc_match_ip(hostname, ipaddr)
>>
>>   1. Overview
>>
>> @@ -124,6 +127,7 @@ Chapter 1. Admin Guide
>>      4.8. compare_pure_ips (ip1, ip2)
>>      4.9. is_ip_rfc1918 (ip)
>>      4.10. is_in_subnet (ip, subnet)
>> +   4.11. dns_nc_match_ip(hostname, ipaddr)
>>
>>   4.1. is_ip (ip)
>>
>> @@ -329,3 +333,23 @@ if (is_in_subnet("10.0.123.123", 
>> "10.0.123.1/24")) {
>>     xlog("L_INFO", "it's in the subnet\n");
>>   }
>>   ...
>> +
>> +4.11. dns_nc_match_ip(hostname, ipaddr)
>> +
>> +   Returns TRUE if ipaddr is associated by DNS to hostname. FALSE
>> +   otherwise. It does not use the internal DNS cache, but directly
>> +   getaddrinfo(...).
>> +
>> +   Parameters:
>> +     * ipaddr - string or pseudo-variable containing the ip address.
>> +     * hostname - string or pseudo-variable containing the hostname. 
>> The
>> +       resulting IP addresses from DNS query are compared with 
>> ipaddress.
>> +
>> +   This function can be used from ANY_ROUTE.
>> +
>> +   Example 1.11. dns_nc_match_ip usage
>> +...
>> +if (!dns_nc_match_ip("myhost.com", "1.2.3.4")) {
>> +    xdbg("ip address not associated with hostname\n");
>> +}
>> +...
>> diff --git a/modules/ipops/doc/ipops_admin.xml 
>> b/modules/ipops/doc/ipops_admin.xml
>> index c7ce810..afb03d8 100644
>> --- a/modules/ipops/doc/ipops_admin.xml
>> +++ b/modules/ipops/doc/ipops_admin.xml
>> @@ -529,6 +529,51 @@ if (is_in_subnet("10.0.123.123", 
>> "10.0.123.1/24")) {
>>
>>       </section>
>>
>> +    <section id="ipops.f.dns_nc_match_ip">
>> +      <title>
>> +        <function moreinfo="none">dns_nc_match_ip(hostname, 
>> ipaddr)</function>
>> +      </title>
>> +
>> +      <para>
>> +          Returns TRUE if ipaddr is associated by DNS to hostname. 
>> FALSE otherwise. It
>> +          does not use the internal DNS cache, but directly 
>> getaddrinfo(...).
>> +      </para>
>> +
>> +      <para>Parameters:</para>
>> +
>> +      <itemizedlist>
>> +        <listitem>
>> +          <para>
>> +            <emphasis>ipaddr</emphasis> - string or pseudo-variable 
>> containing the ip address.
>> +          </para>
>> +        </listitem>
>> +        <listitem>
>> +          <para>
>> +              <emphasis>hostname</emphasis> - string or 
>> pseudo-variable containing the hostname.
>> +              The resulting IP addresses from DNS query are compared 
>> with ipaddress.
>> +          </para>
>> +        </listitem>
>> +      </itemizedlist>
>> +
>> +      <para>
>> +        This function can be used from ANY_ROUTE.
>> +      </para>
>> +
>> +      <example>
>> +        <title>
>> +          <function>dns_nc_match_ip</function> usage
>> +        </title>
>> +        <programlisting format="linespecific">
>> +...
>> +if (!dns_nc_match_ip("myhost.com", "1.2.3.4")) {
>> +    xdbg("ip address not associated with hostname\n");
>> +}
>> +...
>> +        </programlisting>
>> +      </example>
>> +
>> +    </section>
>> +
>>     </section>
>>
>>   </chapter>
>> diff --git a/modules/ipops/ipops_mod.c b/modules/ipops/ipops_mod.c
>> index 164177b..d21546c 100644
>> --- a/modules/ipops/ipops_mod.c
>> +++ b/modules/ipops/ipops_mod.c
>> @@ -40,12 +40,16 @@
>>   #include <stdio.h>
>>   #include <stdlib.h>
>>   #include <string.h>
>> +#include <sys/types.h>
>> +#include <sys/socket.h>
>> +#include <netdb.h>
>>   #include <arpa/inet.h>
>>   #include "../../sr_module.h"
>>   #include "../../dprint.h"
>>   #include "../../str.h"
>>   #include "../../mod_fix.h"
>>   #include "../../pvar.h"
>> +#include "../../resolve.h"
>>   #include "api.h"
>>   #include "ip_parser.h"
>>   #include "rfc1918_parser.h"
>> @@ -83,6 +87,7 @@ static int w_compare_ips(struct sip_msg*, char*, 
>> char*);
>>   static int w_compare_pure_ips(struct sip_msg*, char*, char*);
>>   static int w_is_ip_rfc1918(struct sip_msg*, char*);
>>   static int w_ip_is_in_subnet(struct sip_msg*, char*, char*);
>> +static int w_dns_nc_match_ip(sip_msg_t*, char*, char*);
>>
>>
>>   /*
>> @@ -110,6 +115,8 @@ static cmd_export_t cmds[] =
>> REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
>>     { "is_in_subnet", (cmd_function)w_ip_is_in_subnet, 2, 
>> fixup_spve_spve, 0,
>> REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
>> +  { "dns_nc_match_ip", (cmd_function)w_dns_nc_match_ip, 2, 
>> fixup_spve_spve, 0,
>> +  ANY_ROUTE },
>>     { "bind_ipops", (cmd_function)bind_ipops, 0, 0, 0, 0},
>>     { 0, 0, 0, 0, 0, 0 }
>>   };
>> @@ -596,3 +603,80 @@ static int w_is_ip_rfc1918(struct sip_msg* _msg, 
>> char* _s)
>>     else
>>       return -1;
>>   }
>> +
>> +static inline ip_addr_t *strtoipX(str *ips)
>> +{
>> +    /* try to figure out INET class */
>> +    if(ips->s[0] == '[' || memchr(ips->s, ':', ips->len)!=NULL)
>> +    {
>> +        /* IPv6 */
>> +        return str2ip6(ips);
>> +    } else {
>> +        /* IPv4 */
>> +        return str2ip(ips);
>> +    }
>> +}
>> +
>> +static int w_dns_nc_match_ip(sip_msg_t *msg, char *hnp, char *ipp)
>> +{
>> +    struct addrinfo hints, *res, *p;
>> +    int status;
>> +    ip_addr_t *ipa;
>> +    void *addr;
>> +    str hns;
>> +    str ips;
>> +    struct sockaddr_in *ipv4;
>> +    struct sockaddr_in6 *ipv6;
>> +
>> +    if (fixup_get_svalue(msg, (gparam_p)hnp, &hns))
>> +    {
>> +        LM_ERR("cannot evaluate hostname parameter\n");
>> +        return -2;
>> +    }
>> +
>> +    if (fixup_get_svalue(msg, (gparam_p)ipp, &ips))
>> +    {
>> +        LM_ERR("cannot evaluate ip address parameter\n");
>> +        return -2;
>> +    }
>> +
>> +    ipa = strtoipX(&ips);
>> +    if(ipa==NULL)
>> +    {
>> +        LM_ERR("invalid ip address: %.*s\n", ips.len, ips.s);
>> +        return -3;
>> +    }
>> +
>> +    memset(&hints, 0, sizeof(hints));
>> +    hints.ai_family = AF_UNSPEC; /* allow any of AF_INET or AF_INET6 */
>> +
>> +    if ((status = getaddrinfo(hns.s, NULL, &hints, &res)) != 0)
>> +    {
>> +        LM_ERR("getaddrinfo: %s\n", gai_strerror(status));
>> +        return -2;
>> +    }
>> +
>> +    for(p = res;p != NULL; p = p->ai_next)
>> +    {
>> +        if(p->ai_family==ipa->af)
>> +        {
>> +            if (p->ai_family==AF_INET)
>> +            {
>> +                ipv4 = (struct sockaddr_in *)p->ai_addr;
>> +                addr = &(ipv4->sin_addr);
>> +            } else {
>> +                ipv6 = (struct sockaddr_in6 *)p->ai_addr;
>> +                addr = &(ipv6->sin6_addr);
>> +            }
>> +            if(memcmp(ipa->u.addr, addr, ipa->len)==0)
>> +            {
>> +                /* matched IP */
>> +                freeaddrinfo(res);
>> +                return 1;
>> +            }
>> +        }
>> +    }
>> +    freeaddrinfo(res);
>> +
>> +    return -1;
>> +}
>>
>>
>> _______________________________________________
>> sr-dev mailing list
>> sr-dev at lists.sip-router.org
>> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
>>

-- 
Daniel-Constantin Mierla - http://www.asipto.com
http://twitter.com/#!/miconda - http://www.linkedin.com/in/miconda




More information about the sr-dev mailing list