10Sstevel@tonic-gate #if !defined(lint) && !defined(SABER) 2*11038SRao.Shoaib@Sun.COM static const char rcsid[] = "$Id: ctl_p.c,v 1.4 2005/04/27 04:56:35 sra Exp $"; 30Sstevel@tonic-gate #endif /* not lint */ 40Sstevel@tonic-gate 50Sstevel@tonic-gate /* 6*11038SRao.Shoaib@Sun.COM * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 70Sstevel@tonic-gate * Copyright (c) 1998,1999 by Internet Software Consortium. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any 100Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 110Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 120Sstevel@tonic-gate * 13*11038SRao.Shoaib@Sun.COM * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 14*11038SRao.Shoaib@Sun.COM * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15*11038SRao.Shoaib@Sun.COM * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 16*11038SRao.Shoaib@Sun.COM * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17*11038SRao.Shoaib@Sun.COM * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18*11038SRao.Shoaib@Sun.COM * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 19*11038SRao.Shoaib@Sun.COM * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate 220Sstevel@tonic-gate /* Extern. */ 230Sstevel@tonic-gate 240Sstevel@tonic-gate #include "port_before.h" 250Sstevel@tonic-gate 260Sstevel@tonic-gate #include <sys/param.h> 270Sstevel@tonic-gate #include <sys/file.h> 280Sstevel@tonic-gate #include <sys/socket.h> 290Sstevel@tonic-gate #include <sys/un.h> 300Sstevel@tonic-gate 310Sstevel@tonic-gate #include <netinet/in.h> 320Sstevel@tonic-gate #include <arpa/nameser.h> 330Sstevel@tonic-gate #include <arpa/inet.h> 340Sstevel@tonic-gate 350Sstevel@tonic-gate #include <errno.h> 360Sstevel@tonic-gate #include <stdio.h> 370Sstevel@tonic-gate #include <stdlib.h> 380Sstevel@tonic-gate #include <string.h> 390Sstevel@tonic-gate #include <time.h> 400Sstevel@tonic-gate 410Sstevel@tonic-gate #include <isc/assertions.h> 420Sstevel@tonic-gate #include <isc/eventlib.h> 430Sstevel@tonic-gate #include <isc/logging.h> 440Sstevel@tonic-gate #include <isc/memcluster.h> 450Sstevel@tonic-gate #include <isc/ctl.h> 460Sstevel@tonic-gate 470Sstevel@tonic-gate #include "ctl_p.h" 480Sstevel@tonic-gate 490Sstevel@tonic-gate #include "port_after.h" 500Sstevel@tonic-gate 510Sstevel@tonic-gate /* Constants. */ 520Sstevel@tonic-gate 530Sstevel@tonic-gate const char * const ctl_sevnames[] = { 540Sstevel@tonic-gate "debug", "warning", "error" 550Sstevel@tonic-gate }; 560Sstevel@tonic-gate 570Sstevel@tonic-gate /* Public. */ 580Sstevel@tonic-gate 59*11038SRao.Shoaib@Sun.COM /*% 600Sstevel@tonic-gate * ctl_logger() 610Sstevel@tonic-gate * if ctl_startup()'s caller didn't specify a logger, this one 620Sstevel@tonic-gate * is used. this pollutes stderr with all kinds of trash so it will 630Sstevel@tonic-gate * probably never be used in real applications. 640Sstevel@tonic-gate */ 650Sstevel@tonic-gate void 660Sstevel@tonic-gate ctl_logger(enum ctl_severity severity, const char *format, ...) { 670Sstevel@tonic-gate va_list ap; 680Sstevel@tonic-gate static const char me[] = "ctl_logger"; 690Sstevel@tonic-gate 700Sstevel@tonic-gate fprintf(stderr, "%s(%s): ", me, ctl_sevnames[severity]); 710Sstevel@tonic-gate va_start(ap, format); 720Sstevel@tonic-gate vfprintf(stderr, format, ap); 730Sstevel@tonic-gate va_end(ap); 740Sstevel@tonic-gate fputc('\n', stderr); 750Sstevel@tonic-gate } 760Sstevel@tonic-gate 770Sstevel@tonic-gate int 780Sstevel@tonic-gate ctl_bufget(struct ctl_buf *buf, ctl_logfunc logger) { 790Sstevel@tonic-gate static const char me[] = "ctl_bufget"; 800Sstevel@tonic-gate 81*11038SRao.Shoaib@Sun.COM REQUIRE(!allocated_p(*buf) && buf->used == 0U); 820Sstevel@tonic-gate buf->text = memget(MAX_LINELEN); 830Sstevel@tonic-gate if (!allocated_p(*buf)) { 840Sstevel@tonic-gate (*logger)(ctl_error, "%s: getmem: %s", me, strerror(errno)); 850Sstevel@tonic-gate return (-1); 860Sstevel@tonic-gate } 870Sstevel@tonic-gate buf->used = 0; 880Sstevel@tonic-gate return (0); 890Sstevel@tonic-gate } 900Sstevel@tonic-gate 910Sstevel@tonic-gate void 920Sstevel@tonic-gate ctl_bufput(struct ctl_buf *buf) { 930Sstevel@tonic-gate 940Sstevel@tonic-gate REQUIRE(allocated_p(*buf)); 950Sstevel@tonic-gate memput(buf->text, MAX_LINELEN); 960Sstevel@tonic-gate buf->text = NULL; 970Sstevel@tonic-gate buf->used = 0; 980Sstevel@tonic-gate } 990Sstevel@tonic-gate 1000Sstevel@tonic-gate const char * 1010Sstevel@tonic-gate ctl_sa_ntop(const struct sockaddr *sa, 1020Sstevel@tonic-gate char *buf, size_t size, 1030Sstevel@tonic-gate ctl_logfunc logger) 1040Sstevel@tonic-gate { 1050Sstevel@tonic-gate static const char me[] = "ctl_sa_ntop"; 1060Sstevel@tonic-gate static const char punt[] = "[0].-1"; 1070Sstevel@tonic-gate char tmp[INET6_ADDRSTRLEN]; 1080Sstevel@tonic-gate 1090Sstevel@tonic-gate switch (sa->sa_family) { 1100Sstevel@tonic-gate case AF_INET6: { 1110Sstevel@tonic-gate const struct sockaddr_in6 *in6 = 1120Sstevel@tonic-gate (const struct sockaddr_in6 *) sa; 1130Sstevel@tonic-gate 1140Sstevel@tonic-gate if (inet_ntop(in6->sin6_family, &in6->sin6_addr, tmp, sizeof tmp) 1150Sstevel@tonic-gate == NULL) { 1160Sstevel@tonic-gate (*logger)(ctl_error, "%s: inet_ntop(%u %04x): %s", 1170Sstevel@tonic-gate me, in6->sin6_family, 1180Sstevel@tonic-gate in6->sin6_port, strerror(errno)); 1190Sstevel@tonic-gate return (punt); 1200Sstevel@tonic-gate } 1210Sstevel@tonic-gate if (strlen(tmp) + sizeof "[].65535" > size) { 1220Sstevel@tonic-gate (*logger)(ctl_error, "%s: buffer overflow", me); 1230Sstevel@tonic-gate return (punt); 1240Sstevel@tonic-gate } 1250Sstevel@tonic-gate (void) sprintf(buf, "[%s].%u", tmp, ntohs(in6->sin6_port)); 1260Sstevel@tonic-gate return (buf); 1270Sstevel@tonic-gate } 1280Sstevel@tonic-gate case AF_INET: { 1290Sstevel@tonic-gate const struct sockaddr_in *in = 1300Sstevel@tonic-gate (const struct sockaddr_in *) sa; 1310Sstevel@tonic-gate 1320Sstevel@tonic-gate if (inet_ntop(in->sin_family, &in->sin_addr, tmp, sizeof tmp) 1330Sstevel@tonic-gate == NULL) { 1340Sstevel@tonic-gate (*logger)(ctl_error, "%s: inet_ntop(%u %04x %08x): %s", 1350Sstevel@tonic-gate me, in->sin_family, 1360Sstevel@tonic-gate in->sin_port, in->sin_addr.s_addr, 1370Sstevel@tonic-gate strerror(errno)); 1380Sstevel@tonic-gate return (punt); 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate if (strlen(tmp) + sizeof "[].65535" > size) { 1410Sstevel@tonic-gate (*logger)(ctl_error, "%s: buffer overflow", me); 1420Sstevel@tonic-gate return (punt); 1430Sstevel@tonic-gate } 1440Sstevel@tonic-gate (void) sprintf(buf, "[%s].%u", tmp, ntohs(in->sin_port)); 1450Sstevel@tonic-gate return (buf); 1460Sstevel@tonic-gate } 1470Sstevel@tonic-gate #ifndef NO_SOCKADDR_UN 1480Sstevel@tonic-gate case AF_UNIX: { 1490Sstevel@tonic-gate const struct sockaddr_un *un = 1500Sstevel@tonic-gate (const struct sockaddr_un *) sa; 1510Sstevel@tonic-gate unsigned int x = sizeof un->sun_path; 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate if (x > size) 1540Sstevel@tonic-gate x = size; 1550Sstevel@tonic-gate strncpy(buf, un->sun_path, x - 1); 1560Sstevel@tonic-gate buf[x - 1] = '\0'; 1570Sstevel@tonic-gate return (buf); 1580Sstevel@tonic-gate } 1590Sstevel@tonic-gate #endif 1600Sstevel@tonic-gate default: 1610Sstevel@tonic-gate return (punt); 1620Sstevel@tonic-gate } 1630Sstevel@tonic-gate } 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate void 1660Sstevel@tonic-gate ctl_sa_copy(const struct sockaddr *src, struct sockaddr *dst) { 1670Sstevel@tonic-gate switch (src->sa_family) { 1680Sstevel@tonic-gate case AF_INET6: 1690Sstevel@tonic-gate *((struct sockaddr_in6 *)dst) = 1700Sstevel@tonic-gate *((const struct sockaddr_in6 *)src); 1710Sstevel@tonic-gate break; 1720Sstevel@tonic-gate case AF_INET: 1730Sstevel@tonic-gate *((struct sockaddr_in *)dst) = 1740Sstevel@tonic-gate *((const struct sockaddr_in *)src); 1750Sstevel@tonic-gate break; 1760Sstevel@tonic-gate #ifndef NO_SOCKADDR_UN 1770Sstevel@tonic-gate case AF_UNIX: 1780Sstevel@tonic-gate *((struct sockaddr_un *)dst) = 1790Sstevel@tonic-gate *((const struct sockaddr_un *)src); 1800Sstevel@tonic-gate break; 1810Sstevel@tonic-gate #endif 1820Sstevel@tonic-gate default: 1830Sstevel@tonic-gate *dst = *src; 1840Sstevel@tonic-gate break; 1850Sstevel@tonic-gate } 1860Sstevel@tonic-gate } 187*11038SRao.Shoaib@Sun.COM 188*11038SRao.Shoaib@Sun.COM /*! \file */ 189