2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include <sys/param.h>
34 #include <sys/ioctl.h>
35 #include <sys/socket.h>
39 #include <net/if_var.h>
41 #include <netinet/in.h>
42 #include <netinet/in_var.h>
43 #include <netinet/icmp6.h>
50 struct config_is_set {
54 struct dst_list *dl_head;
55 struct payload_list *pl_head, ple_cur;
57 char errbuf[LINE_MAX];
60 extern void yyerror __P((const char *s));
61 static struct payload_list * pllist_lookup __P((int seqnum));
62 static void pllist_enqueue __P((struct payload_list *pl_entry));
64 #define MAX_RETRYNUM 10 /* upper limit of retry in this rrenumd program */
65 #define MAX_SEQNUM 256 /* upper limit of seqnum in this rrenumd program */
77 struct in6_addr addr6;
83 struct payload_list *pl;
87 %token <num> ADD CHANGE SETGLOBAL
88 %token DEBUG_CMD DEST_CMD RETRY_CMD SEQNUM_CMD
89 %token MATCH_PREFIX_CMD MAXLEN_CMD MINLEN_CMD
90 %token USE_PREFIX_CMD KEEPLEN_CMD
91 %token VLTIME_CMD PLTIME_CMD
92 %token RAF_ONLINK_CMD RAF_AUTO_CMD RAF_DECRVALID_CMD RAF_DECRPREFD_CMD
93 %token <num> DAYS HOURS MINUTES SECONDS INFINITY
95 %token BCL ECL EOS ERROR
96 %token <cs> NAME HOSTNAME QSTRING DECSTRING
97 %token <addr4> IPV4ADDR
98 %token <addr6> IPV6ADDR
99 %token <num> PREFIXLEN
101 %type <num> retrynum seqnum rrenum_cmd
102 %type <num> prefixlen maxlen minlen keeplen vltime pltime
103 %type <num> lifetime days hours minutes seconds
104 %type <num> decstring
105 %type <num> raf_onlink raf_auto raf_decrvalid raf_decrprefd flag
106 %type <dl> dest_addrs dest_addr sin6
107 %type <pl> rrenum_statement
109 %type <prefix> prefixval
119 | statements statement
124 | destination_statement
125 | rrenum_statement_without_seqnum
126 | rrenum_statement_with_seqnum
143 destination_statement:
144 DEST_CMD dest_addrs retrynum EOS
153 | dest_addrs dest_addr
167 struct sockaddr_in6 *sin6;
169 sin6 = (struct sockaddr_in6 *)$1->dl_dst;
170 sin6->sin6_scope_id = if_nametoindex($2.cp);
176 struct sockaddr_storage *ss;
177 struct addrinfo hints, *res;
180 memset(&hints, 0, sizeof(hints));
181 hints.ai_flags = AI_CANONNAME;
182 hints.ai_family = AF_INET6;
183 hints.ai_socktype = SOCK_RAW;
184 hints.ai_protocol = 0;
185 error = getaddrinfo($1.cp, 0, &hints, &res);
187 sprintf(errbuf, "name resolution failed for %s"
188 ":%s", $1, gai_strerror(error));
191 ss = (struct sockaddr_storage *)malloc(sizeof(*ss));
192 memset(ss, 0, sizeof(*ss));
193 memcpy(ss, res->ai_addr, res->ai_addr->sa_len);
196 $$ = (struct dst_list *)
197 malloc(sizeof(struct dst_list));
198 memset($$, 0, sizeof(struct dst_list));
199 $$->dl_dst = (struct sockaddr *)ss;
206 struct sockaddr_in6 *sin6;
208 sin6 = (struct sockaddr_in6 *)malloc(sizeof(*sin6));
209 memset(sin6, 0, sizeof(*sin6));
210 sin6->sin6_len = sizeof(*sin6);
211 sin6->sin6_family = AF_INET6;
212 sin6->sin6_addr = $1;
214 $$ = (struct dst_list *)
215 malloc(sizeof(struct dst_list));
216 memset($$, 0, sizeof(struct dst_list));
217 $$->dl_dst = (struct sockaddr *)sin6;
223 $$.cp = strdup($1.cp);
228 $1.cp[$1.len - 1] = 0;
229 $$.cp = strdup(&$1.cp[1]);
239 | RETRY_CMD decstring
241 if ($2 > MAX_RETRYNUM)
247 rrenum_statement_with_seqnum:
250 if (pllist_lookup($2)) {
251 sprintf(errbuf, "duplicate seqnum %d specified"
252 " at %d", $2, lineno);
256 BCL rrenum_statement EOS ECL EOS
258 $5->pl_irr.rr_seqnum = $2;
270 if ($1 > MAX_SEQNUM) {
271 sprintf(errbuf, "seqnum %d is illegal for this"
272 " program. should be between 0 and %d",
280 rrenum_statement_without_seqnum:
283 if (pllist_lookup(0)) {
284 sprintf(errbuf, "duplicate seqnum %d specified"
285 " at %d", 0, lineno);
288 $1->pl_irr.rr_seqnum = 0;
294 match_prefix_definition use_prefix_definition
296 $$ = (struct payload_list *)
297 malloc(sizeof(struct payload_list));
298 memcpy($$, &ple_cur, sizeof(ple_cur));
302 match_prefix_definition:
303 rrenum_cmd MATCH_PREFIX_CMD prefixval maxlen minlen
305 struct icmp6_router_renum *irr;
306 struct rr_pco_match *rpm;
308 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
309 rpm = (struct rr_pco_match *)(irr + 1);
310 memset(rpm, 0, sizeof(*rpm));
313 rpm->rpm_prefix = $3.addr;
314 rpm->rpm_matchlen = $3.plen;
315 rpm->rpm_maxlen = $4;
316 rpm->rpm_minlen = $5;
351 | MAXLEN_CMD decstring
364 | MINLEN_CMD decstring
372 use_prefix_definition:
375 struct icmp6_router_renum *irr;
376 struct rr_pco_match *rpm;
377 struct rr_pco_use *rpu;
379 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
380 rpm = (struct rr_pco_match *)(irr + 1);
381 rpu = (struct rr_pco_use *)(rpm + 1);
382 memset(rpu, 0, sizeof(*rpu));
384 | USE_PREFIX_CMD prefixval keeplen use_prefix_values
386 struct icmp6_router_renum *irr;
387 struct rr_pco_match *rpm;
388 struct rr_pco_use *rpu;
390 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
391 rpm = (struct rr_pco_match *)(irr + 1);
392 rpu = (struct rr_pco_use *)(rpm + 1);
394 rpu->rpu_prefix = $2.addr;
395 rpu->rpu_uselen = $2.plen;
396 rpu->rpu_keeplen = $3;
403 struct icmp6_router_renum *irr;
404 struct rr_pco_match *rpm;
405 struct rr_pco_use *rpu;
407 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
408 rpm = (struct rr_pco_match *)(irr + 1);
409 rpu = (struct rr_pco_use *)(rpm + 1);
410 memset(rpu, 0, sizeof(*rpu));
412 rpu->rpu_vltime = DEF_VLTIME;
413 rpu->rpu_pltime = DEF_PLTIME;
417 | BCL vltime pltime raf_onlink raf_auto raf_decrvalid raf_decrprefd ECL
419 struct icmp6_router_renum *irr;
420 struct rr_pco_match *rpm;
421 struct rr_pco_use *rpu;
423 irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
424 rpm = (struct rr_pco_match *)(irr + 1);
425 rpu = (struct rr_pco_use *)(rpm + 1);
426 memset(rpu, 0, sizeof(*rpu));
428 rpu->rpu_vltime = $2;
429 rpu->rpu_pltime = $3;
432 ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
435 ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
438 ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
441 ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
445 ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
448 ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
451 ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
454 ~ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
459 ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME;
462 ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME;
471 | KEEPLEN_CMD decstring
485 | VLTIME_CMD lifetime
496 | PLTIME_CMD lifetime
506 | RAF_ONLINK_CMD flag
528 | RAF_DECRVALID_CMD flag
539 | RAF_DECRPREFD_CMD flag
556 | days hours minutes seconds
560 d = $1 * 24 * 60 * 60;
612 static struct payload_list *
613 pllist_lookup(int seqnum)
615 struct payload_list *pl;
616 for (pl = pl_head; pl && pl->pl_irr.rr_seqnum != seqnum;
623 pllist_enqueue(struct payload_list *pl_entry)
625 struct payload_list *pl, *pl_last;
626 if (pl_head == NULL) {
631 pl && pl->pl_irr.rr_seqnum < pl_entry->pl_irr.rr_seqnum;
632 pl_last = pl, pl = pl->pl_next)
634 pl_last->pl_next = pl_entry;