GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/relayd/parse.c Lines: 480 1271 37.8 %
Date: 2017-11-13 Branches: 268 829 32.3 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#define YYBYACC 1
4
#define YYMAJOR 1
5
#define YYMINOR 9
6
#define YYLEX yylex()
7
#define YYEMPTY -1
8
#define yyclearin (yychar=(YYEMPTY))
9
#define yyerrok (yyerrflag=0)
10
#define YYRECOVERING() (yyerrflag!=0)
11
#define YYPREFIX "yy"
12
#line 28 "parse.y"
13
#include <sys/types.h>
14
#include <sys/socket.h>
15
#include <sys/stat.h>
16
#include <sys/queue.h>
17
#include <sys/ioctl.h>
18
#include <sys/time.h>
19
#include <sys/tree.h>
20
21
#include <netinet/in.h>
22
#include <arpa/inet.h>
23
#include <net/if.h>
24
#include <net/pfvar.h>
25
#include <net/route.h>
26
27
#include <stdint.h>
28
#include <stdarg.h>
29
#include <stdio.h>
30
#include <unistd.h>
31
#include <ctype.h>
32
#include <err.h>
33
#include <endian.h>
34
#include <errno.h>
35
#include <limits.h>
36
#include <netdb.h>
37
#include <string.h>
38
#include <ifaddrs.h>
39
#include <syslog.h>
40
#include <md5.h>
41
42
#include "relayd.h"
43
#include "http.h"
44
#include "snmp.h"
45
46
TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
47
static struct file {
48
	TAILQ_ENTRY(file)	 entry;
49
	FILE			*stream;
50
	char			*name;
51
	int			 lineno;
52
	int			 errors;
53
} *file, *topfile;
54
struct file	*pushfile(const char *, int);
55
int		 popfile(void);
56
int		 check_file_secrecy(int, const char *);
57
int		 yyparse(void);
58
int		 yylex(void);
59
int		 yyerror(const char *, ...);
60
int		 kw_cmp(const void *, const void *);
61
int		 lookup(char *);
62
int		 lgetc(int);
63
int		 lungetc(int);
64
int		 findeol(void);
65
66
TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
67
struct sym {
68
	TAILQ_ENTRY(sym)	 entry;
69
	int			 used;
70
	int			 persist;
71
	char			*nam;
72
	char			*val;
73
};
74
int		 symset(const char *, const char *, int);
75
char		*symget(const char *);
76
77
struct relayd		*conf = NULL;
78
static int		 errors = 0;
79
static int		 loadcfg = 0;
80
objid_t			 last_rdr_id = 0;
81
objid_t			 last_table_id = 0;
82
objid_t			 last_host_id = 0;
83
objid_t			 last_relay_id = 0;
84
objid_t			 last_proto_id = 0;
85
objid_t			 last_rt_id = 0;
86
objid_t			 last_nr_id = 0;
87
objid_t			 last_key_id = 0;
88
89
static struct rdr	*rdr = NULL;
90
static struct table	*table = NULL;
91
static struct relay	*rlay = NULL;
92
static struct host	*hst = NULL;
93
struct relaylist	 relays;
94
static struct protocol	*proto = NULL;
95
static struct relay_rule *rule = NULL;
96
static struct router	*router = NULL;
97
static int		 label = 0;
98
static int		 tagged = 0;
99
static int		 tag = 0;
100
static in_port_t	 tableport = 0;
101
static int		 dstmode;
102
static enum key_type	 keytype = KEY_TYPE_NONE;
103
static enum direction	 dir = RELAY_DIR_ANY;
104
static char		*rulefile = NULL;
105
static union hashkey	*hashkey = NULL;
106
107
struct address	*host_v4(const char *);
108
struct address	*host_v6(const char *);
109
int		 host_dns(const char *, struct addresslist *,
110
		    int, struct portrange *, const char *, int);
111
int		 host_if(const char *, struct addresslist *,
112
		    int, struct portrange *, const char *, int);
113
int		 host(const char *, struct addresslist *,
114
		    int, struct portrange *, const char *, int);
115
void		 host_free(struct addresslist *);
116
117
struct table	*table_inherit(struct table *);
118
int		 relay_id(struct relay *);
119
struct relay	*relay_inherit(struct relay *, struct relay *);
120
int		 getservice(char *);
121
int		 is_if_in_group(const char *, const char *);
122
123
typedef struct {
124
	union {
125
		int64_t			 number;
126
		char			*string;
127
		struct host		*host;
128
		struct timeval		 tv;
129
		struct table		*table;
130
		struct portrange	 port;
131
		struct {
132
			union hashkey	 key;
133
			int		 keyset;
134
		}			 key;
135
		enum direction		 dir;
136
		struct {
137
			struct sockaddr_storage	 ss;
138
			char			 name[HOST_NAME_MAX+1];
139
		}			 addr;
140
		struct {
141
			enum digest_type type;
142
			char		*digest;
143
		}			 digest;
144
	} v;
145
	int lineno;
146
} YYSTYPE;
147
148
#line 149 "parse.c"
149
#define ALL 257
150
#define APPEND 258
151
#define BACKLOG 259
152
#define BACKUP 260
153
#define BUFFER 261
154
#define CA 262
155
#define CACHE 263
156
#define SET 264
157
#define CHECK 265
158
#define CIPHERS 266
159
#define CODE 267
160
#define COOKIE 268
161
#define DEMOTE 269
162
#define DIGEST 270
163
#define DISABLE 271
164
#define ERROR 272
165
#define EXPECT 273
166
#define PASS 274
167
#define BLOCK 275
168
#define EXTERNAL 276
169
#define FILENAME 277
170
#define FORWARD 278
171
#define FROM 279
172
#define HASH 280
173
#define HEADER 281
174
#define HOST 282
175
#define ICMP 283
176
#define INCLUDE 284
177
#define INET 285
178
#define INET6 286
179
#define INTERFACE 287
180
#define INTERVAL 288
181
#define IP 289
182
#define LABEL 290
183
#define LISTEN 291
184
#define VALUE 292
185
#define LOADBALANCE 293
186
#define LOG 294
187
#define LOOKUP 295
188
#define METHOD 296
189
#define MODE 297
190
#define NAT 298
191
#define NO 299
192
#define DESTINATION 300
193
#define NODELAY 301
194
#define NOTHING 302
195
#define ON 303
196
#define PARENT 304
197
#define PATH 305
198
#define PFTAG 306
199
#define PORT 307
200
#define PREFORK 308
201
#define PRIORITY 309
202
#define PROTO 310
203
#define QUERYSTR 311
204
#define REAL 312
205
24
#define REDIRECT 313
206
24
#define RELAY 314
207
#define REMOVE 315
208
#define REQUEST 316
209
#define RESPONSE 317
210
#define RETRY 318
211
#define QUICK 319
212
#define RETURN 320
213
#define ROUNDROBIN 321
214
#define ROUTE 322
215
#define SACK 323
216
#define SCRIPT 324
217
#define SEND 325
218
#define SESSION 326
219
#define SNMP 327
220
#define SOCKET 328
221
#define SPLICE 329
222
#define SSL 330
223
#define STICKYADDR 331
224
#define STYLE 332
225
#define TABLE 333
226
#define TAG 334
227
#define TAGGED 335
228
#define TCP 336
229
#define TIMEOUT 337
230
#define TLS 338
231
#define TO 339
232
416
#define ROUTER 340
233
548
#define RTLABEL 341
234
132
#define TRANSPARENT 342
235
#define TRAP 343
236
416
#define UPDATES 344
237
548
#define URL 345
238
132
#define VIRTUAL 346
239
#define WITH 347
240
#define TTL 348
241
#define RTABLE 349
242
#define MATCH 350
243
#define PARAMS 351
244
#define RANDOM 352
245
#define LEASTSTATES 353
246
#define SRCHASH 354
247
#define KEY 355
248
#define CERTIFICATE 356
249
#define PASSWORD 357
250
#define ECDH 358
251
#define EDH 359
252
#define CURVE 360
253
#define TICKETS 361
254
#define STRING 362
255
#define NUMBER 363
256
#define YYERRCODE 256
257
const short yylhs[] =
258
	{                                        -1,
259
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
260
    0,   31,   39,   39,   14,   14,   15,   15,    6,    1,
261
    1,   17,   17,   17,   16,   16,   16,   40,   40,   43,
262
   43,   41,   22,   22,   32,   44,   44,   33,   33,   33,
263
   33,   33,    9,    9,    7,    7,   45,   34,   47,   47,
264
   48,   48,   48,   48,   48,   48,   48,   18,   18,   12,
265
   12,   12,    3,   51,   35,   50,   50,   52,   52,   53,
266
140
   53,   54,   54,   56,   28,   55,   55,   57,   57,   57,
267
148
   57,   57,   57,   30,   30,   58,   58,   58,   58,   58,
268
8
   58,   58,   26,   27,   27,   60,   37,   59,   59,   59,
269
956
   61,   61,   62,   62,   62,   62,   62,   62,   62,   62,
270
   66,   66,   65,   65,   65,   65,   65,   65,   65,   65,
271
8
   65,   64,   64,   63,   63,   63,   63,   63,   63,   63,
272
   63,   63,   63,   63,   63,   63,   63,   11,   71,   67,
273
   19,   19,   19,   29,   29,   29,    8,    8,   20,   20,
274
8
   20,   68,   69,   70,   70,   72,   72,   73,   73,   73,
275
8
   73,   73,   73,   73,   73,   73,   73,   73,   73,   73,
276
8
   73,   73,   73,   73,   73,    4,    4,   21,   21,   21,
277
   21,   21,   21,   74,   36,   75,   75,   76,   76,   76,
278
948
   76,   76,   76,   77,   77,   77,   77,   10,   10,   10,
279
   10,   10,   10,   10,   79,   38,   80,   80,   81,   81,
280
948
   81,   81,   81,   81,   78,   78,   78,    2,    2,   83,
281
   23,   82,   82,   84,   84,   85,   85,   85,   85,   24,
282
   13,   13,   25,   42,   42,   42,   46,   46,   49,    5,
283
    5,
284
};
285
const short yylen[] =
286
	{                                         2,
287
    0,    3,    2,    3,    3,    3,    3,    3,    3,    3,
288
    3,    2,    1,    1,    0,    1,    0,    2,    1,    0,
289
    2,    0,    1,    1,    0,    1,    1,    3,    1,    0,
290
    1,    2,    2,    2,    3,    1,    1,    2,    2,    2,
291
    2,    3,    0,    1,    1,    1,    0,    7,    3,    2,
292
    4,    6,    1,    1,    3,    3,    1,    0,    1,    1,
293
    1,    2,    3,    0,    4,    2,    1,    1,    4,    3,
294
    2,    1,    1,    0,    3,    2,    1,    2,    1,    2,
295
    2,    2,    3,    0,    1,    1,    1,    1,    5,    4,
296
    5,    2,    2,    1,    1,    0,    5,    0,    2,    4,
297
    3,    2,    2,    4,    2,    4,    3,    5,    1,    1,
298
    3,    1,    1,    2,    1,    2,    1,    2,    2,    3,
299
    3,    3,    1,    2,    3,    2,    2,    1,    3,    2,
300
    1,    3,    3,    5,    3,    2,    1,    1,    0,    8,
301
    1,    1,    1,    0,    1,    1,    0,    1,    0,    1,
302
    1,    0,    0,    0,    1,    2,    1,    2,    4,    2,
303
    4,    2,    4,    2,    4,    2,    4,    2,    3,    2,
304
    2,    2,    2,    2,    3,    0,    2,    0,    1,    1,
305
    1,    1,    1,    0,    7,    3,    2,    5,    5,    3,
306
    2,    1,    1,    3,    3,    2,    1,    0,    1,    1,
307
    1,    1,    1,    1,    0,    7,    3,    2,    4,    3,
308
    2,    2,    1,    1,    0,    1,    2,    0,    2,    0,
309
    3,    0,    1,    2,    1,    2,    2,    2,    3,    1,
310
    0,    2,    1,    1,    1,    0,    2,    0,    2,    1,
311
    0,
312
};
313
const short yydefred[] =
314
	{                                      1,
315
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
316
   23,    0,    0,    0,    3,    0,    0,    0,    0,    0,
317
    0,    0,    0,    0,   11,   12,   38,   46,   45,   39,
318
   41,   47,  184,   44,    0,    0,   64,  233,   40,  205,
319
    0,    0,    2,    4,    5,    6,    7,    8,    9,   10,
320
    0,    0,  240,   42,    0,    0,    0,   35,   96,    0,
321
    0,   63,   68,    0,    0,   67,    0,    0,    0,    0,
322
    0,    0,   66,    0,    0,   97,  237,   53,   60,    0,
323
   61,    0,   54,    0,   59,    0,    0,   57,    0,    0,
324
  192,    0,    0,    0,    0,  193,    0,    0,  230,   72,
325
  220,   73,    0,    0,  213,    0,    0,    0,    0,  214,
326
    0,    0,   99,    0,    0,    0,   62,    0,    0,   48,
327
    0,   50,    0,  191,    0,    0,    0,  185,    0,  187,
328
    0,   69,    0,  234,    0,   71,  235,    0,    0,  212,
329
  211,  206,    0,  208,  141,  142,    0,   13,    0,   14,
330
  143,    0,  110,    0,    0,    0,  109,    0,   56,   74,
331
    0,   55,    0,   49,    0,  190,   18,    0,  186,    0,
332
    0,    0,    0,  221,  223,    0,    0,   70,  210,    0,
333
  207,    0,    0,    0,    0,  115,  113,    0,  117,    0,
334
  105,  145,  146,    0,    0,    0,    0,    0,    0,    0,
335
  138,    0,  137,  103,  100,    0,  102,   26,   27,    0,
336
    0,    0,   51,  239,    0,    0,    0,    0,    0,  197,
337
    0,    0,  227,  228,  226,  224,  209,    0,    0,   31,
338
  107,  119,    0,  116,  114,  118,    0,    0,    0,  148,
339
    0,    0,    0,    0,  126,    0,  130,  127,  136,  124,
340
    0,    0,    0,    0,  101,    0,    0,    0,    0,    0,
341

2192
    0,   79,   75,    0,  219,   33,   34,  188,   16,    0,
342
    0,  196,    0,  216,    0,  189,  229,   32,    0,    0,
343
  121,  120,    0,  106,  151,  150,  152,  133,    0,  135,
344
  125,  132,  129,    0,  104,   52,   86,    0,    0,   87,
345
1096
   19,    0,   88,   78,   81,   82,  201,  199,  200,  204,
346
1096
  202,  203,    0,   80,   76,  195,  232,  194,  217,  108,
347
    0,  111,  153,    0,  122,   92,   36,   37,    0,    0,
348
1096
   85,   83,   28,  139,  134,    0,    0,    0,    0,    0,
349
   21,    0,    0,   90,    0,    0,    0,    0,    0,    0,
350
    0,    0,    0,    0,    0,    0,  140,  155,    0,   91,
351
   89,   93,  179,  180,  182,  183,  181,    0,    0,    0,
352
    0,  173,  158,  174,  171,    0,    0,  170,  172,    0,
353
  156,    0,    0,  175,  169,    0,    0,    0,   95,   94,
354
    0,  159,  177,  161,  163,  165,  167,
355
};
356
const short yydgoto[] =
357
	{                                       1,
358
  338,  213,  160,  384,   54,  302,   30,  241,   35,  313,
359
  203,   86,  272,  268,  127,  210,   16,   87,  152,  287,
360
  368,  262,  100,  101,   39,  344,  391,  161,  194,  332,
361
   88,   18,   19,   20,   21,   22,   23,   24,  154,  279,
362
  280,  135,  231,  329,   51,   70,   89,   90,  137,   65,
363
   56,   66,  103,  104,  263,  211,  264,  304,   76,   68,
364
  155,  156,  253,  254,  238,  239,  157,  323,  334,  357,
365
  339,  358,  359,   52,   97,   98,  221,  276,   57,  111,
366
  112,  174,  131,  175,  176,
367
};
368
const short yysindex[] =
369
	{                                      0,
370
  189,   36, -309, -301, -237, -293, -284, -275, -254,   66,
371
    0, -233, -211,   95,    0, -151,  151,  153,  158,  168,
372
  172,  175,  179,  182,    0,    0,    0,    0,    0,    0,
373
    0,    0,    0,    0, -168, -166,    0,    0,    0,    0,
374
 -161, -160,    0,    0,    0,    0,    0,    0,    0,    0,
375
   74,   80,    0,    0,  142, -111,   86,    0,    0,  200,
376
  200,    0,    0,  200, -111,    0,  200,   88,  200, 1005,
377
  841, -261,    0, -199,    4,    0,    0,    0,    0,  -88,
378
    0, -118,    0,  -61,    0, -117,  -82,    0,  381,  200,
379
    0,  -77, -131, -105, -102,    0,  936,  200,    0,    0,
380
    0,    0,  111,   32,    0,  -81, -125, -107, -106,    0,
381
  -78,  200,    0, 1018, -103,  -99,    0,   66,  -97,    0,
382
  251,    0,  -96,    0,  -95, -280,  -72,    0,  251,    0,
383
 -123,    0,  200,    0, -261,    0,    0,   66,  223,    0,
384
1104
    0,    0,  251,    0,    0,    0,   12,    0,  192,    0,
385
    0, -207,    0, -119, -122,  200,    0, -302,    0,    0,
386
1104
    8,    0,  200,    0,  -21,    0,    0,  -52,    0,  -48,
387
  -76,  -67,  -60,    0,    0, -123,    0,    0,    0,  -55,
388
    0, -112,  -54,  -51, -156,    0,    0,   41,    0,  181,
389
    0,    0,    0,    6, -220,  -44, -294,  -27,  -22,  -12,
390
    0, -244,    0,    0,    0,  251,    0,    0,    0,  -21,
391

2208
 -217,  -18,    0,    0, -263, -280,   51,   30,  -21,    0,
392
 -137,  -13,    0,    0,    0,    0,    0,    5,   38,    0,
393
    0,    0,  -11,    0,    0,    0,    9,   33,  248,    0,
394
  -98,   13,   16,   23,    0,   27,    0,    0,    0,    0,
395
   31,   37,   33,  249,    0,    8, -197,   39,   26,   76,
396
1104
 -233,    0,    0, -217,    0,    0,    0,    0,    0,   30,
397
   42,    0,   30,    0,   48,    0,    0,    0,  270,   33,
398
1104
    0,    0,  181,    0,    0,    0,    0,    0,   43,    0,
399
    0,    0,    0, -244,    0,    0,    0,   49, -274,    0,
400
    0,   52,    0,    0,    0,    0,    0,    0,    0,    0,
401
    0,    0,   53,    0,    0,    0,    0,    0,    0,    0,
402
   38,    0,    0,   54,    0,    0,    0,    0,  131,  136,
403
    0,    0,    0,    0,    0,   58,   62, -172, 1007, -280,
404
    0,   50,   64,    0, -219,   71,   97, -219,   72,   77,
405
 -265, -219, -219,   79,   84, -219,    0,    0, 1007,    0,
406
    0,    0,    0,    0,    0,    0,    0,   85,  146,   66,
407
   90,    0,    0,    0,    0,   93,   94,    0,    0, -251,
408
    0,  146,   98,    0,    0,  146,  146,  146,    0,    0,
409
  146,    0,    0,    0,    0,    0,    0,};
410
const short yyrindex[] =
411
	{                                      0,
412
  132,    0,    0,    0,    0,    0,    0,    0,   -8,    0,
413
    0,    0,    0,  140,    0,    0,    0,    0,    0,    0,
414
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
415
    0,    0,    0,    0,  447,    0,    0,    0,    0,    0,
416
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
417
    0,    0,    0,    0,    0,    0,    0,    0,    0,  973,
418
 1048,    0,    0, -258,  449,    0, -165,  452,  911,  157,
419
    0,    0,    0,    0, 1033,    0,    0,    0,    0,    0,
420
    0,    0,    0,    0,    0,    0,    0,    0,  157, -101,
421
    0,    0,    0,    0,  126,    0,    0,  945,    0,    0,
422
1104
    0,    0,    0, -120,    0,    0,    0,    0,    0,    0,
423
1104
    0,  201,    0,    0,    0,    0,    0,    0,    0,    0,
424
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
425
   -4,    0, -115,    0,    0,    0,    0,    0,    0,    0,
426
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
427
    0,  262,    0,    0,    0,  819,    0,  160,    0,    0,
428
  399,    0,  911,    0,    0,    0,    0,    0,    0,    0,
429
    0,    0,    0,    0,    0,   -3, -110,    0,    0,    0,
430
    0,   -1,    0,    0,    0,    0,    0,    0,    0,    0,
431
    0,    0,    0,  294,    0,    0,    0,    0,  128,  169,
432
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
433
    0,    0,    0,    0,    0,  850,    0,   21,    0,    0,
434
  852,    0,    0,    0,    0,    0,    0,    0,    0,    0,
435
    0,    0,    0,    0,    0,    0,    0,  521,    0,    0,
436
  491,    0,    0,    0,    0,    0,    0,    0,    0,    0,
437
    0,    0, -108,    0,    0,  399,    0,    0,    0,   -9,
438
    0,    0,    0,  796,    0,    0,    0,    0,    0,   21,
439
    0,    0,   21,    0,    0,    0,    0,    0,    0, -109,
440
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
441
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
442
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
443
    0,    0,  369,    0,    0,    0,    0,    0,    0,    0,
444
    0,    0,    0,    0,    0,    0,    0,    0,    0, -162,
445
    0,    0,    0,    0,    0,    0,    0,    0,  281,  451,
446
    0,    0,    0,    0,   87,    0,    0,   87,    0,    0,
447
    0,   87,   87,    0,    0,   46,    0,    0,  478,    0,
448
    0,    0,    0,    0,    0,    0,    0,  556,  603,    0,
449
  635,    0,    0,    0,    0,  682,  714,    0,    0,  779,
450
    0,  603,    0,    0,    0,  603,  603,  603,    0,    0,
451
  603,    0,    0,    0,    0,    0,    0,};
