Skip to content
DnsParseResponse

DnsParseResponse

Description

Parse a wire-format response into out. The caller is responsible for DnsResponseDeinit(out) afterwards.

Parameters

Name Direction Description
out out Receives parsed structure. Strings + Vecs use alloc.
buf in Wire bytes received from the nameserver.
len in Number of bytes in buf.
alloc in Allocator used for all strings + record Vecs.

Success

Returns true. out is populated, including a possibly empty answer list (NXDOMAIN with no records is valid).

Failure

Returns false on header truncation, name-compression cycles, oversized labels, or out-of-bounds reads. out is left partially filled but is safe to DnsResponseDeinit.

Usage example (Cross-references)

Usage examples (Cross-references)
        // DnsParseResponse takes `Allocator *` -- legitimate erasure
        // boundary; pass at the call site, no intermediate variable.
        bool ok = DnsParseResponse(&resp, resp_buf, (u64)got, ALLOCATOR_OF(&scratch));
        if (!ok || resp.id != id || resp.rcode != DNS_RCODE_NOERROR) {
            DnsResponseDeinit(&resp);
    }
    
    bool DnsParseResponse(DnsResponse *out, const u8 *buf, u64 len, Allocator *alloc) {
        if (!out || !buf || !alloc) {
            return false;
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
    
        bool match = ok && resp.id == 0x1234 && resp.is_response && resp.recursion_desired && resp.recursion_avail &&
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && resp.rcode == DNS_RCODE_NXDOMAIN && VecLen(&resp.answers) == 0;
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        if (match) {
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        if (match) {
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && resp.id == 0x0005;
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, p, a);
        bool        match = ok && resp.id == 0x0009;
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, p, a);
        bool        match = ok && q2_off == 256 && VecLen(&resp.answers) == 1;
        if (match) {
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        if (match) {
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = !ok; // must be rejected
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = !ok; // self pointer must be rejected
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && resp.id == 0xABCD && VecLen(&resp.answers) == 0 && VecLen(&resp.authority) == 0 &&
                     VecLen(&resp.additional) == 0;
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
    
        DnsResponseDeinit(&resp);
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && resp.id == 0x1122 && resp.is_response == true && resp.authoritative == true &&
                     resp.truncated == false && resp.recursion_desired == true && resp.recursion_avail == true &&
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && resp.is_response == false && resp.authoritative == false && resp.truncated == true &&
                     resp.recursion_desired == false && resp.recursion_avail == false;
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && resp.rcode == DNS_RCODE_NXDOMAIN;
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 2;
        if (match) {
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        if (match) {
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        if (match) {
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 2;
        if (match) {
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 2;
        if (match) {
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool match = ok && VecLen(&resp.answers) == 1 && VecLen(&resp.authority) == 1 && VecLen(&resp.additional) == 1;
        if (match) {
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        if (match) {
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        if (match) {
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
    
        DnsResponseDeinit(&resp);
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
    
        DnsResponseDeinit(&resp);
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, p, a);
        bool        match = !ok; // real code rejects: 191 + 1 + 62 = 254 > 253.
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, p, a);
        bool        match = ok && resp.id == 0x000a;
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, p, a);
        bool        match = !ok; // real code rejects the truncated rdata.
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        if (match) {
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
        DnsResponseDeinit(&resp);
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
        DnsResponseDeinit(&resp);
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
        DnsResponseDeinit(&resp);
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, len, a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        if (match) {
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), adbg);
        ok               = ok && (VecLen(&resp.answers) == 1);
        DnsRecord *r     = ok ? VecPtrAt(&resp.answers, 0) : NULL;
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, p, adbg);
        ok               = ok && (VecLen(&resp.authority) == 1);
        ok               = ok && (VecLen(&resp.answers) == 0) && (VecLen(&resp.additional) == 0);
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, p, adbg);
        ok               = ok && (VecLen(&resp.additional) == 1);
        ok               = ok && (VecLen(&resp.answers) == 0) && (VecLen(&resp.authority) == 0);
Last updated on