GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ospf6d/parse.c Lines: 0 290 0.0 %
Date: 2017-11-07 Branches: 0 253 0.0 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#define YYBYACC 1
4
#define YYMAJOR 1
5
#define YYMINOR 9
6
#define YYLEX yylex()
7
#define YYEMPTY -1
8
#define yyclearin (yychar=(YYEMPTY))
9
#define yyerrok (yyerrflag=0)
10
#define YYRECOVERING() (yyerrflag!=0)
11
#define YYPREFIX "yy"
12
#line 25 "parse.y"
13
#include <sys/types.h>
14
#include <sys/socket.h>
15
#include <sys/stat.h>
16
#include <netinet/in.h>
17
#include <arpa/inet.h>
18
19
#include <ctype.h>
20
#include <err.h>
21
#include <errno.h>
22
#include <unistd.h>
23
#include <ifaddrs.h>
24
#include <limits.h>
25
#include <netdb.h>
26
#include <stdarg.h>
27
#include <stdio.h>
28
#include <string.h>
29
#include <syslog.h>
30
31
#include "ospf6.h"
32
#include "ospf6d.h"
33
#include "ospfe.h"
34
#include "log.h"
35
36
TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
37
static struct file {
38
	TAILQ_ENTRY(file)	 entry;
39
	FILE			*stream;
40
	char			*name;
41
	int			 lineno;
42
	int			 errors;
43
} *file, *topfile;
44
struct file	*pushfile(const char *, int);
45
int		 popfile(void);
46
int		 check_file_secrecy(int, const char *);
47
int		 yyparse(void);
48
int		 yylex(void);
49
int		 yyerror(const char *, ...)
50
    __attribute__((__format__ (printf, 1, 2)))
51
    __attribute__((__nonnull__ (1)));
52
int		 kw_cmp(const void *, const void *);
53
int		 lookup(char *);
54
int		 lgetc(int);
55
int		 lungetc(int);
56
int		 findeol(void);
57
58
TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
59
struct sym {
60
	TAILQ_ENTRY(sym)	 entry;
61
	int			 used;
62
	int			 persist;
63
	char			*nam;
64
	char			*val;
65
};
66
int		 symset(const char *, const char *, int);
67
char		*symget(const char *);
68
69
void		 clear_config(struct ospfd_conf *xconf);
70
u_int32_t	 get_rtr_id(void);
71
int	 host(const char *, struct in6_addr *);
72
int	 prefix(const char *, struct in6_addr *, u_int8_t *);
73
74
static struct ospfd_conf	*conf;
75
static int			 errors = 0;
76
77
struct area	*area = NULL;
78
struct iface	*iface = NULL;
79
80
struct config_defaults {
81
	u_int16_t	dead_interval;
82
	u_int16_t	transmit_delay;
83
	u_int16_t	hello_interval;
84
	u_int16_t	rxmt_interval;
85
	u_int16_t	metric;
86
	u_int8_t	priority;
87
};
88
89
struct config_defaults	 globaldefs;
90
struct config_defaults	 areadefs;
91
struct config_defaults	 ifacedefs;
92
struct config_defaults	*defs;
93
94
struct area	*conf_get_area(struct in_addr);
95
96
typedef struct {
97
	union {
98
		int64_t		 number;
99
		char		*string;
100
		struct redistribute *redist;
101
	} v;
102
	int lineno;
103
} YYSTYPE;
104
105
#line 106 "parse.c"
106
#define AREA 257
107
#define INTERFACE 258
108
#define ROUTERID 259
109
#define FIBUPDATE 260
110
#define REDISTRIBUTE 261
111
#define RTLABEL 262
112
#define STUB 263
113
#define ROUTER 264
114
#define SPFDELAY 265
115
#define SPFHOLDTIME 266
116
#define EXTTAG 267
117
#define METRIC 268
118
#define PASSIVE 269
119
#define HELLOINTERVAL 270
120
#define TRANSMITDELAY 271
121
#define RETRANSMITINTERVAL 272
122
#define ROUTERDEADTIME 273
123
#define ROUTERPRIORITY 274
124
#define SET 275
125
#define TYPE 276
126
#define YES 277
127
#define NO 278
128
#define DEMOTE 279
129
#define INCLUDE 280
130
#define ERROR 281
131
#define STRING 282
132
#define NUMBER 283
133
#define YYERRCODE 256
134
const short yylhs[] =
135
	{                                        -1,
136
    0,    0,    0,    0,    0,    0,    0,    9,    7,    7,
137
    1,    1,    2,    2,   11,   10,   10,   10,   10,   10,
138
   10,   10,   10,    8,    8,    3,    3,    3,    4,    4,
139
    5,    5,   13,   13,   13,   13,   13,   13,   14,   14,
140
   16,   15,   15,   17,   12,    6,    6,   18,   18,   19,
141
   19,   19,   22,   20,   21,   21,   21,   23,   23,   24,
142
   24,   24,
143
};
144
const short yylen[] =
145
	{                                         2,
146
    0,    3,    2,    3,    3,    3,    3,    2,    2,    1,
147
    1,    1,    0,    1,    3,    2,    2,    1,    4,    2,
148
    2,    3,    1,    4,    5,    0,    2,    7,    3,    1,
149
    2,    2,    2,    2,    2,    2,    2,    2,    2,    0,
150
    2,    1,    0,    0,    7,    1,    0,    3,    2,    1,
151
    3,    1,    0,    4,    4,    3,    0,    3,    2,    1,
152
    2,    1,
153
};
154
const short yydefred[] =
155
	{                                      1,
156
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
157
    0,    0,    0,    0,    0,   14,    0,    0,    3,    0,
158
   18,    0,    0,    0,    0,   23,    7,   44,   16,   11,
159
   12,   17,    0,    0,   20,   21,   33,   37,   36,   38,
160
   35,   34,    8,    0,    0,    2,    4,    5,    6,    0,
161
    0,   22,   10,    0,    0,    0,    0,   19,    9,    0,
162
    0,   24,    0,    0,   25,    0,    0,   27,    0,   39,
163
    0,    0,   52,    0,    0,   50,   31,   32,    0,   53,
164
    0,   45,    0,   49,    0,    0,   46,   51,    0,   48,
165
    0,   30,    0,   54,   41,   42,    0,    0,    0,   28,
166
   29,   60,    0,   56,   62,    0,    0,   61,   55,    0,
167
   59,   58,
168
};
169
const short yydgoto[] =
170
	{                                       1,
171
   32,   20,   62,   91,   68,   88,   54,   21,   22,   23,
172
   24,   25,   73,   64,   98,   90,   50,   74,   75,   76,
173
   94,   86,  106,  107,
174
};
175
const short yysindex[] =
176
	{                                      0,
177
  -10,    6, -271, -262, -263, -259, -246, -258, -256, -252,
178
 -250, -244, -241, -240, -239,    0, -254,  -15,    0, -231,
179
    0,   42,   45,   48,   49,    0,    0,    0,    0,    0,
180
    0,    0, -207, -263,    0,    0,    0,    0,    0,    0,
181
    0,    0,    0, -221, -253,    0,    0,    0,    0,  -61,
182
 -220,    0,    0, -218, -216, -200,   58,    0,    0, -200,
183
   -9,    0,   58, -223,    0, -209, -206,    0,  -47,    0,
184
 -203, -202,    0,  -84,   58,    0,    0,    0,   58,    0,
185
 -199,    0,   71,    0, -264,  -40,    0,    0,   58,    0,
186
   -7,    0,   58,    0,    0,    0,  -39, -264,  -72,    0,
187
    0,    0, -197,    0,    0,  -60,   58,    0,    0,   71,
188
    0,    0,};