452
const short yygindex[] =
453
	{                                      0,
454
    0,  213,  -10, -153,    0,    0,    0,    0,    0,    0,
455
  274,  -34, -133,  134,    0,    0,    0,    0,    0,    0,
456
  -63, -136,    0,  368,  215,  104,    0,  -84,    0,    0,
457
   20,    0,    0,    0,    0,    0,    0,    0, -113,  171,
458
  314, -187,    0,    0,    0,  -31,    0,  409,  -94,    0,
459
    0,  435,  373,    0,  247,    0,    0,    0,    0,    0,
460
    0,  357,  359,  220,  383,  234,    0,    0,    0,    0,
461
    0,  159,    0,    0,    0,  436,    0,    0,    0,    0,
462
  423,    0,    0,  362,    0,
463
};
464
#define YYTABLESIZE 1390
465
const short yytable[] =
466
	{                                      37,
467
  198,   43,  205,  202,  238,  222,  225,   36,   30,  238,
468
  229,   64,  167,   69,  237,   29,  123,  195,  343,   28,
469
   17,  196,    3,  238,  374,  238,  164,  327,  216,   71,
470
  231,  246,   72,  208,  169,   74,   95,   77,  363,  222,
471
  225,  133,  163,  114,  364,   25,  142,  257,  181,  148,
472
  283,  258,   26,  179,  197,  178,  242,  150,  122,  209,
473
  365,   27,   95,  247,  248,  294,  130,  201,  375,   31,
474
  259,  105,  136,  256,  366,  134,  134,   32,  106,  260,
475
  144,  198,  273,  220,    3,  297,   33,  328,   34,  215,
476
   96,  102,  321,  110,  342,  367,  178,  343,  266,  267,
477
   99,  177,  269,  238,   20,  238,   29,   20,  192,  193,
478
  389,  255,  238,  199,  200,  198,   96,  201,  238,  261,
479
  222,  225,  107,   30,  207,   36,  298,  299,  113,   38,
480
  110,  214,  148,  153,  243,  244,  316,  131,  300,  318,
481
  150,  108,  195,  303,  234,  231,  196,  274,  275,  109,
482
   40,  145,  146,  236,  102,   41,  238,  236,   42,   63,
483
   43,    3,   44,  236,  301,  170,  235,   45,  238,  238,
484
  178,  131,  236,  239,  153,  238,  238,   46,  128,  197,
485
  171,   47,  238,  238,   48,  172,  285,  286,   49,  238,
486
  236,   50,  105,   53,  173,   55,   60,  147,   15,  106,
487
   58,   59,   61,   62,  238,    3,  198,  148,   67,   69,
488
   75,  178,  128,  149,  115,  150,  117,  236,  116,  228,
489
  238,  118,  236,  119,  238,  123,  269,  151,  392,  238,
490
  124,  125,  394,  395,  396,  132,   99,  397,  199,  200,
491
  238,  236,  201,  107,  126,  217,  238,  218,  238,  236,
492
  236,  239,  131,  236,  140,  198,  141,  138,  158,  198,
493
  163,  198,  108,  159,  162,  165,  168,  166,  198,  180,
494
  109,  144,   30,   30,  198,  198,  198,  198,  198,  222,
495
  225,  198,   30,  182,  371,  215,  223,  198,  376,  377,
496
  154,  231,  380,  128,  212,  224,  198,  198,  231,  222,
497
  198,  237,  225,  147,  231,  231,  231,  227,  232,  219,
498
  233,  231,  198,  178,  190,  178,  198,  245,   30,  178,
499
  178,  198,  178,  178,  240,  238,  178,  198,   30,  178,
500
  231,  198,  198,  250,   30,  178,   30,  251,  252,  198,
501
  198,  178,  231,  265,  178,  270,  231,  271,   30,  277,
502
  178,  281,  198,   43,  178,  307,  178,  222,  225,  385,
503
  178,  178,  231,  178,  178,  178,  278,  178,  308,  228,
504
  178,  282,  284,  295,  288,  178,  178,  289,   84,  178,
505
  178,  178,  178,  178,  290,  178,  144,  291,  306,  131,
506
  178,  178,  292,  131,  320,  178,  309,  178,  293,  324,
507
  305,  131,  131,  336,  317,  154,  178,  178,  218,  319,
508
  326,  131,  361,  330,  331,  335,  178,  337,  147,  340,
509
  178,  178,  178,  341,  178,  362,  131,  310,  311,  312,
510
  128,  178,  369,  372,  128,  370,  178,  383,  373,  183,
511
  378,   22,  128,  128,    2,  379,  382,  131,  178,   24,
512
  183,  386,  128,  131,  387,  388,  241,  131,   65,  393,
513
   15,   98,   58,  131,   17,  131,   25,  128,  296,  184,
514
  249,  238,    3,  360,  139,  314,    4,  131,  238,  185,
515
  184,  186,    5,  390,  238,  131,  131,  157,  128,  131,
516
  185,  333,  186,   84,  128,  230,    6,  121,  128,   73,
517
  149,    7,    8,  187,  128,  120,  128,  178,  188,  189,
518
  315,  206,  204,  325,  187,    9,  322,  381,  128,  188,
519
  189,   10,  238,  218,   11,   12,  128,  128,   13,  144,
520
  128,  191,  129,  143,    0,  144,  144,  226,  144,  144,
521
    0,  238,  144,    0,    0,  144,  144,  144,    0,  238,
522
   14,  144,    0,    0,  154,  154,    0,  144,    0,    0,
523
  144,  147,    0,    0,  154,  160,  144,  147,  147,    0,
524
  147,  147,  144,    0,  147,   15,    0,  147,  147,  147,
525
  144,  144,    0,  147,    0,    0,    0,    0,    0,  147,
526
    0,  144,  147,    0,    0,  144,  144,  144,  147,  144,
527
  154,    0,  157,    0,  147,    0,  144,    0,    0,    0,
528
  154,  144,  176,  147,    0,  149,  154,    0,  154,    0,
529
    0,    0,    0,  147,    0,    0,    0,  147,  147,  147,
530
  154,  147,    0,   84,    0,    0,    0,   84,  147,   84,
531
    0,    0,    0,  147,  162,  112,   84,    0,    0,    0,
532
    0,   78,   84,   84,   84,   84,   84,    0,   79,   84,
533
    0,    0,    0,    0,    3,   84,    0,    0,    0,  218,
534
    0,   80,    0,    0,   84,   84,  218,    0,   84,    0,
535
  160,    0,  218,    0,    0,    0,    0,    0,    0,  218,
536
   84,  164,    0,    0,   84,    0,    0,    0,    0,   84,
537
    0,    0,   81,    0,  218,   84,   82,    0,    0,   84,
538
   84,   83,    0,    0,    0,   15,    0,   84,   84,   15,
539
  218,   15,   84,  166,  218,    0,    0,  176,   15,  218,
540
   85,    0,    0,    0,   15,   15,   15,   15,   15,    0,
541
  218,   15,    0,    0,    0,    0,    0,   15,  218,    0,
542
    0,  157,  157,    0,    0,    0,   15,   15,  149,  162,
543
   15,  157,    0,    0,  149,  149,    0,  149,  149,    0,
544
    0,  149,   15,    0,  149,    0,   15,    0,    0,  236,
545
  149,   15,    0,    0,    0,    0,  149,   15,  168,  149,
546
    0,   15,   15,    0,    0,  149,    0,  157,    0,   15,
547
   15,  149,    0,    0,    0,   77,  164,  157,    0,  236,
548
  149,    0,    0,  157,    0,  157,    0,    0,    0,  236,
549
  149,  236,    0,  160,  149,  149,  149,  157,  149,  160,
550
  160,    0,  160,  160,    0,  149,  160,    0,  166,  160,
551
  149,    0,    0,  236,    0,  160,    0,    0,  236,  236,
552
    0,  160,    0,    0,  160,    0,    0,    0,    0,   15,
553
  160,  215,    0,    0,    0,    0,  160,    0,    0,    0,
554
  176,    0,    0,    0,    0,  160,  176,  176,    0,  176,
555
  176,    0,    0,  176,    0,  160,  176,    0,    0,  160,
556
  160,  160,  176,  160,    0,    0,    0,    0,  176,    0,
557
  160,  176,  162,  168,    0,  160,    0,  176,  162,  162,
558
    0,  162,  162,  176,    0,  162,    0,    0,  162,    0,
559
   77,    0,  176,    0,  162,    0,    0,    0,    0,    0,
560
  162,    0,  176,  162,    0,    0,  176,  176,  176,  162,
561
  176,    0,    0,  238,    0,  162,    0,  176,    0,  164,
562
    0,    0,  176,    0,  162,  164,  164,    0,  164,  164,
563
    0,    0,  164,    0,  162,  164,    0,    0,  162,  162,
564
  162,  164,  162,    0,   15,    0,  215,  164,    0,  162,
565
  164,  166,    0,    0,  162,    0,  164,  166,  166,    0,
566
  166,  166,  164,    0,  166,    0,    0,  166,    0,    0,
567
    0,  164,    0,  166,    0,    0,    0,    0,    0,  166,
568
    0,  164,  166,    0,    0,  164,  164,  164,  166,  164,
569
    0,    0,    0,    0,  166,    0,  164,    0,    0,    0,
570
    0,  164,    0,  166,    0,  238,    0,    0,    0,    0,
571
    0,    0,    0,  166,    0,    0,  168,  166,  166,  166,
572
    0,  166,  168,  168,    0,  168,  168,    0,  166,  168,
573
  128,    0,  168,  166,    0,    0,   77,    0,  168,  238,
574
    0,    0,    0,   77,  168,    0,    0,  168,    0,   77,
575
   77,   77,   77,  168,    0,    0,   77,    0,    0,  168,
576
    0,    0,  238,  238,    0,    0,    0,    0,  168,    0,
577
    0,   77,  238,    0,    0,   77,    0,    0,  168,    0,
578
    0,   91,  168,  168,  168,    0,  168,   77,   79,    0,
579
   15,   77,  215,  168,    3,    0,   77,   15,  168,  215,
580
    0,   92,    0,   15,    0,  215,   77,   77,  238,    0,
581
   15,    0,  215,    0,   77,   77,    0,    0,  238,    0,
582
   93,    0,    0,    0,  238,    0,  238,    0,    0,   15,
583
    0,  215,   81,    0,    0,    0,   94,    0,  238,  238,
584
    0,   15,  238,  215,    0,   15,  238,  215,    0,    0,
585
    0,  238,   84,    0,  238,  238,    0,    0,  238,    0,
586
    0,   15,    0,  215,  238,    0,    0,    0,    0,  238,
587
    0,  238,    0,    0,    0,    0,   91,    0,    0,  238,
588
    0,  238,    0,   79,    0,  238,  238,    0,    0,    3,
589
  238,    0,  238,    0,    0,    0,   92,    0,  238,    0,
590
  238,    0,  238,  238,    0,  238,  238,    0,  238,  238,
591
  238,  238,  238,  238,    0,   93,  238,    0,  238,    0,
592
  238,  238,  238,    0,  238,    0,  238,   81,    0,  238,
593
  238,   94,    0,  238,    0,    0,  238,    0,  238,  238,
594
  238,    0,  238,    0,  345,   78,    0,   84,  238,    0,
595
    0,    0,   79,  346,  347,    0,  238,  348,    3,    0,
596
    0,  145,  146,    0,  238,   80,  349,    0,  238,    0,
597
    0,    3,  350,  238,    0,  351,  238,  238,    0,    0,
598
    0,  352,    0,    0,  238,    0,  238,  353,  238,    0,
599
    0,    0,  238,    0,    0,  238,   81,    0,    0,    0,
600
   82,  238,    0,    0,    0,   83,    0,  147,  238,    0,
601
  354,  355,    0,    0,    0,    0,   84,  148,    0,    0,
602
    0,  356,  238,  149,   85,  150,    0,  238,    0,    0,
603
    0,    0,  238,    0,    0,    0,    0,  151,  238,  238,
604
  238,    0,    0,  238,    0,    0,    0,    0,    0,    0,
605
    0,    0,  238,    0,    0,    0,    0,    0,    0,  238,
606
};
607
const short yycheck[] =
608
	{                                      10,
609
   10,   10,  125,  123,  125,   10,   10,   60,   10,  125,
610
548
  123,  123,  126,   10,  125,  125,  125,  262,  270,  257,
611
548
    1,  266,  284,  125,  290,  284,  121,  302,  165,   61,
612
   10,  326,   64,  336,  129,   67,   71,   69,  258,   44,
613
   44,   10,   10,   75,  264,   10,  125,  265,  143,  330,
614
  238,  269,  362,  138,  299,   10,  277,  338,   90,  362,
615
  280,  363,   97,  358,  359,  253,   98,  362,  334,  363,
616
24
  288,  271,  104,  210,  294,   44,   44,  362,  278,  297,
617
  112,  326,  219,  168,  284,  283,  362,  362,  343,  307,
618
   71,   72,  280,   74,  267,  315,   10,  270,  362,  363,
619
  362,  133,  216,  362,  267,  271,  344,  270,  316,  317,
620
  362,  206,  278,  358,  359,  125,   97,  362,  284,  337,
621
24
  125,  125,  322,  125,  156,   60,  324,  325,  125,  363,
622
  111,  163,  330,  114,  355,  356,  270,   10,  336,  273,
623
24
  338,  341,  262,  257,  301,  125,  266,  285,  286,  349,
624
  362,  274,  275,  262,  135,   61,  322,  266,  310,  271,
625
   10,  284,   10,  284,  362,  289,  323,   10,  284,  271,
626
  125,   44,  329,  284,  155,  341,  278,   10,   10,  299,
627
  304,   10,  284,  349,   10,  309,  285,  286,   10,  291,
628
16
  299,   10,  271,  362,  318,  362,  123,  320,   10,  278,
629
8
  362,  362,  123,   62,  306,  284,  326,  330,  123,   10,
630
8
  123,  125,   44,  336,  303,  338,  278,  326,  337,  332,
631
  322,  339,  332,  306,  326,  303,  340,  350,  382,  331,
632
  362,  337,  386,  387,  388,  125,  362,  391,  358,  359,
633
16
  342,  362,  362,  322,  347,  298,  362,  300,  350,  358,
634
  359,  362,  125,  362,  362,  265,  363,  339,  362,  269,
635
   10,  271,  341,  363,  362,  362,  339,  363,  278,   47,
636
8
  349,   10,  274,  275,  284,  285,  286,  287,  288,  284,
637
  284,  291,  284,  272,  348,  307,  363,  297,  352,  353,
638
   10,  271,  356,  125,  287,  363,  306,  307,  278,  348,
639
  310,  261,  363,   10,  284,  285,  286,  363,  363,  362,
640
  362,  291,  322,  268,  123,  270,  326,  362,  320,  274,
641
  275,  331,  277,  278,  319,  125,  281,  337,  330,  284,
642
8
  310,  341,  342,  361,  336,  290,  338,  360,  351,  349,
643
  350,  296,  322,  362,  299,  295,  326,  318,  350,  363,
644
  305,  363,  362,  362,  268,  280,  311,  362,  362,  370,
645
16
  274,  275,  342,  277,  278,  320,  362,  281,  293,  332,
646
8
  284,  363,  125,  125,  362,  330,  290,  362,   10,  334,
647
  335,  336,  296,  338,  362,  299,  125,  361,  363,  262,
648
  345,  305,  362,  266,  125,  350,  321,  311,  362,  357,
649
  362,  274,  275,  273,  363,  125,  320,  362,   10,  362,
650
  362,  284,  363,  362,  362,  362,  330,  282,  125,  362,
651
8
  334,  335,  336,  362,  338,  362,  299,  352,  353,  354,
652
  262,  345,  362,  362,  266,  339,  350,  292,  362,  259,
653
8
  362,  310,  274,  275,  256,  362,  362,  320,  362,  310,
654
8
  259,  362,  284,  326,  362,  362,   10,  330,   10,  362,
655
   10,   10,  306,  336,  339,  338,  307,  299,  256,  289,
656
8
  197,  271,  284,  340,  107,  261,  288,  350,  278,  299,
657
8
  289,  301,  294,  380,  284,  358,  359,   10,  320,  362,
658
8
  299,  321,  301,  125,  326,  182,  308,   89,  330,   65,
659

8
   10,  313,  314,  323,  336,  125,  338,  135,  328,  329,
660
8
  264,  155,  154,  294,  323,  327,  283,  359,  350,  328,
661
  329,  333,  322,  125,  336,  337,  358,  359,  340,  268,
662
  362,  149,   97,  111,   -1,  274,  275,  176,  277,  278,
663
   -1,  341,  281,   -1,   -1,  284,  285,  286,   -1,  349,
664
  362,  290,   -1,   -1,  274,  275,   -1,  296,   -1,   -1,
665
8
  299,  268,   -1,   -1,  284,   10,  305,  274,  275,   -1,
666
8
  277,  278,  311,   -1,  281,  125,   -1,  284,  285,  286,
667
  319,  320,   -1,  290,   -1,   -1,   -1,   -1,   -1,  296,
668
8
   -1,  330,  299,   -1,   -1,  334,  335,  336,  305,  338,
669
  320,   -1,  125,   -1,  311,   -1,  345,   -1,   -1,   -1,
670
  330,  350,   10,  320,   -1,  125,  336,   -1,  338,   -1,
671
   -1,   -1,   -1,  330,   -1,   -1,   -1,  334,  335,  336,
672
  350,  338,   -1,  265,   -1,   -1,   -1,  269,  345,  271,
673
   -1,   -1,   -1,  350,   10,  125,  278,   -1,   -1,   -1,
674
   -1,  271,  284,  285,  286,  287,  288,   -1,  278,  291,
675
   -1,   -1,   -1,   -1,  284,  297,   -1,   -1,   -1,  271,
676
   -1,  291,   -1,   -1,  306,  307,  278,   -1,  310,   -1,
677
  125,   -1,  284,   -1,   -1,   -1,   -1,   -1,   -1,  291,
678
  322,   10,   -1,   -1,  326,   -1,   -1,   -1,   -1,  331,
679
   -1,   -1,  322,   -1,  306,  337,  326,   -1,   -1,  341,
680
  342,  331,   -1,   -1,   -1,  265,   -1,  349,  350,  269,
681
  322,  271,  342,   10,  326,   -1,   -1,  125,  278,  331,
682
  350,   -1,   -1,   -1,  284,  285,  286,  287,  288,   -1,
683
8
  342,  291,   -1,   -1,   -1,   -1,   -1,  297,  350,   -1,
684
8
   -1,  274,  275,   -1,   -1,   -1,  306,  307,  268,  125,
685
8
  310,  284,   -1,   -1,  274,  275,   -1,  277,  278,   -1,
686
   -1,  281,  322,   -1,  284,   -1,  326,   -1,   -1,  259,
687
8
  290,  331,   -1,   -1,   -1,   -1,  296,  337,   10,  299,
688
   -1,  341,  342,   -1,   -1,  305,   -1,  320,   -1,  349,
689
  350,  311,   -1,   -1,   -1,   10,  125,  330,   -1,  289,
690
  320,   -1,   -1,  336,   -1,  338,   -1,   -1,   -1,  299,
691
  330,  301,   -1,  268,  334,  335,  336,  350,  338,  274,
692
8
  275,   -1,  277,  278,   -1,  345,  281,   -1,  125,  284,
693
  350,   -1,   -1,  323,   -1,  290,   -1,   -1,  328,  329,
694
16
   -1,  296,   -1,   -1,  299,   -1,   -1,   -1,   -1,   10,
695
8
  305,   10,   -1,   -1,   -1,   -1,  311,   -1,   -1,   -1,
696
  268,   -1,   -1,   -1,   -1,  320,  274,  275,   -1,  277,
697
  278,   -1,   -1,  281,   -1,  330,  284,   -1,   -1,  334,
698
  335,  336,  290,  338,   -1,   -1,   -1,   -1,  296,   -1,
699
  345,  299,  268,  125,   -1,  350,   -1,  305,  274,  275,
700
8
   -1,  277,  278,  311,   -1,  281,   -1,   -1,  284,   -1,
701
8
  125,   -1,  320,   -1,  290,   -1,   -1,   -1,   -1,   -1,
702
8
  296,   -1,  330,  299,   -1,   -1,  334,  335,  336,  305,
703
8
  338,   -1,   -1,  125,   -1,  311,   -1,  345,   -1,  268,
704
8
   -1,   -1,  350,   -1,  320,  274,  275,   -1,  277,  278,
705
   -1,   -1,  281,   -1,  330,  284,   -1,   -1,  334,  335,
706
8
  336,  290,  338,   -1,  125,   -1,  125,  296,   -1,  345,
707
  299,  268,   -1,   -1,  350,   -1,  305,  274,  275,   -1,
708
  277,  278,  311,   -1,  281,   -1,   -1,  284,   -1,   -1,
709
8
   -1,  320,   -1,  290,   -1,   -1,   -1,   -1,   -1,  296,
710
8
   -1,  330,  299,   -1,   -1,  334,  335,  336,  305,  338,
711
   -1,   -1,   -1,   -1,  311,   -1,  345,   -1,   -1,   -1,
712
8
   -1,  350,   -1,  320,   -1,  125,   -1,   -1,   -1,   -1,
713
8
   -1,   -1,   -1,  330,   -1,   -1,  268,  334,  335,  336,
714
   -1,  338,  274,  275,   -1,  277,  278,   -1,  345,  281,
715
  125,   -1,  284,  350,   -1,   -1,  271,   -1,  290,  125,
716
   -1,   -1,   -1,  278,  296,   -1,   -1,  299,   -1,  284,
717
  285,  286,  287,  305,   -1,   -1,  291,   -1,   -1,  311,
718
   -1,   -1,  274,  275,   -1,   -1,   -1,   -1,  320,   -1,
719
   -1,  306,  284,   -1,   -1,  310,   -1,   -1,  330,   -1,
720
   -1,  271,  334,  335,  336,   -1,  338,  322,  278,   -1,
721
  271,  326,  271,  345,  284,   -1,  331,  278,  350,  278,
722
8
   -1,  291,   -1,  284,   -1,  284,  341,  342,  320,   -1,
723
  291,   -1,  291,   -1,  349,  350,   -1,   -1,  330,   -1,
724
  310,   -1,   -1,   -1,  336,   -1,  338,   -1,   -1,  310,
725
   -1,  310,  322,   -1,   -1,   -1,  326,   -1,  350,  259,
726
8
   -1,  322,  262,  322,   -1,  326,  266,  326,   -1,   -1,
727
   -1,  271,  342,   -1,  274,  275,   -1,   -1,  278,   -1,
728
8
   -1,  342,   -1,  342,  284,   -1,   -1,   -1,   -1,  289,
729
   -1,  291,   -1,   -1,   -1,   -1,  271,   -1,   -1,  299,
730
   -1,  301,   -1,  278,   -1,  271,  306,   -1,   -1,  284,
731
  310,   -1,  278,   -1,   -1,   -1,  291,   -1,  284,   -1,
732
  320,   -1,  322,  323,   -1,  291,  326,   -1,  328,  329,
733
  330,  331,  332,  271,   -1,  310,  336,   -1,  338,   -1,
734
  278,  341,  342,   -1,  310,   -1,  284,  322,   -1,  349,
735
  350,  326,   -1,  291,   -1,   -1,  322,   -1,  358,  359,
736
  326,   -1,  362,   -1,  268,  271,   -1,  342,  306,   -1,
737
   -1,   -1,  278,  277,  278,   -1,  342,  281,  284,   -1,
738
   -1,  274,  275,   -1,  322,  291,  290,   -1,  326,   -1,
739
   -1,  284,  296,  331,   -1,  299,  274,  275,   -1,   -1,
740
   -1,  305,   -1,   -1,  342,   -1,  284,  311,  271,   -1,
741
   -1,   -1,  350,   -1,   -1,  278,  322,   -1,   -1,   -1,
742
  326,  284,   -1,   -1,   -1,  331,   -1,  320,  291,   -1,
743
  334,  335,   -1,   -1,   -1,   -1,  342,  330,   -1,   -1,
744
   -1,  345,  320,  336,  350,  338,   -1,  310,   -1,   -1,
745
   -1,   -1,  330,   -1,   -1,   -1,   -1,  350,  336,  322,
746
  338,   -1,   -1,  326,   -1,   -1,   -1,   -1,   -1,   -1,
747
   -1,   -1,  350,   -1,   -1,   -1,   -1,   -1,   -1,  342,
748
};
749
#define YYFINAL 1
750
#ifndef YYDEBUG
751
#define YYDEBUG 0
752
#endif
753
#define YYMAXTOKEN 363
754
#if YYDEBUG
755
const char * const yyname[] =
756
	{
757
"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
758
0,0,0,0,0,0,0,0,0,0,0,0,0,"','",0,0,"'/'",0,0,0,0,0,0,0,0,0,0,0,0,"'<'","'='",
759
"'>'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
760
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,
761
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
762
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
763
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
764
0,"ALL","APPEND","BACKLOG","BACKUP","BUFFER","CA","CACHE","SET","CHECK",
765
"CIPHERS","CODE","COOKIE","DEMOTE","DIGEST","DISABLE","ERROR","EXPECT","PASS",
766
"BLOCK","EXTERNAL","FILENAME","FORWARD","FROM","HASH","HEADER","HOST","ICMP",
767
"INCLUDE","INET","INET6","INTERFACE","INTERVAL","IP","LABEL","LISTEN","VALUE",
768
"LOADBALANCE","LOG","LOOKUP","METHOD","MODE","NAT","NO","DESTINATION","NODELAY",
769
"NOTHING","ON","PARENT","PATH","PFTAG","PORT","PREFORK","PRIORITY","PROTO",
770
"QUERYSTR","REAL","REDIRECT","RELAY","REMOVE","REQUEST","RESPONSE","RETRY",
771
"QUICK","RETURN","ROUNDROBIN","ROUTE","SACK","SCRIPT","SEND","SESSION","SNMP",
772
"SOCKET","SPLICE","SSL","STICKYADDR","STYLE","TABLE","TAG","TAGGED","TCP",
773
"TIMEOUT","TLS","TO","ROUTER","RTLABEL","TRANSPARENT","TRAP","UPDATES","URL",
774
"VIRTUAL","WITH","TTL","RTABLE","MATCH","PARAMS","RANDOM","LEASTSTATES",
775
"SRCHASH","KEY","CERTIFICATE","PASSWORD","ECDH","EDH","CURVE","TICKETS",
776
"STRING","NUMBER",
777
};
778
const char * const yyrule[] =
779
	{"$accept : grammar",
780
"grammar :",
781
"grammar : grammar include '\\n'",
782
"grammar : grammar '\\n'",
783
"grammar : grammar varset '\\n'",
784
"grammar : grammar main '\\n'",
785
"grammar : grammar rdr '\\n'",
786
"grammar : grammar tabledef '\\n'",
787
"grammar : grammar relay '\\n'",
788
"grammar : grammar proto '\\n'",
789
"grammar : grammar router '\\n'",
790
"grammar : grammar error '\\n'",
791
"include : INCLUDE STRING",
792
"ssltls : SSL",
793
"ssltls : TLS",
794
"opttls :",
795
"opttls : ssltls",
796
"opttlsclient :",
797
"opttlsclient : WITH ssltls",
798
"http_type : STRING",
799
"hostname :",
800
"hostname : HOST STRING",
801
"relay_proto :",
802
"relay_proto : TCP",
803
"relay_proto : STRING",
804
"redirect_proto :",
805
"redirect_proto : TCP",
806
"redirect_proto : STRING",
807
"eflags_l : eflags comma eflags_l",
808
"eflags_l : eflags",
809
"opteflags :",
810
"opteflags : eflags",
811
"eflags : STYLE STRING",
812
"port : PORT STRING",
813
"port : PORT NUMBER",
814
"varset : STRING '=' STRING",
815
"sendbuf : NOTHING",
816
"sendbuf : STRING",
817
"main : INTERVAL NUMBER",
818
"main : LOG loglevel",
819
"main : TIMEOUT timeout",
820
"main : PREFORK NUMBER",
821
"main : SNMP trap optstring",
822
"trap :",
823
"trap : TRAP",
824
"loglevel : UPDATES",
825
"loglevel : ALL",
826
"$$1 :",
827
"rdr : REDIRECT STRING $$1 '{' optnl rdropts_l '}'",
828
"rdropts_l : rdropts_l rdroptsl nl",
829
"rdropts_l : rdroptsl optnl",
830
"rdroptsl : forwardmode TO tablespec interface",
831
"rdroptsl : LISTEN ON STRING redirect_proto port interface",
832
"rdroptsl : DISABLE",
833
"rdroptsl : STICKYADDR",
834
"rdroptsl : match PFTAG STRING",
835
"rdroptsl : SESSION TIMEOUT NUMBER",
836
"rdroptsl : include",
837
"match :",
838
"match : MATCH",
839
"forwardmode : FORWARD",
840
"forwardmode : ROUTE",
841
"forwardmode : TRANSPARENT FORWARD",
842
"table : '<' STRING '>'",
843
"$$2 :",
844
"tabledef : TABLE table $$2 tabledefopts_l",
845
"tabledefopts_l : tabledefopts_l tabledefopts",
846
"tabledefopts_l : tabledefopts",
847
"tabledefopts : DISABLE",
848
"tabledefopts : '{' optnl tablelist_l '}'",
849
"tablelist_l : tablelist comma tablelist_l",
850
"tablelist_l : tablelist optnl",
851
"tablelist : host",
852
"tablelist : include",
853
"$$3 :",
854
"tablespec : table $$3 tableopts_l",
855
"tableopts_l : tableopts tableopts_l",
856
"tableopts_l : tableopts",
857
"tableopts : CHECK tablecheck",
858
"tableopts : port",
859
"tableopts : TIMEOUT timeout",
860
"tableopts : DEMOTE STRING",
861
"tableopts : INTERVAL NUMBER",
862
"tableopts : MODE dstmode hashkey",
863
"hashkey :",
864
"hashkey : STRING",
865
"tablecheck : ICMP",
866
"tablecheck : TCP",
867
"tablecheck : ssltls",
868
"tablecheck : http_type STRING hostname CODE NUMBER",
869
"tablecheck : http_type STRING hostname digest",
870
"tablecheck : SEND sendbuf EXPECT STRING opttls",
871
"tablecheck : SCRIPT STRING",
872
"digest : DIGEST STRING",
873
"optdigest : digest",
874
"optdigest : STRING",
875
"$$4 :",
876
"proto : relay_proto PROTO STRING $$4 protopts_n",
877
"protopts_n :",
878
"protopts_n : '{' '}'",
879
"protopts_n : '{' optnl protopts_l '}'",
880
"protopts_l : protopts_l protoptsl nl",
881
"protopts_l : protoptsl optnl",
882
"protoptsl : ssltls tlsflags",
883
"protoptsl : ssltls '{' tlsflags_l '}'",
884
"protoptsl : TCP tcpflags",
885
"protoptsl : TCP '{' tcpflags_l '}'",
886
"protoptsl : RETURN ERROR opteflags",
887
"protoptsl : RETURN ERROR '{' eflags_l '}'",
888
"protoptsl : filterrule",
889
"protoptsl : include",
890
"tcpflags_l : tcpflags comma tcpflags_l",
891
"tcpflags_l : tcpflags",
892
"tcpflags : SACK",
893
"tcpflags : NO SACK",
894
"tcpflags : NODELAY",
895
"tcpflags : NO NODELAY",
896
"tcpflags : SPLICE",
897
"tcpflags : NO SPLICE",
898
"tcpflags : BACKLOG NUMBER",
899
"tcpflags : SOCKET BUFFER NUMBER",
900
"tcpflags : IP STRING NUMBER",
901
"tlsflags_l : tlsflags comma tlsflags_l",
902
"tlsflags_l : tlsflags",
903
"tlsflags : SESSION TICKETS",
904
"tlsflags : NO SESSION TICKETS",
905
"tlsflags : CIPHERS STRING",
906
"tlsflags : NO EDH",
907
"tlsflags : EDH",
908
"tlsflags : EDH PARAMS STRING",
909
"tlsflags : NO ECDH",
910
"tlsflags : ECDH",
911
"tlsflags : ECDH CURVE STRING",
912
"tlsflags : CA FILENAME STRING",
913
"tlsflags : CA KEY STRING PASSWORD STRING",
914
"tlsflags : CA CERTIFICATE STRING",
915
"tlsflags : NO flag",
916
"tlsflags : flag",
917
"flag : STRING",
918
"$$5 :",
919
"filterrule : action dir quick ruleaf rulesrc ruledst $$5 ruleopts_l",
920
"action : PASS",
921
"action : BLOCK",
922
"action : MATCH",
923
"dir :",
924
"dir : REQUEST",
925
"dir : RESPONSE",
926
"quick :",
927
"quick : QUICK",
928
"ruleaf :",
929
"ruleaf : INET6",
930
"ruleaf : INET",
931
"rulesrc :",
932
"ruledst :",
933
"ruleopts_l :",
934
"ruleopts_l : ruleopts_t",
935
"ruleopts_t : ruleopts ruleopts_t",
936
"ruleopts_t : ruleopts",
937
16
"ruleopts : METHOD STRING",
938
"ruleopts : COOKIE key_option STRING value",
939
"ruleopts : COOKIE key_option",
940
8
"ruleopts : HEADER key_option STRING value",
941
"ruleopts : HEADER key_option",
942
"ruleopts : PATH key_option STRING value",
943
"ruleopts : PATH key_option",
944
"ruleopts : QUERYSTR key_option STRING value",
945
"ruleopts : QUERYSTR key_option",
946
"ruleopts : URL key_option optdigest value",
947
"ruleopts : URL key_option",
948
"ruleopts : FORWARD TO table",
949
8
"ruleopts : TAG STRING",
950
"ruleopts : NO TAG",
951
8
"ruleopts : TAGGED STRING",
952
"ruleopts : LABEL STRING",
953
"ruleopts : NO LABEL",
954
8
"ruleopts : FILENAME STRING value",
955
8
"value :",
956
"value : VALUE STRING",
957
8
"key_option :",
958
24
"key_option : APPEND",
959
24
"key_option : SET",
960
"key_option : REMOVE",
961
24
"key_option : HASH",
962
"key_option : LOG",
963
"$$6 :",
964
"relay : RELAY STRING $$6 '{' optnl relayopts_l '}'",
965
"relayopts_l : relayopts_l relayoptsl nl",
966
1088
"relayopts_l : relayoptsl optnl",
967
540
"relayoptsl : LISTEN ON STRING port opttls",
968
540
"relayoptsl : forwardmode opttlsclient TO forwardspec dstaf",
969
"relayoptsl : SESSION TIMEOUT NUMBER",
970
"relayoptsl : PROTO STRING",
971
548
"relayoptsl : DISABLE",
972
"relayoptsl : include",
973
"forwardspec : STRING port retry",
974
1096
"forwardspec : NAT LOOKUP retry",
975
"forwardspec : DESTINATION retry",
976
"forwardspec : tablespec",
977
"dstmode :",
978
548
"dstmode : LOADBALANCE",
979
"dstmode : ROUNDROBIN",
980
"dstmode : HASH",
981
"dstmode : LEASTSTATES",
982
"dstmode : SRCHASH",
983
548
"dstmode : RANDOM",
984
"$$7 :",
985
"router : ROUTER STRING $$7 '{' optnl routeopts_l '}'",
986
548
"routeopts_l : routeopts_l routeoptsl nl",
987
"routeopts_l : routeoptsl optnl",
988
"routeoptsl : ROUTE address '/' NUMBER",
989
"routeoptsl : FORWARD TO tablespec",
990
"routeoptsl : RTABLE NUMBER",
991
"routeoptsl : RTLABEL STRING",
992
"routeoptsl : DISABLE",
993
548
"routeoptsl : include",
994
548
"dstaf :",
995
548
"dstaf : INET",
996
548
"dstaf : INET6 STRING",
997
548
"interface :",
998
548
"interface : INTERFACE STRING",
999
548
"$$8 :",
1000
548
"host : address $$8 opthostflags",
1001
"opthostflags :",
1002
548
"opthostflags : hostflags_l",
1003
"hostflags_l : hostflags hostflags_l",
1004
548
"hostflags_l : hostflags",
1005
"hostflags : RETRY NUMBER",
1006
548
"hostflags : PARENT NUMBER",
1007
"hostflags : PRIORITY NUMBER",
1008
"hostflags : IP TTL NUMBER",
1009
"address : STRING",
1010
"retry :",
1011
548
"retry : RETRY NUMBER",
1012

548
"timeout : NUMBER",
1013
548
"comma : ','",
1014
"comma : nl",
1015
548
"comma :",
1016
"optnl : '\\n' optnl",
1017
"optnl :",
1018
"nl : '\\n' optnl",
1019
"optstring : STRING",
1020
548
"optstring :",
1021
};
1022
548
#endif
1023
#ifdef YYSTACKSIZE
1024
#undef YYMAXDEPTH
1025
#define YYMAXDEPTH YYSTACKSIZE
1026
#else
1027
#ifdef YYMAXDEPTH
1028
#define YYSTACKSIZE YYMAXDEPTH
1029
#else
1030
#define YYSTACKSIZE 10000
1031
#define YYMAXDEPTH 10000
1032
#endif
1033
#endif
1034
#define YYINITSTACKSIZE 200
1035
/* LINTUSED */
1036
int yydebug;
1037
64
int yynerrs;
1038
64
int yyerrflag;
1039
int yychar;
1040
short *yyssp;
1041
YYSTYPE *yyvsp;
1042
YYSTYPE yyval;
1043
YYSTYPE yylval;
1044
short *yyss;
1045
short *yysslim;
1046
YYSTYPE *yyvs;
1047
unsigned int yystacksize;
1048
int yyparse(void);
1049
#line 2152 "parse.y"
1050
1051
struct keywords {
1052
276
	const char	*k_name;
1053
276
	int		 k_val;
1054
};
1055
1056
int
1057
yyerror(const char *fmt, ...)
1058
{
1059
	va_list		 ap;
1060
	char		*msg;
1061
8
1062
8
	file->errors++;
1063
	va_start(ap, fmt);
1064
	if (vasprintf(&msg, fmt, ap) == -1)
1065
		fatalx("yyerror vasprintf");
1066
	va_end(ap);
1067
	logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
1068
	free(msg);
1069
	return (0);
1070
}
1071
1072
int
1073
kw_cmp(const void *k, const void *e)
1074
{
1075
	return (strcmp(k, ((const struct keywords *)e)->k_name));
1076
}
1077
1078
int
1079
lookup(char *s)
1080
{
1081
	/* this has to be sorted always */
1082
	static const struct keywords keywords[] = {
1083
		{ "all",		ALL },
1084
		{ "append",		APPEND },
1085
		{ "backlog",		BACKLOG },
1086
		{ "backup",		BACKUP },
1087
		{ "block",		BLOCK },
1088
		{ "buffer",		BUFFER },
1089
		{ "ca",			CA },
1090
		{ "cache",		CACHE },
1091
		{ "cert",		CERTIFICATE },
1092
		{ "check",		CHECK },
1093
		{ "ciphers",		CIPHERS },
1094
		{ "code",		CODE },
1095
		{ "cookie",		COOKIE },
1096
		{ "curve",		CURVE },
1097
		{ "demote",		DEMOTE },
1098
		{ "destination",	DESTINATION },
1099
		{ "digest",		DIGEST },
1100
		{ "disable",		DISABLE },
1101
		{ "ecdh",		ECDH },
1102
		{ "edh",		EDH },
1103
		{ "error",		ERROR },
1104
		{ "expect",		EXPECT },
1105
		{ "external",		EXTERNAL },
1106
		{ "file",		FILENAME },
1107
		{ "forward",		FORWARD },
1108
		{ "from",		FROM },
1109
		{ "hash",		HASH },
1110
		{ "header",		HEADER },
1111
		{ "host",		HOST },
1112
		{ "icmp",		ICMP },
1113
		{ "include",		INCLUDE },
1114
		{ "inet",		INET },
1115
		{ "inet6",		INET6 },
1116
		{ "interface",		INTERFACE },
1117
		{ "interval",		INTERVAL },
1118
		{ "ip",			IP },
1119
		{ "key",		KEY },
1120
		{ "label",		LABEL },
1121
		{ "least-states",	LEASTSTATES },
1122
		{ "listen",		LISTEN },
1123
		{ "loadbalance",	LOADBALANCE },
1124
		{ "log",		LOG },
1125
		{ "lookup",		LOOKUP },
1126
		{ "match",		MATCH },
1127
		{ "method",		METHOD },
1128
		{ "mode",		MODE },
1129
		{ "nat",		NAT },
1130
		{ "no",			NO },
1131
		{ "nodelay",		NODELAY },
1132
		{ "nothing",		NOTHING },
1133
		{ "on",			ON },
1134
		{ "params",		PARAMS },
1135
		{ "parent",		PARENT },
1136
		{ "pass",		PASS },
1137
		{ "password",		PASSWORD },
1138
		{ "path",		PATH },
1139
		{ "pftag",		PFTAG },
1140
		{ "port",		PORT },
1141
		{ "prefork",		PREFORK },
1142
		{ "priority",		PRIORITY },
1143
		{ "protocol",		PROTO },
1144
		{ "query",		QUERYSTR },
1145
		{ "quick",		QUICK },
1146
		{ "random",		RANDOM },
1147
		{ "real",		REAL },
1148
		{ "redirect",		REDIRECT },
1149
		{ "relay",		RELAY },
1150
		{ "remove",		REMOVE },
1151
		{ "request",		REQUEST },
1152
		{ "response",		RESPONSE },
1153
		{ "retry",		RETRY },
1154
		{ "return",		RETURN },
1155
		{ "roundrobin",		ROUNDROBIN },
1156
		{ "route",		ROUTE },
1157
		{ "router",		ROUTER },
1158
		{ "rtable",		RTABLE },
1159
		{ "rtlabel",		RTLABEL },
1160
		{ "sack",		SACK },
1161
		{ "script",		SCRIPT },
1162
		{ "send",		SEND },
1163
		{ "session",		SESSION },
1164
		{ "set",		SET },
1165
		{ "snmp",		SNMP },
1166
		{ "socket",		SOCKET },
1167
		{ "source-hash",	SRCHASH },
1168
		{ "splice",		SPLICE },
1169
		{ "ssl",		SSL },
1170
		{ "sticky-address",	STICKYADDR },
1171
		{ "style",		STYLE },
1172
		{ "table",		TABLE },
1173
		{ "tag",		TAG },
1174
		{ "tagged",		TAGGED },
1175
		{ "tcp",		TCP },
1176
		{ "tickets",		TICKETS },
1177
		{ "timeout",		TIMEOUT },
1178
		{ "tls",		TLS },
1179
32
		{ "to",			TO },
1180
16
		{ "transparent",	TRANSPARENT },
1181
		{ "trap",		TRAP },
1182
		{ "ttl",		TTL },
1183
		{ "updates",		UPDATES },
1184
		{ "url",		URL },
1185
		{ "value",		VALUE },
1186
		{ "virtual",		VIRTUAL },
1187
16
		{ "with",		WITH }
1188
	};
1189
	const struct keywords	*p;
1190
1191
	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
1192
	    sizeof(keywords[0]), kw_cmp);
