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