Bug Summary

File:src/usr.sbin/relayd/obj/parse.c
Warning:line 2378, column 12
Use of zero-allocated memory

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name parse.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/relayd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/relayd -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/relayd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c parse.c
1#include <stdlib.h>
2#include <string.h>
3#define YYBYACC1 1
4#define YYMAJOR1 1
5#define YYMINOR9 9
6#define YYLEXyylex() yylex()
7#define YYEMPTY-1 -1
8#define yyclearin(yychar=(-1)) (yychar=(YYEMPTY-1))
9#define yyerrok(yyerrflag=0) (yyerrflag=0)
10#define YYRECOVERING()(yyerrflag!=0) (yyerrflag!=0)
11#define YYPREFIX"yy" "yy"
12#line 28 "/usr/src/usr.sbin/relayd/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 <agentx.h>
28#include <stdint.h>
29#include <stdarg.h>
30#include <stdio.h>
31#include <unistd.h>
32#include <ctype.h>
33#include <err.h>
34#include <endian.h>
35#include <errno(*__errno()).h>
36#include <limits.h>
37#include <netdb.h>
38#include <string.h>
39#include <ifaddrs.h>
40#include <syslog.h>
41#include <md5.h>
42
43#include "relayd.h"
44#include "http.h"
45
46TAILQ_HEAD(files, file)struct files { struct file *tqh_first; struct file **tqh_last
; }
files = TAILQ_HEAD_INITIALIZER(files){ ((void*)0), &(files).tqh_first };
47static struct file {
48 TAILQ_ENTRY(file)struct { struct file *tqe_next; struct file **tqe_prev; } entry;
49 FILE *stream;
50 char *name;
51 size_t ungetpos;
52 size_t ungetsize;
53 u_char *ungetbuf;
54 int eof_reached;
55 int lineno;
56 int errors;
57} *file, *topfile;
58struct file *pushfile(const char *, int);
59int popfile(void);
60int check_file_secrecy(int, const char *);
61int yyparse(void);
62int yylex(void);
63int yyerror(const char *, ...)
64 __attribute__((__format__ (printf, 1, 2)))
65 __attribute__((__nonnull__ (1)));
66int kw_cmp(const void *, const void *);
67int lookup(char *);
68int igetc(void);
69int lgetc(int);
70void lungetc(int);
71int findeol(void);
72
73TAILQ_HEAD(symhead, sym)struct symhead { struct sym *tqh_first; struct sym **tqh_last
; }
symhead = TAILQ_HEAD_INITIALIZER(symhead){ ((void*)0), &(symhead).tqh_first };
74struct sym {
75 TAILQ_ENTRY(sym)struct { struct sym *tqe_next; struct sym **tqe_prev; } entry;
76 int used;
77 int persist;
78 char *nam;
79 char *val;
80};
81int symset(const char *, const char *, int);
82char *symget(const char *);
83
84struct relayd *conf = NULL((void*)0);
85static int errors = 0;
86static int loadcfg = 0;
87objid_t last_rdr_id = 0;
88objid_t last_table_id = 0;
89objid_t last_host_id = 0;
90objid_t last_relay_id = 0;
91objid_t last_proto_id = 0;
92objid_t last_rt_id = 0;
93objid_t last_nr_id = 0;
94
95static struct rdr *rdr = NULL((void*)0);
96static struct table *table = NULL((void*)0);
97static struct relay *rlay = NULL((void*)0);
98static struct host *hst = NULL((void*)0);
99struct relaylist relays;
100static struct protocol *proto = NULL((void*)0);
101static struct relay_rule *rule = NULL((void*)0);
102static struct router *router = NULL((void*)0);
103static int label = 0;
104static int tagged = 0;
105static int tag = 0;
106static in_port_t tableport = 0;
107static int dstmode;
108static enum key_type keytype = KEY_TYPE_NONE;
109static enum direction dir = RELAY_DIR_ANY;
110static char *rulefile = NULL((void*)0);
111static union hashkey *hashkey = NULL((void*)0);
112
113struct address *host_ip(const char *);
114int host_dns(const char *, struct addresslist *,
115 int, struct portrange *, const char *, int);
116int host_if(const char *, struct addresslist *,
117 int, struct portrange *, const char *, int);
118int host(const char *, struct addresslist *,
119 int, struct portrange *, const char *, int);
120void host_free(struct addresslist *);
121
122struct table *table_inherit(struct table *);
123int relay_id(struct relay *);
124struct relay *relay_inherit(struct relay *, struct relay *);
125int getservice(char *);
126int is_if_in_group(const char *, const char *);
127
128typedef struct {
129 union {
130 int64_t number;
131 char *string;
132 struct host *host;
133 struct timeval tv;
134 struct table *table;
135 struct portrange port;
136 struct {
137 union hashkey key;
138 int keyset;
139 } key;
140 enum direction dir;
141 struct {
142 struct sockaddr_storage ss;
143 int prefixlen;
144 char name[HOST_NAME_MAX255+1];
145 } addr;
146 struct {
147 enum digest_type type;
148 char *digest;
149 } digest;
150 } v;
151 int lineno;
152} YYSTYPE;
153
154#line 155 "parse.c"
155#define AGENTX257 257
156#define APPEND258 258
157#define BACKLOG259 259
158#define BACKUP260 260
159#define BINARY261 261
160#define BUFFER262 262
161#define CA263 263
162#define CACHE264 264
163#define SET265 265
164#define CHECK266 266
165#define CIPHERS267 267
166#define CODE268 268
167#define COOKIE269 269
168#define DEMOTE270 270
169#define DIGEST271 271
170#define DISABLE272 272
171#define ERROR273 273
172#define EXPECT274 274
173#define PASS275 275
174#define BLOCK276 276
175#define EXTERNAL277 277
176#define FILENAME278 278
177#define FORWARD279 279
178#define FROM280 280
179#define HASH281 281
180#define HEADER282 282
181#define HEADERLEN283 283
182#define HOST284 284
183#define HTTP285 285
184#define ICMP286 286
185#define INCLUDE287 287
186#define INET288 288
187#define INET6289 289
188#define INTERFACE290 290
189#define INTERVAL291 291
190#define IP292 292
191#define KEYPAIR293 293
192#define LABEL294 294
193#define LISTEN295 295
194#define VALUE296 296
195#define LOADBALANCE297 297
196#define LOG298 298
197#define LOOKUP299 299
198#define METHOD300 300
199#define MODE301 301
200#define NAT302 302
201#define NO303 303
202#define DESTINATION304 304
203#define NODELAY305 305
204#define NOTHING306 306
205#define ON307 307
206#define PARENT308 308
207#define PATH309 309
208#define PFTAG310 310
209#define PORT311 311
210#define PREFORK312 312
211#define PRIORITY313 313
212#define PROTO314 314
213#define QUERYSTR315 315
214#define REAL316 316
215#define REDIRECT317 317
216#define RELAY318 318
217#define REMOVE319 319
218#define REQUEST320 320
219#define RESPONSE321 321
220#define RETRY322 322
221#define QUICK323 323
222#define RETURN324 324
223#define ROUNDROBIN325 325
224#define ROUTE326 326
225#define SACK327 327
226#define SCRIPT328 328
227#define SEND329 329
228#define SESSION330 330
229#define SOCKET331 331
230#define SPLICE332 332
231#define SSL333 333
232#define STICKYADDR334 334
233#define STRIP335 335
234#define STYLE336 336
235#define TABLE337 337
236#define TAG338 338
237#define TAGGED339 339
238#define TCP340 340
239#define TIMEOUT341 341
240#define TLS342 342
241#define TO343 343
242#define ROUTER344 344
243#define RTLABEL345 345
244#define TRANSPARENT346 346
245#define URL347 347
246#define WITH348 348
247#define TTL349 349
248#define RTABLE350 350
249#define MATCH351 351
250#define PARAMS352 352
251#define RANDOM353 353
252#define LEASTSTATES354 354
253#define SRCHASH355 355
254#define KEY356 356
255#define CERTIFICATE357 357
256#define PASSWORD358 358
257#define ECDHE359 359
258#define EDH360 360
259#define TICKETS361 361
260#define CONNECTION362 362
261#define CONNECTIONS363 363
262#define CONTEXT364 364
263#define ERRORS365 365
264#define STATE366 366
265#define CHANGES367 367
266#define CHECKS368 368
267#define WEBSOCKETS369 369
268#define STRING370 370
269#define NUMBER371 371
270#define YYERRCODE256 256
271const short yylhs[] =
272 { -1,
273 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
274 0, 34, 42, 42, 14, 14, 15, 15, 7, 7,
275 2, 2, 17, 17, 17, 17, 16, 16, 16, 43,
276 43, 46, 46, 44, 22, 22, 22, 35, 47, 47,
277 48, 48, 36, 36, 36, 36, 36, 36, 6, 6,
278 1, 1, 8, 8, 8, 8, 49, 37, 51, 51,
279 52, 52, 52, 52, 52, 52, 52, 18, 18, 12,
280 12, 12, 4, 55, 38, 54, 54, 56, 56, 57,
281 57, 58, 58, 60, 31, 59, 59, 61, 61, 61,
282 61, 61, 61, 33, 33, 62, 62, 62, 62, 62,
283 62, 62, 62, 29, 30, 30, 64, 40, 63, 63,
284 63, 65, 65, 68, 66, 69, 66, 72, 66, 73,
285 66, 76, 66, 77, 66, 66, 66, 66, 66, 78,
286 78, 75, 75, 75, 74, 74, 71, 71, 71, 71,
287 71, 71, 71, 71, 71, 70, 70, 67, 67, 67,
288 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
289 11, 81, 79, 19, 19, 19, 32, 32, 32, 9,
290 9, 20, 20, 20, 25, 25, 26, 26, 80, 80,
291 82, 82, 83, 83, 83, 83, 83, 83, 83, 83,
292 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
293 83, 5, 5, 21, 21, 21, 21, 21, 21, 84,
294 39, 85, 85, 86, 86, 86, 86, 86, 86, 87,
295 87, 87, 87, 10, 10, 10, 10, 10, 10, 10,
296 89, 41, 90, 90, 91, 91, 91, 91, 91, 91,
297 88, 88, 88, 3, 3, 93, 23, 92, 92, 94,
298 94, 95, 95, 95, 95, 24, 27, 27, 13, 13,
299 28, 45, 45, 45, 50, 50, 53,
300};
301const short yylen[] =
302 { 2,
303 0, 3, 2, 3, 3, 3, 3, 3, 3, 3,
304 3, 2, 1, 1, 0, 1, 0, 2, 1, 1,
305 0, 2, 0, 1, 1, 1, 0, 1, 1, 3,
306 1, 0, 1, 2, 2, 2, 2, 3, 1, 1,
307 1, 1, 2, 2, 2, 2, 3, 2, 0, 2,
308 0, 2, 2, 2, 1, 2, 0, 7, 3, 2,
309 4, 6, 1, 1, 3, 3, 1, 0, 1, 1,
310 1, 2, 3, 0, 4, 2, 1, 1, 4, 3,
311 2, 1, 1, 0, 3, 2, 1, 2, 1, 2,
312 2, 2, 3, 0, 1, 1, 1, 1, 5, 4,
313 5, 6, 2, 2, 1, 1, 0, 5, 0, 2,
314 4, 3, 2, 0, 3, 0, 5, 0, 3, 0,
315 5, 0, 3, 0, 5, 3, 5, 1, 1, 3,
316 1, 2, 1, 2, 3, 1, 1, 2, 1, 2,
317 1, 2, 2, 3, 3, 3, 1, 2, 3, 2,
318 2, 1, 3, 2, 3, 5, 3, 2, 2, 1,
319 1, 0, 8, 1, 1, 1, 0, 1, 1, 0,
320 1, 0, 1, 1, 0, 2, 0, 2, 0, 1,
321 2, 1, 2, 4, 2, 4, 2, 4, 2, 3,
322 4, 2, 4, 2, 3, 2, 2, 2, 2, 2,
323 3, 0, 2, 0, 1, 1, 1, 1, 1, 0,
324 7, 3, 2, 5, 5, 3, 2, 1, 1, 3,
325 3, 2, 1, 0, 1, 1, 1, 1, 1, 1,
326 0, 7, 3, 2, 2, 3, 2, 2, 1, 1,
327 0, 1, 2, 0, 2, 0, 3, 0, 1, 2,
328 1, 2, 2, 2, 3, 1, 3, 1, 0, 2,
329 1, 1, 1, 0, 2, 0, 2,
330};
331const short yydefred[] =
332 { 1,
333 0, 0, 0, 25, 0, 0, 0, 0, 0, 0,
334 0, 0, 24, 0, 0, 0, 3, 0, 0, 0,
335 0, 0, 0, 0, 0, 0, 11, 0, 0, 12,
336 43, 0, 0, 0, 44, 46, 57, 210, 48, 0,
337 74, 261, 45, 231, 0, 0, 2, 4, 5, 6,
338 7, 8, 9, 10, 52, 0, 47, 54, 56, 53,
339 0, 0, 0, 0, 0, 38, 107, 50, 0, 0,
340 73, 78, 0, 0, 77, 0, 0, 0, 0, 0,
341 0, 76, 0, 0, 108, 265, 63, 70, 0, 71,
342 0, 64, 0, 69, 0, 0, 67, 0, 0, 218,
343 0, 0, 0, 0, 219, 0, 0, 256, 82, 246,
344 83, 0, 0, 239, 0, 0, 0, 0, 240, 0,
345 0, 110, 0, 0, 0, 72, 0, 0, 58, 0,
346 60, 0, 217, 0, 0, 0, 211, 0, 213, 0,
347 79, 0, 262, 0, 81, 263, 0, 0, 235, 238,
348 237, 232, 0, 234, 164, 165, 0, 0, 13, 0,
349 14, 166, 0, 129, 0, 0, 0, 128, 0, 66,
350 84, 0, 65, 0, 59, 0, 216, 18, 0, 212,
351 0, 0, 0, 0, 247, 249, 0, 0, 80, 236,
352 0, 233, 0, 0, 0, 0, 0, 168, 169, 0,
353 0, 0, 111, 0, 113, 28, 29, 0, 0, 0,
354 61, 267, 0, 0, 0, 0, 0, 223, 0, 0,
355 253, 254, 252, 250, 257, 0, 0, 133, 123, 0,
356 0, 0, 33, 126, 0, 0, 0, 139, 137, 0,
357 141, 119, 0, 171, 0, 0, 0, 0, 0, 0,
358 0, 0, 161, 160, 115, 0, 112, 0, 0, 0,
359 0, 0, 0, 89, 85, 0, 245, 35, 36, 37,
360 214, 16, 0, 0, 222, 0, 242, 0, 215, 255,
361 132, 134, 0, 0, 34, 0, 0, 143, 0, 140,
362 138, 142, 0, 0, 0, 174, 173, 0, 0, 0,
363 0, 150, 158, 0, 151, 159, 148, 154, 0, 0,
364 0, 62, 0, 19, 96, 0, 0, 97, 20, 0,
365 98, 88, 91, 92, 227, 225, 226, 230, 228, 229,
366 0, 90, 86, 221, 260, 220, 243, 0, 125, 127,
367 0, 145, 144, 0, 121, 0, 0, 155, 0, 157,
368 149, 153, 0, 117, 0, 103, 39, 40, 0, 0,
369 95, 93, 130, 30, 135, 176, 0, 162, 0, 146,
370 41, 42, 0, 0, 0, 0, 178, 0, 156, 0,
371 0, 22, 0, 0, 100, 0, 0, 0, 0, 0,
372 0, 0, 0, 0, 0, 0, 0, 163, 180, 0,
373 0, 101, 99, 104, 205, 206, 208, 209, 207, 0,
374 0, 0, 0, 199, 183, 200, 197, 0, 0, 0,
375 196, 198, 0, 181, 102, 0, 0, 201, 195, 0,
376 190, 0, 0, 106, 105, 0, 184, 203, 186, 188,
377 191, 193,
378};
379const short yydgoto[] =
380 { 1,
381 29, 376, 211, 171, 428, 57, 320, 35, 245, 331,
382 254, 95, 275, 271, 136, 208, 18, 96, 163, 298,
383 410, 264, 109, 148, 347, 368, 149, 43, 385, 436,
384 172, 200, 362, 97, 20, 21, 22, 23, 24, 25,
385 26, 272, 286, 287, 144, 234, 359, 373, 61, 79,
386 98, 99, 146, 74, 64, 75, 112, 113, 265, 209,
387 266, 322, 85, 77, 166, 167, 310, 201, 202, 311,
388 294, 196, 197, 295, 283, 193, 194, 284, 168, 398,
389 378, 399, 400, 62, 106, 107, 219, 279, 65, 120,
390 121, 185, 140, 186, 187,
391};
392const short yysindex[] =
393 { 0,
394 166, 46, -293, 0, -291, -290, -234, -285, -274, -247,
395 -230, 50, 0, -227, -213, 100, 0, -149, 164, 168,
396 180, 182, 197, 199, 201, 204, 0, -150, -88, 0,
397 0, -139, -134, -133, 0, 0, 0, 0, 0, -135,
398 0, 0, 0, 0, -121, -114, 0, 0, 0, 0,
399 0, 0, 0, 0, 0, -106, 0, 0, 0, 0,
400 144, 145, 210, -118, 165, 0, 0, 0, 277, 277,
401 0, 0, 277, -118, 0, 277, 170, 277, 109, -71,
402 -262, 0, -197, 1, 0, 0, 0, 0, -16, 0,
403 -46, 0, 17, 0, -45, -13, 0, -57, 277, 0,
404 -8, -62, -32, -37, 0, 488, 277, 0, 0, 0,
405 0, 189, 25, 0, -25, -43, -42, -41, 0, -74,
406 277, 0, 1180, -36, -31, 0, 50, -35, 0, 314,
407 0, -27, 0, -21, -196, 13, 0, 314, 0, -142,
408 0, 277, 0, -262, 0, 0, 50, 311, 0, 0,
409 0, 0, 314, 0, 0, 0, 0, 87, 0, 0,
410 0, 0, -157, 0, 0, 578, 277, 0, -298, 0,
411 0, 72, 0, 277, 0, 52, 0, 0, -58, 0,
412 16, -2, 3, 4, 0, 0, -142, 0, 0, 0,
413 5, 0, -256, 248, -113, 437, 249, 0, 0, 55,
414 -245, 257, 0, 314, 0, 0, 0, 52, 279, 20,
415 0, 0, -253, -196, 88, 75, 52, 0, -89, 27,
416 0, 0, 0, 0, 0, 34, 37, 0, 0, -256,
417 45, 82, 0, 0, 49, 56, -235, 0, 0, 175,
418 0, 0, 437, 0, -86, -223, 57, 58, -287, 69,
419 62, 86, 0, 0, 0, -245, 0, 72, -240, 71,
420 73, -248, -227, 0, 0, 279, 0, 0, 0, 0,
421 0, 0, 75, 74, 0, 75, 0, 77, 0, 0,
422 0, 0, 47, 317, 0, 324, 47, 0, 81, 0,
423 0, 0, 83, 47, 333, 0, 0, 181, 92, 93,
424 97, 0, 0, 110, 0, 0, 0, 0, 102, 47,
425 349, 0, 146, 0, 0, 111, -267, 0, 0, 117,
426 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
427 123, 0, 0, 0, 0, 0, 0, -256, 0, 0,
428 82, 0, 0, 437, 0, -43, 136, 0, 122, 0,
429 0, 0, -245, 0, -239, 0, 0, 0, 216, 215,
430 0, 0, 0, 0, 0, 0, -43, 0, 124, 0,
431 0, 0, 238, 147, 148, -159, 0, 1224, 0, 152,
432 -196, 0, 143, 153, 0, -123, 154, 172, -123, 155,
433 157, -260, 211, -123, 158, 163, -123, 0, 0, 1224,
434 -196, 0, 0, 0, 0, 0, 0, 0, 0, 167,
435 223, 50, 169, 0, 0, 0, 0, 171, 173, 177,
436 0, 0, -259, 0, 0, 223, 183, 0, 0, 223,
437 0, 223, 223, 0, 0, 223, 0, 0, 0, 0,
438 0, 0,};
439const short yyrindex[] =
440 { 0,
441 224, 0, -6, 0, 0, 0, 0, 0, 0, 0,
442 0, 0, 0, 0, 0, 237, 0, 0, 0, 0,
443 0, 0, 0, 0, 0, 0, 0, 0, 180, 0,
444 0, 0, 530, 0, 0, 0, 0, 0, 0, 0,
445 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
446 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
447 0, 0, 0, 0, 0, 0, 0, 0, 1204, 1011,
448 0, 0, -251, 544, 0, 120, 545, 1118, 247, 0,
449 0, 0, 0, 1225, 0, 0, 0, 0, 0, 0,
450 0, 0, 0, 0, 0, 0, 0, 247, 1092, 0,
451 0, 0, 0, 219, 0, 0, 998, 0, 0, 0,
452 0, 0, -110, 0, 0, 0, 0, 0, 0, 0,
453 -60, 0, 0, 0, 0, 0, 0, 0, 0, 0,
454 0, 0, 0, 0, 0, 0, 0, 0, 0, -4,
455 0, -108, 0, 0, 0, 0, 0, 226, 0, 0,
456 0, 0, 0, 0, 0, 0, -115, 0, 0, -99,
457 0, 0, 306, 0, -120, 0, 1195, 0, 252, 0,
458 0, 1009, 0, 1118, 0, 0, 0, 0, 0, 0,
459 0, 0, 0, 0, 0, 0, -3, -105, 0, 0,
460 0, 0, 0, 0, 149, 0, 0, 0, 0, 323,
461 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
462 0, 0, 0, 587, 0, 1074, 0, 0, 932, 0,
463 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
464 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
465 0, 0, 0, 0, 406, 0, 0, 0, 0, 0,
466 0, 126, 0, 0, 0, 0, 0, 1009, 0, 0,
467 0, -9, 0, 0, 0, 965, 0, 0, 0, 0,
468 0, 0, 1074, 0, 0, 1074, 0, 0, 0, 0,
469 0, 0, -116, 0, 0, 0, -111, 0, 0, 0,
470 0, 0, 0, 229, 0, 0, 0, 423, 0, 0,
471 0, 0, 0, 0, 0, 0, 0, 0, 0, -112,
472 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
473 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
474 506, 0, 0, 0, 0, 0, 0, 0, 0, 0,
475 0, 0, 0, 0, 0, 0, 612, 0, 0, 0,
476 0, 0, 0, 0, 0, 0, 0, 0, 0, -82,
477 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
478 0, 0, 0, 0, 0, 0, 0, 981, 0, 0,
479 534, 0, 0, 0, 0, 70, 0, 0, 70, 0,
480 0, 0, 70, 70, 0, 0, 44, 0, 0, 989,
481 534, 0, 0, 0, 0, 0, 0, 0, 0, 662,
482 703, 0, 780, 0, 0, 0, 0, 0, 800, 883,
483 0, 0, 900, 0, 0, 703, 0, 0, 0, 703,
484 0, 703, 703, 0, 0, 703, 0, 0, 0, 0,
485 0, 0,};
486const short yygindex[] =
487 { 0,
488 0, 0, 300, -12, -126, 0, 0, 0, 0, 0,
489 318, -19, -79, -337, 0, 0, 0, 0, 0, 0,
490 -152, 9, 0, -5, 0, 0, -283, 309, 151, 0,
491 -85, 0, 0, 18, 0, 0, 0, 0, 0, 0,
492 0, -107, 242, 383, -138, 0, 0, 0, 0, -47,
493 0, 481, -100, 0, 0, 513, 445, 0, 330, 0,
494 0, 0, 0, 0, 0, 438, 413, 0, 0, 254,
495 420, 0, 0, 274, 426, 0, 0, 286, 0, 0,
496 0, 225, 0, 0, 0, 521, 0, 0, 0, 0,
497 508, 0, 0, 446, 0,
498};
499#define YYTABLESIZE1576 1576
500const short yytable[] =
501 { 41,
502 224, 40, 116, 51, 73, 248, 251, 124, 131, 232,
503 78, 384, 147, 31, 266, 165, 266, 246, 19, 265,
504 313, 247, 80, 120, 5, 81, 226, 178, 83, 175,
505 86, 268, 325, 416, 142, 266, 123, 180, 357, 248,
506 251, 206, 304, 402, 314, 315, 227, 248, 326, 32,
507 152, 131, 192, 204, 299, 27, 174, 249, 165, 139,
508 104, 190, 366, 425, 266, 145, 371, 129, 143, 290,
509 28, 207, 305, 154, 114, 110, 327, 417, 30, 204,
510 31, 115, 253, 377, 250, 36, 104, 316, 317, 5,
511 143, 291, 159, 218, 188, 37, 292, 105, 111, 318,
512 119, 161, 358, 257, 328, 329, 330, 108, 383, 40,
513 434, 384, 228, 251, 252, 224, 269, 270, 266, 205,
514 248, 251, 38, 105, 253, 122, 212, 33, 116, 319,
515 372, 34, 300, 301, 405, 152, 159, 119, 110, 39,
516 164, 406, 114, 42, 338, 161, 114, 117, 341, 181,
517 264, 321, 118, 72, 264, 344, 44, 407, 32, 118,
518 45, 111, 198, 199, 46, 182, 264, 122, 204, 152,
519 183, 353, 114, 47, 408, 17, 264, 48, 266, 184,
520 264, 267, 114, 164, 214, 21, 264, 122, 21, 49,
521 264, 50, 118, 334, 204, 409, 336, 114, 277, 278,
522 100, 296, 297, 118, 115, 118, 51, 88, 52, 114,
523 53, 266, 5, 54, 87, 5, 258, 264, 266, 55,
524 56, 88, 231, 101, 264, 276, 266, 118, 58, 5,
525 59, 118, 118, 60, 63, 258, 413, 89, 114, 114,
526 419, 420, 102, 215, 423, 216, 264, 264, 66, 114,
527 152, 116, 264, 122, 90, 67, 224, 264, 103, 264,
528 224, 266, 224, 68, 267, 266, 69, 70, 90, 224,
529 117, 71, 91, 32, 93, 118, 92, 224, 224, 224,
530 224, 224, 248, 251, 266, 224, 78, 76, 93, 266,
531 124, 224, 84, 94, 125, 126, 128, 127, 132, 437,
532 224, 224, 51, 439, 224, 440, 441, 133, 134, 442,
533 135, 217, 204, 141, 204, 167, 224, 147, 204, 204,
534 224, 204, 204, 174, 224, 204, 108, 150, 204, 151,
535 204, 224, 170, 169, 173, 224, 224, 204, 204, 170,
536 224, 224, 176, 204, 204, 204, 204, 204, 204, 177,
537 258, 204, 204, 136, 204, 179, 204, 191, 204, 195,
538 224, 210, 213, 204, 220, 248, 251, 204, 221, 204,
539 230, 243, 204, 222, 223, 225, 204, 244, 204, 256,
540 87, 204, 204, 204, 204, 204, 273, 88, 152, 267,
541 204, 266, 152, 204, 204, 5, 274, 280, 266, 429,
542 152, 152, 204, 89, 281, 282, 266, 204, 204, 204,
543 152, 204, 152, 204, 285, 172, 204, 231, 152, 288,
544 204, 2, 3, 32, 32, 289, 302, 303, 152, 307,
545 167, 308, 175, 32, 90, 32, 293, 309, 91, 204,
546 323, 339, 92, 324, 335, 266, 337, 170, 340, 152,
547 4, 342, 5, 343, 93, 152, 6, 345, 152, 94,
548 346, 348, 349, 7, 266, 152, 350, 152, 405, 266,
549 351, 352, 32, 354, 355, 406, 152, 8, 367, 369,
550 356, 32, 9, 10, 152, 152, 360, 264, 32, 374,
551 32, 407, 361, 379, 258, 152, 11, 258, 375, 32,
552 258, 258, 12, 258, 258, 13, 14, 258, 408, 15,
553 258, 380, 258, 403, 412, 94, 381, 382, 427, 258,
554 264, 401, 404, 411, 414, 258, 415, 421, 258, 409,
555 172, 264, 422, 264, 258, 16, 426, 23, 430, 55,
556 258, 431, 432, 15, 259, 418, 433, 175, 260, 258,
557 26, 258, 438, 75, 109, 264, 68, 312, 258, 264,
558 264, 17, 27, 258, 258, 258, 306, 258, 258, 261,
559 258, 332, 258, 435, 167, 258, 258, 233, 130, 262,
560 167, 167, 364, 167, 167, 167, 82, 167, 189, 213,
561 167, 170, 167, 167, 167, 333, 15, 170, 170, 167,
562 170, 170, 170, 204, 170, 167, 370, 170, 167, 170,
563 170, 170, 137, 255, 167, 242, 170, 365, 229, 263,
564 167, 177, 170, 363, 424, 170, 138, 153, 167, 167,
565 94, 170, 224, 0, 0, 0, 0, 170, 167, 0,
566 0, 0, 0, 167, 167, 167, 170, 167, 167, 0,
567 0, 0, 167, 0, 0, 170, 167, 0, 15, 0,
568 170, 170, 170, 0, 170, 170, 0, 0, 0, 170,
569 0, 185, 0, 170, 172, 0, 0, 0, 0, 0,
570 172, 172, 0, 172, 172, 172, 0, 172, 0, 0,
571 172, 175, 172, 0, 0, 235, 0, 175, 175, 172,
572 175, 175, 203, 0, 175, 172, 0, 175, 172, 175,
573 0, 15, 202, 0, 172, 0, 175, 0, 0, 0,
574 172, 0, 175, 0, 0, 175, 0, 0, 236, 172,
575 0, 175, 0, 0, 0, 0, 177, 175, 172, 237,
576 0, 238, 0, 172, 172, 172, 175, 172, 172, 0,
577 0, 0, 172, 0, 0, 175, 172, 0, 0, 100,
578 175, 175, 175, 239, 175, 175, 88, 240, 241, 175,
579 0, 94, 0, 175, 5, 94, 0, 94, 0, 0,
580 0, 0, 101, 0, 94, 0, 185, 0, 0, 187,
581 0, 0, 94, 94, 94, 94, 94, 0, 0, 15,
582 94, 102, 0, 15, 0, 15, 94, 0, 0, 189,
583 0, 0, 15, 90, 0, 94, 94, 103, 0, 94,
584 15, 15, 15, 15, 15, 0, 0, 202, 15, 0,
585 0, 94, 0, 93, 15, 94, 0, 0, 0, 94,
586 0, 0, 0, 15, 15, 0, 94, 15, 0, 0,
587 94, 94, 155, 156, 0, 94, 94, 0, 15, 15,
588 0, 0, 157, 15, 5, 15, 0, 15, 0, 0,
589 0, 0, 0, 15, 15, 0, 0, 0, 15, 15,
590 177, 15, 0, 15, 15, 0, 177, 177, 0, 177,
591 177, 0, 192, 177, 0, 0, 177, 0, 177, 0,
592 15, 158, 0, 0, 187, 177, 0, 0, 0, 194,
593 159, 177, 15, 0, 177, 0, 15, 160, 0, 161,
594 177, 0, 0, 0, 189, 0, 177, 0, 162, 0,
595 185, 0, 15, 0, 0, 177, 185, 185, 0, 185,
596 185, 241, 0, 185, 177, 0, 185, 0, 185, 177,
597 177, 177, 0, 177, 0, 185, 0, 0, 177, 0,
598 0, 185, 177, 0, 185, 0, 0, 0, 0, 0,
599 185, 202, 0, 0, 87, 0, 185, 202, 202, 0,
600 202, 202, 0, 0, 202, 185, 0, 202, 0, 202,
601 179, 0, 0, 0, 185, 0, 202, 0, 182, 185,
602 185, 185, 202, 185, 0, 202, 0, 192, 185, 0,
603 0, 202, 185, 0, 0, 0, 0, 202, 244, 0,
604 0, 0, 0, 0, 194, 0, 202, 0, 0, 0,
605 0, 0, 0, 0, 0, 202, 0, 0, 0, 0,
606 202, 202, 202, 0, 202, 0, 0, 0, 187, 202,
607 0, 0, 0, 202, 187, 187, 241, 187, 187, 0,
608 0, 187, 0, 0, 187, 0, 187, 0, 189, 0,
609 0, 0, 0, 187, 189, 189, 0, 189, 189, 187,
610 0, 189, 187, 259, 189, 0, 189, 0, 187, 87,
611 0, 0, 0, 189, 187, 0, 0, 0, 0, 189,
612 0, 0, 189, 187, 0, 179, 0, 0, 189, 0,
613 0, 0, 187, 182, 189, 0, 0, 187, 187, 187,
614 0, 187, 266, 189, 0, 0, 187, 0, 0, 0,
615 187, 0, 189, 244, 0, 0, 0, 189, 189, 189,
616 0, 189, 0, 0, 0, 0, 189, 0, 0, 0,
617 189, 192, 0, 0, 0, 0, 0, 192, 192, 0,
618 192, 192, 0, 0, 192, 0, 0, 192, 194, 192,
619 0, 0, 0, 0, 194, 194, 192, 194, 194, 0,
620 0, 194, 192, 0, 194, 192, 194, 0, 0, 0,
621 0, 192, 0, 194, 0, 0, 0, 192, 259, 194,
622 0, 0, 194, 241, 0, 0, 192, 0, 194, 0,
623 241, 0, 0, 0, 194, 192, 266, 0, 241, 0,
624 192, 192, 192, 194, 192, 0, 241, 0, 0, 192,
625 0, 0, 194, 192, 0, 0, 87, 194, 194, 194,
626 0, 194, 266, 87, 0, 241, 194, 0, 0, 0,
627 194, 87, 87, 87, 87, 179, 179, 241, 0, 87,
628 0, 241, 0, 182, 182, 179, 0, 179, 0, 266,
629 0, 0, 0, 182, 87, 182, 266, 241, 87, 0,
630 244, 0, 266, 0, 266, 0, 0, 244, 0, 266,
631 87, 0, 266, 0, 87, 244, 0, 266, 87, 0,
632 0, 0, 0, 244, 179, 266, 0, 0, 0, 87,
633 87, 266, 182, 179, 87, 87, 0, 0, 244, 266,
634 179, 182, 179, 266, 266, 0, 0, 266, 182, 0,
635 182, 179, 0, 0, 244, 0, 266, 0, 244, 182,
636 266, 0, 244, 266, 0, 259, 0, 0, 0, 0,
637 0, 0, 259, 0, 244, 0, 266, 0, 0, 244,
638 259, 259, 259, 266, 0, 0, 0, 0, 259, 0,
639 266, 0, 0, 0, 0, 0, 266, 0, 266, 0,
640 266, 0, 0, 0, 266, 0, 266, 259, 0, 266,
641 0, 0, 266, 266, 0, 0, 266, 0, 0, 259,
642 266, 266, 266, 259, 266, 0, 0, 0, 0, 266,
643 266, 0, 266, 0, 0, 0, 0, 266, 0, 259,
644 266, 266, 266, 0, 0, 266, 0, 266, 0, 0,
645 0, 266, 0, 0, 0, 0, 0, 266, 0, 0,
646 0, 266, 266, 266, 266, 0, 0, 266, 266, 266,
647 266, 266, 0, 266, 155, 156, 0, 266, 0, 266,
648 0, 0, 266, 266, 157, 0, 5, 266, 266, 266,
649 266, 0, 0, 0, 0, 266, 266, 266, 0, 266,
650 0, 266, 266, 0, 0, 0, 266, 266, 0, 0,
651 266, 0, 386, 0, 0, 0, 0, 0, 266, 266,
652 266, 387, 388, 158, 0, 389, 0, 0, 0, 266,
653 0, 266, 159, 266, 0, 0, 0, 390, 266, 160,
654 0, 161, 0, 391, 0, 0, 392, 266, 0, 266,
655 162, 0, 393, 266, 266, 0, 266, 266, 394, 0,
656 0, 0, 0, 0, 0, 266, 0, 0, 266, 266,
657 0, 0, 0, 0, 266, 0, 0, 266, 0, 0,
658 0, 395, 396, 0, 266, 0, 266, 0, 0, 0,
659 397, 0, 0, 0, 0, 266,
660};
661const short yycheck[] =
662 { 12,
663 10, 60, 123, 10, 123, 10, 10, 123, 125, 123,
664 10, 271, 125, 125, 125, 123, 125, 263, 1, 125,
665 261, 267, 70, 123, 287, 73, 283, 135, 76, 130,
666 78, 285, 281, 294, 10, 287, 84, 138, 306, 44,
667 44, 340, 330, 381, 285, 286, 303, 293, 297, 284,
668 125, 99, 153, 10, 278, 10, 10, 303, 166, 107,
669 80, 147, 346, 401, 125, 113, 306, 125, 44, 305,
670 364, 370, 360, 121, 272, 81, 325, 338, 370, 10,
671 371, 279, 370, 367, 330, 371, 106, 328, 329, 287,
672 44, 327, 333, 179, 142, 370, 332, 80, 81, 340,
673 83, 342, 370, 204, 353, 354, 355, 370, 268, 60,
674 370, 271, 369, 359, 360, 125, 370, 371, 370, 167,
675 125, 125, 370, 106, 370, 125, 174, 362, 326, 370,
676 370, 366, 356, 357, 258, 10, 333, 120, 144, 370,
677 123, 265, 263, 371, 283, 342, 267, 345, 287, 292,
678 263, 259, 350, 272, 267, 294, 370, 281, 10, 259,
679 61, 144, 320, 321, 314, 308, 283, 283, 125, 44,
680 313, 310, 293, 10, 298, 10, 287, 10, 287, 322,
681 293, 287, 303, 166, 176, 268, 303, 303, 271, 10,
682 303, 10, 292, 273, 125, 319, 276, 272, 288, 289,
683 272, 288, 289, 303, 279, 305, 10, 279, 10, 330,
684 10, 272, 287, 10, 272, 287, 208, 330, 279, 370,
685 309, 279, 336, 295, 336, 217, 287, 327, 368, 287,
686 365, 331, 332, 367, 370, 10, 389, 295, 359, 360,
687 393, 394, 314, 302, 397, 304, 359, 360, 370, 370,
688 125, 326, 369, 369, 326, 370, 266, 370, 330, 370,
689 270, 370, 272, 370, 370, 326, 123, 123, 326, 279,
690 345, 62, 330, 125, 346, 350, 334, 287, 288, 289,
691 290, 291, 287, 287, 345, 295, 10, 123, 346, 350,
692 307, 301, 123, 351, 341, 279, 310, 343, 307, 426,
693 310, 311, 309, 430, 314, 432, 433, 370, 341, 436,
694 348, 370, 269, 125, 271, 10, 326, 343, 275, 276,
695 330, 278, 279, 10, 334, 282, 370, 370, 285, 371,
696 287, 341, 10, 370, 370, 345, 346, 294, 269, 371,
697 350, 351, 370, 300, 275, 276, 303, 278, 279, 371,
698 125, 282, 309, 125, 285, 343, 287, 47, 315, 273,
699 370, 290, 311, 294, 349, 370, 370, 324, 371, 300,
700 123, 123, 303, 371, 371, 371, 333, 323, 309, 123,
701 272, 338, 339, 340, 315, 342, 299, 279, 263, 370,
702 347, 272, 267, 324, 351, 287, 322, 371, 279, 412,
703 275, 276, 333, 295, 371, 369, 287, 338, 339, 340,
704 285, 342, 287, 370, 370, 10, 347, 336, 293, 371,
705 351, 256, 257, 275, 276, 370, 370, 370, 303, 361,
706 125, 370, 10, 285, 326, 287, 262, 352, 330, 370,
707 370, 125, 334, 371, 371, 326, 370, 125, 125, 324,
708 285, 371, 287, 371, 346, 330, 291, 125, 333, 351,
709 280, 370, 370, 298, 345, 340, 370, 342, 258, 350,
710 361, 370, 324, 125, 329, 265, 351, 312, 343, 358,
711 370, 333, 317, 318, 359, 360, 370, 259, 340, 274,
712 342, 281, 370, 370, 269, 370, 331, 272, 284, 351,
713 275, 276, 337, 278, 279, 340, 341, 282, 298, 344,
714 285, 274, 287, 371, 343, 10, 370, 370, 296, 294,
715 292, 370, 370, 370, 370, 300, 370, 370, 303, 319,
716 125, 303, 370, 305, 309, 370, 370, 314, 370, 10,
717 315, 371, 370, 10, 266, 335, 370, 125, 270, 324,
718 314, 326, 370, 10, 10, 327, 310, 258, 333, 331,
719 332, 343, 311, 338, 339, 340, 249, 342, 343, 291,
720 345, 263, 347, 423, 269, 350, 351, 195, 98, 301,
721 275, 276, 341, 278, 279, 280, 74, 282, 144, 311,
722 285, 269, 287, 288, 289, 266, 10, 275, 276, 294,
723 278, 279, 280, 166, 282, 300, 353, 285, 303, 287,
724 288, 289, 125, 201, 309, 196, 294, 344, 193, 341,
725 315, 10, 300, 338, 400, 303, 106, 120, 323, 324,
726 125, 309, 187, -1, -1, -1, -1, 315, 333, -1,
727 -1, -1, -1, 338, 339, 340, 324, 342, 343, -1,
728 -1, -1, 347, -1, -1, 333, 351, -1, 125, -1,
729 338, 339, 340, -1, 342, 343, -1, -1, -1, 347,
730 -1, 10, -1, 351, 269, -1, -1, -1, -1, -1,
731 275, 276, -1, 278, 279, 280, -1, 282, -1, -1,
732 285, 269, 287, -1, -1, 259, -1, 275, 276, 294,
733 278, 279, 125, -1, 282, 300, -1, 285, 303, 287,
734 -1, 125, 10, -1, 309, -1, 294, -1, -1, -1,
735 315, -1, 300, -1, -1, 303, -1, -1, 292, 324,
736 -1, 309, -1, -1, -1, -1, 125, 315, 333, 303,
737 -1, 305, -1, 338, 339, 340, 324, 342, 343, -1,
738 -1, -1, 347, -1, -1, 333, 351, -1, -1, 272,
739 338, 339, 340, 327, 342, 343, 279, 331, 332, 347,
740 -1, 266, -1, 351, 287, 270, -1, 272, -1, -1,
741 -1, -1, 295, -1, 279, -1, 125, -1, -1, 10,
742 -1, -1, 287, 288, 289, 290, 291, -1, -1, 266,
743 295, 314, -1, 270, -1, 272, 301, -1, -1, 10,
744 -1, -1, 279, 326, -1, 310, 311, 330, -1, 314,
745 287, 288, 289, 290, 291, -1, -1, 125, 295, -1,
746 -1, 326, -1, 346, 301, 330, -1, -1, -1, 334,
747 -1, -1, -1, 310, 311, -1, 341, 314, -1, -1,
748 345, 346, 275, 276, -1, 350, 351, -1, 272, 326,
749 -1, -1, 285, 330, 287, 279, -1, 334, -1, -1,
750 -1, -1, -1, 287, 341, -1, -1, -1, 345, 346,
751 269, 295, -1, 350, 351, -1, 275, 276, -1, 278,
752 279, -1, 10, 282, -1, -1, 285, -1, 287, -1,
753 314, 324, -1, -1, 125, 294, -1, -1, -1, 10,
754 333, 300, 326, -1, 303, -1, 330, 340, -1, 342,
755 309, -1, -1, -1, 125, -1, 315, -1, 351, -1,
756 269, -1, 346, -1, -1, 324, 275, 276, -1, 278,
757 279, 10, -1, 282, 333, -1, 285, -1, 287, 338,
758 339, 340, -1, 342, -1, 294, -1, -1, 347, -1,
759 -1, 300, 351, -1, 303, -1, -1, -1, -1, -1,
760 309, 269, -1, -1, 10, -1, 315, 275, 276, -1,
761 278, 279, -1, -1, 282, 324, -1, 285, -1, 287,
762 10, -1, -1, -1, 333, -1, 294, -1, 10, 338,
763 339, 340, 300, 342, -1, 303, -1, 125, 347, -1,
764 -1, 309, 351, -1, -1, -1, -1, 315, 10, -1,
765 -1, -1, -1, -1, 125, -1, 324, -1, -1, -1,
766 -1, -1, -1, -1, -1, 333, -1, -1, -1, -1,
767 338, 339, 340, -1, 342, -1, -1, -1, 269, 347,
768 -1, -1, -1, 351, 275, 276, 125, 278, 279, -1,
769 -1, 282, -1, -1, 285, -1, 287, -1, 269, -1,
770 -1, -1, -1, 294, 275, 276, -1, 278, 279, 300,
771 -1, 282, 303, 10, 285, -1, 287, -1, 309, 125,
772 -1, -1, -1, 294, 315, -1, -1, -1, -1, 300,
773 -1, -1, 303, 324, -1, 125, -1, -1, 309, -1,
774 -1, -1, 333, 125, 315, -1, -1, 338, 339, 340,
775 -1, 342, 125, 324, -1, -1, 347, -1, -1, -1,
776 351, -1, 333, 125, -1, -1, -1, 338, 339, 340,
777 -1, 342, -1, -1, -1, -1, 347, -1, -1, -1,
778 351, 269, -1, -1, -1, -1, -1, 275, 276, -1,
779 278, 279, -1, -1, 282, -1, -1, 285, 269, 287,
780 -1, -1, -1, -1, 275, 276, 294, 278, 279, -1,
781 -1, 282, 300, -1, 285, 303, 287, -1, -1, -1,
782 -1, 309, -1, 294, -1, -1, -1, 315, 125, 300,
783 -1, -1, 303, 272, -1, -1, 324, -1, 309, -1,
784 279, -1, -1, -1, 315, 333, 125, -1, 287, -1,
785 338, 339, 340, 324, 342, -1, 295, -1, -1, 347,
786 -1, -1, 333, 351, -1, -1, 272, 338, 339, 340,
787 -1, 342, 125, 279, -1, 314, 347, -1, -1, -1,
788 351, 287, 288, 289, 290, 275, 276, 326, -1, 295,
789 -1, 330, -1, 275, 276, 285, -1, 287, -1, 272,
790 -1, -1, -1, 285, 310, 287, 279, 346, 314, -1,
791 272, -1, 272, -1, 287, -1, -1, 279, -1, 279,
792 326, -1, 295, -1, 330, 287, -1, 287, 334, -1,
793 -1, -1, -1, 295, 324, 295, -1, -1, -1, 345,
794 346, 314, 324, 333, 350, 351, -1, -1, 310, 125,
795 340, 333, 342, 326, 314, -1, -1, 330, 340, -1,
796 342, 351, -1, -1, 326, -1, 326, -1, 330, 351,
797 330, -1, 334, 346, -1, 272, -1, -1, -1, -1,
798 -1, -1, 279, -1, 346, -1, 346, -1, -1, 351,
799 287, 288, 289, 272, -1, -1, -1, -1, 295, -1,
800 279, -1, -1, -1, -1, -1, 259, -1, 287, -1,
801 263, -1, -1, -1, 267, -1, 295, 314, -1, 272,
802 -1, -1, 275, 276, -1, -1, 279, -1, -1, 326,
803 283, 310, 285, 330, 287, -1, -1, -1, -1, 292,
804 293, -1, 295, -1, -1, -1, -1, 326, -1, 346,
805 303, 330, 305, -1, -1, 334, -1, 310, -1, -1,
806 -1, 314, -1, -1, -1, -1, -1, 346, -1, -1,
807 -1, 324, 351, 326, 327, -1, -1, 330, 331, 332,
808 333, 334, -1, 336, 275, 276, -1, 340, -1, 342,
809 -1, -1, 345, 346, 285, -1, 287, 350, 351, 275,
810 276, -1, -1, -1, -1, 272, 359, 360, -1, 285,
811 -1, 287, 279, -1, -1, -1, 369, 370, -1, -1,
812 287, -1, 269, -1, -1, -1, -1, -1, 295, 275,
813 276, 278, 279, 324, -1, 282, -1, -1, -1, 285,
814 -1, 287, 333, 310, -1, -1, -1, 294, 324, 340,
815 -1, 342, -1, 300, -1, -1, 303, 333, -1, 326,
816 351, -1, 309, 330, 340, -1, 342, 334, 315, -1,
817 -1, -1, -1, -1, -1, 351, -1, -1, 324, 346,
818 -1, -1, -1, -1, 351, -1, -1, 333, -1, -1,
819 -1, 338, 339, -1, 340, -1, 342, -1, -1, -1,
820 347, -1, -1, -1, -1, 351,
821};
822#define YYFINAL1 1
823#ifndef YYDEBUG0
824#define YYDEBUG0 0
825#endif
826#define YYMAXTOKEN371 371
827#if YYDEBUG0
828const char * const yyname[] =
829 {
830"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,
8310,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,"'<'","'='",
832"'>'",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,
8330,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,
8340,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,
8350,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,
8360,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,
8370,"AGENTX","APPEND","BACKLOG","BACKUP","BINARY","BUFFER","CA","CACHE","SET",
838"CHECK","CIPHERS","CODE","COOKIE","DEMOTE","DIGEST","DISABLE","ERROR","EXPECT",
839"PASS","BLOCK","EXTERNAL","FILENAME","FORWARD","FROM","HASH","HEADER",
840"HEADERLEN","HOST","HTTP","ICMP","INCLUDE","INET","INET6","INTERFACE",
841"INTERVAL","IP","KEYPAIR","LABEL","LISTEN","VALUE","LOADBALANCE","LOG","LOOKUP",
842"METHOD","MODE","NAT","NO","DESTINATION","NODELAY","NOTHING","ON","PARENT",
843"PATH","PFTAG","PORT","PREFORK","PRIORITY","PROTO","QUERYSTR","REAL","REDIRECT",
844"RELAY","REMOVE","REQUEST","RESPONSE","RETRY","QUICK","RETURN","ROUNDROBIN",
845"ROUTE","SACK","SCRIPT","SEND","SESSION","SOCKET","SPLICE","SSL","STICKYADDR",
846"STRIP","STYLE","TABLE","TAG","TAGGED","TCP","TIMEOUT","TLS","TO","ROUTER",
847"RTLABEL","TRANSPARENT","URL","WITH","TTL","RTABLE","MATCH","PARAMS","RANDOM",
848"LEASTSTATES","SRCHASH","KEY","CERTIFICATE","PASSWORD","ECDHE","EDH","TICKETS",
849"CONNECTION","CONNECTIONS","CONTEXT","ERRORS","STATE","CHANGES","CHECKS",
850"WEBSOCKETS","STRING","NUMBER",
851};
852const char * const yyrule[] =
853 {"$accept : grammar",
854"grammar :",
855"grammar : grammar include '\\n'",
856"grammar : grammar '\\n'",
857"grammar : grammar varset '\\n'",
858"grammar : grammar main '\\n'",
859"grammar : grammar rdr '\\n'",
860"grammar : grammar tabledef '\\n'",
861"grammar : grammar relay '\\n'",
862"grammar : grammar proto '\\n'",
863"grammar : grammar router '\\n'",
864"grammar : grammar error '\\n'",
865"include : INCLUDE STRING",
866"ssltls : SSL",
867"ssltls : TLS",
868"opttls :",
869"opttls : ssltls",
870"opttlsclient :",
871"opttlsclient : WITH ssltls",
872"http_type : HTTP",
873"http_type : STRING",
874"hostname :",
875"hostname : HOST STRING",
876"relay_proto :",
877"relay_proto : TCP",
878"relay_proto : HTTP",
879"relay_proto : STRING",
880"redirect_proto :",
881"redirect_proto : TCP",
882"redirect_proto : STRING",
883"eflags_l : eflags comma eflags_l",
884"eflags_l : eflags",
885"opteflags :",
886"opteflags : eflags",
887"eflags : STYLE STRING",
888"port : PORT HTTP",
889"port : PORT STRING",
890"port : PORT NUMBER",
891"varset : STRING '=' STRING",
892"sendbuf : NOTHING",
893"sendbuf : STRING",
894"sendbinbuf : NOTHING",
895"sendbinbuf : STRING",
896"main : INTERVAL NUMBER",
897"main : LOG loglevel",
898"main : TIMEOUT timeout",
899"main : PREFORK NUMBER",
900"main : AGENTX context path",
901"main : SOCKET STRING",
902"path :",
903"path : PATH STRING",
904"context :",
905"context : CONTEXT STRING",
906"loglevel : STATE CHANGES",
907"loglevel : HOST CHECKS",
908"loglevel : CONNECTION",
909"loglevel : CONNECTION ERRORS",
910"$$1 :",
911"rdr : REDIRECT STRING $$1 '{' optnl rdropts_l '}'",
912"rdropts_l : rdropts_l rdroptsl nl",
913"rdropts_l : rdroptsl optnl",
914"rdroptsl : forwardmode TO tablespec interface",
915"rdroptsl : LISTEN ON STRING redirect_proto port interface",
916"rdroptsl : DISABLE",
917"rdroptsl : STICKYADDR",
918"rdroptsl : match PFTAG STRING",
919"rdroptsl : SESSION TIMEOUT NUMBER",
920"rdroptsl : include",
921"match :",
922"match : MATCH",
923"forwardmode : FORWARD",
924"forwardmode : ROUTE",
925"forwardmode : TRANSPARENT FORWARD",
926"table : '<' STRING '>'",
927"$$2 :",
928"tabledef : TABLE table $$2 tabledefopts_l",
929"tabledefopts_l : tabledefopts_l tabledefopts",
930"tabledefopts_l : tabledefopts",
931"tabledefopts : DISABLE",
932"tabledefopts : '{' optnl tablelist_l '}'",
933"tablelist_l : tablelist comma tablelist_l",
934"tablelist_l : tablelist optnl",
935"tablelist : host",
936"tablelist : include",
937"$$3 :",
938"tablespec : table $$3 tableopts_l",
939"tableopts_l : tableopts tableopts_l",
940"tableopts_l : tableopts",
941"tableopts : CHECK tablecheck",
942"tableopts : port",
943"tableopts : TIMEOUT timeout",
944"tableopts : DEMOTE STRING",
945"tableopts : INTERVAL NUMBER",
946"tableopts : MODE dstmode hashkey",
947"hashkey :",
948"hashkey : STRING",
949"tablecheck : ICMP",
950"tablecheck : TCP",
951"tablecheck : ssltls",
952"tablecheck : http_type STRING hostname CODE NUMBER",
953"tablecheck : http_type STRING hostname digest",
954"tablecheck : SEND sendbuf EXPECT STRING opttls",
955"tablecheck : BINARY SEND sendbinbuf EXPECT STRING opttls",
956"tablecheck : SCRIPT STRING",
957"digest : DIGEST STRING",
958"optdigest : digest",
959"optdigest : STRING",
960"$$4 :",
961"proto : relay_proto PROTO STRING $$4 protopts_n",
962"protopts_n :",
963"protopts_n : '{' '}'",
964"protopts_n : '{' optnl protopts_l '}'",
965"protopts_l : protopts_l protoptsl nl",
966"protopts_l : protoptsl optnl",
967"$$5 :",
968"protoptsl : ssltls $$5 tlsflags",
969"$$6 :",
970"protoptsl : ssltls $$6 '{' tlsflags_l '}'",
971"$$7 :",
972"protoptsl : TCP $$7 tcpflags",
973"$$8 :",
974"protoptsl : TCP $$8 '{' tcpflags_l '}'",
975"$$9 :",
976"protoptsl : HTTP $$9 httpflags",
977"$$10 :",
978"protoptsl : HTTP $$10 '{' httpflags_l '}'",
979"protoptsl : RETURN ERROR opteflags",
980"protoptsl : RETURN ERROR '{' eflags_l '}'",
981"protoptsl : filterrule",
982"protoptsl : include",
983"httpflags_l : httpflags comma httpflags_l",
984"httpflags_l : httpflags",
985"httpflags : HEADERLEN NUMBER",
986"httpflags : WEBSOCKETS",
987"httpflags : NO WEBSOCKETS",
988"tcpflags_l : tcpflags comma tcpflags_l",
989"tcpflags_l : tcpflags",
990"tcpflags : SACK",
991"tcpflags : NO SACK",
992"tcpflags : NODELAY",
993"tcpflags : NO NODELAY",
994"tcpflags : SPLICE",
995"tcpflags : NO SPLICE",
996"tcpflags : BACKLOG NUMBER",
997"tcpflags : SOCKET BUFFER NUMBER",
998"tcpflags : IP STRING NUMBER",
999"tlsflags_l : tlsflags comma tlsflags_l",
1000"tlsflags_l : tlsflags",
1001"tlsflags : SESSION TICKETS",
1002"tlsflags : NO SESSION TICKETS",
1003"tlsflags : CIPHERS STRING",
1004"tlsflags : NO EDH",
1005"tlsflags : EDH",
1006"tlsflags : EDH PARAMS STRING",
1007"tlsflags : ECDHE STRING",
1008"tlsflags : CA FILENAME STRING",
1009"tlsflags : CA KEY STRING PASSWORD STRING",
1010"tlsflags : CA CERTIFICATE STRING",
1011"tlsflags : KEYPAIR STRING",
1012"tlsflags : NO flag",
1013"tlsflags : flag",
1014"flag : STRING",
1015"$$11 :",
1016"filterrule : action dir quick ruleaf rulesrc ruledst $$11 ruleopts_l",
1017"action : PASS",
1018"action : BLOCK",
1019"action : MATCH",
1020"dir :",
1021"dir : REQUEST",
1022"dir : RESPONSE",
1023"quick :",
1024"quick : QUICK",
1025"ruleaf :",
1026"ruleaf : INET6",
1027"ruleaf : INET",
1028"rulesrc :",
1029"rulesrc : FROM addrprefix",
1030"ruledst :",
1031"ruledst : TO addrprefix",
1032"ruleopts_l :",
1033"ruleopts_l : ruleopts_t",
1034"ruleopts_t : ruleopts ruleopts_t",
1035"ruleopts_t : ruleopts",
1036"ruleopts : METHOD STRING",
1037"ruleopts : COOKIE key_option STRING value",
1038"ruleopts : COOKIE key_option",
1039"ruleopts : HEADER key_option STRING value",
1040"ruleopts : HEADER key_option",
1041"ruleopts : PATH key_option STRING value",
1042"ruleopts : PATH key_option",
1043"ruleopts : PATH STRIP NUMBER",
1044"ruleopts : QUERYSTR key_option STRING value",
1045"ruleopts : QUERYSTR key_option",
1046"ruleopts : URL key_option optdigest value",
1047"ruleopts : URL key_option",
1048"ruleopts : FORWARD TO table",
1049"ruleopts : TAG STRING",
1050"ruleopts : NO TAG",
1051"ruleopts : TAGGED STRING",
1052"ruleopts : LABEL STRING",
1053"ruleopts : NO LABEL",
1054"ruleopts : FILENAME STRING value",
1055"value :",
1056"value : VALUE STRING",
1057"key_option :",
1058"key_option : APPEND",
1059"key_option : SET",
1060"key_option : REMOVE",
1061"key_option : HASH",
1062"key_option : LOG",
1063"$$12 :",
1064"relay : RELAY STRING $$12 '{' optnl relayopts_l '}'",
1065"relayopts_l : relayopts_l relayoptsl nl",
1066"relayopts_l : relayoptsl optnl",
1067"relayoptsl : LISTEN ON STRING port opttls",
1068"relayoptsl : forwardmode opttlsclient TO forwardspec dstaf",
1069"relayoptsl : SESSION TIMEOUT NUMBER",
1070"relayoptsl : PROTO STRING",
1071"relayoptsl : DISABLE",
1072"relayoptsl : include",
1073"forwardspec : STRING port retry",
1074"forwardspec : NAT LOOKUP retry",
1075"forwardspec : DESTINATION retry",
1076"forwardspec : tablespec",
1077"dstmode :",
1078"dstmode : LOADBALANCE",
1079"dstmode : ROUNDROBIN",
1080"dstmode : HASH",
1081"dstmode : LEASTSTATES",
1082"dstmode : SRCHASH",
1083"dstmode : RANDOM",
1084"$$13 :",
1085"router : ROUTER STRING $$13 '{' optnl routeopts_l '}'",
1086"routeopts_l : routeopts_l routeoptsl nl",
1087"routeopts_l : routeoptsl optnl",
1088"routeoptsl : ROUTE addrprefix",
1089"routeoptsl : FORWARD TO tablespec",
1090"routeoptsl : RTABLE NUMBER",
1091"routeoptsl : RTLABEL STRING",
1092"routeoptsl : DISABLE",
1093"routeoptsl : include",
1094"dstaf :",
1095"dstaf : INET",
1096"dstaf : INET6 STRING",
1097"interface :",
1098"interface : INTERFACE STRING",
1099"$$14 :",
1100"host : address $$14 opthostflags",
1101"opthostflags :",
1102"opthostflags : hostflags_l",
1103"hostflags_l : hostflags hostflags_l",
1104"hostflags_l : hostflags",
1105"hostflags : RETRY NUMBER",
1106"hostflags : PARENT NUMBER",
1107"hostflags : PRIORITY NUMBER",
1108"hostflags : IP TTL NUMBER",
1109"address : STRING",
1110"addrprefix : address '/' NUMBER",
1111"addrprefix : address",
1112"retry :",
1113"retry : RETRY NUMBER",
1114"timeout : NUMBER",
1115"comma : ','",
1116"comma : nl",
1117"comma :",
1118"optnl : '\\n' optnl",
1119"optnl :",
1120"nl : '\\n' optnl",
1121};
1122#endif
1123#ifdef YYSTACKSIZE10000
1124#undef YYMAXDEPTH10000
1125#define YYMAXDEPTH10000 YYSTACKSIZE10000
1126#else
1127#ifdef YYMAXDEPTH10000
1128#define YYSTACKSIZE10000 YYMAXDEPTH10000
1129#else
1130#define YYSTACKSIZE10000 10000
1131#define YYMAXDEPTH10000 10000
1132#endif
1133#endif
1134#define YYINITSTACKSIZE200 200
1135/* LINTUSED */
1136int yydebug;
1137int yynerrs;
1138int yyerrflag;
1139int yychar;
1140short *yyssp;
1141YYSTYPE *yyvsp;
1142YYSTYPE yyval;
1143YYSTYPE yylval;
1144short *yyss;
1145short *yysslim;
1146YYSTYPE *yyvs;
1147unsigned int yystacksize;
1148int yyparse(void);
1149#line 2369 "/usr/src/usr.sbin/relayd/parse.y"
1150
1151struct keywords {
1152 const char *k_name;
1153 int k_val;
1154};
1155
1156int
1157yyerror(const char *fmt, ...)
1158{
1159 va_list ap;
1160 char *msg;
1161
1162 file->errors++;
1163 va_start(ap, fmt)__builtin_va_start(ap, fmt);
1164 if (vasprintf(&msg, fmt, ap) == -1)
1165 fatalx("yyerror vasprintf");
1166 va_end(ap)__builtin_va_end(ap);
1167 logit(LOG_CRIT2, "%s:%d: %s", file->name, yylval.lineno, msg);
1168 free(msg);
1169 return (0);
1170}
1171
1172int
1173kw_cmp(const void *k, const void *e)
1174{
1175 return (strcmp(k, ((const struct keywords *)e)->k_name));
1176}
1177
1178int
1179lookup(char *s)
1180{
1181 /* this has to be sorted always */
1182 static const struct keywords keywords[] = {
1183 { "agentx", AGENTX257 },
1184 { "append", APPEND258 },
1185 { "backlog", BACKLOG259 },
1186 { "backup", BACKUP260 },
1187 { "binary", BINARY261 },
1188 { "block", BLOCK276 },
1189 { "buffer", BUFFER262 },
1190 { "ca", CA263 },
1191 { "cache", CACHE264 },
1192 { "cert", CERTIFICATE357 },
1193 { "changes", CHANGES367 },
1194 { "check", CHECK266 },
1195 { "checks", CHECKS368 },
1196 { "ciphers", CIPHERS267 },
1197 { "code", CODE268 },
1198 { "connection", CONNECTION362 },
1199 { "context", CONTEXT364 },
1200 { "cookie", COOKIE269 },
1201 { "demote", DEMOTE270 },
1202 { "destination", DESTINATION304 },
1203 { "digest", DIGEST271 },
1204 { "disable", DISABLE272 },
1205 { "ecdhe", ECDHE359 },
1206 { "edh", EDH360 },
1207 { "error", ERROR273 },
1208 { "errors", ERRORS365 },
1209 { "expect", EXPECT274 },
1210 { "external", EXTERNAL277 },
1211 { "file", FILENAME278 },
1212 { "forward", FORWARD279 },
1213 { "from", FROM280 },
1214 { "hash", HASH281 },
1215 { "header", HEADER282 },
1216 { "headerlen", HEADERLEN283 },
1217 { "host", HOST284 },
1218 { "http", HTTP285 },
1219 { "icmp", ICMP286 },
1220 { "include", INCLUDE287 },
1221 { "inet", INET288 },
1222 { "inet6", INET6289 },
1223 { "interface", INTERFACE290 },
1224 { "interval", INTERVAL291 },
1225 { "ip", IP292 },
1226 { "key", KEY356 },
1227 { "keypair", KEYPAIR293 },
1228 { "label", LABEL294 },
1229 { "least-states", LEASTSTATES354 },
1230 { "listen", LISTEN295 },
1231 { "loadbalance", LOADBALANCE297 },
1232 { "log", LOG298 },
1233 { "lookup", LOOKUP299 },
1234 { "match", MATCH351 },
1235 { "method", METHOD300 },
1236 { "mode", MODE301 },
1237 { "nat", NAT302 },
1238 { "no", NO303 },
1239 { "nodelay", NODELAY305 },
1240 { "nothing", NOTHING306 },
1241 { "on", ON307 },
1242 { "params", PARAMS352 },
1243 { "parent", PARENT308 },
1244 { "pass", PASS275 },
1245 { "password", PASSWORD358 },
1246 { "path", PATH309 },
1247 { "pftag", PFTAG310 },
1248 { "port", PORT311 },
1249 { "prefork", PREFORK312 },
1250 { "priority", PRIORITY313 },
1251 { "protocol", PROTO314 },
1252 { "query", QUERYSTR315 },
1253 { "quick", QUICK323 },
1254 { "random", RANDOM353 },
1255 { "real", REAL316 },
1256 { "redirect", REDIRECT317 },
1257 { "relay", RELAY318 },
1258 { "remove", REMOVE319 },
1259 { "request", REQUEST320 },
1260 { "response", RESPONSE321 },
1261 { "retry", RETRY322 },
1262 { "return", RETURN324 },
1263 { "roundrobin", ROUNDROBIN325 },
1264 { "route", ROUTE326 },
1265 { "router", ROUTER344 },
1266 { "rtable", RTABLE350 },
1267 { "rtlabel", RTLABEL345 },
1268 { "sack", SACK327 },
1269 { "script", SCRIPT328 },
1270 { "send", SEND329 },
1271 { "session", SESSION330 },
1272 { "set", SET265 },
1273 { "socket", SOCKET331 },
1274 { "source-hash", SRCHASH355 },
1275 { "splice", SPLICE332 },
1276 { "ssl", SSL333 },
1277 { "state", STATE366 },
1278 { "sticky-address", STICKYADDR334 },
1279 { "strip", STRIP335 },
1280 { "style", STYLE336 },
1281 { "table", TABLE337 },
1282 { "tag", TAG338 },
1283 { "tagged", TAGGED339 },
1284 { "tcp", TCP340 },
1285 { "tickets", TICKETS361 },
1286 { "timeout", TIMEOUT341 },
1287 { "tls", TLS342 },
1288 { "to", TO343 },
1289 { "transparent", TRANSPARENT346 },
1290 { "ttl", TTL349 },
1291 { "url", URL347 },
1292 { "value", VALUE296 },
1293 { "websockets", WEBSOCKETS369 },
1294 { "with", WITH348 }
1295 };
1296 const struct keywords *p;
1297
1298 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
1299 sizeof(keywords[0]), kw_cmp);
1300
1301 if (p)
1302 return (p->k_val);
1303 else
1304 return (STRING370);
1305}
1306
1307
1308#define START_EXPAND1 1
1309#define DONE_EXPAND2 2
1310
1311static int expanding;
1312
1313int
1314igetc(void)
1315{
1316 int c;
1317
1318 while (1) {
1319 if (file->ungetpos > 0)
1320 c = file->ungetbuf[--file->ungetpos];
1321 else c = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget
(file->stream) : (int)(*(file->stream)->_p++)) : (getc
)(file->stream))
;
1322
1323 if (c == START_EXPAND1)
1324 expanding = 1;
1325 else if (c == DONE_EXPAND2)
1326 expanding = 0;
1327 else
1328 break;
1329 }
1330 return (c);
1331}
1332
1333int
1334lgetc(int quotec)
1335{
1336 int c, next;
1337
1338 if (quotec) {
1339 if ((c = igetc()) == EOF(-1)) {
1340 yyerror("reached end of file while parsing "
1341 "quoted string");
1342 if (file == topfile || popfile() == EOF(-1))
1343 return (EOF(-1));
1344 return (quotec);
1345 }
1346 return (c);
1347 }
1348
1349 while ((c = igetc()) == '\\') {
1350 next = igetc();
1351 if (next != '\n') {
1352 c = next;
1353 break;
1354 }
1355 yylval.lineno = file->lineno;
1356 file->lineno++;
1357 }
1358
1359 if (c == EOF(-1)) {
1360 /*
1361 * Fake EOL when hit EOF for the first time. This gets line
1362 * count right if last line in included file is syntactically
1363 * invalid and has no newline.
1364 */
1365 if (file->eof_reached == 0) {
1366 file->eof_reached = 1;
1367 return ('\n');
1368 }
1369 while (c == EOF(-1)) {
1370 if (file == topfile || popfile() == EOF(-1))
1371 return (EOF(-1));
1372 c = igetc();
1373 }
1374 }
1375 return (c);
1376}
1377
1378void
1379lungetc(int c)
1380{
1381 if (c == EOF(-1))
1382 return;
1383
1384 if (file->ungetpos >= file->ungetsize) {
1385 void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
1386 if (p == NULL((void*)0))
1387 err(1, "%s", __func__);
1388 file->ungetbuf = p;
1389 file->ungetsize *= 2;
1390 }
1391 file->ungetbuf[file->ungetpos++] = c;
1392}
1393
1394int
1395findeol(void)
1396{
1397 int c;
1398
1399 /* skip to either EOF or the first real EOL */
1400 while (1) {
1401 c = lgetc(0);
1402 if (c == '\n') {
1403 file->lineno++;
1404 break;
1405 }
1406 if (c == EOF(-1))
1407 break;
1408 }
1409 return (ERROR273);
1410}
1411
1412int
1413yylex(void)
1414{
1415 char buf[8096];
1416 char *p, *val;
1417 int quotec, next, c;
1418 int token;
1419
1420top:
1421 p = buf;
1422 while ((c = lgetc(0)) == ' ' || c == '\t')
1423 ; /* nothing */
1424
1425 yylval.lineno = file->lineno;
1426 if (c == '#')
1427 while ((c = lgetc(0)) != '\n' && c != EOF(-1))
1428 ; /* nothing */
1429 if (c == '$' && !expanding) {
1430 while (1) {
1431 if ((c = lgetc(0)) == EOF(-1))
1432 return (0);
1433
1434 if (p + 1 >= buf + sizeof(buf) - 1) {
1435 yyerror("string too long");
1436 return (findeol());
1437 }
1438 if (isalnum(c) || c == '_') {
1439 *p++ = c;
1440 continue;
1441 }
1442 *p = '\0';
1443 lungetc(c);
1444 break;
1445 }
1446 val = symget(buf);
1447 if (val == NULL((void*)0)) {
1448 yyerror("macro '%s' not defined", buf);
1449 return (findeol());
1450 }
1451 p = val + strlen(val) - 1;
1452 lungetc(DONE_EXPAND2);
1453 while (p >= val) {
1454 lungetc((unsigned char)*p);
1455 p--;
1456 }
1457 lungetc(START_EXPAND1);
1458 goto top;
1459 }
1460
1461 switch (c) {
1462 case '\'':
1463 case '"':
1464 quotec = c;
1465 while (1) {
1466 if ((c = lgetc(quotec)) == EOF(-1))
1467 return (0);
1468 if (c == '\n') {
1469 file->lineno++;
1470 continue;
1471 } else if (c == '\\') {
1472 if ((next = lgetc(quotec)) == EOF(-1))
1473 return (0);
1474 if (next == quotec || next == ' ' ||
1475 next == '\t')
1476 c = next;
1477 else if (next == '\n') {
1478 file->lineno++;
1479 continue;
1480 } else
1481 lungetc(next);
1482 } else if (c == quotec) {
1483 *p = '\0';
1484 break;
1485 } else if (c == '\0') {
1486 yyerror("syntax error");
1487 return (findeol());
1488 }
1489 if (p + 1 >= buf + sizeof(buf) - 1) {
1490 yyerror("string too long");
1491 return (findeol());
1492 }
1493 *p++ = c;
1494 }
1495 yylval.v.string = strdup(buf);
1496 if (yylval.v.string == NULL((void*)0))
1497 err(1, "%s", __func__);
1498 return (STRING370);
1499 }
1500
1501#define allowed_to_end_number(x)(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' ||
x == '=')
\
1502 (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
1503
1504 if (c == '-' || isdigit(c)) {
1505 do {
1506 *p++ = c;
1507 if ((size_t)(p-buf) >= sizeof(buf)) {
1508 yyerror("string too long");
1509 return (findeol());
1510 }
1511 } while ((c = lgetc(0)) != EOF(-1) && isdigit(c));
1512 lungetc(c);
1513 if (p == buf + 1 && buf[0] == '-')
1514 goto nodigits;
1515 if (c == EOF(-1) || allowed_to_end_number(c)(isspace(c) || c == ')' || c ==',' || c == '/' || c == '}' ||
c == '=')
) {
1516 const char *errstr = NULL((void*)0);
1517
1518 *p = '\0';
1519 yylval.v.number = strtonum(buf, LLONG_MIN(-9223372036854775807LL -1LL),
1520 LLONG_MAX9223372036854775807LL, &errstr);
1521 if (errstr) {
1522 yyerror("\"%s\" invalid number: %s",
1523 buf, errstr);
1524 return (findeol());
1525 }
1526 return (NUMBER371);
1527 } else {
1528nodigits:
1529 while (p > buf + 1)
1530 lungetc((unsigned char)*--p);
1531 c = (unsigned char)*--p;
1532 if (c == '-')
1533 return (c);
1534 }
1535 }
1536
1537#define allowed_in_string(x)(isalnum(x) || (ispunct(x) && x != '(' && x !=
')' && x != '{' && x != '}' && x != '<'
&& x != '>' && x != '!' && x != '='
&& x != '#' && x != ',' && x != '/')
)
\
1538 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1539 x != '{' && x != '}' && x != '<' && x != '>' && \
1540 x != '!' && x != '=' && x != '#' && \
1541 x != ',' && x != '/'))
1542
1543 if (isalnum(c) || c == ':' || c == '_') {
1544 do {
1545 *p++ = c;
1546 if ((size_t)(p-buf) >= sizeof(buf)) {
1547 yyerror("string too long");
1548 return (findeol());
1549 }
1550 } while ((c = lgetc(0)) != EOF(-1) && (allowed_in_string(c)(isalnum(c) || (ispunct(c) && c != '(' && c !=
')' && c != '{' && c != '}' && c != '<'
&& c != '>' && c != '!' && c != '='
&& c != '#' && c != ',' && c != '/')
)
));
1551 lungetc(c);
1552 *p = '\0';
1553 if ((token = lookup(buf)) == STRING370)
1554 if ((yylval.v.string = strdup(buf)) == NULL((void*)0))
1555 err(1, "%s", __func__);
1556 return (token);
1557 }
1558 if (c == '\n') {
1559 yylval.lineno = file->lineno;
1560 file->lineno++;
1561 }
1562 if (c == EOF(-1))
1563 return (0);
1564 return (c);
1565}
1566
1567int
1568check_file_secrecy(int fd, const char *fname)
1569{
1570 struct stat st;
1571
1572 if (fstat(fd, &st)) {
1573 log_warn("cannot stat %s", fname);
1574 return (-1);
1575 }
1576 if (st.st_uid != 0 && st.st_uid != getuid()) {
1577 log_warnx("%s: owner not root or current user", fname);
1578 return (-1);
1579 }
1580 if (st.st_mode & (S_IWGRP0000020 | S_IXGRP0000010 | S_IRWXO0000007)) {
1581 log_warnx("%s: group writable or world read/writable", fname);
1582 return (-1);
1583 }
1584 return (0);
1585}
1586
1587struct file *
1588pushfile(const char *name, int secret)
1589{
1590 struct file *nfile;
1591
1592 if ((nfile = calloc(1, sizeof(struct file))) == NULL((void*)0)) {
1593 log_warn("%s", __func__);
1594 return (NULL((void*)0));
1595 }
1596 if ((nfile->name = strdup(name)) == NULL((void*)0)) {
1597 log_warn("%s", __func__);
1598 free(nfile);
1599 return (NULL((void*)0));
1600 }
1601 if ((nfile->stream = fopen(nfile->name, "r")) == NULL((void*)0)) {
1602 log_warn("%s: %s", __func__, nfile->name);
1603 free(nfile->name);
1604 free(nfile);
1605 return (NULL((void*)0));
1606 } else if (secret &&
1607 check_file_secrecy(fileno(nfile->stream)(!__isthreaded ? ((nfile->stream)->_file) : (fileno)(nfile
->stream))
, nfile->name)) {
1608 fclose(nfile->stream);
1609 free(nfile->name);
1610 free(nfile);
1611 return (NULL((void*)0));
1612 }
1613 nfile->lineno = TAILQ_EMPTY(&files)(((&files)->tqh_first) == ((void*)0)) ? 1 : 0;
1614 nfile->ungetsize = 16;
1615 nfile->ungetbuf = malloc(nfile->ungetsize);
1616 if (nfile->ungetbuf == NULL((void*)0)) {
1617 log_warn("%s", __func__);
1618 fclose(nfile->stream);
1619 free(nfile->name);
1620 free(nfile);
1621 return (NULL((void*)0));
1622 }
1623 TAILQ_INSERT_TAIL(&files, nfile, entry)do { (nfile)->entry.tqe_next = ((void*)0); (nfile)->entry
.tqe_prev = (&files)->tqh_last; *(&files)->tqh_last
= (nfile); (&files)->tqh_last = &(nfile)->entry
.tqe_next; } while (0)
;
1624 return (nfile);
1625}
1626
1627int
1628popfile(void)
1629{
1630 struct file *prev;
1631
1632 if ((prev = TAILQ_PREV(file, files, entry)(*(((struct files *)((file)->entry.tqe_prev))->tqh_last
))
) != NULL((void*)0))
1633 prev->errors += file->errors;
1634
1635 TAILQ_REMOVE(&files, file, entry)do { if (((file)->entry.tqe_next) != ((void*)0)) (file)->
entry.tqe_next->entry.tqe_prev = (file)->entry.tqe_prev
; else (&files)->tqh_last = (file)->entry.tqe_prev;
*(file)->entry.tqe_prev = (file)->entry.tqe_next; ; ; }
while (0)
;
1636 fclose(file->stream);
1637 free(file->name);
1638 free(file->ungetbuf);
1639 free(file);
1640 file = prev;
1641 return (file ? 0 : EOF(-1));
1642}
1643
1644int
1645parse_config(const char *filename, struct relayd *x_conf)
1646{
1647 struct sym *sym, *next;
1648
1649 conf = x_conf;
1650 if (config_init(conf) == -1) {
1651 log_warn("%s: cannot initialize configuration", __func__);
1652 return (-1);
1653 }
1654
1655 errors = 0;
1656
1657 if ((file = pushfile(filename, 0)) == NULL((void*)0))
1658 return (-1);
1659
1660 topfile = file;
1661 setservent(1);
1662
1663 yyparse();
1664 errors = file->errors;
1665 while (popfile() != EOF(-1))
1666 ;
1667
1668 endservent();
1669 endprotoent();
1670
1671 /* Free macros */
1672 TAILQ_FOREACH_SAFE(sym, &symhead, entry, next)for ((sym) = ((&symhead)->tqh_first); (sym) != ((void*
)0) && ((next) = ((sym)->entry.tqe_next), 1); (sym
) = (next))
{
1673 if (!sym->persist) {
1674 free(sym->nam);
1675 free(sym->val);
1676 TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void*)0)) (sym)->
entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev;
else (&symhead)->tqh_last = (sym)->entry.tqe_prev;
*(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while
(0)
;
1677 free(sym);
1678 }
1679 }
1680
1681 return (errors ? -1 : 0);
1682}
1683
1684int
1685load_config(const char *filename, struct relayd *x_conf)
1686{
1687 struct sym *sym, *next;
1688 struct table *nexttb;
1689 struct host *h, *ph;
1690 struct relay_table *rlt;
1691
1692 conf = x_conf;
1693 conf->sc_conf.flags = 0;
1694
1695 loadcfg = 1;
1696 errors = 0;
1697 last_host_id = last_table_id = last_rdr_id = last_proto_id =
1698 last_relay_id = last_rt_id = last_nr_id = 0;
1699
1700 rdr = NULL((void*)0);
1701 table = NULL((void*)0);
1702 rlay = NULL((void*)0);
1703 proto = NULL((void*)0);
1704 router = NULL((void*)0);
1705
1706 if ((file = pushfile(filename, 0)) == NULL((void*)0))
1707 return (-1);
1708
1709 topfile = file;
1710 setservent(1);
1711
1712 yyparse();
1713 errors = file->errors;
1714 while (popfile() != EOF(-1))
1715 ;
1716
1717 endservent();
1718 endprotoent();
1719
1720 /* Free macros and check which have not been used. */
1721 for (sym = TAILQ_FIRST(&symhead)((&symhead)->tqh_first); sym != NULL((void*)0); sym = next) {
1722 next = TAILQ_NEXT(sym, entry)((sym)->entry.tqe_next);
1723 if ((conf->sc_conf.opts & RELAYD_OPT_VERBOSE0x01) && !sym->used)
1724 fprintf(stderr(&__sF[2]), "warning: macro '%s' not "
1725 "used\n", sym->nam);
1726 if (!sym->persist) {
1727 free(sym->nam);
1728 free(sym->val);
1729 TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void*)0)) (sym)->
entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev;
else (&symhead)->tqh_last = (sym)->entry.tqe_prev;
*(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while
(0)
;
1730 free(sym);
1731 }
1732 }
1733
1734 if (TAILQ_EMPTY(conf->sc_rdrs)(((conf->sc_rdrs)->tqh_first) == ((void*)0)) &&
1735 TAILQ_EMPTY(conf->sc_relays)(((conf->sc_relays)->tqh_first) == ((void*)0)) &&
1736 TAILQ_EMPTY(conf->sc_rts)(((conf->sc_rts)->tqh_first) == ((void*)0))) {
1737 log_warnx("no actions, nothing to do");
1738 errors++;
1739 }
1740
1741 /* Cleanup relay list to inherit */
1742 while ((rlay = TAILQ_FIRST(&relays)((&relays)->tqh_first)) != NULL((void*)0)) {
1743 TAILQ_REMOVE(&relays, rlay, rl_entry)do { if (((rlay)->rl_entry.tqe_next) != ((void*)0)) (rlay)
->rl_entry.tqe_next->rl_entry.tqe_prev = (rlay)->rl_entry
.tqe_prev; else (&relays)->tqh_last = (rlay)->rl_entry
.tqe_prev; *(rlay)->rl_entry.tqe_prev = (rlay)->rl_entry
.tqe_next; ; ; } while (0)
;
1744 while ((rlt = TAILQ_FIRST(&rlay->rl_tables)((&rlay->rl_tables)->tqh_first))) {
1745 TAILQ_REMOVE(&rlay->rl_tables, rlt, rlt_entry)do { if (((rlt)->rlt_entry.tqe_next) != ((void*)0)) (rlt)->
rlt_entry.tqe_next->rlt_entry.tqe_prev = (rlt)->rlt_entry
.tqe_prev; else (&rlay->rl_tables)->tqh_last = (rlt
)->rlt_entry.tqe_prev; *(rlt)->rlt_entry.tqe_prev = (rlt
)->rlt_entry.tqe_next; ; ; } while (0)
;
1746 free(rlt);
1747 }
1748 free(rlay);
1749 }
1750
1751 if (timercmp(&conf->sc_conf.timeout, &conf->sc_conf.interval, >=)(((&conf->sc_conf.timeout)->tv_sec == (&conf->
sc_conf.interval)->tv_sec) ? ((&conf->sc_conf.timeout
)->tv_usec >= (&conf->sc_conf.interval)->tv_usec
) : ((&conf->sc_conf.timeout)->tv_sec >= (&conf
->sc_conf.interval)->tv_sec))
) {
1752 log_warnx("global timeout exceeds interval");
1753 errors++;
1754 }
1755
1756 /* Verify that every table is used */
1757 for (table = TAILQ_FIRST(conf->sc_tables)((conf->sc_tables)->tqh_first); table != NULL((void*)0);
1758 table = nexttb) {
1759 nexttb = TAILQ_NEXT(table, entry)((table)->entry.tqe_next);
1760 if (table->conf.port == 0) {
1761 TAILQ_REMOVE(conf->sc_tables, table, entry)do { if (((table)->entry.tqe_next) != ((void*)0)) (table)->
entry.tqe_next->entry.tqe_prev = (table)->entry.tqe_prev
; else (conf->sc_tables)->tqh_last = (table)->entry.
tqe_prev; *(table)->entry.tqe_prev = (table)->entry.tqe_next
; ; ; } while (0)
;
1762 while ((h = TAILQ_FIRST(&table->hosts)((&table->hosts)->tqh_first)) != NULL((void*)0)) {
1763 TAILQ_REMOVE(&table->hosts, h, entry)do { if (((h)->entry.tqe_next) != ((void*)0)) (h)->entry
.tqe_next->entry.tqe_prev = (h)->entry.tqe_prev; else (
&table->hosts)->tqh_last = (h)->entry.tqe_prev; *
(h)->entry.tqe_prev = (h)->entry.tqe_next; ; ; } while (
0)
;
1764 free(h);
1765 }
1766 if (table->sendbuf != NULL((void*)0))
1767 free(table->sendbuf);
1768 if (table->sendbinbuf != NULL((void*)0))
1769 ibuf_free(table->sendbinbuf);
1770 free(table);
1771 continue;
1772 }
1773
1774 TAILQ_FOREACH(h, &table->hosts, entry)for((h) = ((&table->hosts)->tqh_first); (h) != ((void
*)0); (h) = ((h)->entry.tqe_next))
{
1775 if (h->conf.parentid) {
1776 ph = host_find(conf, h->conf.parentid);
1777
1778 /* Validate the parent id */
1779 if (h->conf.id == h->conf.parentid ||
1780 ph == NULL((void*)0) || ph->conf.parentid)
1781 ph = NULL((void*)0);
1782
1783 if (ph == NULL((void*)0)) {
1784 log_warnx("host parent id %d invalid",
1785 h->conf.parentid);
1786 errors++;
1787 } else
1788 SLIST_INSERT_HEAD(&ph->children,do { (h)->child.sle_next = (&ph->children)->slh_first
; (&ph->children)->slh_first = (h); } while (0)
1789 h, child)do { (h)->child.sle_next = (&ph->children)->slh_first
; (&ph->children)->slh_first = (h); } while (0)
;
1790 }
1791 }
1792
1793 if (!(table->conf.flags & F_USED0x00000004)) {
1794 log_warnx("unused table: %s", table->conf.name);
1795 errors++;
1796 }
1797 if (timercmp(&table->conf.timeout,(((&table->conf.timeout)->tv_sec == (&conf->
sc_conf.interval)->tv_sec) ? ((&table->conf.timeout
)->tv_usec >= (&conf->sc_conf.interval)->tv_usec
) : ((&table->conf.timeout)->tv_sec >= (&conf
->sc_conf.interval)->tv_sec))
1798 &conf->sc_conf.interval, >=)(((&table->conf.timeout)->tv_sec == (&conf->
sc_conf.interval)->tv_sec) ? ((&table->conf.timeout
)->tv_usec >= (&conf->sc_conf.interval)->tv_usec
) : ((&table->conf.timeout)->tv_sec >= (&conf
->sc_conf.interval)->tv_sec))
) {
1799 log_warnx("table timeout exceeds interval: %s",
1800 table->conf.name);
1801 errors++;
1802 }
1803 }
1804
1805 /* Verify that every non-default protocol is used */
1806 TAILQ_FOREACH(proto, conf->sc_protos, entry)for((proto) = ((conf->sc_protos)->tqh_first); (proto) !=
((void*)0); (proto) = ((proto)->entry.tqe_next))
{
1807 if (!(proto->flags & F_USED0x00000004)) {
1808 log_warnx("unused protocol: %s", proto->name);
1809 }
1810 }
1811
1812 return (errors ? -1 : 0);
1813}
1814
1815int
1816symset(const char *nam, const char *val, int persist)
1817{
1818 struct sym *sym;
1819
1820 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void*)
0); (sym) = ((sym)->entry.tqe_next))
{
1821 if (strcmp(nam, sym->nam) == 0)
1822 break;
1823 }
1824
1825 if (sym != NULL((void*)0)) {
1826 if (sym->persist == 1)
1827 return (0);
1828 else {
1829 free(sym->nam);
1830 free(sym->val);
1831 TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void*)0)) (sym)->
entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev;
else (&symhead)->tqh_last = (sym)->entry.tqe_prev;
*(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while
(0)
;
1832 free(sym);
1833 }
1834 }
1835 if ((sym = calloc(1, sizeof(*sym))) == NULL((void*)0))
1836 return (-1);
1837
1838 sym->nam = strdup(nam);
1839 if (sym->nam == NULL((void*)0)) {
1840 free(sym);
1841 return (-1);
1842 }
1843 sym->val = strdup(val);
1844 if (sym->val == NULL((void*)0)) {
1845 free(sym->nam);
1846 free(sym);
1847 return (-1);
1848 }
1849 sym->used = 0;
1850 sym->persist = persist;
1851 TAILQ_INSERT_TAIL(&symhead, sym, entry)do { (sym)->entry.tqe_next = ((void*)0); (sym)->entry.tqe_prev
= (&symhead)->tqh_last; *(&symhead)->tqh_last =
(sym); (&symhead)->tqh_last = &(sym)->entry.tqe_next
; } while (0)
;
1852 return (0);
1853}
1854
1855int
1856cmdline_symset(char *s)
1857{
1858 char *sym, *val;
1859 int ret;
1860
1861 if ((val = strrchr(s, '=')) == NULL((void*)0))
1862 return (-1);
1863 sym = strndup(s, val - s);
1864 if (sym == NULL((void*)0))
1865 errx(1, "%s: strndup", __func__);
1866 ret = symset(sym, val + 1, 1);
1867 free(sym);
1868
1869 return (ret);
1870}
1871
1872char *
1873symget(const char *nam)
1874{
1875 struct sym *sym;
1876
1877 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void*)
0); (sym) = ((sym)->entry.tqe_next))
{
1878 if (strcmp(nam, sym->nam) == 0) {
1879 sym->used = 1;
1880 return (sym->val);
1881 }
1882 }
1883 return (NULL((void*)0));
1884}
1885
1886struct address *
1887host_ip(const char *s)
1888{
1889 struct addrinfo hints, *res;
1890 struct address *h = NULL((void*)0);
1891
1892 memset(&hints, 0, sizeof(hints));
1893 hints.ai_family = AF_UNSPEC0;
1894 hints.ai_socktype = SOCK_DGRAM2; /*dummy*/
1895 hints.ai_flags = AI_NUMERICHOST4;
1896 if (getaddrinfo(s, "0", &hints, &res) == 0) {
1897 if (res->ai_family == AF_INET2 ||
1898 res->ai_family == AF_INET624) {
1899 if ((h = calloc(1, sizeof(*h))) == NULL((void*)0))
1900 fatal(NULL((void*)0));
1901 memcpy(&h->ss, res->ai_addr, res->ai_addrlen);
1902 }
1903 freeaddrinfo(res);
1904 }
1905
1906 return (h);
1907}
1908
1909int
1910host_dns(const char *s, struct addresslist *al, int max,
1911 struct portrange *port, const char *ifname, int ipproto)
1912{
1913 struct addrinfo hints, *res0, *res;
1914 int error, cnt = 0;
1915 struct address *h;
1916
1917 if ((cnt = host_if(s, al, max, port, ifname, ipproto)) != 0)
1918 return (cnt);
1919
1920 bzero(&hints, sizeof(hints));
1921 hints.ai_family = AF_UNSPEC0;
1922 hints.ai_socktype = SOCK_DGRAM2; /* DUMMY */
1923 hints.ai_flags = AI_ADDRCONFIG64;
1924 error = getaddrinfo(s, NULL((void*)0), &hints, &res0);
1925 if (error == EAI_AGAIN-3 || error == EAI_NODATA-5 || error == EAI_NONAME-2)
1926 return (0);
1927 if (error) {
1928 log_warnx("%s: could not parse \"%s\": %s", __func__, s,
1929 gai_strerror(error));
1930 return (-1);
1931 }
1932
1933 for (res = res0; res && cnt < max; res = res->ai_next) {
1934 if (res->ai_family != AF_INET2 &&
1935 res->ai_family != AF_INET624)
1936 continue;
1937 if ((h = calloc(1, sizeof(*h))) == NULL((void*)0))
1938 fatal(__func__);
1939
1940 if (port != NULL((void*)0))
1941 bcopy(port, &h->port, sizeof(h->port));
1942 if (ifname != NULL((void*)0)) {
1943 if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
1944 sizeof(h->ifname))
1945 log_warnx("%s: interface name truncated",
1946 __func__);
1947 freeaddrinfo(res0);
1948 free(h);
1949 return (-1);
1950 }
1951 if (ipproto != -1)
1952 h->ipproto = ipproto;
1953
1954 memcpy(&h->ss, res->ai_addr, res->ai_addrlen);
1955
1956 TAILQ_INSERT_HEAD(al, h, entry)do { if (((h)->entry.tqe_next = (al)->tqh_first) != ((void
*)0)) (al)->tqh_first->entry.tqe_prev = &(h)->entry
.tqe_next; else (al)->tqh_last = &(h)->entry.tqe_next
; (al)->tqh_first = (h); (h)->entry.tqe_prev = &(al
)->tqh_first; } while (0)
;
1957 cnt++;
1958 }
1959 if (cnt == max && res) {
1960 log_warnx("%s: %s resolves to more than %d hosts", __func__,
1961 s, max);
1962 }
1963 freeaddrinfo(res0);
1964 return (cnt);
1965}
1966
1967int
1968host_if(const char *s, struct addresslist *al, int max,
1969 struct portrange *port, const char *ifname, int ipproto)
1970{
1971 struct ifaddrs *ifap, *p;
1972 struct sockaddr_in *sain;
1973 struct sockaddr_in6 *sin6;
1974 struct address *h;
1975 int cnt = 0, af;
1976
1977 if (getifaddrs(&ifap) == -1)
1978 fatal("getifaddrs");
1979
1980 /* First search for IPv4 addresses */
1981 af = AF_INET2;
1982
1983 nextaf:
1984 for (p = ifap; p != NULL((void*)0) && cnt < max; p = p->ifa_next) {
1985 if (p->ifa_addr == NULL((void*)0) ||
1986 p->ifa_addr->sa_family != af ||
1987 (strcmp(s, p->ifa_name) != 0 &&
1988 !is_if_in_group(p->ifa_name, s)))
1989 continue;
1990 if ((h = calloc(1, sizeof(*h))) == NULL((void*)0))
1991 fatal("calloc");
1992
1993 if (port != NULL((void*)0))
1994 bcopy(port, &h->port, sizeof(h->port));
1995 if (ifname != NULL((void*)0)) {
1996 if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
1997 sizeof(h->ifname))
1998 log_warnx("%s: interface name truncated",
1999 __func__);
2000 freeifaddrs(ifap);
2001 free(h);
2002 return (-1);
2003 }
2004 if (ipproto != -1)
2005 h->ipproto = ipproto;
2006 h->ss.ss_family = af;
2007
2008 if (af == AF_INET2) {
2009 sain = (struct sockaddr_in *)&h->ss;
2010 sain->sin_len = sizeof(struct sockaddr_in);
2011 sain->sin_addr.s_addr = ((struct sockaddr_in *)
2012 p->ifa_addr)->sin_addr.s_addr;
2013 } else {
2014 sin6 = (struct sockaddr_in6 *)&h->ss;
2015 sin6->sin6_len = sizeof(struct sockaddr_in6);
2016 memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *)
2017 p->ifa_addr)->sin6_addr, sizeof(struct in6_addr));
2018 sin6->sin6_scope_id = ((struct sockaddr_in6 *)
2019 p->ifa_addr)->sin6_scope_id;
2020 }
2021
2022 TAILQ_INSERT_HEAD(al, h, entry)do { if (((h)->entry.tqe_next = (al)->tqh_first) != ((void
*)0)) (al)->tqh_first->entry.tqe_prev = &(h)->entry
.tqe_next; else (al)->tqh_last = &(h)->entry.tqe_next
; (al)->tqh_first = (h); (h)->entry.tqe_prev = &(al
)->tqh_first; } while (0)
;
2023 cnt++;
2024 }
2025 if (af == AF_INET2) {
2026 /* Next search for IPv6 addresses */
2027 af = AF_INET624;
2028 goto nextaf;
2029 }
2030
2031 if (cnt > max) {
2032 log_warnx("%s: %s resolves to more than %d hosts", __func__,
2033 s, max);
2034 }
2035 freeifaddrs(ifap);
2036 return (cnt);
2037}
2038
2039int
2040host(const char *s, struct addresslist *al, int max,
2041 struct portrange *port, const char *ifname, int ipproto)
2042{
2043 struct address *h;
2044
2045 if ((h = host_ip(s)) == NULL((void*)0))
2046 return (host_dns(s, al, max, port, ifname, ipproto));
2047
2048 if (port != NULL((void*)0))
2049 bcopy(port, &h->port, sizeof(h->port));
2050 if (ifname != NULL((void*)0)) {
2051 if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
2052 sizeof(h->ifname)) {
2053 log_warnx("%s: interface name truncated",
2054 __func__);
2055 free(h);
2056 return (-1);
2057 }
2058 }
2059 if (ipproto != -1)
2060 h->ipproto = ipproto;
2061
2062 TAILQ_INSERT_HEAD(al, h, entry)do { if (((h)->entry.tqe_next = (al)->tqh_first) != ((void
*)0)) (al)->tqh_first->entry.tqe_prev = &(h)->entry
.tqe_next; else (al)->tqh_last = &(h)->entry.tqe_next
; (al)->tqh_first = (h); (h)->entry.tqe_prev = &(al
)->tqh_first; } while (0)
;
2063 return (1);
2064}
2065
2066void
2067host_free(struct addresslist *al)
2068{
2069 struct address *h;
2070
2071 while ((h = TAILQ_FIRST(al)((al)->tqh_first)) != NULL((void*)0)) {
2072 TAILQ_REMOVE(al, h, entry)do { if (((h)->entry.tqe_next) != ((void*)0)) (h)->entry
.tqe_next->entry.tqe_prev = (h)->entry.tqe_prev; else (
al)->tqh_last = (h)->entry.tqe_prev; *(h)->entry.tqe_prev
= (h)->entry.tqe_next; ; ; } while (0)
;
2073 free(h);
2074 }
2075}
2076
2077struct table *
2078table_inherit(struct table *tb)
2079{
2080 char pname[TABLE_NAME_SIZE64 + 6];
2081 struct host *h, *dsth;
2082 struct table *dsttb, *oldtb;
2083
2084 /* Get the table or table template */
2085 if ((dsttb = table_findbyname(conf, tb->conf.name)) == NULL((void*)0)) {
2086 yyerror("unknown table %s", tb->conf.name);
2087 goto fail;
2088 }
2089 if (dsttb->conf.port != 0)
2090 fatal("invalid table"); /* should not happen */
2091
2092 if (tb->conf.port == 0) {
2093 yyerror("invalid port");
2094 goto fail;
2095 }
2096
2097 /* Check if a matching table already exists */
2098 if (snprintf(pname, sizeof(pname), "%s:%u",
2099 tb->conf.name, ntohs(tb->conf.port)(__uint16_t)(__builtin_constant_p(tb->conf.port) ? (__uint16_t
)(((__uint16_t)(tb->conf.port) & 0xffU) << 8 | (
(__uint16_t)(tb->conf.port) & 0xff00U) >> 8) : __swap16md
(tb->conf.port))
) >= (int)sizeof(pname)) {
2100 yyerror("invalid table name");
2101 goto fail;
2102 }
2103 if (strlcpy(tb->conf.name, pname, sizeof(tb->conf.name)) >=
2104 sizeof(tb->conf.name)) {
2105 yyerror("invalid table mame");
2106 goto fail;
2107 }
2108 if ((oldtb = table_findbyconf(conf, tb)) != NULL((void*)0)) {
2109 purge_table(conf, NULL((void*)0), tb);
2110 return (oldtb);
2111 }
2112
2113 /* Create a new table */
2114 tb->conf.id = ++last_table_id;
2115 if (last_table_id == INT_MAX2147483647) {
2116 yyerror("too many tables defined");
2117 goto fail;
2118 }
2119 tb->conf.flags |= dsttb->conf.flags;
2120
2121 /* Inherit global table options */
2122 if (tb->conf.timeout.tv_sec == 0 && tb->conf.timeout.tv_usec == 0)
2123 bcopy(&dsttb->conf.timeout, &tb->conf.timeout,
2124 sizeof(struct timeval));
2125
2126 /* Copy the associated hosts */
2127 TAILQ_INIT(&tb->hosts)do { (&tb->hosts)->tqh_first = ((void*)0); (&tb
->hosts)->tqh_last = &(&tb->hosts)->tqh_first
; } while (0)
;
2128 TAILQ_FOREACH(dsth, &dsttb->hosts, entry)for((dsth) = ((&dsttb->hosts)->tqh_first); (dsth) !=
((void*)0); (dsth) = ((dsth)->entry.tqe_next))
{
2129 if ((h = (struct host *)
2130 calloc(1, sizeof (*h))) == NULL((void*)0))
2131 fatal("out of memory");
2132 bcopy(dsth, h, sizeof(*h));
2133 h->conf.id = ++last_host_id;
2134 if (last_host_id == INT_MAX2147483647) {
2135 yyerror("too many hosts defined");
2136 free(h);
2137 goto fail;
2138 }
2139 h->conf.tableid = tb->conf.id;
2140 h->tablename = tb->conf.name;
2141 SLIST_INIT(&h->children){ ((&h->children)->slh_first) = ((void*)0); };
2142 TAILQ_INSERT_TAIL(&tb->hosts, h, entry)do { (h)->entry.tqe_next = ((void*)0); (h)->entry.tqe_prev
= (&tb->hosts)->tqh_last; *(&tb->hosts)->
tqh_last = (h); (&tb->hosts)->tqh_last = &(h)->
entry.tqe_next; } while (0)
;
2143 TAILQ_INSERT_TAIL(&conf->sc_hosts, h, globalentry)do { (h)->globalentry.tqe_next = ((void*)0); (h)->globalentry
.tqe_prev = (&conf->sc_hosts)->tqh_last; *(&conf
->sc_hosts)->tqh_last = (h); (&conf->sc_hosts)->
tqh_last = &(h)->globalentry.tqe_next; } while (0)
;
2144 }
2145
2146 conf->sc_tablecount++;
2147 TAILQ_INSERT_TAIL(conf->sc_tables, tb, entry)do { (tb)->entry.tqe_next = ((void*)0); (tb)->entry.tqe_prev
= (conf->sc_tables)->tqh_last; *(conf->sc_tables)->
tqh_last = (tb); (conf->sc_tables)->tqh_last = &(tb
)->entry.tqe_next; } while (0)
;
2148
2149 return (tb);
2150
2151 fail:
2152 purge_table(conf, NULL((void*)0), tb);
2153 return (NULL((void*)0));
2154}
2155
2156int
2157relay_id(struct relay *rl)
2158{
2159 rl->rl_conf.id = ++last_relay_id;
2160
2161 if (last_relay_id == INT_MAX2147483647)
2162 return (-1);
2163
2164 return (0);
2165}
2166
2167struct relay *
2168relay_inherit(struct relay *ra, struct relay *rb)
2169{
2170 struct relay_config rc;
2171 struct relay_table *rta, *rtb;
2172
2173 bcopy(&rb->rl_conf, &rc, sizeof(rc));
2174 bcopy(ra, rb, sizeof(*rb));
2175
2176 bcopy(&rc.ss, &rb->rl_conf.ss, sizeof(rb->rl_conf.ss));
2177 rb->rl_conf.port = rc.port;
2178 rb->rl_conf.flags =
2179 (ra->rl_conf.flags & ~F_TLS0x00000800) | (rc.flags & F_TLS0x00000800);
2180 if (!(rb->rl_conf.flags & F_TLS0x00000800)) {
2181 rb->rl_tls_cacert_fd = -1;
2182 rb->rl_tls_ca_fd = -1;
2183 }
2184 TAILQ_INIT(&rb->rl_tables)do { (&rb->rl_tables)->tqh_first = ((void*)0); (&
rb->rl_tables)->tqh_last = &(&rb->rl_tables)
->tqh_first; } while (0)
;
2185
2186 if (relay_id(rb) == -1) {
2187 yyerror("too many relays defined");
2188 goto err;
2189 }
2190
2191 if (snprintf(rb->rl_conf.name, sizeof(rb->rl_conf.name), "%s%u:%u",
2192 ra->rl_conf.name, rb->rl_conf.id, ntohs(rc.port)(__uint16_t)(__builtin_constant_p(rc.port) ? (__uint16_t)(((__uint16_t
)(rc.port) & 0xffU) << 8 | ((__uint16_t)(rc.port) &
0xff00U) >> 8) : __swap16md(rc.port))
) >=
2193 (int)sizeof(rb->rl_conf.name)) {
2194 yyerror("invalid relay name");
2195 goto err;
2196 }
2197
2198 if (relay_findbyname(conf, rb->rl_conf.name) != NULL((void*)0) ||
2199 relay_findbyaddr(conf, &rb->rl_conf) != NULL((void*)0)) {
2200 yyerror("relay %s or listener defined twice",
2201 rb->rl_conf.name);
2202 goto err;
2203 }
2204
2205 if (relay_load_certfiles(conf, rb, NULL((void*)0)) == -1) {
2206 yyerror("cannot load certificates for relay %s",
2207 rb->rl_conf.name);
2208 goto err;
2209 }
2210
2211 TAILQ_FOREACH(rta, &ra->rl_tables, rlt_entry)for((rta) = ((&ra->rl_tables)->tqh_first); (rta) !=
((void*)0); (rta) = ((rta)->rlt_entry.tqe_next))
{
2212 if ((rtb = calloc(1, sizeof(*rtb))) == NULL((void*)0)) {
2213 yyerror("cannot allocate relay table");
2214 goto err;
2215 }
2216 rtb->rlt_table = rta->rlt_table;
2217 rtb->rlt_mode = rta->rlt_mode;
2218 rtb->rlt_flags = rta->rlt_flags;
2219
2220 TAILQ_INSERT_TAIL(&rb->rl_tables, rtb, rlt_entry)do { (rtb)->rlt_entry.tqe_next = ((void*)0); (rtb)->rlt_entry
.tqe_prev = (&rb->rl_tables)->tqh_last; *(&rb->
rl_tables)->tqh_last = (rtb); (&rb->rl_tables)->
tqh_last = &(rtb)->rlt_entry.tqe_next; } while (0)
;
2221 }
2222
2223 conf->sc_relaycount++;
2224 SPLAY_INIT(&rlay->rl_sessions)do { (&rlay->rl_sessions)->sph_root = ((void*)0); }
while (0)
;
2225 TAILQ_INSERT_TAIL(conf->sc_relays, rb, rl_entry)do { (rb)->rl_entry.tqe_next = ((void*)0); (rb)->rl_entry
.tqe_prev = (conf->sc_relays)->tqh_last; *(conf->sc_relays
)->tqh_last = (rb); (conf->sc_relays)->tqh_last = &
(rb)->rl_entry.tqe_next; } while (0)
;
2226
2227 return (rb);
2228
2229 err:
2230 while ((rtb = TAILQ_FIRST(&rb->rl_tables)((&rb->rl_tables)->tqh_first))) {
2231 TAILQ_REMOVE(&rb->rl_tables, rtb, rlt_entry)do { if (((rtb)->rlt_entry.tqe_next) != ((void*)0)) (rtb)->
rlt_entry.tqe_next->rlt_entry.tqe_prev = (rtb)->rlt_entry
.tqe_prev; else (&rb->rl_tables)->tqh_last = (rtb)->
rlt_entry.tqe_prev; *(rtb)->rlt_entry.tqe_prev = (rtb)->
rlt_entry.tqe_next; ; ; } while (0)
;
2232 free(rtb);
2233 }
2234 free(rb);
2235 return (NULL((void*)0));
2236}
2237
2238int
2239getservice(char *n)
2240{
2241 struct servent *s;
2242 const char *errstr;
2243 long long llval;
2244
2245 llval = strtonum(n, 0, UINT16_MAX0xffff, &errstr);
2246 if (errstr) {
2247 s = getservbyname(n, "tcp");
2248 if (s == NULL((void*)0))
2249 s = getservbyname(n, "udp");
2250 if (s == NULL((void*)0)) {
2251 yyerror("unknown port %s", n);
2252 return (-1);
2253 }
2254 return (s->s_port);
2255 }
2256
2257 return (htons((u_short)llval)(__uint16_t)(__builtin_constant_p((u_short)llval) ? (__uint16_t
)(((__uint16_t)((u_short)llval) & 0xffU) << 8 | ((__uint16_t
)((u_short)llval) & 0xff00U) >> 8) : __swap16md((u_short
)llval))
);
2258}
2259
2260int
2261is_if_in_group(const char *ifname, const char *groupname)
2262{
2263 unsigned int len;
2264 struct ifgroupreq ifgr;
2265 struct ifg_req *ifg;
2266 int s;
2267 int ret = 0;
2268
2269 if ((s = socket(AF_INET2, SOCK_DGRAM2, 0)) == -1)
2270 err(1, "socket");
2271
2272 memset(&ifgr, 0, sizeof(ifgr));
2273 if (strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ16) >= IFNAMSIZ16)
2274 err(1, "IFNAMSIZ");
2275 if (ioctl(s, SIOCGIFGROUP(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifgroupreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((136)))
, (caddr_t)&ifgr) == -1) {
2276 if (errno(*__errno()) == EINVAL22 || errno(*__errno()) == ENOTTY25)
2277 goto end;
2278 err(1, "SIOCGIFGROUP");
2279 }
2280
2281 len = ifgr.ifgr_len;
2282 ifgr.ifgr_groupsifgr_ifgru.ifgru_groups = calloc(len / sizeof(struct ifg_req),
2283 sizeof(struct ifg_req));
2284 if (ifgr.ifgr_groupsifgr_ifgru.ifgru_groups == NULL((void*)0))
2285 err(1, "getifgroups");
2286 if (ioctl(s, SIOCGIFGROUP(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifgroupreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((136)))
, (caddr_t)&ifgr) == -1)
2287 err(1, "SIOCGIFGROUP");
2288
2289 ifg = ifgr.ifgr_groupsifgr_ifgru.ifgru_groups;
2290 for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
2291 len -= sizeof(struct ifg_req);
2292 if (strcmp(ifg->ifgrq_groupifgrq_ifgrqu.ifgrqu_group, groupname) == 0) {
2293 ret = 1;
2294 break;
2295 }
2296 }
2297 free(ifgr.ifgr_groupsifgr_ifgru.ifgru_groups);
2298
2299end:
2300 close(s);
2301 return (ret);
2302}
2303#line 2296 "parse.c"
2304/* allocate initial stack or double stack size, up to YYMAXDEPTH */
2305static int yygrowstack(void)
2306{
2307 unsigned int newsize;
2308 long sslen;
2309 short *newss;
2310 YYSTYPE *newvs;
2311
2312 if ((newsize = yystacksize) == 0)
3
Assuming the condition is false
4
Taking false branch
2313 newsize = YYINITSTACKSIZE200;
2314 else if (newsize >= YYMAXDEPTH10000)
5
Assuming 'newsize' is < YYMAXDEPTH
6
Taking false branch
2315 return -1;
2316 else if ((newsize *= 2) > YYMAXDEPTH10000)
7
Assuming the condition is false
8
Taking false branch
2317 newsize = YYMAXDEPTH10000;
2318 sslen = yyssp - yyss;
2319#ifdef SIZE_MAX0xffffffffffffffffUL
2320#define YY_SIZE_MAX0xffffffffffffffffUL SIZE_MAX0xffffffffffffffffUL
2321#else
2322#define YY_SIZE_MAX0xffffffffffffffffUL 0xffffffffU
2323#endif
2324 if (newsize && YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newss)
9
Assuming 'newsize' is 0
2325 goto bail;
2326 newss = (short *)realloc(yyss, newsize * sizeof *newss);
2327 if (newss == NULL((void*)0))
10
Assuming 'newss' is not equal to NULL
11
Taking false branch
2328 goto bail;
2329 yyss = newss;
2330 yyssp = newss + sslen;
2331 if (newsize
11.1
'newsize' is 0
&& YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newvs)
2332 goto bail;
2333 newvs = (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs);
2334 if (newvs == NULL((void*)0))
12
Assuming 'newvs' is not equal to NULL
13
Taking false branch
2335 goto bail;
2336 yyvs = newvs;
2337 yyvsp = newvs + sslen;
2338 yystacksize = newsize;
2339 yysslim = yyss + newsize - 1;
2340 return 0;
2341bail:
2342 if (yyss)
2343 free(yyss);
2344 if (yyvs)
2345 free(yyvs);
2346 yyss = yyssp = NULL((void*)0);
2347 yyvs = yyvsp = NULL((void*)0);
2348 yystacksize = 0;
2349 return -1;
2350}
2351
2352#define YYABORTgoto yyabort goto yyabort
2353#define YYREJECTgoto yyabort goto yyabort
2354#define YYACCEPTgoto yyaccept goto yyaccept
2355#define YYERRORgoto yyerrlab goto yyerrlab
2356int
2357yyparse(void)
2358{
2359 int yym, yyn, yystate;
2360#if YYDEBUG0
2361 const char *yys;
2362
2363 if ((yys = getenv("YYDEBUG")))
2364 {
2365 yyn = *yys;
2366 if (yyn >= '0' && yyn <= '9')
2367 yydebug = yyn - '0';
2368 }
2369#endif /* YYDEBUG */
2370
2371 yynerrs = 0;
2372 yyerrflag = 0;
2373 yychar = (-1);
2374
2375 if (yyss == NULL((void*)0) && yygrowstack()) goto yyoverflow;
1
Assuming 'yyss' is equal to NULL
2
Calling 'yygrowstack'
14
Returning from 'yygrowstack'
15
Taking false branch
2376 yyssp = yyss;
2377 yyvsp = yyvs;
2378 *yyssp = yystate = 0;
16
Use of zero-allocated memory
2379
2380yyloop:
2381 if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
2382 if (yychar < 0)
2383 {
2384 if ((yychar = yylex()) < 0) yychar = 0;
2385#if YYDEBUG0
2386 if (yydebug)
2387 {
2388 yys = 0;
2389 if (yychar <= YYMAXTOKEN371) yys = yyname[yychar];
2390 if (!yys) yys = "illegal-symbol";
2391 printf("%sdebug: state %d, reading %d (%s)\n",
2392 YYPREFIX"yy", yystate, yychar, yys);
2393 }
2394#endif
2395 }
2396 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
2397 yyn <= YYTABLESIZE1576 && yycheck[yyn] == yychar)
2398 {
2399#if YYDEBUG0
2400 if (yydebug)
2401 printf("%sdebug: state %d, shifting to state %d\n",
2402 YYPREFIX"yy", yystate, yytable[yyn]);
2403#endif
2404 if (yyssp >= yysslim && yygrowstack())
2405 {
2406 goto yyoverflow;
2407 }
2408 *++yyssp = yystate = yytable[yyn];
2409 *++yyvsp = yylval;
2410 yychar = (-1);
2411 if (yyerrflag > 0) --yyerrflag;
2412 goto yyloop;
2413 }
2414 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
2415 yyn <= YYTABLESIZE1576 && yycheck[yyn] == yychar)
2416 {
2417 yyn = yytable[yyn];
2418 goto yyreduce;
2419 }
2420 if (yyerrflag) goto yyinrecovery;
2421#if defined(__GNUC__4)
2422 goto yynewerror;
2423#endif
2424yynewerror:
2425 yyerror("syntax error");
2426#if defined(__GNUC__4)
2427 goto yyerrlab;
2428#endif
2429yyerrlab:
2430 ++yynerrs;
2431yyinrecovery:
2432 if (yyerrflag < 3)
2433 {
2434 yyerrflag = 3;
2435 for (;;)
2436 {
2437 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE256) >= 0 &&
2438 yyn <= YYTABLESIZE1576 && yycheck[yyn] == YYERRCODE256)
2439 {
2440#if YYDEBUG0
2441 if (yydebug)
2442 printf("%sdebug: state %d, error recovery shifting\
2443 to state %d\n", YYPREFIX"yy", *yyssp, yytable[yyn]);
2444#endif
2445 if (yyssp >= yysslim && yygrowstack())
2446 {
2447 goto yyoverflow;
2448 }
2449 *++yyssp = yystate = yytable[yyn];
2450 *++yyvsp = yylval;
2451 goto yyloop;
2452 }
2453 else
2454 {
2455#if YYDEBUG0
2456 if (yydebug)
2457 printf("%sdebug: error recovery discarding state %d\n",
2458 YYPREFIX"yy", *yyssp);
2459#endif
2460 if (yyssp <= yyss) goto yyabort;
2461 --yyssp;
2462 --yyvsp;
2463 }
2464 }
2465 }
2466 else
2467 {
2468 if (yychar == 0) goto yyabort;
2469#if YYDEBUG0
2470 if (yydebug)
2471 {
2472 yys = 0;
2473 if (yychar <= YYMAXTOKEN371) yys = yyname[yychar];
2474 if (!yys) yys = "illegal-symbol";
2475 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
2476 YYPREFIX"yy", yystate, yychar, yys);
2477 }
2478#endif
2479 yychar = (-1);
2480 goto yyloop;
2481 }
2482yyreduce:
2483#if YYDEBUG0
2484 if (yydebug)
2485 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
2486 YYPREFIX"yy", yystate, yyn, yyrule[yyn]);
2487#endif
2488 yym = yylen[yyn];
2489 if (yym)
2490 yyval = yyvsp[1-yym];
2491 else
2492 memset(&yyval, 0, sizeof yyval);
2493 switch (yyn)
2494 {
2495case 11:
2496#line 212 "/usr/src/usr.sbin/relayd/parse.y"
2497{ file->errors++; }
2498break;
2499case 12:
2500#line 215 "/usr/src/usr.sbin/relayd/parse.y"
2501{
2502 struct file *nfile;
2503
2504 if ((nfile = pushfile(yyvsp[0].v.string, 0)) == NULL((void*)0)) {
2505 yyerror("failed to include file %s", yyvsp[0].v.string);
2506 free(yyvsp[0].v.string);
2507 YYERRORgoto yyerrlab;
2508 }
2509 free(yyvsp[0].v.string);
2510
2511 file = nfile;
2512 lungetc('\n');
2513 }
2514break;
2515case 13:
2516#line 230 "/usr/src/usr.sbin/relayd/parse.y"
2517{
2518 log_warnx("%s:%d: %s",
2519 file->name, yylval.lineno,
2520 "please use the \"tls\" keyword"
2521 " instead of \"ssl\"");
2522 }
2523break;
2524case 15:
2525#line 239 "/usr/src/usr.sbin/relayd/parse.y"
2526{ yyval.v.number = 0; }
2527break;
2528case 16:
2529#line 240 "/usr/src/usr.sbin/relayd/parse.y"
2530{ yyval.v.number = 1; }
2531break;
2532case 17:
2533#line 243 "/usr/src/usr.sbin/relayd/parse.y"
2534{ yyval.v.number = 0; }
2535break;
2536case 18:
2537#line 244 "/usr/src/usr.sbin/relayd/parse.y"
2538{ yyval.v.number = 1; }
2539break;
2540case 19:
2541#line 247 "/usr/src/usr.sbin/relayd/parse.y"
2542{ yyval.v.number = 0; }
2543break;
2544case 20:
2545#line 248 "/usr/src/usr.sbin/relayd/parse.y"
2546{
2547 if (strcmp("https", yyvsp[0].v.string) == 0) {
2548 yyval.v.number = 1;
2549 } else {
2550 yyerror("invalid check type: %s", yyvsp[0].v.string);
2551 free(yyvsp[0].v.string);
2552 YYERRORgoto yyerrlab;
2553 }
2554 free(yyvsp[0].v.string);
2555 }
2556break;
2557case 21:
2558#line 260 "/usr/src/usr.sbin/relayd/parse.y"
2559{
2560 yyval.v.string = strdup("");
2561 if (yyval.v.string == NULL((void*)0))
2562 fatal("calloc");
2563 }
2564break;
2565case 22:
2566#line 265 "/usr/src/usr.sbin/relayd/parse.y"
2567{
2568 if (asprintf(&yyval.v.string, "Host: %s\r\nConnection: close\r\n",
2569 yyvsp[0].v.string) == -1)
2570 fatal("asprintf");
2571 }
2572break;
2573case 23:
2574#line 272 "/usr/src/usr.sbin/relayd/parse.y"
2575{ yyval.v.number = RELAY_PROTO_TCP; }
2576break;
2577case 24:
2578#line 273 "/usr/src/usr.sbin/relayd/parse.y"
2579{ yyval.v.number = RELAY_PROTO_TCP; }
2580break;
2581case 25:
2582#line 274 "/usr/src/usr.sbin/relayd/parse.y"
2583{ yyval.v.number = RELAY_PROTO_HTTP; }
2584break;
2585case 26:
2586#line 275 "/usr/src/usr.sbin/relayd/parse.y"
2587{
2588 if (strcmp("dns", yyvsp[0].v.string) == 0) {
2589 yyval.v.number = RELAY_PROTO_DNS;
2590 } else {
2591 yyerror("invalid protocol type: %s", yyvsp[0].v.string);
2592 free(yyvsp[0].v.string);
2593 YYERRORgoto yyerrlab;
2594 }
2595 free(yyvsp[0].v.string);
2596 }
2597break;
2598case 27:
2599#line 287 "/usr/src/usr.sbin/relayd/parse.y"
2600{ yyval.v.number = IPPROTO_TCP6; }
2601break;
2602case 28:
2603#line 288 "/usr/src/usr.sbin/relayd/parse.y"
2604{ yyval.v.number = IPPROTO_TCP6; }
2605break;
2606case 29:
2607#line 289 "/usr/src/usr.sbin/relayd/parse.y"
2608{
2609 struct protoent *p;
2610
2611 if ((p = getprotobyname(yyvsp[0].v.string)) == NULL((void*)0)) {
2612 yyerror("invalid protocol: %s", yyvsp[0].v.string);
2613 free(yyvsp[0].v.string);
2614 YYERRORgoto yyerrlab;
2615 }
2616 free(yyvsp[0].v.string);
2617
2618 yyval.v.number = p->p_proto;
2619 }
2620break;
2621case 34:
2622#line 312 "/usr/src/usr.sbin/relayd/parse.y"
2623{
2624 if ((proto->style = strdup(yyvsp[0].v.string)) == NULL((void*)0))
2625 fatal("out of memory");
2626 free(yyvsp[0].v.string);
2627 }
2628break;
2629case 35:
2630#line 319 "/usr/src/usr.sbin/relayd/parse.y"
2631{
2632 int p = 0;
2633 yyval.v.port.op = PF_OP_EQ;
2634 if ((p = getservice("http")) == -1)
2635 YYERRORgoto yyerrlab;
2636 yyval.v.port.val[0] = p;
2637 yyval.v.port.val[1] = 0;
2638 }
2639break;
2640case 36:
2641#line 327 "/usr/src/usr.sbin/relayd/parse.y"
2642{
2643 char *a, *b;
2644 int p[2];
2645
2646 p[0] = p[1] = 0;
2647
2648 a = yyvsp[0].v.string;
2649 b = strchr(yyvsp[0].v.string, ':');
2650 if (b == NULL((void*)0))
2651 yyval.v.port.op = PF_OP_EQ;
2652 else {
2653 *b++ = '\0';
2654 if ((p[1] = getservice(b)) == -1) {
2655 free(yyvsp[0].v.string);
2656 YYERRORgoto yyerrlab;
2657 }
2658 yyval.v.port.op = PF_OP_RRG;
2659 }
2660 if ((p[0] = getservice(a)) == -1) {
2661 free(yyvsp[0].v.string);
2662 YYERRORgoto yyerrlab;
2663 }
2664 yyval.v.port.val[0] = p[0];
2665 yyval.v.port.val[1] = p[1];
2666 free(yyvsp[0].v.string);
2667 }
2668break;
2669case 37:
2670#line 353 "/usr/src/usr.sbin/relayd/parse.y"
2671{
2672 if (yyvsp[0].v.number <= 0 || yyvsp[0].v.number > (int)USHRT_MAX(32767 *2 +1)) {
2673 yyerror("invalid port: %lld", yyvsp[0].v.number);
2674 YYERRORgoto yyerrlab;
2675 }
2676 yyval.v.port.val[0] = htons(yyvsp[0].v.number)(__uint16_t)(__builtin_constant_p(yyvsp[0].v.number) ? (__uint16_t
)(((__uint16_t)(yyvsp[0].v.number) & 0xffU) << 8 | (
(__uint16_t)(yyvsp[0].v.number) & 0xff00U) >> 8) : __swap16md
(yyvsp[0].v.number))
;
2677 yyval.v.port.op = PF_OP_EQ;
2678 }
2679break;
2680case 38:
2681#line 363 "/usr/src/usr.sbin/relayd/parse.y"
2682{
2683 char *s = yyvsp[-2].v.string;
2684 while (*s++) {
2685 if (isspace((unsigned char)*s)) {
2686 yyerror("macro name cannot contain "
2687 "whitespace");
2688 free(yyvsp[-2].v.string);
2689 free(yyvsp[0].v.string);
2690 YYERRORgoto yyerrlab;
2691 }
2692 }
2693 if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)
2694 fatal("cannot store variable");
2695 free(yyvsp[-2].v.string);
2696 free(yyvsp[0].v.string);
2697 }
2698break;
2699case 39:
2700#line 381 "/usr/src/usr.sbin/relayd/parse.y"
2701{
2702 table->sendbuf = NULL((void*)0);
2703 }
2704break;
2705case 40:
2706#line 384 "/usr/src/usr.sbin/relayd/parse.y"
2707{
2708 table->sendbuf = strdup(yyvsp[0].v.string);
2709 if (table->sendbuf == NULL((void*)0))
2710 fatal("out of memory");
2711 free(yyvsp[0].v.string);
2712 }
2713break;
2714case 41:
2715#line 392 "/usr/src/usr.sbin/relayd/parse.y"
2716{
2717 table->sendbinbuf = NULL((void*)0);
2718 }
2719break;
2720case 42:
2721#line 395 "/usr/src/usr.sbin/relayd/parse.y"
2722{
2723 if (strlen(yyvsp[0].v.string) == 0) {
2724 yyerror("empty binary send data");
2725 free(yyvsp[0].v.string);
2726 YYERRORgoto yyerrlab;
2727 }
2728 table->sendbuf = strdup(yyvsp[0].v.string);
2729 if (table->sendbuf == NULL((void*)0))
2730 fatal("out of memory");
2731 table->sendbinbuf = string2binary(yyvsp[0].v.string);
2732 if (table->sendbinbuf == NULL((void*)0))
2733 fatal("failed in binary send data");
2734 free(yyvsp[0].v.string);
2735 }
2736break;
2737case 43:
2738#line 411 "/usr/src/usr.sbin/relayd/parse.y"
2739{
2740 if ((conf->sc_conf.interval.tv_sec = yyvsp[0].v.number) < 0) {
2741 yyerror("invalid interval: %lld", yyvsp[0].v.number);
2742 YYERRORgoto yyerrlab;
2743 }
2744 }
2745break;
2746case 44:
2747#line 417 "/usr/src/usr.sbin/relayd/parse.y"
2748{
2749 conf->sc_conf.opts |= yyvsp[0].v.number;
2750 }
2751break;
2752case 45:
2753#line 420 "/usr/src/usr.sbin/relayd/parse.y"
2754{
2755 bcopy(&yyvsp[0].v.tv, &conf->sc_conf.timeout,
2756 sizeof(struct timeval));
2757 }
2758break;
2759case 46:
2760#line 424 "/usr/src/usr.sbin/relayd/parse.y"
2761{
2762 if (yyvsp[0].v.number <= 0 || yyvsp[0].v.number > PROC_MAX_INSTANCES32) {
2763 yyerror("invalid number of preforked "
2764 "relays: %lld", yyvsp[0].v.number);
2765 YYERRORgoto yyerrlab;
2766 }
2767 conf->sc_conf.prefork_relay = yyvsp[0].v.number;
2768 }
2769break;
2770case 47:
2771#line 432 "/usr/src/usr.sbin/relayd/parse.y"
2772{
2773 conf->sc_conf.flags |= F_AGENTX0x00040000;
2774 if (yyvsp[-1].v.string != NULL((void*)0)) {
2775 if (strlcpy(conf->sc_conf.agentx_context, yyvsp[-1].v.string,
2776 sizeof(conf->sc_conf.agentx_context)) >=
2777 sizeof(conf->sc_conf.agentx_context)) {
2778 yyerror("agentx context too long");
2779 free(yyvsp[-1].v.string);
2780 free(yyvsp[0].v.string);
2781 YYERRORgoto yyerrlab;
2782 }
2783 free(yyvsp[-1].v.string);
2784 } else
2785 conf->sc_conf.agentx_context[0] = '\0';
2786 if (yyvsp[0].v.string != NULL((void*)0)) {
2787 if (strlcpy(conf->sc_conf.agentx_path, yyvsp[0].v.string,
2788 sizeof(conf->sc_conf.agentx_path)) >=
2789 sizeof(conf->sc_conf.agentx_path)) {
2790 yyerror("agentx path too long");
2791 free(yyvsp[0].v.string);
2792 YYERRORgoto yyerrlab;
2793 }
2794 free(yyvsp[0].v.string);
2795 } else
2796 (void)strlcpy(conf->sc_conf.agentx_path,
2797 AGENTX_MASTER_PATH"/var/agentx/master",
2798 sizeof(conf->sc_conf.agentx_path));
2799 }
2800break;
2801case 48:
2802#line 460 "/usr/src/usr.sbin/relayd/parse.y"
2803{
2804 conf->sc_ps->ps_csock.cs_name = yyvsp[0].v.string;
2805 }
2806break;
2807case 49:
2808#line 465 "/usr/src/usr.sbin/relayd/parse.y"
2809{ yyval.v.string = NULL((void*)0); }
2810break;
2811case 50:
2812#line 466 "/usr/src/usr.sbin/relayd/parse.y"
2813{ yyval.v.string = yyvsp[0].v.string; }
2814break;
2815case 51:
2816#line 468 "/usr/src/usr.sbin/relayd/parse.y"
2817{ yyval.v.string = NULL((void*)0); }
2818break;
2819case 52:
2820#line 469 "/usr/src/usr.sbin/relayd/parse.y"
2821{ yyval.v.string = yyvsp[0].v.string; }
2822break;
2823case 53:
2824#line 471 "/usr/src/usr.sbin/relayd/parse.y"
2825{ yyval.v.number = RELAYD_OPT_LOGUPDATE0x08; }
2826break;
2827case 54:
2828#line 472 "/usr/src/usr.sbin/relayd/parse.y"
2829{ yyval.v.number = RELAYD_OPT_LOGHOSTCHECK0x10; }
2830break;
2831case 55:
2832#line 473 "/usr/src/usr.sbin/relayd/parse.y"
2833{ yyval.v.number = (RELAYD_OPT_LOGCON0x20 |
2834 RELAYD_OPT_LOGCONERR0x40); }
2835break;
2836case 56:
2837#line 475 "/usr/src/usr.sbin/relayd/parse.y"
2838{ yyval.v.number = RELAYD_OPT_LOGCONERR0x40; }
2839break;
2840case 57:
2841#line 478 "/usr/src/usr.sbin/relayd/parse.y"
2842{
2843 struct rdr *srv;
2844
2845 conf->sc_conf.flags |= F_NEEDPF0x00080000;
2846
2847 if (!loadcfg) {
2848 free(yyvsp[0].v.string);
2849 YYACCEPTgoto yyaccept;
2850 }
2851
2852 TAILQ_FOREACH(srv, conf->sc_rdrs, entry)for((srv) = ((conf->sc_rdrs)->tqh_first); (srv) != ((void
*)0); (srv) = ((srv)->entry.tqe_next))
2853 if (!strcmp(srv->conf.name, yyvsp[0].v.string))
2854 break;
2855 if (srv != NULL((void*)0)) {
2856 yyerror("redirection %s defined twice", yyvsp[0].v.string);
2857 free(yyvsp[0].v.string);
2858 YYERRORgoto yyerrlab;
2859 }
2860 if ((srv = calloc(1, sizeof (*srv))) == NULL((void*)0))
2861 fatal("out of memory");
2862
2863 if (strlcpy(srv->conf.name, yyvsp[0].v.string,
2864 sizeof(srv->conf.name)) >=
2865 sizeof(srv->conf.name)) {
2866 yyerror("redirection name truncated");
2867 free(yyvsp[0].v.string);
2868 free(srv);
2869 YYERRORgoto yyerrlab;
2870 }
2871 free(yyvsp[0].v.string);
2872 srv->conf.id = ++last_rdr_id;
2873 srv->conf.timeout.tv_sec = RELAY_TIMEOUT600;
2874 if (last_rdr_id == INT_MAX2147483647) {
2875 yyerror("too many redirections defined");
2876 free(srv);
2877 YYERRORgoto yyerrlab;
2878 }
2879 rdr = srv;
2880 }
2881break;
2882case 58:
2883#line 516 "/usr/src/usr.sbin/relayd/parse.y"
2884{
2885 if (rdr->table == NULL((void*)0)) {
2886 yyerror("redirection %s has no table",
2887 rdr->conf.name);
2888 YYERRORgoto yyerrlab;
2889 }
2890 if (TAILQ_EMPTY(&rdr->virts)(((&rdr->virts)->tqh_first) == ((void*)0))) {
2891 yyerror("redirection %s has no virtual ip",
2892 rdr->conf.name);
2893 YYERRORgoto yyerrlab;
2894 }
2895 conf->sc_rdrcount++;
2896 if (rdr->backup == NULL((void*)0)) {
2897 rdr->conf.backup_id =
2898 conf->sc_empty_table.conf.id;
2899 rdr->backup = &conf->sc_empty_table;
2900 } else if (rdr->backup->conf.port !=
2901 rdr->table->conf.port) {
2902 yyerror("redirection %s uses two different "
2903 "ports for its table and backup table",
2904 rdr->conf.name);
2905 YYERRORgoto yyerrlab;
2906 }
2907 if (!(rdr->conf.flags & F_DISABLE0x00000001))
2908 rdr->conf.flags |= F_ADD0x00000010;
2909 TAILQ_INSERT_TAIL(conf->sc_rdrs, rdr, entry)do { (rdr)->entry.tqe_next = ((void*)0); (rdr)->entry.tqe_prev
= (conf->sc_rdrs)->tqh_last; *(conf->sc_rdrs)->tqh_last
= (rdr); (conf->sc_rdrs)->tqh_last = &(rdr)->entry
.tqe_next; } while (0)
;
2910 tableport = 0;
2911 rdr = NULL((void*)0);
2912 }
2913break;
2914case 61:
2915#line 551 "/usr/src/usr.sbin/relayd/parse.y"
2916{
2917 if (hashkey != NULL((void*)0)) {
2918 memcpy(&rdr->conf.key,
2919 hashkey, sizeof(rdr->conf.key));
2920 rdr->conf.flags |= F_HASHKEY0x08000000;
2921 free(hashkey);
2922 hashkey = NULL((void*)0);
2923 }
2924
2925 switch (yyvsp[-3].v.number) {
2926 case FWD_NORMAL:
2927 if (yyvsp[0].v.string == NULL((void*)0))
2928 break;
2929 yyerror("superfluous interface");
2930 free(yyvsp[0].v.string);
2931 YYERRORgoto yyerrlab;
2932 case FWD_ROUTE:
2933 if (yyvsp[0].v.string != NULL((void*)0))
2934 break;
2935 yyerror("missing interface to route to");
2936 free(yyvsp[0].v.string);
2937 YYERRORgoto yyerrlab;
2938 case FWD_TRANS:
2939 yyerror("no transparent forward here");
2940 if (yyvsp[0].v.string != NULL((void*)0))
2941 free(yyvsp[0].v.string);
2942 YYERRORgoto yyerrlab;
2943 }
2944 if (yyvsp[0].v.string != NULL((void*)0)) {
2945 if (strlcpy(yyvsp[-1].v.table->conf.ifname, yyvsp[0].v.string,
2946 sizeof(yyvsp[-1].v.table->conf.ifname)) >=
2947 sizeof(yyvsp[-1].v.table->conf.ifname)) {
2948 yyerror("interface name truncated");
2949 free(yyvsp[0].v.string);
2950 YYERRORgoto yyerrlab;
2951 }
2952 free(yyvsp[0].v.string);
2953 }
2954
2955 if (yyvsp[-1].v.table->conf.check == CHECK_NOCHECK) {
2956 yyerror("table %s has no check", yyvsp[-1].v.table->conf.name);
2957 purge_table(conf, conf->sc_tables, yyvsp[-1].v.table);
2958 YYERRORgoto yyerrlab;
2959 }
2960 if (rdr->backup) {
2961 yyerror("only one backup table is allowed");
2962 purge_table(conf, conf->sc_tables, yyvsp[-1].v.table);
2963 YYERRORgoto yyerrlab;
2964 }
2965 if (rdr->table) {
2966 rdr->backup = yyvsp[-1].v.table;
2967 rdr->conf.backup_id = yyvsp[-1].v.table->conf.id;
2968 if (dstmode != rdr->conf.mode) {
2969 yyerror("backup table for %s with "
2970 "different mode", rdr->conf.name);
2971 YYERRORgoto yyerrlab;
2972 }
2973 } else {
2974 rdr->table = yyvsp[-1].v.table;
2975 rdr->conf.table_id = yyvsp[-1].v.table->conf.id;
2976 rdr->conf.mode = dstmode;
2977 }
2978 yyvsp[-1].v.table->conf.fwdmode = yyvsp[-3].v.number;
2979 yyvsp[-1].v.table->conf.rdrid = rdr->conf.id;
2980 yyvsp[-1].v.table->conf.flags |= F_USED0x00000004;
2981 }
2982break;
2983case 62:
2984#line 617 "/usr/src/usr.sbin/relayd/parse.y"
2985{
2986 if (host(yyvsp[-3].v.string, &rdr->virts,
2987 SRV_MAX_VIRTS16, &yyvsp[-1].v.port, yyvsp[0].v.string, yyvsp[-2].v.number) <= 0) {
2988 yyerror("invalid virtual ip: %s", yyvsp[-3].v.string);
2989 free(yyvsp[-3].v.string);
2990 free(yyvsp[0].v.string);
2991 YYERRORgoto yyerrlab;
2992 }
2993 free(yyvsp[-3].v.string);
2994 free(yyvsp[0].v.string);
2995 if (rdr->conf.port == 0)
2996 rdr->conf.port = yyvsp[-1].v.port.val[0];
2997 tableport = rdr->conf.port;
2998 }
2999break;
3000case 63:
3001#line 631 "/usr/src/usr.sbin/relayd/parse.y"
3002{ rdr->conf.flags |= F_DISABLE0x00000001; }
3003break;
3004case 64:
3005#line 632 "/usr/src/usr.sbin/relayd/parse.y"
3006{ rdr->conf.flags |= F_STICKY0x00000080; }
3007break;
3008case 65:
3009#line 633 "/usr/src/usr.sbin/relayd/parse.y"
3010{
3011 conf->sc_conf.flags |= F_NEEDPF0x00080000;
3012 if (strlcpy(rdr->conf.tag, yyvsp[0].v.string,
3013 sizeof(rdr->conf.tag)) >=
3014 sizeof(rdr->conf.tag)) {
3015 yyerror("redirection tag name truncated");
3016 free(yyvsp[0].v.string);
3017 YYERRORgoto yyerrlab;
3018 }
3019 if (yyvsp[-2].v.number)
3020 rdr->conf.flags |= F_MATCH0x00800000;
3021 free(yyvsp[0].v.string);
3022 }
3023break;
3024case 66:
3025#line 646 "/usr/src/usr.sbin/relayd/parse.y"
3026{
3027 if ((rdr->conf.timeout.tv_sec = yyvsp[0].v.number) < 0) {
3028 yyerror("invalid timeout: %lld", yyvsp[0].v.number);
3029 YYERRORgoto yyerrlab;
3030 }
3031 if (rdr->conf.timeout.tv_sec > INT_MAX2147483647) {
3032 yyerror("timeout too large: %lld", yyvsp[0].v.number);
3033 YYERRORgoto yyerrlab;
3034 }
3035 }
3036break;
3037case 68:
3038#line 659 "/usr/src/usr.sbin/relayd/parse.y"
3039{ yyval.v.number = 0; }
3040break;
3041case 69:
3042#line 660 "/usr/src/usr.sbin/relayd/parse.y"
3043{ yyval.v.number = 1; }
3044break;
3045case 70:
3046#line 663 "/usr/src/usr.sbin/relayd/parse.y"
3047{ yyval.v.number = FWD_NORMAL; }
3048break;
3049case 71:
3050#line 664 "/usr/src/usr.sbin/relayd/parse.y"
3051{ yyval.v.number = FWD_ROUTE; }
3052break;
3053case 72:
3054#line 665 "/usr/src/usr.sbin/relayd/parse.y"
3055{ yyval.v.number = FWD_TRANS; }
3056break;
3057case 73:
3058#line 668 "/usr/src/usr.sbin/relayd/parse.y"
3059{
3060 if (strlen(yyvsp[-1].v.string) >= TABLE_NAME_SIZE64) {
3061 yyerror("invalid table name");
3062 free(yyvsp[-1].v.string);
3063 YYERRORgoto yyerrlab;
3064 }
3065 yyval.v.string = yyvsp[-1].v.string;
3066 }
3067break;
3068case 74:
3069#line 678 "/usr/src/usr.sbin/relayd/parse.y"
3070{
3071 struct table *tb;
3072
3073 if (!loadcfg) {
3074 free(yyvsp[0].v.string);
3075 YYACCEPTgoto yyaccept;
3076 }
3077
3078 TAILQ_FOREACH(tb, conf->sc_tables, entry)for((tb) = ((conf->sc_tables)->tqh_first); (tb) != ((void
*)0); (tb) = ((tb)->entry.tqe_next))
3079 if (!strcmp(tb->conf.name, yyvsp[0].v.string))
3080 break;
3081 if (tb != NULL((void*)0)) {
3082 yyerror("table %s defined twice", yyvsp[0].v.string);
3083 free(yyvsp[0].v.string);
3084 YYERRORgoto yyerrlab;
3085 }
3086
3087 if ((tb = calloc(1, sizeof (*tb))) == NULL((void*)0))
3088 fatal("out of memory");
3089
3090 if (strlcpy(tb->conf.name, yyvsp[0].v.string,
3091 sizeof(tb->conf.name)) >= sizeof(tb->conf.name)) {
3092 yyerror("table name truncated");
3093 free(yyvsp[0].v.string);
3094 YYERRORgoto yyerrlab;
3095 }
3096 free(yyvsp[0].v.string);
3097
3098 tb->conf.id = 0; /* will be set later */
3099 bcopy(&conf->sc_conf.timeout, &tb->conf.timeout,
3100 sizeof(struct timeval));
3101 TAILQ_INIT(&tb->hosts)do { (&tb->hosts)->tqh_first = ((void*)0); (&tb
->hosts)->tqh_last = &(&tb->hosts)->tqh_first
; } while (0)
;
3102 table = tb;
3103 dstmode = RELAY_DSTMODE_DEFAULTRELAY_DSTMODE_ROUNDROBIN;
3104 }
3105break;
3106case 75:
3107#line 712 "/usr/src/usr.sbin/relayd/parse.y"
3108{
3109 if (TAILQ_EMPTY(&table->hosts)(((&table->hosts)->tqh_first) == ((void*)0))) {
3110 yyerror("table %s has no hosts",
3111 table->conf.name);
3112 YYERRORgoto yyerrlab;
3113 }
3114 conf->sc_tablecount++;
3115 TAILQ_INSERT_TAIL(conf->sc_tables, table, entry)do { (table)->entry.tqe_next = ((void*)0); (table)->entry
.tqe_prev = (conf->sc_tables)->tqh_last; *(conf->sc_tables
)->tqh_last = (table); (conf->sc_tables)->tqh_last =
&(table)->entry.tqe_next; } while (0)
;
3116 }
3117break;
3118case 78:
3119#line 727 "/usr/src/usr.sbin/relayd/parse.y"
3120{ table->conf.flags |= F_DISABLE0x00000001; }
3121break;
3122case 82:
3123#line 735 "/usr/src/usr.sbin/relayd/parse.y"
3124{
3125 yyvsp[0].v.host->conf.tableid = table->conf.id;
3126 yyvsp[0].v.host->tablename = table->conf.name;
3127 TAILQ_INSERT_TAIL(&table->hosts, yyvsp[0].v.host, entry)do { (yyvsp[0].v.host)->entry.tqe_next = ((void*)0); (yyvsp
[0].v.host)->entry.tqe_prev = (&table->hosts)->tqh_last
; *(&table->hosts)->tqh_last = (yyvsp[0].v.host); (
&table->hosts)->tqh_last = &(yyvsp[0].v.host)->
entry.tqe_next; } while (0)
;
3128 }
3129break;
3130case 84:
3131#line 743 "/usr/src/usr.sbin/relayd/parse.y"
3132{
3133 struct table *tb;
3134 if ((tb = calloc(1, sizeof (*tb))) == NULL((void*)0))
3135 fatal("out of memory");
3136 if (strlcpy(tb->conf.name, yyvsp[0].v.string,
3137 sizeof(tb->conf.name)) >= sizeof(tb->conf.name)) {
3138 yyerror("table name truncated");
3139 free(yyvsp[0].v.string);
3140 YYERRORgoto yyerrlab;
3141 }
3142 free(yyvsp[0].v.string);
3143 table = tb;
3144 dstmode = RELAY_DSTMODE_DEFAULTRELAY_DSTMODE_ROUNDROBIN;
3145 hashkey = NULL((void*)0);
3146 }
3147break;
3148case 85:
3149#line 757 "/usr/src/usr.sbin/relayd/parse.y"
3150{
3151 struct table *tb;
3152 if (table->conf.port == 0)
3153 table->conf.port = tableport;
3154 else
3155 table->conf.flags |= F_PORT0x00100000;
3156 if ((tb = table_inherit(table)) == NULL((void*)0))
3157 YYERRORgoto yyerrlab;
3158 yyval.v.table = tb;
3159 }
3160break;
3161case 89:
3162#line 774 "/usr/src/usr.sbin/relayd/parse.y"
3163{
3164 if (yyvsp[0].v.port.op != PF_OP_EQ) {
3165 yyerror("invalid port");
3166 YYERRORgoto yyerrlab;
3167 }
3168 table->conf.port = yyvsp[0].v.port.val[0];
3169 }
3170break;
3171case 90:
3172#line 781 "/usr/src/usr.sbin/relayd/parse.y"
3173{
3174 bcopy(&yyvsp[0].v.tv, &table->conf.timeout,
3175 sizeof(struct timeval));
3176 }
3177break;
3178case 91:
3179#line 785 "/usr/src/usr.sbin/relayd/parse.y"
3180{
3181 table->conf.flags |= F_DEMOTE0x00002000;
3182 if (strlcpy(table->conf.demote_group, yyvsp[0].v.string,
3183 sizeof(table->conf.demote_group))
3184 >= sizeof(table->conf.demote_group)) {
3185 yyerror("yyparse: demote group name too long");
3186 free(yyvsp[0].v.string);
3187 YYERRORgoto yyerrlab;
3188 }
3189 free(yyvsp[0].v.string);
3190 if (carp_demote_init(table->conf.demote_group, 1)
3191 == -1) {
3192 yyerror("yyparse: error initializing group "
3193 "'%s'", table->conf.demote_group);
3194 YYERRORgoto yyerrlab;
3195 }
3196 }
3197break;
3198case 92:
3199#line 802 "/usr/src/usr.sbin/relayd/parse.y"
3200{
3201 if (yyvsp[0].v.number < conf->sc_conf.interval.tv_sec ||
3202 yyvsp[0].v.number % conf->sc_conf.interval.tv_sec) {
3203 yyerror("table interval must be "
3204 "divisible by global interval");
3205 YYERRORgoto yyerrlab;
3206 }
3207 table->conf.skip_cnt =
3208 (yyvsp[0].v.number / conf->sc_conf.interval.tv_sec) - 1;
3209 }
3210break;
3211case 93:
3212#line 812 "/usr/src/usr.sbin/relayd/parse.y"
3213{
3214 switch (yyvsp[-1].v.number) {
3215 case RELAY_DSTMODE_LOADBALANCE:
3216 case RELAY_DSTMODE_HASH:
3217 case RELAY_DSTMODE_SRCHASH:
3218 if (hashkey != NULL((void*)0)) {
3219 yyerror("key already specified");
3220 free(hashkey);
3221 YYERRORgoto yyerrlab;
3222 }
3223 if ((hashkey = calloc(1,
3224 sizeof(*hashkey))) == NULL((void*)0))
3225 fatal("out of memory");
3226 memcpy(hashkey, &yyvsp[0].v.key.key, sizeof(*hashkey));
3227 break;
3228 default:
3229 if (yyvsp[0].v.key.keyset) {
3230 yyerror("key not supported by mode");
3231 YYERRORgoto yyerrlab;
3232 }
3233 hashkey = NULL((void*)0);
3234 break;
3235 }
3236
3237 switch (yyvsp[-1].v.number) {
3238 case RELAY_DSTMODE_LOADBALANCE:
3239 case RELAY_DSTMODE_HASH:
3240 if (rdr != NULL((void*)0)) {
3241 yyerror("mode not supported "
3242 "for redirections");
3243 YYERRORgoto yyerrlab;
3244 }
3245 /* FALLTHROUGH */
3246 case RELAY_DSTMODE_RANDOM:
3247 case RELAY_DSTMODE_ROUNDROBIN:
3248 case RELAY_DSTMODE_SRCHASH:
3249 dstmode = yyvsp[-1].v.number;
3250 break;
3251 case RELAY_DSTMODE_LEASTSTATES:
3252 if (rdr == NULL((void*)0)) {
3253 yyerror("mode not supported "
3254 "for relays");
3255 YYERRORgoto yyerrlab;
3256 }
3257 dstmode = yyvsp[-1].v.number;
3258 break;
3259 }
3260 }
3261break;
3262case 94:
3263#line 863 "/usr/src/usr.sbin/relayd/parse.y"
3264{
3265 yyval.v.key.keyset = 0;
3266 yyval.v.key.key.data[0] = arc4random();
3267 yyval.v.key.key.data[1] = arc4random();
3268 yyval.v.key.key.data[2] = arc4random();
3269 yyval.v.key.key.data[3] = arc4random();
3270 }
3271break;
3272case 95:
3273#line 870 "/usr/src/usr.sbin/relayd/parse.y"
3274{
3275 /* manual key configuration */
3276 yyval.v.key.keyset = 1;
3277
3278 if (!strncmp(yyvsp[0].v.string, "0x", 2)) {
3279 if (strlen(yyvsp[0].v.string) != 34) {
3280 free(yyvsp[0].v.string);
3281 yyerror("hex key must be 128 bits "
3282 "(32 hex digits) long");
3283 YYERRORgoto yyerrlab;
3284 }
3285
3286 if (sscanf(yyvsp[0].v.string, "0x%8x%8x%8x%8x",
3287 &yyval.v.key.key.data[0], &yyval.v.key.key.data[1],
3288 &yyval.v.key.key.data[2], &yyval.v.key.key.data[3]) != 4) {
3289 free(yyvsp[0].v.string);
3290 yyerror("invalid hex key");
3291 YYERRORgoto yyerrlab;
3292 }
3293 } else {
3294 MD5_CTX context;
3295
3296 MD5Init(&context);
3297 MD5Update(&context, (unsigned char *)yyvsp[0].v.string,
3298 strlen(yyvsp[0].v.string));
3299 MD5Final((unsigned char *)yyval.v.key.key.data,
3300 &context);
3301 HTONL(yyval.v.key.key.data[0])(yyval.v.key.key.data[0]) = (__uint32_t)(__builtin_constant_p
((u_int32_t)(yyval.v.key.key.data[0])) ? (__uint32_t)(((__uint32_t
)((u_int32_t)(yyval.v.key.key.data[0])) & 0xff) << 24
| ((__uint32_t)((u_int32_t)(yyval.v.key.key.data[0])) & 0xff00
) << 8 | ((__uint32_t)((u_int32_t)(yyval.v.key.key.data
[0])) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(
yyval.v.key.key.data[0])) & 0xff000000) >> 24) : __swap32md
((u_int32_t)(yyval.v.key.key.data[0])))
;
3302 HTONL(yyval.v.key.key.data[1])(yyval.v.key.key.data[1]) = (__uint32_t)(__builtin_constant_p
((u_int32_t)(yyval.v.key.key.data[1])) ? (__uint32_t)(((__uint32_t
)((u_int32_t)(yyval.v.key.key.data[1])) & 0xff) << 24
| ((__uint32_t)((u_int32_t)(yyval.v.key.key.data[1])) & 0xff00
) << 8 | ((__uint32_t)((u_int32_t)(yyval.v.key.key.data
[1])) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(
yyval.v.key.key.data[1])) & 0xff000000) >> 24) : __swap32md
((u_int32_t)(yyval.v.key.key.data[1])))
;
3303 HTONL(yyval.v.key.key.data[2])(yyval.v.key.key.data[2]) = (__uint32_t)(__builtin_constant_p
((u_int32_t)(yyval.v.key.key.data[2])) ? (__uint32_t)(((__uint32_t
)((u_int32_t)(yyval.v.key.key.data[2])) & 0xff) << 24
| ((__uint32_t)((u_int32_t)(yyval.v.key.key.data[2])) & 0xff00
) << 8 | ((__uint32_t)((u_int32_t)(yyval.v.key.key.data
[2])) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(
yyval.v.key.key.data[2])) & 0xff000000) >> 24) : __swap32md
((u_int32_t)(yyval.v.key.key.data[2])))
;
3304 HTONL(yyval.v.key.key.data[3])(yyval.v.key.key.data[3]) = (__uint32_t)(__builtin_constant_p
((u_int32_t)(yyval.v.key.key.data[3])) ? (__uint32_t)(((__uint32_t
)((u_int32_t)(yyval.v.key.key.data[3])) & 0xff) << 24
| ((__uint32_t)((u_int32_t)(yyval.v.key.key.data[3])) & 0xff00
) << 8 | ((__uint32_t)((u_int32_t)(yyval.v.key.key.data
[3])) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(
yyval.v.key.key.data[3])) & 0xff000000) >> 24) : __swap32md
((u_int32_t)(yyval.v.key.key.data[3])))
;
3305 }
3306 free(yyvsp[0].v.string);
3307 }
3308break;
3309case 96:
3310#line 906 "/usr/src/usr.sbin/relayd/parse.y"
3311{ table->conf.check = CHECK_ICMP; }
3312break;
3313case 97:
3314#line 907 "/usr/src/usr.sbin/relayd/parse.y"
3315{ table->conf.check = CHECK_TCP; }
3316break;
3317case 98:
3318#line 908 "/usr/src/usr.sbin/relayd/parse.y"
3319{
3320 table->conf.check = CHECK_TCP;
3321 conf->sc_conf.flags |= F_TLS0x00000800;
3322 table->conf.flags |= F_TLS0x00000800;
3323 }
3324break;
3325case 99:
3326#line 913 "/usr/src/usr.sbin/relayd/parse.y"
3327{
3328 if (yyvsp[-4].v.number) {
3329 conf->sc_conf.flags |= F_TLS0x00000800;
3330 table->conf.flags |= F_TLS0x00000800;
3331 }
3332 table->conf.check = CHECK_HTTP_CODE;
3333 if ((table->conf.retcode = yyvsp[0].v.number) <= 0) {
3334 yyerror("invalid HTTP code: %lld", yyvsp[0].v.number);
3335 free(yyvsp[-3].v.string);
3336 free(yyvsp[-2].v.string);
3337 YYERRORgoto yyerrlab;
3338 }
3339 if (asprintf(&table->sendbuf,
3340 "HEAD %s HTTP/1.%c\r\n%s\r\n",
3341 yyvsp[-3].v.string, strlen(yyvsp[-2].v.string) ? '1' : '0', yyvsp[-2].v.string) == -1)
3342 fatal("asprintf");
3343 free(yyvsp[-3].v.string);
3344 free(yyvsp[-2].v.string);
3345 if (table->sendbuf == NULL((void*)0))
3346 fatal("out of memory");
3347 }
3348break;
3349case 100:
3350#line 934 "/usr/src/usr.sbin/relayd/parse.y"
3351{
3352 if (yyvsp[-3].v.number) {
3353 conf->sc_conf.flags |= F_TLS0x00000800;
3354 table->conf.flags |= F_TLS0x00000800;
3355 }
3356 table->conf.check = CHECK_HTTP_DIGEST;
3357 if (asprintf(&table->sendbuf,
3358 "GET %s HTTP/1.%c\r\n%s\r\n",
3359 yyvsp[-2].v.string, strlen(yyvsp[-1].v.string) ? '1' : '0', yyvsp[-1].v.string) == -1)
3360 fatal("asprintf");
3361 free(yyvsp[-2].v.string);
3362 free(yyvsp[-1].v.string);
3363 if (table->sendbuf == NULL((void*)0))
3364 fatal("out of memory");
3365 if (strlcpy(table->conf.digest, yyvsp[0].v.digest.digest,
3366 sizeof(table->conf.digest)) >=
3367 sizeof(table->conf.digest)) {
3368 yyerror("digest truncated");
3369 free(yyvsp[0].v.digest.digest);
3370 YYERRORgoto yyerrlab;
3371 }
3372 table->conf.digest_type = yyvsp[0].v.digest.type;
3373 free(yyvsp[0].v.digest.digest);
3374 }
3375break;
3376case 101:
3377#line 958 "/usr/src/usr.sbin/relayd/parse.y"
3378{
3379 table->conf.check = CHECK_SEND_EXPECT;
3380 if (yyvsp[0].v.number) {
3381 conf->sc_conf.flags |= F_TLS0x00000800;
3382 table->conf.flags |= F_TLS0x00000800;
3383 }
3384 if (strlcpy(table->conf.exbuf, yyvsp[-1].v.string,
3385 sizeof(table->conf.exbuf))
3386 >= sizeof(table->conf.exbuf)) {
3387 yyerror("yyparse: expect buffer truncated");
3388 free(yyvsp[-1].v.string);
3389 YYERRORgoto yyerrlab;
3390 }
3391 translate_string(table->conf.exbuf);
3392 free(yyvsp[-1].v.string);
3393 }
3394break;
3395case 102:
3396#line 974 "/usr/src/usr.sbin/relayd/parse.y"
3397{
3398 table->conf.check = CHECK_BINSEND_EXPECT;
3399 if (yyvsp[0].v.number) {
3400 conf->sc_conf.flags |= F_TLS0x00000800;
3401 table->conf.flags |= F_TLS0x00000800;
3402 }
3403 if (strlen(yyvsp[-1].v.string) == 0) {
3404 yyerror("empty binary expect data");
3405 free(yyvsp[-1].v.string);
3406 YYERRORgoto yyerrlab;
3407 }
3408 if (strlcpy(table->conf.exbuf, yyvsp[-1].v.string,
3409 sizeof(table->conf.exbuf))
3410 >= sizeof(table->conf.exbuf)) {
3411 yyerror("expect buffer truncated");
3412 free(yyvsp[-1].v.string);
3413 YYERRORgoto yyerrlab;
3414 }
3415 struct ibuf *ibuf = string2binary(yyvsp[-1].v.string);
3416 if (ibuf == NULL((void*)0)) {
3417 yyerror("failed in binary expect data buffer");
3418 ibuf_free(ibuf);
3419 free(yyvsp[-1].v.string);
3420 YYERRORgoto yyerrlab;
3421 }
3422 memcpy(table->conf.exbinbuf, ibuf->buf,
3423 ibuf_size(ibuf));
3424 ibuf_free(ibuf);
3425 free(yyvsp[-1].v.string);
3426 }
3427break;
3428case 103:
3429#line 1004 "/usr/src/usr.sbin/relayd/parse.y"
3430{
3431 table->conf.check = CHECK_SCRIPT;
3432 if (strlcpy(table->conf.path, yyvsp[0].v.string,
3433 sizeof(table->conf.path)) >=
3434 sizeof(table->conf.path)) {
3435 yyerror("script path truncated");
3436 free(yyvsp[0].v.string);
3437 YYERRORgoto yyerrlab;
3438 }
3439 conf->sc_conf.flags |= F_SCRIPT0x02000000;
3440 free(yyvsp[0].v.string);
3441 }
3442break;
3443case 104:
3444#line 1019 "/usr/src/usr.sbin/relayd/parse.y"
3445{
3446 switch (strlen(yyvsp[0].v.string)) {
3447 case 40:
3448 yyval.v.digest.type = DIGEST_SHA1;
3449 break;
3450 case 32:
3451 yyval.v.digest.type = DIGEST_MD5;
3452 break;
3453 default:
3454 yyerror("invalid http digest");
3455 free(yyvsp[0].v.string);
3456 YYERRORgoto yyerrlab;
3457 }
3458 yyval.v.digest.digest = yyvsp[0].v.string;
3459 }
3460break;
3461case 105:
3462#line 1036 "/usr/src/usr.sbin/relayd/parse.y"
3463{
3464 yyval.v.digest.digest = yyvsp[0].v.digest.digest;
3465 yyval.v.digest.type = yyvsp[0].v.digest.type;
3466 }
3467break;
3468case 106:
3469#line 1040 "/usr/src/usr.sbin/relayd/parse.y"
3470{
3471 yyval.v.digest.digest = yyvsp[0].v.string;
3472 yyval.v.digest.type = DIGEST_NONE;
3473 }
3474break;
3475case 107:
3476#line 1046 "/usr/src/usr.sbin/relayd/parse.y"
3477{
3478 struct protocol *p;
3479
3480 if (!loadcfg) {
3481 free(yyvsp[0].v.string);
3482 YYACCEPTgoto yyaccept;
3483 }
3484
3485 if (strcmp(yyvsp[0].v.string, "default") == 0) {
3486 p = &conf->sc_proto_default;
3487 } else {
3488 TAILQ_FOREACH(p, conf->sc_protos, entry)for((p) = ((conf->sc_protos)->tqh_first); (p) != ((void
*)0); (p) = ((p)->entry.tqe_next))
3489 if (!strcmp(p->name, yyvsp[0].v.string))
3490 break;
3491 }
3492 if (p != NULL((void*)0)) {
3493 yyerror("protocol %s defined twice", yyvsp[0].v.string);
3494 free(yyvsp[0].v.string);
3495 YYERRORgoto yyerrlab;
3496 }
3497 if ((p = calloc(1, sizeof (*p))) == NULL((void*)0))
3498 fatal("out of memory");
3499
3500 if (strlcpy(p->name, yyvsp[0].v.string, sizeof(p->name)) >=
3501 sizeof(p->name)) {
3502 yyerror("protocol name truncated");
3503 free(yyvsp[0].v.string);
3504 free(p);
3505 YYERRORgoto yyerrlab;
3506 }
3507 free(yyvsp[0].v.string);
3508 p->id = ++last_proto_id;
3509 p->type = yyvsp[-2].v.number;
3510 p->tcpflags = TCPFLAG_DEFAULT0x00;
3511 p->tlsflags = TLSFLAG_DEFAULT(0x08|0x10|0x20);
3512 p->tcpbacklog = RELAY_BACKLOG10;
3513 p->httpheaderlen = RELAY_DEFHEADERLENGTH8192;
3514 TAILQ_INIT(&p->rules)do { (&p->rules)->tqh_first = ((void*)0); (&p->
rules)->tqh_last = &(&p->rules)->tqh_first; }
while (0)
;
3515 TAILQ_INIT(&p->tlscerts)do { (&p->tlscerts)->tqh_first = ((void*)0); (&
p->tlscerts)->tqh_last = &(&p->tlscerts)->
tqh_first; } while (0)
;
3516 (void)strlcpy(p->tlsciphers, TLSCIPHERS_DEFAULT"HIGH:!aNULL",
3517 sizeof(p->tlsciphers));
3518 (void)strlcpy(p->tlsecdhecurves, TLSECDHECURVES_DEFAULT"default",
3519 sizeof(p->tlsecdhecurves));
3520 (void)strlcpy(p->tlsdhparams, TLSDHPARAM_DEFAULT"none",
3521 sizeof(p->tlsdhparams));
3522 if (last_proto_id == INT_MAX2147483647) {
3523 yyerror("too many protocols defined");
3524 free(p);
3525 YYERRORgoto yyerrlab;
3526 }
3527 proto = p;
3528 }
3529break;
3530case 108:
3531#line 1097 "/usr/src/usr.sbin/relayd/parse.y"
3532{
3533 conf->sc_protocount++;
3534
3535 if ((proto->tlsflags & TLSFLAG_VERSION0x1f) == 0) {
3536 yyerror("invalid TLS protocol");
3537 YYERRORgoto yyerrlab;
3538 }
3539 TAILQ_INSERT_TAIL(conf->sc_protos, proto, entry)do { (proto)->entry.tqe_next = ((void*)0); (proto)->entry
.tqe_prev = (conf->sc_protos)->tqh_last; *(conf->sc_protos
)->tqh_last = (proto); (conf->sc_protos)->tqh_last =
&(proto)->entry.tqe_next; } while (0)
;
3540 }
3541break;
3542case 114:
3543#line 1117 "/usr/src/usr.sbin/relayd/parse.y"
3544{
3545 if (!(proto->type == RELAY_PROTO_TCP ||
3546 proto->type == RELAY_PROTO_HTTP)) {
3547 yyerror("can set tls options only for "
3548 "tcp or http protocols");
3549 YYERRORgoto yyerrlab;
3550 }
3551 }
3552break;
3553case 116:
3554#line 1125 "/usr/src/usr.sbin/relayd/parse.y"
3555{
3556 if (!(proto->type == RELAY_PROTO_TCP ||
3557 proto->type == RELAY_PROTO_HTTP)) {
3558 yyerror("can set tls options only for "
3559 "tcp or http protocols");
3560 YYERRORgoto yyerrlab;
3561 }
3562 }
3563break;
3564case 118:
3565#line 1133 "/usr/src/usr.sbin/relayd/parse.y"
3566{
3567 if (!(proto->type == RELAY_PROTO_TCP ||
3568 proto->type == RELAY_PROTO_HTTP)) {
3569 yyerror("can set tcp options only for "
3570 "tcp or http protocols");
3571 YYERRORgoto yyerrlab;
3572 }
3573 }
3574break;
3575case 120:
3576#line 1141 "/usr/src/usr.sbin/relayd/parse.y"
3577{
3578 if (!(proto->type == RELAY_PROTO_TCP ||
3579 proto->type == RELAY_PROTO_HTTP)) {
3580 yyerror("can set tcp options only for "
3581 "tcp or http protocols");
3582 YYERRORgoto yyerrlab;
3583 }
3584 }
3585break;
3586case 122:
3587#line 1149 "/usr/src/usr.sbin/relayd/parse.y"
3588{
3589 if (proto->type != RELAY_PROTO_HTTP) {
3590 yyerror("can set http options only for "
3591 "http protocol");
3592 YYERRORgoto yyerrlab;
3593 }
3594 }
3595break;
3596case 124:
3597#line 1156 "/usr/src/usr.sbin/relayd/parse.y"
3598{
3599 if (proto->type != RELAY_PROTO_HTTP) {
3600 yyerror("can set http options only for "
3601 "http protocol");
3602 YYERRORgoto yyerrlab;
3603 }
3604 }
3605break;
3606case 126:
3607#line 1163 "/usr/src/usr.sbin/relayd/parse.y"
3608{ proto->flags |= F_RETURN0x00020000; }
3609break;
3610case 127:
3611#line 1164 "/usr/src/usr.sbin/relayd/parse.y"
3612{ proto->flags |= F_RETURN0x00020000; }
3613break;
3614case 132:
3615#line 1174 "/usr/src/usr.sbin/relayd/parse.y"
3616{
3617 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > RELAY_MAXHEADERLENGTH131072) {
3618 yyerror("invalid headerlen: %lld", yyvsp[0].v.number);
3619 YYERRORgoto yyerrlab;
3620 }
3621 proto->httpheaderlen = yyvsp[0].v.number;
3622 }
3623break;
3624case 133:
3625#line 1181 "/usr/src/usr.sbin/relayd/parse.y"
3626{ proto->httpflags |= HTTPFLAG_WEBSOCKETS0x01; }
3627break;
3628case 134:
3629#line 1182 "/usr/src/usr.sbin/relayd/parse.y"
3630{ proto->httpflags &= ~HTTPFLAG_WEBSOCKETS0x01; }
3631break;
3632case 137:
3633#line 1189 "/usr/src/usr.sbin/relayd/parse.y"
3634{ proto->tcpflags |= TCPFLAG_SACK0x04; }
3635break;
3636case 138:
3637#line 1190 "/usr/src/usr.sbin/relayd/parse.y"
3638{ proto->tcpflags |= TCPFLAG_NSACK0x08; }
3639break;
3640case 139:
3641#line 1191 "/usr/src/usr.sbin/relayd/parse.y"
3642{ proto->tcpflags |= TCPFLAG_NODELAY0x01; }
3643break;
3644case 140:
3645#line 1192 "/usr/src/usr.sbin/relayd/parse.y"
3646{ proto->tcpflags |= TCPFLAG_NNODELAY0x02; }
3647break;
3648case 141:
3649#line 1193 "/usr/src/usr.sbin/relayd/parse.y"
3650{ /* default */ }
3651break;
3652case 142:
3653#line 1194 "/usr/src/usr.sbin/relayd/parse.y"
3654{ proto->tcpflags |= TCPFLAG_NSPLICE0x80; }
3655break;
3656case 143:
3657#line 1195 "/usr/src/usr.sbin/relayd/parse.y"
3658{
3659 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > RELAY_MAX_BACKLOG512) {
3660 yyerror("invalid backlog: %lld", yyvsp[0].v.number);
3661 YYERRORgoto yyerrlab;
3662 }
3663 proto->tcpbacklog = yyvsp[0].v.number;
3664 }
3665break;
3666case 144:
3667#line 1202 "/usr/src/usr.sbin/relayd/parse.y"
3668{
3669 proto->tcpflags |= TCPFLAG_BUFSIZ0x10;
3670 if ((proto->tcpbufsiz = yyvsp[0].v.number) < 0) {
3671 yyerror("invalid socket buffer size: %lld", yyvsp[0].v.number);
3672 YYERRORgoto yyerrlab;
3673 }
3674 }
3675break;
3676case 145:
3677#line 1209 "/usr/src/usr.sbin/relayd/parse.y"
3678{
3679 if (yyvsp[0].v.number < 0) {
3680 yyerror("invalid ttl: %lld", yyvsp[0].v.number);
3681 free(yyvsp[-1].v.string);
3682 YYERRORgoto yyerrlab;
3683 }
3684 if (strcasecmp("ttl", yyvsp[-1].v.string) == 0) {
3685 proto->tcpflags |= TCPFLAG_IPTTL0x20;
3686 proto->tcpipttl = yyvsp[0].v.number;
3687 } else if (strcasecmp("minttl", yyvsp[-1].v.string) == 0) {
3688 proto->tcpflags |= TCPFLAG_IPMINTTL0x40;
3689 proto->tcpipminttl = yyvsp[0].v.number;
3690 } else {
3691 yyerror("invalid TCP/IP flag: %s", yyvsp[-1].v.string);
3692 free(yyvsp[-1].v.string);
3693 YYERRORgoto yyerrlab;
3694 }
3695 free(yyvsp[-1].v.string);
3696 }
3697break;
3698case 148:
3699#line 1234 "/usr/src/usr.sbin/relayd/parse.y"
3700{ proto->tickets = 1; }
3701break;
3702case 149:
3703#line 1235 "/usr/src/usr.sbin/relayd/parse.y"
3704{ proto->tickets = 0; }
3705break;
3706case 150:
3707#line 1236 "/usr/src/usr.sbin/relayd/parse.y"
3708{
3709 if (strlcpy(proto->tlsciphers, yyvsp[0].v.string,
3710 sizeof(proto->tlsciphers)) >=
3711 sizeof(proto->tlsciphers)) {
3712 yyerror("tlsciphers truncated");
3713 free(yyvsp[0].v.string);
3714 YYERRORgoto yyerrlab;
3715 }
3716 free(yyvsp[0].v.string);
3717 }
3718break;
3719case 151:
3720#line 1246 "/usr/src/usr.sbin/relayd/parse.y"
3721{
3722 (void)strlcpy(proto->tlsdhparams, "none",
3723 sizeof(proto->tlsdhparams));
3724 }
3725break;
3726case 152:
3727#line 1250 "/usr/src/usr.sbin/relayd/parse.y"
3728{
3729 (void)strlcpy(proto->tlsdhparams, "auto",
3730 sizeof(proto->tlsdhparams));
3731 }
3732break;
3733case 153:
3734#line 1254 "/usr/src/usr.sbin/relayd/parse.y"
3735{
3736 struct tls_config *tls_cfg;
3737 if ((tls_cfg = tls_config_new()) == NULL((void*)0)) {
3738 yyerror("tls_config_new failed");
3739 free(yyvsp[0].v.string);
3740 YYERRORgoto yyerrlab;
3741 }
3742 if (tls_config_set_dheparams(tls_cfg, yyvsp[0].v.string) != 0) {
3743 yyerror("tls edh params %s: %s", yyvsp[0].v.string,
3744 tls_config_error(tls_cfg));
3745 tls_config_free(tls_cfg);
3746 free(yyvsp[0].v.string);
3747 YYERRORgoto yyerrlab;
3748 }
3749 tls_config_free(tls_cfg);
3750 if (strlcpy(proto->tlsdhparams, yyvsp[0].v.string,
3751 sizeof(proto->tlsdhparams)) >=
3752 sizeof(proto->tlsdhparams)) {
3753 yyerror("tls edh truncated");
3754 free(yyvsp[0].v.string);
3755 YYERRORgoto yyerrlab;
3756 }
3757 free(yyvsp[0].v.string);
3758 }
3759break;
3760case 154:
3761#line 1278 "/usr/src/usr.sbin/relayd/parse.y"
3762{
3763 struct tls_config *tls_cfg;
3764 if ((tls_cfg = tls_config_new()) == NULL((void*)0)) {
3765 yyerror("tls_config_new failed");
3766 free(yyvsp[0].v.string);
3767 YYERRORgoto yyerrlab;
3768 }
3769 if (tls_config_set_ecdhecurves(tls_cfg, yyvsp[0].v.string) != 0) {
3770 yyerror("tls ecdhe %s: %s", yyvsp[0].v.string,
3771 tls_config_error(tls_cfg));
3772 tls_config_free(tls_cfg);
3773 free(yyvsp[0].v.string);
3774 YYERRORgoto yyerrlab;
3775 }
3776 tls_config_free(tls_cfg);
3777 if (strlcpy(proto->tlsecdhecurves, yyvsp[0].v.string,
3778 sizeof(proto->tlsecdhecurves)) >=
3779 sizeof(proto->tlsecdhecurves)) {
3780 yyerror("tls ecdhe curves truncated");
3781 free(yyvsp[0].v.string);
3782 YYERRORgoto yyerrlab;
3783 }
3784 free(yyvsp[0].v.string);
3785 }
3786break;
3787case 155:
3788#line 1302 "/usr/src/usr.sbin/relayd/parse.y"
3789{
3790 if (strlcpy(proto->tlsca, yyvsp[0].v.string,
3791 sizeof(proto->tlsca)) >=
3792 sizeof(proto->tlsca)) {
3793 yyerror("tlsca truncated");
3794 free(yyvsp[0].v.string);
3795 YYERRORgoto yyerrlab;
3796 }
3797 free(yyvsp[0].v.string);
3798 }
3799break;
3800case 156:
3801#line 1312 "/usr/src/usr.sbin/relayd/parse.y"
3802{
3803 if (strlcpy(proto->tlscakey, yyvsp[-2].v.string,
3804 sizeof(proto->tlscakey)) >=
3805 sizeof(proto->tlscakey)) {
3806 yyerror("tlscakey truncated");
3807 free(yyvsp[-2].v.string);
3808 free(yyvsp[0].v.string);
3809 YYERRORgoto yyerrlab;
3810 }
3811 if ((proto->tlscapass = strdup(yyvsp[0].v.string)) == NULL((void*)0)) {
3812 yyerror("tlscapass");
3813 free(yyvsp[-2].v.string);
3814 free(yyvsp[0].v.string);
3815 YYERRORgoto yyerrlab;
3816 }
3817 free(yyvsp[-2].v.string);
3818 free(yyvsp[0].v.string);
3819 }
3820break;
3821case 157:
3822#line 1330 "/usr/src/usr.sbin/relayd/parse.y"
3823{
3824 if (strlcpy(proto->tlscacert, yyvsp[0].v.string,
3825 sizeof(proto->tlscacert)) >=
3826 sizeof(proto->tlscacert)) {
3827 yyerror("tlscacert truncated");
3828 free(yyvsp[0].v.string);
3829 YYERRORgoto yyerrlab;
3830 }
3831 free(yyvsp[0].v.string);
3832 }
3833break;
3834case 158:
3835#line 1340 "/usr/src/usr.sbin/relayd/parse.y"
3836{
3837 struct keyname *name;
3838
3839 if (strlen(yyvsp[0].v.string) >= PATH_MAX1024) {
3840 yyerror("keypair name too long");
3841 free(yyvsp[0].v.string);
3842 YYERRORgoto yyerrlab;
3843 }
3844 if ((name = calloc(1, sizeof(*name))) == NULL((void*)0)) {
3845 yyerror("calloc");
3846 free(yyvsp[0].v.string);
3847 YYERRORgoto yyerrlab;
3848 }
3849 name->name = yyvsp[0].v.string;
3850 TAILQ_INSERT_TAIL(&proto->tlscerts, name, entry)do { (name)->entry.tqe_next = ((void*)0); (name)->entry
.tqe_prev = (&proto->tlscerts)->tqh_last; *(&proto
->tlscerts)->tqh_last = (name); (&proto->tlscerts
)->tqh_last = &(name)->entry.tqe_next; } while (0)
;
3851 }
3852break;
3853case 159:
3854#line 1356 "/usr/src/usr.sbin/relayd/parse.y"
3855{ proto->tlsflags &= ~(yyvsp[0].v.number); }
3856break;
3857case 160:
3858#line 1357 "/usr/src/usr.sbin/relayd/parse.y"
3859{ proto->tlsflags |= yyvsp[0].v.number; }
3860break;
3861case 161:
3862#line 1360 "/usr/src/usr.sbin/relayd/parse.y"
3863{
3864 if (strcmp("sslv3", yyvsp[0].v.string) == 0)
3865 yyval.v.number = TLSFLAG_SSLV30x01;
3866 else if (strcmp("tlsv1", yyvsp[0].v.string) == 0)
3867 yyval.v.number = TLSFLAG_TLSV10x1e;
3868 else if (strcmp("tlsv1.0", yyvsp[0].v.string) == 0)
3869 yyval.v.number = TLSFLAG_TLSV1_00x02;
3870 else if (strcmp("tlsv1.1", yyvsp[0].v.string) == 0)
3871 yyval.v.number = TLSFLAG_TLSV1_10x04;
3872 else if (strcmp("tlsv1.2", yyvsp[0].v.string) == 0)
3873 yyval.v.number = TLSFLAG_TLSV1_20x08;
3874 else if (strcmp("tlsv1.3", yyvsp[0].v.string) == 0)
3875 yyval.v.number = TLSFLAG_TLSV1_30x10;
3876 else if (strcmp("cipher-server-preference", yyvsp[0].v.string) == 0)
3877 yyval.v.number = TLSFLAG_CIPHER_SERVER_PREF0x20;
3878 else if (strcmp("client-renegotiation", yyvsp[0].v.string) == 0)
3879 yyval.v.number = TLSFLAG_CLIENT_RENEG0x40;
3880 else {
3881 yyerror("invalid TLS flag: %s", yyvsp[0].v.string);
3882 free(yyvsp[0].v.string);
3883 YYERRORgoto yyerrlab;
3884 }
3885 free(yyvsp[0].v.string);
3886 }
3887break;
3888case 162:
3889#line 1386 "/usr/src/usr.sbin/relayd/parse.y"
3890{
3891 if ((rule = calloc(1, sizeof(*rule))) == NULL((void*)0))
3892 fatal("out of memory");
3893
3894 rule->rule_action = yyvsp[-5].v.number;
3895 rule->rule_proto = proto->type;
3896 rule->rule_dir = yyvsp[-4].v.dir;
3897 rule->rule_flags |= yyvsp[-3].v.number;
3898 rule->rule_af = yyvsp[-2].v.number;
3899 rule->rule_src.addr = yyvsp[-1].v.addr.ss;
3900 rule->rule_src.addr_mask = yyvsp[-1].v.addr.prefixlen;
3901 rule->rule_dst.addr = yyvsp[0].v.addr.ss;
3902 rule->rule_dst.addr_mask = yyvsp[0].v.addr.prefixlen;
3903
3904 if (RELAY_AF_NEQ(rule->rule_af,(((rule->rule_af) != 0) && ((rule->rule_src.addr
.ss_family) != 0) && ((rule->rule_af) != (rule->
rule_src.addr.ss_family)))
3905 rule->rule_src.addr.ss_family)(((rule->rule_af) != 0) && ((rule->rule_src.addr
.ss_family) != 0) && ((rule->rule_af) != (rule->
rule_src.addr.ss_family)))
||
3906 RELAY_AF_NEQ(rule->rule_af,(((rule->rule_af) != 0) && ((rule->rule_dst.addr
.ss_family) != 0) && ((rule->rule_af) != (rule->
rule_dst.addr.ss_family)))
3907 rule->rule_dst.addr.ss_family)(((rule->rule_af) != 0) && ((rule->rule_dst.addr
.ss_family) != 0) && ((rule->rule_af) != (rule->
rule_dst.addr.ss_family)))
||
3908 RELAY_AF_NEQ(rule->rule_src.addr.ss_family,(((rule->rule_src.addr.ss_family) != 0) && ((rule->
rule_dst.addr.ss_family) != 0) && ((rule->rule_src
.addr.ss_family) != (rule->rule_dst.addr.ss_family)))
3909 rule->rule_dst.addr.ss_family)(((rule->rule_src.addr.ss_family) != 0) && ((rule->
rule_dst.addr.ss_family) != 0) && ((rule->rule_src
.addr.ss_family) != (rule->rule_dst.addr.ss_family)))
) {
3910 yyerror("address family mismatch");
3911 YYERRORgoto yyerrlab;
3912 }
3913
3914 rulefile = NULL((void*)0);
3915 }
3916break;
3917case 163:
3918#line 1411 "/usr/src/usr.sbin/relayd/parse.y"
3919{
3920 if (rule_add(proto, rule, rulefile) == -1) {
3921 if (rulefile == NULL((void*)0)) {
3922 yyerror("failed to load rule");
3923 } else {
3924 yyerror("failed to load rules from %s",
3925 rulefile);
3926 free(rulefile);
3927 }
3928 rule_free(rule);
3929 free(rule);
3930 YYERRORgoto yyerrlab;
3931 }
3932 if (rulefile)
3933 free(rulefile);
3934 rulefile = NULL((void*)0);
3935 rule = NULL((void*)0);
3936 keytype = KEY_TYPE_NONE;
3937 }
3938break;
3939case 164:
3940#line 1432 "/usr/src/usr.sbin/relayd/parse.y"
3941{ yyval.v.number = RULE_ACTION_PASS; }
3942break;
3943case 165:
3944#line 1433 "/usr/src/usr.sbin/relayd/parse.y"
3945{ yyval.v.number = RULE_ACTION_BLOCK; }
3946break;
3947case 166:
3948#line 1434 "/usr/src/usr.sbin/relayd/parse.y"
3949{ yyval.v.number = RULE_ACTION_MATCH; }
3950break;
3951case 167:
3952#line 1437 "/usr/src/usr.sbin/relayd/parse.y"
3953{
3954 yyval.v.dir = dir = RELAY_DIR_REQUEST;
3955 }
3956break;
3957case 168:
3958#line 1440 "/usr/src/usr.sbin/relayd/parse.y"
3959{
3960 yyval.v.dir = dir = RELAY_DIR_REQUEST;
3961 }
3962break;
3963case 169:
3964#line 1443 "/usr/src/usr.sbin/relayd/parse.y"
3965{
3966 yyval.v.dir = dir = RELAY_DIR_RESPONSE;
3967 }
3968break;
3969case 170:
3970#line 1448 "/usr/src/usr.sbin/relayd/parse.y"
3971{ yyval.v.number = 0; }
3972break;
3973case 171:
3974#line 1449 "/usr/src/usr.sbin/relayd/parse.y"
3975{ yyval.v.number = RULE_FLAG_QUICK0x01; }
3976break;
3977case 172:
3978#line 1452 "/usr/src/usr.sbin/relayd/parse.y"
3979{ yyval.v.number = AF_UNSPEC0; }
3980break;
3981case 173:
3982#line 1453 "/usr/src/usr.sbin/relayd/parse.y"
3983{ yyval.v.number = AF_INET624; }
3984break;
3985case 174:
3986#line 1454 "/usr/src/usr.sbin/relayd/parse.y"
3987{ yyval.v.number = AF_INET2; }
3988break;
3989case 175:
3990#line 1457 "/usr/src/usr.sbin/relayd/parse.y"
3991{
3992 memset(&yyval.v.addr, 0, sizeof(yyval.v.addr));
3993 }
3994break;
3995case 176:
3996#line 1460 "/usr/src/usr.sbin/relayd/parse.y"
3997{
3998 yyval.v.addr = yyvsp[0].v.addr;
3999 }
4000break;
4001case 177:
4002#line 1465 "/usr/src/usr.sbin/relayd/parse.y"
4003{
4004 memset(&yyval.v.addr, 0, sizeof(yyval.v.addr));
4005 }
4006break;
4007case 178:
4008#line 1468 "/usr/src/usr.sbin/relayd/parse.y"
4009{
4010 yyval.v.addr = yyvsp[0].v.addr;
4011 }
4012break;
4013case 183:
4014#line 1481 "/usr/src/usr.sbin/relayd/parse.y"
4015{
4016 u_int id;
4017 if ((id = relay_httpmethod_byname(yyvsp[0].v.string)) ==
4018 HTTP_METHOD_NONE) {
4019 yyerror("unknown HTTP method currently not "
4020 "supported");
4021 free(yyvsp[0].v.string);
4022 YYERRORgoto yyerrlab;
4023 }
4024 rule->rule_method = id;
4025 free(yyvsp[0].v.string);
4026 }
4027break;
4028case 184:
4029#line 1493 "/usr/src/usr.sbin/relayd/parse.y"
4030{
4031 keytype = KEY_TYPE_COOKIE;
4032 rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.string);
4033 rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;
4034 rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL((void*)0)) ?
4035 strdup(yyvsp[0].v.string) : strdup("*"));
4036 if (rule->rule_kv[keytype].kv_key == NULL((void*)0) ||
4037 rule->rule_kv[keytype].kv_value == NULL((void*)0))
4038 fatal("out of memory");
4039 free(yyvsp[-1].v.string);
4040 if (yyvsp[0].v.string)
4041 free(yyvsp[0].v.string);
4042 rule->rule_kv[keytype].kv_type = keytype;
4043 }
4044break;
4045case 185:
4046#line 1507 "/usr/src/usr.sbin/relayd/parse.y"
4047{
4048 keytype = KEY_TYPE_COOKIE;
4049 rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;
4050 rule->rule_kv[keytype].kv_type = keytype;
4051 }
4052break;
4053case 186:
4054#line 1512 "/usr/src/usr.sbin/relayd/parse.y"
4055{
4056 keytype = KEY_TYPE_HEADER;
4057 memset(&rule->rule_kv[keytype], 0,
4058 sizeof(rule->rule_kv[keytype]));
4059 rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;
4060 rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.string);
4061 rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL((void*)0)) ?
4062 strdup(yyvsp[0].v.string) : strdup("*"));
4063 if (rule->rule_kv[keytype].kv_key == NULL((void*)0) ||
4064 rule->rule_kv[keytype].kv_value == NULL((void*)0))
4065 fatal("out of memory");
4066 free(yyvsp[-1].v.string);
4067 if (yyvsp[0].v.string)
4068 free(yyvsp[0].v.string);
4069 rule->rule_kv[keytype].kv_type = keytype;
4070 }
4071break;
4072case 187:
4073#line 1528 "/usr/src/usr.sbin/relayd/parse.y"
4074{
4075 keytype = KEY_TYPE_HEADER;
4076 rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;
4077 rule->rule_kv[keytype].kv_type = keytype;
4078 }
4079break;
4080case 188:
4081#line 1533 "/usr/src/usr.sbin/relayd/parse.y"
4082{
4083 keytype = KEY_TYPE_PATH;
4084 rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;
4085 rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.string);
4086 rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL((void*)0)) ?
4087 strdup(yyvsp[0].v.string) : strdup("*"));
4088 if (rule->rule_kv[keytype].kv_key == NULL((void*)0) ||
4089 rule->rule_kv[keytype].kv_value == NULL((void*)0))
4090 fatal("out of memory");
4091 free(yyvsp[-1].v.string);
4092 if (yyvsp[0].v.string)
4093 free(yyvsp[0].v.string);
4094 rule->rule_kv[keytype].kv_type = keytype;
4095 }
4096break;
4097case 189:
4098#line 1547 "/usr/src/usr.sbin/relayd/parse.y"
4099{
4100 keytype = KEY_TYPE_PATH;
4101 rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;
4102 rule->rule_kv[keytype].kv_type = keytype;
4103 }
4104break;
4105case 190:
4106#line 1552 "/usr/src/usr.sbin/relayd/parse.y"
4107{
4108 char *strip = NULL((void*)0);
4109
4110 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX2147483647) {
4111 yyerror("invalid strip number");
4112 YYERRORgoto yyerrlab;
4113 }
4114 if (asprintf(&strip, "%lld", yyvsp[0].v.number) <= 0)
4115 fatal("can't parse strip");
4116 keytype = KEY_TYPE_PATH;
4117 rule->rule_kv[keytype].kv_option = KEY_OPTION_STRIP;
4118 rule->rule_kv[keytype].kv_value = strip;
4119 rule->rule_kv[keytype].kv_type = keytype;
4120 }
4121break;
4122case 191:
4123#line 1566 "/usr/src/usr.sbin/relayd/parse.y"
4124{
4125 switch (yyvsp[-2].v.number) {
4126 case KEY_OPTION_APPEND:
4127 case KEY_OPTION_SET:
4128 case KEY_OPTION_REMOVE:
4129 yyerror("combining query type and the given "
4130 "option is not supported");
4131 free(yyvsp[-1].v.string);
4132 if (yyvsp[0].v.string)
4133 free(yyvsp[0].v.string);
4134 YYERRORgoto yyerrlab;
4135 break;
4136 }
4137 keytype = KEY_TYPE_QUERY;
4138 rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;
4139 rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.string);
4140 rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL((void*)0)) ?
4141 strdup(yyvsp[0].v.string) : strdup("*"));
4142 if (rule->rule_kv[keytype].kv_key == NULL((void*)0) ||
4143 rule->rule_kv[keytype].kv_value == NULL((void*)0))
4144 fatal("out of memory");
4145 free(yyvsp[-1].v.string);
4146 if (yyvsp[0].v.string)
4147 free(yyvsp[0].v.string);
4148 rule->rule_kv[keytype].kv_type = keytype;
4149 }
4150break;
4151case 192:
4152#line 1592 "/usr/src/usr.sbin/relayd/parse.y"
4153{
4154 switch (yyvsp[0].v.number) {
4155 case KEY_OPTION_APPEND:
4156 case KEY_OPTION_SET:
4157 case KEY_OPTION_REMOVE:
4158 yyerror("combining query type and the given "
4159 "option is not supported");
4160 YYERRORgoto yyerrlab;
4161 break;
4162 }
4163 keytype = KEY_TYPE_QUERY;
4164 rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;
4165 rule->rule_kv[keytype].kv_type = keytype;
4166 }
4167break;
4168case 193:
4169#line 1606 "/usr/src/usr.sbin/relayd/parse.y"
4170{
4171 switch (yyvsp[-2].v.number) {
4172 case KEY_OPTION_APPEND:
4173 case KEY_OPTION_SET:
4174 case KEY_OPTION_REMOVE:
4175 yyerror("combining url type and the given "
4176 "option is not supported");
4177 free(yyvsp[-1].v.digest.digest);
4178 free(yyvsp[0].v.string);
4179 YYERRORgoto yyerrlab;
4180 break;
4181 }
4182 keytype = KEY_TYPE_URL;
4183 rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;
4184 rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.digest.digest);
4185 rule->rule_kv[keytype].kv_digest = yyvsp[-1].v.digest.type;
4186 rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL((void*)0)) ?
4187 strdup(yyvsp[0].v.string) : strdup("*"));
4188 if (rule->rule_kv[keytype].kv_key == NULL((void*)0) ||
4189 rule->rule_kv[keytype].kv_value == NULL((void*)0))
4190 fatal("out of memory");
4191 free(yyvsp[-1].v.digest.digest);
4192 if (yyvsp[0].v.string)
4193 free(yyvsp[0].v.string);
4194 rule->rule_kv[keytype].kv_type = keytype;
4195 }
4196break;
4197case 194:
4198#line 1632 "/usr/src/usr.sbin/relayd/parse.y"
4199{
4200 switch (yyvsp[0].v.number) {
4201 case KEY_OPTION_APPEND:
4202 case KEY_OPTION_SET:
4203 case KEY_OPTION_REMOVE:
4204 yyerror("combining url type and the given "
4205 "option is not supported");
4206 YYERRORgoto yyerrlab;
4207 break;
4208 }
4209 keytype = KEY_TYPE_URL;
4210 rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;
4211 rule->rule_kv[keytype].kv_type = keytype;
4212 }
4213break;
4214case 195:
4215#line 1646 "/usr/src/usr.sbin/relayd/parse.y"
4216{
4217 if (table_findbyname(conf, yyvsp[0].v.string) == NULL((void*)0)) {
4218 yyerror("undefined forward table");
4219 free(yyvsp[0].v.string);
4220 YYERRORgoto yyerrlab;
4221 }
4222 if (strlcpy(rule->rule_tablename, yyvsp[0].v.string,
4223 sizeof(rule->rule_tablename)) >=
4224 sizeof(rule->rule_tablename)) {
4225 yyerror("invalid forward table name");
4226 free(yyvsp[0].v.string);
4227 YYERRORgoto yyerrlab;
4228 }
4229 free(yyvsp[0].v.string);
4230 }
4231break;
4232case 196:
4233#line 1661 "/usr/src/usr.sbin/relayd/parse.y"
4234{
4235 tag = tag_name2id(yyvsp[0].v.string);
4236 if (rule->rule_tag) {
4237 yyerror("tag already defined");
4238 free(yyvsp[0].v.string);
4239 rule_free(rule);
4240 free(rule);
4241 YYERRORgoto yyerrlab;
4242 }
4243 if (tag == 0) {
4244 yyerror("invalid tag");
4245 free(yyvsp[0].v.string);
4246 rule_free(rule);
4247 free(rule);
4248 YYERRORgoto yyerrlab;
4249 }
4250 rule->rule_tag = tag;
4251 if (strlcpy(rule->rule_tagname, yyvsp[0].v.string,
4252 sizeof(rule->rule_tagname)) >=
4253 sizeof(rule->rule_tagname)) {
4254 yyerror("tag truncated");
4255 free(yyvsp[0].v.string);
4256 rule_free(rule);
4257 free(rule);
4258 YYERRORgoto yyerrlab;
4259 }
4260 free(yyvsp[0].v.string);
4261 }
4262break;
4263case 197:
4264#line 1689 "/usr/src/usr.sbin/relayd/parse.y"
4265{
4266 if (tag == 0) {
4267 yyerror("no tag defined");
4268 YYERRORgoto yyerrlab;
4269 }
4270 rule->rule_tag = -1;
4271 memset(rule->rule_tagname, 0,
4272 sizeof(rule->rule_tagname));
4273 }
4274break;
4275case 198:
4276#line 1698 "/usr/src/usr.sbin/relayd/parse.y"
4277{
4278 tagged = tag_name2id(yyvsp[0].v.string);
4279 if (rule->rule_tagged) {
4280 yyerror("tagged already defined");
4281 free(yyvsp[0].v.string);
4282 rule_free(rule);
4283 free(rule);
4284 YYERRORgoto yyerrlab;
4285 }
4286 if (tagged == 0) {
4287 yyerror("invalid tag");
4288 free(yyvsp[0].v.string);
4289 rule_free(rule);
4290 free(rule);
4291 YYERRORgoto yyerrlab;
4292 }
4293 rule->rule_tagged = tagged;
4294 if (strlcpy(rule->rule_taggedname, yyvsp[0].v.string,
4295 sizeof(rule->rule_taggedname)) >=
4296 sizeof(rule->rule_taggedname)) {
4297 yyerror("tagged truncated");
4298 free(yyvsp[0].v.string);
4299 rule_free(rule);
4300 free(rule);
4301 YYERRORgoto yyerrlab;
4302 }
4303 free(yyvsp[0].v.string);
4304 }
4305break;
4306case 199:
4307#line 1726 "/usr/src/usr.sbin/relayd/parse.y"
4308{
4309 label = label_name2id(yyvsp[0].v.string);
4310 if (rule->rule_label) {
4311 yyerror("label already defined");
4312 free(yyvsp[0].v.string);
4313 rule_free(rule);
4314 free(rule);
4315 YYERRORgoto yyerrlab;
4316 }
4317 if (label == 0) {
4318 yyerror("invalid label");
4319 free(yyvsp[0].v.string);
4320 rule_free(rule);
4321 free(rule);
4322 YYERRORgoto yyerrlab;
4323 }
4324 rule->rule_label = label;
4325 if (strlcpy(rule->rule_labelname, yyvsp[0].v.string,
4326 sizeof(rule->rule_labelname)) >=
4327 sizeof(rule->rule_labelname)) {
4328 yyerror("label truncated");
4329 free(yyvsp[0].v.string);
4330 rule_free(rule);
4331 free(rule);
4332 YYERRORgoto yyerrlab;
4333 }
4334 free(yyvsp[0].v.string);
4335 }
4336break;
4337case 200:
4338#line 1754 "/usr/src/usr.sbin/relayd/parse.y"
4339{
4340 if (label == 0) {
4341 yyerror("no label defined");
4342 YYERRORgoto yyerrlab;
4343 }
4344 rule->rule_label = -1;
4345 memset(rule->rule_labelname, 0,
4346 sizeof(rule->rule_labelname));
4347 }
4348break;
4349case 201:
4350#line 1763 "/usr/src/usr.sbin/relayd/parse.y"
4351{
4352 if (rulefile != NULL((void*)0)) {
4353 yyerror("only one file per rule supported");
4354 free(yyvsp[-1].v.string);
4355 free(yyvsp[0].v.string);
4356 rule_free(rule);
4357 free(rule);
4358 YYERRORgoto yyerrlab;
4359 }
4360 if (yyvsp[0].v.string) {
4361 if ((rule->rule_kv[keytype].kv_value =
4362 strdup(yyvsp[0].v.string)) == NULL((void*)0))
4363 fatal("out of memory");
4364 free(yyvsp[0].v.string);
4365 } else
4366 rule->rule_kv[keytype].kv_value = NULL((void*)0);
4367 rulefile = yyvsp[-1].v.string;
4368 }
4369break;
4370case 202:
4371#line 1783 "/usr/src/usr.sbin/relayd/parse.y"
4372{ yyval.v.string = NULL((void*)0); }
4373break;
4374case 203:
4375#line 1784 "/usr/src/usr.sbin/relayd/parse.y"
4376{ yyval.v.string = yyvsp[0].v.string; }
4377break;
4378case 204:
4379#line 1787 "/usr/src/usr.sbin/relayd/parse.y"
4380{ yyval.v.number = KEY_OPTION_NONE; }
4381break;
4382case 205:
4383#line 1788 "/usr/src/usr.sbin/relayd/parse.y"
4384{ yyval.v.number = KEY_OPTION_APPEND; }
4385break;
4386case 206:
4387#line 1789 "/usr/src/usr.sbin/relayd/parse.y"
4388{ yyval.v.number = KEY_OPTION_SET; }
4389break;
4390case 207:
4391#line 1790 "/usr/src/usr.sbin/relayd/parse.y"
4392{ yyval.v.number = KEY_OPTION_REMOVE; }
4393break;
4394case 208:
4395#line 1791 "/usr/src/usr.sbin/relayd/parse.y"
4396{ yyval.v.number = KEY_OPTION_HASH; }
4397break;
4398case 209:
4399#line 1792 "/usr/src/usr.sbin/relayd/parse.y"
4400{ yyval.v.number = KEY_OPTION_LOG; }
4401break;
4402case 210:
4403#line 1795 "/usr/src/usr.sbin/relayd/parse.y"
4404{
4405 struct relay *r;
4406
4407 if (!loadcfg) {
4408 free(yyvsp[0].v.string);
4409 YYACCEPTgoto yyaccept;
4410 }
4411
4412 if ((r = calloc(1, sizeof (*r))) == NULL((void*)0))
4413 fatal("out of memory");
4414 TAILQ_INIT(&relays)do { (&relays)->tqh_first = ((void*)0); (&relays)->
tqh_last = &(&relays)->tqh_first; } while (0)
;
4415
4416 if (strlcpy(r->rl_conf.name, yyvsp[0].v.string,
4417 sizeof(r->rl_conf.name)) >=
4418 sizeof(r->rl_conf.name)) {
4419 yyerror("relay name truncated");
4420 free(yyvsp[0].v.string);
4421 free(r);
4422 YYERRORgoto yyerrlab;
4423 }
4424 free(yyvsp[0].v.string);
4425 if (relay_id(r) == -1) {
4426 yyerror("too many relays defined");
4427 free(r);
4428 YYERRORgoto yyerrlab;
4429 }
4430 r->rl_conf.timeout.tv_sec = RELAY_TIMEOUT600;
4431 r->rl_proto = NULL((void*)0);
4432 r->rl_conf.proto = EMPTY_ID(2147483647 *2U +1U);
4433 r->rl_conf.dstretry = 0;
4434 r->rl_tls_ca_fd = -1;
4435 r->rl_tls_cacert_fd = -1;
4436 TAILQ_INIT(&r->rl_tables)do { (&r->rl_tables)->tqh_first = ((void*)0); (&
r->rl_tables)->tqh_last = &(&r->rl_tables)->
tqh_first; } while (0)
;
4437 if (last_relay_id == INT_MAX2147483647) {
4438 yyerror("too many relays defined");
4439 free(r);
4440 YYERRORgoto yyerrlab;
4441 }
4442 dstmode = RELAY_DSTMODE_DEFAULTRELAY_DSTMODE_ROUNDROBIN;
4443 rlay = r;
4444 }
4445break;
4446case 211:
4447#line 1835 "/usr/src/usr.sbin/relayd/parse.y"
4448{
4449 struct relay *r;
4450 struct relay_config *rlconf = &rlay->rl_conf;
4451 struct keyname *name;
4452
4453 if (relay_findbyname(conf, rlconf->name) != NULL((void*)0) ||
4454 relay_findbyaddr(conf, rlconf) != NULL((void*)0)) {
4455 yyerror("relay %s or listener defined twice",
4456 rlconf->name);
4457 YYERRORgoto yyerrlab;
4458 }
4459
4460 if (rlay->rl_conf.ss.ss_family == AF_UNSPEC0) {
4461 yyerror("relay %s has no listener",
4462 rlay->rl_conf.name);
4463 YYERRORgoto yyerrlab;
4464 }
4465 if ((rlay->rl_conf.flags & (F_NATLOOK0x00001000|F_DIVERT0x01000000)) ==
4466 (F_NATLOOK0x00001000|F_DIVERT0x01000000)) {
4467 yyerror("relay %s with conflicting nat lookup "
4468 "and peer options", rlay->rl_conf.name);
4469 YYERRORgoto yyerrlab;
4470 }
4471 if ((rlay->rl_conf.flags & (F_NATLOOK0x00001000|F_DIVERT0x01000000)) == 0 &&
4472 rlay->rl_conf.dstss.ss_family == AF_UNSPEC0 &&
4473 TAILQ_EMPTY(&rlay->rl_tables)(((&rlay->rl_tables)->tqh_first) == ((void*)0))) {
4474 yyerror("relay %s has no target, rdr, "
4475 "or table", rlay->rl_conf.name);
4476 YYERRORgoto yyerrlab;
4477 }
4478 if (rlay->rl_conf.proto == EMPTY_ID(2147483647 *2U +1U)) {
4479 rlay->rl_proto = &conf->sc_proto_default;
4480 rlay->rl_conf.proto = conf->sc_proto_default.id;
4481 }
4482
4483 if (TAILQ_EMPTY(&rlay->rl_proto->tlscerts)(((&rlay->rl_proto->tlscerts)->tqh_first) == ((void
*)0))
&&
4484 relay_load_certfiles(conf, rlay, NULL((void*)0)) == -1) {
4485 yyerror("cannot load certificates for relay %s",
4486 rlay->rl_conf.name);
4487 YYERRORgoto yyerrlab;
4488 }
4489 TAILQ_FOREACH(name, &rlay->rl_proto->tlscerts, entry)for((name) = ((&rlay->rl_proto->tlscerts)->tqh_first
); (name) != ((void*)0); (name) = ((name)->entry.tqe_next)
)
{
4490 if (relay_load_certfiles(conf,
4491 rlay, name->name) == -1) {
4492 yyerror("cannot load keypair %s"
4493 " for relay %s", name->name,
4494 rlay->rl_conf.name);
4495 YYERRORgoto yyerrlab;
4496 }
4497 }
4498
4499 conf->sc_relaycount++;
4500 SPLAY_INIT(&rlay->rl_sessions)do { (&rlay->rl_sessions)->sph_root = ((void*)0); }
while (0)
;
4501 TAILQ_INSERT_TAIL(conf->sc_relays, rlay, rl_entry)do { (rlay)->rl_entry.tqe_next = ((void*)0); (rlay)->rl_entry
.tqe_prev = (conf->sc_relays)->tqh_last; *(conf->sc_relays
)->tqh_last = (rlay); (conf->sc_relays)->tqh_last = &
(rlay)->rl_entry.tqe_next; } while (0)
;
4502
4503 tableport = 0;
4504
4505 while ((r = TAILQ_FIRST(&relays)((&relays)->tqh_first)) != NULL((void*)0)) {
4506 TAILQ_REMOVE(&relays, r, rl_entry)do { if (((r)->rl_entry.tqe_next) != ((void*)0)) (r)->rl_entry
.tqe_next->rl_entry.tqe_prev = (r)->rl_entry.tqe_prev; else
(&relays)->tqh_last = (r)->rl_entry.tqe_prev; *(r)
->rl_entry.tqe_prev = (r)->rl_entry.tqe_next; ; ; } while
(0)
;
4507 if (relay_inherit(rlay, r) == NULL((void*)0)) {
4508 YYERRORgoto yyerrlab;
4509 }
4510 }
4511 rlay = NULL((void*)0);
4512 }
4513break;
4514case 214:
4515#line 1906 "/usr/src/usr.sbin/relayd/parse.y"
4516{
4517 struct addresslist al;
4518 struct address *h;
4519 struct relay *r;
4520
4521 if (rlay->rl_conf.ss.ss_family != AF_UNSPEC0) {
4522 if ((r = calloc(1, sizeof (*r))) == NULL((void*)0))
4523 fatal("out of memory");
4524 TAILQ_INSERT_TAIL(&relays, r, rl_entry)do { (r)->rl_entry.tqe_next = ((void*)0); (r)->rl_entry
.tqe_prev = (&relays)->tqh_last; *(&relays)->tqh_last
= (r); (&relays)->tqh_last = &(r)->rl_entry.tqe_next
; } while (0)
;
4525 } else
4526 r = rlay;
4527 if (yyvsp[-1].v.port.op != PF_OP_EQ) {
4528 yyerror("invalid port");
4529 free(yyvsp[-2].v.string);
4530 YYERRORgoto yyerrlab;
4531 }
4532
4533 TAILQ_INIT(&al)do { (&al)->tqh_first = ((void*)0); (&al)->tqh_last
= &(&al)->tqh_first; } while (0)
;
4534 if (host(yyvsp[-2].v.string, &al, 1, &yyvsp[-1].v.port, NULL((void*)0), -1) <= 0) {
4535 yyerror("invalid listen ip: %s", yyvsp[-2].v.string);
4536 free(yyvsp[-2].v.string);
4537 YYERRORgoto yyerrlab;
4538 }
4539 free(yyvsp[-2].v.string);
4540 h = TAILQ_FIRST(&al)((&al)->tqh_first);
4541 bcopy(&h->ss, &r->rl_conf.ss, sizeof(r->rl_conf.ss));
4542 r->rl_conf.port = h->port.val[0];
4543 if (yyvsp[0].v.number) {
4544 r->rl_conf.flags |= F_TLS0x00000800;
4545 conf->sc_conf.flags |= F_TLS0x00000800;
4546 }
4547 tableport = h->port.val[0];
4548 host_free(&al);
4549 }
4550break;
4551case 215:
4552#line 1940 "/usr/src/usr.sbin/relayd/parse.y"
4553{
4554 rlay->rl_conf.fwdmode = yyvsp[-4].v.number;
4555 if (yyvsp[-4].v.number == FWD_ROUTE) {
4556 yyerror("no route for relays");
4557 YYERRORgoto yyerrlab;
4558 }
4559 if (yyvsp[-3].v.number) {
4560 rlay->rl_conf.flags |= F_TLSCLIENT0x00200000;
4561 conf->sc_conf.flags |= F_TLSCLIENT0x00200000;
4562 }
4563 }
4564break;
4565case 216:
4566#line 1951 "/usr/src/usr.sbin/relayd/parse.y"
4567{
4568 if ((rlay->rl_conf.timeout.tv_sec = yyvsp[0].v.number) < 0) {
4569 yyerror("invalid timeout: %lld", yyvsp[0].v.number);
4570 YYERRORgoto yyerrlab;
4571 }
4572 if (rlay->rl_conf.timeout.tv_sec > INT_MAX2147483647) {
4573 yyerror("timeout too large: %lld", yyvsp[0].v.number);
4574 YYERRORgoto yyerrlab;
4575 }
4576 }
4577break;
4578case 217:
4579#line 1961 "/usr/src/usr.sbin/relayd/parse.y"
4580{
4581 struct protocol *p;
4582
4583 if (rlay->rl_conf.proto != EMPTY_ID(2147483647 *2U +1U)) {
4584 yyerror("more than one protocol specified");
4585 YYERRORgoto yyerrlab;
4586 }
4587
4588 TAILQ_FOREACH(p, conf->sc_protos, entry)for((p) = ((conf->sc_protos)->tqh_first); (p) != ((void
*)0); (p) = ((p)->entry.tqe_next))
4589 if (!strcmp(p->name, yyvsp[0].v.string))
4590 break;
4591 if (p == NULL((void*)0)) {
4592 yyerror("no such protocol: %s", yyvsp[0].v.string);
4593 free(yyvsp[0].v.string);
4594 YYERRORgoto yyerrlab;
4595 }
4596 p->flags |= F_USED0x00000004;
4597 rlay->rl_conf.proto = p->id;
4598 rlay->rl_proto = p;
4599 free(yyvsp[0].v.string);
4600 }
4601break;
4602case 218:
4603#line 1982 "/usr/src/usr.sbin/relayd/parse.y"
4604{ rlay->rl_conf.flags |= F_DISABLE0x00000001; }
4605break;
4606case 220:
4607#line 1986 "/usr/src/usr.sbin/relayd/parse.y"
4608{
4609 struct addresslist al;
4610 struct address *h;
4611
4612 if (rlay->rl_conf.dstss.ss_family != AF_UNSPEC0) {
4613 yyerror("relay %s target or redirection "
4614 "already specified", rlay->rl_conf.name);
4615 free(yyvsp[-2].v.string);
4616 YYERRORgoto yyerrlab;
4617 }
4618 if (yyvsp[-1].v.port.op != PF_OP_EQ) {
4619 yyerror("invalid port");
4620 free(yyvsp[-2].v.string);
4621 YYERRORgoto yyerrlab;
4622 }
4623
4624 TAILQ_INIT(&al)do { (&al)->tqh_first = ((void*)0); (&al)->tqh_last
= &(&al)->tqh_first; } while (0)
;
4625 if (host(yyvsp[-2].v.string, &al, 1, &yyvsp[-1].v.port, NULL((void*)0), -1) <= 0) {
4626 yyerror("invalid forward ip: %s", yyvsp[-2].v.string);
4627 free(yyvsp[-2].v.string);
4628 YYERRORgoto yyerrlab;
4629 }
4630 free(yyvsp[-2].v.string);
4631 h = TAILQ_FIRST(&al)((&al)->tqh_first);
4632 bcopy(&h->ss, &rlay->rl_conf.dstss,
4633 sizeof(rlay->rl_conf.dstss));
4634 rlay->rl_conf.dstport = h->port.val[0];
4635 rlay->rl_conf.dstretry = yyvsp[0].v.number;
4636 host_free(&al);
4637 }
4638break;
4639case 221:
4640#line 2016 "/usr/src/usr.sbin/relayd/parse.y"
4641{
4642 conf->sc_conf.flags |= F_NEEDPF0x00080000;
4643 rlay->rl_conf.flags |= F_NATLOOK0x00001000;
4644 rlay->rl_conf.dstretry = yyvsp[0].v.number;
4645 }
4646break;
4647case 222:
4648#line 2021 "/usr/src/usr.sbin/relayd/parse.y"
4649{
4650 conf->sc_conf.flags |= F_NEEDPF0x00080000;
4651 rlay->rl_conf.flags |= F_DIVERT0x01000000;
4652 rlay->rl_conf.dstretry = yyvsp[0].v.number;
4653 }
4654break;
4655case 223:
4656#line 2026 "/usr/src/usr.sbin/relayd/parse.y"
4657{
4658 struct relay_table *rlt;
4659
4660 if ((rlt = calloc(1, sizeof(*rlt))) == NULL((void*)0)) {
4661 yyerror("failed to allocate table reference");
4662 YYERRORgoto yyerrlab;
4663 }
4664
4665 rlt->rlt_table = yyvsp[0].v.table;
4666 rlt->rlt_table->conf.flags |= F_USED0x00000004;
4667 rlt->rlt_mode = dstmode;
4668 rlt->rlt_flags = F_USED0x00000004;
4669 if (!TAILQ_EMPTY(&rlay->rl_tables)(((&rlay->rl_tables)->tqh_first) == ((void*)0)))
4670 rlt->rlt_flags |= F_BACKUP0x00000002;
4671
4672 if (hashkey != NULL((void*)0) &&
4673 (rlay->rl_conf.flags & F_HASHKEY0x08000000) == 0) {
4674 memcpy(&rlay->rl_conf.hashkey,
4675 hashkey, sizeof(rlay->rl_conf.hashkey));
4676 rlay->rl_conf.flags |= F_HASHKEY0x08000000;
4677 }
4678 free(hashkey);
4679 hashkey = NULL((void*)0);
4680
4681 TAILQ_INSERT_TAIL(&rlay->rl_tables, rlt, rlt_entry)do { (rlt)->rlt_entry.tqe_next = ((void*)0); (rlt)->rlt_entry
.tqe_prev = (&rlay->rl_tables)->tqh_last; *(&rlay
->rl_tables)->tqh_last = (rlt); (&rlay->rl_tables
)->tqh_last = &(rlt)->rlt_entry.tqe_next; } while (
0)
;
4682 }
4683break;
4684case 224:
4685#line 2054 "/usr/src/usr.sbin/relayd/parse.y"
4686{ yyval.v.number = RELAY_DSTMODE_DEFAULTRELAY_DSTMODE_ROUNDROBIN; }
4687break;
4688case 225:
4689#line 2055 "/usr/src/usr.sbin/relayd/parse.y"
4690{ yyval.v.number = RELAY_DSTMODE_LOADBALANCE; }
4691break;
4692case 226:
4693#line 2056 "/usr/src/usr.sbin/relayd/parse.y"
4694{ yyval.v.number = RELAY_DSTMODE_ROUNDROBIN; }
4695break;
4696case 227:
4697#line 2057 "/usr/src/usr.sbin/relayd/parse.y"
4698{ yyval.v.number = RELAY_DSTMODE_HASH; }
4699break;
4700case 228:
4701#line 2058 "/usr/src/usr.sbin/relayd/parse.y"
4702{ yyval.v.number = RELAY_DSTMODE_LEASTSTATES; }
4703break;
4704case 229:
4705#line 2059 "/usr/src/usr.sbin/relayd/parse.y"
4706{ yyval.v.number = RELAY_DSTMODE_SRCHASH; }
4707break;
4708case 230:
4709#line 2060 "/usr/src/usr.sbin/relayd/parse.y"
4710{ yyval.v.number = RELAY_DSTMODE_RANDOM; }
4711break;
4712case 231:
4713#line 2063 "/usr/src/usr.sbin/relayd/parse.y"
4714{
4715 struct router *rt = NULL((void*)0);
4716
4717 if (!loadcfg) {
4718 free(yyvsp[0].v.string);
4719 YYACCEPTgoto yyaccept;
4720 }
4721
4722 conf->sc_conf.flags |= F_NEEDRT0x00400000;
4723 TAILQ_FOREACH(rt, conf->sc_rts, rt_entry)for((rt) = ((conf->sc_rts)->tqh_first); (rt) != ((void*
)0); (rt) = ((rt)->rt_entry.tqe_next))
4724 if (!strcmp(rt->rt_conf.name, yyvsp[0].v.string))
4725 break;
4726 if (rt != NULL((void*)0)) {
4727 yyerror("router %s defined twice", yyvsp[0].v.string);
4728 free(yyvsp[0].v.string);
4729 YYERRORgoto yyerrlab;
4730 }
4731
4732 if ((rt = calloc(1, sizeof (*rt))) == NULL((void*)0))
4733 fatal("out of memory");
4734
4735 if (strlcpy(rt->rt_conf.name, yyvsp[0].v.string,
4736 sizeof(rt->rt_conf.name)) >=
4737 sizeof(rt->rt_conf.name)) {
4738 yyerror("router name truncated");
4739 free(rt);
4740 YYERRORgoto yyerrlab;
4741 }
4742 free(yyvsp[0].v.string);
4743 rt->rt_conf.id = ++last_rt_id;
4744 if (last_rt_id == INT_MAX2147483647) {
4745 yyerror("too many routers defined");
4746 free(rt);
4747 YYERRORgoto yyerrlab;
4748 }
4749 TAILQ_INIT(&rt->rt_netroutes)do { (&rt->rt_netroutes)->tqh_first = ((void*)0); (
&rt->rt_netroutes)->tqh_last = &(&rt->rt_netroutes
)->tqh_first; } while (0)
;
4750 router = rt;
4751
4752 tableport = -1;
4753 }
4754break;
4755case 232:
4756#line 2102 "/usr/src/usr.sbin/relayd/parse.y"
4757{
4758 if (!router->rt_conf.nroutes) {
4759 yyerror("router %s without routes",
4760 router->rt_conf.name);
4761 free(router);
4762 router = NULL((void*)0);
4763 YYERRORgoto yyerrlab;
4764 }
4765
4766 conf->sc_routercount++;
4767 TAILQ_INSERT_TAIL(conf->sc_rts, router, rt_entry)do { (router)->rt_entry.tqe_next = ((void*)0); (router)->
rt_entry.tqe_prev = (conf->sc_rts)->tqh_last; *(conf->
sc_rts)->tqh_last = (router); (conf->sc_rts)->tqh_last
= &(router)->rt_entry.tqe_next; } while (0)
;
4768 router = NULL((void*)0);
4769
4770 tableport = 0;
4771 }
4772break;
4773case 235:
4774#line 2123 "/usr/src/usr.sbin/relayd/parse.y"
4775{
4776 struct netroute *nr;
4777
4778 if (router->rt_conf.af == AF_UNSPEC0)
4779 router->rt_conf.af = yyvsp[0].v.addr.ss.ss_family;
4780 else if (router->rt_conf.af != yyvsp[0].v.addr.ss.ss_family) {
4781 yyerror("router %s address family mismatch",
4782 router->rt_conf.name);
4783 YYERRORgoto yyerrlab;
4784 }
4785
4786 if ((nr = calloc(1, sizeof(*nr))) == NULL((void*)0))
4787 fatal("out of memory");
4788
4789 nr->nr_conf.id = ++last_nr_id;
4790 if (last_nr_id == INT_MAX2147483647) {
4791 yyerror("too many routes defined");
4792 free(nr);
4793 YYERRORgoto yyerrlab;
4794 }
4795 nr->nr_conf.prefixlen = yyvsp[0].v.addr.prefixlen;
4796 nr->nr_conf.routerid = router->rt_conf.id;
4797 nr->nr_router = router;
4798 bcopy(&yyvsp[0].v.addr.ss, &nr->nr_conf.ss, sizeof(yyvsp[0].v.addr.ss));
4799
4800 router->rt_conf.nroutes++;
4801 conf->sc_routecount++;
4802 TAILQ_INSERT_TAIL(&router->rt_netroutes, nr, nr_entry)do { (nr)->nr_entry.tqe_next = ((void*)0); (nr)->nr_entry
.tqe_prev = (&router->rt_netroutes)->tqh_last; *(&
router->rt_netroutes)->tqh_last = (nr); (&router->
rt_netroutes)->tqh_last = &(nr)->nr_entry.tqe_next;
} while (0)
;
4803 TAILQ_INSERT_TAIL(conf->sc_routes, nr, nr_route)do { (nr)->nr_route.tqe_next = ((void*)0); (nr)->nr_route
.tqe_prev = (conf->sc_routes)->tqh_last; *(conf->sc_routes
)->tqh_last = (nr); (conf->sc_routes)->tqh_last = &
(nr)->nr_route.tqe_next; } while (0)
;
4804 }
4805break;
4806case 236:
4807#line 2153 "/usr/src/usr.sbin/relayd/parse.y"
4808{
4809 free(hashkey);
4810 hashkey = NULL((void*)0);
4811
4812 if (router->rt_gwtable) {
4813 yyerror("router %s table already specified",
4814 router->rt_conf.name);
4815 purge_table(conf, conf->sc_tables, yyvsp[0].v.table);
4816 YYERRORgoto yyerrlab;
4817 }
4818 router->rt_gwtable = yyvsp[0].v.table;
4819 router->rt_gwtable->conf.flags |= F_USED0x00000004;
4820 router->rt_conf.gwtable = yyvsp[0].v.table->conf.id;
4821 router->rt_conf.gwport = yyvsp[0].v.table->conf.port;
4822 }
4823break;
4824case 237:
4825#line 2168 "/usr/src/usr.sbin/relayd/parse.y"
4826{
4827 if (router->rt_conf.rtable) {
4828 yyerror("router %s rtable already specified",
4829 router->rt_conf.name);
4830 YYERRORgoto yyerrlab;
4831 }
4832 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > RT_TABLEID_MAX255) {
4833 yyerror("invalid rtable id %lld", yyvsp[0].v.number);
4834 YYERRORgoto yyerrlab;
4835 }
4836 router->rt_conf.rtable = yyvsp[0].v.number;
4837 }
4838break;
4839case 238:
4840#line 2180 "/usr/src/usr.sbin/relayd/parse.y"
4841{
4842 if (strlcpy(router->rt_conf.label, yyvsp[0].v.string,
4843 sizeof(router->rt_conf.label)) >=
4844 sizeof(router->rt_conf.label)) {
4845 yyerror("route label truncated");
4846 free(yyvsp[0].v.string);
4847 YYERRORgoto yyerrlab;
4848 }
4849 free(yyvsp[0].v.string);
4850 }
4851break;
4852case 239:
4853#line 2190 "/usr/src/usr.sbin/relayd/parse.y"
4854{ rlay->rl_conf.flags |= F_DISABLE0x00000001; }
4855break;
4856case 241:
4857#line 2194 "/usr/src/usr.sbin/relayd/parse.y"
4858{
4859 rlay->rl_conf.dstaf.ss_family = AF_UNSPEC0;
4860 }
4861break;
4862case 242:
4863#line 2197 "/usr/src/usr.sbin/relayd/parse.y"
4864{
4865 rlay->rl_conf.dstaf.ss_family = AF_INET2;
4866 }
4867break;
4868case 243:
4869#line 2200 "/usr/src/usr.sbin/relayd/parse.y"
4870{
4871 struct sockaddr_in6 *sin6;
4872
4873 sin6 = (struct sockaddr_in6 *)&rlay->rl_conf.dstaf;
4874 if (inet_pton(AF_INET624, yyvsp[0].v.string, &sin6->sin6_addr) == -1) {
4875 yyerror("invalid ipv6 address %s", yyvsp[0].v.string);
4876 free(yyvsp[0].v.string);
4877 YYERRORgoto yyerrlab;
4878 }
4879 free(yyvsp[0].v.string);
4880
4881 sin6->sin6_family = AF_INET624;
4882 sin6->sin6_len = sizeof(*sin6);
4883 }
4884break;
4885case 244:
4886#line 2216 "/usr/src/usr.sbin/relayd/parse.y"
4887{ yyval.v.string = NULL((void*)0); }
4888break;
4889case 245:
4890#line 2217 "/usr/src/usr.sbin/relayd/parse.y"
4891{ yyval.v.string = yyvsp[0].v.string; }
4892break;
4893case 246:
4894#line 2220 "/usr/src/usr.sbin/relayd/parse.y"
4895{
4896 if ((hst = calloc(1, sizeof(*(hst)))) == NULL((void*)0))
4897 fatal("out of memory");
4898
4899 if (strlcpy(hst->conf.name, yyvsp[0].v.addr.name,
4900 sizeof(hst->conf.name)) >= sizeof(hst->conf.name)) {
4901 yyerror("host name truncated");
4902 free(hst);
4903 YYERRORgoto yyerrlab;
4904 }
4905 bcopy(&yyvsp[0].v.addr.ss, &hst->conf.ss, sizeof(yyvsp[0].v.addr.ss));
4906 hst->conf.id = 0; /* will be set later */
4907 SLIST_INIT(&hst->children){ ((&hst->children)->slh_first) = ((void*)0); };
4908 }
4909break;
4910case 247:
4911#line 2233 "/usr/src/usr.sbin/relayd/parse.y"
4912{
4913 yyval.v.host = hst;
4914 hst = NULL((void*)0);
4915 }
4916break;
4917case 252:
4918#line 2247 "/usr/src/usr.sbin/relayd/parse.y"
4919{
4920 if (hst->conf.retry) {
4921 yyerror("retry value already set");
4922 YYERRORgoto yyerrlab;
4923 }
4924 if (yyvsp[0].v.number < 0) {
4925 yyerror("invalid retry value: %lld\n", yyvsp[0].v.number);
4926 YYERRORgoto yyerrlab;
4927 }
4928 hst->conf.retry = yyvsp[0].v.number;
4929 }
4930break;
4931case 253:
4932#line 2258 "/usr/src/usr.sbin/relayd/parse.y"
4933{
4934 if (hst->conf.parentid) {
4935 yyerror("parent value already set");
4936 YYERRORgoto yyerrlab;
4937 }
4938 if (yyvsp[0].v.number < 0) {
4939 yyerror("invalid parent value: %lld\n", yyvsp[0].v.number);
4940 YYERRORgoto yyerrlab;
4941 }
4942 hst->conf.parentid = yyvsp[0].v.number;
4943 }
4944break;
4945case 254:
4946#line 2269 "/usr/src/usr.sbin/relayd/parse.y"
4947{
4948 if (hst->conf.priority) {
4949 yyerror("priority already set");
4950 YYERRORgoto yyerrlab;
4951 }
4952 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > RTP_MAX63) {
4953 yyerror("invalid priority value: %lld\n", yyvsp[0].v.number);
4954 YYERRORgoto yyerrlab;
4955 }
4956 hst->conf.priority = yyvsp[0].v.number;
4957 }
4958break;
4959case 255:
4960#line 2280 "/usr/src/usr.sbin/relayd/parse.y"
4961{
4962 if (hst->conf.ttl) {
4963 yyerror("ttl value already set");
4964 YYERRORgoto yyerrlab;
4965 }
4966 if (yyvsp[0].v.number < 0) {
4967 yyerror("invalid ttl value: %lld\n", yyvsp[0].v.number);
4968 YYERRORgoto yyerrlab;
4969 }
4970 hst->conf.ttl = yyvsp[0].v.number;
4971 }
4972break;
4973case 256:
4974#line 2293 "/usr/src/usr.sbin/relayd/parse.y"
4975{
4976 struct address *h;
4977 struct addresslist al;
4978
4979 if (strlcpy(yyval.v.addr.name, yyvsp[0].v.string,
4980 sizeof(yyval.v.addr.name)) >= sizeof(yyval.v.addr.name)) {
4981 yyerror("host name truncated");
4982 free(yyvsp[0].v.string);
4983 YYERRORgoto yyerrlab;
4984 }
4985
4986 TAILQ_INIT(&al)do { (&al)->tqh_first = ((void*)0); (&al)->tqh_last
= &(&al)->tqh_first; } while (0)
;
4987 if (host(yyvsp[0].v.string, &al, 1, NULL((void*)0), NULL((void*)0), -1) <= 0) {
4988 yyerror("invalid host %s", yyvsp[0].v.string);
4989 free(yyvsp[0].v.string);
4990 YYERRORgoto yyerrlab;
4991 }
4992 free(yyvsp[0].v.string);
4993 h = TAILQ_FIRST(&al)((&al)->tqh_first);
4994 memcpy(&yyval.v.addr.ss, &h->ss, sizeof(yyval.v.addr.ss));
4995 host_free(&al);
4996 }
4997break;
4998case 257:
4999#line 2317 "/usr/src/usr.sbin/relayd/parse.y"
5000{
5001 yyval.v.addr = yyvsp[-2].v.addr;
5002 if ((yyval.v.addr.ss.ss_family == AF_INET2 &&
5003 (yyvsp[0].v.number > 32 || yyvsp[0].v.number < 0)) ||
5004 (yyval.v.addr.ss.ss_family == AF_INET624 &&
5005 (yyvsp[0].v.number > 128 || yyvsp[0].v.number < 0))) {
5006 yyerror("invalid prefixlen %lld", yyvsp[0].v.number);
5007 YYERRORgoto yyerrlab;
5008 }
5009 yyval.v.addr.prefixlen = yyvsp[0].v.number;
5010 }
5011break;
5012case 258:
5013#line 2328 "/usr/src/usr.sbin/relayd/parse.y"
5014{
5015 yyval.v.addr = yyvsp[0].v.addr;
5016 if (yyval.v.addr.ss.ss_family == AF_INET2)
5017 yyval.v.addr.prefixlen = 32;
5018 else if (yyval.v.addr.ss.ss_family == AF_INET624)
5019 yyval.v.addr.prefixlen = 128;
5020 }
5021break;
5022case 259:
5023#line 2337 "/usr/src/usr.sbin/relayd/parse.y"
5024{ yyval.v.number = 0; }
5025break;
5026case 260:
5027#line 2338 "/usr/src/usr.sbin/relayd/parse.y"
5028{
5029 if ((yyval.v.number = yyvsp[0].v.number) < 0) {
5030 yyerror("invalid retry value: %lld\n", yyvsp[0].v.number);
5031 YYERRORgoto yyerrlab;
5032 }
5033 }
5034break;
5035case 261:
5036#line 2347 "/usr/src/usr.sbin/relayd/parse.y"
5037{
5038 if (yyvsp[0].v.number < 0) {
5039 yyerror("invalid timeout: %lld\n", yyvsp[0].v.number);
5040 YYERRORgoto yyerrlab;
5041 }
5042 yyval.v.tv.tv_sec = yyvsp[0].v.number / 1000;
5043 yyval.v.tv.tv_usec = (yyvsp[0].v.number % 1000) * 1000;
5044 }
5045break;
5046#line 5039 "parse.c"
5047 }
5048 yyssp -= yym;
5049 yystate = *yyssp;
5050 yyvsp -= yym;
5051 yym = yylhs[yyn];
5052 if (yystate == 0 && yym == 0)
5053 {
5054#if YYDEBUG0
5055 if (yydebug)
5056 printf("%sdebug: after reduction, shifting from state 0 to\
5057 state %d\n", YYPREFIX"yy", YYFINAL1);
5058#endif
5059 yystate = YYFINAL1;
5060 *++yyssp = YYFINAL1;
5061 *++yyvsp = yyval;
5062 if (yychar < 0)
5063 {
5064 if ((yychar = yylex()) < 0) yychar = 0;
5065#if YYDEBUG0
5066 if (yydebug)
5067 {
5068 yys = 0;
5069 if (yychar <= YYMAXTOKEN371) yys = yyname[yychar];
5070 if (!yys) yys = "illegal-symbol";
5071 printf("%sdebug: state %d, reading %d (%s)\n",
5072 YYPREFIX"yy", YYFINAL1, yychar, yys);
5073 }
5074#endif
5075 }
5076 if (yychar == 0) goto yyaccept;
5077 goto yyloop;
5078 }
5079 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
5080 yyn <= YYTABLESIZE1576 && yycheck[yyn] == yystate)
5081 yystate = yytable[yyn];
5082 else
5083 yystate = yydgoto[yym];
5084#if YYDEBUG0
5085 if (yydebug)
5086 printf("%sdebug: after reduction, shifting from state %d \
5087to state %d\n", YYPREFIX"yy", *yyssp, yystate);
5088#endif
5089 if (yyssp >= yysslim && yygrowstack())
5090 {
5091 goto yyoverflow;
5092 }
5093 *++yyssp = yystate;
5094 *++yyvsp = yyval;
5095 goto yyloop;
5096yyoverflow:
5097 yyerror("yacc stack overflow");
5098yyabort:
5099 if (yyss)
5100 free(yyss);
5101 if (yyvs)
5102 free(yyvs);
5103 yyss = yyssp = NULL((void*)0);
5104 yyvs = yyvsp = NULL((void*)0);
5105 yystacksize = 0;
5106 return (1);
5107yyaccept:
5108 if (yyss)
5109 free(yyss);
5110 if (yyvs)
5111 free(yyvs);
5112 yyss = yyssp = NULL((void*)0);
5113 yyvs = yyvsp = NULL((void*)0);
5114 yystacksize = 0;
5115 return (0);
5116}