summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/include/ipxe/dns.h
blob: 738dea6e4803c87cbc8c03bd1afe31b5f1deb314 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#ifndef _IPXE_DNS_H
#define _IPXE_DNS_H

/** @file
 *
 * DNS protocol
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdint.h>
#include <ipxe/in.h>

/** 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 )

/** 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 {
	/** 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 ));

/** Recursion desired flag */
#define DNS_FLAG_RD 0x0100

/** A DNS question */
struct dns_question {
	/** Query type */
	uint16_t qtype;
	/** Query class */
	uint16_t qclass;
} __attribute__ (( packed ));

/** 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 ));

/** 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 ));

/** 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 ));

/** 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 ));

/** 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 */