~kf5jwc/dns-server-rs

b466c1c15c45fabe5651820d3ae6382acb2e3db1 — Kyle Jones 6 months ago 50d06f2
$ rustfmt
M src/bin/packet_parser.rs => src/bin/packet_parser.rs +5 -8
@@ 1,21 1,18 @@
extern crate log;
extern crate env_logger;
extern crate dns_server;
extern crate env_logger;
extern crate log;
extern crate structopt;

use std::path::PathBuf;
use dns_server::{BytePacketBuffer, DnsPacket};
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
use structopt::StructOpt;
use dns_server::{
    BytePacketBuffer,
    DnsPacket,
};

#[derive(Debug, StructOpt)]
#[structopt()]
struct Args {
    #[structopt(parse(from_os_str), default_value="packets/response_packet")]
    #[structopt(parse(from_os_str), default_value = "packets/response_packet")]
    packet_file: PathBuf,
}


M src/bin/proxy_resolver.rs => src/bin/proxy_resolver.rs +58 -36
@@ 1,30 1,24 @@
extern crate log;
extern crate dns_server;
extern crate env_logger;
extern crate log;
extern crate rand;
extern crate structopt;
extern crate dns_server;

use dns_server::{BytePacketBuffer, DnsPacket, DnsQuestion, QueryType, ResultCode};
use log::{debug, info, trace, warn};
use rand::Rng;
use std::io;
use std::net::{IpAddr, SocketAddr, UdpSocket};
use log::{warn, info, debug, trace};
use rand::Rng;
use structopt::StructOpt;
use dns_server::{
    BytePacketBuffer,
    DnsPacket,
    DnsQuestion,
    QueryType,
    ResultCode,
};

#[derive(Debug, StructOpt)]
#[structopt()]
struct Args {
    #[structopt(short="h", parse(try_from_str), default_value="0.0.0.0")]
    #[structopt(short = "h", parse(try_from_str), default_value = "0.0.0.0")]
    server_host: IpAddr,
    #[structopt(short="p", default_value="5655")]
    #[structopt(short = "p", default_value = "5655")]
    server_port: u16,
    #[structopt(short="u", parse(try_from_str), default_value="192.168.1.1")]
    #[structopt(short = "u", parse(try_from_str), default_value = "192.168.1.1")]
    upstream_server: IpAddr,
}



@@ 40,31 34,41 @@ fn main() {
    env_logger::init();
    let args = Args::from_args();

    info!("Starting server on {}:{}", args.server_host, args.server_port);
    let server_socket = UdpSocket::bind((args.server_host, args.server_port)).expect("Opening server listen socket");
    info!(
        "Starting server on {}:{}",
        args.server_host, args.server_port
    );
    let server_socket = UdpSocket::bind((args.server_host, args.server_port))
        .expect("Opening server listen socket");

    loop {
        let (request_source, request_packet): (_, DnsPacket) = match stage_1(&server_socket) {
            Ok((src, request_buffer)) => {
                info!("Recieved request from {:?}", src);
                (src, request_buffer.into())
            },
            }
            Err(e) => {
                warn!("An error occurred while reading request from socket: {}", e);
                continue;
            },
            }
        };

        if request_packet.questions.is_empty() {
            info!("Request packet contains no questions!");
            send_failure_response(&server_socket, &request_source, &request_packet, ResultCode::FORMERR);
            send_failure_response(
                &server_socket,
                &request_source,
                &request_packet,
                ResultCode::FORMERR,
            );
            continue;
        }

        let question = &request_packet.questions[0];
        debug!("Recv'd query: {:?}", question);

        let upstream_socket = UdpSocket::bind(("0.0.0.0", 43102)).expect("Opening upstream request socket");
        let upstream_socket =
            UdpSocket::bind(("0.0.0.0", 43102)).expect("Opening upstream request socket");

        debug!("Preparing upstream request");
        let upstream_packet = build_dns_query_packet(question.name.clone(), question.qtype.clone());


@@ 72,23 76,36 @@ fn main() {

        debug!("Sending upstream request");
        match upstream_socket.send_to(upstream_buffer.raw_buffer(), (args.upstream_server, 53)) {
            Ok(_) => {},
            Ok(_) => {}
            Err(e) => {
                warn!("Unable to send the upstream request: {:?}", e);
                send_failure_response(&server_socket, &request_source, &request_packet, ResultCode::SERVFAIL);
                send_failure_response(
                    &server_socket,
                    &request_source,
                    &request_packet,
                    ResultCode::SERVFAIL,
                );
                continue;
            },
            }
        }

        debug!("Receiving upstream response");
        let mut upstream_response_buffer = BytePacketBuffer::default();
        match upstream_socket.recv_from(&mut upstream_response_buffer.buf) {
            Ok(_) => {},
            Ok(_) => {}
            Err(e) => {
                warn!("Error occurred while attempting to recv an upstream response: {:?}", e);
                send_failure_response(&server_socket, &request_source, &request_packet, ResultCode::SERVFAIL);
                warn!(
                    "Error occurred while attempting to recv an upstream response: {:?}",
                    e
                );
                send_failure_response(
                    &server_socket,
                    &request_source,
                    &request_packet,
                    ResultCode::SERVFAIL,
                );
                continue;
            },
            }
        }

        debug!("Parsing upstream response");


@@ 100,19 117,19 @@ fn main() {
        info!("Sending response packet");
        let response_buffer: BytePacketBuffer = response_packet.into();
        match server_socket.send_to(response_buffer.raw_buffer(), request_source) {
            Ok(_) => {},
            Ok(_) => {}
            Err(e) => {
                warn!("Failed to send response: {:?}", e);
                continue;
            },
            }
        }


    }

}

fn build_response_packet(request_packet: DnsPacket, upstream_response_packet: DnsPacket) -> DnsPacket {
fn build_response_packet(
    request_packet: DnsPacket,
    upstream_response_packet: DnsPacket,
) -> DnsPacket {
    let mut response_packet = DnsPacket::default();
    response_packet.header.id = request_packet.header.id;
    response_packet.header.recursion_desired = true;


@@ 142,13 159,18 @@ fn build_response_packet(request_packet: DnsPacket, upstream_response_packet: Dn
    return response_packet;
}

fn send_failure_response(server_socket: &UdpSocket, request_source: &SocketAddr, request_packet: &DnsPacket, result_code: ResultCode) {
fn send_failure_response(
    server_socket: &UdpSocket,
    request_source: &SocketAddr,
    request_packet: &DnsPacket,
    result_code: ResultCode,
) {
    let mut response_packet = DnsPacket::default();
    response_packet.header.id = request_packet.header.id;
    response_packet.header.rescode = result_code;
    let response_buffer: BytePacketBuffer = response_packet.into();
    match server_socket.send_to(response_buffer.raw_buffer(), request_source) {
        Ok(_) => {},
        Ok(_) => {}
        Err(e) => warn!("Failed to send response buffer: {:?}", e),
    };
}


@@ 160,7 182,7 @@ fn build_dns_query_packet(name: String, qtype: QueryType) -> DnsPacket {
    packet.header.questions = 1;
    packet.header.recursion_desired = true;
    packet.questions.push({
        DnsQuestion{
        DnsQuestion {
            name: name,
            qtype: qtype,
        }

M src/bin/stub_resolver.rs => src/bin/stub_resolver.rs +12 -15
@@ 1,31 1,26 @@
extern crate log;
extern crate dns_server;
extern crate env_logger;
extern crate log;
extern crate rand;
extern crate structopt;
extern crate dns_server;

use dns_server::{BytePacketBuffer, DnsPacket, DnsQuestion, QueryType};
use log::info;
use rand::Rng;
use std::net::IpAddr;
use std::net::UdpSocket;
use log::{info, debug};
use rand::Rng;
use structopt::StructOpt;
use dns_server::{
    BytePacketBuffer,
    DnsPacket,
    DnsQuestion,
    QueryType,
};

#[derive(Debug, StructOpt)]
#[structopt()]
struct Args {
    #[structopt()]
    domain: String,
    #[structopt(short, parse(try_from_str), default_value="A")]
    #[structopt(short, parse(try_from_str), default_value = "A")]
    record_type: QueryType,
    #[structopt(short, parse(try_from_str), default_value="192.168.1.1")]
    #[structopt(short, parse(try_from_str), default_value = "192.168.1.1")]
    server: IpAddr,
    #[structopt(short, parse(try_from_str), default_value="53")]
    #[structopt(short, parse(try_from_str), default_value = "53")]
    port: u16,
}



@@ 41,7 36,9 @@ fn main() {
    let server = (args.server, args.port);
    let socket = UdpSocket::bind(("0.0.0.0", 43120)).expect("Opening upstream request socket");
    info!("Sending request to server");
    socket.send_to(&req_buffer.buf[0..req_buffer.pos], server).expect("Sending message to upstream server");
    socket
        .send_to(&req_buffer.buf[0..req_buffer.pos], server)
        .expect("Sending message to upstream server");

    info!("Awaiting response from server");
    let mut res_buffer = BytePacketBuffer::default();


@@ 72,7 69,7 @@ fn make_dns_query_packet(qname: String, qtype: QueryType) -> DnsPacket {
    packet.header.questions = 1;
    packet.header.recursion_desired = true;
    packet.questions.push({
        DnsQuestion{
        DnsQuestion {
            name: qname,
            qtype: qtype,
        }

M src/dns_packet.rs => src/dns_packet.rs +19 -9
@@ 1,14 1,14 @@
mod byte_packet_buffer;
mod dns_header;
mod dns_question;
mod dns_record;
mod byte_packet_buffer;
mod query_type;

use log::debug;
pub use byte_packet_buffer::BytePacketBuffer;
pub use dns_header::{DnsHeader, ResultCode};
pub use dns_question::DnsQuestion;
pub use dns_record::DnsRecord;
use log::debug;
pub use query_type::QueryType;

#[derive(Default, Clone, Debug)]


@@ 36,16 36,21 @@ impl Into<BytePacketBuffer> for DnsPacket {
        self.header.write(&mut buffer).expect("Writing to header");

        for question in &self.questions {
            question.write(&mut buffer).expect("Writing questions to buffer");
            question
                .write(&mut buffer)
                .expect("Writing questions to buffer");
        }
        for rec in &self.answers {
            rec.write(&mut buffer).expect("Writing answer records to buffer");
            rec.write(&mut buffer)
                .expect("Writing answer records to buffer");
        }
        for rec in &self.authorities {
            rec.write(&mut buffer).expect("Writing authority records to buffer");
            rec.write(&mut buffer)
                .expect("Writing authority records to buffer");
        }
        for rec in &self.resources {
            rec.write(&mut buffer).expect("Writing resource records to buffer");
            rec.write(&mut buffer)
                .expect("Writing resource records to buffer");
        }
        return buffer;
    }


@@ 54,14 59,19 @@ impl Into<BytePacketBuffer> for DnsPacket {
impl From<BytePacketBuffer> for DnsPacket {
    fn from(mut buffer: BytePacketBuffer) -> Self {
        let mut result = DnsPacket::default();
        result.header.read(&mut buffer).expect("Error reading header from packet buffer!");
        result
            .header
            .read(&mut buffer)
            .expect("Error reading header from packet buffer!");

        for _ in 0..result.header.questions {
            let mut question = DnsQuestion{
            let mut question = DnsQuestion {
                name: "".to_string(),
                qtype: QueryType::UNKNOWN(0),
            };
            question.read(&mut buffer).expect("Error reading question from packet buffer!");
            question
                .read(&mut buffer)
                .expect("Error reading question from packet buffer!");
            result.questions.push(question);
        }


M src/dns_packet/byte_packet_buffer.rs => src/dns_packet/byte_packet_buffer.rs +16 -15
@@ 37,7 37,7 @@ impl BytePacketBuffer {
        if start + len >= self.buf.len() {
            return Err(Error::new(ErrorKind::InvalidInput, "End of buffer"));
        }
        Ok(&self.buf[start..start+len as usize])
        Ok(&self.buf[start..start + len as usize])
    }

    pub fn raw_buffer(&self) -> &[u8] {


@@ 50,20 50,19 @@ impl BytePacketBuffer {
        }

        self.pos += 1;
        Ok(self.buf[self.pos-1])
        Ok(self.buf[self.pos - 1])
    }

    pub fn read_u16(&mut self) -> Result<u16> {
        let res = ((self.read()? as u16) << 8) |
                  ((self.read()? as u16) << 0);
        let res = ((self.read()? as u16) << 8) | ((self.read()? as u16) << 0);
        Ok(res)
    }

    pub fn read_u32(&mut self) -> Result<u32> {
        let res = ((self.read()? as u32) << 24) |
                  ((self.read()? as u32) << 16) |
                  ((self.read()? as u32) <<  8) |
                  ((self.read()? as u32) <<  0);
        let res = ((self.read()? as u32) << 24)
            | ((self.read()? as u32) << 16)
            | ((self.read()? as u32) << 8)
            | ((self.read()? as u32) << 0);
        Ok(res)
    }



@@ 82,12 81,12 @@ impl BytePacketBuffer {
            if (len & 0xC0) == 0xC0 {
                debug!("Jumping");
                if !jumped {
                    debug!("Seeking: {:?}", local_pos+2);
                    self.seek(local_pos+2)?;
                    debug!("Seeking: {:?}", local_pos + 2);
                    self.seek(local_pos + 2)?;
                }

                debug!("get({:?})", local_pos+1);
                let b2 = self.get(local_pos+1)? as u16;
                debug!("get({:?})", local_pos + 1);
                let b2 = self.get(local_pos + 1)? as u16;
                debug!("-> {:?}", b2);
                let offset = (((len as u16) ^ 0xC0) << 8) | b2;
                local_pos = offset as usize;


@@ 154,7 153,10 @@ impl BytePacketBuffer {
        for label in domain_parts {
            let len = label.len();
            if len > 0x34 {
                return Err(Error::new(ErrorKind::InvalidInput, "Single label exceeds 63 characters of length"));
                return Err(Error::new(
                    ErrorKind::InvalidInput,
                    "Single label exceeds 63 characters of length",
                ));
            }

            self.write_u8(len as u8)?;


@@ 180,9 182,8 @@ impl BytePacketBuffer {
    pub fn set_u16(&mut self, pos: usize, val: u16) -> Result<()> {
        let shifts: &[u8] = &[8, 0];
        for (pos_modifier, shift) in shifts.iter().enumerate() {
            self.set(pos+pos_modifier, ((val >> shift) & 0xFF) as u8)?
            self.set(pos + pos_modifier, ((val >> shift) & 0xFF) as u8)?
        }
        Ok(())
    }

}

M src/dns_packet/dns_header.rs => src/dns_packet/dns_header.rs +11 -11
@@ 1,8 1,8 @@
mod result_code;

use std::io::Result;
use super::BytePacketBuffer;
pub use result_code::ResultCode;
use std::io::Result;

#[derive(Default, Clone, Debug)]
pub struct DnsHeader {


@@ 51,17 51,17 @@ impl DnsHeader {
    }

    pub fn write(&self, buffer: &mut BytePacketBuffer) -> Result<()> {
        let mask1 = ((self.recursion_desired as u8) << 0) |
                    ((self.truncated_message as u8) << 1) |
                    ((self.authoritative_answer as u8) << 2) |
                    ((self.opcode) << 3) |
                    ((self.response as u8) << 7);
        let mask1 = ((self.recursion_desired as u8) << 0)
            | ((self.truncated_message as u8) << 1)
            | ((self.authoritative_answer as u8) << 2)
            | ((self.opcode) << 3)
            | ((self.response as u8) << 7);

        let mask2 = ((self.rescode.clone() as u8) << 0) |
                    ((self.checking_disabled as u8) << 4) |
                    ((self.authed_data as u8) << 5) |
                    ((self.z as u8) << 6) |
                    ((self.recursion_available as u8) << 7);
        let mask2 = ((self.rescode.clone() as u8) << 0)
            | ((self.checking_disabled as u8) << 4)
            | ((self.authed_data as u8) << 5)
            | ((self.z as u8) << 6)
            | ((self.recursion_available as u8) << 7);

        buffer.write_u16(self.id)?;
        buffer.write_u8(mask1 as u8)?;

M src/dns_packet/dns_header/result_code.rs => src/dns_packet/dns_header/result_code.rs +1 -1
@@ 1,4 1,4 @@
#[derive(Copy,Clone,Debug,PartialEq,Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ResultCode {
    NOERROR = 0,
    FORMERR = 1,

M src/dns_packet/dns_question.rs => src/dns_packet/dns_question.rs +2 -2
@@ 1,8 1,8 @@
use std::io::Result;
use super::BytePacketBuffer;
use super::QueryType;
use std::io::Result;

#[derive(Debug,Clone,PartialEq,Eq)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DnsQuestion {
    pub name: String,
    pub qtype: QueryType,

M src/dns_packet/dns_record.rs => src/dns_packet/dns_record.rs +82 -55
@@ 1,42 1,42 @@
use std::io::Result;
use std::net::{Ipv4Addr, Ipv6Addr};
use super::BytePacketBuffer;
use super::QueryType;
use std::io::Result;
use std::net::{Ipv4Addr, Ipv6Addr};

#[derive(Debug,Clone,PartialEq,Eq,Hash,PartialOrd,Ord)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[allow(dead_code)]
pub enum DnsRecord {
    UNKNOWN {
        domain: String,
        qtype: u16,
        data_len: u16,
        ttl: u32
        ttl: u32,
    }, // 0
    A {
        domain: String,
        addr: Ipv4Addr,
        ttl: u32
        ttl: u32,
    }, // 1
    NS {
        domain: String,
        host: String,
        ttl: u32
        ttl: u32,
    }, // 2
    CNAME {
        domain: String,
        host: String,
        ttl: u32
        ttl: u32,
    }, // 5
    MX {
        domain: String,
        priority: u16,
        host: String,
        ttl: u32
        ttl: u32,
    }, // 15
    AAAA {
        domain: String,
        addr: Ipv6Addr,
        ttl: u32
        ttl: u32,
    }, // 28
}



@@ 51,67 51,73 @@ impl DnsRecord {
        match qtype {
            QueryType::A => {
                let raw_addr = buffer.read_u32().expect("Next raw address group");
                let addr_groups: Vec<u8> = [24u8, 16, 8, 0].iter()
                let addr_groups: Vec<u8> = [24u8, 16, 8, 0]
                    .iter()
                    .map(|shift| ((raw_addr >> shift) & 0xFF) as u8)
                    .collect();
                let addr = Ipv4Addr::new(addr_groups[0], addr_groups[1], addr_groups[2], addr_groups[3]);
                let addr = Ipv4Addr::new(
                    addr_groups[0],
                    addr_groups[1],
                    addr_groups[2],
                    addr_groups[3],
                );

                Ok(DnsRecord::A {
                    domain: domain,
                    addr: addr,
                    ttl: ttl,
                })
            },
            }
            QueryType::AAAA => {
                let raw_addrs: Vec<u32> = (0..8).map(|_| buffer.read_u32().expect("Next raw address group")).collect();
                let raw_addrs: Vec<u32> = (0..8)
                    .map(|_| buffer.read_u32().expect("Next raw address group"))
                    .collect();
                let addr_groups: Vec<u16> = {
                    let shifts = vec![16u8, 0].into_iter().fuse();
                    raw_addrs
                        .iter()
                        .zip(shifts)
                        .map(|(raw_addr, shift)| {
                            ((raw_addr >> shift) & 0xFFFF) as u16
                        })
                        .map(|(raw_addr, shift)| ((raw_addr >> shift) & 0xFFFF) as u16)
                        .collect()
                };
                let addr = Ipv6Addr::new(
                    addr_groups[0], addr_groups[1], addr_groups[2], addr_groups[3],
                    addr_groups[4], addr_groups[5], addr_groups[6], addr_groups[7],
                    );
                    addr_groups[0],
                    addr_groups[1],
                    addr_groups[2],
                    addr_groups[3],
                    addr_groups[4],
                    addr_groups[5],
                    addr_groups[6],
                    addr_groups[7],
                );

                Ok(DnsRecord::AAAA {
                    domain: domain,
                    addr: addr,
                    ttl: ttl,
                })
            },
            }

            // NS and CNAME both have the same structure.
            QueryType::NS => {
                Ok(DnsRecord::NS {
                    domain: domain,
                    host: buffer.read_qname()?,
                    ttl: ttl
                })
            },

            QueryType::CNAME => {
                Ok(DnsRecord::CNAME {
                    domain: domain,
                    host: buffer.read_qname()?,
                    ttl: ttl
                })
            },
            QueryType::NS => Ok(DnsRecord::NS {
                domain: domain,
                host: buffer.read_qname()?,
                ttl: ttl,
            }),

            QueryType::CNAME => Ok(DnsRecord::CNAME {
                domain: domain,
                host: buffer.read_qname()?,
                ttl: ttl,
            }),

            // MX is almost like the previous two, but with one extra field for priority.
            QueryType::MX => {
                Ok(DnsRecord::MX {
                    domain: domain,
                    priority: buffer.read_u16()?,
                    host: buffer.read_qname()?,
                    ttl: ttl
                })
            },
            QueryType::MX => Ok(DnsRecord::MX {
                domain: domain,
                priority: buffer.read_u16()?,
                host: buffer.read_qname()?,
                ttl: ttl,
            }),

            QueryType::UNKNOWN(qtype_num) => {
                buffer.step(data_len as usize)?;


@@ 130,7 136,11 @@ impl DnsRecord {
        let start_pos = buffer.pos;

        match *self {
            Self::A { ref domain, ref addr, ttl } => {
            Self::A {
                ref domain,
                ref addr,
                ttl,
            } => {
                buffer.write_qname(domain)?;
                buffer.write_u16(QueryType::A.into())?;
                buffer.write_u16(1)?;


@@ 142,9 152,13 @@ impl DnsRecord {
                buffer.write_u8(octets[1])?;
                buffer.write_u8(octets[2])?;
                buffer.write_u8(octets[3])?;
            },
            }

            Self::NS { ref domain, ref host, ttl } => {
            Self::NS {
                ref domain,
                ref host,
                ttl,
            } => {
                buffer.write_qname(domain)?;
                buffer.write_u16(QueryType::NS.into())?;
                buffer.write_u16(1)?;


@@ 156,9 170,13 @@ impl DnsRecord {

                let size = buffer.pos - (pre_pos + 2);
                buffer.set_u16(pre_pos, size as u16)?;
            },
            }

            Self::CNAME { ref domain, ref host, ttl } => {
            Self::CNAME {
                ref domain,
                ref host,
                ttl,
            } => {
                buffer.write_qname(domain)?;
                buffer.write_u16(QueryType::CNAME.into())?;
                buffer.write_u16(1)?;


@@ 170,9 188,14 @@ impl DnsRecord {

                let size = buffer.pos - (pre_pos + 2);
                buffer.set_u16(pre_pos, size as u16)?;
            },
            }

            Self::MX { ref domain, priority, ref host, ttl } => {
            Self::MX {
                ref domain,
                priority,
                ref host,
                ttl,
            } => {
                buffer.write_qname(domain)?;
                buffer.write_u16(QueryType::MX.into())?;
                buffer.write_u16(1)?;


@@ 186,9 209,13 @@ impl DnsRecord {

                let size = buffer.pos - (pre_pos + 2);
                buffer.set_u16(pre_pos, size as u16)?;
            },
            }

            Self::AAAA { ref domain, ref addr, ttl } => {
            Self::AAAA {
                ref domain,
                ref addr,
                ttl,
            } => {
                buffer.write_qname(domain)?;
                buffer.write_u16(QueryType::AAAA.into())?;
                buffer.write_u16(1)?;


@@ 198,11 225,11 @@ impl DnsRecord {
                for octet in &addr.segments() {
                    buffer.write_u16(*octet)?;
                }
            },
            }

            Self:: UNKNOWN { .. } => {
            Self::UNKNOWN { .. } => {
                println!("Skipping record: {:?}", self);
            },
            }
        }

        Ok(buffer.pos - start_pos)

M src/dns_packet/query_type.rs => src/dns_packet/query_type.rs +8 -8
@@ 1,16 1,16 @@
use std::str::FromStr;

#[derive(PartialEq,Eq,Debug,Clone,Hash,Copy)]
#[derive(PartialEq, Eq, Debug, Clone, Hash, Copy)]
pub enum QueryType {
    UNKNOWN(u16),
    A, // 1
    NS, // 2
    AAAA, // 28
    A,     // 1
    NS,    // 2
    AAAA,  // 28
    CNAME, // 5
    MX, // 15
    //SRV, // ?
    //CERT, // ?
    //TXT, // ?
    MX,    // 15
           //SRV, // ?
           //CERT, // ?
           //TXT, // ?
}

impl Into<u16> for QueryType {

M src/lib.rs => src/lib.rs +1 -7
@@ 1,9 1,3 @@
mod dns_packet;

pub use dns_packet::{
    BytePacketBuffer,
    DnsPacket,
    DnsQuestion,
    ResultCode,
    QueryType,
};
pub use dns_packet::{BytePacketBuffer, DnsPacket, DnsQuestion, QueryType, ResultCode};