32 #include <arpa/nameser.h> 33 #include <netinet/in.h> 69 char known_flag_found = 0;
71 if (flags_size == 0) {
76 if (flags_size == 1) {
77 if (*flags ==
's' || *flags ==
'S' ||
78 *flags ==
'a' || *flags ==
'A' ||
79 *flags ==
'u' || *flags ==
'U') {
81 }
else if (!isalnum(*flags)) {
92 for (i = 0; i < flags_size; ++i) {
93 if (!isalnum(flags[i])) {
95 }
else if (flags[i] ==
's' || flags[i] ==
'S') {
96 if (known_flag_found && known_flag_found !=
's') {
99 known_flag_found =
's';
100 }
else if (flags[i] ==
'u' || flags[i] ==
'U') {
101 if (known_flag_found && known_flag_found !=
'u') {
104 known_flag_found =
'u';
105 }
else if (flags[i] ==
'a' || flags[i] ==
'A') {
106 if (known_flag_found && known_flag_found !=
'a') {
109 known_flag_found =
'a';
110 }
else if (flags[i] ==
'p' || flags[i] ==
'P') {
111 if (known_flag_found && known_flag_found !=
'p') {
114 known_flag_found =
'p';
132 const char *current_pos = services;
133 const char *end_of_services = services + services_size;
135 if (services_size == 0) {
145 char *plus_pos = memchr(current_pos,
'+', end_of_services - current_pos);
146 uint8_t current_size = plus_pos ? plus_pos - current_pos : end_of_services - current_pos;
149 if (!isalpha(current_pos[0])) {
153 if (current_size > 32) {
157 for (i = 1; i < current_size; ++i) {
158 if (!isalnum(current_pos[i])) {
166 current_pos = plus_pos + 1;
195 if (end - flags > 1) {
230 const char *ptr = repl;
238 char *backslash_pos = memchr(ptr,
'\\', end - ptr);
239 if (!backslash_pos) {
248 if (!strchr(
"12345689", backslash_pos[1]) && backslash_pos[1] != delim) {
252 ptr = backslash_pos + 1;
277 int pattern_size = end - pattern;
278 char pattern_str[pattern_size + 1];
283 memcpy(pattern_str, pattern, pattern_size);
284 pattern_str[pattern_size] =
'\0';
286 res = regcomp(®, pattern_str, REG_EXTENDED);
312 const char *delim2_pos;
313 const char *delim3_pos;
314 const char *ptr = regexp;
315 const char *end_of_regexp = regexp + regexp_size;
316 const char *regex_pos;
317 const char *repl_pos;
318 const char *flags_pos;
320 if (regexp_size == 0) {
333 if (strchr(
"123456789\\i", delim)) {
341 delim2_pos = memchr(ptr, delim, end_of_regexp - ptr);
345 ptr = delim2_pos + 1;
346 if (delim2_pos[-1] !=
'\\') {
351 if (ptr >= end_of_regexp) {
358 delim3_pos = memchr(ptr, delim, end_of_regexp - ptr);
362 ptr = delim3_pos + 1;
363 if (delim3_pos[-1] !=
'\\') {
378 #define PAST_END_OF_RECORD ptr >= end_of_record 388 uint8_t services_size;
393 int replacement_size;
394 const char *end_of_record;
401 end_of_record = ptr + size;
444 replacement_size = dn_expand((
unsigned char *)query->
result->
answer,
445 (
unsigned char *) end_of_record, (
unsigned char *) ptr,
446 replacement,
sizeof(replacement) - 1);
447 if (replacement_size < 0) {
452 ptr += replacement_size;
454 if (ptr != end_of_record) {
464 ast_log(
LOG_ERROR,
"NAPTR Record contained invalid flags %.*s\n", flags_size, flags);
469 ast_log(
LOG_ERROR,
"NAPTR record contained invalid services %.*s\n", services_size, services);
474 ast_log(
LOG_ERROR,
"NAPTR record contained invalid regexp %.*s\n", regexp_size, regexp);
481 if (regexp_size && replacement_size > 1) {
482 ast_log(
LOG_ERROR,
"NAPTR record contained both a regexp and replacement\n");
486 naptr_len =
sizeof(*naptr) + size + flags_size + 1 + services_size + 1
487 + regexp_size + 1 + strlen(replacement) + 1;
499 strncpy(ptr, flags, flags_size);
500 ptr[flags_size] =
'\0';
502 ptr += flags_size + 1;
504 strncpy(ptr, services, services_size);
505 ptr[services_size] =
'\0';
507 ptr += services_size + 1;
509 strncpy(ptr, regexp, regexp_size);
510 ptr[regexp_size] =
'\0';
512 ptr += regexp_size + 1;
514 strcpy(ptr, replacement);
528 if ((*left)->order < (*right)->order) {
530 }
else if ((*left)->order > (*right)->order) {
542 if ((*left)->preference < (*right)->preference) {
544 }
else if ((*left)->preference > (*right)->preference) {
554 size_t num_records = 0;
566 if (num_records == 0) {
571 records =
ast_alloca(num_records *
sizeof(*records));
581 qsort(records, num_records,
sizeof(*records),
compare_order);
584 for (i = 0; i < num_records; i = j) {
585 cur_order = records[i]->
order;
586 for (j = i + 1; j < num_records; ++j) {
587 if (records[j]->
order != cur_order) {
595 for (i = 0; i < num_records; ++i) {
Asterisk main include file. File version handling, generic pbx functions.
void dns_naptr_sort(struct ast_dns_result *result)
Sort the NAPTR records on a result.
int dns_parse_string(char *cur, uint8_t *size, char **val)
Parse a DNS string from a DNS record.
static int compare_order(const void *record1, const void *record2)
const char * replacement
The replacement from the NAPTR record.
char * data_ptr
pointer to record-specific data.
const char * ast_dns_naptr_get_flags(const struct ast_dns_record *record)
Get the flags from a NAPTR record.
const char * flags
The flags from the NAPTR record.
int dns_parse_short(unsigned char *cur, uint16_t *val)
Parse a 16-bit unsigned value from a DNS record.
static int regexp_flags_invalid(const char *flags, const char *end)
Determine if flags in the regexp are invalid.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
const char * regexp
The regular expression from the NAPTR record.
unsigned short ast_dns_naptr_get_order(const struct ast_dns_record *record)
Get the order from a NAPTR record.
static int services_invalid(const char *services, uint8_t services_size)
Analyze NAPTR services for validity as defined by RFC 3404.
static int compare_preference(const void *record1, const void *record2)
static int regexp_repl_invalid(const char *repl, const char *end, char delim)
Determine if the replacement in the regexp is invalid.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
A set of macros to manage forward-linked lists.
unsigned short ast_dns_naptr_get_preference(const struct ast_dns_record *record)
Get the preference from a NAPTR record.
struct ast_dns_record * dns_naptr_alloc(struct ast_dns_query *query, const char *data, const size_t size)
Allocate and parse a DNS NAPTR record.
const char * ast_dns_naptr_get_service(const struct ast_dns_record *record)
Get the service from a NAPTR record.
char data[0]
The raw DNS record.
const char * service
The service from the NAPTR record.
The result of a DNS query.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define PAST_END_OF_RECORD
static enum flags_result interpret_flags(const char *flags, uint8_t flags_size)
Analyze and interpret NAPTR flags as per RFC 3404.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
char data[0]
Buffer for NAPTR-specific data.
struct ast_dns_result * result
Result of the DNS query.
const char * ast_dns_naptr_get_replacement(const struct ast_dns_record *record)
Get the replacement value from a NAPTR record.
static int regexp_pattern_invalid(const char *pattern, const char *end)
Determine if the pattern in a regexp is invalid.
const char * ast_dns_naptr_get_regexp(const struct ast_dns_record *record)
Get the regular expression from a NAPTR record.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Internal DNS structure definitions.
#define ast_calloc(num, len)
A wrapper for calloc()
unsigned short preference
The preference of the NAPTR record.
flags_result
Result of analyzing NAPTR flags on a record.
static int regexp_invalid(const char *regexp, uint8_t regexp_size)
Determine if the regexp in a NAPTR record is invalid.
DNS NAPTR Record Parsing API.
struct ast_dns_record generic
Generic DNS record information.
char * dns_find_record(const char *record, size_t record_size, const char *response, size_t response_size)
Find the location of a DNS record within the entire DNS answer.
size_t answer_size
The size of the raw DNS answer.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
int ast_dns_record_get_rr_type(const struct ast_dns_record *record)
Get the resource record type of a DNS record.
const char * answer
The raw DNS answer.
struct ast_dns_result::dns_records records
unsigned short order
The order for the NAPTR record.