4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 #include <sys/types.h>
29 #include <sys/errno.h>
31 #include <ipsec_util.h>
43 static rwlock_t proto_rw
= DEFAULTRWLOCK
; /* Protects cached algorithm list. */
44 static time_t proto_last_update
;
45 static ipsec_proto_t
*protos
;
46 static int num_protos
;
49 _clean_trash(ipsec_proto_t
*proto
, int num
)
57 free(proto
[num
].proto_name
);
58 free(proto
[num
].proto_pkg
);
59 for (alg_offset
= 0; alg_offset
< proto
[num
].proto_numalgs
;
61 freeipsecalgent(proto
[num
].proto_algs
[alg_offset
]);
62 free(proto
[num
].proto_algs
);
63 for (alg_offset
= 0; alg_offset
< proto
[num
].proto_algs_npkgs
;
65 free(proto
[num
].proto_algs_pkgs
[alg_offset
].pkg_name
);
66 free(proto
[num
].proto_algs_pkgs
);
72 static const char *pipechar
= "|";
73 static const char *comma
= ",";
74 static const char *dash
= "-";
75 static const char *slash
= "/";
78 * Returns >= 0 if success (and > 0 means "increment").
79 * Returns -1 if failure.
82 build_keysizes(int **sizep
, char *input_string
)
85 int *key_sizes
= NULL
, num_sizes
, key_low
, key_high
, key_default
;
86 int key_increment
= 0;
89 * Okay, let's check the format of the key string. It'll be either:
91 * enumeration: size1,size2...,sizeN
92 * range: defaultSize/sizeLow-sizeHi,increment
94 * In the case of an enumeration, the default key size is the
95 * first one in the list.
98 if (strchr(input_string
, '/') != NULL
) {
99 /* key sizes specified by range */
102 token
= strtok_r(input_string
, slash
, &lasts
);
103 if (token
== NULL
|| (key_default
= atoi(token
)) == 0)
107 token
= strtok_r(NULL
, dash
, &lasts
);
108 if (token
== NULL
|| (key_low
= atoi(token
)) == 0)
112 token
= strtok_r(NULL
, comma
, &lasts
);
113 if (token
== NULL
|| (key_high
= atoi(token
)) == 0 ||
118 token
= strtok_r(NULL
, "", &lasts
);
119 if (token
== NULL
|| (key_increment
= atoi(token
)) == 0)
122 key_sizes
= (int *)malloc(LIBIPSEC_ALGS_KEY_NUM_VAL
*
124 if (key_sizes
== NULL
)
127 key_sizes
[LIBIPSEC_ALGS_KEY_DEF_IDX
] = key_default
;
128 key_sizes
[LIBIPSEC_ALGS_KEY_MIN_IDX
] = key_low
;
129 key_sizes
[LIBIPSEC_ALGS_KEY_MAX_IDX
] = key_high
;
130 key_sizes
[LIBIPSEC_ALGS_KEY_MAX_IDX
+ 1] = 0;
132 /* key sizes specified by enumeration */
134 key_sizes
= (int *)malloc(sizeof (int));
135 if (key_sizes
== NULL
)
139 token
= strtok_r(input_string
, comma
, &lasts
);
148 nks
= reallocarray(key_sizes
,
149 (++num_sizes
) + 1, sizeof (int));
155 /* Can't check for atoi() == 0 here... */
156 key_sizes
[num_sizes
- 1] = atoi(token
);
157 key_sizes
[num_sizes
] = 0;
158 } while ((token
= strtok_r(NULL
, comma
, &lasts
)) != NULL
);
162 return (key_increment
);
166 * Find the execution mode corresponding to the given string.
167 * Returns 0 on success, -1 on failure.
170 _str_to_ipsec_exec_mode(char *str
, ipsecalgs_exec_mode_t
*exec_mode
)
172 if (strcmp(str
, "sync") == 0) {
173 *exec_mode
= LIBIPSEC_ALGS_EXEC_SYNC
;
175 } else if (strcmp(str
, "async") == 0) {
176 *exec_mode
= LIBIPSEC_ALGS_EXEC_ASYNC
;
184 * Given a file pointer, read all the text from the file and convert it into
185 * a bunch of ipsec_proto_t's, each with an array of struct ipsecalgent
186 * pointers - one for each algorithm.
188 static ipsec_proto_t
*
189 build_list(FILE *f
, int *num
)
192 char *token
, *lasts
, *alg_names
, *ef_name
, *key_string
, *block_string
;
193 char *proto_name
, *params_string
;
194 ipsec_proto_t
*rc
= NULL
, *new_proto
= NULL
;
195 int *block_sizes
= NULL
, *key_sizes
= NULL
, *mech_params
= NULL
;
196 int rc_num
= 0, key_increment
;
197 int new_num
, alg_num
, num_sizes
, flags
= 0;
198 struct ipsecalgent
*curalg
, **newalglist
;
200 boolean_t doing_pkg
= B_FALSE
;
201 ipsecalgs_exec_mode_t exec_mode
;
206 while (fgets(line
, sizeof (line
), f
) != NULL
) {
207 if (strncasecmp(line
, LIBIPSEC_ALGS_LINE_PROTO
,
208 sizeof (LIBIPSEC_ALGS_LINE_PROTO
) - 1) != 0 &&
209 strncasecmp(line
, LIBIPSEC_ALGS_LINE_ALG
,
210 sizeof (LIBIPSEC_ALGS_LINE_ALG
) - 1) != 0 &&
211 strncasecmp(line
, LIBIPSEC_ALGS_LINE_PKGSTART
,
212 sizeof (LIBIPSEC_ALGS_LINE_PKGSTART
) - 1) != 0 &&
213 strncasecmp(line
, LIBIPSEC_ALGS_LINE_PKGEND
,
214 sizeof (LIBIPSEC_ALGS_LINE_PKGEND
) - 1) != 0) {
215 if ((token
= strtok_r(line
, " \t\n", &lasts
)) == NULL
||
219 (void) snprintf(diag_buf
, sizeof (diag_buf
),
220 "non-recognized start of line");
225 if (strncasecmp(line
, LIBIPSEC_ALGS_LINE_PROTO
,
226 sizeof (LIBIPSEC_ALGS_LINE_PROTO
) - 1) == 0) {
227 /* current line defines a new protocol */
229 /* skip the protocol token */
230 token
= strtok_r(line
, pipechar
, &lasts
);
232 /* protocol number */
233 token
= strtok_r(NULL
, pipechar
, &lasts
);
234 if (token
== NULL
|| (new_num
= atoi(token
)) == 0) {
235 (void) snprintf(diag_buf
, sizeof (diag_buf
),
236 "invalid protocol number");
241 token
= strtok_r(NULL
, pipechar
, &lasts
);
243 (void) snprintf(diag_buf
, sizeof (diag_buf
),
244 "cannot read protocol name");
250 token
= strtok_r(NULL
, pipechar
, &lasts
);
252 (void) snprintf(diag_buf
, sizeof (diag_buf
),
253 "cannot read execution mode");
256 /* remove trailing '\n' */
257 token
[strlen(token
) - 1] = '\0';
258 if (_str_to_ipsec_exec_mode(token
, &exec_mode
) != 0) {
259 (void) snprintf(diag_buf
, sizeof (diag_buf
),
260 "invalid execution mode: \"%s\"", token
);
264 /* initialize protocol structure */
266 new_proto
= reallocarray(rc
, rc_num
,
267 sizeof (ipsec_proto_t
));
269 if (new_proto
== NULL
)
271 new_proto
+= (rc_num
- 1);
272 new_proto
->proto_num
= new_num
;
273 new_proto
->proto_algs
= NULL
;
274 new_proto
->proto_numalgs
= 0;
275 new_proto
->proto_name
= strdup(proto_name
);
276 if (new_proto
->proto_name
== NULL
)
278 new_proto
->proto_exec_mode
= exec_mode
;
281 /* record proto as being part of current pkg */
282 new_proto
->proto_pkg
= strdup(cur_pkg
);
283 if (new_proto
->proto_pkg
== NULL
)
286 new_proto
->proto_pkg
= NULL
;
289 new_proto
->proto_algs_pkgs
= NULL
;
290 new_proto
->proto_algs_npkgs
= 0;
292 } else if (strncasecmp(line
, LIBIPSEC_ALGS_LINE_ALG
,
293 sizeof (LIBIPSEC_ALGS_LINE_ALG
) - 1) == 0) {
294 /* current line defines a new algorithm */
296 /* skip the algorithm token */
297 token
= strtok_r(line
, pipechar
, &lasts
);
299 /* protocol number */
300 token
= strtok_r(NULL
, pipechar
, &lasts
);
301 if (token
== NULL
|| (new_num
= atoi(token
)) == 0) {
302 (void) snprintf(diag_buf
, sizeof (diag_buf
),
303 "invalid algorithm number");
307 /* We can be O(N) for now. There aren't that many. */
308 for (new_proto
= rc
; new_proto
< (rc
+ new_num
);
310 if (new_proto
->proto_num
== new_num
)
312 if (new_proto
== (rc
+ new_num
)) {
313 (void) snprintf(diag_buf
, sizeof (diag_buf
),
314 "invalid protocol number %d for algorithm",
319 /* algorithm number */
320 token
= strtok_r(NULL
, pipechar
, &lasts
);
322 (void) snprintf(diag_buf
, sizeof (diag_buf
),
323 "cannot read algorithm number");
326 /* Can't check for 0 here. */
327 alg_num
= atoi(token
);
329 /* algorithm names */
330 token
= strtok_r(NULL
, pipechar
, &lasts
);
332 (void) snprintf(diag_buf
, sizeof (diag_buf
),
333 "cannot read algorithm number");
339 token
= strtok_r(NULL
, pipechar
, &lasts
);
341 (void) snprintf(diag_buf
, sizeof (diag_buf
),
342 "cannot read mechanism name for alg %d "
343 "(proto %d)", alg_num
,
344 new_proto
->proto_num
);
350 token
= strtok_r(NULL
, pipechar
, &lasts
);
352 (void) snprintf(diag_buf
, sizeof (diag_buf
),
353 "cannot read key sizes for alg %d "
354 "(proto %d)", alg_num
,
355 new_proto
->proto_num
);
361 token
= strtok_r(NULL
, pipechar
, &lasts
);
363 (void) snprintf(diag_buf
, sizeof (diag_buf
),
364 "cannot read block sizes for alg %d "
365 "(proto %d)", alg_num
,
366 new_proto
->proto_num
);
369 block_string
= token
;
372 * Check for mechanism params and flags. As these
373 * are optional, we won't bail if they don't exist.
375 token
= strtok_r(NULL
, pipechar
, &lasts
);
376 params_string
= token
;
378 token
= strtok_r(NULL
, pipechar
, &lasts
);
382 /* extract key sizes */
383 key_increment
= build_keysizes(&key_sizes
, key_string
);
384 if (key_increment
== -1) {
385 (void) snprintf(diag_buf
, sizeof (diag_buf
),
386 "invalid key sizes for alg %d (proto %d)",
387 alg_num
, new_proto
->proto_num
);
391 /* extract block sizes */
392 block_sizes
= (int *)malloc(sizeof (int));
393 if (block_sizes
== NULL
) {
397 token
= strtok_r(block_string
, comma
, &lasts
);
399 (void) snprintf(diag_buf
, sizeof (diag_buf
),
400 "invalid block sizes for alg %d (proto %d)",
401 alg_num
, new_proto
->proto_num
);
408 nbk
= reallocarray(block_sizes
,
409 (++num_sizes
) + 1, sizeof (int));
414 /* Can't check for 0 here... */
415 block_sizes
[num_sizes
- 1] = atoi(token
);
416 block_sizes
[num_sizes
] = 0;
417 } while ((token
= strtok_r(NULL
, comma
, &lasts
)) !=
420 /* extract mech params */
421 mech_params
= (int *)malloc(sizeof (int));
422 if (mech_params
== NULL
) {
427 if (params_string
!= NULL
) {
428 token
= strtok_r(params_string
, comma
, &lasts
);
430 (void) snprintf(diag_buf
,
431 sizeof (diag_buf
), "invalid mech "
432 "params for alg %d (proto %d)",
433 alg_num
, new_proto
->proto_num
);
439 nbk
= reallocarray(mech_params
,
440 (++num_sizes
) + 1, sizeof (int));
445 /* Can't check for 0 here... */
446 mech_params
[num_sizes
- 1] =
448 mech_params
[num_sizes
] = 0;
449 } while ((token
= strtok_r(NULL
, comma
, &lasts
))
452 /* Allocate a new struct ipsecalgent. */
453 curalg
= (struct ipsecalgent
*)calloc(
454 sizeof (struct ipsecalgent
), 1);
455 if (curalg
== NULL
) {
458 curalg
->a_proto_num
= new_num
;
459 curalg
->a_alg_num
= alg_num
;
460 curalg
->a_block_sizes
= block_sizes
;
461 curalg
->a_alg_flags
= flags
;
462 curalg
->a_mech_params
= mech_params
;
463 curalg
->a_key_sizes
= key_sizes
;
464 curalg
->a_key_increment
= key_increment
;
465 if ((curalg
->a_mech_name
= strdup(ef_name
)) == NULL
) {
466 freeipsecalgent(curalg
);
470 curalg
->a_names
= (char **)malloc(sizeof (char *));
471 num_sizes
= 0; /* Recycle "sizes" */
472 token
= strtok_r(alg_names
, comma
, &lasts
);
473 if (curalg
->a_names
== NULL
|| token
== NULL
) {
474 freeipsecalgent(curalg
);
480 nnames
= reallocarray(curalg
->a_names
,
481 (++num_sizes
) + 1, sizeof (char *));
482 if (nnames
== NULL
) {
483 freeipsecalgent(curalg
);
486 curalg
->a_names
= nnames
;
487 curalg
->a_names
[num_sizes
] = NULL
;
488 curalg
->a_names
[num_sizes
- 1] =
490 if (curalg
->a_names
[num_sizes
- 1] == NULL
) {
491 freeipsecalgent(curalg
);
494 } while ((token
= strtok_r(NULL
, comma
, &lasts
)) !=
498 /* record alg as being part of current pkg */
499 int npkgs
= new_proto
->proto_algs_npkgs
;
501 new_proto
->proto_algs_pkgs
= reallocarray(new_proto
->proto_algs_pkgs
,
502 npkgs
+ 1, sizeof (ipsecalgs_pkg_t
));
503 if (new_proto
->proto_algs_pkgs
== NULL
)
506 new_proto
->proto_algs_pkgs
[npkgs
].alg_num
=
508 new_proto
->proto_algs_pkgs
[npkgs
].pkg_name
=
510 if (new_proto
->proto_algs_pkgs
[npkgs
].pkg_name
514 new_proto
->proto_algs_npkgs
= npkgs
+ 1;
517 /* add new alg to protocol */
518 newalglist
= reallocarray(new_proto
->proto_algs
,
519 new_proto
->proto_numalgs
+ 1,
520 sizeof (struct ipsecalgent
*));
521 if (newalglist
== NULL
) {
522 freeipsecalgent(curalg
);
525 newalglist
[new_proto
->proto_numalgs
] = curalg
;
526 new_proto
->proto_numalgs
++;
527 new_proto
->proto_algs
= newalglist
;
529 } else if (strncasecmp(line
, LIBIPSEC_ALGS_LINE_PKGSTART
,
530 sizeof (LIBIPSEC_ALGS_LINE_PKGSTART
) - 1) == 0) {
531 /* start of package delimiter */
533 (void) snprintf(diag_buf
, sizeof (diag_buf
),
534 "duplicate package start delimiters");
537 (void) strncpy(cur_pkg
, line
+
538 (sizeof (LIBIPSEC_ALGS_LINE_PKGSTART
) - 1),
540 /* remove trailing '\n' */
541 cur_pkg
[strlen(cur_pkg
) - 1] = '\0';
545 /* end of package delimiter */
549 (void) snprintf(diag_buf
, sizeof (diag_buf
),
550 "end package delimiter without start");
554 * Get specified pkg name, fail if it doesn't match
555 * the package specified by the last # Begin.
557 (void) strncpy(tmp_pkg
, line
+
558 (sizeof (LIBIPSEC_ALGS_LINE_PKGEND
) - 1),
560 /* remove trailing '\n' */
561 tmp_pkg
[strlen(tmp_pkg
) - 1] = '\0';
562 if (strncmp(cur_pkg
, tmp_pkg
, sizeof (cur_pkg
)) != 0)
572 if (strlen(diag_buf
) > 0) {
573 syslog(LOG_ERR
, "possibly corrupt %s file: %s\n",
574 INET_IPSECALGSFILE
, diag_buf
);
579 _clean_trash(rc
, rc_num
);
584 * If alg_context is NULL, update the library's cached copy of
585 * INET_IPSECALGSFILE. If alg_context is non-NULL, hang a
586 * library-internal representation of a cached copy. The latter is useful
587 * for routines in libipsecutil that _write_ the contents out.
590 _build_internal_algs(ipsec_proto_t
**alg_context
, int *alg_nums
)
594 ipsec_proto_t
*new_protos
= NULL
, *trash
;
599 * Construct new_protos from the file.
601 if (alg_context
== NULL
) {
603 * Check the time w/o holding the lock. This is just a
604 * cache reality check. We'll do it again for real if this
605 * surface check fails.
607 if (stat(INET_IPSECALGSFILE
, &statbuf
) == -1 ||
608 (statbuf
.st_mtime
< proto_last_update
&& protos
!= NULL
))
610 (void) rw_wrlock(&proto_rw
);
613 f
= fopen(INET_IPSECALGSFILE
, "rF");
615 rc
= fstat(fileno(f
), &statbuf
);
618 * Update if the file is newer than our
621 filetime
= statbuf
.st_mtime
;
622 if (alg_context
!= NULL
||
623 filetime
> proto_last_update
)
624 new_protos
= build_list(f
, &rc
);
626 /* Since f is read-only, can avoid all of the failures... */
630 if (alg_context
== NULL
) {
632 * If we have failed anywhere above, new_protoss will be NULL.
633 * This way, the previous cached protos will still be intact.
635 if (new_protos
!= NULL
) {
636 proto_last_update
= filetime
;
638 trash_num
= num_protos
;
643 * Else the original protocols and algorithms lists
648 (void) rw_unlock(&proto_rw
);
649 _clean_trash(trash
, trash_num
);
652 * Assume caller has done the appropriate locking,
653 * cleanup, etc. And if new_protos is NULL, it's the caller's
656 *alg_context
= new_protos
;
663 * Assume input is 0-terminated.
666 duplicate_intarr(int *orig
)
668 size_t allocsize
= sizeof (int);
674 while (*iwalker
!= 0) {
675 allocsize
+= sizeof (int);
679 iwalker
= malloc(allocsize
);
681 (void) memcpy(iwalker
, orig
, allocsize
);
687 * Assume input is NULL terminated.
690 duplicate_strarr(char **orig
)
699 /* count number of elements in source array */
700 for (swalker
= orig
; *swalker
!= NULL
; swalker
++)
703 /* use calloc() to get NULL-initialization */
704 newbie
= calloc(swalker
- orig
+ 1, sizeof (char *));
706 if (newbie
!= NULL
) {
708 for (i
= 0; orig
[i
] != NULL
; i
++) {
709 newbie
[i
] = strdup(orig
[i
]);
710 if (newbie
[i
] == NULL
) {
711 for (swalker
= newbie
; *swalker
!= NULL
;
724 _duplicate_alg(struct ipsecalgent
*orig
)
726 struct ipsecalgent
*rc
;
728 /* use calloc() to get NULL-initialization. */
729 rc
= calloc(1, sizeof (struct ipsecalgent
));
733 rc
->a_proto_num
= orig
->a_proto_num
;
734 rc
->a_alg_num
= orig
->a_alg_num
;
735 rc
->a_key_increment
= orig
->a_key_increment
;
736 rc
->a_mech_name
= strdup(orig
->a_mech_name
);
737 rc
->a_alg_flags
= orig
->a_alg_flags
;
738 rc
->a_block_sizes
= duplicate_intarr(orig
->a_block_sizes
);
739 rc
->a_mech_params
= duplicate_intarr(orig
->a_mech_params
);
740 rc
->a_key_sizes
= duplicate_intarr(orig
->a_key_sizes
);
741 rc
->a_names
= duplicate_strarr(orig
->a_names
);
743 if (rc
->a_mech_name
== NULL
|| rc
->a_block_sizes
== NULL
||
744 rc
->a_key_sizes
== NULL
|| rc
->a_names
== NULL
||
745 rc
->a_mech_params
== NULL
) {
754 * Assume the rwlock is held for reading.
756 static ipsec_proto_t
*
757 findprotobynum(int proto_num
)
761 for (i
= 0; i
< num_protos
; i
++) {
762 if (protos
[i
].proto_num
== proto_num
)
769 static ipsec_proto_t
*
770 findprotobyname(const char *name
)
777 for (i
= 0; i
< num_protos
; i
++) {
778 /* Can use strcasecmp because our proto_name is bounded. */
779 if (strcasecmp(protos
[i
].proto_name
, name
) == 0)
787 _real_getipsecprotos(int *nentries
)
791 if (nentries
== NULL
)
794 _build_internal_algs(NULL
, NULL
);
796 (void) rw_rdlock(&proto_rw
);
797 *nentries
= num_protos
;
799 * Allocate 1 byte if there are no protocols so a non-NULL return
802 rc
= malloc((num_protos
== 0) ? 1 : num_protos
* sizeof (int));
804 for (i
= 0; i
< num_protos
; i
++)
805 rc
[i
] = protos
[i
].proto_num
;
807 (void) rw_unlock(&proto_rw
);
812 _real_getipsecalgs(int *nentries
, int proto_num
)
815 ipsec_proto_t
*proto
;
817 if (nentries
== NULL
)
820 _build_internal_algs(NULL
, NULL
);
822 (void) rw_rdlock(&proto_rw
);
823 proto
= findprotobynum(proto_num
);
825 *nentries
= proto
->proto_numalgs
;
827 * Allocate 1 byte if there are no algorithms so a non-NULL
830 rc
= malloc((proto
->proto_numalgs
== 0) ? 1 :
831 proto
->proto_numalgs
* sizeof (int));
833 for (i
= 0; i
< proto
->proto_numalgs
; i
++)
834 rc
[i
] = proto
->proto_algs
[i
]->a_alg_num
;
837 (void) rw_unlock(&proto_rw
);
842 getipsecalgbyname(const char *name
, int proto_num
, int *errnop
)
844 ipsec_proto_t
*proto
;
845 struct ipsecalgent
*rc
= NULL
;
846 int i
, my_errno
= ENOENT
;
849 _build_internal_algs(NULL
, NULL
);
855 (void) rw_rdlock(&proto_rw
);
856 proto
= findprotobynum(proto_num
);
858 for (i
= 0; i
< proto
->proto_numalgs
; i
++) {
859 for (name_check
= proto
->proto_algs
[i
]->a_names
;
860 *name_check
!= NULL
; name_check
++) {
862 * Can use strcasecmp because our name_check
865 if (strcasecmp(*name_check
, name
) == 0) {
868 proto
->proto_algs
[i
]);
869 my_errno
= (rc
== NULL
) ? ENOMEM
: 0;
870 (void) rw_unlock(&proto_rw
);
879 (void) rw_unlock(&proto_rw
);
887 getipsecalgbynum(int alg_num
, int proto_num
, int *errnop
)
889 ipsec_proto_t
*proto
;
890 struct ipsecalgent
*rc
= NULL
;
891 int i
, my_errno
= ENOENT
;
893 _build_internal_algs(NULL
, NULL
);
895 (void) rw_rdlock(&proto_rw
);
897 proto
= findprotobynum(proto_num
);
899 for (i
= 0; i
< proto
->proto_numalgs
; i
++) {
900 if (proto
->proto_algs
[i
]->a_alg_num
== alg_num
) {
901 rc
= _duplicate_alg(proto
->proto_algs
[i
]);
902 my_errno
= (rc
== NULL
) ? ENOMEM
: 0;
910 (void) rw_unlock(&proto_rw
);
917 getipsecprotobyname(const char *proto_name
)
920 ipsec_proto_t
*proto
;
922 _build_internal_algs(NULL
, NULL
);
924 (void) rw_rdlock(&proto_rw
);
925 proto
= findprotobyname(proto_name
);
927 rc
= proto
->proto_num
;
928 (void) rw_unlock(&proto_rw
);
933 getipsecprotobynum(int proto_num
)
935 ipsec_proto_t
*proto
;
938 _build_internal_algs(NULL
, NULL
);
940 (void) rw_rdlock(&proto_rw
);
941 proto
= findprotobynum(proto_num
);
943 rc
= strdup(proto
->proto_name
);
945 (void) rw_unlock(&proto_rw
);
950 freeipsecalgent(struct ipsecalgent
*ptr
)
957 if (ptr
->a_names
!= NULL
) {
958 for (walker
= ptr
->a_names
; *walker
!= NULL
; walker
++)
963 * Remember folks, free(NULL) works.
966 free(ptr
->a_mech_name
);
967 free(ptr
->a_block_sizes
);
968 free(ptr
->a_mech_params
);
969 free(ptr
->a_key_sizes
);