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