| Gisle Vanem on 18 Apr 2004 18:59:02 -0000 |
|
Hi list, I did a port of 1.4 and now 1.5-beta5 to gcc/MingW (on Win-XP). Is there any interest to make tcptraceroute support the most popular OS ever? If so, a patch + makefile is attached. It works well too. --gv GNU GPL: Free as in herpes. diff -u3 -H -B -w tcptraceroute-1.5beta5/tcptraceroute.c ./tcptraceroute.c
--- tcptraceroute-1.5beta5/tcptraceroute.c Thu Jul 03 21:56:41 2003
+++ .\tcptraceroute.c Sun Apr 18 20:52:42 2004
@@ -47,26 +47,35 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
#include <ctype.h>
#include <time.h>
#include <errno.h>
+
+#ifdef WIN32
+ #include <time.h>
+ #include <sys/timeb.h>
+ #define CLOSE_SOCK closesocket
+#else
+ #include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/ioctl.h>
+ #include <arpa/inet.h>
+ #define CLOSE_SOCK close
+#endif /* WIN32 */
+
#include <fcntl.h>
-#ifndef __OpenBSD__
+#if !defined(__OpenBSD__) && !defined(WIN32)
#include <net/if.h> /* Why doesn't OpenBSD deal with this for us? */
#endif
-#include <arpa/inet.h>
#include <libnet.h>
#include <pcap.h>
-#ifndef SIOCGIFCONF
+#if !defined(SIOCGIFCONF) && !defined(WIN32)
#include <sys/sockio.h> /* Solaris, maybe others? */
#endif
@@ -230,8 +239,73 @@
extern char *optarg;
extern int optind, opterr, optopt;
-extern char pcap_version[];
-extern int errno;
+
+#ifdef WIN32
+struct timezone {
+ int tz_minuteswest; /* minutes west of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+ };
+
+static int gettimeofday (struct timeval *tv, struct timezone *tz);
+
+int getuid (void)
+{
+ return (0);
+}
+
+int geteuid (void)
+{
+ return (0);
+}
+
+int setuid (int u)
+{
+ (void)u;
+ return (0);
+}
+
+int seteuid (int u)
+{
+ (void)u;
+ return (0);
+}
+
+char *unicode_to_ascii_device (char* device)
+{
+ DWORD dwVersion;
+ DWORD dwWindowsMajorVersion;
+ char dev[256] = "";
+
+ dwVersion = GetVersion();
+ dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
+
+ if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) /* Windows '95 */
+ {
+ strncpy (dev, device, sizeof(dev)-1);
+ device [sizeof(dev)-1] = '\0';
+ }
+ else
+ {
+ int i, j;
+ for (i = 0, j = 0; i < sizeof(dev)/2; i++)
+ {
+ if (device[i] == '\0' && device[i+1] == '\0')
+ break;
+ if (device[i])
+ dev[j++] = device[i];
+ }
+ dev[j] = '\0';
+ }
+ return strdup (dev);
+}
+
+#define pcap_version pcap_lib_version()
+
+#else /* WIN32 */
+
+extern char pcap_version[]; /* WinPcap doesn't have this */
+extern int errno; /* A macro on Windows */
+#endif
/*
* fatal() and pfatal() are useful stdarg functions from
@@ -534,6 +608,7 @@
void getinterfaces(void)
{
+#ifndef WIN32
struct interface_entry *p;
struct ifconf ifc;
struct ifreq *ifrp, ifr;
@@ -672,6 +747,7 @@
free(ifc.ifc_buf);
debug("leaving getinterfaces()\n");
+#endif /* WIN32 */
}
/*
@@ -701,7 +777,7 @@
if (getsockname(s, (struct sockaddr *)&sinsrc, &size) < 0)
pfatal("getsockname");
- close(s);
+ CLOSE_SOCK(s);
debug("Determined source address of %s to reach %s\n",
iptos(sinsrc.sin_addr.s_addr), iptos(dest));
return sinsrc.sin_addr.s_addr;
@@ -764,7 +840,7 @@
if ((getsockname(s, (struct sockaddr *)&in, &insize)) < 0)
pfatal("getsockname");
- close(s);
+ CLOSE_SOCK(s);
return ntohs(in.sin_port);
}
@@ -985,9 +1061,15 @@
if (device == NULL)
{
+#ifdef WIN32
+ device = pcap_lookupdev(errbuf);
+ if (device)
+ device = unicode_to_ascii_device(device);
+#else
/* couldn't find an appropriate interface */
warn("Could not determine appropriate device; resorting to pcap_lookupdev()\n");
device = pcap_lookupdev(errbuf);
+#endif
}
if (device == NULL)
@@ -1132,10 +1214,19 @@
if (pcap_setfilter(pcap, &fcode) < 0)
fatal("pcap_setfilter failed\n");
+ /* setting non-blocking mode on WinPcap is a terrible CPU hog. Hence use
+ * the read-timeout (10msec) specified in pcap_open_live()
+ */
+#ifndef WIN32
+#ifdef HAVE_PCAP_SETNONBLOCK
+ if (pcap_setnonblock (pcap, 1, NULL) < 0)
+ fatal("pcap_setnonblock() failed: %s", pcap_geterr(pcap));
+#else
pcap_fd = pcap_fileno(pcap);
if (fcntl(pcap_fd, F_SETFL, O_NONBLOCK) < 0)
pfatal("fcntl(F_SETFL, O_NONBLOCK) failed");
-
+#endif
+#endif /* WIN32 */
pcap_freecode(&fcode);
}
@@ -1392,6 +1483,7 @@
if ((packet = (u_char *)pcap_next(pcap, &packet_hdr)) == NULL)
{
+ if (!o_noselect)
debug("null pointer from pcap_next()\n");
continue;
}
@@ -1774,7 +1866,8 @@
o_nofilter = 0;
o_nogetinterfaces = 0;
-#ifdef NOSELECT_DEFAULT
+ /* Win32's select() cannot handle pcap_fd */
+#if defined(NOSELECT_DEFAULT) || defined(WIN32)
o_noselect = 1;
#else
o_noselect = 0;
@@ -1825,6 +1918,7 @@
continue;
}
+#ifndef WIN32
/* undocumented, for debugging only */
if (CHECKLONG("--select"))
{
@@ -1832,7 +1926,7 @@
debug("o_noselect disabled\n");
continue;
}
-
+#endif
if (CHECKLONG("--track-id") ||
CHECKLONG("--track-ipid"))
{
@@ -2009,3 +2103,23 @@
#endif
return exitcode;
}
+
+#ifdef WIN32
+static int gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+ struct _timeb tb;
+
+ if (!tv)
+ return (-1);
+
+ _ftime (&tb);
+ tv->tv_sec = tb.time;
+ tv->tv_usec = tb.millitm * 1000 + 500;
+ if (tz)
+ {
+ tz->tz_minuteswest = -60 * _timezone;
+ tz->tz_dsttime = _daylight;
+ }
+ return (0);
+}
+#endif
Attachment:
Makefile.Mingw
|
|