1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved. 3*0Sstevel@tonic-gate * Use is subject to license terms. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate 6*0Sstevel@tonic-gate #if !defined(lint) && !defined(SABER) 7*0Sstevel@tonic-gate static const char rcsid[] = "$Id: ctl_p.c,v 8.8 2001/05/29 05:49:26 marka Exp $"; 8*0Sstevel@tonic-gate #endif /* not lint */ 9*0Sstevel@tonic-gate 10*0Sstevel@tonic-gate /* 11*0Sstevel@tonic-gate * Copyright (c) 1998,1999 by Internet Software Consortium. 12*0Sstevel@tonic-gate * 13*0Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any 14*0Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 15*0Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 16*0Sstevel@tonic-gate * 17*0Sstevel@tonic-gate * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 18*0Sstevel@tonic-gate * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 19*0Sstevel@tonic-gate * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 20*0Sstevel@tonic-gate * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 21*0Sstevel@tonic-gate * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 22*0Sstevel@tonic-gate * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 23*0Sstevel@tonic-gate * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 24*0Sstevel@tonic-gate * SOFTWARE. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 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 <sys/param.h> 34*0Sstevel@tonic-gate #include <sys/file.h> 35*0Sstevel@tonic-gate #include <sys/socket.h> 36*0Sstevel@tonic-gate #include <sys/un.h> 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate #include <netinet/in.h> 39*0Sstevel@tonic-gate #include <arpa/nameser.h> 40*0Sstevel@tonic-gate #include <arpa/inet.h> 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gate #include <errno.h> 43*0Sstevel@tonic-gate #include <stdio.h> 44*0Sstevel@tonic-gate #include <stdlib.h> 45*0Sstevel@tonic-gate #include <string.h> 46*0Sstevel@tonic-gate #include <time.h> 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate #include <isc/assertions.h> 49*0Sstevel@tonic-gate #include <isc/eventlib.h> 50*0Sstevel@tonic-gate #include <isc/logging.h> 51*0Sstevel@tonic-gate #include <isc/memcluster.h> 52*0Sstevel@tonic-gate #include <isc/ctl.h> 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate #include "ctl_p.h" 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate #include "port_after.h" 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate /* Constants. */ 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate const char * const ctl_sevnames[] = { 61*0Sstevel@tonic-gate "debug", "warning", "error" 62*0Sstevel@tonic-gate }; 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate /* Public. */ 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate /* 67*0Sstevel@tonic-gate * ctl_logger() 68*0Sstevel@tonic-gate * if ctl_startup()'s caller didn't specify a logger, this one 69*0Sstevel@tonic-gate * is used. this pollutes stderr with all kinds of trash so it will 70*0Sstevel@tonic-gate * probably never be used in real applications. 71*0Sstevel@tonic-gate */ 72*0Sstevel@tonic-gate void 73*0Sstevel@tonic-gate ctl_logger(enum ctl_severity severity, const char *format, ...) { 74*0Sstevel@tonic-gate va_list ap; 75*0Sstevel@tonic-gate static const char me[] = "ctl_logger"; 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate fprintf(stderr, "%s(%s): ", me, ctl_sevnames[severity]); 78*0Sstevel@tonic-gate va_start(ap, format); 79*0Sstevel@tonic-gate vfprintf(stderr, format, ap); 80*0Sstevel@tonic-gate va_end(ap); 81*0Sstevel@tonic-gate fputc('\n', stderr); 82*0Sstevel@tonic-gate } 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate int 85*0Sstevel@tonic-gate ctl_bufget(struct ctl_buf *buf, ctl_logfunc logger) { 86*0Sstevel@tonic-gate static const char me[] = "ctl_bufget"; 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate REQUIRE(!allocated_p(*buf) && buf->used == 0); 89*0Sstevel@tonic-gate buf->text = memget(MAX_LINELEN); 90*0Sstevel@tonic-gate if (!allocated_p(*buf)) { 91*0Sstevel@tonic-gate (*logger)(ctl_error, "%s: getmem: %s", me, strerror(errno)); 92*0Sstevel@tonic-gate return (-1); 93*0Sstevel@tonic-gate } 94*0Sstevel@tonic-gate buf->used = 0; 95*0Sstevel@tonic-gate return (0); 96*0Sstevel@tonic-gate } 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate void 99*0Sstevel@tonic-gate ctl_bufput(struct ctl_buf *buf) { 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate REQUIRE(allocated_p(*buf)); 102*0Sstevel@tonic-gate memput(buf->text, MAX_LINELEN); 103*0Sstevel@tonic-gate buf->text = NULL; 104*0Sstevel@tonic-gate buf->used = 0; 105*0Sstevel@tonic-gate } 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate const char * 108*0Sstevel@tonic-gate ctl_sa_ntop(const struct sockaddr *sa, 109*0Sstevel@tonic-gate char *buf, size_t size, 110*0Sstevel@tonic-gate ctl_logfunc logger) 111*0Sstevel@tonic-gate { 112*0Sstevel@tonic-gate static const char me[] = "ctl_sa_ntop"; 113*0Sstevel@tonic-gate static const char punt[] = "[0].-1"; 114*0Sstevel@tonic-gate char tmp[INET6_ADDRSTRLEN]; 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate switch (sa->sa_family) { 117*0Sstevel@tonic-gate case AF_INET6: { 118*0Sstevel@tonic-gate const struct sockaddr_in6 *in6 = 119*0Sstevel@tonic-gate (const struct sockaddr_in6 *) sa; 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate if (inet_ntop(in6->sin6_family, &in6->sin6_addr, tmp, sizeof tmp) 122*0Sstevel@tonic-gate == NULL) { 123*0Sstevel@tonic-gate (*logger)(ctl_error, "%s: inet_ntop(%u %04x): %s", 124*0Sstevel@tonic-gate me, in6->sin6_family, 125*0Sstevel@tonic-gate in6->sin6_port, strerror(errno)); 126*0Sstevel@tonic-gate return (punt); 127*0Sstevel@tonic-gate } 128*0Sstevel@tonic-gate if (strlen(tmp) + sizeof "[].65535" > size) { 129*0Sstevel@tonic-gate (*logger)(ctl_error, "%s: buffer overflow", me); 130*0Sstevel@tonic-gate return (punt); 131*0Sstevel@tonic-gate } 132*0Sstevel@tonic-gate (void) sprintf(buf, "[%s].%u", tmp, ntohs(in6->sin6_port)); 133*0Sstevel@tonic-gate return (buf); 134*0Sstevel@tonic-gate } 135*0Sstevel@tonic-gate case AF_INET: { 136*0Sstevel@tonic-gate const struct sockaddr_in *in = 137*0Sstevel@tonic-gate (const struct sockaddr_in *) sa; 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate if (inet_ntop(in->sin_family, &in->sin_addr, tmp, sizeof tmp) 140*0Sstevel@tonic-gate == NULL) { 141*0Sstevel@tonic-gate (*logger)(ctl_error, "%s: inet_ntop(%u %04x %08x): %s", 142*0Sstevel@tonic-gate me, in->sin_family, 143*0Sstevel@tonic-gate in->sin_port, in->sin_addr.s_addr, 144*0Sstevel@tonic-gate strerror(errno)); 145*0Sstevel@tonic-gate return (punt); 146*0Sstevel@tonic-gate } 147*0Sstevel@tonic-gate if (strlen(tmp) + sizeof "[].65535" > size) { 148*0Sstevel@tonic-gate (*logger)(ctl_error, "%s: buffer overflow", me); 149*0Sstevel@tonic-gate return (punt); 150*0Sstevel@tonic-gate } 151*0Sstevel@tonic-gate (void) sprintf(buf, "[%s].%u", tmp, ntohs(in->sin_port)); 152*0Sstevel@tonic-gate return (buf); 153*0Sstevel@tonic-gate } 154*0Sstevel@tonic-gate #ifndef NO_SOCKADDR_UN 155*0Sstevel@tonic-gate case AF_UNIX: { 156*0Sstevel@tonic-gate const struct sockaddr_un *un = 157*0Sstevel@tonic-gate (const struct sockaddr_un *) sa; 158*0Sstevel@tonic-gate unsigned int x = sizeof un->sun_path; 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate if (x > size) 161*0Sstevel@tonic-gate x = size; 162*0Sstevel@tonic-gate strncpy(buf, un->sun_path, x - 1); 163*0Sstevel@tonic-gate buf[x - 1] = '\0'; 164*0Sstevel@tonic-gate return (buf); 165*0Sstevel@tonic-gate } 166*0Sstevel@tonic-gate #endif 167*0Sstevel@tonic-gate default: 168*0Sstevel@tonic-gate return (punt); 169*0Sstevel@tonic-gate } 170*0Sstevel@tonic-gate } 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate void 173*0Sstevel@tonic-gate ctl_sa_copy(const struct sockaddr *src, struct sockaddr *dst) { 174*0Sstevel@tonic-gate switch (src->sa_family) { 175*0Sstevel@tonic-gate case AF_INET6: 176*0Sstevel@tonic-gate *((struct sockaddr_in6 *)dst) = 177*0Sstevel@tonic-gate *((const struct sockaddr_in6 *)src); 178*0Sstevel@tonic-gate break; 179*0Sstevel@tonic-gate case AF_INET: 180*0Sstevel@tonic-gate *((struct sockaddr_in *)dst) = 181*0Sstevel@tonic-gate *((const struct sockaddr_in *)src); 182*0Sstevel@tonic-gate break; 183*0Sstevel@tonic-gate #ifndef NO_SOCKADDR_UN 184*0Sstevel@tonic-gate case AF_UNIX: 185*0Sstevel@tonic-gate *((struct sockaddr_un *)dst) = 186*0Sstevel@tonic-gate *((const struct sockaddr_un *)src); 187*0Sstevel@tonic-gate break; 188*0Sstevel@tonic-gate #endif 189*0Sstevel@tonic-gate default: 190*0Sstevel@tonic-gate *dst = *src; 191*0Sstevel@tonic-gate break; 192*0Sstevel@tonic-gate } 193*0Sstevel@tonic-gate } 194