diff -urNb old.nmap.rev/Makefile.in new.nmap.rev/Makefile.in
--- old.nmap.rev/Makefile.in	2006-08-26 23:47:47.000000000 -0700
+++ new.nmap.rev/Makefile.in	2006-08-26 23:47:47.000000000 -0700
@@ -48,11 +48,11 @@
 TARGETNMAPFE=@TARGETNMAPFE@
 INSTALLNMAPFE=@INSTALLNMAPFE@
 
-export SRCS = main.cc nmap.cc targets.cc tcpip.cc nmap_error.cc utils.cc idle_scan.cc osscan.cc osscan2.cc output.cc scan_engine.cc timing.cc charpool.cc services.cc protocols.cc nmap_rpc.cc portlist.cc NmapOps.cc TargetGroup.cc Target.cc FingerPrintResults.cc service_scan.cc NmapOutputTable.cc MACLookup.cc nmap_tty.cc nmap_dns.cc @COMPAT_SRCS@
+export SRCS = main.cc nmap.cc targets.cc tcpip.cc nmap_error.cc utils.cc idle_scan.cc osscan.cc osscan2.cc output.cc scan_engine.cc timing.cc charpool.cc services.cc protocols.cc nmap_rpc.cc portlist.cc NmapOps.cc TargetGroup.cc Target.cc FingerPrintResults.cc service_scan.cc NmapOutputTable.cc MACLookup.cc nmap_tty.cc nmap_dns.cc qscan.cc @COMPAT_SRCS@
 
 export HDRS = charpool.h FingerPrintResults.h global_structures.h idle_scan.h MACLookup.h nmap_amigaos.h nmap_dns.h nmap_error.h nmap.h NmapOps.h NmapOutputTable.h nmap_rpc.h nmap_tty.h nmap_winconfig.h osscan.h osscan2.h output.h portlist.h protocols.h scan_engine.h service_scan.h services.h TargetGroup.h Target.h targets.h tcpip.h timing.h utils.h
 
-OBJS = main.o nmap.o targets.o tcpip.o nmap_error.o utils.o idle_scan.o osscan.o osscan2.o output.o scan_engine.o timing.o charpool.o services.o protocols.o nmap_rpc.o portlist.o NmapOps.o TargetGroup.o Target.o FingerPrintResults.o service_scan.o NmapOutputTable.o MACLookup.o nmap_tty.o nmap_dns.o @COMPAT_OBJS@
+OBJS = main.o nmap.o targets.o tcpip.o nmap_error.o utils.o idle_scan.o osscan.o osscan2.o output.o scan_engine.o timing.o charpool.o services.o protocols.o nmap_rpc.o portlist.o NmapOps.o TargetGroup.o Target.o FingerPrintResults.o service_scan.o NmapOutputTable.o MACLookup.o nmap_tty.o nmap_dns.o qscan.o @COMPAT_OBJS@
 
 # %.o : %.cc -- nope this is a GNU extension
 .cc.o:
diff -urNb old.nmap.rev/nmap.cc new.nmap.rev/nmap.cc
--- old.nmap.rev/nmap.cc	2006-08-26 23:47:47.000000000 -0700
+++ new.nmap.rev/nmap.cc	2006-08-26 23:47:47.000000000 -0700
@@ -582,6 +582,9 @@
       {"log-errors", no_argument, 0, 0},
       {"dns_servers", required_argument, 0, 0},
       {"dns-servers", required_argument, 0, 0},
+      {"qscan-delay", required_argument, 0, 0},
+      {"qscan-numtrips", required_argument, 0, 0},
+      {"qscan-confidence", required_argument, 0, 0},
       {0, 0, 0, 0}
     };
 
