| 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 |  |  | } |