diff options
| author | Florian Westphal <fw@strlen.de> | 2008-02-26 23:50:35 +0100 |
|---|---|---|
| committer | Florian Westphal <fw@strlen.de> | 2008-02-26 23:50:35 +0100 |
| commit | feb31e4200b42e0a5e9fb9637fa5f03c7ec05fcb (patch) | |
| tree | b572467ece1a378bc5939b7094c46f2e97fd1963 /src/ipaddr/ng_ipaddr.h | |
| parent | c31ad221a6cc48b709af056181d8d0be09898910 (diff) | |
| download | ngircd-feb31e4200b42e0a5e9fb9637fa5f03c7ec05fcb.tar.gz ngircd-feb31e4200b42e0a5e9fb9637fa5f03c7ec05fcb.zip | |
IPv6 support.
all references to struct sockaddr/in_addr have been removed from src/ngircd. libngipaddr (in src/ipaddr/) hides all the gory details. See src/ipaddr/ng_ipaddr.h for API description.
Diffstat (limited to 'src/ipaddr/ng_ipaddr.h')
| -rw-r--r-- | src/ipaddr/ng_ipaddr.h | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/ipaddr/ng_ipaddr.h b/src/ipaddr/ng_ipaddr.h new file mode 100644 index 00000000..1e198b0e --- /dev/null +++ b/src/ipaddr/ng_ipaddr.h @@ -0,0 +1,115 @@ +/* + * Functions for AF_ agnostic ipv4/ipv6 handling. + * + * (c) 2008 Florian Westphal <fw@strlen.de>, public domain. + */ + +#ifndef NG_IPADDR_HDR +#define NG_IPADDR_HDR +#include "portab.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) +{ +#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) +{ +#ifdef WANT_IPV6 + assert(a->sa.sa_family == AF_INET || a->sa.sa_family == AF_INET6); + if (a->sa.sa_family == AF_INET6) + return sizeof(a->sin6); +#endif + assert(a->sin4.sin_family == AF_INET); + return sizeof(a->sin4); +} + + +static inline UINT16 +ng_ipaddr_getport(const ng_ipaddr_t *a) +{ +#ifdef WANT_IPV6 + int af = a->sa.sa_family; + + assert(af == AF_INET || af == AF_INET6); + + if (af == AF_INET6) + return ntohs(a->sin6.sin6_port); +#endif /* WANT_IPV6 */ + 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 + * if ip_str is NULL it is treated as 0.0.0.0/[::] + * @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) { return inet_ntoa(addr->sin4.sin_addr); } + +static inline bool +ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *d) +{ + strlcpy(d, inet_ntoa(addr->sin4.sin_addr), NG_INET_ADDRSTRLEN); + return true; +} +#endif +#endif + +/* -eof- */ |