Skip to content

A no-std and no alloc rust crate for the DNS protocol as defined by RFC 1035.

Notifications You must be signed in to change notification settings

safiworks/simpldns

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

simpldns

A rust no-std and no alloc crate providing a wrapper around the DNS protocol as defined by RFC 1035.

Example

use smpldns as dns;
use dns::message::{
    DnsMessage, DnsMessageFlags, DnsMessageHeader, DnsOpCode, DnsQuestion, DnsRCode,
};
use std::net::{Ipv4Addr, UdpSocket};

let mut buf = [0; 512];
let questions =
    [
        DnsQuestion::try_new("example.com.", message::DnsType::A, message::DnsClass::IN)
            .expect("Failed to construct question"),
    ];

let msg = DnsMessage::new(DnsMessageHeader::new(
    0xFEED,
    DnsOpCode::Query,
    DnsRCode::NoError,
    DnsMessageFlags::RECURSION_DESIRED | DnsMessageFlags::QUERY,
))
.with_questions(&questions);

let encoded = msg.encode_to(&mut buf).expect("Failed to encode message");
let udp = UdpSocket::bind("0.0.0.0:0").expect("Failed to bind");
udp.send_to(encoded, "8.8.8.8:53")
    .expect("Failed to send message");

let (size, _) = udp.recv_from(&mut buf).expect("Failed to receive response");

let encoded_response = &buf[..size];
let parsed = DnsMessage::parse(encoded_response).expect("Failed to parse response");
let header = parsed.header();

assert_eq!(header.trans_id(), 0xFEED);
assert_eq!(header.rcode(), DnsRCode::NoError);
assert!(header.is_response());

assert_eq!(parsed.questions().next(), Some(questions[0]));
let expected_answers = [
    Ipv4Addr::new(23, 215, 0, 138),
    Ipv4Addr::new(23, 220, 75, 232),
    Ipv4Addr::new(23, 220, 75, 245),
];

let answers = parsed
    .answers()
    .flat_map(|a| match a.rdata() {
        message::RRData::A(a) => Some(*a),
        _ => None,
    })
    .collect::<Vec<_>>();

for a in expected_answers {
    assert!(answers.contains(&a), "Answers: {answers:#?}");
}

Goals

This would end up as a dependecy of std in my project and as such:

  • no-std support
  • zero allocations
  • zero dependecies

Motivation

I need this for networking in my pure rust hobby OS, My OS's API written in rust and is a dependency of my rust libstd port needs host lookup support.

Existing crates all require std, are to complicated, and even if I ported them, they unefficently use allocations and I need total control.

About

A no-std and no alloc rust crate for the DNS protocol as defined by RFC 1035.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages