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