1 /* $KAME: parser.y,v 1.8 2000/11/08 03:03:34 jinmei Exp $ */
4 * SPDX-License-Identifier: BSD-3-Clause
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include <sys/param.h>
38 #include <sys/ioctl.h>
39 #include <sys/socket.h>
41 #include <sys/queue.h>
45 #include <netinet/in.h>
46 #include <netinet/in_var.h>
47 #include <netinet/icmp6.h>
56 struct config_is_set {
60 struct dst_list *dl_head;
61 struct payload_list *pl_head, ple_cur;
63 char errbuf[LINE_MAX];
66 extern void yyerror(const char *s);
67 extern int yylex(void);
68 static struct payload_list * pllist_lookup(int seqnum);
69 static void pllist_enqueue(struct payload_list *pl_entry);
71 #define MAX_RETRYNUM 10 /* upper limit of retry in this rrenumd program */
72 #define MAX_SEQNUM 256 /* upper limit of seqnum in this rrenumd program */
84 struct in6_addr addr6;
90 struct payload_list *pl;
94 %token <num> ADD CHANGE SETGLOBAL
95 %token DEBUG_CMD DEST_CMD RETRY_CMD SEQNUM_CMD
96 %token MATCH_PREFIX_CMD MAXLEN_CMD MINLEN_CMD
97 %token USE_PREFIX_CMD KEEPLEN_CMD
98 %token VLTIME_CMD PLTIME_CMD
99 %token RAF_ONLINK_CMD RAF_AUTO_CMD RAF_DECRVALID_CMD RAF_DECRPREFD_CMD
100 %token <num> DAYS HOURS MINUTES SECONDS INFINITY
102 %token BCL ECL EOS ERROR
103 %token <cs> NAME HOSTNAME QSTRING DECSTRING
104 %token <addr4> IPV4ADDR
105 %token <addr6> IPV6ADDR
106 %token <num> PREFIXLEN
108 %type <num> retrynum seqnum rrenum_cmd
109 %type <num> prefixlen maxlen minlen keeplen vltime pltime
110 %type <num> lifetime days hours minutes seconds
111 %type <num> decstring
112 %type <num> raf_onlink raf_auto raf_decrvalid raf_decrprefd flag
113 %type <dl> dest_addrs dest_addr sin sin6
114 %type <pl> rrenum_statement
116 %type <prefix> prefixval
126 | statements statement
131 | destination_statement
132 | rrenum_statement_without_seqnum
133 | rrenum_statement_with_seqnum
150 destination_statement:
151 DEST_CMD dest_addrs retrynum EOS
160 | dest_addrs dest_addr
178 struct sockaddr_in6 *sin6;
180 sin6 = (struct sockaddr_in6 *)$1->dl_dst;
181 sin6->sin6_scope_id = if_nametoindex($2.cp);
187 struct sockaddr_storage *ss;
188 struct addrinfo hints, *res;
191 memset(&hints, 0, sizeof(hints));
192 hints.ai_flags = AI_CANONNAME;
193 hints.ai_family = AF_UNSPEC;
194 hints.ai_socktype = SOCK_RAW;
195 hints.ai_protocol = 0;
196 error = getaddrinfo($1.cp, 0, &hints, &res);
198 snprintf(errbuf, sizeof(errbuf),
199 "name resolution failed for %s:%s",
200 $1.cp, gai_strerror(error));
203 ss = (struct sockaddr_storage *)malloc(sizeof(*ss));
204 memset(ss, 0, sizeof(*ss));
205 memcpy(ss, res->ai_addr, res->ai_addr->sa_len);
208 $$ = (struct dst_list *)
209 malloc(sizeof(struct dst_list));
210 memset($$, 0, sizeof(struct dst_list));
211 $$->dl_dst = (struct sockaddr *)ss;
218 struct sockaddr_in *sin;
220 sin = (struct sockaddr_in *)malloc(sizeof(*sin));
221 memset(sin, 0, sizeof(*sin));
222 sin->sin_len = sizeof(*sin);
223 sin->sin_family = AF_INET;
226 $$ = (struct dst_list *)
227 malloc(sizeof(struct dst_list));
228 memset($$, 0, sizeof(struct dst_list));
229 $$->dl_dst = (struct sockaddr *)sin;
236 struct sockaddr_in6 *sin6;
238 sin6 = (struct sockaddr_in6 *)malloc(sizeof(*sin6));
239 memset(sin6, 0, sizeof(*sin6));
240 sin6->sin6_len = sizeof(*sin6);
241 sin6->sin6_family = AF_INET6;
242 sin6->sin6_addr = $1;
244 $$ = (struct dst_list *)
245 malloc(sizeof(struct dst_list));
246 memset($$, 0, sizeof(struct dst_list));
247 $$->dl_dst = (struct sockaddr *)sin6;
253 $$.cp = strdup($1.cp);
258 $1.cp[$1.len - 1] = 0;
259 $$.cp = strdup(&$1.cp[1]);
269 | RETRY_CMD decstring
271 if ($2 > MAX_RETRYNUM)
277 rrenum_statement_with_seqnum:
280 if (pllist_lookup($2)) {
281 snprintf(errbuf, sizeof(errbuf),
282 "duplicate seqnum %ld specified at %d",
287 BCL rrenum_statement EOS ECL EOS
289 $5->pl_irr.rr_seqnum = $2;
301 if ($1 > MAX_SEQNUM) {
302 snprintf(errbuf, sizeof(errbuf),
303 "seqnum %ld is illegal for this program. "
304 "should be between 0 and %d",
312 rrenum_statement_without_seqnum:
315 if (pllist_lookup(0)) {
316 snprintf(errbuf, sizeof(errbuf),
317 "duplicate seqnum %d specified at %d",
321 $1->pl_irr.rr_seqnum = 0;
327 match_prefix_definition use_prefix_definition
329 $$ = (struct payload_list *)
330 malloc(sizeof(struct payload_list));
331 memcpy($$, &ple_cur, sizeof(ple_cur));
335 match_prefix_definition:
336 rrenum_cmd MATCH_PREFIX_CMD prefixval maxlen minlen
338 struct rr_pco_match *rpm;
340 rpm = &ple_cur.pl_rpm;
341 memset(rpm, 0, sizeof(*rpm));
344 rpm->rpm_prefix = $3.addr;
345 rpm->rpm_matchlen = $3.plen;
346 rpm->rpm_maxlen = $4;
347 rpm->rpm_minlen = $5;
382 | MAXLEN_CMD decstring
395 | MINLEN_CMD decstring
403 use_prefix_definition:
406 struct icmp6_router_renum *irr;
407 struct rr_pco_match *rpm;
408 struct rr_pco_use *rpu;
410 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
411 rpm = (struct rr_pco_match *)(irr + 1);
412 rpu = (struct rr_pco_use *)(rpm + 1);
413 memset(rpu, 0, sizeof(*rpu));
415 | USE_PREFIX_CMD prefixval keeplen use_prefix_values
417 struct icmp6_router_renum *irr;
418 struct rr_pco_match *rpm;
419 struct rr_pco_use *rpu;
421 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
422 rpm = (struct rr_pco_match *)(irr + 1);
423 rpu = (struct rr_pco_use *)(rpm + 1);
425 rpu->rpu_prefix = $2.addr;
426 rpu->rpu_uselen = $2.plen;
427 rpu->rpu_keeplen = $3;
434 struct icmp6_router_renum *irr;
435 struct rr_pco_match *rpm;
436 struct rr_pco_use *rpu;
438 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
439 rpm = (struct rr_pco_match *)(irr + 1);
440 rpu = (struct rr_pco_use *)(rpm + 1);
441 memset(rpu, 0, sizeof(*rpu));
443 rpu->rpu_vltime = htonl(DEF_VLTIME);
444 rpu->rpu_pltime = htonl(DEF_PLTIME);
448 | BCL vltime pltime raf_onlink raf_auto raf_decrvalid raf_decrprefd ECL
450 struct icmp6_router_renum *irr;
451 struct rr_pco_match *rpm;
452 struct rr_pco_use *rpu;
454 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
455 rpm = (struct rr_pco_match *)(irr + 1);
456 rpu = (struct rr_pco_use *)(rpm + 1);
457 memset(rpu, 0, sizeof(*rpu));
459 rpu->rpu_vltime = $2;
460 rpu->rpu_pltime = $3;
463 ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
466 ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
469 ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
472 ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
477 ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
480 ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
483 ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
486 ~ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
492 ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME;
496 ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME;
506 | KEEPLEN_CMD decstring
518 $$ = htonl(DEF_VLTIME);
520 | VLTIME_CMD lifetime
529 $$ = htonl(DEF_PLTIME);
531 | PLTIME_CMD lifetime
541 | RAF_ONLINK_CMD flag
563 | RAF_DECRVALID_CMD flag
574 | RAF_DECRPREFD_CMD flag
591 | days hours minutes seconds
595 d = $1 * 24 * 60 * 60;
647 static struct payload_list *
648 pllist_lookup(int seqnum)
650 struct payload_list *pl;
651 for (pl = pl_head; pl && pl->pl_irr.rr_seqnum != seqnum;
658 pllist_enqueue(struct payload_list *pl_entry)
660 struct payload_list *pl, *pl_last;
664 pl && pl->pl_irr.rr_seqnum < pl_entry->pl_irr.rr_seqnum;
665 pl_last = pl, pl = pl->pl_next)
668 pl_last->pl_next = pl_entry;