diff --git a/idle_scan.cc b/idle_scan.cc index f01239426..0124fdb7e 100644 --- a/idle_scan.cc +++ b/idle_scan.cc @@ -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]); 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); if (ip) { 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) { 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); diff --git a/osscan2.cc b/osscan2.cc index 669466421..b67e69006 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -3347,7 +3347,7 @@ static void doSeqTests(OsScanInfo *OSI, HostOsScan *HOS) { if(o.debugging > 2) 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); @@ -3516,7 +3516,7 @@ static void doTUITests(OsScanInfo *OSI, HostOsScan *HOS) { if(o.debugging > 2) 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); diff --git a/scan_engine.cc b/scan_engine.cc index 45641e7e4..a05904367 100644 --- a/scan_engine.cc +++ b/scan_engine.cc @@ -4139,7 +4139,7 @@ static bool get_pcap_result(UltraScanInfo *USI, struct timeval *stime) { to_usec = TIMEVAL_SUBTRACT(*stime, USI->now); 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); if (!ip_tmp && TIMEVAL_SUBTRACT(*stime, USI->now) < 0) { timedout = true; @@ -4705,7 +4705,7 @@ static int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) { do { to_usec = TIMEVAL_SUBTRACT(*stime, USI->now); 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); gettimeofday(&USI->now, NULL); if (!ip_tmp) { diff --git a/tcpip.cc b/tcpip.cc index 0337d81a3..c8aa630a3 100644 --- a/tcpip.cc +++ b/tcpip.cc @@ -1458,220 +1458,25 @@ static bool validatepkt(u8 *ipc, unsigned *len) { linknfo->header will be filled with the appropriate values. */ /* Specifying true for validate will enable validity checks against the received IP packet. See validatepkt() for a list of checks. */ -char *readip_pcap(pcap_t *pd, unsigned int *len, long to_usec, - struct timeval *rcvdtime, struct link_header *linknfo, - bool validate) { - unsigned int offset = 0; - 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; +char *readipv4_pcap(pcap_t *pd, unsigned int *len, long to_usec, + struct timeval *rcvdtime, struct link_header *linknfo, + bool validate) { + char *buf; - if (linknfo) { - memset(linknfo, 0, sizeof(*linknfo)); - } + buf = readip_pcap(pd, len, to_usec, rcvdtime, linknfo, validate); + if (buf != NULL) { + struct ip *ip; - if (!pd) - fatal("NULL packet device passed to %s", __func__); - - 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; - } - 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) { - *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; + ip = (struct ip *) buf; + if (*len < 1 || ip->ip_v != 4) 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) - PacketTrace::trace(PacketTrace::RCVD, (u8 *) alignedbuf, *len, - rcvdtime); - else - PacketTrace::trace(PacketTrace::RCVD, (u8 *) alignedbuf, *len); - - return alignedbuf; + return buf; } -char *readip46_pcap(pcap_t *pd, unsigned int *len, long to_usec, - struct timeval *rcvdtime, struct link_header *linknfo, bool validate) { +char *readip_pcap(pcap_t *pd, unsigned int *len, long to_usec, + struct timeval *rcvdtime, struct link_header *linknfo, bool validate) { unsigned int offset = 0; struct pcap_pkthdr head; char *p; diff --git a/tcpip.h b/tcpip.h index b9223b434..aed4071fd 100644 --- a/tcpip.h +++ b/tcpip.h @@ -632,12 +632,12 @@ int get_link_offset(char *device); filled with the time that packet was captured from the wire by pcap. If linknfo is not NULL, lnknfo->headerlen and lnkinfo->header will be filled with the appropriate values. */ -char *readip_pcap(pcap_t *pd, unsigned int *len, long to_usec, - struct timeval *rcvdtime, struct link_header *linknfo, bool validate); - -char *readip46_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); +char *readip_pcap(pcap_t *pd, unsigned int *len, long to_usec, + struct timeval *rcvdtime, struct link_header *linknfo, bool validate); + /* Attempts to read one IPv4/Ethernet ARP reply packet from the pcap descriptor pd. If it receives one, fills in sendermac (must pass in 6 bytes), senderIP, and rcvdtime (can be NULL if you don't care) diff --git a/traceroute.cc b/traceroute.cc index 6655a3890..4f7b8fa81 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -1235,7 +1235,7 @@ static bool read_reply(Reply *reply, pcap_t *pd, long timeout) { unsigned int iplen; 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) return false; if (ip->ip_v == 4 || ip->ip_v == 6)