1193
16
1194
16
	if (p)
1195
		return (p->k_val);
1196
16
	else
1197
32
		return (STRING);
1198
16
}
1199
1200
#define MAXPUSHBACK	128
1201
1202
u_char	*parsebuf;
1203
int	 parseindex;
1204
16
u_char	 pushback_buffer[MAXPUSHBACK];
1205
int	 pushback_index = 0;
1206
16
1207
int
1208
lgetc(int quotec)
1209
{
1210
	int		c, next;
1211
1212
	if (parsebuf) {
1213
		/* Read character from the parsebuffer instead of input. */
1214
		if (parseindex >= 0) {
1215
			c = parsebuf[parseindex++];
1216
			if (c != '\0')
1217
				return (c);
1218
			parsebuf = NULL;
1219
		} else
1220
			parseindex++;
1221
	}
1222
1223
	if (pushback_index)
1224
		return (pushback_buffer[--pushback_index]);
1225
1226
	if (quotec) {
1227
		if ((c = getc(file->stream)) == EOF) {
1228
			yyerror("reached end of file while parsing "
1229
			    "quoted string");
1230
			if (file == topfile || popfile() == EOF)
1231
				return (EOF);
1232
			return (quotec);
1233
		}
1234
		return (c);
1235
804
	}
1236
1237
	while ((c = getc(file->stream)) == '\\') {
1238
804
		next = getc(file->stream);
1239
804
		if (next != '\n') {
1240
804
			c = next;
1241
804
			break;
1242
804
		}
1243
		yylval.lineno = file->lineno;
1244
804
		file->lineno++;
1245
	}
1246
1608
1247
	while (c == EOF) {
1248
		if (file == topfile || popfile() == EOF)
1249
			return (EOF);
1250
		c = getc(file->stream);
1251
	}
1252
	return (c);
1253
}
1254
1255
int
1256
lungetc(int c)
1257
{
1258
804
	if (c == EOF)
1259
8
		return (EOF);
1260
804
	if (parsebuf) {
1261
804
		parseindex--;
1262
804
		if (parseindex >= 0)
1263
			return (c);
1264
804
	}
1265
	if (pushback_index < MAXPUSHBACK-1)
1266
56
		return (pushback_buffer[pushback_index++] = c);
1267
184
	else
1268
748
		return (EOF);
1269
620
}
1270
1271
int
1272
64
findeol(void)
1273
{
1274
64
	int	c;
1275
510
1276
	parsebuf = NULL;
1277
510
1278
230
	/* skip to either EOF or the first real EOL */
1279
	while (1) {
1280
230
		if (pushback_index)
1281
			c = pushback_buffer[--pushback_index];
1282
796
		else
1283
804
			c = lgetc(0);
1284
8
		if (c == '\n') {
1285
			file->lineno++;
1286
804
			break;
1287
804
		}
1288
		if (c == EOF)
1289
			break;
1290
	}
1291
	return (ERROR);
1292
}
1293
1294
int
1295
yylex(void)
1296
{
1297
	u_char	 buf[8096];
1298
	u_char	*p, *val;
1299
	int	 quotec, next, c;
1300
	int	 token;
1301
1302
top:
1303
	p = buf;
1304
	while ((c = lgetc(0)) == ' ' || c == '\t')
1305
		; /* nothing */
1306
1307
8
	yylval.lineno = file->lineno;
1308
	if (c == '#')
1309
		while ((c = lgetc(0)) != '\n' && c != EOF)
1310
			; /* nothing */
1311
	if (c == '$' && parsebuf == NULL) {
1312
		while (1) {
1313
			if ((c = lgetc(0)) == EOF)
1314
8
				return (0);
1315
8
1316
8
			if (p + 1 >= buf + sizeof(buf) - 1) {
1317
				yyerror("string too long");
1318
24
				return (findeol());
1319
24
			}
1320
24
			if (isalnum(c) || c == '_') {
1321
72
				*p++ = c;
1322
24
				continue;
1323

48
			}
1324
24
			*p = '\0';
1325
			lungetc(c);
1326
24
			break;
1327
24
		}
1328
24
		val = symget(buf);
1329
24
		if (val == NULL) {
1330
			yyerror("macro '%s' not defined", buf);
1331
24
			return (findeol());
1332
		}
1333
		parsebuf = val;
1334
		parseindex = 0;
1335
		goto top;
1336
	}
1337
500
1338
500
	switch (c) {
1339
	case '\'':
1340
500
	case '"':
1341
500
		quotec = c;
1342
1088
		while (1) {
1343
500
			if ((c = lgetc(quotec)) == EOF)
1344

1000
				return (0);
1345
500
			if (c == '\n') {
1346
				file->lineno++;
1347
500
				continue;
1348
500
			} else if (c == '\\') {
1349
88
				if ((next = lgetc(quotec)) == EOF)
1350
500
					return (0);
1351
				if (next == quotec || c == ' ' || c == '\t')
1352
500
					c = next;
1353
8
				else if (next == '\n') {
1354
8
					file->lineno++;
1355
8
					continue;
1356
				} else
1357
8
					lungetc(next);
1358
120
			} else if (c == quotec) {
1359
120
				*p = '\0';
1360
120
				break;
1361
264
			} else if (c == '\0') {
1362
120
				yyerror("syntax error");
1363

240
				return (findeol());
1364
120
			}
1365
			if (p + 1 >= buf + sizeof(buf) - 1) {
1366
120
				yyerror("string too long");
1367
120
				return (findeol());
1368
24
			}
1369
120
			*p++ = c;
1370
		}
1371
120
		yylval.v.string = strdup(buf);
1372
16
		if (yylval.v.string == NULL)
1373
16
			err(1, "yylex: strdup");
1374
16
		return (STRING);
1375
	}
1376
16
1377
32
#define allowed_to_end_number(x) \
1378
	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
1379
1380
	if (c == '-' || isdigit(c)) {
1381
		do {
1382
			*p++ = c;
1383
			if ((unsigned)(p-buf) >= sizeof(buf)) {
1384
				yyerror("string too long");
1385
				return (findeol());
1386
			}
1387
		} while ((c = lgetc(0)) != EOF && isdigit(c));
1388
		lungetc(c);
1389
32
		if (p == buf + 1 && buf[0] == '-')
1390
32
			goto nodigits;
1391
32
		if (c == EOF || allowed_to_end_number(c)) {
1392
88
			const char *errstr = NULL;
1393
32
1394

64
			*p = '\0';
1395
32
			yylval.v.number = strtonum(buf, LLONG_MIN,
1396
			    LLONG_MAX, &errstr);
1397
32
			if (errstr) {
1398
32
				yyerror("\"%s\" invalid number: %s",
1399
24
				    buf, errstr);
1400
32
				return (findeol());
1401
			}
1402
32
			return (NUMBER);
1403
		} else {
1404
nodigits:
1405
			while (p > buf + 1)
1406
				lungetc(*--p);
1407
			c = *--p;
1408
			if (c == '-')
1409
				return (c);
1410
		}
1411
	}
1412
1413
#define allowed_in_string(x) \
1414
	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1415
	x != '{' && x != '}' && x != '<' && x != '>' && \
1416
	x != '!' && x != '=' && x != '#' && \
1417
32
	x != ',' && x != '/'))
1418
1419
	if (isalnum(c) || c == ':' || c == '_') {
1420
		do {
1421
			*p++ = c;
1422
			if ((unsigned)(p-buf) >= sizeof(buf)) {
1423
				yyerror("string too long");
1424
				return (findeol());
1425
			}
1426
		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
1427
		lungetc(c);
1428
32
		*p = '\0';
1429
32
		if ((token = lookup(buf)) == STRING)
1430
32
			if ((yylval.v.string = strdup(buf)) == NULL)
1431
32
				err(1, "yylex: strdup");
1432
64
		return (token);
1433
32
	}
1434

64
	if (c == '\n') {
1435
32
		yylval.lineno = file->lineno;
1436
		file->lineno++;
1437
32
	}
1438
32
	if (c == EOF)
1439
		return (0);
1440
32
	return (c);
1441
}
1442
32
1443
8
int
1444
check_file_secrecy(int fd, const char *fname)
1445
{
1446
	struct stat	st;
1447
1448
	if (fstat(fd, &st)) {
1449
		log_warn("cannot stat %s", fname);
1450
		return (-1);
1451
	}
1452
8
	if (st.st_uid != 0 && st.st_uid != getuid()) {
1453
8
		log_warnx("%s: owner not root or current user", fname);
1454
8
		return (-1);
1455
	}
1456
8
	if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) {
1457
		log_warnx("%s: group writable or world read/writable", fname);
1458
		return (-1);
1459
	}
