mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
for file in `grep "* including the terms and conditions of this license text as well. \*" * -r --files-with-match `; do sed "s/\* including the terms and conditions of this license text as well. \*/* including the terms and conditions of this license text as well. */g" -i $file; done
914 lines
32 KiB
C
914 lines
32 KiB
C
|
|
/***************************************************************************
|
|
* nbase_misc.c -- Some small miscelaneous utility/compatability *
|
|
* functions. *
|
|
* *
|
|
***********************IMPORTANT NMAP LICENSE TERMS************************
|
|
* *
|
|
* The Nmap Security Scanner is (C) 1996-2013 Insecure.Com LLC. Nmap is *
|
|
* also a registered trademark of Insecure.Com LLC. This program is free *
|
|
* software; you may redistribute and/or modify it under the terms of the *
|
|
* GNU General Public License as published by the Free Software *
|
|
* Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE CLARIFICATIONS *
|
|
* AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your right to use, *
|
|
* modify, and redistribute this software under certain conditions. If *
|
|
* you wish to embed Nmap technology into proprietary software, we sell *
|
|
* alternative licenses (contact sales@nmap.com). Dozens of software *
|
|
* vendors already license Nmap technology such as host discovery, port *
|
|
* scanning, OS detection, version detection, and the Nmap Scripting *
|
|
* Engine. *
|
|
* *
|
|
* Note that the GPL places important restrictions on "derivative works", *
|
|
* yet it does not provide a detailed definition of that term. To avoid *
|
|
* misunderstandings, we interpret that term as broadly as copyright law *
|
|
* allows. For example, we consider an application to constitute a *
|
|
* derivative work for the purpose of this license if it does any of the *
|
|
* following with any software or content covered by this license *
|
|
* ("Covered Software"): *
|
|
* *
|
|
* o Integrates source code from Covered Software. *
|
|
* *
|
|
* o Reads or includes copyrighted data files, such as Nmap's nmap-os-db *
|
|
* or nmap-service-probes. *
|
|
* *
|
|
* o Is designed specifically to execute Covered Software and parse the *
|
|
* results (as opposed to typical shell or execution-menu apps, which will *
|
|
* execute anything you tell them to). *
|
|
* *
|
|
* o Includes Covered Software in a proprietary executable installer. The *
|
|
* installers produced by InstallShield are an example of this. Including *
|
|
* Nmap with other software in compressed or archival form does not *
|
|
* trigger this provision, provided appropriate open source decompression *
|
|
* or de-archiving software is widely available for no charge. For the *
|
|
* purposes of this license, an installer is considered to include Covered *
|
|
* Software even if it actually retrieves a copy of Covered Software from *
|
|
* another source during runtime (such as by downloading it from the *
|
|
* Internet). *
|
|
* *
|
|
* o Links (statically or dynamically) to a library which does any of the *
|
|
* above. *
|
|
* *
|
|
* o Executes a helper program, module, or script to do any of the above. *
|
|
* *
|
|
* This list is not exclusive, but is meant to clarify our interpretation *
|
|
* of derived works with some common examples. Other people may interpret *
|
|
* the plain GPL differently, so we consider this a special exception to *
|
|
* the GPL that we apply to Covered Software. Works which meet any of *
|
|
* these conditions must conform to all of the terms of this license, *
|
|
* particularly including the GPL Section 3 requirements of providing *
|
|
* source code and allowing free redistribution of the work as a whole. *
|
|
* *
|
|
* As another special exception to the GPL terms, Insecure.Com LLC grants *
|
|
* permission to link the code of this program with any version of the *
|
|
* OpenSSL library which is distributed under a license identical to that *
|
|
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
|
* linked combinations including the two. *
|
|
* *
|
|
* Any redistribution of Covered Software, including any derived works, *
|
|
* must obey and carry forward all of the terms of this license, including *
|
|
* obeying all GPL rules and restrictions. For example, source code of *
|
|
* the whole work must be provided and free redistribution must be *
|
|
* allowed. All GPL references to "this License", are to be treated as *
|
|
* including the terms and conditions of this license text as well. *
|
|
* *
|
|
* Because this license imposes special exceptions to the GPL, Covered *
|
|
* Work may not be combined (even as part of a larger work) with plain GPL *
|
|
* software. The terms, conditions, and exceptions of this license must *
|
|
* be included as well. This license is incompatible with some other open *
|
|
* source licenses as well. In some cases we can relicense portions of *
|
|
* Nmap or grant special permissions to use it in other open source *
|
|
* software. Please contact fyodor@nmap.org with any such requests. *
|
|
* Similarly, we don't incorporate incompatible open source software into *
|
|
* Covered Software without special permission from the copyright holders. *
|
|
* *
|
|
* If you have any questions about the licensing restrictions on using *
|
|
* Nmap in other works, are happy to help. As mentioned above, we also *
|
|
* offer alternative license to integrate Nmap into proprietary *
|
|
* applications and appliances. These contracts have been sold to dozens *
|
|
* of software vendors, and generally include a perpetual license as well *
|
|
* as providing for priority support and updates. They also fund the *
|
|
* continued development of Nmap. Please email sales@nmap.com for further *
|
|
* information. *
|
|
* *
|
|
* If you have received a written license agreement or contract for *
|
|
* Covered Software stating terms other than these, you may choose to use *
|
|
* and redistribute Covered Software under those terms instead of these. *
|
|
* *
|
|
* Source is provided to this software because we believe users have a *
|
|
* right to know exactly what a program is going to do before they run it. *
|
|
* This also allows you to audit the software for security holes (none *
|
|
* have been found so far). *
|
|
* *
|
|
* Source code also allows you to port Nmap to new platforms, fix bugs, *
|
|
* and add new features. You are highly encouraged to send your changes *
|
|
* to the dev@nmap.org mailing list for possible incorporation into the *
|
|
* main distribution. By sending these changes to Fyodor or one of the *
|
|
* Insecure.Org development mailing lists, or checking them into the Nmap *
|
|
* source code repository, it is understood (unless you specify otherwise) *
|
|
* that you are offering the Nmap Project (Insecure.Com LLC) the *
|
|
* unlimited, non-exclusive right to reuse, modify, and relicense the *
|
|
* code. Nmap will always be available Open Source, but this is important *
|
|
* because the inability to relicense code has caused devastating problems *
|
|
* for other Free Software projects (such as KDE and NASM). We also *
|
|
* occasionally relicense the code to third parties as discussed above. *
|
|
* If you wish to specify special license conditions of your *
|
|
* contributions, just say so when you send them. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, but *
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Nmap *
|
|
* license file for more details (it's in a COPYING file included with *
|
|
* Nmap, and also available from https://svn.nmap.org/nmap/COPYING *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
/* $Id$ */
|
|
|
|
#include "nbase.h"
|
|
|
|
#ifndef WIN32
|
|
#include <errno.h>
|
|
#ifndef errno
|
|
extern int errno;
|
|
#endif
|
|
#else
|
|
#include <winsock2.h>
|
|
#endif
|
|
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
#include "nbase_ipv6.h"
|
|
#include "nbase_crc32ct.h"
|
|
|
|
#include <assert.h>
|
|
#include <fcntl.h>
|
|
|
|
#ifdef WIN32
|
|
#include <conio.h>
|
|
#endif
|
|
|
|
#ifndef INET6_ADDRSTRLEN
|
|
#define INET6_ADDRSTRLEN 46
|
|
#endif
|
|
|
|
/* Returns the UNIX/Windows errno-equivalent. Note that the Windows
|
|
call is socket/networking specific. The windows error number
|
|
returned is like WSAMSGSIZE, but nbase.h includes #defines to
|
|
correlate many of the common UNIX errors with their closest Windows
|
|
equivalents. So you can use EMSGSIZE or EINTR. */
|
|
int socket_errno() {
|
|
#ifdef WIN32
|
|
return WSAGetLastError();
|
|
#else
|
|
return errno;
|
|
#endif
|
|
}
|
|
|
|
/* We can't just use strerror to get socket errors on Windows because it has
|
|
its own set of error codes: WSACONNRESET not ECONNRESET for example. This
|
|
function will do the right thing on Windows. Call it like
|
|
socket_strerror(socket_errno())
|
|
*/
|
|
char *socket_strerror(int errnum) {
|
|
#ifdef WIN32
|
|
static char buffer[128];
|
|
|
|
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS |
|
|
FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
|
0, errnum, 0, buffer, sizeof(buffer), NULL);
|
|
|
|
return buffer;
|
|
#else
|
|
return strerror(errnum);
|
|
#endif
|
|
}
|
|
|
|
/* Compares two sockaddr_storage structures with a return value like strcmp.
|
|
First the address families are compared, then the addresses if the families
|
|
are equal. The structures must be real full-length sockaddr_storage
|
|
structures, not something shorter like sockaddr_in. */
|
|
int sockaddr_storage_cmp(const struct sockaddr_storage *a,
|
|
const struct sockaddr_storage *b) {
|
|
if (a->ss_family < b->ss_family)
|
|
return -1;
|
|
else if (a->ss_family > b->ss_family)
|
|
return 1;
|
|
if (a->ss_family == AF_INET) {
|
|
struct sockaddr_in *sin_a = (struct sockaddr_in *) a;
|
|
struct sockaddr_in *sin_b = (struct sockaddr_in *) b;
|
|
if (sin_a->sin_addr.s_addr < sin_b->sin_addr.s_addr)
|
|
return -1;
|
|
else if (sin_a->sin_addr.s_addr > sin_b->sin_addr.s_addr)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
} else if (a->ss_family == AF_INET6) {
|
|
struct sockaddr_in6 *sin6_a = (struct sockaddr_in6 *) a;
|
|
struct sockaddr_in6 *sin6_b = (struct sockaddr_in6 *) b;
|
|
return memcmp(sin6_a->sin6_addr.s6_addr, sin6_b->sin6_addr.s6_addr,
|
|
sizeof(sin6_a->sin6_addr.s6_addr));
|
|
} else {
|
|
assert(0);
|
|
}
|
|
return 0; /* Not reached */
|
|
}
|
|
|
|
int sockaddr_storage_equal(const struct sockaddr_storage *a,
|
|
const struct sockaddr_storage *b) {
|
|
return sockaddr_storage_cmp(a, b) == 0;
|
|
}
|
|
|
|
/* This function is an easier version of inet_ntop because you don't
|
|
need to pass a dest buffer. Instead, it returns a static buffer that
|
|
you can use until the function is called again (by the same or another
|
|
thread in the process). If there is a wierd error (like sslen being
|
|
too short) then NULL will be returned. */
|
|
const char *inet_ntop_ez(const struct sockaddr_storage *ss, size_t sslen) {
|
|
|
|
const struct sockaddr_in *sin = (struct sockaddr_in *) ss;
|
|
static char str[INET6_ADDRSTRLEN];
|
|
#if HAVE_IPV6
|
|
const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) ss;
|
|
#endif
|
|
|
|
str[0] = '\0';
|
|
|
|
if (sin->sin_family == AF_INET) {
|
|
if (sslen < sizeof(struct sockaddr_in))
|
|
return NULL;
|
|
return inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str));
|
|
}
|
|
#if HAVE_IPV6
|
|
else if(sin->sin_family == AF_INET6) {
|
|
if (sslen < sizeof(struct sockaddr_in6))
|
|
return NULL;
|
|
return inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str));
|
|
}
|
|
#endif
|
|
//Some laptops report the ip and address family of disabled wifi cards as null
|
|
//so yes, we will hit this sometimes.
|
|
return NULL;
|
|
}
|
|
|
|
/* Create a new socket inheritable by subprocesses. On non-Windows systems it's
|
|
just a normal socket. */
|
|
int inheritable_socket(int af, int style, int protocol) {
|
|
#ifdef WIN32
|
|
/* WSASocket is just like socket, except that the sockets it creates are
|
|
inheritable by subprocesses (such as are created by CreateProcess), while
|
|
those created by socket are not. */
|
|
return WSASocket(af, style, protocol, NULL, 0, 0);
|
|
#else
|
|
return socket(af, style, protocol);
|
|
#endif
|
|
}
|
|
|
|
/* The dup function on Windows works only on file descriptors, not socket
|
|
handles. This function accomplishes the same thing for sockets. */
|
|
int dup_socket(int sd) {
|
|
#ifdef WIN32
|
|
HANDLE copy;
|
|
|
|
if (DuplicateHandle(GetCurrentProcess(), (HANDLE) sd,
|
|
GetCurrentProcess(), ©,
|
|
0, FALSE, DUPLICATE_SAME_ACCESS) == 0) {
|
|
return -1;
|
|
}
|
|
|
|
return (int) copy;
|
|
#else
|
|
return dup(sd);
|
|
#endif
|
|
}
|
|
|
|
int unblock_socket(int sd) {
|
|
#ifdef WIN32
|
|
unsigned long one = 1;
|
|
|
|
if (sd != 501) /* Hack related to WinIP Raw Socket support */
|
|
ioctlsocket(sd, FIONBIO, &one);
|
|
|
|
return 0;
|
|
#else
|
|
int options;
|
|
|
|
/* Unblock our socket to prevent recvfrom from blocking forever on certain
|
|
* target ports. */
|
|
options = fcntl(sd, F_GETFL);
|
|
if (options == -1)
|
|
return -1;
|
|
|
|
return fcntl(sd, F_SETFL, O_NONBLOCK | options);
|
|
#endif /* WIN32 */
|
|
}
|
|
|
|
/* Convert a socket to blocking mode */
|
|
int block_socket(int sd) {
|
|
#ifdef WIN32
|
|
unsigned long options = 0;
|
|
|
|
if (sd != 501)
|
|
ioctlsocket(sd, FIONBIO, &options);
|
|
|
|
return 0;
|
|
#else
|
|
int options;
|
|
|
|
options = fcntl(sd, F_GETFL);
|
|
if (options == -1)
|
|
return -1;
|
|
|
|
return fcntl(sd, F_SETFL, (~O_NONBLOCK) & options);
|
|
#endif
|
|
}
|
|
|
|
/* Use the SO_BINDTODEVICE sockopt to bind with a specific interface (Linux
|
|
only). Pass NULL or an empty string to remove device binding. */
|
|
int socket_bindtodevice(int sd, const char *device) {
|
|
char padded[sizeof(int)];
|
|
size_t len;
|
|
|
|
len = strlen(device) + 1;
|
|
/* In Linux 2.6.20 and earlier, there is a bug in SO_BINDTODEVICE that causes
|
|
EINVAL to be returned if the optlen < sizeof(int); this happens for example
|
|
with the interface names "" and "lo". Pad the string with null characters
|
|
so it is above this limit if necessary.
|
|
http://article.gmane.org/gmane.linux.network/71887
|
|
http://article.gmane.org/gmane.linux.network/72216 */
|
|
if (len < sizeof(padded)) {
|
|
/* We rely on strncpy padding with nulls here. */
|
|
strncpy(padded, device, sizeof(padded));
|
|
device = padded;
|
|
len = sizeof(padded);
|
|
}
|
|
|
|
#ifdef SO_BINDTODEVICE
|
|
/* Linux-specific sockopt asking to use a specific interface. See socket(7). */
|
|
if (setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, device, len) < 0)
|
|
return 0;
|
|
#endif
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* Convert a time specification into a count of seconds. A time specification is
|
|
* a non-negative real number, possibly followed by a units suffix. The suffixes
|
|
* are "ms" for milliseconds, "s" for seconds, "m" for minutes, or "h" for
|
|
* hours. Seconds is the default with no suffix. -1 is returned if the string
|
|
* can't be parsed. */
|
|
double tval2secs(const char *tspec) {
|
|
double d;
|
|
char *tail;
|
|
|
|
errno = 0;
|
|
d = strtod(tspec, &tail);
|
|
if (*tspec == '\0' || errno != 0)
|
|
return -1;
|
|
if (strcasecmp(tail, "ms") == 0)
|
|
return d / 1000.0;
|
|
else if (*tail == '\0' || strcasecmp(tail, "s") == 0)
|
|
return d;
|
|
else if (strcasecmp(tail, "m") == 0)
|
|
return d * 60.0;
|
|
else if (strcasecmp(tail, "h") == 0)
|
|
return d * 60.0 * 60.0;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
long tval2msecs(const char *tspec) {
|
|
double s, ms;
|
|
|
|
s = tval2secs(tspec);
|
|
if (s == -1)
|
|
return -1;
|
|
ms = s * 1000.0;
|
|
if (ms > LONG_MAX || ms < LONG_MIN)
|
|
return -1;
|
|
|
|
return (long) ms;
|
|
}
|
|
|
|
/* Returns the unit portion of a time specification (such as "ms", "s", "m", or
|
|
"h"). Returns NULL if there was a parsing error or no unit is present. */
|
|
const char *tval_unit(const char *tspec) {
|
|
double d;
|
|
char *tail;
|
|
|
|
errno = 0;
|
|
d = strtod(tspec, &tail);
|
|
/* Avoid GCC 4.6 error "variable 'd' set but not used
|
|
[-Wunused-but-set-variable]". */
|
|
(void) d;
|
|
if (*tspec == '\0' || errno != 0 || *tail == '\0')
|
|
return NULL;
|
|
|
|
return tail;
|
|
}
|
|
|
|
/* A replacement for select on Windows that allows selecting on stdin
|
|
* (file descriptor 0) and selecting on zero file descriptors (just for
|
|
* the timeout). Plain Windows select doesn't work on non-sockets like
|
|
* stdin and returns an error if no file descriptors were given, because
|
|
* they were NULL or empty. This only works for sockets and stdin; if
|
|
* you have a descriptor referring to a normal open file in the set,
|
|
* Windows will return WSAENOTSOCK. */
|
|
int fselect(int s, fd_set *rmaster, fd_set *wmaster, fd_set *emaster, struct timeval *tv)
|
|
{
|
|
#ifdef WIN32
|
|
static int stdin_thread_started = 0;
|
|
int fds_ready = 0;
|
|
int iter = -1, i;
|
|
struct timeval stv;
|
|
fd_set rset, wset, eset;
|
|
|
|
/* Figure out whether there are any FDs in the sets, as @$@!$# Windows
|
|
returns WSAINVAL (10022) if you call a select() with no FDs, even though
|
|
the Linux man page says that doing so is a good, reasonably portable way
|
|
to sleep with subsecond precision. Sigh. */
|
|
for(i = s; i > STDIN_FILENO; i--) {
|
|
if ((rmaster != NULL && FD_ISSET(i, rmaster))
|
|
|| (wmaster != NULL && FD_ISSET(i, wmaster))
|
|
|| (emaster != NULL && FD_ISSET(i, emaster)))
|
|
break;
|
|
s--;
|
|
}
|
|
|
|
/* Handle the case where stdin is not being read from. */
|
|
if (rmaster == NULL || !FD_ISSET(STDIN_FILENO, rmaster)) {
|
|
if (s > 0) {
|
|
/* Do a normal select. */
|
|
return select(s, rmaster, wmaster, emaster, tv);
|
|
} else {
|
|
/* No file descriptors given. Just sleep. */
|
|
if (tv == NULL) {
|
|
/* Sleep forever. */
|
|
while (1)
|
|
sleep(10000);
|
|
} else {
|
|
usleep(tv->tv_sec * 1000000UL + tv->tv_usec);
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* This is a hack for Windows, which doesn't allow select()ing on
|
|
* non-sockets (like stdin). We remove stdin from the fd_set and
|
|
* loop while select()ing on everything else, with a timeout of
|
|
* 125ms. Then we check if stdin is ready and increment fds_ready
|
|
* and set stdin in rmaster if it looks good. We just keep looping
|
|
* until we have something or it times out.
|
|
*/
|
|
|
|
/* nbase_winunix.c has all the nasty details behind checking if
|
|
* stdin has input. It involves a background thread, which we start
|
|
* now if necessary. */
|
|
if (!stdin_thread_started) {
|
|
int ret = win_stdin_start_thread();
|
|
assert(ret != 0);
|
|
stdin_thread_started = 1;
|
|
}
|
|
|
|
FD_CLR(STDIN_FILENO, rmaster);
|
|
|
|
if (tv) {
|
|
int usecs = (tv->tv_sec * 1000000) + tv->tv_usec;
|
|
|
|
iter = usecs / 125000;
|
|
|
|
if (usecs % 125000)
|
|
iter++;
|
|
}
|
|
|
|
FD_ZERO(&rset);
|
|
FD_ZERO(&wset);
|
|
FD_ZERO(&eset);
|
|
|
|
while (!fds_ready && iter) {
|
|
stv.tv_sec = 0;
|
|
stv.tv_usec = 125000;
|
|
|
|
if (rmaster)
|
|
rset = *rmaster;
|
|
if (wmaster)
|
|
wset = *wmaster;
|
|
if (emaster)
|
|
eset = *emaster;
|
|
|
|
fds_ready = 0;
|
|
/* selecting on anything other than stdin? */
|
|
if (s > 1)
|
|
fds_ready = select(s, &rset, &wset, &eset, &stv);
|
|
else
|
|
usleep(stv.tv_sec * 1000000UL + stv.tv_usec);
|
|
|
|
if (fds_ready > -1 && win_stdin_ready()) {
|
|
FD_SET(STDIN_FILENO, &rset);
|
|
fds_ready++;
|
|
}
|
|
|
|
if (tv)
|
|
iter--;
|
|
}
|
|
|
|
if (rmaster)
|
|
*rmaster = rset;
|
|
if (wmaster)
|
|
*wmaster = wset;
|
|
if (emaster)
|
|
*emaster = eset;
|
|
|
|
return fds_ready;
|
|
#else
|
|
return select(s, rmaster, wmaster, emaster, tv);
|
|
#endif
|
|
}
|
|
|
|
|
|
/*
|
|
* CRC32 Cyclic Redundancy Check
|
|
*
|
|
* From: http://www.ietf.org/rfc/rfc1952.txt
|
|
*
|
|
* Copyright (c) 1996 L. Peter Deutsch
|
|
*
|
|
* Permission is granted to copy and distribute this document for any
|
|
* purpose and without charge, including translations into other
|
|
* languages and incorporation into compilations, provided that the
|
|
* copyright notice and this notice are preserved, and that any
|
|
* substantive changes or deletions from the original are clearly
|
|
* marked.
|
|
*
|
|
*/
|
|
|
|
/* Table of CRCs of all 8-bit messages. */
|
|
static unsigned long crc_table[256];
|
|
|
|
/* Flag: has the table been computed? Initially false. */
|
|
static int crc_table_computed = 0;
|
|
|
|
/* Make the table for a fast CRC. */
|
|
static void make_crc_table(void)
|
|
{
|
|
unsigned long c;
|
|
int n, k;
|
|
|
|
for (n = 0; n < 256; n++) {
|
|
c = (unsigned long) n;
|
|
for (k = 0; k < 8; k++) {
|
|
if (c & 1) {
|
|
c = 0xedb88320L ^ (c >> 1);
|
|
} else {
|
|
c = c >> 1;
|
|
}
|
|
}
|
|
crc_table[n] = c;
|
|
}
|
|
crc_table_computed = 1;
|
|
}
|
|
|
|
/*
|
|
Update a running crc with the bytes buf[0..len-1] and return
|
|
the updated crc. The crc should be initialized to zero. Pre- and
|
|
post-conditioning (one's complement) is performed within this
|
|
function so it shouldn't be done by the caller. Usage example:
|
|
|
|
unsigned long crc = 0L;
|
|
|
|
while (read_buffer(buffer, length) != EOF) {
|
|
crc = update_crc(crc, buffer, length);
|
|
}
|
|
if (crc != original_crc) error();
|
|
*/
|
|
static unsigned long update_crc(unsigned long crc,
|
|
unsigned char *buf, int len)
|
|
{
|
|
unsigned long c = crc ^ 0xffffffffL;
|
|
int n;
|
|
|
|
if (!crc_table_computed)
|
|
make_crc_table();
|
|
for (n = 0; n < len; n++) {
|
|
c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
|
|
}
|
|
return c ^ 0xffffffffL;
|
|
}
|
|
|
|
/* Return the CRC of the bytes buf[0..len-1]. */
|
|
unsigned long nbase_crc32(unsigned char *buf, int len)
|
|
{
|
|
return update_crc(0L, buf, len);
|
|
}
|
|
|
|
|
|
/*
|
|
* CRC-32C (Castagnoli) Cyclic Redundancy Check.
|
|
* Taken straight from Appendix C of RFC 4960 (SCTP), with the difference that
|
|
* the remainder register (crc32) is initialized to 0xffffffffL rather than ~0L,
|
|
* for correct operation on platforms where unisigned long is longer than 32
|
|
* bits.
|
|
*/
|
|
|
|
/* Return the CRC-32C of the bytes buf[0..len-1] */
|
|
unsigned long nbase_crc32c(unsigned char *buf, int len)
|
|
{
|
|
int i;
|
|
unsigned long crc32 = 0xffffffffL;
|
|
unsigned long result;
|
|
unsigned char byte0, byte1, byte2, byte3;
|
|
|
|
for (i = 0; i < len; i++) {
|
|
CRC32C(crc32, buf[i]);
|
|
}
|
|
|
|
result = ~crc32;
|
|
|
|
/* result now holds the negated polynomial remainder;
|
|
* since the table and algorithm is "reflected" [williams95].
|
|
* That is, result has the same value as if we mapped the message
|
|
* to a polynomial, computed the host-bit-order polynomial
|
|
* remainder, performed final negation, then did an end-for-end
|
|
* bit-reversal.
|
|
* Note that a 32-bit bit-reversal is identical to four inplace
|
|
* 8-bit reversals followed by an end-for-end byteswap.
|
|
* In other words, the bytes of each bit are in the right order,
|
|
* but the bytes have been byteswapped. So we now do an explicit
|
|
* byteswap. On a little-endian machine, this byteswap and
|
|
* the final ntohl cancel out and could be elided.
|
|
*/
|
|
|
|
byte0 = result & 0xff;
|
|
byte1 = (result >> 8) & 0xff;
|
|
byte2 = (result >> 16) & 0xff;
|
|
byte3 = (result >> 24) & 0xff;
|
|
crc32 = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
|
|
return crc32;
|
|
}
|
|
|
|
|
|
/*
|
|
* Adler32 Checksum Calculation.
|
|
* Taken straight from RFC 2960 (SCTP).
|
|
*/
|
|
|
|
#define ADLER32_BASE 65521 /* largest prime smaller than 65536 */
|
|
|
|
/*
|
|
* Update a running Adler-32 checksum with the bytes buf[0..len-1]
|
|
* and return the updated checksum. The Adler-32 checksum should
|
|
* be initialized to 1.
|
|
*/
|
|
static unsigned long update_adler32(unsigned long adler,
|
|
unsigned char *buf, int len)
|
|
{
|
|
unsigned long s1 = adler & 0xffff;
|
|
unsigned long s2 = (adler >> 16) & 0xffff;
|
|
int n;
|
|
|
|
for (n = 0; n < len; n++) {
|
|
s1 = (s1 + buf[n]) % ADLER32_BASE;
|
|
s2 = (s2 + s1) % ADLER32_BASE;
|
|
}
|
|
return (s2 << 16) + s1;
|
|
}
|
|
|
|
/* Return the Adler32 of the bytes buf[0..len-1] */
|
|
unsigned long nbase_adler32(unsigned char *buf, int len)
|
|
{
|
|
return update_adler32(1L, buf, len);
|
|
}
|
|
|
|
#undef ADLER32_BASE
|
|
|
|
|
|
/* This function returns a string containing the hexdump of the supplied
|
|
* buffer. It uses current locale to determine if a character is printable or
|
|
* not. It prints 73char+\n wide lines like these:
|
|
|
|
0000 e8 60 65 86 d7 86 6d 30 35 97 54 87 ff 67 05 9e .`e...m05.T..g..
|
|
0010 07 5a 98 c0 ea ad 50 d2 62 4f 7b ff e1 34 f8 fc .Z....P.bO{..4..
|
|
0020 c4 84 0a 6a 39 ad 3c 10 63 b2 22 c4 24 40 f4 b1 ...j9.<.c.".$@..
|
|
|
|
* The lines look basically like Wireshark's hex dump.
|
|
* WARNING: This function returns a pointer to a DYNAMICALLY allocated buffer
|
|
* that the caller is supposed to free().
|
|
* */
|
|
char *hexdump(const u8 *cp, u32 length){
|
|
static char asciify[257]; /* Stores cha6acter table */
|
|
int asc_init=0; /* Flag to generate table only once */
|
|
u32 i=0, hex=0, asc=0; /* Array indexes */
|
|
u32 line_count=0; /* For byte count at line start */
|
|
char *current_line=NULL; /* Current line to write */
|
|
char *buffer=NULL; /* Dynamic buffer we return */
|
|
#define LINE_LEN 74 /* Lenght of printed line */
|
|
char line2print[LINE_LEN]; /* Stores current line */
|
|
char printbyte[16]; /* For byte conversion */
|
|
int bytes2alloc; /* For buffer */
|
|
memset(line2print, ' ', LINE_LEN); /* We fill the line with spaces */
|
|
|
|
/* On the first run, generate a list of nice printable characters
|
|
* (according to current locale) */
|
|
if( asc_init==0){
|
|
asc_init=1;
|
|
for(i=0; i<256; i++){
|
|
if( isalnum(i) || isdigit(i) || ispunct(i) ){ asciify[i]=i; }
|
|
else{ asciify[i]='.'; }
|
|
}
|
|
}
|
|
/* Allocate enough space to print the hex dump */
|
|
bytes2alloc=(length%16==0)? (1 + LINE_LEN * (length/16)) : (1 + LINE_LEN * (1+(length/16))) ;
|
|
buffer=(char *)safe_zalloc(bytes2alloc);
|
|
current_line=buffer;
|
|
#define HEX_START 7
|
|
#define ASC_START 57
|
|
/* This is how or line looks like.
|
|
0000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f .`e...m05.T..g..[\n]
|
|
01234567890123456789012345678901234567890123456789012345678901234567890123
|
|
0 1 2 3 4 5 6 7
|
|
^ ^ ^
|
|
| | |
|
|
HEX_START ASC_START Newline
|
|
*/
|
|
i=0;
|
|
while( i < length ){
|
|
memset(line2print, ' ', LINE_LEN); /* Fill line with spaces */
|
|
snprintf(line2print, sizeof(line2print), "%04x", (16*line_count++) % 0xFFFF); /* Add line No.*/
|
|
line2print[4]=' '; /* Replace the '\0' inserted by snprintf() with a space */
|
|
hex=HEX_START; asc=ASC_START;
|
|
do { /* Print 16 bytes in both hex and ascii */
|
|
if (i%16 == 8) hex++; /* Insert space every 8 bytes */
|
|
snprintf(printbyte, sizeof(printbyte), "%02x", cp[i]);/* First print the hex number */
|
|
line2print[hex++]=printbyte[0];
|
|
line2print[hex++]=printbyte[1];
|
|
line2print[hex++]=' ';
|
|
line2print[asc++]=asciify[ cp[i] ]; /* Then print its ASCII equivalent */
|
|
i++;
|
|
} while (i < length && i%16 != 0);
|
|
/* Copy line to output buffer */
|
|
line2print[LINE_LEN-1]='\n';
|
|
memcpy(current_line, line2print, LINE_LEN);
|
|
current_line += LINE_LEN;
|
|
}
|
|
buffer[bytes2alloc-1]='\0';
|
|
return buffer;
|
|
} /* End of hexdump() */
|
|
|
|
/* This is like strtol or atoi, but it allows digits only. No whitespace, sign,
|
|
or radix prefix. */
|
|
long parse_long(const char *s, char **tail)
|
|
{
|
|
if (!isdigit((int) (unsigned char) *s)) {
|
|
*tail = (char *) s;
|
|
return 0;
|
|
}
|
|
|
|
return strtol(s, (char **) tail, 10);
|
|
}
|
|
|
|
|
|
|
|
/* This function takes a byte count and stores a short ascii equivalent
|
|
in the supplied buffer. Eg: 0.122MB, 10.322Kb or 128B. */
|
|
char *format_bytecount(unsigned long long bytes, char *buf, size_t buflen) {
|
|
assert(buf != NULL);
|
|
|
|
if (bytes < 1000)
|
|
Snprintf(buf, buflen, "%uB", (unsigned int) bytes);
|
|
else if (bytes < 1000000)
|
|
Snprintf(buf, buflen, "%.3fKB", bytes / 1000.0);
|
|
else
|
|
Snprintf(buf, buflen, "%.3fMB", bytes / 1000000.0);
|
|
|
|
return buf;
|
|
}
|
|
|
|
/* Compare a canonical option name (e.g. "max-scan-delay") with a
|
|
user-generated option such as "max_scan_delay" and returns 0 if the
|
|
two values are considered equivalent (for example, - and _ are
|
|
considered to be the same), nonzero otherwise. */
|
|
int optcmp(const char *a, const char *b) {
|
|
while(*a && *b) {
|
|
if (*a == '_' || *a == '-') {
|
|
if (*b != '_' && *b != '-')
|
|
return 1;
|
|
}
|
|
else if (*a != *b)
|
|
return 1;
|
|
a++; b++;
|
|
}
|
|
if (*a || *b)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
/* Returns one if the file pathname given exists, is not a directory and
|
|
* is readable by the executing process. Returns two if it is readable
|
|
* and is a directory. Otherwise returns 0. */
|
|
int file_is_readable(const char *pathname) {
|
|
char *pathname_buf = strdup(pathname);
|
|
int status = 0;
|
|
struct stat st;
|
|
|
|
#ifdef WIN32
|
|
// stat on windows only works for "dir_name" not for "dir_name/" or "dir_name\\"
|
|
int pathname_len = strlen(pathname_buf);
|
|
char last_char = pathname_buf[pathname_len - 1];
|
|
|
|
if( last_char == '/'
|
|
|| last_char == '\\')
|
|
pathname_buf[pathname_len - 1] = '\0';
|
|
|
|
#endif
|
|
|
|
if (stat(pathname_buf, &st) == -1)
|
|
status = 0;
|
|
else if (access(pathname_buf, R_OK) != -1)
|
|
status = S_ISDIR(st.st_mode) ? 2 : 1;
|
|
|
|
free(pathname_buf);
|
|
return status;
|
|
}
|
|
|
|
#if HAVE_PROC_SELF_EXE
|
|
static char *executable_path_proc_self_exe(void) {
|
|
char buf[1024];
|
|
char *path;
|
|
int n;
|
|
|
|
n = readlink("/proc/self/exe", buf, sizeof(buf));
|
|
if (n < 0 || n >= sizeof(buf))
|
|
return NULL;
|
|
path = (char *) safe_malloc(n + 1);
|
|
/* readlink does not null-terminate. */
|
|
memcpy(path, buf, n);
|
|
path[n] = '\0';
|
|
|
|
return path;
|
|
}
|
|
#endif
|
|
|
|
#if HAVE_MACH_O_DYLD_H
|
|
#include <mach-o/dyld.h>
|
|
/* See the dyld(3) man page on OS X. */
|
|
static char *executable_path_NSGetExecutablePath(void) {
|
|
char buf[1024];
|
|
uint32_t size;
|
|
|
|
size = sizeof(buf);
|
|
if (_NSGetExecutablePath(buf, &size) == 0)
|
|
return strdup(buf);
|
|
else
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
#if WIN32
|
|
static char *executable_path_GetModuleFileName(void) {
|
|
char buf[1024];
|
|
int n;
|
|
|
|
n = GetModuleFileName(GetModuleHandle(0), buf, sizeof(buf));
|
|
if (n <= 0 || n >= sizeof(buf))
|
|
return NULL;
|
|
|
|
return strdup(buf);
|
|
}
|
|
#endif
|
|
|
|
static char *executable_path_argv0(const char *argv0) {
|
|
if (argv0 == NULL)
|
|
return NULL;
|
|
/* We can get the path from argv[0] if it contains a directory separator.
|
|
(Otherwise it was looked up in $PATH). */
|
|
if (strchr(argv0, '/') != NULL)
|
|
return strdup(argv0);
|
|
#if WIN32
|
|
if (strchr(argv0, '\\') != NULL)
|
|
return strdup(argv0);
|
|
#endif
|
|
return NULL;
|
|
}
|
|
|
|
char *executable_path(const char *argv0) {
|
|
char *path;
|
|
|
|
path = NULL;
|
|
#if HAVE_PROC_SELF_EXE
|
|
if (path == NULL)
|
|
path = executable_path_proc_self_exe();
|
|
#endif
|
|
#if HAVE_MACH_O_DYLD_H
|
|
if (path == NULL)
|
|
path = executable_path_NSGetExecutablePath();
|
|
#endif
|
|
#if WIN32
|
|
if (path == NULL)
|
|
path = executable_path_GetModuleFileName();
|
|
#endif
|
|
if (path == NULL)
|
|
path = executable_path_argv0(argv0);
|
|
|
|
return path;
|
|
}
|