1use std::env;
6use std::fs;
7use std::io::{prelude::*, BufReader};
8use std::net::Ipv4Addr;
9use std::net::{IpAddr, UdpSocket};
10use std::process;
11
12use dns_protocol::Flags;
13use dns_protocol::{Message, Question, ResourceRecord, ResourceType};
14
15fn main() -> Result<(), Box<dyn std::error::Error>> {
16 let mut args = env::args();
18 let program_name = args.next().unwrap();
19 let name = match args.next() {
20 Some(name) => name,
21 None => {
22 eprintln!("Usage: {} <name>", &program_name);
23 process::exit(1);
24 }
25 };
26
27 let resolv = BufReader::new(fs::File::open("/etc/resolv.conf")?);
32 let mut nameserver = None;
33
34 for line in resolv.lines() {
35 let line = line?;
36 if line.starts_with("nameserver") {
37 let result = line.split_whitespace().nth(1).unwrap();
38 if let Ok(ns) = result.parse::<IpAddr>() {
39 nameserver = Some(ns);
40 break;
41 }
42 }
43 }
44
45 let nameserver = match nameserver {
46 Some(ns) => ns,
47 None => {
48 eprintln!("No nameserver found in /etc/resolv.conf");
49 process::exit(1);
50 }
51 };
52
53 println!("Nameserver: {}", nameserver);
54
55 let mut questions = [Question::new(name.as_str(), ResourceType::A, 1)];
57 let message = Message::new(
58 0xFEE7,
59 Flags::standard_query(),
60 &mut questions,
61 &mut [],
62 &mut [],
63 &mut [],
64 );
65
66 let mut buffer = vec![0; message.space_needed()];
68 message.write(&mut buffer)?;
69
70 let socket = UdpSocket::bind((Ipv4Addr::from([127, 0, 0, 1]), 0))?;
72 socket.send_to(&buffer, (nameserver, 53))?;
73
74 let mut buffer = vec![0; 1024];
79 let len = socket.recv(&mut buffer)?;
80
81 let mut answers = [ResourceRecord::default(); 16];
83 let mut authority = [ResourceRecord::default(); 16];
84 let mut additional = [ResourceRecord::default(); 16];
85 let message = Message::read(
86 &buffer[..len],
87 &mut questions,
88 &mut answers,
89 &mut authority,
90 &mut additional,
91 )?;
92
93 println!(";; Got answer: {:?}", message.flags().response_code());
94
95 for answer in message.answers() {
97 match answer.data().len() {
99 4 => {
100 let mut ip = [0u8; 4];
101 ip.copy_from_slice(answer.data());
102 let ip = Ipv4Addr::from(ip);
103 println!("{} has address {}", answer.name(), ip);
104 }
105 16 => {
106 let mut ip = [0u8; 16];
107 ip.copy_from_slice(answer.data());
108 let ip = IpAddr::from(ip);
109 println!("{} has address {}", answer.name(), ip);
110 }
111 _ => {
112 println!("{} has unknown address type", answer.name());
113 }
114 }
115 }
116
117 Ok(())
118}