1460
	return (0);
1461
}
1462
1463
struct file *
1464
pushfile(const char *name, int secret)
1465
{
1466
	struct file	*nfile;
1467
1468
	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
1469
		log_warn("%s: malloc", __func__);
1470
		return (NULL);
1471
	}
1472
48
	if ((nfile->name = strdup(name)) == NULL) {
1473
48
		log_warn("%s: malloc", __func__);
1474
		free(nfile);
1475
		return (NULL);
1476
	}
1477
	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
1478
		log_warn("%s: %s", __func__, nfile->name);
1479
		free(nfile->name);
1480
48
		free(nfile);
1481
		return (NULL);
1482
	} else if (secret &&
1483
	    check_file_secrecy(fileno(nfile->stream), nfile->name)) {
1484
		fclose(nfile->stream);
1485
		free(nfile->name);
1486
		free(nfile);
1487
48
		return (NULL);
1488
96
	}
1489
48
	nfile->lineno = 1;
1490
	TAILQ_INSERT_TAIL(&files, nfile, entry);
1491
	return (nfile);
1492
}
1493
1494
int
1495
popfile(void)
1496
{
1497
48
	struct file	*prev;
1498
1499
48
	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
1500
		prev->errors += file->errors;
1501
1502
	TAILQ_REMOVE(&files, file, entry);
1503
	fclose(file->stream);
1504
	free(file->name);
1505
	free(file);
1506
	file = prev;
1507
	return (file ? 0 : EOF);
1508
}
1509
40
1510
40
int
1511
parse_config(const char *filename, struct relayd *x_conf)
1512
{
1513
	struct sym	*sym, *next;
1514
1515
	conf = x_conf;
1516
	if (config_init(conf) == -1) {
1517
40
		log_warn("%s: cannot initialize configuration", __func__);
1518
		return (-1);
1519
	}
1520
1521
	errors = 0;
1522
1523
	if ((file = pushfile(filename, 0)) == NULL)
1524
40
		return (-1);
1525
80
1526
40
	topfile = file;
1527
	setservent(1);
1528
1529
	yyparse();
1530
	errors = file->errors;
1531
	popfile();
1532
1533
	endservent();
1534
40
	endprotoent();
1535
1536
40
	/* Free macros */
1537
24
	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
1538
24
		if (!sym->persist) {
1539
			free(sym->nam);
1540
			free(sym->val);
1541
			TAILQ_REMOVE(&symhead, sym, entry);
1542
			free(sym);
1543
		}
1544
	}
1545
24
1546
	return (errors ? -1 : 0);
1547
}
1548
1549
int
1550
load_config(const char *filename, struct relayd *x_conf)
1551
{
1552
24
	struct sym		*sym, *next;
1553
48
	struct table		*nexttb;
1554
24
	struct host		*h, *ph;
1555
	struct relay_table	*rlt;
1556
1557
	conf = x_conf;
1558
	conf->sc_conf.flags = 0;
1559
1560
	loadcfg = 1;
1561
	errors = 0;
1562
24
	last_host_id = last_table_id = last_rdr_id = last_proto_id =
1563
	    last_relay_id = last_rt_id = last_nr_id = 0;
1564
24
1565
	rdr = NULL;
1566
	table = NULL;
1567
	rlay = NULL;
1568
	proto = NULL;
1569
	router = NULL;
1570
1571
	if ((file = pushfile(filename, 0)) == NULL)
1572
		return (-1);
1573
1574
8
	topfile = file;
1575
	setservent(1);
1576
1577
	yyparse();
1578
	errors = file->errors;
1579
	popfile();
1580
1581
	endservent();
1582
8
	endprotoent();
1583
16
1584
16
	/* Free macros and check which have not been used. */
1585
	for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
1586
8
		next = TAILQ_NEXT(sym, entry);
1587
8
		if ((conf->sc_conf.opts & RELAYD_OPT_VERBOSE) && !sym->used)
1588
			fprintf(stderr, "warning: macro '%s' not "
1589
8
			    "used\n", sym->nam);
1590
		if (!sym->persist) {
1591
8
			free(sym->nam);
1592
			free(sym->val);
1593
548
			TAILQ_REMOVE(&symhead, sym, entry);
1594
716
			free(sym);
1595
168
		}
1596
	}
1597
96
1598
136
	if (TAILQ_EMPTY(conf->sc_rdrs) &&
1599
96
	    TAILQ_EMPTY(conf->sc_relays) &&
1600
64
	    TAILQ_EMPTY(conf->sc_rts)) {
1601
16
		log_warnx("no actions, nothing to do");
1602
540
		errors++;
1603
532
	}
1604
1605
	/* Cleanup relay list to inherit */
1606
	while ((rlay = TAILQ_FIRST(&relays)) != NULL) {
1607
		TAILQ_REMOVE(&relays, rlay, rl_entry);
1608
556
		while ((rlt = TAILQ_FIRST(&rlay->rl_tables))) {
1609
8
			TAILQ_REMOVE(&rlay->rl_tables, rlt, rlt_entry);
1610
8
			free(rlt);
1611
		}
1612
		free(rlay);
1613
1096
	}
1614
1615
	if (timercmp(&conf->sc_conf.timeout, &conf->sc_conf.interval, >=)) {
1616
548
		log_warnx("global timeout exceeds interval");
1617
		errors++;
1618
	}
1619
1620
	/* Verify that every table is used */
1621
548
	for (table = TAILQ_FIRST(conf->sc_tables); table != NULL;
1622
	     table = nexttb) {
1623
548
		nexttb = TAILQ_NEXT(table, entry);
1624
		if (table->conf.port == 0) {
1625
			TAILQ_REMOVE(conf->sc_tables, table, entry);
1626
1096
			while ((h = TAILQ_FIRST(&table->hosts)) != NULL) {
1627
548
				TAILQ_REMOVE(&table->hosts, h, entry);
1628
				free(h);
1629
			}
1630
			if (table->sendbuf != NULL)
1631
				free(table->sendbuf);
1632
			free(table);
1633
			continue;
1634
548
		}
1635
548
1636
		TAILQ_FOREACH(h, &table->hosts, entry) {
1637
			if (h->conf.parentid) {
1638
				ph = host_find(conf, h->conf.parentid);
1639
1640
548
				/* Validate the parent id */
1641
548
				if (h->conf.id == h->conf.parentid ||
1642
548
				    ph == NULL || ph->conf.parentid)
1643
548
					ph = NULL;
1644
548
1645
548
				if (ph == NULL) {
1646
					log_warnx("host parent id %d invalid",
1647
					    h->conf.parentid);
1648
					errors++;
1649
				} else
1650
548
					SLIST_INSERT_HEAD(&ph->children,
1651
548
					    h, child);
1652

548
			}
1653
		}
1654
1655
548
		if (!(table->conf.flags & F_USED)) {
1656
			log_warnx("unused table: %s", table->conf.name);
1657
			errors++;
1658
		}
1659
		if (timercmp(&table->conf.timeout,
1660
548
		    &conf->sc_conf.interval, >=)) {
1661
			log_warnx("table timeout exceeds interval: %s",
1662
			    table->conf.name);
1663
			errors++;
1664
		}
1665
	}
1666

556
1667
548
	/* Verify that every non-default protocol is used */
1668
8
	TAILQ_FOREACH(proto, conf->sc_protos, entry) {
1669
		if (!(proto->flags & F_USED)) {
1670
			log_warnx("unused protocol: %s", proto->name);
1671
		}
1672
	}
1673
548
1674
	return (errors ? -1 : 0);
1675
}
1676
1677
548
int
1678
symset(const char *nam, const char *val, int persist)
1679
{
1680
	struct sym	*sym;
1681
1682
548
	TAILQ_FOREACH(sym, &symhead, entry) {
1683
548
		if (strcmp(nam, sym->nam) == 0)
1684
548
			break;
1685
	}
1686
548
1687
	if (sym != NULL) {
1688
1096
		if (sym->persist == 1)
1689
			return (0);
1690
		else {
1691
			free(sym->nam);
1692
			free(sym->val);
1693
			TAILQ_REMOVE(&symhead, sym, entry);
1694
548
			free(sym);
1695
548
		}
1696
	}
1697
	if ((sym = calloc(1, sizeof(*sym))) == NULL)
1698
		return (-1);
1699
1700
	sym->nam = strdup(nam);
1701
	if (sym->nam == NULL) {
1702
		free(sym);
1703
548
		return (-1);
1704
	}
1705
	sym->val = strdup(val);
1706
	if (sym->val == NULL) {
1707
548
		free(sym->nam);
1708
		free(sym);
1709
		return (-1);
1710
	}
1711
	sym->used = 0;
1712
	sym->persist = persist;
1713
548
	TAILQ_INSERT_TAIL(&symhead, sym, entry);
1714
	return (0);
1715
}
1716
1717
int
1718
cmdline_symset(char *s)
1719
548
{
1720
548
	char	*sym, *val;
1721
	int	ret;
1722
	size_t	len;
1723
1724
	if ((val = strrchr(s, '=')) == NULL)
1725
548
		return (-1);
1726
548
1727
548
	len = strlen(s) - strlen(val) + 1;
1728
548
	if ((sym = malloc(len)) == NULL)
1729
548
		errx(1, "cmdline_symset: malloc");
1730
132
1731
132
	(void)strlcpy(sym, s, len);
1732
132
1733
548
	ret = symset(sym, val + 1, 1);
1734
548
	free(sym);
1735
1096
1736
	return (ret);
1737
548
}
1738
548
1739
char *
1740
symget(const char *nam)
1741
{
1742
548
	struct sym	*sym;
1743
132
1744
132
	TAILQ_FOREACH(sym, &symhead, entry) {
1745
132
		if (strcmp(nam, sym->nam) == 0) {
1746
			sym->used = 1;
1747
			return (sym->val);
1748
32
		}
1749
	}
1750
	return (NULL);
1751
}
1752
32
1753
struct address *
1754
host_v4(const char *s)
1755
{
1756
	struct in_addr		 ina;
1757
	struct sockaddr_in	*sain;
1758
	struct address		*h;
1759
1760
1096
	bzero(&ina, sizeof(ina));
1761
548
	if (inet_pton(AF_INET, s, &ina) != 1)
1762
		return (NULL);
1763
548
1764
	if ((h = calloc(1, sizeof(*h))) == NULL)
1765
		fatal(__func__);
1766
	sain = (struct sockaddr_in *)&h->ss;
1767
	sain->sin_len = sizeof(struct sockaddr_in);
1768
548
	sain->sin_family = AF_INET;
1769
548
	sain->sin_addr.s_addr = ina.s_addr;
1770
548
1771
548
	return (h);
1772
548
}
1773
1774
struct address *
1775
host_v6(const char *s)
1776
{
1777
	struct addrinfo		 hints, *res;
1778
540
	struct sockaddr_in6	*sa_in6;
1779
	struct address		*h = NULL;
1780
1781
540
	bzero(&hints, sizeof(hints));
1782
	hints.ai_family = AF_INET6;
1783
	hints.ai_socktype = SOCK_DGRAM; /* dummy */
1784
	hints.ai_flags = AI_NUMERICHOST;
1785
	if (getaddrinfo(s, "0", &hints, &res) == 0) {
1786
		if ((h = calloc(1, sizeof(*h))) == NULL)
1787
540
			fatal(__func__);
1788
		sa_in6 = (struct sockaddr_in6 *)&h->ss;
1789
		sa_in6->sin6_len = sizeof(struct sockaddr_in6);
1790
		sa_in6->sin6_family = AF_INET6;
1791
		memcpy(&sa_in6->sin6_addr,
1792
		    &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
1793
540
		    sizeof(sa_in6->sin6_addr));
1794
540
		sa_in6->sin6_scope_id =
1795
		    ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
1796
1797
		freeaddrinfo(res);
1798
	}
1799
540
1800
540
	return (h);
1801
540
}
1802
1803
540
int
1804
540
host_dns(const char *s, struct addresslist *al, int max,
1805
540
    struct portrange *port, const char *ifname, int ipproto)
1806
1080
{
1807
	struct addrinfo		 hints, *res0, *res;
1808
	int			 error, cnt = 0;
1809
	struct sockaddr_in	*sain;
1810
	struct sockaddr_in6	*sin6;
1811
	struct address		*h;
1812
1813
	if ((cnt = host_if(s, al, max, port, ifname, ipproto)) != 0)
1814
		return (cnt);
1815
1816
	bzero(&hints, sizeof(hints));
1817
	hints.ai_family = PF_UNSPEC;
1818
	hints.ai_socktype = SOCK_DGRAM; /* DUMMY */
1819
	hints.ai_flags = AI_ADDRCONFIG;
1820
8
	error = getaddrinfo(s, NULL, &hints, &res0);
1821
	if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME)
1822
		return (0);
1823
	if (error) {
1824
		log_warnx("%s: could not parse \"%s\": %s", __func__, s,
1825
8
		    gai_strerror(error));
1826
8
		return (-1);
1827
8
	}
1828
8
1829
8
	for (res = res0; res && cnt < max; res = res->ai_next) {
1830
		if (res->ai_family != AF_INET &&
1831
		    res->ai_family != AF_INET6)
1832

8
			continue;
1833
		if ((h = calloc(1, sizeof(*h))) == NULL)
1834
			fatal(__func__);
1835
1836
		if (port != NULL)
1837
			bcopy(port, &h->port, sizeof(h->port));
1838
8
		if (ifname != NULL) {
1839
8
			if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
1840
			    sizeof(h->ifname))
1841
8
				log_warnx("%s: interface name truncated",
1842
8
				    __func__);
1843
			freeaddrinfo(res0);
1844
			free(h);
1845
			return (-1);
1846
		}
1847
		if (ipproto != -1)
1848
			h->ipproto = ipproto;
1849
		h->ss.ss_family = res->ai_family;
1850
1851
		if (res->ai_family == AF_INET) {
1852
			sain = (struct sockaddr_in *)&h->ss;
1853
			sain->sin_len = sizeof(struct sockaddr_in);
1854
			sain->sin_addr.s_addr = ((struct sockaddr_in *)
1855
			    res->ai_addr)->sin_addr.s_addr;
1856
		} else {
1857
			sin6 = (struct sockaddr_in6 *)&h->ss;
1858
			sin6->sin6_len = sizeof(struct sockaddr_in6);
1859
			memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *)
1860
			    res->ai_addr)->sin6_addr, sizeof(struct in6_addr));
1861
		}
1862
1863
		TAILQ_INSERT_HEAD(al, h, entry);
1864
		cnt++;
1865
	}
1866
	if (cnt == max && res) {
1867
		log_warnx("%s: %s resolves to more than %d hosts", __func__,
1868
		    s, max);
1869
	}
1870
	freeaddrinfo(res0);
1871
	return (cnt);
1872
}
1873
1874
int
1875
host_if(const char *s, struct addresslist *al, int max,
1876
    struct portrange *port, const char *ifname, int ipproto)
1877
{
1878
	struct ifaddrs		*ifap, *p;
1879
	struct sockaddr_in	*sain;
1880
	struct sockaddr_in6	*sin6;
1881
	struct address		*h;
1882
	int			 cnt = 0, af;
1883
1884
	if (getifaddrs(&ifap) == -1)
1885
		fatal("getifaddrs");
1886
1887
	/* First search for IPv4 addresses */
1888
	af = AF_INET;
1889
1890
 nextaf:
1891
	for (p = ifap; p != NULL && cnt < max; p = p->ifa_next) {
1892
		if (p->ifa_addr->sa_family != af ||
1893
		    (strcmp(s, p->ifa_name) != 0 &&
1894
		    !is_if_in_group(p->ifa_name, s)))
1895
			continue;
1896
		if ((h = calloc(1, sizeof(*h))) == NULL)
1897
			fatal("calloc");
1898
1899
		if (port != NULL)
1900
			bcopy(port, &h->port, sizeof(h->port));
1901
		if (ifname != NULL) {
1902
			if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
1903
			    sizeof(h->ifname))
1904
				log_warnx("%s: interface name truncated",
1905
				    __func__);
1906
			freeifaddrs(ifap);
1907
			return (-1);
1908
		}
1909
		if (ipproto != -1)
1910
			h->ipproto = ipproto;
1911
		h->ss.ss_family = af;
1912
1913
		if (af == AF_INET) {
1914
			sain = (struct sockaddr_in *)&h->ss;
1915
			sain->sin_len = sizeof(struct sockaddr_in);
1916
			sain->sin_addr.s_addr = ((struct sockaddr_in *)
1917
			    p->ifa_addr)->sin_addr.s_addr;
1918
		} else {
1919
			sin6 = (struct sockaddr_in6 *)&h->ss;
1920
			sin6->sin6_len = sizeof(struct sockaddr_in6);
1921
			memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *)
1922
			    p->ifa_addr)->sin6_addr, sizeof(struct in6_addr));
1923
			sin6->sin6_scope_id = ((struct sockaddr_in6 *)
1924
			    p->ifa_addr)->sin6_scope_id;
1925
		}
1926
1927
		TAILQ_INSERT_HEAD(al, h, entry);
1928
		cnt++;
1929
	}
1930
	if (af == AF_INET) {
1931
		/* Next search for IPv6 addresses */
1932
		af = AF_INET6;
1933
		goto nextaf;
1934
	}
1935
1936
	if (cnt > max) {
1937
		log_warnx("%s: %s resolves to more than %d hosts", __func__,
1938
		    s, max);
1939
	}
1940
	freeifaddrs(ifap);
1941
	return (cnt);
1942
}
1943
1944
int
1945
host(const char *s, struct addresslist *al, int max,
1946
    struct portrange *port, const char *ifname, int ipproto)
1947
{
1948
	struct address *h;
1949
1950
	h = host_v4(s);
1951
1952
	/* IPv6 address? */
1953
	if (h == NULL)
1954
		h = host_v6(s);
1955
1956
	if (h != NULL) {
1957
		if (port != NULL)
1958
			bcopy(port, &h->port, sizeof(h->port));
1959
		if (ifname != NULL) {
1960
			if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
1961
			    sizeof(h->ifname)) {
1962
				log_warnx("%s: interface name truncated",
1963
				    __func__);
1964
				free(h);
1965
				return (-1);
1966
			}
1967
		}
1968
		if (ipproto != -1)
1969
			h->ipproto = ipproto;
1970
1971
		TAILQ_INSERT_HEAD(al, h, entry);
1972
		return (1);
1973
	}
1974
1975
	return (host_dns(s, al, max, port, ifname, ipproto));
1976
}
1977
1978
void
1979
host_free(struct addresslist *al)
1980
{
1981
	struct address	 *h;
1982
1983
	while ((h = TAILQ_FIRST(al)) != NULL) {
1984
		TAILQ_REMOVE(al, h, entry);
1985
		free(h);
1986
	}
1987
}
1988
1989
struct table *
1990
table_inherit(struct table *tb)
1991
{
1992
	char		pname[TABLE_NAME_SIZE + 6];
1993
	struct host	*h, *dsth;
1994
548
	struct table	*dsttb, *oldtb;
1995
1996
548
	/* Get the table or table template */
1997
	if ((dsttb = table_findbyname(conf, tb->conf.name)) == NULL) {
1998
		yyerror("unknown table %s", tb->conf.name);
1999
		goto fail;
2000
	}
2001
	if (dsttb->conf.port != 0)
2002
		fatal("invalid table");	/* should not happen */
2003
2004
	if (tb->conf.port == 0) {
2005
		yyerror("invalid port");
2006
		goto fail;
2007
	}
2008
2009
	/* Check if a matching table already exists */
2010
	if (snprintf(pname, sizeof(pname), "%s:%u",
2011
	    tb->conf.name, ntohs(tb->conf.port)) >= (int)sizeof(pname)) {
2012
		yyerror("invalid table name");
2013
		goto fail;
2014
	}
2015
	if (strlcpy(tb->conf.name, pname, sizeof(tb->conf.name)) >=
2016
	    sizeof(tb->conf.name)) {
2017
		yyerror("invalid table mame");
2018
		goto fail;
2019
	}
2020
8
	if ((oldtb = table_findbyconf(conf, tb)) != NULL) {
2021
		purge_table(conf, NULL, tb);
2022
		return (oldtb);
2023
16
	}
2024
8
2025
	/* Create a new table */
2026
	tb->conf.id = ++last_table_id;
2027
	if (last_table_id == INT_MAX) {
2028
		yyerror("too many tables defined");
2029
8
		goto fail;
2030
8
	}
2031
8
	tb->conf.flags |= dsttb->conf.flags;
2032
2033
16
	/* Inherit global table options */
2034
8
	if (tb->conf.timeout.tv_sec == 0 && tb->conf.timeout.tv_usec == 0)
2035
		bcopy(&dsttb->conf.timeout, &tb->conf.timeout,
2036
8
		    sizeof(struct timeval));
2037
2038
	/* Copy the associated hosts */
2039
	TAILQ_INIT(&tb->hosts);
2040
	TAILQ_FOREACH(dsth, &dsttb->hosts, entry) {
2041
		if ((h = (struct host *)
2042
		    calloc(1, sizeof (*h))) == NULL)
2043
			fatal("out of memory");
2044
		bcopy(dsth, h, sizeof(*h));
2045
		h->conf.id = ++last_host_id;
2046
		if (last_host_id == INT_MAX) {
2047
			yyerror("too many hosts defined");
2048
			free(h);
2049
			goto fail;
2050
		}
2051
		h->conf.tableid = tb->conf.id;
2052
		h->tablename = tb->conf.name;
2053
		SLIST_INIT(&h->children);
2054
		TAILQ_INSERT_TAIL(&tb->hosts, h, entry);
2055
		TAILQ_INSERT_TAIL(&conf->sc_hosts, h, globalentry);
2056
	}
2057
2058
	conf->sc_tablecount++;
2059
	TAILQ_INSERT_TAIL(conf->sc_tables, tb, entry);
2060
2061
	return (tb);
2062
2063
 fail:
2064
	purge_table(conf, NULL, tb);
2065
	return (NULL);
2066
}
2067
2068
int
2069
relay_id(struct relay *rl)
2070
{
2071
	rl->rl_conf.id = ++last_relay_id;
2072
	rl->rl_conf.tls_keyid = ++last_key_id;
2073
	rl->rl_conf.tls_cakeyid = ++last_key_id;
2074
2075
	if (last_relay_id == INT_MAX || last_key_id == INT_MAX)
2076
		return (-1);
2077
2078
	return (0);
2079
}
2080
2081
struct relay *
2082
relay_inherit(struct relay *ra, struct relay *rb)
2083
{
2084
	struct relay_config	 rc;
2085
	struct relay_table	*rta, *rtb;
2086
2087
	bcopy(&rb->rl_conf, &rc, sizeof(rc));
2088
	bcopy(ra, rb, sizeof(*rb));
2089
2090
	bcopy(&rc.ss, &rb->rl_conf.ss, sizeof(rb->rl_conf.ss));
2091
	rb->rl_conf.port = rc.port;
2092
	rb->rl_conf.flags =
2093
	    (ra->rl_conf.flags & ~F_TLS) | (rc.flags & F_TLS);
2094
8
	if (!(rb->rl_conf.flags & F_TLS)) {
2095
		rb->rl_tls_cert = NULL;
2096
16
		rb->rl_conf.tls_cert_len = 0;
2097
8
		rb->rl_tls_key = NULL;
2098
		rb->rl_conf.tls_key_len = 0;
2099
	}
2100
	TAILQ_INIT(&rb->rl_tables);
2101
2102
	if (relay_id(rb) == -1) {
2103
8
		yyerror("too many relays defined");
2104
8
		goto err;
2105
	}
2106
2107
	if (snprintf(rb->rl_conf.name, sizeof(rb->rl_conf.name), "%s%u:%u",
2108
	    ra->rl_conf.name, rb->rl_conf.id, ntohs(rc.port)) >=
2109
8
	    (int)sizeof(rb->rl_conf.name)) {
2110
8
		yyerror("invalid relay name");
2111
8
		goto err;
2112
8
	}
2113
16
2114
	if (relay_findbyname(conf, rb->rl_conf.name) != NULL ||
2115
	    relay_findbyaddr(conf, &rb->rl_conf) != NULL) {
2116
540
		yyerror("relay %s defined twice", rb->rl_conf.name);
2117
540
		goto err;
2118
	}
2119
	if (relay_load_certfiles(rb) == -1) {
2120
		yyerror("cannot load certificates for relay %s",
2121
		    rb->rl_conf.name);
2122
		goto err;
2123
	}
2124
2125
	TAILQ_FOREACH(rta, &ra->rl_tables, rlt_entry) {
2126
		if ((rtb = calloc(1, sizeof(*rtb))) == NULL) {
2127
			yyerror("cannot allocate relay table");
2128
			goto err;
2129
		}
2130
		rtb->rlt_table = rta->rlt_table;
2131
		rtb->rlt_mode = rta->rlt_mode;
2132
		rtb->rlt_flags = rta->rlt_flags;
2133
2134
		TAILQ_INSERT_TAIL(&rb->rl_tables, rtb, rlt_entry);
2135
	}
2136
2137
	conf->sc_relaycount++;
2138
	SPLAY_INIT(&rlay->rl_sessions);
2139
	TAILQ_INSERT_TAIL(conf->sc_relays, rb, rl_entry);
2140
2141
	return (rb);
2142
2143
 err:
2144
	while ((rtb = TAILQ_FIRST(&rb->rl_tables))) {
2145
		TAILQ_REMOVE(&rb->rl_tables, rtb, rlt_entry);
2146
		free(rtb);
2147
	}
2148
	free(rb);
2149
	return (NULL);
2150
}
2151
2152
int
2153
getservice(char *n)
2154
{
2155
	struct servent	*s;
2156
	const char	*errstr;
2157
	long long	 llval;
2158
2159
	llval = strtonum(n, 0, UINT16_MAX, &errstr);
2160
	if (errstr) {
2161
		s = getservbyname(n, "tcp");
2162
		if (s == NULL)
2163
			s = getservbyname(n, "udp");
2164
		if (s == NULL) {
2165
			yyerror("unknown port %s", n);
2166
			return (-1);
2167
		}
2168
		return (s->s_port);
2169
	}
2170
2171
	return (htons((u_short)llval));
2172
}
2173
2174
int
2175
is_if_in_group(const char *ifname, const char *groupname)
2176
{
2177
	unsigned int		 len;
2178
	struct ifgroupreq	 ifgr;
2179
	struct ifg_req		*ifg;
2180
	int			 s;
2181
	int			 ret = 0;
2182
2183
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
2184
		err(1, "socket");
2185
2186
	memset(&ifgr, 0, sizeof(ifgr));
2187
	if (strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ) >= IFNAMSIZ)
