Skip to content

DnsResponse

Description

Parsed DNS message. id echoes the client-supplied transaction id from the matching query so the resolver can pair responses.

Usage example (Cross-references)

Usage examples (Cross-references)
            DnsRecords authority;
            DnsRecords additional;
        } DnsResponse;
    
    #include <Misra/Parsers/Dns/Private.h>
        ///           `DnsResponseDeinit`.
        ///
        bool DnsParseResponse(DnsResponse *out, const u8 *buf, u64 len, Allocator *alloc);
    
        ///
        /// TAGS: Dns, Parser, Deinit, Lifecycle
        ///
        void DnsResponseDeinit(DnsResponse *self);
    
        ///
        }
    
        DnsResponse resp = {0};
        // DnsParseResponse takes `Allocator *` -- legitimate erasure
        // boundary; pass at the call site, no intermediate variable.
    }
    
    bool DnsParseResponse(DnsResponse *out, const u8 *buf, u64 len, Allocator *alloc) {
        if (!out || !buf || !alloc) {
            return false;
    }
    
    void DnsResponseDeinit(DnsResponse *self) {
        if (!self) {
            return;
        };
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
        };
    
        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;
        };
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        };
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && resp.id == 0x0005;
        wire[p++] = 0x01;
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, p, a);
        bool        match = ok && resp.id == 0x0009;
        wire[p++] = 0x04;
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, p, a);
        bool        match = ok && q2_off == 256 && VecLen(&resp.answers) == 1;
        };
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        };
    
        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
        static const u8 wire[] = {0xab, 0xcd, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
        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 &&
        static const u8 wire[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
        static const u8 wire[] = {0x11, 0x22, 0x85, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && resp.id == 0x1122 && resp.is_response == true && resp.authoritative == true &&
        static const u8 wire[] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && resp.is_response == false && resp.authoritative == false && resp.truncated == true &&
        static const u8 wire[] = {0x00, 0x01, 0x81, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
        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;
                                  0x00, 0x01, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04};
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
                                  0x00, 0x04, 0x7f, 0x00, 0x00, 0x01};
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        };
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 2;
        };
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 2;
        };
    
        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;
        };
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        };
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, sizeof(wire), a);
        bool        match = ok && VecLen(&resp.answers) == 1;
        };
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
        };
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
        wire[p++] = 0x01;
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, p, a);
        bool        match = !ok; // real code rejects: 191 + 1 + 62 = 254 > 253.
        wire[p++] = 0x01;
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, p, a);
        bool        match = ok && resp.id == 0x000a;
        // Mutant: 90 - 40 = 50,  not > 94 -> accept (over-reads 40 garbage bytes).
    
        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;
                                  0x0a, 'a',  'b',  'c',  'd',  'e',  'f',  'g',  'h',  'i',  'j',  0x14};
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
        DnsResponseDeinit(&resp);
                                  0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
        DnsResponseDeinit(&resp);
        static const u8 wire[] = {0x00, 0x01, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0};
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), a);
        DnsResponseDeinit(&resp);
        u64 len = build_hop_chain(wire, 63); // 64 hops total
    
        DnsResponse resp  = {0};
        bool        ok    = DnsParseResponse(&resp, wire, len, a);
        bool        match = ok && VecLen(&resp.answers) == 1;
                                  0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x02, 0xc0, 0x10};
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, sizeof(wire), adbg);
        ok               = ok && (VecLen(&resp.answers) == 1);
        p = leak_put_a_record(wire, p, 'n');
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, p, adbg);
        ok               = ok && (VecLen(&resp.authority) == 1);
        p = leak_put_a_record(wire, p, 'd');
    
        DnsResponse resp = {0};
        bool        ok   = DnsParseResponse(&resp, wire, p, adbg);
        ok               = ok && (VecLen(&resp.additional) == 1);
Last updated on