178064Sume/*	$KAME: parser.y,v 1.8 2000/11/08 03:03:34 jinmei Exp $	*/
262638Skris
355505Sshin/*
455505Sshin * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
555505Sshin * All rights reserved.
655505Sshin *
755505Sshin * Redistribution and use in source and binary forms, with or without
855505Sshin * modification, are permitted provided that the following conditions
955505Sshin * are met:
1055505Sshin * 1. Redistributions of source code must retain the above copyright
1155505Sshin *    notice, this list of conditions and the following disclaimer.
1255505Sshin * 2. Redistributions in binary form must reproduce the above copyright
1355505Sshin *    notice, this list of conditions and the following disclaimer in the
1455505Sshin *    documentation and/or other materials provided with the distribution.
1555505Sshin * 3. Neither the name of the project nor the names of its contributors
1655505Sshin *    may be used to endorse or promote products derived from this software
1755505Sshin *    without specific prior written permission.
1855505Sshin *
1955505Sshin * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
2055505Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2155505Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2255505Sshin * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
2355505Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2455505Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2555505Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2655505Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2755505Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2855505Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2955505Sshin * SUCH DAMAGE.
3055505Sshin *
3155505Sshin * $FreeBSD$
3255505Sshin */
3355505Sshin
3455505Sshin%{
3555505Sshin#include <sys/param.h>
3655505Sshin#include <sys/ioctl.h>
3755505Sshin#include <sys/socket.h>
3855505Sshin#include <sys/uio.h>
3978064Sume#include <sys/queue.h>
4055505Sshin
4155505Sshin#include <net/if.h>
4262638Skris#if defined(__FreeBSD__) && __FreeBSD__ >= 3
4355505Sshin#include <net/if_var.h>
4462638Skris#endif /* __FreeBSD__ >= 3 */
4555505Sshin
4655505Sshin#include <netinet/in.h>
4755505Sshin#include <netinet/in_var.h>
4855505Sshin#include <netinet/icmp6.h>
4955505Sshin
50106054Swollman#include <limits.h>
5155505Sshin#include <netdb.h>
5255505Sshin#include <string.h>
5378064Sume#include <stdio.h>
5455505Sshin
5555505Sshin#include "rrenumd.h"
5655505Sshin
5755505Sshinstruct config_is_set {
5862638Skris	u_short cis_dest : 1;
5955505Sshin} cis;
6055505Sshin
6162638Skrisstruct dst_list *dl_head;
6262638Skrisstruct payload_list *pl_head, ple_cur;
6362638Skrisu_int retry;
6462638Skrischar errbuf[LINE_MAX];
6555505Sshin
6662638Skrisextern int lineno;
67173412Skevloextern void yyerror(const char *s);
68173412Skevloextern int yylex(void);
69173412Skevlostatic struct payload_list * pllist_lookup(int seqnum);
70173412Skevlostatic void pllist_enqueue(struct payload_list *pl_entry);
7155505Sshin
7262638Skris#define MAX_RETRYNUM 10 /* upper limit of retry in this rrenumd program */
7362638Skris#define MAX_SEQNUM 256 /* upper limit of seqnum in this rrenumd program */
7462638Skris#define NOSPEC	-1
7555505Sshin
7655505Sshin%}
7755505Sshin
7855505Sshin%union {
7962638Skris	u_long num;
8055505Sshin	struct {
8162638Skris		char *cp;
8262638Skris		int len;
8355505Sshin	} cs;
8462638Skris	struct in_addr addr4;
8562638Skris	struct in6_addr addr6;
8655505Sshin	struct {
8762638Skris		struct in6_addr addr;
8862638Skris		u_char plen;
8955505Sshin	} prefix;
9062638Skris	struct dst_list *dl;
9162638Skris	struct payload_list *pl;
9262638Skris	struct sockaddr *sa;
9355505Sshin}
9455505Sshin
9555505Sshin%token <num> ADD CHANGE SETGLOBAL
9655505Sshin%token DEBUG_CMD DEST_CMD RETRY_CMD SEQNUM_CMD
9755505Sshin%token MATCH_PREFIX_CMD MAXLEN_CMD MINLEN_CMD
9855505Sshin%token USE_PREFIX_CMD KEEPLEN_CMD
9955505Sshin%token VLTIME_CMD PLTIME_CMD
10055505Sshin%token RAF_ONLINK_CMD RAF_AUTO_CMD RAF_DECRVALID_CMD RAF_DECRPREFD_CMD
10155505Sshin%token <num> DAYS HOURS MINUTES SECONDS INFINITY
10255505Sshin%token <num> ON OFF
10355505Sshin%token BCL ECL EOS ERROR
10455505Sshin%token <cs> NAME HOSTNAME QSTRING DECSTRING
10555505Sshin%token <addr4> IPV4ADDR
10655505Sshin%token <addr6> IPV6ADDR
10755505Sshin%token <num> PREFIXLEN
10855505Sshin
10955505Sshin%type <num> retrynum seqnum rrenum_cmd
11055505Sshin%type <num> prefixlen maxlen minlen keeplen vltime pltime
11155505Sshin%type <num> lifetime days hours minutes seconds
11255505Sshin%type <num> decstring
11355505Sshin%type <num> raf_onlink raf_auto raf_decrvalid raf_decrprefd flag
11462638Skris%type <dl> dest_addrs dest_addr sin sin6
11555505Sshin%type <pl> rrenum_statement
11655505Sshin%type <cs> ifname
11755505Sshin%type <prefix> prefixval
11855505Sshin
11955505Sshin%%
12055505Sshinconfig:
12155505Sshin		/* empty */
12255505Sshin	| 	statements
12355505Sshin	;
12455505Sshin
12555505Sshinstatements:
12655505Sshin		statement
12755505Sshin	| 	statements statement
12855505Sshin	;
12955505Sshin
13055505Sshinstatement:
13155505Sshin		debug_statement
13255505Sshin	|	destination_statement
13355505Sshin	|	rrenum_statement_without_seqnum
13455505Sshin	|	rrenum_statement_with_seqnum
13555505Sshin	|	error EOS
13655505Sshin		{
13755505Sshin			yyerrok;
13855505Sshin		}
13955505Sshin	|	EOS
14055505Sshin	;
14155505Sshin
14255505Sshindebug_statement:
14355505Sshin		DEBUG_CMD flag EOS
14455505Sshin		{
14555505Sshin#ifdef YYDEBUG
14655505Sshin			yydebug = $2;
14755505Sshin#endif /* YYDEBUG */
14855505Sshin		}
14955505Sshin	;
15055505Sshin
15155505Sshindestination_statement:
15255505Sshin		DEST_CMD dest_addrs retrynum EOS
15355505Sshin		{
15455505Sshin			dl_head = $2;
15555505Sshin			retry = $3;
15655505Sshin		}
15755505Sshin	;
15855505Sshin
15955505Sshindest_addrs:
16055505Sshin		dest_addr
16155505Sshin	|	dest_addrs dest_addr
16255505Sshin		{
16355505Sshin			$2->dl_next = $1;
16455505Sshin			$$ = $2;
16555505Sshin		}
16655505Sshin	;
16755505Sshin
16855505Sshindest_addr :
16962638Skris		sin
17055505Sshin		{
17162638Skris			with_v4dest = 1;
17262638Skris		}
17362638Skris	|	sin6
17462638Skris		{
17555505Sshin			with_v6dest = 1;
17655505Sshin		}
17755505Sshin	|	sin6 ifname
17855505Sshin		{
17955505Sshin			struct sockaddr_in6 *sin6;
18055505Sshin
18155505Sshin			sin6 = (struct sockaddr_in6 *)$1->dl_dst;
18255505Sshin			sin6->sin6_scope_id = if_nametoindex($2.cp);
18355505Sshin			with_v6dest = 1;
18455505Sshin			$$ = $1;
18555505Sshin		}
18655505Sshin	|	HOSTNAME
18755505Sshin		{
18855505Sshin			struct sockaddr_storage *ss;
18955505Sshin			struct addrinfo hints, *res;
19055505Sshin			int error;
19155505Sshin
19255505Sshin			memset(&hints, 0, sizeof(hints));
19355505Sshin			hints.ai_flags = AI_CANONNAME;
19462638Skris			hints.ai_family = AF_UNSPEC;
19555505Sshin			hints.ai_socktype = SOCK_RAW;
19655505Sshin			hints.ai_protocol = 0;
19755505Sshin			error = getaddrinfo($1.cp, 0, &hints, &res);
19855505Sshin			if (error) {
19978064Sume				snprintf(errbuf, sizeof(errbuf),
20078064Sume				    "name resolution failed for %s:%s",
20178064Sume				    $1.cp, gai_strerror(error));
20255505Sshin				yyerror(errbuf);
20355505Sshin			}
20455505Sshin			ss = (struct sockaddr_storage *)malloc(sizeof(*ss));
20555505Sshin			memset(ss, 0, sizeof(*ss));
20655505Sshin			memcpy(ss, res->ai_addr, res->ai_addr->sa_len);
20755505Sshin			freeaddrinfo(res);
20855505Sshin
20955505Sshin			$$ = (struct dst_list *)
21055505Sshin			     malloc(sizeof(struct dst_list));
21155505Sshin			memset($$, 0, sizeof(struct dst_list));
21255505Sshin			$$->dl_dst = (struct sockaddr *)ss;
21355505Sshin		}
21455505Sshin	;
21555505Sshin
21662638Skrissin:
21762638Skris		IPV4ADDR
21862638Skris		{
21962638Skris			struct sockaddr_in *sin;
22062638Skris
22162638Skris			sin = (struct sockaddr_in *)malloc(sizeof(*sin));
22262638Skris			memset(sin, 0, sizeof(*sin));
22362638Skris			sin->sin_len = sizeof(*sin);
22462638Skris			sin->sin_family = AF_INET;
22562638Skris			sin->sin_addr = $1;
22662638Skris
22762638Skris			$$ = (struct dst_list *)
22862638Skris			     malloc(sizeof(struct dst_list));
22962638Skris			memset($$, 0, sizeof(struct dst_list));
23062638Skris			$$->dl_dst = (struct sockaddr *)sin;
23162638Skris		}
23262638Skris	;
23362638Skris
23455505Sshinsin6:
23555505Sshin		IPV6ADDR
23655505Sshin		{
23755505Sshin			struct sockaddr_in6 *sin6;
23855505Sshin
23955505Sshin			sin6 = (struct sockaddr_in6 *)malloc(sizeof(*sin6));
24055505Sshin			memset(sin6, 0, sizeof(*sin6));
24155505Sshin			sin6->sin6_len = sizeof(*sin6);
24255505Sshin			sin6->sin6_family = AF_INET6;
24355505Sshin			sin6->sin6_addr = $1;
24455505Sshin
24555505Sshin			$$ = (struct dst_list *)
24655505Sshin			     malloc(sizeof(struct dst_list));
24755505Sshin			memset($$, 0, sizeof(struct dst_list));
24855505Sshin			$$->dl_dst = (struct sockaddr *)sin6;
24955505Sshin		}
25055505Sshin
25155505Sshinifname:
25255505Sshin		NAME
25355505Sshin		{
25455505Sshin			$$.cp = strdup($1.cp);
25555505Sshin			$$.len = $1.len;
25655505Sshin		}
25755505Sshin	|	QSTRING
25855505Sshin		{
25955505Sshin			$1.cp[$1.len - 1] = 0;
26055505Sshin			$$.cp = strdup(&$1.cp[1]);
26155505Sshin			$$.len = $1.len - 2;
26255505Sshin		}
26355505Sshin	;
26455505Sshin
26555505Sshinretrynum:
26655505Sshin		/* empty */
26755505Sshin		{
26855505Sshin			$$ = 2;
26955505Sshin		}
27055505Sshin	|	RETRY_CMD decstring
27155505Sshin		{
27255505Sshin			if ($2 > MAX_RETRYNUM)
27355505Sshin				$2 = MAX_RETRYNUM;
27455505Sshin			$$ = $2;
27555505Sshin		}
27655505Sshin	;
27755505Sshin
27855505Sshinrrenum_statement_with_seqnum:
27955505Sshin		SEQNUM_CMD seqnum
28055505Sshin		{
28155505Sshin			if (pllist_lookup($2)) {
28278064Sume				snprintf(errbuf, sizeof(errbuf),
28378064Sume				    "duplicate seqnum %ld specified at %d",
28478064Sume				    $2, lineno);
28555505Sshin				yyerror(errbuf);
28655505Sshin			}
28755505Sshin		}
28855505Sshin		BCL rrenum_statement EOS ECL EOS
28955505Sshin		{
29055505Sshin			$5->pl_irr.rr_seqnum = $2;
29155505Sshin			pllist_enqueue($5);
29255505Sshin		}
29355505Sshin	;
29455505Sshin
29555505Sshinseqnum:
29655505Sshin		/* empty */
29755505Sshin		{
29855505Sshin			$$ = 0;
29955505Sshin		}
30055505Sshin	|	decstring
30155505Sshin		{
30255505Sshin			if ($1 > MAX_SEQNUM) {
30378064Sume				snprintf(errbuf, sizeof(errbuf),
30478064Sume				    "seqnum %ld is illegal for this  program. "
30578064Sume				    "should be between 0 and %d",
30678064Sume				    $1, MAX_SEQNUM);
30755505Sshin				yyerror(errbuf);
30855505Sshin			}
30955505Sshin			$$ = $1;
31055505Sshin		}
31155505Sshin	;
31255505Sshin
31355505Sshinrrenum_statement_without_seqnum:
31455505Sshin		rrenum_statement EOS
31555505Sshin		{
31655505Sshin			if (pllist_lookup(0)) {
31778064Sume				snprintf(errbuf, sizeof(errbuf),
31878064Sume				    "duplicate seqnum %d specified  at %d",
31978064Sume				    0, lineno);
32055505Sshin				yyerror(errbuf);
32155505Sshin			}
32255505Sshin			$1->pl_irr.rr_seqnum = 0;
32355505Sshin			pllist_enqueue($1);
32455505Sshin		}
32555505Sshin	;
32655505Sshin
32755505Sshinrrenum_statement:
32855505Sshin		match_prefix_definition use_prefix_definition
32955505Sshin		{
33055505Sshin			$$ = (struct payload_list *)
33155505Sshin			     malloc(sizeof(struct payload_list));
33255505Sshin			memcpy($$, &ple_cur, sizeof(ple_cur));
33355505Sshin		}
33455505Sshin	;
33555505Sshin
33655505Sshinmatch_prefix_definition:
33755505Sshin		rrenum_cmd MATCH_PREFIX_CMD prefixval maxlen minlen
33855505Sshin		{
33955505Sshin			struct icmp6_router_renum *irr;
34055505Sshin			struct rr_pco_match *rpm;
34155505Sshin
34255505Sshin			irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
34355505Sshin			rpm = (struct rr_pco_match *)(irr + 1);
34455505Sshin			memset(rpm, 0, sizeof(*rpm));
34555505Sshin
34655505Sshin			rpm->rpm_code = $1;
34755505Sshin			rpm->rpm_prefix = $3.addr;
34855505Sshin			rpm->rpm_matchlen = $3.plen;
34955505Sshin			rpm->rpm_maxlen = $4;
35055505Sshin			rpm->rpm_minlen = $5;
35155505Sshin		}
35255505Sshin	;
35355505Sshin
35455505Sshinrrenum_cmd:
35555505Sshin		/* empty */
35655505Sshin		{
35755505Sshin			$$ = RPM_PCO_ADD;
35855505Sshin		}
35955505Sshin	|	ADD
36055505Sshin	|	CHANGE
36155505Sshin	|	SETGLOBAL
36255505Sshin	;
36355505Sshin
36455505Sshinprefixval:
36555505Sshin		IPV6ADDR prefixlen
36655505Sshin		{
36755505Sshin			$$.addr = $1;
36855505Sshin			$$.plen = $2;
36955505Sshin		}
37055505Sshin	;
37155505Sshin
37255505Sshinprefixlen:
37355505Sshin		/* empty */
37455505Sshin		{
37555505Sshin			$$ = 64;
37655505Sshin		}
37755505Sshin	|	PREFIXLEN
37855505Sshin	;
37955505Sshin
38055505Sshinmaxlen:
38155505Sshin		/* empty */
38255505Sshin		{
38355505Sshin			$$ = 128;
38455505Sshin		}
38555505Sshin	|	MAXLEN_CMD decstring
38655505Sshin		{
38755505Sshin			if ($2 > 128)
38855505Sshin				$2 = 128;
38955505Sshin			$$ = $2;
39055505Sshin		}
39155505Sshin	;
39255505Sshin
39355505Sshinminlen:
39455505Sshin		/* empty */
39555505Sshin		{
39655505Sshin			$$ = 0;
39755505Sshin		}
39855505Sshin	|	MINLEN_CMD decstring
39955505Sshin		{
40055505Sshin			if ($2 > 128)
40155505Sshin				$2 = 128;
40255505Sshin			$$ = $2;
40355505Sshin		}
40455505Sshin	;
40555505Sshin
40655505Sshinuse_prefix_definition:
40755505Sshin		/* empty */
40855505Sshin		{
40955505Sshin			struct icmp6_router_renum *irr;
41055505Sshin			struct rr_pco_match *rpm;
41155505Sshin			struct rr_pco_use *rpu;
41255505Sshin
41355505Sshin			irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
41455505Sshin			rpm = (struct rr_pco_match *)(irr + 1);
41555505Sshin			rpu = (struct rr_pco_use *)(rpm + 1);
41655505Sshin			memset(rpu, 0, sizeof(*rpu));
41755505Sshin		}
41855505Sshin	|	USE_PREFIX_CMD prefixval keeplen use_prefix_values
41955505Sshin		{
42055505Sshin			struct icmp6_router_renum *irr;
42155505Sshin			struct rr_pco_match *rpm;
42255505Sshin			struct rr_pco_use *rpu;
42355505Sshin
42455505Sshin			irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
42555505Sshin			rpm = (struct rr_pco_match *)(irr + 1);
42655505Sshin			rpu = (struct rr_pco_use *)(rpm + 1);
42755505Sshin
42855505Sshin			rpu->rpu_prefix = $2.addr;
42955505Sshin			rpu->rpu_uselen = $2.plen;
43055505Sshin			rpu->rpu_keeplen = $3;
43155505Sshin		}
43255505Sshin	;
43355505Sshin
43455505Sshinuse_prefix_values:
43555505Sshin		/* empty */
43655505Sshin		{
43755505Sshin			struct icmp6_router_renum *irr;
43855505Sshin			struct rr_pco_match *rpm;
43955505Sshin			struct rr_pco_use *rpu;
44055505Sshin
44155505Sshin			irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
44255505Sshin			rpm = (struct rr_pco_match *)(irr + 1);
44355505Sshin			rpu = (struct rr_pco_use *)(rpm + 1);
44455505Sshin			memset(rpu, 0, sizeof(*rpu));
44555505Sshin
44678064Sume			rpu->rpu_vltime = htonl(DEF_VLTIME);
44778064Sume			rpu->rpu_pltime = htonl(DEF_PLTIME);
44855505Sshin			rpu->rpu_ramask = 0;
44955505Sshin			rpu->rpu_flags = 0;
45055505Sshin		}
45155505Sshin	|	BCL vltime pltime raf_onlink raf_auto raf_decrvalid raf_decrprefd ECL
45255505Sshin		{
45355505Sshin			struct icmp6_router_renum *irr;
45455505Sshin			struct rr_pco_match *rpm;
45555505Sshin			struct rr_pco_use *rpu;
45655505Sshin
45755505Sshin			irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
45855505Sshin			rpm = (struct rr_pco_match *)(irr + 1);
45955505Sshin			rpu = (struct rr_pco_use *)(rpm + 1);
46055505Sshin			memset(rpu, 0, sizeof(*rpu));
46155505Sshin
46255505Sshin			rpu->rpu_vltime = $2;
46355505Sshin			rpu->rpu_pltime = $3;
46462638Skris			if ($4 == NOSPEC) {
46555505Sshin				rpu->rpu_ramask &=
46662638Skris				    ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
46762638Skris			} else {
46855505Sshin				rpu->rpu_ramask |=
46962638Skris				    ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
47062638Skris				if ($4 == ON) {
47155505Sshin					rpu->rpu_raflags |=
47262638Skris					    ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
47362638Skris				} else {
47455505Sshin					rpu->rpu_raflags &=
47562638Skris					    ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
47662638Skris				}
47755505Sshin			}
47862638Skris			if ($5 == NOSPEC) {
47955505Sshin				rpu->rpu_ramask &=
48062638Skris				    ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
48162638Skris			} else {
48255505Sshin				rpu->rpu_ramask |=
48362638Skris				    ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
48462638Skris				if ($5 == ON) {
48555505Sshin					rpu->rpu_raflags |=
48662638Skris					    ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
48762638Skris				} else {
48855505Sshin					rpu->rpu_raflags &=
48962638Skris					    ~ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
49062638Skris				}
49155505Sshin			}
49255505Sshin			rpu->rpu_flags = 0;
49362638Skris			if ($6 == ON) {
49455505Sshin				rpu->rpu_flags |=
49562638Skris				    ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME;
49662638Skris			}
49762638Skris			if ($7 == ON) {
49855505Sshin				rpu->rpu_flags |=
49962638Skris				    ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME;
50062638Skris			}
50155505Sshin		}
50255505Sshin	;
50355505Sshin
50455505Sshinkeeplen:
50555505Sshin		/* empty */
50655505Sshin		{
50755505Sshin			$$ = 0;
50855505Sshin		}
50955505Sshin	|	KEEPLEN_CMD decstring
51055505Sshin		{
51155505Sshin			if ($2 > 128)
51255505Sshin				$2 = 128;
51355505Sshin			$$ = $2;
51455505Sshin		}
51555505Sshin	;
51655505Sshin
51755505Sshin
51855505Sshinvltime:
51955505Sshin		/* empty */
52055505Sshin		{
52178064Sume			$$ = htonl(DEF_VLTIME);
52255505Sshin		}
52355505Sshin	|	VLTIME_CMD lifetime
52455505Sshin		{
52555505Sshin			$$ = htonl($2);
52655505Sshin		}
52755505Sshin	;
52855505Sshin
52955505Sshinpltime:
53055505Sshin		/* empty */
53155505Sshin		{
53278064Sume			$$ = htonl(DEF_PLTIME);
53355505Sshin		}
53455505Sshin	|	PLTIME_CMD lifetime
53555505Sshin		{
53655505Sshin			$$ = htonl($2);
53755505Sshin		}
53855505Sshin
53955505Sshinraf_onlink:
54055505Sshin		/* empty */
54155505Sshin		{
54255505Sshin			$$ = NOSPEC;
54355505Sshin		}
54455505Sshin	|	RAF_ONLINK_CMD flag
54555505Sshin		{
54655505Sshin			$$ = $2;
54755505Sshin		}
54855505Sshin	;
54955505Sshin
55055505Sshinraf_auto:
55155505Sshin		/* empty */
55255505Sshin		{
55355505Sshin			$$ = NOSPEC;
55455505Sshin		}
55555505Sshin	|	RAF_AUTO_CMD flag
55655505Sshin		{
55755505Sshin			$$ = $2;
55855505Sshin		}
55955505Sshin	;
56055505Sshin
56155505Sshinraf_decrvalid:
56255505Sshin		/* empty */
56355505Sshin		{
56455505Sshin			$$ = NOSPEC;
56555505Sshin		}
56655505Sshin	|	RAF_DECRVALID_CMD flag
56755505Sshin		{
56855505Sshin			$$ = $2;
56955505Sshin		}
57055505Sshin	;
57155505Sshin
57255505Sshinraf_decrprefd:
57355505Sshin		/* empty */
57455505Sshin		{
57555505Sshin			$$ = NOSPEC;
57655505Sshin		}
57755505Sshin	|	RAF_DECRPREFD_CMD flag
57855505Sshin		{
57955505Sshin			$$ = $2;
58055505Sshin		}
58155505Sshin	;
58255505Sshin
58355505Sshinflag:
58478064Sume		ON { $$ = ON; }
58578064Sume	|	OFF { $$ = OFF; }
58655505Sshin	;
58755505Sshin
58855505Sshinlifetime:
58955505Sshin		decstring
59055505Sshin	|	INFINITY
59155505Sshin		{
59255505Sshin			$$ = 0xffffffff;
59355505Sshin		}
59455505Sshin	|	days hours minutes seconds
59555505Sshin		{
59655505Sshin			int d, h, m, s;
59755505Sshin
59855505Sshin			d = $1 * 24 * 60 * 60;
59955505Sshin			h = $2 * 60 * 60;
60055505Sshin			m = $3 * 60;
60155505Sshin			s = $4;
60255505Sshin			$$ = d + h + m + s;
60355505Sshin		}
60455505Sshin	;
60555505Sshin
60655505Sshindays:
60755505Sshin		/* empty */
60855505Sshin		{
60955505Sshin			$$ = 0;
61055505Sshin		}
61155505Sshin	|	DAYS
61255505Sshin	;
61355505Sshin
61455505Sshinhours:
61555505Sshin		/* empty */
61655505Sshin		{
61755505Sshin			$$ = 0;
61855505Sshin		}
61955505Sshin	|	HOURS
62055505Sshin	;
62155505Sshin
62255505Sshinminutes:
62355505Sshin		/* empty */
62455505Sshin		{
62555505Sshin			$$ = 0;
62655505Sshin		}
62755505Sshin	|	MINUTES
62855505Sshin	;
62955505Sshin
63055505Sshinseconds:
63155505Sshin		/* empty */
63255505Sshin		{
63355505Sshin			$$ = 0;
63455505Sshin		}
63555505Sshin	|	SECONDS
63655505Sshin	;
63755505Sshin
63855505Sshindecstring:
63955505Sshin		DECSTRING
64055505Sshin		{
64155505Sshin			int dval;
64255505Sshin
64355505Sshin			dval = atoi($1.cp);
64455505Sshin			$$ = dval;
64555505Sshin		}
64655505Sshin	;
64755505Sshin
64855505Sshin%%
64955505Sshin
65055505Sshinstatic struct payload_list *
65155505Sshinpllist_lookup(int seqnum)
65255505Sshin{
65355505Sshin	struct payload_list *pl;
65455505Sshin	for (pl = pl_head; pl && pl->pl_irr.rr_seqnum != seqnum;
65555505Sshin	     pl = pl->pl_next)
65655505Sshin		continue;
65755505Sshin	return (pl);
65855505Sshin}
65955505Sshin
66055505Sshinstatic void
66155505Sshinpllist_enqueue(struct payload_list *pl_entry)
66255505Sshin{
66355505Sshin	struct payload_list *pl, *pl_last;
66478064Sume
66578064Sume	pl_last = NULL;
66655505Sshin	for (pl = pl_head;
66755505Sshin	     pl && pl->pl_irr.rr_seqnum < pl_entry->pl_irr.rr_seqnum;
66855505Sshin	     pl_last = pl, pl = pl->pl_next)
66955505Sshin		continue;
67078064Sume	if (pl_last)
67178064Sume		pl_last->pl_next = pl_entry;
67278064Sume	else
67378064Sume		pl_head = pl_entry;
67455505Sshin
67555505Sshin	return;
67655505Sshin}
677