189
const short yyrindex[] =
190
	{                                      0,
191
 -174,    0,    0,    0,    0,    0,    0,    0,    0,    0,
192
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
193
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
194
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
195
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
196
    0,    0,    0,   78,    0,   79, -201,    0,    0,   79,
197
  -33,    0, -118,    0,    0,    0,    0,    0,    0,    0,
198
    0,    0,    0,    0,  -43,    0,    0,    0, -255,    0,
199
    7,    0,    0,    0,    0,   24,    0,    0, -101,    0,
200
  -93,    0,  -31,    0,    0,    0,    0,    0,    0,    0,
201
    0,    0,    0,    0,    0,    0,  -31,    0,    0,    0,
202
    0,    0,};
203
const short yygindex[] =
204
	{                                      0,
205
   57,    0,   32,    0,  -79,    0,    0,    0,    0,    0,
206
    0,    0,    1,  -53,    0,  -17,    0,    0,   21,    0,
207
    0,    0,    0,   -8,
208
};
209
#define YYTABLESIZE 303
210
const short yytable[] =
211
	{                                      19,
212
   63,   26,   63,   66,   40,   92,   40,   69,   55,   70,
213
   28,   67,   40,   30,   31,   27,   47,   34,  101,   29,
214
   40,   84,   33,   40,   35,   85,   36,   43,   56,   45,
215
   37,   40,   38,   57,   71,   95,   96,   97,   39,   99,
216
   82,   40,   41,   42,   10,   44,   11,   12,   13,   14,
217
   15,   46,  104,  111,   47,   72,   40,   48,   49,   51,
218
   53,   57,   58,   59,  109,   60,   40,   63,   40,   40,
219
   40,   40,   40,   77,   61,   79,   78,   40,   80,   81,
220
   89,   40,   93,   87,  108,  100,   13,   15,   26,   40,
221
   52,   65,  112,   40,   83,    0,    0,  110,    0,  105,
222
    0,    0,    0,    0,    0,    0,  105,    0,    0,    0,
223
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
224
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
225
    0,   47,    0,    0,    0,    0,    0,    0,    0,   40,
226
    0,    0,    0,    0,    0,    0,    0,    0,   57,   40,
227
   40,   40,   40,   40,   40,   40,   40,   40,    0,    0,
228
   40,    0,    0,    0,    0,    0,   40,   40,   40,   40,
229
   40,   40,   40,   71,   43,    0,    0,   40,    0,    0,
230
    0,    0,   43,   10,    0,   11,   12,   13,   14,   15,
231
    0,    0,    0,    0,   72,   10,  102,   11,   12,   13,
232
   14,   15,    0,    0,    0,    0,  103,   10,  102,   11,
233
   12,   13,   14,   15,   40,    0,    0,    0,  103,    0,
234
    0,    0,    0,    0,   40,    0,   40,   40,   40,   40,
235
   40,    0,    0,    0,    0,   40,   40,   40,   40,   40,
236
   40,   40,   40,    0,    0,    2,    3,   40,    4,    5,
237
    0,    6,    7,    0,    8,    9,    0,   10,   66,   11,
238
   12,   13,   14,   15,   47,    0,   67,   16,    0,   17,
239
    0,   18,    0,    0,   47,    0,   47,   47,   47,   47,
240
   47,   57,    0,    0,    0,   47,    0,    0,    0,    0,
241
    0,   57,    0,   57,   57,   57,   57,   57,    0,    0,
242
    0,    0,   57,
243
};
244
const short yycheck[] =
245
	{                                      10,
246
   10,    1,   10,  268,  123,   85,  125,   61,  262,   63,
247
  282,  276,  268,  277,  278,   10,   10,  264,   98,  282,
248
  276,   75,  282,  125,  283,   79,  283,  282,  282,  261,
249
  283,  125,  283,   10,  258,   89,   44,   91,  283,   93,
250
  125,  283,  283,  283,  268,   61,  270,  271,  272,  273,
251
  274,   10,  125,  107,   10,  279,  258,   10,   10,  267,
252
  282,  123,  283,  282,  125,  282,  268,   10,  270,  271,
253
  272,  273,  274,  283,  275,  123,  283,  279,  282,  282,
254
   10,  125,  123,  283,  282,  125,  261,   10,   10,  123,
255
   34,   60,  110,  125,   74,   -1,   -1,  106,   -1,   99,
256
   -1,   -1,   -1,   -1,   -1,   -1,  106,   -1,   -1,   -1,
257
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
258
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
259
   -1,  125,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  258,
260
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  125,  268,
261
  269,  270,  271,  272,  273,  274,  258,  276,   -1,   -1,
262
  279,   -1,   -1,   -1,   -1,   -1,  268,  269,  270,  271,
263
  272,  273,  274,  258,  268,   -1,   -1,  279,   -1,   -1,
264
   -1,   -1,  276,  268,   -1,  270,  271,  272,  273,  274,
265
   -1,   -1,   -1,   -1,  279,  268,  269,  270,  271,  272,
266
  273,  274,   -1,   -1,   -1,   -1,  279,  268,  269,  270,
267
  271,  272,  273,  274,  258,   -1,   -1,   -1,  279,   -1,
268
   -1,   -1,   -1,   -1,  268,   -1,  270,  271,  272,  273,
269
  274,   -1,   -1,   -1,   -1,  279,  268,  269,  270,  271,
270
  272,  273,  274,   -1,   -1,  256,  257,  279,  259,  260,
271
   -1,  262,  263,   -1,  265,  266,   -1,  268,  268,  270,
272
  271,  272,  273,  274,  258,   -1,  276,  278,   -1,  280,
273
   -1,  282,   -1,   -1,  268,   -1,  270,  271,  272,  273,
274
  274,  258,   -1,   -1,   -1,  279,   -1,   -1,   -1,   -1,
275
   -1,  268,   -1,  270,  271,  272,  273,  274,   -1,   -1,
276
   -1,   -1,  279,
277
};
278
#define YYFINAL 1
279
#ifndef YYDEBUG
280
#define YYDEBUG 0
281
#endif
282
#define YYMAXTOKEN 283
283
#if YYDEBUG
284
const char * const yyname[] =
285
	{
286
"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,
287
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,
288
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
289
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,
290
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
291
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
292
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,"AREA",
293
"INTERFACE","ROUTERID","FIBUPDATE","REDISTRIBUTE","RTLABEL","STUB","ROUTER",
294
"SPFDELAY","SPFHOLDTIME","EXTTAG","METRIC","PASSIVE","HELLOINTERVAL",
295
"TRANSMITDELAY","RETRANSMITINTERVAL","ROUTERDEADTIME","ROUTERPRIORITY","SET",
296
"TYPE","YES","NO","DEMOTE","INCLUDE","ERROR","STRING","NUMBER",
297
};
298
const char * const yyrule[] =
299
	{"$accept : grammar",
300
"grammar :",
301
"grammar : grammar include '\\n'",
302
"grammar : grammar '\\n'",
303
"grammar : grammar conf_main '\\n'",
304
"grammar : grammar varset '\\n'",
305
"grammar : grammar area '\\n'",
306
"grammar : grammar error '\\n'",
307
"include : INCLUDE STRING",
308
"string : string STRING",
309
"string : STRING",
310
"yesno : YES",
311
"yesno : NO",
312
"no :",
313
"no : NO",
314
"varset : STRING '=' string",
315
"conf_main : ROUTERID STRING",
316
"conf_main : FIBUPDATE yesno",
317
"conf_main : redistribute",
318
"conf_main : RTLABEL STRING EXTTAG NUMBER",
319
"conf_main : SPFDELAY NUMBER",
320
"conf_main : SPFHOLDTIME NUMBER",
321
"conf_main : STUB ROUTER yesno",
322
"conf_main : defaults",
323
"redistribute : no REDISTRIBUTE STRING optlist",
324
"redistribute : no REDISTRIBUTE RTLABEL STRING optlist",
325
"optlist :",
326
"optlist : SET option",
327
"optlist : SET optnl '{' optnl optlist_l optnl '}'",
328
"optlist_l : optlist_l comma option",
329
"optlist_l : option",
330
"option : METRIC NUMBER",
331
"option : TYPE NUMBER",
332
"defaults : METRIC NUMBER",
333
"defaults : ROUTERPRIORITY NUMBER",
334
"defaults : ROUTERDEADTIME NUMBER",
335
"defaults : TRANSMITDELAY NUMBER",
336
"defaults : HELLOINTERVAL NUMBER",
337
"defaults : RETRANSMITINTERVAL NUMBER",
338
"optnl : '\\n' optnl",
339
"optnl :",
340
"nl : '\\n' optnl",
341
"comma : ','",
342
"comma :",
343
"$$1 :",
344
"area : AREA STRING $$1 '{' optnl areaopts_l '}'",
345
"demotecount : NUMBER",
346
"demotecount :",
347
"areaopts_l : areaopts_l areaoptsl nl",
348
"areaopts_l : areaoptsl optnl",
349
"areaoptsl : interface",
350
"areaoptsl : DEMOTE STRING demotecount",
351
"areaoptsl : defaults",
352
"$$2 :",
353
"interface : INTERFACE STRING $$2 interface_block",
354
"interface_block : '{' optnl interfaceopts_l '}'",
355
"interface_block : '{' optnl '}'",
356
"interface_block :",
357
"interfaceopts_l : interfaceopts_l interfaceoptsl nl",
358
"interfaceopts_l : interfaceoptsl optnl",
359
"interfaceoptsl : PASSIVE",
360
"interfaceoptsl : DEMOTE STRING",
361
"interfaceoptsl : defaults",
362
};
363
#endif
364
#ifdef YYSTACKSIZE
365
#undef YYMAXDEPTH
366
#define YYMAXDEPTH YYSTACKSIZE
367
#else
368
#ifdef YYMAXDEPTH
369
#define YYSTACKSIZE YYMAXDEPTH
370
#else
371
#define YYSTACKSIZE 10000
372
#define YYMAXDEPTH 10000
373
#endif
374
#endif
375
#define YYINITSTACKSIZE 200
376
/* LINTUSED */
377
int yydebug;
378
int yynerrs;
379
int yyerrflag;
380
int yychar;
381
short *yyssp;
382
YYSTYPE *yyvsp;
383
YYSTYPE yyval;
384
YYSTYPE yylval;
385
short *yyss;
386
short *yysslim;
387
YYSTYPE *yyvs;
388
unsigned int yystacksize;
389
int yyparse(void);
390
#line 523 "parse.y"
391
392
struct keywords {
393
	const char	*k_name;
394
	int		 k_val;
395
};
396
397
int
398
yyerror(const char *fmt, ...)
399
{
400
	va_list		 ap;
401
	char		*msg;
402
403
	file->errors++;
404
	va_start(ap, fmt);
405
	if (vasprintf(&msg, fmt, ap) == -1)
406
		fatalx("yyerror vasprintf");
407
	va_end(ap);
408
	logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
409
	free(msg);
410
	return (0);
411
}
412
413
int
414
kw_cmp(const void *k, const void *e)
415
{
416
	return (strcmp(k, ((const struct keywords *)e)->k_name));
417
}
418
419
int
420
lookup(char *s)
421
{
422
	/* this has to be sorted always */
423
	static const struct keywords keywords[] = {
424
		{"area",		AREA},
425
		{"demote",		DEMOTE},
426
		{"external-tag",	EXTTAG},
427
		{"fib-update",		FIBUPDATE},
428
		{"hello-interval",	HELLOINTERVAL},
429
		{"include",		INCLUDE},
430
		{"interface",		INTERFACE},
431
		{"metric",		METRIC},
432
		{"no",			NO},
433
		{"passive",		PASSIVE},
434
		{"redistribute",	REDISTRIBUTE},
435
		{"retransmit-interval",	RETRANSMITINTERVAL},
436
		{"router",		ROUTER},
437
		{"router-dead-time",	ROUTERDEADTIME},
438
		{"router-id",		ROUTERID},
439
		{"router-priority",	ROUTERPRIORITY},
440
		{"rtlabel",		RTLABEL},
441
		{"set",			SET},
442
		{"spf-delay",		SPFDELAY},
443
		{"spf-holdtime",	SPFHOLDTIME},
444
		{"stub",		STUB},
445
		{"transmit-delay",	TRANSMITDELAY},
446
		{"type",		TYPE},
447
		{"yes",			YES}
448
	};
449
	const struct keywords	*p;
450
451
	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
452
	    sizeof(keywords[0]), kw_cmp);
