minidlna support now Samsung TV C550/C650 (thx amir909)
[tomato.git] / release / src / router / dhcpv6 / cfparse.y
blobdcac3d74ed17ac4f0af1cd65f17e5c527943bb48
1 /* $KAME: cfparse.y,v 1.36 2005/05/03 06:46:00 jinmei Exp $ */
3 /*
4 * Copyright (C) 2002 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.
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <sys/queue.h>
35 #include <sys/time.h>
37 #include <netinet/in.h>
39 #include <arpa/inet.h>
41 #include <stdlib.h>
42 #include <string.h>
44 #include "dhcp6.h"
45 #include "config.h"
46 #include "common.h"
48 extern int lineno;
49 extern int cfdebug;
51 extern void yywarn __P((char *, ...))
52 __attribute__((__format__(__printf__, 1, 2)));
53 extern void yyerror __P((char *, ...))
54 __attribute__((__format__(__printf__, 1, 2)));
56 #define MAKE_NAMELIST(l, n, p) do { \
57 (l) = (struct cf_namelist *)malloc(sizeof(*(l))); \
58 if ((l) == NULL) { \
59 yywarn("can't allocate memory"); \
60 if (p) cleanup_cflist(p); \
61 return (-1); \
62 } \
63 memset((l), 0, sizeof(*(l))); \
64 l->line = lineno; \
65 l->name = (n); \
66 l->params = (p); \
67 } while (0)
69 #define MAKE_CFLIST(l, t, pp, pl) do { \
70 (l) = (struct cf_list *)malloc(sizeof(*(l))); \
71 if ((l) == NULL) { \
72 yywarn("can't allocate memory"); \
73 if (pp) free(pp); \
74 if (pl) cleanup_cflist(pl); \
75 return (-1); \
76 } \
77 memset((l), 0, sizeof(*(l))); \
78 l->line = lineno; \
79 l->type = (t); \
80 l->ptr = (pp); \
81 l->list = (pl); \
82 l->tail = (l); \
83 } while (0)
85 static struct cf_namelist *iflist_head, *hostlist_head, *iapdlist_head;
86 static struct cf_namelist *addrpoollist_head;
87 static struct cf_namelist *authinfolist_head, *keylist_head;
88 static struct cf_namelist *ianalist_head;
89 struct cf_list *cf_dns_list, *cf_dns_name_list, *cf_ntp_list;
90 struct cf_list *cf_sip_list, *cf_sip_name_list;
91 struct cf_list *cf_nis_list, *cf_nis_name_list;
92 struct cf_list *cf_nisp_list, *cf_nisp_name_list;
93 struct cf_list *cf_bcmcs_list, *cf_bcmcs_name_list;
94 long long cf_refreshtime = -1;
96 extern int yylex __P((void));
97 extern int cfswitch_buffer __P((char *));
98 static int add_namelist __P((struct cf_namelist *, struct cf_namelist **));
99 static void cleanup __P((void));
100 static void cleanup_namelist __P((struct cf_namelist *));
101 static void cleanup_cflist __P((struct cf_list *));
104 %token INTERFACE IFNAME
105 %token PREFIX_INTERFACE SLA_ID SLA_LEN DUID_ID
106 %token ID_ASSOC IA_PD IAID IA_NA
107 %token ADDRESS
108 %token REQUEST SEND ALLOW PREFERENCE
109 %token HOST HOSTNAME DUID
110 %token OPTION RAPID_COMMIT DNS_SERVERS DNS_NAME NTP_SERVERS REFRESHTIME
111 %token SIP_SERVERS SIP_NAME
112 %token NIS_SERVERS NIS_NAME
113 %token NISP_SERVERS NISP_NAME
114 %token BCMCS_SERVERS BCMCS_NAME
115 %token INFO_ONLY
116 %token SCRIPT DELAYEDKEY
117 %token AUTHENTICATION PROTOCOL ALGORITHM DELAYED RECONFIG HMACMD5 MONOCOUNTER
118 %token AUTHNAME RDM KEY
119 %token KEYINFO REALM KEYID SECRET KEYNAME EXPIRE
120 %token ADDRPOOL POOLNAME RANGE TO ADDRESS_POOL
121 %token INCLUDE
123 %token NUMBER SLASH EOS BCL ECL STRING QSTRING PREFIX INFINITY
124 %token COMMA
126 %union {
127 long long num;
128 char* str;
129 struct cf_list *list;
130 struct dhcp6_prefix *prefix;
131 struct dhcp6_range *range;
132 struct dhcp6_poolspec *pool;
135 %type <str> IFNAME HOSTNAME AUTHNAME KEYNAME DUID_ID STRING QSTRING IAID
136 %type <str> POOLNAME
137 %type <num> NUMBER duration authproto authalg authrdm
138 %type <list> declaration declarations dhcpoption ifparam ifparams
139 %type <list> address_list address_list_ent dhcpoption_list
140 %type <list> iapdconf_list iapdconf prefix_interface
141 %type <list> ianaconf_list ianaconf
142 %type <list> authparam_list authparam
143 %type <list> keyparam_list keyparam
144 %type <prefix> addressparam prefixparam
145 %type <range> rangeparam
146 %type <pool> poolparam
149 statements:
150 /* empty */
151 | statements statement
154 statement:
155 interface_statement
156 | host_statement
157 | option_statement
158 | ia_statement
159 | authentication_statement
160 | key_statement
161 | addrpool_statement
162 | include_statement
165 interface_statement:
166 INTERFACE IFNAME BCL declarations ECL EOS
168 struct cf_namelist *ifl;
170 MAKE_NAMELIST(ifl, $2, $4);
172 if (add_namelist(ifl, &iflist_head))
173 return (-1);
177 host_statement:
178 HOST HOSTNAME BCL declarations ECL EOS
180 struct cf_namelist *host;
182 MAKE_NAMELIST(host, $2, $4);
184 if (add_namelist(host, &hostlist_head))
185 return (-1);
189 option_statement:
190 OPTION DNS_SERVERS address_list EOS
192 if (cf_dns_list == NULL)
193 cf_dns_list = $3;
194 else {
195 cf_dns_list->tail->next = $3;
196 cf_dns_list->tail = $3->tail;
199 | OPTION DNS_NAME QSTRING EOS
201 struct cf_list *l;
203 MAKE_CFLIST(l, CFLISTENT_GENERIC, $3, NULL);
205 if (cf_dns_name_list == NULL) {
206 cf_dns_name_list = l;
207 cf_dns_name_list->tail = l;
208 cf_dns_name_list->next = NULL;
209 } else {
210 cf_dns_name_list->tail->next = l;
211 cf_dns_name_list->tail = l->tail;
214 | OPTION NTP_SERVERS address_list EOS
216 if (cf_ntp_list == NULL)
217 cf_ntp_list = $3;
218 else {
219 cf_ntp_list->tail->next = $3;
220 cf_ntp_list->tail = $3->tail;
223 | OPTION SIP_SERVERS address_list EOS
225 if (cf_sip_list == NULL)
226 cf_sip_list = $3;
227 else {
228 cf_sip_list->tail->next = $3;
229 cf_sip_list->tail = $3->tail;
232 | OPTION SIP_NAME QSTRING EOS
234 struct cf_list *l;
236 MAKE_CFLIST(l, CFLISTENT_GENERIC, $3, NULL);
238 if (cf_sip_name_list == NULL) {
239 cf_sip_name_list = l;
240 cf_sip_name_list->tail = l;
241 cf_sip_name_list->next = NULL;
242 } else {
243 cf_sip_name_list->tail->next = l;
244 cf_sip_name_list->tail = l->tail;
247 | OPTION NIS_SERVERS address_list EOS
249 if (cf_nis_list == NULL)
250 cf_nis_list = $3;
251 else {
252 cf_nis_list->tail->next = $3;
253 cf_nis_list->tail = $3->tail;
256 | OPTION NIS_NAME QSTRING EOS
258 struct cf_list *l;
260 MAKE_CFLIST(l, CFLISTENT_GENERIC, $3, NULL);
262 if (cf_nis_name_list == NULL) {
263 cf_nis_name_list = l;
264 cf_nis_name_list->tail = l;
265 cf_nis_name_list->next = NULL;
266 } else {
267 cf_nis_name_list->tail->next = l;
268 cf_nis_name_list->tail = l->tail;
271 | OPTION NISP_SERVERS address_list EOS
273 if (cf_nisp_list == NULL)
274 cf_nisp_list = $3;
275 else {
276 cf_nisp_list->tail->next = $3;
277 cf_nisp_list->tail = $3->tail;
280 | OPTION NISP_NAME QSTRING EOS
282 struct cf_list *l;
284 MAKE_CFLIST(l, CFLISTENT_GENERIC, $3, NULL);
286 if (cf_nisp_name_list == NULL) {
287 cf_nisp_name_list = l;
288 cf_nisp_name_list->tail = l;
289 cf_nisp_name_list->next = NULL;
290 } else {
291 cf_nisp_name_list->tail->next = l;
292 cf_nisp_name_list->tail = l->tail;
295 | OPTION BCMCS_SERVERS address_list EOS
297 if (cf_bcmcs_list == NULL)
298 cf_bcmcs_list = $3;
299 else {
300 cf_bcmcs_list->tail->next = $3;
301 cf_bcmcs_list->tail = $3->tail;
304 | OPTION BCMCS_NAME QSTRING EOS
306 struct cf_list *l;
308 MAKE_CFLIST(l, CFLISTENT_GENERIC, $3, NULL);
310 if (cf_bcmcs_name_list == NULL) {
311 cf_bcmcs_name_list = l;
312 cf_bcmcs_name_list->tail = l;
313 cf_bcmcs_name_list->next = NULL;
314 } else {
315 cf_bcmcs_name_list->tail->next = l;
316 cf_bcmcs_name_list->tail = l->tail;
319 | OPTION REFRESHTIME NUMBER EOS
321 if (cf_refreshtime == -1) {
322 cf_refreshtime = $3;
323 if (cf_refreshtime < -1 ||
324 cf_refreshtime > 0xffffffff) {
326 * refresh time should not be negative
327 * according to the lex definition,
328 * but check it for safety.
330 yyerror("refresh time is out of range");
332 if (cf_refreshtime < DHCP6_IRT_MINIMUM) {
334 * the value MUST NOT be smaller than
335 * IRT_MINIMUM.
337 yyerror("refresh time is too small "
338 "(must not be smaller than %d)",
339 DHCP6_IRT_MINIMUM);
341 } else {
342 yywarn("multiple refresh times (ignored)");
347 ia_statement:
348 ID_ASSOC IA_PD IAID BCL iapdconf_list ECL EOS
350 struct cf_namelist *iapd;
352 MAKE_NAMELIST(iapd, $3, $5);
354 if (add_namelist(iapd, &iapdlist_head))
355 return (-1);
357 | ID_ASSOC IA_PD BCL iapdconf_list ECL EOS
359 struct cf_namelist *iapd;
360 char *zero;
362 if ((zero = strdup("0")) == NULL) {
363 yywarn("can't allocate memory");
364 return (-1);
366 MAKE_NAMELIST(iapd, zero, $4);
368 if (add_namelist(iapd, &iapdlist_head))
369 return (-1);
371 | ID_ASSOC IA_NA IAID BCL ianaconf_list ECL EOS
373 struct cf_namelist *iana;
375 MAKE_NAMELIST(iana, $3, $5);
377 if (add_namelist(iana, &ianalist_head))
378 return (-1);
380 | ID_ASSOC IA_NA BCL ianaconf_list ECL EOS
382 struct cf_namelist *iana;
383 char *zero;
385 if ((zero = strdup("0")) == NULL) {
386 yywarn("can't allocate memory");
387 return (-1);
389 MAKE_NAMELIST(iana, zero, $4);
391 if (add_namelist(iana, &ianalist_head))
392 return (-1);
396 authentication_statement:
397 AUTHENTICATION AUTHNAME BCL authparam_list ECL EOS
399 struct cf_namelist *authinfo;
401 MAKE_NAMELIST(authinfo, $2, $4);
403 if (add_namelist(authinfo, &authinfolist_head))
404 return (-1);
408 key_statement:
409 KEYINFO KEYNAME BCL keyparam_list ECL EOS
411 struct cf_namelist *key;
413 MAKE_NAMELIST(key, $2, $4);
415 if (add_namelist(key, &keylist_head))
416 return (-1);
420 include_statement:
421 INCLUDE QSTRING EOS
423 if (cfswitch_buffer($2)) {
424 free($2);
425 return (-1);
427 free($2);
431 addrpool_statement:
432 ADDRPOOL POOLNAME BCL declarations ECL EOS
434 struct cf_namelist *pool;
436 MAKE_NAMELIST(pool, $2, $4);
438 if (add_namelist(pool, &addrpoollist_head))
439 return (-1);
443 address_list:
444 { $$ = NULL; }
445 | address_list address_list_ent
447 struct cf_list *head;
449 if ((head = $1) == NULL) {
450 $2->next = NULL;
451 $2->tail = $2;
452 head = $2;
453 } else {
454 head->tail->next = $2;
455 head->tail = $2->tail;
458 $$ = head;
462 address_list_ent:
463 STRING
465 struct cf_list *l;
466 struct in6_addr a0, *a;
468 if (inet_pton(AF_INET6, $1, &a0) != 1) {
469 yywarn("invalid IPv6 address: %s", $1);
470 free($1);
471 return (-1);
473 if ((a = malloc(sizeof(*a))) == NULL) {
474 yywarn("can't allocate memory");
475 return (-1);
477 *a = a0;
479 MAKE_CFLIST(l, CFLISTENT_GENERIC, a, NULL);
481 $$ = l;
485 declarations:
486 { $$ = NULL; }
487 | declarations declaration
489 struct cf_list *head;
491 if ((head = $1) == NULL) {
492 $2->next = NULL;
493 $2->tail = $2;
494 head = $2;
495 } else {
496 head->tail->next = $2;
497 head->tail = $2->tail;
500 $$ = head;
504 declaration:
505 SEND dhcpoption_list EOS
507 struct cf_list *l;
509 MAKE_CFLIST(l, DECL_SEND, NULL, $2);
511 $$ = l;
513 | REQUEST dhcpoption_list EOS
515 struct cf_list *l;
517 MAKE_CFLIST(l, DECL_REQUEST, NULL, $2);
519 $$ = l;
521 | INFO_ONLY EOS
523 struct cf_list *l;
525 MAKE_CFLIST(l, DECL_INFO_ONLY, NULL, NULL);
526 /* no value */
527 $$ = l;
529 | ALLOW dhcpoption EOS
531 struct cf_list *l;
533 MAKE_CFLIST(l, DECL_ALLOW, NULL, $2);
535 $$ = l;
537 | DUID DUID_ID EOS
539 struct cf_list *l;
541 MAKE_CFLIST(l, DECL_DUID, $2, NULL);
543 $$ = l;
545 | ADDRESS addressparam EOS
547 struct cf_list *l;
549 MAKE_CFLIST(l, DECL_ADDRESS, $2,NULL);
551 $$ = l;
553 | PREFIX prefixparam EOS
555 struct cf_list *l;
557 MAKE_CFLIST(l, DECL_PREFIX, $2, NULL);
559 $$ = l;
561 | PREFERENCE NUMBER EOS
563 struct cf_list *l;
565 MAKE_CFLIST(l, DECL_PREFERENCE, NULL, NULL);
566 l->num = $2;
568 $$ = l;
570 | SCRIPT QSTRING EOS
572 struct cf_list *l;
574 MAKE_CFLIST(l, DECL_SCRIPT, $2, NULL);
576 $$ = l;
578 | DELAYEDKEY STRING EOS
580 struct cf_list *l;
582 MAKE_CFLIST(l, DECL_DELAYEDKEY, $2, NULL);
584 $$ = l;
586 | RANGE rangeparam EOS
588 struct cf_list *l;
590 MAKE_CFLIST(l, DECL_RANGE, $2, NULL);
592 $$ = l;
594 | ADDRESS_POOL poolparam EOS
596 struct cf_list *l;
598 MAKE_CFLIST(l, DECL_ADDRESSPOOL, $2, NULL);
600 $$ = l;
604 dhcpoption_list:
605 dhcpoption
607 $$ = $1;
609 | dhcpoption COMMA dhcpoption_list
611 $1->next = $3;
612 $1->tail = $3->tail;
614 $$ = $1;
618 dhcpoption:
619 RAPID_COMMIT
621 struct cf_list *l;
623 MAKE_CFLIST(l, DHCPOPT_RAPID_COMMIT, NULL, NULL);
624 /* no value */
625 $$ = l;
627 | AUTHENTICATION AUTHNAME
629 struct cf_list *l;
631 MAKE_CFLIST(l, DHCPOPT_AUTHINFO, NULL, NULL);
632 l->ptr = $2;
633 $$ = l;
635 | IA_PD NUMBER
637 struct cf_list *l;
639 MAKE_CFLIST(l, DHCPOPT_IA_PD, NULL, NULL);
640 l->num = $2;
641 $$ = l;
643 | IA_NA NUMBER
645 struct cf_list *l;
647 MAKE_CFLIST(l, DHCPOPT_IA_NA, NULL, NULL);
648 l->num = $2;
649 $$ = l;
651 | SIP_SERVERS
653 struct cf_list *l;
655 MAKE_CFLIST(l, DHCPOPT_SIP, NULL, NULL);
656 /* currently no value */
657 $$ = l;
659 | SIP_NAME
661 struct cf_list *l;
663 MAKE_CFLIST(l, DHCPOPT_SIPNAME, NULL, NULL);
664 /* currently no value */
665 $$ = l;
667 | DNS_SERVERS
669 struct cf_list *l;
671 MAKE_CFLIST(l, DHCPOPT_DNS, NULL, NULL);
672 /* currently no value */
673 $$ = l;
675 | DNS_NAME
677 struct cf_list *l;
679 MAKE_CFLIST(l, DHCPOPT_DNSNAME, NULL, NULL);
680 /* currently no value */
681 $$ = l;
683 | NTP_SERVERS
685 struct cf_list *l;
687 MAKE_CFLIST(l, DHCPOPT_NTP, NULL, NULL);
688 /* currently no value */
689 $$ = l;
691 | REFRESHTIME
693 struct cf_list *l;
695 MAKE_CFLIST(l, DHCPOPT_REFRESHTIME, NULL, NULL);
696 /* currently no value */
697 $$ = l;
699 | NIS_SERVERS
701 struct cf_list *l;
703 MAKE_CFLIST(l, DHCPOPT_NIS, NULL, NULL);
704 /* currently no value */
705 $$ = l;
707 | NIS_NAME
709 struct cf_list *l;
711 MAKE_CFLIST(l, DHCPOPT_NISNAME, NULL, NULL);
712 /* currently no value */
713 $$ = l;
715 | NISP_SERVERS
717 struct cf_list *l;
719 MAKE_CFLIST(l, DHCPOPT_NISP, NULL, NULL);
720 /* currently no value */
721 $$ = l;
723 | NISP_NAME
725 struct cf_list *l;
727 MAKE_CFLIST(l, DHCPOPT_NISPNAME, NULL, NULL);
728 /* currently no value */
729 $$ = l;
731 | BCMCS_SERVERS
733 struct cf_list *l;
735 MAKE_CFLIST(l, DHCPOPT_BCMCS, NULL, NULL);
736 /* currently no value */
737 $$ = l;
739 | BCMCS_NAME
741 struct cf_list *l;
743 MAKE_CFLIST(l, DHCPOPT_BCMCSNAME, NULL, NULL);
744 /* currently no value */
745 $$ = l;
749 rangeparam:
750 STRING TO STRING
752 struct dhcp6_range range0, *range;
754 memset(&range0, 0, sizeof(range0));
755 if (inet_pton(AF_INET6, $1, &range0.min) != 1) {
756 yywarn("invalid IPv6 address: %s", $1);
757 free($1);
758 free($3);
759 return (-1);
761 if (inet_pton(AF_INET6, $3, &range0.max) != 1) {
762 yywarn("invalid IPv6 address: %s", $3);
763 free($1);
764 free($3);
765 return (-1);
767 free($1);
768 free($3);
770 if ((range = malloc(sizeof(*range))) == NULL) {
771 yywarn("can't allocate memory");
772 return (-1);
774 *range = range0;
776 $$ = range;
780 addressparam:
781 STRING duration
783 struct dhcp6_prefix pconf0, *pconf;
785 memset(&pconf0, 0, sizeof(pconf0));
786 if (inet_pton(AF_INET6, $1, &pconf0.addr) != 1) {
787 yywarn("invalid IPv6 address: %s", $1);
788 free($1);
789 return (-1);
791 free($1);
792 /* validate other parameters later */
793 pconf0.plen = 128; /* XXX this field is ignored */
794 if ($2 < 0)
795 pconf0.pltime = DHCP6_DURATION_INFINITE;
796 else
797 pconf0.pltime = (u_int32_t)$2;
798 pconf0.vltime = pconf0.pltime;
800 if ((pconf = malloc(sizeof(*pconf))) == NULL) {
801 yywarn("can't allocate memory");
802 return (-1);
804 *pconf = pconf0;
806 $$ = pconf;
808 | STRING duration duration
810 struct dhcp6_prefix pconf0, *pconf;
812 memset(&pconf0, 0, sizeof(pconf0));
813 if (inet_pton(AF_INET6, $1, &pconf0.addr) != 1) {
814 yywarn("invalid IPv6 address: %s", $1);
815 free($1);
816 return (-1);
818 free($1);
819 /* validate other parameters later */
820 pconf0.plen = 128; /* XXX */
821 if ($2 < 0)
822 pconf0.pltime = DHCP6_DURATION_INFINITE;
823 else
824 pconf0.pltime = (u_int32_t)$2;
825 if ($3 < 0)
826 pconf0.vltime = DHCP6_DURATION_INFINITE;
827 else
828 pconf0.vltime = (u_int32_t)$3;
830 if ((pconf = malloc(sizeof(*pconf))) == NULL) {
831 yywarn("can't allocate memory");
832 return (-1);
834 *pconf = pconf0;
836 $$ = pconf;
840 prefixparam:
841 STRING SLASH NUMBER duration
843 struct dhcp6_prefix pconf0, *pconf;
845 memset(&pconf0, 0, sizeof(pconf0));
846 if (inet_pton(AF_INET6, $1, &pconf0.addr) != 1) {
847 yywarn("invalid IPv6 address: %s", $1);
848 free($1);
849 return (-1);
851 free($1);
852 /* validate other parameters later */
853 pconf0.plen = $3;
854 if ($4 < 0)
855 pconf0.pltime = DHCP6_DURATION_INFINITE;
856 else
857 pconf0.pltime = (u_int32_t)$4;
858 pconf0.vltime = pconf0.pltime;
860 if ((pconf = malloc(sizeof(*pconf))) == NULL) {
861 yywarn("can't allocate memory");
862 return (-1);
864 *pconf = pconf0;
866 $$ = pconf;
868 | STRING SLASH NUMBER duration duration
870 struct dhcp6_prefix pconf0, *pconf;
872 memset(&pconf0, 0, sizeof(pconf0));
873 if (inet_pton(AF_INET6, $1, &pconf0.addr) != 1) {
874 yywarn("invalid IPv6 address: %s", $1);
875 free($1);
876 return (-1);
878 free($1);
879 /* validate other parameters later */
880 pconf0.plen = $3;
881 if ($4 < 0)
882 pconf0.pltime = DHCP6_DURATION_INFINITE;
883 else
884 pconf0.pltime = (u_int32_t)$4;
885 if ($5 < 0)
886 pconf0.vltime = DHCP6_DURATION_INFINITE;
887 else
888 pconf0.vltime = (u_int32_t)$5;
890 if ((pconf = malloc(sizeof(*pconf))) == NULL) {
891 yywarn("can't allocate memory");
892 return (-1);
894 *pconf = pconf0;
896 $$ = pconf;
900 poolparam:
901 STRING duration
903 struct dhcp6_poolspec* pool;
905 if ((pool = malloc(sizeof(*pool))) == NULL) {
906 yywarn("can't allocate memory");
907 free($1);
908 return (-1);
910 if ((pool->name = strdup($1)) == NULL) {
911 yywarn("can't allocate memory");
912 free($1);
913 return (-1);
915 free($1);
917 /* validate other parameters later */
918 if ($2 < 0)
919 pool->pltime = DHCP6_DURATION_INFINITE;
920 else
921 pool->pltime = (u_int32_t)$2;
922 pool->vltime = pool->pltime;
924 $$ = pool;
926 | STRING duration duration
928 struct dhcp6_poolspec* pool;
930 if ((pool = malloc(sizeof(*pool))) == NULL) {
931 yywarn("can't allocate memory");
932 free($1);
933 return (-1);
935 if ((pool->name = strdup($1)) == NULL) {
936 yywarn("can't allocate memory");
937 free($1);
938 return (-1);
940 free($1);
942 /* validate other parameters later */
943 if ($2 < 0)
944 pool->pltime = DHCP6_DURATION_INFINITE;
945 else
946 pool->pltime = (u_int32_t)$2;
947 if ($3 < 0)
948 pool->vltime = DHCP6_DURATION_INFINITE;
949 else
950 pool->vltime = (u_int32_t)$3;
952 $$ = pool;
956 duration:
957 INFINITY
959 $$ = -1;
961 | NUMBER
963 $$ = $1;
967 iapdconf_list:
968 { $$ = NULL; }
969 | iapdconf_list iapdconf
971 struct cf_list *head;
973 if ((head = $1) == NULL) {
974 $2->next = NULL;
975 $2->tail = $2;
976 head = $2;
977 } else {
978 head->tail->next = $2;
979 head->tail = $2->tail;
982 $$ = head;
986 iapdconf:
987 prefix_interface { $$ = $1; }
988 | PREFIX prefixparam EOS
990 struct cf_list *l;
992 MAKE_CFLIST(l, IACONF_PREFIX, $2, NULL);
994 $$ = l;
998 prefix_interface:
999 PREFIX_INTERFACE IFNAME BCL ifparams ECL EOS
1001 struct cf_list *ifl;
1003 MAKE_CFLIST(ifl, IACONF_PIF, $2, $4);
1004 $$ = ifl;
1008 ifparams:
1009 { $$ = NULL; }
1010 | ifparams ifparam
1012 struct cf_list *head;
1014 if ((head = $1) == NULL) {
1015 $2->next = NULL;
1016 $2->tail = $2;
1017 head = $2;
1018 } else {
1019 head->tail->next = $2;
1020 head->tail = $2->tail;
1023 $$ = head;
1027 ifparam:
1028 SLA_ID NUMBER EOS
1030 struct cf_list *l;
1032 MAKE_CFLIST(l, IFPARAM_SLA_ID, NULL, NULL);
1033 l->num = $2;
1034 $$ = l;
1036 | SLA_LEN NUMBER EOS
1038 struct cf_list *l;
1040 MAKE_CFLIST(l, IFPARAM_SLA_LEN, NULL, NULL);
1041 l->num = $2;
1042 $$ = l;
1046 ianaconf_list:
1047 { $$ = NULL; }
1048 | ianaconf_list ianaconf
1050 struct cf_list *head;
1052 if ((head = $1) == NULL) {
1053 $2->next = NULL;
1054 $2->tail = $2;
1055 head = $2;
1056 } else {
1057 head->tail->next = $2;
1058 head->tail = $2->tail;
1061 $$ = head;
1065 ianaconf:
1066 ADDRESS addressparam EOS
1068 struct cf_list *l;
1070 MAKE_CFLIST(l, IACONF_ADDR, $2, NULL);
1072 $$ = l;
1076 authparam_list:
1077 { $$ = NULL; }
1078 | authparam_list authparam
1080 struct cf_list *head;
1082 if ((head = $1) == NULL) {
1083 $2->next = NULL;
1084 $2->tail = $2;
1085 head = $2;
1086 } else {
1087 head->tail->next = $2;
1088 head->tail = $2->tail;
1091 $$ = head;
1095 authparam:
1096 PROTOCOL authproto EOS
1098 struct cf_list *l;
1100 MAKE_CFLIST(l, AUTHPARAM_PROTO, NULL, NULL);
1101 l->num = $2;
1102 $$ = l;
1104 | ALGORITHM authalg EOS
1106 struct cf_list *l;
1108 MAKE_CFLIST(l, AUTHPARAM_ALG, NULL, NULL);
1109 l->num = $2;
1110 $$ = l;
1112 | RDM authrdm EOS
1114 struct cf_list *l;
1116 MAKE_CFLIST(l, AUTHPARAM_RDM, NULL, NULL);
1117 l->num = $2;
1118 $$ = l;
1120 | KEY STRING EOS
1122 struct cf_list *l;
1124 MAKE_CFLIST(l, AUTHPARAM_KEY, NULL, NULL);
1125 l->ptr = $2;
1126 $$ = l;
1130 authproto:
1131 DELAYED { $$ = DHCP6_AUTHPROTO_DELAYED; }
1132 | RECONFIG { $$ = DHCP6_AUTHPROTO_RECONFIG; }
1135 authalg:
1136 HMACMD5 { $$ = DHCP6_AUTHALG_HMACMD5; }
1139 authrdm:
1140 MONOCOUNTER { $$ = DHCP6_AUTHRDM_MONOCOUNTER; }
1143 keyparam_list:
1144 { $$ = NULL; }
1145 | keyparam_list keyparam
1147 struct cf_list *head;
1149 if ((head = $1) == NULL) {
1150 $2->next = NULL;
1151 $2->tail = $2;
1152 head = $2;
1153 } else {
1154 head->tail->next = $2;
1155 head->tail = $2->tail;
1158 $$ = head;
1162 keyparam:
1163 REALM QSTRING EOS
1165 struct cf_list *l;
1167 MAKE_CFLIST(l, KEYPARAM_REALM, NULL, NULL);
1168 l->ptr = $2;
1169 $$ = l;
1171 | KEYID NUMBER EOS
1173 struct cf_list *l;
1175 MAKE_CFLIST(l, KEYPARAM_KEYID, NULL, NULL);
1176 l->num = $2;
1177 $$ = l;
1179 | SECRET QSTRING EOS
1181 struct cf_list *l;
1183 MAKE_CFLIST(l, KEYPARAM_SECRET, NULL, NULL);
1184 l->ptr = $2;
1185 $$ = l;
1187 | EXPIRE QSTRING EOS
1189 struct cf_list *l;
1191 MAKE_CFLIST(l, KEYPARAM_EXPIRE, NULL, NULL);
1192 l->ptr = $2;
1193 $$ = l;
1198 /* supplement routines for configuration */
1199 static int
1200 add_namelist(new, headp)
1201 struct cf_namelist *new, **headp;
1203 struct cf_namelist *n;
1205 /* check for duplicated configuration */
1206 for (n = *headp; n; n = n->next) {
1207 if (strcmp(n->name, new->name) == 0) {
1208 yywarn("duplicated name: %s (ignored)",
1209 new->name);
1210 cleanup_namelist(new);
1211 return (0);
1215 new->next = *headp;
1216 *headp = new;
1218 return (0);
1221 /* free temporary resources */
1222 static void
1223 cleanup()
1225 cleanup_namelist(iflist_head);
1226 iflist_head = NULL;
1227 cleanup_namelist(hostlist_head);
1228 hostlist_head = NULL;
1229 cleanup_namelist(iapdlist_head);
1230 iapdlist_head = NULL;
1231 cleanup_namelist(ianalist_head);
1232 ianalist_head = NULL;
1233 cleanup_namelist(authinfolist_head);
1234 authinfolist_head = NULL;
1235 cleanup_namelist(keylist_head);
1236 keylist_head = NULL;
1237 cleanup_namelist(addrpoollist_head);
1238 addrpoollist_head = NULL;
1240 cleanup_cflist(cf_sip_list);
1241 cf_sip_list = NULL;
1242 cleanup_cflist(cf_sip_name_list);
1243 cf_sip_name_list = NULL;
1244 cleanup_cflist(cf_dns_list);
1245 cf_dns_list = NULL;
1246 cleanup_cflist(cf_dns_name_list);
1247 cf_dns_name_list = NULL;
1248 cleanup_cflist(cf_ntp_list);
1249 cf_ntp_list = NULL;
1250 cleanup_cflist(cf_nis_list);
1251 cf_nis_list = NULL;
1252 cleanup_cflist(cf_nis_name_list);
1253 cf_nis_name_list = NULL;
1254 cleanup_cflist(cf_nisp_list);
1255 cf_nisp_list = NULL;
1256 cleanup_cflist(cf_nisp_name_list);
1257 cf_nisp_name_list = NULL;
1258 cleanup_cflist(cf_bcmcs_list);
1259 cf_bcmcs_list = NULL;
1260 cleanup_cflist(cf_bcmcs_name_list);
1261 cf_bcmcs_name_list = NULL;
1264 static void
1265 cleanup_namelist(head)
1266 struct cf_namelist *head;
1268 struct cf_namelist *ifp, *ifp_next;
1270 for (ifp = head; ifp; ifp = ifp_next) {
1271 ifp_next = ifp->next;
1272 cleanup_cflist(ifp->params);
1273 free(ifp->name);
1274 free(ifp);
1278 static void
1279 cleanup_cflist(p)
1280 struct cf_list *p;
1282 struct cf_list *n;
1284 if (p == NULL)
1285 return;
1287 n = p->next;
1288 if (p->type == DECL_ADDRESSPOOL) {
1289 free(((struct dhcp6_poolspec *)p->ptr)->name);
1291 if (p->ptr)
1292 free(p->ptr);
1293 if (p->list)
1294 cleanup_cflist(p->list);
1295 free(p);
1297 cleanup_cflist(n);
1300 #define config_fail() \
1301 do { cleanup(); configure_cleanup(); return (-1); } while(0)
1304 cf_post_config()
1306 if (configure_keys(keylist_head))
1307 config_fail();
1309 if (configure_authinfo(authinfolist_head))
1310 config_fail();
1312 if (configure_ia(iapdlist_head, IATYPE_PD))
1313 config_fail();
1315 if (configure_ia(ianalist_head, IATYPE_NA))
1316 config_fail();
1318 if (configure_pool(addrpoollist_head))
1319 config_fail();
1321 if (configure_interface(iflist_head))
1322 config_fail();
1324 if (configure_host(hostlist_head))
1325 config_fail();
1327 if (configure_global_option())
1328 config_fail();
1330 configure_commit();
1331 cleanup();
1332 return (0);
1334 #undef config_fail
1336 void
1337 cf_init()
1339 iflist_head = NULL;