From: guy Date: Wed, 9 Feb 2005 02:25:45 +0000 (+0000) Subject: From Gisle Vanem: X-Git-Tag: tcpdump-3.9.1~194 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/273460ed8819ec1434ef26ff54d931fe284cb8ce?ds=sidebyside From Gisle Vanem: the _errno() stuff isn't needed for current versions of MinGW; get rid of some definitions not needed with MSVC++ and other non-MinGW32/non-Watcom compilers; add IPv6 capability to inet_pton.c, courtesy of Paul Vixie; add inline ntoh{ls}/hton{ls} functions for GCC/i386. --- diff --git a/missing/inet_ntop.c b/missing/inet_ntop.c index 30dff51e..d17d5925 100644 --- a/missing/inet_ntop.c +++ b/missing/inet_ntop.c @@ -36,11 +36,11 @@ * SUCH DAMAGE. */ -/* $Id: inet_ntop.c,v 1.7 2003-11-16 09:36:50 guy Exp $ */ +/* $Id: inet_ntop.c,v 1.8 2005-02-09 02:25:46 guy Exp $ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/missing/inet_ntop.c,v 1.7 2003-11-16 09:36:50 guy Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/missing/inet_ntop.c,v 1.8 2005-02-09 02:25:46 guy Exp $"; #endif #include @@ -52,8 +52,12 @@ static const char rcsid[] _U_ = * */ -#ifndef INET_ADDRSTRLEN -#define INET_ADDRSTRLEN 16 +#ifndef IN6ADDRSZ +#define IN6ADDRSZ 16 /* IPv6 T_AAAA */ +#endif + +#ifndef INT16SZ +#define INT16SZ 2 /* word size */ #endif static const char * @@ -91,12 +95,123 @@ inet_ntop_v4 (const void *src, char *dst, size_t size) return orig_dst; } +#ifdef INET6 +/* + * Convert IPv6 binary address into presentation (printable) format. + */ +static const char * +inet_ntop_v6 (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 [INET6_ADDRSTRLEN+1]; + char *tp; + struct { + long base; + long len; + } best, cur; + u_long 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) && (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_ntop_v4(src+12, tp, sizeof(tmp) - (tp - tmp))) + { + errno = ENOSPC; + return (NULL); + } + tp += strlen(tp); + break; + } + tp += sprintf (tp, "%lX", 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); + } + return strcpy (dst, tmp); + return (NULL); +} +#endif /* INET6 */ + + const char * inet_ntop(int af, const void *src, char *dst, size_t size) { switch (af) { case AF_INET : return inet_ntop_v4 (src, dst, size); +#ifdef INET6 + case AF_INET6: + return inet_ntop_v6 ((const u_char*)src, dst, size); +#endif default : errno = EAFNOSUPPORT; return NULL; diff --git a/tcpdump-stdinc.h b/tcpdump-stdinc.h index c0b920c8..c24ad6de 100644 --- a/tcpdump-stdinc.h +++ b/tcpdump-stdinc.h @@ -29,7 +29,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * - * @(#) $Header: /tcpdump/master/tcpdump/tcpdump-stdinc.h,v 1.9 2004-04-17 08:56:15 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/tcpdump-stdinc.h,v 1.10 2005-02-09 02:25:45 guy Exp $ (LBL) */ /* @@ -52,16 +52,27 @@ #include #include "IP6_misc.h" #include +#include +#include /* in wpcap's Win32/include */ #ifdef __MINGW32__ #include -int* _errno(); -#define errno (*_errno()) +#endif + +/* Protos for missing/x.c functions (ideally + * should be used, but it clashes with ). + */ +extern const char *inet_ntop (int, const void *, char *, size_t); +extern int inet_pton (int, const char *, void *); +extern int inet_aton (const char *cp, struct in_addr *addr); +#ifndef INET_ADDRSTRLEN #define INET_ADDRSTRLEN 16 -#define INET6_ADDRSTRLEN 46 +#endif -#endif /* __MINGW32__ */ +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN 46 +#endif #ifndef toascii #define toascii(c) ((c) & 0x7f) @@ -77,19 +88,6 @@ typedef char* caddr_t; #define vsnprintf _vsnprintf #define RETSIGTYPE void -#if !defined(__MINGW32__) && !defined(__WATCOMC__) -#undef toascii -#define isascii __isascii -#define toascii __toascii -#define stat _stat -#define open _open -#define fstat _fstat -#define read _read -#define O_RDONLY _O_RDONLY - -typedef short ino_t; -#endif /* __MINGW32__ */ - #else /* WIN32 */ #include @@ -128,4 +126,32 @@ typedef short ino_t; #define FOPEN_WRITE_BIN FOPEN_WRITE_TXT #endif +#if defined(__GNUC__) && defined(__i386__) + #undef ntohl + #undef ntohs + #undef htonl + #undef htons + + #define ntohl(x) __ntohl(x) + #define ntohs(x) __ntohs(x) + #define htonl(x) __ntohl(x) + #define htons(x) __ntohs(x) + + extern __inline__ unsigned long __ntohl (unsigned long x) + { + __asm__ ("xchgb %b0, %h0\n\t" /* swap lower bytes */ + "rorl $16, %0\n\t" /* swap words */ + "xchgb %b0, %h0" /* swap higher bytes */ + : "=q" (x) : "0" (x)); + return (x); + } + + extern __inline__ unsigned short __ntohs (unsigned short x) + { + __asm__ ("xchgb %b0, %h0" /* swap bytes */ + : "=q" (x) : "0" (x)); + return (x); + } +#endif + #endif /* tcpdump_stdinc_h */