Bug Summary

File:src/usr.sbin/rad/obj/parse.c
Warning:line 1656, column 5
Potential leak of memory pointed to by 'ra_dnssl_conf'

Annotated Source Code

Press '?' to see keyboard shortcuts

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