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