ADDED Makefile Index: Makefile ================================================================== --- /dev/null +++ Makefile @@ -0,0 +1,151 @@ +TOOLCHAIN = i686-w64-mingw32 +TOOLCHAIN_CMD = $(TOOLCHAIN)- + +TWAPI_VERSION = 3.1.17 +TWAPI_URL = http://sourceforge.net/projects/twapi/files/Current%20Releases/Tcl%20Windows%20API/twapi-$(TWAPI_VERSION)/twapi-$(TWAPI_VERSION).zip +TWAPI_ZIP = archive/twapi-$(TWAPI_VERSION).zip + +TCPDUMP_VERSION = 4.5.1 +TCPDUMP_URL = http://www.tcpdump.org/release/tcpdump-$(TCPDUMP_VERSION).tar.gz +TCPDUMP_TARBALL = archive/tcpdump-$(TCPDUMP_VERSION).tar.gz + +WINPCAP_DEV_VERSION = 4.1.2 +WINPCAP_DEV_URL = http://www.winpcap.org/install/bin/WpdPack_4_1_2.zip +WINPCAP_DEV_ZIP = archive/winpcap-dev-$(WINPCAP_DEV_VERSION).zip + +WINPCAP_INST_VERSION = 4.1.3 +WINPCAP_INST_URL = http://www.winpcap.org/install/bin/WinPcap_4_1_3.exe +WINPCAP_INST_7ZIP = archive/winpcap-inst-$(WINPCAP_INST_VERSION).exe +WINPCAP_INST_FILES = files/npf32.sys files/npf64.sys files/packet.dll files/pthreadvc.dll files/wpcap.dll + +KITCREATOR_VERSION = 0.7.0 +KITCREATOR_URL = http://www.rkeene.org/devel/kitcreator-$(KITCREATOR_VERSION).tar.gz +KITCREATOR_TARBALL = archive/kitcreator-$(KITCREATOR_VERSION).tar.gz + +# Point to real target +all: tcpdump.exe + +# WinPcap +$(WINPCAP_INST_7ZIP): + @-mkdir -p archive >/dev/null 2>/dev/null + wget --no-use-server-timestamps -O "$(WINPCAP_INST_7ZIP).new" "$(WINPCAP_INST_URL)" + 7z t "$(WINPCAP_INST_7ZIP).new" + mv "$(WINPCAP_INST_7ZIP).new" "$(WINPCAP_INST_7ZIP)" + +$(WINPCAP_INST_FILES): $(WINPCAP_INST_7ZIP) + @-mkdir -p files + rm -rf __TMP_WPCAP__ + mkdir __TMP_WPCAP__ + echo u | ( cd __TMP_WPCAP__ && 7z x ../$(WINPCAP_INST_7ZIP) ) + cp '__TMP_WPCAP__/$$SYSDIR/Packet_4.dll' files/packet.dll + cp '__TMP_WPCAP__/$$SYSDIR/pthreadVC.dll' files/pthreadvc.dll + cp '__TMP_WPCAP__/$$SYSDIR/wpcap.dll' files/wpcap.dll + cp '__TMP_WPCAP__/$$SYSDIR/drivers/npf_1.sys' files/npf64.sys + cp '__TMP_WPCAP__/$$SYSDIR/drivers/npf.sys' files/npf32.sys + rm -rf __TMP_WPCAP__ + +# TCPDUMP +$(TCPDUMP_TARBALL): + @-mkdir -p archive >/dev/null 2>/dev/null + wget --no-use-server-timestamps -O "$(TCPDUMP_TARBALL).new" "$(TCPDUMP_URL)" + gzip -dc "$(TCPDUMP_TARBALL).new" | tar -tf - >/dev/null + mv "$(TCPDUMP_TARBALL).new" "$(TCPDUMP_TARBALL)" + +$(WINPCAP_DEV_ZIP): + @-mkdir -p archive >/dev/null 2>/dev/null + wget --no-use-server-timestamps -O "$(WINPCAP_DEV_ZIP).new" "$(WINPCAP_DEV_URL)" + unzip -l "$(WINPCAP_DEV_ZIP).new" + mv "$(WINPCAP_DEV_ZIP).new" "$(WINPCAP_DEV_ZIP)" + +files/tcpdump.exe: $(TCPDUMP_TARBALL) $(WINPCAP_DEV_ZIP) pcap-config + rm -rf __TMP_TCP__ + mkdir __TMP_TCP__ + ( \ + set -e; \ + cd __TMP_TCP__; \ + gzip -dc ../$(TCPDUMP_TARBALL) | tar -xf -; \ + unzip ../$(WINPCAP_DEV_ZIP); \ + cp ../pcap-config WpdPack/; \ + cd WpdPack; \ + echo '#define pcap_can_set_rfmon(x) 0' >> Include/pcap/pcap.h; \ + echo '#define pcap_set_rfmon(x, y) -1' >> Include/pcap/pcap.h; \ + echo '#define pcap_statustostr(x) ""' >> Include/pcap/pcap.h; \ + cd ../tcpdump-$(TCPDUMP_VERSION); \ + ./configure --without-smi --disable-smb --enable-ipv6 --without-crypto --host=$(TOOLCHAIN) PCAP_CONFIG="$$(pwd)/../WpdPack/pcap-config" LIBS='-lws2_32' CFLAGS='-D_WIN32_WINNT=0x0501' CPPFLAGS='-D_WIN32_WINNT=0x0501' ac_cv_func_getnameinfo='yes'; \ + sed -i 's@Ws2tcpip\.h@ws2tcpip.h@' tcpdump-stdinc.h; \ + grep -v '^# *define.*UNALIGNED' tcpdump-stdinc.h | \ + grep -v '' > tcpdump-stdinc.h.new && mv tcpdump-stdinc.h.new tcpdump-stdinc.h; \ + echo '#define HAVE_SOCKADDR_STORAGE 1' >> config.h; \ + echo '#define HAVE_U_INT8_T 1' >> config.h; \ + echo '#define HAVE_U_INT16_T 1' >> config.h; \ + echo '#define HAVE_U_INT32_T 1' >> config.h; \ + echo '#define HAVE_U_INT64_T 1' >> config.h; \ + echo '#define HAVE_INT8_T 1' >> config.h; \ + echo '#define HAVE_INT16_T 1' >> config.h; \ + echo '#define HAVE_INT32_T 1' >> config.h; \ + echo '#define HAVE_INT64_T 1' >> config.h; \ + echo '#define HAVE_GENERATED_VERSION 1' >> config.h; \ + echo '#define IN6_IS_ADDR_UNSPECIFIED IN6_IS_ADDR_UNSPECIFIED' >> config.h; \ + echo '#undef HAVE_ALARM' >> config.h; \ + grep -v '^# *define *inline' config.h > config.h.new && mv config.h.new config.h; \ + make; \ + ) + @-mkdir -p files + cp __TMP_TCP__/tcpdump-$(TCPDUMP_VERSION)/tcpdump files/tcpdump.exe.new + $(TOOLCHAIN_CMD)strip files/tcpdump.exe.new + mv files/tcpdump.exe.new files/tcpdump.exe + rm -rf __TMP_TCP__ + +# TWAPI (TCL Windows API) +$(TWAPI_ZIP): + @-mkdir -p archive >/dev/null 2>/dev/null + wget --no-use-server-timestamps -O "$(TWAPI_ZIP).new" "$(TWAPI_URL)" + unzip -l "$(TWAPI_ZIP).new" + mv "$(TWAPI_ZIP).new" "$(TWAPI_ZIP)" + +# Tclkit +$(KITCREATOR_TARBALL): + @-mkdir -p archive >/dev/null 2>/dev/null + wget --no-use-server-timestamps -O "$(KITCREATOR_TARBALL).new" "$(KITCREATOR_URL)" + gzip -dc "$(KITCREATOR_TARBALL).new" | tar -tf - >/dev/null + mv "$(KITCREATOR_TARBALL).new" "$(KITCREATOR_TARBALL)" + +tclkit-zip: $(KITCREATOR_TARBALL) + rm -rf kitcreator-$(KITCREATOR_VERSION) + gzip -dc "$(KITCREATOR_TARBALL)" | tar -xf - + cd kitcreator-$(KITCREATOR_VERSION) && KITCREATOR_PKGS=' ' AR=$(TOOLCHAIN_CMD)ar CC=$(TOOLCHAIN_CMD)gcc ./kitcreator 8.5.15 --host=$(TOOLCHAIN) --enable-kit-storage=zip + cp kitcreator-$(KITCREATOR_VERSION)/tclkit-8.5.15 tclkit-zip.new + mv tclkit-zip.new tclkit-zip + rm -rf kitcreator-$(KITCREATOR_VERSION) + +# The wrapper +## Split Tclkit header from zip file contents +tcpdump.exe.bin: tclkit-zip + cp tclkit-zip tcpdump.exe.bin + strip tcpdump.exe.bin + +## Merge Tclkit zip file with TWAPI and re-combine +tcpdump.exe: main.tcl tclkit-zip tcpdump.exe.bin files/tcpdump.exe $(WINPCAP_INST_FILES) $(TWAPI_ZIP) + rm -f tcpdump.exe.zip + cp tclkit-zip tcpdump.exe.zip + zip -J -A -r -u tcpdump.exe.zip files main.tcl + zipmerge tcpdump.exe.zip $(TWAPI_ZIP) + cat tcpdump.exe.bin tcpdump.exe.zip > tcpdump.exe.new + mv tcpdump.exe.new tcpdump.exe + rm -f tcpdump.exe.zip + zip -A tcpdump.exe + +# Cleanup +clean: + rm -f tcpdump.exe.zip tcpdump.exe.bin tcpdump.exe.new tcpdump.exe + rm -rf kitcreator-$(KITCREATOR_VERSION) + rm -rf __TMP_TCP__ __TMP_WPCAP__ + +distclean: clean + rm -f "$(TWAPI_ZIP)" "$(TCPDUMP_TARBALL)" "$(WINPCAP_DEV_ZIP)" "$(KITCREATOR_TARBALL)" "$(WINPCAP_INST_7ZIP)" + rm -f "$(TWAPI_ZIP).new" "$(TCPDUMP_TARBALL).new" "$(WINPCAP_DEV_ZIP).new" "$(KITCREATOR_TARBALL).new" "$(WINPCAP_INST_7ZIP).new" + rm -f $(WINPCAP_INST_FILES) + rm -f tclkit-zip files/tcpdump.exe + -rmdir archive files + +.PHONY: all clean distclean ADDED main.tcl Index: main.tcl ================================================================== --- /dev/null +++ main.tcl @@ -0,0 +1,162 @@ +#! /usr/bin/env tclsh + +package require starkit +starkit::startup + +lappend auto_path [file join $::starkit::topdir twapi] + +package require twapi + +# http://blogs.msdn.com/b/david.wang/archive/2006/03/26/howto-detect-process-bitness.aspx +if {[info exists ::env(PROCESSOR_ARCHITEW6432)]} { + set arch $::env(PROCESSOR_ARCHITEW6432) +} else { + if {[info exists ::env(PROCESSOR_ARCHITECTURE)]} { + set arch $::env(PROCESSOR_ARCHITECTURE) + } else { + set arch "x86" + } +} +switch -- [string tolower $arch] { + "x86" { + set bits "32" + } + default { + set bits "64" + } +} + +# Determine temp directory +if {[info exists ::env(TEMP)]} { + set tmpdir $::env(TEMP) +} elseif {[info exists ::env(TMPDIR)]} { + set tmpdir $::env(TMPDIR) +} else { + if {$tcl_platform(platform) == "windows"} { + set tmpdir {C:/TEMP} + } else { + set tmpdir /tmp + } +} +set tmpdir "C:/TEMP" + +# Determine interface to lookup +set dest_parm_idx [lsearch -exact $argv "-i"] +if {$dest_parm_idx != -1} { + incr dest_parm_idx + + set dest_chk [lindex $argv $dest_parm_idx] + if {[string match "*.*.*.*" $dest_chk] || [string match "*:*:*" $dest_chk]} { + set dest $dest_chk + + ## Determine the index to specified destination + set iface_idx 1 + catch { + set iface_idx [::twapi::get_outgoing_interface $dest] + } + if {$iface_idx == ""} { + set iface_idx 1 + } + + ## Determine the NPF name for the adapter found above + set iface_adapter [lindex [::twapi::get_netif_info $iface_idx -adaptername] 1] + set iface_npf "\\Device\\NPF_${iface_adapter}" + + set argv [lreplace $argv $dest_parm_idx $dest_parm_idx $iface_npf] + } +} + +# Copy files neeed to temporary directory +for {set i 0} {$i < 20} {incr i} { + append random_bin [format %c [expr {int(rand() * 256)}]] +} +binary scan $random_bin H* random + +set srcdir [file join $::starkit::topdir files] +set dstdir [file join $tmpdir tcpdmp-$random] + +file delete -force -- $dstdir + +# Run tcpdump +set exit 1 +set start_npf_service 0 +set npf_failed 0 +if {[catch { + set filesdir [file join $dstdir files] + + exec cmd /c mkdir [file nativename $dstdir] + exec cmd /c mkdir [file nativename $filesdir] + + file copy -- {*}[glob -directory $srcdir *] $filesdir + + ## Delete extraneous service + if {[::twapi::service_exists npf]} { + if {![catch { + ::twapi::stop_service npf + }]} { + set start_npf_service 1 + } + } + + catch { + ::twapi::stop_service npf_tcpdump + } + + catch { + ::twapi::delete_service npf_tcpdump + } + + ## Install driver and start service + if {[catch { + set driver [file join $filesdir npf${bits}.sys] + set driver [file nativename $driver] + ::twapi::create_service npf_tcpdump $driver -displayname "NPF for TCPDUMP (ignore)" -servicetype kernel_driver -starttype demand_start -errorcontrol ignore + +puts [exec net start npf_tcpdump] + ::twapi::start_service npf_tcpdump +puts [exec net start npf_tcpdump] + } npf_err]} { + set npf_failed 1 + } + + after 5000 + + ## Launch tcpdump with the apropriate parameters + #puts [list exec -- [file join $filesdir tcpdump.exe] {*}$argv] + exec -- [file join $filesdir tcpdump.exe] {*}$argv >&@ stdout + + set exit 0 +} err]} { + if {$npf_failed} { + puts "NPF Failed: $npf_err" + } + + puts "Failed: $::errorInfo" + + set exit 1 +} + +# Debug +puts [exec net stop npf_tcpdump] +puts [exec net start npf_tcpdump] + +# Cleanup +catch { + ::twapi::stop_service npf_tcpdump +} +catch { + ::twapi::delete_service npf_tcpdump +} + +if {$start_npf_service} { + catch { + ::twapi::start_service npf + } +} + +catch { + file delete -force -- $dstdir +} + +# Terminate +exit $exit ADDED pcap-config Index: pcap-config ================================================================== --- /dev/null +++ pcap-config @@ -0,0 +1,21 @@ +#! /bin/bash + +opt="$1" + +ourdir="$(dirname "$(readlink -f "$(which "$0")")")" + +case "$opt" in + --cflags) + echo "-Iwin32/Include -I${ourdir}/Include" + + ;; + --libs) + echo "-L${ourdir}/Lib -lwpcap -lws2_32" + ;; + *) + echo "Unknown option: $opt" >&2 + exit 1 + ;; +esac + +exit 0