1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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[YPMAXRECORD + 2]; 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 bcopy((char *)result, (char *)&ypbuf, resultlen); 81 ypbuf[resultlen] = '\0'; 82 free(result); 83 result = (char *)&ypbuf; 84 85 if ((cp = strchr(result, '\n'))) 86 *cp = '\0'; 87 88 cp = strpbrk(result, " \t"); 89 *cp++ = '\0'; 90 bp = ned->netbuf; 91 ep = ned->netbuf + sizeof ned->netbuf; 92 len = strlen(result) + 1; 93 if (ep - bp < len) { 94 RES_SET_H_ERRNO(__res_state(), NO_RECOVERY); 95 return (-1); 96 } 97 strlcpy(bp, result, ep - bp); 98 ne->n_name = bp; 99 bp += len; 100 101 while (*cp == ' ' || *cp == '\t') 102 cp++; 103 104 ne->n_net = inet_network(cp); 105 ne->n_addrtype = AF_INET; 106 107 q = ne->n_aliases = ned->net_aliases; 108 cp = strpbrk(cp, " \t"); 109 if (cp != NULL) 110 *cp++ = '\0'; 111 while (cp && *cp) { 112 if (*cp == ' ' || *cp == '\t') { 113 cp++; 114 continue; 115 } 116 if (q > &ned->net_aliases[_MAXALIASES - 1]) 117 break; 118 p = strpbrk(cp, " \t"); 119 if (p != NULL) 120 *p++ = '\0'; 121 len = strlen(cp) + 1; 122 if (ep - bp < len) 123 break; 124 strlcpy(bp, cp, ep - bp); 125 *q++ = bp; 126 bp += len; 127 cp = p; 128 } 129 *q = NULL; 130 return (0); 131 } 132 #endif /* YP */ 133 134 int 135 _nis_getnetbyname(void *rval, void *cb_data, va_list ap) 136 { 137 #ifdef YP 138 const char *name; 139 char *buffer; 140 size_t buflen; 141 int *errnop, *h_errnop; 142 struct netent *nptr, ne; 143 struct netent_data *ned; 144 res_state statp; 145 146 name = va_arg(ap, const char *); 147 nptr = va_arg(ap, struct netent *); 148 buffer = va_arg(ap, char *); 149 buflen = va_arg(ap, size_t); 150 errnop = va_arg(ap, int *); 151 h_errnop = va_arg(ap, int *); 152 153 statp = __res_state(); 154 if ((ned = __netent_data_init()) == NULL) { 155 RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 156 *h_errnop = statp->res_h_errno; 157 return (NS_UNAVAIL); 158 } 159 160 if (_getnetbynis(name, "networks.byname", AF_INET, &ne, ned) != 0) { 161 *h_errnop = statp->res_h_errno; 162 return (NS_NOTFOUND); 163 } 164 if (__copy_netent(&ne, nptr, buffer, buflen) != 0) { 165 *errnop = errno; 166 RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 167 *h_errnop = statp->res_h_errno; 168 return (NS_RETURN); 169 } 170 *((struct netent **)rval) = nptr; 171 return (NS_SUCCESS); 172 #else 173 return (NS_UNAVAIL); 174 #endif 175 176 } 177 178 int 179 _nis_getnetbyaddr(void *rval, void *cb_data, va_list ap) 180 { 181 #ifdef YP 182 uint32_t addr; 183 int af; 184 char *buffer; 185 size_t buflen; 186 int *errnop, *h_errnop; 187 struct netent *nptr, ne; 188 struct netent_data *ned; 189 char *str, *cp; 190 uint32_t net2; 191 int nn; 192 unsigned int netbr[4]; 193 char buf[MAXDNAME]; 194 res_state statp; 195 196 addr = va_arg(ap, uint32_t); 197 af = va_arg(ap, int); 198 nptr = va_arg(ap, struct netent *); 199 buffer = va_arg(ap, char *); 200 buflen = va_arg(ap, size_t); 201 errnop = va_arg(ap, int *); 202 h_errnop = va_arg(ap, int *); 203 204 statp = __res_state(); 205 if ((ned = __netent_data_init()) == NULL) { 206 RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 207 *h_errnop = statp->res_h_errno; 208 return (NS_UNAVAIL); 209 } 210 211 if (af != AF_INET) { 212 RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 213 *h_errnop = statp->res_h_errno; 214 errno = EAFNOSUPPORT; 215 return (NS_UNAVAIL); 216 } 217 218 for (nn = 4, net2 = addr; net2; net2 >>= 8) { 219 netbr[--nn] = net2 & 0xff; 220 } 221 222 switch (nn) { 223 case 3: /* Class A */ 224 sprintf(buf, "%u", netbr[3]); 225 break; 226 case 2: /* Class B */ 227 sprintf(buf, "%u.%u", netbr[2], netbr[3]); 228 break; 229 case 1: /* Class C */ 230 sprintf(buf, "%u.%u.%u", netbr[1], netbr[2], netbr[3]); 231 break; 232 case 0: /* Class D - E */ 233 sprintf(buf, "%u.%u.%u.%u", netbr[0], netbr[1], 234 netbr[2], netbr[3]); 235 break; 236 } 237 238 str = (char *)&buf; 239 cp = str + (strlen(str) - 2); 240 241 while(!strcmp(cp, ".0")) { 242 *cp = '\0'; 243 cp = str + (strlen(str) - 2); 244 } 245 246 if (_getnetbynis(str, "networks.byaddr", af, &ne, ned) != 0) { 247 *h_errnop = statp->res_h_errno; 248 return (NS_NOTFOUND); 249 } 250 if (__copy_netent(&ne, nptr, buffer, buflen) != 0) { 251 *errnop = errno; 252 RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 253 *h_errnop = statp->res_h_errno; 254 return (NS_RETURN); 255 } 256 *((struct netent **)rval) = nptr; 257 return (NS_SUCCESS); 258 #else 259 return (NS_UNAVAIL); 260 #endif /* YP */ 261 } 262