1 /* 2 * dname.h -- Domain name handling. 3 * 4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 10 #ifndef DNAME_H 11 #define DNAME_H 12 13 #include <assert.h> 14 #include <stdio.h> 15 16 #include "buffer.h" 17 #include "region-allocator.h" 18 #include "dns.h" /* for MAXDOMAINLEN */ 19 20 #if defined(NAMEDB_UPPERCASE) || defined(USE_NAMEDB_UPPERCASE) 21 #define DNAME_NORMALIZE toupper 22 #else 23 #define DNAME_NORMALIZE tolower 24 #endif 25 26 27 /* 28 * Domain names stored in memory add some additional information to be 29 * able to quickly index and compare by label. 30 */ 31 typedef struct dname dname_type; 32 struct dname 33 { 34 /* 35 * The size (in bytes) of the domain name in wire format. 36 */ 37 uint8_t name_size; 38 39 /* 40 * The number of labels in this domain name (including the 41 * root label). 42 */ 43 uint8_t label_count; 44 45 /* 46 uint8_t label_offsets[label_count]; 47 uint8_t name[name_size]; 48 */ 49 }; 50 51 52 /* 53 * Construct a new domain name based on NAME in wire format. NAME 54 * cannot contain compression pointers. 55 * 56 * Pre: NAME != NULL. 57 */ 58 const dname_type *dname_make(region_type *region, const uint8_t *name, 59 int normalize); 60 61 /* 62 * Construct a new domain name based on wire format dname stored at 63 * PACKET's current position. Compression pointers are followed. The 64 * PACKET's current position is changed to the end of the wire format 65 * dname or set to just after the first compression pointer. 66 */ 67 const dname_type *dname_make_from_packet(region_type *region, 68 buffer_type *packet, 69 int allow_pointers, 70 int normalize); 71 72 /* 73 * parse wireformat from packet (following pointers) into the 74 * given buffer. Returns length in buffer or 0 on error. 75 * buffer must be MAXDOMAINLEN+1 long. 76 */ 77 int dname_make_wire_from_packet(uint8_t *buf, 78 buffer_type *packet, 79 int allow_pointers); 80 81 /* 82 * Construct a new domain name based on the ASCII representation NAME. 83 * If ORIGIN is not NULL and NAME is not terminated by a "." the 84 * ORIGIN is appended to the result. NAME can contain escape 85 * sequences. 86 * 87 * Returns NULL on failure. Otherwise a newly allocated domain name 88 * is returned. 89 * 90 * Pre: name != NULL. 91 */ 92 const dname_type *dname_parse(region_type *region, const char *name); 93 94 /* 95 * parse ascii string to wireformat domain name (without compression ptrs) 96 * returns 0 on failure, the length of the wireformat on success. 97 * the result is stored in the wirefmt which must be at least MAXDOMAINLEN 98 * in size. On failure, the wirefmt can be altered. 99 */ 100 int dname_parse_wire(uint8_t* wirefmt, const char* name); 101 102 /* 103 * Return NULL if DNAME is NULL or a copy of DNAME otherwise. 104 */ 105 const dname_type *dname_copy(region_type *region, const dname_type *dname); 106 107 108 /* 109 * Copy the most significant LABEL_COUNT labels from dname. 110 */ 111 const dname_type *dname_partial_copy(region_type *region, 112 const dname_type *dname, 113 uint8_t label_count); 114 115 116 /* 117 * The origin of DNAME. 118 */ 119 const dname_type *dname_origin(region_type *region, const dname_type *dname); 120 121 /* 122 * Return true if LEFT is a subdomain of RIGHT. 123 */ 124 int dname_is_subdomain(const dname_type *left, const dname_type *right); 125 126 127 /* 128 * Offsets into NAME for each label starting with the most 129 * significant label (the root label, followed by the TLD, 130 * etc). 131 */ 132 static inline const uint8_t * 133 dname_label_offsets(const dname_type *dname) 134 { 135 return (const uint8_t *) ((const char *) dname + sizeof(dname_type)); 136 } 137 138 139 /* 140 * The actual name in wire format (a sequence of label, each 141 * prefixed by a length byte, terminated by a zero length 142 * label). 143 */ 144 static inline const uint8_t * 145 dname_name(const dname_type *dname) 146 { 147 return (const uint8_t *) ((const char *) dname 148 + sizeof(dname_type) 149 + dname->label_count * sizeof(uint8_t)); 150 } 151 152 153 /* 154 * Return the label for DNAME specified by LABEL_INDEX. The first 155 * label (LABEL_INDEX == 0) is the root label, the next label is the 156 * TLD, etc. 157 * 158 * Pre: dname != NULL && label_index < dname->label_count. 159 */ 160 static inline const uint8_t * 161 dname_label(const dname_type *dname, uint8_t label) 162 { 163 uint8_t label_index; 164 165 assert(dname != NULL); 166 assert(label < dname->label_count); 167 168 label_index = dname_label_offsets(dname)[label]; 169 assert(label_index < dname->name_size); 170 171 return dname_name(dname) + label_index; 172 } 173 174 175 /* 176 * Compare two domain names. The comparison defines a lexicographical 177 * ordering based on the domain name's labels, starting with the most 178 * significant label. 179 * 180 * Return < 0 if LEFT < RIGHT, 0 if LEFT == RIGHT, and > 0 if LEFT > 181 * RIGHT. The comparison is case sensitive. 182 * 183 * Pre: left != NULL && right != NULL 184 */ 185 int dname_compare(const dname_type *left, const dname_type *right); 186 187 188 /* 189 * Compare two labels. The comparison defines a lexicographical 190 * ordering based on the characters in the labels. 191 * 192 * Return < 0 if LEFT < RIGHT, 0 if LEFT == RIGHT, and > 0 if LEFT > 193 * RIGHT. The comparison is case sensitive. 194 * 195 * Pre: left != NULL && right != NULL 196 * label_is_normal(left) && label_is_normal(right) 197 */ 198 int label_compare(const uint8_t *left, const uint8_t *right); 199 200 201 /* 202 * Returns the number of labels that match in LEFT and RIGHT, starting 203 * with the most significant label. Because the root label always 204 * matches, the result will always be >= 1. 205 * 206 * Pre: left != NULL && right != NULL 207 */ 208 uint8_t dname_label_match_count(const dname_type *left, 209 const dname_type *right); 210 211 212 /* 213 * The total size (in bytes) allocated to store DNAME. 214 * 215 * Pre: dname != NULL 216 */ 217 static inline size_t 218 dname_total_size(const dname_type *dname) 219 { 220 return (sizeof(dname_type) 221 + ((((size_t)dname->label_count) + ((size_t)dname->name_size)) 222 * sizeof(uint8_t))); 223 } 224 225 226 /* 227 * Is LABEL a normal LABEL (not a pointer or reserved)? 228 * 229 * Pre: label != NULL; 230 */ 231 static inline int 232 label_is_normal(const uint8_t *label) 233 { 234 assert(label); 235 return (label[0] & 0xc0) == 0; 236 } 237 238 239 /* 240 * Is LABEL a pointer? 241 * 242 * Pre: label != NULL; 243 */ 244 static inline int 245 label_is_pointer(const uint8_t *label) 246 { 247 assert(label); 248 return (label[0] & 0xc0) == 0xc0; 249 } 250 251 252 /* 253 * LABEL's pointer location. 254 * 255 * Pre: label != NULL && label_is_pointer(label) 256 */ 257 static inline uint16_t 258 label_pointer_location(const uint8_t *label) 259 { 260 assert(label); 261 assert(label_is_pointer(label)); 262 return ((uint16_t) (label[0] & ~0xc0) << 8) | (uint16_t) label[1]; 263 } 264 265 266 /* 267 * Length of LABEL. 268 * 269 * Pre: label != NULL && label_is_normal(label) 270 */ 271 static inline uint8_t 272 label_length(const uint8_t *label) 273 { 274 assert(label); 275 assert(label_is_normal(label)); 276 return label[0]; 277 } 278 279 280 /* 281 * The data of LABEL. 282 * 283 * Pre: label != NULL && label_is_normal(label) 284 */ 285 static inline const uint8_t * 286 label_data(const uint8_t *label) 287 { 288 assert(label); 289 assert(label_is_normal(label)); 290 return label + 1; 291 } 292 293 294 /* 295 * Is LABEL the root label? 296 * 297 * Pre: label != NULL 298 */ 299 static inline int 300 label_is_root(const uint8_t *label) 301 { 302 assert(label); 303 return label[0] == 0; 304 } 305 306 307 /* 308 * Is LABEL the wildcard label? 309 * 310 * Pre: label != NULL 311 */ 312 static inline int 313 label_is_wildcard(const uint8_t *label) 314 { 315 assert(label); 316 return label[0] == 1 && label[1] == '*'; 317 } 318 319 320 /* 321 * The next label of LABEL. 322 * 323 * Pre: label != NULL 324 * label_is_normal(label) 325 * !label_is_root(label) 326 */ 327 static inline const uint8_t * 328 label_next(const uint8_t *label) 329 { 330 assert(label); 331 assert(label_is_normal(label)); 332 assert(!label_is_root(label)); 333 return label + label_length(label) + 1; 334 } 335 336 337 /* 338 * Convert DNAME to its string representation. The result points to a 339 * static buffer that is overwritten the next time this function is 340 * invoked. 341 * 342 * If ORIGIN is provided and DNAME is a subdomain of ORIGIN the dname 343 * will be represented relative to ORIGIN. 344 * 345 * Pre: dname != NULL 346 */ 347 const char *dname_to_string(const dname_type *dname, 348 const dname_type *origin); 349 350 /* 351 * Convert DNAME to its string representation. The result if written 352 * to the provided buffer buf, which must be at least 5 times 353 * MAXDOMAINNAMELEN. 354 * 355 * If ORIGIN is provided and DNAME is a subdomain of ORIGIN the dname 356 * will be represented relative to ORIGIN. 357 * 358 * Pre: dname != NULL 359 */ 360 const char *dname_to_string_buf(const dname_type *dname, 361 const dname_type *origin, 362 char buf[MAXDOMAINLEN * 5]); 363 364 /* 365 * Create a dname containing the single label specified by STR 366 * followed by the root label. 367 */ 368 const dname_type *dname_make_from_label(region_type *region, 369 const uint8_t *label, 370 const size_t length); 371 372 373 /* 374 * Concatenate two dnames. 375 */ 376 const dname_type *dname_concatenate(region_type *region, 377 const dname_type *left, 378 const dname_type *right); 379 380 381 /* 382 * Perform DNAME substitution on a name, replace src with dest. 383 * Name must be a subdomain of src. The returned name is a subdomain of dest. 384 * Returns NULL if the result domain name is too long. 385 */ 386 const dname_type *dname_replace(region_type* region, 387 const dname_type* name, 388 const dname_type* src, 389 const dname_type* dest); 390 391 /** Convert uncompressed wireformat dname to a string */ 392 char* wiredname2str(const uint8_t* dname); 393 /** convert uncompressed label to string */ 394 char* wirelabel2str(const uint8_t* label); 395 /** check if two uncompressed dnames of the same total length are equal */ 396 int dname_equal_nocase(uint8_t* a, uint8_t* b, uint16_t len); 397 398 #endif /* DNAME_H */ 399