1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-18 13:39:02 +00:00

Rename readip_pcap -> readipv4_pcap and readip46_pcap to readip_pcap.

We should have the multiprotocol version be the main version, with
IPv4-only code being a noted exception. Also these functions are almost
the same so one can call the other.
This commit is contained in:
david
2011-06-08 23:46:21 +00:00
parent 97412e5522
commit 381bb03d70
6 changed files with 23 additions and 218 deletions

View File

@@ -189,7 +189,7 @@ static int ipid_proxy_probe(struct idle_proxy_info *proxy, int *probes_sent,
to_usec = proxy->host.to.timeout - TIMEVAL_SUBTRACT(tv_end, tv_sent[tries-1]); to_usec = proxy->host.to.timeout - TIMEVAL_SUBTRACT(tv_end, tv_sent[tries-1]);
if (to_usec < 0) to_usec = 0; // Final no-block poll if (to_usec < 0) to_usec = 0; // Final no-block poll
ip = (struct ip *) readip_pcap(proxy->pd, &bytes, to_usec, &rcvdtime, NULL, true); ip = (struct ip *) readipv4_pcap(proxy->pd, &bytes, to_usec, &rcvdtime, NULL, true);
gettimeofday(&tv_end, NULL); gettimeofday(&tv_end, NULL);
if (ip) { if (ip) {
if (bytes < ( 4 * ip->ip_hl) + 14U) if (bytes < ( 4 * ip->ip_hl) + 14U)
@@ -435,7 +435,7 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
while(probes_returned < probes_sent && !timedout) { while(probes_returned < probes_sent && !timedout) {
to_usec = (probes_sent == NUM_IPID_PROBES)? hardtimeout : 1000; to_usec = (probes_sent == NUM_IPID_PROBES)? hardtimeout : 1000;
ip = (struct ip *) readip_pcap(proxy->pd, &bytes, to_usec, &rcvdtime, NULL, true); ip = (struct ip *) readipv4_pcap(proxy->pd, &bytes, to_usec, &rcvdtime, NULL, true);
gettimeofday(&tmptv, NULL); gettimeofday(&tmptv, NULL);

View File

@@ -3347,7 +3347,7 @@ static void doSeqTests(OsScanInfo *OSI, HostOsScan *HOS) {
if(o.debugging > 2) if(o.debugging > 2)
log_write(LOG_PLAIN, "pcap wait time is %ld.\n", to_usec); log_write(LOG_PLAIN, "pcap wait time is %ld.\n", to_usec);
ip = (struct ip*) readip_pcap(HOS->pd, &bytes, to_usec, &rcvdtime, &linkhdr, true); ip = (struct ip*) readipv4_pcap(HOS->pd, &bytes, to_usec, &rcvdtime, &linkhdr, true);
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
@@ -3516,7 +3516,7 @@ static void doTUITests(OsScanInfo *OSI, HostOsScan *HOS) {
if(o.debugging > 2) if(o.debugging > 2)
log_write(LOG_PLAIN, "pcap wait time is %ld.\n", to_usec); log_write(LOG_PLAIN, "pcap wait time is %ld.\n", to_usec);
ip = (struct ip*) readip_pcap(HOS->pd, &bytes, to_usec, &rcvdtime, &linkhdr, true); ip = (struct ip*) readipv4_pcap(HOS->pd, &bytes, to_usec, &rcvdtime, &linkhdr, true);
gettimeofday(&now, NULL); gettimeofday(&now, NULL);

View File

@@ -4139,7 +4139,7 @@ static bool get_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
to_usec = TIMEVAL_SUBTRACT(*stime, USI->now); to_usec = TIMEVAL_SUBTRACT(*stime, USI->now);
if (to_usec < 2000) to_usec = 2000; if (to_usec < 2000) to_usec = 2000;
ip_tmp = (struct ip *) readip46_pcap(USI->pd, &bytes, to_usec, &rcvdtime, &linkhdr, true); ip_tmp = (struct ip *) readip_pcap(USI->pd, &bytes, to_usec, &rcvdtime, &linkhdr, true);
gettimeofday(&USI->now, NULL); gettimeofday(&USI->now, NULL);
if (!ip_tmp && TIMEVAL_SUBTRACT(*stime, USI->now) < 0) { if (!ip_tmp && TIMEVAL_SUBTRACT(*stime, USI->now) < 0) {
timedout = true; timedout = true;
@@ -4705,7 +4705,7 @@ static int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
do { do {
to_usec = TIMEVAL_SUBTRACT(*stime, USI->now); to_usec = TIMEVAL_SUBTRACT(*stime, USI->now);
if (to_usec < 2000) to_usec = 2000; if (to_usec < 2000) to_usec = 2000;
ip_tmp = (struct ip *) readip46_pcap(USI->pd, &bytes, to_usec, &rcvdtime, ip_tmp = (struct ip *) readip_pcap(USI->pd, &bytes, to_usec, &rcvdtime,
&linkhdr, true); &linkhdr, true);
gettimeofday(&USI->now, NULL); gettimeofday(&USI->now, NULL);
if (!ip_tmp) { if (!ip_tmp) {

213
tcpip.cc
View File

@@ -1458,219 +1458,24 @@ static bool validatepkt(u8 *ipc, unsigned *len) {
linknfo->header will be filled with the appropriate values. */ linknfo->header will be filled with the appropriate values. */
/* Specifying true for validate will enable validity checks against the /* Specifying true for validate will enable validity checks against the
received IP packet. See validatepkt() for a list of checks. */ received IP packet. See validatepkt() for a list of checks. */
char *readip_pcap(pcap_t *pd, unsigned int *len, long to_usec, char *readipv4_pcap(pcap_t *pd, unsigned int *len, long to_usec,
struct timeval *rcvdtime, struct link_header *linknfo, struct timeval *rcvdtime, struct link_header *linknfo,
bool validate) { bool validate) {
unsigned int offset = 0; char *buf;
struct pcap_pkthdr head;
char *p;
int datalink;
int timedout = 0;
struct timeval tv_start, tv_end;
static char *alignedbuf = NULL;
static unsigned int alignedbufsz = 0;
static int warning = 0;
if (linknfo) { buf = readip_pcap(pd, len, to_usec, rcvdtime, linknfo, validate);
memset(linknfo, 0, sizeof(*linknfo)); if (buf != NULL) {
} struct ip *ip;
if (!pd) ip = (struct ip *) buf;
fatal("NULL packet device passed to %s", __func__); if (*len < 1 || ip->ip_v != 4)
if (to_usec < 0) {
if (!warning) {
warning = 1;
error("WARNING: Negative timeout value (%lu) passed to %s() -- using 0", to_usec, __func__);
}
to_usec = 0;
}
/* New packet capture device, need to recompute offset */
if ((datalink = pcap_datalink(pd)) < 0)
fatal("Cannot obtain datalink information: %s", pcap_geterr(pd));
/* NOTE: IF A NEW OFFSET EVER EXCEEDS THE CURRENT MAX (24), ADJUST
MAX_LINK_HEADERSZ in tcpip.h */
switch (datalink) {
case DLT_EN10MB:
offset = 14;
break;
case DLT_IEEE802:
offset = 22;
break;
#ifdef __amigaos__
case DLT_MIAMI:
offset = 16;
break;
#endif
#ifdef DLT_LOOP
case DLT_LOOP:
#endif
case DLT_NULL:
offset = 4;
break;
case DLT_SLIP:
#ifdef DLT_SLIP_BSDOS
case DLT_SLIP_BSDOS:
#endif
#if (FREEBSD || OPENBSD || NETBSD || BSDI || MACOSX)
offset = 16;
#else
offset = 24; /* Anyone use this??? */
#endif
break;
case DLT_PPP:
#ifdef DLT_PPP_BSDOS
case DLT_PPP_BSDOS:
#endif
#ifdef DLT_PPP_SERIAL
case DLT_PPP_SERIAL:
#endif
#ifdef DLT_PPP_ETHER
case DLT_PPP_ETHER:
#endif
#if (FREEBSD || OPENBSD || NETBSD || BSDI || MACOSX)
offset = 4;
#else
#ifdef SOLARIS
offset = 8;
#else
offset = 24; /* Anyone use this? */
#endif /* ifdef solaris */
#endif /* if freebsd || openbsd || netbsd || bsdi */
break;
case DLT_RAW:
offset = 0;
break;
case DLT_FDDI:
offset = 21;
break;
#ifdef DLT_ENC
case DLT_ENC:
offset = 12;
break;
#endif /* DLT_ENC */
#ifdef DLT_LINUX_SLL
case DLT_LINUX_SLL:
offset = 16;
break;
#endif
default:
p = (char *) pcap_next(pd, &head);
if (head.caplen == 0) {
/* Lets sleep a brief time and try again to increase the chance of seeing
a real packet ... */
usleep(500000);
p = (char *) pcap_next(pd, &head);
}
if (head.caplen > 100000) {
fatal("FATAL: %s: bogus caplen from libpcap (%d) on interface type %d", __func__, head.caplen, datalink);
}
error("FATAL: Unknown datalink type (%d). Caplen: %d; Packet:", datalink, head.caplen);
nmap_hexdump((unsigned char *) p, head.caplen);
exit(1);
}
if (to_usec > 0) {
gettimeofday(&tv_start, NULL);
}
do {
#ifdef WIN32
long to_left;
if (to_usec > 0) {
gettimeofday(&tv_end, NULL);
to_left = MAX(1, (to_usec - TIMEVAL_SUBTRACT(tv_end, tv_start)) / 1000);
} else {
to_left = 1;
}
// Set the timeout (BUGBUG: this is cheating)
PacketSetReadTimeout(pd->adapter, to_left);
#endif
p = NULL;
if (pcap_select(pd, to_usec) == 0)
timedout = 1;
else
p = (char *) pcap_next(pd, &head);
if (p) {
if (head.caplen <= offset) {
*len = 0;
return NULL; return NULL;
} }
if (offset && linknfo) {
linknfo->datalinktype = datalink;
linknfo->headerlen = offset;
assert(offset < MAX_LINK_HEADERSZ);
memcpy(linknfo->header, p, MIN(sizeof(linknfo->header), offset));
}
p += offset;
}
if (!p) {
/* Should we timeout? */
if (to_usec == 0) {
timedout = 1;
} else if (to_usec > 0) {
gettimeofday(&tv_end, NULL);
if (TIMEVAL_SUBTRACT(tv_end, tv_start) >= to_usec) {
timedout = 1;
}
}
}
} while (!timedout && (!p));
if (timedout) { return buf;
*len = 0;
return NULL;
}
*len = head.caplen - offset;
if (*len > alignedbufsz) {
alignedbuf = (char *) safe_realloc(alignedbuf, *len);
alignedbufsz = *len;
}
memcpy(alignedbuf, p, *len);
if (validate) {
const struct ip *ip = (struct ip *) alignedbuf;
/* Let's see if this packet passes inspection.. */
if (!validatepkt((u8 *) alignedbuf, len) || ip->ip_v != 4) {
*len = 0;
return NULL;
}
}
// printf("Just got a packet at %li,%li\n", head.ts.tv_sec, head.ts.tv_usec);
if (rcvdtime) {
// FIXME: I eventually need to figure out why Windows head.ts time is sometimes BEFORE the time I
// sent the packet (which is according to gettimeofday() in nbase). For now, I will sadly have to
// use gettimeofday() for Windows in this case
// Actually I now allow .05 discrepancy. So maybe this isn't needed. I'll comment out for now.
// Nope: it is still needed at least for Windows. Sometimes the time from he pcap header is a
// COUPLE SECONDS before the gettimeofday() results :(.
#if defined(WIN32) || defined(__amigaos__)
gettimeofday(&tv_end, NULL);
*rcvdtime = tv_end;
#else
rcvdtime->tv_sec = head.ts.tv_sec;
rcvdtime->tv_usec = head.ts.tv_usec;
assert(head.ts.tv_sec);
#endif
} }
if (rcvdtime) char *readip_pcap(pcap_t *pd, unsigned int *len, long to_usec,
PacketTrace::trace(PacketTrace::RCVD, (u8 *) alignedbuf, *len,
rcvdtime);
else
PacketTrace::trace(PacketTrace::RCVD, (u8 *) alignedbuf, *len);
return alignedbuf;
}
char *readip46_pcap(pcap_t *pd, unsigned int *len, long to_usec,
struct timeval *rcvdtime, struct link_header *linknfo, bool validate) { struct timeval *rcvdtime, struct link_header *linknfo, bool validate) {
unsigned int offset = 0; unsigned int offset = 0;
struct pcap_pkthdr head; struct pcap_pkthdr head;

View File

@@ -632,10 +632,10 @@ int get_link_offset(char *device);
filled with the time that packet was captured from the wire by filled with the time that packet was captured from the wire by
pcap. If linknfo is not NULL, lnknfo->headerlen and pcap. If linknfo is not NULL, lnknfo->headerlen and
lnkinfo->header will be filled with the appropriate values. */ lnkinfo->header will be filled with the appropriate values. */
char *readip_pcap(pcap_t *pd, unsigned int *len, long to_usec, char *readipv4_pcap(pcap_t *pd, unsigned int *len, long to_usec,
struct timeval *rcvdtime, struct link_header *linknfo, bool validate); struct timeval *rcvdtime, struct link_header *linknfo, bool validate);
char *readip46_pcap(pcap_t *pd, unsigned int *len, long to_usec, char *readip_pcap(pcap_t *pd, unsigned int *len, long to_usec,
struct timeval *rcvdtime, struct link_header *linknfo, bool validate); struct timeval *rcvdtime, struct link_header *linknfo, bool validate);
/* Attempts to read one IPv4/Ethernet ARP reply packet from the pcap /* Attempts to read one IPv4/Ethernet ARP reply packet from the pcap

View File

@@ -1235,7 +1235,7 @@ static bool read_reply(Reply *reply, pcap_t *pd, long timeout) {
unsigned int iplen; unsigned int iplen;
struct link_header linkhdr; struct link_header linkhdr;
ip = (struct ip *) readip46_pcap(pd, &iplen, timeout, &reply->rcvdtime, &linkhdr, true); ip = (struct ip *) readip_pcap(pd, &iplen, timeout, &reply->rcvdtime, &linkhdr, true);
if (ip == NULL) if (ip == NULL)
return false; return false;
if (ip->ip_v == 4 || ip->ip_v == 6) if (ip->ip_v == 4 || ip->ip_v == 6)