diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 | 
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /rfc1035/rfc1035an.c | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'rfc1035/rfc1035an.c')
| -rw-r--r-- | rfc1035/rfc1035an.c | 141 | 
1 files changed, 141 insertions, 0 deletions
| diff --git a/rfc1035/rfc1035an.c b/rfc1035/rfc1035an.c new file mode 100644 index 0000000..7459530 --- /dev/null +++ b/rfc1035/rfc1035an.c @@ -0,0 +1,141 @@ +/* +** Copyright 1998 - 2000 Double Precision, Inc. +** See COPYING for distribution information. +*/ +#include	"config.h" +#include	"rfc1035.h" +#include	<sys/types.h> +#include	<sys/socket.h> +#include	<arpa/inet.h> +#include	<errno.h> +#include	<string.h> + + +void rfc1035_ntoa_ipv4(const struct in_addr *in, char *buf) +{ +union	{ +	unsigned char addr[4]; +	RFC1035_UINT32 n; +	} u; + +int	i; +char	*p; +char	pbuf[4]; + +	u.n=in->s_addr; +	for (i=0; i<4; i++) +	{ +		if (i)	*buf++='.'; +		p=pbuf+3; +		*p=0; +		do +		{ +			*--p = '0' + (u.addr[i] % 10); +		} while ( (u.addr[i] /= 10) != 0); +		while (*p) +			*buf++ = *p++; +	} +	*buf=0; +} + +void rfc1035_ntoa(const RFC1035_ADDR *in, char *buf) +{ +#if	RFC1035_IPV6 +	inet_ntop(AF_INET6, in, buf, RFC1035_MAXNAMESIZE+1); +#else +	rfc1035_ntoa_ipv4(in, buf); +#endif +} + +static RFC1035_UINT32 doaton(const char *p, int *err) +{ +RFC1035_UINT32 octets[4]; +int	i; +int	base; + +	*err=1; +	for (i=0; i<4; i++) +	{ +		if (i > 0) +		{ +			if (*p == '\0')	break; +			if (*p != '.')	return ( -1 ); +			++p; +		} +		if (*p < '0' || *p > '9')	return (-1); +		octets[i]=0; +		base=10; +		if (*p == '0')	base=8; + +		while (*p >= '0' && *p < '0'+base) +			octets[i] = octets[i] * base + (*p++ - '0'); +	} +	if (*p)	return ( -1 ); +	*err=0; +	if (i == 1)	return (octets[0]); +	*err=1; +	if (octets[0] > 255)	return ( -1 ); +	octets[0] <<= 24; + +	if (i == 2) +	{ +		if (octets[1] > 0x00FFFFFF)	return ( -1 ); +		*err=0; +		return (octets[0] | octets[1]); +	} + +	if (octets[1] > 255)	return ( -1 ); +	octets[1] <<= 16; +	if (i == 3) +	{ +		if (octets[2] > 0x0000FFFF)	return ( -1 ); +		*err=0; +		return (octets[0] | octets[1] | octets[2]); +	} +	if (octets[2] > 255 || octets[3] > 255)	return ( -1 ); +	*err=0; +	return (octets[0] | octets[1] | (octets[2] << 8) | octets[3]); +} + +int rfc1035_aton_ipv4(const char *p, struct in_addr *in4) +{ +int	dummy; +RFC1035_UINT32 n=doaton(p, &dummy); +union	{ +	unsigned char addr[4]; +	struct in_addr n; +	} u; + +	u.addr[3]=n; +	u.addr[2]=n >> 8; +	u.addr[1]=n >> 16; +	u.addr[0]=n >> 24; + +	if (dummy)	errno=EINVAL; +	*in4=u.n; +	return (dummy); +} + +#if	RFC1035_IPV6 + +int rfc1035_aton(const char *p, RFC1035_ADDR *in6) +{ +struct in_addr	in4; + +	if (rfc1035_aton_ipv4(p, &in4) == 0) +	{ +		rfc1035_ipv4to6(in6, &in4); +		return (0); +	} +	if (inet_pton(AF_INET6, p, in6) <= 0) +		return (-1); +	return (0); +} + +#else + +int rfc1035_aton(const char *p, RFC1035_ADDR *in4) +{ +	return (rfc1035_aton_ipv4(p, in4)); +} +#endif | 
