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 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_pr.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 /* extern */ 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate #include "port_before.h" 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate #include <syslog.h> 34*0Sstevel@tonic-gate #include <sys/types.h> 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate #include <errno.h> 37*0Sstevel@tonic-gate #include <fcntl.h> 38*0Sstevel@tonic-gate #include <string.h> 39*0Sstevel@tonic-gate #include <stdio.h> 40*0Sstevel@tonic-gate #include <stdlib.h> 41*0Sstevel@tonic-gate #include <netdb.h> 42*0Sstevel@tonic-gate #include <syslog.h> 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate #include <irs.h> 45*0Sstevel@tonic-gate #include <irp.h> 46*0Sstevel@tonic-gate #include <isc/memcluster.h> 47*0Sstevel@tonic-gate #include <isc/irpmarshall.h> 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate #include "irs_p.h" 50*0Sstevel@tonic-gate #include "lcl_p.h" 51*0Sstevel@tonic-gate #include "irp_p.h" 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate #include "port_after.h" 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate #define MAXALIASES 35 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate /* Types */ 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate struct pvt { 61*0Sstevel@tonic-gate struct irp_p *girpdata; 62*0Sstevel@tonic-gate int warned; 63*0Sstevel@tonic-gate struct protoent proto; 64*0Sstevel@tonic-gate }; 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate /* Forward */ 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gate static void pr_close(struct irs_pr *); 69*0Sstevel@tonic-gate static struct protoent * pr_next(struct irs_pr *); 70*0Sstevel@tonic-gate static struct protoent * pr_byname(struct irs_pr *, const char *); 71*0Sstevel@tonic-gate static struct protoent * pr_bynumber(struct irs_pr *, int); 72*0Sstevel@tonic-gate static void pr_rewind(struct irs_pr *); 73*0Sstevel@tonic-gate static void pr_minimize(struct irs_pr *); 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate static void free_proto(struct protoent *pr); 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate /* Public */ 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gate /* 82*0Sstevel@tonic-gate * struct irs_pr * irs_irp_pr(struct irs_acc *this) 83*0Sstevel@tonic-gate * 84*0Sstevel@tonic-gate */ 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate struct irs_pr * 87*0Sstevel@tonic-gate irs_irp_pr(struct irs_acc *this) { 88*0Sstevel@tonic-gate struct irs_pr *pr; 89*0Sstevel@tonic-gate struct pvt *pvt; 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate if (!(pr = memget(sizeof *pr))) { 92*0Sstevel@tonic-gate errno = ENOMEM; 93*0Sstevel@tonic-gate return (NULL); 94*0Sstevel@tonic-gate } 95*0Sstevel@tonic-gate memset(pr, 0x0, sizeof *pr); 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate if (!(pvt = memget(sizeof *pvt))) { 98*0Sstevel@tonic-gate memput(pr, sizeof *pr); 99*0Sstevel@tonic-gate errno = ENOMEM; 100*0Sstevel@tonic-gate return (NULL); 101*0Sstevel@tonic-gate } 102*0Sstevel@tonic-gate memset(pvt, 0, sizeof *pvt); 103*0Sstevel@tonic-gate pvt->girpdata = this->private; 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate pr->private = pvt; 106*0Sstevel@tonic-gate pr->close = pr_close; 107*0Sstevel@tonic-gate pr->byname = pr_byname; 108*0Sstevel@tonic-gate pr->bynumber = pr_bynumber; 109*0Sstevel@tonic-gate pr->next = pr_next; 110*0Sstevel@tonic-gate pr->rewind = pr_rewind; 111*0Sstevel@tonic-gate pr->minimize = pr_minimize; 112*0Sstevel@tonic-gate return (pr); 113*0Sstevel@tonic-gate } 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate /* Methods */ 116*0Sstevel@tonic-gate 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate /* 120*0Sstevel@tonic-gate * void pr_close(struct irs_pr *this) 121*0Sstevel@tonic-gate * 122*0Sstevel@tonic-gate */ 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate static void 125*0Sstevel@tonic-gate pr_close(struct irs_pr *this) { 126*0Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate pr_minimize(this); 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate free_proto(&pvt->proto); 131*0Sstevel@tonic-gate 132*0Sstevel@tonic-gate memput(pvt, sizeof *pvt); 133*0Sstevel@tonic-gate memput(this, sizeof *this); 134*0Sstevel@tonic-gate } 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate /* 139*0Sstevel@tonic-gate * struct protoent * pr_byname(struct irs_pr *this, const char *name) 140*0Sstevel@tonic-gate * 141*0Sstevel@tonic-gate */ 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate static struct protoent * 144*0Sstevel@tonic-gate pr_byname(struct irs_pr *this, const char *name) { 145*0Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 146*0Sstevel@tonic-gate struct protoent *pr = &pvt->proto; 147*0Sstevel@tonic-gate char *body = NULL; 148*0Sstevel@tonic-gate size_t bodylen; 149*0Sstevel@tonic-gate int code; 150*0Sstevel@tonic-gate int i; 151*0Sstevel@tonic-gate char text[256]; 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gate if (pr->p_name != NULL && strcmp(name, pr->p_name) == 0) { 154*0Sstevel@tonic-gate return (pr); 155*0Sstevel@tonic-gate } 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 158*0Sstevel@tonic-gate return (NULL); 159*0Sstevel@tonic-gate } 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate i = irs_irp_send_command(pvt->girpdata, "getprotobyname %s", name); 162*0Sstevel@tonic-gate if (i != 0) 163*0Sstevel@tonic-gate return (NULL); 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate if (irs_irp_get_full_response(pvt->girpdata, &code, 166*0Sstevel@tonic-gate text, sizeof text, 167*0Sstevel@tonic-gate &body, &bodylen) != 0) { 168*0Sstevel@tonic-gate return (NULL); 169*0Sstevel@tonic-gate } 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate if (code == IRPD_GETPROTO_OK) { 172*0Sstevel@tonic-gate free_proto(pr); 173*0Sstevel@tonic-gate if (irp_unmarshall_pr(pr, body) != 0) { 174*0Sstevel@tonic-gate pr = NULL; 175*0Sstevel@tonic-gate } 176*0Sstevel@tonic-gate } else { 177*0Sstevel@tonic-gate pr = NULL; 178*0Sstevel@tonic-gate } 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate if (body != NULL) { 181*0Sstevel@tonic-gate memput(body, bodylen); 182*0Sstevel@tonic-gate } 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate return (pr); 185*0Sstevel@tonic-gate } 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate /* 190*0Sstevel@tonic-gate * struct protoent * pr_bynumber(struct irs_pr *this, int proto) 191*0Sstevel@tonic-gate * 192*0Sstevel@tonic-gate */ 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gate static struct protoent * 195*0Sstevel@tonic-gate pr_bynumber(struct irs_pr *this, int proto) { 196*0Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 197*0Sstevel@tonic-gate struct protoent *pr = &pvt->proto; 198*0Sstevel@tonic-gate char *body = NULL; 199*0Sstevel@tonic-gate size_t bodylen; 200*0Sstevel@tonic-gate int code; 201*0Sstevel@tonic-gate int i; 202*0Sstevel@tonic-gate char text[256]; 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate if (pr->p_name != NULL && proto == pr->p_proto) { 205*0Sstevel@tonic-gate return (pr); 206*0Sstevel@tonic-gate } 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 209*0Sstevel@tonic-gate return (NULL); 210*0Sstevel@tonic-gate } 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate i = irs_irp_send_command(pvt->girpdata, "getprotobynumber %d", proto); 213*0Sstevel@tonic-gate if (i != 0) 214*0Sstevel@tonic-gate return (NULL); 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate if (irs_irp_get_full_response(pvt->girpdata, &code, 217*0Sstevel@tonic-gate text, sizeof text, 218*0Sstevel@tonic-gate &body, &bodylen) != 0) { 219*0Sstevel@tonic-gate return (NULL); 220*0Sstevel@tonic-gate } 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate if (code == IRPD_GETPROTO_OK) { 223*0Sstevel@tonic-gate free_proto(pr); 224*0Sstevel@tonic-gate if (irp_unmarshall_pr(pr, body) != 0) { 225*0Sstevel@tonic-gate pr = NULL; 226*0Sstevel@tonic-gate } 227*0Sstevel@tonic-gate } else { 228*0Sstevel@tonic-gate pr = NULL; 229*0Sstevel@tonic-gate } 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate if (body != NULL) { 232*0Sstevel@tonic-gate memput(body, bodylen); 233*0Sstevel@tonic-gate } 234*0Sstevel@tonic-gate 235*0Sstevel@tonic-gate return (pr); 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate /* 242*0Sstevel@tonic-gate * void pr_rewind(struct irs_pr *this) 243*0Sstevel@tonic-gate * 244*0Sstevel@tonic-gate */ 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gate static void 247*0Sstevel@tonic-gate pr_rewind(struct irs_pr *this) { 248*0Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 249*0Sstevel@tonic-gate char text[256]; 250*0Sstevel@tonic-gate int code; 251*0Sstevel@tonic-gate 252*0Sstevel@tonic-gate if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 253*0Sstevel@tonic-gate return; 254*0Sstevel@tonic-gate } 255*0Sstevel@tonic-gate 256*0Sstevel@tonic-gate if (irs_irp_send_command(pvt->girpdata, "setprotoent") != 0) { 257*0Sstevel@tonic-gate return; 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate 260*0Sstevel@tonic-gate code = irs_irp_read_response(pvt->girpdata, text, sizeof text); 261*0Sstevel@tonic-gate if (code != IRPD_GETPROTO_SETOK) { 262*0Sstevel@tonic-gate if (irp_log_errors) { 263*0Sstevel@tonic-gate syslog(LOG_WARNING, "setprotoent failed: %s", text); 264*0Sstevel@tonic-gate } 265*0Sstevel@tonic-gate } 266*0Sstevel@tonic-gate 267*0Sstevel@tonic-gate return; 268*0Sstevel@tonic-gate } 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate 272*0Sstevel@tonic-gate 273*0Sstevel@tonic-gate /* 274*0Sstevel@tonic-gate * struct protoent * pr_next(struct irs_pr *this) 275*0Sstevel@tonic-gate * 276*0Sstevel@tonic-gate * Notes: 277*0Sstevel@tonic-gate * 278*0Sstevel@tonic-gate * Prepares the cache if necessary and returns the next item in it. 279*0Sstevel@tonic-gate * 280*0Sstevel@tonic-gate */ 281*0Sstevel@tonic-gate 282*0Sstevel@tonic-gate static struct protoent * 283*0Sstevel@tonic-gate pr_next(struct irs_pr *this) { 284*0Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 285*0Sstevel@tonic-gate struct protoent *pr = &pvt->proto; 286*0Sstevel@tonic-gate char *body; 287*0Sstevel@tonic-gate size_t bodylen; 288*0Sstevel@tonic-gate int code; 289*0Sstevel@tonic-gate char text[256]; 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 292*0Sstevel@tonic-gate return (NULL); 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate if (irs_irp_send_command(pvt->girpdata, "getprotoent") != 0) { 296*0Sstevel@tonic-gate return (NULL); 297*0Sstevel@tonic-gate } 298*0Sstevel@tonic-gate 299*0Sstevel@tonic-gate if (irs_irp_get_full_response(pvt->girpdata, &code, 300*0Sstevel@tonic-gate text, sizeof text, 301*0Sstevel@tonic-gate &body, &bodylen) != 0) { 302*0Sstevel@tonic-gate return (NULL); 303*0Sstevel@tonic-gate } 304*0Sstevel@tonic-gate 305*0Sstevel@tonic-gate if (code == IRPD_GETPROTO_OK) { 306*0Sstevel@tonic-gate free_proto(pr); 307*0Sstevel@tonic-gate if (irp_unmarshall_pr(pr, body) != 0) { 308*0Sstevel@tonic-gate pr = NULL; 309*0Sstevel@tonic-gate } 310*0Sstevel@tonic-gate } else { 311*0Sstevel@tonic-gate pr = NULL; 312*0Sstevel@tonic-gate } 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate if (body != NULL) { 315*0Sstevel@tonic-gate memput(body, bodylen); 316*0Sstevel@tonic-gate } 317*0Sstevel@tonic-gate 318*0Sstevel@tonic-gate return (pr); 319*0Sstevel@tonic-gate } 320*0Sstevel@tonic-gate 321*0Sstevel@tonic-gate 322*0Sstevel@tonic-gate 323*0Sstevel@tonic-gate 324*0Sstevel@tonic-gate /* 325*0Sstevel@tonic-gate * void pr_minimize(struct irs_pr *this) 326*0Sstevel@tonic-gate * 327*0Sstevel@tonic-gate */ 328*0Sstevel@tonic-gate 329*0Sstevel@tonic-gate static void 330*0Sstevel@tonic-gate pr_minimize(struct irs_pr *this) { 331*0Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 332*0Sstevel@tonic-gate 333*0Sstevel@tonic-gate irs_irp_disconnect(pvt->girpdata); 334*0Sstevel@tonic-gate } 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate 337*0Sstevel@tonic-gate 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate /* 342*0Sstevel@tonic-gate * static void free_proto(struct protoent *pw); 343*0Sstevel@tonic-gate * 344*0Sstevel@tonic-gate * Deallocate all the memory irp_unmarshall_pr allocated. 345*0Sstevel@tonic-gate * 346*0Sstevel@tonic-gate */ 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gate static void 349*0Sstevel@tonic-gate free_proto(struct protoent *pr) { 350*0Sstevel@tonic-gate char **p; 351*0Sstevel@tonic-gate 352*0Sstevel@tonic-gate if (pr == NULL) 353*0Sstevel@tonic-gate return; 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate if (pr->p_name != NULL) 356*0Sstevel@tonic-gate free(pr->p_name); 357*0Sstevel@tonic-gate 358*0Sstevel@tonic-gate for (p = pr->p_aliases ; p != NULL && *p != NULL ; p++) 359*0Sstevel@tonic-gate free(*p); 360*0Sstevel@tonic-gate } 361