-
Notifications
You must be signed in to change notification settings - Fork 4
/
iterative.zig
82 lines (69 loc) · 2.66 KB
/
iterative.zig
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
80
81
82
const std = @import("std");
const mem = std.mem;
const debug = std.debug;
const testing = std.testing;
const dns = @import("dns.zig");
const network = @import("network");
const root_server = "a.root-servers.net";
pub fn main() anyerror!void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
var allocator = gpa.allocator();
try network.init();
defer network.deinit();
var args = try std.process.argsWithAllocator(allocator);
defer args.deinit();
_ = args.next();
const domain = args.next() orelse {
std.debug.print("usage: iterative <domain>\n", .{});
std.os.exit(1);
};
const qtype = std.meta.stringToEnum(dns.QType, args.next() orelse "A") orelse .A;
std.debug.print("querying: {s}\n", .{root_server});
var query = try makeNonRecursiveQuery(allocator, root_server, domain, qtype);
var resolved = false;
while (!resolved) {
if (query.answers.len != 0) {
resolved = true;
} else if (query.authorities.len != 0) {
switch (query.authorities[0].resource_data) {
.ns => {
const ns = try query.authorities[0].resource_data.ns.nsdname.to_string(allocator);
defer allocator.free(ns);
query.deinit();
std.debug.print("querying: {s}\n", .{ns});
query = try makeNonRecursiveQuery(allocator, ns, domain, qtype);
},
else => {
std.debug.print("No record found\n", .{});
query.deinit();
return;
},
}
} else {
std.debug.print("No record found\n", .{});
query.deinit();
return;
}
}
for (query.answers) |answer| {
std.debug.print("{}\n", .{answer.resource_data});
}
query.deinit();
}
pub fn makeNonRecursiveQuery(allocator: mem.Allocator, name_server: []const u8, domain: []const u8, query_type: dns.QType) !dns.Message {
const sock = try network.connectToHost(allocator, name_server, 53, .udp);
defer sock.close();
const writer = sock.writer();
var message = try dns.createQuery(allocator, domain, query_type);
defer message.deinit();
message.header.recursion_desired = false;
const message_bytes = try message.to_bytes(allocator);
defer allocator.free(message_bytes);
try writer.writeAll(message_bytes);
var recv = [_]u8{0} ** 2048;
const recv_size = try sock.receive(&recv);
const response_bytes = recv[0..recv_size];
const response = try dns.Message.from_bytes(allocator, response_bytes);
return response;
}