1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 1994, Garrett Wollman 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include <sys/param.h> 32 #include <sys/socket.h> 33 #include <netinet/in.h> 34 #include <arpa/inet.h> 35 #include <netdb.h> 36 #include <resolv.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <ctype.h> 40 #include <errno.h> 41 #include <string.h> 42 #include <stdarg.h> 43 #include <nsswitch.h> 44 #include <arpa/nameser.h> 45 #ifdef YP 46 #include <rpc/rpc.h> 47 #include <rpcsvc/yp_prot.h> 48 #include <rpcsvc/ypclnt.h> 49 #endif 50 #include "netdb_private.h" 51 52 #ifdef YP 53 static int 54 _getnetbynis(const char *name, char *map, int af, struct netent *ne, 55 struct netent_data *ned) 56 { 57 char *p, *bp, *ep; 58 char *cp, **q; 59 char *result; 60 int resultlen, len; 61 char *ypbuf; 62 63 switch(af) { 64 case AF_INET: 65 break; 66 default: 67 case AF_INET6: 68 errno = EAFNOSUPPORT; 69 return (-1); 70 } 71 72 if (ned->yp_domain == (char *)NULL) 73 if (yp_get_default_domain (&ned->yp_domain)) 74 return (-1); 75 76 if (yp_match(ned->yp_domain, map, name, strlen(name), &result, 77 &resultlen)) 78 return (-1); 79 80 ypbuf = alloca(resultlen + 2); 81 bcopy(result, ypbuf, resultlen); 82 ypbuf[resultlen] = '\0'; 83 free(result); 84 result = ypbuf; 85 86 if ((cp = strchr(result, '\n'))) 87 *cp = '\0'; 88 89 cp = strpbrk(result, " \t"); 90 *cp++ = '\0'; 91 bp = ned->netbuf; 92 ep = ned->netbuf + sizeof ned->netbuf; 93 len = strlen(result) + 1; 94 if (ep - bp < len) { 95 RES_SET_H_ERRNO(__res_state(), NO_RECOVERY); 96 return (-1); 97 } 98 strlcpy(bp, result, ep - bp); 99 ne->n_name = bp; 100 bp += len; 101 102 while (*cp == ' ' || *cp == '\t') 103 cp++; 104 105 ne->n_net = inet_network(cp); 106 ne->n_addrtype = AF_INET; 107 108 q = ne->n_aliases = ned->net_aliases; 109 cp = strpbrk(cp, " \t"); 110 if (cp != NULL) 111 *cp++ = '\0'; 112 while (cp && *cp) { 113 if (*cp == ' ' || *cp == '\t') { 114 cp++; 115 continue; 116 } 117 if (q > &ned->net_aliases[_MAXALIASES - 1]) 118 break; 119 p = strpbrk(cp, " \t"); 120 if (p != NULL) 121 *p++ = '\0'; 122 len = strlen(cp) + 1; 123 if (ep - bp < len) 124 break; 125 strlcpy(bp, cp, ep - bp); 126 *q++ = bp; 127 bp += len; 128 cp = p; 129 } 130 *q = NULL; 131 return (0); 132 } 133 #endif /* YP */ 134 135 int 136 _nis_getnetbyname(void *rval, void *cb_data, va_list ap) 137 { 138 #ifdef YP 139 const char *name; 140 char *buffer; 141 size_t buflen; 142 int *errnop, *h_errnop; 143 struct netent *nptr, ne; 144 struct netent_data *ned; 145 res_state statp; 146 147 name = va_arg(ap, const char *); 148 nptr = va_arg(ap, struct netent *); 149 buffer = va_arg(ap, char *); 150 buflen = va_arg(ap, size_t); 151 errnop = va_arg(ap, int *); 152 h_errnop = va_arg(ap, int *); 153 154 statp = __res_state(); 155 if ((ned = __netent_data_init()) == NULL) { 156 RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 157 *h_errnop = statp->res_h_errno; 158 return (NS_UNAVAIL); 159 } 160 161 if (_getnetbynis(name, "networks.byname", AF_INET, &ne, ned) != 0) { 162 *h_errnop = statp->res_h_errno; 163 return (NS_NOTFOUND); 164 } 165 if (__copy_netent(&ne, nptr, buffer, buflen) != 0) { 166 *errnop = errno; 167 RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 168 *h_errnop = statp->res_h_errno; 169 return (NS_RETURN); 170 } 171 *((struct netent **)rval) = nptr; 172 return (NS_SUCCESS); 173 #else 174 return (NS_UNAVAIL); 175 #endif 176 177 } 178 179 int 180 _nis_getnetbyaddr(void *rval, void *cb_data, va_list ap) 181 { 182 #ifdef YP 183 uint32_t addr; 184 int af; 185 char *buffer; 186 size_t buflen; 187 int *errnop, *h_errnop; 188 struct netent *nptr, ne; 189 struct netent_data *ned; 190 char *str, *cp; 191 uint32_t net2; 192 int nn; 193 unsigned int netbr[4]; 194 char buf[MAXDNAME]; 195 res_state statp; 196 197 addr = va_arg(ap, uint32_t); 198 af = va_arg(ap, int); 199 nptr = va_arg(ap, struct netent *); 200 buffer = va_arg(ap, char *); 201 buflen = va_arg(ap, size_t); 202 errnop = va_arg(ap, int *); 203 h_errnop = va_arg(ap, int *); 204 205 statp = __res_state(); 206 if ((ned = __netent_data_init()) == NULL) { 207 RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 208 *h_errnop = statp->res_h_errno; 209 return (NS_UNAVAIL); 210 } 211 212 if (af != AF_INET) { 213 RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 214 *h_errnop = statp->res_h_errno; 215 errno = EAFNOSUPPORT; 216 return (NS_UNAVAIL); 217 } 218 219 for (nn = 4, net2 = addr; net2; net2 >>= 8) { 220 netbr[--nn] = net2 & 0xff; 221 } 222 223 switch (nn) { 224 case 3: /* Class A */ 225 sprintf(buf, "%u", netbr[3]); 226 break; 227 case 2: /* Class B */ 228 sprintf(buf, "%u.%u", netbr[2], netbr[3]); 229 break; 230 case 1: /* Class C */ 231 sprintf(buf, "%u.%u.%u", netbr[1], netbr[2], netbr[3]); 232 break; 233 case 0: /* Class D - E */ 234 sprintf(buf, "%u.%u.%u.%u", netbr[0], netbr[1], 235 netbr[2], netbr[3]); 236 break; 237 } 238 239 str = (char *)&buf; 240 cp = str + (strlen(str) - 2); 241 242 while(!strcmp(cp, ".0")) { 243 *cp = '\0'; 244 cp = str + (strlen(str) - 2); 245 } 246 247 if (_getnetbynis(str, "networks.byaddr", af, &ne, ned) != 0) { 248 *h_errnop = statp->res_h_errno; 249 return (NS_NOTFOUND); 250 } 251 if (__copy_netent(&ne, nptr, buffer, buflen) != 0) { 252 *errnop = errno; 253 RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 254 *h_errnop = statp->res_h_errno; 255 return (NS_RETURN); 256 } 257 *((struct netent **)rval) = nptr; 258 return (NS_SUCCESS); 259 #else 260 return (NS_UNAVAIL); 261 #endif /* YP */ 262 } 263