Experimental DNS library implemented in zig
Experimental DNS library implemented in zig.
So far implements RFC 1035 plus some updates.
The library itself has no dependencies, the CLI example uses zig-network
to send and receive packets over the network.
src/dns.zig
src/main.zig
For testing and development purposes you can call the library interactively from the command line.
Usage: zig-dns <dns-server> <domain> <query-type>
$ zig-dns 1.1.1.1 www.lambda.cx A
Sending bytes: { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 119, 119, 119, 6, 108, 97, 109, 98, 100, 97, 2, 99, 120, 0, 0, 1, 0, 1 }
Query:
Message {
Header {
ID: 1
Response: false
OpCode: query
Authoritative Answer: false
Truncation: false
Recursion Desired: true
Recursion Available: false
Z: 0
Response Code: no_error
}
Questions {
Question {
Name: www.lambda.cx.
QType: A
QClass: IN
}
}
Ansewrs {
}
Authorities {
}
Additional {
}
}
Recv: { 0, 1, 129, 128, 0, 1, 0, 2, 0, 0, 0, 0, 3, 119, 119, 119, 6, 108, 97, 109, 98, 100, 97, 2, 99, 120, 0, 0, 1, 0, 1, 192, 12, 0, 5, 0, 1, 0, 0, 7, 8, 0, 2, 192, 16, 192, 16, 0, 1, 0, 1, 0, 0, 7, 8, 0, 4, 155, 138, 137, 134 }
Response:
Message {
Header {
ID: 1
Response: true
OpCode: query
Authoritative Answer: false
Truncation: false
Recursion Desired: true
Recursion Available: true
Z: 0
Response Code: no_error
}
Questions {
Question {
Name: www.lambda.cx.
QType: A
QClass: IN
}
}
Ansewrs {
Resource Record {
Name: www.lambda.cx.
Type: CNAME
Class: IN
TTL: 1800
Resource Data Length: 2
Resource Data: lambda.cx.
}
Resource Record {
Name: lambda.cx.
Type: A
Class: IN
TTL: 1800
Resource Data Length: 4
Resource Data: 155.138.137.134
}
}
Authorities {
}
Additional {
}
}
const std = @import("std");
const io = std.io;
const network = @import("network");
const dns = @import("zig-dns/src/dns.zig");
// [...] Main function, allocator, etc.
try network.init();
defer network.deinit();
const sock = try network.connectToHost(allocator, "8.8.8.8", 53, .udp);
defer sock.close();
const writer = sock.writer();
const message = try dns.createQuery(allocator, "lambda.cx", .A);
defer message.deinit();
var message_bytes = try message.to_bytes();
try writer.writeAll(message_bytes);
var recv = [_]u8{0} ** 1024;
const recv_size = try sock.receive(&recv);
const response = try dns.Message.from_bytes(allocator, recv[0..recv_size]);
defer response.deinit();
std.debug.print("Response:\n{any}\n", .{ response });
Output:
Response:
Message {
Header {
ID: 1
Response: true
OpCode: query
Authoritative Answer: false
Truncation: false
Recursion Desired: true
Recursion Available: true
Z: 0
Response Code: no_error
}
Questions {
Question {
Name: www.lambda.cx.
QType: A
QClass: IN
}
}
Ansewrs {
Resource Record {
Name: www.lambda.cx.
Type: CNAME
Class: IN
TTL: 1800
Resource Data Length: 2
Resource Data: lambda.cx.
}
Resource Record {
Name: lambda.cx.
Type: A
Class: IN
TTL: 1800
Resource Data Length: 4
Resource Data: 155.138.137.134
}
}
Authorities {
}
Additional {
}
}
See iterative.zig as an example for how to use this library iteratively.