diff options
| author | Mistivia <i@mistivia.com> | 2025-11-02 15:29:28 +0800 |
|---|---|---|
| committer | Mistivia <i@mistivia.com> | 2025-11-02 15:29:28 +0800 |
| commit | 9f42c2d5f911cb4e215d7873221e642ce7df4d61 (patch) | |
| tree | 6dac90a889a7402a9556d3d1bcc5cb53cdb9f123 /deprecated-ngircd/src/ipaddr | |
| parent | fb2d9de539b660a261af19b1cbcceb7ee7980cb1 (diff) | |
deprecate webircdateway and ngircd
Diffstat (limited to 'deprecated-ngircd/src/ipaddr')
| -rw-r--r-- | deprecated-ngircd/src/ipaddr/Makefile.ng | 21 | ||||
| -rw-r--r-- | deprecated-ngircd/src/ipaddr/ng_ipaddr.c | 179 | ||||
| -rw-r--r-- | deprecated-ngircd/src/ipaddr/ng_ipaddr.h | 134 |
3 files changed, 334 insertions, 0 deletions
diff --git a/deprecated-ngircd/src/ipaddr/Makefile.ng b/deprecated-ngircd/src/ipaddr/Makefile.ng new file mode 100644 index 0000000..ecfce29 --- /dev/null +++ b/deprecated-ngircd/src/ipaddr/Makefile.ng @@ -0,0 +1,21 @@ +# +# ipaddr/Makefile.am +# (c) 2008 Florian Westphal <fw@strlen.de>, public domain. +# + +__ng_Makefile_am_template__ + +EXTRA_DIST = Makefile.ng + +AM_CPPFLAGS = -I$(srcdir)/../portab + +noinst_LIBRARIES = libngipaddr.a + +libngipaddr_a_SOURCES = ng_ipaddr.c + +noinst_HEADERS = ng_ipaddr.h + +maintainer-clean-local: + rm -f Makefile Makefile.in Makefile.am + +# -eof- diff --git a/deprecated-ngircd/src/ipaddr/ng_ipaddr.c b/deprecated-ngircd/src/ipaddr/ng_ipaddr.c new file mode 100644 index 0000000..37f75b6 --- /dev/null +++ b/deprecated-ngircd/src/ipaddr/ng_ipaddr.c @@ -0,0 +1,179 @@ +/* + * (c) 2008 Florian Westphal <fw@strlen.de>, public domain. + */ + +#include "portab.h" + +/** + * @file + * Functions for AF_ agnostic ipv4/ipv6 handling. + */ + +#include <assert.h> +#include <stdio.h> +#include <string.h> + +#ifdef HAVE_GETADDRINFO +#include <netdb.h> +#include <sys/types.h> +#endif + +#include "ng_ipaddr.h" + +GLOBAL bool +ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port) +{ +#ifdef HAVE_WORKING_GETADDRINFO + int ret; + char portstr[64]; + struct addrinfo *res0; + struct addrinfo hints; + + assert(ip_str); + + memset(&hints, 0, sizeof(hints)); +#ifdef AI_NUMERICHOST + hints.ai_flags = AI_NUMERICHOST; +#endif +#ifndef WANT_IPV6 /* do not convert ipv6 addresses */ + hints.ai_family = AF_INET; +#endif + + /* some getaddrinfo implementations require that ai_socktype is set. */ + hints.ai_socktype = SOCK_STREAM; + + /* silly, but ngircd stores UINT16 in server config, not string */ + snprintf(portstr, sizeof(portstr), "%u", (unsigned int) port); + + ret = getaddrinfo(ip_str, portstr, &hints, &res0); + if (ret != 0) + return false; + + assert(sizeof(*addr) >= (size_t)res0->ai_addrlen); + if (sizeof(*addr) >= (size_t)res0->ai_addrlen) + memcpy(addr, res0->ai_addr, res0->ai_addrlen); + else + ret = -1; + freeaddrinfo(res0); + return ret == 0; +#else /* HAVE_GETADDRINFO */ + assert(ip_str); + memset(addr, 0, sizeof *addr); +#ifdef HAVE_sockaddr_in_len + addr->sin4.sin_len = sizeof(addr->sin4); +#endif + addr->sin4.sin_family = AF_INET; +# ifdef HAVE_INET_ATON + if (inet_aton(ip_str, &addr->sin4.sin_addr) == 0) + return false; +# else + addr->sin4.sin_addr.s_addr = inet_addr(ip_str); + if (addr->sin4.sin_addr.s_addr == (unsigned) -1) + return false; +# endif + ng_ipaddr_setport(addr, port); + return true; +#endif /* HAVE_GETADDRINFO */ +} + + +GLOBAL void +ng_ipaddr_setport(ng_ipaddr_t *a, UINT16 port) +{ +#ifdef WANT_IPV6 + int af; + + assert(a != NULL); + + af = a->sa.sa_family; + + assert(af == AF_INET || af == AF_INET6); + + switch (af) { + case AF_INET: + a->sin4.sin_port = htons(port); + break; + case AF_INET6: + a->sin6.sin6_port = htons(port); + break; + } +#else /* WANT_IPV6 */ + assert(a != NULL); + assert(a->sin4.sin_family == AF_INET); + a->sin4.sin_port = htons(port); +#endif /* WANT_IPV6 */ +} + + + +GLOBAL bool +ng_ipaddr_ipequal(const ng_ipaddr_t *a, const ng_ipaddr_t *b) +{ + assert(a != NULL); + assert(b != NULL); +#ifdef WANT_IPV6 + if (a->sa.sa_family != b->sa.sa_family) + return false; + assert(ng_ipaddr_salen(a) == ng_ipaddr_salen(b)); + switch (a->sa.sa_family) { + case AF_INET6: + return IN6_ARE_ADDR_EQUAL(&a->sin6.sin6_addr, &b->sin6.sin6_addr); + case AF_INET: + return memcmp(&a->sin4.sin_addr, &b->sin4.sin_addr, sizeof(a->sin4.sin_addr)) == 0; + } + return false; +#else + assert(a->sin4.sin_family == AF_INET); + assert(b->sin4.sin_family == AF_INET); + return memcmp(&a->sin4.sin_addr, &b->sin4.sin_addr, sizeof(a->sin4.sin_addr)) == 0; +#endif +} + + +#ifdef WANT_IPV6 +GLOBAL const char * +ng_ipaddr_tostr(const ng_ipaddr_t *addr) +{ + static char strbuf[NG_INET_ADDRSTRLEN]; + + strbuf[0] = 0; + + ng_ipaddr_tostr_r(addr, strbuf); + return strbuf; +} + + +/* str must be at least NG_INET_ADDRSTRLEN bytes long */ +GLOBAL bool +ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *str) +{ +#ifdef HAVE_GETNAMEINFO + const struct sockaddr *sa = (const struct sockaddr *) addr; + int ret; + + *str = 0; + + ret = getnameinfo(sa, ng_ipaddr_salen(addr), + str, NG_INET_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST); + /* + * avoid leading ':'. + * causes mis-interpretation of client host in e.g. /WHOIS + */ + if (*str == ':') { + char tmp[NG_INET_ADDRSTRLEN] = "0"; + ret = getnameinfo(sa, ng_ipaddr_salen(addr), + tmp + 1, (socklen_t)sizeof(tmp) - 1, + NULL, 0, NI_NUMERICHOST); + if (ret == 0) + strlcpy(str, tmp, NG_INET_ADDRSTRLEN); + } + assert (ret == 0); + return ret == 0; +#else + abort(); /* WANT_IPV6 depends on HAVE_GETNAMEINFO */ +#endif +} + +#endif /* WANT_IPV6 */ + +/* -eof- */ diff --git a/deprecated-ngircd/src/ipaddr/ng_ipaddr.h b/deprecated-ngircd/src/ipaddr/ng_ipaddr.h new file mode 100644 index 0000000..f8409de --- /dev/null +++ b/deprecated-ngircd/src/ipaddr/ng_ipaddr.h @@ -0,0 +1,134 @@ +/* + * (c) 2008 Florian Westphal <fw@strlen.de>, public domain. + */ + +#ifndef NG_IPADDR_HDR +#define NG_IPADDR_HDR + +#include "portab.h" + +/** + * @file + * Functions for AF_ agnostic ipv4/ipv6 handling (header). + */ + +#include <assert.h> +#include <string.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#ifdef HAVE_ARPA_INET_H +# include <arpa/inet.h> +#else +# define PF_INET AF_INET +#endif + + +#ifdef WANT_IPV6 +#define NG_INET_ADDRSTRLEN INET6_ADDRSTRLEN +#else +#define NG_INET_ADDRSTRLEN 16 +#endif + + +#ifdef WANT_IPV6 +typedef union { + struct sockaddr sa; + struct sockaddr_in sin4; + struct sockaddr_in6 sin6; +} ng_ipaddr_t; +#else +/* assume compiler can't deal with typedef struct {... */ +struct NG_IP_ADDR_DONTUSE { + struct sockaddr_in sin4; +}; +typedef struct NG_IP_ADDR_DONTUSE ng_ipaddr_t; +#endif + + +static inline int +ng_ipaddr_af(const ng_ipaddr_t *a) +{ + assert(a != NULL); +#ifdef WANT_IPV6 + return a->sa.sa_family; +#else + assert(a->sin4.sin_family == 0 || a->sin4.sin_family == AF_INET); + return a->sin4.sin_family; +#endif +} + + +static inline socklen_t +ng_ipaddr_salen(const ng_ipaddr_t *a) +{ + assert(a != NULL); +#ifdef WANT_IPV6 + assert(a->sa.sa_family == AF_INET || a->sa.sa_family == AF_INET6); + if (a->sa.sa_family == AF_INET6) + return (socklen_t)sizeof(a->sin6); +#endif + assert(a->sin4.sin_family == AF_INET); + return (socklen_t)sizeof(a->sin4); +} + + +static inline UINT16 +ng_ipaddr_getport(const ng_ipaddr_t *a) +{ +#ifdef WANT_IPV6 + int af = a->sa.sa_family; + + assert(a != NULL); + assert(af == AF_INET || af == AF_INET6); + + if (af == AF_INET6) + return ntohs(a->sin6.sin6_port); +#endif /* WANT_IPV6 */ + + assert(a != NULL); + assert(a->sin4.sin_family == AF_INET); + return ntohs(a->sin4.sin_port); +} + +/* + * init a ng_ipaddr_t object. + * @param addr: pointer to ng_ipaddr_t to initialize. + * @param ip_str: ip address in dotted-decimal (ipv4) or hexadecimal (ipv6) notation + * @param port: transport layer port number to use. + */ +GLOBAL bool ng_ipaddr_init PARAMS((ng_ipaddr_t *addr, const char *ip_str, UINT16 port)); + +/* set sin4/sin6_port, depending on a->sa_family */ +GLOBAL void ng_ipaddr_setport PARAMS((ng_ipaddr_t *a, UINT16 port)); + +/* return true if a and b have the same IP address. If a and b have different AF, return false. */ +GLOBAL bool ng_ipaddr_ipequal PARAMS((const ng_ipaddr_t *a, const ng_ipaddr_t *b)); + + +#ifdef WANT_IPV6 +/* convert struct sockaddr to string, returns pointer to static buffer */ +GLOBAL const char *ng_ipaddr_tostr PARAMS((const ng_ipaddr_t *addr)); + +/* convert struct sockaddr to string. dest must be NG_INET_ADDRSTRLEN bytes long */ +GLOBAL bool ng_ipaddr_tostr_r PARAMS((const ng_ipaddr_t *addr, char *dest)); +#else +static inline const char* +ng_ipaddr_tostr(const ng_ipaddr_t *addr) +{ + assert(addr != NULL); + return inet_ntoa(addr->sin4.sin_addr); +} + +static inline bool +ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *d) +{ + assert(addr != NULL); + assert(d != NULL); + strlcpy(d, inet_ntoa(addr->sin4.sin_addr), NG_INET_ADDRSTRLEN); + return true; +} +#endif +#endif + +/* -eof- */ |
