1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 12:41:29 +00:00
This commit is contained in:
fyodor
2005-10-01 23:50:27 +00:00
parent b80808b3f3
commit d187c68017
29 changed files with 99 additions and 83 deletions

View File

@@ -1,10 +1,24 @@
# Nmap Changelog ($Id$) # Nmap Changelog ($Id$)
Nmap 3.92
o Fixed a possible aliasing problem in tcpip.cc by applying a patch sent in by
Gwenole Beauchesne (gbeauchesne(a)mandriva.com). This problem
shouldn't have had any effect on users since we already include the
-fno-strict-aliasing option whenever gcc 4 is detected, but it
brings us closer to being able to remove that option.
o Fixed a bug that caused Nmap to crash if an nmap-service-probes file
was used which didn't contain the Exclude directive.
o Fixed a bunch of typos and misspellings throughout the Nmap source
code (mostly in comments). This was a 625-line patch by Saint Xavier
(skyxav(a)skynet.be).
Nmap 3.93
o Modified Libpcap's configure.ac to compile with the o Modified Libpcap's configure.ac to compile with the
--fno-strict-aliasing option if gcc 4.X is used. This prevents when -fno-strict-aliasing option if gcc 4.X is used. This prevents
said compiler is used. This was done for Nmap in 3.90, but is crashes when said compiler is used. This was done for Nmap in 3.90, but is
apparently needed for pcap too. Thanks to Craig Humphrey apparently needed for pcap too. Thanks to Craig Humphrey
(Craig.Humphrey(a)chapmantripp.com) for the discovery. (Craig.Humphrey(a)chapmantripp.com) for the discovery.
@@ -148,7 +162,7 @@ o Fixed a crash problem related to non-portable varargs (vsnprintf)
CPU in 64-bit mode. CPU in 64-bit mode.
o Fixed crash when Nmap is compiled using gcc 4.X by adding the o Fixed crash when Nmap is compiled using gcc 4.X by adding the
--fno-strict-aliasing option when that compiler is detected. Thanks -fno-strict-aliasing option when that compiler is detected. Thanks
to Greg Darke (starstuff(a)optusnet.com.au) for discovering that to Greg Darke (starstuff(a)optusnet.com.au) for discovering that
this option fixes (hides) the problem and to Duilio J. Protti this option fixes (hides) the problem and to Duilio J. Protti
(dprotti(a)flowgate.net) for writing the configure patch to detect (dprotti(a)flowgate.net) for writing the configure patch to detect

View File