2188
		err(1, "IFNAMSIZ");
2189
	if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) {
2190
		if (errno == EINVAL || errno == ENOTTY)
2191
			goto end;
2192
		err(1, "SIOCGIFGROUP");
2193
	}
2194
2195
	len = ifgr.ifgr_len;
2196
	ifgr.ifgr_groups = calloc(len / sizeof(struct ifg_req),
2197
	    sizeof(struct ifg_req));
2198
	if (ifgr.ifgr_groups == NULL)
2199
		err(1, "getifgroups");
2200
	if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
2201
		err(1, "SIOCGIFGROUP");
2202
2203
	ifg = ifgr.ifgr_groups;
2204
	for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
2205
		len -= sizeof(struct ifg_req);
2206
		if (strcmp(ifg->ifgrq_group, groupname) == 0) {
2207
			ret = 1;
2208
			break;
2209
		}
2210
	}
2211
	free(ifgr.ifgr_groups);
2212
2213
end:
2214
	close(s);
2215
	return (ret);
2216
}
2217
#line 2210 "parse.c"
2218
2208
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
2219
1104
static int yygrowstack(void)
2220
{
2221
    unsigned int newsize;
2222
    long sslen;
2223
    short *newss;
2224
1104
    YYSTYPE *newvs;
2225
2226
    if ((newsize = yystacksize) == 0)
2227
        newsize = YYINITSTACKSIZE;
2228
    else if (newsize >= YYMAXDEPTH)
2229
        return -1;
2230

2208
    else if ((newsize *= 2) > YYMAXDEPTH)
2231
        newsize = YYMAXDEPTH;
2232
2208
    sslen = yyssp - yyss;
2233
1104
#ifdef SIZE_MAX
2234
1104
#define YY_SIZE_MAX SIZE_MAX
2235
#else
2236
1104
#define YY_SIZE_MAX 0xffffffffU
2237
1104
#endif
2238

2208
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
2239
        goto bail;
2240
2208
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
2241
1104
      (short *)malloc(newsize * sizeof *newss); /* overflow check above */
2242
1104
    if (newss == NULL)
2243
        goto bail;
2244
1104
    yyss = newss;
2245
1104
    yyssp = newss + sslen;
2246
1104
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
2247
1104
        goto bail;
2248
1104
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
2249
      (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
2250
    if (newvs == NULL)
2251
        goto bail;
2252
    yyvs = newvs;
2253
    yyvsp = newvs + sslen;
2254
    yystacksize = newsize;
2255
    yysslim = yyss + newsize - 1;
2256
    return 0;
2257
bail:
2258
1104
    if (yyss)
2259
            free(yyss);
2260
    if (yyvs)
2261
            free(yyvs);
2262
    yyss = yyssp = NULL;
2263
    yyvs = yyvsp = NULL;
2264
    yystacksize = 0;
2265
    return -1;
2266
}
2267
2268
#define YYABORT goto yyabort
2269
#define YYREJECT goto yyabort
2270
#define YYACCEPT goto yyaccept
2271
#define YYERROR goto yyerrlab
2272
int
2273
yyparse(void)
2274
{
2275
    int yym, yyn, yystate;
2276
#if YYDEBUG
2277
    const char *yys;
2278
2279
2208
    if ((yys = getenv("YYDEBUG")))
2280
1104
    {
2281
1104
        yyn = *yys;
2282
        if (yyn >= '0' && yyn <= '9')
2283

2208
            yydebug = yyn - '0';
2284
1104
    }
2285
1104
#endif /* YYDEBUG */
2286
1104
2287
    yynerrs = 0;
2288
    yyerrflag = 0;
2289
74408
    yychar = (-1);
2290
42084
2291
    if (yyss == NULL && yygrowstack()) goto yyoverflow;
2292
27684
    yyssp = yyss;
2293
    yyvsp = yyvs;
2294
    *yyssp = yystate = 0;
2295
2296
yyloop:
2297
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
2298
    if (yychar < 0)
2299
    {
2300
        if ((yychar = yylex()) < 0) yychar = 0;
2301
#if YYDEBUG
2302
        if (yydebug)
2303
27684
        {
2304

167196
            yys = 0;
2305
83028
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
2306
            if (!yys) yys = "illegal-symbol";
2307
            printf("%sdebug: state %d, reading %d (%s)\n",
2308
                    YYPREFIX, yystate, yychar, yys);
2309
        }
2310
#endif
2311
    }
2312

31532
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
2313
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
2314
    {
2315
#if YYDEBUG
2316
31532
        if (yydebug)
2317
31532
            printf("%sdebug: state %d, shifting to state %d\n",
2318
31532
                    YYPREFIX, yystate, yytable[yyn]);
2319
31580
#endif
2320
31532
        if (yyssp >= yysslim && yygrowstack())
2321
        {
2322

42052
            goto yyoverflow;
2323
21000
        }
2324
        *++yyssp = yystate = yytable[yyn];
2325
10492
        *++yyvsp = yylval;
2326
10492
        yychar = (-1);
2327
        if (yyerrflag > 0)  --yyerrflag;
2328
60
        goto yyloop;
2329
    }
2330
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
2331
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
2332
    {
2333
        yyn = yytable[yyn];
2334
        goto yyreduce;
2335
    }
2336
    if (yyerrflag) goto yyinrecovery;
2337
#if defined(__GNUC__)
2338
8
    goto yynewerror;
2339
#endif
2340
68
yynewerror:
2341
    yyerror("syntax error");
2342
24
#if defined(__GNUC__)
2343
40
    goto yyerrlab;
2344
#endif
2345

160
yyerrlab:
2346
80
    ++yynerrs;
2347
yyinrecovery:
2348
    if (yyerrflag < 3)
2349
    {
2350
        yyerrflag = 3;
2351
        for (;;)
2352
        {
2353

24
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
2354
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
2355
            {
2356
#if YYDEBUG
2357
24
                if (yydebug)
2358
24
                    printf("%sdebug: state %d, error recovery shifting\
2359
24
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
2360
#endif
2361
                if (yyssp >= yysslim && yygrowstack())
2362
                {
2363
                    goto yyoverflow;
2364
                }
2365
                *++yyssp = yystate = yytable[yyn];
2366
                *++yyvsp = yylval;
2367
                goto yyloop;
2368
16
            }
2369
16
            else
2370
16
            {
2371
#if YYDEBUG
2372
                if (yydebug)
2373
                    printf("%sdebug: error recovery discarding state %d\n",
2374
                            YYPREFIX, *yyssp);
2375
#endif
2376
44
                if (yyssp <= yyss) goto yyabort;
2377
                --yyssp;
2378
                --yyvsp;
2379
            }
2380
        }
2381
    }
2382
    else
2383
    {
2384
        if (yychar == 0) goto yyabort;
2385
#if YYDEBUG
2386
        if (yydebug)
2387
44
        {
2388
44
            yys = 0;
2389
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
2390
            if (!yys) yys = "illegal-symbol";
2391
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
2392
                    YYPREFIX, yystate, yychar, yys);
2393
        }
2394
#endif
2395
        yychar = (-1);
2396
42816
        goto yyloop;
2397
42816
    }
2398
28884
yyreduce:
2399
#if YYDEBUG
2400
13932
    if (yydebug)
2401












































62044
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
2402
                YYPREFIX, yystate, yyn, yyrule[yyn]);
2403
#endif
2404
    yym = yylen[yyn];
2405
    if (yym)
2406
        yyval = yyvsp[1-yym];
2407
    else
2408
        memset(&yyval, 0, sizeof yyval);
2409
    switch (yyn)
2410
    {
2411
case 11:
2412
#line 205 "parse.y"
2413
{ file->errors++; }
2414
break;
2415
case 12:
2416
#line 208 "parse.y"
2417
{
2418
			struct file	*nfile;
2419
2420
			if ((nfile = pushfile(yyvsp[0].v.string, 0)) == NULL) {
2421
				yyerror("failed to include file %s", yyvsp[0].v.string);
2422
				free(yyvsp[0].v.string);
2423
				YYERROR;
2424
			}
2425
			free(yyvsp[0].v.string);
2426
2427
			file = nfile;
2428
			lungetc('\n');
2429
		}
2430
break;
2431
case 13:
2432
#line 223 "parse.y"
2433
{
2434
			log_warnx("%s:%d: %s",
2435
			    file->name, yylval.lineno,
2436
			    "please use the \"tls\" keyword"
2437
			    " instead of \"ssl\"");
2438
		}
2439
break;
2440
case 15:
2441
#line 232 "parse.y"
2442
{ yyval.v.number = 0; }
2443
break;
2444
case 16:
2445
#line 233 "parse.y"
2446
{ yyval.v.number = 1; }
2447
break;
2448
case 17:
2449
#line 236 "parse.y"
2450
{ yyval.v.number = 0; }
2451
break;
2452
case 18:
2453
#line 237 "parse.y"
2454
{ yyval.v.number = 1; }
2455
break;
2456
case 19:
2457
#line 240 "parse.y"
2458
{
2459
			if (strcmp("https", yyvsp[0].v.string) == 0) {
2460
				yyval.v.number = 1;
2461
			} else if (strcmp("http", yyvsp[0].v.string) == 0) {
2462
				yyval.v.number = 0;
2463
			} else {
2464
				yyerror("invalid check type: %s", yyvsp[0].v.string);
2465
				free(yyvsp[0].v.string);
2466
				YYERROR;
2467
			}
2468
			free(yyvsp[0].v.string);
2469
		}
2470
break;
2471
case 20:
2472
#line 254 "parse.y"
2473
{
2474
			yyval.v.string = strdup("");
2475
			if (yyval.v.string == NULL)
2476
				fatal("calloc");
2477
		}
2478
break;
2479
case 21:
2480
#line 259 "parse.y"
2481
{
2482
			if (asprintf(&yyval.v.string, "Host: %s\r\nConnection: close\r\n",
2483
			    yyvsp[0].v.string) == -1)
2484
				fatal("asprintf");
2485
		}
2486
break;
2487
case 22:
2488
#line 266 "parse.y"
2489
{ yyval.v.number = RELAY_PROTO_TCP; }
2490
break;
2491
case 23:
2492
#line 267 "parse.y"
2493
{ yyval.v.number = RELAY_PROTO_TCP; }
2494
break;
2495
case 24:
2496
#line 268 "parse.y"
2497
{
2498
			if (strcmp("http", yyvsp[0].v.string) == 0) {
2499
				yyval.v.number = RELAY_PROTO_HTTP;
2500
			} else if (strcmp("dns", yyvsp[0].v.string) == 0) {
2501
				yyval.v.number = RELAY_PROTO_DNS;
2502
			} else {
2503
				yyerror("invalid protocol type: %s", yyvsp[0].v.string);
2504
				free(yyvsp[0].v.string);
2505
				YYERROR;
2506
			}
2507
			free(yyvsp[0].v.string);
2508
		}
2509
break;
2510
case 25:
2511
#line 282 "parse.y"
2512
{ yyval.v.number = IPPROTO_TCP; }
2513
break;
2514
case 26:
2515
#line 283 "parse.y"
2516
{ yyval.v.number = IPPROTO_TCP; }
2517
break;
2518
case 27:
2519
#line 284 "parse.y"
2520
{
2521
			struct protoent	*p;
2522
2523
			if ((p = getprotobyname(yyvsp[0].v.string)) == NULL) {
2524
				yyerror("invalid protocol: %s", yyvsp[0].v.string);
2525
				free(yyvsp[0].v.string);
2526
				YYERROR;
2527
			}
2528
			free(yyvsp[0].v.string);
2529
2530
			yyval.v.number = p->p_proto;
2531
		}
2532
break;
2533
case 32:
2534
#line 307 "parse.y"
2535
{
2536
			if ((proto->style = strdup(yyvsp[0].v.string)) == NULL)
2537
				fatal("out of memory");
2538
			free(yyvsp[0].v.string);
2539
		}
2540
break;
2541
case 33:
2542
#line 314 "parse.y"
2543
{
2544
			char		*a, *b;
2545
			int		 p[2];
2546
2547
			p[0] = p[1] = 0;
2548
2549
			a = yyvsp[0].v.string;
2550
			b = strchr(yyvsp[0].v.string, ':');
2551
			if (b == NULL)
2552
				yyval.v.port.op = PF_OP_EQ;
2553
			else {
2554
				*b++ = '\0';
2555
				if ((p[1] = getservice(b)) == -1) {
2556
					free(yyvsp[0].v.string);
2557
					YYERROR;
2558
				}
2559
				yyval.v.port.op = PF_OP_RRG;
2560
			}
2561
			if ((p[0] = getservice(a)) == -1) {
2562
				free(yyvsp[0].v.string);
2563
				YYERROR;
2564
			}
2565
			yyval.v.port.val[0] = p[0];
2566
			yyval.v.port.val[1] = p[1];
2567
			free(yyvsp[0].v.string);
2568
		}
2569
break;
2570
case 34:
2571
#line 340 "parse.y"
2572
{
2573
			if (yyvsp[0].v.number <= 0 || yyvsp[0].v.number > (int)USHRT_MAX) {
2574
				yyerror("invalid port: %d", yyvsp[0].v.number);
2575
				YYERROR;
2576
			}
2577
			yyval.v.port.val[0] = htons(yyvsp[0].v.number);
2578
			yyval.v.port.op = PF_OP_EQ;
2579
		}
2580
break;
2581
case 35:
2582
#line 350 "parse.y"
2583
{
2584
			char *s = yyvsp[-2].v.string;
2585
			while (*s++) {
2586
				if (isspace((unsigned char)*s)) {
2587
					yyerror("macro name cannot contain "
2588
					    "whitespace");
2589
					YYERROR;
2590
				}
2591
			}
2592
			if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)
2593
				fatal("cannot store variable");
2594
			free(yyvsp[-2].v.string);
2595
			free(yyvsp[0].v.string);
2596
		}
2597
break;
2598
case 36:
2599
#line 366 "parse.y"
2600
{
2601
			table->sendbuf = NULL;
2602
		}
2603
break;
2604
case 37:
2605
#line 369 "parse.y"
2606
{
2607
			table->sendbuf = strdup(yyvsp[0].v.string);
2608
			if (table->sendbuf == NULL)
2609
				fatal("out of memory");
2610
			free(yyvsp[0].v.string);
2611
		}
2612
break;
2613
case 38:
2614
#line 377 "parse.y"
2615
{
2616
			if ((conf->sc_conf.interval.tv_sec = yyvsp[0].v.number) < 0) {
2617
				yyerror("invalid interval: %d", yyvsp[0].v.number);
2618
				YYERROR;
2619
			}
2620
		}
2621
break;
2622
case 39:
2623
#line 383 "parse.y"
2624
{
2625
			conf->sc_conf.opts |= yyvsp[0].v.number;
2626
		}
2627
break;
2628
case 40:
2629
#line 386 "parse.y"
2630
{
2631
			bcopy(&yyvsp[0].v.tv, &conf->sc_conf.timeout,
2632
			    sizeof(struct timeval));
2633
		}
2634
break;
2635
case 41:
2636
#line 390 "parse.y"
2637
{
2638
			if (yyvsp[0].v.number <= 0 || yyvsp[0].v.number > PROC_MAX_INSTANCES) {
2639
				yyerror("invalid number of preforked "
2640
				    "relays: %d", yyvsp[0].v.number);
2641
				YYERROR;
2642
			}
2643
			conf->sc_conf.prefork_relay = yyvsp[0].v.number;
2644
		}
2645
break;
2646
case 42:
2647
#line 398 "parse.y"
2648
{
2649
			conf->sc_conf.flags |= F_SNMP;
2650
			if (yyvsp[-1].v.number)
2651
				conf->sc_conf.flags |= F_SNMP_TRAPONLY;
2652
			if (yyvsp[0].v.string) {
2653
				if (strlcpy(conf->sc_conf.snmp_path,
2654
				    yyvsp[0].v.string, sizeof(conf->sc_conf.snmp_path)) >=
2655
				    sizeof(conf->sc_conf.snmp_path)) {
2656
					yyerror("snmp path truncated");
2657
					free(yyvsp[0].v.string);
2658
					YYERROR;
2659
				}
2660
				free(yyvsp[0].v.string);
2661
			} else
2662
				(void)strlcpy(conf->sc_conf.snmp_path,
2663
				    AGENTX_SOCKET,
2664
				    sizeof(conf->sc_conf.snmp_path));
2665
		}
2666
break;
2667
case 43:
2668
#line 418 "parse.y"
2669
{ yyval.v.number = 0; }
2670
break;
2671
case 44:
2672
#line 419 "parse.y"
2673
{ yyval.v.number = 1; }
2674
break;
2675
case 45:
2676
#line 421 "parse.y"
2677
{ yyval.v.number = RELAYD_OPT_LOGUPDATE; }
2678
break;
2679
case 46:
2680
#line 422 "parse.y"
2681
{ yyval.v.number = RELAYD_OPT_LOGALL; }
2682
break;
2683
case 47:
2684
#line 425 "parse.y"
2685
{
2686
			struct rdr *srv;
2687
2688
			conf->sc_conf.flags |= F_NEEDPF;
2689
2690
			if (!loadcfg) {
2691
				free(yyvsp[0].v.string);
2692
				YYACCEPT;
2693
			}
2694
2695
			TAILQ_FOREACH(srv, conf->sc_rdrs, entry)
2696
				if (!strcmp(srv->conf.name, yyvsp[0].v.string))
2697
					break;
2698
			if (srv != NULL) {
2699
				yyerror("redirection %s defined twice", yyvsp[0].v.string);
2700
				free(yyvsp[0].v.string);
2701
				YYERROR;
2702
			}
2703
			if ((srv = calloc(1, sizeof (*srv))) == NULL)
2704
				fatal("out of memory");
2705
2706
			if (strlcpy(srv->conf.name, yyvsp[0].v.string,
2707
			    sizeof(srv->conf.name)) >=
2708
			    sizeof(srv->conf.name)) {
2709
				yyerror("redirection name truncated");
2710
				free(yyvsp[0].v.string);
2711
				free(srv);
2712
				YYERROR;
2713
			}
2714
			free(yyvsp[0].v.string);
2715
			srv->conf.id = ++last_rdr_id;
2716
			srv->conf.timeout.tv_sec = RELAY_TIMEOUT;
2717
			if (last_rdr_id == INT_MAX) {
2718
				yyerror("too many redirections defined");
2719
				free(srv);
2720
				YYERROR;
2721
			}
2722
			rdr = srv;
2723
		}
2724
break;
2725
case 48:
2726
#line 463 "parse.y"
2727
{
2728
			if (rdr->table == NULL) {
2729
				yyerror("redirection %s has no table",
2730
				    rdr->conf.name);
2731
				YYERROR;
2732
			}
2733
			if (TAILQ_EMPTY(&rdr->virts)) {
2734
				yyerror("redirection %s has no virtual ip",
2735
				    rdr->conf.name);
2736
				YYERROR;
2737
			}
2738
			conf->sc_rdrcount++;
2739
			if (rdr->backup == NULL) {
2740
				rdr->conf.backup_id =
2741
				    conf->sc_empty_table.conf.id;
2742
				rdr->backup = &conf->sc_empty_table;
2743
			} else if (rdr->backup->conf.port !=
2744
			    rdr->table->conf.port) {
2745
				yyerror("redirection %s uses two different "
2746
				    "ports for its table and backup table",
2747
				    rdr->conf.name);
2748
				YYERROR;
2749
			}
2750
			if (!(rdr->conf.flags & F_DISABLE))
2751
				rdr->conf.flags |= F_ADD;
2752
			TAILQ_INSERT_TAIL(conf->sc_rdrs, rdr, entry);
2753
			tableport = 0;
2754
			rdr = NULL;
2755
		}
2756
break;
2757
case 51:
2758
#line 498 "parse.y"
2759
{
2760
			if (hashkey != NULL) {
2761
				memcpy(&rdr->conf.key,
2762
				    hashkey, sizeof(rdr->conf.key));
2763
				rdr->conf.flags |= F_HASHKEY;
2764
				free(hashkey);
2765
				hashkey = NULL;
2766
			}
2767
2768
			switch (yyvsp[-3].v.number) {
2769
			case FWD_NORMAL:
2770
				if (yyvsp[0].v.string == NULL)
2771
					break;
2772
				yyerror("superfluous interface");
2773
				free(yyvsp[0].v.string);
2774
				YYERROR;
2775
			case FWD_ROUTE:
2776
				if (yyvsp[0].v.string != NULL)
2777
					break;
2778
				yyerror("missing interface to route to");
2779
				free(yyvsp[0].v.string);
2780
				YYERROR;
2781
			case FWD_TRANS:
2782
				yyerror("no transparent forward here");
2783
				if (yyvsp[0].v.string != NULL)
2784
					free(yyvsp[0].v.string);
2785
				YYERROR;
2786
			}
2787
			if (yyvsp[0].v.string != NULL) {
2788
				if (strlcpy(yyvsp[-1].v.table->conf.ifname, yyvsp[0].v.string,
2789
				    sizeof(yyvsp[-1].v.table->conf.ifname)) >=
2790
				    sizeof(yyvsp[-1].v.table->conf.ifname)) {
2791
					yyerror("interface name truncated");
2792
					free(yyvsp[0].v.string);
2793
					YYERROR;
2794
				}
2795
				free(yyvsp[0].v.string);
2796
			}
2797
2798
			if (yyvsp[-1].v.table->conf.check == CHECK_NOCHECK) {
2799
				yyerror("table %s has no check", yyvsp[-1].v.table->conf.name);
2800
				purge_table(conf, conf->sc_tables, yyvsp[-1].v.table);
2801
				YYERROR;
2802
			}
2803
			if (rdr->backup) {
2804
				yyerror("only one backup table is allowed");
2805
				purge_table(conf, conf->sc_tables, yyvsp[-1].v.table);
2806
				YYERROR;
2807
			}
2808
			if (rdr->table) {
2809
				rdr->backup = yyvsp[-1].v.table;
2810
				rdr->conf.backup_id = yyvsp[-1].v.table->conf.id;
2811
				if (dstmode != rdr->conf.mode) {
2812
					yyerror("backup table for %s with "
2813
					    "different mode", rdr->conf.name);
2814
					YYERROR;
2815
				}
2816
			} else {
2817
				rdr->table = yyvsp[-1].v.table;
2818
				rdr->conf.table_id = yyvsp[-1].v.table->conf.id;
2819
				rdr->conf.mode = dstmode;
2820
			}
2821
			yyvsp[-1].v.table->conf.fwdmode = yyvsp[-3].v.number;
2822
			yyvsp[-1].v.table->conf.rdrid = rdr->conf.id;
2823
			yyvsp[-1].v.table->conf.flags |= F_USED;
2824
		}
2825
break;
2826
case 52:
2827
#line 564 "parse.y"
2828
{
2829
			if (host(yyvsp[-3].v.string, &rdr->virts,
2830
			    SRV_MAX_VIRTS, &yyvsp[-1].v.port, yyvsp[0].v.string, yyvsp[-2].v.number) <= 0) {
2831
				yyerror("invalid virtual ip: %s", yyvsp[-3].v.string);
2832
				free(yyvsp[-3].v.string);
2833
				free(yyvsp[0].v.string);
2834
				YYERROR;
2835
			}
2836
			free(yyvsp[-3].v.string);
2837
			free(yyvsp[0].v.string);
2838
			if (rdr->conf.port == 0)
2839
				rdr->conf.port = yyvsp[-1].v.port.val[0];
2840
			tableport = rdr->conf.port;
2841
		}
2842
break;
2843
case 53:
2844
#line 578 "parse.y"
2845
{ rdr->conf.flags |= F_DISABLE; }
2846
break;
2847
case 54:
2848
#line 579 "parse.y"
2849
{ rdr->conf.flags |= F_STICKY; }
2850
break;
2851
case 55:
2852
#line 580 "parse.y"
2853
{
2854
			conf->sc_conf.flags |= F_NEEDPF;
2855
			if (strlcpy(rdr->conf.tag, yyvsp[0].v.string,
2856
			    sizeof(rdr->conf.tag)) >=
2857
			    sizeof(rdr->conf.tag)) {
2858
				yyerror("redirection tag name truncated");
2859
				free(yyvsp[0].v.string);
2860
				YYERROR;
2861
			}
2862
			if (yyvsp[-2].v.number)
2863
				rdr->conf.flags |= F_MATCH;
2864
			free(yyvsp[0].v.string);
2865
		}
2866
break;
2867
case 56:
2868
#line 593 "parse.y"
2869
{
2870
			if ((rdr->conf.timeout.tv_sec = yyvsp[0].v.number) < 0) {
2871
				yyerror("invalid timeout: %lld", yyvsp[0].v.number);
2872
				YYERROR;
2873
			}
2874
			if (rdr->conf.timeout.tv_sec > INT_MAX) {
2875
				yyerror("timeout too large: %lld", yyvsp[0].v.number);
2876
				YYERROR;
2877
			}
2878
		}
2879
break;
2880
case 58:
2881
#line 606 "parse.y"
2882
{ yyval.v.number = 0; }
2883
break;
2884
case 59:
2885
#line 607 "parse.y"
2886
{ yyval.v.number = 1; }
2887
break;
2888
case 60:
2889
#line 610 "parse.y"
2890
{ yyval.v.number = FWD_NORMAL; }
2891
break;
2892
case 61:
2893
#line 611 "parse.y"
2894
{ yyval.v.number = FWD_ROUTE; }
2895
break;
2896
case 62:
2897
#line 612 "parse.y"
2898
{ yyval.v.number = FWD_TRANS; }
2899
break;
2900
case 63:
2901
#line 615 "parse.y"
2902
{
2903
			if (strlen(yyvsp[-1].v.string) >= TABLE_NAME_SIZE) {
2904
				yyerror("invalid table name");
2905
				free(yyvsp[-1].v.string);
2906
				YYERROR;
2907
			}
2908
			yyval.v.string = yyvsp[-1].v.string;
2909
		}
2910
break;
2911
case 64:
2912
#line 625 "parse.y"
2913
{
2914
			struct table *tb;
2915
2916
			if (!loadcfg) {
2917
				free(yyvsp[0].v.string);
2918
				YYACCEPT;
2919
			}
2920
2921
			TAILQ_FOREACH(tb, conf->sc_tables, entry)
2922
				if (!strcmp(tb->conf.name, yyvsp[0].v.string))
2923
					break;
2924
			if (tb != NULL) {
2925
				yyerror("table %s defined twice", yyvsp[0].v.string);
2926
				free(yyvsp[0].v.string);
2927
				YYERROR;
2928
			}
2929
2930
			if ((tb = calloc(1, sizeof (*tb))) == NULL)
2931
				fatal("out of memory");
2932
2933
			if (strlcpy(tb->conf.name, yyvsp[0].v.string,
2934
			    sizeof(tb->conf.name)) >= sizeof(tb->conf.name)) {
2935
				yyerror("table name truncated");
2936
				free(yyvsp[0].v.string);
2937
				YYERROR;
2938
			}
2939
			free(yyvsp[0].v.string);
2940
2941
			tb->conf.id = 0; /* will be set later */
2942
			bcopy(&conf->sc_conf.timeout, &tb->conf.timeout,
2943
			    sizeof(struct timeval));
2944
			TAILQ_INIT(&tb->hosts);
2945
			table = tb;
2946
			dstmode = RELAY_DSTMODE_DEFAULT;
2947
		}
2948
break;
2949
case 65:
2950
#line 659 "parse.y"
2951
{
2952
			if (TAILQ_EMPTY(&table->hosts)) {
2953
				yyerror("table %s has no hosts",
2954
				    table->conf.name);
2955
				YYERROR;
2956
			}
2957
			conf->sc_tablecount++;
2958
			TAILQ_INSERT_TAIL(conf->sc_tables, table, entry);
2959
		}
2960
break;
2961
case 68:
2962
#line 674 "parse.y"
2963
{ table->conf.flags |= F_DISABLE; }
2964
break;
2965
case 72:
2966
#line 682 "parse.y"
2967
{
2968
			yyvsp[0].v.host->conf.tableid = table->conf.id;
2969
			yyvsp[0].v.host->tablename = table->conf.name;
2970
			TAILQ_INSERT_TAIL(&table->hosts, yyvsp[0].v.host, entry);
2971
		}
2972
break;
2973
case 74:
2974
#line 690 "parse.y"
2975
{
2976
			struct table	*tb;
2977
			if ((tb = calloc(1, sizeof (*tb))) == NULL)
2978
				fatal("out of memory");
2979
			if (strlcpy(tb->conf.name, yyvsp[0].v.string,
2980
			    sizeof(tb->conf.name)) >= sizeof(tb->conf.name)) {
2981
				yyerror("table name truncated");
2982
				free(yyvsp[0].v.string);
2983
				YYERROR;
2984
			}
2985
			free(yyvsp[0].v.string);
2986
			table = tb;
2987
			dstmode = RELAY_DSTMODE_DEFAULT;
2988
			hashkey = NULL;
2989
		}
2990
break;
2991
case 75:
2992
#line 704 "parse.y"
2993
{
2994
			struct table	*tb;
2995
			if (table->conf.port == 0)
2996
				table->conf.port = tableport;
2997
			else
2998
				table->conf.flags |= F_PORT;
2999
			if ((tb = table_inherit(table)) == NULL)
3000
				YYERROR;
3001
			yyval.v.table = tb;
3002
		}
3003
break;
3004
case 79:
3005
#line 721 "parse.y"
3006
{
3007
			if (yyvsp[0].v.port.op != PF_OP_EQ) {
3008
				yyerror("invalid port");
3009
				YYERROR;
3010
			}
3011
			table->conf.port = yyvsp[0].v.port.val[0];
3012
		}
3013
break;
3014
case 80:
3015
#line 728 "parse.y"
3016
{
3017
			bcopy(&yyvsp[0].v.tv, &table->conf.timeout,
3018
			    sizeof(struct timeval));
3019
		}
3020
break;
3021
case 81:
3022
#line 732 "parse.y"
3023
{
3024
			table->conf.flags |= F_DEMOTE;
3025
			if (strlcpy(table->conf.demote_group, yyvsp[0].v.string,
3026
			    sizeof(table->conf.demote_group))
3027
			    >= sizeof(table->conf.demote_group)) {
3028
				yyerror("yyparse: demote group name too long");
3029
				free(yyvsp[0].v.string);
3030
				YYERROR;
3031
			}
3032
			free(yyvsp[0].v.string);
3033
			if (carp_demote_init(table->conf.demote_group, 1)
3034
			    == -1) {
3035
				yyerror("yyparse: error initializing group "
3036
				    "'%s'", table->conf.demote_group);
3037
				YYERROR;
3038
			}
3039
		}
3040
break;
3041
case 82:
3042
#line 749 "parse.y"
3043
{
3044
			if (yyvsp[0].v.number < conf->sc_conf.interval.tv_sec ||
3045
			    yyvsp[0].v.number % conf->sc_conf.interval.tv_sec) {
3046
				yyerror("table interval must be "
3047
				    "divisible by global interval");
3048
				YYERROR;
3049
			}
3050
			table->conf.skip_cnt =
3051
			    (yyvsp[0].v.number / conf->sc_conf.interval.tv_sec) - 1;
3052
		}
3053
break;
3054
case 83:
3055
#line 759 "parse.y"
3056
{
3057
			switch (yyvsp[-1].v.number) {
3058
			case RELAY_DSTMODE_LOADBALANCE:
3059
			case RELAY_DSTMODE_HASH:
3060
			case RELAY_DSTMODE_SRCHASH:
3061
				if (hashkey != NULL) {
3062
					yyerror("key already specified");
3063
					free(hashkey);
3064
					YYERROR;
3065
				}
3066
				if ((hashkey = calloc(1,
3067
				    sizeof(*hashkey))) == NULL)
3068
					fatal("out of memory");
3069
				memcpy(hashkey, &yyvsp[0].v.key.key, sizeof(*hashkey));
3070
				break;
3071
			default:
3072
				if (yyvsp[0].v.key.keyset) {
3073
					yyerror("key not supported by mode");
3074
					YYERROR;
3075
				}
3076
				hashkey = NULL;
3077
				break;
3078
			}
3079
3080
			switch (yyvsp[-1].v.number) {
3081
			case RELAY_DSTMODE_LOADBALANCE:
3082
			case RELAY_DSTMODE_HASH:
3083
				if (rdr != NULL) {
3084
					yyerror("mode not supported "
3085
					    "for redirections");
3086
					YYERROR;
3087
				}
3088
				/* FALLTHROUGH */
3089
			case RELAY_DSTMODE_RANDOM:
3090
			case RELAY_DSTMODE_ROUNDROBIN:
3091
			case RELAY_DSTMODE_SRCHASH:
3092
				dstmode = yyvsp[-1].v.number;
3093
				break;
3094
			case RELAY_DSTMODE_LEASTSTATES:
3095
				if (rdr == NULL) {
3096
					yyerror("mode not supported "
3097
					    "for relays");
3098
					YYERROR;
3099
				}
3100
				dstmode = yyvsp[-1].v.number;
3101
				break;
3102
			}
3103
		}
3104
break;
3105
case 84:
3106
#line 810 "parse.y"
3107
{
3108
			yyval.v.key.keyset = 0;
3109
			yyval.v.key.key.data[0] = arc4random();
3110
			yyval.v.key.key.data[1] = arc4random();
3111
			yyval.v.key.key.data[2] = arc4random();
3112
			yyval.v.key.key.data[3] = arc4random();
3113
		}
3114
break;
3115
case 85:
3116
#line 817 "parse.y"
3117
{
3118
			/* manual key configuration */
3119
			yyval.v.key.keyset = 1;
3120
3121
			if (!strncmp(yyvsp[0].v.string, "0x", 2)) {
3122
				if (strlen(yyvsp[0].v.string) != 34) {
3123
					free(yyvsp[0].v.string);
3124
					yyerror("hex key must be 128 bits "
3125
					    "(32 hex digits) long");
3126
					YYERROR;
3127
				}
3128
3129
				if (sscanf(yyvsp[0].v.string, "0x%8x%8x%8x%8x",
3130
				    &yyval.v.key.key.data[0], &yyval.v.key.key.data[1],
3131
				    &yyval.v.key.key.data[2], &yyval.v.key.key.data[3]) != 4) {
3132
					free(yyvsp[0].v.string);
3133
					yyerror("invalid hex key");
3134
					YYERROR;
3135
				}
3136
			} else {
3137
				MD5_CTX	context;
3138
3139
				MD5Init(&context);
3140
				MD5Update(&context, (unsigned char *)yyvsp[0].v.string,
3141
				    strlen(yyvsp[0].v.string));
3142
				MD5Final((unsigned char *)yyval.v.key.key.data,
3143
				    &context);
3144
				HTONL(yyval.v.key.key.data[0]);
3145
				HTONL(yyval.v.key.key.data[1]);
3146
				HTONL(yyval.v.key.key.data[2]);
3147
				HTONL(yyval.v.key.key.data[3]);
3148
			}
3149
			free(yyvsp[0].v.string);
3150
		}
3151
break;
3152
case 86:
3153
#line 853 "parse.y"
3154
{ table->conf.check = CHECK_ICMP; }
3155
break;
3156
case 87:
3157
#line 854 "parse.y"
3158
{ table->conf.check = CHECK_TCP; }
3159
break;
3160
case 88:
3161
#line 855 "parse.y"
3162
{
3163
			table->conf.check = CHECK_TCP;
3164
			conf->sc_conf.flags |= F_TLS;
3165
			table->conf.flags |= F_TLS;
3166
		}
3167
break;
3168
case 89:
3169
#line 860 "parse.y"
3170
{
3171
			if (yyvsp[-4].v.number) {
3172
				conf->sc_conf.flags |= F_TLS;
3173
				table->conf.flags |= F_TLS;
3174
			}
3175
			table->conf.check = CHECK_HTTP_CODE;
3176
			if ((table->conf.retcode = yyvsp[0].v.number) <= 0) {
3177
				yyerror("invalid HTTP code: %d", yyvsp[0].v.number);
3178
				free(yyvsp[-3].v.string);
3179
				free(yyvsp[-2].v.string);
3180
				YYERROR;
3181
			}
3182
			if (asprintf(&table->sendbuf,
3183
			    "HEAD %s HTTP/1.%c\r\n%s\r\n",
3184
			    yyvsp[-3].v.string, strlen(yyvsp[-2].v.string) ? '1' : '0', yyvsp[-2].v.string) == -1)
3185
				fatal("asprintf");
3186
			free(yyvsp[-3].v.string);
3187
			free(yyvsp[-2].v.string);
3188
			if (table->sendbuf == NULL)
3189
				fatal("out of memory");
3190
		}
3191
break;
3192
case 90:
3193
#line 881 "parse.y"
3194
{
3195
			if (yyvsp[-3].v.number) {
3196
				conf->sc_conf.flags |= F_TLS;
3197
				table->conf.flags |= F_TLS;
3198
			}
3199
			table->conf.check = CHECK_HTTP_DIGEST;
3200
			if (asprintf(&table->sendbuf,
3201
			    "GET %s HTTP/1.%c\r\n%s\r\n",
3202
			    yyvsp[-2].v.string, strlen(yyvsp[-1].v.string) ? '1' : '0', yyvsp[-1].v.string) == -1)
3203
				fatal("asprintf");
3204
			free(yyvsp[-2].v.string);
3205
			free(yyvsp[-1].v.string);
3206
			if (table->sendbuf == NULL)
3207
				fatal("out of memory");
3208
			if (strlcpy(table->conf.digest, yyvsp[0].v.digest.digest,
3209
			    sizeof(table->conf.digest)) >=
3210
			    sizeof(table->conf.digest)) {
3211
				yyerror("digest truncated");
3212
				free(yyvsp[0].v.digest.digest);
3213
				YYERROR;
3214
			}
3215
			table->conf.digest_type = yyvsp[0].v.digest.type;
3216
			free(yyvsp[0].v.digest.digest);
3217
		}
3218
break;
3219
case 91:
3220
#line 905 "parse.y"
3221
{
3222
			table->conf.check = CHECK_SEND_EXPECT;
3223
			if (yyvsp[0].v.number) {
3224
				conf->sc_conf.flags |= F_TLS;
3225
				table->conf.flags |= F_TLS;
3226
			}
3227
			if (strlcpy(table->conf.exbuf, yyvsp[-1].v.string,
3228
			    sizeof(table->conf.exbuf))
3229
			    >= sizeof(table->conf.exbuf)) {
3230
				yyerror("yyparse: expect buffer truncated");
3231
				free(yyvsp[-1].v.string);
3232
				YYERROR;
3233
			}
3234
			translate_string(table->conf.exbuf);
3235
			free(yyvsp[-1].v.string);
3236
		}
3237
break;
3238
case 92:
3239
#line 921 "parse.y"
3240
{
3241
			table->conf.check = CHECK_SCRIPT;
3242
			if (strlcpy(table->conf.path, yyvsp[0].v.string,
3243
			    sizeof(table->conf.path)) >=
3244
			    sizeof(table->conf.path)) {
3245
				yyerror("script path truncated");
3246
				free(yyvsp[0].v.string);
3247
				YYERROR;
3248
			}
3249
			conf->sc_conf.flags |= F_SCRIPT;
3250
			free(yyvsp[0].v.string);
3251
		}
3252
break;
3253
case 93:
3254
#line 936 "parse.y"
3255
{
3256
			switch (strlen(yyvsp[0].v.string)) {
3257
			case 40:
3258
				yyval.v.digest.type = DIGEST_SHA1;
3259
				break;
3260
			case 32:
3261
				yyval.v.digest.type = DIGEST_MD5;
3262
				break;
3263
			default:
3264
				yyerror("invalid http digest");
3265
				free(yyvsp[0].v.string);
3266
				YYERROR;
3267
			}
3268
			yyval.v.digest.digest = yyvsp[0].v.string;
3269
		}
3270
break;
3271
case 94:
3272
#line 953 "parse.y"
3273
{
3274
			yyval.v.digest.digest = yyvsp[0].v.digest.digest;
3275
			yyval.v.digest.type = yyvsp[0].v.digest.type;
3276
		}
3277
break;
3278
case 95:
3279
#line 957 "parse.y"
3280
{
3281
			yyval.v.digest.digest = yyvsp[0].v.string;
3282
			yyval.v.digest.type = DIGEST_NONE;
3283
		}
3284
break;
3285
case 96:
3286
#line 963 "parse.y"
3287
{
3288
			struct protocol *p;
3289
3290
			if (!loadcfg) {
3291
				free(yyvsp[0].v.string);
3292
				YYACCEPT;
3293
			}
3294
3295
			if (strcmp(yyvsp[0].v.string, "default") == 0) {
3296
				p = &conf->sc_proto_default;
3297
			} else {
3298
				TAILQ_FOREACH(p, conf->sc_protos, entry)
3299
					if (!strcmp(p->name, yyvsp[0].v.string))
3300
						break;
3301
			}
3302
			if (p != NULL) {
3303
				yyerror("protocol %s defined twice", yyvsp[0].v.string);
3304
				free(yyvsp[0].v.string);
3305
				YYERROR;
3306
			}
3307
			if ((p = calloc(1, sizeof (*p))) == NULL)
3308
				fatal("out of memory");
3309
3310
			if (strlcpy(p->name, yyvsp[0].v.string, sizeof(p->name)) >=
3311
			    sizeof(p->name)) {
3312
				yyerror("protocol name truncated");
3313
				free(yyvsp[0].v.string);
3314
				free(p);
3315
				YYERROR;
3316
			}
3317
			free(yyvsp[0].v.string);
3318
			p->id = ++last_proto_id;
3319
			p->type = yyvsp[-2].v.number;
3320
			p->tcpflags = TCPFLAG_DEFAULT;
3321
			p->tlsflags = TLSFLAG_DEFAULT;
3322
			p->tcpbacklog = RELAY_BACKLOG;
3323
			TAILQ_INIT(&p->rules);
3324
			(void)strlcpy(p->tlsciphers, TLSCIPHERS_DEFAULT,
3325
			    sizeof(p->tlsciphers));
3326
			(void)strlcpy(p->tlsecdhcurve, TLSECDHCURVE_DEFAULT,
3327
			    sizeof(p->tlsecdhcurve));
3328
			(void)strlcpy(p->tlsdhparams, TLSDHPARAM_DEFAULT,
3329
			    sizeof(p->tlsdhparams));
3330
			if (last_proto_id == INT_MAX) {
3331
				yyerror("too many protocols defined");
3332
				free(p);
3333
				YYERROR;
3334
			}
3335
			proto = p;
3336
		}
3337
break;
3338
case 97:
3339
#line 1012 "parse.y"
3340
{
3341
			conf->sc_protocount++;
3342
3343
			if ((proto->tlsflags & TLSFLAG_VERSION) == 0) {
3344
				yyerror("invalid TLS protocol");
3345
				YYERROR;
3346
			}
3347
3348
			TAILQ_INSERT_TAIL(conf->sc_protos, proto, entry);
3349
		}
3350
break;
3351
case 107:
3352
#line 1037 "parse.y"
3353
{ proto->flags |= F_RETURN; }
3354
break;
3355
case 108:
3356
#line 1038 "parse.y"
3357
{ proto->flags |= F_RETURN; }
3358
break;
3359
case 113:
3360
#line 1047 "parse.y"
3361
{ proto->tcpflags |= TCPFLAG_SACK; }
3362
break;
3363
case 114:
3364
#line 1048 "parse.y"
3365
{ proto->tcpflags |= TCPFLAG_NSACK; }
3366
break;
3367
case 115:
3368
#line 1049 "parse.y"
3369
{ proto->tcpflags |= TCPFLAG_NODELAY; }
3370
break;
3371
case 116:
3372
#line 1050 "parse.y"
3373
{ proto->tcpflags |= TCPFLAG_NNODELAY; }
3374
break;
3375
case 117:
3376
#line 1051 "parse.y"
3377
{ /* default */ }
3378
break;
3379
case 118:
3380
#line 1052 "parse.y"
3381
{ proto->tcpflags |= TCPFLAG_NSPLICE; }
3382
break;
3383
case 119:
3384
#line 1053 "parse.y"
3385
{
3386
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > RELAY_MAX_SESSIONS) {
3387
				yyerror("invalid backlog: %d", yyvsp[0].v.number);
3388
				YYERROR;
3389
			}
3390
			proto->tcpbacklog = yyvsp[0].v.number;
3391
		}
3392
break;
3393
case 120:
3394
#line 1060 "parse.y"
3395
{
3396
			proto->tcpflags |= TCPFLAG_BUFSIZ;
3397
			if ((proto->tcpbufsiz = yyvsp[0].v.number) < 0) {
3398
				yyerror("invalid socket buffer size: %d", yyvsp[0].v.number);
3399
				YYERROR;
3400
			}
3401
		}
3402
break;
3403
case 121:
3404
#line 1067 "parse.y"
3405
{
3406
			if (yyvsp[0].v.number < 0) {
3407
				yyerror("invalid ttl: %d", yyvsp[0].v.number);
3408
				free(yyvsp[-1].v.string);
3409
				YYERROR;
3410
			}
3411
			if (strcasecmp("ttl", yyvsp[-1].v.string) == 0) {
3412
				proto->tcpflags |= TCPFLAG_IPTTL;
3413
				proto->tcpipttl = yyvsp[0].v.number;
3414
			} else if (strcasecmp("minttl", yyvsp[-1].v.string) == 0) {
3415
				proto->tcpflags |= TCPFLAG_IPMINTTL;
3416
				proto->tcpipminttl = yyvsp[0].v.number;
3417
			} else {
3418
				yyerror("invalid TCP/IP flag: %s", yyvsp[-1].v.string);
3419
				free(yyvsp[-1].v.string);
3420
				YYERROR;
3421
			}
3422
			free(yyvsp[-1].v.string);
3423
		}
3424
break;
3425
case 124:
3426
#line 1092 "parse.y"
3427
{ proto->tickets = 1; }
3428
break;
3429
case 125:
3430
#line 1093 "parse.y"
3431
{ proto->tickets = 0; }
3432
break;
3433
case 126:
3434
#line 1094 "parse.y"
3435
{
3436
			if (strlcpy(proto->tlsciphers, yyvsp[0].v.string,
3437
			    sizeof(proto->tlsciphers)) >=
3438
			    sizeof(proto->tlsciphers)) {
3439
				yyerror("tlsciphers truncated");
3440
				free(yyvsp[0].v.string);
3441
				YYERROR;
3442
			}
3443
			free(yyvsp[0].v.string);
3444
		}
3445
break;
3446
case 127:
3447
#line 1104 "parse.y"
3448
{
3449
			(void)strlcpy(proto->tlsdhparams, "none",
3450
			    sizeof(proto->tlsdhparams));
3451
		}
3452
break;
3453
case 128:
3454
#line 1108 "parse.y"
3455
{
3456
			(void)strlcpy(proto->tlsdhparams, "auto",
3457
			    sizeof(proto->tlsdhparams));
3458
		}
