/src/knot-dns/src/libknot/rdata.h
Line | Count | Source |
1 | | /* Copyright (C) CZ.NIC, z.s.p.o. and contributors |
2 | | * SPDX-License-Identifier: GPL-2.0-or-later |
3 | | * For more information, see <https://www.knot-dns.cz/> |
4 | | */ |
5 | | |
6 | | /*! |
7 | | * \file |
8 | | * |
9 | | * \brief API for manipulating rdata. |
10 | | * |
11 | | * \addtogroup rr |
12 | | * @{ |
13 | | */ |
14 | | |
15 | | #pragma once |
16 | | |
17 | | #include <assert.h> |
18 | | #include <stddef.h> |
19 | | #include <stdint.h> |
20 | | #include <string.h> |
21 | | |
22 | | /*!< \brief Maximum rdata length. */ |
23 | | #define KNOT_RDATA_MAXLEN 65535 |
24 | | |
25 | | /*!< \brief Maximum required pointer alignment (assuming sizeof(void *) is a power of two). */ |
26 | 0 | #define KNOT_PTR_ALIGN_MAX (sizeof(void *) - 1) |
27 | | |
28 | | /*! |
29 | | * \brief Structure holding single rdata payload. |
30 | | */ |
31 | | typedef struct { |
32 | | uint16_t len; |
33 | | uint8_t data[]; |
34 | | } knot_rdata_t; |
35 | | |
36 | | /*! |
37 | | * \brief Inits rdata structure. |
38 | | * |
39 | | * \param rdata Rdata structure to be initialized. At least knot_rdata_size bytes |
40 | | * must fit into it! |
41 | | * \param len Rdata length. |
42 | | * \param data Rdata itself. |
43 | | */ |
44 | | inline static void knot_rdata_init(knot_rdata_t *rdata, uint16_t len, const uint8_t *data) |
45 | 59.8k | { |
46 | 59.8k | assert(rdata); |
47 | 59.8k | rdata->len = len; |
48 | 59.8k | if (rdata->len > 0) { |
49 | 12.1k | assert(data); |
50 | 12.1k | memcpy(rdata->data, data, len); |
51 | 12.1k | if (len & 1) { // Initialize possible padding to mute analytical tools. |
52 | 7.43k | rdata->data[len] = 0; |
53 | 7.43k | } |
54 | 12.1k | } |
55 | 59.8k | } Unexecuted instantiation: fuzz_packet.c:knot_rdata_init Unexecuted instantiation: pkt.c:knot_rdata_init Unexecuted instantiation: rrset-wire.c:knot_rdata_init rdataset.c:knot_rdata_init Line | Count | Source | 45 | 35.9k | { | 46 | 35.9k | assert(rdata); | 47 | 35.9k | rdata->len = len; | 48 | 35.9k | if (rdata->len > 0) { | 49 | 12.1k | assert(data); | 50 | 12.1k | memcpy(rdata->data, data, len); | 51 | 12.1k | if (len & 1) { // Initialize possible padding to mute analytical tools. | 52 | 7.43k | rdata->data[len] = 0; | 53 | 7.43k | } | 54 | 12.1k | } | 55 | 35.9k | } |
Line | Count | Source | 45 | 23.8k | { | 46 | 23.8k | assert(rdata); | 47 | 23.8k | rdata->len = len; | 48 | 23.8k | if (rdata->len > 0) { | 49 | 0 | assert(data); | 50 | 0 | memcpy(rdata->data, data, len); | 51 | 0 | if (len & 1) { // Initialize possible padding to mute analytical tools. | 52 | 0 | rdata->data[len] = 0; | 53 | 0 | } | 54 | 0 | } | 55 | 23.8k | } |
Unexecuted instantiation: opt.c:knot_rdata_init Unexecuted instantiation: tsig.c:knot_rdata_init Unexecuted instantiation: tsig-op.c:knot_rdata_init Unexecuted instantiation: codes.c:knot_rdata_init |
56 | | |
57 | | /*! |
58 | | * \brief Returns actual size of the rdata structure for given rdata length. |
59 | | * |
60 | | * \param len Rdata length. |
61 | | * |
62 | | * \return Actual structure size. |
63 | | */ |
64 | | inline static size_t knot_rdata_size(uint16_t len) |
65 | 108k | { |
66 | 108k | return sizeof(uint16_t) + len + (len & 1); |
67 | 108k | } Unexecuted instantiation: fuzz_packet.c:knot_rdata_size Unexecuted instantiation: pkt.c:knot_rdata_size rrset-wire.c:knot_rdata_size Line | Count | Source | 65 | 12.3k | { | 66 | 12.3k | return sizeof(uint16_t) + len + (len & 1); | 67 | 12.3k | } |
rdataset.c:knot_rdata_size Line | Count | Source | 65 | 71.9k | { | 66 | 71.9k | return sizeof(uint16_t) + len + (len & 1); | 67 | 71.9k | } |
Line | Count | Source | 65 | 23.8k | { | 66 | 23.8k | return sizeof(uint16_t) + len + (len & 1); | 67 | 23.8k | } |
Unexecuted instantiation: opt.c:knot_rdata_size Unexecuted instantiation: tsig.c:knot_rdata_size Unexecuted instantiation: tsig-op.c:knot_rdata_size Unexecuted instantiation: codes.c:knot_rdata_size |
68 | | |
69 | | /*! |
70 | | * \brief Canonical comparison of two rdata structures. |
71 | | * |
72 | | * \param rdata1 First rdata to compare. |
73 | | * \param rdata2 Second rdata to compare. |
74 | | * |
75 | | * \retval = 0 if rdata1 == rdata2. |
76 | | * \retval < 0 if rdata1 < rdata2. |
77 | | * \retval > 0 if rdata1 > rdata2. |
78 | | */ |
79 | | inline static int knot_rdata_cmp(const knot_rdata_t *rdata1, const knot_rdata_t *rdata2) |
80 | 0 | { |
81 | 0 | assert(rdata1); |
82 | 0 | assert(rdata2); |
83 | |
|
84 | 0 | size_t common_len = (rdata1->len <= rdata2->len) ? rdata1->len : rdata2->len; |
85 | |
|
86 | 0 | int cmp = memcmp(rdata1->data, rdata2->data, common_len); |
87 | 0 | if (cmp == 0 && rdata1->len != rdata2->len) { |
88 | 0 | cmp = rdata1->len < rdata2->len ? -1 : 1; |
89 | 0 | } |
90 | 0 | return cmp; |
91 | 0 | } Unexecuted instantiation: fuzz_packet.c:knot_rdata_cmp Unexecuted instantiation: pkt.c:knot_rdata_cmp Unexecuted instantiation: rrset-wire.c:knot_rdata_cmp Unexecuted instantiation: rdataset.c:knot_rdata_cmp Unexecuted instantiation: rrset.c:knot_rdata_cmp Unexecuted instantiation: opt.c:knot_rdata_cmp Unexecuted instantiation: tsig.c:knot_rdata_cmp Unexecuted instantiation: tsig-op.c:knot_rdata_cmp Unexecuted instantiation: codes.c:knot_rdata_cmp |
92 | | |
93 | | /*! |
94 | | * \brief Converts rdata into canonical format. |
95 | | * |
96 | | * Rdata domain names are converted only for types listed in RFC 4034, |
97 | | * Section 6.2, except for NSEC (updated by RFC 6840, Section 5.1) and |
98 | | * A6 (not supported). |
99 | | * |
100 | | * \warning This function expects either empty rdata or full, not malformed |
101 | | * rdata. If malformed rdata is passed to this function, memory errors |
102 | | * may occur. |
103 | | * |
104 | | * \param rdata Rdata to convert. |
105 | | * \param type Rdata type. |
106 | | * |
107 | | * \return Error code, KNOT_EOK if successful. |
108 | | */ |
109 | | int knot_rdata_to_canonical(knot_rdata_t *rdata, uint16_t type); |
110 | | |
111 | | /*! @} */ |