1 /* 2 * Copyright (c) 1999 by Sun Microsystems, Inc. 3 * All rights reserved. 4 */ 5 6 /* 7 * Portions Copyright (c) 1996,1998 by Internet Software Consortium. 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 14 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 16 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 17 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 18 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 19 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20 * SOFTWARE. 21 */ 22 23 #pragma ident "%Z%%M% %I% %E% SMI" 24 25 #if defined(LIBC_SCCS) && !defined(lint) 26 static const char rcsid[] = "$Id: irp_nw.c,v 8.1 1999/01/18 07:46:54 vixie Exp $"; 27 #endif /* LIBC_SCCS and not lint */ 28 29 #if 0 30 31 #endif 32 33 /* Imports */ 34 35 #include "port_before.h" 36 37 #include <syslog.h> 38 #include <sys/types.h> 39 #include <sys/socket.h> 40 41 #include <netinet/in.h> 42 #include <arpa/inet.h> 43 #include <arpa/nameser.h> 44 45 #include <errno.h> 46 #include <fcntl.h> 47 #include <resolv.h> 48 #include <stdio.h> 49 #include <stdlib.h> 50 #include <string.h> 51 #include <syslog.h> 52 53 #include <irs.h> 54 #include <irp.h> 55 #include <isc/irpmarshall.h> 56 57 #include <isc/memcluster.h> 58 #include <isc/misc.h> 59 60 #include "irs_p.h" 61 #include "lcl_p.h" 62 #include "irp_p.h" 63 64 #include "port_after.h" 65 66 #define MAXALIASES 35 67 #define MAXADDRSIZE 4 68 69 struct pvt { 70 struct irp_p *girpdata; 71 int warned; 72 struct nwent net; 73 }; 74 75 /* Forward */ 76 77 static void nw_close(struct irs_nw *); 78 static struct nwent * nw_byname(struct irs_nw *, const char *, int); 79 static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int); 80 static struct nwent * nw_next(struct irs_nw *); 81 static void nw_rewind(struct irs_nw *); 82 static void nw_minimize(struct irs_nw *); 83 84 static void free_nw(struct nwent *nw); 85 86 87 /* Public */ 88 89 90 91 /* 92 * struct irs_nw * irs_irp_nw(struct irs_acc *this) 93 * 94 */ 95 96 struct irs_nw * 97 irs_irp_nw(struct irs_acc *this) { 98 struct irs_nw *nw; 99 struct pvt *pvt; 100 101 if (!(pvt = memget(sizeof *pvt))) { 102 errno = ENOMEM; 103 return (NULL); 104 } 105 memset(pvt, 0, sizeof *pvt); 106 107 if (!(nw = memget(sizeof *nw))) { 108 memput(pvt, sizeof *pvt); 109 errno = ENOMEM; 110 return (NULL); 111 } 112 memset(nw, 0x0, sizeof *nw); 113 pvt->girpdata = this->private; 114 115 nw->private = pvt; 116 nw->close = nw_close; 117 nw->byname = nw_byname; 118 nw->byaddr = nw_byaddr; 119 nw->next = nw_next; 120 nw->rewind = nw_rewind; 121 nw->minimize = nw_minimize; 122 return (nw); 123 } 124 125 /* Methods */ 126 127 128 129 /* 130 * void nw_close(struct irs_nw *this) 131 * 132 */ 133 134 static void 135 nw_close(struct irs_nw *this) { 136 struct pvt *pvt = (struct pvt *)this->private; 137 138 nw_minimize(this); 139 140 free_nw(&pvt->net); 141 142 memput(pvt, sizeof *pvt); 143 memput(this, sizeof *this); 144 } 145 146 147 148 149 /* 150 * struct nwent * nw_byaddr(struct irs_nw *this, void *net, 151 * int length, int type) 152 * 153 */ 154 155 static struct nwent * 156 nw_byaddr(struct irs_nw *this, void *net, int length, int type) { 157 struct pvt *pvt = (struct pvt *)this->private; 158 struct nwent *nw = &pvt->net; 159 char *body = NULL; 160 size_t bodylen; 161 int code; 162 char paddr[24]; /* bigenough for ip4 w/ cidr spec. */ 163 char text[256]; 164 165 if (inet_net_ntop(type, net, length, paddr, sizeof paddr) == NULL) { 166 return (NULL); 167 } 168 169 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 170 return (NULL); 171 } 172 173 if (irs_irp_send_command(pvt->girpdata, "getnetbyaddr %s %s", 174 paddr, ADDR_T_STR(type)) != 0) 175 return (NULL); 176 177 if (irs_irp_get_full_response(pvt->girpdata, &code, 178 text, sizeof text, 179 &body, &bodylen) != 0) { 180 return (NULL); 181 } 182 183 if (code == IRPD_GETNET_OK) { 184 free_nw(nw); 185 if (irp_unmarshall_nw(nw, body) != 0) { 186 nw = NULL; 187 } 188 } else { 189 nw = NULL; 190 } 191 192 if (body != NULL) { 193 memput(body, bodylen); 194 } 195 196 return (nw); 197 } 198 199 200 201 202 /* 203 * struct nwent * nw_byname(struct irs_nw *this, const char *name, int type) 204 * 205 */ 206 207 static struct nwent * 208 nw_byname(struct irs_nw *this, const char *name, int type) { 209 struct pvt *pvt = (struct pvt *)this->private; 210 struct nwent *nw = &pvt->net; 211 char *body = NULL; 212 size_t bodylen; 213 int code; 214 char text[256]; 215 216 if (nw->n_name != NULL && 217 strcmp(name, nw->n_name) == 0 && 218 nw->n_addrtype == type) { 219 return (nw); 220 } 221 222 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 223 return (NULL); 224 } 225 226 if (irs_irp_send_command(pvt->girpdata, "getnetbyname %s", name) != 0) 227 return (NULL); 228 229 if (irs_irp_get_full_response(pvt->girpdata, &code, 230 text, sizeof text, 231 &body, &bodylen) != 0) { 232 return (NULL); 233 } 234 235 if (code == IRPD_GETNET_OK) { 236 free_nw(nw); 237 if (irp_unmarshall_nw(nw, body) != 0) { 238 nw = NULL; 239 } 240 } else { 241 nw = NULL; 242 } 243 244 if (body != NULL) { 245 memput(body, bodylen); 246 } 247 248 return (nw); 249 } 250 251 252 253 254 /* 255 * void nw_rewind(struct irs_nw *this) 256 * 257 */ 258 259 static void 260 nw_rewind(struct irs_nw *this) { 261 struct pvt *pvt = (struct pvt *)this->private; 262 char text[256]; 263 int code; 264 265 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 266 return; 267 } 268 269 if (irs_irp_send_command(pvt->girpdata, "setnetent") != 0) { 270 return; 271 } 272 273 code = irs_irp_read_response(pvt->girpdata, text, sizeof text); 274 if (code != IRPD_GETNET_SETOK) { 275 if (irp_log_errors) { 276 syslog(LOG_WARNING, "setnetent failed: %s", text); 277 } 278 } 279 280 return; 281 } 282 283 284 285 286 287 288 /* 289 * struct nwent * nw_next(struct irs_nw *this) 290 * 291 * Notes: 292 * 293 * Prepares the cache if necessary and returns the first, or 294 * next item from it. 295 */ 296 297 static struct nwent * 298 nw_next(struct irs_nw *this) { 299 struct pvt *pvt = (struct pvt *)this->private; 300 struct nwent *nw = &pvt->net; 301 char *body; 302 size_t bodylen; 303 int code; 304 char text[256]; 305 306 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 307 return (NULL); 308 } 309 310 if (irs_irp_send_command(pvt->girpdata, "getnetent") != 0) { 311 return (NULL); 312 } 313 314 if (irs_irp_get_full_response(pvt->girpdata, &code, 315 text, sizeof text, 316 &body, &bodylen) != 0) { 317 return (NULL); 318 } 319 320 if (code == IRPD_GETNET_OK) { 321 free_nw(nw); 322 if (irp_unmarshall_nw(nw, body) != 0) { 323 nw = NULL; 324 } 325 } else { 326 nw = NULL; 327 } 328 329 return (nw); 330 } 331 332 333 334 335 336 337 /* 338 * void nw_minimize(struct irs_nw *this) 339 * 340 */ 341 342 static void 343 nw_minimize(struct irs_nw *this) { 344 struct pvt *pvt = (struct pvt *)this->private; 345 346 irs_irp_disconnect(pvt->girpdata); 347 } 348 349 350 351 352 /* private. */ 353 354 355 356 /* 357 * static void free_passwd(struct passwd *pw); 358 * 359 * deallocate all the memory irp_unmarshall_pw allocated. 360 * 361 */ 362 363 static void 364 free_nw(struct nwent *nw) { 365 char **p; 366 367 if (nw == NULL) 368 return; 369 370 if (nw->n_name != NULL) 371 free(nw->n_name); 372 373 if (nw->n_aliases != NULL) { 374 for (p = nw->n_aliases ; *p != NULL ; p++) { 375 free(*p); 376 } 377 free(nw->n_aliases); 378 } 379 380 if (nw->n_addr != NULL) 381 free(nw->n_addr); 382 } 383