3459
break;
3460
case 129:
3461
#line 1112 "parse.y"
3462
{
3463
			struct tls_config	*tls_cfg;
3464
			if ((tls_cfg = tls_config_new()) == NULL) {
3465
				yyerror("tls_config_new failed");
3466
				free(yyvsp[0].v.string);
3467
				YYERROR;
3468
			}
3469
			if (tls_config_set_dheparams(tls_cfg, yyvsp[0].v.string) != 0) {
3470
				yyerror("tls edh params %s: %s", yyvsp[0].v.string,
3471
				    tls_config_error(tls_cfg));
3472
				tls_config_free(tls_cfg);
3473
				free(yyvsp[0].v.string);
3474
				YYERROR;
3475
			}
3476
			tls_config_free(tls_cfg);
3477
			if (strlcpy(proto->tlsdhparams, yyvsp[0].v.string,
3478
			    sizeof(proto->tlsdhparams)) >=
3479
			    sizeof(proto->tlsdhparams)) {
3480
				yyerror("tls edh truncated");
3481
				free(yyvsp[0].v.string);
3482
				YYERROR;
3483
			}
3484
			free(yyvsp[0].v.string);
3485
		}
3486
break;
3487
case 130:
3488
#line 1136 "parse.y"
3489
{
3490
			(void)strlcpy(proto->tlsecdhcurve, "none",
3491
			    sizeof(proto->tlsecdhcurve));
3492
		}
3493
break;
3494
case 131:
3495
#line 1140 "parse.y"
3496
{
3497
			(void)strlcpy(proto->tlsecdhcurve, "auto",
3498
			    sizeof(proto->tlsecdhcurve));
3499
		}
3500
break;
3501
case 132:
3502
#line 1144 "parse.y"
3503
{
3504
			struct tls_config	*tls_cfg;
3505
			if ((tls_cfg = tls_config_new()) == NULL) {
3506
				yyerror("tls_config_new failed");
3507
				free(yyvsp[0].v.string);
3508
				YYERROR;
3509
			}
3510
			if (tls_config_set_ecdhecurve(tls_cfg, yyvsp[0].v.string) != 0) {
3511
				yyerror("tls ecdh curve %s: %s", yyvsp[0].v.string,
3512
				    tls_config_error(tls_cfg));
3513
				tls_config_free(tls_cfg);
3514
				free(yyvsp[0].v.string);
3515
				YYERROR;
3516
			}
3517
			tls_config_free(tls_cfg);
3518
			if (strlcpy(proto->tlsecdhcurve, yyvsp[0].v.string,
3519
			    sizeof(proto->tlsecdhcurve)) >=
3520
			    sizeof(proto->tlsecdhcurve)) {
3521
				yyerror("tls ecdh truncated");
3522
				free(yyvsp[0].v.string);
3523
				YYERROR;
3524
			}
3525
			free(yyvsp[0].v.string);
3526
		}
3527
break;
3528
case 133:
3529
#line 1168 "parse.y"
3530
{
3531
			if (strlcpy(proto->tlsca, yyvsp[0].v.string,
3532
			    sizeof(proto->tlsca)) >=
3533
			    sizeof(proto->tlsca)) {
3534
				yyerror("tlsca truncated");
3535
				free(yyvsp[0].v.string);
3536
				YYERROR;
3537
			}
3538
			free(yyvsp[0].v.string);
3539
		}
3540
break;
3541
case 134:
3542
#line 1178 "parse.y"
3543
{
3544
			if (strlcpy(proto->tlscakey, yyvsp[-2].v.string,
3545
			    sizeof(proto->tlscakey)) >=
3546
			    sizeof(proto->tlscakey)) {
3547
				yyerror("tlscakey truncated");
3548
				free(yyvsp[-2].v.string);
3549
				free(yyvsp[0].v.string);
3550
				YYERROR;
3551
			}
3552
			if ((proto->tlscapass = strdup(yyvsp[0].v.string)) == NULL) {
3553
				yyerror("tlscapass");
3554
				free(yyvsp[-2].v.string);
3555
				free(yyvsp[0].v.string);
3556
				YYERROR;
3557
			}
3558
			free(yyvsp[-2].v.string);
3559
			free(yyvsp[0].v.string);
3560
		}
3561
break;
3562
case 135:
3563
#line 1196 "parse.y"
3564
{
3565
			if (strlcpy(proto->tlscacert, yyvsp[0].v.string,
3566
			    sizeof(proto->tlscacert)) >=
3567
			    sizeof(proto->tlscacert)) {
3568
				yyerror("tlscacert truncated");
3569
				free(yyvsp[0].v.string);
3570
				YYERROR;
3571
			}
3572
			free(yyvsp[0].v.string);
3573
		}
3574
break;
3575
case 136:
3576
#line 1206 "parse.y"
3577
{ proto->tlsflags &= ~(yyvsp[0].v.number); }
3578
break;
3579
case 137:
3580
#line 1207 "parse.y"
3581
{ proto->tlsflags |= yyvsp[0].v.number; }
3582
break;
3583
case 138:
3584
#line 1210 "parse.y"
3585
{
3586
			if (strcmp("sslv3", yyvsp[0].v.string) == 0)
3587
				yyval.v.number = TLSFLAG_SSLV3;
3588
			else if (strcmp("tlsv1", yyvsp[0].v.string) == 0)
3589
				yyval.v.number = TLSFLAG_TLSV1;
3590
			else if (strcmp("tlsv1.0", yyvsp[0].v.string) == 0)
3591
				yyval.v.number = TLSFLAG_TLSV1_0;
3592
			else if (strcmp("tlsv1.1", yyvsp[0].v.string) == 0)
3593
				yyval.v.number = TLSFLAG_TLSV1_1;
3594
			else if (strcmp("tlsv1.2", yyvsp[0].v.string) == 0)
3595
				yyval.v.number = TLSFLAG_TLSV1_2;
3596
			else if (strcmp("cipher-server-preference", yyvsp[0].v.string) == 0)
3597
				yyval.v.number = TLSFLAG_CIPHER_SERVER_PREF;
3598
			else if (strcmp("client-renegotiation", yyvsp[0].v.string) == 0)
3599
				yyval.v.number = TLSFLAG_CLIENT_RENEG;
3600
			else {
3601
				yyerror("invalid TLS flag: %s", yyvsp[0].v.string);
3602
				free(yyvsp[0].v.string);
3603
				YYERROR;
3604
			}
3605
			free(yyvsp[0].v.string);
3606
		}
3607
break;
3608
case 139:
3609
#line 1234 "parse.y"
3610
{
3611
			if ((rule = calloc(1, sizeof(*rule))) == NULL)
3612
				fatal("out of memory");
3613
3614
			rule->rule_action = yyvsp[-5].v.number;
3615
			rule->rule_proto = proto->type;
3616
			rule->rule_dir = yyvsp[-4].v.dir;
3617
			rule->rule_flags |= yyvsp[-3].v.number;
3618
			rule->rule_af = yyvsp[-2].v.number;
3619
3620
			rulefile = NULL;
3621
		}
3622
break;
3623
case 140:
3624
#line 1245 "parse.y"
3625
{
3626
			if (rule_add(proto, rule, rulefile) == -1) {
3627
				if (rulefile == NULL) {
3628
					yyerror("failed to load rule");
3629
				} else {
3630
					yyerror("failed to load rules from %s",
3631
					    rulefile);
3632
					free(rulefile);
3633
				}
3634
				rule_free(rule);
3635
				free(rule);
3636
				YYERROR;
3637
			}
3638
			if (rulefile)
3639
				free(rulefile);
3640
			rulefile = NULL;
3641
			rule = NULL;
3642
			keytype = KEY_TYPE_NONE;
3643
		}
3644
break;
3645
case 141:
3646
#line 1266 "parse.y"
3647
{ yyval.v.number = RULE_ACTION_PASS; }
3648
break;
3649
case 142:
3650
#line 1267 "parse.y"
3651
{ yyval.v.number = RULE_ACTION_BLOCK; }
3652
break;
3653
case 143:
3654
#line 1268 "parse.y"
3655
{ yyval.v.number = RULE_ACTION_MATCH; }
3656
break;
3657
case 144:
3658
#line 1271 "parse.y"
3659
{
3660
			yyval.v.dir = dir = RELAY_DIR_REQUEST;
3661
		}
3662
break;
3663
case 145:
3664
#line 1274 "parse.y"
3665
{
3666
			yyval.v.dir = dir = RELAY_DIR_REQUEST;
3667
		}
3668
break;
3669
case 146:
3670
#line 1277 "parse.y"
3671
{
3672
			yyval.v.dir = dir = RELAY_DIR_RESPONSE;
3673
		}
3674
break;
3675
case 147:
3676
#line 1282 "parse.y"
3677
{ yyval.v.number = 0; }
3678
break;
3679
case 148:
3680
#line 1283 "parse.y"
3681
{ yyval.v.number = RULE_FLAG_QUICK; }
3682
break;
3683
case 149:
3684
#line 1286 "parse.y"
3685
{ yyval.v.number = AF_UNSPEC; }
3686
break;
3687
case 150:
3688
#line 1287 "parse.y"
3689
{ yyval.v.number = AF_INET6; }
3690
break;
3691
case 151:
3692
#line 1288 "parse.y"
3693
{ yyval.v.number = AF_INET; }
3694
break;
3695
case 158:
3696
#line 1305 "parse.y"
3697
{
3698
			u_int	id;
3699
			if ((id = relay_httpmethod_byname(yyvsp[0].v.string)) ==
3700
			    HTTP_METHOD_NONE) {
3701
				yyerror("unknown HTTP method currently not "
3702
				    "supported");
3703
				free(yyvsp[0].v.string);
3704
				YYERROR;
3705
			}
3706
			rule->rule_method = id;
3707
			free(yyvsp[0].v.string);
3708
		}
3709
break;
3710
case 159:
3711
#line 1317 "parse.y"
3712
{
3713
			keytype = KEY_TYPE_COOKIE;
3714
			rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.string);
3715
			rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;
3716
			rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL) ?
3717
			    strdup(yyvsp[0].v.string) : strdup("*"));
3718
			if (rule->rule_kv[keytype].kv_key == NULL ||
3719
			    rule->rule_kv[keytype].kv_value == NULL)
3720
				fatal("out of memory");
3721
			free(yyvsp[-1].v.string);
3722
			if (yyvsp[0].v.string)
3723
				free(yyvsp[0].v.string);
3724
			rule->rule_kv[keytype].kv_type = keytype;
3725
		}
3726
break;
3727
case 160:
3728
#line 1331 "parse.y"
3729
{
3730
			keytype = KEY_TYPE_COOKIE;
3731
			rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;
3732
			rule->rule_kv[keytype].kv_type = keytype;
3733
		}
3734
break;
3735
case 161:
3736
#line 1336 "parse.y"
3737
{
3738
			keytype = KEY_TYPE_HEADER;
3739
			memset(&rule->rule_kv[keytype], 0,
3740
			    sizeof(rule->rule_kv[keytype]));
3741
			rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;
3742
			rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.string);
3743
			rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL) ?
3744
			    strdup(yyvsp[0].v.string) : strdup("*"));
3745
			if (rule->rule_kv[keytype].kv_key == NULL ||
3746
			    rule->rule_kv[keytype].kv_value == NULL)
3747
				fatal("out of memory");
3748
			free(yyvsp[-1].v.string);
3749
			if (yyvsp[0].v.string)
3750
				free(yyvsp[0].v.string);
3751
			rule->rule_kv[keytype].kv_type = keytype;
3752
		}
3753
break;
3754
case 162:
3755
#line 1352 "parse.y"
3756
{
3757
			keytype = KEY_TYPE_HEADER;
3758
			rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;
3759
			rule->rule_kv[keytype].kv_type = keytype;
3760
		}
3761
break;
3762
case 163:
3763
#line 1357 "parse.y"
3764
{
3765
			keytype = KEY_TYPE_PATH;
3766
			rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;
3767
			rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.string);
3768
			rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL) ?
3769
			    strdup(yyvsp[0].v.string) : strdup("*"));
3770
			if (rule->rule_kv[keytype].kv_key == NULL ||
3771
			    rule->rule_kv[keytype].kv_value == NULL)
3772
				fatal("out of memory");
3773
			free(yyvsp[-1].v.string);
3774
			if (yyvsp[0].v.string)
3775
				free(yyvsp[0].v.string);
3776
			rule->rule_kv[keytype].kv_type = keytype;
3777
		}
3778
break;
3779
case 164:
3780
#line 1371 "parse.y"
3781
{
3782
			keytype = KEY_TYPE_PATH;
3783
			rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;
3784
			rule->rule_kv[keytype].kv_type = keytype;
3785
		}
3786
break;
3787
case 165:
3788
#line 1376 "parse.y"
3789
{
3790
			switch (yyvsp[-2].v.number) {
3791
			case KEY_OPTION_APPEND:
3792
			case KEY_OPTION_SET:
3793
			case KEY_OPTION_REMOVE:
3794
				yyerror("combining query type and the given "
3795
				    "option is not supported");
3796
				free(yyvsp[-1].v.string);
3797
				if (yyvsp[0].v.string)
3798
					free(yyvsp[0].v.string);
3799
				YYERROR;
3800
				break;
3801
			}
3802
			keytype = KEY_TYPE_QUERY;
3803
			rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;
3804
			rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.string);
3805
			rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL) ?
3806
			    strdup(yyvsp[0].v.string) : strdup("*"));
3807
			if (rule->rule_kv[keytype].kv_key == NULL ||
3808
			    rule->rule_kv[keytype].kv_value == NULL)
3809
				fatal("out of memory");
3810
			free(yyvsp[-1].v.string);
3811
			if (yyvsp[0].v.string)
3812
				free(yyvsp[0].v.string);
3813
			rule->rule_kv[keytype].kv_type = keytype;
3814
		}
3815
break;
3816
case 166:
3817
#line 1402 "parse.y"
3818
{
3819
			switch (yyvsp[0].v.number) {
3820
			case KEY_OPTION_APPEND:
3821
			case KEY_OPTION_SET:
3822
			case KEY_OPTION_REMOVE:
3823
				yyerror("combining query type and the given "
3824
				    "option is not supported");
3825
				YYERROR;
3826
				break;
3827
			}
3828
			keytype = KEY_TYPE_QUERY;
3829
			rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;
3830
			rule->rule_kv[keytype].kv_type = keytype;
3831
		}
3832
break;
3833
case 167:
3834
#line 1416 "parse.y"
3835
{
3836
			switch (yyvsp[-2].v.number) {
3837
			case KEY_OPTION_APPEND:
3838
			case KEY_OPTION_SET:
3839
			case KEY_OPTION_REMOVE:
3840
				yyerror("combining url type and the given "
3841
				"option is not supported");
3842
				free(yyvsp[-1].v.digest.digest);
3843
				free(yyvsp[0].v.string);
3844
				YYERROR;
3845
				break;
3846
			}
3847
			keytype = KEY_TYPE_URL;
3848
			rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;
3849
			rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.digest.digest);
3850
			rule->rule_kv[keytype].kv_digest = yyvsp[-1].v.digest.type;
3851
			rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL) ?
3852
			    strdup(yyvsp[0].v.string) : strdup("*"));
3853
			if (rule->rule_kv[keytype].kv_key == NULL ||
3854
			    rule->rule_kv[keytype].kv_value == NULL)
3855
				fatal("out of memory");
3856
			free(yyvsp[-1].v.digest.digest);
3857
			if (yyvsp[0].v.string)
3858
				free(yyvsp[0].v.string);
3859
			rule->rule_kv[keytype].kv_type = keytype;
3860
		}
3861
break;
3862
case 168:
3863
#line 1442 "parse.y"
3864
{
3865
			switch (yyvsp[0].v.number) {
3866
			case KEY_OPTION_APPEND:
3867
			case KEY_OPTION_SET:
3868
			case KEY_OPTION_REMOVE:
3869
				yyerror("combining url type and the given "
3870
				    "option is not supported");
3871
				YYERROR;
3872
				break;
3873
			}
3874
			keytype = KEY_TYPE_URL;
3875
			rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;
3876
			rule->rule_kv[keytype].kv_type = keytype;
3877
		}
3878
break;
3879
case 169:
3880
#line 1456 "parse.y"
3881
{
3882
			if (table_findbyname(conf, yyvsp[0].v.string) == NULL) {
3883
				yyerror("undefined forward table");
3884
				free(yyvsp[0].v.string);
3885
				YYERROR;
3886
			}
3887
			if (strlcpy(rule->rule_tablename, yyvsp[0].v.string,
3888
			    sizeof(rule->rule_tablename)) >=
3889
			    sizeof(rule->rule_tablename)) {
3890
				yyerror("invalid forward table name");
3891
				free(yyvsp[0].v.string);
3892
				YYERROR;
3893
			}
3894
			free(yyvsp[0].v.string);
3895
		}
3896
break;
3897
case 170:
3898
#line 1471 "parse.y"
3899
{
3900
			tag = tag_name2id(yyvsp[0].v.string);
3901
			if (rule->rule_tag) {
3902
				yyerror("tag already defined");
3903
				free(yyvsp[0].v.string);
3904
				rule_free(rule);
3905
				free(rule);
3906
				YYERROR;
3907
			}
3908
			if (tag == 0) {
3909
				yyerror("invalid tag");
3910
				free(yyvsp[0].v.string);
3911
				rule_free(rule);
3912
				free(rule);
3913
				YYERROR;
3914
			}
3915
			rule->rule_tag = tag;
3916
			if (strlcpy(rule->rule_tagname, yyvsp[0].v.string,
3917
			    sizeof(rule->rule_tagname)) >=
3918
			    sizeof(rule->rule_tagname)) {
3919
				yyerror("tag truncated");
3920
				free(yyvsp[0].v.string);
3921
				rule_free(rule);
3922
				free(rule);
3923
				YYERROR;
3924
			}
3925
			free(yyvsp[0].v.string);
3926
		}
3927
break;
3928
case 171:
3929
#line 1499 "parse.y"
3930
{
3931
			if (tag == 0) {
3932
				yyerror("no tag defined");
3933
				YYERROR;
3934
			}
3935
			rule->rule_tag = -1;
3936
			memset(rule->rule_tagname, 0,
3937
			    sizeof(rule->rule_tagname));
3938
		}
3939
break;
3940
case 172:
3941
#line 1508 "parse.y"
3942
{
3943
			tagged = tag_name2id(yyvsp[0].v.string);
3944
			if (rule->rule_tagged) {
3945
				yyerror("tagged already defined");
3946
				free(yyvsp[0].v.string);
3947
				rule_free(rule);
3948
				free(rule);
3949
				YYERROR;
3950
			}
3951
			if (tagged == 0) {
3952
				yyerror("invalid tag");
3953
				free(yyvsp[0].v.string);
3954
				rule_free(rule);
3955
				free(rule);
3956
				YYERROR;
3957
			}
3958
			rule->rule_tagged = tagged;
3959
			if (strlcpy(rule->rule_taggedname, yyvsp[0].v.string,
3960
			    sizeof(rule->rule_taggedname)) >=
3961
			    sizeof(rule->rule_taggedname)) {
3962
				yyerror("tagged truncated");
3963
				free(yyvsp[0].v.string);
3964
				rule_free(rule);
3965
				free(rule);
3966
				YYERROR;
3967
			}
3968
			free(yyvsp[0].v.string);
3969
		}
3970
break;
3971
case 173:
3972
#line 1536 "parse.y"
3973
{
3974
			label = label_name2id(yyvsp[0].v.string);
3975
			if (rule->rule_label) {
3976
				yyerror("label already defined");
3977
				free(yyvsp[0].v.string);
3978
				rule_free(rule);
3979
				free(rule);
3980
				YYERROR;
3981
			}
3982
			if (label == 0) {
3983
				yyerror("invalid label");
3984
				free(yyvsp[0].v.string);
3985
				rule_free(rule);
3986
				free(rule);
3987
				YYERROR;
3988
			}
3989
			rule->rule_label = label;
3990
			if (strlcpy(rule->rule_labelname, yyvsp[0].v.string,
3991
			    sizeof(rule->rule_labelname)) >=
3992
			    sizeof(rule->rule_labelname)) {
3993
				yyerror("label truncated");
3994
				free(yyvsp[0].v.string);
3995
				rule_free(rule);
3996
				free(rule);
3997
				YYERROR;
3998
			}
3999
			free(yyvsp[0].v.string);
4000
		}
4001
break;
4002
case 174:
4003
#line 1564 "parse.y"
4004
{
4005
			if (label == 0) {
4006
				yyerror("no label defined");
4007
				YYERROR;
4008
			}
4009
			rule->rule_label = -1;
4010
			memset(rule->rule_labelname, 0,
4011
			    sizeof(rule->rule_labelname));
4012
		}
4013
break;
4014
case 175:
4015
#line 1573 "parse.y"
4016
{
4017
			if (rulefile != NULL) {
4018
				yyerror("only one file per rule supported");
4019
				free(yyvsp[-1].v.string);
4020
				free(yyvsp[0].v.string);
4021
				rule_free(rule);
4022
				free(rule);
4023
				YYERROR;
4024
			}
4025
			if (yyvsp[0].v.string) {
4026
				if ((rule->rule_kv[keytype].kv_value =
4027
				    strdup(yyvsp[0].v.string)) == NULL)
4028
					fatal("out of memory");
4029
				free(yyvsp[0].v.string);
4030
			} else
4031
				rule->rule_kv[keytype].kv_value = NULL;
4032
			rulefile = yyvsp[-1].v.string;
4033
		}
4034
break;
4035
case 176:
4036
#line 1593 "parse.y"
4037
{ yyval.v.string = NULL; }
4038
break;
4039
case 177:
4040
#line 1594 "parse.y"
4041
{ yyval.v.string = yyvsp[0].v.string; }
4042
break;
4043
case 178:
4044
#line 1597 "parse.y"
4045
{ yyval.v.number = KEY_OPTION_NONE; }
4046
break;
4047
case 179:
4048
#line 1598 "parse.y"
4049
{ yyval.v.number = KEY_OPTION_APPEND; }
4050
break;
4051
case 180:
4052
#line 1599 "parse.y"
4053
{ yyval.v.number = KEY_OPTION_SET; }
4054
break;
4055
case 181:
4056
#line 1600 "parse.y"
4057
{ yyval.v.number = KEY_OPTION_REMOVE; }
4058
break;
4059
case 182:
4060
#line 1601 "parse.y"
4061
{ yyval.v.number = KEY_OPTION_HASH; }
4062
break;
4063
case 183:
4064
#line 1602 "parse.y"
4065
{ yyval.v.number = KEY_OPTION_LOG; }
4066
break;
4067
case 184:
4068
#line 1605 "parse.y"
4069
{
4070
			struct relay *r;
4071
4072
			if (!loadcfg) {
4073
				free(yyvsp[0].v.string);
4074
				YYACCEPT;
4075
			}
4076
4077
			TAILQ_FOREACH(r, conf->sc_relays, rl_entry)
4078
				if (!strcmp(r->rl_conf.name, yyvsp[0].v.string))
4079
					break;
4080
			if (r != NULL) {
4081
				yyerror("relay %s defined twice", yyvsp[0].v.string);
4082
				free(yyvsp[0].v.string);
4083
				YYERROR;
4084
			}
4085
			TAILQ_INIT(&relays);
4086
4087
			if ((r = calloc(1, sizeof (*r))) == NULL)
4088
				fatal("out of memory");
4089
4090
			if (strlcpy(r->rl_conf.name, yyvsp[0].v.string,
4091
			    sizeof(r->rl_conf.name)) >=
4092
			    sizeof(r->rl_conf.name)) {
4093
				yyerror("relay name truncated");
4094
				free(yyvsp[0].v.string);
4095
				free(r);
4096
				YYERROR;
4097
			}
4098
			free(yyvsp[0].v.string);
4099
			if (relay_id(r) == -1) {
4100
				yyerror("too many relays defined");
4101
				free(r);
4102
				YYERROR;
4103
			}
4104
			r->rl_conf.timeout.tv_sec = RELAY_TIMEOUT;
4105
			r->rl_proto = NULL;
4106
			r->rl_conf.proto = EMPTY_ID;
4107
			r->rl_conf.dstretry = 0;
4108
			TAILQ_INIT(&r->rl_tables);
4109
			if (last_relay_id == INT_MAX) {
4110
				yyerror("too many relays defined");
4111
				free(r);
4112
				YYERROR;
4113
			}
4114
			dstmode = RELAY_DSTMODE_DEFAULT;
4115
			rlay = r;
4116
		}