453
454
	if (p)
455
		return (p->k_val);
456
	else
457
		return (STRING);
458
}
459
460
#define MAXPUSHBACK	128
461
462
u_char	*parsebuf;
463
int	 parseindex;
464
u_char	 pushback_buffer[MAXPUSHBACK];
465
int	 pushback_index = 0;
466
467
int
468
lgetc(int quotec)
469
{
470
	int		c, next;
471
472
	if (parsebuf) {
473
		/* Read character from the parsebuffer instead of input. */
474
		if (parseindex >= 0) {
475
			c = parsebuf[parseindex++];
476
			if (c != '\0')
477
				return (c);
478
			parsebuf = NULL;
479
		} else
480
			parseindex++;
481
	}
482
483
	if (pushback_index)
484
		return (pushback_buffer[--pushback_index]);
485
486
	if (quotec) {
487
		if ((c = getc(file->stream)) == EOF) {
488
			yyerror("reached end of file while parsing "
489
			    "quoted string");
490
			if (file == topfile || popfile() == EOF)
491
				return (EOF);
492
			return (quotec);
493
		}
494
		return (c);
495
	}
496
497
	while ((c = getc(file->stream)) == '\\') {
498
		next = getc(file->stream);
499
		if (next != '\n') {
500
			c = next;
501
			break;
502
		}
503
		yylval.lineno = file->lineno;
504
		file->lineno++;
505
	}
506
507
	while (c == EOF) {
508
		if (file == topfile || popfile() == EOF)
509
			return (EOF);
510
		c = getc(file->stream);
511
	}
512
	return (c);
513
}
514
515
int
516
lungetc(int c)
517
{
518
	if (c == EOF)
519
		return (EOF);
520
	if (parsebuf) {
521
		parseindex--;
522
		if (parseindex >= 0)
523
			return (c);
524
	}
525
	if (pushback_index < MAXPUSHBACK-1)
526
		return (pushback_buffer[pushback_index++] = c);
527
	else
528
		return (EOF);
529
}
530
531
int
532
findeol(void)
533
{
534
	int	c;
535
536
	parsebuf = NULL;
537
538
	/* skip to either EOF or the first real EOL */
539
	while (1) {
540
		if (pushback_index)
541
			c = pushback_buffer[--pushback_index];
542
		else
543
			c = lgetc(0);
544
		if (c == '\n') {
545
			file->lineno++;
546
			break;
547
		}
548
		if (c == EOF)
549
			break;
550
	}
551
	return (ERROR);
552
}
553
554
int
555
yylex(void)
556
{
557
	u_char	 buf[8096];
558
	u_char	*p, *val;
559
	int	 quotec, next, c;
560
	int	 token;
561
562
top:
563
	p = buf;
564
	while ((c = lgetc(0)) == ' ' || c == '\t')
565
		; /* nothing */
566
567
	yylval.lineno = file->lineno;
568
	if (c == '#')
569
		while ((c = lgetc(0)) != '\n' && c != EOF)
570
			; /* nothing */
571
	if (c == '$' && parsebuf == NULL) {
572
		while (1) {
573
			if ((c = lgetc(0)) == EOF)
574
				return (0);
575
576
			if (p + 1 >= buf + sizeof(buf) - 1) {
577
				yyerror("string too long");
578
				return (findeol());
579
			}
580
			if (isalnum(c) || c == '_') {
581
				*p++ = c;
582
				continue;
583
			}
584
			*p = '\0';
585
			lungetc(c);
586
			break;
587
		}
588
		val = symget(buf);
589
		if (val == NULL) {
590
			yyerror("macro '%s' not defined", buf);
591
			return (findeol());
592
		}
593
		parsebuf = val;
594
		parseindex = 0;
595
		goto top;
596
	}
597
598
	switch (c) {
599
	case '\'':
600
	case '"':
601
		quotec = c;
602
		while (1) {
603
			if ((c = lgetc(quotec)) == EOF)
604
				return (0);
605
			if (c == '\n') {
606
				file->lineno++;
607
				continue;
608
			} else if (c == '\\') {
609
				if ((next = lgetc(quotec)) == EOF)
610
					return (0);
611
				if (next == quotec || c == ' ' || c == '\t')
612
					c = next;
613
				else if (next == '\n') {
614
					file->lineno++;
615
					continue;
616
				} else
617
					lungetc(next);
618
			} else if (c == quotec) {
619
				*p = '\0';
620
				break;
621
			} else if (c == '\0') {
622
				yyerror("syntax error");
623
				return (findeol());
624
			}
625
			if (p + 1 >= buf + sizeof(buf) - 1) {
626
				yyerror("string too long");
627
				return (findeol());
628
			}
629
			*p++ = c;
630
		}
631
		yylval.v.string = strdup(buf);
632
		if (yylval.v.string == NULL)
633
			err(1, "yylex: strdup");
634
		return (STRING);
635
	}
636
637
#define allowed_to_end_number(x) \
638
	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
639
640
	if (c == '-' || isdigit(c)) {
641
		do {
642
			*p++ = c;
643
			if ((unsigned)(p-buf) >= sizeof(buf)) {
644
				yyerror("string too long");
645
				return (findeol());
646
			}
647
		} while ((c = lgetc(0)) != EOF && isdigit(c));
648
		lungetc(c);
649
		if (p == buf + 1 && buf[0] == '-')
650
			goto nodigits;
651
		if (c == EOF || allowed_to_end_number(c)) {
652
			const char *errstr = NULL;
653
654
			*p = '\0';
655
			yylval.v.number = strtonum(buf, LLONG_MIN,
656
			    LLONG_MAX, &errstr);
657
			if (errstr) {
658
				yyerror("\"%s\" invalid number: %s",
659
				    buf, errstr);
660
				return (findeol());
661
			}
662
			return (NUMBER);
663
		} else {
664
nodigits:
665
			while (p > buf + 1)
666
				lungetc(*--p);
667
			c = *--p;
668
			if (c == '-')
669
				return (c);
670
		}
671
	}
672
673
#define allowed_in_string(x) \
674
	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
675
	x != '{' && x != '}' && \
676
	x != '!' && x != '=' && x != '#' && \
677
	x != ','))
