parse.y revision 1.35
1/*	$OpenBSD: parse.y,v 1.35 2016/05/23 15:41:04 renato Exp $ */
2
3/*
4 * Copyright (c) 2004, 2005, 2008 Esben Norby <norby@openbsd.org>
5 * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
6 * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
7 * Copyright (c) 2001 Markus Friedl.  All rights reserved.
8 * Copyright (c) 2001 Daniel Hartmeier.  All rights reserved.
9 * Copyright (c) 2001 Theo de Raadt.  All rights reserved.
10 *
11 * Permission to use, copy, modify, and distribute this software for any
12 * purpose with or without fee is hereby granted, provided that the above
13 * copyright notice and this permission notice appear in all copies.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 */
23
24%{
25#include <sys/types.h>
26#include <sys/socket.h>
27#include <sys/stat.h>
28#include <netinet/in.h>
29#include <arpa/inet.h>
30#include <ctype.h>
31#include <err.h>
32#include <errno.h>
33#include <unistd.h>
34#include <ifaddrs.h>
35#include <net/if_types.h>
36#include <limits.h>
37#include <stdarg.h>
38#include <stdio.h>
39#include <string.h>
40#include <syslog.h>
41
42#include "ldp.h"
43#include "ldpd.h"
44#include "lde.h"
45#include "ldpe.h"
46#include "log.h"
47
48TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
49static struct file {
50	TAILQ_ENTRY(file)	 entry;
51	FILE			*stream;
52	char			*name;
53	int			 lineno;
54	int			 errors;
55} *file, *topfile;
56struct file	*pushfile(const char *, int);
57int		 popfile(void);
58int		 check_file_secrecy(int, const char *);
59int		 yyparse(void);
60int		 yylex(void);
61int		 yyerror(const char *, ...)
62    __attribute__((__format__ (printf, 1, 2)))
63    __attribute__((__nonnull__ (1)));
64int		 kw_cmp(const void *, const void *);
65int		 lookup(char *);
66int		 lgetc(int);
67int		 lungetc(int);
68int		 findeol(void);
69
70TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
71struct sym {
72	TAILQ_ENTRY(sym)	 entry;
73	int			 used;
74	int			 persist;
75	char			*nam;
76	char			*val;
77};
78
79int		 symset(const char *, const char *, int);
80char		*symget(const char *);
81
82void		 clear_config(struct ldpd_conf *xconf);
83u_int32_t	 get_rtr_id(void);
84int		 host(const char *, struct in_addr *, struct in_addr *);
85
86static struct ldpd_conf	*conf;
87static int			 errors = 0;
88
89struct iface		*iface = NULL;
90struct tnbr		*tnbr = NULL;
91struct nbr_params	*nbrp = NULL;
92struct l2vpn		*l2vpn = NULL;
93struct l2vpn_pw		*pw = NULL;
94
95struct config_defaults {
96	u_int16_t	lhello_holdtime;
97	u_int16_t	lhello_interval;
98	u_int16_t	thello_holdtime;
99	u_int16_t	thello_interval;
100	u_int8_t	pwflags;
101};
102
103struct config_defaults	 globaldefs;
104struct config_defaults	 ifacedefs;
105struct config_defaults	 tnbrdefs;
106struct config_defaults	 pwdefs;
107struct config_defaults	*defs;
108
109int			 bad_ip_addr(struct in_addr);
110
111struct iface		*conf_get_if(struct kif *);
112struct tnbr		*conf_get_tnbr(struct in_addr);
113struct nbr_params	*conf_get_nbrp(struct in_addr);
114struct l2vpn		*conf_get_l2vpn(char *);
115struct l2vpn_if		*conf_get_l2vpn_if(struct l2vpn *, struct kif *);
116struct l2vpn_pw		*conf_get_l2vpn_pw(struct l2vpn *, struct kif *);
117
118typedef struct {
119	union {
120		int64_t		 number;
121		char		*string;
122	} v;
123	int lineno;
124} YYSTYPE;
125
126%}
127
128%token	INTERFACE TNEIGHBOR ROUTERID FIBUPDATE
129%token	LHELLOHOLDTIME LHELLOINTERVAL
130%token	THELLOHOLDTIME THELLOINTERVAL
131%token	THELLOACCEPT
132%token	KEEPALIVE
133%token	NEIGHBOR PASSWORD
134%token	L2VPN TYPE VPLS PWTYPE MTU BRIDGE
135%token	ETHERNET ETHERNETTAGGED STATUSTLV CONTROLWORD
136%token	PSEUDOWIRE NEIGHBOR PWID
137%token	EXTTAG
138%token	YES NO
139%token	INCLUDE
140%token	ERROR
141%token	<v.string>	STRING
142%token	<v.number>	NUMBER
143%type	<v.number>	yesno
144%type	<v.number>	l2vpn_type
145%type	<v.number>	pw_type
146%type	<v.string>	string
147
148%%
149
150grammar		: /* empty */
151		| grammar include '\n'
152		| grammar '\n'
153		| grammar conf_main '\n'
154		| grammar varset '\n'
155		| grammar interface '\n'
156		| grammar tneighbor '\n'
157		| grammar neighbor '\n'
158		| grammar l2vpn '\n'
159		| grammar error '\n'		{ file->errors++; }
160		;
161
162include		: INCLUDE STRING		{
163			struct file	*nfile;
164
165			if ((nfile = pushfile($2, 1)) == NULL) {
166				yyerror("failed to include file %s", $2);
167				free($2);
168				YYERROR;
169			}
170			free($2);
171
172			file = nfile;
173			lungetc('\n');
174		}
175		;
176
177string		: string STRING	{
178			if (asprintf(&$$, "%s %s", $1, $2) == -1) {
179				free($1);
180				free($2);
181				yyerror("string: asprintf");
182				YYERROR;
183			}
184			free($1);
185			free($2);
186		}
187		| STRING
188		;
189
190yesno		: YES	{ $$ = 1; }
191		| NO	{ $$ = 0; }
192		;
193
194l2vpn_type	: VPLS	{ $$ = L2VPN_TYPE_VPLS; }
195		;
196
197pw_type		: ETHERNET		{ $$ = PW_TYPE_ETHERNET; }
198		| ETHERNETTAGGED	{ $$ = PW_TYPE_ETHERNET_TAGGED; }
199		;
200
201varset		: STRING '=' string {
202			if (conf->opts & LDPD_OPT_VERBOSE)
203				printf("%s = \"%s\"\n", $1, $3);
204			if (symset($1, $3, 0) == -1)
205				fatal("cannot store variable");
206			free($1);
207			free($3);
208		}
209		;
210
211conf_main	: ROUTERID STRING {
212			if (!inet_aton($2, &conf->rtr_id)) {
213				yyerror("error parsing router-id");
214				free($2);
215				YYERROR;
216			}
217			free($2);
218			if (bad_ip_addr(conf->rtr_id)) {
219				yyerror("invalid router-id");
220				YYERROR;
221			}
222		}
223		| FIBUPDATE yesno {
224			if ($2 == 0)
225				conf->flags |= LDPD_FLAG_NO_FIB_UPDATE;
226			else
227				conf->flags &= ~LDPD_FLAG_NO_FIB_UPDATE;
228		}
229		| THELLOACCEPT yesno {
230			if ($2 == 0)
231				conf->flags &= ~LDPD_FLAG_TH_ACCEPT;
232			else
233				conf->flags |= LDPD_FLAG_TH_ACCEPT;
234		}
235		| KEEPALIVE NUMBER {
236			if ($2 < MIN_KEEPALIVE || $2 > MAX_KEEPALIVE) {
237				yyerror("keepalive out of range (%d-%d)",
238				    MIN_KEEPALIVE, MAX_KEEPALIVE);
239				YYERROR;
240			}
241			conf->keepalive = $2;
242		}
243		| iface_defaults
244		| tnbr_defaults
245		;
246
247iface_defaults	: LHELLOHOLDTIME NUMBER {
248			if ($2 < MIN_HOLDTIME ||
249			    $2 > MAX_HOLDTIME) {
250				yyerror("hello holdtime out of range (%d-%d)",
251				    MIN_HOLDTIME, MAX_HOLDTIME);
252				YYERROR;
253			}
254			defs->lhello_holdtime = $2;
255		}
256		| LHELLOINTERVAL NUMBER {
257			if ($2 < MIN_HELLO_INTERVAL ||
258			    $2 > MAX_HELLO_INTERVAL) {
259				yyerror("hello-interval out of range (%d-%d)",
260				    MIN_HELLO_INTERVAL, MAX_HELLO_INTERVAL);
261				YYERROR;
262			}
263			defs->lhello_interval = $2;
264		}
265		;
266
267tnbr_defaults	: THELLOHOLDTIME NUMBER {
268			if ($2 < MIN_HOLDTIME ||
269			    $2 > MAX_HOLDTIME) {
270				yyerror("hello holdtime out of range (%d-%d)",
271				    MIN_HOLDTIME, MAX_HOLDTIME);
272				YYERROR;
273			}
274			conf->thello_holdtime = $2;
275			defs->thello_holdtime = $2;
276		}
277		| THELLOINTERVAL NUMBER {
278			if ($2 < MIN_HELLO_INTERVAL ||
279			    $2 > MAX_HELLO_INTERVAL) {
280				yyerror("hello-interval out of range (%d-%d)",
281				    MIN_HELLO_INTERVAL, MAX_HELLO_INTERVAL);
282				YYERROR;
283			}
284			conf->thello_interval = $2;
285			defs->thello_interval = $2;
286		}
287		;
288
289nbr_opts	: KEEPALIVE NUMBER {
290			if ($2 < MIN_KEEPALIVE || $2 > MAX_KEEPALIVE) {
291				yyerror("keepalive out of range (%d-%d)",
292				    MIN_KEEPALIVE, MAX_KEEPALIVE);
293				YYERROR;
294			}
295			nbrp->keepalive = $2;
296			nbrp->flags |= F_NBRP_KEEPALIVE;
297		}
298		| PASSWORD STRING {
299			if (strlcpy(nbrp->auth.md5key, $2,
300			    sizeof(nbrp->auth.md5key)) >=
301			    sizeof(nbrp->auth.md5key)) {
302				yyerror("tcp md5sig password too long: max %zu",
303				    sizeof(nbrp->auth.md5key) - 1);
304				free($2);
305				YYERROR;
306			}
307			nbrp->auth.md5key_len = strlen($2);
308			nbrp->auth.method = AUTH_MD5SIG;
309			free($2);
310		}
311		;
312
313pw_defaults	: STATUSTLV yesno {
314			if ($2 == 1) {
315				defs->pwflags |= F_PW_STATUSTLV_CONF;
316				defs->pwflags |= F_PW_STATUSTLV;
317			} else {
318				defs->pwflags &= ~F_PW_STATUSTLV_CONF;
319				defs->pwflags &= ~F_PW_STATUSTLV;
320			}
321		}
322		| CONTROLWORD yesno {
323			if ($2 == 1) {
324				defs->pwflags |= F_PW_CONTROLWORD_CONF;
325				defs->pwflags |= F_PW_CONTROLWORD;
326			} else {
327				defs->pwflags &= ~F_PW_CONTROLWORD_CONF;
328				defs->pwflags &= ~F_PW_CONTROLWORD;
329			}
330		}
331		;
332
333pwopts		: PWID NUMBER {
334			if ($2 < MIN_PWID_ID ||
335			    $2 > MAX_PWID_ID) {
336				yyerror("pw-id out of range (%d-%d)",
337				    MIN_PWID_ID, MAX_PWID_ID);
338				YYERROR;
339			}
340
341			pw->pwid = $2;
342		}
343		| NEIGHBOR STRING {
344			struct in_addr	 addr;
345			struct tnbr	*t;
346
347			if (inet_aton($2, &addr) == 0) {
348				yyerror(
349				    "error parsing neighbor address");
350				free($2);
351				YYERROR;
352			}
353			free($2);
354
355			pw->addr.s_addr = addr.s_addr;
356
357			t = tnbr_find(conf, addr);
358			if (t == NULL) {
359				t = tnbr_new(conf, addr);
360				LIST_INSERT_HEAD(&conf->tnbr_list, t, entry);
361			}
362
363			t->pw_count++;
364		}
365		| pw_defaults
366		;
367
368pseudowire	: PSEUDOWIRE STRING {
369			struct kif	*kif;
370
371			if ((kif = kif_findname($2)) == NULL) {
372				yyerror("unknown interface %s", $2);
373				free($2);
374				YYERROR;
375			}
376			free($2);
377
378			if (kif->if_type != IFT_MPLSTUNNEL) {
379				yyerror("unsupported interface type on "
380				    "interface %s", kif->ifname);
381				YYERROR;
382			}
383
384			pw = conf_get_l2vpn_pw(l2vpn, kif);
385			if (pw == NULL)
386				YYERROR;
387			LIST_INSERT_HEAD(&l2vpn->pw_list, pw, entry);
388
389			memcpy(&pwdefs, defs, sizeof(pwdefs));
390			defs = &pwdefs;
391		} pw_block {
392			struct l2vpn	*l;
393			struct l2vpn_pw *p;
394
395			LIST_FOREACH(l, &conf->l2vpn_list, entry)
396				LIST_FOREACH(p, &l->pw_list, entry)
397					if (pw != p &&
398					    pw->pwid == p->pwid &&
399					    pw->addr.s_addr == p->addr.s_addr) {
400						yyerror("pseudowire already "
401						    "configured");
402						YYERROR;
403					}
404
405			pw->flags = defs->pwflags;
406			defs = &globaldefs;
407			pw = NULL;
408		}
409		;
410
411pw_block	: '{' optnl pwopts_l '}'
412		| '{' optnl '}'
413		| /* nothing */
414		;
415
416pwopts_l	: pwopts_l pwopts nl
417		| pwopts optnl
418		;
419
420l2vpnopts	: PWTYPE pw_type {
421			l2vpn->pw_type = $2;
422		}
423		| MTU NUMBER {
424			if ($2 < MIN_L2VPN_MTU ||
425			    $2 > MAX_L2VPN_MTU) {
426				yyerror("l2vpn mtu out of range (%d-%d)",
427				    MIN_L2VPN_MTU, MAX_L2VPN_MTU);
428				YYERROR;
429			}
430			l2vpn->mtu = $2;
431		}
432		| pw_defaults
433		| BRIDGE STRING {
434			struct l2vpn	 *l;
435			struct kif	 *kif;
436
437			if ((kif = kif_findname($2)) == NULL) {
438				yyerror("unknown interface %s", $2);
439				free($2);
440				YYERROR;
441			}
442			free($2);
443
444			if (l2vpn->br_ifindex != 0) {
445				yyerror("bridge interface cannot be "
446				    "redefined on l2vpn %s", l2vpn->name);
447				YYERROR;
448			}
449
450			if (kif->if_type != IFT_BRIDGE) {
451				yyerror("unsupported interface type on "
452				    "interface %s", kif->ifname);
453				YYERROR;
454			}
455
456			LIST_FOREACH(l, &conf->l2vpn_list, entry) {
457				if (l->br_ifindex == kif->ifindex) {
458					yyerror("bridge %s is already being "
459					    "used by l2vpn %s", kif->ifname,
460					    l->name);
461					YYERROR;
462				}
463			}
464
465			l2vpn->br_ifindex = kif->ifindex;
466			strlcpy(l2vpn->br_ifname, kif->ifname,
467			    sizeof(l2vpn->br_ifname));
468		}
469		| INTERFACE STRING {
470			struct kif	*kif;
471			struct l2vpn_if	*lif;
472
473			if ((kif = kif_findname($2)) == NULL) {
474				yyerror("unknown interface %s", $2);
475				free($2);
476				YYERROR;
477			}
478			free($2);
479
480			if (kif->if_type == IFT_BRIDGE
481			    || kif->if_type == IFT_LOOP
482			    || kif->if_type == IFT_CARP) {
483				yyerror("unsupported interface type on "
484				    "interface %s", kif->ifname);
485				YYERROR;
486			}
487
488			lif = conf_get_l2vpn_if(l2vpn, kif);
489			if (lif == NULL)
490				YYERROR;
491			LIST_INSERT_HEAD(&l2vpn->if_list, lif, entry);
492		}
493		| pseudowire
494		;
495
496optnl		: '\n' optnl
497		|
498		;
499
500nl		: '\n' optnl		/* one newline or more */
501		;
502
503interface	: INTERFACE STRING	{
504			struct kif	*kif;
505
506			if ((kif = kif_findname($2)) == NULL) {
507				yyerror("unknown interface %s", $2);
508				free($2);
509				YYERROR;
510			}
511			free($2);
512			iface = conf_get_if(kif);
513			if (iface == NULL)
514				YYERROR;
515			if (iface->if_type == IFT_LOOP ||
516			    iface->if_type == IFT_CARP ||
517			    iface->if_type == IFT_MPLSTUNNEL) {
518				yyerror("unsupported interface type on "
519				    "interface %s", iface->name);
520				YYERROR;
521			}
522			LIST_INSERT_HEAD(&conf->iface_list, iface, entry);
523
524			memcpy(&ifacedefs, defs, sizeof(ifacedefs));
525			defs = &ifacedefs;
526		} interface_block {
527			iface->hello_holdtime = defs->lhello_holdtime;
528			iface->hello_interval = defs->lhello_interval;
529			iface = NULL;
530
531			defs = &globaldefs;
532		}
533		;
534
535interface_block	: '{' optnl interfaceopts_l '}'
536		| '{' optnl '}'
537		| /* nothing */
538		;
539
540interfaceopts_l	: interfaceopts_l iface_defaults nl
541		| iface_defaults optnl
542		;
543
544tneighbor	: TNEIGHBOR STRING	{
545			struct in_addr	 addr;
546
547			if (inet_aton($2, &addr) == 0) {
548				yyerror(
549				    "error parsing neighbor address");
550				free($2);
551				YYERROR;
552			}
553			free($2);
554			if (bad_ip_addr(addr)) {
555				yyerror("invalid neighbor address");
556				YYERROR;
557			}
558
559			tnbr = conf_get_tnbr(addr);
560			if (tnbr == NULL)
561				YYERROR;
562
563			tnbr->flags |= F_TNBR_CONFIGURED;
564			LIST_INSERT_HEAD(&conf->tnbr_list, tnbr, entry);
565
566			memcpy(&tnbrdefs, defs, sizeof(tnbrdefs));
567			defs = &tnbrdefs;
568		} tneighbor_block {
569			tnbr->hello_holdtime = defs->thello_holdtime;
570			tnbr->hello_interval = defs->thello_interval;
571			tnbr = NULL;
572
573			defs = &globaldefs;
574		}
575		;
576
577tneighbor_block	: '{' optnl tneighboropts_l '}'
578		| '{' optnl '}'
579		| /* nothing */
580		;
581
582tneighboropts_l	: tneighboropts_l tnbr_defaults nl
583		| tnbr_defaults optnl
584		;
585
586neighbor	: NEIGHBOR STRING	{
587			struct in_addr	 addr;
588
589			if (inet_aton($2, &addr) == 0) {
590				yyerror(
591				    "error parsing neighbor address");
592				free($2);
593				YYERROR;
594			}
595			free($2);
596			if (bad_ip_addr(addr)) {
597				yyerror("invalid neighbor address");
598				YYERROR;
599			}
600
601			nbrp = conf_get_nbrp(addr);
602			if (nbrp == NULL)
603				YYERROR;
604			LIST_INSERT_HEAD(&conf->nbrp_list, nbrp, entry);
605		} neighbor_block {
606			nbrp = NULL;
607		}
608		;
609
610neighbor_block	: '{' optnl neighboropts_l '}'
611		| '{' optnl '}'
612		| /* nothing */
613		;
614
615neighboropts_l	: neighboropts_l nbr_opts nl
616		| nbr_opts optnl
617		;
618
619l2vpn		: L2VPN STRING TYPE l2vpn_type {
620			l2vpn = conf_get_l2vpn($2);
621			if (l2vpn == NULL)
622				YYERROR;
623			l2vpn->type = $4;
624			LIST_INSERT_HEAD(&conf->l2vpn_list, l2vpn, entry);
625		} l2vpn_block {
626			l2vpn = NULL;
627		}
628		;
629
630l2vpn_block	: '{' optnl l2vpnopts_l '}'
631		| '{' optnl '}'
632		| /* nothing */
633		;
634
635l2vpnopts_l	: l2vpnopts_l l2vpnopts nl
636		| l2vpnopts optnl
637		;
638
639%%
640
641struct keywords {
642	const char	*k_name;
643	int		 k_val;
644};
645
646int
647yyerror(const char *fmt, ...)
648{
649	va_list		 ap;
650	char		*msg;
651
652	file->errors++;
653	va_start(ap, fmt);
654	if (vasprintf(&msg, fmt, ap) == -1)
655		fatalx("yyerror vasprintf");
656	va_end(ap);
657	logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
658	free(msg);
659	return (0);
660}
661
662int
663kw_cmp(const void *k, const void *e)
664{
665	return (strcmp(k, ((const struct keywords *)e)->k_name));
666}
667
668int
669lookup(char *s)
670{
671	/* this has to be sorted always */
672	static const struct keywords keywords[] = {
673		{"bridge",			BRIDGE},
674		{"control-word",		CONTROLWORD},
675		{"ethernet",			ETHERNET},
676		{"ethernet-tagged",		ETHERNETTAGGED},
677		{"fib-update",			FIBUPDATE},
678		{"include",			INCLUDE},
679		{"interface",			INTERFACE},
680		{"keepalive",			KEEPALIVE},
681		{"l2vpn",			L2VPN},
682		{"link-hello-holdtime",		LHELLOHOLDTIME},
683		{"link-hello-interval",		LHELLOINTERVAL},
684		{"mtu",				MTU},
685		{"neighbor",			NEIGHBOR},
686		{"no",				NO},
687		{"password",			PASSWORD},
688		{"pseudowire",			PSEUDOWIRE},
689		{"pw-id",			PWID},
690		{"pw-type",			PWTYPE},
691		{"router-id",			ROUTERID},
692		{"status-tlv",			STATUSTLV},
693		{"targeted-hello-accept",	THELLOACCEPT},
694		{"targeted-hello-holdtime",	THELLOHOLDTIME},
695		{"targeted-hello-interval",	THELLOINTERVAL},
696		{"targeted-neighbor",		TNEIGHBOR},
697		{"type",			TYPE},
698		{"vpls",			VPLS},
699		{"yes",				YES}
700	};
701	const struct keywords	*p;
702
703	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
704	    sizeof(keywords[0]), kw_cmp);
705
706	if (p)
707		return (p->k_val);
708	else
709		return (STRING);
710}
711
712#define MAXPUSHBACK	128
713
714u_char	*parsebuf;
715int	 parseindex;
716u_char	 pushback_buffer[MAXPUSHBACK];
717int	 pushback_index = 0;
718
719int
720lgetc(int quotec)
721{
722	int		c, next;
723
724	if (parsebuf) {
725		/* Read character from the parsebuffer instead of input. */
726		if (parseindex >= 0) {
727			c = parsebuf[parseindex++];
728			if (c != '\0')
729				return (c);
730			parsebuf = NULL;
731		} else
732			parseindex++;
733	}
734
735	if (pushback_index)
736		return (pushback_buffer[--pushback_index]);
737
738	if (quotec) {
739		if ((c = getc(file->stream)) == EOF) {
740			yyerror("reached end of file while parsing "
741			    "quoted string");
742			if (file == topfile || popfile() == EOF)
743				return (EOF);
744			return (quotec);
745		}
746		return (c);
747	}
748
749	while ((c = getc(file->stream)) == '\\') {
750		next = getc(file->stream);
751		if (next != '\n') {
752			c = next;
753			break;
754		}
755		yylval.lineno = file->lineno;
756		file->lineno++;
757	}
758
759	while (c == EOF) {
760		if (file == topfile || popfile() == EOF)
761			return (EOF);
762		c = getc(file->stream);
763	}
764	return (c);
765}
766
767int
768lungetc(int c)
769{
770	if (c == EOF)
771		return (EOF);
772	if (parsebuf) {
773		parseindex--;
774		if (parseindex >= 0)
775			return (c);
776	}
777	if (pushback_index < MAXPUSHBACK-1)
778		return (pushback_buffer[pushback_index++] = c);
779	else
780		return (EOF);
781}
782
783int
784findeol(void)
785{
786	int	c;
787
788	parsebuf = NULL;
789
790	/* skip to either EOF or the first real EOL */
791	while (1) {
792		if (pushback_index)
793			c = pushback_buffer[--pushback_index];
794		else
795			c = lgetc(0);
796		if (c == '\n') {
797			file->lineno++;
798			break;
799		}
800		if (c == EOF)
801			break;
802	}
803	return (ERROR);
804}
805
806int
807yylex(void)
808{
809	u_char	 buf[8096];
810	u_char	*p, *val;
811	int	 quotec, next, c;
812	int	 token;
813
814top:
815	p = buf;
816	while ((c = lgetc(0)) == ' ' || c == '\t')
817		; /* nothing */
818
819	yylval.lineno = file->lineno;
820	if (c == '#')
821		while ((c = lgetc(0)) != '\n' && c != EOF)
822			; /* nothing */
823	if (c == '$' && parsebuf == NULL) {
824		while (1) {
825			if ((c = lgetc(0)) == EOF)
826				return (0);
827
828			if (p + 1 >= buf + sizeof(buf) - 1) {
829				yyerror("string too long");
830				return (findeol());
831			}
832			if (isalnum(c) || c == '_') {
833				*p++ = c;
834				continue;
835			}
836			*p = '\0';
837			lungetc(c);
838			break;
839		}
840		val = symget(buf);
841		if (val == NULL) {
842			yyerror("macro '%s' not defined", buf);
843			return (findeol());
844		}
845		parsebuf = val;
846		parseindex = 0;
847		goto top;
848	}
849
850	switch (c) {
851	case '\'':
852	case '"':
853		quotec = c;
854		while (1) {
855			if ((c = lgetc(quotec)) == EOF)
856				return (0);
857			if (c == '\n') {
858				file->lineno++;
859				continue;
860			} else if (c == '\\') {
861				if ((next = lgetc(quotec)) == EOF)
862					return (0);
863				if (next == quotec || c == ' ' || c == '\t')
864					c = next;
865				else if (next == '\n') {
866					file->lineno++;
867					continue;
868				} else
869					lungetc(next);
870			} else if (c == quotec) {
871				*p = '\0';
872				break;
873			} else if (c == '\0') {
874				yyerror("syntax error");
875				return (findeol());
876			}
877			if (p + 1 >= buf + sizeof(buf) - 1) {
878				yyerror("string too long");
879				return (findeol());
880			}
881			*p++ = c;
882		}
883		yylval.v.string = strdup(buf);
884		if (yylval.v.string == NULL)
885			err(1, "yylex: strdup");
886		return (STRING);
887	}
888
889#define allowed_to_end_number(x) \
890	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
891
892	if (c == '-' || isdigit(c)) {
893		do {
894			*p++ = c;
895			if ((unsigned)(p-buf) >= sizeof(buf)) {
896				yyerror("string too long");
897				return (findeol());
898			}
899		} while ((c = lgetc(0)) != EOF && isdigit(c));
900		lungetc(c);
901		if (p == buf + 1 && buf[0] == '-')
902			goto nodigits;
903		if (c == EOF || allowed_to_end_number(c)) {
904			const char *errstr = NULL;
905
906			*p = '\0';
907			yylval.v.number = strtonum(buf, LLONG_MIN,
908			    LLONG_MAX, &errstr);
909			if (errstr) {
910				yyerror("\"%s\" invalid number: %s",
911				    buf, errstr);
912				return (findeol());
913			}
914			return (NUMBER);
915		} else {
916nodigits:
917			while (p > buf + 1)
918				lungetc(*--p);
919			c = *--p;
920			if (c == '-')
921				return (c);
922		}
923	}
924
925#define allowed_in_string(x) \
926	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
927	x != '{' && x != '}' && \
928	x != '!' && x != '=' && x != '#' && \
929	x != ','))
930
931	if (isalnum(c) || c == ':' || c == '_') {
932		do {
933			*p++ = c;
934			if ((unsigned)(p-buf) >= sizeof(buf)) {
935				yyerror("string too long");
936				return (findeol());
937			}
938		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
939		lungetc(c);
940		*p = '\0';
941		if ((token = lookup(buf)) == STRING)
942			if ((yylval.v.string = strdup(buf)) == NULL)
943				err(1, "yylex: strdup");
944		return (token);
945	}
946	if (c == '\n') {
947		yylval.lineno = file->lineno;
948		file->lineno++;
949	}
950	if (c == EOF)
951		return (0);
952	return (c);
953}
954
955int
956check_file_secrecy(int fd, const char *fname)
957{
958	struct stat	st;
959
960	if (fstat(fd, &st)) {
961		log_warn("cannot stat %s", fname);
962		return (-1);
963	}
964	if (st.st_uid != 0 && st.st_uid != getuid()) {
965		log_warnx("%s: owner not root or current user", fname);
966		return (-1);
967	}
968	if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) {
969		log_warnx("%s: group writable or world read/writable", fname);
970		return (-1);
971	}
972	return (0);
973}
974
975struct file *
976pushfile(const char *name, int secret)
977{
978	struct file	*nfile;
979
980	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
981		log_warn("malloc");
982		return (NULL);
983	}
984	if ((nfile->name = strdup(name)) == NULL) {
985		log_warn("strdup");
986		free(nfile);
987		return (NULL);
988	}
989	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
990		log_warn("%s", nfile->name);
991		free(nfile->name);
992		free(nfile);
993		return (NULL);
994	} else if (secret &&
995	    check_file_secrecy(fileno(nfile->stream), nfile->name)) {
996		fclose(nfile->stream);
997		free(nfile->name);
998		free(nfile);
999		return (NULL);
1000	}
1001	nfile->lineno = 1;
1002	TAILQ_INSERT_TAIL(&files, nfile, entry);
1003	return (nfile);
1004}
1005
1006int
1007popfile(void)
1008{
1009	struct file	*prev;
1010
1011	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
1012		prev->errors += file->errors;
1013
1014	TAILQ_REMOVE(&files, file, entry);
1015	fclose(file->stream);
1016	free(file->name);
1017	free(file);
1018	file = prev;
1019	return (file ? 0 : EOF);
1020}
1021
1022struct ldpd_conf *
1023parse_config(char *filename, int opts)
1024{
1025	struct sym	*sym, *next;
1026
1027	if ((conf = calloc(1, sizeof(struct ldpd_conf))) == NULL)
1028		fatal("parse_config");
1029	conf->opts = opts;
1030	conf->keepalive = DEFAULT_KEEPALIVE;
1031
1032	bzero(&globaldefs, sizeof(globaldefs));
1033	defs = &globaldefs;
1034	defs->lhello_holdtime = LINK_DFLT_HOLDTIME;
1035	defs->lhello_interval = DEFAULT_HELLO_INTERVAL;
1036	defs->thello_holdtime = TARGETED_DFLT_HOLDTIME;
1037	defs->thello_interval = DEFAULT_HELLO_INTERVAL;
1038	conf->thello_holdtime = TARGETED_DFLT_HOLDTIME;
1039	conf->thello_interval = DEFAULT_HELLO_INTERVAL;
1040	defs->pwflags |= F_PW_STATUSTLV_CONF;
1041	defs->pwflags |= F_PW_STATUSTLV;
1042	defs->pwflags |= F_PW_CONTROLWORD_CONF;
1043	defs->pwflags |= F_PW_CONTROLWORD;
1044
1045	if ((file = pushfile(filename, !(conf->opts & LDPD_OPT_NOACTION))) == NULL) {
1046		free(conf);
1047		return (NULL);
1048	}
1049	topfile = file;
1050
1051	LIST_INIT(&conf->iface_list);
1052	LIST_INIT(&conf->addr_list);
1053	LIST_INIT(&conf->tnbr_list);
1054	LIST_INIT(&conf->nbrp_list);
1055	LIST_INIT(&conf->l2vpn_list);
1056
1057	yyparse();
1058	errors = file->errors;
1059	popfile();
1060
1061	/* Free macros and check which have not been used. */
1062	for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
1063		next = TAILQ_NEXT(sym, entry);
1064		if ((conf->opts & LDPD_OPT_VERBOSE2) && !sym->used)
1065			fprintf(stderr, "warning: macro '%s' not "
1066			    "used\n", sym->nam);
1067		if (!sym->persist) {
1068			free(sym->nam);
1069			free(sym->val);
1070			TAILQ_REMOVE(&symhead, sym, entry);
1071			free(sym);
1072		}
1073	}
1074
1075	/* free global config defaults */
1076	if (errors) {
1077		clear_config(conf);
1078		return (NULL);
1079	}
1080
1081	if (conf->rtr_id.s_addr == 0)
1082		conf->rtr_id.s_addr = get_rtr_id();
1083
1084	return (conf);
1085}
1086
1087int
1088symset(const char *nam, const char *val, int persist)
1089{
1090	struct sym	*sym;
1091
1092	for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
1093	    sym = TAILQ_NEXT(sym, entry))
1094		;	/* nothing */
1095
1096	if (sym != NULL) {
1097		if (sym->persist == 1)
1098			return (0);
1099		else {
1100			free(sym->nam);
1101			free(sym->val);
1102			TAILQ_REMOVE(&symhead, sym, entry);
1103			free(sym);
1104		}
1105	}
1106	if ((sym = calloc(1, sizeof(*sym))) == NULL)
1107		return (-1);
1108
1109	sym->nam = strdup(nam);
1110	if (sym->nam == NULL) {
1111		free(sym);
1112		return (-1);
1113	}
1114	sym->val = strdup(val);
1115	if (sym->val == NULL) {
1116		free(sym->nam);
1117		free(sym);
1118		return (-1);
1119	}
1120	sym->used = 0;
1121	sym->persist = persist;
1122	TAILQ_INSERT_TAIL(&symhead, sym, entry);
1123	return (0);
1124}
1125
1126int
1127cmdline_symset(char *s)
1128{
1129	char	*sym, *val;
1130	int	ret;
1131	size_t	len;
1132
1133	if ((val = strrchr(s, '=')) == NULL)
1134		return (-1);
1135
1136	len = strlen(s) - strlen(val) + 1;
1137	if ((sym = malloc(len)) == NULL)
1138		errx(1, "cmdline_symset: malloc");
1139
1140	strlcpy(sym, s, len);
1141
1142	ret = symset(sym, val + 1, 1);
1143	free(sym);
1144
1145	return (ret);
1146}
1147
1148char *
1149symget(const char *nam)
1150{
1151	struct sym	*sym;
1152
1153	TAILQ_FOREACH(sym, &symhead, entry)
1154		if (strcmp(nam, sym->nam) == 0) {
1155			sym->used = 1;
1156			return (sym->val);
1157		}
1158	return (NULL);
1159}
1160
1161int
1162bad_ip_addr(struct in_addr addr)
1163{
1164	u_int32_t a = ntohl(addr.s_addr);
1165
1166	return (((a >> IN_CLASSA_NSHIFT) == 0)
1167	    || ((a >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
1168	    || IN_MULTICAST(a) || IN_BADCLASS(a));
1169}
1170
1171struct iface *
1172conf_get_if(struct kif *kif)
1173{
1174	struct iface	*i;
1175
1176	LIST_FOREACH(i, &conf->iface_list, entry) {
1177		if (i->ifindex == kif->ifindex) {
1178			yyerror("interface %s already configured",
1179			    kif->ifname);
1180			return (NULL);
1181		}
1182	}
1183
1184	i = if_new(kif);
1185
1186	return (i);
1187}
1188
1189struct tnbr *
1190conf_get_tnbr(struct in_addr addr)
1191{
1192	struct tnbr	*t;
1193
1194	t = tnbr_find(conf, addr);
1195	if (t && (t->flags & F_TNBR_CONFIGURED)) {
1196		yyerror("targeted neighbor %s already configured",
1197		    inet_ntoa(addr));
1198		return (NULL);
1199	}
1200
1201	t = tnbr_new(conf, addr);
1202
1203	return (t);
1204}
1205
1206struct nbr_params *
1207conf_get_nbrp(struct in_addr addr)
1208{
1209	struct nbr_params	*n;
1210
1211	LIST_FOREACH(n, &conf->nbrp_list, entry) {
1212		if (n->addr.s_addr == addr.s_addr) {
1213			yyerror("neighbor %s already configured",
1214			    inet_ntoa(addr));
1215			return (NULL);
1216		}
1217	}
1218
1219	n = nbr_params_new(addr);
1220
1221	return (n);
1222}
1223
1224struct l2vpn *
1225conf_get_l2vpn(char *name)
1226{
1227	struct l2vpn	 *l;
1228
1229	if (l2vpn_find(conf, name)) {
1230		yyerror("l2vpn %s already configured", name);
1231		return (NULL);
1232	}
1233
1234	l = l2vpn_new(name);
1235
1236	return (l);
1237}
1238
1239struct l2vpn_if *
1240conf_get_l2vpn_if(struct l2vpn *l, struct kif *kif)
1241{
1242	struct iface	*i;
1243	struct l2vpn	*ltmp;
1244
1245	LIST_FOREACH(i, &conf->iface_list, entry) {
1246		if (i->ifindex == kif->ifindex) {
1247			yyerror("interface %s already configured",
1248			    kif->ifname);
1249			return (NULL);
1250		}
1251	}
1252
1253	LIST_FOREACH(ltmp, &conf->l2vpn_list, entry)
1254		if (l2vpn_if_find(ltmp, kif->ifindex)) {
1255			yyerror("interface %s is already being "
1256			    "used by l2vpn %s", kif->ifname, ltmp->name);
1257			return (NULL);
1258		}
1259
1260	return (l2vpn_if_new(l, kif));
1261}
1262
1263struct l2vpn_pw *
1264conf_get_l2vpn_pw(struct l2vpn *l, struct kif *kif)
1265{
1266	struct l2vpn	*ltmp;
1267
1268	LIST_FOREACH(ltmp, &conf->l2vpn_list, entry) {
1269		if (l2vpn_pw_find(ltmp, kif->ifindex)) {
1270			yyerror("pseudowire %s is already being "
1271			    "used by l2vpn %s", kif->ifname, ltmp->name);
1272			return (NULL);
1273		}
1274	}
1275
1276	return (l2vpn_pw_new(l, kif));
1277}
1278
1279void
1280clear_config(struct ldpd_conf *xconf)
1281{
1282	struct iface		*i;
1283	struct tnbr		*t;
1284	struct nbr_params	*n;
1285	struct l2vpn		*l;
1286	struct l2vpn_if		*f;
1287	struct l2vpn_pw		*p;
1288
1289	while ((i = LIST_FIRST(&xconf->iface_list)) != NULL) {
1290		LIST_REMOVE(i, entry);
1291		if_del(i);
1292	}
1293
1294	while ((t = LIST_FIRST(&xconf->tnbr_list)) != NULL) {
1295		LIST_REMOVE(t, entry);
1296		tnbr_del(t);
1297	}
1298
1299	while ((n = LIST_FIRST(&xconf->nbrp_list)) != NULL) {
1300		LIST_REMOVE(n, entry);
1301		free(n);
1302	}
1303
1304	while ((l = LIST_FIRST(&xconf->l2vpn_list)) != NULL) {
1305		while ((f = LIST_FIRST(&l->if_list)) != NULL) {
1306			LIST_REMOVE(f, entry);
1307			free(f);
1308		}
1309		while ((p = LIST_FIRST(&l->pw_list)) != NULL) {
1310			LIST_REMOVE(p, entry);
1311			free(p);
1312		}
1313		LIST_REMOVE(l, entry);
1314		free(l);
1315	}
1316
1317	free(xconf);
1318}
1319
1320u_int32_t
1321get_rtr_id(void)
1322{
1323	struct ifaddrs		*ifap, *ifa;
1324	u_int32_t		 ip = 0, cur, localnet;
1325
1326	localnet = htonl(INADDR_LOOPBACK & IN_CLASSA_NET);
1327
1328	if (getifaddrs(&ifap) == -1)
1329		fatal("getifaddrs");
1330
1331	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1332		if (strncmp(ifa->ifa_name, "carp", 4) == 0)
1333			continue;
1334		if (ifa->ifa_addr->sa_family != AF_INET)
1335			continue;
1336		cur = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
1337		if ((cur & localnet) == localnet)	/* skip 127/8 */
1338			continue;
1339		if (ntohl(cur) < ntohl(ip) || ip == 0)
1340			ip = cur;
1341	}
1342	freeifaddrs(ifap);
1343
1344	if (ip == 0)
1345		fatal("router-id is 0.0.0.0");
1346
1347	return (ip);
1348}
1349
1350int
1351host(const char *s, struct in_addr *addr, struct in_addr *mask)
1352{
1353	struct in_addr		 ina;
1354	int			 bits = 32;
1355
1356	bzero(&ina, sizeof(struct in_addr));
1357	if (strrchr(s, '/') != NULL) {
1358		if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) == -1)
1359			return (0);
1360	} else {
1361		if (inet_pton(AF_INET, s, &ina) != 1)
1362			return (0);
1363	}
1364
1365	addr->s_addr = ina.s_addr;
1366	mask->s_addr = prefixlen2mask(bits);
1367
1368	return (1);
1369}
1370