diff options
Diffstat (limited to 'src/include/ipxe/dns.h')
| -rw-r--r-- | src/include/ipxe/dns.h | 178 |
1 files changed, 117 insertions, 61 deletions
diff --git a/src/include/ipxe/dns.h b/src/include/ipxe/dns.h index 164c16aec..4f6cab3a4 100644 --- a/src/include/ipxe/dns.h +++ b/src/include/ipxe/dns.h @@ -12,88 +12,144 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <stdint.h> #include <ipxe/in.h> -/* - * Constants +/** DNS server port */ +#define DNS_PORT 53 + +/** An RFC1035-encoded DNS name */ +struct dns_name { + /** Start of data */ + void *data; + /** Offset of name within data */ + size_t offset; + /** Total length of data */ + size_t len; +}; + +/** + * Test for a DNS compression pointer + * + * @v byte Initial byte + * @ret is_compressed Is a compression pointer + */ +#define DNS_IS_COMPRESSED( byte ) ( (byte) & 0xc0 ) + +/** + * Extract DNS compression pointer + * + * @v word Initial word + * @ret offset Offset + */ +#define DNS_COMPRESSED_OFFSET( word ) ( (word) & ~0xc000 ) + +/** + * Extract DNS label length * + * @v byte Initial byte + * @ret len Label length */ +#define DNS_LABEL_LEN( byte ) ( (byte) & ~0xc0 ) -#define DNS_TYPE_A 1 -#define DNS_TYPE_CNAME 5 -#define DNS_TYPE_AAAA 28 -#define DNS_TYPE_ANY 255 - -#define DNS_CLASS_IN 1 -#define DNS_CLASS_CS 2 -#define DNS_CLASS_CH 3 -#define DNS_CLASS_HS 4 - -#define DNS_FLAG_QUERY ( 0x00 << 15 ) -#define DNS_FLAG_RESPONSE ( 0x01 << 15 ) -#define DNS_FLAG_QR(flags) ( (flags) & ( 0x01 << 15 ) ) -#define DNS_FLAG_OPCODE_QUERY ( 0x00 << 11 ) -#define DNS_FLAG_OPCODE_IQUERY ( 0x01 << 11 ) -#define DNS_FLAG_OPCODE_STATUS ( 0x02 << 11 ) -#define DNS_FLAG_OPCODE(flags) ( (flags) & ( 0x0f << 11 ) ) -#define DNS_FLAG_RD ( 0x01 << 8 ) -#define DNS_FLAG_RA ( 0x01 << 7 ) -#define DNS_FLAG_RCODE_OK ( 0x00 << 0 ) -#define DNS_FLAG_RCODE_NX ( 0x03 << 0 ) -#define DNS_FLAG_RCODE(flags) ( (flags) & ( 0x0f << 0 ) ) - -#define DNS_PORT 53 -#define DNS_MAX_RETRIES 3 -#define DNS_MAX_CNAME_RECURSION 0x30 - -/* - * DNS protocol structures +/** Maximum length of a single DNS label */ +#define DNS_MAX_LABEL_LEN 0x3f + +/** Maximum length of a DNS name (mandated by RFC1035 section 2.3.4) */ +#define DNS_MAX_NAME_LEN 255 + +/** Maximum depth of CNAME recursion * + * This is a policy decision. */ +#define DNS_MAX_CNAME_RECURSION 32 + +/** A DNS packet header */ struct dns_header { - uint16_t id; - uint16_t flags; - uint16_t qdcount; - uint16_t ancount; - uint16_t nscount; - uint16_t arcount; + /** Query identifier */ + uint16_t id; + /** Flags */ + uint16_t flags; + /** Number of question records */ + uint16_t qdcount; + /** Number of answer records */ + uint16_t ancount; + /** Number of name server records */ + uint16_t nscount; + /** Number of additional records */ + uint16_t arcount; } __attribute__ (( packed )); -struct dns_query_info { - uint16_t qtype; - uint16_t qclass; -} __attribute__ (( packed )); +/** Recursion desired flag */ +#define DNS_FLAG_RD 0x0100 -struct dns_query { - struct dns_header dns; - char payload[ 256 + sizeof ( struct dns_query_info ) ]; +/** A DNS question */ +struct dns_question { + /** Query type */ + uint16_t qtype; + /** Query class */ + uint16_t qclass; } __attribute__ (( packed )); -struct dns_rr_info_common { - uint16_t type; - uint16_t class; - uint32_t ttl; - uint16_t rdlength; +/** DNS class "IN" */ +#define DNS_CLASS_IN 1 + +/** A DNS resource record */ +struct dns_rr_common { + /** Type */ + uint16_t type; + /** Class */ + uint16_t class; + /** Time to live */ + uint32_t ttl; + /** Resource data length */ + uint16_t rdlength; } __attribute__ (( packed )); -struct dns_rr_info_a { - struct dns_rr_info_common common; +/** Type of a DNS "A" record */ +#define DNS_TYPE_A 1 + +/** A DNS "A" record */ +struct dns_rr_a { + /** Common fields */ + struct dns_rr_common common; + /** IPv4 address */ struct in_addr in_addr; } __attribute__ (( packed )); -struct dns_rr_info_aaaa { - struct dns_rr_info_common common; +/** Type of a DNS "AAAA" record */ +#define DNS_TYPE_AAAA 28 + +/** A DNS "AAAA" record */ +struct dns_rr_aaaa { + /** Common fields */ + struct dns_rr_common common; + /** IPv6 address */ struct in6_addr in6_addr; } __attribute__ (( packed )); -struct dns_rr_info_cname { - struct dns_rr_info_common common; - char cname[0]; +/** Type of a DNS "NAME" record */ +#define DNS_TYPE_CNAME 5 + +/** A DNS "CNAME" record */ +struct dns_rr_cname { + /** Common fields */ + struct dns_rr_common common; } __attribute__ (( packed )); -union dns_rr_info { - struct dns_rr_info_common common; - struct dns_rr_info_a a; - struct dns_rr_info_aaaa aaaa; - struct dns_rr_info_cname cname; +/** A DNS resource record */ +union dns_rr { + /** Common fields */ + struct dns_rr_common common; + /** "A" record */ + struct dns_rr_a a; + /** "AAAA" record */ + struct dns_rr_aaaa aaaa; + /** "CNAME" record */ + struct dns_rr_cname cname; }; +extern int dns_encode ( const char *string, struct dns_name *name ); +extern int dns_decode ( struct dns_name *name, char *data, size_t len ); +extern int dns_compare ( struct dns_name *first, struct dns_name *second ); +extern int dns_copy ( struct dns_name *src, struct dns_name *dst ); +extern int dns_skip ( struct dns_name *name ); + #endif /* _IPXE_DNS_H */ |