678
679
	if (isalnum(c) || c == ':' || c == '_') {
680
		do {
681
			*p++ = c;
682
			if ((unsigned)(p-buf) >= sizeof(buf)) {
683
				yyerror("string too long");
684
				return (findeol());
685
			}
686
		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
687
		lungetc(c);
688
		*p = '\0';
689
		if ((token = lookup(buf)) == STRING)
690
			if ((yylval.v.string = strdup(buf)) == NULL)
691
				err(1, "yylex: strdup");
692
		return (token);
693
	}
694
	if (c == '\n') {
695
		yylval.lineno = file->lineno;
696
		file->lineno++;
697
	}
698
	if (c == EOF)
699
		return (0);
700
	return (c);
701
}
702
703
int
704
check_file_secrecy(int fd, const char *fname)
705
{
706
	struct stat	st;
707
708
	if (fstat(fd, &st)) {
709
		log_warn("cannot stat %s", fname);
710
		return (-1);
711
	}
712
	if (st.st_uid != 0 && st.st_uid != getuid()) {
713
		log_warnx("%s: owner not root or current user", fname);
714
		return (-1);
715
	}
716
	if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) {
717
		log_warnx("%s: group writable or world read/writable", fname);
718
		return (-1);
719
	}
720
	return (0);
721
}
722
723
struct file *
724
pushfile(const char *name, int secret)
725
{
726
	struct file	*nfile;
727
728
	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
729
		log_warn("malloc");
730
		return (NULL);
731
	}
732
	if ((nfile->name = strdup(name)) == NULL) {
733
		log_warn("malloc");
734
		free(nfile);
735
		return (NULL);
736
	}
737
	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
738
		log_warn("%s", nfile->name);
739
		free(nfile->name);
740
		free(nfile);
741
		return (NULL);
742
	} else if (secret &&
743
	    check_file_secrecy(fileno(nfile->stream), nfile->name)) {
744
		fclose(nfile->stream);
745
		free(nfile->name);
746
		free(nfile);
747
		return (NULL);
748
	}
749
	nfile->lineno = 1;
750
	TAILQ_INSERT_TAIL(&files, nfile, entry);
751
	return (nfile);
752
}
753
754
int
755
popfile(void)
756
{
757
	struct file	*prev;
758
759
	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
760
		prev->errors += file->errors;
761
762
	TAILQ_REMOVE(&files, file, entry);
763
	fclose(file->stream);
764
	free(file->name);
765
	free(file);
766
	file = prev;
767
	return (file ? 0 : EOF);
768
}
769
770
struct ospfd_conf *
771
parse_config(char *filename, int opts)
772
{
773
	struct sym	*sym, *next;
774
775
	if ((conf = calloc(1, sizeof(struct ospfd_conf))) == NULL)
776
		fatal("parse_config");
777
	conf->opts = opts;
778
	if (conf->opts & OSPFD_OPT_STUB_ROUTER)
779
		conf->flags |= OSPFD_FLAG_STUB_ROUTER;
780
781
	bzero(&globaldefs, sizeof(globaldefs));
782
	defs = &globaldefs;
783
	defs->dead_interval = DEFAULT_RTR_DEAD_TIME;
784
	defs->transmit_delay = DEFAULT_TRANSMIT_DELAY;
785
	defs->hello_interval = DEFAULT_HELLO_INTERVAL;
786
	defs->rxmt_interval = DEFAULT_RXMT_INTERVAL;
787
	defs->metric = DEFAULT_METRIC;
788
	defs->priority = DEFAULT_PRIORITY;
789
790
	conf->spf_delay = DEFAULT_SPF_DELAY;
791
	conf->spf_hold_time = DEFAULT_SPF_HOLDTIME;
792
	conf->spf_state = SPF_IDLE;
793
794
	if ((file = pushfile(filename, !(conf->opts & OSPFD_OPT_NOACTION))) == NULL) {
795
		free(conf);
796
		return (NULL);
797
	}
798
	topfile = file;
799
800
	LIST_INIT(&conf->area_list);
801
	LIST_INIT(&conf->cand_list);
802
	SIMPLEQ_INIT(&conf->redist_list);
803
804
	yyparse();
805
	errors = file->errors;
806
	popfile();
807
808
	/* Free macros and check which have not been used. */
809
	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
810
		if ((conf->opts & OSPFD_OPT_VERBOSE2) && !sym->used)
811
			fprintf(stderr, "warning: macro '%s' not "
812
			    "used\n", sym->nam);
813
		if (!sym->persist) {
814
			free(sym->nam);
815
			free(sym->val);
816
			TAILQ_REMOVE(&symhead, sym, entry);
817
			free(sym);
818
		}
819
	}
820
821
	/* free global config defaults */
822
	if (errors) {
823
		clear_config(conf);
824
		return (NULL);
825
	}
826
827
	if (conf->rtr_id.s_addr == 0)
