60#define ENXIO_NO_RECORD __einfo_error ( EINFO_ENXIO_NO_RECORD )
61#define EINFO_ENXIO_NO_RECORD \
62 __einfo_uniqify ( EINFO_ENXIO, 0x01, "DNS name does not exist" )
63#define ENXIO_NO_NAMESERVER __einfo_error ( EINFO_ENXIO_NO_NAMESERVER )
64#define EINFO_ENXIO_NO_NAMESERVER \
65 __einfo_uniqify ( EINFO_ENXIO, 0x02, "No DNS servers available" )
109 while ( ( c = *(
string++) ) ) {
115 if ( (
len == 0 ) && ( dst !=
start ) )
119 if ( *
string ==
'\0' )
153 return ( dst -
start );
172 if ( (
offset +
sizeof ( *
byte) ) >
name->len )
218 unsigned int recursion_limit =
name->len;
221 size_t decoded_len = 0;
225 while ( recursion_limit-- ) {
234 label_len = *(
label++);
235 if ( label_len == 0 ) {
236 if ( decoded_len <
len )
242 if ( decoded_len && ( decoded_len++ <
len ) )
246 copy_len = ( ( decoded_len <
len ) ? (
len - decoded_len ) : 0);
247 if ( copy_len > label_len )
248 copy_len = label_len;
251 decoded_len += label_len;
254 offset += (
sizeof ( *label ) + label_len );
269 unsigned int recursion_limit =
first->len;
270 int first_offset =
first->offset;
271 int second_offset = second->
offset;
277 while ( recursion_limit-- ) {
281 if ( first_offset < 0 )
283 second_offset =
dns_label ( second, second_offset );
284 if ( second_offset < 0 )
285 return second_offset;
288 first_label = (
first->data + first_offset );
289 second_label = ( second->
data + second_offset );
290 label_len = *(first_label++);
291 if ( label_len != *(second_label++) )
293 len = (
sizeof ( *first_label ) + label_len );
296 if ( label_len == 0 )
300 while ( label_len-- ) {
301 if (
tolower ( *(first_label++) ) !=
302 tolower ( *(second_label++) ) )
308 second_offset +=
len;
323 unsigned int recursion_limit =
src->len;
324 int src_offset =
src->offset;
325 size_t dst_offset = dst->
offset;
331 while ( recursion_limit-- ) {
335 if ( src_offset < 0 )
341 len = (
sizeof ( *label ) + label_len );
342 copy_len = ( ( dst_offset < dst->
len ) ?
343 ( dst->
len - dst_offset ) : 0 );
344 if ( copy_len >
len )
351 if ( label_len == 0 )
352 return ( dst_offset - dst->
offset );
366 unsigned int recursion_limit =
name->len;
372 while ( recursion_limit-- ) {
381 if (
offset != prev_offset )
382 return ( prev_offset +
sizeof (
uint16_t ) );
387 offset += (
sizeof ( *label ) + label_len );
390 if ( label_len == 0 )
430 static char buf[256];
434 return ( (
len < 0 ) ?
"<INVALID>" : buf );
448 default:
return "<UNKNOWN>";
520 DBGC ( dns,
"DNS %p found address %s\n",
537 static struct dns_name search_root = {
547 search = &search_root;
558 DBGC ( dns,
"DNS %p name is too long\n", dns );
576 DBGC2 ( dns,
"DNS %p question is %s type %s\n", dns,
603 memset ( &nameserver, 0,
sizeof ( nameserver ) );
606 DBGC ( dns,
"DNS %p lost DNS servers mid query\n", dns );
611 nameserver.sin6.sin6_family =
AF_INET6;
613 sizeof ( nameserver.sin6.sin6_addr ) );
615 nameserver.sin.sin_family =
AF_INET;
621 meta.dest = &nameserver.sa;
628 DBGC ( dns,
"DNS %p sending %s query ID %#04x for %s type %s\n", dns,
677 size_t answer_offset;
684 if (
iob_len ( iobuf ) <
sizeof ( *response ) ) {
685 DBGC ( dns,
"DNS %p received underlength packet length %zd\n",
692 if ( response->
id != query->
id ) {
693 DBGC ( dns,
"DNS %p received unexpected response ID %#04x "
694 "(wanted %d)\n", dns,
ntohs ( response->
id ),
699 DBGC ( dns,
"DNS %p received response ID %#04x\n",
704 DBGC ( dns,
"DNS %p received response with %d questions\n",
712 buf.
offset =
sizeof ( *response );
717 DBGC ( dns,
"DNS %p received response with malformed "
729 buf.
offset = next_offset ) {
732 offset = dns_skip ( &buf );
735 DBGC ( dns,
"DNS %p received response with malformed "
736 "answer: %s\n", dns, strerror ( rc ) );
743 DBGC ( dns,
"DNS %p received response with underlength "
749 next_offset = (
offset + sizeof ( rr->
common ) + rdlength );
750 if ( next_offset > buf.
len ) {
751 DBGC ( dns,
"DNS %p received response with underlength "
759 DBGC2 ( dns,
"DNS %p ignoring response for %s type "
760 "%s\n", dns, dns_name ( &buf ),
761 dns_type ( rr->common.type ) );
768 case htons ( DNS_TYPE_AAAA ):
771 if ( rdlength < sizeof ( dns->address.sin6.sin6_addr )){
772 DBGC ( dns,
"DNS %p received response with "
773 "underlength AAAA\n", dns );
789 DBGC ( dns,
"DNS %p received response with "
790 "underlength A\n", dns );
804 DBGC ( dns,
"DNS %p recursion exceeded\n",
813 DBGC ( dns,
"DNS %p found CNAME %s\n",
823 next_offset = answer_offset;
827 DBGC ( dns,
"DNS %p got unknown record type %d\n",
849 DBGC ( dns,
"DNS %p found no AAAA record; trying A\n", dns );
859 DBGC ( dns,
"DNS %p found no A record; trying CNAME\n", dns );
879 if ( dns->search.offset == dns->search.len ) {
880 DBGC ( dns,
"DNS %p found no CNAME record\n", dns );
889 DBGC ( dns,
"DNS %p found no CNAME record; trying next "
939 ( sizeof ( progress->
message ) - 1 ) );
986 DBG (
"DNS not attempting to resolve \"%s\": "
987 "no DNS servers\n",
name );
989 goto err_no_nameserver;
996 dns =
zalloc (
sizeof ( *dns ) + search_len );
1006 dns->
search.
data = ( ( (
void * ) dns ) +
sizeof ( *dns ) );
1022 if ( name_len < 0 ) {
1034 DBGC ( dns,
"DNS %p could not open socket: %s\n",
1036 goto err_open_socket;
1081 char *buf,
size_t len ) {
1083 .data = ( (
void * )
raw ),
1086 size_t remaining =
len;
1093 remaining = ( ( total <
len ) ? (
len - total ) : 0 );
1122 .description =
"DNS server",
1124 .type = &setting_type_ipv4,
1130 .description =
"DNS server",
1132 .type = &setting_type_ipv6,
1139 .description =
"DNS search list",
1141 .type = &setting_type_dnssl,
1190 if ( localdomain ) {
1199 free ( localdomain );
1222 DBGC2 ( dbgcol,
"DNS servers:" );
1223 for ( i = 0 ; i <
dns6.count ; i++ ) {
1226 sizeof (
u.sin6.sin6_addr ) );
1229 for ( i = 0 ; i <
dns4.count ; i++ ) {
1231 u.sin.sin_addr =
dns4.in[i];
1234 DBGC2 ( dbgcol,
"\n" );
1243 DBGC2 ( dbgcol,
"DNS search list:" );
1245 while (
name.offset !=
name.len ) {
1252 DBGC2 ( dbgcol,
"\n" );
#define NULL
NULL pointer (VOID *)
typeof(acpi_finder=acpi_find)
ACPI table finder.
struct arbelprm_rc_send_wqe rc
#define assert(condition)
Assert a condition at run-time.
struct bofm_section_header done
uint16_t offset
Offset to command line.
static int tolower(int character)
Convert character to lower case.
union @104331263140136355135267063077374276003064103115 u
Dynamic Host Configuration Protocol for IPv6.
#define DHCPV6_DNS_SERVERS
DHCPv6 DNS recursive name server option.
static int dns_progress(struct dns_request *dns, struct job_progress *progress)
Report job progress.
static unsigned int dns_count
Total number of DNS servers.
static int apply_dns_settings(void)
Apply DNS settings.
static struct dns_server dns6
IPv6 DNS server list.
static struct dns_server dns4
IPv4 DNS server list.
static void dns_xfer_close(struct dns_request *dns, int rc)
Receive new data.
static struct interface_descriptor dns_resolv_desc
DNS resolver interface descriptor.
static void dns_done(struct dns_request *dns, int rc)
Mark DNS request as complete.
int dns_encode(const char *string, struct dns_name *name)
Encode a DNS name using RFC1035 encoding.
static int dns_skip_search(struct dns_name *name)
Skip RFC1035-encoded DNS name in search list.
static const char * dns_type(uint16_t type)
Name a DNS query type (for debugging)
static void apply_dns_servers(void)
Apply DNS server addresses.
static int format_dnssl_setting(const struct setting_type *type __unused, const void *raw, size_t raw_len, char *buf, size_t len)
Format DNS search list setting.
static void dns_timer_expired(struct retry_timer *timer, int fail)
Handle DNS (re)transmission timer expiry.
static int dns_xfer_deliver(struct dns_request *dns, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Receive new data.
static int dns_resolv(struct interface *resolv, const char *name, struct sockaddr *sa)
Resolve name using DNS.
int dns_skip(struct dns_name *name)
Skip RFC1035-encoded DNS name.
int dns_copy(struct dns_name *src, struct dns_name *dst)
Copy a DNS name.
static void apply_dns_search(void)
Apply DNS search list.
int dns_compare(struct dns_name *first, struct dns_name *second)
Compare DNS names for equality.
static int dns_label(struct dns_name *name, size_t offset)
Find start of valid label within an RFC1035-encoded DNS name.
#define ENXIO_NO_NAMESERVER
static struct interface_operation dns_socket_operations[]
DNS socket interface operations.
static struct interface_operation dns_resolv_op[]
DNS resolver interface operations.
static struct dns_name dns_search
The DNS search list.
int dns_decode(struct dns_name *name, char *data, size_t len)
Decode RFC1035-encoded DNS name.
static struct interface_descriptor dns_socket_desc
DNS socket interface descriptor.
static const char * dns_name(struct dns_name *name)
Transcribe DNS name (for debugging)
static int dns_send_packet(struct dns_request *dns)
Send DNS query.
static void dns_resolved(struct dns_request *dns)
Mark DNS request as resolved and complete.
static int dns_question(struct dns_request *dns)
Construct DNS question.
#define DNS_MAX_CNAME_RECURSION
Maximum depth of CNAME recursion.
#define DNS_FLAG_RD
Recursion desired flag.
#define DNS_TYPE_CNAME
Type of a DNS "NAME" record.
#define DNS_COMPRESSED_OFFSET(word)
Extract DNS compression pointer.
#define DNS_IS_COMPRESSED(byte)
Test for a DNS compression pointer.
#define DNS_MAX_NAME_LEN
Maximum length of a DNS name (mandated by RFC1035 section 2.3.4)
#define DNS_CLASS_IN
DNS class "IN".
#define DNS_PORT
DNS server port.
#define DNS_MAX_LABEL_LEN
Maximum length of a single DNS label.
#define DNS_TYPE_AAAA
Type of a DNS "AAAA" record.
#define DNS_TYPE_A
Type of a DNS "A" record.
const struct setting dns_setting
const struct setting dns6_setting
uint32_t type
Operating system type.
uint8_t data[48]
Additional event data.
uint8_t meta
Metadata flags.
uint64_t address
Base address.
#define AF_INET
IPv4 Internet addresses.
#define AF_INET6
IPv6 Internet addresses.
#define __unused
Declare a variable or data structure as unused.
#define DBG(...)
Print a debugging message.
#define DHCP_EB_FEATURE_DNS
DNS protocol.
#define DHCP_DNS_SERVERS
DNS servers.
#define DHCP_DOMAIN_SEARCH
DNS domain search list.
#define FEATURE_PROTOCOL
Network protocols.
uint32_t start
Starting offset.
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
#define ENOENT
No such file or directory.
#define EINVAL
Invalid argument.
#define ELOOP
Too many levels of symbolic links.
#define ECONNABORTED
Connection aborted.
#define ETIMEDOUT
Connection timed out.
#define ENOMEM
Not enough space.
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
#define SETTING_IP4_EXTRA
IPv4 additional settings.
#define SETTING_IP_EXTRA
IPv4 additional settings.
#define SETTING_IP6_EXTRA
IPv6 additional settings.
Dynamic Host Configuration Protocol.
#define __setting(setting_order, name)
Declare a configuration setting.
#define __setting_type
Declare a configuration setting type.
#define __settings_applicator
Declare a settings applicator.
Transport-network layer interface.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void intf_close(struct interface *intf, int rc)
Close an object interface.
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
#define FEATURE(category, text, feature_opt, version)
Declare a feature.
void * zalloc(size_t size)
Allocate cleared memory.
void * malloc(size_t size)
Allocate memory.
if(natsemi->flags &NATSEMI_64BIT) return 1
uint32_t end
Ending offset.
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Data transfer interface opening.
uint32_t first
First block in range.
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
static void(* free)(struct refcnt *refcnt))
#define ref_put(refcnt)
Drop reference to object.
#define ref_init(refcnt, free)
Initialise a reference counter.
void resolv_done(struct interface *intf, struct sockaddr *sa)
Name resolved.
int resolv(struct interface *resolv, const char *name, struct sockaddr *sa)
Start name resolution.
#define __resolver(resolv_order)
Register as a name resolver.
#define RESOLV_NORMAL
Normal resolver priority.
void start_timer(struct retry_timer *timer)
Start timer.
void stop_timer(struct retry_timer *timer)
Stop timer.
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
int fetch_raw_setting_copy(struct settings *settings, const struct setting *setting, void **data)
Fetch value of setting.
const struct settings_scope dhcpv6_scope
IPv6 settings scope.
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
const char * sock_ntoa(struct sockaddr *sa)
Transcribe socket address.
#define offsetof(type, field)
Get offset of a field within a structure.
#define container_of(ptr, type, field)
Get containing structure.
char * strerror(int errno)
Retrieve string representation of error number.
char * strchr(const char *src, int character)
Find character within a string.
An RFC1035-encoded DNS name.
size_t offset
Offset of name within data.
void * data
Start of data.
size_t len
Total length of data.
uint16_t qtype
Query type.
uint16_t qclass
Query class.
struct refcnt refcnt
Reference counter.
struct dns_name search
Search list.
uint16_t qtype
Initial query type.
unsigned int recursion
Recursion counter.
size_t offset
Offset of search suffix within current query.
struct dns_question * question
Question within current query.
struct dns_header query
Query header.
unsigned int index
Server index.
struct retry_timer timer
Retry timer.
size_t len
Length of current query.
struct interface resolv
Name resolution interface.
char name[DNS_MAX_NAME_LEN]
Name buffer.
union dns_request::@312034134017066265334376202135341175127303247071 address
Socket address to fill in with resolved address.
struct dns_question padding
Space for question.
struct dns_request::@313264154177366216076030311163113224373276371112 buf
Buffer for current query.
struct interface socket
Data transfer interface.
struct in_addr in_addr
IPv4 address.
struct in6_addr in6_addr
IPv6 address.
uint16_t rdlength
Resource data length.
struct in_addr * in
IPv4 addresses.
unsigned int count
Number of servers.
struct in6_addr * in6
IPv6 addresses.
An object interface descriptor.
An object interface operation.
void * data
Start of data.
char message[32]
Message (optional)
struct in6_addr sin6_addr
IPv6 address.
sa_family_t sin6_family
Socket address family (part of struct sockaddr)
struct in_addr sin_addr
IPv4 address.
sa_family_t sin_family
Socket address family (part of struct sockaddr)
Generalized socket address structure.
struct dns_rr_aaaa aaaa
"AAAA" record
struct dns_rr_cname cname
"CNAME" record
struct dns_rr_common common
Common fields.
struct dns_rr_a a
"A" record
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
int xfer_deliver_raw_meta(struct interface *intf, const void *data, size_t len, struct xfer_metadata *meta)
Deliver datagram as raw data.
Data transfer interfaces.