diff options
-rw-r--r-- | include/dns.h | 43 | ||||
-rw-r--r-- | src/dns.cpp | 59 | ||||
-rw-r--r-- | src/modules/m_testcommand.cpp | 24 |
3 files changed, 103 insertions, 23 deletions
diff --git a/include/dns.h b/include/dns.h index 8550e5e70..a769f11bc 100644 --- a/include/dns.h +++ b/include/dns.h @@ -92,10 +92,13 @@ typedef requestlist::iterator requestlist_iter; */ enum QueryType { - DNS_QUERY_A = 1, /* 'A' record: an ipv4 address */ - DNS_QUERY_CNAME = 5, /* 'CNAME' record: An alias */ - DNS_QUERY_PTR = 12, /* 'PTR' record: a hostname */ - DNS_QUERY_AAAA = 28, /* 'AAAA' record: an ipv6 address */ + DNS_QUERY_A = 1, /* 'A' record: an ipv4 address */ + DNS_QUERY_CNAME = 5, /* 'CNAME' record: An alias */ + DNS_QUERY_PTR = 12, /* 'PTR' record: a hostname */ + DNS_QUERY_AAAA = 28, /* 'AAAA' record: an ipv6 address */ + + DNS_QUERY_PTR4 = 0xFFFD, /* Force 'PTR' to use IPV4 scemantics */ + DNS_QUERY_PTR6 = 0xFFFE, /* Force 'PTR' to use IPV6 scemantics */ }; #ifdef IPV6 @@ -107,6 +110,16 @@ const QueryType DNS_QUERY_REVERSE = DNS_QUERY_PTR; #endif /** + * Used internally to force PTR lookups to use a certain protocol scemantics, + * e.g. x.x.x.x.in-addr.arpa for v4, and *.ip6.int for v6. + */ +enum ForceProtocol +{ + PROTOCOL_IPV4 = 0, /* Forced to use ipv4 */ + PROTOCOL_IPV6 = 1 /* Forced to use ipv6 */ +}; + +/** * The Resolver class is a high-level abstraction for resolving DNS entries. * It can do forward and reverse IPv4 lookups, and where IPv6 is supported, will * also be able to do those, transparent of protocols. Module developers must @@ -155,9 +168,13 @@ class Resolver : public Extensible * is supported. Use one of the QueryType enum values to initiate this type of * lookup. Resolution of 'AAAA' ipv6 records is always supported, regardless of * wether InspIRCd is built with ipv6 support. - * If you attempt to resolve a 'PTR' record and InspIRCd is built with ipv6 support, - * the 'PTR' record will be formatted to ipv6 specs, e.g. x.x.x.x.x....ip6.int. - * otherwise it will be formatted to ipv4 specs, e.g. x.x.x.x.in-addr.arpa. + * If you attempt to resolve a 'PTR' record using DNS_QUERY_PTR, and InspIRCd is + * built with ipv6 support, the 'PTR' record will be formatted to ipv6 specs, + * e.g. x.x.x.x.x....ip6.int. otherwise it will be formatted to ipv4 specs, + * e.g. x.x.x.x.in-addr.arpa. This is automatic. + * To get around this automatic behaviour, you must use one of the values + * DNS_QUERY_PTR4 or DNS_QUERY_PTR6 to force ipv4 or ipv6 behaviour on the lookup, + * irrespective of what protocol InspIRCd has been built for. * @throw ModuleException This class may throw an instance of ModuleException, in the * event a lookup could not be allocated, or a similar hard error occurs such as * the network being down. This will also be thrown if an invalid IP address is @@ -266,11 +283,21 @@ class DNS : public Extensible int GetIP(const char* name); /** - * Start the lookup of a hostname from an ip + * Start the lookup of a hostname from an ip, + * always using the protocol inspircd is built for, + * e.g. use ipv6 reverse lookup when built for ipv6, + * or ipv4 lookup when built for ipv4. */ int GetName(const insp_inaddr* ip); /** + * Start lookup of a hostname from an ip, but + * force a specific protocol to be used for the lookup + * for example to perform an ipv6 reverse lookup. + */ + int GetNameForce(const char *ip, ForceProtocol fp); + + /** * Start lookup of an ipv6 from a hostname */ int GetIP6(const char *name); diff --git a/src/dns.cpp b/src/dns.cpp index fac10d98e..2c4cd807b 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -423,6 +423,51 @@ int DNS::GetName(const insp_inaddr *ip) return id; } +/* Start lookup of an IP address to a hostname */ +int DNS::GetNameForce(const char *ip, ForceProtocol fp) +{ + char query[128]; + DNSHeader h; + int id; + int length; + + if (fp == PROTOCOL_IPV6) + { + in6_addr i; + if (inet_pton(AF_INET6, ip, &i) > 0) + { + DNS::MakeIP6Int(query, &i); + } + else + /* Invalid IP address */ + return -1; + } + else + { + in_addr i; + if (inet_aton(ip, &i)) + { + unsigned char* c = (unsigned char*)&i.s_addr; + sprintf(query,"%d.%d.%d.%d.in-addr.arpa",c[3],c[2],c[1],c[0]); + } + else + /* Invalid IP address */ + return -1; + } + + log(DEBUG,"DNS::GetNameForce: %s %d",query, fp); + + if ((length = this->MakePayload(query, DNS_QUERY_PTR, 1, (unsigned char*)&h.payload)) == -1) + return -1; + + DNSRequest* req = this->AddQuery(&h, id); + + if ((!req) || (req->SendRequests(&h, length, DNS_QUERY_PTR) == -1)) + return -1; + + return id; +} + void DNS::MakeIP6Int(char* query, const in6_addr *ip) { const char* hex = "0123456789abcdef"; @@ -568,6 +613,10 @@ DNSResult DNS::GetResult() /* Reverse lookups just come back as char* */ resultstr = std::string((const char*)data.first); break; + + default: + log(DEBUG,"WARNING: Somehow we made a request for a DNS_QUERY_PTR4 or DNS_QUERY_PTR6, but these arent real rr types!"); + break; } @@ -748,6 +797,16 @@ Resolver::Resolver(const std::string &source, QueryType qt) : input(source), que } break; + case DNS_QUERY_PTR4: + querytype = DNS_QUERY_PTR; + this->myid = ServerInstance->Res->GetNameForce(source.c_str(), PROTOCOL_IPV4); + break; + + case DNS_QUERY_PTR6: + querytype = DNS_QUERY_PTR; + this->myid = ServerInstance->Res->GetNameForce(source.c_str(), PROTOCOL_IPV6); + break; + case DNS_QUERY_AAAA: this->myid = ServerInstance->Res->GetIP6(source.c_str()); break; diff --git a/src/modules/m_testcommand.cpp b/src/modules/m_testcommand.cpp index cca30de5d..6f517e8ce 100644 --- a/src/modules/m_testcommand.cpp +++ b/src/modules/m_testcommand.cpp @@ -27,24 +27,16 @@ using namespace std; class MyV6Resolver : public Resolver { + bool fw; public: - MyV6Resolver(const std::string &source) : Resolver(source, DNS_QUERY_AAAA) { } + MyV6Resolver(const std::string &source, bool forward) : Resolver(source, forward ? DNS_QUERY_AAAA : DNS_QUERY_PTR6) + { + fw = forward; + } virtual void OnLookupComplete(const std::string &result) { - log(DEBUG,"*** RESOLVER COMPLETED LOOKUP, IP IS: '%s'",result.c_str()); - - char query[128]; - in6_addr n; - if (inet_pton(AF_INET6, result.c_str(), &n) > 0) - { - DNS::MakeIP6Int(query, &n); - log(DEBUG,"Translation: %s",query); - } - else - { - log(DEBUG,"Bad IPV6 IP: %s",result.c_str()); - } + log(DEBUG,"*** RESOLVER COMPLETED %s LOOKUP, IP IS: '%s'",fw ? "FORWARD" : "REVERSE", result.c_str()); } virtual void OnError(ResolverError e, const std::string &errormessage) @@ -70,7 +62,9 @@ class cmd_woot : public command_t try { - MyV6Resolver* r = new MyV6Resolver("shake.stacken.kth.se"); + MyV6Resolver* r = new MyV6Resolver("shake.stacken.kth.se", true); + Srv->AddResolver(r); + r = new MyV6Resolver("2001:6b0:1:ea:202:a5ff:fecd:13a6", false); Srv->AddResolver(r); } catch (ModuleException& e) |