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.