Mercurial > notdcc
diff dcclib/su2str.c @ 0:c7f6b056b673
First import of vendor version
author | Peter Gervai <grin@grin.hu> |
---|---|
date | Tue, 10 Mar 2009 13:49:58 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcclib/su2str.c Tue Mar 10 13:49:58 2009 +0100 @@ -0,0 +1,245 @@ +/* Distributed Checksum Clearinghouse + * + * Copyright (c) 2008 by Rhyolite Software, LLC + * + * This agreement is not applicable to any entity which sells anti-spam + * solutions to others or provides an anti-spam solution as part of a + * security solution sold to other entities, or to a private network + * which employs the DCC or uses data provided by operation of the DCC + * but does not provide corresponding data to other users. + * + * Permission to use, copy, modify, and distribute this software without + * changes for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice appear in all + * copies and any distributed versions or copies are either unchanged + * or not called anything similar to "DCC" or "Distributed Checksum + * Clearinghouse". + * + * Parties not eligible to receive a license under this agreement can + * obtain a commercial license to use DCC by contacting Rhyolite Software + * at sales@rhyolite.com. + * + * A commercial license would be for Distributed Checksum and Reputation + * Clearinghouse software. That software includes additional features. This + * free license for Distributed ChecksumClearinghouse Software does not in any + * way grant permision to use Distributed Checksum and Reputation Clearinghouse + * software + * + * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC + * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Rhyolite Software DCC 1.3.103-1.42 $Revision$ + */ + +#include "dcc_defs.h" +#ifndef DCC_WIN32 +#include <arpa/inet.h> +#endif + +#if !defined(HAVE_INET_NTOP) || defined(NO_IPV6) +#define DCC_INET_NTOP dcc_inet_ntop +extern const char *DCC_INET_NTOP(int, const void *, char *, size_t); +#else +#define DCC_INET_NTOP inet_ntop +#endif + + + +/* strip IPv6 prefix from ::ffff:10.2.3.4 */ +const char * +dcc_trim_ffff(const char *str) +{ + return strncmp("::ffff:", str, 7) ? str : (str+7); +} + + + +const char * +dcc_ipv4tostr(char *buf, int buf_len, const struct in_addr *addr4) +{ + if (!DCC_INET_NTOP(AF_INET, addr4, buf, buf_len)) + STRLCPY(buf, "???", buf_len); + return buf; +} + + + +const char * +dcc_ipv6tostr(char *buf, int buf_len, const struct in6_addr *addr6) +{ + if (!DCC_INET_NTOP(AF_INET6, addr6, buf, buf_len)) + STRLCPY(buf, "???", buf_len); + return buf; +} + + + +const char * +dcc_ipv6tostr2(char *buf, int buf_len, const struct in6_addr *addr6) +{ + struct in_addr addr4; + + if (dcc_ipv6toipv4(&addr4, addr6)) + return dcc_ipv4tostr(buf, buf_len, &addr4); + + if (!DCC_INET_NTOP(AF_INET6, addr6, buf, buf_len)) + STRLCPY(buf, "???", buf_len); + return buf; +} + + + +const char * +dcc_ip2str(char *buf, int buf_len, const DCC_IP *ip) +{ + if (ip->family == AF_INET) + return dcc_ipv4tostr(buf, buf_len, &ip->u.v4); + else + return dcc_ipv6tostr(buf, buf_len, &ip->u.v6); +} + + + +/* convert to a string including the port number. + * try to make a short IPv4 string */ +const char * +dcc_su2str(char *buf, int buf_len, const DCC_SOCKU *su) +{ + int i; + + if (su->sa.sa_family == AF_INET) { + dcc_ipv4tostr(buf, buf_len, &su->ipv4.sin_addr); + } else { + dcc_ipv6tostr2(buf, buf_len, &su->ipv6.sin6_addr); + } + i = strlen(buf); + snprintf(buf+i, buf_len-i, ",%d", ntohs(*DCC_SU_PORTP(su))); + return buf; +} + + + +/* convert to a string without the port number. + * try to make a short IPv4 string */ +const char * +dcc_su2str2(char *buf, int buf_len, const DCC_SOCKU *su) +{ + if (su->sa.sa_family == AF_INET) + return dcc_ipv4tostr(buf, buf_len, &su->ipv4.sin_addr); + + return dcc_ipv6tostr2(buf, buf_len, &su->ipv6.sin6_addr); +} + + + +/* convert to a string without a boring port number + * try to make a short IPv4 string */ +const char * +dcc_su2str3(char *buf, int buf_len, const DCC_SOCKU *su, u_short port) +{ + if (*DCC_SU_PORTP(su) != port) { + return dcc_su2str(buf, buf_len, su); + } else { + return dcc_su2str2(buf, buf_len, su); + } +} + + + +/* Convert IP address to a string, but not into a single buffer + * This is not thread safe but good enough for error messages */ +const char * +dcc_su2str_err(const DCC_SOCKU *su) +{ + static int bufno; + static struct { + char str[DCC_SU2STR_SIZE]; + } bufs[4]; + char *s; + + s = bufs[bufno].str; + bufno = (bufno+1) % DIM(bufs); + return dcc_su2str(s, sizeof(bufs[0].str), su); +} + + + +const char * +dcc_host_portname(char *buf, int buf_len, + const char *hostname, const char *portname) +{ + if (!portname || *portname == '\0' || !strcmp(portname, "-")) { + STRLCPY(buf, hostname, buf_len); + } else { + snprintf(buf, buf_len, "%s,%s", hostname, portname); + } + return buf; +} + + + +/* Convert IP address to a name */ +const char * +dcc_su2name(char *name, int name_len, const DCC_SOCKU *su) +{ +#undef EXPANDED +#if defined(USE_GETIPNODEBYNAME) && !defined(EXPANDED) && !defined(NO_IPV6) +#define EXPANDED + struct hostent *hp; + int error; + + dcc_host_lock(); + if (su->sa.sa_family == AF_INET) + hp = getipnodebyaddr(&su->ipv4.sin_addr, + sizeof(su->ipv4.sin_addr), + su->sa.sa_family, &error); + else + hp = getipnodebyaddr(&su->ipv6.sin6_addr, + sizeof(su->ipv6.sin6_addr), + su->sa.sa_family, &error); + if (!hp) { + if (name_len > 0) + *name = '\0'; + } else { + if (name_len > 0) + STRLCPY(name, hp->h_name, name_len); + freehostent(hp); + } + dcc_host_unlock(); +#endif +#if defined(USE_GETADDRINFO) && !defined(EXPANDED) && !defined(NO_IPV6) +#define EXPANDED + int error; + + dcc_host_lock(); + error = getnameinfo(&su->sa, DCC_SU_LEN(su), + name, name_len, 0, 0, NI_NAMEREQD); + dcc_host_unlock(); + if (error && name_len > 0) + *name = '\0'; +#endif +#ifndef EXPANDED + struct hostent *hp; + DCC_SOCKU su4; + + dcc_host_lock(); + if (dcc_ipv6sutoipv4(&su4, su)) { + hp = gethostbyaddr((char *)&su4.ipv4.sin_addr, + sizeof(su4.ipv4.sin_addr), + AF_INET); + } else { + hp = 0; + } + if (name_len > 0) + STRLCPY(name, hp ? hp->h_name : "", name_len); + dcc_host_unlock(); +#endif + return name; +#undef EXPANDED +}