LTO: Disable safety feature.
[dragonfly.git] / usr.sbin / rrenumd / parser.y
blob048a2f6ca0f2d8a9c45b5d99fef7568ea236dcb0
1 /* $KAME: parser.y,v 1.8 2000/11/08 03:03:34 jinmei Exp $ */
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
31 * $FreeBSD: src/usr.sbin/rrenumd/parser.y,v 1.1.2.2 2001/07/03 11:02:10 ume Exp $
32 * $DragonFly: src/usr.sbin/rrenumd/parser.y,v 1.4 2004/02/10 02:59:43 rob Exp $
36 #include <sys/param.h>
37 #include <sys/ioctl.h>
38 #include <sys/socket.h>
39 #include <sys/uio.h>
40 #include <sys/queue.h>
42 #include <net/if.h>
43 #if defined(__DragonFly__)
44 #include <net/if_var.h>
45 #endif /* __DragonFly__ */
47 #include <netinet/in.h>
48 #include <netinet/in_var.h>
49 #include <netinet/icmp6.h>
51 #include <limits.h>
52 #include <netdb.h>
53 #include <string.h>
54 #include <stdio.h>
56 #include "rrenumd.h"
58 struct config_is_set {
59 u_short cis_dest : 1;
60 } cis;
62 struct dst_list *dl_head;
63 struct payload_list *pl_head, ple_cur;
64 u_int retry;
65 char errbuf[LINE_MAX];
67 extern int lineno;
68 extern void yyerror(const char *s);
69 extern int yylex(void);
70 static struct payload_list * pllist_lookup(int seqnum);
71 static void pllist_enqueue(struct payload_list *pl_entry);
73 #define MAX_RETRYNUM 10 /* upper limit of retry in this rrenumd program */
74 #define MAX_SEQNUM 256 /* upper limit of seqnum in this rrenumd program */
75 #define NOSPEC -1
79 %union {
80 u_long num;
81 struct {
82 char *cp;
83 int len;
84 } cs;
85 struct in_addr addr4;
86 struct in6_addr addr6;
87 struct {
88 struct in6_addr addr;
89 u_char plen;
90 } prefix;
91 struct dst_list *dl;
92 struct payload_list *pl;
93 struct sockaddr *sa;
96 %token <num> ADD CHANGE SETGLOBAL
97 %token DEBUG_CMD DEST_CMD RETRY_CMD SEQNUM_CMD
98 %token MATCH_PREFIX_CMD MAXLEN_CMD MINLEN_CMD
99 %token USE_PREFIX_CMD KEEPLEN_CMD
100 %token VLTIME_CMD PLTIME_CMD
101 %token RAF_ONLINK_CMD RAF_AUTO_CMD RAF_DECRVALID_CMD RAF_DECRPREFD_CMD
102 %token <num> DAYS HOURS MINUTES SECONDS INFINITY
103 %token <num> ON OFF
104 %token BCL ECL EOS ERROR
105 %token <cs> NAME HOSTNAME QSTRING DECSTRING
106 %token <addr4> IPV4ADDR
107 %token <addr6> IPV6ADDR
108 %token <num> PREFIXLEN
110 %type <num> retrynum seqnum rrenum_cmd
111 %type <num> prefixlen maxlen minlen keeplen vltime pltime
112 %type <num> lifetime days hours minutes seconds
113 %type <num> decstring
114 %type <num> raf_onlink raf_auto raf_decrvalid raf_decrprefd flag
115 %type <dl> dest_addrs dest_addr sin sin6
116 %type <pl> rrenum_statement
117 %type <cs> ifname
118 %type <prefix> prefixval
121 config:
122 /* empty */
123 | statements
126 statements:
127 statement
128 | statements statement
131 statement:
132 debug_statement
133 | destination_statement
134 | rrenum_statement_without_seqnum
135 | rrenum_statement_with_seqnum
136 | error EOS
138 yyerrok;
140 | EOS
143 debug_statement:
144 DEBUG_CMD flag EOS
146 #ifdef YYDEBUG
147 yydebug = $2;
148 #endif /* YYDEBUG */
152 destination_statement:
153 DEST_CMD dest_addrs retrynum EOS
155 dl_head = $2;
156 retry = $3;
160 dest_addrs:
161 dest_addr
162 | dest_addrs dest_addr
164 $2->dl_next = $1;
165 $$ = $2;
169 dest_addr :
172 with_v4dest = 1;
174 | sin6
176 with_v6dest = 1;
178 | sin6 ifname
180 struct sockaddr_in6 *sin6;
182 sin6 = (struct sockaddr_in6 *)$1->dl_dst;
183 sin6->sin6_scope_id = if_nametoindex($2.cp);
184 with_v6dest = 1;
185 $$ = $1;
187 | HOSTNAME
189 struct sockaddr_storage *ss;
190 struct addrinfo hints, *res;
191 int error;
193 memset(&hints, 0, sizeof(hints));
194 hints.ai_flags = AI_CANONNAME;
195 hints.ai_family = AF_UNSPEC;
196 hints.ai_socktype = SOCK_RAW;
197 hints.ai_protocol = 0;
198 error = getaddrinfo($1.cp, 0, &hints, &res);
199 if (error) {
200 snprintf(errbuf, sizeof(errbuf),
201 "name resolution failed for %s:%s",
202 $1.cp, gai_strerror(error));
203 yyerror(errbuf);
205 ss = (struct sockaddr_storage *)malloc(sizeof(*ss));
206 memset(ss, 0, sizeof(*ss));
207 memcpy(ss, res->ai_addr, res->ai_addr->sa_len);
208 freeaddrinfo(res);
210 $$ = (struct dst_list *)
211 malloc(sizeof(struct dst_list));
212 memset($$, 0, sizeof(struct dst_list));
213 $$->dl_dst = (struct sockaddr *)ss;
217 sin:
218 IPV4ADDR
220 struct sockaddr_in *sin;
222 sin = (struct sockaddr_in *)malloc(sizeof(*sin));
223 memset(sin, 0, sizeof(*sin));
224 sin->sin_len = sizeof(*sin);
225 sin->sin_family = AF_INET;
226 sin->sin_addr = $1;
228 $$ = (struct dst_list *)
229 malloc(sizeof(struct dst_list));
230 memset($$, 0, sizeof(struct dst_list));
231 $$->dl_dst = (struct sockaddr *)sin;
235 sin6:
236 IPV6ADDR
238 struct sockaddr_in6 *sin6;
240 sin6 = (struct sockaddr_in6 *)malloc(sizeof(*sin6));
241 memset(sin6, 0, sizeof(*sin6));
242 sin6->sin6_len = sizeof(*sin6);
243 sin6->sin6_family = AF_INET6;
244 sin6->sin6_addr = $1;
246 $$ = (struct dst_list *)
247 malloc(sizeof(struct dst_list));
248 memset($$, 0, sizeof(struct dst_list));
249 $$->dl_dst = (struct sockaddr *)sin6;
252 ifname:
253 NAME
255 $$.cp = strdup($1.cp);
256 $$.len = $1.len;
258 | QSTRING
260 $1.cp[$1.len - 1] = 0;
261 $$.cp = strdup(&$1.cp[1]);
262 $$.len = $1.len - 2;
266 retrynum:
267 /* empty */
269 $$ = 2;
271 | RETRY_CMD decstring
273 if ($2 > MAX_RETRYNUM)
274 $2 = MAX_RETRYNUM;
275 $$ = $2;
279 rrenum_statement_with_seqnum:
280 SEQNUM_CMD seqnum
282 if (pllist_lookup($2)) {
283 snprintf(errbuf, sizeof(errbuf),
284 "duplicate seqnum %ld specified at %d",
285 $2, lineno);
286 yyerror(errbuf);
289 BCL rrenum_statement EOS ECL EOS
291 $5->pl_irr.rr_seqnum = $2;
292 pllist_enqueue($5);
296 seqnum:
297 /* empty */
299 $$ = 0;
301 | decstring
303 if ($1 > MAX_SEQNUM) {
304 snprintf(errbuf, sizeof(errbuf),
305 "seqnum %ld is illegal for this program. "
306 "should be between 0 and %d",
307 $1, MAX_SEQNUM);
308 yyerror(errbuf);
310 $$ = $1;
314 rrenum_statement_without_seqnum:
315 rrenum_statement EOS
317 if (pllist_lookup(0)) {
318 snprintf(errbuf, sizeof(errbuf),
319 "duplicate seqnum %d specified at %d",
320 0, lineno);
321 yyerror(errbuf);
323 $1->pl_irr.rr_seqnum = 0;
324 pllist_enqueue($1);
328 rrenum_statement:
329 match_prefix_definition use_prefix_definition
331 $$ = (struct payload_list *)
332 malloc(sizeof(struct payload_list));
333 memcpy($$, &ple_cur, sizeof(ple_cur));
337 match_prefix_definition:
338 rrenum_cmd MATCH_PREFIX_CMD prefixval maxlen minlen
340 struct icmp6_router_renum *irr;
341 struct rr_pco_match *rpm;
343 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
344 rpm = (struct rr_pco_match *)(irr + 1);
345 memset(rpm, 0, sizeof(*rpm));
347 rpm->rpm_code = $1;
348 rpm->rpm_prefix = $3.addr;
349 rpm->rpm_matchlen = $3.plen;
350 rpm->rpm_maxlen = $4;
351 rpm->rpm_minlen = $5;
355 rrenum_cmd:
356 /* empty */
358 $$ = RPM_PCO_ADD;
360 | ADD
361 | CHANGE
362 | SETGLOBAL
365 prefixval:
366 IPV6ADDR prefixlen
368 $$.addr = $1;
369 $$.plen = $2;
373 prefixlen:
374 /* empty */
376 $$ = 64;
378 | PREFIXLEN
381 maxlen:
382 /* empty */
384 $$ = 128;
386 | MAXLEN_CMD decstring
388 if ($2 > 128)
389 $2 = 128;
390 $$ = $2;
394 minlen:
395 /* empty */
397 $$ = 0;
399 | MINLEN_CMD decstring
401 if ($2 > 128)
402 $2 = 128;
403 $$ = $2;
407 use_prefix_definition:
408 /* empty */
410 struct icmp6_router_renum *irr;
411 struct rr_pco_match *rpm;
412 struct rr_pco_use *rpu;
414 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
415 rpm = (struct rr_pco_match *)(irr + 1);
416 rpu = (struct rr_pco_use *)(rpm + 1);
417 memset(rpu, 0, sizeof(*rpu));
419 | USE_PREFIX_CMD prefixval keeplen use_prefix_values
421 struct icmp6_router_renum *irr;
422 struct rr_pco_match *rpm;
423 struct rr_pco_use *rpu;
425 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
426 rpm = (struct rr_pco_match *)(irr + 1);
427 rpu = (struct rr_pco_use *)(rpm + 1);
429 rpu->rpu_prefix = $2.addr;
430 rpu->rpu_uselen = $2.plen;
431 rpu->rpu_keeplen = $3;
435 use_prefix_values:
436 /* empty */
438 struct icmp6_router_renum *irr;
439 struct rr_pco_match *rpm;
440 struct rr_pco_use *rpu;
442 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
443 rpm = (struct rr_pco_match *)(irr + 1);
444 rpu = (struct rr_pco_use *)(rpm + 1);
445 memset(rpu, 0, sizeof(*rpu));
447 rpu->rpu_vltime = htonl(DEF_VLTIME);
448 rpu->rpu_pltime = htonl(DEF_PLTIME);
449 rpu->rpu_ramask = 0;
450 rpu->rpu_flags = 0;
452 | BCL vltime pltime raf_onlink raf_auto raf_decrvalid raf_decrprefd ECL
454 struct icmp6_router_renum *irr;
455 struct rr_pco_match *rpm;
456 struct rr_pco_use *rpu;
458 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
459 rpm = (struct rr_pco_match *)(irr + 1);
460 rpu = (struct rr_pco_use *)(rpm + 1);
461 memset(rpu, 0, sizeof(*rpu));
463 rpu->rpu_vltime = $2;
464 rpu->rpu_pltime = $3;
465 if ($4 == NOSPEC) {
466 rpu->rpu_ramask &=
467 ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
468 } else {
469 rpu->rpu_ramask |=
470 ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
471 if ($4 == ON) {
472 rpu->rpu_raflags |=
473 ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
474 } else {
475 rpu->rpu_raflags &=
476 ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
479 if ($5 == NOSPEC) {
480 rpu->rpu_ramask &=
481 ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
482 } else {
483 rpu->rpu_ramask |=
484 ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
485 if ($5 == ON) {
486 rpu->rpu_raflags |=
487 ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
488 } else {
489 rpu->rpu_raflags &=
490 ~ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
493 rpu->rpu_flags = 0;
494 if ($6 == ON) {
495 rpu->rpu_flags |=
496 ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME;
498 if ($7 == ON) {
499 rpu->rpu_flags |=
500 ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME;
505 keeplen:
506 /* empty */
508 $$ = 0;
510 | KEEPLEN_CMD decstring
512 if ($2 > 128)
513 $2 = 128;
514 $$ = $2;
519 vltime:
520 /* empty */
522 $$ = htonl(DEF_VLTIME);
524 | VLTIME_CMD lifetime
526 $$ = htonl($2);
530 pltime:
531 /* empty */
533 $$ = htonl(DEF_PLTIME);
535 | PLTIME_CMD lifetime
537 $$ = htonl($2);
540 raf_onlink:
541 /* empty */
543 $$ = NOSPEC;
545 | RAF_ONLINK_CMD flag
547 $$ = $2;
551 raf_auto:
552 /* empty */
554 $$ = NOSPEC;
556 | RAF_AUTO_CMD flag
558 $$ = $2;
562 raf_decrvalid:
563 /* empty */
565 $$ = NOSPEC;
567 | RAF_DECRVALID_CMD flag
569 $$ = $2;
573 raf_decrprefd:
574 /* empty */
576 $$ = NOSPEC;
578 | RAF_DECRPREFD_CMD flag
580 $$ = $2;
584 flag:
585 ON { $$ = ON; }
586 | OFF { $$ = OFF; }
589 lifetime:
590 decstring
591 | INFINITY
593 $$ = 0xffffffff;
595 | days hours minutes seconds
597 int d, h, m, s;
599 d = $1 * 24 * 60 * 60;
600 h = $2 * 60 * 60;
601 m = $3 * 60;
602 s = $4;
603 $$ = d + h + m + s;
607 days:
608 /* empty */
610 $$ = 0;
612 | DAYS
615 hours:
616 /* empty */
618 $$ = 0;
620 | HOURS
623 minutes:
624 /* empty */
626 $$ = 0;
628 | MINUTES
631 seconds:
632 /* empty */
634 $$ = 0;
636 | SECONDS
639 decstring:
640 DECSTRING
642 int dval;
644 dval = atoi($1.cp);
645 $$ = dval;
651 static struct payload_list *
652 pllist_lookup(int seqnum)
654 struct payload_list *pl;
655 for (pl = pl_head; pl && pl->pl_irr.rr_seqnum != seqnum;
656 pl = pl->pl_next)
657 continue;
658 return (pl);
661 static void
662 pllist_enqueue(struct payload_list *pl_entry)
664 struct payload_list *pl, *pl_last;
666 pl_last = NULL;
667 for (pl = pl_head;
668 pl && pl->pl_irr.rr_seqnum < pl_entry->pl_irr.rr_seqnum;
669 pl_last = pl, pl = pl->pl_next)
670 continue;
671 if (pl_last)
672 pl_last->pl_next = pl_entry;
673 else
674 pl_head = pl_entry;
676 return;