]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/setkey/parse.y
Update our copy of the Linux dts files to be in sync with Linux 4.5-rc1. We
[FreeBSD/FreeBSD.git] / sbin / setkey / parse.y
1 /*      $FreeBSD$       */
2 /*      $KAME: parse.y,v 1.83 2004/05/18 08:48:23 sakane Exp $  */
3
4 /*
5  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 %{
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/socket.h>
37
38 #include <net/route.h>
39 #include <netinet/in.h>
40 #include <net/pfkeyv2.h>
41 #include <netipsec/key_var.h>
42 #include <netipsec/ipsec.h>
43 #include <arpa/inet.h>
44
45 #include <string.h>
46 #include <unistd.h>
47 #include <stdio.h>
48 #include <netdb.h>
49 #include <ctype.h>
50 #include <errno.h>
51
52 #include "libpfkey.h"
53 #include "vchar.h"
54
55 #define ATOX(c) \
56   (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10)))
57
58 u_int32_t p_spi;
59 u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
60 u_int32_t p_reqid;
61 u_int p_key_enc_len, p_key_auth_len;
62 caddr_t p_key_enc, p_key_auth;
63 time_t p_lt_hard, p_lt_soft;
64
65 static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
66
67 static struct addrinfo *parse_addr(char *, char *);
68 static int fix_portstr(vchar_t *, vchar_t *, vchar_t *);
69 static int setvarbuf(char *, int *, struct sadb_ext *, int, caddr_t, int);
70 void parse_init(void);
71 void free_buffer(void);
72
73 int setkeymsg0(struct sadb_msg *, unsigned int, unsigned int, size_t);
74 static int setkeymsg_spdaddr(unsigned int, unsigned int, vchar_t *,
75         struct addrinfo *, int, struct addrinfo *, int);
76 static int setkeymsg_addr(unsigned int, unsigned int,
77         struct addrinfo *, struct addrinfo *, int);
78 static int setkeymsg_add(unsigned int, unsigned int,
79         struct addrinfo *, struct addrinfo *);
80 extern int setkeymsg(char *, size_t *);
81 extern int sendkeymsg(char *, size_t);
82
83 extern int yylex(void);
84 extern void yyfatal(const char *);
85 extern void yyerror(const char *);
86 %}
87
88 %union {
89         int num;
90         unsigned long ulnum;
91         vchar_t val;
92         struct addrinfo *res;
93 }
94
95 %token EOT SLASH BLCL ELCL
96 %token ADD GET DELETE DELETEALL FLUSH DUMP
97 %token PR_ESP PR_AH PR_IPCOMP PR_TCP
98 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
99 %token F_MODE MODE F_REQID
100 %token F_EXT EXTENSION NOCYCLICSEQ
101 %token ALG_AUTH ALG_AUTH_NOKEY
102 %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
103 %token ALG_ENC_SALT
104 %token ALG_COMP
105 %token F_LIFETIME_HARD F_LIFETIME_SOFT
106 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
107         /* SPD management */
108 %token SPDADD SPDDELETE SPDDUMP SPDFLUSH
109 %token F_POLICY PL_REQUESTS
110 %token F_AIFLAGS
111 %token TAGGED
112
113 %type <num> prefix protocol_spec upper_spec
114 %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
115 %type <num> ALG_ENC_SALT
116 %type <num> ALG_AUTH ALG_AUTH_NOKEY
117 %type <num> ALG_COMP
118 %type <num> PR_ESP PR_AH PR_IPCOMP PR_TCP
119 %type <num> EXTENSION MODE
120 %type <ulnum> DECSTRING
121 %type <val> PL_REQUESTS portstr key_string
122 %type <val> policy_requests
123 %type <val> QUOTEDSTRING HEXSTRING STRING
124 %type <val> F_AIFLAGS
125 %type <val> upper_misc_spec policy_spec
126 %type <res> ipaddr
127
128 %%
129 commands
130         :       /*NOTHING*/
131         |       commands command
132                 {
133                         free_buffer();
134                         parse_init();
135                 }
136         ;
137
138 command
139         :       add_command
140         |       get_command
141         |       delete_command
142         |       deleteall_command
143         |       flush_command
144         |       dump_command
145         |       spdadd_command
146         |       spddelete_command
147         |       spddump_command
148         |       spdflush_command
149         ;
150         /* commands concerned with management, there is in tail of this file. */
151
152         /* add command */
153 add_command
154         :       ADD ipaddropts ipaddr ipaddr protocol_spec spi extension_spec algorithm_spec EOT
155                 {
156                         int status;
157
158                         status = setkeymsg_add(SADB_ADD, $5, $3, $4);
159                         if (status < 0)
160                                 return -1;
161                 }
162         ;
163
164         /* delete */
165 delete_command
166         :       DELETE ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT
167                 {
168                         int status;
169
170                         if ($3->ai_next || $4->ai_next) {
171                                 yyerror("multiple address specified");
172                                 return -1;
173                         }
174                         if (p_mode != IPSEC_MODE_ANY)
175                                 yyerror("WARNING: mode is obsolete");
176
177                         status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0);
178                         if (status < 0)
179                                 return -1;
180                 }
181         ;
182
183         /* deleteall command */
184 deleteall_command
185         :       DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
186                 {
187                         int status;
188
189                         status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1);
190                         if (status < 0)
191                                 return -1;
192                 }
193         ;
194
195         /* get command */
196 get_command
197         :       GET ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT
198                 {
199                         int status;
200
201                         if (p_mode != IPSEC_MODE_ANY)
202                                 yyerror("WARNING: mode is obsolete");
203
204                         status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0);
205                         if (status < 0)
206                                 return -1;
207                 }
208         ;
209
210         /* flush */
211 flush_command
212         :       FLUSH protocol_spec EOT
213                 {
214                         struct sadb_msg msg;
215                         setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg));
216                         sendkeymsg((char *)&msg, sizeof(msg));
217                 }
218         ;
219
220         /* dump */
221 dump_command
222         :       DUMP protocol_spec EOT
223                 {
224                         struct sadb_msg msg;
225                         setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg));
226                         sendkeymsg((char *)&msg, sizeof(msg));
227                 }
228         ;
229
230 protocol_spec
231         :       /*NOTHING*/
232                 {
233                         $$ = SADB_SATYPE_UNSPEC;
234                 }
235         |       PR_ESP
236                 {
237                         $$ = SADB_SATYPE_ESP;
238                         if ($1 == 1)
239                                 p_ext |= SADB_X_EXT_OLD;
240                         else
241                                 p_ext &= ~SADB_X_EXT_OLD;
242                 }
243         |       PR_AH
244                 {
245                         $$ = SADB_SATYPE_AH;
246                         if ($1 == 1)
247                                 p_ext |= SADB_X_EXT_OLD;
248                         else
249                                 p_ext &= ~SADB_X_EXT_OLD;
250                 }
251         |       PR_IPCOMP
252                 {
253                         $$ = SADB_X_SATYPE_IPCOMP;
254                 }
255         |       PR_TCP
256                 {
257                         $$ = SADB_X_SATYPE_TCPSIGNATURE;
258                 }
259         ;
260
261 spi
262         :       DECSTRING { p_spi = $1; }
263         |       HEXSTRING
264                 {
265                         char *ep;
266                         unsigned long v;
267
268                         ep = NULL;
269                         v = strtoul($1.buf, &ep, 16);
270                         if (!ep || *ep) {
271                                 yyerror("invalid SPI");
272                                 return -1;
273                         }
274                         if (v & ~0xffffffff) {
275                                 yyerror("SPI too big.");
276                                 return -1;
277                         }
278
279                         p_spi = v;
280                 }
281         ;
282
283 algorithm_spec
284         :       esp_spec
285         |       ah_spec
286         |       ipcomp_spec
287         ;
288
289 esp_spec
290         :       F_ENC enc_alg F_AUTH auth_alg
291         |       F_ENC enc_alg
292         ;
293
294 ah_spec
295         :       F_AUTH auth_alg
296         ;
297
298 ipcomp_spec
299         :       F_COMP ALG_COMP
300                 {
301                         if ($2 < 0) {
302                                 yyerror("unsupported algorithm");
303                                 return -1;
304                         }
305                         p_alg_enc = $2;
306                 }
307         |       F_COMP ALG_COMP F_RAWCPI
308                 {
309                         if ($2 < 0) {
310                                 yyerror("unsupported algorithm");
311                                 return -1;
312                         }
313                         p_alg_enc = $2;
314                         p_ext |= SADB_X_EXT_RAWCPI;
315                 }
316         ;
317
318 enc_alg
319         :       ALG_ENC_NOKEY {
320                         if ($1 < 0) {
321                                 yyerror("unsupported algorithm");
322                                 return -1;
323                         }
324                         p_alg_enc = $1;
325
326                         p_key_enc_len = 0;
327                         p_key_enc = NULL;
328                         if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
329                             p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
330                                 yyerror(ipsec_strerror());
331                                 return -1;
332                         }
333                 }
334         |       ALG_ENC key_string {
335                         if ($1 < 0) {
336                                 yyerror("unsupported algorithm");
337                                 return -1;
338                         }
339                         p_alg_enc = $1;
340
341                         p_key_enc_len = $2.len;
342                         p_key_enc = $2.buf;
343                         if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
344                             p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
345                                 yyerror(ipsec_strerror());
346                                 return -1;
347                         }
348                 }
349         |       ALG_ENC_OLD {
350                         if ($1 < 0) {
351                                 yyerror("unsupported algorithm");
352                                 return -1;
353                         }
354                         yyerror("WARNING: obsolete algorithm");
355                         p_alg_enc = $1;
356
357                         p_key_enc_len = 0;
358                         p_key_enc = NULL;
359                         if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
360                             p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
361                                 yyerror(ipsec_strerror());
362                                 return -1;
363                         }
364                 }
365         |       ALG_ENC_DESDERIV key_string
366                 {
367                         if ($1 < 0) {
368                                 yyerror("unsupported algorithm");
369                                 return -1;
370                         }
371                         p_alg_enc = $1;
372                         if (p_ext & SADB_X_EXT_OLD) {
373                                 yyerror("algorithm mismatched");
374                                 return -1;
375                         }
376                         p_ext |= SADB_X_EXT_DERIV;
377
378                         p_key_enc_len = $2.len;
379                         p_key_enc = $2.buf;
380                         if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
381                             p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
382                                 yyerror(ipsec_strerror());
383                                 return -1;
384                         }
385                 }
386         |       ALG_ENC_DES32IV key_string
387                 {
388                         if ($1 < 0) {
389                                 yyerror("unsupported algorithm");
390                                 return -1;
391                         }
392                         p_alg_enc = $1;
393                         if (!(p_ext & SADB_X_EXT_OLD)) {
394                                 yyerror("algorithm mismatched");
395                                 return -1;
396                         }
397                         p_ext |= SADB_X_EXT_IV4B;
398
399                         p_key_enc_len = $2.len;
400                         p_key_enc = $2.buf;
401                         if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
402                             p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
403                                 yyerror(ipsec_strerror());
404                                 return -1;
405                         }
406                 }
407         |       ALG_ENC_SALT key_string
408                 {
409                         if ($1 < 0) {
410                                 yyerror("unsupported algorithm");
411                                 return -1;
412                         }
413                         p_alg_enc = $1;
414
415                         p_key_enc_len = $2.len;
416
417                         p_key_enc = $2.buf;
418                         /*
419                          * Salted keys include a 4 byte value that is
420                          * not part of the key.
421                          */
422                         if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
423                             p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len - 4)) < 0) {
424                                 yyerror(ipsec_strerror());
425                                 return -1;
426                         }
427                 }
428         ;
429
430 auth_alg
431         :       ALG_AUTH key_string {
432                         if ($1 < 0) {
433                                 yyerror("unsupported algorithm");
434                                 return -1;
435                         }
436                         p_alg_auth = $1;
437
438                         p_key_auth_len = $2.len;
439                         p_key_auth = $2.buf;
440
441                         if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
442                                 if ((p_key_auth_len < 1) || (p_key_auth_len >
443                                     80))
444                                         return -1;
445                         } else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
446                             p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
447                                 yyerror(ipsec_strerror());
448                                 return -1;
449                         }
450                 }
451         |       ALG_AUTH_NOKEY {
452                         if ($1 < 0) {
453                                 yyerror("unsupported algorithm");
454                                 return -1;
455                         }
456                         p_alg_auth = $1;
457
458                         p_key_auth_len = 0;
459                         p_key_auth = NULL;
460                 }
461         ;
462
463 key_string
464         :       QUOTEDSTRING
465                 {
466                         $$ = $1;
467                 }
468         |       HEXSTRING
469                 {
470                         caddr_t pp_key;
471                         caddr_t bp;
472                         caddr_t yp = $1.buf;
473                         int l;
474
475                         l = strlen(yp) % 2 + strlen(yp) / 2;
476                         if ((pp_key = malloc(l)) == 0) {
477                                 yyerror("not enough core");
478                                 return -1;
479                         }
480                         memset(pp_key, 0, l);
481
482                         bp = pp_key;
483                         if (strlen(yp) % 2) {
484                                 *bp = ATOX(yp[0]);
485                                 yp++, bp++;
486                         }
487                         while (*yp) {
488                                 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
489                                 yp += 2, bp++;
490                         }
491
492                         $$.len = l;
493                         $$.buf = pp_key;
494                 }
495         ;
496
497 extension_spec
498         :       /*NOTHING*/
499         |       extension_spec extension
500         ;
501
502 extension
503         :       F_EXT EXTENSION { p_ext |= $2; }
504         |       F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
505         |       F_MODE MODE { p_mode = $2; }
506         |       F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
507         |       F_REQID DECSTRING { p_reqid = $2; }
508         |       F_REPLAY DECSTRING
509                 {
510                         if ((p_ext & SADB_X_EXT_OLD) != 0) {
511                                 yyerror("replay prevention cannot be used with "
512                                     "ah/esp-old");
513                                 return -1;
514                         }
515                         p_replay = $2;
516                 }
517         |       F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
518         |       F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
519         ;
520
521         /* definition about command for SPD management */
522         /* spdadd */
523 spdadd_command
524         :       SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
525                 {
526                         int status;
527                         struct addrinfo *src, *dst;
528
529                         /* fixed port fields if ulp is icmpv6 */
530                         if ($10.buf != NULL) {
531                                 if ($9 != IPPROTO_ICMPV6)
532                                         return -1;
533                                 free($5.buf);
534                                 free($8.buf);
535                                 if (fix_portstr(&$10, &$5, &$8))
536                                         return -1;
537                         }
538
539                         src = parse_addr($3.buf, $5.buf);
540                         dst = parse_addr($6.buf, $8.buf);
541                         if (!src || !dst) {
542                                 /* yyerror is already called */
543                                 return -1;
544                         }
545                         if (src->ai_next || dst->ai_next) {
546                                 yyerror("multiple address specified");
547                                 freeaddrinfo(src);
548                                 freeaddrinfo(dst);
549                                 return -1;
550                         }
551
552                         status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11,
553                             src, $4, dst, $7);
554                         freeaddrinfo(src);
555                         freeaddrinfo(dst);
556                         if (status < 0)
557                                 return -1;
558                 }
559         |       SPDADD TAGGED QUOTEDSTRING policy_spec EOT
560                 {
561                         return -1;
562                 }
563         ;
564
565 spddelete_command
566         :       SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
567                 {
568                         int status;
569                         struct addrinfo *src, *dst;
570
571                         /* fixed port fields if ulp is icmpv6 */
572                         if ($10.buf != NULL) {
573                                 if ($9 != IPPROTO_ICMPV6)
574                                         return -1;
575                                 free($5.buf);
576                                 free($8.buf);
577                                 if (fix_portstr(&$10, &$5, &$8))
578                                         return -1;
579                         }
580
581                         src = parse_addr($3.buf, $5.buf);
582                         dst = parse_addr($6.buf, $8.buf);
583                         if (!src || !dst) {
584                                 /* yyerror is already called */
585                                 return -1;
586                         }
587                         if (src->ai_next || dst->ai_next) {
588                                 yyerror("multiple address specified");
589                                 freeaddrinfo(src);
590                                 freeaddrinfo(dst);
591                                 return -1;
592                         }
593
594                         status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11,
595                             src, $4, dst, $7);
596                         freeaddrinfo(src);
597                         freeaddrinfo(dst);
598                         if (status < 0)
599                                 return -1;
600                 }
601         ;
602
603 spddump_command:
604                 SPDDUMP EOT
605                 {
606                         struct sadb_msg msg;
607                         setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC,
608                             sizeof(msg));
609                         sendkeymsg((char *)&msg, sizeof(msg));
610                 }
611         ;
612
613 spdflush_command:
614                 SPDFLUSH EOT
615                 {
616                         struct sadb_msg msg;
617                         setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC,
618                             sizeof(msg));
619                         sendkeymsg((char *)&msg, sizeof(msg));
620                 }
621         ;
622
623 ipaddropts
624         :       /* nothing */
625         |       ipaddropts ipaddropt
626         ;
627
628 ipaddropt
629         :       F_AIFLAGS
630                 {
631                         char *p;
632
633                         for (p = $1.buf + 1; *p; p++)
634                                 switch (*p) {
635                                 case '4':
636                                         p_aifamily = AF_INET;
637                                         break;
638 #ifdef INET6
639                                 case '6':
640                                         p_aifamily = AF_INET6;
641                                         break;
642 #endif
643                                 case 'n':
644                                         p_aiflags = AI_NUMERICHOST;
645                                         break;
646                                 default:
647                                         yyerror("invalid flag");
648                                         return -1;
649                                 }
650                 }
651         ;
652
653 ipaddr
654         :       STRING
655                 {
656                         $$ = parse_addr($1.buf, NULL);
657                         if ($$ == NULL) {
658                                 /* yyerror already called by parse_addr */
659                                 return -1;
660                         }
661                 }
662         ;
663
664 prefix
665         :       /*NOTHING*/ { $$ = -1; }
666         |       SLASH DECSTRING { $$ = $2; }
667         ;
668
669 portstr
670         :       /*NOTHING*/
671                 {
672                         $$.buf = strdup("0");
673                         if (!$$.buf) {
674                                 yyerror("insufficient memory");
675                                 return -1;
676                         }
677                         $$.len = strlen($$.buf);
678                 }
679         |       BLCL ANY ELCL
680                 {
681                         $$.buf = strdup("0");
682                         if (!$$.buf) {
683                                 yyerror("insufficient memory");
684                                 return -1;
685                         }
686                         $$.len = strlen($$.buf);
687                 }
688         |       BLCL DECSTRING ELCL
689                 {
690                         char buf[20];
691                         snprintf(buf, sizeof(buf), "%lu", $2);
692                         $$.buf = strdup(buf);
693                         if (!$$.buf) {
694                                 yyerror("insufficient memory");
695                                 return -1;
696                         }
697                         $$.len = strlen($$.buf);
698                 }
699         |       BLCL STRING ELCL
700                 {
701                         $$ = $2;
702                 }
703         ;
704
705 upper_spec
706         :       DECSTRING { $$ = $1; }
707         |       ANY { $$ = IPSEC_ULPROTO_ANY; }
708         |       PR_TCP { $$ = IPPROTO_TCP; }
709         |       PR_ESP { $$ = IPPROTO_ESP; }
710         |       STRING
711                 {
712                         struct protoent *ent;
713
714                         ent = getprotobyname($1.buf);
715                         if (ent)
716                                 $$ = ent->p_proto;
717                         else {
718                                 if (strcmp("icmp6", $1.buf) == 0) {
719                                         $$ = IPPROTO_ICMPV6;
720                                 } else if(strcmp("ip4", $1.buf) == 0) {
721                                         $$ = IPPROTO_IPV4;
722                                 } else {
723                                         yyerror("invalid upper layer protocol");
724                                         return -1;
725                                 }
726                         }
727                         endprotoent();
728                 }
729         ;
730
731 upper_misc_spec
732         :       /*NOTHING*/
733                 {
734                         $$.buf = NULL;
735                         $$.len = 0;
736                 }
737         |       STRING
738                 {
739                         $$.buf = strdup($1.buf);
740                         if (!$$.buf) {
741                                 yyerror("insufficient memory");
742                                 return -1;
743                         }
744                         $$.len = strlen($$.buf);
745                 }
746         ;
747
748 policy_spec
749         :       F_POLICY policy_requests
750                 {
751                         char *policy;
752
753                         policy = ipsec_set_policy($2.buf, $2.len);
754                         if (policy == NULL) {
755                                 yyerror(ipsec_strerror());
756                                 return -1;
757                         }
758
759                         $$.buf = policy;
760                         $$.len = ipsec_get_policylen(policy);
761                 }
762         ;
763
764 policy_requests
765         :       PL_REQUESTS { $$ = $1; }
766         ;
767
768 %%
769
770 int
771 setkeymsg0(msg, type, satype, l)
772         struct sadb_msg *msg;
773         unsigned int type;
774         unsigned int satype;
775         size_t l;
776 {
777
778         msg->sadb_msg_version = PF_KEY_V2;
779         msg->sadb_msg_type = type;
780         msg->sadb_msg_errno = 0;
781         msg->sadb_msg_satype = satype;
782         msg->sadb_msg_reserved = 0;
783         msg->sadb_msg_seq = 0;
784         msg->sadb_msg_pid = getpid();
785         msg->sadb_msg_len = PFKEY_UNIT64(l);
786         return 0;
787 }
788
789 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
790 static int
791 setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen)
792         unsigned int type;
793         unsigned int upper;
794         vchar_t *policy;
795         struct addrinfo *srcs;
796         int splen;
797         struct addrinfo *dsts;
798         int dplen;
799 {
800         struct sadb_msg *msg;
801         char buf[BUFSIZ];
802         int l, l0;
803         struct sadb_address m_addr;
804         struct addrinfo *s, *d;
805         int n;
806         int plen;
807         struct sockaddr *sa;
808         int salen;
809
810         msg = (struct sadb_msg *)buf;
811
812         if (!srcs || !dsts)
813                 return -1;
814
815         /* fix up length afterwards */
816         setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
817         l = sizeof(struct sadb_msg);
818
819         memcpy(buf + l, policy->buf, policy->len);
820         l += policy->len;
821
822         l0 = l;
823         n = 0;
824
825         /* do it for all src/dst pairs */
826         for (s = srcs; s; s = s->ai_next) {
827                 for (d = dsts; d; d = d->ai_next) {
828                         /* rewind pointer */
829                         l = l0;
830
831                         if (s->ai_addr->sa_family != d->ai_addr->sa_family)
832                                 continue;
833                         switch (s->ai_addr->sa_family) {
834                         case AF_INET:
835                                 plen = sizeof(struct in_addr) << 3;
836                                 break;
837 #ifdef INET6
838                         case AF_INET6:
839                                 plen = sizeof(struct in6_addr) << 3;
840                                 break;
841 #endif
842                         default:
843                                 continue;
844                         }
845
846                         /* set src */
847                         sa = s->ai_addr;
848                         salen = s->ai_addr->sa_len;
849                         m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
850                             PFKEY_ALIGN8(salen));
851                         m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
852                         m_addr.sadb_address_proto = upper;
853                         m_addr.sadb_address_prefixlen =
854                             (splen >= 0 ? splen : plen);
855                         m_addr.sadb_address_reserved = 0;
856
857                         setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
858                             sizeof(m_addr), (caddr_t)sa, salen);
859
860                         /* set dst */
861                         sa = d->ai_addr;
862                         salen = d->ai_addr->sa_len;
863                         m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
864                             PFKEY_ALIGN8(salen));
865                         m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
866                         m_addr.sadb_address_proto = upper;
867                         m_addr.sadb_address_prefixlen =
868                             (dplen >= 0 ? dplen : plen);
869                         m_addr.sadb_address_reserved = 0;
870
871                         setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
872                             sizeof(m_addr), (caddr_t)sa, salen);
873
874                         msg->sadb_msg_len = PFKEY_UNIT64(l);
875
876                         sendkeymsg(buf, l);
877
878                         n++;
879                 }
880         }
881
882         if (n == 0)
883                 return -1;
884         else
885                 return 0;
886 }
887
888 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
889 static int
890 setkeymsg_addr(type, satype, srcs, dsts, no_spi)
891         unsigned int type;
892         unsigned int satype;
893         struct addrinfo *srcs;
894         struct addrinfo *dsts;
895         int no_spi;
896 {
897         struct sadb_msg *msg;
898         char buf[BUFSIZ];
899         int l, l0, len;
900         struct sadb_sa m_sa;
901         struct sadb_x_sa2 m_sa2;
902         struct sadb_address m_addr;
903         struct addrinfo *s, *d;
904         int n;
905         int plen;
906         struct sockaddr *sa;
907         int salen;
908
909         msg = (struct sadb_msg *)buf;
910
911         if (!srcs || !dsts)
912                 return -1;
913
914         /* fix up length afterwards */
915         setkeymsg0(msg, type, satype, 0);
916         l = sizeof(struct sadb_msg);
917
918         if (!no_spi) {
919                 len = sizeof(struct sadb_sa);
920                 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
921                 m_sa.sadb_sa_exttype = SADB_EXT_SA;
922                 m_sa.sadb_sa_spi = htonl(p_spi);
923                 m_sa.sadb_sa_replay = p_replay;
924                 m_sa.sadb_sa_state = 0;
925                 m_sa.sadb_sa_auth = p_alg_auth;
926                 m_sa.sadb_sa_encrypt = p_alg_enc;
927                 m_sa.sadb_sa_flags = p_ext;
928
929                 memcpy(buf + l, &m_sa, len);
930                 l += len;
931
932                 len = sizeof(struct sadb_x_sa2);
933                 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
934                 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
935                 m_sa2.sadb_x_sa2_mode = p_mode;
936                 m_sa2.sadb_x_sa2_reqid = p_reqid;
937
938                 memcpy(buf + l, &m_sa2, len);
939                 l += len;
940         }
941
942         l0 = l;
943         n = 0;
944
945         /* do it for all src/dst pairs */
946         for (s = srcs; s; s = s->ai_next) {
947                 for (d = dsts; d; d = d->ai_next) {
948                         /* rewind pointer */
949                         l = l0;
950
951                         if (s->ai_addr->sa_family != d->ai_addr->sa_family)
952                                 continue;
953                         switch (s->ai_addr->sa_family) {
954                         case AF_INET:
955                                 plen = sizeof(struct in_addr) << 3;
956                                 break;
957 #ifdef INET6
958                         case AF_INET6:
959                                 plen = sizeof(struct in6_addr) << 3;
960                                 break;
961 #endif
962                         default:
963                                 continue;
964                         }
965
966                         /* set src */
967                         sa = s->ai_addr;
968                         salen = s->ai_addr->sa_len;
969                         m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
970                             PFKEY_ALIGN8(salen));
971                         m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
972                         m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
973                         m_addr.sadb_address_prefixlen = plen;
974                         m_addr.sadb_address_reserved = 0;
975
976                         setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
977                             sizeof(m_addr), (caddr_t)sa, salen);
978
979                         /* set dst */
980                         sa = d->ai_addr;
981                         salen = d->ai_addr->sa_len;
982                         m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
983                             PFKEY_ALIGN8(salen));
984                         m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
985                         m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
986                         m_addr.sadb_address_prefixlen = plen;
987                         m_addr.sadb_address_reserved = 0;
988
989                         setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
990                             sizeof(m_addr), (caddr_t)sa, salen);
991
992                         msg->sadb_msg_len = PFKEY_UNIT64(l);
993
994                         sendkeymsg(buf, l);
995
996                         n++;
997                 }
998         }
999
1000         if (n == 0)
1001                 return -1;
1002         else
1003                 return 0;
1004 }
1005
1006 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1007 static int
1008 setkeymsg_add(type, satype, srcs, dsts)
1009         unsigned int type;
1010         unsigned int satype;
1011         struct addrinfo *srcs;
1012         struct addrinfo *dsts;
1013 {
1014         struct sadb_msg *msg;
1015         char buf[BUFSIZ];
1016         int l, l0, len;
1017         struct sadb_sa m_sa;
1018         struct sadb_x_sa2 m_sa2;
1019         struct sadb_address m_addr;
1020         struct addrinfo *s, *d;
1021         int n;
1022         int plen;
1023         struct sockaddr *sa;
1024         int salen;
1025
1026         msg = (struct sadb_msg *)buf;
1027
1028         if (!srcs || !dsts)
1029                 return -1;
1030
1031         /* fix up length afterwards */
1032         setkeymsg0(msg, type, satype, 0);
1033         l = sizeof(struct sadb_msg);
1034
1035         /* set encryption algorithm, if present. */
1036         if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1037                 struct sadb_key m_key;
1038
1039                 m_key.sadb_key_len =
1040                         PFKEY_UNIT64(sizeof(m_key)
1041                                    + PFKEY_ALIGN8(p_key_enc_len));
1042                 m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1043                 m_key.sadb_key_bits = p_key_enc_len * 8;
1044                 m_key.sadb_key_reserved = 0;
1045
1046                 setvarbuf(buf, &l,
1047                         (struct sadb_ext *)&m_key, sizeof(m_key),
1048                         (caddr_t)p_key_enc, p_key_enc_len);
1049         }
1050
1051         /* set authentication algorithm, if present. */
1052         if (p_key_auth) {
1053                 struct sadb_key m_key;
1054
1055                 m_key.sadb_key_len =
1056                         PFKEY_UNIT64(sizeof(m_key)
1057                                    + PFKEY_ALIGN8(p_key_auth_len));
1058                 m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1059                 m_key.sadb_key_bits = p_key_auth_len * 8;
1060                 m_key.sadb_key_reserved = 0;
1061
1062                 setvarbuf(buf, &l,
1063                         (struct sadb_ext *)&m_key, sizeof(m_key),
1064                         (caddr_t)p_key_auth, p_key_auth_len);
1065         }
1066
1067         /* set lifetime for HARD */
1068         if (p_lt_hard != 0) {
1069                 struct sadb_lifetime m_lt;
1070                 u_int slen = sizeof(struct sadb_lifetime);
1071
1072                 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1073                 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1074                 m_lt.sadb_lifetime_allocations = 0;
1075                 m_lt.sadb_lifetime_bytes = 0;
1076                 m_lt.sadb_lifetime_addtime = p_lt_hard;
1077                 m_lt.sadb_lifetime_usetime = 0;
1078
1079                 memcpy(buf + l, &m_lt, slen);
1080                 l += slen;
1081         }
1082
1083         /* set lifetime for SOFT */
1084         if (p_lt_soft != 0) {
1085                 struct sadb_lifetime m_lt;
1086                 u_int slen = sizeof(struct sadb_lifetime);
1087
1088                 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1089                 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1090                 m_lt.sadb_lifetime_allocations = 0;
1091                 m_lt.sadb_lifetime_bytes = 0;
1092                 m_lt.sadb_lifetime_addtime = p_lt_soft;
1093                 m_lt.sadb_lifetime_usetime = 0;
1094
1095                 memcpy(buf + l, &m_lt, slen);
1096                 l += slen;
1097         }
1098
1099         len = sizeof(struct sadb_sa);
1100         m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1101         m_sa.sadb_sa_exttype = SADB_EXT_SA;
1102         m_sa.sadb_sa_spi = htonl(p_spi);
1103         m_sa.sadb_sa_replay = p_replay;
1104         m_sa.sadb_sa_state = 0;
1105         m_sa.sadb_sa_auth = p_alg_auth;
1106         m_sa.sadb_sa_encrypt = p_alg_enc;
1107         m_sa.sadb_sa_flags = p_ext;
1108
1109         memcpy(buf + l, &m_sa, len);
1110         l += len;
1111
1112         len = sizeof(struct sadb_x_sa2);
1113         m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1114         m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1115         m_sa2.sadb_x_sa2_mode = p_mode;
1116         m_sa2.sadb_x_sa2_reqid = p_reqid;
1117
1118         memcpy(buf + l, &m_sa2, len);
1119         l += len;
1120
1121         l0 = l;
1122         n = 0;
1123
1124         /* do it for all src/dst pairs */
1125         for (s = srcs; s; s = s->ai_next) {
1126                 for (d = dsts; d; d = d->ai_next) {
1127                         /* rewind pointer */
1128                         l = l0;
1129
1130                         if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1131                                 continue;
1132                         switch (s->ai_addr->sa_family) {
1133                         case AF_INET:
1134                                 plen = sizeof(struct in_addr) << 3;
1135                                 break;
1136 #ifdef INET6
1137                         case AF_INET6:
1138                                 plen = sizeof(struct in6_addr) << 3;
1139                                 break;
1140 #endif
1141                         default:
1142                                 continue;
1143                         }
1144
1145                         /* set src */
1146                         sa = s->ai_addr;
1147                         salen = s->ai_addr->sa_len;
1148                         m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1149                             PFKEY_ALIGN8(salen));
1150                         m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1151                         m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1152                         m_addr.sadb_address_prefixlen = plen;
1153                         m_addr.sadb_address_reserved = 0;
1154
1155                         setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1156                             sizeof(m_addr), (caddr_t)sa, salen);
1157
1158                         /* set dst */
1159                         sa = d->ai_addr;
1160                         salen = d->ai_addr->sa_len;
1161                         m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1162                             PFKEY_ALIGN8(salen));
1163                         m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1164                         m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1165                         m_addr.sadb_address_prefixlen = plen;
1166                         m_addr.sadb_address_reserved = 0;
1167
1168                         setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1169                             sizeof(m_addr), (caddr_t)sa, salen);
1170
1171                         msg->sadb_msg_len = PFKEY_UNIT64(l);
1172
1173                         sendkeymsg(buf, l);
1174
1175                         n++;
1176                 }
1177         }
1178
1179         if (n == 0)
1180                 return -1;
1181         else
1182                 return 0;
1183 }
1184
1185 static struct addrinfo *
1186 parse_addr(host, port)
1187         char *host;
1188         char *port;
1189 {
1190         struct addrinfo hints, *res = NULL;
1191         int error;
1192
1193         memset(&hints, 0, sizeof(hints));
1194         hints.ai_family = p_aifamily;
1195         hints.ai_socktype = SOCK_DGRAM;         /*dummy*/
1196         hints.ai_protocol = IPPROTO_UDP;        /*dummy*/
1197         hints.ai_flags = p_aiflags;
1198         error = getaddrinfo(host, port, &hints, &res);
1199         if (error != 0) {
1200                 yyerror(gai_strerror(error));
1201                 return NULL;
1202         }
1203         return res;
1204 }
1205
1206 static int
1207 fix_portstr(spec, sport, dport)
1208         vchar_t *spec, *sport, *dport;
1209 {
1210         char *p, *p2;
1211         u_int l;
1212
1213         l = 0;
1214         for (p = spec->buf; *p != ',' && *p != '\0' && l < spec->len; p++, l++)
1215                 ;
1216         if (*p == '\0') {
1217                 p2 = "0";
1218         } else {
1219                 if (*p == ',') {
1220                         *p = '\0';
1221                         p2 = ++p;
1222                 }
1223                 for (p = p2; *p != '\0' && l < spec->len; p++, l++)
1224                         ;
1225                 if (*p != '\0' || *p2 == '\0') {
1226                         yyerror("invalid an upper layer protocol spec");
1227                         return -1;
1228                 }
1229         }
1230
1231         sport->buf = strdup(spec->buf);
1232         if (!sport->buf) {
1233                 yyerror("insufficient memory");
1234                 return -1;
1235         }
1236         sport->len = strlen(sport->buf);
1237         dport->buf = strdup(p2);
1238         if (!dport->buf) {
1239                 yyerror("insufficient memory");
1240                 return -1;
1241         }
1242         dport->len = strlen(dport->buf);
1243
1244         return 0;
1245 }
1246
1247 static int
1248 setvarbuf(buf, off, ebuf, elen, vbuf, vlen)
1249         char *buf;
1250         int *off;
1251         struct sadb_ext *ebuf;
1252         int elen;
1253         caddr_t vbuf;
1254         int vlen;
1255 {
1256         memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1257         memcpy(buf + *off, (caddr_t)ebuf, elen);
1258         memcpy(buf + *off + elen, vbuf, vlen);
1259         (*off) += PFKEY_ALIGN8(elen + vlen);
1260
1261         return 0;
1262 }
1263
1264 void
1265 parse_init()
1266 {
1267         p_spi = 0;
1268
1269         p_ext = SADB_X_EXT_CYCSEQ;
1270         p_alg_enc = SADB_EALG_NONE;
1271         p_alg_auth = SADB_AALG_NONE;
1272         p_mode = IPSEC_MODE_ANY;
1273         p_reqid = 0;
1274         p_replay = 0;
1275         p_key_enc_len = p_key_auth_len = 0;
1276         p_key_enc = p_key_auth = 0;
1277         p_lt_hard = p_lt_soft = 0;
1278
1279         p_aiflags = 0;
1280         p_aifamily = PF_UNSPEC;
1281
1282         return;
1283 }
1284
1285 void
1286 free_buffer()
1287 {
1288         /* we got tons of memory leaks in the parser anyways, leave them */
1289
1290         return;
1291 }