828
		conf->rtr_id.s_addr = get_rtr_id();
829
830
	return (conf);
831
}
832
833
int
834
symset(const char *nam, const char *val, int persist)
835
{
836
	struct sym	*sym;
837
838
	TAILQ_FOREACH(sym, &symhead, entry) {
839
		if (strcmp(nam, sym->nam) == 0)
840
			break;
841
	}
842
843
	if (sym != NULL) {
844
		if (sym->persist == 1)
845
			return (0);
846
		else {
847
			free(sym->nam);
848
			free(sym->val);
849
			TAILQ_REMOVE(&symhead, sym, entry);
850
			free(sym);
851
		}
852
	}
853
	if ((sym = calloc(1, sizeof(*sym))) == NULL)
854
		return (-1);
855
856
	sym->nam = strdup(nam);
857
	if (sym->nam == NULL) {
858
		free(sym);
859
		return (-1);
860
	}
861
	sym->val = strdup(val);
862
	if (sym->val == NULL) {
863
		free(sym->nam);
864
		free(sym);
865
		return (-1);
866
	}
867
	sym->used = 0;
868
	sym->persist = persist;
869
	TAILQ_INSERT_TAIL(&symhead, sym, entry);
870
	return (0);
871
}
872
873
int
874
cmdline_symset(char *s)
875
{
876
	char	*sym, *val;
877
	int	ret;
878
	size_t	len;
879
880
	if ((val = strrchr(s, '=')) == NULL)
881
		return (-1);
882
883
	len = strlen(s) - strlen(val) + 1;
884
	if ((sym = malloc(len)) == NULL)
885
		errx(1, "cmdline_symset: malloc");
886
887
	strlcpy(sym, s, len);
888
889
	ret = symset(sym, val + 1, 1);
890
	free(sym);
891
892
	return (ret);
893
}
894
895
char *
896
symget(const char *nam)
897
{
898
	struct sym	*sym;
899
900
	TAILQ_FOREACH(sym, &symhead, entry) {
901
		if (strcmp(nam, sym->nam) == 0) {
902
			sym->used = 1;
903
			return (sym->val);
904
		}
905
	}
906
	return (NULL);
907
}
908
909
struct area *
910
conf_get_area(struct in_addr id)
911
{
912
	struct area	*a;
913
914
	a = area_find(conf, id);
915
	if (a)
916
		return (a);
917
	a = area_new();
918
	LIST_INSERT_HEAD(&conf->area_list, a, entry);
919
920
	a->id.s_addr = id.s_addr;
921
922
	return (a);
923
}
924
925
void
926
clear_config(struct ospfd_conf *xconf)
927
{
928
	struct area	*a;
929
930
	while ((a = LIST_FIRST(&xconf->area_list)) != NULL) {
931
		LIST_REMOVE(a, entry);
932
		area_del(a);
933
	}
934
935
	free(xconf);
936
}
937
938
u_int32_t
939
get_rtr_id(void)
940
{
941
	struct ifaddrs		*ifap, *ifa;
942
	u_int32_t		 ip = 0, cur, localnet;
943
944
	localnet = htonl(INADDR_LOOPBACK & IN_CLASSA_NET);
945
946
	if (getifaddrs(&ifap) == -1)
947
		fatal("getifaddrs");
948
949
	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
950
		if (strncmp(ifa->ifa_name, "carp", 4) == 0)
951
			continue;
952
		if (ifa->ifa_addr->sa_family != AF_INET)
953
			continue;
954
		cur = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
955
		if ((cur & localnet) == localnet)	/* skip 127/8 */
956
			continue;
957
		if (ntohl(cur) < ntohl(ip) || ip == 0)
958
			ip = cur;
959
	}
960
	freeifaddrs(ifap);
961
962
	if (ip == 0)
963
		fatal("router-id is 0.0.0.0");
964
965
	return (ip);
966
}
967
968
int
969
host(const char *s, struct in6_addr *addr)
970
{
971
	struct addrinfo	hints, *r;
972
973
	if (s == NULL)
974
		return (0);
975
976
	bzero(addr, sizeof(struct in6_addr));
977
	bzero(&hints, sizeof(hints));
978
	hints.ai_family = AF_INET6;
979
	hints.ai_socktype = SOCK_DGRAM; /*dummy*/
980
	hints.ai_flags = AI_NUMERICHOST;
981
	if (getaddrinfo(s, "0", &hints, &r) == 0) {
982
		*addr = ((struct sockaddr_in6 *)r->ai_addr)->sin6_addr;
983
		/* XXX address scope !!! */
984
		/* ((struct sockaddr_in6 *)r->ai_addr)->sin6_scope_id */
985
		freeaddrinfo(r);
986
		return (1);
987
	}
988
	return (0);
989
}
990
991
int
992
prefix(const char *s, struct in6_addr *addr, u_int8_t *plen)
993
{
994
	char		*p, *ps;
995
	const char	*errstr;
996
	int		 mask;
997
998
	if (s == NULL)
999
		return (0);
1000
1001
	if ((p = strrchr(s, '/')) != NULL) {
1002
		mask = strtonum(p + 1, 0, 128, &errstr);
1003
		if (errstr)
1004
			errx(1, "invalid netmask: %s", errstr);
1005
1006
		if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL)
1007
			err(1, "parse_prefix: malloc");
1008
		strlcpy(ps, s, strlen(s) - strlen(p) + 1);
1009
1010
		if (host(ps, addr) == 0) {
1011
			free(ps);
1012
			return (0);
1013
		}
1014
1015
		inet6applymask(addr, addr, mask);
1016
		*plen = mask;
1017
		return (1);
1018
	}
1019
	*plen = 128;
1020
	return (host(s, addr));
