Commit d2f207cd authored by Stewart Brodie's avatar Stewart Brodie
Browse files

Added new conversion functions from latest resolver libraries.

Detail:
  New function inet_net_ntop, inet_net_pton, inet_ntop, inet_pton
    added.  These are thread-safe versions of other functions and
    should be used in preference to things like inet_ntoa, inet_aton.
    These functions are IPv6 aware - pass AF_INET6 to them if you
    want IPv6 operations, pass AF_INET if you want IPv4 (ie. current
    behaviour).
  Extra address family, protocol family definitions added for IPv6
    (and others since they were there in the FreeBSD headers),
    specifically: AF_INET6, PF_INET6, IN6ADDRSZ.  Corresponding
    extra DNS record types (T_AAAA) have been added too.
  APIs are standard APIs - documentation added to LibraryDoc.
  New inetlib/c/* files also contain their own documentation.
Admin:
  Required by TFTPserver (RISC OS version)
  Note: addition of these macros to the header file does *not* imply
    that the Internet module now supports IPv6.  These are header
    file macros added for the benefit of the conversion routines.

Version 5.30. Tagged as 'TCPIPLibs-5_30'
parent a54dbd5e
Acorn TCP/IP libraries version 5.26
Acorn TCP/IP libraries version 5.30
-----------------------------------
These libraries are an update to the libraries described in chapter 123 of the PRM
......@@ -1261,6 +1261,39 @@ New prototypes: u_long inet_addr(const char *cp);
u_long inet_network(const char *cp);
struct in_addr inet_makeaddr(u_long net, u_long host);
Four new functions have been defined:
char *inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size);
This function convert network number from network to presentation format.
Generates CIDR style result always. The return value is pointer to dst, or
NULL if an error occurred (check errno).
int inet_net_pton(int af, const char *buf, void *, size_t);
This function parses a presentation format (ie. textual) address into a
network address (the reverse operation to inet_net_ntop). af is the address
type (AF_INET or AF_INET6); buf points to the textual representation, buf
points to the output buffer and size is the length of that buffer. The
return value is the number of bits, either imputed classfully or specified
with /CIDR, or -1 if some failure occurred (check errno). ENOENT means it was
not a valid network specification.
int inet_pton(int af, const char *src, void *dst);
Convert from presentation format (which usually means ASCII printable) to network
format (which is usually some kind of binary format). Return:
1 if the address was valid for the specified address family
0 if the address wasn't valid (`dst' is untouched in this case)
-1 if some other error occurred (`dst' is untouched in this case, too)
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
Convert a network format address to presentation format. Returns a pointer to
presentation format address (`dst'), or NULL (see errno).
_INET_ERROR
===========
......
/* (5.29)
/* (5.30)
*
* This file is automatically maintained by srccommit, do not edit manually.
*
*/
#define Module_MajorVersion_CMHG 5.29
#define Module_MajorVersion_CMHG 5.30
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 22 Jul 1999
#define Module_Date_CMHG 28 Jul 1999
#define Module_MajorVersion "5.29"
#define Module_Version 529
#define Module_MajorVersion "5.30"
#define Module_Version 530
#define Module_MinorVersion ""
#define Module_Date "22 Jul 1999"
#define Module_Date "28 Jul 1999"
#define Module_FullVersion "5.29"
#define Module_FullVersion "5.30"
......@@ -47,7 +47,11 @@ unsigned long inet_lnaof(struct in_addr);
struct in_addr inet_makeaddr(u_long , u_long);
unsigned long inet_netof(struct in_addr);
unsigned long inet_network(const char *);
char *inet_net_ntop(int, const void *, int, char *, size_t);
int inet_net_pton(int, const char *, void *, size_t);
char *inet_ntoa(struct in_addr);
int inet_pton(int, const char *, void *);
const char *inet_ntop(int, const void *, char *, size_t);
__END_DECLS
#endif /* !_INET_H_ */
......@@ -87,6 +87,7 @@
#define INT32SZ 4 /* for systems without 32-bit ints */
#define INT16SZ 2 /* for systems without 16-bit ints */
#define INADDRSZ 4 /* for sizeof(struct inaddr) != 4 */
#define IN6ADDRSZ 16 /* IPv6 T_AAAA */
/*
* Internet nameserver port number
......@@ -158,12 +159,19 @@
#define T_GPOS 27 /* geographical position (withdrawn) */
#define T_AAAA 28 /* IP6 Address */
#define T_LOC 29 /* Location Information */
#define T_NXT 30 /* Next Valid Name in Zone */
#define T_EID 31 /* Endpoint identifier */
#define T_NIMLOC 32 /* Nimrod locator */
#define T_SRV 33 /* Server selection */
#define T_ATMA 34 /* ATM Address */
#define T_NAPTR 35 /* Naming Authority PoinTeR */
/* non standard */
#define T_UINFO 100 /* user (finger) information */
#define T_UID 101 /* user ID */
#define T_GID 102 /* group ID */
#define T_UNSPEC 103 /* Unspecified format (binary data) */
/* Query type values which do not appear in resource records */
#define T_IXFR 251 /* incremental zone transfer */
#define T_AXFR 252 /* transfer zone of authority */
#define T_MAILB 253 /* transfer mailbox records */
#define T_MAILA 254 /* transfer mail agent records */
......@@ -179,6 +187,48 @@
/* Query class values which do not appear in resource records */
#define C_ANY 255 /* wildcard match */
/*
* Flags field of the KEY RR rdata
*/
#define KEYFLAG_TYPEMASK 0xC000 /* Mask for "type" bits */
#define KEYFLAG_TYPE_AUTH_CONF 0x0000 /* Key usable for both */
#define KEYFLAG_TYPE_CONF_ONLY 0x8000 /* Key usable for confidentiality */
#define KEYFLAG_TYPE_AUTH_ONLY 0x4000 /* Key usable for authentication */
#define KEYFLAG_TYPE_NO_KEY 0xC000 /* No key usable for either; no key */
/* The type bits can also be interpreted independently, as single bits: */
#define KEYFLAG_NO_AUTH 0x8000 /* Key not usable for authentication */
#define KEYFLAG_NO_CONF 0x4000 /* Key not usable for confidentiality */
#define KEYFLAG_EXPERIMENTAL 0x2000 /* Security is *mandatory* if bit=0 */
#define KEYFLAG_RESERVED3 0x1000 /* reserved - must be zero */
#define KEYFLAG_RESERVED4 0x0800 /* reserved - must be zero */
#define KEYFLAG_USERACCOUNT 0x0400 /* key is assoc. with a user acct */
#define KEYFLAG_ENTITY 0x0200 /* key is assoc. with entity eg host */
#define KEYFLAG_ZONEKEY 0x0100 /* key is zone key for the zone named */
#define KEYFLAG_IPSEC 0x0080 /* key is for IPSEC use (host or user)*/
#define KEYFLAG_EMAIL 0x0040 /* key is for email (MIME security) */
#define KEYFLAG_RESERVED10 0x0020 /* reserved - must be zero */
#define KEYFLAG_RESERVED11 0x0010 /* reserved - must be zero */
#define KEYFLAG_SIGNATORYMASK 0x000F /* key can sign DNS RR's of same name */
#define KEYFLAG_RESERVED_BITMASK ( KEYFLAG_RESERVED3 | \
KEYFLAG_RESERVED4 | \
KEYFLAG_RESERVED10| KEYFLAG_RESERVED11)
/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
#define ALGORITHM_MD5RSA 1 /* MD5 with RSA */
#define ALGORITHM_EXPIRE_ONLY 253 /* No alg, no security */
#define ALGORITHM_PRIVATE_OID 254 /* Key begins with OID indicating alg */
/* Signatures */
/* Size of a mod or exp in bits */
#define MIN_MD5RSA_KEY_PART_BITS 512
#define MAX_MD5RSA_KEY_PART_BITS 2552
/* Total of binary mod and exp, bytes */
#define MAX_MD5RSA_KEY_BYTES ((MAX_MD5RSA_KEY_PART_BITS+7/8)*2+3)
/* Max length of text sig block */
#define MAX_KEY_BASE64 (((MAX_MD5RSA_KEY_BYTES+2)/3)*4)
/*
* Status return codes for T_UNSPEC conversion routines
*/
......
......@@ -122,8 +122,12 @@ struct linger {
#define pseudo_AF_PIP 25 /* Help Identify PIP packets */
#define AF_ISDN 26 /* Integrated Services Digital Network*/
#define AF_E164 AF_ISDN /* CCITT E.164 recommendation */
#define pseudo_AF_KEY 27 /* Internal key-management function */
#define AF_INET6 28 /* IPv6 */
#define AF_NATM 29 /* native ATM access */
#define AF_ATM 30 /* ATM */
#define AF_MAX 27
#define AF_MAX 31
/*
* Structure used by kernel to store most
......@@ -184,6 +188,10 @@ struct sockproto {
#define PF_RTIP pseudo_AF_FTIP /* same format as AF_INET */
#define PF_PIP pseudo_AF_PIP
#define PF_ISDN AF_ISDN
#define PF_KEY pseudo_AF_KEY
#define PF_INET6 AF_INET6
#define PF_NATM AF_NATM
#define PF_ATM AF_ATM
#define PF_MAX AF_MAX
......@@ -224,6 +232,10 @@ struct sockproto {
{ "ipx", CTLTYPE_NODE }, \
{ "sip", CTLTYPE_NODE }, \
{ "pip", CTLTYPE_NODE }, \
{ "isdn", CTLTYPE_NODE }, \
{ "key", CTLTYPE_NODE }, \
{ "inet6", CTLTYPE_NODE }, \
{ "natm", CTLTYPE_NODE }, \
}
/*
......
......@@ -57,19 +57,22 @@ CFILES= gethent.c gethnad.c getnbyad.c getnbyna.c getnent.c \
getprent.c getprnam.c getproto.c getsbyna.c getsbypo.c \
getsent.c htonl.c inet_addr.c inet_lnaof.c inet_maddr.c \
inet_nof.c inet_ntoa.c inet_nwork.c rresvport.c \
linkaddr.c ns_addr.c ns_ntoa.c iso_addr.c sysctlbyna.c
linkaddr.c ns_addr.c ns_ntoa.c iso_addr.c sysctlbyna.c \
inet_nntop.c inet_npton.c inet_ntop.c inet_pton.c
OFILES= gethent.o gethnad.o getnbyad.o getnbyna.o getnent.o \
getprent.o getprnam.o getproto.o getsbyna.o getsbypo.o \
getsent.o htonl.o inet_addr.o inet_lnaof.o inet_maddr.o \
inet_nof.o inet_ntoa.o inet_nwork.o rresvport.o \
linkaddr.o ns_addr.o ns_ntoa.o iso_addr.o sysctlbyna.o
linkaddr.o ns_addr.o ns_ntoa.o iso_addr.o sysctlbyna.o \
inet_nntop.o inet_npton.o inet_ntop.o inet_pton.o
ZFILES= z.gethent z.gethnad z.getnbyad z.getnbyna z.getnent \
z.getprent z.getprnam z.getproto z.getsbyna z.getsbypo \
z.getsent z.htonl z.inet_addr z.inet_lnaof z.inet_maddr \
z.inet_nof z.inet_ntoa z.inet_nwork z.rresvport \
z.linkaddr z.ns_addr z.ns_ntoa z.iso_addr z.sysctlbyna
z.linkaddr z.ns_addr z.ns_ntoa z.iso_addr z.sysctlbyna \
z.inet_nntop z.inet_npton z.inet_ntop z.inet_pton
.SUFFIXES: .z .o .c .s
......
/*
* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static const char rcsid[] = "$Id$";
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "inetlib.h"
#ifdef SPRINTF_CHAR
# define SPRINTF(x) strlen(sprintf/**/x)
#else
# define SPRINTF(x) ((size_t)sprintf x)
#endif
static char * inet_net_ntop_ipv4(const u_char *src, int bits,
char *dst, size_t size);
/*
* char *
* inet_net_ntop(af, src, bits, dst, size)
* convert network number from network to presentation format.
* generates CIDR style result always.
* return:
* pointer to dst, or NULL if an error occurred (check errno).
* author:
* Paul Vixie (ISC), July 1996
*/
char *
inet_net_ntop(af, src, bits, dst, size)
int af;
const void *src;
int bits;
char *dst;
size_t size;
{
switch (af) {
case AF_INET:
return (inet_net_ntop_ipv4(src, bits, dst, size));
default:
errno = EAFNOSUPPORT;
return (NULL);
}
}
/*
* static char *
* inet_net_ntop_ipv4(src, bits, dst, size)
* convert IPv4 network number from network to presentation format.
* generates CIDR style result always.
* return:
* pointer to dst, or NULL if an error occurred (check errno).
* note:
* network byte order assumed. this means 192.5.5.240/28 has
* 0x11110000 in its fourth octet.
* author:
* Paul Vixie (ISC), July 1996
*/
static char *
inet_net_ntop_ipv4(src, bits, dst, size)
const u_char *src;
int bits;
char *dst;
size_t size;
{
char *odst = dst;
char *t;
u_int m;
int b;
if (bits < 0 || bits > 32) {
errno = EINVAL;
return (NULL);
}
if (bits == 0) {
if (size < sizeof "0")
goto emsgsize;
*dst++ = '0';
*dst = '\0';
}
/* Format whole octets. */
for (b = bits / 8; b > 0; b--) {
if (size < sizeof "255.")
goto emsgsize;
t = dst;
dst += SPRINTF((dst, "%u", *src++));
if (b > 1) {
*dst++ = '.';
*dst = '\0';
}
size -= (size_t)(dst - t);
}
/* Format partial octet. */
b = bits % 8;
if (b > 0) {
if (size < sizeof ".255")
goto emsgsize;
t = dst;
if (dst != odst)
*dst++ = '.';
m = ((1 << b) - 1) << (8 - b);
dst += SPRINTF((dst, "%u", *src & m));
size -= (size_t)(dst - t);
}
/* Format CIDR /width. */
if (size < sizeof "/32")
goto emsgsize;
dst += SPRINTF((dst, "/%u", bits));
return (odst);
emsgsize:
errno = EMSGSIZE;
return (NULL);
}
/*
* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static const char rcsid[] = "$Id$";
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define NDEBUG
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <sys/errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "inetlib.h"
#ifdef SPRINTF_CHAR
# define SPRINTF(x) strlen(sprintf/**/x)
#else
# define SPRINTF(x) ((size_t)sprintf x)
#endif
#define isascii(val) (1)
static int inet_net_pton_ipv4(const char *src, u_char *dst,
size_t size);
/*
* static int
* inet_net_pton(af, src, dst, size)
* convert network number from presentation to network format.
* accepts hex octets, hex strings, decimal octets, and /CIDR.
* "size" is in bytes and describes "dst".
* return:
* number of bits, either imputed classfully or specified with /CIDR,
* or -1 if some failure occurred (check errno). ENOENT means it was
* not a valid network specification.
* author:
* Paul Vixie (ISC), June 1996
*/
int
inet_net_pton(af, src, dst, size)
int af;
const char *src;
void *dst;
size_t size;
{
switch (af) {
case AF_INET:
return (inet_net_pton_ipv4(src, dst, size));
default:
errno = EAFNOSUPPORT;
return (-1);
}
}
/*
* static int
* inet_net_pton_ipv4(src, dst, size)
* convert IPv4 network number from presentation to network format.
* accepts hex octets, hex strings, decimal octets, and /CIDR.
* "size" is in bytes and describes "dst".
* return:
* number of bits, either imputed classfully or specified with /CIDR,
* or -1 if some failure occurred (check errno). ENOENT means it was
* not an IPv4 network specification.
* note:
* network byte order assumed. this means 192.5.5.240/28 has
* 0x11110000 in its fourth octet.
* author:
* Paul Vixie (ISC), June 1996
*/
static int
inet_net_pton_ipv4(src, dst, size)
const char *src;
u_char *dst;
size_t size;
{
static const char
xdigits[] = "0123456789abcdef",
digits[] = "0123456789";
int n, ch, tmp, dirty, bits;
const u_char *odst = dst;
ch = *src++;
if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
&& isascii(src[1]) && isxdigit(src[1])) {
/* Hexadecimal: Eat nybble string. */
if (size <= 0)
goto emsgsize;
*dst = 0, dirty = 0;
src++; /* skip x or X. */
while ((ch = *src++) != '\0' &&
isascii(ch) && isxdigit(ch)) {
if (isupper(ch))
ch = tolower(ch);
n = strchr(xdigits, ch) - xdigits;
assert(n >= 0 && n <= 15);
*dst |= n;
if (!dirty++)
*dst <<= 4;
else if (size-- > 0)
*++dst = 0, dirty = 0;
else
goto emsgsize;
}
if (dirty)
size--;
} else if (isascii(ch) && isdigit(ch)) {
/* Decimal: eat dotted digit string. */
for (;;) {
tmp = 0;
do {
n = strchr(digits, ch) - digits;
assert(n >= 0 && n <= 9);
tmp *= 10;
tmp += n;
if (tmp > 255)
goto enoent;
} while ((ch = *src++) != '\0' &&
isascii(ch) && isdigit(ch));
if (size-- <= 0)
goto emsgsize;
*dst++ = (u_char) tmp;
if (ch == '\0' || ch == '/')
break;
if (ch != '.')
goto enoent;
ch = *src++;
if (!isascii(ch) || !isdigit(ch))
goto enoent;
}
} else
goto enoent;
bits = -1;
if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
/* CIDR width specifier. Nothing can follow it. */
ch = *src++; /* Skip over the /. */
bits = 0;
do {
n = strchr(digits, ch) - digits;
assert(n >= 0 && n <= 9);
bits *= 10;
bits += n;
} while ((ch = *src++) != '\0' &&
isascii(ch) && isdigit(ch));
if (ch != '\0')
goto enoent;
if (bits > 32)
goto emsgsize;
}
/* Firey death and destruction unless we prefetched EOS. */
if (ch != '\0')
goto enoent;
/* If nothing was written to the destination, we found no address. */
if (dst == odst)
goto enoent;
/* If no CIDR spec was given, infer width from net class. */
if (bits == -1) {
if (*odst >= 240) /* Class E */
bits = 32;
else if (*odst >= 224) /* Class D */
bits = 4;
else if (*odst >= 192) /* Class C */
bits = 24;
else if (*odst >= 128) /* Class B */
bits = 16;
else /* Class A */
bits = 8;
/* If imputed mask is narrower than specified octets, widen. */
if (bits >= 8 && bits < ((dst - odst) * 8))
bits = (dst - odst) * 8;
}
/* Extend network to cover the actual mask. */
while (bits > ((dst - odst) * 8)) {
if (size-- <= 0)
goto emsgsize;
*dst++ = '\0';
}
return (bits);
enoent:
errno = ENOENT;
return (-1);
emsgsize:
errno = EMSGSIZE;
return (-1);
}
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char rcsid[] = "$Id$";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <string.h>
#include <errno.h>
#include <sys/errno.h>
#include <stdio.h>
#include "inetlib.h"
#ifdef SPRINTF_CHAR
# define SPRINTF(x) strlen(sprintf/**/x)
#else
# define SPRINTF(x) ((size_t)sprintf x)
#endif
/*
* WARNING: Don't even consider trying to compile this on a system where
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/
static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
/* char *
* inet_ntop(af, src, dst, size)
* convert a network format address to presentation format.
* return:
* pointer to presentation format address (`dst'), or NULL (see errno).
* author:
* Paul Vixie, 1996.
*/
const char *
inet_ntop(af, src, dst, size)
int af;
const void *src;
char *dst;
size_t size;
{
switch (af) {
case AF_INET:
return (inet_ntop4(src, dst, size));
case AF_INET6:
return (inet_ntop6(src, dst, size));
default:
errno = EAFNOSUPPORT;
return (NULL);
}
/* NOTREACHED */
}
/* const char *
* inet_ntop4(src, dst, size)
* format an IPv4 address, more or less like inet_ntoa()
* return:
* `dst' (as a const)
* notes:
* (1) uses no statics
* (2) takes a u_char* not an in_addr as input
* author:
* Paul Vixie, 1996.
*/
static const char *
inet_ntop4(src, dst, size)
const u_char *src;
char *dst;
size_t size;
{
static const char fmt[] = "%u.%u.%u.%u";
char tmp[sizeof "255.255.255.255"];
if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
errno = ENOSPC;
return (NULL);
}
strcpy(dst, tmp);
return (dst);
}
/* const char *
* inet_ntop6(src, dst, size)
* convert IPv6 binary address into presentation (printable) format
* author:
* Paul Vixie, 1996.
*/
static const char *
inet_ntop6(src, dst, size)
const u_char *src;
char *dst;
size_t size;
{
/*
* Note that int32_t and int16_t need only be "at least" large enough
* to contain a value of the specified size. On some systems, like
* Crays, there is no such thing as an integer variable with 16 bits.
* Keep this in mind if you think this function should have been coded
* to use pointer overlays. All the world's not a VAX.
*/
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
struct { int base, len; } best, cur;
u_int words[IN6ADDRSZ / INT16SZ];
int i;
/*
* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
memset(words, '\0', sizeof words);
for (i = 0; i < IN6ADDRSZ; i++)
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
best.base = -1;
cur.base = -1;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
if (words[i] == 0) {
if (cur.base == -1)
cur.base = i, cur.len = 1;
else
cur.len++;
} else {
if (cur.base != -1) {
if (best.base == -1 || cur.len > best.len)
best = cur;
cur.base = -1;
}
}
}
if (cur.base != -1) {
if (best.base == -1 || cur.len > best.len)
best = cur;
}
if (best.base != -1 && best.len < 2)
best.base = -1;
/*
* Format the result.
*/
tp = tmp;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
/* Are we inside the best run of 0x00's? */
if (best.base != -1 && i >= best.base &&
i < (best.base + best.len)) {
if (i == best.base)
*tp++ = ':';
continue;
}
/* Are we following an initial run of 0x00s or any real hex? */
if (i != 0)
*tp++ = ':';
/* Is this address an encapsulated IPv4? */
if (i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
return (NULL);
tp += strlen(tp);
break;
}
tp += SPRINTF((tp, "%x", words[i]));
}
/* Was it a trailing run of 0x00's? */
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
*tp++ = ':';
*tp++ = '\0';
/*
* Check for overflow, copy, and we're done.
*/
if ((size_t)(tp - tmp) > size) {
errno = ENOSPC;
return (NULL);
}
strcpy(dst, tmp);
return (dst);
}
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char rcsid[] = "$Id$";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <string.h>
#include <errno.h>
#include <sys/errno.h>
#include "inetlib.h"
/*
* WARNING: Don't even consider trying to compile this on a system where
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/
static int inet_pton4(const char *src, u_char *dst);
static int inet_pton6(const char *src, u_char *dst);
/* int
* inet_pton(af, src, dst)
* convert from presentation format (which usually means ASCII printable)
* to network format (which is usually some kind of binary format).
* return:
* 1 if the address was valid for the specified address family
* 0 if the address wasn't valid (`dst' is untouched in this case)
* -1 if some other error occurred (`dst' is untouched in this case, too)
* author:
* Paul Vixie, 1996.
*/
int
inet_pton(af, src, dst)
int af;
const char *src;
void *dst;
{
switch (af) {
case AF_INET:
return (inet_pton4(src, dst));
case AF_INET6:
return (inet_pton6(src, dst));
default:
errno = EAFNOSUPPORT;
return (-1);
}
/* NOTREACHED */
}
/* int
* inet_pton4(src, dst)
* like inet_aton() but without all the hexadecimal and shorthand.
* return:
* 1 if `src' is a valid dotted quad, else 0.
* notice:
* does not touch `dst' unless it's returning 1.
* author:
* Paul Vixie, 1996.
*/
static int
inet_pton4(src, dst)
const char *src;
u_char *dst;
{
static const char digits[] = "0123456789";
int saw_digit, octets, ch;
u_char tmp[INADDRSZ], *tp;
saw_digit = 0;
octets = 0;
*(tp = tmp) = 0;
while ((ch = *src++) != '\0') {
const char *pch;
if ((pch = strchr(digits, ch)) != NULL) {
u_int new = *tp * 10 + (pch - digits);
if (new > 255)
return (0);
*tp = new;
if (! saw_digit) {
if (++octets > 4)
return (0);
saw_digit = 1;
}
} else if (ch == '.' && saw_digit) {
if (octets == 4)
return (0);
*++tp = 0;
saw_digit = 0;
} else
return (0);
}
if (octets < 4)
return (0);
memcpy(dst, tmp, INADDRSZ);
return (1);
}
/* int
* inet_pton6(src, dst)
* convert presentation level address to network order binary form.
* return:
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
* notice:
* (1) does not touch `dst' unless it's returning 1.
* (2) :: in a full address is silently ignored.
* credit:
* inspired by Mark Andrews.
* author:
* Paul Vixie, 1996.
*/
static int
inet_pton6(src, dst)
const char *src;
u_char *dst;
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
const char *xdigits, *curtok;
int ch, saw_xdigit;
u_int val;
memset((tp = tmp), '\0', IN6ADDRSZ);
endp = tp + IN6ADDRSZ;
colonp = NULL;
/* Leading :: requires some special handling. */
if (*src == ':')
if (*++src != ':')
return (0);
curtok = src;
saw_xdigit = 0;
val = 0;
while ((ch = *src++) != '\0') {
const char *pch;
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
pch = strchr((xdigits = xdigits_u), ch);
if (pch != NULL) {
val <<= 4;
val |= (pch - xdigits);
if (val > 0xffff)
return (0);
saw_xdigit = 1;
continue;
}
if (ch == ':') {
curtok = src;
if (!saw_xdigit) {
if (colonp)
return (0);
colonp = tp;
continue;
}
if (tp + INT16SZ > endp)
return (0);
*tp++ = (u_char) (val >> 8) & 0xff;
*tp++ = (u_char) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
inet_pton4(curtok, tp) > 0) {
tp += INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */
}
return (0);
}
if (saw_xdigit) {
if (tp + INT16SZ > endp)
return (0);
*tp++ = (u_char) (val >> 8) & 0xff;
*tp++ = (u_char) val & 0xff;
}
if (colonp != NULL) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
int i;
for (i = 1; i <= n; i++) {
endp[- i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp)
return (0);
memcpy(dst, tmp, IN6ADDRSZ);
return (1);
}
......@@ -75,7 +75,11 @@ extern u_long inet_lnaof(struct in_addr in);
extern struct in_addr inet_makeaddr(u_long net, u_long host);
extern u_long inet_network(const char *cp);
extern u_long inet_netof(struct in_addr in);
extern char *inet_ntoa(struct in_addr in);
extern char *inet_net_ntop(int, const void *, int, char *, size_t);
extern int inet_net_pton(int, const char *, void *, size_t);
extern char *inet_ntoa(struct in_addr);
extern const char *inet_ntop(int, const void *, char *, size_t);
extern int inet_pton(int, const char *, void *);
extern struct hostent *namisipadr(const char *nam);
extern u_long ntohl(u_long x);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment