~kf5jwc/dns-server-rs

ref: b466c1c15c45fabe5651820d3ae6382acb2e3db1 dns-server-rs/src/bin/stub_resolver.rs -rw-r--r-- 2.2 KiB View raw
b466c1c1 — Kyle Jones $ rustfmt 6 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
extern crate dns_server;
extern crate env_logger;
extern crate log;
extern crate rand;
extern crate structopt;

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

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

fn main() {
    env_logger::init();
    let args = Args::from_args();

    info!("Generating query packet");
    let packet = make_dns_query_packet(args.domain, args.record_type);
    let req_buffer: BytePacketBuffer = packet.into();

    info!("Starting resolver");
    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");

    info!("Awaiting response from server");
    let mut res_buffer = BytePacketBuffer::default();
    socket.recv_from(&mut res_buffer.buf).unwrap();

    info!("Parsing response");
    let res_packet: DnsPacket = res_buffer.into();
    println!("{:?}", res_packet.header);

    for q in res_packet.questions {
        println!("{:?}", q);
    }
    for rec in res_packet.answers {
        println!("{:?}", rec);
    }
    for rec in res_packet.authorities {
        println!("{:?}", rec);
    }
    for rec in res_packet.resources {
        println!("{:?}", rec);
    }
}

fn make_dns_query_packet(qname: String, qtype: QueryType) -> DnsPacket {
    let mut rng = rand::thread_rng();
    let mut packet = DnsPacket::default();
    packet.header.id = rng.gen();
    packet.header.questions = 1;
    packet.header.recursion_desired = true;
    packet.questions.push({
        DnsQuestion {
            name: qname,
            qtype: qtype,
        }
    });

    return packet;
}