- // - Additional records, pass to handler
- for( unsigned int i = 0; i < ar_count; i ++ )
- {
- enum eTypes type;
- enum eClass class;
- uint32_t ttl;
- size_t rdlength;
- int rv = DNS_int_ParseRR(packet + pos, return_len - pos, rr_name, &type, &class, &ttl, &rdlength);
- if( rv < 0 ) {
- return 1;
- }
- pos += rv;
-
- handle_record(info, rr_name, type, class, ttl, rdlength, packet + pos);
- }
-
- return 0;
-}
-
-/// Encode a dotted name as a DNS name
-size_t DNS_EncodeName(void *buf, const char *dotted_name)
-{
- size_t ret = 0;
- const char *str = dotted_name;
- uint8_t *buf8 = buf;
- while( *str )
- {
- const char *next = strchr(str, '.');
- size_t seg_len = (next ? next - str : strlen(str));
- if( seg_len > 63 ) {
- // Oops, too long (truncate)
- seg_len = 63;
- }
- if( seg_len == 0 && next != NULL ) {
- // '..' encountered, invalid (skip)
- str = next+1;
- continue ;
- }
-
- if( buf8 )
- {
- buf8[ret] = seg_len;
- memcpy(buf8+ret+1, str, seg_len);
- }
- ret += 1 + seg_len;
-
- if( next == NULL ) {
- // No trailing '.', assume it's there? Yes, need to be NUL terminated
- if(buf8) buf8[ret] = 0;
- ret ++;
- break;
- }
- else {
- str = next + 1;
- }
- }
- return ret;
-}
-
-// Decode a name (including trailing . for root)
-int DNS_DecodeName(char dotted_name[256], const void *buf, size_t space)
-{
- int consumed = 0;
- int out_pos = 0;
- const uint8_t *buf8 = buf;
- while( *buf8 && space > 0 )
- {
- if( consumed + 1 > space ) return -1;
- uint8_t seg_len = *buf8;
- buf8 ++;
- consumed ++;
- // Protocol violation (overflowed end of buffer)
- if( consumed + seg_len > space )
- return -1;
- // Protocol violation (segment too long)
- if( seg_len >= 64 )
- return -1;
- // Protocol violation (name was too long)
- if( out_pos + seg_len + 1 > sizeof(dotted_name)-1 )
- return -1;
-
- // Read segment
- memcpy(dotted_name + out_pos, buf8, seg_len);
- buf8 += seg_len;
- consumed += seg_len;
-
- // Place '.'
- dotted_name[out_pos+seg_len+1] = '.';
- // Increment output counter
- out_pos += seg_len + 1;