aboutsummaryrefslogtreecommitdiff
path: root/contrib/ldns/ldns/dname.h
blob: 16b45429fb21afcc933f491664b60aa51c9042ed (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
 * dname.h
 *
 * dname definitions
 *
 * a Net::DNS like library for C
 *
 * (c) NLnet Labs, 2004-2006
 *
 * See the file LICENSE for the license
 */

/**
 * \file dname.h
 *
 * dname contains function to read and manipulate domain names.
 *
 * Example domain names are "www.nlnetlabs.nl." and "." (the root)
 *
 * If a domain name ends with a dot ("."), it is called a Fully Qualified
 * Domain Name (FQDN). In certain places (for instance when reading a zone
 * file), an origin (which is just another domain name) non-FQDNs will be
 * placed after the current. For instance, if i have a zone file where the
 * origin has been set to "nl.", and my file contains the name
 * "www.nlnetlabs", it will result in "www.nlnetlabs.nl.". Internally, dnames are
 * always absolute (the dot is added when it is missing and there is no origin).
 *
 * An FQDN is also
 * known as an absolute domain name, therefore the function to check this is
 * called \ref ldns_dname_str_absolute
 *
 * Domain names are stored in \ref ldns_rdf structures, with the type
 * \ref LDNS_RDF_TYPE_DNAME
 *
 * This module is *NOT* about the RR type called DNAME.
 */


#ifndef LDNS_DNAME_H
#define LDNS_DNAME_H

#include <ldns/common.h>
#include <ldns/rdata.h>

#ifdef __cplusplus
extern "C" {
#endif

#define LDNS_DNAME_NORMALIZE        tolower

/**
 * concatenates two dnames together
 * \param[in] rd1 the leftside
 * \param[in] rd2 the rightside
 * \return a new rdf with leftside/rightside
 */
ldns_rdf *ldns_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2);

/**
 * concatenates rd2 after rd1 (rd2 is copied, rd1 is modified)
 * \param[in] rd1 the leftside
 * \param[in] rd2 the rightside
 * \return LDNS_STATUS_OK on success
 */
ldns_status 	ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2);

/**
 * Returns a clone of the given dname with the labels
 * reversed
 * \param[in] d the dname to reverse
 * \return clone of the dname with the labels reversed.
 */
ldns_rdf *ldns_dname_reverse(const ldns_rdf *d);

/**
 * Clones the given dname from the nth label on
 * \param[in] d The dname to clone
 * \param[in] n the label nr to clone from, if this is 0, the complete
 *              dname is cloned
 * \return A newly allocated *rdf structure, containing the cloned dname,
 *         or NULL if either d was NULL, not a dname, or if n >=
 *         label_count
 */
ldns_rdf *
ldns_dname_clone_from(const ldns_rdf *d, uint16_t n);

/**
 * chop one label off the left side of a dname. so
 * wwww.nlnetlabs.nl, becomes nlnetlabs.nl
 * This new name is a clone and must be freed with ldns_deep_free()
 * \param[in] d the dname to chop
 * \return the remaining dname
 */
ldns_rdf *ldns_dname_left_chop(const ldns_rdf *d);

/**
 * count the number of labels inside a LDNS_RDF_DNAME type rdf.
 * \param[in] *r the rdf
 * \return the number of labels
 */
uint8_t  ldns_dname_label_count(const ldns_rdf *r);

/**
 * creates a new dname rdf from a string.
 * \param[in] str string to use
 * \return ldns_rdf* or NULL in case of an error
 */
ldns_rdf *ldns_dname_new_frm_str(const char *str);

/**
 * Create a new dname rdf from a string
 * \param[in] s the size of the new dname
 * \param[in] *data pointer to the actual data
 *
 * \return ldns_rdf*
 */
ldns_rdf *ldns_dname_new(uint16_t s, void *data);

/**
 * Create a new dname rdf from data (the data is copied)
 * \param[in] size the size of the data
 * \param[in] *data pointer to the actual data
 *
 * \return ldns_rdf*
 */
ldns_rdf *ldns_dname_new_frm_data(uint16_t size, const void *data);

/**
 * Put a dname into canonical fmt - ie. lowercase it
 * \param[in] rdf the dname to lowercase
 * \return void
 */
void ldns_dname2canonical(const ldns_rdf *rdf);

/**
 * test wether the name sub falls under parent (i.e. is a subdomain
 * of parent). This function will return false if the given dnames are
 * equal.
 * \param[in] sub the name to test
 * \param[in] parent the parent's name
 * \return true if sub falls under parent, otherwise false
 */
bool ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent);

/**
 * Compares the two dname rdf's according to the algorithm for ordering
 * in RFC4034 Section 6.
 * \param[in] dname1 First dname rdf to compare
 * \param[in] dname2 Second dname rdf to compare
 * \return -1 if dname1 comes before dname2, 1 if dname1 comes after dname2, and 0 if they are equal.
 */
int ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2);

/**
 * Checks whether the dname matches the given wildcard
 * \param[in] dname The dname to check
 * \param[in] wildcard The wildcard to check with
 * \return 1 If the wildcard matches, OR if 'wildcard' is not a wildcard and
 *           the names are *exactly* the same
 *         0 If the wildcard does not match, or if it is not a wildcard and
 *           the names are not the same
 */
int ldns_dname_match_wildcard(const ldns_rdf *dname, const ldns_rdf *wildcard);

/**
 * check if middle lays in the interval defined by prev and next
 * prev <= middle < next. This is usefull for nsec checking
 * \param[in] prev the previous dname
 * \param[in] middle the dname to check
 * \param[in] next the next dname
 * return 0 on error or unknown, -1 when middle is in the interval, +1 when not
 */
int ldns_dname_interval(const ldns_rdf *prev, const ldns_rdf *middle, const ldns_rdf *next);

/**
 * Checks whether the given dname string is absolute (i.e. ends with a '.')
 * \param[in] *dname_str a string representing the dname
 * \return true or false
 */
bool ldns_dname_str_absolute(const char *dname_str);

/**
 * Checks whether the given dname is absolute (i.e. ends with a '.')
 * \param[in] *dname a rdf representing the dname
 * \return true or false
 */
bool ldns_dname_absolute(const ldns_rdf *dname);

/**
 * look inside the rdf and if it is an LDNS_RDF_TYPE_DNAME
 * try and retrieve a specific label. The labels are numbered
 * starting from 0 (left most).
 * \param[in] rdf the rdf to look in
 * \param[in] labelpos return the label with this number
 * \return a ldns_rdf* with the label as name or NULL on error
 */
ldns_rdf * ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos);

/**
 * Check if dname is a wildcard, starts with *.
 * \param[in] dname: the rdf to look in
 * \return true if a wildcard, false if not.
 */
int ldns_dname_is_wildcard(const ldns_rdf* dname);

#ifdef __cplusplus
}
#endif

#endif	/* LDNS_DNAME_H */