Nmap Security Scanner
*Intro
*Ref Guide
*Install Guide
*Download
*Changelog
*Book
*Docs
Security Lists
*Nmap Hackers
*Nmap Dev
*Bugtraq
*Full Disclosure
*Pen Test
*Basics
*More
Security Tools
*Pass crackers
*Sniffers
*Vuln Scanners
*Web scanners
*Wireless
*Exploitation
*Packet crafters
*More
Site News
Site Search:
Exploit World
Advertising
About/Contact
Credits
Sponsors:
edgeos



Nmap Development: [PATCH] Consolidate select()ing pcap fd code in tcpip.cc

[PATCH] Consolidate select()ing pcap fd code in tcpip.cc

From: Kris Katterjohn <katterjohn_at_gmail.com>
Date: Wed, 20 Dec 2006 18:20:32 -0600

The attached patch removes redundant code when select()ing file
descriptor's from my_pcap_get_selectable_fd() in tcpip.cc. I wrote the
two separate functions because (I suppose) the time will come when it
could be used when a struct timeval is all ready handy. If you don't
like it, it won't be much trouble at all to copy the timeval stuff and
drop the second function.

I tested a bit and didn't run into any problems with it.

It's a diff against 4.21ALPHA1

Thanks,
Kris Katterjohn

--- x/tcpip.cc 2006-12-07 21:01:19.000000000 -0600
+++ y/tcpip.cc 2006-12-19 21:30:30.000000000 -0600
@@ -1740,6 +1740,39 @@ fcntl(sd, F_SETFL, options);
 return 1;
 }
 
+/* returns -1 if we can't use select() on the pcap device, 0 for timeout, and
+ * >0 for success. If select() fails we bail out because it couldn't work with
+ * the file descriptor we got from my_pcap_get_selectable_fd()
+ */
+int pcap_select(pcap_t *p, struct timeval *timeout)
+{
+ int fd, ret;
+ fd_set rfds;
+
+ if ((fd = my_pcap_get_selectable_fd(p)) == -1)
+ return -1;
+
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+
+ ret = select(fd + 1, &rfds, NULL, NULL, timeout);
+
+ if (ret == -1)
+ fatal("Your system does not support select()ing on pcap devices (%s). PLEASE REPORT THIS ALONG WITH DETAILED SYSTEM INFORMATION TO THE nmap-dev MAILING LIST!", strerror(errno));
+
+ return ret;
+}
+
+int pcap_select(pcap_t *p, long usecs)
+{
+ struct timeval tv;
+
+ tv.tv_sec = usecs / 1000000;
+ tv.tv_usec = usecs % 1000000;
+
+ return pcap_select(p, &tv);
+}
+
 /* Read an IP packet using libpcap . We return the packet and take
    a pcap descripter and a pointer to the packet length (which we set
    in the function. If you want a maximum length returned, you
@@ -1760,7 +1793,6 @@ unsigned int offset = 0;
 struct pcap_pkthdr head;
 char *p;
 int datalink;
-int pcap_descriptor=-1; // -1 means we CANNOT select()
 int timedout = 0;
 struct timeval tv_start, tv_end;
 static char *alignedbuf = NULL;
@@ -1853,10 +1885,6 @@ if (!pd) fatal("NULL packet device passe
    gettimeofday(&tv_start, NULL);
  }
 
- pcap_descriptor = -1;
- if (pcap_selectable_fd_valid())
- pcap_descriptor = my_pcap_get_selectable_fd(pd);
-
  do {
 #ifdef WIN32
    gettimeofday(&tv_end, NULL);
@@ -1866,31 +1894,11 @@ if (!pd) fatal("NULL packet device passe
 #endif
 
    p = NULL;
- if (pcap_descriptor != -1) {
- fd_set rfds;
- struct timeval sel_tv;
- int rv=0;
-
- FD_ZERO(&rfds);
- FD_SET(pcap_descriptor, &rfds);
-
- sel_tv.tv_sec = to_usec/1000000;
- sel_tv.tv_usec = to_usec%1000000;
-
- rv = select(pcap_descriptor+1, &rfds, NULL, NULL, to_usec ? &sel_tv : NULL);
-
- if (rv == -1) {
- fatal("Your system does not support select()ing on pcap devices (%s). PLEASE REPORT THIS ALONG WITH DETAILED SYSTEM INFORMATION TO THE nmap-dev MAILING LIST!", strerror(errno));
- } else if (rv == 0) {
- timedout = 1;
- } else {
- p = (char *) pcap_next(pd, &head);
- }
- } else {
- // THIS CALL CAN BLOCK INAPPROPRIATLEY! (ie, will block until it sees another
- // packet - to_usec notwithstanding) Use the select() code if possible.
+
+ if (pcap_select(pd, to_usec) == 0)
+ timedout = 1;
+ else
      p = (char *) pcap_next(pd, &head);
- }
 
    if (p) {
      if (head.caplen <= offset) {
@@ -2064,7 +2072,6 @@ int read_arp_reply_pcap(pcap_t *pd, u8 *
   int timedout = 0;
   int badcounter = 0;
   struct timeval tv_start, tv_end;
- int pcap_descriptor = -1;
 
   if (!pd) fatal("NULL packet device passed to readarp_reply_pcap");
 
@@ -2099,36 +2106,12 @@ int read_arp_reply_pcap(pcap_t *pd, u8 *
     }
 #endif
 
- pcap_descriptor = -1;
- if (pcap_selectable_fd_valid())
- pcap_descriptor = my_pcap_get_selectable_fd(pd);
-
    p = NULL;
- if (pcap_descriptor != -1) {
- fd_set rfds;
- struct timeval sel_tv;
- int rv=0;
-
- FD_ZERO(&rfds);
- FD_SET(pcap_descriptor, &rfds);
-
- sel_tv.tv_sec = to_usec/1000000;
- sel_tv.tv_usec = to_usec%1000000;
-
- rv = select(pcap_descriptor+1, &rfds, NULL, NULL, to_usec ? &sel_tv : NULL);
-
- if (rv == -1) {
- fatal("Your system does not support select()ing on pcap devices (%s). PLEASE REPORT THIS ALONG WITH DETAILED SYSTEM INFORMATION TO THE nmap-dev MAILING LIST!", strerror(errno));
- } else if (rv == 0) {
- timedout = 1;
- } else {
- p = (u8 *) pcap_next(pd, &head);
- }
- } else {
- // THIS CALL CAN BLOCK INAPPROPRIATLEY! (ie, will block until it sees another
- // packet - to_usec notwithstanding) Use the select() code if possible.
+
+ if (pcap_select(pd, to_usec) == 0)
+ timedout = 1;
+ else
      p = (u8 *) pcap_next(pd, &head);
- }
 
     if (p && head.caplen >= 42) { /* >= because Ethernet padding makes 60 */
       /* frame type 0x0806 (arp), hw type eth (0x0001), prot ip (0x0800),

_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org
Received on Dec 20 2006

[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]