@@ -730,6 +733,18 @@
         o.mass_dns = false;
       } else if (optcmp(long_options[option_index].name, "dns-servers") == 0) {
         o.dns_servers = strdup(optarg);
+      } else if (optcmp(long_options[option_index].name, "qscan-delay") == 0) {
+        o.qscan_delay = atoi(optarg);
+        if (o.qscan_delay <= 0)
+          fatal("qscan-delay must be greater than 0");
+      } else if (optcmp(long_options[option_index].name, "qscan-numtrips") == 0) {
+        o.qscan_numtrips = atoi(optarg);
+        if (o.qscan_numtrips < 3)
+          fatal("qscan-numtrips must be 3 or greater");
+      } else if (optcmp(long_options[option_index].name, "qscan-confidence") == 0) {
+        o.qscan_confidence = atof(optarg);
+        if (o.qscan_confidence <= 0 || o.qscan_confidence >= 1.0)
+          fatal("qscan-confidence must be between 0 and 1");
       } else if (optcmp(long_options[option_index].name, "log-errors") == 0) {
         o.log_errors = 1;
       } else if (strcmp(long_options[option_index].name, "webxml") == 0) {
@@ -1004,6 +1019,7 @@
 	case 'N':  o.nullscan = 1; break;
 	case 'O':  o.ipprotscan = 1; break;
 	case 'P':  o.pingscan = 1; break;
+	case 'Q':  o.qscan = 1; randomize = 0; break;
 	case 'R':  o.rpcscan = 1; break;
 	case 'S':  o.synscan = 1; break;	  
 	case 'W':  o.windowscan = 1; break;
@@ -1544,6 +1560,9 @@
     if (o.ipprotscan)
       ultra_scan(Targets, ports, IPPROT_SCAN);
     
+    if (o.qscan)
+      qscan(&Targets[0], Targets.size(), ports);
+    
     /* These lame functions can only handle one target at a time */
     for(targetno = 0; targetno < Targets.size(); targetno++) {
       currenths = Targets[targetno];
diff -urNb old.nmap.rev/nmap.h new.nmap.rev/nmap.h
--- old.nmap.rev/nmap.h	2006-08-26 23:47:47.000000000 -0700
+++ new.nmap.rev/nmap.h	2006-08-26 23:47:47.000000000 -0700
@@ -489,4 +489,6 @@
 int nmap_fetchfile(char *filename_returned, int bufferlen, char *file);
 int gather_logfile_resumption_state(char *fname, int *myargc, char ***myargv);
 
+void qscan(Target **targets, int num_targets, struct scan_lists *ports);
+
 #endif /* NMAP_H */
diff -urNb old.nmap.rev/NmapOps.cc new.nmap.rev/NmapOps.cc
--- old.nmap.rev/NmapOps.cc	2006-08-26 23:47:47.000000000 -0700
+++ new.nmap.rev/NmapOps.cc	2006-08-26 23:47:47.000000000 -0700
@@ -227,7 +227,7 @@
   version_intensity = 7;
   pingtype = PINGTYPE_UNKNOWN;
   listscan = pingscan = allowall = ackscan = bouncescan = connectscan = 0;
-  rpcscan = nullscan = xmasscan = fragscan = synscan = windowscan = 0;
+  rpcscan = nullscan = xmasscan = fragscan = synscan = windowscan = qscan = 0;
   maimonscan = idlescan = finscan = udpscan = ipprotscan = noresolve = 0;
   force = append_output = 0;
   memset(logfd, 0, sizeof(FILE *) * LOG_NUM_FILES);
@@ -253,11 +253,14 @@
   noninteractive = false;
   current_scantype = STYPE_UNKNOWN;
   release_memory = false;
+  qscan_delay = 200;
+  qscan_numtrips = 10;
+  qscan_confidence = 0.95;
 
 }
 
 bool NmapOps::TCPScan() {
-  return ackscan|bouncescan|connectscan|finscan|idlescan|maimonscan|nullscan|synscan|windowscan|xmasscan;
+  return ackscan|bouncescan|connectscan|finscan|idlescan|maimonscan|nullscan|synscan|windowscan|xmasscan|qscan;
 }
 
 bool NmapOps::UDPScan() {
@@ -269,7 +272,7 @@
      IPv6 is being used.  It will return false in those cases where a
      RawScan is not neccessarily used. */
 bool NmapOps::RawScan() {
-  if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|osscan|synscan|udpscan|windowscan|xmasscan)
+  if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|osscan|synscan|udpscan|windowscan|xmasscan|qscan)
     return true;
   if (o.pingtype & (PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS|PINGTYPE_TCP_USE_ACK|PINGTYPE_RAWTCP|PINGTYPE_UDP))
     return true;
diff -urNb old.nmap.rev/NmapOps.h new.nmap.rev/NmapOps.h
--- old.nmap.rev/NmapOps.h	2006-08-26 23:47:47.000000000 -0700
+++ new.nmap.rev/NmapOps.h	2006-08-26 23:47:47.000000000 -0700
@@ -275,6 +275,7 @@
   int ipprotscan;
   int maimonscan;
   int nullscan;
+  int qscan;
   int rpcscan;
   int synscan;
   int udpscan;
@@ -292,6 +293,9 @@
   int resolve_all;
   char *dns_servers;
   bool log_errors;
+  int qscan_delay;
+  int qscan_numtrips;
+  double qscan_confidence;
 
   // Statistics Options set in nmap.cc
   int numhosts_scanned;
diff -urNb old.nmap.rev/qscan.cc new.nmap.rev/qscan.cc
--- old.nmap.rev/qscan.cc	1969-12-31 16:00:00.000000000 -0800
+++ new.nmap.rev/qscan.cc	2006-08-26 23:47:47.000000000 -0700
@@ -0,0 +1,393 @@
+/******************************************************************
+                        The Nmap Qscan
+
+              (C) 2006 Doug Hoyte and HCSW Labs
+
+     R&D partially funded by a Google Summer of Code 2006 grant
+
+          Some test equipment and servers are property
+                of Zerosum Holding Corporation
+******************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "nmap.h"
+#include "Target.h"
+#include "NmapOps.h"
+#include "nmap_tty.h"
+
+
+// Outstanding probe window
+#define OWIN_SIZE 10
+#define TIMEOUT_NUM 10
+
+struct qtarg_s {
+  Target *t;
+  int port;
+
+  struct timeval owin[OWIN_SIZE];
+  int owin_offset;
+  int recvs, trans;
+
+  int num;
+  double sum, sum_of_squares;
+
+  int family;
+
+  struct qtarg_s *next;
+};
+
+static int rawsd, tcpPortBase;
+static pcap_t *pd;
+static struct eth_nfo eth;
+static struct eth_nfo *ethptr;
+static struct qtarg_s *qtargbase;
+static ScanProgressMeter *SPM;
+static int total_n=0, total_n_needed;
+
+
+extern NmapOps o;
+
+
+static double calculate_stddev(int n, double sum, double sum_of_squares) {
+  return sqrt((n*sum_of_squares - sum*sum) / (n*(n-1)));
+}
+
+// Calculates the intermediate statistic 't given
+// the quantity, mean, and standard deviation of 2 samples.
+static double calculate_t(int n1, int n2, double u1, double u2, double s1, double s2) {
+  double a, b;
+  double dof = n1 + n2 - 2;
+
+  a = ((double)n1 + n2) / (n1 * n2);
+  b = ((n1-1) * (s1*s1)) + ((n2-1) * (s2*s2));
+  b /= dof;
+
+  return fabs(u1 - u2) / sqrt(a*b);
+
+}
+
+/* http://www.owlnet.rice.edu/~elec428/projects/tinv.c
+ * Uncredited ?
+ * tinv(p,dof) returns the inverse t-distribution value for probability
+ * 'p and degrees of freedom 'dof.  It does this by looking up the appropriate
+ * value in the array tinv_array.  Only dof between 1 and 20 are exact.
+ * For dof > 20, tinv() returns approximations.  Also, only probabilities
+ * of 0.75, 0.9, 0.95, 0.975, 0.99, 0.995, and 0.9995 are provided.
+ *
+ * If p is not one of the 7 provided values, or if dof is not greater than or
+ * equal to 1, tinv() causes the program to exit.
+ */
+
+static double tinv(double p, int dof) {
+  int dofindex, pindex = -1;
+
+  double tinv_array[31][7] = {
+   {1.0000, 3.0777, 6.3138, 12.7062, 31.8207, 63.6574, 636.6192}, /* 1 */
+   {0.8165, 1.8856, 2.9200, 4.3027, 6.9646, 9.9248, 31.5991}, /* 2 */
+   {0.7649, 1.6377, 2.3534, 3.1824, 4.5407, 5.8409, 12.9240}, /* 3 */
+   {0.7407, 1.5332, 2.1318, 2.7764, 3.7649, 4.6041, 8.6103},  /* 4 */
+   {0.7267, 1.4759, 2.0150, 2.5706, 3.3649, 4.0322, 6.8688},  /* 5 */
+   {0.7176, 1.4398, 1.9432, 2.4469, 3.1427, 3.7074, 5.9588},  /* 6 */
+   {0.7111, 1.4149, 1.8946, 2.3646, 2.9980, 3.4995, 5.4079},  /* 7 */
+   {0.7064, 1.3968, 1.8595, 3.3060, 2.8965, 3.3554, 5.0413},  /* 8 */
+   {0.7027, 1.3830, 1.8331, 2.2622, 2.8214, 3.2498, 4.7809},  /* 9 */
+   {0.6998, 1.3722, 1.8125, 2.2281, 2.7638, 1.1693, 4.5869},  /* 10 */
+   {0.6974, 1.3634, 1.7959, 2.2010, 2.7181, 3.1058, 4.4370},  /* 11 */
+   {0.6955, 1.3562, 1.7823, 2.1788, 2.6810, 3.0545, 4.3178},  /* 12 */
+   {0.6938, 1.3502, 1.7709, 2.1604, 2.6403, 3.0123, 4.2208},  /* 13 */
+   {0.6924, 1.3450, 1.7613, 2.1448, 2.6245, 2.9768, 4.1405},  /* 14 */
+   {0.6912, 1.3406, 1.7531, 2.1315, 2.6025, 2.9467, 4.0728},  /* 15 */
+   {0.6901, 1.3368, 1.7459, 2.1199, 2.5835, 2.9208, 4.0150},  /* 16 */
+   {0.6892, 1.3334, 1.7396, 2.1098, 2.5669, 2.8982, 3.9651},  /* 17 */
+   {0.6884, 1.3304, 1.7341, 2.1009, 2.5524, 2.8784, 3.9216},  /* 18 */
+   {0.6876, 1.3277, 1.7291, 2.0930, 2.5395, 2.8609, 3.8834},  /* 19 */
+   {0.6870, 1.3253, 1.7247, 2.0860, 2.5280, 2.8453, 3.8495},  /* 20 */
+   {0.6844, 1.3163, 1.7081, 2.0595, 2.4851, 2.7874, 3.7251},  /* 25 */
+   {0.6828, 1.3104, 1.6973, 2.0423, 2.4573, 2.7500, 3.6460},  /* 30 */
+   {0.6816, 1.3062, 1.6896, 2.0301, 2.4377, 2.7238, 3.5911},  /* 35 */
+   {0.6807, 1.3031, 1.6839, 2.0211, 2.4233, 2.7045, 3.5510},  /* 40 */
+   {0.6800, 1.3006, 1.6794, 2.0141, 2.4121, 2.6896, 3.5203},  /* 45 */
+   {0.6794, 1.2987, 1.6759, 2.0086, 2.4033, 2.6778, 3.4960},  /* 50 */
+   {0.6786, 1.2958, 1.6706, 2.0003, 2.3901, 2.6603, 3.4602},  /* 60 */
+   {0.6780, 1.2938, 1.6669, 1.9944, 2.3808, 2.6479, 3.4350},  /* 70 */
+   {0.6776, 1.2922, 1.6641, 1.9901, 2.3739, 2.6387, 3.4163},  /* 80 */
+   {0.6772, 1.2910, 1.6620, 1.9867, 2.3685, 2.6316, 3.4019},  /* 90 */
+   {0.6770, 1.2901, 1.6602, 1.9840, 2.3642, 2.6259, 3.3905}}; /* 100 */
+
+   if (dof >= 1 && dof <= 20) dofindex = dof-1;
+   else if (dof < 25) dofindex = 19;
+   else if (dof < 30) dofindex = 20;
+   else if (dof < 35) dofindex = 21;
+   else if (dof < 40) dofindex = 22;
+   else if (dof < 45) dofindex = 23;
+   else if (dof < 50) dofindex = 24;
+   else if (dof < 60) dofindex = 25;
+   else if (dof < 70) dofindex = 26;
+   else if (dof < 80) dofindex = 27;
+   else if (dof < 90) dofindex = 28;
+   else if (dof < 100) dofindex = 29;
+   else if (dof >= 100) dofindex = 30;
+   else
+     fatal("tinv: degrees of freedom must be at least 1\n");
+
+   if (p == .75)        pindex = 0;
+   else if (p == .9)    pindex = 1;
+   else if (p == .95)   pindex = 2;
+   else if (p == .975)  pindex = 3;
+   else if (p == .99)   pindex = 4;
+   else if (p == .995)  pindex = 5;
+   else if (p == .9995) pindex = 6;
+   else
+     fatal("tinv: probability not tabulated\n");
+
+   return(tinv_array[dofindex][pindex]);
+}
+
+
+
+static void qscan_transmit(struct qtarg_s *qt, struct timeval *now) {
+  send_tcp_raw(rawsd, ethptr, qt->t->v4sourceip(), qt->t->v4hostip(), o.ttl, false, 
+               tcpPortBase + qt->owin_offset, qt->port, get_random_u32(), get_random_u32(), 0, TH_SYN,
+               0, 0, NULL, 0, NULL, 0);
+
+  qt->owin[qt->owin_offset].tv_sec = now->tv_sec;
+  qt->owin[qt->owin_offset].tv_usec = now->tv_usec;
+
+  qt->owin_offset = (qt->owin_offset+1) % OWIN_SIZE;
+
+  qt->trans++;
+}
+
+
+static void update_statistics(struct qtarg_s *qt, double rtt_ms) {
+  total_n++;
+  qt->num++;
+  qt->sum += rtt_ms;
+  qt->sum_of_squares += rtt_ms*rtt_ms;
+}
+
+
+static void qscan_families() {
+  struct qtarg_s *qti, *qtj;
+  double t, critical_value;
+  int curr_family = 0;
+
+  for (qti=qtargbase; qti; qti=qti->next) {
+    if (qti->family != -1 || qti->num == 0) continue;
+
+    qti->family = curr_family++;
+
+    for (qtj=qti->next; qtj; qtj=qtj->next) {
+      if (qtj->family != -1 || qtj->num == 0) continue;
+
+      t = calculate_t(qti->num, qtj->num,
+                      qti->sum/qti->num, qtj->sum/qtj->num,
+                      calculate_stddev(qti->num, qti->sum, qti->sum_of_squares),
+                      calculate_stddev(qtj->num, qtj->sum, qtj->sum_of_squares));
+
+      critical_value = tinv(o.qscan_confidence, qti->num + qtj->num - 2);
+
+      if (t < critical_value) qtj->family = qti->family;
+    }
+  }
+}
+
+
+static void qscan_parse_packet(struct ip *myip, struct timeval *seen) {
+  struct tcphdr *tcp;
+  int sport, dport;
+  struct in_addr saddr;
+  struct qtarg_s *qt;
+  double rtt_ms;
+
+  saddr = myip->ip_src;
+  tcp = (struct tcphdr *) ((u8 *) myip + myip->ip_hl * 4);
+  sport = ntohs(tcp->th_sport);
+  dport = ntohs(tcp->th_dport);
+
+  // We're only after resets or syn|acks..
+  if ((tcp->th_flags & TH_RST) == 0 && tcp->th_flags != (TH_SYN|TH_ACK)) return;
+
+  if (dport < tcpPortBase || dport >= (tcpPortBase + OWIN_SIZE)) return;
+
+  for (qt=qtargbase; qt!=NULL; qt=qt->next)
+    if (memcmp(qt->t->v4hostip(), &saddr, sizeof(struct in_addr)) == 0
+        && sport == qt->port) break;
+
+  if (qt == NULL) return;
+
+  // Something fisy going on if this returns: An unexpected reply...
+  // We'll just ignore for now.
+  if (qt->owin[dport - tcpPortBase].tv_sec == -1) return;
+
+  rtt_ms = TIMEVAL_SUBTRACT(*seen, qt->owin[dport - tcpPortBase]) / 1000.0;
+
+  if (qt->recvs++ > OWIN_SIZE)
+    update_statistics(qt, rtt_ms);
+
+  qt->owin[dport - tcpPortBase].tv_sec = -1;
+}
+
+
+static void qscan_run() {
+  struct qtarg_s *qt = qtargbase, *qtp;
+  struct timeval tv, now, seen;
+  struct ip *myip;
+  unsigned int len;
+  int minpackets;
+  int finished=0;
+
+  while(1) {
+    gettimeofday(&now, NULL);
+    qscan_transmit(qt, &now);
+
+    qt = qt->next;
+    if (qt == NULL) qt = qtargbase;
+
+    // Random wait from N/2 to 3N/2 ms between transmissions
+    TIMEVAL_MSEC_ADD(tv, now, (get_random_u16() % o.qscan_delay) + (o.qscan_delay / 2));
+
+    do {
+      if (keyWasPressed())
+        SPM->printStats((double) total_n / total_n_needed, NULL);
+
+      myip = (struct ip *) readip_pcap(pd, &len, TIMEVAL_SUBTRACT(tv, now), &seen, NULL);
+
+      if (myip != NULL)
+        qscan_parse_packet(myip, &seen);
+
+      for (qtp=qtargbase, minpackets=o.qscan_numtrips; qtp!=NULL; qtp=qtp->next)
+        if ((qtp->trans-TIMEOUT_NUM) < qtp->recvs && qtp->num < minpackets) minpackets = qtp->num;
+
+      if (!finished && minpackets == o.qscan_numtrips) {
+        finished=1;
+        gettimeofday(&now, NULL);
+        TIMEVAL_MSEC_ADD(tv, now, (o.qscan_delay*3)/2);
+      }
+
+      gettimeofday(&now, NULL);
+    } while(TIMEVAL_SUBTRACT(tv, now) > 0);
+
+    if (finished) return;
+  }
+}
+
+
+
+void qscan(Target **targets, int num_targets, struct scan_lists *ports) {
+  int i, j, k;
+  struct qtarg_s *qt, *qt2;
+  char pcap_filter[2048];
+
+  if (num_targets == 0 || ports->tcp_count == 0)
+    fatal("Qscan: No targets or no TCP ports specified");
+
+  rawsd = -1;
+  qtargbase = NULL;
+  tcpPortBase = o.magic_port_set? o.magic_port : o.magic_port + get_random_u8();
+  total_n_needed = num_targets * ports->tcp_count * o.qscan_numtrips;
+
+  // 1.3 second "potential conflict" seems to work well
+  if ((num_targets * ports->tcp_count * o.qscan_delay * OWIN_SIZE) < 1300)
+    error("WARNING: --qscan-delay (%d) is dangerously low", o.qscan_delay);
+
+  // Initialise our main linked list
+  for (i=num_targets-1; i>=0; i--) {
+    for (j=ports->tcp_count-1; j>=0; j--) {
+      qt = (struct qtarg_s *) malloc(sizeof(struct qtarg_s));
+      if (qt == NULL) fatal("Qscan: out of memory");
+
+      qt->t = targets[i];
+      qt->port = ports->tcp_ports[j];
+
+      for (k=0; k<OWIN_SIZE; k++)
+        qt->owin[k].tv_sec = -1;
+
+      qt->owin_offset = 0;
+      qt->recvs = qt->trans = 0;
+
+      qt->num = 0;
+      qt->sum = qt->sum_of_squares = 0;
+
+      qt->family = -1;
+
+      qt->next = qtargbase;
+      qtargbase = qt;
+    }
+  }
+
+  // Initialise our raw sending socket
+  // Assume, for now, that all target packets will be sent on same
+  // ethernet device
+  if ((o.sendpref & PACKET_SEND_ETH) && targets[0]->ifType() == devt_ethernet) {
+    memcpy(eth.srcmac, targets[0]->SrcMACAddress(), 6);
+    memcpy(eth.dstmac, targets[0]->NextHopMACAddress(), 6);
+    if ((eth.ethsd = eth_open_cached(targets[0]->deviceName())) == NULL)
+      fatal("%s: Failed to open ethernet device (%s)", __FUNCTION__, targets[0]->deviceName());
+    rawsd = -1;
+    ethptr = &eth;
+  } else {
+    /* Init our raw socket */
+    if ((rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 )
+      pfatal("socket troubles in qscan");
+    unblock_socket(rawsd);
+    broadcast_socket(rawsd);
+#ifndef WIN32
+    sethdrinclude(rawsd);
+#endif
+    ethptr = NULL;
+    eth.ethsd = NULL;
+  }
+
+
+  // Initialise our pcap descriptor
+
+  pd = my_pcap_open_live(targets[0]->deviceName(), 8192, (o.spoofsource)? 1 : 0, 1);
+
+  snprintf(pcap_filter, sizeof(pcap_filter), "tcp and dst host %s", inet_ntoa(targets[0]->v4source())); 
+
+  if (o.debugging > 2) printf("Qscan pcap filter: %s\n", pcap_filter);
+  set_pcap_filter(targets[0]->deviceName(), pd, pcap_filter);
+
+
+
+  // Let's do it!
+
+  printf("Qscan parameters: round trips: %d, avg delay = %dms, confidence = %g\n", o.qscan_numtrips, o.qscan_delay, o.qscan_confidence);
+
+  SPM = new ScanProgressMeter("QScan");
+
+  qscan_run();
+
+  SPM->endTask(NULL, NULL);
+  delete SPM;
+
+  qscan_families();
+
+  printf("         Target:Port  Fam  uRTT  +/- Stddev  Loss%%\n");
+  for(qt = qtargbase; qt != NULL; qt=qt->next) {
+    if (qt->num == 0)
+      printf("%15s:%-5d ?     N/A  +/-   N/A   %3.0f\n", qt->t->targetipstr(), qt->port, 100* (1.0 - ((double)qt->recvs / qt->trans)));
+    else
+      printf("%15s:%-5d %c   %5.1f  +/- %5.1f   %3.0f\n", qt->t->targetipstr(), qt->port, 'A'+qt->family, qt->sum/qt->num, calculate_stddev(qt->num, qt->sum, qt->sum_of_squares), 100* (1.0 - ((double)qt->recvs / qt->trans)));
+  }
+
+
+  // Clean up
+
+  pcap_close(pd);
+
+  if (rawsd < 0) close(rawsd);
+
+  for(qt = qtargbase; qt != NULL;) {
+    qt2 = qt->next;
+    free(qt);
+    qt = qt2;
+  }
+
+}
