1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-23 07:59:03 +00:00

make a ton of global symbols static

This commit is contained in:
fyodor
2006-03-05 23:59:46 +00:00
parent 7224f4a52d
commit 76ab1500b3
25 changed files with 2982 additions and 3194 deletions

473
tcpip.cc
View File

@@ -256,156 +256,13 @@ void PacketTrace::traceArp(pdirection pdir, const u8 *frame, u32 len,
return;
}
/* Takes an IP PACKET and prints it if packet tracing is enabled.
'packet' must point to the IPv4 header. The direction must be
PacketTrace::SENT or PacketTrace::RCVD . Optional 'now' argument
makes this function slightly more efficient by avoiding a gettimeofday()
call. */
void PacketTrace::trace(pdirection pdir, const u8 *packet, u32 len,
struct timeval *now) {
struct timeval tv;
if (pdir == SENT) {
PktCt.sendPackets++;
PktCt.sendBytes += len;
} else {
PktCt.recvPackets++;
PktCt.recvBytes += len;
}
if (!o.packetTrace()) return;
if (now)
tv = *now;
else gettimeofday(&tv, NULL);
if (len < 20) {
error("Packet tracer: tiny packet encountered");
return;
}
log_write(LOG_STDOUT|LOG_NORMAL, "%s (%.4fs) %s\n", (pdir == SENT)? "SENT" : "RCVD", o.TimeSinceStartMS(&tv) / 1000.0, ippackethdrinfo(packet, len));
return;
}
/* Adds a trace entry when a connect() is attempted if packet tracing
is enabled. Pass IPPROTO_TCP or IPPROTO_UDP as the protocol. The
sock may be a sockaddr_in or sockaddr_in6. The return code of
connect is passed in connectrc. If the return code is -1, get the
errno and pass that as connect_errno. */
void PacketTrace::traceConnect(u8 proto, const struct sockaddr *sock,
int socklen, int connectrc, int connect_errno,
const struct timeval *now) {
struct sockaddr_in *sin = (struct sockaddr_in *) sock;
#if HAVE_IPV6
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sock;
#endif
struct timeval tv;
char errbuf[64] = "";
char targetipstr[INET6_ADDRSTRLEN] = "";
u16 targetport = 0;
if (!o.packetTrace()) return;
if (now)
tv = *now;
else gettimeofday(&tv, NULL);
assert(proto == IPPROTO_TCP || proto == IPPROTO_UDP);
if (connectrc == 0)
Strncpy(errbuf, "Connected", sizeof(errbuf));
else {
snprintf(errbuf, sizeof(errbuf), "%s", strerror(connect_errno));
}
if (sin->sin_family == AF_INET) {
if (inet_ntop(sin->sin_family, (char *) &sin->sin_addr, targetipstr,
sizeof(targetipstr)) == NULL)
fatal("Failed to convert target IPv4 address to presentation format!?!");
targetport = ntohs(sin->sin_port);
} else {
#if HAVE_IPV6
assert(sin->sin_family == AF_INET6);
if (inet_ntop(sin->sin_family, (char *) &sin6->sin6_addr, targetipstr,
sizeof(targetipstr)) == NULL)
fatal("Failed to convert target IPv4 address to presentation format!?!");
targetport = ntohs(sin6->sin6_port);
#else
assert(0);
#endif
}
log_write(LOG_STDOUT|LOG_NORMAL, "CONN (%.4fs) %s localhost > %s:%d => %s\n",
o.TimeSinceStartMS(&tv) / 1000.0,
(proto == IPPROTO_TCP)? "TCP" : "UDP", targetipstr, targetport,
errbuf);
}
/* Converts an IP address given in a sockaddr_storage to an IPv4 or
IPv6 IP address string. Since a static buffer is returned, this is
not thread-safe and can only be used once in calls like printf()
*/
const char *inet_socktop(struct sockaddr_storage *ss) {
static char buf[INET6_ADDRSTRLEN];
struct sockaddr_in *sin = (struct sockaddr_in *) ss;
#if HAVE_IPV6
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) ss;
#endif
if (inet_ntop(sin->sin_family, (sin->sin_family == AF_INET)?
(char *) &sin->sin_addr :
#if HAVE_IPV6
(char *) &sin6->sin6_addr,
#else
(char *) NULL,
#endif /* HAVE_IPV6 */
buf, sizeof(buf)) == NULL) {
fatal("Failed to convert target address to presentation format in inet_socktop!?! Error: %s", strerror(socket_errno()));
}
return buf;
}
/* Tries to resolve the given name (or literal IP) into a sockaddr
structure. The af should be PF_INET (for IPv4) or PF_INET6. Returns 0
if hostname cannot be resolved. It is OK to pass in a sockaddr_in or
sockaddr_in6 casted to a sockaddr_storage as long as you use the matching
pf.*/
int resolve(char *hostname, struct sockaddr_storage *ss, size_t *sslen,
int pf) {
struct addrinfo hints;
struct addrinfo *result;
int rc;
assert(ss);
assert(sslen);
memset(&hints, 0, sizeof(hints));
hints.ai_family = pf;
rc = getaddrinfo(hostname, NULL, &hints, &result);
if (rc != 0)
return 0;
assert(result->ai_addrlen > 0 && result->ai_addrlen <= (int) sizeof(struct sockaddr_storage));
*sslen = result->ai_addrlen;
memcpy(ss, result->ai_addr, *sslen);
freeaddrinfo(result);
return 1;
}
/* Returns a buffer of ASCII information about a packet that may look
like "TCP 127.0.0.1:50923 > 127.0.0.1:3 S ttl=61 id=39516 iplen=40
seq=625950769" or "ICMP PING (0/1) ttl=61 id=39516 iplen=40".
Since this is a static buffer, don't use threads or call twice
within (say) printf(). And certainly don't try to free() it! The
returned buffer is NUL-terminated */
const char *ippackethdrinfo(const u8 *packet, u32 len) {
static const char *ippackethdrinfo(const u8 *packet, u32 len) {
static char protoinfo[256];
struct ip *ip = (struct ip *) packet;
struct tcphdr *tcp;
@@ -619,6 +476,148 @@ const char *ippackethdrinfo(const u8 *packet, u32 len) {
return protoinfo;
}
/* Takes an IP PACKET and prints it if packet tracing is enabled.
'packet' must point to the IPv4 header. The direction must be
PacketTrace::SENT or PacketTrace::RCVD . Optional 'now' argument
makes this function slightly more efficient by avoiding a gettimeofday()
call. */
void PacketTrace::trace(pdirection pdir, const u8 *packet, u32 len,
struct timeval *now) {
struct timeval tv;
if (pdir == SENT) {
PktCt.sendPackets++;
PktCt.sendBytes += len;
} else {
PktCt.recvPackets++;
PktCt.recvBytes += len;
}
if (!o.packetTrace()) return;
if (now)
tv = *now;
else gettimeofday(&tv, NULL);
if (len < 20) {
error("Packet tracer: tiny packet encountered");
return;
}
log_write(LOG_STDOUT|LOG_NORMAL, "%s (%.4fs) %s\n", (pdir == SENT)? "SENT" : "RCVD", o.TimeSinceStartMS(&tv) / 1000.0, ippackethdrinfo(packet, len));
return;
}
/* Adds a trace entry when a connect() is attempted if packet tracing
is enabled. Pass IPPROTO_TCP or IPPROTO_UDP as the protocol. The
sock may be a sockaddr_in or sockaddr_in6. The return code of
connect is passed in connectrc. If the return code is -1, get the
errno and pass that as connect_errno. */
void PacketTrace::traceConnect(u8 proto, const struct sockaddr *sock,
int socklen, int connectrc, int connect_errno,
const struct timeval *now) {
struct sockaddr_in *sin = (struct sockaddr_in *) sock;
#if HAVE_IPV6
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sock;
#endif
struct timeval tv;
char errbuf[64] = "";
char targetipstr[INET6_ADDRSTRLEN] = "";
u16 targetport = 0;
if (!o.packetTrace()) return;
if (now)
tv = *now;
else gettimeofday(&tv, NULL);
assert(proto == IPPROTO_TCP || proto == IPPROTO_UDP);
if (connectrc == 0)
Strncpy(errbuf, "Connected", sizeof(errbuf));
else {
snprintf(errbuf, sizeof(errbuf), "%s", strerror(connect_errno));
}
if (sin->sin_family == AF_INET) {
if (inet_ntop(sin->sin_family, (char *) &sin->sin_addr, targetipstr,
sizeof(targetipstr)) == NULL)
fatal("Failed to convert target IPv4 address to presentation format!?!");
targetport = ntohs(sin->sin_port);
} else {
#if HAVE_IPV6
assert(sin->sin_family == AF_INET6);
if (inet_ntop(sin->sin_family, (char *) &sin6->sin6_addr, targetipstr,
sizeof(targetipstr)) == NULL)
fatal("Failed to convert target IPv4 address to presentation format!?!");
targetport = ntohs(sin6->sin6_port);
#else
assert(0);
#endif
}
log_write(LOG_STDOUT|LOG_NORMAL, "CONN (%.4fs) %s localhost > %s:%d => %s\n",
o.TimeSinceStartMS(&tv) / 1000.0,
(proto == IPPROTO_TCP)? "TCP" : "UDP", targetipstr, targetport,
errbuf);
}
/* Converts an IP address given in a sockaddr_storage to an IPv4 or
IPv6 IP address string. Since a static buffer is returned, this is
not thread-safe and can only be used once in calls like printf()
*/
const char *inet_socktop(struct sockaddr_storage *ss) {
static char buf[INET6_ADDRSTRLEN];
struct sockaddr_in *sin = (struct sockaddr_in *) ss;
#if HAVE_IPV6
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) ss;
#endif
if (inet_ntop(sin->sin_family, (sin->sin_family == AF_INET)?
(char *) &sin->sin_addr :
#if HAVE_IPV6
(char *) &sin6->sin6_addr,
#else
(char *) NULL,
#endif /* HAVE_IPV6 */
buf, sizeof(buf)) == NULL) {
fatal("Failed to convert target address to presentation format in inet_socktop!?! Error: %s", strerror(socket_errno()));
}
return buf;
}
/* Tries to resolve the given name (or literal IP) into a sockaddr
structure. The af should be PF_INET (for IPv4) or PF_INET6. Returns 0
if hostname cannot be resolved. It is OK to pass in a sockaddr_in or
sockaddr_in6 casted to a sockaddr_storage as long as you use the matching
pf.*/
int resolve(char *hostname, struct sockaddr_storage *ss, size_t *sslen,
int pf) {
struct addrinfo hints;
struct addrinfo *result;
int rc;
assert(ss);
assert(sslen);
memset(&hints, 0, sizeof(hints));
hints.ai_family = pf;
rc = getaddrinfo(hostname, NULL, &hints, &result);
if (rc != 0)
return 0;
assert(result->ai_addrlen > 0 && result->ai_addrlen <= (int) sizeof(struct sockaddr_storage));
*sslen = result->ai_addrlen;
memcpy(ss, result->ai_addr, *sslen);
freeaddrinfo(result);
return 1;
}
int islocalhost(const struct in_addr * const addr) {
char dev[128];
@@ -937,6 +936,87 @@ int send_tcp_raw( int sd, struct eth_nfo *eth, const struct in_addr *source,
return res;
}
/* Create and send all fragments of a pre-built IPv4 packet
* Minimal MTU for IPv4 is 68 and maximal IPv4 header size is 60
* which gives us a right to cut TCP header after 8th byte
* (shouldn't we inflate the header to 60 bytes too?) */
int send_frag_ip_packet(int sd, struct eth_nfo *eth, u8 *packet,
unsigned int packetlen, unsigned int mtu)
{
struct ip *ip = (struct ip *) packet;
int headerlen = ip->ip_hl * 4; // better than sizeof(struct ip)
unsigned int datalen = packetlen - headerlen;
int fdatalen = 0, res = 0;
assert(headerlen <= (int) packetlen);
assert(headerlen >= 20 && headerlen <= 60); // sanity check (RFC791)
assert(mtu > 0 && mtu % 8 == 0); // otherwise, we couldn't set Fragment offset (ip->ip_off) correctly
if (datalen <= mtu) {
error("Warning: fragmentation (mtu=%i) requested but the payload is too small already (%i)", mtu, datalen);
return send_ip_packet(sd, eth, packet, packetlen);
}
u8 *fpacket = (u8 *) safe_malloc(headerlen + mtu);
memcpy(fpacket, packet, headerlen + mtu);
ip = (struct ip *) fpacket;
// create fragments and send them
for (int fragment = 1; fragment * mtu < datalen + mtu; fragment++) {
fdatalen = (fragment * mtu <= datalen ? mtu : datalen % mtu);
ip->ip_len = htons(headerlen + fdatalen);
ip->ip_off = htons((fragment-1) * mtu / 8);
if ((fragment-1) * mtu + fdatalen < datalen)
ip->ip_off |= htons(IP_MF);
#if HAVE_IP_IP_SUM
ip->ip_sum = in_cksum((unsigned short *)ip, headerlen);
#endif
if (fragment > 1) // copy data payload
memcpy(fpacket + headerlen, packet + headerlen + (fragment - 1) * mtu, fdatalen);
res = send_ip_packet(sd, eth, fpacket, headerlen + fdatalen);
if (res == -1)
break;
}
free(fpacket);
return res;
}
static int Sendto(char *functionname, int sd, const unsigned char *packet,
int len, unsigned int flags, struct sockaddr *to, int tolen) {
struct sockaddr_in *sin = (struct sockaddr_in *) to;
int res;
int retries = 0;
int sleeptime = 0;
do {
if ((res = sendto(sd, (const char *) packet, len, flags, to, tolen)) == -1) {
int err = socket_errno();
error("sendto in %s: sendto(%d, packet, %d, 0, %s, %d) => %s",
functionname, sd, len, inet_ntoa(sin->sin_addr), tolen,
strerror(err));
#if WIN32
return -1;
#else
if (retries > 2 || err == EPERM || err == EACCES || err == EADDRNOTAVAIL
|| err == EINVAL)
return -1;
sleeptime = 15 * (1 << (2 * retries));
error("Sleeping %d seconds then retrying", sleeptime);
fflush(stderr);
sleep(sleeptime);
#endif
}
retries++;
} while( res == -1);
PacketTrace::trace(PacketTrace::SENT, packet, len);
return res;
}
/* Send a pre-built IPv4 packet */
int send_ip_packet(int sd, struct eth_nfo *eth, u8 *packet, unsigned int packetlen) {
struct sockaddr_in sock;
@@ -1007,53 +1087,6 @@ int send_ip_packet(int sd, struct eth_nfo *eth, u8 *packet, unsigned int packetl
return res;
}
/* Create and send all fragments of a pre-built IPv4 packet
* Minimal MTU for IPv4 is 68 and maximal IPv4 header size is 60
* which gives us a right to cut TCP header after 8th byte
* (shouldn't we inflate the header to 60 bytes too?) */
int send_frag_ip_packet(int sd, struct eth_nfo *eth, u8 *packet,
unsigned int packetlen, unsigned int mtu)
{
struct ip *ip = (struct ip *) packet;
int headerlen = ip->ip_hl * 4; // better than sizeof(struct ip)
unsigned int datalen = packetlen - headerlen;
int fdatalen = 0, res = 0;
assert(headerlen <= (int) packetlen);
assert(headerlen >= 20 && headerlen <= 60); // sanity check (RFC791)
assert(mtu > 0 && mtu % 8 == 0); // otherwise, we couldn't set Fragment offset (ip->ip_off) correctly
if (datalen <= mtu) {
error("Warning: fragmentation (mtu=%i) requested but the payload is too small already (%i)", mtu, datalen);
return send_ip_packet(sd, eth, packet, packetlen);
}
u8 *fpacket = (u8 *) safe_malloc(headerlen + mtu);
memcpy(fpacket, packet, headerlen + mtu);
ip = (struct ip *) fpacket;
// create fragments and send them
for (int fragment = 1; fragment * mtu < datalen + mtu; fragment++) {
fdatalen = (fragment * mtu <= datalen ? mtu : datalen % mtu);
ip->ip_len = htons(headerlen + fdatalen);
ip->ip_off = htons((fragment-1) * mtu / 8);
if ((fragment-1) * mtu + fdatalen < datalen)
ip->ip_off |= htons(IP_MF);
#if HAVE_IP_IP_SUM
ip->ip_sum = in_cksum((unsigned short *)ip, headerlen);
#endif
if (fragment > 1) // copy data payload
memcpy(fpacket + headerlen, packet + headerlen + (fragment - 1) * mtu, fdatalen);
res = send_ip_packet(sd, eth, fpacket, headerlen + fdatalen);
if (res == -1)
break;
}
free(fpacket);
return res;
}
/* Builds an ICMP packet (including an IP header) by packing the fields
with the given information. It allocates a new buffer to store the
packet contents, and then returns that buffer. The packet is not
@@ -1113,19 +1146,6 @@ return build_ip_raw(source, victim, o.ttl, IPPROTO_ICMP, get_random_u16(),
ping, icmplen, packetlen);
}
void readippacket(const u8 *packet, int readdata) {
struct ip *ip = (struct ip *) packet;
switch(ip->ip_p) {
case IPPROTO_UDP:
readudppacket(packet, readdata);
break;
/* Should add ICMP here at some point */
default:
readtcppacket(packet, readdata);
break;
}
}
/* A simple function I wrote to help in debugging, shows the important fields
of a TCP packet*/
@@ -1659,7 +1679,9 @@ bool pcap_recv_timeval_valid() {
with the given ip (ss) and mac address. An existing entry for the
IP ss will be overwritten with the new MAC address. true is always
returned for the set command. */
bool NmapArpCache(int command, struct sockaddr_storage *ss, u8 *mac) {
#define ARPCACHE_GET 1
#define ARPCACHE_SET 2
static bool NmapArpCache(int command, struct sockaddr_storage *ss, u8 *mac) {
struct sockaddr_in *sin = (struct sockaddr_in *) ss;
struct ArpCache {
u32 ip; /* Network byte order */
@@ -1856,7 +1878,7 @@ int setTargetMACIfAvailable(Target *target, struct link_header *linkhdr,
broadcast MAC address. The transmission is attempted up to 3
times. If none of these elicit a response, false will be returned.
If the mac is determined, true is returned. */
bool doArp(const char *dev, const u8 *srcmac,
static bool doArp(const char *dev, const u8 *srcmac,
const struct sockaddr_storage *srcip,
const struct sockaddr_storage *targetip, u8 *targetmac) {
/* timeouts in microseconds ... the first ones are retransmit times, while
@@ -2084,7 +2106,7 @@ struct dnet_collector_route_nfo {
int numifaces;
};
int collect_dnet_routes(const struct route_entry *entry, void *arg) {
static int collect_dnet_routes(const struct route_entry *entry, void *arg) {
struct dnet_collector_route_nfo *dcrn = (struct dnet_collector_route_nfo *) arg;
int i;
@@ -2122,7 +2144,7 @@ int collect_dnet_routes(const struct route_entry *entry, void *arg) {
return 0;
}
int collect_dnet_interfaces(const struct intf_entry *entry, void *arg) {
static int collect_dnet_interfaces(const struct intf_entry *entry, void *arg) {
struct dnet_collector_route_nfo *dcrn = (struct dnet_collector_route_nfo *) arg;
int i;
int numifaces = dcrn->numifaces;
@@ -2840,41 +2862,6 @@ if (echots) *echots = 0;
return 0;
}
int Sendto(char *functionname, int sd, const unsigned char *packet, int len,
unsigned int flags, struct sockaddr *to, int tolen) {
struct sockaddr_in *sin = (struct sockaddr_in *) to;
int res;
int retries = 0;
int sleeptime = 0;
do {
if ((res = sendto(sd, (const char *) packet, len, flags, to, tolen)) == -1) {
int err = socket_errno();
error("sendto in %s: sendto(%d, packet, %d, 0, %s, %d) => %s",
functionname, sd, len, inet_ntoa(sin->sin_addr), tolen,
strerror(err));
#if WIN32
return -1;
#else
if (retries > 2 || err == EPERM || err == EACCES || err == EADDRNOTAVAIL
|| err == EINVAL)
return -1;
sleeptime = 15 * (1 << (2 * retries));
error("Sleeping %d seconds then retrying", sleeptime);
fflush(stderr);
sleep(sleeptime);
#endif
}
retries++;
} while( res == -1);
PacketTrace::trace(PacketTrace::SENT, packet, len);
return res;
}
IPProbe::IPProbe() {
packetbuflen = 0;
packetbuf = NULL;