ipquery 0.1.1

Tool to query your own public IP address.
Documentation
use std::net::*;
use std::str::FromStr;
use trust_dns::client::{Client, SyncClient};
use trust_dns::op::DnsResponse;
use trust_dns::rr::{DNSClass, Name, RData, Record, RecordType};
use trust_dns::udp::UdpClientConnection;
use failure::*;

mod dns_ip;
pub use dns_ip::{Provider as DnsIpProvider};

#[derive(Fail, Debug)]
enum Errors {
    #[fail(display = "No response.")]
    NoResponse,
}

pub enum Provider {
    OpenDNS,
}

impl Default for Provider {
    fn default() -> Provider {
        Provider::OpenDNS
    }
}

impl Provider {
    pub fn query_ipv4(&self) -> Result<Ipv4Addr, Error> {
        match self {
            Provider::OpenDNS => self.query_ipv4_opendns(),
        }
    }

    pub fn query_ipv6(&self) -> Result<Ipv6Addr, Error> {
        match self {
            Provider::OpenDNS => self.query_ipv6_opendns(),
        }
    }

    fn query_ipv4_opendns(&self) -> Result<Ipv4Addr, Error> {
        let address = "208.67.222.222:53".parse()?;
        let conn = UdpClientConnection::new(address)?;
        let client = SyncClient::new(conn);

        let name = Name::from_str("myip.opendns.com.")?;

        let response: DnsResponse = client.query(&name, DNSClass::IN, RecordType::A)?;

        let answers: &[Record] = response.answers();

        if let &RData::A(ref ip) = answers[0].rdata() {
            Ok(*ip)
        } else {
            bail!(Errors::NoResponse)
        }
    }

    fn query_ipv6_opendns(&self) -> Result<Ipv6Addr, Error> {
        let address = "[2620:119:35::35]:53".parse()?;
        let conn = UdpClientConnection::new(address)?;
        let client = SyncClient::new(conn);

        let name = Name::from_str("myip.opendns.com.")?;

        let response: DnsResponse = client.query(&name, DNSClass::IN, RecordType::AAAA)?;

        let answers: &[Record] = response.answers();

        if let &RData::AAAA(ref ip) = answers[0].rdata() {
            Ok(*ip)
        } else {
            bail!(Errors::NoResponse)
        }
    }
}