diff options
| author | christos <christos@NetBSD.org> | 2004-11-19 21:37:19 +0000 |
|---|---|---|
| committer | christos <christos@NetBSD.org> | 2004-11-19 21:37:19 +0000 |
| commit | eb6484700a73a8dacd698c895aefc95c41063645 (patch) | |
| tree | ec6521706012ad76f3e2da52174d1010d2ace723 | |
| parent | 8ff9670d6095aa285b6c7b1b904634fd31afdea2 (diff) | |
Add sockaddr_snprintf; XXX: Needs a man page.
| -rw-r--r-- | lib/libutil/Makefile | 4 | ||||
| -rw-r--r-- | lib/libutil/shlib_version | 4 | ||||
| -rw-r--r-- | lib/libutil/sockaddr_snprintf.c | 194 |
3 files changed, 198 insertions, 4 deletions
diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile index 7d3f86f15c0..bb111dc3368 100644 --- a/lib/libutil/Makefile +++ b/lib/libutil/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.44 2004/11/11 20:36:28 dsl Exp $ +# $NetBSD: Makefile,v 1.45 2004/11/19 21:37:19 christos Exp $ # @(#)Makefile 8.1 (Berkeley) 6/4/93 USE_SHLIBDIR= yes @@ -14,7 +14,7 @@ SRCS= getbootfile.c getlabelsector.c getmaxpartitions.c \ login.c loginx.c login_cap.c login_tty.c logout.c logoutx.c \ logwtmp.c logwtmpx.c opendisk.c \ passwd.c pw_scan.c pidfile.c pidlock.c pty.c secure_path.c \ - snprintb.c ttyaction.c ttymsg.c + snprintb.c sockaddr_snprintf.c ttyaction.c ttymsg.c MAN= getbootfile.3 getlabelsector.3 getmaxpartitions.3 \ getmntopts.3 \ diff --git a/lib/libutil/shlib_version b/lib/libutil/shlib_version index 2e0489fb5f4..997f9e77f1e 100644 --- a/lib/libutil/shlib_version +++ b/lib/libutil/shlib_version @@ -1,5 +1,5 @@ -# $NetBSD: shlib_version,v 1.34 2004/08/03 23:29:05 thorpej Exp $ +# $NetBSD: shlib_version,v 1.35 2004/11/19 21:37:19 christos Exp $ # Remember to update distrib/sets/lists/base/shl.* when changing # major=7 -minor=4 +minor=5 diff --git a/lib/libutil/sockaddr_snprintf.c b/lib/libutil/sockaddr_snprintf.c new file mode 100644 index 00000000000..095527243f2 --- /dev/null +++ b/lib/libutil/sockaddr_snprintf.c @@ -0,0 +1,194 @@ +/* $NetBSD: sockaddr_snprintf.c,v 1.1 2004/11/19 21:37:19 christos Exp $ */ + +/*- + * Copyright (c) 2004 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: sockaddr_snprintf.c,v 1.1 2004/11/19 21:37:19 christos Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> + +#include <netinet/in.h> +#include <netatalk/at.h> +#include <net/if_dl.h> + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <util.h> +#include <netdb.h> + +int +sockaddr_snprintf(char *buf, size_t len, const char *fmt, + const struct sockaddr *sa) +{ + const void *a = NULL; + char abuf[1024], nbuf[1024], *addr, *w; + char *ebuf = &buf[len - 1], *sbuf = buf; + const char *ptr, *s; + in_port_t p = (in_port_t)~0; + const struct sockaddr_at *sat = NULL; + const struct sockaddr_in *sin4 = NULL; + const struct sockaddr_in6 *sin6 = NULL; + const struct sockaddr_un *sun = NULL; + const struct sockaddr_dl *sdl = NULL; + +#define ADDC(c) if (buf < ebuf) *buf++ = c; else buf++ +#define ADDN() if (buf < ebuf) *buf++ = '\0'; else buf[len - 1] = '\0' +#define ADDS(p) for (s = p; *s; s++) ADDC(*s) +#define ADDNA() ADDS("N/A") + + switch (sa->sa_family) { + case AF_UNSPEC: + goto done; + case AF_APPLETALK: + sat = ((const struct sockaddr_at *)(const void *)sa); + p = ntohs(sat->sat_port); + (void)snprintf(addr = abuf, sizeof(abuf), "%u.%u", + ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node); + break; + case AF_LOCAL: + sun = ((const struct sockaddr_un *)(const void *)sa); + (void)strlcpy(addr = abuf, sun->sun_path, SUN_LEN(sun)); + break; + case AF_INET: + sin4 = ((const struct sockaddr_in *)(const void *)sa); + p = ntohs(sin4->sin_port); + a = &sin4->sin_addr; + break; + case AF_INET6: + sin6 = ((const struct sockaddr_in6 *)(const void *)sa); + p = ntohs(sin6->sin6_port); + a = &sin6->sin6_addr; + break; + case AF_LINK: + sdl = ((const struct sockaddr_dl *)(const void *)sa); + (void)strlcpy(addr = abuf, link_ntoa(sdl), sizeof(abuf)); + if ((w = strchr(addr, ':')) != 0) { + *w++ = '\0'; + addr = w; + + } + break; + default: + errno = EAFNOSUPPORT; + return -1; + } + + if (a && getnameinfo(sa, sa->sa_len, addr = abuf, sizeof(abuf), + NULL, 0, NI_NUMERICHOST|NI_NUMERICSERV) == -1) + return -1; + + for (ptr = fmt; *ptr; ptr++) { + if (*ptr != '%') { + ADDC(*ptr); + continue; + } + switch (*++ptr) { + case '\0': + ADDC('%'); + goto done; + case 'a': + ADDS(addr); + break; + case 'p': + if (p != (in_port_t)~0) { + (void)snprintf(nbuf, sizeof(nbuf), "%d", p); + ADDS(nbuf); + } else { + ADDNA(); + } + break; + case 'f': + (void)snprintf(nbuf, sizeof(nbuf), "%d", sa->sa_family); + ADDS(nbuf); + break; + case 'l': + (void)snprintf(nbuf, sizeof(nbuf), "%d", sa->sa_len); + ADDS(nbuf); + break; + case 'I': + if (sdl && addr != abuf) { + ADDS(abuf); + } else { + ADDNA(); + } + break; + case 'F': + if (sin6) { + (void)snprintf(nbuf, sizeof(nbuf), "%d", + sin6->sin6_flowinfo); + ADDS(nbuf); + break; + } else { + ADDNA(); + } + break; + case 'S': + if (sin6) { + (void)snprintf(nbuf, sizeof(nbuf), "%d", + sin6->sin6_scope_id); + ADDS(nbuf); + break; + } else { + ADDNA(); + } + break; + case 'R': + if (sat) { + const struct netrange *n = + &sat->sat_range.r_netrange; + (void)snprintf(nbuf, sizeof(nbuf), + "%d:[%d,%d]", n->nr_phase , n->nr_firstnet, + n->nr_lastnet); + ADDS(nbuf); + } else { + ADDNA(); + } + break; + default: + ADDC('%'); + ADDC(*ptr); + break; + } + } +done: + ADDN(); + return buf - sbuf; +} |
