|
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
|
Re: [tcptra-dev] MingW port
|
> 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.
A updated patch attached; fixes pcap_setnonblock() and
meaningful Windows version of pfatal().
--gv
GNU GPL: Free as in herpes. --- tcptraceroute-1.5beta5/tcptraceroute.c Thu Jul 03 21:56:41 2003
+++ tcptraceroute.c Mon Apr 19 12:52:49 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
@@ -273,9 +347,22 @@
void pfatal(char *err)
{
+#ifdef WIN32
+ char buf[1024] = "unknown error";
+ int error = WSAGetLastError();
+
+ debug("WS-error == %d\n", error);
+ fflush(stdout);
+ if (err)
+ fprintf(stderr, "%s: ", err);
+ FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, error,
+ LANG_NEUTRAL, buf, sizeof(buf), NULL);
+ fprintf(stderr, "%s\n", buf);
+#else
debug("errno == %d\n", errno);
fflush(stdout);
perror(err);
+#endif
exit(1);
}
@@ -534,6 +621,7 @@
void getinterfaces(void)
{
+#ifndef WIN32
struct interface_entry *p;
struct ifconf ifc;
struct ifreq *ifrp, ifr;
@@ -672,6 +760,7 @@
free(ifc.ifc_buf);
debug("leaving getinterfaces()\n");
+#endif /* WIN32 */
}
/*
@@ -701,7 +790,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 +853,7 @@
if ((getsockname(s, (struct sockaddr *)&in, &insize)) < 0)
pfatal("getsockname");
- close(s);
+ CLOSE_SOCK(s);
return ntohs(in.sin_port);
}
@@ -985,9 +1074,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 +1227,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, errbuf) < 0)
+ fatal("pcap_setnonblock() failed: %s", errbuf);
+#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 +1496,7 @@
if ((packet = (u_char *)pcap_next(pcap, &packet_hdr)) == NULL)
{
+ if (!o_noselect)
debug("null pointer from pcap_next()\n");
continue;
}
@@ -1774,7 +1879,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 +1931,7 @@
continue;
}
+#ifndef WIN32
/* undocumented, for debugging only */
if (CHECKLONG("--select"))
{
@@ -1832,7 +1939,7 @@
debug("o_noselect disabled\n");
continue;
}
-
+#endif
if (CHECKLONG("--track-id") ||
CHECKLONG("--track-ipid"))
{
@@ -2009,3 +2116,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
|
|