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