Home

Awesome

zig-dns

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.

Features

Currently supported record types

Interactive

For testing and development purposes you can call the library interactively from the command line.

Usage: zig-dns <dns-server> <domain> <query-type>

Interactive Example

$ 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 {
  }
}

Example Code

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 {
  }
}

Iterative Example

See iterative.zig as an example for how to use this library iteratively.