Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name parse.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/rad/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/rad -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/rad/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c parse.c
1#include <stdlib.h>
2#include <string.h>
3#define YYBYACC1 1
4#define YYMAJOR1 1
5#define YYMINOR9 9
6#define YYLEXyylex() yylex()
7#define YYEMPTY-1 -1
8#define yyclearin(yychar=(-1)) (yychar=(YYEMPTY-1))
9#define yyerrok(yyerrflag=0) (yyerrflag=0)
10#define YYRECOVERING()(yyerrflag!=0) (yyerrflag!=0)
11#define YYPREFIX"yy" "yy"
12#line 26 "/usr/src/usr.sbin/rad/parse.y"
13#include <sys/types.h>
14#include <sys/queue.h>
15#include <sys/socket.h>
16#include <sys/stat.h>
17
18#include <netinet/in.h>
19#include <net/if.h>
20
21#include <arpa/inet.h>
22
23#include <ctype.h>
24#include <err.h>
25#include <errno(*__errno()).h>
26#include <event.h>
27#include <imsg.h>
28#include <limits.h>
29#include <stdarg.h>
30#include <stdio.h>
31#include <string.h>
32#include <syslog.h>
33#include <unistd.h>
34
35#include "log.h"
36#include "rad.h"
37#include "frontend.h"
38
39TAILQ_HEAD(files, file)struct files { struct file *tqh_first; struct file **tqh_last
; }
files = TAILQ_HEAD_INITIALIZER(files){ ((void *)0), &(files).tqh_first };
40static struct file {
41 TAILQ_ENTRY(file)struct { struct file *tqe_next; struct file **tqe_prev; } entry;
42 FILE *stream;
43 char *name;
44 size_t ungetpos;
45 size_t ungetsize;
46 u_char *ungetbuf;
47 int eof_reached;
48 int lineno;
49 int errors;
50} *file, *topfile;
51struct file *pushfile(const char *, int);
52int popfile(void);
53int check_file_secrecy(int, const char *);
54int yyparse(void);
55int yylex(void);
56int yyerror(const char *, ...)
57 __attribute__((__format__ (printf, 1, 2)))
58 __attribute__((__nonnull__ (1)));
59int kw_cmp(const void *, const void *);
60int lookup(char *);
61int igetc(void);
62int lgetc(int);
63void lungetc(int);
64int findeol(void);
65
66TAILQ_HEAD(symhead, sym)struct symhead { struct sym *tqh_first; struct sym **tqh_last
; }
symhead = TAILQ_HEAD_INITIALIZER(symhead){ ((void *)0), &(symhead).tqh_first };
67struct sym {
68 TAILQ_ENTRY(sym)struct { struct sym *tqe_next; struct sym **tqe_prev; } entry;
69 int used;
70 int persist;
71 char *nam;
72 char *val;
73};
74
75int symset(const char *, const char *, int);
76char *symget(const char *);
77
78void clear_config(struct rad_conf *xconf);
79
80static struct rad_conf *conf;
81static struct ra_options_conf *ra_options;
82static int errors;
83
84static struct ra_iface_conf *ra_iface_conf;
85static struct ra_prefix_conf *ra_prefix_conf;
86
87struct ra_prefix_conf *conf_get_ra_prefix(struct in6_addr*, int);
88struct ra_iface_conf *conf_get_ra_iface(char *);
89void copy_dns_options(const struct ra_options_conf *,
90 struct ra_options_conf *);
91
92typedef struct {
93 union {
94 int64_t number;
95 char *string;
96 } v;
97 int lineno;
98} YYSTYPE;
99
100#line 101 "parse.c"
101#define RA_IFACE257 257
102#define YES258 258
103#define NO259 259
104#define INCLUDE260 260
105#define ERROR261 261
106#define DEFAULT262 262
107#define ROUTER263 263
108#define HOP264 264
109#define LIMIT265 265
110#define MANAGED266 266
111#define ADDRESS267 267
112#define CONFIGURATION268 268
113#define OTHER269 269
114#define LIFETIME270 270
115#define REACHABLE271 271
116#define TIME272 272
117#define RETRANS273 273
118#define TIMER274 274
119#define AUTO275 275
120#define PREFIX276 276
121#define VALID277 277
122#define PREFERRED278 278
123#define ONLINK279 279
124#define AUTONOMOUS280 280
125#define ADDRESS_CONFIGURATION281 281
126#define DNS282 282
127#define NAMESERVER283 283
128#define SEARCH284 284
129#define MTU285 285
130#define STRING286 286
131#define NUMBER287 287
132#define YYERRCODE256 256
133const short yylhs[] =
134 { -1,
135 0, 0, 0, 5, 0, 0, 0, 0, 3, 2,
136 2, 1, 1, 6, 4, 8, 8, 8, 8, 8,
137 8, 8, 8, 8, 10, 10, 11, 13, 7, 12,
138 12, 12, 14, 14, 15, 17, 15, 18, 15, 15,
139 16, 16, 16, 19, 19, 20, 20, 20, 20, 9,
140 9, 9, 21, 21, 22, 22, 22, 23, 23, 23,
141 23, 25, 25, 26, 24, 24, 24, 24, 27, 27,
142 28,
143};
144const short yylen[] =
145 { 2,
146 0, 3, 2, 0, 4, 3, 3, 3, 2, 2,
147 1, 1, 1, 3, 1, 3, 3, 4, 3, 3,
148 3, 3, 2, 2, 2, 0, 2, 0, 4, 4,
149 3, 0, 3, 2, 3, 0, 4, 0, 4, 1,
150 4, 3, 0, 3, 2, 3, 3, 2, 3, 4,
151 3, 0, 3, 2, 2, 2, 2, 4, 3, 1,
152 0, 3, 2, 1, 4, 3, 1, 0, 3, 2,
153 1,
154};
155const short yydefred[] =
156 { 1,
157 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
158 8, 28, 9, 0, 2, 0, 0, 0, 0, 0,
159 0, 0, 0, 0, 0, 15, 6, 7, 0, 11,
160 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,
161 23, 5, 0, 29, 10, 12, 13, 16, 20, 17,
162 0, 19, 21, 22, 0, 0, 0, 18, 25, 0,
163 0, 0, 51, 0, 0, 0, 0, 0, 31, 40,
164 0, 0, 55, 64, 0, 56, 60, 71, 0, 57,
165 67, 50, 0, 54, 0, 36, 38, 30, 0, 34,
166 0, 0, 0, 53, 35, 0, 0, 33, 59, 0,
167 0, 66, 0, 0, 27, 0, 37, 39, 58, 0,
168 63, 65, 0, 70, 0, 62, 69, 0, 0, 0,
169 0, 42, 0, 0, 0, 0, 48, 0, 41, 0,
170 45, 46, 47, 49, 44,
171};
172const short yydgoto[] =
173 { 1,
174 48, 31, 7, 25, 8, 9, 10, 70, 40, 56,
175 94, 44, 29, 71, 72, 107, 96, 97, 123, 124,
176 64, 65, 76, 80, 100, 77, 103, 81,
177};
178const short yysindex[] =
179 { 0,
180 -10, -2, -276, -275, -47, 0, 6, -235, 22, 23,
181 0, 0, 0, -249, 0, -223, -229, -222, -216, -224,
182 -220, -221, -69, -232, 46, 0, 0, 0, -65, 0,
183 -226, -252, -230, -225, -207, -252, -219, -218, 54, 0,
184 0, 0, 54, 0, 0, 0, 0, 0, 0, 0,
185 -252, 0, 0, 0, 54, -66, -50, 0, 0, -215,
186 -122, -120, 0, -55, 54, -210, -209, -213, 0, 0,
187 59, 54, 0, 0, 54, 0, 0, 0, 54, 0,
188 0, 0, 56, 0, -199, 0, 0, 0, 56, 0,
189 -113, -107, 54, 0, 0, -45, -45, 0, 0, -106,
190 54, 0, -105, 54, 0, 54, 0, 0, 0, 54,
191 0, 0, 54, 0, -38, 0, 0, -189, -188, -252,
192 -197, 0, -7, 54, -202, -201, 0, -252, 0, 56,
193 0, 0, 0, 0, 0,};
194const short yyrindex[] =
195 { 0,
196 -174, 0, 0, 0, 0, 0, 0, 0, 0, 0,
197 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
198 0, 0, -8, 0, 0, 0, 0, 0, 81, 0,
199 88, 0, 0, 0, 0, 0, 0, 0, -46, 0,
200 0, 0, 86, 0, 0, 0, 0, 0, 0, 0,
201 0, 0, 0, 0, -108, 0, 0, 0, 0, 0,
202 11, 13, 0, 0, -46, 0, 0, 0, 0, 0,
203 0, 86, 0, 0, -103, 0, 0, 0, -103, 0,
204 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
205 0, 0, -77, 0, 0, 16, 16, 0, 0, 0,
206 -103, 0, 0, -103, 0, 25, 0, 0, 0, -103,
207 0, 0, -103, 0, 0, 0, 0, 0, 0, 0,
208 0, 0, 0, 25, 0, 0, 0, 0, 0, 0,
209 0, 0, 0, 0, 0,};
210const short yygindex[] =
211 { 0,
212 -27, 0, 0, 0, 0, 0, 0, 92, 0, -30,
213 -84, 0, 0, 0, 31, -1, 0, 0, 0, -20,
214 0, 40, 0, 0, 0, -61, 0, -88,
215};
216#define YYTABLESIZE371 371
217const short yytable[] =
218 { 6,
219 75, 52, 79, 104, 98, 46, 47, 11, 52, 12,
220 13, 99, 57, 14, 113, 15, 26, 102, 109, 112,
221 61, 26, 68, 58, 59, 43, 16, 17, 18, 101,
222 19, 27, 28, 20, 84, 21, 30, 22, 110, 32,
223 33, 90, 34, 36, 91, 135, 23, 26, 92, 24,
224 35, 37, 38, 39, 41, 42, 49, 43, 63, 45,
225 51, 50, 105, 55, 85, 93, 86, 53, 54, 82,
226 111, 73, 87, 114, 69, 115, 95, 106, 26, 116,
227 125, 126, 117, 128, 132, 133, 122, 4, 4, 4,
228 32, 4, 127, 131, 4, 108, 4, 14, 4, 26,
229 134, 89, 130, 83, 0, 0, 0, 4, 0, 0,
230 4, 0, 0, 0, 0, 0, 52, 129, 0, 0,
231 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
232 0, 0, 0, 0, 0, 61, 0, 68, 0, 0,
233 43, 0, 0, 0, 0, 0, 0, 0, 0, 26,
234 26, 0, 0, 26, 26, 26, 0, 26, 0, 0,
235 26, 26, 26, 74, 26, 78, 26, 26, 26, 26,
236 26, 26, 74, 26, 26, 26, 26, 26, 78, 74,
237 78, 26, 26, 88, 26, 26, 26, 0, 26, 0,
238 0, 26, 26, 26, 0, 26, 0, 26, 26, 26,
239 26, 26, 26, 60, 26, 26, 26, 26, 66, 0,
240 26, 16, 17, 18, 60, 19, 61, 62, 20, 0,
241 21, 0, 22, 26, 67, 68, 0, 61, 62, 0,
242 0, 23, 0, 0, 24, 0, 26, 26, 118, 119,
243 120, 121, 0, 0, 0, 2, 3, 0, 0, 4,
244 52, 0, 0, 52, 52, 52, 0, 52, 0, 0,
245 52, 0, 52, 0, 52, 0, 52, 52, 0, 118,
246 119, 120, 121, 52, 43, 5, 52, 43, 43, 43,
247 61, 43, 68, 0, 43, 0, 43, 0, 43, 0,
248 43, 43, 0, 61, 61, 68, 68, 43, 0, 0,
249 43, 26, 26, 26, 26, 0, 0, 0, 0, 0,
250 0, 0, 0, 0, 0, 0, 0, 66, 0, 0,
251 16, 17, 18, 0, 19, 0, 0, 20, 0, 21,
252 0, 22, 0, 67, 68, 0, 0, 0, 0, 0,
253 23, 0, 0, 24, 26, 0, 0, 26, 26, 26,
254 0, 26, 0, 0, 26, 0, 26, 0, 26, 0,
255 26, 26, 0, 0, 0, 0, 0, 26, 0, 0,
256 26,
257};
258const short yycheck[] =
259 { 10,
260 123, 10, 123, 92, 89, 258, 259, 10, 36, 286,
261 286, 125, 43, 61, 103, 10, 125, 125, 125, 125,
262 10, 125, 10, 51, 55, 10, 262, 263, 264, 91,
263 266, 10, 10, 269, 65, 271, 286, 273, 100, 263,
264 270, 72, 265, 268, 75, 130, 282, 125, 79, 285,
265 267, 272, 274, 123, 287, 10, 287, 123, 125, 286,
266 268, 287, 93, 10, 275, 10, 276, 287, 287, 125,
267 101, 287, 286, 104, 125, 106, 276, 123, 125, 110,
268 270, 270, 113, 281, 287, 287, 125, 262, 263, 264,
269 10, 266, 120, 124, 269, 97, 271, 10, 273, 8,
270 128, 71, 123, 64, -1, -1, -1, 282, -1, -1,
271 285, -1, -1, -1, -1, -1, 125, 125, -1, -1,
272 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
273 -1, -1, -1, -1, -1, 125, -1, 125, -1, -1,
274 125, -1, -1, -1, -1, -1, -1, -1, -1, 125,
275 259, -1, -1, 262, 263, 264, -1, 266, -1, -1,
276 269, 270, 271, 286, 273, 286, 275, 276, 277, 278,
277 279, 280, 286, 282, 283, 284, 285, 286, 286, 286,
278 286, 259, 286, 125, 262, 263, 264, -1, 266, -1,
279 -1, 269, 270, 271, -1, 273, -1, 275, 276, 277,
280 278, 279, 280, 270, 282, 283, 284, 285, 259, -1,
281 125, 262, 263, 264, 270, 266, 283, 284, 269, -1,
282 271, -1, 273, 270, 275, 276, -1, 283, 284, -1,
283 -1, 282, -1, -1, 285, -1, 283, 284, 277, 278,
284 279, 280, -1, -1, -1, 256, 257, -1, -1, 260,
285 259, -1, -1, 262, 263, 264, -1, 266, -1, -1,
286 269, -1, 271, -1, 273, -1, 275, 276, -1, 277,
287 278, 279, 280, 282, 259, 286, 285, 262, 263, 264,
288 270, 266, 270, -1, 269, -1, 271, -1, 273, -1,
289 275, 276, -1, 283, 284, 283, 284, 282, -1, -1,
290 285, 277, 278, 279, 280, -1, -1, -1, -1, -1,
291 -1, -1, -1, -1, -1, -1, -1, 259, -1, -1,
292 262, 263, 264, -1, 266, -1, -1, 269, -1, 271,
293 -1, 273, -1, 275, 276, -1, -1, -1, -1, -1,
294 282, -1, -1, 285, 259, -1, -1, 262, 263, 264,
295 -1, 266, -1, -1, 269, -1, 271, -1, 273, -1,
296 275, 276, -1, -1, -1, -1, -1, 282, -1, -1,
297 285,
298};
299#define YYFINAL1 1
300#ifndef YYDEBUG0
301#define YYDEBUG0 0
302#endif
303#define YYMAXTOKEN287 287
304#if YYDEBUG0
305const char * const yyname[] =
306 {
307"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,
3080,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'='",0,0,0,0,0,0,0,
3090,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3100,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3130,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"RA_IFACE",
314"YES","NO","INCLUDE","ERROR","DEFAULT","ROUTER","HOP","LIMIT","MANAGED",
315"ADDRESS","CONFIGURATION","OTHER","LIFETIME","REACHABLE","TIME","RETRANS",
316"TIMER","AUTO","PREFIX","VALID","PREFERRED","ONLINK","AUTONOMOUS",
317"ADDRESS_CONFIGURATION","DNS","NAMESERVER","SEARCH","MTU","STRING","NUMBER",
318};
319const char * const yyrule[] =
320 {"$accept : grammar",
321"grammar :",
322"grammar : grammar include '\\n'",
323"grammar : grammar '\\n'",
324"$$1 :",
325"grammar : grammar $$1 conf_main '\\n'",
326"grammar : grammar varset '\\n'",
327"grammar : grammar ra_iface '\\n'",
328"grammar : grammar error '\\n'",
329"include : INCLUDE STRING",
330"string : string STRING",
331"string : STRING",
332"yesno : YES",
333"yesno : NO",
334"varset : STRING '=' string",
335"conf_main : ra_opt_block",
336"ra_opt_block : DEFAULT ROUTER yesno",
337"ra_opt_block : HOP LIMIT NUMBER",
338"ra_opt_block : MANAGED ADDRESS CONFIGURATION yesno",
339"ra_opt_block : OTHER CONFIGURATION yesno",
340"ra_opt_block : ROUTER LIFETIME NUMBER",
341"ra_opt_block : REACHABLE TIME NUMBER",
342"ra_opt_block : RETRANS TIMER NUMBER",
343"ra_opt_block : MTU NUMBER",
344"ra_opt_block : DNS dns_block",
345"optnl : '\\n' optnl",
346"optnl :",
347"nl : '\\n' optnl",
348"$$2 :",
349"ra_iface : RA_IFACE STRING $$2 ra_iface_block",
350"ra_iface_block : '{' optnl ra_ifaceopts_l '}'",
351"ra_iface_block : '{' optnl '}'",
352"ra_iface_block :",
353"ra_ifaceopts_l : ra_ifaceopts_l ra_ifaceoptsl nl",
354"ra_ifaceopts_l : ra_ifaceoptsl optnl",
355"ra_ifaceoptsl : NO AUTO PREFIX",
356"$$3 :",
357"ra_ifaceoptsl : AUTO PREFIX $$3 ra_prefix_block",
358"$$4 :",
359"ra_ifaceoptsl : PREFIX STRING $$4 ra_prefix_block",
360"ra_ifaceoptsl : ra_opt_block",
361"ra_prefix_block : '{' optnl ra_prefixopts_l '}'",
362"ra_prefix_block : '{' optnl '}'",
363"ra_prefix_block :",
364"ra_prefixopts_l : ra_prefixopts_l ra_prefixoptsl nl",
365"ra_prefixopts_l : ra_prefixoptsl optnl",
366"ra_prefixoptsl : VALID LIFETIME NUMBER",
367"ra_prefixoptsl : PREFERRED LIFETIME NUMBER",
368"ra_prefixoptsl : ONLINK yesno",
369"ra_prefixoptsl : AUTONOMOUS ADDRESS_CONFIGURATION yesno",
370"dns_block : '{' optnl dnsopts_l '}'",
371"dns_block : '{' optnl '}'",
372"dns_block :",
373"dnsopts_l : dnsopts_l dnsoptsl nl",
374"dnsopts_l : dnsoptsl optnl",
375"dnsoptsl : LIFETIME NUMBER",
376"dnsoptsl : NAMESERVER nserver_block",
377"dnsoptsl : SEARCH search_block",
378"nserver_block : '{' optnl nserveropts_l '}'",
379"nserver_block : '{' optnl '}'",
380"nserver_block : nserveroptsl",
381"nserver_block :",
382"nserveropts_l : nserveropts_l nserveroptsl optnl",
383"nserveropts_l : nserveroptsl optnl",
384"nserveroptsl : STRING",
385"search_block : '{' optnl searchopts_l '}'",
386"search_block : '{' optnl '}'",
387"search_block : searchoptsl",
388"search_block :",
389"searchopts_l : searchopts_l searchoptsl optnl",
390"searchopts_l : searchoptsl optnl",
391"searchoptsl : STRING",
392};
393#endif
394#ifdef YYSTACKSIZE10000
395#undef YYMAXDEPTH10000
396#define YYMAXDEPTH10000 YYSTACKSIZE10000
397#else
398#ifdef YYMAXDEPTH10000
399#define YYSTACKSIZE10000 YYMAXDEPTH10000
400#else
401#define YYSTACKSIZE10000 10000
402#define YYMAXDEPTH10000 10000
403#endif
404#endif
405#define YYINITSTACKSIZE200 200
406/* LINTUSED */
407int yydebug;
408int yynerrs;
409int yyerrflag;
410int yychar;
411short *yyssp;
412YYSTYPE *yyvsp;
413YYSTYPE yyval;
414YYSTYPE yylval;
415short *yyss;
416short *yysslim;
417YYSTYPE *yyvs;
418unsigned int yystacksize;
419int yyparse(void);
420#line 401 "/usr/src/usr.sbin/rad/parse.y"
421
422struct keywords {
423 const char *k_name;
424 int k_val;
425};
426
427int
428yyerror(const char *fmt, ...)
429{
430 va_list ap;
431 char *msg;
432
433 file->errors++;
434 va_start(ap, fmt)__builtin_va_start(ap, fmt);
435 if (vasprintf(&msg, fmt, ap) == -1)
436 fatalx("yyerror vasprintf");
437 va_end(ap)__builtin_va_end(ap);
438 logit(LOG_CRIT2, "%s:%d: %s", file->name, yylval.lineno, msg);
439 free(msg);
440 return (0);
441}
442
443int
444kw_cmp(const void *k, const void *e)
445{
446 return (strcmp(k, ((const struct keywords *)e)->k_name));
447}
448
449int
450lookup(char *s)
451{
452 /* This has to be sorted always. */
453 static const struct keywords keywords[] = {
454 {"address", ADDRESS267},
455 {"address-configuration", ADDRESS_CONFIGURATION281},
456 {"auto", AUTO275},
457 {"autonomous", AUTONOMOUS280},
458 {"configuration", CONFIGURATION268},
459 {"default", DEFAULT262},
460 {"dns", DNS282},
461 {"hop", HOP264},
462 {"include", INCLUDE260},
463 {"interface", RA_IFACE257},
464 {"lifetime", LIFETIME270},
465 {"limit", LIMIT265},
466 {"managed", MANAGED266},
467 {"mtu", MTU285},
468 {"nameserver", NAMESERVER283},
469 {"no", NO259},
470 {"on-link", ONLINK279},
471 {"other", OTHER269},
472 {"preferred", PREFERRED278},
473 {"prefix", PREFIX276},
474 {"reachable", REACHABLE271},
475 {"retrans", RETRANS273},
476 {"router", ROUTER263},
477 {"search", SEARCH284},
478 {"time", TIME272},
479 {"timer", TIMER274},
480 {"valid", VALID277},
481 {"yes", YES258},
482 };
483 const struct keywords *p;
484
485 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
486 sizeof(keywords[0]), kw_cmp);
487
488 if (p)
489 return (p->k_val);
490 else
491 return (STRING286);
492}
493
494#define START_EXPAND1 1
495#define DONE_EXPAND2 2
496
497static int expanding;
498
499int
500igetc(void)
501{
502 int c;
503
504 while (1) {
505 if (file->ungetpos > 0)
506 c = file->ungetbuf[--file->ungetpos];
507 else
508 c = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget
(file->stream) : (int)(*(file->stream)->_p++)) : (getc
)(file->stream))
;
509
510 if (c == START_EXPAND1)
511 expanding = 1;
512 else if (c == DONE_EXPAND2)
513 expanding = 0;
514 else
515 break;
516 }
517 return (c);
518}
519
520int
521lgetc(int quotec)
522{
523 int c, next;
524
525 if (quotec) {
526 if ((c = igetc()) == EOF(-1)) {
527 yyerror("reached end of file while parsing "
528 "quoted string");
529 if (file == topfile || popfile() == EOF(-1))
530 return (EOF(-1));
531 return (quotec);
532 }
533 return (c);
534 }
535
536 while ((c = igetc()) == '\\') {
537 next = igetc();
538 if (next != '\n') {
539 c = next;
540 break;
541 }
542 yylval.lineno = file->lineno;
543 file->lineno++;
544 }
545
546 if (c == EOF(-1)) {
547 /*
548 * Fake EOL when hit EOF for the first time. This gets line
549 * count right if last line in included file is syntactically
550 * invalid and has no newline.
551 */
552 if (file->eof_reached == 0) {
553 file->eof_reached = 1;
554 return ('\n');
555 }
556 while (c == EOF(-1)) {
557 if (file == topfile || popfile() == EOF(-1))
558 return (EOF(-1));
559 c = igetc();
560 }
561 }
562 return (c);
563}
564
565void
566lungetc(int c)
567{
568 if (c == EOF(-1))
569 return;
570
571 if (file->ungetpos >= file->ungetsize) {
572 void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
573 if (p == NULL((void *)0))
574 err(1, "lungetc");
575 file->ungetbuf = p;
576 file->ungetsize *= 2;
577 }
578 file->ungetbuf[file->ungetpos++] = c;
579}
580
581int
582findeol(void)
583{
584 int c;
585
586 /* Skip to either EOF or the first real EOL. */
587 while (1) {
588 c = lgetc(0);
589 if (c == '\n') {
590 file->lineno++;
591 break;
592 }
593 if (c == EOF(-1))
594 break;
595 }
596 return (ERROR261);
597}
598
599int
600yylex(void)
601{
602 char buf[8096];
603 char *p, *val;
604 int quotec, next, c;
605 int token;
606
607top:
608 p = buf;
609 while ((c = lgetc(0)) == ' ' || c == '\t')
610 ; /* nothing */
611
612 yylval.lineno = file->lineno;
613 if (c == '#')
614 while ((c = lgetc(0)) != '\n' && c != EOF(-1))
615 ; /* nothing */
616 if (c == '$' && !expanding) {
617 while (1) {
618 if ((c = lgetc(0)) == EOF(-1))
619 return (0);
620
621 if (p + 1 >= buf + sizeof(buf) - 1) {
622 yyerror("string too long");
623 return (findeol());
624 }
625 if (isalnum(c) || c == '_') {
626 *p++ = c;
627 continue;
628 }
629 *p = '\0';
630 lungetc(c);
631 break;
632 }
633 val = symget(buf);
634 if (val == NULL((void *)0)) {
635 yyerror("macro '%s' not defined", buf);
636 return (findeol());
637 }
638 p = val + strlen(val) - 1;
639 lungetc(DONE_EXPAND2);
640 while (p >= val) {
641 lungetc((unsigned char)*p);
642 p--;
643 }
644 lungetc(START_EXPAND1);
645 goto top;
646 }
647
648 switch (c) {
649 case '\'':
650 case '"':
651 quotec = c;
652 while (1) {
653 if ((c = lgetc(quotec)) == EOF(-1))
654 return (0);
655 if (c == '\n') {
656 file->lineno++;
657 continue;
658 } else if (c == '\\') {
659 if ((next = lgetc(quotec)) == EOF(-1))
660 return (0);
661 if (next == quotec || next == ' ' ||
662 next == '\t')
663 c = next;
664 else if (next == '\n') {
665 file->lineno++;
666 continue;
667 } else
668 lungetc(next);
669 } else if (c == quotec) {
670 *p = '\0';
671 break;
672 } else if (c == '\0') {
673 yyerror("syntax error");
674 return (findeol());
675 }
676 if (p + 1 >= buf + sizeof(buf) - 1) {
677 yyerror("string too long");
678 return (findeol());
679 }
680 *p++ = c;
681 }
682 yylval.v.string = strdup(buf);
683 if (yylval.v.string == NULL((void *)0))
684 err(1, "yylex: strdup");
685 return (STRING286);
686 }
687
688#define allowed_to_end_number(x)(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' ||
x == '=')
\
689 (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
690
691 if (c == '-' || isdigit(c)) {
692 do {
693 *p++ = c;
694 if ((size_t)(p-buf) >= sizeof(buf)) {
695 yyerror("string too long");
696 return (findeol());
697 }
698 } while ((c = lgetc(0)) != EOF(-1) && isdigit(c));
699 lungetc(c);
700 if (p == buf + 1 && buf[0] == '-')
701 goto nodigits;
702 if (c == EOF(-1) || allowed_to_end_number(c)(isspace(c) || c == ')' || c ==',' || c == '/' || c == '}' ||
c == '=')
) {
703 const char *errstr = NULL((void *)0);
704
705 *p = '\0';
706 yylval.v.number = strtonum(buf, LLONG_MIN(-9223372036854775807LL -1LL),
707 LLONG_MAX9223372036854775807LL, &errstr);
708 if (errstr) {
709 yyerror("\"%s\" invalid number: %s",
710 buf, errstr);
711 return (findeol());
712 }
713 return (NUMBER287);
714 } else {
715nodigits:
716 while (p > buf + 1)
717 lungetc((unsigned char)*--p);
718 c = (unsigned char)*--p;
719 if (c == '-')
720 return (c);
721 }
722 }
723
724#define allowed_in_string(x)(isalnum(x) || (ispunct(x) && x != '(' && x !=
')' && x != '{' && x != '}' && x != '!'
&& x != '=' && x != '#' && x != ',')
)
\
725 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
726 x != '{' && x != '}' && \
727 x != '!' && x != '=' && x != '#' && \
728 x != ','))
729
730 if (isalnum(c) || c == ':' || c == '_') {
731 do {
732 *p++ = c;
733 if ((size_t)(p-buf) >= sizeof(buf)) {
734 yyerror("string too long");
735 return (findeol());
736 }
737 } while ((c = lgetc(0)) != EOF(-1) && (allowed_in_string(c)(isalnum(c) || (ispunct(c) && c != '(' && c !=
')' && c != '{' && c != '}' && c != '!'
&& c != '=' && c != '#' && c != ',')
)
));
738 lungetc(c);
739 *p = '\0';
740 if ((token = lookup(buf)) == STRING286)
741 if ((yylval.v.string = strdup(buf)) == NULL((void *)0))
742 err(1, "yylex: strdup");
743 return (token);
744 }
745 if (c == '\n') {
746 yylval.lineno = file->lineno;
747 file->lineno++;
748 }
749 if (c == EOF(-1))
750 return (0);
751 return (c);
752}
753
754int
755check_file_secrecy(int fd, const char *fname)
756{
757 struct stat st;
758
759 if (fstat(fd, &st)) {
760 log_warn("cannot stat %s", fname);
761 return (-1);
762 }
763 if (st.st_uid != 0 && st.st_uid != getuid()) {
764 log_warnx("%s: owner not root or current user", fname);
765 return (-1);
766 }
767 if (st.st_mode & (S_IWGRP0000020 | S_IXGRP0000010 | S_IRWXO0000007)) {
768 log_warnx("%s: group writable or world read/writable", fname);
769 return (-1);
770 }
771 return (0);
772}
773
774struct file *
775pushfile(const char *name, int secret)
776{
777 struct file *nfile;
778
779 if ((nfile = calloc(1, sizeof(struct file))) == NULL((void *)0)) {
780 log_warn("calloc");
781 return (NULL((void *)0));
782 }
783 if ((nfile->name = strdup(name)) == NULL((void *)0)) {
784 log_warn("strdup");
785 free(nfile);
786 return (NULL((void *)0));
787 }
788 if ((nfile->stream = fopen(nfile->name, "r")) == NULL((void *)0)) {
789 log_warn("%s", nfile->name);
790 free(nfile->name);
791 free(nfile);
792 return (NULL((void *)0));
793 } else if (secret &&
794 check_file_secrecy(fileno(nfile->stream)(!__isthreaded ? ((nfile->stream)->_file) : (fileno)(nfile
->stream))
, nfile->name)) {
795 fclose(nfile->stream);
796 free(nfile->name);
797 free(nfile);
798 return (NULL((void *)0));
799 }
800 nfile->lineno = TAILQ_EMPTY(&files)(((&files)->tqh_first) == ((void *)0)) ? 1 : 0;
801 nfile->ungetsize = 16;
802 nfile->ungetbuf = malloc(nfile->ungetsize);
803 if (nfile->ungetbuf == NULL((void *)0)) {
804 log_warn("malloc");
805 fclose(nfile->stream);
806 free(nfile->name);
807 free(nfile);
808 return (NULL((void *)0));
809 }
810 TAILQ_INSERT_TAIL(&files, nfile, entry)do { (nfile)->entry.tqe_next = ((void *)0); (nfile)->entry
.tqe_prev = (&files)->tqh_last; *(&files)->tqh_last
= (nfile); (&files)->tqh_last = &(nfile)->entry
.tqe_next; } while (0)
;
811 return (nfile);
812}
813
814int
815popfile(void)
816{
817 struct file *prev;
818
819 if ((prev = TAILQ_PREV(file, files, entry)(*(((struct files *)((file)->entry.tqe_prev))->tqh_last
))
) != NULL((void *)0))
820 prev->errors += file->errors;
821
822 TAILQ_REMOVE(&files, file, entry)do { if (((file)->entry.tqe_next) != ((void *)0)) (file)->
entry.tqe_next->entry.tqe_prev = (file)->entry.tqe_prev
; else (&files)->tqh_last = (file)->entry.tqe_prev;
*(file)->entry.tqe_prev = (file)->entry.tqe_next; ; ; }
while (0)
;
823 fclose(file->stream);
824 free(file->name);
825 free(file->ungetbuf);
826 free(file);
827 file = prev;
828 return (file ? 0 : EOF(-1));
829}
830
831struct rad_conf *
832parse_config(char *filename)
833{
834 struct sym *sym, *next;
835 struct ra_iface_conf *iface;
836
837 conf = config_new_empty();
838 ra_options = NULL((void *)0);
839
840 file = pushfile(filename, 0);
841 if (file == NULL((void *)0)) {
842 free(conf);
843 return (NULL((void *)0));
844 }
845 topfile = file;
846
847 yyparse();
848 errors = file->errors;
849 popfile();
850
851 /* Free macros and check which have not been used. */
852 TAILQ_FOREACH_SAFE(sym, &symhead, entry, next)for ((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0) && ((next) = ((sym)->entry.tqe_next), 1); (sym
) = (next))
{
853 if ((cmd_opts & OPT_VERBOSE20x00000002) && !sym->used)
854 fprintf(stderr(&__sF[2]), "warning: macro '%s' not used\n",
855 sym->nam);
856 if (!sym->persist) {
857 free(sym->nam);
858 free(sym->val);
859 TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void *)0)) (sym)->
entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev;
else (&symhead)->tqh_last = (sym)->entry.tqe_prev;
*(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while
(0)
;
860 free(sym);
861 }
862 }
863
864 if (errors) {
865 clear_config(conf);
866 return (NULL((void *)0));
867 }
868
869 if (!SIMPLEQ_EMPTY(&conf->ra_options.ra_rdnss_list)(((&conf->ra_options.ra_rdnss_list)->sqh_first) == (
(void *)0))
||
870 !SIMPLEQ_EMPTY(&conf->ra_options.ra_dnssl_list)(((&conf->ra_options.ra_dnssl_list)->sqh_first) == (
(void *)0))
) {
871 SIMPLEQ_FOREACH(iface, &conf->ra_iface_list, entry)for((iface) = ((&conf->ra_iface_list)->sqh_first); (
iface) != ((void *)0); (iface) = ((iface)->entry.sqe_next)
)
872 copy_dns_options(&conf->ra_options,
873 &iface->ra_options);
874 }
875
876 return (conf);
877}
878
879void
880copy_dns_options(const struct ra_options_conf *src, struct ra_options_conf *dst)
881{
882 struct ra_rdnss_conf *ra_rdnss, *nra_rdnss;
883 struct ra_dnssl_conf *ra_dnssl, *nra_dnssl;
884
885 if (SIMPLEQ_EMPTY(&dst->ra_rdnss_list)(((&dst->ra_rdnss_list)->sqh_first) == ((void *)0))) {
886 SIMPLEQ_FOREACH(ra_rdnss, &src->ra_rdnss_list, entry)for((ra_rdnss) = ((&src->ra_rdnss_list)->sqh_first)
; (ra_rdnss) != ((void *)0); (ra_rdnss) = ((ra_rdnss)->entry
.sqe_next))
{
887 if ((nra_rdnss = calloc(1, sizeof(*nra_rdnss))) == NULL((void *)0))
888 errx(1, "%s", __func__);
889 memcpy(nra_rdnss, ra_rdnss, sizeof(*nra_rdnss));
890 SIMPLEQ_INSERT_TAIL(&dst->ra_rdnss_list, nra_rdnss,do { (nra_rdnss)->entry.sqe_next = ((void *)0); *(&dst
->ra_rdnss_list)->sqh_last = (nra_rdnss); (&dst->
ra_rdnss_list)->sqh_last = &(nra_rdnss)->entry.sqe_next
; } while (0)
891 entry)do { (nra_rdnss)->entry.sqe_next = ((void *)0); *(&dst
->ra_rdnss_list)->sqh_last = (nra_rdnss); (&dst->
ra_rdnss_list)->sqh_last = &(nra_rdnss)->entry.sqe_next
; } while (0)
;
892 }
893 dst->rdnss_count = src->rdnss_count;
894 }
895 if (SIMPLEQ_EMPTY(&dst->ra_dnssl_list)(((&dst->ra_dnssl_list)->sqh_first) == ((void *)0))) {
896 SIMPLEQ_FOREACH(ra_dnssl, &src->ra_dnssl_list, entry)for((ra_dnssl) = ((&src->ra_dnssl_list)->sqh_first)
; (ra_dnssl) != ((void *)0); (ra_dnssl) = ((ra_dnssl)->entry
.sqe_next))
{
897 if ((nra_dnssl = calloc(1, sizeof(*nra_dnssl))) == NULL((void *)0))
898 errx(1, "%s", __func__);
899 memcpy(nra_dnssl, ra_dnssl, sizeof(*nra_dnssl));
900 SIMPLEQ_INSERT_TAIL(&dst->ra_dnssl_list, nra_dnssl,do { (nra_dnssl)->entry.sqe_next = ((void *)0); *(&dst
->ra_dnssl_list)->sqh_last = (nra_dnssl); (&dst->
ra_dnssl_list)->sqh_last = &(nra_dnssl)->entry.sqe_next
; } while (0)
901 entry)do { (nra_dnssl)->entry.sqe_next = ((void *)0); *(&dst
->ra_dnssl_list)->sqh_last = (nra_dnssl); (&dst->
ra_dnssl_list)->sqh_last = &(nra_dnssl)->entry.sqe_next
; } while (0)
;
902 }
903 dst->dnssl_len = src->dnssl_len;
904 }
905}
906
907int
908symset(const char *nam, const char *val, int persist)
909{
910 struct sym *sym;
911
912 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0); (sym) = ((sym)->entry.tqe_next))
{
913 if (strcmp(nam, sym->nam) == 0)
914 break;
915 }
916
917 if (sym != NULL((void *)0)) {
918 if (sym->persist == 1)
919 return (0);
920 else {
921 free(sym->nam);
922 free(sym->val);
923 TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void *)0)) (sym)->
entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev;
else (&symhead)->tqh_last = (sym)->entry.tqe_prev;
*(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while
(0)
;
924 free(sym);
925 }
926 }
927 if ((sym = calloc(1, sizeof(*sym))) == NULL((void *)0))
928 return (-1);
929
930 sym->nam = strdup(nam);
931 if (sym->nam == NULL((void *)0)) {
932 free(sym);
933 return (-1);
934 }
935 sym->val = strdup(val);
936 if (sym->val == NULL((void *)0)) {
937 free(sym->nam);
938 free(sym);
939 return (-1);
940 }
941 sym->used = 0;
942 sym->persist = persist;
943 TAILQ_INSERT_TAIL(&symhead, sym, entry)do { (sym)->entry.tqe_next = ((void *)0); (sym)->entry.
tqe_prev = (&symhead)->tqh_last; *(&symhead)->tqh_last
= (sym); (&symhead)->tqh_last = &(sym)->entry.
tqe_next; } while (0)
;
944 return (0);
945}
946
947int
948cmdline_symset(char *s)
949{
950 char *sym, *val;
951 int ret;
952
953 if ((val = strrchr(s, '=')) == NULL((void *)0))
954 return (-1);
955 sym = strndup(s, val - s);
956 if (sym == NULL((void *)0))
957 errx(1, "%s: strndup", __func__);
958 ret = symset(sym, val + 1, 1);
959 free(sym);
960
961 return (ret);
962}
963
964char *
965symget(const char *nam)
966{
967 struct sym *sym;
968
969 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0); (sym) = ((sym)->entry.tqe_next))
{
970 if (strcmp(nam, sym->nam) == 0) {
971 sym->used = 1;
972 return (sym->val);
973 }
974 }
975 return (NULL((void *)0));
976}
977
978struct ra_prefix_conf *
979conf_get_ra_prefix(struct in6_addr *addr, int prefixlen)
980{
981 struct ra_prefix_conf *prefix;
982
983 if (addr == NULL((void *)0)) {
984 if (ra_iface_conf->autoprefix != NULL((void *)0))
985 return (ra_iface_conf->autoprefix);
986 } else {
987 SIMPLEQ_FOREACH(prefix, &ra_iface_conf->ra_prefix_list, entry)for((prefix) = ((&ra_iface_conf->ra_prefix_list)->sqh_first
); (prefix) != ((void *)0); (prefix) = ((prefix)->entry.sqe_next
))
{
988 if (prefix->prefixlen == prefixlen && memcmp(addr,
989 &prefix->prefix, sizeof(*addr)) == 0)
990 return (prefix);
991 }
992 }
993
994 prefix = calloc(1, sizeof(*prefix));
995 if (prefix == NULL((void *)0))
996 errx(1, "%s: calloc", __func__);
997 prefix->prefixlen = prefixlen;
998 prefix->vltime = ADV_VALID_LIFETIME2592000;
999 prefix->pltime = ADV_PREFERRED_LIFETIME604800;
1000 prefix->lflag = 1;
1001 prefix->aflag = 1;
1002
1003 if (addr == NULL((void *)0))
1004 ra_iface_conf->autoprefix = prefix;
1005 else {
1006 prefix->prefix = *addr;
1007 SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_prefix_list, prefix,do { (prefix)->entry.sqe_next = ((void *)0); *(&ra_iface_conf
->ra_prefix_list)->sqh_last = (prefix); (&ra_iface_conf
->ra_prefix_list)->sqh_last = &(prefix)->entry.sqe_next
; } while (0)
1008 entry)do { (prefix)->entry.sqe_next = ((void *)0); *(&ra_iface_conf
->ra_prefix_list)->sqh_last = (prefix); (&ra_iface_conf
->ra_prefix_list)->sqh_last = &(prefix)->entry.sqe_next
; } while (0)
;
1009 }
1010
1011 return (prefix);
1012}
1013
1014struct ra_iface_conf *
1015conf_get_ra_iface(char *name)
1016{
1017 struct ra_iface_conf *iface;
1018 size_t n;
1019
1020 SIMPLEQ_FOREACH(iface, &conf->ra_iface_list, entry)for((iface) = ((&conf->ra_iface_list)->sqh_first); (
iface) != ((void *)0); (iface) = ((iface)->entry.sqe_next)
)
{
1021 if (strcmp(name, iface->name) == 0)
1022 return (iface);
1023 }
1024
1025 iface = calloc(1, sizeof(*iface));
1026 if (iface == NULL((void *)0))
1027 errx(1, "%s: calloc", __func__);
1028 n = strlcpy(iface->name, name, sizeof(iface->name));
1029 if (n >= sizeof(iface->name))
1030 errx(1, "%s: name too long", __func__);
1031
1032 /* Inherit attributes set in global section. */
1033 iface->ra_options = conf->ra_options;
1034
1035 SIMPLEQ_INIT(&iface->ra_prefix_list)do { (&iface->ra_prefix_list)->sqh_first = ((void *
)0); (&iface->ra_prefix_list)->sqh_last = &(&
iface->ra_prefix_list)->sqh_first; } while (0)
;
1036 SIMPLEQ_INIT(&iface->ra_options.ra_rdnss_list)do { (&iface->ra_options.ra_rdnss_list)->sqh_first =
((void *)0); (&iface->ra_options.ra_rdnss_list)->sqh_last
= &(&iface->ra_options.ra_rdnss_list)->sqh_first
; } while (0)
;
1037 iface->ra_options.rdnss_count = 0;
1038 SIMPLEQ_INIT(&iface->ra_options.ra_dnssl_list)do { (&iface->ra_options.ra_dnssl_list)->sqh_first =
((void *)0); (&iface->ra_options.ra_dnssl_list)->sqh_last
= &(&iface->ra_options.ra_dnssl_list)->sqh_first
; } while (0)
;
1039 iface->ra_options.dnssl_len = 0;
1040
1041 SIMPLEQ_INSERT_TAIL(&conf->ra_iface_list, iface, entry)do { (iface)->entry.sqe_next = ((void *)0); *(&conf->
ra_iface_list)->sqh_last = (iface); (&conf->ra_iface_list
)->sqh_last = &(iface)->entry.sqe_next; } while (0)
;
1042
1043 return (iface);
1044}
1045
1046void
1047clear_config(struct rad_conf *xconf)
1048{
1049 struct ra_iface_conf *iface;
1050
1051 free_dns_options(&xconf->ra_options);
1052
1053 while((iface = SIMPLEQ_FIRST(&xconf->ra_iface_list)((&xconf->ra_iface_list)->sqh_first)) != NULL((void *)0)) {
1054 SIMPLEQ_REMOVE_HEAD(&xconf->ra_iface_list, entry)do { if (((&xconf->ra_iface_list)->sqh_first = (&
xconf->ra_iface_list)->sqh_first->entry.sqe_next) ==
((void *)0)) (&xconf->ra_iface_list)->sqh_last = &
(&xconf->ra_iface_list)->sqh_first; } while (0)
;
1055 free_ra_iface_conf(iface);
1056 }
1057
1058 free(xconf);
1059}
1060#line 1053 "parse.c"
1061/* allocate initial stack or double stack size, up to YYMAXDEPTH */
1062static int yygrowstack(void)
1063{
1064 unsigned int newsize;
1065 long sslen;
1066 short *newss;
1067 YYSTYPE *newvs;
1068
1069 if ((newsize = yystacksize) == 0)
3
Assuming the condition is false
4
Taking false branch
1070 newsize = YYINITSTACKSIZE200;
1071 else if (newsize >= YYMAXDEPTH10000)
5
Assuming 'newsize' is < YYMAXDEPTH
6
Taking false branch
1072 return -1;
1073 else if ((newsize *= 2) > YYMAXDEPTH10000)
7
Assuming the condition is false
8
Taking false branch
1074 newsize = YYMAXDEPTH10000;
1075 sslen = yyssp - yyss;
1076#ifdef SIZE_MAX0xffffffffffffffffUL
1077#define YY_SIZE_MAX0xffffffffffffffffUL SIZE_MAX0xffffffffffffffffUL
1078#else
1079#define YY_SIZE_MAX0xffffffffffffffffUL 0xffffffffU
1080#endif
1081 if (newsize && YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newss)
9
Assuming 'newsize' is 0
1082 goto bail;
1083 newss = (short *)realloc(yyss, newsize * sizeof *newss);
1084 if (newss == NULL((void *)0))
10
Assuming 'newss' is not equal to NULL
11
Taking false branch
1085 goto bail;
1086 yyss = newss;
1087 yyssp = newss + sslen;
1088 if (newsize
11.1
'newsize' is 0
&& YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newvs)
1089 goto bail;
1090 newvs = (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs);
1091 if (newvs == NULL((void *)0))
12
Assuming 'newvs' is not equal to NULL
13
Taking false branch
1092 goto bail;
1093 yyvs = newvs;
1094 yyvsp = newvs + sslen;
1095 yystacksize = newsize;
1096 yysslim = yyss + newsize - 1;
1097 return 0;
1098bail:
1099 if (yyss)
1100 free(yyss);
1101 if (yyvs)
1102 free(yyvs);
1103 yyss = yyssp = NULL((void *)0);
1104 yyvs = yyvsp = NULL((void *)0);
1105 yystacksize = 0;
1106 return -1;
1107}
1108
1109#define YYABORTgoto yyabort goto yyabort
1110#define YYREJECTgoto yyabort goto yyabort
1111#define YYACCEPTgoto yyaccept goto yyaccept
1112#define YYERRORgoto yyerrlab goto yyerrlab
1113int
1114yyparse(void)
1115{
1116 int yym, yyn, yystate;
1117#if YYDEBUG0
1118 const char *yys;
1119
1120 if ((yys = getenv("YYDEBUG")))
1121 {
1122 yyn = *yys;
1123 if (yyn >= '0' && yyn <= '9')
1124 yydebug = yyn - '0';
1125 }
1126#endif /* YYDEBUG */
1127
1128 yynerrs = 0;
1129 yyerrflag = 0;
1130 yychar = (-1);
1131
1132 if (yyss == NULL((void *)0) && yygrowstack()) goto yyoverflow;
1
Assuming 'yyss' is equal to NULL
2
Calling 'yygrowstack'
14
Returning from 'yygrowstack'
15
Taking false branch
1133 yyssp = yyss;
1134 yyvsp = yyvs;
1135 *yyssp = yystate = 0;
16
Use of zero-allocated memory
1136
1137yyloop:
1138 if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1139 if (yychar < 0)
1140 {
1141 if ((yychar = yylex()) < 0) yychar = 0;
1142#if YYDEBUG0
1143 if (yydebug)
1144 {
1145 yys = 0;
1146 if (yychar <= YYMAXTOKEN287) yys = yyname[yychar];
1147 if (!yys) yys = "illegal-symbol";
1148 printf("%sdebug: state %d, reading %d (%s)\n",
1149 YYPREFIX"yy", yystate, yychar, yys);
1150 }
1151#endif
1152 }
1153 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1154 yyn <= YYTABLESIZE371 && yycheck[yyn] == yychar)
1155 {
1156#if YYDEBUG0
1157 if (yydebug)
1158 printf("%sdebug: state %d, shifting to state %d\n",
1159 YYPREFIX"yy", yystate, yytable[yyn]);
1160#endif
1161 if (yyssp >= yysslim && yygrowstack())
1162 {
1163 goto yyoverflow;
1164 }
1165 *++yyssp = yystate = yytable[yyn];
1166 *++yyvsp = yylval;
1167 yychar = (-1);
1168 if (yyerrflag > 0) --yyerrflag;
1169 goto yyloop;
1170 }
1171 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1172 yyn <= YYTABLESIZE371 && yycheck[yyn] == yychar)
1173 {
1174 yyn = yytable[yyn];
1175 goto yyreduce;
1176 }
1177 if (yyerrflag) goto yyinrecovery;
1178#if defined(__GNUC__4)
1179 goto yynewerror;
1180#endif
1181yynewerror:
1182 yyerror("syntax error");
1183#if defined(__GNUC__4)
1184 goto yyerrlab;
1185#endif
1186yyerrlab:
1187 ++yynerrs;
1188yyinrecovery:
1189 if (yyerrflag < 3)
1190 {
1191 yyerrflag = 3;
1192 for (;;)
1193 {
1194 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE256) >= 0 &&
1195 yyn <= YYTABLESIZE371 && yycheck[yyn] == YYERRCODE256)
1196 {
1197#if YYDEBUG0
1198 if (yydebug)
1199 printf("%sdebug: state %d, error recovery shifting\
1200 to state %d\n", YYPREFIX"yy", *yyssp, yytable[yyn]);
1201#endif
1202 if (yyssp >= yysslim && yygrowstack())
1203 {
1204 goto yyoverflow;
1205 }
1206 *++yyssp = yystate = yytable[yyn];
1207 *++yyvsp = yylval;
1208 goto yyloop;
1209 }
1210 else
1211 {
1212#if YYDEBUG0
1213 if (yydebug)
1214 printf("%sdebug: error recovery discarding state %d\n",
1215 YYPREFIX"yy", *yyssp);
1216#endif
1217 if (yyssp <= yyss) goto yyabort;
1218 --yyssp;
1219 --yyvsp;
1220 }
1221 }
1222 }
1223 else
1224 {
1225 if (yychar == 0) goto yyabort;
1226#if YYDEBUG0
1227 if (yydebug)
1228 {
1229 yys = 0;
1230 if (yychar <= YYMAXTOKEN287) yys = yyname[yychar];
1231 if (!yys) yys = "illegal-symbol";
1232 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1233 YYPREFIX"yy", yystate, yychar, yys);
1234 }
1235#endif
1236 yychar = (-1);
1237 goto yyloop;
1238 }
1239yyreduce:
1240#if YYDEBUG0
1241 if (yydebug)
1242 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1243 YYPREFIX"yy", yystate, yyn, yyrule[yyn]);
1244#endif
1245 yym = yylen[yyn];
1246 if (yym)
1247 yyval = yyvsp[1-yym];
1248 else
1249 memset(&yyval, 0, sizeof yyval);
1250 switch (yyn)
1251 {
1252case 4:
1253#line 131 "/usr/src/usr.sbin/rad/parse.y"
1254{ ra_options = &conf->ra_options; }
1255break;
1256case 8:
1257#line 134 "/usr/src/usr.sbin/rad/parse.y"
1258{ file->errors++; }
1259break;
1260case 9:
1261#line 137 "/usr/src/usr.sbin/rad/parse.y"
1262{
1263 struct file *nfile;
1264
1265 if ((nfile = pushfile(yyvsp[0].v.string, 0)) == NULL((void *)0)) {
1266 yyerror("failed to include file %s", yyvsp[0].v.string);
1267 free(yyvsp[0].v.string);
1268 YYERRORgoto yyerrlab;
1269 }
1270 free(yyvsp[0].v.string);
1271
1272 file = nfile;
1273 lungetc('\n');
1274 }
1275break;
1276case 10:
1277#line 152 "/usr/src/usr.sbin/rad/parse.y"
1278{
1279 if (asprintf(&yyval.v.string, "%s %s", yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
1280 free(yyvsp[-1].v.string);
1281 free(yyvsp[0].v.string);
1282 yyerror("string: asprintf");
1283 YYERRORgoto yyerrlab;
1284 }
1285 free(yyvsp[-1].v.string);
1286 free(yyvsp[0].v.string);
1287 }
1288break;
1289case 12:
1290#line 165 "/usr/src/usr.sbin/rad/parse.y"
1291{ yyval.v.number = 1; }
1292break;
1293case 13:
1294#line 166 "/usr/src/usr.sbin/rad/parse.y"
1295{ yyval.v.number = 0; }
1296break;
1297case 14:
1298#line 169 "/usr/src/usr.sbin/rad/parse.y"
1299{
1300 char *s = yyvsp[-2].v.string;
1301 if (cmd_opts & OPT_VERBOSE0x00000001)
1302 printf("%s = \"%s\"\n", yyvsp[-2].v.string, yyvsp[0].v.string);
1303 while (*s++) {
1304 if (isspace((unsigned char)*s)) {
1305 yyerror("macro name cannot contain "
1306 "whitespace");
1307 free(yyvsp[-2].v.string);
1308 free(yyvsp[0].v.string);
1309 YYERRORgoto yyerrlab;
1310 }
1311 }
1312 if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)
1313 fatal("cannot store variable");
1314 free(yyvsp[-2].v.string);
1315 free(yyvsp[0].v.string);
1316 }
1317break;
1318case 15:
1319#line 189 "/usr/src/usr.sbin/rad/parse.y"
1320{
1321 ra_options = &conf->ra_options;
1322 }
1323break;
1324case 16:
1325#line 194 "/usr/src/usr.sbin/rad/parse.y"
1326{
1327 ra_options->dfr = yyvsp[0].v.number;
1328 }
1329break;
1330case 17:
1331#line 197 "/usr/src/usr.sbin/rad/parse.y"
1332{
1333 ra_options->cur_hl = yyvsp[0].v.number;
1334 }
1335break;
1336case 18:
1337#line 200 "/usr/src/usr.sbin/rad/parse.y"
1338{
1339 ra_options->m_flag = yyvsp[0].v.number;
1340 }
1341break;
1342case 19:
1343#line 203 "/usr/src/usr.sbin/rad/parse.y"
1344{
1345 ra_options->o_flag = yyvsp[0].v.number;
1346 }
1347break;
1348case 20:
1349#line 206 "/usr/src/usr.sbin/rad/parse.y"
1350{
1351 ra_options->router_lifetime = yyvsp[0].v.number;
1352 }
1353break;
1354case 21:
1355#line 209 "/usr/src/usr.sbin/rad/parse.y"
1356{
1357 ra_options->reachable_time = yyvsp[0].v.number;
1358 }
1359break;
1360case 22:
1361#line 212 "/usr/src/usr.sbin/rad/parse.y"
1362{
1363 ra_options->retrans_timer = yyvsp[0].v.number;
1364 }
1365break;
1366case 23:
1367#line 215 "/usr/src/usr.sbin/rad/parse.y"
1368{
1369 ra_options->mtu = yyvsp[0].v.number;
1370 }
1371break;
1372case 28:
1373#line 228 "/usr/src/usr.sbin/rad/parse.y"
1374{
1375 ra_iface_conf = conf_get_ra_iface(yyvsp[0].v.string);
1376 /* set auto prefix defaults */
1377 ra_iface_conf->autoprefix = conf_get_ra_prefix(NULL((void *)0), 0);
1378 ra_options = &ra_iface_conf->ra_options;
1379 }
1380break;
1381case 29:
1382#line 233 "/usr/src/usr.sbin/rad/parse.y"
1383{
1384 ra_iface_conf = NULL((void *)0);
1385 ra_options = &conf->ra_options;
1386 }
1387break;
1388case 35:
1389#line 248 "/usr/src/usr.sbin/rad/parse.y"
1390{
1391 free(ra_iface_conf->autoprefix);
1392 ra_iface_conf->autoprefix = NULL((void *)0);
1393 }
1394break;
1395case 36:
1396#line 252 "/usr/src/usr.sbin/rad/parse.y"
1397{
1398 if (ra_iface_conf->autoprefix == NULL((void *)0))
1399 ra_iface_conf->autoprefix =
1400 conf_get_ra_prefix(NULL((void *)0), 0);
1401 ra_prefix_conf = ra_iface_conf->autoprefix;
1402 }
1403break;
1404case 37:
1405#line 257 "/usr/src/usr.sbin/rad/parse.y"
1406{
1407 ra_prefix_conf = NULL((void *)0);
1408 }
1409break;
1410case 38:
1411#line 260 "/usr/src/usr.sbin/rad/parse.y"
1412{
1413 struct in6_addr addr;
1414 int prefixlen;
1415 char *p;
1416 const char *errstr;
1417
1418 memset(&addr, 0, sizeof(addr));
1419 p = strchr(yyvsp[0].v.string, '/');
1420 if (p != NULL((void *)0)) {
1421 *p++ = '\0';
1422 prefixlen = strtonum(p, 0, 128, &errstr);
1423 if (errstr != NULL((void *)0)) {
1424 yyerror("error parsing prefix "
1425 "\"%s/%s\"", yyvsp[0].v.string, p);
1426 free(yyvsp[0].v.string);
1427 YYERRORgoto yyerrlab;
1428 }
1429 } else
1430 prefixlen = 64;
1431 if(inet_pton(AF_INET624, yyvsp[0].v.string, &addr) == 0) {
1432 yyerror("error parsing prefix \"%s/%d\"", yyvsp[0].v.string,
1433 prefixlen);
1434 free(yyvsp[0].v.string);
1435 YYERRORgoto yyerrlab;
1436 }
1437 mask_prefix(&addr, prefixlen);
1438 ra_prefix_conf = conf_get_ra_prefix(&addr, prefixlen);
1439 }
1440break;
1441case 39:
1442#line 287 "/usr/src/usr.sbin/rad/parse.y"
1443{
1444 ra_prefix_conf = NULL((void *)0);
1445 }
1446break;
1447case 46:
1448#line 302 "/usr/src/usr.sbin/rad/parse.y"
1449{
1450 ra_prefix_conf->vltime = yyvsp[0].v.number;
1451 }
1452break;
1453case 47:
1454#line 305 "/usr/src/usr.sbin/rad/parse.y"
1455{
1456 ra_prefix_conf->pltime = yyvsp[0].v.number;
1457 }
1458break;
1459case 48:
1460#line 308 "/usr/src/usr.sbin/rad/parse.y"
1461{
1462 ra_prefix_conf->lflag = yyvsp[0].v.number;
1463 }
1464break;
1465case 49:
1466#line 311 "/usr/src/usr.sbin/rad/parse.y"
1467{
1468 ra_prefix_conf->aflag = yyvsp[0].v.number;
1469 }
1470break;
1471case 55:
1472#line 324 "/usr/src/usr.sbin/rad/parse.y"
1473{
1474 ra_options->rdns_lifetime = yyvsp[0].v.number;
1475 }
1476break;
1477case 64:
1478#line 340 "/usr/src/usr.sbin/rad/parse.y"
1479{
1480 struct ra_rdnss_conf *ra_rdnss_conf;
1481 struct in6_addr addr;
1482
1483 memset(&addr, 0, sizeof(addr));
1484 if (inet_pton(AF_INET624, yyvsp[0].v.string, &addr)
1485 != 1) {
1486 yyerror("error parsing nameserver address %s",
1487 yyvsp[0].v.string);
1488 free(yyvsp[0].v.string);
1489 YYERRORgoto yyerrlab;
1490 }
1491 if ((ra_rdnss_conf = calloc(1, sizeof(*ra_rdnss_conf)))
1492 == NULL((void *)0))
1493 err(1, "%s", __func__);
1494 memcpy(&ra_rdnss_conf->rdnss, &addr, sizeof(addr));
1495 SIMPLEQ_INSERT_TAIL(&ra_options->ra_rdnss_list,do { (ra_rdnss_conf)->entry.sqe_next = ((void *)0); *(&
ra_options->ra_rdnss_list)->sqh_last = (ra_rdnss_conf);
(&ra_options->ra_rdnss_list)->sqh_last = &(ra_rdnss_conf
)->entry.sqe_next; } while (0)
1496 ra_rdnss_conf, entry)do { (ra_rdnss_conf)->entry.sqe_next = ((void *)0); *(&
ra_options->ra_rdnss_list)->sqh_last = (ra_rdnss_conf);
(&ra_options->ra_rdnss_list)->sqh_last = &(ra_rdnss_conf
)->entry.sqe_next; } while (0)
;
1497 ra_options->rdnss_count++;
1498 }
1499break;
1500case 71:
1501#line 371 "/usr/src/usr.sbin/rad/parse.y"
1502{
1503 struct ra_dnssl_conf *ra_dnssl_conf;
1504 size_t len;
1505
1506 if ((ra_dnssl_conf = calloc(1,
1507 sizeof(*ra_dnssl_conf))) == NULL((void *)0))
1508 err(1, "%s", __func__);
1509
1510 if ((len = strlcpy(ra_dnssl_conf->search, yyvsp[0].v.string,
1511 sizeof(ra_dnssl_conf->search))) >=
1512 sizeof(ra_dnssl_conf->search)) {
1513 yyerror("search string too long");
1514 free(yyvsp[0].v.string);
1515 YYERRORgoto yyerrlab;
1516 }
1517 if (ra_dnssl_conf->search[len] != '.') {
1518 if ((len = strlcat(ra_dnssl_conf->search, ".",
1519 sizeof(ra_dnssl_conf->search))) >
1520 sizeof(ra_dnssl_conf->search)) {
1521 yyerror("search string too long");
1522 free(yyvsp[0].v.string);
1523 YYERRORgoto yyerrlab;
1524 }
1525 }
1526 SIMPLEQ_INSERT_TAIL(&ra_options->ra_dnssl_list,do { (ra_dnssl_conf)->entry.sqe_next = ((void *)0); *(&
ra_options->ra_dnssl_list)->sqh_last = (ra_dnssl_conf);
(&ra_options->ra_dnssl_list)->sqh_last = &(ra_dnssl_conf
)->entry.sqe_next; } while (0)
1527 ra_dnssl_conf, entry)do { (ra_dnssl_conf)->entry.sqe_next = ((void *)0); *(&
ra_options->ra_dnssl_list)->sqh_last = (ra_dnssl_conf);
(&ra_options->ra_dnssl_list)->sqh_last = &(ra_dnssl_conf
)->entry.sqe_next; } while (0)
;
1528 ra_options->dnssl_len += len + 1;
1529 }
1530break;
1531#line 1524 "parse.c"
1532 }
1533 yyssp -= yym;
1534 yystate = *yyssp;
1535 yyvsp -= yym;
1536 yym = yylhs[yyn];
1537 if (yystate == 0 && yym == 0)
1538 {
1539#if YYDEBUG0
1540 if (yydebug)
1541 printf("%sdebug: after reduction, shifting from state 0 to\
1542 state %d\n", YYPREFIX"yy", YYFINAL1);
1543#endif
1544 yystate = YYFINAL1;
1545 *++yyssp = YYFINAL1;
1546 *++yyvsp = yyval;
1547 if (yychar < 0)
1548 {
1549 if ((yychar = yylex()) < 0) yychar = 0;
1550#if YYDEBUG0
1551 if (yydebug)
1552 {
1553 yys = 0;
1554 if (yychar <= YYMAXTOKEN287) yys = yyname[yychar];
1555 if (!yys) yys = "illegal-symbol";
1556 printf("%sdebug: state %d, reading %d (%s)\n",
1557 YYPREFIX"yy", YYFINAL1, yychar, yys);
1558 }
1559#endif
1560 }
1561 if (yychar == 0) goto yyaccept;
1562 goto yyloop;
1563 }
1564 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1565 yyn <= YYTABLESIZE371 && yycheck[yyn] == yystate)
1566 yystate = yytable[yyn];
1567 else
1568 yystate = yydgoto[yym];
1569#if YYDEBUG0
1570 if (yydebug)
1571 printf("%sdebug: after reduction, shifting from state %d \
1572to state %d\n", YYPREFIX"yy", *yyssp, yystate);
1573#endif
1574 if (yyssp >= yysslim && yygrowstack())
1575 {
1576 goto yyoverflow;
1577 }
1578 *++yyssp = yystate;
1579 *++yyvsp = yyval;
1580 goto yyloop;
1581yyoverflow:
1582 yyerror("yacc stack overflow");
1583yyabort:
1584 if (yyss)
1585 free(yyss);
1586 if (yyvs)
1587 free(yyvs);
1588 yyss = yyssp = NULL((void *)0);
1589 yyvs = yyvsp = NULL((void *)0);
1590 yystacksize = 0;
1591 return (1);
1592yyaccept:
1593 if (yyss)
1594 free(yyss);
1595 if (yyvs)
1596 free(yyvs);
1597 yyss = yyssp = NULL((void *)0);
1598 yyvs = yyvsp = NULL((void *)0);
1599 yystacksize = 0;
1600 return (0);
1601}