@@ -113,7 +113,7 @@ and just send us the patch: file.c.patch.
Credits Credits
------- -------
I got the idea for this HACKING file from GNet ( I got the idea for this HACKING file from GNet
http://www.eecs.umich.edu/~dhelder/misc/gnet/ ) and followed the (http://www.gnetlibrary.org/) and followed the
general structure of their HACKING file. general structure of their HACKING file.

View File

@@ -163,7 +163,7 @@ const struct in_addr *NmapOps::v4sourceip() {
} }
// Number of milliseconds since getStartTime(). The current time is an // Number of milliseconds since getStartTime(). The current time is an
// optional argument to avoid an extre gettimeofday() call. // optional argument to avoid an extra gettimeofday() call.
int NmapOps::TimeSinceStartMS(struct timeval *now) { int NmapOps::TimeSinceStartMS(struct timeval *now) {
struct timeval tv; struct timeval tv;
if (!now) if (!now)
@@ -209,7 +209,7 @@ void NmapOps::Initialize() {
min_rtt_timeout = MIN_RTT_TIMEOUT; min_rtt_timeout = MIN_RTT_TIMEOUT;
initial_rtt_timeout = INITIAL_RTT_TIMEOUT; initial_rtt_timeout = INITIAL_RTT_TIMEOUT;
min_host_group_sz = 1; min_host_group_sz = 1;
max_host_group_sz = 100000; // don't want to be restrictive unles user sets max_host_group_sz = 100000; // don't want to be restrictive unless user sets
max_tcp_scan_delay = MAX_TCP_SCAN_DELAY; max_tcp_scan_delay = MAX_TCP_SCAN_DELAY;
max_udp_scan_delay = MAX_UDP_SCAN_DELAY; max_udp_scan_delay = MAX_UDP_SCAN_DELAY;
max_ips_to_scan = 0; max_ips_to_scan = 0;
@@ -436,7 +436,7 @@ void NmapOps::setMaxRttTimeout(int rtt)
void NmapOps::setMinRttTimeout(int rtt) void NmapOps::setMinRttTimeout(int rtt)
{ {
if (rtt < 0) fatal("NmapOps::setMaxRttTimeout(): minimum round trip time must be at least 0"); if (rtt < 0) fatal("NmapOps::setMinRttTimeout(): minimum round trip time must be at least 0");
min_rtt_timeout = rtt; min_rtt_timeout = rtt;
if (rtt > max_rtt_timeout) max_rtt_timeout = rtt; if (rtt > max_rtt_timeout) max_rtt_timeout = rtt;
if (rtt > initial_rtt_timeout) initial_rtt_timeout = rtt; if (rtt > initial_rtt_timeout) initial_rtt_timeout = rtt;
@@ -444,7 +444,7 @@ void NmapOps::setMinRttTimeout(int rtt)
void NmapOps::setInitialRttTimeout(int rtt) void NmapOps::setInitialRttTimeout(int rtt)
{ {
if (rtt <= 0) fatal("NmapOps::setMaxRttTimeout(): initial round trip time must be greater than 0"); if (rtt <= 0) fatal("NmapOps::setInitialRttTimeout(): initial round trip time must be greater than 0");
initial_rtt_timeout = rtt; initial_rtt_timeout = rtt;
if (rtt > max_rtt_timeout) max_rtt_timeout = rtt; if (rtt > max_rtt_timeout) max_rtt_timeout = rtt;
if (rtt < min_rtt_timeout) min_rtt_timeout = rtt; if (rtt < min_rtt_timeout) min_rtt_timeout = rtt;

View File

@@ -170,7 +170,7 @@ void NmapOutputTable::addItem(unsigned int row, unsigned int column, bool copy,
return; return;
} }
// Like addItem except this version takes a prinf-style format string // Like addItem except this version takes a printf-style format string
// followed by varargs // followed by varargs
void NmapOutputTable::addItemFormatted(unsigned int row, void NmapOutputTable::addItemFormatted(unsigned int row,
unsigned int column, unsigned int column,
@@ -211,8 +211,8 @@ int NmapOutputTable::printableSize() {
// This function sticks the entire table into a character buffer. // This function sticks the entire table into a character buffer.
// Note that the buffer is likely to be reused if you call the // Note that the buffer is likely to be reused if you call the
// function again, and it will also be invalidated if you free the // function again, and it will also be invalidated if you free the
// Table. if size is not NULL, it will be filled with the size of // table. If size is not NULL, it will be filled with the size of
// the ASCII table in bytes (not including the terminating NUL // the ASCII table in bytes (not including the terminating NUL)
char *NmapOutputTable::printableTable(int *size) { char *NmapOutputTable::printableTable(int *size) {
unsigned int col, row; unsigned int col, row;

View File

@@ -130,7 +130,7 @@ class NmapOutputTable {
// ptr (and you better not free it until this table is destroyed ). Skip the itemlen parameter if you // ptr (and you better not free it until this table is destroyed ). Skip the itemlen parameter if you
// don't know (and the function will use strlen). // don't know (and the function will use strlen).
void addItem(unsigned int row, unsigned int column, bool copy, const char *item, int itemlen = -1); void addItem(unsigned int row, unsigned int column, bool copy, const char *item, int itemlen = -1);
// Like addItem except this version takes a prinf-style format string followed by varargs // Like addItem except this version takes a printf-style format string followed by varargs
void addItemFormatted(unsigned int row, unsigned int column, const char *fmt, ...) void addItemFormatted(unsigned int row, unsigned int column, const char *fmt, ...)
__attribute__ ((format (printf, 4, 5))); __attribute__ ((format (printf, 4, 5)));
// Returns the maximum size neccessary to create a printableTable() (the // Returns the maximum size neccessary to create a printableTable() (the
@@ -140,8 +140,8 @@ class NmapOutputTable {
// This function sticks the entire table into a character buffer. // This function sticks the entire table into a character buffer.
// Note that the buffer is likely to be reused if you call the // Note that the buffer is likely to be reused if you call the
// function again, and it will also be invalidated if you free the // function again, and it will also be invalidated if you free the
// Table. if size is not NULL, it will be filled with the size of // table. If size is not NULL, it will be filled with the size of
// the ASCII table in bytes (not including the terminating NUL // the ASCII table in bytes (not including the terminating NUL)
char *printableTable(int *size); char *printableTable(int *size);
private: private:
@@ -158,8 +158,8 @@ class NmapOutputTable {
int *itemsInRow; int *itemsInRow;
unsigned int numRows; unsigned int numRows;
unsigned int numColumns; unsigned int numColumns;
char *tableout; // If printableTable() is called, we returnthis char *tableout; // If printableTable() is called, we return this
int tableoutsz; // Amount of space ALLOCATED for tableoutsz. Includes space allocated for NUL. int tableoutsz; // Amount of space ALLOCATED for tableout. Includes space allocated for NUL.
}; };

View File

@@ -281,7 +281,7 @@ void Target::setHostName(char *name) {
} }
p = hostname = strdup(name); p = hostname = strdup(name);
while (*p) { while (*p) {
// I think only a-z A-Z 0-9 . and - are allowed, but I'l be a little more // I think only a-z A-Z 0-9 . and - are allowed, but I'll be a little more
// generous. // generous.
if (!isalnum(*p) && !strchr(".-+=:_~*", *p)) { if (!isalnum(*p) && !strchr(".-+=:_~*", *p)) {
log_write(LOG_STDOUT, "Illegal character(s) in hostname -- replacing with '*'\n"); log_write(LOG_STDOUT, "Illegal character(s) in hostname -- replacing with '*'\n");
@@ -292,11 +292,11 @@ void Target::setHostName(char *name) {
} }
} }
/* Generates the a printable string consisting of the host's IP /* Generates a printable string consisting of the host's IP
address and hostname (if available). Eg "www.insecure.org address and hostname (if available). Eg "www.insecure.org
(64.71.184.53)" or "fe80::202:e3ff:fe14:1102". The name is (64.71.184.53)" or "fe80::202:e3ff:fe14:1102". The name is
written into the buffer provided, which is also returned. Results written into the buffer provided, which is also returned. Results
that do not fit in bufflen will be truncated. */ that do not fit in buflen will be truncated. */
const char *Target::NameIP(char *buf, size_t buflen) { const char *Target::NameIP(char *buf, size_t buflen) {
assert(buf); assert(buf);
assert(buflen > 8); assert(buflen > 8);

View File

@@ -151,7 +151,7 @@ class Target {
order order
*/ */
void setHostName(char *name); void setHostName(char *name);
/* Generates the a printable string consisting of the host's IP /* Generates a printable string consisting of the host's IP
address and hostname (if available). Eg "www.insecure.org address and hostname (if available). Eg "www.insecure.org
(64.71.184.53)" or "fe80::202:e3ff:fe14:1102". The name is (64.71.184.53)" or "fe80::202:e3ff:fe14:1102". The name is
written into the buffer provided, which is also returned. Results written into the buffer provided, which is also returned. Results

View File

@@ -179,7 +179,7 @@ int TargetGroup::parse_expr(const char * const target_expr, int af) {
if (strchr(hostexp, ':')) if (strchr(hostexp, ':'))
fatal("Invalid host expression: %s -- colons only allowed in IPv6 addresses, and then you need the -6 switch", hostexp); fatal("Invalid host expression: %s -- colons only allowed in IPv6 addresses, and then you need the -6 switch", hostexp);
/*strauct in_addr current_in;*/ /*struct in_addr current_in;*/
addy[0] = addy[1] = addy[2] = addy[3] = addy[4] = NULL; addy[0] = addy[1] = addy[2] = addy[3] = addy[4] = NULL;
addy[0] = r = hostexp; addy[0] = r = hostexp;
/* First we break the expression up into the four parts of the IP address /* First we break the expression up into the four parts of the IP address
@@ -281,7 +281,7 @@ int TargetGroup::parse_expr(const char * const target_expr, int af) {
hints.ai_family = PF_INET6; hints.ai_family = PF_INET6;
rc = getaddrinfo(hostexp, NULL, &hints, &result); rc = getaddrinfo(hostexp, NULL, &hints, &result);
if (rc != 0) { if (rc != 0) {
fprintf(stderr, "Failed to resolve given IPv6 hostname/IP: %s. Note that you can't use '/mask' or '[1-4,7,100-]' style ranges for IPv6. Error cod %d: %s\n", hostexp, rc, gai_strerror(rc)); fprintf(stderr, "Failed to resolve given IPv6 hostname/IP: %s. Note that you can't use '/mask' or '[1-4,7,100-]' style ranges for IPv6. Error code %d: %s\n", hostexp, rc, gai_strerror(rc));
free(hostexp); free(hostexp);
if (result) freeaddrinfo(result); if (result) freeaddrinfo(result);
return 1; return 1;
@@ -355,7 +355,7 @@ int TargetGroup::skip_range(_octet_nums octet) {
} }
/* Grab the next host from this expression (if any) and uptdates its internal /* Grab the next host from this expression (if any) and uptdates its internal
state to reflect the the IP was given out. Returns 0 and state to reflect that the IP was given out. Returns 0 and
fills in ss if successful. ss must point to a pre-allocated fills in ss if successful. ss must point to a pre-allocated
sockaddr_storage structure */ sockaddr_storage structure */
int TargetGroup::get_next_host(struct sockaddr_storage *ss, size_t *sslen) { int TargetGroup::get_next_host(struct sockaddr_storage *ss, size_t *sslen) {
@@ -416,7 +416,7 @@ int TargetGroup::get_next_host(struct sockaddr_storage *ss, size_t *sslen) {
} }
} }
if (octet == -1) { if (octet == -1) {
/* It didn't find anything to bump up, I muast have taken the last IP */ /* It didn't find anything to bump up, I must have taken the last IP */
assert(ipsleft == 1); assert(ipsleft == 1);
/* So I set current to last with the very final octet up one ... */ /* So I set current to last with the very final octet up one ... */
/* Note that this may make current[3] == 256 */ /* Note that this may make current[3] == 256 */
@@ -486,7 +486,7 @@ int TargetGroup::return_last_host() {
/* Lookahead is the number of hosts that can be /* Lookahead is the number of hosts that can be
checked (such as ping scanned) in advance. Randomize causes each checked (such as ping scanned) in advance. Randomize causes each
group of up to lookahead hosts to be internally shuffled around. group of up to lookahead hosts to be internally shuffled around.
The target_expressions array MUST REMAIN VALID IN MEMMORY as long as The target_expressions array MUST REMAIN VALID IN MEMORY as long as
this class instance is used -- the array is NOT copied. this class instance is used -- the array is NOT copied.
*/ */
HostGroupState::HostGroupState(int lookahead, int rnd, HostGroupState::HostGroupState(int lookahead, int rnd,

View File

@@ -151,7 +151,7 @@ class TargetGroup {
struct in_addr currentaddr; struct in_addr currentaddr;
struct in_addr endaddr; struct in_addr endaddr;
// These three are for the '138.[1-7,16,91-95,200-].12.1 style (IPV4_RANGES) // These three are for the '138.[1-7,16,91-95,200-].12.1' style (IPV4_RANGES)
u8 addresses[4][256]; u8 addresses[4][256];
unsigned int current[4]; unsigned int current[4];
u8 last[4]; u8 last[4];
@@ -172,7 +172,7 @@ class HostGroupState {
int current_batch_sz; /* The number of VALID members of hostbatch[] */ int current_batch_sz; /* The number of VALID members of hostbatch[] */
int next_batch_no; /* The index of the next hostbatch[] member to be given int next_batch_no; /* The index of the next hostbatch[] member to be given
back to the user */ back to the user */
int randomize; /* Whether each bach should be "shuffled" prior to the ping int randomize; /* Whether each batch should be "shuffled" prior to the ping
scan (they will also be out of order when given back one scan (they will also be out of order when given back one
at a time to the client program */ at a time to the client program */
char **target_expressions; /* An array of target expression strings, passed char **target_expressions; /* An array of target expression strings, passed

View File

@@ -1,4 +1,4 @@
Nmap 3.92 Usage: nmap [Scan Type(s)] [Options] <host or net list> Nmap 3.93 Usage: nmap [Scan Type(s)] [Options] <host or net list>
Some Common Scan Types ('*' options require root privileges) Some Common Scan Types ('*' options require root privileges)
* -sS TCP SYN stealth port scan (default if privileged (root)) * -sS TCP SYN stealth port scan (default if privileged (root))
-sT TCP connect() port scan (default for unprivileged users) -sT TCP connect() port scan (default for unprivileged users)

View File

@@ -5069,7 +5069,7 @@ TSeq(Class=64K%IPID=I%TS=U)
T1(DF=N%W=2000%ACK=S++%Flags=AS%Ops=MNW) T1(DF=N%W=2000%ACK=S++%Flags=AS%Ops=MNW)
T2(Resp=Y%DF=N%W=400|800|C00|1000%ACK=S%Flags=AR%Ops=) T2(Resp=Y%DF=N%W=400|800|C00|1000%ACK=S%Flags=AR%Ops=)
T3(Resp=Y%DF=N%W=2000%ACK=O%Flags=A%Ops=) T3(Resp=Y%DF=N%W=2000%ACK=O%Flags=A%Ops=)
T4(DF=N%W==400|800|C00|1000%ACK=S%Flags=AR%Ops=) T4(DF=N%W=400|800|C00|1000%ACK=S%Flags=AR%Ops=)
T5(DF=N%W=0%ACK=S++%Flags=AR%Ops=) T5(DF=N%W=0%ACK=S++%Flags=AR%Ops=)
T6(DF=N%W=400|800|C00|1000%ACK=S%Flags=AR%Ops=) T6(DF=N%W=400|800|C00|1000%ACK=S%Flags=AR%Ops=)
T7(DF=N%W=400|800|C00|1000%ACK=S++%Flags=AR%Ops=) T7(DF=N%W=400|800|C00|1000%ACK=S++%Flags=AR%Ops=)

View File

@@ -249,8 +249,8 @@ match ftp m|^220 ([\w-_.]+) FTP server ready!\r\n| p/ProFTPD/ o/Unix/ h/$1/
match ftp m|^220 FTP Server ready\.\r\n$| p/ProFTPD/ o/Unix/ match ftp m|^220 FTP Server ready\.\r\n$| p/ProFTPD/ o/Unix/
match ftp m/^220.*NcFTPd Server / p/NcFTPd/ o/Unix/ match ftp m/^220.*NcFTPd Server / p/NcFTPd/ o/Unix/
match ftp m/^220.*FTP server \(SunOS 5\.([789])\) ready/ p/Sun Solaris $1 ftpd/ o/Solaris/ match ftp m/^220 ([\w-_.]+) FTP server \(SunOS 5\.([789])\) ready/ p/Sun Solaris $2 ftpd/ o/Solaris/ h/$1/
match ftp m/^220.*FTP server \(SunOS (\S+)\) ready/ p/Sun SunOS ftpd/ v/$1/ o/Solaris/ match ftp m/^220 ([\w-_.]+) FTP server \(SunOS (\S+)\) ready/ p/Sun SunOS ftpd/ v/$2/ o/Solaris/ h/$1/
match ftp m/^220-([-.\w]+) IBM FTP.*(V\d+R\d+)/ p|IBM OS/390 ftpd| h/$1/ v/$2/ o|OS/390| match ftp m/^220-([-.\w]+) IBM FTP.*(V\d+R\d+)/ p|IBM OS/390 ftpd| h/$1/ v/$2/ o|OS/390|
match ftp m|^220-IBM FTP, .*\.\r\n220 Connection will close if idle for more than 120 minutes\.\r\n| p|IBM OS/390 ftpd| o|OS/390| match ftp m|^220-IBM FTP, .*\.\r\n220 Connection will close if idle for more than 120 minutes\.\r\n| p|IBM OS/390 ftpd| o|OS/390|
match ftp m/^220 VxWorks \((\d[^)]+)\) FTP server ready/ p/VxWorks ftpd/ v/$1/ o/VxWorks/ match ftp m/^220 VxWorks \((\d[^)]+)\) FTP server ready/ p/VxWorks ftpd/ v/$1/ o/VxWorks/
@@ -612,7 +612,7 @@ match irc-proxy m|^:dircproxy NOTICE AUTH :Looking up your hostname\.\.\.\r\n:di
# dirkproxy (modificated dircproxy) # dirkproxy (modificated dircproxy)
match irc-proxy m|^:dirkproxy NOTICE AUTH :Looking up your hostname\.\.\.\r\n:dirkproxy NOTICE AUTH :Got your hostname\.\r\n| p/dirkproxy/ match irc-proxy m|^:dirkproxy NOTICE AUTH :Looking up your hostname\.\.\.\r\n:dirkproxy NOTICE AUTH :Got your hostname\.\r\n| p/dirkproxy/
# Unreal IRCD Server version 3.2 beta 17 # Unreal IRCD Server version 3.2 beta 17
match irc m|(^:[-.\w]+) NOTICE AUTH :\*\*\* Looking up your hostname\.\.\.\r\n| p/Unreal ircd/ h/$1/ match irc m|^:([-.\w]+) NOTICE AUTH :\*\*\* Looking up your hostname\.\.\.\r\n| p/Unreal ircd/ h/$1/
# dancer-ircd 1.0.31+maint8-1 # dancer-ircd 1.0.31+maint8-1
match irc m|^NOTICE AUTH :\*\*\* Looking up your hostname\.\.\.\r\nNOTICE AUTH :\*\*\* Checking ident\r\nNOTICE AUTH :\*\*\* No identd \(auth\) response\r\nNOTICE AUTH :\*\*\* Found your hostname\r\n$| p/Dancer ircd/ match irc m|^NOTICE AUTH :\*\*\* Looking up your hostname\.\.\.\r\nNOTICE AUTH :\*\*\* Checking ident\r\nNOTICE AUTH :\*\*\* No identd \(auth\) response\r\nNOTICE AUTH :\*\*\* Found your hostname\r\n$| p/Dancer ircd/

View File

@@ -160,7 +160,7 @@ static int parse_scanflags(char *arg) {
static int parse_bounce_argument(struct ftpinfo *ftp, char *url) { static int parse_bounce_argument(struct ftpinfo *ftp, char *url) {
char *p = url,*q, *s; char *p = url,*q, *s;
if ((q = strrchr(url, '@'))) /*we have username and/or pass */ { if ((q = strrchr(url, '@'))) { /*we have username and/or pass */
*(q++) = '\0'; *(q++) = '\0';
if ((s = strchr(q, ':'))) if ((s = strchr(q, ':')))
{ /* has portno */ { /* has portno */
@@ -309,7 +309,7 @@ int nmap_main(int argc, char *argv[]) {
} }
fakeargv[argc] = NULL; fakeargv[argc] = NULL;
emptystring[0] = '\0'; /* It wouldn't be an emptystring w/o this ;) */ emptystring[0] = '\0'; /* It wouldn't be an empty string w/o this ;) */
if (argc < 2 ) printusage(argv[0], -1); if (argc < 2 ) printusage(argv[0], -1);
Targets.reserve(100); Targets.reserve(100);
@@ -532,7 +532,7 @@ int nmap_main(int argc, char *argv[]) {
if (resolve(p, &o.decoys[o.numdecoys])) { if (resolve(p, &o.decoys[o.numdecoys])) {
o.numdecoys++; o.numdecoys++;
} else { } else {
fatal("Failed to resolve decoy host: %s (must be hostname or IP address", optarg); fatal("Failed to resolve decoy host: %s (must be hostname or IP address)", optarg);
} }
} }
if (q) { if (q) {

View File

@@ -206,7 +206,7 @@ int get_rpc_procs(unsigned long **programs, unsigned long *num_programs) {
/* Send an RPC query to the specified host/port on the specified protocol /* Send an RPC query to the specified host/port on the specified protocol
looking for the specified RPC program. We cache our sending sockets looking for the specified RPC program. We cache our sending sockets
to avoid recreating and (with TCP) reconnect() ing them each time */ to avoid recreating and (with TCP) reconnect()'ing them each time */
int send_rpc_query(const struct in_addr *target_host, unsigned short portno, int send_rpc_query(const struct in_addr *target_host, unsigned short portno,
int ipproto, unsigned long program, int scan_offset, int ipproto, unsigned long program, int scan_offset,
int trynum) { int trynum) {
@@ -399,7 +399,7 @@ int rpc_are_we_done(char *msg, int msg_len, Target *target,
if (current->state != PORT_TESTING && current->state != PORT_CLOSED && if (current->state != PORT_TESTING && current->state != PORT_CLOSED &&
current->state != PORT_FILTERED) { current->state != PORT_FILTERED) {
error("Supposed scan_offset refers to port in state %s (should be testing,closed, or filtered)", statenum2str(current->state)); error("Supposed scan_offset refers to port in state %s (should be testing, closed, or filtered)", statenum2str(current->state));
rsi->rpc_status = RPC_STATUS_NOT_RPC; rsi->rpc_status = RPC_STATUS_NOT_RPC;
ss->numqueries_outstanding = 0; ss->numqueries_outstanding = 0;
return 1; return 1;

View File

@@ -111,7 +111,7 @@
#include "utils.h" #include "utils.h"
#include "timing.h" #include "timing.h"
/* rpc related #defines */ /* rpc related #define's */
#define RECORD_MARKING 4 /* length of recoder marking (bytes) */ #define RECORD_MARKING 4 /* length of recoder marking (bytes) */
/* defines used to check RPC answers */ /* defines used to check RPC answers */

View File

@@ -182,7 +182,7 @@ get_random_bytes(&sequence_base, sizeof(unsigned int));
} else { } else {
/* Init our raw socket */ /* Init our raw socket */
if ((rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 ) if ((rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 )
pfatal("socket trobles in get_fingerprint"); pfatal("socket troubles in get_fingerprint");
unblock_socket(rawsd); unblock_socket(rawsd);
broadcast_socket(rawsd); broadcast_socket(rawsd);
#ifndef WIN32 #ifndef WIN32
@@ -929,7 +929,7 @@ double compare_fingerprints(FingerPrint *referenceFP, FingerPrint *observedFP,
} }
/* Takes a fingerprint and looks for matches inside reference_FPs[]. /* Takes a fingerprint and looks for matches inside reference_FPs[].
The results are stored in in FPR (which must point to an instantiated The results are stored in FPR (which must point to an instantiated
FingerPrintResults class) -- results will be reverse-sorted by FingerPrintResults class) -- results will be reverse-sorted by
accuracy. No results below accuracy_threshhold will be included. accuracy. No results below accuracy_threshhold will be included.
The max matches returned is the maximum that fits in a The max matches returned is the maximum that fits in a
@@ -1172,7 +1172,7 @@ int bestaccidx;
#ifdef WIN32 #ifdef WIN32
if (target->ifType() == devt_loopback) { if (target->ifType() == devt_loopback) {
log_write(LOG_STDOUT, "Skipping OS Scan against %s because it doesn't work against your own machine (localhsot)\n", target->NameIP()); log_write(LOG_STDOUT, "Skipping OS Scan against %s because it doesn't work against your own machine (localhost)\n", target->NameIP());
return 1; return 1;
} }
#endif #endif
@@ -1753,7 +1753,7 @@ for(decoy=0; decoy < o.numdecoys; decoy++) {
udp->uh_dport = htons(dport); udp->uh_dport = htons(dport);
udp->uh_ulen = htons(8 + datalen); udp->uh_ulen = htons(8 + datalen);
/* Now the psuedo header for checksuming */ /* Now the pseudo header for checksuming */
pseudo->source.s_addr = source->s_addr; pseudo->source.s_addr = source->s_addr;
pseudo->dest.s_addr = victim->s_addr; pseudo->dest.s_addr = victim->s_addr;
pseudo->proto = IPPROTO_UDP; pseudo->proto = IPPROTO_UDP;
@@ -2012,7 +2012,7 @@ int ipid_sequence(int numSamples, u16 *ipids, int islocalhost) {
if (ipid_diffs[i] % 256 == 0) /* Stupid MS */ if (ipid_diffs[i] % 256 == 0) /* Stupid MS */
ipid_diffs[i] -= 256; ipid_diffs[i] -= 256;
else else
ipid_diffs[i]--; /* Because on localhost the RST sent back ues an IPID */ ipid_diffs[i]--; /* Because on localhost the RST sent back use an IPID */
} }
} }
} }

View File

@@ -178,8 +178,8 @@ static void populateFullVersionString(struct serviceDeductions *sd) {
} }
// pass in an allocated struct serviceDeductions (don't wory about // pass in an allocated struct serviceDeductions (don't worry about
// initializing, and you don't have to free any inernal ptrs. See the // initializing, and you don't have to free any internal ptrs. See the
// serviceDeductions definition for the fields that are populated. // serviceDeductions definition for the fields that are populated.
// Returns 0 if at least a name is available. // Returns 0 if at least a name is available.
int Port::getServiceDeductions(struct serviceDeductions *sd) { int Port::getServiceDeductions(struct serviceDeductions *sd) {
@@ -258,7 +258,7 @@ int Port::getServiceDeductions(struct serviceDeductions *sd) {
// will be NULL if unavailable. Note that this function makes its // will be NULL if unavailable. Note that this function makes its
// own copy of sname and product/version/extrainfo. This function // own copy of sname and product/version/extrainfo. This function
// also takes care of truncating the version strings to a // also takes care of truncating the version strings to a
// 'reasonable' length if neccessary, and cleaning up any unprinable // 'reasonable' length if neccessary, and cleaning up any unprintable
// chars. (these tests are to avoid annoying DOS (or other) attacks // chars. (these tests are to avoid annoying DOS (or other) attacks
// by malicious services). The fingerprint should be NULL unless // by malicious services). The fingerprint should be NULL unless
// one is available and the user should submit it. tunnel must be // one is available and the user should submit it. tunnel must be
@@ -547,7 +547,7 @@ int PortList::removePort(u16 portno, u8 protocol) {
} }
/* Saves an identification string for the target containing these /* Saves an identification string for the target containing these
ports (an IP addrss might be a good example, but set what you ports (an IP address might be a good example, but set what you
want). Only used when printing new port updates. Optional. A want). Only used when printing new port updates. Optional. A
copy is made. */ copy is made. */
void PortList::setIdStr(const char *id) { void PortList::setIdStr(const char *id) {

View File

@@ -184,7 +184,7 @@ class Port {
Port(); Port();
~Port(); ~Port();
// pass in an allocated struct serviceDeductions (don't wory about initializing, and // pass in an allocated struct serviceDeductions (don't worry about initializing, and
// you don't have to free any internal ptrs. See the serviceDeductions definition for // you don't have to free any internal ptrs. See the serviceDeductions definition for
// the fields that are populated. Returns 0 if at least a name is available. // the fields that are populated. Returns 0 if at least a name is available.
int getServiceDeductions(struct serviceDeductions *sd); int getServiceDeductions(struct serviceDeductions *sd);

View File

@@ -308,7 +308,7 @@ public:
Timedout probes are often marked as such (and sometimes Timedout probes are often marked as such (and sometimes
considered a drop), but kept in the list juts in case they come considered a drop), but kept in the list juts in case they come
really late. But after probeExpire(), I don't waste time keeping really late. But after probeExpire(), I don't waste time keeping
them around. Givein in MICROseconds */ them around. Give in MICROseconds */
unsigned long probeExpire(); unsigned long probeExpire();
/* Returns OK if sending a new probe to this host is OK (to avoid /* Returns OK if sending a new probe to this host is OK (to avoid
flooding). If when is non-NULL, fills it with the time that sending flooding). If when is non-NULL, fills it with the time that sending
@@ -775,9 +775,9 @@ unsigned long HostScanStats::probeTimeout() {
/* How long I'll wait until completely giving up on a probe. /* How long I'll wait until completely giving up on a probe.
Timedout probes are often marked as such (and sometimes Timedout probes are often marked as such (and sometimes
considered a drop), but kept in the list juts in case they come considered a drop), but kept in the list just in case they come
really late. But after probeExpire(), I don't waste time keeping really late. But after probeExpire(), I don't waste time keeping
them around. Givein in MICROseconds */ them around. Give in MICROseconds */
unsigned long HostScanStats::probeExpire() { unsigned long HostScanStats::probeExpire() {
if (USI->scantype == CONNECT_SCAN) if (USI->scantype == CONNECT_SCAN)
return probeTimeout(); /* timedout probes close socket -- late resp. impossible */ return probeTimeout(); /* timedout probes close socket -- late resp. impossible */

View File

@@ -1,6 +1,6 @@
/*************************************************************************** /***************************************************************************
* service_scan.h -- Routines used for service fingerprinting to determine * * service_scan.cc -- Routines used for service fingerprinting to determine *
* what application-level protocol is listening on a given port * * what application-level protocol is listening on a given port *
* (e.g. snmp, http, ftp, smtp, etc.) * * (e.g. snmp, http, ftp, smtp, etc.) *
* * * *
@@ -140,7 +140,7 @@ public:
~ServiceNFO(); ~ServiceNFO();
// If a service response to a given probeName, this function adds // If a service response to a given probeName, this function adds
// the resonse the the fingerprint for that service. The // the response the the fingerprint for that service. The
// fingerprint can be printed when nothing matches the service. You // fingerprint can be printed when nothing matches the service. You
// can obtain the fingerprint (if any) via getServiceFingerprint(); // can obtain the fingerprint (if any) via getServiceFingerprint();
void addToServiceFingerprint(const char *probeName, const u8 *resp, void addToServiceFingerprint(const char *probeName, const u8 *resp,
@@ -207,8 +207,8 @@ public:
private: private:
// Adds a character to servicefp. Takes care of word wrapping if // Adds a character to servicefp. Takes care of word wrapping if
// neccessary at the given (wrapat) column. Chars will only be // necessary at the given (wrapat) column. Chars will only be
// written if there is enough space. Oherwise it exits. // written if there is enough space. Otherwise it exits.
void addServiceChar(char c, int wrapat); void addServiceChar(char c, int wrapat);
// Like addServiceChar, but for a whole zero-terminated string // Like addServiceChar, but for a whole zero-terminated string
void addServiceString(char *s, int wrapat); void addServiceString(char *s, int wrapat);
@@ -974,7 +974,7 @@ void ServiceProbe::setPortVector(vector<u16> *portv, const char *portstr,
// SERVICE_TUNNEL_SSL. Otherwise use SERVICE_TUNNEL_NONE. The line // SERVICE_TUNNEL_SSL. Otherwise use SERVICE_TUNNEL_NONE. The line
// number is requested because this function will bail with an error // number is requested because this function will bail with an error
// (giving the line number) if it fails to parse the string. Ports // (giving the line number) if it fails to parse the string. Ports
// are a comma seperated list of prots and ranges // are a comma seperated list of ports and ranges
// (e.g. 53,80,6000-6010). // (e.g. 53,80,6000-6010).
void ServiceProbe::setProbablePorts(enum service_tunnel_type tunnel, void ServiceProbe::setProbablePorts(enum service_tunnel_type tunnel,
const char *portstr, int lineno) { const char *portstr, int lineno) {
@@ -1201,6 +1201,8 @@ int AllProbes::isExcluded(unsigned short port, int proto) {
unsigned short *p=NULL; unsigned short *p=NULL;
int count=-1,i; int count=-1,i;
if (!excludedports) return 0;
if (proto == IPPROTO_TCP) { if (proto == IPPROTO_TCP) {
p = excludedports->tcp_ports; p = excludedports->tcp_ports;
count = excludedports->tcp_count; count = excludedports->tcp_count;
@@ -1312,8 +1314,8 @@ ServiceNFO::~ServiceNFO() {
} }
// Adds a character to servicefp. Takes care of word wrapping if // Adds a character to servicefp. Takes care of word wrapping if
// neccessary at the given (wrapat) column. Chars will only be // necessary at the given (wrapat) column. Chars will only be
// written if there is enough space. Oherwise it exits. // written if there is enough space. Otherwise it exits.
void ServiceNFO::addServiceChar(char c, int wrapat) { void ServiceNFO::addServiceChar(char c, int wrapat) {
if (servicefpalloc - servicefplen < 6) if (servicefpalloc - servicefplen < 6)

View File

@@ -237,7 +237,7 @@ class ServiceProbe {
// obtains the probe string (in raw binary form) and the length. The string will be // obtains the probe string (in raw binary form) and the length. The string will be
// NUL-terminated, but there may be other \0 in the string, so the termination is only // NUL-terminated, but there may be other \0 in the string, so the termination is only
// done for easo of printing ASCII probes in debugging cases. // done for ease of printing ASCII probes in debugging cases.
const u8 *getProbeString(int *stringlen) { *stringlen = probestringlen; return probestring; } const u8 *getProbeString(int *stringlen) { *stringlen = probestringlen; return probestring; }
void setProbeString(const u8 *ps, int stringlen); void setProbeString(const u8 *ps, int stringlen);
@@ -254,7 +254,7 @@ class ServiceProbe {
// SERVICE_TUNNEL_SSL. Otherwise use SERVICE_TUNNEL_NONE. The line // SERVICE_TUNNEL_SSL. Otherwise use SERVICE_TUNNEL_NONE. The line
// number is requested because this function will bail with an error // number is requested because this function will bail with an error
// (giving the line number) if it fails to parse the string. Ports // (giving the line number) if it fails to parse the string. Ports
// are a comma seperated list of prots and ranges // are a comma seperated list of ports and ranges
// (e.g. 53,80,6000-6010). // (e.g. 53,80,6000-6010).
void setProbablePorts(enum service_tunnel_type tunnel, void setProbablePorts(enum service_tunnel_type tunnel,
const char *portstr, int lineno); const char *portstr, int lineno);

View File

@@ -1,6 +1,6 @@
/*************************************************************************** /***************************************************************************
* services.c -- Various functions relating to reading the nmap-services * * services.h -- Various functions relating to reading the nmap-services *
* file and port <-> service mapping * * file and port <-> service mapping *
* * * *
***********************IMPORTANT NMAP LICENSE TERMS************************ ***********************IMPORTANT NMAP LICENSE TERMS************************

View File

@@ -374,7 +374,7 @@ do {
hs->hostbatch[hidx]->deviceName()) != 0 hs->hostbatch[hidx]->deviceName()) != 0
|| hs->hostbatch[hidx]->directlyConnected() != hs->hostbatch[0]->directlyConnected())) { || hs->hostbatch[hidx]->directlyConnected() != hs->hostbatch[0]->directlyConnected())) {
/* Cancel everything! This guy must go in the next group and we are /* Cancel everything! This guy must go in the next group and we are
outtof here */ out of here */
hs->current_expression.return_last_host(); hs->current_expression.return_last_host();
delete hs->hostbatch[hidx]; delete hs->hostbatch[hidx];
goto batchfull; goto batchfull;
@@ -384,7 +384,7 @@ do {
if (hs->current_batch_sz < hs->max_batch_sz && if (hs->current_batch_sz < hs->max_batch_sz &&
hs->next_expression < hs->num_expressions) { hs->next_expression < hs->num_expressions) {
/* We are going to have to plop in another expression. */ /* We are going to have to pop in another expression. */
while(hs->current_expression.parse_expr(hs->target_expressions[hs->next_expression++], o.af()) != 0) while(hs->current_expression.parse_expr(hs->target_expressions[hs->next_expression++], o.af()) != 0)
if (hs->next_expression >= hs->num_expressions) if (hs->next_expression >= hs->num_expressions)
break; break;
@@ -1554,7 +1554,7 @@ int get_ping_results(int sd, pcap_t *pd, Target *hostbatch[], int pingtype,
if (newport && newportstate != PORT_UNKNOWN) { if (newport && newportstate != PORT_UNKNOWN) {
/* OK, we can add it, but that is only appropriate if this is one /* OK, we can add it, but that is only appropriate if this is one
of the ports the user ASKED for */ of the ports the user ASKED for */
/* This was for the old turbo mode -- which I no longer support now that ultra_scan() can handle parallel hosts. Maybe I'll brign it back someday */ /* This was for the old turbo mode -- which I no longer support now that ultra_scan() can handle parallel hosts. Maybe I'll bring it back someday */
/* /*
if (ports && ports->tcp_count == 1 && ports->tcp_ports[0] == newport) if (ports && ports->tcp_count == 1 && ports->tcp_ports[0] == newport)
hostbatch[hostnum]->ports.addPort(newport, IPPROTO_TCP, NULL, hostbatch[hostnum]->ports.addPort(newport, IPPROTO_TCP, NULL,
@@ -1812,7 +1812,7 @@ int dumpExclude(TargetGroup *exclude_group) {
exclude_group[i++].rewind(); exclude_group[i++].rewind();
} }
/* return debuggin to what it was */ /* return debugging to what it was */
o.debugging = debug_save; o.debugging = debug_save;
return 1; return 1;
} }

View File

@@ -110,7 +110,7 @@
#endif /* WIN32 */ #endif /* WIN32 */
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
/* This contains pretty much everythign we need ... */ /* This contains pretty much everything we need ... */
#if HAVE_SYS_TIME_H #if HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif #endif

View File

@@ -449,7 +449,7 @@ const char *ippackethdrinfo(const u8 *packet, u32 len) {
tcp = (struct tcphdr *) (packet + ip->ip_hl * 4); tcp = (struct tcphdr *) (packet + ip->ip_hl * 4);
if (frag_off > 8 || len < (u32) ip->ip_hl * 4 + 8) if (frag_off > 8 || len < (u32) ip->ip_hl * 4 + 8)
snprintf(protoinfo, sizeof(protoinfo), "TCP %s:?? > %s:?? ?? %s (incomplete)", srchost, dsthost, ipinfo); snprintf(protoinfo, sizeof(protoinfo), "TCP %s:?? > %s:?? ?? %s (incomplete)", srchost, dsthost, ipinfo);
else if (frag_off == 8 && len >= (u32) ip->ip_hl * 4 + 8) {// we can get TCP flags nad ACKn else if (frag_off == 8 && len >= (u32) ip->ip_hl * 4 + 8) {// we can get TCP flags and ACKn
tcp = (struct tcphdr *)((u8 *) tcp - frag_off); // ugly? tcp = (struct tcphdr *)((u8 *) tcp - frag_off); // ugly?
p = tflags; p = tflags;
/* These are basically in tcpdump order */ /* These are basically in tcpdump order */
@@ -1281,7 +1281,7 @@ u8 *build_udp_raw(struct in_addr *source, const struct in_addr *victim,
if (data) if (data)
memcpy(packet + sizeof(struct ip) + sizeof(udphdr_bsd), data, datalen); memcpy(packet + sizeof(struct ip) + sizeof(udphdr_bsd), data, datalen);
/* Now the psuedo header for checksuming */ /* Now the pseudo header for checksuming */
pseudo->source.s_addr = source->s_addr; pseudo->source.s_addr = source->s_addr;
pseudo->dest.s_addr = victim->s_addr; pseudo->dest.s_addr = victim->s_addr;
pseudo->proto = IPPROTO_UDP; pseudo->proto = IPPROTO_UDP;
@@ -1620,7 +1620,7 @@ if (timedout) {
return alignedbuf; return alignedbuf;
} }
// Returns whether the packet receive time value obtaned from libpcap // Returns whether the packet receive time value obtained from libpcap
// (and thus by readip_pcap()) should be considered valid. When // (and thus by readip_pcap()) should be considered valid. When
// invalid (Windows and Amiga), readip_pcap returns the time you called it. // invalid (Windows and Amiga), readip_pcap returns the time you called it.
bool pcap_recv_timeval_valid() { bool pcap_recv_timeval_valid() {
@@ -1633,7 +1633,7 @@ bool pcap_recv_timeval_valid() {
/* A trivial functon that maintains a cache of IP to MAC Address /* A trivial functon that maintains a cache of IP to MAC Address
entries. If the command is ARPCACHE_GEt, this func looks for the entries. If the command is ARPCACHE_GET, this func looks for the
IPv4 address in ss and fills in the 'mac' parameter and returns IPv4 address in ss and fills in the 'mac' parameter and returns
true if it is found. Otherwise (not found), the function returns true if it is found. Otherwise (not found), the function returns
false. If the command is ARPCACHE_SET, the function adds an entry false. If the command is ARPCACHE_SET, the function adds an entry
@@ -1932,7 +1932,7 @@ bool setTargetNextHopMAC(Target *target) {
if (target->ifType() != devt_ethernet) if (target->ifType() != devt_ethernet)
return false; /* Duh. */ return false; /* Duh. */
/* First check if we alread have it, duh. */ /* First check if we already have it, duh. */
if (target->NextHopMACAddress()) if (target->NextHopMACAddress())
return true; return true;
@@ -2226,8 +2226,8 @@ int sd;
printf("Size of struct ifreq: %d\n", sizeof(struct ifreq)); printf("Size of struct ifreq: %d\n", sizeof(struct ifreq));
#endif #endif
for(; ifr && *((u8 *)ifr) && ((u8 *)ifr) < buf + ifc.ifc_len; for(; ifr && ifr->ifr_name[0] && ((char *)ifr) < buf + ifc.ifc_len;
((*(char **)&ifr) += len )) { ifr = (struct ifreq *)(((char *)ifr) + len)) {
#if TCPIP_DEBUGGING #if TCPIP_DEBUGGING
printf("ifr_name size = %d\n", sizeof(ifr->ifr_name)); printf("ifr_name size = %d\n", sizeof(ifr->ifr_name));
printf("ifr = %X\n",(unsigned)(*(char **)&ifr)); printf("ifr = %X\n",(unsigned)(*(char **)&ifr));
@@ -2635,7 +2635,7 @@ void broadcast_socket(int sd) {
} }
} }
/* Do a receive (recv()) on a socket and stick the results (upt to /* Do a receive (recv()) on a socket and stick the results (up to
len) into buf . Give up after 'seconds'. Returns the number of len) into buf . Give up after 'seconds'. Returns the number of
bytes read (or -1 in the case of an error. It only does one recv bytes read (or -1 in the case of an error. It only does one recv
(it will not keep going until len bytes are read). If timedout is (it will not keep going until len bytes are read). If timedout is

View File

@@ -323,7 +323,7 @@ struct route_nfo {
struct interface_info ii; struct interface_info ii;
/* true if the target is directly connected on the network (no routing /* true if the target is directly connected on the network (no routing
required. */ required). */
bool direct_connect; bool direct_connect;
/* This is the source address that should be used by the packets. It /* This is the source address that should be used by the packets. It

View File

@@ -198,7 +198,7 @@ void adjust_timeouts2(const struct timeval *sent,
} */ } */
} }
/* Sleeps if necessary to ensure that it isn't called twice withen less /* Sleeps if necessary to ensure that it isn't called twice within less
time than o.send_delay. If it is passed a non-null tv, the POST-SLEEP time than o.send_delay. If it is passed a non-null tv, the POST-SLEEP
time is recorded in it */ time is recorded in it */
void enforce_scan_delay(struct timeval *tv) { void enforce_scan_delay(struct timeval *tv) {
@@ -253,7 +253,7 @@ ScanProgressMeter::~ScanProgressMeter() {
} }
/* Decides whether a timing report is likely to even be /* Decides whether a timing report is likely to even be
printed. There are stringint limitations on how often they are printed. There are stringent limitations on how often they are
printed, as well as the verbosity level that must exist. So you printed, as well as the verbosity level that must exist. So you
might as well check this before spending much time computing might as well check this before spending much time computing
progress info. now can be NULL if caller doesn't have the current progress info. now can be NULL if caller doesn't have the current

View File

@@ -124,7 +124,7 @@ void adjust_timeouts2(const struct timeval *sent,
void adjust_timeouts(struct timeval sent, struct timeout_info *to); void adjust_timeouts(struct timeval sent, struct timeout_info *to);
/* Sleeps if necessary to ensure that it isn't called twice withen less /* Sleeps if necessary to ensure that it isn't called twice within less
time than o.send_delay. If it is passed a non-null tv, the POST-SLEEP time than o.send_delay. If it is passed a non-null tv, the POST-SLEEP
time is recorded in it */ time is recorded in it */
void enforce_scan_delay(struct timeval *tv); void enforce_scan_delay(struct timeval *tv);
@@ -135,7 +135,7 @@ class ScanProgressMeter {
ScanProgressMeter(char *stypestr); ScanProgressMeter(char *stypestr);
~ScanProgressMeter(); ~ScanProgressMeter();
/* Decides whether a timing report is likely to even be /* Decides whether a timing report is likely to even be
printed. There are stringint limitations on how often they are printed. There are stringent limitations on how often they are
printed, as well as the verbosity level that must exist. So you printed, as well as the verbosity level that must exist. So you
might as well check this before spending much time computing might as well check this before spending much time computing
progress info. now can be NULL if caller doesn't have the current progress info. now can be NULL if caller doesn't have the current

View File

@@ -438,7 +438,7 @@ unsigned int gcd_n_uint(int nvals, unsigned int *val)
into an argv[] style char **, which it sets the argv parameter to. into an argv[] style char **, which it sets the argv parameter to.
The function returns the number of items filled up in the array The function returns the number of items filled up in the array
(argc), or -1 in the case of an error. This function allocates (argc), or -1 in the case of an error. This function allocates
memmory for argv and thus it must be freed -- use argv_parse_free() memory for argv and thus it must be freed -- use argv_parse_free()
for that. If arg_parse returns <1, then argv does not need to be freed. for that. If arg_parse returns <1, then argv does not need to be freed.
The returned arrays are always terminated with a NULL pointer */ The returned arrays are always terminated with a NULL pointer */
int arg_parse(const char *command, char ***argv) { int arg_parse(const char *command, char ***argv) {