1021
}
1022
#line 1015 "parse.c"
1023
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
1024
static int yygrowstack(void)
1025
{
1026
    unsigned int newsize;
1027
    long sslen;
1028
    short *newss;
1029
    YYSTYPE *newvs;
1030
1031
    if ((newsize = yystacksize) == 0)
1032
        newsize = YYINITSTACKSIZE;
1033
    else if (newsize >= YYMAXDEPTH)
1034
        return -1;
1035
    else if ((newsize *= 2) > YYMAXDEPTH)
1036
        newsize = YYMAXDEPTH;
1037
    sslen = yyssp - yyss;
1038
#ifdef SIZE_MAX
1039
#define YY_SIZE_MAX SIZE_MAX
1040
#else
1041
#define YY_SIZE_MAX 0xffffffffU
1042
#endif
1043
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
1044
        goto bail;
1045
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
1046
      (short *)malloc(newsize * sizeof *newss); /* overflow check above */
1047
    if (newss == NULL)
1048
        goto bail;
1049
    yyss = newss;
1050
    yyssp = newss + sslen;
1051
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
1052
        goto bail;
1053
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
1054
      (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
1055
    if (newvs == NULL)
1056
        goto bail;
1057
    yyvs = newvs;
1058
    yyvsp = newvs + sslen;
1059
    yystacksize = newsize;
1060
    yysslim = yyss + newsize - 1;
1061
    return 0;
1062
bail:
1063
    if (yyss)
1064
            free(yyss);
1065
    if (yyvs)
1066
            free(yyvs);
1067
    yyss = yyssp = NULL;
1068
    yyvs = yyvsp = NULL;
1069
    yystacksize = 0;
1070
    return -1;
1071
}
1072
1073
#define YYABORT goto yyabort
1074
#define YYREJECT goto yyabort
1075
#define YYACCEPT goto yyaccept
1076
#define YYERROR goto yyerrlab
1077
int
1078
yyparse(void)
1079
{
1080
    int yym, yyn, yystate;
1081
#if YYDEBUG
1082
    const char *yys;
1083
1084
    if ((yys = getenv("YYDEBUG")))
1085
    {
1086
        yyn = *yys;
1087
        if (yyn >= '0' && yyn <= '9')
1088
            yydebug = yyn - '0';
1089
    }
1090
#endif /* YYDEBUG */
1091
1092
    yynerrs = 0;
1093
    yyerrflag = 0;
1094
    yychar = (-1);
1095
1096
    if (yyss == NULL && yygrowstack()) goto yyoverflow;
1097
    yyssp = yyss;
1098
    yyvsp = yyvs;
1099
    *yyssp = yystate = 0;
1100
1101
yyloop:
1102
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1103
    if (yychar < 0)
1104
    {
1105
        if ((yychar = yylex()) < 0) yychar = 0;
1106
#if YYDEBUG
1107
        if (yydebug)
1108
        {
1109
            yys = 0;
1110
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1111
            if (!yys) yys = "illegal-symbol";
1112
            printf("%sdebug: state %d, reading %d (%s)\n",
1113
                    YYPREFIX, yystate, yychar, yys);
1114
        }
1115
#endif
1116
    }
1117
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1118
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1119
    {
1120
#if YYDEBUG
1121
        if (yydebug)
1122
            printf("%sdebug: state %d, shifting to state %d\n",
1123
                    YYPREFIX, yystate, yytable[yyn]);
1124
#endif
1125
        if (yyssp >= yysslim && yygrowstack())
1126
        {
1127
            goto yyoverflow;
1128
        }
1129
        *++yyssp = yystate = yytable[yyn];
1130
        *++yyvsp = yylval;
1131
        yychar = (-1);
1132
        if (yyerrflag > 0)  --yyerrflag;
1133
        goto yyloop;
1134
    }
1135
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1136
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1137
    {
1138
        yyn = yytable[yyn];
1139
        goto yyreduce;
1140
    }
1141
    if (yyerrflag) goto yyinrecovery;
1142
#if defined(__GNUC__)
1143
    goto yynewerror;
1144
#endif
1145
yynewerror:
1146
    yyerror("syntax error");
1147
#if defined(__GNUC__)
1148
    goto yyerrlab;
1149
#endif
1150
yyerrlab:
1151
    ++yynerrs;
1152
yyinrecovery:
1153
    if (yyerrflag < 3)
1154
    {
1155
        yyerrflag = 3;
1156
        for (;;)
1157
        {
1158
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1159
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1160
            {
1161
#if YYDEBUG
1162
                if (yydebug)
1163
                    printf("%sdebug: state %d, error recovery shifting\
1164
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1165
#endif
1166
                if (yyssp >= yysslim && yygrowstack())
1167
                {
1168
                    goto yyoverflow;
1169
                }
1170
                *++yyssp = yystate = yytable[yyn];
1171
                *++yyvsp = yylval;
1172
                goto yyloop;
1173
            }
1174
            else
1175
            {
1176
#if YYDEBUG
1177
                if (yydebug)
1178
                    printf("%sdebug: error recovery discarding state %d\n",
1179
                            YYPREFIX, *yyssp);
1180
#endif
1181
                if (yyssp <= yyss) goto yyabort;
1182
                --yyssp;
1183
                --yyvsp;
1184
            }
1185
        }
1186
    }
1187
    else
1188
    {
1189
        if (yychar == 0) goto yyabort;
1190
#if YYDEBUG
1191
        if (yydebug)
1192
        {
1193
            yys = 0;
1194
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1195
            if (!yys) yys = "illegal-symbol";
1196
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1197
                    YYPREFIX, yystate, yychar, yys);
1198
        }
1199
#endif
1200
        yychar = (-1);
1201
        goto yyloop;
1202
    }
1203
yyreduce:
1204
#if YYDEBUG
1205
    if (yydebug)
1206
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1207
                YYPREFIX, yystate, yyn, yyrule[yyn]);
1208
#endif
1209
    yym = yylen[yyn];
1210
    if (yym)
1211
        yyval = yyvsp[1-yym];
1212
    else
1213
        memset(&yyval, 0, sizeof yyval);
1214
    switch (yyn)
1215
    {
1216
case 7:
1217
#line 143 "parse.y"
1218
{ file->errors++; }
1219
break;
1220
case 8:
1221
#line 146 "parse.y"
1222
{
1223
			struct file	*nfile;
1224
1225
			if ((nfile = pushfile(yyvsp[0].v.string, 1)) == NULL) {
1226
				yyerror("failed to include file %s", yyvsp[0].v.string);
1227
				free(yyvsp[0].v.string);
1228
				YYERROR;
1229
			}
1230
			free(yyvsp[0].v.string);
1231
1232
			file = nfile;
1233
			lungetc('\n');
1234
		}
1235
break;
1236
case 9:
1237
#line 161 "parse.y"
1238
{
1239
			if (asprintf(&yyval.v.string, "%s %s", yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
1240
				free(yyvsp[-1].v.string);
1241
				free(yyvsp[0].v.string);
1242
				yyerror("string: asprintf");
1243
				YYERROR;
1244
			}
1245
			free(yyvsp[-1].v.string);
1246
			free(yyvsp[0].v.string);
1247
		}
1248
break;
1249
case 11:
1250
#line 174 "parse.y"
1251
{ yyval.v.number = 1; }
1252
break;
1253
case 12:
1254
#line 175 "parse.y"
1255
{ yyval.v.number = 0; }
1256
break;
1257
case 13:
1258
#line 178 "parse.y"
1259
{ yyval.v.number = 0; }
1260
break;
1261
case 14:
1262
#line 179 "parse.y"
1263
{ yyval.v.number = 1; }
1264
break;
1265
case 15:
1266
#line 181 "parse.y"
1267
{
1268
			char *s = yyvsp[-2].v.string;
1269
			if (conf->opts & OSPFD_OPT_VERBOSE)
1270
				printf("%s = \"%s\"\n", yyvsp[-2].v.string, yyvsp[0].v.string);
1271
			while (*s++) {
1272
				if (isspace((unsigned char)*s)) {
1273
					yyerror("macro name cannot contain "
1274
					    "whitespace");
1275
					YYERROR;
1276
				}
1277
			}
1278
			if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)
1279
				fatal("cannot store variable");
1280
			free(yyvsp[-2].v.string);
1281
			free(yyvsp[0].v.string);
1282
		}
1283
break;
1284
case 16:
1285
#line 199 "parse.y"
1286
{
1287
			if (!inet_aton(yyvsp[0].v.string, &conf->rtr_id)) {
1288
				yyerror("error parsing router-id");
1289
				free(yyvsp[0].v.string);
1290
				YYERROR;
1291
			}
1292
			free(yyvsp[0].v.string);
1293
		}
1294
break;
1295
case 17:
1296
#line 207 "parse.y"
1297
{
1298
			if (yyvsp[0].v.number == 0)
1299
				conf->flags |= OSPFD_FLAG_NO_FIB_UPDATE;
1300
			else
1301
				conf->flags &= ~OSPFD_FLAG_NO_FIB_UPDATE;
1302
		}
1303
break;
1304
case 18:
1305
#line 213 "parse.y"
1306
{
1307
			SIMPLEQ_INSERT_TAIL(&conf->redist_list, yyvsp[0].v.redist, entry);
1308
			conf->redistribute = 1;
1309
		}
1310
break;
1311
case 19:
1312
#line 217 "parse.y"
1313
{
1314
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > UINT_MAX) {
1315
				yyerror("invalid external route tag");
1316
				free(yyvsp[-2].v.string);
1317
				YYERROR;
1318
			}
1319
			rtlabel_tag(rtlabel_name2id(yyvsp[-2].v.string), yyvsp[0].v.number);
1320
			free(yyvsp[-2].v.string);
1321
		}
1322
break;
1323
case 20:
1324
#line 226 "parse.y"
1325
{
1326
			if (yyvsp[0].v.number < MIN_SPF_DELAY || yyvsp[0].v.number > MAX_SPF_DELAY) {
1327
				yyerror("spf-delay out of range "
1328
				    "(%d-%d)", MIN_SPF_DELAY,
1329
				    MAX_SPF_DELAY);
1330
				YYERROR;
1331
			}
1332
			conf->spf_delay = yyvsp[0].v.number;
1333
		}
1334
break;
1335
case 21:
1336
#line 235 "parse.y"
1337
{
1338
			if (yyvsp[0].v.number < MIN_SPF_HOLDTIME || yyvsp[0].v.number > MAX_SPF_HOLDTIME) {
1339
				yyerror("spf-holdtime out of range "
1340
				    "(%d-%d)", MIN_SPF_HOLDTIME,
1341
				    MAX_SPF_HOLDTIME);
1342
				YYERROR;
1343
			}
1344
			conf->spf_hold_time = yyvsp[0].v.number;
1345
		}
1346
break;
1347
case 22:
1348
#line 244 "parse.y"
1349
{
1350
			if (yyvsp[0].v.number)
1351
				conf->flags |= OSPFD_FLAG_STUB_ROUTER;
1352
			else
1353
				/* allow to force non stub mode */
1354
				conf->flags &= ~OSPFD_FLAG_STUB_ROUTER;
1355
		}
1356
break;
1357
case 24:
1358
#line 254 "parse.y"
1359
{
1360
			struct redistribute	*r;
1361
1362
			if ((r = calloc(1, sizeof(*r))) == NULL)
1363
				fatal(NULL);
1364
			if (!strcmp(yyvsp[-1].v.string, "default"))
1365
				r->type = REDIST_DEFAULT;
1366
			else if (!strcmp(yyvsp[-1].v.string, "static"))
1367
				r->type = REDIST_STATIC;
1368
			else if (!strcmp(yyvsp[-1].v.string, "connected"))
1369
				r->type = REDIST_CONNECTED;
1370
			else if (prefix(yyvsp[-1].v.string, &r->addr, &r->prefixlen))
1371
				r->type = REDIST_ADDR;
1372
			else {
1373
				yyerror("unknown redistribute type");
1374
				free(yyvsp[-1].v.string);
1375
				free(r);
1376
				YYERROR;
1377
			}
1378
1379
			if (yyvsp[-3].v.number)
1380
				r->type |= REDIST_NO;
1381
			r->metric = yyvsp[0].v.number;
1382
			free(yyvsp[-1].v.string);
1383
			yyval.v.redist = r;
1384
		}
1385
break;
1386
case 25:
1387
#line 280 "parse.y"
1388
{
1389
			struct redistribute	*r;
1390
1391
			if ((r = calloc(1, sizeof(*r))) == NULL)
1392
				fatal(NULL);
1393
			r->type = REDIST_LABEL;
1394
			r->label = rtlabel_name2id(yyvsp[-1].v.string);
1395
			if (yyvsp[-4].v.number)
1396
				r->type |= REDIST_NO;
1397
			r->metric = yyvsp[0].v.number;
1398
			free(yyvsp[-1].v.string);
1399
			yyval.v.redist = r;
1400
		}
1401
break;
1402
case 26:
1403
#line 295 "parse.y"
1404
{ yyval.v.number = DEFAULT_REDIST_METRIC; }
1405
break;
1406
case 27:
1407
#line 296 "parse.y"
1408
{
1409
			yyval.v.number = yyvsp[0].v.number;
1410
			if ((yyval.v.number & LSA_METRIC_MASK) == 0)
1411
				yyval.v.number |= DEFAULT_REDIST_METRIC;
1412
		}
1413
break;
1414
case 28:
1415
#line 301 "parse.y"
1416
{
1417
			yyval.v.number = yyvsp[-2].v.number;
1418
			if ((yyval.v.number & LSA_METRIC_MASK) == 0)
1419
				yyval.v.number |= DEFAULT_REDIST_METRIC;
1420
		}
1421
break;
1422
case 29:
1423
#line 308 "parse.y"
1424
{
1425
			if (yyvsp[-2].v.number & LSA_ASEXT_E_FLAG && yyvsp[0].v.number & LSA_ASEXT_E_FLAG) {
1426
				yyerror("redistribute type already defined");
1427
				YYERROR;
1428
			}
1429
			if (yyvsp[-2].v.number & LSA_METRIC_MASK && yyvsp[0].v.number & LSA_METRIC_MASK) {
1430
				yyerror("redistribute metric already defined");
1431
				YYERROR;
1432
			}
1433
			yyval.v.number = yyvsp[-2].v.number | yyvsp[0].v.number;
1434
		}
1435
break;
1436
case 30:
1437
#line 319 "parse.y"
1438
{ yyval.v.number = yyvsp[0].v.number; }
1439
break;
1440
case 31:
1441
#line 322 "parse.y"
1442
{
1443
			if (yyvsp[0].v.number == 0 || yyvsp[0].v.number > MAX_METRIC) {
1444
				yyerror("invalid redistribute metric");
1445
				YYERROR;
1446
			}
1447
			yyval.v.number = yyvsp[0].v.number;
1448
		}
1449
break;
1450
case 32:
1451
#line 329 "parse.y"
1452
{
1453
			switch (yyvsp[0].v.number) {
1454
			case 1:
1455
				yyval.v.number = 0;
1456
				break;
1457
			case 2:
1458
				yyval.v.number = LSA_ASEXT_E_FLAG;
1459
				break;
1460
			default:
1461
				yyerror("only external type 1 and 2 allowed");
1462
				YYERROR;
1463
			}
1464
		}
1465
break;
1466
case 33:
1467
#line 344 "parse.y"
1468
{
1469
			if (yyvsp[0].v.number < MIN_METRIC || yyvsp[0].v.number > MAX_METRIC) {
1470
				yyerror("metric out of range (%d-%d)",
1471
				    MIN_METRIC, MAX_METRIC);
1472
				YYERROR;
1473
			}
1474
			defs->metric = yyvsp[0].v.number;
1475
		}
1476
break;
1477
case 34:
1478
#line 352 "parse.y"
1479
{
1480
			if (yyvsp[0].v.number < MIN_PRIORITY || yyvsp[0].v.number > MAX_PRIORITY) {
1481
				yyerror("router-priority out of range (%d-%d)",
1482
				    MIN_PRIORITY, MAX_PRIORITY);
1483
				YYERROR;
1484
			}
1485
			defs->priority = yyvsp[0].v.number;
1486
		}
1487
break;
1488
case 35:
1489
#line 360 "parse.y"
1490
{
1491
			if (yyvsp[0].v.number < MIN_RTR_DEAD_TIME || yyvsp[0].v.number > MAX_RTR_DEAD_TIME) {
1492
				yyerror("router-dead-time out of range (%d-%d)",
1493
				    MIN_RTR_DEAD_TIME, MAX_RTR_DEAD_TIME);
1494
				YYERROR;
1495
			}
1496
			defs->dead_interval = yyvsp[0].v.number;
1497
		}
1498
break;
1499
case 36:
1500
#line 368 "parse.y"
1501
{
1502
			if (yyvsp[0].v.number < MIN_TRANSMIT_DELAY ||
1503
			    yyvsp[0].v.number > MAX_TRANSMIT_DELAY) {
1504
				yyerror("transmit-delay out of range (%d-%d)",
1505
				    MIN_TRANSMIT_DELAY, MAX_TRANSMIT_DELAY);
1506
				YYERROR;
1507
			}
1508
			defs->transmit_delay = yyvsp[0].v.number;
1509
		}
1510
break;
1511
case 37:
1512
#line 377 "parse.y"
1513
{
1514
			if (yyvsp[0].v.number < MIN_HELLO_INTERVAL ||
1515
			    yyvsp[0].v.number > MAX_HELLO_INTERVAL) {
1516
				yyerror("hello-interval out of range (%d-%d)",
1517
				    MIN_HELLO_INTERVAL, MAX_HELLO_INTERVAL);
1518
				YYERROR;
1519
			}
1520
			defs->hello_interval = yyvsp[0].v.number;
1521
		}
1522
break;
1523
case 38:
1524
#line 386 "parse.y"
1525
{
1526
			if (yyvsp[0].v.number < MIN_RXMT_INTERVAL || yyvsp[0].v.number > MAX_RXMT_INTERVAL) {
1527
				yyerror("retransmit-interval out of range "
1528
				    "(%d-%d)", MIN_RXMT_INTERVAL,
1529
				    MAX_RXMT_INTERVAL);
1530
				YYERROR;
1531
			}
1532
			defs->rxmt_interval = yyvsp[0].v.number;
1533
		}
1534
break;
1535
case 44:
1536
#line 408 "parse.y"
1537
{
1538
			struct in_addr	id;
1539
			if (inet_aton(yyvsp[0].v.string, &id) == 0) {
1540
				yyerror("error parsing area");
1541
				free(yyvsp[0].v.string);
1542
				YYERROR;
1543
			}
1544
			free(yyvsp[0].v.string);
1545
			area = conf_get_area(id);
1546
1547
			memcpy(&areadefs, defs, sizeof(areadefs));
1548
			defs = &areadefs;
1549
		}
1550
break;
1551
case 45:
1552
#line 420 "parse.y"
1553
{
1554
			area = NULL;
1555
			defs = &globaldefs;
1556
		}
1557
break;
1558
case 46:
1559
#line 426 "parse.y"
1560
{ yyval.v.number = yyvsp[0].v.number; }
1561
break;
1562
case 47:
1563
#line 427 "parse.y"
1564
{ yyval.v.number = 1; }
1565
break;
1566
case 51:
1567
#line 435 "parse.y"
1568
{
1569
			if (yyvsp[0].v.number < 1 || yyvsp[0].v.number > 255) {
1570
				yyerror("demote count out of range (1-255)");
1571
				free(yyvsp[-1].v.string);
1572
				YYERROR;
1573
			}
1574
			area->demote_level = yyvsp[0].v.number;
1575
			if (strlcpy(area->demote_group, yyvsp[-1].v.string,
1576
			    sizeof(area->demote_group)) >=
1577
			    sizeof(area->demote_group)) {
1578
				yyerror("demote group name \"%s\" too long",
1579
				    yyvsp[-1].v.string);
1580
				free(yyvsp[-1].v.string);
1581
				YYERROR;
1582
			}
1583
			free(yyvsp[-1].v.string);
1584
			if (carp_demote_init(area->demote_group,
1585
			    conf->opts & OSPFD_OPT_FORCE_DEMOTE) == -1) {
1586
				yyerror("error initializing group \"%s\"",
1587
				    area->demote_group);
1588
				YYERROR;
1589
			}
1590
		}
1591
break;
1592
case 53:
1593
#line 461 "parse.y"
1594
{
1595
			if ((iface = if_findname(yyvsp[0].v.string)) == NULL) {
1596
				yyerror("unknown interface %s", yyvsp[0].v.string);
1597
				free(yyvsp[0].v.string);
1598
				YYERROR;
1599
			}
1600
			if (IN6_IS_ADDR_UNSPECIFIED(&iface->addr)) {
1601
				yyerror("unnumbered interface %s", yyvsp[0].v.string);
1602
				free(yyvsp[0].v.string);
1603
				YYERROR;
1604
			}
1605
			free(yyvsp[0].v.string);
1606
			iface->area_id.s_addr = area->id.s_addr;
1607
			LIST_INSERT_HEAD(&area->iface_list, iface, entry);
1608
1609
			memcpy(&ifacedefs, defs, sizeof(ifacedefs));
1610
			defs = &ifacedefs;
1611
		}
1612
break;
1613
case 54:
1614
#line 478 "parse.y"
1615
{
1616
			iface->dead_interval = defs->dead_interval;
1617
			iface->transmit_delay = defs->transmit_delay;
1618
			iface->hello_interval = defs->hello_interval;
1619
			iface->rxmt_interval = defs->rxmt_interval;
1620
			iface->metric = defs->metric;
1621
			iface->priority = defs->priority;
1622
			iface->cflags |= F_IFACE_CONFIGURED;
1623
			iface = NULL;
1624
			/* interface is always part of an area */
1625
			defs = &areadefs;
1626
		}
1627
break;
1628
case 60:
1629
#line 501 "parse.y"
1630
{ iface->cflags |= F_IFACE_PASSIVE; }
1631
break;
1632
case 61:
1633
#line 502 "parse.y"
1634
{
1635
			if (strlcpy(iface->demote_group, yyvsp[0].v.string,
1636
			    sizeof(iface->demote_group)) >=
1637
			    sizeof(iface->demote_group)) {
1638
				yyerror("demote group name \"%s\" too long",
1639
				    yyvsp[0].v.string);
1640
				free(yyvsp[0].v.string);
1641
				YYERROR;
1642
			}
1643
			free(yyvsp[0].v.string);
1644
			if (carp_demote_init(iface->demote_group,
1645
			    conf->opts & OSPFD_OPT_FORCE_DEMOTE) == -1) {
1646
				yyerror("error initializing group \"%s\"",
1647
				    iface->demote_group);
1648
				YYERROR;
1649
			}
1650
		}
1651
break;
1652
#line 1645 "parse.c"
1653
    }
