Open newlog opened 9 years ago
I've been able to compile this beast in very similar environment. I'll try to describe the details later, but there are the following key points:
I haven't verified the executable yet. I'll have to clean up all artifcacts and provide clean instruction. Hopefully they can be turned into valid pull requests.
Robert
For the time being I'm posting the exact steps. I hope I'll send patches later on.
Build
"c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
(VC 10)c:\cygwin\cygwin.bat
./autogen.sh
./configure --with-wpdpack=c:/temp/scapy-new/WpdPack
Modify setup.py
#from distutils.core import setup, Extension
from setuptools import setup, Extension
and this
# ROGO - below line modified to contain wpcap
dnet_libs.extend([ 'advapi32', 'iphlpapi', 'ws2_32', 'packet', 'wpcap' ])
modify sources
/* (intf-win32.c) */
IP_ADAPTER_UNICAST_ADDRESS *addr;
char friendly_name[MAX_INTERFACE_NAME_LEN];
const char *name_start;
/* The total length of the entry may be passed inside entry.
Remember it and clear the entry. */
u_int intf_len = entry->intf_len;
memset(entry, 0, sizeof(*entry));
entry->intf_len = intf_len;
type = _if_type_canonicalize(a->IfType);
for (i = 0; i < intf->ifcombo[type].cnt; i++) {
if (intf->ifcombo[type].idx[i].ipv4 == a->IfIndex &&
intf->ifcombo[type].idx[i].ipv6 == a->Ipv6IfIndex) {
break;
}
}
/* XXX - type matches MIB-II ifType. */
snprintf(entry->intf_name, sizeof(entry->intf_name), "%s%lu",
_ifcombo_name(a->IfType), i);
entry->intf_type = (uint16_t)type;
strncpy_wchar(friendly_name, a->FriendlyName, MAX_INTERFACE_NAME_LEN);
snprintf(entry->os_intf_name, MAX_INTERFACE_NAME_LEN, "%s %s", friendly_name,
a->AdapterName);
entry->os_intf_name[MAX_INTERFACE_NAME_LEN - 1] = '\0';
name_start = strstr(a->AdapterName, "{");
if (name_start) {
snprintf(entry->pcap_intf_name, MAX_INTERFACE_NAME_LEN - 1,
"\\Device\\NPF_%s", name_start);
}
and add to the top:
#define MAX_INTERFACE_NAME_LEN 255
exit
python setup.py build --compiler=msvc
python setup.py bdist_wheel
Notes:
Despite compiling it successfully 1.13 seems to be broken. There were numerous changes pulled in (e.g. from nmap), at least one of them broke get_dst() (intf-win32), which is now just unsupported (https://github.com/nmap/nmap/tree/master/libdnet-stripped) Add to the above fact that the code required modifications in order to become compilable, it's status on win32 is poor.
I'll look into fixing things, but that will take several weeks/months.
Regards, Robert
c:\Users\rgomulk\AppData\Local\Programs\Common\Microsoft\Visual C++ for Python\9.0\vcvarsall.bat
c:\cygwin\cygwin.bat
./autogen.sh
./configure --with-wpdpack=../WpdPack
c:\Python27\python.exe c:\Python27\Scripts\pyrexc.py dnet.pyx
c:\python27\python setup.py build --compiler=msvc
c:\python27\python setup.py bdist_wheel
diff -r -u libdnet-orig/include/config.h.in libdnet-master/include/config.h.in
--- libdnet-orig/include/config.h.in 2014-03-18 07:39:14.000000000 +0100
+++ libdnet-master/include/config.h.in 2015-05-29 11:15:16.832308200 +0200
@@ -220,8 +220,7 @@
/* Define to 1 if you have the <winsock2.h> header file. */
#undef HAVE_WINSOCK2_H
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
/* Name of package */
diff -r -u libdnet-orig/include/dnet/intf.h libdnet-master/include/dnet/intf.h
--- libdnet-orig/include/dnet/intf.h 2014-03-18 07:39:14.000000000 +0100
+++ libdnet-master/include/dnet/intf.h 2015-05-29 21:47:32.298636100 +0200
@@ -11,8 +11,16 @@
#ifndef DNET_INTF_H
#define DNET_INTF_H
-#include <stdint.h>
+#ifdef _MSC_VER
+
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+#include <stdint.h>
+#endif
/*
* Interface entry
*/
diff -r -u libdnet-orig/include/dnet/os.h libdnet-master/include/dnet/os.h
--- libdnet-orig/include/dnet/os.h 2014-03-18 07:39:14.000000000 +0100
+++ libdnet-master/include/dnet/os.h 2015-05-29 21:53:47.895192000 +0200
@@ -148,7 +148,16 @@
#define dnet_ntohl(val) (val)
#define dnet_ntohll(val) (val)
#else
+#ifdef _MSC_VER
+
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+#else
#include <stdint.h>
+#endif
#define dnet_htons(val) htons(val)
#define dnet_htonl(val) htonl(val)
#define dnet_htonll(val) (((uint64_t)htonl(val) << 32) | htonl((uint64_t)(val) >> 32))
Only in libdnet-master: libdnet.spec.bak
diff -r -u libdnet-orig/python/dnet.pyx libdnet-master/python/dnet.pyx
--- libdnet-orig/python/dnet.pyx 2014-03-18 07:39:14.000000000 +0100
+++ libdnet-master/python/dnet.pyx 2015-05-29 17:51:01.451833000 +0200
@@ -16,7 +16,7 @@
__copyright__ = 'Copyright (c) 2003 Dug Song'
__license__ = 'BSD'
__url__ = 'http://libdnet.sourceforge.net/'
-__version__ = '1.12'
+__version__ = '1.12.1rg'
cdef extern from "dnet.h":
pass
@@ -37,6 +37,7 @@
void *memset(char *b, int c, int len)
char *strerror(int errnum)
int strlcpy(char *dst, char *src, int size)
+ int strlen(char *src)
unsigned long htonl(unsigned long n)
unsigned long ntohl(unsigned long n)
@@ -160,7 +161,7 @@
return PyString_FromStringAndSize(ea.data, 6)
def eth_pack_hdr(dst=ETH_ADDR_BROADCAST, src=ETH_ADDR_BROADCAST,
- type=ETH_TYPE_IP):
+ typee=ETH_TYPE_IP):
"""Return a packed binary string representing an Ethernet header.
Keyword arguments:
@@ -172,7 +173,7 @@
cdef eth_addr_t s, d
__memcpy(s.data, src, 6)
__memcpy(d.data, dst, 6)
- __eth_pack_hdr(hdr, d, s, type)
+ __eth_pack_hdr(hdr, d, s, typee)
return PyString_FromStringAndSize(hdr, 14)
#
@@ -441,7 +442,7 @@
"""
cdef addr_t _addr
- def __init__(self, addrtxt=None, type=ADDR_TYPE_NONE):
+ def __init__(self, addrtxt=None, typee=ADDR_TYPE_NONE):
if addrtxt != None and addr_aton(addrtxt, &self._addr) < 0:
if PyString_Size(addrtxt) == 4:
self._addr.addr_type = ADDR_TYPE_IP
@@ -785,7 +786,7 @@
cdef extern from *:
void __icmp_pack_hdr "icmp_pack_hdr" (char *hdr, int type, int code)
-def icmp_pack_hdr(type, code):
+def icmp_pack_hdr(typee, code):
"""Return a packed binary string representing an ICMP header.
Keyword arguments:
@@ -793,7 +794,7 @@
code -- ICMP code (8-bit integer)
"""
cdef char buf[4]
- __icmp_pack_hdr(buf, type, code)
+ __icmp_pack_hdr(buf, typee, code)
return PyString_FromStringAndSize(buf, sizeof(buf))
#
@@ -909,6 +910,7 @@
int intf_set(intf_t *intf, intf_entry *entry)
int intf_loop(intf_t *intf, intf_handler callback, void *arg)
intf_t *intf_close(intf_t *intf)
+ int intf_get_pcap_devname(char *intf_name, char *pcapdev, int pcapdevlen)
INTF_TYPE_OTHER = 1 # /* other */
INTF_TYPE_ETH = 6 # /* Ethernet */
@@ -958,7 +960,28 @@
entry.intf_alias_num = len(d['alias_addrs'])
for i from 0 <= i < entry.intf_alias_num:
entry.intf_alias_addrs[i] = (<addr>d['alias_addrs'][i])._addr
-
+"""
+int intf_get_pcap_devname(const char *intf_name, char *pcapdev, int pcapdevlen)
+"""
+def get_pcap_devname(intf_name):
+ """ Get pcap device name from our device name.
+
+ Arguments:
+ intf_name - 'eth0', 'eth1', 'eth2', ...
+
+ Output:
+ pcap interface name
+ """
+
+ cdef char pcapdev[128]
+ if intf_name is not None:
+ if (intf_get_pcap_devname(intf_name, pcapdev, sizeof(pcapdev)) != -1):
+ return PyString_FromStringAndSize(pcapdev, strlen(pcapdev))
+ else:
+ raise RuntimeError("Pcap interface for intf_name '%s' not found" % intf_name)
+ else:
+ return None
+
cdef int __intf_callback(intf_entry *entry, void *arg) except -1:
f, a = <object>arg
ret = f(ifent_to_dict(entry), a)
@@ -1013,7 +1036,7 @@
if intf_get_dst(self.intf, ifent, &dst._addr) < 0:
raise OSError, __oserror()
return ifent_to_dict(ifent)
-
+
def set(self, d):
"""Set the configuration for an interface from a dict.
diff -r -u libdnet-orig/python/setup.py.in libdnet-master/python/setup.py.in
--- libdnet-orig/python/setup.py.in 2014-03-18 07:39:14.000000000 +0100
+++ libdnet-master/python/setup.py.in 2015-05-28 21:33:45.242841200 +0200
@@ -1,7 +1,7 @@
#!/usr/bin/env python
import glob, os, sys
-from distutils.core import setup, Extension
+from setuptools import setup, Extension
dnet_srcs = [ '@srcdir@/dnet.c' ]
dnet_incdirs = [ '@top_srcdir@/include' ]
@@ -15,7 +15,7 @@
dnet_srcs.extend(['../src/addr-util.c', '../src/addr.c', '../src/blob.c', '../src/ip-util.c', '../src/ip6.c', '../src/rand.c', '../src/err.c', '../src/strlcat.c', '../src/strlcpy.c', '../src/err.c', '../src/strlcat.c', '../src/strlcpy.c', '../src/strsep.c', '../src/arp-win32.c', '../src/eth-win32.c', '../src/fw-pktfilter.c', '../src/intf-win32.c', '../src/ip-win32.c', '../src/route-win32.c', '../src/tun-none.c'])
dnet_incdirs.append(winpcap_dir + '/Include')
dnet_libdirs.append(winpcap_dir + '/Lib')
- dnet_libs.extend([ 'advapi32', 'iphlpapi', 'ws2_32', 'packet' ])
+ dnet_libs.extend([ 'advapi32', 'iphlpapi', 'ws2_32', 'packet', 'wpcap' ])
else:
# XXX - can't build on Cygwin+MinGW yet.
#if sys.platform == 'cygwin':
diff -r -u libdnet-orig/src/intf-win32.c libdnet-master/src/intf-win32.c
--- libdnet-orig/src/intf-win32.c 2014-03-18 07:39:14.000000000 +0100
+++ libdnet-master/src/intf-win32.c 2015-06-01 09:50:11.468751700 +0200
@@ -89,6 +89,7 @@
} else if (strncmp(device, "tun", 3) == 0) {
type = INTF_TYPE_TUN;
}
+
return (type);
}
@@ -131,10 +132,12 @@
int i;
int type;
IP_ADAPTER_UNICAST_ADDRESS *addr;
-
+ char friendly_name[MAX_INTERFACE_NAME_LEN];
+ const char *name_start;
/* The total length of the entry may be passed inside entry.
Remember it and clear the entry. */
u_int intf_len = entry->intf_len;
+
memset(entry, 0, sizeof(*entry));
entry->intf_len = intf_len;
@@ -149,13 +152,12 @@
snprintf(entry->intf_name, sizeof(entry->intf_name), "%s%lu",
_ifcombo_name(a->IfType), i);
entry->intf_type = (uint16_t)type;
- char friendly_name[MAX_INTERFACE_NAME_LEN];
strncpy_wchar(friendly_name, a->FriendlyName, MAX_INTERFACE_NAME_LEN);
snprintf(entry->os_intf_name, MAX_INTERFACE_NAME_LEN, "%s %s", friendly_name,
a->AdapterName);
entry->os_intf_name[MAX_INTERFACE_NAME_LEN - 1] = '\0';
- const char *name_start = strstr(a->AdapterName, "{");
+ name_start = strstr(a->AdapterName, "{");
if (name_start) {
snprintf(entry->pcap_intf_name, MAX_INTERFACE_NAME_LEN - 1,
"\\Device\\NPF_%s", name_start);
@@ -277,7 +279,17 @@
char *p = (char *)device;
int n, type = _ifcombo_type(device);
+ /* only ethernet supported (and as a safeguard for invalid
+ interfaces names, leading to crash */
+ if (type != INTF_TYPE_ETH)
+ return NULL;
+
while (isalpha((int) (unsigned char) *p)) p++;
+
+ /* poor check - first digits only - eth0a will be still treated as eth0*/
+ if (!isdigit((int) (unsigned char) *p))
+ return NULL;
+
n = atoi(p);
for (a = intf->iftable; a != NULL; a = a->Next) {
@@ -377,9 +389,28 @@
int
intf_get_dst(intf_t *intf, struct intf_entry *entry, struct addr *dst)
{
- errno = ENOSYS;
- SetLastError(ERROR_NOT_SUPPORTED);
+ IP_ADAPTER_ADDRESSES *a;
+ DWORD intfIdx;
+
+ if (dst->addr_type != ADDR_TYPE_IP) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (_refresh_tables(intf) < 0)
return (-1);
+
+ if (GetBestInterface(dst->addr_ip, &intfIdx) != NO_ERROR)
+ return (-1);
+
+ for (a = intf->iftable; a != NULL; a = a->Next) {
+ if (a->IfIndex == intfIdx) {
+ _adapter_address_to_entry(intf, a, entry);
+ return (0);
+ }
+ }
+
+ return (-1);
}
int
@@ -447,10 +478,12 @@
if ((intf = intf_open()) == NULL)
return (-1);
+
if (_refresh_tables(intf) < 0) {
intf_close(intf);
return (-1);
}
+
a = _find_adapter_address(intf, intf_name);
if (a == NULL) {
After the above dnet can be compiled successfully, but will have some issues interacting with scapy+pcap. The following scapy patch should address scapy issues:
diff -r -u scapy-2.3.1-orig/scapy/arch/pcapdnet.py scapy-2.3.1/scapy/arch/pcapdnet.py
--- scapy-2.3.1-orig/scapy/arch/pcapdnet.py 2014-12-23 11:24:06.000000000 +0100
+++ scapy-2.3.1/scapy/arch/pcapdnet.py 2015-06-01 10:05:29.426547700 +0200
@@ -43,6 +43,10 @@
if hasattr(pcap,"pcap"): # python-pypcap
class _PcapWrapper_pypcap:
def __init__(self, device, snaplen, promisc, to_ms):
+ # avoid interfaces mapping in pcap
+ # there's a lot of guessing going on there
+ # give pcap its own name
+ # and the interfaces can easily be incorrectly mapped
try:
self.pcap = pcap.pcap(device, snaplen, promisc, immediate=1, timeout_ms=to_ms)
except TypeError:
diff -r -u scapy-2.3.1-orig/scapy/arch/windows/__init__.py scapy-2.3.1/scapy/arch/windows/__init__.py
--- scapy-2.3.1-orig/scapy/arch/windows/__init__.py 2014-12-23 11:24:06.000000000 +0100
+++ scapy-2.3.1/scapy/arch/windows/__init__.py 2015-06-01 10:06:20.396644200 +0200
@@ -109,48 +109,16 @@
def _update_pcapdata(self):
"""Supplement more info from pypcap and the Windows registry"""
- # XXX: We try eth0 - eth29 by bruteforce and match by IP address,
- # because only the IP is available in both pypcap and dnet.
- # This may not work with unorthodox network configurations and is
- # slow because we have to walk through the Windows registry.
- for n in range(30):
- guess = "eth%s" % n
- win_name = pcapdnet.pcap.ex_name(guess)
- if win_name.endswith("}"):
- try:
- uuid = win_name[win_name.index("{"):win_name.index("}")+1]
- keyname = r"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\%s" % uuid
- try:
- key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, keyname)
- except WindowsError:
- log_loading.debug("Couldn't open 'HKEY_LOCAL_MACHINE\\%s' (for guessed pcap iface name '%s')." % (keyname, guess))
- continue
- try:
- fixed_ip = _winreg.QueryValueEx(key, "IPAddress")[0][0].encode("utf-8")
- except (WindowsError, UnicodeDecodeError, IndexError):
- fixed_ip = None
- try:
- dhcp_ip = _winreg.QueryValueEx(key, "DhcpIPAddress")[0].encode("utf-8")
- except (WindowsError, UnicodeDecodeError, IndexError):
- dhcp_ip = None
- # "0.0.0.0" or None means the value is not set (at least not correctly).
- # If both fixed_ip and dhcp_ip are set, fixed_ip takes precedence
- if fixed_ip is not None and fixed_ip != "0.0.0.0":
- ip = fixed_ip
- elif dhcp_ip is not None and dhcp_ip != "0.0.0.0":
- ip = dhcp_ip
- else:
- continue
- except IOError:
- continue
- else:
- if ip == self.ip:
- self.pcap_name = guess
- self.win_name = win_name
- self.uuid = uuid
- break
- else:
+ win_name = pcapdnet.dnet.get_pcap_devname(self.name)
+ if win_name is None:
raise PcapNameNotFoundError
+
+ uuid = win_name[win_name.index("{"):win_name.index("}")+1]
+
+ self.win_name = win_name
+ self.uuid = uuid
+ # use win_name as pcap_name to avoid names mismatch
+ self.pcap_name = self.win_name
def __repr__(self):
return "<%s: %s %s %s pcap_name=%s win_name=%s>" % (self.__class__.__name__,
@@ -166,10 +134,7 @@
for i in pcapdnet.dnet.intf():
try:
# XXX: Only Ethernet for the moment: localhost is not supported by dnet and pcap
- # We only take interfaces that have an IP address, because the IP
- # is used for the mapping between dnet and pcap interface names
- # and this significantly improves Scapy's startup performance
- if i["name"].startswith("eth") and "addr" in i:
+ if i["name"].startswith("eth"):
self.data[i["name"]] = NetworkInterface(i)
except (KeyError, PcapNameNotFoundError):
pass
@@ -183,12 +148,10 @@
This mapping is necessary because pypcap numbers the devices differently."""
- try:
- pcap_name = self.data[devname].pcap_name
- except KeyError:
- raise ValueError("Unknown network interface %r" % devname)
+ if devname is not None:
+ return self.data[devname].pcap_name
else:
- return pcap_name
+ return None
def devname(self, pcap_name):
"""Return libdnet/Scapy device name for given pypcap device name
@@ -254,7 +217,7 @@
netif = match.group(4)
metric = match.group(5)
try:
- intf = pcapdnet.dnet.intf().get_dst(pcapdnet.dnet.addr(type=2, addrtxt=dest))
+ intf = pcapdnet.dnet.intf().get_dst(pcapdnet.dnet.addr(typee=2, addrtxt=dest))
except OSError:
log_loading.warning("Building Scapy's routing table: Couldn't get outgoing interface for destination %s" % dest)
continue
Only in scapy-2.3.1/scapy/arch/windows: __init__.py.bak
diff -r -u scapy-2.3.1-orig/scapy/layers/inet6.py scapy-2.3.1/scapy/layers/inet6.py
--- scapy-2.3.1-orig/scapy/layers/inet6.py 2014-12-23 11:24:06.000000000 +0100
+++ scapy-2.3.1/scapy/layers/inet6.py 2015-05-28 21:45:48.729841200 +0200
@@ -3003,4 +3003,5 @@
bind_layers(IPv6, UDP, nh = socket.IPPROTO_UDP )
bind_layers(IP, IPv6, proto = socket.IPPROTO_IPV6 )
bind_layers(IPv6, IPv6, nh = socket.IPPROTO_IPV6 )
-bind_layers(IPv6, IP, nh = socket.IPPROTO_IPIP )
+# bind_layers(IPv6, IP, nh = socket.IPPROTO_IPIP )
+bind_layers(IPv6, IP, nh = 4 )
diff -r -u scapy-2.3.1-orig/setup.py scapy-2.3.1/setup.py
--- scapy-2.3.1-orig/setup.py 2014-12-23 11:35:20.000000000 +0100
+++ scapy-2.3.1/setup.py 2015-05-28 21:49:25.098496700 +0200
@@ -6,9 +6,7 @@
from distutils import archive_util
-from distutils import sysconfig
-from distutils.core import setup
-from distutils.command.sdist import sdist
+from setuptools import setup
import os
I have successfully built libdnet using the instructions and patches given by @rgom above. The patched Scapy can send and receive packets (e.g. its traceroute
command works).
no acceptable ld found in $PATH
, install the binutils
package via Cygwinpatch
package in Cygwin--ignore-whitespace
option to the patch
command to make the patches applyneed MingW32 package to build under Cygwin
. This went away after I added || test "$MINGW" = no
to the if condition on line 85 of configure.ac
and ran autogen.sh
again.python setup.py build bdist_wininst
.Ah, that makes sense now. I must have kept some cygwin packages installed in the past (mingw*). And yes, I've forgotten about some other build dependencies in the description above for the same reason. You're right that configure/autogen additional modifications are necessary.
Best regards, Robert
Ok, forked the repo and created first of pull requests. Let's see how well it goes - this is the easiest one, some of later patches will cause API incompatibility (some function arguments in pyx were named after Python reserved words). That might require further discussion and even version change. I'll see how responsive is upstream.
Robert
There's a possibility to simplify the patches a bit:
I'll try to update the patches next days. (Pull requests already submitted for scapy and dnet still require merging - they are fine by themselves)
Robert
Ok, here it comes. I'll post updated dnet and scapy patches here with added comments. Patches will be split.
Update revision to indicate local changes:
diff -u -r libdnet-master-orig/configure.ac libdnet-master/configure.ac
--- libdnet-master-orig/configure.ac 2014-03-18 07:39:14.000000000 +0100
+++ libdnet-master/configure.ac 2015-06-10 09:05:04.140602600 +0200
@@ -5,7 +5,7 @@
dnl
dnl $Id: configure.in 638 2007-01-20 11:39:21Z dugsong $
-AC_INIT([libdnet], [1.12])
+AC_INIT([libdnet], [1.12.1+rg])
AC_CONFIG_SRCDIR([include/dnet.h])
AC_CONFIG_AUX_DIR(config)
AC_SUBST(ac_aux_dir)
uint32_t not available on MSVC9
diff -u -r libdnet-master-orig/include/dnet/intf.h libdnet-master/include/dnet/intf.h
--- libdnet-master-orig/include/dnet/intf.h 2014-03-18 07:39:14.000000000 +0100
+++ libdnet-master/include/dnet/intf.h 2015-05-29 21:47:32.298636100 +0200
@@ -11,8 +11,16 @@
#ifndef DNET_INTF_H
#define DNET_INTF_H
-#include <stdint.h>
+#ifdef _MSC_VER
+
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+#include <stdint.h>
+#endif
/*
* Interface entry
*/
diff -u -r libdnet-master-orig/include/dnet/os.h libdnet-master/include/dnet/os.h
--- libdnet-master-orig/include/dnet/os.h 2014-03-18 07:39:14.000000000 +0100
+++ libdnet-master/include/dnet/os.h 2015-05-29 21:53:47.895192000 +0200
@@ -148,7 +148,16 @@
#define dnet_ntohl(val) (val)
#define dnet_ntohll(val) (val)
#else
+#ifdef _MSC_VER
+
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+#else
#include <stdint.h>
+#endif
#define dnet_htons(val) htons(val)
#define dnet_htonl(val) htonl(val)
#define dnet_htonll(val) (((uint64_t)htonl(val) << 32) | htonl((uint64_t)(val) >> 32))
Make pyrex 0.9.9 happy about "type" argument name, without API change. Additionally provide already introduced get_pcap_devname to Python.
diff -u -r libdnet-master-orig/python/dnet.pyx libdnet-master/python/dnet.pyx
--- libdnet-master-orig/python/dnet.pyx 2014-03-18 07:39:14.000000000 +0100
+++ libdnet-master/python/dnet.pyx 2015-06-09 22:24:27.695205800 +0200
@@ -16,7 +16,7 @@
__copyright__ = 'Copyright (c) 2003 Dug Song'
__license__ = 'BSD'
__url__ = 'http://libdnet.sourceforge.net/'
-__version__ = '1.12'
+__version__ = '1.12.1rg'
cdef extern from "dnet.h":
pass
@@ -37,6 +37,7 @@
void *memset(char *b, int c, int len)
char *strerror(int errnum)
int strlcpy(char *dst, char *src, int size)
+ int strlen(char *src)
unsigned long htonl(unsigned long n)
unsigned long ntohl(unsigned long n)
@@ -160,7 +161,7 @@
return PyString_FromStringAndSize(ea.data, 6)
def eth_pack_hdr(dst=ETH_ADDR_BROADCAST, src=ETH_ADDR_BROADCAST,
- type=ETH_TYPE_IP):
+ object type=ETH_TYPE_IP):
"""Return a packed binary string representing an Ethernet header.
Keyword arguments:
@@ -441,7 +442,7 @@
"""
cdef addr_t _addr
- def __init__(self, addrtxt=None, type=ADDR_TYPE_NONE):
+ def __init__(self, addrtxt=None, object type=ADDR_TYPE_NONE):
if addrtxt != None and addr_aton(addrtxt, &self._addr) < 0:
if PyString_Size(addrtxt) == 4:
self._addr.addr_type = ADDR_TYPE_IP
@@ -785,7 +786,7 @@
cdef extern from *:
void __icmp_pack_hdr "icmp_pack_hdr" (char *hdr, int type, int code)
-def icmp_pack_hdr(type, code):
+def icmp_pack_hdr(object type, code):
"""Return a packed binary string representing an ICMP header.
Keyword arguments:
@@ -909,6 +910,7 @@
int intf_set(intf_t *intf, intf_entry *entry)
int intf_loop(intf_t *intf, intf_handler callback, void *arg)
intf_t *intf_close(intf_t *intf)
+ int intf_get_pcap_devname(char *intf_name, char *pcapdev, int pcapdevlen)
INTF_TYPE_OTHER = 1 # /* other */
INTF_TYPE_ETH = 6 # /* Ethernet */
@@ -958,7 +960,28 @@
entry.intf_alias_num = len(d['alias_addrs'])
for i from 0 <= i < entry.intf_alias_num:
entry.intf_alias_addrs[i] = (<addr>d['alias_addrs'][i])._addr
-
+"""
+int intf_get_pcap_devname(const char *intf_name, char *pcapdev, int pcapdevlen)
+"""
+def get_pcap_devname(intf_name):
+ """ Get pcap device name from our device name.
+
+ Arguments:
+ intf_name - 'eth0', 'eth1', 'eth2', ...
+
+ Output:
+ pcap interface name
+ """
+
+ cdef char pcapdev[128]
+ if intf_name is not None:
+ if (intf_get_pcap_devname(intf_name, pcapdev, sizeof(pcapdev)) != -1):
+ return PyString_FromStringAndSize(pcapdev, strlen(pcapdev))
+ else:
+ raise RuntimeError("Pcap interface for intf_name '%s' not found" % intf_name)
+ else:
+ return None
+
cdef int __intf_callback(intf_entry *entry, void *arg) except -1:
f, a = <object>arg
ret = f(ifent_to_dict(entry), a)
@@ -1013,7 +1036,7 @@
if intf_get_dst(self.intf, ifent, &dst._addr) < 0:
raise OSError, __oserror()
return ifent_to_dict(ifent)
-
+
def set(self, d):
"""Set the configuration for an interface from a dict.
Use setuptools instead of distutils to allow creating wheels. Add missing wpcap library.
diff -u -r libdnet-master-orig/python/setup.py.in libdnet-master/python/setup.py.in
--- libdnet-master-orig/python/setup.py.in 2014-03-18 07:39:14.000000000 +0100
+++ libdnet-master/python/setup.py.in 2015-05-28 21:33:45.242841200 +0200
@@ -1,7 +1,7 @@
#!/usr/bin/env python
import glob, os, sys
-from distutils.core import setup, Extension
+from setuptools import setup, Extension
dnet_srcs = [ '@srcdir@/dnet.c' ]
dnet_incdirs = [ '@top_srcdir@/include' ]
@@ -15,7 +15,7 @@
dnet_srcs.extend(['../src/addr-util.c', '../src/addr.c', '../src/blob.c', '../src/ip-util.c', '../src/ip6.c', '../src/rand.c', '../src/err.c', '../src/strlcat.c', '../src/strlcpy.c', '../src/err.c', '../src/strlcat.c', '../src/strlcpy.c', '../src/strsep.c', '../src/arp-win32.c', '../src/eth-win32.c', '../src/fw-pktfilter.c', '../src/intf-win32.c', '../src/ip-win32.c', '../src/route-win32.c', '../src/tun-none.c'])
dnet_incdirs.append(winpcap_dir + '/Include')
dnet_libdirs.append(winpcap_dir + '/Lib')
- dnet_libs.extend([ 'advapi32', 'iphlpapi', 'ws2_32', 'packet' ])
+ dnet_libs.extend([ 'advapi32', 'iphlpapi', 'ws2_32', 'packet', 'wpcap' ])
else:
# XXX - can't build on Cygwin+MinGW yet.
#if sys.platform == 'cygwin':
Implement get_dst(), fix compilation problems (move declarations earlier):
diff -u -r libdnet-master-orig/src/intf-win32.c libdnet-master/src/intf-win32.c
--- libdnet-master-orig/src/intf-win32.c 2014-03-18 07:39:14.000000000 +0100
+++ libdnet-master/src/intf-win32.c 2015-06-01 09:50:11.468751700 +0200
@@ -89,6 +89,7 @@
} else if (strncmp(device, "tun", 3) == 0) {
type = INTF_TYPE_TUN;
}
+
return (type);
}
@@ -131,10 +132,12 @@
int i;
int type;
IP_ADAPTER_UNICAST_ADDRESS *addr;
-
+ char friendly_name[MAX_INTERFACE_NAME_LEN];
+ const char *name_start;
/* The total length of the entry may be passed inside entry.
Remember it and clear the entry. */
u_int intf_len = entry->intf_len;
+
memset(entry, 0, sizeof(*entry));
entry->intf_len = intf_len;
@@ -149,13 +152,12 @@
snprintf(entry->intf_name, sizeof(entry->intf_name), "%s%lu",
_ifcombo_name(a->IfType), i);
entry->intf_type = (uint16_t)type;
- char friendly_name[MAX_INTERFACE_NAME_LEN];
strncpy_wchar(friendly_name, a->FriendlyName, MAX_INTERFACE_NAME_LEN);
snprintf(entry->os_intf_name, MAX_INTERFACE_NAME_LEN, "%s %s", friendly_name,
a->AdapterName);
entry->os_intf_name[MAX_INTERFACE_NAME_LEN - 1] = '\0';
- const char *name_start = strstr(a->AdapterName, "{");
+ name_start = strstr(a->AdapterName, "{");
if (name_start) {
snprintf(entry->pcap_intf_name, MAX_INTERFACE_NAME_LEN - 1,
"\\Device\\NPF_%s", name_start);
@@ -277,7 +279,17 @@
char *p = (char *)device;
int n, type = _ifcombo_type(device);
+ /* only ethernet supported (and as a safeguard for invalid
+ interfaces names, leading to crash */
+ if (type != INTF_TYPE_ETH)
+ return NULL;
+
while (isalpha((int) (unsigned char) *p)) p++;
+
+ /* poor check - first digits only - eth0a will be still treated as eth0*/
+ if (!isdigit((int) (unsigned char) *p))
+ return NULL;
+
n = atoi(p);
for (a = intf->iftable; a != NULL; a = a->Next) {
@@ -377,9 +389,28 @@
int
intf_get_dst(intf_t *intf, struct intf_entry *entry, struct addr *dst)
{
- errno = ENOSYS;
- SetLastError(ERROR_NOT_SUPPORTED);
+ IP_ADAPTER_ADDRESSES *a;
+ DWORD intfIdx;
+
+ if (dst->addr_type != ADDR_TYPE_IP) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (_refresh_tables(intf) < 0)
return (-1);
+
+ if (GetBestInterface(dst->addr_ip, &intfIdx) != NO_ERROR)
+ return (-1);
+
+ for (a = intf->iftable; a != NULL; a = a->Next) {
+ if (a->IfIndex == intfIdx) {
+ _adapter_address_to_entry(intf, a, entry);
+ return (0);
+ }
+ }
+
+ return (-1);
}
int
@@ -447,10 +478,12 @@
if ((intf = intf_open()) == NULL)
return (-1);
+
if (_refresh_tables(intf) < 0) {
intf_close(intf);
return (-1);
}
+
a = _find_adapter_address(intf, intf_name);
if (a == NULL) {
So far, there's a pull request for get_dst().
And now corresponding scapy part:
(This is big, sorry for that). windows/init.py changes:
diff -u -r scapy-2.3.1-orig/scapy/arch/windows/__init__.py scapy-2.3.1/scapy/arch/windows/__init__.py
--- scapy-2.3.1-orig/scapy/arch/windows/__init__.py 2014-12-23 11:24:06.000000000 +0100
+++ scapy-2.3.1/scapy/arch/windows/__init__.py 2015-06-10 10:16:31.945455700 +0200
@@ -109,48 +109,16 @@
def _update_pcapdata(self):
"""Supplement more info from pypcap and the Windows registry"""
- # XXX: We try eth0 - eth29 by bruteforce and match by IP address,
- # because only the IP is available in both pypcap and dnet.
- # This may not work with unorthodox network configurations and is
- # slow because we have to walk through the Windows registry.
- for n in range(30):
- guess = "eth%s" % n
- win_name = pcapdnet.pcap.ex_name(guess)
- if win_name.endswith("}"):
- try:
- uuid = win_name[win_name.index("{"):win_name.index("}")+1]
- keyname = r"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\%s" % uuid
- try:
- key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, keyname)
- except WindowsError:
- log_loading.debug("Couldn't open 'HKEY_LOCAL_MACHINE\\%s' (for guessed pcap iface name '%s')." % (keyname, guess))
- continue
- try:
- fixed_ip = _winreg.QueryValueEx(key, "IPAddress")[0][0].encode("utf-8")
- except (WindowsError, UnicodeDecodeError, IndexError):
- fixed_ip = None
- try:
- dhcp_ip = _winreg.QueryValueEx(key, "DhcpIPAddress")[0].encode("utf-8")
- except (WindowsError, UnicodeDecodeError, IndexError):
- dhcp_ip = None
- # "0.0.0.0" or None means the value is not set (at least not correctly).
- # If both fixed_ip and dhcp_ip are set, fixed_ip takes precedence
- if fixed_ip is not None and fixed_ip != "0.0.0.0":
- ip = fixed_ip
- elif dhcp_ip is not None and dhcp_ip != "0.0.0.0":
- ip = dhcp_ip
- else:
- continue
- except IOError:
- continue
- else:
- if ip == self.ip:
- self.pcap_name = guess
- self.win_name = win_name
- self.uuid = uuid
- break
- else:
+ win_name = pcapdnet.dnet.get_pcap_devname(self.name)
+ if win_name is None:
raise PcapNameNotFoundError
+
+ uuid = win_name[win_name.index("{"):win_name.index("}")+1]
+
+ self.win_name = win_name
+ self.uuid = uuid
+ # use win_name as pcap_name to avoid names mismatch
+ self.pcap_name = self.win_name
def __repr__(self):
return "<%s: %s %s %s pcap_name=%s win_name=%s>" % (self.__class__.__name__,
@@ -166,10 +134,7 @@
for i in pcapdnet.dnet.intf():
try:
# XXX: Only Ethernet for the moment: localhost is not supported by dnet and pcap
- # We only take interfaces that have an IP address, because the IP
- # is used for the mapping between dnet and pcap interface names
- # and this significantly improves Scapy's startup performance
- if i["name"].startswith("eth") and "addr" in i:
+ if i["name"].startswith("eth"):
self.data[i["name"]] = NetworkInterface(i)
except (KeyError, PcapNameNotFoundError):
pass
@@ -183,12 +148,10 @@
This mapping is necessary because pypcap numbers the devices differently."""
- try:
- pcap_name = self.data[devname].pcap_name
- except KeyError:
- raise ValueError("Unknown network interface %r" % devname)
+ if devname is not None:
+ return self.data[devname].pcap_name
else:
- return pcap_name
+ return None
def devname(self, pcap_name):
"""Return libdnet/Scapy device name for given pypcap device name
@@ -313,15 +276,17 @@
import scapy.layers.l2
scapy.layers.l2.getmacbyip = getmacbyip
-try:
- import readline
- console = readline.GetOutputFile()
-except (ImportError, AttributeError):
- log_loading.info("Could not get readline console. Will not interpret ANSI color codes.")
-else:
- conf.readfunc = readline.rl.readline
- orig_stdout = sys.stdout
- sys.stdout = console
+# don't use readline when using scapy non-interactively
+if conf.interactive:
+ try:
+ import readline
+ console = readline.GetOutputFile()
+ except (ImportError, AttributeError):
+ log_loading.info("Could not get readline console. Will not interpret ANSI color codes.")
+ else:
+ conf.readfunc = readline.rl.readline
+ orig_stdout = sys.stdout
+ sys.stdout = console
@@ -472,7 +437,7 @@
import scapy.sendrecv
scapy.sendrecv.sndrcv = sndrcv
-def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, *arg, **karg):
+def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, stop_filter=None, *arg, **karg):
"""Sniff packets
sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets
@@ -487,6 +452,11 @@
offline: pcap file to read packets from, instead of sniffing them
timeout: stop sniffing after a given time (default: None)
L2socket: use the provided L2socket
+stop_filter: python function applied to each packet to determine
+ if we have to stop the capture after this packet
+ (is executed on each loop with None as well
+ to allow stopping sniffing even in case of no packets)
+ ex: stop_filter = lambda x: x.haslayer(TCP) if x else False
"""
c = 0
@@ -501,7 +471,7 @@
if timeout is not None:
stoptime = time.time()+timeout
remain = None
- while 1:
+ while not (stop_filter and stop_filter(None)):
try:
if timeout is not None:
remain = stoptime-time.time()
@@ -523,6 +493,8 @@
r = prn(p)
if r is not None:
print r
+ if stop_filter and stop_filter(p):
+ break
if count > 0 and c >= count:
break
except KeyboardInterrupt:
Pull request submitted for this one (IPPROTO_IPIP unavailable on some platforms) (https://bitbucket.org/secdev/scapy/pull-request/117/add-missing-socketipproto_ipip)
diff -u -r scapy-2.3.1-orig/scapy/layers/inet6.py scapy-2.3.1/scapy/layers/inet6.py
--- scapy-2.3.1-orig/scapy/layers/inet6.py 2014-12-23 11:24:06.000000000 +0100
+++ scapy-2.3.1/scapy/layers/inet6.py 2015-06-10 09:59:52.908562000 +0200
@@ -30,7 +30,10 @@
if not hasattr(socket, "IPPROTO_IPV6"):
# Workaround for http://bugs.python.org/issue6926
socket.IPPROTO_IPV6 = 41
-
+if not hasattr(socket, "IPPROTO_IPIP"):
+ # Workaround for https://bitbucket.org/secdev/scapy/issue/5119
+ socket.IPPROTO_IPIP = 4
+
from scapy.config import conf
from scapy.layers.l2 import *
from scapy.layers.inet import *
Bump up scapy revision, use setuptools instead of distutils to allow wheels creation:
diff -u -r scapy-2.3.1-orig/setup.py scapy-2.3.1/setup.py
--- scapy-2.3.1-orig/setup.py 2014-12-23 11:35:20.000000000 +0100
+++ scapy-2.3.1/setup.py 2015-06-10 09:16:02.039482600 +0200
@@ -6,9 +6,7 @@
from distutils import archive_util
-from distutils import sysconfig
-from distutils.core import setup
-from distutils.command.sdist import sdist
+from setuptools import setup
import os
@@ -46,7 +44,7 @@
setup(
name = 'scapy',
- version = '2.3.1',
+ version = '2.3.1+rg1',
packages=['scapy','scapy/arch', 'scapy/arch/windows', 'scapy/layers','scapy/asn1','scapy/tools','scapy/modules', 'scapy/crypto', 'scapy/contrib'],
scripts = SCRIPTS,
data_files = [('share/man/man1', ["doc/scapy.1.gz"])],
Thanks for the steps to build libdnet library for Windows 64bit. Currently stuck at below error. Could you share this prebuilt libdnet library.
C:\Users\Admin\AppData\Local\Programs\Common\Microsoft\Visual C++ for Python\9.0\VC\Bin\amd64\link.exe /DLL /nologo /INCREMENTAL:NO /LIBPATH:../../WPdpack/Lib /LIBPATH:c:\python27\libs /LIBPATH:c:\python27\PCbuild\amd64 /LIBPATH:c:\python27\PC\VS9.0\amd64 advapi32.lib iphlpapi.lib ws2_32.lib packet.lib wpcap.lib /EXPORT:initdnet build\temp.win-amd64-2.7\Release./dnet.obj build\temp.win-amd64-2.7\Release../src/addr-util.obj build\temp.win-amd64-2.7\Release../src/addr.obj build\temp.win-amd64-2.7\Release../src/blob.obj build\temp.win-amd64-2.7\Release../src/ip-util.obj build\temp.win-amd64-2.7\Release../src/ip6.obj build\temp.win-amd64-2.7\Release../src/rand.obj build\temp.win-amd64-2.7\Release../src/err.obj build\temp.win-amd64-2.7\Release../src/strlcat.obj build\temp.win-amd64-2.7\Release../src/strlcpy.obj build\temp.win-amd64-2.7\Release../src/err.obj build\temp.win-amd64-2.7\Release../src/strlcat.obj build\temp.win-amd64-2.7\Release../src/strlcpy.obj build\temp.win-amd64-2.7\Release../src/strsep.obj build\temp.win-amd64-2.7\Release../src/arp-win32.obj build\temp.win-amd64-2.7\Release../src/eth-win32.obj build\temp.win-amd64-2.7\Release../src/fw-pktfilter.obj build\temp.win-amd64-2.7\Release../src/intf-win32.obj build\temp.win-amd64-2.7\Release../src/ip-win32.obj build\temp.win-amd64-2.7\Release../src/route-win32.obj build\temp.win-amd64-2.7\Release../src/tun-none.obj /OUT:build\lib.win-amd64-2.7\dnet.pyd /IMPLIB:build\temp.win-amd64-2.7\Release.\dnet.lib /MANIFESTFILE:build\temp.win-amd64-2.7\Release.\dnet.pyd.manifest build\temp.win-amd64-2.7\Release../src/err.obj : warning LNK4042: object specified more than once; extras ignored build\temp.win-amd64-2.7\Release../src/strlcat.obj : warning LNK4042: object specified more than once; extras ignored build\temp.win-amd64-2.7\Release../src/strlcpy.obj : warning LNK4042: object specified more than once; extras ignored dnet.obj : warning LNK4197: export 'initdnet' specified multiple times; using first specification Creating library build\temp.win-amd64-2.7\Release.\dnet.lib and object build\temp.win-amd64-2.7\Release.\dnet.exp eth-win32.obj : error LNK2019: unresolved external symbol PacketSendPacket referenced in function eth_send eth-win32.obj : error LNK2019: unresolved external symbol PacketInitPacket referenced in function eth_send eth-win32.obj : error LNK2019: unresolved external symbol PacketCloseAdapter referenced in function eth_close eth-win32.obj : error LNK2019: unresolved external symbol PacketFreePacket referenced in function eth_close eth-win32.obj : error LNK2019: unresolved external symbol PacketRequest referenced in function eth_get eth-win32.obj : error LNK2019: unresolved external symbol PacketAllocatePacket referenced in function eth_open eth-win32.obj : error LNK2019: unresolved external symbol PacketSetBuff referenced in function eth_open eth-win32.obj : error LNK2019: unresolved external symbol PacketOpenAdapter referenced in function eth_open intf-win32.obj : error LNK2019: unresolved external symbol pcap_freealldevs referenced in function intf_get_pcap_devname intf-win32.obj : error LNK2019: unresolved external symbol pcap_findalldevs referenced in function intf_get_pcap_devname build\lib.win-amd64-2.7\dnet.pyd : fatal error LNK1120: 10 unresolved externals error: command 'C:\Users\Admin\AppData\Local\Programs\Common\Microsoft\Visual C++ for Python\9.0\VC\Bin\amd64\link.exe' failed with exit status 1120
Hello,
First of all, thanks for creating this fork. I've ended here after having to fight with the "WARNING: No match between your pcap and dnet network interfaces found." error without success.
So I've tried to build your fork in my Windows 8.1 x64 machine with Python 2.7. I've had a lot of problems and I'd be really grateful if you could help me.
These are the steps I've followed:
autogen.sh
script inside Cygwin, having MinGW also installed. This gave me a lot of trouble, basically for using libtool from MinGW instead of the one from Cygwin. So I uninstalled the one from MinGW and installed the one from Cygwin. After this, theautogen.sh
worked and theconfigure
file was created../configure
and failed when checking for Python, it seemed a MinGW32 issue. So I installed a bunch of MinGW packages of 32 bits such as headers and so. Don't know exactly how, but this solved the problem. Nevertheless, the./configure
failed again. Now the problem was because of winpcap developer library not found. So I executed configure as:./configure --with-wpdpack=<path_to_lib>
cd python
and executed/c/cygdrive/python2.7/python.exe setup.py build
and got this error:First real unsolved problem here. So instead of using OS python.exe I've also tried to use cygwin python. I got this error:
Seems that Python.h is not found, although it's in the
/usr/include/Python2.7
folder. I've added it to PATH withexport PATH="$PATH:/usr/include/python2.7"
but it gave the same error.Then I came back to the
Unable to find vcvarsall.bat
error. Still from cygwin I executed:Ok, this problem about not locating 'cl.exe' is because if you use the OS python.exe and you have not built it, the compiler that was used to build it is used to build the python extension. I've tried to add the location of
cl.exe
folder in path (export PATH="$PATH:/cygwin/c/Program Files (x86)/Microsoft Visual Studio 12.0/VC/bin/x86_amd64"
), but it didn't work.So...Next step was to open
Visual C++ 2008 64-bits Command Prompt
so cl.exe is easily found. I exported the symbols mentioned before and executed:This is the REAL problem. It seems that python already defines the ssize_t type in pyconfig.h. I could remove declarations or make them match. The best approach was to make them match types (modifying
__int64
forlong
) by modifying line 199 of pyconfig.h:This solved the problem of redefinitions, but still remained the
fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory
.I've tried to comment this includes in os.h and intf.h, but it ended up giving me this error after a large number of warnings:
I realised that the lack of stdint.h was because of Microsoft VC 2008 didn't supported some C99 features, so I tried with VC 2013. After removing comments from the stdint.h includes (I also could remove the modification of pyconfig.h) I executed the same command from the
Developer Command Prompt for VS 2013
and got the following (complete) output:Seems that the problem is that
size_t
is already defined asint
so the following code incrtdefs.h
fails:It seems that there's again a redefinition. I've found it in libdnet source at
include/config.h
in line 270:After commenting it, the build process has continued with a lot of warnings until this error:
Given that the libdnet doesn't have any
pcap.h
file, I guess that this file must refer to the winpcap development library. So I try to add the correct directory to theINCLUDE
environment variable withset INCLUDE=%INCLUDE%;<path_to_winpcap_dev>\WpdPack_4_1_2\WpdPack\Include
There are two
pcap.h
files. One in theInclude
directory and another in theInclude\pcap
directory. I've tried to add both of them in the INCLUDE environment, but neither worked. I finally got a long list of new errors:So I'm stuck here and I don't know what else to do. This is a nightmare, guys. How could you build this? I'm defeated....
Thank you very much for reading until here.