1 1.1 christos /* $NetBSD: support.c,v 1.1 2025/02/06 19:35:28 christos Exp $ */ 2 1.1 christos 3 1.1 christos /*- 4 1.1 christos * Copyright (c) 2013 The NetBSD Foundation, Inc. 5 1.1 christos * All rights reserved. 6 1.1 christos * 7 1.1 christos * This code is derived from software contributed to The NetBSD Foundation 8 1.1 christos * by Taylor R. Campbell. 9 1.1 christos * 10 1.1 christos * Redistribution and use in source and binary forms, with or without 11 1.1 christos * modification, are permitted provided that the following conditions 12 1.1 christos * are met: 13 1.1 christos * 1. Redistributions of source code must retain the above copyright 14 1.1 christos * notice, this list of conditions and the following disclaimer. 15 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 christos * notice, this list of conditions and the following disclaimer in the 17 1.1 christos * documentation and/or other materials provided with the distribution. 18 1.1 christos * 19 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 christos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 christos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 christos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 christos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 christos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 christos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 christos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 christos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 christos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 christos * POSSIBILITY OF SUCH DAMAGE. 30 1.1 christos */ 31 1.1 christos 32 1.1 christos #include <sys/cdefs.h> 33 1.1 christos __RCSID("$NetBSD: support.c,v 1.1 2025/02/06 19:35:28 christos Exp $"); 34 1.1 christos 35 1.1 christos #include <assert.h> 36 1.1 christos #include <limits.h> 37 1.1 christos #include <errno.h> 38 1.1 christos #include <netdb.h> 39 1.1 christos #include <stdbool.h> 40 1.1 christos #include <stdint.h> 41 1.1 christos #include <stdlib.h> 42 1.1 christos #include <string.h> 43 1.1 christos #include <unistd.h> 44 1.1 christos 45 1.1 christos #include "tables.h" 46 1.1 christos #include "support.h" 47 1.1 christos 48 1.1 christos static bool 49 1.1 christos parse_numeric(const char *string, int *rv) 50 1.1 christos { 51 1.1 christos char *end; 52 1.1 christos long value; 53 1.1 christos 54 1.1 christos errno = 0; 55 1.1 christos value = strtol(string, &end, 0); 56 1.1 christos if ((string[0] == '\0') || (*end != '\0')) 57 1.1 christos return false; 58 1.1 christos if ((errno == ERANGE) && ((value == LONG_MAX) || (value == LONG_MIN))) 59 1.1 christos return false; 60 1.1 christos if ((value > INT_MAX) || (value < INT_MIN)) 61 1.1 christos return false; 62 1.1 christos *rv = (int)value; 63 1.1 christos return true; 64 1.1 christos } 65 1.1 christos 66 1.1 christos bool 67 1.1 christos parse_af(const char *string, int *afp) 68 1.1 christos { 69 1.1 christos 70 1.1 christos return parse_numeric_tabular(string, afp, address_families, 71 1.1 christos __arraycount(address_families)); 72 1.1 christos } 73 1.1 christos 74 1.1 christos bool 75 1.1 christos parse_protocol(const char *string, int *protop) 76 1.1 christos { 77 1.1 christos struct protoent *protoent; 78 1.1 christos 79 1.1 christos if (parse_numeric(string, protop)) 80 1.1 christos return true; 81 1.1 christos 82 1.1 christos protoent = getprotobyname(string); 83 1.1 christos if (protoent == NULL) 84 1.1 christos return false; 85 1.1 christos 86 1.1 christos *protop = protoent->p_proto; 87 1.1 christos return true; 88 1.1 christos } 89 1.1 christos 90 1.1 christos bool 91 1.1 christos parse_socktype(const char *string, int *typep) 92 1.1 christos { 93 1.1 christos 94 1.1 christos return parse_numeric_tabular(string, typep, socket_types, 95 1.1 christos __arraycount(socket_types)); 96 1.1 christos } 97 1.1 christos 98 1.1 christos bool 99 1.1 christos parse_numeric_tabular(const char *string, int *valuep, 100 1.1 christos const char *const *table, size_t n) 101 1.1 christos { 102 1.1 christos 103 1.1 christos assert((uintmax_t)n <= (uintmax_t)INT_MAX); 104 1.1 christos 105 1.1 christos if (parse_numeric(string, valuep)) 106 1.1 christos return true; 107 1.1 christos 108 1.1 christos for (size_t i = 0; i < n; i++) 109 1.1 christos if ((table[i] != NULL) && (strcmp(string, table[i]) == 0)) { 110 1.1 christos *valuep = (int)i; 111 1.1 christos return true; 112 1.1 christos } 113 1.1 christos return false; 114 1.1 christos } 115