4117
break;
4118
case 185:
4119
#line 1652 "parse.y"
4120
{
4121
			struct relay	*r;
4122
4123
			if (rlay->rl_conf.ss.ss_family == AF_UNSPEC) {
4124
				yyerror("relay %s has no listener",
4125
				    rlay->rl_conf.name);
4126
				YYERROR;
4127
			}
4128
			if ((rlay->rl_conf.flags & (F_NATLOOK|F_DIVERT)) ==
4129
			    (F_NATLOOK|F_DIVERT)) {
4130
				yyerror("relay %s with conflicting nat lookup "
4131
				    "and peer options", rlay->rl_conf.name);
4132
				YYERROR;
4133
			}
4134
			if ((rlay->rl_conf.flags & (F_NATLOOK|F_DIVERT)) == 0 &&
4135
			    rlay->rl_conf.dstss.ss_family == AF_UNSPEC &&
4136
			    TAILQ_EMPTY(&rlay->rl_tables)) {
4137
				yyerror("relay %s has no target, rdr, "
4138
				    "or table", rlay->rl_conf.name);
4139
				YYERROR;
4140
			}
4141
			if (rlay->rl_conf.proto == EMPTY_ID) {
4142
				rlay->rl_proto = &conf->sc_proto_default;
4143
				rlay->rl_conf.proto = conf->sc_proto_default.id;
4144
			}
4145
			if (relay_load_certfiles(rlay) == -1) {
4146
				yyerror("cannot load certificates for relay %s",
4147
				    rlay->rl_conf.name);
4148
				YYERROR;
4149
			}
4150
			conf->sc_relaycount++;
4151
			SPLAY_INIT(&rlay->rl_sessions);
4152
			TAILQ_INSERT_TAIL(conf->sc_relays, rlay, rl_entry);
4153
4154
			tableport = 0;
4155
4156
			while ((r = TAILQ_FIRST(&relays)) != NULL) {
4157
				TAILQ_REMOVE(&relays, r, rl_entry);
4158
				if (relay_inherit(rlay, r) == NULL) {
4159
					YYERROR;
4160
				}
4161
			}
4162
			rlay = NULL;
4163
		}
4164
break;
4165
case 188:
4166
#line 1702 "parse.y"
4167
{
4168
			struct addresslist	 al;
4169
			struct address		*h;
4170
			struct relay		*r;
4171
4172
			if (rlay->rl_conf.ss.ss_family != AF_UNSPEC) {
4173
				if ((r = calloc(1, sizeof (*r))) == NULL)
4174
					fatal("out of memory");
4175
				TAILQ_INSERT_TAIL(&relays, r, rl_entry);
4176
			} else
4177
				r = rlay;
4178
			if (yyvsp[-1].v.port.op != PF_OP_EQ) {
4179
				yyerror("invalid port");
4180
				free(yyvsp[-2].v.string);
4181
				YYERROR;
4182
			}
4183
4184
			TAILQ_INIT(&al);
4185
			if (host(yyvsp[-2].v.string, &al, 1, &yyvsp[-1].v.port, NULL, -1) <= 0) {
4186
				yyerror("invalid listen ip: %s", yyvsp[-2].v.string);
4187
				free(yyvsp[-2].v.string);
4188
				YYERROR;
4189
			}
4190
			free(yyvsp[-2].v.string);
4191
			h = TAILQ_FIRST(&al);
4192
			bcopy(&h->ss, &r->rl_conf.ss, sizeof(r->rl_conf.ss));
4193
			r->rl_conf.port = h->port.val[0];
4194
			if (yyvsp[0].v.number) {
4195
				r->rl_conf.flags |= F_TLS;
4196
				conf->sc_conf.flags |= F_TLS;
4197
			}
4198
			tableport = h->port.val[0];
4199
			host_free(&al);
4200
		}
4201
break;
4202
case 189:
4203
#line 1736 "parse.y"
4204
{
4205
			rlay->rl_conf.fwdmode = yyvsp[-4].v.number;
4206
			if (yyvsp[-4].v.number == FWD_ROUTE) {
4207
				yyerror("no route for relays");
4208
				YYERROR;
4209
			}
4210
			if (yyvsp[-3].v.number) {
4211
				rlay->rl_conf.flags |= F_TLSCLIENT;
4212
				conf->sc_conf.flags |= F_TLSCLIENT;
4213
			}
4214
		}
4215
break;
4216
case 190:
4217
#line 1747 "parse.y"
4218
{
4219
			if ((rlay->rl_conf.timeout.tv_sec = yyvsp[0].v.number) < 0) {
4220
				yyerror("invalid timeout: %lld", yyvsp[0].v.number);
4221
				YYERROR;
4222
			}
4223
			if (rlay->rl_conf.timeout.tv_sec > INT_MAX) {
4224
				yyerror("timeout too large: %lld", yyvsp[0].v.number);
4225
				YYERROR;
4226
			}
4227
		}
4228
break;
4229
case 191:
4230
#line 1757 "parse.y"
4231
{
4232
			struct protocol *p;
4233
4234
			TAILQ_FOREACH(p, conf->sc_protos, entry)
4235
				if (!strcmp(p->name, yyvsp[0].v.string))
4236
					break;
4237
			if (p == NULL) {
4238
				yyerror("no such protocol: %s", yyvsp[0].v.string);
4239
				free(yyvsp[0].v.string);
4240
				YYERROR;
4241
			}
4242
			p->flags |= F_USED;
4243
			rlay->rl_conf.proto = p->id;
4244
			rlay->rl_proto = p;
4245
			free(yyvsp[0].v.string);
4246
		}
4247
break;
4248
case 192:
4249
#line 1773 "parse.y"
4250
{ rlay->rl_conf.flags |= F_DISABLE; }
4251
break;
4252
case 194:
4253
#line 1777 "parse.y"
4254
{
4255
			struct addresslist	 al;
4256
			struct address		*h;
4257
4258
			if (rlay->rl_conf.dstss.ss_family != AF_UNSPEC) {
4259
				yyerror("relay %s target or redirection "
4260
				    "already specified", rlay->rl_conf.name);
4261
				free(yyvsp[-2].v.string);
4262
				YYERROR;
4263
			}
4264
			if (yyvsp[-1].v.port.op != PF_OP_EQ) {
4265
				yyerror("invalid port");
4266
				free(yyvsp[-2].v.string);
4267
				YYERROR;
4268
			}
4269
4270
			TAILQ_INIT(&al);
4271
			if (host(yyvsp[-2].v.string, &al, 1, &yyvsp[-1].v.port, NULL, -1) <= 0) {
4272
				yyerror("invalid listen ip: %s", yyvsp[-2].v.string);
4273
				free(yyvsp[-2].v.string);
4274
				YYERROR;
4275
			}
4276
			free(yyvsp[-2].v.string);
4277
			h = TAILQ_FIRST(&al);
4278
			bcopy(&h->ss, &rlay->rl_conf.dstss,
4279
			    sizeof(rlay->rl_conf.dstss));
4280
			rlay->rl_conf.dstport = h->port.val[0];
4281
			rlay->rl_conf.dstretry = yyvsp[0].v.number;
4282
			host_free(&al);
4283
		}
4284
break;
4285
case 195:
4286
#line 1807 "parse.y"
4287
{
4288
			conf->sc_conf.flags |= F_NEEDPF;
4289
			rlay->rl_conf.flags |= F_NATLOOK;
4290
			rlay->rl_conf.dstretry = yyvsp[0].v.number;
4291
		}
4292
break;
4293
case 196:
4294
#line 1812 "parse.y"
4295
{
4296
			conf->sc_conf.flags |= F_NEEDPF;
4297
			rlay->rl_conf.flags |= F_DIVERT;
4298
			rlay->rl_conf.dstretry = yyvsp[0].v.number;
4299
		}
4300
break;
4301
case 197:
4302
#line 1817 "parse.y"
4303
{
4304
			struct relay_table	*rlt;
4305
4306
			if ((rlt = calloc(1, sizeof(*rlt))) == NULL) {
4307
				yyerror("failed to allocate table reference");
4308
				YYERROR;
4309
			}
4310
4311
			rlt->rlt_table = yyvsp[0].v.table;
4312
			rlt->rlt_table->conf.flags |= F_USED;
4313
			rlt->rlt_mode = dstmode;
4314
			rlt->rlt_flags = F_USED;
4315
			if (!TAILQ_EMPTY(&rlay->rl_tables))
4316
				rlt->rlt_flags |= F_BACKUP;
4317
4318
			if (hashkey != NULL &&
4319
			    (rlay->rl_conf.flags & F_HASHKEY) == 0) {
4320
				memcpy(&rlay->rl_conf.hashkey,
4321
				    hashkey, sizeof(rlay->rl_conf.hashkey));
4322
				rlay->rl_conf.flags |= F_HASHKEY;
4323
			}
4324
			free(hashkey);
4325
			hashkey = NULL;
4326
4327
			TAILQ_INSERT_TAIL(&rlay->rl_tables, rlt, rlt_entry);
4328
		}
4329
break;
4330
case 198:
4331
#line 1845 "parse.y"
4332
{ yyval.v.number = RELAY_DSTMODE_DEFAULT; }
4333
break;
4334
case 199:
4335
#line 1846 "parse.y"
4336
{ yyval.v.number = RELAY_DSTMODE_LOADBALANCE; }
4337
break;
4338
case 200:
4339
#line 1847 "parse.y"
4340
{ yyval.v.number = RELAY_DSTMODE_ROUNDROBIN; }
4341
break;
4342
case 201:
4343
#line 1848 "parse.y"
4344
{ yyval.v.number = RELAY_DSTMODE_HASH; }
4345
break;
4346
case 202:
4347
#line 1849 "parse.y"
4348
{ yyval.v.number = RELAY_DSTMODE_LEASTSTATES; }
4349
break;
4350
case 203:
4351
#line 1850 "parse.y"
4352
{ yyval.v.number = RELAY_DSTMODE_SRCHASH; }
4353
break;
4354
case 204:
4355
#line 1851 "parse.y"
4356
{ yyval.v.number = RELAY_DSTMODE_RANDOM; }
4357
break;
4358
case 205:
4359
#line 1854 "parse.y"
4360
{
4361
			struct router *rt = NULL;
4362
4363
			if (!loadcfg) {
4364
				free(yyvsp[0].v.string);
4365
				YYACCEPT;
4366
			}
4367
4368
			conf->sc_conf.flags |= F_NEEDRT;
4369
			TAILQ_FOREACH(rt, conf->sc_rts, rt_entry)
4370
				if (!strcmp(rt->rt_conf.name, yyvsp[0].v.string))
4371
					break;
4372
			if (rt != NULL) {
4373
				yyerror("router %s defined twice", yyvsp[0].v.string);
4374
				free(yyvsp[0].v.string);
4375
				YYERROR;
4376
			}
4377
4378
			if ((rt = calloc(1, sizeof (*rt))) == NULL)
4379
				fatal("out of memory");
4380
4381
			if (strlcpy(rt->rt_conf.name, yyvsp[0].v.string,
4382
			    sizeof(rt->rt_conf.name)) >=
4383
			    sizeof(rt->rt_conf.name)) {
4384
				yyerror("router name truncated");
4385
				free(rt);
4386
				YYERROR;
4387
			}
4388
			free(yyvsp[0].v.string);
4389
			rt->rt_conf.id = ++last_rt_id;
4390
			if (last_rt_id == INT_MAX) {
4391
				yyerror("too many routers defined");
4392
				free(rt);
4393
				YYERROR;
4394
			}
4395
			TAILQ_INIT(&rt->rt_netroutes);
4396
			router = rt;
4397
4398
			tableport = -1;
4399
		}
4400
break;
4401
case 206:
4402
#line 1893 "parse.y"
4403
{
4404
			if (!router->rt_conf.nroutes) {
4405
				yyerror("router %s without routes",
4406
				    router->rt_conf.name);
4407
				free(router);
4408
				router = NULL;
4409
				YYERROR;
4410
			}
4411
4412
			conf->sc_routercount++;
4413
			TAILQ_INSERT_TAIL(conf->sc_rts, router, rt_entry);
4414
			router = NULL;
4415
4416
			tableport = 0;
4417
		}
4418
break;
4419
case 209:
4420
#line 1914 "parse.y"
4421
{
4422
			struct netroute	*nr;
4423
4424
			if (router->rt_conf.af == AF_UNSPEC)
4425
				router->rt_conf.af = yyvsp[-2].v.addr.ss.ss_family;
4426
			else if (router->rt_conf.af != yyvsp[-2].v.addr.ss.ss_family) {
4427
				yyerror("router %s address family mismatch",
4428
				    router->rt_conf.name);
4429
				YYERROR;
4430
			}
4431
4432
			if ((router->rt_conf.af == AF_INET &&
4433
			    (yyvsp[0].v.number > 32 || yyvsp[0].v.number < 0)) ||
4434
			    (router->rt_conf.af == AF_INET6 &&
4435
			    (yyvsp[0].v.number > 128 || yyvsp[0].v.number < 0))) {
4436
				yyerror("invalid prefixlen %d", yyvsp[0].v.number);
4437
				YYERROR;
4438
			}
4439
4440
			if ((nr = calloc(1, sizeof(*nr))) == NULL)
4441
				fatal("out of memory");
4442
4443
			nr->nr_conf.id = ++last_nr_id;
4444
			if (last_nr_id == INT_MAX) {
4445
				yyerror("too many routes defined");
4446
				free(nr);
4447
				YYERROR;
4448
			}
4449
			nr->nr_conf.prefixlen = yyvsp[0].v.number;
4450
			nr->nr_conf.routerid = router->rt_conf.id;
4451
			nr->nr_router = router;
4452
			bcopy(&yyvsp[-2].v.addr.ss, &nr->nr_conf.ss, sizeof(yyvsp[-2].v.addr.ss));
4453
4454
			router->rt_conf.nroutes++;
4455
			conf->sc_routecount++;
4456
			TAILQ_INSERT_TAIL(&router->rt_netroutes, nr, nr_entry);
4457
			TAILQ_INSERT_TAIL(conf->sc_routes, nr, nr_route);
4458
		}
4459
break;
4460
case 210:
4461
#line 1952 "parse.y"
4462
{
4463
			free(hashkey);
4464
			hashkey = NULL;
4465
4466
			if (router->rt_gwtable) {
4467
				yyerror("router %s table already specified",
4468
				    router->rt_conf.name);
4469
				purge_table(conf, conf->sc_tables, yyvsp[0].v.table);
4470
				YYERROR;
4471
			}
4472
			router->rt_gwtable = yyvsp[0].v.table;
4473
			router->rt_gwtable->conf.flags |= F_USED;
4474
			router->rt_conf.gwtable = yyvsp[0].v.table->conf.id;
4475
			router->rt_conf.gwport = yyvsp[0].v.table->conf.port;
4476
		}
4477
break;
4478
case 211:
4479
#line 1967 "parse.y"
4480
{
4481
			if (router->rt_conf.rtable) {
4482
				yyerror("router %s rtable already specified",
4483
				    router->rt_conf.name);
4484
				YYERROR;
4485
			}
4486
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > RT_TABLEID_MAX) {
4487
				yyerror("invalid rtable id %d", yyvsp[0].v.number);
4488
				YYERROR;
4489
			}
4490
			router->rt_conf.rtable = yyvsp[0].v.number;
4491
		}
4492
break;
4493
case 212:
4494
#line 1979 "parse.y"
4495
{
4496
			if (strlcpy(router->rt_conf.label, yyvsp[0].v.string,
4497
			    sizeof(router->rt_conf.label)) >=
4498
			    sizeof(router->rt_conf.label)) {
4499
				yyerror("route label truncated");
4500
				free(yyvsp[0].v.string);
4501
				YYERROR;
4502
			}
4503
			free(yyvsp[0].v.string);
4504
		}
4505
break;
4506
case 213:
4507
#line 1989 "parse.y"
4508
{ rlay->rl_conf.flags |= F_DISABLE; }
4509
break;
4510
case 215:
4511
#line 1993 "parse.y"
4512
{
4513
			rlay->rl_conf.dstaf.ss_family = AF_UNSPEC;
4514
		}
4515
break;
4516
case 216:
4517
#line 1996 "parse.y"
4518
{
4519
			rlay->rl_conf.dstaf.ss_family = AF_INET;
4520
		}
4521
break;
4522
case 217:
4523
#line 1999 "parse.y"
4524
{
4525
			struct sockaddr_in6	*sin6;
4526
4527
			sin6 = (struct sockaddr_in6 *)&rlay->rl_conf.dstaf;
4528
			if (inet_pton(AF_INET6, yyvsp[0].v.string, &sin6->sin6_addr) == -1) {
4529
				yyerror("invalid ipv6 address %s", yyvsp[0].v.string);
4530
				free(yyvsp[0].v.string);
4531
				YYERROR;
4532
			}
4533
			free(yyvsp[0].v.string);
4534
4535
			sin6->sin6_family = AF_INET6;
4536
			sin6->sin6_len = sizeof(*sin6);
4537
		}
4538
break;
4539
case 218:
4540
#line 2015 "parse.y"
4541
{ yyval.v.string = NULL; }
4542
break;
4543
case 219:
4544
#line 2016 "parse.y"
4545
{ yyval.v.string = yyvsp[0].v.string; }
4546
break;
4547
case 220:
4548
#line 2019 "parse.y"
4549
{
4550
			if ((hst = calloc(1, sizeof(*(hst)))) == NULL)
4551
				fatal("out of memory");
4552
4553
			if (strlcpy(hst->conf.name, yyvsp[0].v.addr.name,
4554
			    sizeof(hst->conf.name)) >= sizeof(hst->conf.name)) {
4555
				yyerror("host name truncated");
4556
				free(hst);
4557
				YYERROR;
4558
			}
4559
			bcopy(&yyvsp[0].v.addr.ss, &hst->conf.ss, sizeof(yyvsp[0].v.addr.ss));
4560
			hst->conf.id = 0; /* will be set later */
4561
			SLIST_INIT(&hst->children);
4562
		}
4563
break;
4564
case 221:
4565
#line 2032 "parse.y"
4566
{
4567
			yyval.v.host = hst;
4568
			hst = NULL;
4569
		}
4570
break;
4571
case 226:
4572
#line 2046 "parse.y"
4573
{
4574
			if (hst->conf.retry) {
4575
				yyerror("retry value already set");
4576
				YYERROR;
4577
			}
4578
			if (yyvsp[0].v.number < 0) {
4579
				yyerror("invalid retry value: %d\n", yyvsp[0].v.number);
4580
				YYERROR;
4581
			}
4582
			hst->conf.retry = yyvsp[0].v.number;
4583
		}
4584
break;
4585
case 227:
4586
#line 2057 "parse.y"
4587
{
4588
			if (hst->conf.parentid) {
4589
				yyerror("parent value already set");
4590
				YYERROR;
4591
			}
4592
			if (yyvsp[0].v.number < 0) {
4593
				yyerror("invalid parent value: %d\n", yyvsp[0].v.number);
4594
				YYERROR;
4595
			}
4596
			hst->conf.parentid = yyvsp[0].v.number;
4597
		}
4598
break;
4599
case 228:
4600
#line 2068 "parse.y"
4601
{
4602
			if (hst->conf.priority) {
4603
				yyerror("priority already set");
4604
				YYERROR;
4605
			}
4606
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > RTP_MAX) {
4607
				yyerror("invalid priority value: %d\n", yyvsp[0].v.number);
4608
				YYERROR;
4609
			}
4610
			hst->conf.priority = yyvsp[0].v.number;
4611
		}
4612
break;
4613
case 229:
4614
#line 2079 "parse.y"
4615
{
4616
			if (hst->conf.ttl) {
4617
				yyerror("ttl value already set");
4618
				YYERROR;
4619
			}
4620
			if (yyvsp[0].v.number < 0) {
4621
				yyerror("invalid ttl value: %d\n", yyvsp[0].v.number);
4622
				YYERROR;
4623
			}
4624
			hst->conf.ttl = yyvsp[0].v.number;
4625
		}
4626
break;
4627
case 230:
4628
#line 2092 "parse.y"
4629
{
4630
			struct address *h;
4631
			struct addresslist al;
4632
4633
			if (strlcpy(yyval.v.addr.name, yyvsp[0].v.string,
4634
			    sizeof(yyval.v.addr.name)) >= sizeof(yyval.v.addr.name)) {
4635
				yyerror("host name truncated");
4636
				free(yyvsp[0].v.string);
4637
				YYERROR;
4638
			}
4639
4640
			TAILQ_INIT(&al);
4641
			if (host(yyvsp[0].v.string, &al, 1, NULL, NULL, -1) <= 0) {
4642
				yyerror("invalid host %s", yyvsp[0].v.string);
4643
				free(yyvsp[0].v.string);
4644
				YYERROR;
4645
			}
4646
			free(yyvsp[0].v.string);
4647
			h = TAILQ_FIRST(&al);
4648
			memcpy(&yyval.v.addr.ss, &h->ss, sizeof(yyval.v.addr.ss));
4649
			host_free(&al);
4650
		}
4651
break;
4652
case 231:
4653
#line 2116 "parse.y"
4654
{ yyval.v.number = 0; }
4655
break;
4656
case 232:
4657
#line 2117 "parse.y"
4658
{
4659
			if ((yyval.v.number = yyvsp[0].v.number) < 0) {
4660
				yyerror("invalid retry value: %d\n", yyvsp[0].v.number);
4661
				YYERROR;
4662
			}
4663
		}
4664
break;
4665
case 233:
4666
#line 2126 "parse.y"
4667
{
4668
			if (yyvsp[0].v.number < 0) {
4669
				yyerror("invalid timeout: %d\n", yyvsp[0].v.number);
4670
				YYERROR;
4671
			}
4672
			yyval.v.tv.tv_sec = yyvsp[0].v.number / 1000;
4673
			yyval.v.tv.tv_usec = (yyvsp[0].v.number % 1000) * 1000;
4674
		}
4675
break;
4676
case 240:
4677
#line 2148 "parse.y"
4678
42252
{ yyval.v.string = yyvsp[0].v.string; }
4679
42252
break;
4680
42252
case 241:
4681
42252
#line 2149 "parse.y"
4682
42252
{ yyval.v.string = NULL; }
4683
break;
4684
#line 4677 "parse.c"
4685
    }
4686
    yyssp -= yym;
4687
    yystate = *yyssp;
4688
    yyvsp -= yym;
4689
    yym = yylhs[yyn];
4690
4440
    if (yystate == 0 && yym == 0)
4691
4440
    {
4692
4440
#if YYDEBUG
4693
        if (yydebug)
4694
4440
            printf("%sdebug: after reduction, shifting from state 0 to\
4695
 state %d\n", YYPREFIX, YYFINAL);
4696
#endif
4697
        yystate = YYFINAL;
4698
        *++yyssp = YYFINAL;
4699
        *++yyvsp = yyval;
4700
        if (yychar < 0)
4701
        {
4702
            if ((yychar = yylex()) < 0) yychar = 0;
4703
#if YYDEBUG
4704
            if (yydebug)
4705
4440
            {
4706
4440
                yys = 0;
4707
3892
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
4708
                if (!yys) yys = "illegal-symbol";
4709

90660
                printf("%sdebug: state %d, reading %d (%s)\n",
4710
35232
                        YYPREFIX, YYFINAL, yychar, yys);
4711
15112
            }
4712
#endif
4713
22700
        }
4714
        if (yychar == 0) goto yyaccept;
4715
        goto yyloop;
4716
    }
4717
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
4718
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
4719

37812
        yystate = yytable[yyn];
4720
    else
4721
        yystate = yydgoto[yym];
4722
#if YYDEBUG
4723
37812
    if (yydebug)
4724
37812
        printf("%sdebug: after reduction, shifting from state %d \
4725
37812
to state %d\n", YYPREFIX, *yyssp, yystate);
4726
#endif
4727
    if (yyssp >= yysslim && yygrowstack())
4728
    {
4729
        goto yyoverflow;
4730
    }
4731
    *++yyssp = yystate;
4732
    *++yyvsp = yyval;
4733
    goto yyloop;
4734
yyoverflow:
4735
    yyerror("yacc stack overflow");
4736
yyabort:
4737
    if (yyss)
4738
1104
            free(yyss);
4739
1104
    if (yyvs)
4740
1104
            free(yyvs);
4741
1104
    yyss = yyssp = NULL;
4742
1104
    yyvs = yyvsp = NULL;
4743
1104
    yystacksize = 0;
4744
1104
    return (1);
4745
1104
yyaccept:
4746
1104
    if (yyss)
4747
            free(yyss);
4748
    if (yyvs)
4749
            free(yyvs);
4750
    yyss = yyssp = NULL;
4751
    yyvs = yyvsp = NULL;
4752
    yystacksize = 0;
4753
    return (0);
4754
}