]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/rrenumd/parser.y
This commit was generated by cvs2svn to compensate for changes in r56944,
[FreeBSD/FreeBSD.git] / usr.sbin / rrenumd / parser.y
1 /*
2  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
16  *
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
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31
32 %{
33 #include <sys/param.h>
34 #include <sys/ioctl.h>
35 #include <sys/socket.h>
36 #include <sys/uio.h>
37
38 #include <net/if.h>
39 #include <net/if_var.h>
40
41 #include <netinet/in.h>
42 #include <netinet/in_var.h>
43 #include <netinet/icmp6.h>
44
45 #include <netdb.h>
46 #include <string.h>
47
48 #include "rrenumd.h"
49
50 struct config_is_set {
51         u_short cis_dest : 1;
52 } cis;
53
54 struct  dst_list *dl_head;
55 struct  payload_list *pl_head, ple_cur;
56 u_int   retry;
57 char    errbuf[LINE_MAX];
58
59 extern int      lineno;
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));
63
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 */
66 #define NOSPEC  -1
67
68 %}
69
70 %union {
71         u_long  num;
72         struct {
73                 char    *cp;
74                 int     len;
75         } cs;
76         struct  in_addr addr4;
77         struct  in6_addr addr6;
78         struct {
79                 struct  in6_addr addr;
80                 u_char  plen;
81         } prefix;
82         struct  dst_list *dl;
83         struct  payload_list *pl;
84         struct  sockaddr *sa;
85 }
86
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
94 %token <num> ON OFF
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
100
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
108 %type <cs> ifname
109 %type <prefix> prefixval
110
111 %%
112 config:
113                 /* empty */
114         |       statements
115         ;
116
117 statements:
118                 statement
119         |       statements statement
120         ;
121
122 statement:
123                 debug_statement
124         |       destination_statement
125         |       rrenum_statement_without_seqnum
126         |       rrenum_statement_with_seqnum
127         |       error EOS
128                 {
129                         yyerrok;
130                 }
131         |       EOS
132         ;
133
134 debug_statement:
135                 DEBUG_CMD flag EOS
136                 {
137 #ifdef YYDEBUG
138                         yydebug = $2;
139 #endif /* YYDEBUG */
140                 }
141         ;
142
143 destination_statement:
144                 DEST_CMD dest_addrs retrynum EOS
145                 {
146                         dl_head = $2;
147                         retry = $3;
148                 }
149         ;
150
151 dest_addrs:
152                 dest_addr
153         |       dest_addrs dest_addr
154                 {
155                         $2->dl_next = $1;
156                         $$ = $2;
157                 }
158         ;
159
160 dest_addr :
161                 sin6
162                 {
163                         with_v6dest = 1;
164                 }
165         |       sin6 ifname
166                 {
167                         struct sockaddr_in6 *sin6;
168
169                         sin6 = (struct sockaddr_in6 *)$1->dl_dst;
170                         sin6->sin6_scope_id = if_nametoindex($2.cp);
171                         with_v6dest = 1;
172                         $$ = $1;
173                 }
174         |       HOSTNAME
175                 {
176                         struct sockaddr_storage *ss;
177                         struct addrinfo hints, *res;
178                         int error;
179
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);
186                         if (error) {
187                                 sprintf(errbuf, "name resolution failed for %s"
188                                 ":%s", $1, gai_strerror(error));
189                                 yyerror(errbuf);
190                         }
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);
194                         freeaddrinfo(res);
195
196                         $$ = (struct dst_list *)
197                              malloc(sizeof(struct dst_list));
198                         memset($$, 0, sizeof(struct dst_list));
199                         $$->dl_dst = (struct sockaddr *)ss;
200                 }
201         ;
202
203 sin6:
204                 IPV6ADDR
205                 {
206                         struct sockaddr_in6 *sin6;
207
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;
213
214                         $$ = (struct dst_list *)
215                              malloc(sizeof(struct dst_list));
216                         memset($$, 0, sizeof(struct dst_list));
217                         $$->dl_dst = (struct sockaddr *)sin6;
218                 }
219
220 ifname:
221                 NAME
222                 {
223                         $$.cp = strdup($1.cp);
224                         $$.len = $1.len;
225                 }
226         |       QSTRING
227                 {
228                         $1.cp[$1.len - 1] = 0;
229                         $$.cp = strdup(&$1.cp[1]);
230                         $$.len = $1.len - 2;
231                 }
232         ;
233
234 retrynum:
235                 /* empty */
236                 {
237                         $$ = 2;
238                 }
239         |       RETRY_CMD decstring
240                 {
241                         if ($2 > MAX_RETRYNUM)
242                                 $2 = MAX_RETRYNUM;
243                         $$ = $2;
244                 }
245         ;
246
247 rrenum_statement_with_seqnum:
248                 SEQNUM_CMD seqnum
249                 {
250                         if (pllist_lookup($2)) {
251                                 sprintf(errbuf, "duplicate seqnum %d specified"
252                                         " at %d", $2, lineno);
253                                 yyerror(errbuf);
254                         }
255                 }
256                 BCL rrenum_statement EOS ECL EOS
257                 {
258                         $5->pl_irr.rr_seqnum = $2;
259                         pllist_enqueue($5);
260                 }
261         ;
262
263 seqnum:
264                 /* empty */
265                 {
266                         $$ = 0;
267                 }
268         |       decstring
269                 {
270                         if ($1 > MAX_SEQNUM) {
271                                 sprintf(errbuf, "seqnum %d is illegal for this"
272                                         " program. should be between 0 and %d",
273                                         $1, MAX_SEQNUM);
274                                 yyerror(errbuf);
275                         }
276                         $$ = $1;
277                 }
278         ;
279
280 rrenum_statement_without_seqnum:
281                 rrenum_statement EOS
282                 {
283                         if (pllist_lookup(0)) {
284                                 sprintf(errbuf, "duplicate seqnum %d specified"
285                                         " at %d", 0, lineno);
286                                 yyerror(errbuf);
287                         }
288                         $1->pl_irr.rr_seqnum = 0;
289                         pllist_enqueue($1);
290                 }
291         ;
292
293 rrenum_statement:
294                 match_prefix_definition use_prefix_definition
295                 {
296                         $$ = (struct payload_list *)
297                              malloc(sizeof(struct payload_list));
298                         memcpy($$, &ple_cur, sizeof(ple_cur));
299                 }
300         ;
301
302 match_prefix_definition:
303                 rrenum_cmd MATCH_PREFIX_CMD prefixval maxlen minlen
304                 {
305                         struct icmp6_router_renum *irr;
306                         struct rr_pco_match *rpm;
307
308                         irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
309                         rpm = (struct rr_pco_match *)(irr + 1);
310                         memset(rpm, 0, sizeof(*rpm));
311
312                         rpm->rpm_code = $1;
313                         rpm->rpm_prefix = $3.addr;
314                         rpm->rpm_matchlen = $3.plen;
315                         rpm->rpm_maxlen = $4;
316                         rpm->rpm_minlen = $5;
317                 }
318         ;
319
320 rrenum_cmd:
321                 /* empty */
322                 {
323                         $$ = RPM_PCO_ADD;
324                 }
325         |       ADD
326         |       CHANGE
327         |       SETGLOBAL
328         ;
329
330 prefixval:
331                 IPV6ADDR prefixlen
332                 {
333                         $$.addr = $1;
334                         $$.plen = $2;
335                 }
336         ;
337
338 prefixlen:
339                 /* empty */
340                 {
341                         $$ = 64;
342                 }
343         |       PREFIXLEN
344         ;
345
346 maxlen:
347                 /* empty */
348                 {
349                         $$ = 128;
350                 }
351         |       MAXLEN_CMD decstring
352                 {
353                         if ($2 > 128)
354                                 $2 = 128;
355                         $$ = $2;
356                 }
357         ;
358
359 minlen:
360                 /* empty */
361                 {
362                         $$ = 0;
363                 }
364         |       MINLEN_CMD decstring
365                 {
366                         if ($2 > 128)
367                                 $2 = 128;
368                         $$ = $2;
369                 }
370         ;
371
372 use_prefix_definition:
373                 /* empty */
374                 {
375                         struct icmp6_router_renum *irr;
376                         struct rr_pco_match *rpm;
377                         struct rr_pco_use *rpu;
378
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));
383                 }
384         |       USE_PREFIX_CMD prefixval keeplen use_prefix_values
385                 {
386                         struct icmp6_router_renum *irr;
387                         struct rr_pco_match *rpm;
388                         struct rr_pco_use *rpu;
389
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);
393
394                         rpu->rpu_prefix = $2.addr;
395                         rpu->rpu_uselen = $2.plen;
396                         rpu->rpu_keeplen = $3;
397                 }
398         ;
399
400 use_prefix_values:
401                 /* empty */
402                 {
403                         struct icmp6_router_renum *irr;
404                         struct rr_pco_match *rpm;
405                         struct rr_pco_use *rpu;
406
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));
411
412                         rpu->rpu_vltime = DEF_VLTIME;
413                         rpu->rpu_pltime = DEF_PLTIME;
414                         rpu->rpu_ramask = 0;
415                         rpu->rpu_flags = 0;
416                 }
417         |       BCL vltime pltime raf_onlink raf_auto raf_decrvalid raf_decrprefd ECL
418                 {
419                         struct icmp6_router_renum *irr;
420                         struct rr_pco_match *rpm;
421                         struct rr_pco_use *rpu;
422
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));
427
428                         rpu->rpu_vltime = $2;
429                         rpu->rpu_pltime = $3;
430                         if ($4 == NOSPEC)
431                                 rpu->rpu_ramask &=
432                                         ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
433                         else {
434                                 rpu->rpu_ramask |=
435                                         ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
436                                 if ($4 == ON)
437                                         rpu->rpu_raflags |=
438                                                 ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
439                                 else
440                                         rpu->rpu_raflags &=
441                                                 ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
442                         }
443                         if ($5 == NOSPEC)
444                                 rpu->rpu_ramask &=
445                                         ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
446                         else {
447                                 rpu->rpu_ramask |=
448                                         ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
449                                 if ($5 == ON)
450                                         rpu->rpu_raflags |=
451                                                 ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
452                                 else
453                                         rpu->rpu_raflags &=
454                                                 ~ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
455                         }
456                         rpu->rpu_flags = 0;
457                         if ($6 == ON)
458                                 rpu->rpu_flags |=
459                                         ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME;
460                         if ($7 == ON)
461                                 rpu->rpu_flags |=
462                                         ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME;
463                 }
464         ;
465
466 keeplen:
467                 /* empty */
468                 {
469                         $$ = 0;
470                 }
471         |       KEEPLEN_CMD decstring
472                 {
473                         if ($2 > 128)
474                                 $2 = 128;
475                         $$ = $2;
476                 }
477         ;
478
479
480 vltime:
481                 /* empty */
482                 {
483                         $$ = DEF_VLTIME;
484                 }
485         |       VLTIME_CMD lifetime
486                 {
487                         $$ = htonl($2);
488                 }
489         ;
490
491 pltime:
492                 /* empty */
493                 {
494                         $$ = DEF_PLTIME;
495                 }
496         |       PLTIME_CMD lifetime
497                 {
498                         $$ = htonl($2);
499                 }
500
501 raf_onlink:
502                 /* empty */
503                 {
504                         $$ = NOSPEC;
505                 }
506         |       RAF_ONLINK_CMD flag
507                 {
508                         $$ = $2;
509                 }
510         ;
511
512 raf_auto:
513                 /* empty */
514                 {
515                         $$ = NOSPEC;
516                 }
517         |       RAF_AUTO_CMD flag
518                 {
519                         $$ = $2;
520                 }
521         ;
522
523 raf_decrvalid:
524                 /* empty */
525                 {
526                         $$ = NOSPEC;
527                 }
528         |       RAF_DECRVALID_CMD flag
529                 {
530                         $$ = $2;
531                 }
532         ;
533
534 raf_decrprefd:
535                 /* empty */
536                 {
537                         $$ = NOSPEC;
538                 }
539         |       RAF_DECRPREFD_CMD flag
540                 {
541                         $$ = $2;
542                 }
543         ;
544
545 flag:
546                 ON
547         |       OFF
548         ;
549
550 lifetime:
551                 decstring
552         |       INFINITY
553                 {
554                         $$ = 0xffffffff;
555                 }
556         |       days hours minutes seconds
557                 {
558                         int d, h, m, s;
559
560                         d = $1 * 24 * 60 * 60;
561                         h = $2 * 60 * 60;
562                         m = $3 * 60;
563                         s = $4;
564                         $$ = d + h + m + s;
565                 }
566         ;
567
568 days:
569                 /* empty */
570                 {
571                         $$ = 0;
572                 }
573         |       DAYS
574         ;
575
576 hours:
577                 /* empty */
578                 {
579                         $$ = 0;
580                 }
581         |       HOURS
582         ;
583
584 minutes:
585                 /* empty */
586                 {
587                         $$ = 0;
588                 }
589         |       MINUTES
590         ;
591
592 seconds:
593                 /* empty */
594                 {
595                         $$ = 0;
596                 }
597         |       SECONDS
598         ;
599
600 decstring:
601                 DECSTRING
602                 {
603                         int dval;
604
605                         dval = atoi($1.cp);
606                         $$ = dval;
607                 }
608         ;
609
610 %%
611
612 static struct payload_list *
613 pllist_lookup(int seqnum)
614 {
615         struct payload_list *pl;
616         for (pl = pl_head; pl && pl->pl_irr.rr_seqnum != seqnum;
617              pl = pl->pl_next)
618                 continue;
619         return (pl);
620 }
621
622 static void
623 pllist_enqueue(struct payload_list *pl_entry)
624 {
625         struct payload_list *pl, *pl_last;
626         if (pl_head == NULL) {
627                 pl_head = pl_entry;
628                 return;
629         }
630         for (pl = pl_head;
631              pl && pl->pl_irr.rr_seqnum < pl_entry->pl_irr.rr_seqnum;
632              pl_last = pl, pl = pl->pl_next)
633                 continue;
634         pl_last->pl_next = pl_entry;
635
636         return;
637 }