1654
    yyssp -= yym;
1655
    yystate = *yyssp;
1656
    yyvsp -= yym;
1657
    yym = yylhs[yyn];
1658
    if (yystate == 0 && yym == 0)
1659
    {
1660
#if YYDEBUG
1661
        if (yydebug)
1662
            printf("%sdebug: after reduction, shifting from state 0 to\
1663
 state %d\n", YYPREFIX, YYFINAL);
1664
#endif
1665
        yystate = YYFINAL;
1666
        *++yyssp = YYFINAL;
1667
        *++yyvsp = yyval;
1668
        if (yychar < 0)
1669
        {
1670
            if ((yychar = yylex()) < 0) yychar = 0;
1671
#if YYDEBUG
1672
            if (yydebug)
1673
            {
1674
                yys = 0;
1675
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1676
                if (!yys) yys = "illegal-symbol";
1677
                printf("%sdebug: state %d, reading %d (%s)\n",
1678
                        YYPREFIX, YYFINAL, yychar, yys);
1679
            }
1680
#endif
1681
        }
1682
        if (yychar == 0) goto yyaccept;
1683
        goto yyloop;
1684
    }
1685
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1686
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1687
        yystate = yytable[yyn];
1688
    else
1689
        yystate = yydgoto[yym];
1690
#if YYDEBUG
1691
    if (yydebug)
1692
        printf("%sdebug: after reduction, shifting from state %d \
1693
to state %d\n", YYPREFIX, *yyssp, yystate);
1694
#endif
1695
    if (yyssp >= yysslim && yygrowstack())
1696
    {
1697
        goto yyoverflow;
1698
    }
1699
    *++yyssp = yystate;
1700
    *++yyvsp = yyval;
1701
    goto yyloop;
1702
yyoverflow:
1703
    yyerror("yacc stack overflow");
1704
yyabort:
1705
    if (yyss)
1706
            free(yyss);
1707
    if (yyvs)
1708
            free(yyvs);
1709
    yyss = yyssp = NULL;
1710
    yyvs = yyvsp = NULL;
1711
    yystacksize = 0;
1712
    return (1);
1713
yyaccept:
1714
    if (yyss)
1715
            free(yyss);
1716
    if (yyvs)
1717
            free(yyvs);
1718
    yyss = yyssp = NULL;
1719
    yyvs = yyvsp = NULL;
1720
    yystacksize = 0;
1721
    return (0);
1722
}