summaryrefslogtreecommitdiff
path: root/src/zscanner/scanner.h
blob: d7689f78939d40b476bd00c6a162adb85ac7a3df (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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
/*  Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/*!
 * \file scanner.h
 *
 * \author Daniel Salzman <daniel.salzman@nic.cz>
 *
 * \brief Zone scanner.
 *
 * \addtogroup zone_scanner
 * @{
 */

#ifndef _ZSCANNER__SCANNER_H_
#define _ZSCANNER__SCANNER_H_

#include <stdint.h>			// uint32_t
#include <stdbool.h>			// bool

/*! \brief Maximal length of rdata. */
#define MAX_RDATA_LENGTH		65535
/*! \brief Maximal length of rdata item. */
#define MAX_ITEM_LENGTH			255
/*! \brief Maximal length of domain name. */
#define MAX_DNAME_LENGTH		255
/*! \brief Maximal length of domain name label. */
#define MAX_LABEL_LENGTH		63
/*! \brief Maximal number or rdata items. */
#define MAX_RDATA_ITEMS			64

/*! \brief Number of bitmap windows. */
#define BITMAP_WINDOWS			256

/*! \brief Length of ipv4 address in wire format. */
#define INET4_ADDR_LENGTH		4
/*! \brief Length of ipv6 address in wire format. */
#define INET6_ADDR_LENGTH		16

/*! \brief Ragel call stack size (see Ragel internals). */
#define RAGEL_STACK_SIZE		16

/*! \brief ASCII value of '0' character. */
#define ASCII_0				48

/*! \brief Latitude value for equator (2^31). */
#define LOC_LAT_ZERO	(uint32_t)2147483648
/*! \brief Longitude value for meridian (2^31). */
#define LOC_LONG_ZERO	(uint32_t)2147483648
/*! \brief Zero level altitude value. */
#define LOC_ALT_ZERO	(uint32_t)10000000

/*! \brief Auxiliary structure for storing bitmap window items (see RFC4034). */
typedef struct {
	uint8_t bitmap[32];
	uint8_t length;
} window_t;

/*! \brief Auxiliary structure for storing one APL record (see RFC3123). */
typedef struct {
	uint8_t  excl_flag;
	uint16_t addr_family;
	uint8_t  prefix_length;
} apl_t;

/*! \brief Auxiliary structure for storing LOC information (see RFC1876). */
typedef struct {
	uint32_t d1, d2;
	uint32_t m1, m2;
	uint32_t s1, s2;
	uint32_t alt;
	uint64_t siz, hp, vp;
	int8_t   lat_sign, long_sign, alt_sign;
} loc_t;

/*!
 * \brief Context structure for zone scanner.
 *
 * This structure contains folowing items:
 *  - Copies of Ragel internal variables. The scanner can be called many times
 *    on smaller parts of zone file/memory. So it is necessary to preserve
 *    internal values between subsequent scanner callings.
 *  - Auxiliary variables which are used during processing zone data.
 *  - Pointers to callback functions and pointer to any arbitrary data which
 *    can be used in callback functions.
 *  - Zone file and error information.
 *  - Output variables (r_ prefix) containing all parts of zone record. These
 *    data are usefull during processing via callback function.
 */
typedef struct scanner scanner_t; // Forward declaration due to arguments.
struct scanner {
	/*! Current state (Ragel internals). */
	int      cs;
	/*! Stack top (Ragel internals). */
	int      top;
	/*! Call stack (Ragel internals). */
	int      stack[RAGEL_STACK_SIZE];

	/*! Indicates whether current record is multiline. */
	bool     multiline;
	/*! Auxiliary number for all numeric operations. */
	uint64_t number64;
	/*! Auxiliary variable for time and other numeric operations. */
	uint64_t number64_tmp;
	/*! Auxiliary variable for float numeric operations. */
	uint32_t decimals;
	/*! Auxiliary variable for float numeric operations. */
	uint32_t decimal_counter;

	/*! Auxiliary variable for item length (label, base64, ...). */
	uint32_t item_length;
	/*! Auxiliary index for item length position in array. */
	uint32_t item_length_position;
	/*! Auxiliary pointer to item length. */
	uint8_t *item_length_location;
	/*! Auxiliary buffer for data storing. */
	uint8_t  buffer[MAX_RDATA_LENGTH];
	/*! Auxiliary buffer length. */
	uint32_t buffer_length;
	/*! Auxiliary buffer for current included file name. */
	char     include_filename[MAX_RDATA_LENGTH + 1];

	/*! Auxiliary array of bitmap window blocks. */
	window_t windows[BITMAP_WINDOWS];
	/*! Last window block which is used (-1 means no window). */
	int16_t  last_window;
	/*! Auxiliary apl structure. */
	apl_t    apl;
	/*! Auxiliary loc structure. */
	loc_t    loc;

	/*! Pointer to the actual dname storage (origin/owner/rdata). */
	uint8_t  *dname;
	/*! Pointer to the actual dname length storage. */
	uint32_t *dname_length;
	/*!
	 * Temporary dname length which is copied to dname_length after
	 * dname processing.
	 */
	uint32_t dname_tmp_length;
	/*! Position of the last free r_data byte. */
	uint32_t r_data_tail;

	/*! Wire format of the current origin (ORIGIN directive sets this). */
	uint8_t  zone_origin[MAX_DNAME_LENGTH];
	/*! Length of the current origin. */
	uint32_t zone_origin_length;
	/*! Value of the default class. */
	uint16_t default_class;
	/*! Value of the current default ttl (TTL directive sets this). */
	uint32_t default_ttl;

	/*! Callback function for correct zone record. */
	void (*process_record)(const scanner_t *);
	/*! Callback function for wrong situations. */
	void (*process_error)(const scanner_t *);
	/*! Arbitrary data useful inside callback functions. */
	void *data;

	/*! Absolute path for relative includes. */
	char     *path;
	/*! Zone file name, if specified. */
	char     *file_name;
	/*! Zone file line counter. */
	uint64_t line_counter;
	/*! Last occured error/warning code. */
	int      error_code;
	/*! Errors/warnings counter. */
	uint64_t error_counter;
	/*!
	 * Indicates serious warning which is considered as an error and
	 * forces zone processing to stop.
	 */
	bool     stop;

	/*!
	 * Owner of the current record.
	 *
	 * \note The double length of the r_owner is due to dname length
	 *       check is after concatenation of relative and origin dnames.
	 */
	uint8_t  r_owner[2 * MAX_DNAME_LENGTH];
	/*! Length of the current record owner. */
	uint32_t r_owner_length;
	/*! Class of the current record. */
	uint16_t r_class;
	/*! TTL of the current record. */
	uint32_t r_ttl;
	/*! Type of the current record data. */
	uint16_t r_type;
	/*! Current rdata. */
	uint8_t  r_data[MAX_RDATA_LENGTH];
	/*! Length of the current rdata. */
	uint32_t r_data_length;

	/*
	 * Example: a. IN 60 MX 1 b.
	 *
	 *          r_owner = 016100
	 *          r_owner_length = 3
	 *          r_class = 1
	 *          r_ttl = 60
	 *          r_type = 15
	 *          r_data = 0001016200
	 *          r_data_length = 5
	 */
};

/*!
 * \brief Creates zone scanner structure.
 *
 * \param file_name		Name of file to process (NULL if parsing from
 * 				memory).
 * \param origin		Initial zone origin.
 * \param rclass		Zone class value.
 * \param ttl			Initial ttl value.
 * \param process_record	Processing callback function.
 * \param process_error 	Error callback function.
 * \param data			Arbitrary data useful in callback functions.
 *
 * \retval scanner	if success.
 * \retval 0		if error.
 */
scanner_t* scanner_create(const char     *file_name,
                          const char     *origin,
                          const uint16_t rclass,
                          const uint32_t ttl,
                          void (*process_record)(const scanner_t *),
                          void (*process_error)(const scanner_t *),
                          void *data);

/*!
 * \brief Destroys zone scanner structure.
 *
 * \param scanner	Zone scanner structure.
 */
void scanner_free(scanner_t *scanner);

/*!
 * \brief Executes zone scanner on data block.
 *
 * \note Zone scanner error code and other information are stored in
 *       the scanner structure.
 *
 * \param start		First byte of the zone data to scan.
 * \param end		Last byte of the zone data to scan.
 * \param is_complete	Indicates if the current block is complete i.e. the
 * 			last record line doesn't continue in the next block.
 * \param scanner	Zone scanner structure.
 *
 * \retval  0		if success.
 * \retval -1		if error.
 */
int scanner_process(const char *start,
                    const char *end,
                    const bool is_complete,
                    scanner_t  *scanner);

#endif // _ZSCANNER__SCANNER_H_

/*! @} */