From 6eca0cba10aa25c7ef7a21dc5ad65e09f24fec46 Mon Sep 17 00:00:00 2001 From: chongyc Date: Wed, 25 Jun 2008 19:50:03 +0800 Subject: [PATCH] add winpcap 4.0.2 from url http://www.winpcap.org/ --- winpcap/Common/Devioctl.h | 90 + winpcap/Common/Ntddndis.h | 1400 ++++ winpcap/Common/Ntddpack.h | 26 + winpcap/Common/Packet32.h | 405 + winpcap/Common/WpcapNames.h | 83 + winpcap/Common/dagc.h | 225 + winpcap/Examples-pcap/GNUmakefile | 10 + winpcap/Examples-pcap/MakeaAll.dsw | 137 + winpcap/Examples-pcap/UDPdump/GNUmakefile | 17 + winpcap/Examples-pcap/UDPdump/UDPdump.dsp | 110 + winpcap/Examples-pcap/UDPdump/UDPdump.dsw | 29 + winpcap/Examples-pcap/UDPdump/udpdump.c | 230 + winpcap/Examples-pcap/basic_dump/GNUmakefile | 17 + winpcap/Examples-pcap/basic_dump/basic_dump.c | 95 + winpcap/Examples-pcap/basic_dump/basic_dump.dsp | 110 + winpcap/Examples-pcap/basic_dump/basic_dump.dsw | 29 + winpcap/Examples-pcap/basic_dump_ex/GNUmakefile | 17 + .../Examples-pcap/basic_dump_ex/basic_dump_ex.c | 99 + .../Examples-pcap/basic_dump_ex/basic_dump_ex.dsp | 110 + .../Examples-pcap/basic_dump_ex/basic_dump_ex.dsw | 29 + winpcap/Examples-pcap/iflist/GNUmakefile | 17 + winpcap/Examples-pcap/iflist/iflist.c | 165 + winpcap/Examples-pcap/iflist/iflist.dsp | 110 + winpcap/Examples-pcap/iflist/iflist.dsw | 29 + winpcap/Examples-pcap/pcap_filter/GNUmakefile | 17 + winpcap/Examples-pcap/pcap_filter/Makefile.unix | 9 + winpcap/Examples-pcap/pcap_filter/pcap_filter.c | 179 + winpcap/Examples-pcap/pcap_filter/pcap_filter.dsp | 110 + winpcap/Examples-pcap/pcap_filter/pcap_filter.dsw | 29 + winpcap/Examples-pcap/pktdump_ex/GNUmakefile | 14 + winpcap/Examples-pcap/pktdump_ex/pktdump_ex.c | 159 + winpcap/Examples-pcap/pktdump_ex/pktdump_ex.dsp | 110 + winpcap/Examples-pcap/pktdump_ex/pktdump_ex.dsw | 29 + winpcap/Examples-pcap/readfile/GNUmakefile | 17 + winpcap/Examples-pcap/readfile/readfile.c | 56 + winpcap/Examples-pcap/readfile/readfile.dsp | 110 + winpcap/Examples-pcap/readfile/readfile.dsw | 29 + winpcap/Examples-pcap/readfile_ex/GNUmakefile | 17 + winpcap/Examples-pcap/readfile_ex/readfile_ex.c | 56 + winpcap/Examples-pcap/readfile_ex/readfile_ex.dsp | 110 + winpcap/Examples-pcap/readfile_ex/readfile_ex.dsw | 29 + winpcap/Examples-pcap/savedump/GNUmakefile | 17 + winpcap/Examples-pcap/savedump/savedump.c | 103 + winpcap/Examples-pcap/savedump/savedump.dsp | 110 + winpcap/Examples-pcap/savedump/savedump.dsw | 29 + winpcap/Examples-pcap/sendpack/GNUmakefile | 17 + winpcap/Examples-pcap/sendpack/sendpack.c | 68 + winpcap/Examples-pcap/sendpack/sendpack.dsp | 110 + winpcap/Examples-pcap/sendpack/sendpack.dsw | 29 + winpcap/Examples-pcap/stats/stats.c | 174 + winpcap/Examples-pcap/stats/stats.dsp | 110 + winpcap/Examples-pcap/stats/stats.dsw | 29 + .../Examples-pcap/winpcap_stress/winpcap_stress.c | 498 ++ .../winpcap_stress/winpcap_stress.dsp | 106 + .../winpcap_stress/winpcap_stress.dsw | 29 + winpcap/Examples/MakeaAll.dsw | 221 + winpcap/Examples/NETMETER/CapDll.h | 96 + winpcap/Examples/NETMETER/CaptureThread.cpp | 89 + winpcap/Examples/NETMETER/Console.h | 45 + winpcap/Examples/NETMETER/LineColl.cpp | 107 + winpcap/Examples/NETMETER/LineColl.h | 61 + winpcap/Examples/NETMETER/MainFrm.cpp | 92 + winpcap/Examples/NETMETER/MainFrm.h | 85 + winpcap/Examples/NETMETER/NETMETER.CPP | 161 + winpcap/Examples/NETMETER/NETMETER.H | 80 + winpcap/Examples/NETMETER/ProgCaptDlg.h | 95 + winpcap/Examples/NETMETER/SelectAdapter.cpp | 245 + winpcap/Examples/NETMETER/SelectAdapter.h | 93 + winpcap/Examples/NETMETER/StdAfx.cpp | 41 + winpcap/Examples/NETMETER/StdAfx.h | 26 + winpcap/Examples/NETMETER/netmeter.dsp | 238 + winpcap/Examples/NETMETER/netmeter.dsw | 29 + winpcap/Examples/NETMETER/netmeter.rc | 407 + winpcap/Examples/NETMETER/netmeterDoc.cpp | 105 + winpcap/Examples/NETMETER/netmeterDoc.h | 88 + winpcap/Examples/NETMETER/netmeterView.cpp | 393 + winpcap/Examples/NETMETER/netmeterView.h | 107 + winpcap/Examples/NETMETER/res/BMP00001.BMP | Bin 0 -> 214 bytes winpcap/Examples/NETMETER/res/bitmap1.bmp | Bin 0 -> 214 bytes winpcap/Examples/NETMETER/res/bitmap2.bmp | Bin 0 -> 214 bytes winpcap/Examples/NETMETER/res/cap_wizi.bmp | Bin 0 -> 598 bytes winpcap/Examples/NETMETER/res/listbmp.bmp | Bin 0 -> 1318 bytes winpcap/Examples/NETMETER/res/netmeter.ico | Bin 0 -> 1078 bytes winpcap/Examples/NETMETER/res/netmeter.rc2 | 13 + winpcap/Examples/NETMETER/res/netmeterDoc.ico | Bin 0 -> 1078 bytes winpcap/Examples/NETMETER/resource.h | 26 + .../PacketDriver/GetMacAddress/GetMacAddress.c | 152 + .../PacketDriver/GetMacAddress/GetMacAddress.dsp | 105 + .../TestPacketCapture/TestPacketCapture.c | 244 + .../TestPacketCapture/TestPacketCapture.dsp | 105 + .../PacketDriver/TestPacketSend/TestPacketSend.c | 235 + .../PacketDriver/TestPacketSend/TestPacketSend.dsp | 107 + winpcap/Examples/PacketDriver/readme.txt | 2 + winpcap/Examples/UDPdump/UDPdump.dsp | 110 + winpcap/Examples/UDPdump/UDPdump.dsw | 29 + winpcap/Examples/UDPdump/udpdump.c | 225 + winpcap/Examples/UserLevelBridge/UserBridge.c | 466 ++ winpcap/Examples/UserLevelBridge/UserBridge.dsp | 106 + winpcap/Examples/UserLevelBridge/UserBridge.dsw | 29 + winpcap/Examples/iflist/iflist.c | 174 + winpcap/Examples/iflist/iflist.dsp | 110 + winpcap/Examples/iflist/iflist.dsw | 29 + winpcap/Examples/kdump/kdump.c | 131 + winpcap/Examples/kdump/kdump.dsp | 110 + winpcap/Examples/kdump/kdump.dsw | 29 + winpcap/Examples/kdump/kdump.exe | Bin 0 -> 32768 bytes winpcap/Examples/misc/MakeaAll.dsw | 89 + winpcap/Examples/misc/basic_dump.c | 94 + winpcap/Examples/misc/basic_dump.dsp | 110 + winpcap/Examples/misc/basic_dump_ex.c | 99 + winpcap/Examples/misc/basic_dump_ex.dsp | 110 + winpcap/Examples/misc/readfile.c | 73 + winpcap/Examples/misc/readfile.dsp | 110 + winpcap/Examples/misc/readfile_ex.c | 73 + winpcap/Examples/misc/readfile_ex.dsp | 110 + winpcap/Examples/misc/savedump.c | 104 + winpcap/Examples/misc/savedump.dsp | 110 + winpcap/Examples/misc/sendpack.c | 64 + winpcap/Examples/misc/sendpack.dsp | 110 + winpcap/Examples/pcap_filter/pcap_filter.c | 169 + winpcap/Examples/pcap_filter/pcap_filter.dsp | 110 + winpcap/Examples/pcap_filter/pcap_filter.dsw | 29 + winpcap/Examples/pktdump_ex/pktdump_ex.c | 163 + winpcap/Examples/pktdump_ex/pktdump_ex.dsp | 110 + winpcap/Examples/pktdump_ex/pktdump_ex.dsw | 29 + winpcap/Examples/sendcap/sencap.dsw | 29 + winpcap/Examples/sendcap/sendcap.c | 184 + winpcap/Examples/sendcap/sendcap.dsp | 110 + winpcap/Examples/smp_1/smp_1.c | 135 + winpcap/Examples/smp_1/smp_1.dsp | 102 + winpcap/Examples/smp_1/smp_1.dsw | 29 + winpcap/Examples/tcptop/tcptop.c | 158 + winpcap/Examples/tcptop/tcptop.dsp | 110 + winpcap/Examples/tcptop/tcptop.dsw | 29 + winpcap/Packet9x/DLL/Packet.def | 41 + winpcap/Packet9x/DLL/Packet32.c | 1234 +++ winpcap/Packet9x/DLL/Project/GNUmakefile | 23 + winpcap/Packet9x/DLL/Project/Packet.dsp | 161 + winpcap/Packet9x/DLL/Project/Packet.dsw | 29 + winpcap/Packet9x/DLL/version.rc | 64 + winpcap/Packet9x/DLL/version.rc2 | 45 + winpcap/Packet9x/VXD/DEVIOCTL.H | 90 + winpcap/Packet9x/VXD/Debug.h | 68 + winpcap/Packet9x/VXD/Functs.asm | 84 + winpcap/Packet9x/VXD/Lock.c | 274 + winpcap/Packet9x/VXD/MAKEFILE | 39 + winpcap/Packet9x/VXD/NPF.def | 31 + winpcap/Packet9x/VXD/NPF.rc | 43 + winpcap/Packet9x/VXD/Ndis.mk | 181 + winpcap/Packet9x/VXD/Ndisdev.asm | 79 + winpcap/Packet9x/VXD/Ntddpack.h | 26 + winpcap/Packet9x/VXD/Openclos.c | 668 ++ winpcap/Packet9x/VXD/Packet.c | 709 ++ winpcap/Packet9x/VXD/Packet.h | 375 + winpcap/Packet9x/VXD/Read.c | 769 ++ winpcap/Packet9x/VXD/Request.c | 219 + winpcap/Packet9x/VXD/Vpacket.rc | 43 + winpcap/Packet9x/VXD/Write.c | 105 + winpcap/Packet9x/VXD/win_Bpf.h | 353 + winpcap/Packet9x/VXD/win_bpf_filter.c | 758 ++ winpcap/build_wpdpack.bat | 11 + winpcap/build_wpdpack.txt | 16 + winpcap/create_docs.bat | 25 + winpcap/create_examples.bat | 37 + winpcap/create_include.bat | 34 + winpcap/create_lib.bat | 20 + winpcap/createdoc.bat | 12 + winpcap/dox/WinPcap_docs.html | 9 + winpcap/dox/compile.htm | 243 + winpcap/dox/doxygen_groups.txt | 105 + winpcap/dox/doxygen_groups_packetdll.txt | 114 + winpcap/dox/footer.htm | 5 + winpcap/dox/internals-arch.gif | Bin 0 -> 4650 bytes winpcap/dox/internals.htm | 63 + winpcap/dox/intro.htm | 157 + winpcap/dox/language.htm | 600 ++ winpcap/dox/libpcap/funcs/pcap.h | 1250 +++ winpcap/dox/libpcap/incs/pcap.h | 185 + winpcap/dox/main.txt | 51 + winpcap/dox/main_packetdll.txt | 55 + winpcap/dox/note.txt | 27 + winpcap/dox/npf-dump.gif | Bin 0 -> 4656 bytes winpcap/dox/npf-ndis.gif | Bin 0 -> 3572 bytes winpcap/dox/npf-npf.gif | Bin 0 -> 8463 bytes winpcap/dox/npf.htm | 262 + winpcap/dox/packet.htm | 54 + winpcap/dox/packet_samp.htm | 59 + winpcap/dox/pics/dump.gif | Bin 0 -> 6353 bytes winpcap/dox/pics/encoding.gif | Bin 0 -> 2777 bytes winpcap/dox/pics/stats.gif | Bin 0 -> 5431 bytes winpcap/dox/pics/stats_wpcap.gif | Bin 0 -> 5267 bytes winpcap/dox/pics/winpcap.gif | Bin 0 -> 10723 bytes winpcap/dox/pics/winpcap_small.gif | Bin 0 -> 2160 bytes winpcap/dox/prj/winpcap_c.dox | 228 + winpcap/dox/prj/winpcap_c_packetdll.dox | 244 + winpcap/dox/prj/winpcap_noc.dox | 204 + winpcap/dox/slides.ppt | Bin 0 -> 31744 bytes winpcap/dox/style.css | 360 + winpcap/dox/wpcap.htm | 45 + winpcap/dox/wpcap_remote.htm | 350 + winpcap/dox/wpcap_samp.htm | 59 + winpcap/dox/wpcap_samp1.htm | 22 + winpcap/dox/wpcap_samp2.htm | 29 + winpcap/dox/wpcap_tut.txt | 17 + winpcap/dox/wpcap_tut1.txt | 77 + winpcap/dox/wpcap_tut2.txt | 21 + winpcap/dox/wpcap_tut3.txt | 31 + winpcap/dox/wpcap_tut4.txt | 27 + winpcap/dox/wpcap_tut5.txt | 50 + winpcap/dox/wpcap_tut6.txt | 48 + winpcap/dox/wpcap_tut7.txt | 67 + winpcap/dox/wpcap_tut8.txt | 59 + winpcap/dox/wpcap_tut9.txt | 52 + winpcap/packetNtx/Compile2k.bat | 28 + winpcap/packetNtx/CompileDriver.bat | 118 + winpcap/packetNtx/CompileNT4.bat | 24 + winpcap/packetNtx/DIRS | 2 + winpcap/packetNtx/Dll/AdInfo.c | 2157 +++++ winpcap/packetNtx/Dll/NpfImExt.c | 96 + winpcap/packetNtx/Dll/NpfImExt.h | 164 + winpcap/packetNtx/Dll/Packet.def | 35 + winpcap/packetNtx/Dll/Packet32-Int.h | 93 + winpcap/packetNtx/Dll/Packet32.c | 3862 +++++++++ winpcap/packetNtx/Dll/Project/GNUmakefile | 23 + winpcap/packetNtx/Dll/Project/Packet.dsp | 590 ++ winpcap/packetNtx/Dll/Project/Packet.dsw | 44 + winpcap/packetNtx/Dll/WanPacket/WanPacket.cpp | 979 +++ winpcap/packetNtx/Dll/WanPacket/WanPacket.def | 13 + winpcap/packetNtx/Dll/WanPacket/WanPacket.dsp | 202 + winpcap/packetNtx/Dll/WanPacket/WanPacket.dsw | 29 + winpcap/packetNtx/Dll/WanPacket/WanPacket.h | 71 + winpcap/packetNtx/Dll/WanPacket/version.rc | 64 + winpcap/packetNtx/Dll/WanPacket/version.rc2 | 45 + winpcap/packetNtx/Dll/debug.h | 229 + winpcap/packetNtx/Dll/strsafe.h | 78 + winpcap/packetNtx/Dll/version.rc | 64 + winpcap/packetNtx/Dll/version.rc2 | 51 + winpcap/packetNtx/driver/DEBUG.H | 108 + winpcap/packetNtx/driver/MAKEFILE | 7 + winpcap/packetNtx/driver/NPF.RC | 48 + winpcap/packetNtx/driver/Openclos.c | 894 +++ winpcap/packetNtx/driver/Packet.c | 2071 +++++ winpcap/packetNtx/driver/Packet.h | 1042 +++ winpcap/packetNtx/driver/Read.c | 987 +++ winpcap/packetNtx/driver/Sources | 20 + .../driver/WinPcap NTx Driver_2003.vcproj | 163 + winpcap/packetNtx/driver/Write.c | 597 ++ winpcap/packetNtx/driver/bucket_lookup.c | 268 + winpcap/packetNtx/driver/bucket_lookup.h | 54 + winpcap/packetNtx/driver/count_packets.c | 69 + winpcap/packetNtx/driver/count_packets.h | 62 + winpcap/packetNtx/driver/dump.c | 588 ++ winpcap/packetNtx/driver/functions.c | 89 + winpcap/packetNtx/driver/functions.h | 78 + winpcap/packetNtx/driver/jitter.c | 684 ++ winpcap/packetNtx/driver/jitter.h | 387 + winpcap/packetNtx/driver/memory_t.h | 133 + winpcap/packetNtx/driver/normal_lookup.c | 202 + winpcap/packetNtx/driver/normal_lookup.h | 56 + winpcap/packetNtx/driver/resource.h | 15 + winpcap/packetNtx/driver/tcp_session.c | 294 + winpcap/packetNtx/driver/tcp_session.h | 96 + winpcap/packetNtx/driver/time_calls.h | 485 ++ winpcap/packetNtx/driver/tme.c | 390 + winpcap/packetNtx/driver/tme.h | 176 + winpcap/packetNtx/driver/valid_insns.h | 117 + winpcap/packetNtx/driver/win_bpf.h | 417 + winpcap/packetNtx/driver/win_bpf_filter.c | 1138 +++ winpcap/packetNtx/driver/win_bpf_filter_init.c | 514 ++ winpcap/packetNtx/driver/win_bpf_filter_init.h | 50 + winpcap/readme-cygwin | 24 + winpcap/readme-visualC | 199 + winpcap/todo.txt | 3 + winpcap/version.h | 35 + winpcap/wpcap/PRJ/GNUmakefile | 85 + winpcap/wpcap/PRJ/WPCAP.DEF | 86 + winpcap/wpcap/PRJ/WPCAP.dsw | 59 + winpcap/wpcap/PRJ/Wpcap_no_extensions.def | 77 + winpcap/wpcap/PRJ/build_scanner_parser.bat | 26 + winpcap/wpcap/PRJ/wpcap.dsp | 501 ++ winpcap/wpcap/Win32-Extensions/Win32-Extensions.c | 380 + winpcap/wpcap/Win32-Extensions/Win32-Extensions.h | 113 + winpcap/wpcap/Win32-Extensions/version.aps | Bin 0 -> 32508 bytes winpcap/wpcap/Win32-Extensions/version.rc | 64 + winpcap/wpcap/Win32-Extensions/version.rc2 | 45 + winpcap/wpcap/libpcap/CHANGES | 431 + winpcap/wpcap/libpcap/CREDITS | 103 + winpcap/wpcap/libpcap/ChmodBPF/ChmodBPF | 33 + .../wpcap/libpcap/ChmodBPF/StartupParameters.plist | 4 + winpcap/wpcap/libpcap/FILES | 125 + winpcap/wpcap/libpcap/INSTALL.txt | 383 + winpcap/wpcap/libpcap/LICENSE | 19 + winpcap/wpcap/libpcap/Makefile.in | 244 + winpcap/wpcap/libpcap/README | 94 + winpcap/wpcap/libpcap/README.Win32 | 46 + winpcap/wpcap/libpcap/README.aix | 78 + winpcap/wpcap/libpcap/README.dag | 114 + winpcap/wpcap/libpcap/README.hpux | 254 + winpcap/wpcap/libpcap/README.linux | 88 + winpcap/wpcap/libpcap/README.macosx | 43 + winpcap/wpcap/libpcap/README.septel | 50 + winpcap/wpcap/libpcap/README.tru64 | 49 + winpcap/wpcap/libpcap/SUNOS4/nit_if.o.sparc | Bin 0 -> 5212 bytes winpcap/wpcap/libpcap/SUNOS4/nit_if.o.sun3 | Bin 0 -> 4267 bytes winpcap/wpcap/libpcap/SUNOS4/nit_if.o.sun4c.4.0.3c | Bin 0 -> 5291 bytes winpcap/wpcap/libpcap/TODO | 42 + winpcap/wpcap/libpcap/VERSION | 1 + winpcap/wpcap/libpcap/Win32/Include/Gnuc.h | 46 + winpcap/wpcap/libpcap/Win32/Include/addrinfo.h | 122 + winpcap/wpcap/libpcap/Win32/Include/arpa/nameser.h | 349 + winpcap/wpcap/libpcap/Win32/Include/bittypes.h | 135 + winpcap/wpcap/libpcap/Win32/Include/cdecl_ext.h | 37 + winpcap/wpcap/libpcap/Win32/Include/inetprivate.h | 67 + winpcap/wpcap/libpcap/Win32/Include/ip6_misc.h | 165 + winpcap/wpcap/libpcap/Win32/Include/net/if.h | 230 + winpcap/wpcap/libpcap/Win32/Include/net/netdb.h | 164 + winpcap/wpcap/libpcap/Win32/Include/net/paths.h | 105 + winpcap/wpcap/libpcap/Win32/Include/sockstorage.h | 38 + winpcap/wpcap/libpcap/Win32/Prj/libpcap.dsp | 218 + winpcap/wpcap/libpcap/Win32/Prj/libpcap.dsw | 29 + winpcap/wpcap/libpcap/Win32/Src/ffs.c | 54 + winpcap/wpcap/libpcap/Win32/Src/gai_strerror.c | 77 + winpcap/wpcap/libpcap/Win32/Src/getaddrinfo.c | 1119 +++ winpcap/wpcap/libpcap/Win32/Src/getnetbynm.c | 44 + winpcap/wpcap/libpcap/Win32/Src/getnetent.c | 119 + winpcap/wpcap/libpcap/Win32/Src/getopt.c | 121 + winpcap/wpcap/libpcap/Win32/Src/getservent.c | 125 + winpcap/wpcap/libpcap/Win32/Src/inet_aton.c | 61 + winpcap/wpcap/libpcap/Win32/Src/inet_net.c | 101 + winpcap/wpcap/libpcap/Win32/Src/inet_pton.c | 69 + winpcap/wpcap/libpcap/acconfig.h | 7 + winpcap/wpcap/libpcap/aclocal.m4 | 900 +++ winpcap/wpcap/libpcap/arcnet.h | 52 + winpcap/wpcap/libpcap/atmuni31.h | 87 + winpcap/wpcap/libpcap/bpf/net/bpf_filter.c | 565 ++ winpcap/wpcap/libpcap/bpf_dump.c | 62 + winpcap/wpcap/libpcap/bpf_image.c | 288 + winpcap/wpcap/libpcap/config.guess | 1429 ++++ winpcap/wpcap/libpcap/config.h.in | 189 + winpcap/wpcap/libpcap/config.sub | 1531 ++++ winpcap/wpcap/libpcap/configure | 8409 ++++++++++++++++++++ winpcap/wpcap/libpcap/configure.in | 852 ++ winpcap/wpcap/libpcap/doc/pcap.html | 997 +++ winpcap/wpcap/libpcap/doc/pcap.txt | 1680 ++++ winpcap/wpcap/libpcap/doc/pcap.xml | 746 ++ winpcap/wpcap/libpcap/etherent.c | 162 + winpcap/wpcap/libpcap/ethertype.h | 119 + winpcap/wpcap/libpcap/fad-getad.c | 284 + winpcap/wpcap/libpcap/fad-gifc.c | 578 ++ winpcap/wpcap/libpcap/fad-glifc.c | 386 + winpcap/wpcap/libpcap/fad-null.c | 65 + winpcap/wpcap/libpcap/fad-win32.c | 318 + winpcap/wpcap/libpcap/gencode.c | 6944 ++++++++++++++++ winpcap/wpcap/libpcap/gencode.h | 326 + winpcap/wpcap/libpcap/grammar.c | 2919 +++++++ winpcap/wpcap/libpcap/grammar.y | 465 ++ winpcap/wpcap/libpcap/inet.c | 750 ++ winpcap/wpcap/libpcap/install-sh | 250 + winpcap/wpcap/libpcap/lbl/os-aix4.h | 25 + winpcap/wpcap/libpcap/lbl/os-hpux11.h | 25 + winpcap/wpcap/libpcap/lbl/os-osf4.h | 28 + winpcap/wpcap/libpcap/lbl/os-osf5.h | 32 + winpcap/wpcap/libpcap/lbl/os-solaris2.h | 26 + winpcap/wpcap/libpcap/lbl/os-sunos4.h | 215 + winpcap/wpcap/libpcap/lbl/os-ultrix4.h | 39 + winpcap/wpcap/libpcap/llc.h | 69 + winpcap/wpcap/libpcap/missing/snprintf.c | 632 ++ winpcap/wpcap/libpcap/mkdep | 109 + winpcap/wpcap/libpcap/msdos/bin2c.c | 43 + winpcap/wpcap/libpcap/msdos/common.dj | 80 + winpcap/wpcap/libpcap/msdos/makefile | 184 + winpcap/wpcap/libpcap/msdos/makefile.dj | 152 + winpcap/wpcap/libpcap/msdos/makefile.wc | 131 + winpcap/wpcap/libpcap/msdos/ndis2.c | 860 ++ winpcap/wpcap/libpcap/msdos/ndis2.h | 559 ++ winpcap/wpcap/libpcap/msdos/ndis_0.asm | 188 + winpcap/wpcap/libpcap/msdos/pkt_rx0.asm | 197 + winpcap/wpcap/libpcap/msdos/pkt_rx1.s | 155 + winpcap/wpcap/libpcap/msdos/pktdrvr.c | 1437 ++++ winpcap/wpcap/libpcap/msdos/pktdrvr.h | 153 + winpcap/wpcap/libpcap/msdos/readme.dos | 162 + winpcap/wpcap/libpcap/nametoaddr.c | 505 ++ winpcap/wpcap/libpcap/nlpid.h | 58 + winpcap/wpcap/libpcap/optimize.c | 2295 ++++++ winpcap/wpcap/libpcap/packaging/pcap.spec | 65 + winpcap/wpcap/libpcap/packaging/pcap.spec.in | 65 + winpcap/wpcap/libpcap/pcap-bpf.c | 1169 +++ winpcap/wpcap/libpcap/pcap-bpf.h | 736 ++ winpcap/wpcap/libpcap/pcap-dag.c | 927 +++ winpcap/wpcap/libpcap/pcap-dag.h | 14 + winpcap/wpcap/libpcap/pcap-dlpi.c | 1873 +++++ winpcap/wpcap/libpcap/pcap-dos.c | 1474 ++++ winpcap/wpcap/libpcap/pcap-dos.h | 227 + winpcap/wpcap/libpcap/pcap-enet.c | 235 + winpcap/wpcap/libpcap/pcap-int.h | 373 + winpcap/wpcap/libpcap/pcap-linux.c | 2250 ++++++ winpcap/wpcap/libpcap/pcap-namedb.h | 89 + winpcap/wpcap/libpcap/pcap-new.c | 1231 +++ winpcap/wpcap/libpcap/pcap-nit.c | 356 + winpcap/wpcap/libpcap/pcap-nit.h | 19 + winpcap/wpcap/libpcap/pcap-null.c | 54 + winpcap/wpcap/libpcap/pcap-pf.c | 610 ++ winpcap/wpcap/libpcap/pcap-pf.h | 19 + winpcap/wpcap/libpcap/pcap-remote.c | 2109 +++++ winpcap/wpcap/libpcap/pcap-remote.h | 362 + winpcap/wpcap/libpcap/pcap-septel.c | 307 + winpcap/wpcap/libpcap/pcap-septel.h | 15 + winpcap/wpcap/libpcap/pcap-snit.c | 419 + winpcap/wpcap/libpcap/pcap-snoop.c | 405 + winpcap/wpcap/libpcap/pcap-stdinc.h | 64 + winpcap/wpcap/libpcap/pcap-win32.c | 867 ++ winpcap/wpcap/libpcap/pcap.3 | 1311 +++ winpcap/wpcap/libpcap/pcap.c | 967 +++ winpcap/wpcap/libpcap/pcap.h | 344 + winpcap/wpcap/libpcap/pcap1.h | 302 + winpcap/wpcap/libpcap/pf.h | 77 + winpcap/wpcap/libpcap/ppp.h | 58 + winpcap/wpcap/libpcap/readme-rpcap.txt | 31 + winpcap/wpcap/libpcap/remote-ext.h | 441 + winpcap/wpcap/libpcap/remote_code.patch | 713 ++ winpcap/wpcap/libpcap/rpcapd/Makefile | 50 + winpcap/wpcap/libpcap/rpcapd/daemon.c | 1604 ++++ winpcap/wpcap/libpcap/rpcapd/daemon.h | 51 + winpcap/wpcap/libpcap/rpcapd/fileconf.c | 220 + winpcap/wpcap/libpcap/rpcapd/fileconf.h | 42 + winpcap/wpcap/libpcap/rpcapd/resource.h | 15 + winpcap/wpcap/libpcap/rpcapd/rpcapd.c | 723 ++ winpcap/wpcap/libpcap/rpcapd/rpcapd.dsp | 219 + winpcap/wpcap/libpcap/rpcapd/rpcapd.dsw | 29 + winpcap/wpcap/libpcap/rpcapd/rpcapd.h | 56 + winpcap/wpcap/libpcap/rpcapd/utils.c | 125 + winpcap/wpcap/libpcap/rpcapd/utils.h | 45 + winpcap/wpcap/libpcap/rpcapd/version.rc | 64 + winpcap/wpcap/libpcap/rpcapd/version.rc2 | 45 + .../wpcap/libpcap/rpcapd/win32-pthreads/pthread.h | 1300 +++ .../libpcap/rpcapd/win32-pthreads/pthreadVC.dll | Bin 0 -> 53299 bytes .../libpcap/rpcapd/win32-pthreads/pthreadVC.lib | Bin 0 -> 28866 bytes .../wpcap/libpcap/rpcapd/win32-pthreads/sched.h | 174 + .../libpcap/rpcapd/win32-pthreads/semaphore.h | 163 + winpcap/wpcap/libpcap/rpcapd/win32-svc.c | 173 + winpcap/wpcap/libpcap/rpcapd/win32-svc.h | 33 + winpcap/wpcap/libpcap/savefile.c | 1383 ++++ winpcap/wpcap/libpcap/scanner.c | 4352 ++++++++++ winpcap/wpcap/libpcap/scanner.l | 430 + winpcap/wpcap/libpcap/sll.h | 124 + winpcap/wpcap/libpcap/sockutils.c | 1241 +++ winpcap/wpcap/libpcap/sockutils.h | 244 + winpcap/wpcap/libpcap/sunatmpos.h | 45 + winpcap/wpcap/libpcap/tokdefs.h | 262 + 449 files changed, 128548 insertions(+) create mode 100644 winpcap/Common/Devioctl.h create mode 100644 winpcap/Common/Ntddndis.h create mode 100644 winpcap/Common/Ntddpack.h create mode 100644 winpcap/Common/Packet32.h create mode 100644 winpcap/Common/WpcapNames.h create mode 100644 winpcap/Common/dagc.h create mode 100644 winpcap/Examples-pcap/GNUmakefile create mode 100644 winpcap/Examples-pcap/MakeaAll.dsw create mode 100644 winpcap/Examples-pcap/UDPdump/GNUmakefile create mode 100644 winpcap/Examples-pcap/UDPdump/UDPdump.dsp create mode 100644 winpcap/Examples-pcap/UDPdump/UDPdump.dsw create mode 100644 winpcap/Examples-pcap/UDPdump/udpdump.c create mode 100644 winpcap/Examples-pcap/basic_dump/GNUmakefile create mode 100644 winpcap/Examples-pcap/basic_dump/basic_dump.c create mode 100644 winpcap/Examples-pcap/basic_dump/basic_dump.dsp create mode 100644 winpcap/Examples-pcap/basic_dump/basic_dump.dsw create mode 100644 winpcap/Examples-pcap/basic_dump_ex/GNUmakefile create mode 100644 winpcap/Examples-pcap/basic_dump_ex/basic_dump_ex.c create mode 100644 winpcap/Examples-pcap/basic_dump_ex/basic_dump_ex.dsp create mode 100644 winpcap/Examples-pcap/basic_dump_ex/basic_dump_ex.dsw create mode 100644 winpcap/Examples-pcap/iflist/GNUmakefile create mode 100644 winpcap/Examples-pcap/iflist/iflist.c create mode 100644 winpcap/Examples-pcap/iflist/iflist.dsp create mode 100644 winpcap/Examples-pcap/iflist/iflist.dsw create mode 100644 winpcap/Examples-pcap/pcap_filter/GNUmakefile create mode 100644 winpcap/Examples-pcap/pcap_filter/Makefile.unix create mode 100644 winpcap/Examples-pcap/pcap_filter/pcap_filter.c create mode 100644 winpcap/Examples-pcap/pcap_filter/pcap_filter.dsp create mode 100644 winpcap/Examples-pcap/pcap_filter/pcap_filter.dsw create mode 100644 winpcap/Examples-pcap/pktdump_ex/GNUmakefile create mode 100644 winpcap/Examples-pcap/pktdump_ex/pktdump_ex.c create mode 100644 winpcap/Examples-pcap/pktdump_ex/pktdump_ex.dsp create mode 100644 winpcap/Examples-pcap/pktdump_ex/pktdump_ex.dsw create mode 100644 winpcap/Examples-pcap/readfile/GNUmakefile create mode 100644 winpcap/Examples-pcap/readfile/readfile.c create mode 100644 winpcap/Examples-pcap/readfile/readfile.dsp create mode 100644 winpcap/Examples-pcap/readfile/readfile.dsw create mode 100644 winpcap/Examples-pcap/readfile_ex/GNUmakefile create mode 100644 winpcap/Examples-pcap/readfile_ex/readfile_ex.c create mode 100644 winpcap/Examples-pcap/readfile_ex/readfile_ex.dsp create mode 100644 winpcap/Examples-pcap/readfile_ex/readfile_ex.dsw create mode 100644 winpcap/Examples-pcap/savedump/GNUmakefile create mode 100644 winpcap/Examples-pcap/savedump/savedump.c create mode 100644 winpcap/Examples-pcap/savedump/savedump.dsp create mode 100644 winpcap/Examples-pcap/savedump/savedump.dsw create mode 100644 winpcap/Examples-pcap/sendpack/GNUmakefile create mode 100644 winpcap/Examples-pcap/sendpack/sendpack.c create mode 100644 winpcap/Examples-pcap/sendpack/sendpack.dsp create mode 100644 winpcap/Examples-pcap/sendpack/sendpack.dsw create mode 100644 winpcap/Examples-pcap/stats/stats.c create mode 100644 winpcap/Examples-pcap/stats/stats.dsp create mode 100644 winpcap/Examples-pcap/stats/stats.dsw create mode 100644 winpcap/Examples-pcap/winpcap_stress/winpcap_stress.c create mode 100644 winpcap/Examples-pcap/winpcap_stress/winpcap_stress.dsp create mode 100644 winpcap/Examples-pcap/winpcap_stress/winpcap_stress.dsw create mode 100644 winpcap/Examples/MakeaAll.dsw create mode 100644 winpcap/Examples/NETMETER/CapDll.h create mode 100644 winpcap/Examples/NETMETER/CaptureThread.cpp create mode 100644 winpcap/Examples/NETMETER/Console.h create mode 100644 winpcap/Examples/NETMETER/LineColl.cpp create mode 100644 winpcap/Examples/NETMETER/LineColl.h create mode 100644 winpcap/Examples/NETMETER/MainFrm.cpp create mode 100644 winpcap/Examples/NETMETER/MainFrm.h create mode 100644 winpcap/Examples/NETMETER/NETMETER.CPP create mode 100644 winpcap/Examples/NETMETER/NETMETER.H create mode 100644 winpcap/Examples/NETMETER/ProgCaptDlg.h create mode 100644 winpcap/Examples/NETMETER/SelectAdapter.cpp create mode 100644 winpcap/Examples/NETMETER/SelectAdapter.h create mode 100644 winpcap/Examples/NETMETER/StdAfx.cpp create mode 100644 winpcap/Examples/NETMETER/StdAfx.h create mode 100644 winpcap/Examples/NETMETER/netmeter.dsp create mode 100644 winpcap/Examples/NETMETER/netmeter.dsw create mode 100644 winpcap/Examples/NETMETER/netmeter.rc create mode 100644 winpcap/Examples/NETMETER/netmeterDoc.cpp create mode 100644 winpcap/Examples/NETMETER/netmeterDoc.h create mode 100644 winpcap/Examples/NETMETER/netmeterView.cpp create mode 100644 winpcap/Examples/NETMETER/netmeterView.h create mode 100644 winpcap/Examples/NETMETER/res/BMP00001.BMP create mode 100644 winpcap/Examples/NETMETER/res/bitmap1.bmp create mode 100644 winpcap/Examples/NETMETER/res/bitmap2.bmp create mode 100644 winpcap/Examples/NETMETER/res/cap_wizi.bmp create mode 100644 winpcap/Examples/NETMETER/res/listbmp.bmp create mode 100644 winpcap/Examples/NETMETER/res/netmeter.ico create mode 100644 winpcap/Examples/NETMETER/res/netmeter.rc2 create mode 100644 winpcap/Examples/NETMETER/res/netmeterDoc.ico create mode 100644 winpcap/Examples/NETMETER/resource.h create mode 100644 winpcap/Examples/PacketDriver/GetMacAddress/GetMacAddress.c create mode 100644 winpcap/Examples/PacketDriver/GetMacAddress/GetMacAddress.dsp create mode 100644 winpcap/Examples/PacketDriver/TestPacketCapture/TestPacketCapture.c create mode 100644 winpcap/Examples/PacketDriver/TestPacketCapture/TestPacketCapture.dsp create mode 100644 winpcap/Examples/PacketDriver/TestPacketSend/TestPacketSend.c create mode 100644 winpcap/Examples/PacketDriver/TestPacketSend/TestPacketSend.dsp create mode 100644 winpcap/Examples/PacketDriver/readme.txt create mode 100644 winpcap/Examples/UDPdump/UDPdump.dsp create mode 100644 winpcap/Examples/UDPdump/UDPdump.dsw create mode 100644 winpcap/Examples/UDPdump/udpdump.c create mode 100644 winpcap/Examples/UserLevelBridge/UserBridge.c create mode 100644 winpcap/Examples/UserLevelBridge/UserBridge.dsp create mode 100644 winpcap/Examples/UserLevelBridge/UserBridge.dsw create mode 100644 winpcap/Examples/iflist/iflist.c create mode 100644 winpcap/Examples/iflist/iflist.dsp create mode 100644 winpcap/Examples/iflist/iflist.dsw create mode 100644 winpcap/Examples/kdump/kdump.c create mode 100644 winpcap/Examples/kdump/kdump.dsp create mode 100644 winpcap/Examples/kdump/kdump.dsw create mode 100644 winpcap/Examples/kdump/kdump.exe create mode 100644 winpcap/Examples/misc/MakeaAll.dsw create mode 100644 winpcap/Examples/misc/basic_dump.c create mode 100644 winpcap/Examples/misc/basic_dump.dsp create mode 100644 winpcap/Examples/misc/basic_dump_ex.c create mode 100644 winpcap/Examples/misc/basic_dump_ex.dsp create mode 100644 winpcap/Examples/misc/readfile.c create mode 100644 winpcap/Examples/misc/readfile.dsp create mode 100644 winpcap/Examples/misc/readfile_ex.c create mode 100644 winpcap/Examples/misc/readfile_ex.dsp create mode 100644 winpcap/Examples/misc/savedump.c create mode 100644 winpcap/Examples/misc/savedump.dsp create mode 100644 winpcap/Examples/misc/sendpack.c create mode 100644 winpcap/Examples/misc/sendpack.dsp create mode 100644 winpcap/Examples/pcap_filter/pcap_filter.c create mode 100644 winpcap/Examples/pcap_filter/pcap_filter.dsp create mode 100644 winpcap/Examples/pcap_filter/pcap_filter.dsw create mode 100644 winpcap/Examples/pktdump_ex/pktdump_ex.c create mode 100644 winpcap/Examples/pktdump_ex/pktdump_ex.dsp create mode 100644 winpcap/Examples/pktdump_ex/pktdump_ex.dsw create mode 100644 winpcap/Examples/sendcap/sencap.dsw create mode 100644 winpcap/Examples/sendcap/sendcap.c create mode 100644 winpcap/Examples/sendcap/sendcap.dsp create mode 100644 winpcap/Examples/smp_1/smp_1.c create mode 100644 winpcap/Examples/smp_1/smp_1.dsp create mode 100644 winpcap/Examples/smp_1/smp_1.dsw create mode 100644 winpcap/Examples/tcptop/tcptop.c create mode 100644 winpcap/Examples/tcptop/tcptop.dsp create mode 100644 winpcap/Examples/tcptop/tcptop.dsw create mode 100644 winpcap/Packet9x/DLL/Packet.def create mode 100644 winpcap/Packet9x/DLL/Packet32.c create mode 100644 winpcap/Packet9x/DLL/Project/GNUmakefile create mode 100644 winpcap/Packet9x/DLL/Project/Packet.dsp create mode 100644 winpcap/Packet9x/DLL/Project/Packet.dsw create mode 100644 winpcap/Packet9x/DLL/version.rc create mode 100644 winpcap/Packet9x/DLL/version.rc2 create mode 100644 winpcap/Packet9x/VXD/DEVIOCTL.H create mode 100644 winpcap/Packet9x/VXD/Debug.h create mode 100644 winpcap/Packet9x/VXD/Functs.asm create mode 100644 winpcap/Packet9x/VXD/Lock.c create mode 100644 winpcap/Packet9x/VXD/MAKEFILE create mode 100644 winpcap/Packet9x/VXD/NPF.def create mode 100644 winpcap/Packet9x/VXD/NPF.rc create mode 100644 winpcap/Packet9x/VXD/Ndis.mk create mode 100644 winpcap/Packet9x/VXD/Ndisdev.asm create mode 100644 winpcap/Packet9x/VXD/Ntddpack.h create mode 100644 winpcap/Packet9x/VXD/Openclos.c create mode 100644 winpcap/Packet9x/VXD/Packet.c create mode 100644 winpcap/Packet9x/VXD/Packet.h create mode 100644 winpcap/Packet9x/VXD/Read.c create mode 100644 winpcap/Packet9x/VXD/Request.c create mode 100644 winpcap/Packet9x/VXD/Vpacket.rc create mode 100644 winpcap/Packet9x/VXD/Write.c create mode 100644 winpcap/Packet9x/VXD/win_Bpf.h create mode 100644 winpcap/Packet9x/VXD/win_bpf_filter.c create mode 100644 winpcap/build_wpdpack.bat create mode 100644 winpcap/build_wpdpack.txt create mode 100644 winpcap/create_docs.bat create mode 100644 winpcap/create_examples.bat create mode 100644 winpcap/create_include.bat create mode 100644 winpcap/create_lib.bat create mode 100644 winpcap/createdoc.bat create mode 100644 winpcap/dox/WinPcap_docs.html create mode 100644 winpcap/dox/compile.htm create mode 100644 winpcap/dox/doxygen_groups.txt create mode 100644 winpcap/dox/doxygen_groups_packetdll.txt create mode 100644 winpcap/dox/footer.htm create mode 100644 winpcap/dox/internals-arch.gif create mode 100644 winpcap/dox/internals.htm create mode 100644 winpcap/dox/intro.htm create mode 100644 winpcap/dox/language.htm create mode 100644 winpcap/dox/libpcap/funcs/pcap.h create mode 100644 winpcap/dox/libpcap/incs/pcap.h create mode 100644 winpcap/dox/main.txt create mode 100644 winpcap/dox/main_packetdll.txt create mode 100644 winpcap/dox/note.txt create mode 100644 winpcap/dox/npf-dump.gif create mode 100644 winpcap/dox/npf-ndis.gif create mode 100644 winpcap/dox/npf-npf.gif create mode 100644 winpcap/dox/npf.htm create mode 100644 winpcap/dox/packet.htm create mode 100644 winpcap/dox/packet_samp.htm create mode 100644 winpcap/dox/pics/dump.gif create mode 100644 winpcap/dox/pics/encoding.gif create mode 100644 winpcap/dox/pics/stats.gif create mode 100644 winpcap/dox/pics/stats_wpcap.gif create mode 100644 winpcap/dox/pics/winpcap.gif create mode 100644 winpcap/dox/pics/winpcap_small.gif create mode 100644 winpcap/dox/prj/winpcap_c.dox create mode 100644 winpcap/dox/prj/winpcap_c_packetdll.dox create mode 100644 winpcap/dox/prj/winpcap_noc.dox create mode 100644 winpcap/dox/slides.ppt create mode 100644 winpcap/dox/style.css create mode 100644 winpcap/dox/wpcap.htm create mode 100644 winpcap/dox/wpcap_remote.htm create mode 100644 winpcap/dox/wpcap_samp.htm create mode 100644 winpcap/dox/wpcap_samp1.htm create mode 100644 winpcap/dox/wpcap_samp2.htm create mode 100644 winpcap/dox/wpcap_tut.txt create mode 100644 winpcap/dox/wpcap_tut1.txt create mode 100644 winpcap/dox/wpcap_tut2.txt create mode 100644 winpcap/dox/wpcap_tut3.txt create mode 100644 winpcap/dox/wpcap_tut4.txt create mode 100644 winpcap/dox/wpcap_tut5.txt create mode 100644 winpcap/dox/wpcap_tut6.txt create mode 100644 winpcap/dox/wpcap_tut7.txt create mode 100644 winpcap/dox/wpcap_tut8.txt create mode 100644 winpcap/dox/wpcap_tut9.txt create mode 100644 winpcap/packetNtx/Compile2k.bat create mode 100644 winpcap/packetNtx/CompileDriver.bat create mode 100644 winpcap/packetNtx/CompileNT4.bat create mode 100644 winpcap/packetNtx/DIRS create mode 100644 winpcap/packetNtx/Dll/AdInfo.c create mode 100644 winpcap/packetNtx/Dll/NpfImExt.c create mode 100644 winpcap/packetNtx/Dll/NpfImExt.h create mode 100644 winpcap/packetNtx/Dll/Packet.def create mode 100644 winpcap/packetNtx/Dll/Packet32-Int.h create mode 100644 winpcap/packetNtx/Dll/Packet32.c create mode 100644 winpcap/packetNtx/Dll/Project/GNUmakefile create mode 100644 winpcap/packetNtx/Dll/Project/Packet.dsp create mode 100644 winpcap/packetNtx/Dll/Project/Packet.dsw create mode 100644 winpcap/packetNtx/Dll/WanPacket/WanPacket.cpp create mode 100644 winpcap/packetNtx/Dll/WanPacket/WanPacket.def create mode 100644 winpcap/packetNtx/Dll/WanPacket/WanPacket.dsp create mode 100644 winpcap/packetNtx/Dll/WanPacket/WanPacket.dsw create mode 100644 winpcap/packetNtx/Dll/WanPacket/WanPacket.h create mode 100644 winpcap/packetNtx/Dll/WanPacket/version.rc create mode 100644 winpcap/packetNtx/Dll/WanPacket/version.rc2 create mode 100644 winpcap/packetNtx/Dll/debug.h create mode 100644 winpcap/packetNtx/Dll/strsafe.h create mode 100644 winpcap/packetNtx/Dll/version.rc create mode 100644 winpcap/packetNtx/Dll/version.rc2 create mode 100644 winpcap/packetNtx/driver/DEBUG.H create mode 100644 winpcap/packetNtx/driver/MAKEFILE create mode 100644 winpcap/packetNtx/driver/NPF.RC create mode 100644 winpcap/packetNtx/driver/Openclos.c create mode 100644 winpcap/packetNtx/driver/Packet.c create mode 100644 winpcap/packetNtx/driver/Packet.h create mode 100644 winpcap/packetNtx/driver/Read.c create mode 100644 winpcap/packetNtx/driver/Sources create mode 100644 winpcap/packetNtx/driver/WinPcap NTx Driver_2003.vcproj create mode 100644 winpcap/packetNtx/driver/Write.c create mode 100644 winpcap/packetNtx/driver/bucket_lookup.c create mode 100644 winpcap/packetNtx/driver/bucket_lookup.h create mode 100644 winpcap/packetNtx/driver/count_packets.c create mode 100644 winpcap/packetNtx/driver/count_packets.h create mode 100644 winpcap/packetNtx/driver/dump.c create mode 100644 winpcap/packetNtx/driver/functions.c create mode 100644 winpcap/packetNtx/driver/functions.h create mode 100644 winpcap/packetNtx/driver/jitter.c create mode 100644 winpcap/packetNtx/driver/jitter.h create mode 100644 winpcap/packetNtx/driver/memory_t.h create mode 100644 winpcap/packetNtx/driver/normal_lookup.c create mode 100644 winpcap/packetNtx/driver/normal_lookup.h create mode 100644 winpcap/packetNtx/driver/resource.h create mode 100644 winpcap/packetNtx/driver/tcp_session.c create mode 100644 winpcap/packetNtx/driver/tcp_session.h create mode 100644 winpcap/packetNtx/driver/time_calls.h create mode 100644 winpcap/packetNtx/driver/tme.c create mode 100644 winpcap/packetNtx/driver/tme.h create mode 100644 winpcap/packetNtx/driver/valid_insns.h create mode 100644 winpcap/packetNtx/driver/win_bpf.h create mode 100644 winpcap/packetNtx/driver/win_bpf_filter.c create mode 100644 winpcap/packetNtx/driver/win_bpf_filter_init.c create mode 100644 winpcap/packetNtx/driver/win_bpf_filter_init.h create mode 100644 winpcap/readme-cygwin create mode 100644 winpcap/readme-visualC create mode 100644 winpcap/todo.txt create mode 100644 winpcap/version.h create mode 100644 winpcap/wpcap/PRJ/GNUmakefile create mode 100644 winpcap/wpcap/PRJ/WPCAP.DEF create mode 100644 winpcap/wpcap/PRJ/WPCAP.dsw create mode 100644 winpcap/wpcap/PRJ/Wpcap_no_extensions.def create mode 100644 winpcap/wpcap/PRJ/build_scanner_parser.bat create mode 100644 winpcap/wpcap/PRJ/wpcap.dsp create mode 100644 winpcap/wpcap/Win32-Extensions/Win32-Extensions.c create mode 100644 winpcap/wpcap/Win32-Extensions/Win32-Extensions.h create mode 100644 winpcap/wpcap/Win32-Extensions/version.aps create mode 100644 winpcap/wpcap/Win32-Extensions/version.rc create mode 100644 winpcap/wpcap/Win32-Extensions/version.rc2 create mode 100644 winpcap/wpcap/libpcap/CHANGES create mode 100644 winpcap/wpcap/libpcap/CREDITS create mode 100644 winpcap/wpcap/libpcap/ChmodBPF/ChmodBPF create mode 100644 winpcap/wpcap/libpcap/ChmodBPF/StartupParameters.plist create mode 100644 winpcap/wpcap/libpcap/FILES create mode 100644 winpcap/wpcap/libpcap/INSTALL.txt create mode 100644 winpcap/wpcap/libpcap/LICENSE create mode 100644 winpcap/wpcap/libpcap/Makefile.in create mode 100644 winpcap/wpcap/libpcap/README create mode 100644 winpcap/wpcap/libpcap/README.Win32 create mode 100644 winpcap/wpcap/libpcap/README.aix create mode 100644 winpcap/wpcap/libpcap/README.dag create mode 100644 winpcap/wpcap/libpcap/README.hpux create mode 100644 winpcap/wpcap/libpcap/README.linux create mode 100644 winpcap/wpcap/libpcap/README.macosx create mode 100644 winpcap/wpcap/libpcap/README.septel create mode 100644 winpcap/wpcap/libpcap/README.tru64 create mode 100644 winpcap/wpcap/libpcap/SUNOS4/nit_if.o.sparc create mode 100644 winpcap/wpcap/libpcap/SUNOS4/nit_if.o.sun3 create mode 100644 winpcap/wpcap/libpcap/SUNOS4/nit_if.o.sun4c.4.0.3c create mode 100644 winpcap/wpcap/libpcap/TODO create mode 100644 winpcap/wpcap/libpcap/VERSION create mode 100644 winpcap/wpcap/libpcap/Win32/Include/Gnuc.h create mode 100644 winpcap/wpcap/libpcap/Win32/Include/addrinfo.h create mode 100644 winpcap/wpcap/libpcap/Win32/Include/arpa/nameser.h create mode 100644 winpcap/wpcap/libpcap/Win32/Include/bittypes.h create mode 100644 winpcap/wpcap/libpcap/Win32/Include/cdecl_ext.h create mode 100644 winpcap/wpcap/libpcap/Win32/Include/inetprivate.h create mode 100644 winpcap/wpcap/libpcap/Win32/Include/ip6_misc.h create mode 100644 winpcap/wpcap/libpcap/Win32/Include/net/if.h create mode 100644 winpcap/wpcap/libpcap/Win32/Include/net/netdb.h create mode 100644 winpcap/wpcap/libpcap/Win32/Include/net/paths.h create mode 100644 winpcap/wpcap/libpcap/Win32/Include/sockstorage.h create mode 100644 winpcap/wpcap/libpcap/Win32/Prj/libpcap.dsp create mode 100644 winpcap/wpcap/libpcap/Win32/Prj/libpcap.dsw create mode 100644 winpcap/wpcap/libpcap/Win32/Src/ffs.c create mode 100644 winpcap/wpcap/libpcap/Win32/Src/gai_strerror.c create mode 100644 winpcap/wpcap/libpcap/Win32/Src/getaddrinfo.c create mode 100644 winpcap/wpcap/libpcap/Win32/Src/getnetbynm.c create mode 100644 winpcap/wpcap/libpcap/Win32/Src/getnetent.c create mode 100644 winpcap/wpcap/libpcap/Win32/Src/getopt.c create mode 100644 winpcap/wpcap/libpcap/Win32/Src/getservent.c create mode 100644 winpcap/wpcap/libpcap/Win32/Src/inet_aton.c create mode 100644 winpcap/wpcap/libpcap/Win32/Src/inet_net.c create mode 100644 winpcap/wpcap/libpcap/Win32/Src/inet_pton.c create mode 100644 winpcap/wpcap/libpcap/acconfig.h create mode 100644 winpcap/wpcap/libpcap/aclocal.m4 create mode 100644 winpcap/wpcap/libpcap/arcnet.h create mode 100644 winpcap/wpcap/libpcap/atmuni31.h create mode 100644 winpcap/wpcap/libpcap/bpf/net/bpf_filter.c create mode 100644 winpcap/wpcap/libpcap/bpf_dump.c create mode 100644 winpcap/wpcap/libpcap/bpf_image.c create mode 100644 winpcap/wpcap/libpcap/config.guess create mode 100644 winpcap/wpcap/libpcap/config.h.in create mode 100644 winpcap/wpcap/libpcap/config.sub create mode 100644 winpcap/wpcap/libpcap/configure create mode 100644 winpcap/wpcap/libpcap/configure.in create mode 100644 winpcap/wpcap/libpcap/doc/pcap.html create mode 100644 winpcap/wpcap/libpcap/doc/pcap.txt create mode 100644 winpcap/wpcap/libpcap/doc/pcap.xml create mode 100644 winpcap/wpcap/libpcap/etherent.c create mode 100644 winpcap/wpcap/libpcap/ethertype.h create mode 100644 winpcap/wpcap/libpcap/fad-getad.c create mode 100644 winpcap/wpcap/libpcap/fad-gifc.c create mode 100644 winpcap/wpcap/libpcap/fad-glifc.c create mode 100644 winpcap/wpcap/libpcap/fad-null.c create mode 100644 winpcap/wpcap/libpcap/fad-win32.c create mode 100644 winpcap/wpcap/libpcap/gencode.c create mode 100644 winpcap/wpcap/libpcap/gencode.h create mode 100644 winpcap/wpcap/libpcap/grammar.c create mode 100644 winpcap/wpcap/libpcap/grammar.y create mode 100644 winpcap/wpcap/libpcap/inet.c create mode 100644 winpcap/wpcap/libpcap/install-sh create mode 100644 winpcap/wpcap/libpcap/lbl/os-aix4.h create mode 100644 winpcap/wpcap/libpcap/lbl/os-hpux11.h create mode 100644 winpcap/wpcap/libpcap/lbl/os-osf4.h create mode 100644 winpcap/wpcap/libpcap/lbl/os-osf5.h create mode 100644 winpcap/wpcap/libpcap/lbl/os-solaris2.h create mode 100644 winpcap/wpcap/libpcap/lbl/os-sunos4.h create mode 100644 winpcap/wpcap/libpcap/lbl/os-ultrix4.h create mode 100644 winpcap/wpcap/libpcap/llc.h create mode 100644 winpcap/wpcap/libpcap/missing/snprintf.c create mode 100644 winpcap/wpcap/libpcap/mkdep create mode 100644 winpcap/wpcap/libpcap/msdos/bin2c.c create mode 100644 winpcap/wpcap/libpcap/msdos/common.dj create mode 100644 winpcap/wpcap/libpcap/msdos/makefile create mode 100644 winpcap/wpcap/libpcap/msdos/makefile.dj create mode 100644 winpcap/wpcap/libpcap/msdos/makefile.wc create mode 100644 winpcap/wpcap/libpcap/msdos/ndis2.c create mode 100644 winpcap/wpcap/libpcap/msdos/ndis2.h create mode 100644 winpcap/wpcap/libpcap/msdos/ndis_0.asm create mode 100644 winpcap/wpcap/libpcap/msdos/pkt_rx0.asm create mode 100644 winpcap/wpcap/libpcap/msdos/pkt_rx1.s create mode 100644 winpcap/wpcap/libpcap/msdos/pktdrvr.c create mode 100644 winpcap/wpcap/libpcap/msdos/pktdrvr.h create mode 100644 winpcap/wpcap/libpcap/msdos/readme.dos create mode 100644 winpcap/wpcap/libpcap/nametoaddr.c create mode 100644 winpcap/wpcap/libpcap/nlpid.h create mode 100644 winpcap/wpcap/libpcap/optimize.c create mode 100644 winpcap/wpcap/libpcap/packaging/pcap.spec create mode 100644 winpcap/wpcap/libpcap/packaging/pcap.spec.in create mode 100644 winpcap/wpcap/libpcap/pcap-bpf.c create mode 100644 winpcap/wpcap/libpcap/pcap-bpf.h create mode 100644 winpcap/wpcap/libpcap/pcap-dag.c create mode 100644 winpcap/wpcap/libpcap/pcap-dag.h create mode 100644 winpcap/wpcap/libpcap/pcap-dlpi.c create mode 100644 winpcap/wpcap/libpcap/pcap-dos.c create mode 100644 winpcap/wpcap/libpcap/pcap-dos.h create mode 100644 winpcap/wpcap/libpcap/pcap-enet.c create mode 100644 winpcap/wpcap/libpcap/pcap-int.h create mode 100644 winpcap/wpcap/libpcap/pcap-linux.c create mode 100644 winpcap/wpcap/libpcap/pcap-namedb.h create mode 100644 winpcap/wpcap/libpcap/pcap-new.c create mode 100644 winpcap/wpcap/libpcap/pcap-nit.c create mode 100644 winpcap/wpcap/libpcap/pcap-nit.h create mode 100644 winpcap/wpcap/libpcap/pcap-null.c create mode 100644 winpcap/wpcap/libpcap/pcap-pf.c create mode 100644 winpcap/wpcap/libpcap/pcap-pf.h create mode 100644 winpcap/wpcap/libpcap/pcap-remote.c create mode 100644 winpcap/wpcap/libpcap/pcap-remote.h create mode 100644 winpcap/wpcap/libpcap/pcap-septel.c create mode 100644 winpcap/wpcap/libpcap/pcap-septel.h create mode 100644 winpcap/wpcap/libpcap/pcap-snit.c create mode 100644 winpcap/wpcap/libpcap/pcap-snoop.c create mode 100644 winpcap/wpcap/libpcap/pcap-stdinc.h create mode 100644 winpcap/wpcap/libpcap/pcap-win32.c create mode 100644 winpcap/wpcap/libpcap/pcap.3 create mode 100644 winpcap/wpcap/libpcap/pcap.c create mode 100644 winpcap/wpcap/libpcap/pcap.h create mode 100644 winpcap/wpcap/libpcap/pcap1.h create mode 100644 winpcap/wpcap/libpcap/pf.h create mode 100644 winpcap/wpcap/libpcap/ppp.h create mode 100644 winpcap/wpcap/libpcap/readme-rpcap.txt create mode 100644 winpcap/wpcap/libpcap/remote-ext.h create mode 100644 winpcap/wpcap/libpcap/remote_code.patch create mode 100644 winpcap/wpcap/libpcap/rpcapd/Makefile create mode 100644 winpcap/wpcap/libpcap/rpcapd/daemon.c create mode 100644 winpcap/wpcap/libpcap/rpcapd/daemon.h create mode 100644 winpcap/wpcap/libpcap/rpcapd/fileconf.c create mode 100644 winpcap/wpcap/libpcap/rpcapd/fileconf.h create mode 100644 winpcap/wpcap/libpcap/rpcapd/resource.h create mode 100644 winpcap/wpcap/libpcap/rpcapd/rpcapd.c create mode 100644 winpcap/wpcap/libpcap/rpcapd/rpcapd.dsp create mode 100644 winpcap/wpcap/libpcap/rpcapd/rpcapd.dsw create mode 100644 winpcap/wpcap/libpcap/rpcapd/rpcapd.h create mode 100644 winpcap/wpcap/libpcap/rpcapd/utils.c create mode 100644 winpcap/wpcap/libpcap/rpcapd/utils.h create mode 100644 winpcap/wpcap/libpcap/rpcapd/version.rc create mode 100644 winpcap/wpcap/libpcap/rpcapd/version.rc2 create mode 100644 winpcap/wpcap/libpcap/rpcapd/win32-pthreads/pthread.h create mode 100644 winpcap/wpcap/libpcap/rpcapd/win32-pthreads/pthreadVC.dll create mode 100644 winpcap/wpcap/libpcap/rpcapd/win32-pthreads/pthreadVC.lib create mode 100644 winpcap/wpcap/libpcap/rpcapd/win32-pthreads/sched.h create mode 100644 winpcap/wpcap/libpcap/rpcapd/win32-pthreads/semaphore.h create mode 100644 winpcap/wpcap/libpcap/rpcapd/win32-svc.c create mode 100644 winpcap/wpcap/libpcap/rpcapd/win32-svc.h create mode 100644 winpcap/wpcap/libpcap/savefile.c create mode 100644 winpcap/wpcap/libpcap/scanner.c create mode 100644 winpcap/wpcap/libpcap/scanner.l create mode 100644 winpcap/wpcap/libpcap/sll.h create mode 100644 winpcap/wpcap/libpcap/sockutils.c create mode 100644 winpcap/wpcap/libpcap/sockutils.h create mode 100644 winpcap/wpcap/libpcap/sunatmpos.h create mode 100644 winpcap/wpcap/libpcap/tokdefs.h diff --git a/winpcap/Common/Devioctl.h b/winpcap/Common/Devioctl.h new file mode 100644 index 0000000..af8784b --- /dev/null +++ b/winpcap/Common/Devioctl.h @@ -0,0 +1,90 @@ +/*++ BUILD Version: 0004 // Increment this if a change has global effects + Copyright (c) 1992-1993 Microsoft Corporation + Module Name: + devioctl.h + Revision History: + -- */ +// begin_winioctl +#ifndef _DEVIOCTL_ +#define _DEVIOCTL_ +// begin_ntddk begin_nthal begin_ntifs +// +// Define the various device type values. Note that values used by Microsoft +// Corporation are in the range 0-32767, and 32768-65535 are reserved for use +// by customers. +// +#define DEVICE_TYPE ULONG +#define FILE_DEVICE_BEEP 0x00000001 +#define FILE_DEVICE_CD_ROM 0x00000002 +#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 +#define FILE_DEVICE_CONTROLLER 0x00000004 +#define FILE_DEVICE_DATALINK 0x00000005 +#define FILE_DEVICE_DFS 0x00000006 +#define FILE_DEVICE_DISK 0x00000007 +#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 +#define FILE_DEVICE_FILE_SYSTEM 0x00000009 +#define FILE_DEVICE_INPORT_PORT 0x0000000a +#define FILE_DEVICE_KEYBOARD 0x0000000b +#define FILE_DEVICE_MAILSLOT 0x0000000c +#define FILE_DEVICE_MIDI_IN 0x0000000d +#define FILE_DEVICE_MIDI_OUT 0x0000000e +#define FILE_DEVICE_MOUSE 0x0000000f +#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 +#define FILE_DEVICE_NAMED_PIPE 0x00000011 +#define FILE_DEVICE_NETWORK 0x00000012 +#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 +#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 +#define FILE_DEVICE_NULL 0x00000015 +#define FILE_DEVICE_PARALLEL_PORT 0x00000016 +#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 +#define FILE_DEVICE_PRINTER 0x00000018 +#define FILE_DEVICE_SCANNER 0x00000019 +#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a +#define FILE_DEVICE_SERIAL_PORT 0x0000001b +#define FILE_DEVICE_SCREEN 0x0000001c +#define FILE_DEVICE_SOUND 0x0000001d +#define FILE_DEVICE_STREAMS 0x0000001e +#define FILE_DEVICE_TAPE 0x0000001f +#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 +#define FILE_DEVICE_TRANSPORT 0x00000021 +#define FILE_DEVICE_UNKNOWN 0x00000022 +#define FILE_DEVICE_VIDEO 0x00000023 +#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 +#define FILE_DEVICE_WAVE_IN 0x00000025 +#define FILE_DEVICE_WAVE_OUT 0x00000026 +#define FILE_DEVICE_8042_PORT 0x00000027 +#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 +#define FILE_DEVICE_BATTERY 0x00000029 +#define FILE_DEVICE_BUS_EXTENDER 0x0000002a +#define FILE_DEVICE_MODEM 0x0000002b +#define FILE_DEVICE_VDM 0x0000002c +#define FILE_DEVICE_MASS_STORAGE 0x0000002d +// +// Macro definition for defining IOCTL and FSCTL function control codes. Note +// that function codes 0-2047 are reserved for Microsoft Corporation, and +// 2048-4095 are reserved for customers. +// +#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ +) +// +// Define the method codes for how buffers are passed for I/O and FS controls +// +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 +// +// Define the access check value for any access +// +// +// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in +// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these +// constants *MUST* always be in sync. +// +#define FILE_ANY_ACCESS 0 +#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe +#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe +// end_ntddk end_nthal end_ntifs +#endif // _DEVIOCTL_ +// end_winioctl diff --git a/winpcap/Common/Ntddndis.h b/winpcap/Common/Ntddndis.h new file mode 100644 index 0000000..0b62980 --- /dev/null +++ b/winpcap/Common/Ntddndis.h @@ -0,0 +1,1400 @@ +/*++ BUILD Version: 0001 // Increment this if a change has global effects + Copyright (c) 1990-1993 Microsoft Corporation + Module Name: + ntddndis.h + Abstract: + This is the include file that defines all constants and types for + accessing the Network driver interface device. + Author: + Steve Wood (stevewo) 27-May-1990 + Revision History: + Adam Barr (adamba) 04-Nov-1992 added the correct values for NDIS 3.0. + Jameel Hyder (jameelh) 01-Aug-95 added Pnp IoCTLs and structures + Kyle Brandon (kyleb) 09/24/96 added general co ndis oids. + -- */ +#ifndef _NTDDNDIS_ +#define _NTDDNDIS_ +// +// Device Name - this string is the name of the device. It is the name +// that should be passed to NtOpenFile when accessing the device. +// +// Note: For devices that support multiple units, it should be suffixed +// with the Ascii representation of the unit number. +// +#define DD_NDIS_DEVICE_NAME "\\Device\\UNKNOWN" +// +// NtDeviceIoControlFile IoControlCode values for this device. +// +// Warning: Remember that the low two bits of the code specify how the +// buffers are passed to the driver! +// +#define _NDIS_CONTROL_CODE(request,method) \ + CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, request, method, FILE_ANY_ACCESS) +#define IOCTL_NDIS_QUERY_GLOBAL_STATS _NDIS_CONTROL_CODE( 0, METHOD_OUT_DIRECT ) +#define IOCTL_NDIS_QUERY_ALL_STATS _NDIS_CONTROL_CODE( 1, METHOD_OUT_DIRECT ) +#define IOCTL_NDIS_ADD_DEVICE _NDIS_CONTROL_CODE( 2, METHOD_BUFFERED ) +#define IOCTL_NDIS_DELETE_DEVICE _NDIS_CONTROL_CODE( 3, METHOD_BUFFERED ) +#define IOCTL_NDIS_TRANSLATE_NAME _NDIS_CONTROL_CODE( 4, METHOD_BUFFERED ) +#define IOCTL_NDIS_ADD_TDI_DEVICE _NDIS_CONTROL_CODE( 5, METHOD_BUFFERED ) +#define IOCTL_NDIS_NOTIFY_PROTOCOL _NDIS_CONTROL_CODE( 6, METHOD_BUFFERED ) +#define IOCTL_NDIS_GET_LOG_DATA _NDIS_CONTROL_CODE( 7, METHOD_OUT_DIRECT ) +// +// NtDeviceIoControlFile InputBuffer/OutputBuffer record structures for +// this device. +// +// +// This is the type of an NDIS OID value. +// +typedef ULONG NDIS_OID, *PNDIS_OID; +// +// IOCTL_NDIS_QUERY_ALL_STATS returns a sequence of these, packed +// together (no padding is required since statistics all have +// four or eight bytes of data). +// +typedef struct _NDIS_STATISTICS_VALUE { + NDIS_OID Oid; + ULONG DataLength; + UCHAR Data[1]; // variable length + +} NDIS_STATISTICS_VALUE, *PNDIS_STATISTICS_VALUE; + +// +// Structure used by TRANSLATE_NAME IOCTL +// +typedef struct _NET_PNP_ID { + ULONG ClassId; + ULONG Token; +} NET_PNP_ID, *PNET_PNP_ID; + +typedef struct _NET_PNP_TRANSLATE_LIST { + ULONG BytesNeeded; + NET_PNP_ID IdArray[ANYSIZE_ARRAY]; +} NET_PNP_TRANSLATE_LIST, *PNET_PNP_TRANSLATE_LIST; + +// +// Structure used to define a self-contained variable data structure +// +typedef struct _NDIS_VAR_DATA_DESC { + USHORT Length; // # of octects of data + + USHORT MaximumLength; // # of octects available + + LONG Offset; // Offset of data relative to the descriptor + +} NDIS_VAR_DATA_DESC, *PNDIS_VAR_DATA_DESC; + +// +// Object Identifiers used by NdisRequest Query/Set Information +// +// +// General Objects +// +#define OID_GEN_SUPPORTED_LIST 0x00010101 +#define OID_GEN_HARDWARE_STATUS 0x00010102 +#define OID_GEN_MEDIA_SUPPORTED 0x00010103 +#define OID_GEN_MEDIA_IN_USE 0x00010104 +#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 +#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 +#define OID_GEN_LINK_SPEED 0x00010107 +#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 +#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 +#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A +#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B +#define OID_GEN_VENDOR_ID 0x0001010C +#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D +#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E +#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F +#define OID_GEN_DRIVER_VERSION 0x00010110 +#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 +#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 +#define OID_GEN_MAC_OPTIONS 0x00010113 +#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 +#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 +#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 +#define OID_GEN_XMIT_OK 0x00020101 +#define OID_GEN_RCV_OK 0x00020102 +#define OID_GEN_XMIT_ERROR 0x00020103 +#define OID_GEN_RCV_ERROR 0x00020104 +#define OID_GEN_RCV_NO_BUFFER 0x00020105 +#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 +#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 +#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 +#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 +#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 +#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 +#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 +#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 +#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 +#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A +#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B +#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C +#define OID_GEN_RCV_CRC_ERROR 0x0002020D +#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E +#define OID_GEN_GET_TIME_CAPS 0x0002020F +#define OID_GEN_GET_NETCARD_TIME 0x00020210 +// +// These are connection-oriented general OIDs. +// These replace the above OIDs for connection-oriented media. +// +#define OID_GEN_CO_SUPPORTED_LIST 0x00010101 +#define OID_GEN_CO_HARDWARE_STATUS 0x00010102 +#define OID_GEN_CO_MEDIA_SUPPORTED 0x00010103 +#define OID_GEN_CO_MEDIA_IN_USE 0x00010104 +#define OID_GEN_CO_LINK_SPEED 0x00010105 +#define OID_GEN_CO_VENDOR_ID 0x00010106 +#define OID_GEN_CO_VENDOR_DESCRIPTION 0x00010107 +#define OID_GEN_CO_DRIVER_VERSION 0x00010108 +#define OID_GEN_CO_PROTOCOL_OPTIONS 0x00010109 +#define OID_GEN_CO_MAC_OPTIONS 0x0001010A +#define OID_GEN_CO_MEDIA_CONNECT_STATUS 0x0001010B +#define OID_GEN_CO_VENDOR_DRIVER_VERSION 0x0001010C +#define OID_GEN_CO_MINIMUM_LINK_SPEED 0x0001010D +#define OID_GEN_CO_GET_TIME_CAPS 0x00010201 +#define OID_GEN_CO_GET_NETCARD_TIME 0x00010202 +// +// These are connection-oriented statistics OIDs. +// +#define OID_GEN_CO_XMIT_PDUS_OK 0x00020101 +#define OID_GEN_CO_RCV_PDUS_OK 0x00020102 +#define OID_GEN_CO_XMIT_PDUS_ERROR 0x00020103 +#define OID_GEN_CO_RCV_PDUS_ERROR 0x00020104 +#define OID_GEN_CO_RCV_PDUS_NO_BUFFER 0x00020105 +#define OID_GEN_CO_RCV_CRC_ERROR 0x00020201 +#define OID_GEN_CO_TRANSMIT_QUEUE_LENGTH 0x00020202 +#define OID_GEN_CO_BYTES_XMIT 0x00020203 +#define OID_GEN_CO_BYTES_RCV 0x00020204 +#define OID_GEN_CO_BYTES_XMIT_OUTSTANDING 0x00020205 +#define OID_GEN_CO_NETCARD_LOAD 0x00020206 +// +// These are objects for Connection-oriented media call-managers and are not +// valid for ndis drivers. Under construction. +// +#define OID_CO_ADD_PVC 0xFF000001 +#define OID_CO_DELETE_PVC 0xFF000002 +#define OID_CO_GET_CALL_INFORMATION 0xFF000003 +#define OID_CO_ADD_ADDRESS 0xFF000004 +#define OID_CO_DELETE_ADDRESS 0xFF000005 +#define OID_CO_GET_ADDRESSES 0xFF000006 +#define OID_CO_ADDRESS_CHANGE 0xFF000007 +#define OID_CO_SIGNALING_ENABLED 0xFF000008 +#define OID_CO_SIGNALING_DISABLED 0xFF000009 +// +// 802.3 Objects (Ethernet) +// +#define OID_802_3_PERMANENT_ADDRESS 0x01010101 +#define OID_802_3_CURRENT_ADDRESS 0x01010102 +#define OID_802_3_MULTICAST_LIST 0x01010103 +#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 +#define OID_802_3_MAC_OPTIONS 0x01010105 +// +// +#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 +#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 +#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 +#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 +#define OID_802_3_XMIT_DEFERRED 0x01020201 +#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 +#define OID_802_3_RCV_OVERRUN 0x01020203 +#define OID_802_3_XMIT_UNDERRUN 0x01020204 +#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 +#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 +#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 +// +// 802.5 Objects (Token-Ring) +// +#define OID_802_5_PERMANENT_ADDRESS 0x02010101 +#define OID_802_5_CURRENT_ADDRESS 0x02010102 +#define OID_802_5_CURRENT_FUNCTIONAL 0x02010103 +#define OID_802_5_CURRENT_GROUP 0x02010104 +#define OID_802_5_LAST_OPEN_STATUS 0x02010105 +#define OID_802_5_CURRENT_RING_STATUS 0x02010106 +#define OID_802_5_CURRENT_RING_STATE 0x02010107 +#define OID_802_5_LINE_ERRORS 0x02020101 +#define OID_802_5_LOST_FRAMES 0x02020102 +#define OID_802_5_BURST_ERRORS 0x02020201 +#define OID_802_5_AC_ERRORS 0x02020202 +#define OID_802_5_ABORT_DELIMETERS 0x02020203 +#define OID_802_5_FRAME_COPIED_ERRORS 0x02020204 +#define OID_802_5_FREQUENCY_ERRORS 0x02020205 +#define OID_802_5_TOKEN_ERRORS 0x02020206 +#define OID_802_5_INTERNAL_ERRORS 0x02020207 +// +// FDDI Objects +// +#define OID_FDDI_LONG_PERMANENT_ADDR 0x03010101 +#define OID_FDDI_LONG_CURRENT_ADDR 0x03010102 +#define OID_FDDI_LONG_MULTICAST_LIST 0x03010103 +#define OID_FDDI_LONG_MAX_LIST_SIZE 0x03010104 +#define OID_FDDI_SHORT_PERMANENT_ADDR 0x03010105 +#define OID_FDDI_SHORT_CURRENT_ADDR 0x03010106 +#define OID_FDDI_SHORT_MULTICAST_LIST 0x03010107 +#define OID_FDDI_SHORT_MAX_LIST_SIZE 0x03010108 +#define OID_FDDI_ATTACHMENT_TYPE 0x03020101 +#define OID_FDDI_UPSTREAM_NODE_LONG 0x03020102 +#define OID_FDDI_DOWNSTREAM_NODE_LONG 0x03020103 +#define OID_FDDI_FRAME_ERRORS 0x03020104 +#define OID_FDDI_FRAMES_LOST 0x03020105 +#define OID_FDDI_RING_MGT_STATE 0x03020106 +#define OID_FDDI_LCT_FAILURES 0x03020107 +#define OID_FDDI_LEM_REJECTS 0x03020108 +#define OID_FDDI_LCONNECTION_STATE 0x03020109 +#define OID_FDDI_SMT_STATION_ID 0x03030201 +#define OID_FDDI_SMT_OP_VERSION_ID 0x03030202 +#define OID_FDDI_SMT_HI_VERSION_ID 0x03030203 +#define OID_FDDI_SMT_LO_VERSION_ID 0x03030204 +#define OID_FDDI_SMT_MANUFACTURER_DATA 0x03030205 +#define OID_FDDI_SMT_USER_DATA 0x03030206 +#define OID_FDDI_SMT_MIB_VERSION_ID 0x03030207 +#define OID_FDDI_SMT_MAC_CT 0x03030208 +#define OID_FDDI_SMT_NON_MASTER_CT 0x03030209 +#define OID_FDDI_SMT_MASTER_CT 0x0303020A +#define OID_FDDI_SMT_AVAILABLE_PATHS 0x0303020B +#define OID_FDDI_SMT_CONFIG_CAPABILITIES 0x0303020C +#define OID_FDDI_SMT_CONFIG_POLICY 0x0303020D +#define OID_FDDI_SMT_CONNECTION_POLICY 0x0303020E +#define OID_FDDI_SMT_T_NOTIFY 0x0303020F +#define OID_FDDI_SMT_STAT_RPT_POLICY 0x03030210 +#define OID_FDDI_SMT_TRACE_MAX_EXPIRATION 0x03030211 +#define OID_FDDI_SMT_PORT_INDEXES 0x03030212 +#define OID_FDDI_SMT_MAC_INDEXES 0x03030213 +#define OID_FDDI_SMT_BYPASS_PRESENT 0x03030214 +#define OID_FDDI_SMT_ECM_STATE 0x03030215 +#define OID_FDDI_SMT_CF_STATE 0x03030216 +#define OID_FDDI_SMT_HOLD_STATE 0x03030217 +#define OID_FDDI_SMT_REMOTE_DISCONNECT_FLAG 0x03030218 +#define OID_FDDI_SMT_STATION_STATUS 0x03030219 +#define OID_FDDI_SMT_PEER_WRAP_FLAG 0x0303021A +#define OID_FDDI_SMT_MSG_TIME_STAMP 0x0303021B +#define OID_FDDI_SMT_TRANSITION_TIME_STAMP 0x0303021C +#define OID_FDDI_SMT_SET_COUNT 0x0303021D +#define OID_FDDI_SMT_LAST_SET_STATION_ID 0x0303021E +#define OID_FDDI_MAC_FRAME_STATUS_FUNCTIONS 0x0303021F +#define OID_FDDI_MAC_BRIDGE_FUNCTIONS 0x03030220 +#define OID_FDDI_MAC_T_MAX_CAPABILITY 0x03030221 +#define OID_FDDI_MAC_TVX_CAPABILITY 0x03030222 +#define OID_FDDI_MAC_AVAILABLE_PATHS 0x03030223 +#define OID_FDDI_MAC_CURRENT_PATH 0x03030224 +#define OID_FDDI_MAC_UPSTREAM_NBR 0x03030225 +#define OID_FDDI_MAC_DOWNSTREAM_NBR 0x03030226 +#define OID_FDDI_MAC_OLD_UPSTREAM_NBR 0x03030227 +#define OID_FDDI_MAC_OLD_DOWNSTREAM_NBR 0x03030228 +#define OID_FDDI_MAC_DUP_ADDRESS_TEST 0x03030229 +#define OID_FDDI_MAC_REQUESTED_PATHS 0x0303022A +#define OID_FDDI_MAC_DOWNSTREAM_PORT_TYPE 0x0303022B +#define OID_FDDI_MAC_INDEX 0x0303022C +#define OID_FDDI_MAC_SMT_ADDRESS 0x0303022D +#define OID_FDDI_MAC_LONG_GRP_ADDRESS 0x0303022E +#define OID_FDDI_MAC_SHORT_GRP_ADDRESS 0x0303022F +#define OID_FDDI_MAC_T_REQ 0x03030230 +#define OID_FDDI_MAC_T_NEG 0x03030231 +#define OID_FDDI_MAC_T_MAX 0x03030232 +#define OID_FDDI_MAC_TVX_VALUE 0x03030233 +#define OID_FDDI_MAC_T_PRI0 0x03030234 +#define OID_FDDI_MAC_T_PRI1 0x03030235 +#define OID_FDDI_MAC_T_PRI2 0x03030236 +#define OID_FDDI_MAC_T_PRI3 0x03030237 +#define OID_FDDI_MAC_T_PRI4 0x03030238 +#define OID_FDDI_MAC_T_PRI5 0x03030239 +#define OID_FDDI_MAC_T_PRI6 0x0303023A +#define OID_FDDI_MAC_FRAME_CT 0x0303023B +#define OID_FDDI_MAC_COPIED_CT 0x0303023C +#define OID_FDDI_MAC_TRANSMIT_CT 0x0303023D +#define OID_FDDI_MAC_TOKEN_CT 0x0303023E +#define OID_FDDI_MAC_ERROR_CT 0x0303023F +#define OID_FDDI_MAC_LOST_CT 0x03030240 +#define OID_FDDI_MAC_TVX_EXPIRED_CT 0x03030241 +#define OID_FDDI_MAC_NOT_COPIED_CT 0x03030242 +#define OID_FDDI_MAC_LATE_CT 0x03030243 +#define OID_FDDI_MAC_RING_OP_CT 0x03030244 +#define OID_FDDI_MAC_FRAME_ERROR_THRESHOLD 0x03030245 +#define OID_FDDI_MAC_FRAME_ERROR_RATIO 0x03030246 +#define OID_FDDI_MAC_NOT_COPIED_THRESHOLD 0x03030247 +#define OID_FDDI_MAC_NOT_COPIED_RATIO 0x03030248 +#define OID_FDDI_MAC_RMT_STATE 0x03030249 +#define OID_FDDI_MAC_DA_FLAG 0x0303024A +#define OID_FDDI_MAC_UNDA_FLAG 0x0303024B +#define OID_FDDI_MAC_FRAME_ERROR_FLAG 0x0303024C +#define OID_FDDI_MAC_NOT_COPIED_FLAG 0x0303024D +#define OID_FDDI_MAC_MA_UNITDATA_AVAILABLE 0x0303024E +#define OID_FDDI_MAC_HARDWARE_PRESENT 0x0303024F +#define OID_FDDI_MAC_MA_UNITDATA_ENABLE 0x03030250 +#define OID_FDDI_PATH_INDEX 0x03030251 +#define OID_FDDI_PATH_RING_LATENCY 0x03030252 +#define OID_FDDI_PATH_TRACE_STATUS 0x03030253 +#define OID_FDDI_PATH_SBA_PAYLOAD 0x03030254 +#define OID_FDDI_PATH_SBA_OVERHEAD 0x03030255 +#define OID_FDDI_PATH_CONFIGURATION 0x03030256 +#define OID_FDDI_PATH_T_R_MODE 0x03030257 +#define OID_FDDI_PATH_SBA_AVAILABLE 0x03030258 +#define OID_FDDI_PATH_TVX_LOWER_BOUND 0x03030259 +#define OID_FDDI_PATH_T_MAX_LOWER_BOUND 0x0303025A +#define OID_FDDI_PATH_MAX_T_REQ 0x0303025B +#define OID_FDDI_PORT_MY_TYPE 0x0303025C +#define OID_FDDI_PORT_NEIGHBOR_TYPE 0x0303025D +#define OID_FDDI_PORT_CONNECTION_POLICIES 0x0303025E +#define OID_FDDI_PORT_MAC_INDICATED 0x0303025F +#define OID_FDDI_PORT_CURRENT_PATH 0x03030260 +#define OID_FDDI_PORT_REQUESTED_PATHS 0x03030261 +#define OID_FDDI_PORT_MAC_PLACEMENT 0x03030262 +#define OID_FDDI_PORT_AVAILABLE_PATHS 0x03030263 +#define OID_FDDI_PORT_MAC_LOOP_TIME 0x03030264 +#define OID_FDDI_PORT_PMD_CLASS 0x03030265 +#define OID_FDDI_PORT_CONNECTION_CAPABILITIES 0x03030266 +#define OID_FDDI_PORT_INDEX 0x03030267 +#define OID_FDDI_PORT_MAINT_LS 0x03030268 +#define OID_FDDI_PORT_BS_FLAG 0x03030269 +#define OID_FDDI_PORT_PC_LS 0x0303026A +#define OID_FDDI_PORT_EB_ERROR_CT 0x0303026B +#define OID_FDDI_PORT_LCT_FAIL_CT 0x0303026C +#define OID_FDDI_PORT_LER_ESTIMATE 0x0303026D +#define OID_FDDI_PORT_LEM_REJECT_CT 0x0303026E +#define OID_FDDI_PORT_LEM_CT 0x0303026F +#define OID_FDDI_PORT_LER_CUTOFF 0x03030270 +#define OID_FDDI_PORT_LER_ALARM 0x03030271 +#define OID_FDDI_PORT_CONNNECT_STATE 0x03030272 +#define OID_FDDI_PORT_PCM_STATE 0x03030273 +#define OID_FDDI_PORT_PC_WITHHOLD 0x03030274 +#define OID_FDDI_PORT_LER_FLAG 0x03030275 +#define OID_FDDI_PORT_HARDWARE_PRESENT 0x03030276 +#define OID_FDDI_SMT_STATION_ACTION 0x03030277 +#define OID_FDDI_PORT_ACTION 0x03030278 +#define OID_FDDI_IF_DESCR 0x03030279 +#define OID_FDDI_IF_TYPE 0x0303027A +#define OID_FDDI_IF_MTU 0x0303027B +#define OID_FDDI_IF_SPEED 0x0303027C +#define OID_FDDI_IF_PHYS_ADDRESS 0x0303027D +#define OID_FDDI_IF_ADMIN_STATUS 0x0303027E +#define OID_FDDI_IF_OPER_STATUS 0x0303027F +#define OID_FDDI_IF_LAST_CHANGE 0x03030280 +#define OID_FDDI_IF_IN_OCTETS 0x03030281 +#define OID_FDDI_IF_IN_UCAST_PKTS 0x03030282 +#define OID_FDDI_IF_IN_NUCAST_PKTS 0x03030283 +#define OID_FDDI_IF_IN_DISCARDS 0x03030284 +#define OID_FDDI_IF_IN_ERRORS 0x03030285 +#define OID_FDDI_IF_IN_UNKNOWN_PROTOS 0x03030286 +#define OID_FDDI_IF_OUT_OCTETS 0x03030287 +#define OID_FDDI_IF_OUT_UCAST_PKTS 0x03030288 +#define OID_FDDI_IF_OUT_NUCAST_PKTS 0x03030289 +#define OID_FDDI_IF_OUT_DISCARDS 0x0303028A +#define OID_FDDI_IF_OUT_ERRORS 0x0303028B +#define OID_FDDI_IF_OUT_QLEN 0x0303028C +#define OID_FDDI_IF_SPECIFIC 0x0303028D +// +// WAN objects +// +#define OID_WAN_PERMANENT_ADDRESS 0x04010101 +#define OID_WAN_CURRENT_ADDRESS 0x04010102 +#define OID_WAN_QUALITY_OF_SERVICE 0x04010103 +#define OID_WAN_PROTOCOL_TYPE 0x04010104 +#define OID_WAN_MEDIUM_SUBTYPE 0x04010105 +#define OID_WAN_HEADER_FORMAT 0x04010106 +#define OID_WAN_GET_INFO 0x04010107 +#define OID_WAN_SET_LINK_INFO 0x04010108 +#define OID_WAN_GET_LINK_INFO 0x04010109 +#define OID_WAN_LINE_COUNT 0x0401010A +#define OID_WAN_GET_BRIDGE_INFO 0x0401020A +#define OID_WAN_SET_BRIDGE_INFO 0x0401020B +#define OID_WAN_GET_COMP_INFO 0x0401020C +#define OID_WAN_SET_COMP_INFO 0x0401020D +#define OID_WAN_GET_STATS_INFO 0x0401020E +// +// LocalTalk objects +// +#define OID_LTALK_CURRENT_NODE_ID 0x05010102 +#define OID_LTALK_IN_BROADCASTS 0x05020101 +#define OID_LTALK_IN_LENGTH_ERRORS 0x05020102 +#define OID_LTALK_OUT_NO_HANDLERS 0x05020201 +#define OID_LTALK_COLLISIONS 0x05020202 +#define OID_LTALK_DEFERS 0x05020203 +#define OID_LTALK_NO_DATA_ERRORS 0x05020204 +#define OID_LTALK_RANDOM_CTS_ERRORS 0x05020205 +#define OID_LTALK_FCS_ERRORS 0x05020206 +// +// Arcnet objects +// +#define OID_ARCNET_PERMANENT_ADDRESS 0x06010101 +#define OID_ARCNET_CURRENT_ADDRESS 0x06010102 +#define OID_ARCNET_RECONFIGURATIONS 0x06020201 +// +// TAPI objects +// +#define OID_TAPI_ACCEPT 0x07030101 +#define OID_TAPI_ANSWER 0x07030102 +#define OID_TAPI_CLOSE 0x07030103 +#define OID_TAPI_CLOSE_CALL 0x07030104 +#define OID_TAPI_CONDITIONAL_MEDIA_DETECTION 0x07030105 +#define OID_TAPI_CONFIG_DIALOG 0x07030106 +#define OID_TAPI_DEV_SPECIFIC 0x07030107 +#define OID_TAPI_DIAL 0x07030108 +#define OID_TAPI_DROP 0x07030109 +#define OID_TAPI_GET_ADDRESS_CAPS 0x0703010A +#define OID_TAPI_GET_ADDRESS_ID 0x0703010B +#define OID_TAPI_GET_ADDRESS_STATUS 0x0703010C +#define OID_TAPI_GET_CALL_ADDRESS_ID 0x0703010D +#define OID_TAPI_GET_CALL_INFO 0x0703010E +#define OID_TAPI_GET_CALL_STATUS 0x0703010F +#define OID_TAPI_GET_DEV_CAPS 0x07030110 +#define OID_TAPI_GET_DEV_CONFIG 0x07030111 +#define OID_TAPI_GET_EXTENSION_ID 0x07030112 +#define OID_TAPI_GET_ID 0x07030113 +#define OID_TAPI_GET_LINE_DEV_STATUS 0x07030114 +#define OID_TAPI_MAKE_CALL 0x07030115 +#define OID_TAPI_NEGOTIATE_EXT_VERSION 0x07030116 +#define OID_TAPI_OPEN 0x07030117 +#define OID_TAPI_PROVIDER_INITIALIZE 0x07030118 +#define OID_TAPI_PROVIDER_SHUTDOWN 0x07030119 +#define OID_TAPI_SECURE_CALL 0x0703011A +#define OID_TAPI_SELECT_EXT_VERSION 0x0703011B +#define OID_TAPI_SEND_USER_USER_INFO 0x0703011C +#define OID_TAPI_SET_APP_SPECIFIC 0x0703011D +#define OID_TAPI_SET_CALL_PARAMS 0x0703011E +#define OID_TAPI_SET_DEFAULT_MEDIA_DETECTION 0x0703011F +#define OID_TAPI_SET_DEV_CONFIG 0x07030120 +#define OID_TAPI_SET_MEDIA_MODE 0x07030121 +#define OID_TAPI_SET_STATUS_MESSAGES 0x07030122 +// +// ATM Connection Oriented Ndis +// +#define OID_ATM_SUPPORTED_VC_RATES 0x08010101 +#define OID_ATM_SUPPORTED_SERVICE_CATEGORY 0x08010102 +#define OID_ATM_SUPPORTED_AAL_TYPES 0x08010103 +#define OID_ATM_HW_CURRENT_ADDRESS 0x08010104 +#define OID_ATM_MAX_ACTIVE_VCS 0x08010105 +#define OID_ATM_MAX_ACTIVE_VCI_BITS 0x08010106 +#define OID_ATM_MAX_ACTIVE_VPI_BITS 0x08010107 +#define OID_ATM_MAX_AAL0_PACKET_SIZE 0x08010108 +#define OID_ATM_MAX_AAL1_PACKET_SIZE 0x08010109 +#define OID_ATM_MAX_AAL34_PACKET_SIZE 0x0801010A +#define OID_ATM_MAX_AAL5_PACKET_SIZE 0x0801010B +#define OID_ATM_SIGNALING_VPIVCI 0x08010201 +#define OID_ATM_ASSIGNED_VPI 0x08010202 +#define OID_ATM_ACQUIRE_ACCESS_NET_RESOURCES 0x08010203 +#define OID_ATM_RELEASE_ACCESS_NET_RESOURCES 0x08010204 +#define OID_ATM_ILMI_VPIVCI 0x08010205 +#define OID_ATM_DIGITAL_BROADCAST_VPIVCI 0x08010206 +#define OID_ATM_GET_NEAREST_FLOW 0x08010207 +#define OID_ATM_ALIGNMENT_REQUIRED 0x08010208 +// +// ATM specific statistics OIDs. +// +#define OID_ATM_RCV_CELLS_OK 0x08020101 +#define OID_ATM_XMIT_CELLS_OK 0x08020102 +#define OID_ATM_RCV_CELLS_DROPPED 0x08020103 +#define OID_ATM_RCV_INVALID_VPI_VCI 0x08020201 +#define OID_ATM_CELLS_HEC_ERROR 0x08020202 +#define OID_ATM_RCV_REASSEMBLY_ERROR 0x08020203 +// +// PCCA (Wireless) object +// +// +// All WirelessWAN devices must support the following OIDs +// +#define OID_WW_GEN_NETWORK_TYPES_SUPPORTED 0x09010101 +#define OID_WW_GEN_NETWORK_TYPE_IN_USE 0x09010102 +#define OID_WW_GEN_HEADER_FORMATS_SUPPORTED 0x09010103 +#define OID_WW_GEN_HEADER_FORMAT_IN_USE 0x09010104 +#define OID_WW_GEN_INDICATION_REQUEST 0x09010105 +#define OID_WW_GEN_DEVICE_INFO 0x09010106 +#define OID_WW_GEN_OPERATION_MODE 0x09010107 +#define OID_WW_GEN_LOCK_STATUS 0x09010108 +#define OID_WW_GEN_DISABLE_TRANSMITTER 0x09010109 +#define OID_WW_GEN_NETWORK_ID 0x0901010A +#define OID_WW_GEN_PERMANENT_ADDRESS 0x0901010B +#define OID_WW_GEN_CURRENT_ADDRESS 0x0901010C +#define OID_WW_GEN_SUSPEND_DRIVER 0x0901010D +#define OID_WW_GEN_BASESTATION_ID 0x0901010E +#define OID_WW_GEN_CHANNEL_ID 0x0901010F +#define OID_WW_GEN_ENCRYPTION_SUPPORTED 0x09010110 +#define OID_WW_GEN_ENCRYPTION_IN_USE 0x09010111 +#define OID_WW_GEN_ENCRYPTION_STATE 0x09010112 +#define OID_WW_GEN_CHANNEL_QUALITY 0x09010113 +#define OID_WW_GEN_REGISTRATION_STATUS 0x09010114 +#define OID_WW_GEN_RADIO_LINK_SPEED 0x09010115 +#define OID_WW_GEN_LATENCY 0x09010116 +#define OID_WW_GEN_BATTERY_LEVEL 0x09010117 +#define OID_WW_GEN_EXTERNAL_POWER 0x09010118 +// +// Network Dependent OIDs - Mobitex: +// +#define OID_WW_MBX_SUBADDR 0x09050101 +// OID 0x09050102 is reserved and may not be used +#define OID_WW_MBX_FLEXLIST 0x09050103 +#define OID_WW_MBX_GROUPLIST 0x09050104 +#define OID_WW_MBX_TRAFFIC_AREA 0x09050105 +#define OID_WW_MBX_LIVE_DIE 0x09050106 +#define OID_WW_MBX_TEMP_DEFAULTLIST 0x09050107 +// +// Network Dependent OIDs - Pinpoint: +// +#define OID_WW_PIN_LOC_AUTHORIZE 0x09090101 +#define OID_WW_PIN_LAST_LOCATION 0x09090102 +#define OID_WW_PIN_LOC_FIX 0x09090103 +// +// Network Dependent - CDPD: +// +#define OID_WW_CDPD_SPNI 0x090D0101 +#define OID_WW_CDPD_WASI 0x090D0102 +#define OID_WW_CDPD_AREA_COLOR 0x090D0103 +#define OID_WW_CDPD_TX_POWER_LEVEL 0x090D0104 +#define OID_WW_CDPD_EID 0x090D0105 +#define OID_WW_CDPD_HEADER_COMPRESSION 0x090D0106 +#define OID_WW_CDPD_DATA_COMPRESSION 0x090D0107 +#define OID_WW_CDPD_CHANNEL_SELECT 0x090D0108 +#define OID_WW_CDPD_CHANNEL_STATE 0x090D0109 +#define OID_WW_CDPD_NEI 0x090D010A +#define OID_WW_CDPD_NEI_STATE 0x090D010B +#define OID_WW_CDPD_SERVICE_PROVIDER_IDENTIFIER 0x090D010C +#define OID_WW_CDPD_SLEEP_MODE 0x090D010D +#define OID_WW_CDPD_CIRCUIT_SWITCHED 0x090D010E +#define OID_WW_CDPD_TEI 0x090D010F +#define OID_WW_CDPD_RSSI 0x090D0110 +// +// Network Dependent - Ardis: +// +#define OID_WW_ARD_SNDCP 0x09110101 +#define OID_WW_ARD_TMLY_MSG 0x09110102 +#define OID_WW_ARD_DATAGRAM 0x09110103 +// +// Network Dependent - DataTac: +// +#define OID_WW_TAC_COMPRESSION 0x09150101 +#define OID_WW_TAC_SET_CONFIG 0x09150102 +#define OID_WW_TAC_GET_STATUS 0x09150103 +#define OID_WW_TAC_USER_HEADER 0x09150104 +// +// Network Dependent - Metricom: +// +#define OID_WW_MET_FUNCTION 0x09190101 +// +// IRDA objects +// +#define OID_IRDA_RECEIVING 0x0A010100 +#define OID_IRDA_TURNAROUND_TIME 0x0A010101 +#define OID_IRDA_SUPPORTED_SPEEDS 0x0A010102 +#define OID_IRDA_LINK_SPEED 0x0A010103 +#define OID_IRDA_MEDIA_BUSY 0x0A010104 +#define OID_IRDA_EXTRA_RCV_BOFS 0x0A010200 +#define OID_IRDA_RATE_SNIFF 0x0A010201 +#define OID_IRDA_UNICAST_LIST 0x0A010202 +#define OID_IRDA_MAX_UNICAST_LIST_SIZE 0x0A010203 +#define OID_IRDA_MAX_RECEIVE_WINDOW_SIZE 0x0A010204 +#define OID_IRDA_MAX_SEND_WINDOW_SIZE 0x0A010205 +// +// Medium the Ndis Driver is running on (OID_GEN_MEDIA_SUPPORTED/ +// OID_GEN_MEDIA_IN_USE). +// +typedef enum _NDIS_MEDIUM { + NdisMedium802_3, + NdisMedium802_5, + NdisMediumFddi, + NdisMediumWan, + NdisMediumLocalTalk, + NdisMediumDix, // defined for convenience, not a real medium + NdisMediumArcnetRaw, + NdisMediumArcnet878_2, + NdisMediumAtm, + NdisMediumWirelessWan, + NdisMediumIrda, + NdisMediumMax // Not a real medium, defined as an upper-bound +} NDIS_MEDIUM, *PNDIS_MEDIUM; + +// +// Hardware status codes (OID_GEN_HARDWARE_STATUS). +// +typedef enum _NDIS_HARDWARE_STATUS { + NdisHardwareStatusReady, + NdisHardwareStatusInitializing, + NdisHardwareStatusReset, + NdisHardwareStatusClosing, + NdisHardwareStatusNotReady +} NDIS_HARDWARE_STATUS, *PNDIS_HARDWARE_STATUS; + +// +// this is the type passed in the OID_GEN_GET_TIME_CAPS request +// +typedef struct _GEN_GET_TIME_CAPS { + ULONG Flags; // Bits defined below + + ULONG ClockPrecision; +} GEN_GET_TIME_CAPS, *PGEN_GET_TIME_CAPS; + +#define READABLE_LOCAL_CLOCK 0x000000001 +#define CLOCK_NETWORK_DERIVED 0x000000002 +#define CLOCK_PRECISION 0x000000004 +#define RECEIVE_TIME_INDICATION_CAPABLE 0x000000008 +#define TIMED_SEND_CAPABLE 0x000000010 +#define TIME_STAMP_CAPABLE 0x000000020 +// +// +// this is the type passed in the OID_GEN_GET_NETCARD_TIME request +// +typedef struct _GEN_GET_NETCARD_TIME { + ULONG ReadTime; +} GEN_GET_NETCARD_TIME, *PGEN_GET_NETCARD_TIME; + +// +// Defines the attachment types for FDDI (OID_FDDI_ATTACHMENT_TYPE). +// +typedef enum _NDIS_FDDI_ATTACHMENT_TYPE { + NdisFddiTypeIsolated = 1, + NdisFddiTypeLocalA, + NdisFddiTypeLocalB, + NdisFddiTypeLocalAB, + NdisFddiTypeLocalS, + NdisFddiTypeWrapA, + NdisFddiTypeWrapB, + NdisFddiTypeWrapAB, + NdisFddiTypeWrapS, + NdisFddiTypeCWrapA, + NdisFddiTypeCWrapB, + NdisFddiTypeCWrapS, + NdisFddiTypeThrough +} NDIS_FDDI_ATTACHMENT_TYPE, *PNDIS_FDDI_ATTACHMENT_TYPE; + +// +// Defines the ring management states for FDDI (OID_FDDI_RING_MGT_STATE). +// +typedef enum _NDIS_FDDI_RING_MGT_STATE { + NdisFddiRingIsolated = 1, + NdisFddiRingNonOperational, + NdisFddiRingOperational, + NdisFddiRingDetect, + NdisFddiRingNonOperationalDup, + NdisFddiRingOperationalDup, + NdisFddiRingDirected, + NdisFddiRingTrace +} NDIS_FDDI_RING_MGT_STATE, *PNDIS_FDDI_RING_MGT_STATE; + +// +// Defines the Lconnection state for FDDI (OID_FDDI_LCONNECTION_STATE). +// +typedef enum _NDIS_FDDI_LCONNECTION_STATE { + NdisFddiStateOff = 1, + NdisFddiStateBreak, + NdisFddiStateTrace, + NdisFddiStateConnect, + NdisFddiStateNext, + NdisFddiStateSignal, + NdisFddiStateJoin, + NdisFddiStateVerify, + NdisFddiStateActive, + NdisFddiStateMaintenance +} NDIS_FDDI_LCONNECTION_STATE, *PNDIS_FDDI_LCONNECTION_STATE; + +// +// Defines the medium subtypes for WAN medium (OID_WAN_MEDIUM_SUBTYPE). +// +typedef enum _NDIS_WAN_MEDIUM_SUBTYPE { + NdisWanMediumHub, + NdisWanMediumX_25, + NdisWanMediumIsdn, + NdisWanMediumSerial, + NdisWanMediumFrameRelay, + NdisWanMediumAtm, + NdisWanMediumSonet, + NdisWanMediumSW56K +} NDIS_WAN_MEDIUM_SUBTYPE, *PNDIS_WAN_MEDIUM_SUBTYPE; + +// +// Defines the header format for WAN medium (OID_WAN_HEADER_FORMAT). +// +typedef enum _NDIS_WAN_HEADER_FORMAT { + NdisWanHeaderNative, // src/dest based on subtype, followed by NLPID + NdisWanHeaderEthernet // emulation of ethernet header +} NDIS_WAN_HEADER_FORMAT, *PNDIS_WAN_HEADER_FORMAT; + +// +// Defines the line quality on a WAN line (OID_WAN_QUALITY_OF_SERVICE). +// +typedef enum _NDIS_WAN_QUALITY { + NdisWanRaw, + NdisWanErrorControl, + NdisWanReliable +} NDIS_WAN_QUALITY, *PNDIS_WAN_QUALITY; + +// +// Defines the state of a token-ring adapter (OID_802_5_CURRENT_RING_STATE). +// +typedef enum _NDIS_802_5_RING_STATE { + NdisRingStateOpened = 1, + NdisRingStateClosed, + NdisRingStateOpening, + NdisRingStateClosing, + NdisRingStateOpenFailure, + NdisRingStateRingFailure +} NDIS_802_5_RING_STATE, *PNDIS_802_5_RING_STATE; + +// +// Defines the state of the LAN media +// +typedef enum _NDIS_MEDIA_STATE { + NdisMediaStateConnected, + NdisMediaStateDisconnected +} NDIS_MEDIA_STATE, *PNDIS_MEDIA_STATE; + +// +// The following is set on a per-packet basis as OOB data with NdisClass802_3Priority +// +typedef ULONG Priority_802_3; // 0-7 priority levels +// +// The following structure is used to query OID_GEN_CO_LINK_SPEED and +// OID_GEN_CO_MINIMUM_LINK_SPEED. The first OID will return the current +// link speed of the adapter. The second will return the minimum link speed +// the adapter is capable of. +// + +typedef struct _NDIS_CO_LINK_SPEED { + ULONG Outbound; + ULONG Inbound; +} NDIS_CO_LINK_SPEED, + +*PNDIS_CO_LINK_SPEED; +// +// Ndis Packet Filter Bits (OID_GEN_CURRENT_PACKET_FILTER). +// +#define NDIS_PACKET_TYPE_DIRECTED 0x0001 +#define NDIS_PACKET_TYPE_MULTICAST 0x0002 +#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x0004 +#define NDIS_PACKET_TYPE_BROADCAST 0x0008 +#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x0010 +#define NDIS_PACKET_TYPE_PROMISCUOUS 0x0020 +#define NDIS_PACKET_TYPE_SMT 0x0040 +#define NDIS_PACKET_TYPE_ALL_LOCAL 0x0080 +#define NDIS_PACKET_TYPE_MAC_FRAME 0x8000 +#define NDIS_PACKET_TYPE_FUNCTIONAL 0x4000 +#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x2000 +#define NDIS_PACKET_TYPE_GROUP 0x1000 +// +// Ndis Token-Ring Ring Status Codes (OID_802_5_CURRENT_RING_STATUS). +// +#define NDIS_RING_SIGNAL_LOSS 0x00008000 +#define NDIS_RING_HARD_ERROR 0x00004000 +#define NDIS_RING_SOFT_ERROR 0x00002000 +#define NDIS_RING_TRANSMIT_BEACON 0x00001000 +#define NDIS_RING_LOBE_WIRE_FAULT 0x00000800 +#define NDIS_RING_AUTO_REMOVAL_ERROR 0x00000400 +#define NDIS_RING_REMOVE_RECEIVED 0x00000200 +#define NDIS_RING_COUNTER_OVERFLOW 0x00000100 +#define NDIS_RING_SINGLE_STATION 0x00000080 +#define NDIS_RING_RING_RECOVERY 0x00000040 +// +// Ndis protocol option bits (OID_GEN_PROTOCOL_OPTIONS). +// +#define NDIS_PROT_OPTION_ESTIMATED_LENGTH 0x00000001 +#define NDIS_PROT_OPTION_NO_LOOPBACK 0x00000002 +#define NDIS_PROT_OPTION_NO_RSVD_ON_RCVPKT 0x00000004 +// +// Ndis MAC option bits (OID_GEN_MAC_OPTIONS). +// +#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 +#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 +#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 +#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 +#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 +#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 +#define NDIS_MAC_OPTION_RESERVED 0x80000000 +// +// NDIS MAC option bits for OID_GEN_CO_MAC_OPTIONS. +// +#define NDIS_CO_MAC_OPTION_DYNAMIC_LINK_SPEED 0x00000001 +#ifdef IRDA +// +// The following is set on a per-packet basis as OOB data with NdisClassIrdaPacketInfo +// This is the per-packet info specified on a per-packet basis +// +typedef struct _NDIS_IRDA_PACKET_INFO { + UINT ExtraBOFs; + UINT MinTurnAroundTime; +} NDIS_IRDA_PACKET_INFO, *PNDIS_IRDA_PACKET_INFO; + +#endif +#ifdef WIRELESS_WAN +// +// Wireless WAN structure definitions +// +// +// currently defined Wireless network subtypes +// +typedef enum _NDIS_WW_NETWORK_TYPE { + NdisWWGeneric, + NdisWWMobitex, + NdisWWPinpoint, + NdisWWCDPD, + NdisWWArdis, + NdisWWDataTAC, + NdisWWMetricom, + NdisWWGSM, + NdisWWCDMA, + NdisWWTDMA, + NdisWWAMPS, + NdisWWInmarsat, + NdisWWpACT +} NDIS_WW_NETWORK_TYPE; + +// +// currently defined header formats +// +typedef enum _NDIS_WW_HEADER_FORMAT { + NdisWWDIXEthernetFrames, + NdisWWMPAKFrames, + NdisWWRDLAPFrames, + NdisWWMDC4800Frames +} NDIS_WW_HEADER_FORMAT; + +// +// currently defined encryption types +// +typedef enum _NDIS_WW_ENCRYPTION_TYPE { + NdisWWUnknownEncryption = -1, + NdisWWNoEncryption, + NdisWWDefaultEncryption +} NDIS_WW_ENCRYPTION_TYPE, *PNDIS_WW_ENCRYPTION_TYPE; + +// +// OID_WW_GEN_INDICATION_REQUEST +// +typedef struct _NDIS_WW_INDICATION_REQUEST { + NDIS_OID Oid; // IN + + UINT uIndicationFlag; // IN + + UINT uApplicationToken; // IN OUT + + HANDLE hIndicationHandle; // IN OUT + + INT iPollingInterval; // IN OUT + + NDIS_VAR_DATA_DESC InitialValue; // IN OUT + + NDIS_VAR_DATA_DESC OIDIndicationValue; // OUT - only valid after indication + + NDIS_VAR_DATA_DESC TriggerValue; // IN + +} NDIS_WW_INDICATION_REQUEST, *PNDIS_WW_INDICATION_REQUEST; + +#define OID_INDICATION_REQUEST_ENABLE 0x0000 +#define OID_INDICATION_REQUEST_CANCEL 0x0001 +// +// OID_WW_GEN_DEVICE_INFO +// +typedef struct _WW_DEVICE_INFO { + NDIS_VAR_DATA_DESC Manufacturer; + NDIS_VAR_DATA_DESC ModelNum; + NDIS_VAR_DATA_DESC SWVersionNum; + NDIS_VAR_DATA_DESC SerialNum; +} WW_DEVICE_INFO, *PWW_DEVICE_INFO; + +// +// OID_WW_GEN_OPERATION_MODE +// +typedef INT WW_OPERATION_MODE; // 0 = Normal mode + // 1 = Power saving mode + // -1 = mode unknown +// +// OID_WW_GEN_LOCK_STATUS +// + +typedef INT WW_LOCK_STATUS; // 0 = unlocked + // 1 = locked + // -1 = unknown lock status +// +// OID_WW_GEN_DISABLE_TRANSMITTER +// + +typedef INT WW_DISABLE_TRANSMITTER; // 0 = transmitter enabled + // 1 = transmitter disabled + // -1 = unknown value +// +// OID_WW_GEN_NETWORK_ID +// + +typedef NDIS_VAR_DATA_DESC WW_NETWORK_ID; +// +// OID_WW_GEN_PERMANENT_ADDRESS +// +typedef NDIS_VAR_DATA_DESC WW_PERMANENT_ADDRESS; +// +// OID_WW_GEN_CURRENT_ADDRESS +// +typedef struct _WW_CURRENT_ADDRESS { + NDIS_WW_HEADER_FORMAT Format; + NDIS_VAR_DATA_DESC Address; +} WW_CURRENT_ADDRESS, *PWW_CURRENT_ADDRESS; + +// +// OID_WW_GEN_SUSPEND_DRIVER +// +typedef BOOLEAN WW_SUSPEND_DRIVER; // 0 = driver operational + // 1 = driver suspended +// +// OID_WW_GEN_BASESTATION_ID +// + +typedef NDIS_VAR_DATA_DESC WW_BASESTATION_ID; +// +// OID_WW_GEN_CHANNEL_ID +// +typedef NDIS_VAR_DATA_DESC WW_CHANNEL_ID; +// +// OID_WW_GEN_ENCRYPTION_STATE +// +typedef BOOLEAN WW_ENCRYPTION_STATE; // 0 = if encryption is disabled + // 1 = if encryption is enabled +// +// OID_WW_GEN_CHANNEL_QUALITY +// + +typedef INT WW_CHANNEL_QUALITY; // 0 = Not in network contact, + // 1-100 = Quality of Channel (100 is highest quality). + // -1 = channel quality is unknown +// +// OID_WW_GEN_REGISTRATION_STATUS +// + +typedef INT WW_REGISTRATION_STATUS; // 0 = Registration denied + // 1 = Registration pending + // 2 = Registered + // -1 = unknown registration status +// +// OID_WW_GEN_RADIO_LINK_SPEED +// + +typedef UINT WW_RADIO_LINK_SPEED; // Bits per second. +// +// OID_WW_GEN_LATENCY +// + +typedef UINT WW_LATENCY; // milliseconds +// +// OID_WW_GEN_BATTERY_LEVEL +// + +typedef INT WW_BATTERY_LEVEL; // 0-100 = battery level in percentage + // (100=fully charged) + // -1 = unknown battery level. +// +// OID_WW_GEN_EXTERNAL_POWER +// + +typedef INT WW_EXTERNAL_POWER; // 0 = no external power connected + // 1 = external power connected + // -1 = unknown +// +// OID_WW_MET_FUNCTION +// + +typedef NDIS_VAR_DATA_DESC WW_MET_FUNCTION; +// +// OID_WW_TAC_COMPRESSION +// +typedef BOOLEAN WW_TAC_COMPRESSION; // Determines whether or not network level compression + // is being used. +// +// OID_WW_TAC_SET_CONFIG +// + +typedef struct _WW_TAC_SETCONFIG { + NDIS_VAR_DATA_DESC RCV_MODE; + NDIS_VAR_DATA_DESC TX_CONTROL; + NDIS_VAR_DATA_DESC RX_CONTROL; + NDIS_VAR_DATA_DESC FLOW_CONTROL; + NDIS_VAR_DATA_DESC RESET_CNF; + NDIS_VAR_DATA_DESC READ_CNF; +} WW_TAC_SETCONFIG, *PWW_TAC_SETCONFIG; + +// +// OID_WW_TAC_GET_STATUS +// +typedef struct _WW_TAC_GETSTATUS { + BOOLEAN Action; // Set = Execute command. + + NDIS_VAR_DATA_DESC Command; + NDIS_VAR_DATA_DESC Option; + NDIS_VAR_DATA_DESC Response; // The response to the requested command + // - max. length of string is 256 octets. + +} WW_TAC_GETSTATUS, *PWW_TAC_GETSTATUS; + +// +// OID_WW_TAC_USER_HEADER +// +typedef NDIS_VAR_DATA_DESC WW_TAC_USERHEADER; // This will hold the user header - Max. 64 octets. +// +// OID_WW_ARD_SNDCP +// + +typedef struct _WW_ARD_SNDCP { + NDIS_VAR_DATA_DESC Version; // The version of SNDCP protocol supported. + + INT BlockSize; // The block size used for SNDCP + + INT Window; // The window size used in SNDCP + +} WW_ARD_SNDCP, *PWW_ARD_SNDCP; + +// +// OID_WW_ARD_TMLY_MSG +// +typedef BOOLEAN WW_ARD_CHANNEL_STATUS; // The current status of the inbound RF Channel. +// +// OID_WW_ARD_DATAGRAM +// + +typedef struct _WW_ARD_DATAGRAM { + BOOLEAN LoadLevel; // Byte that contains the load level info. + + INT SessionTime; // Datagram session time remaining. + + NDIS_VAR_DATA_DESC HostAddr; // Host address. + + NDIS_VAR_DATA_DESC THostAddr; // Test host address. + +} WW_ARD_DATAGRAM, *PWW_ARD_DATAGRAM; + +// +// OID_WW_CDPD_SPNI +// +typedef struct _WW_CDPD_SPNI { + UINT SPNI[10]; //10 16-bit service provider network IDs + + INT OperatingMode; // 0 = ignore SPNI, + // 1 = require SPNI from list, + // 2 = prefer SPNI from list. + // 3 = exclude SPNI from list. + +} WW_CDPD_SPNI, *PWW_CDPD_SPNI; + +// +// OID_WW_CDPD_WASI +// +typedef struct _WW_CDPD_WIDE_AREA_SERVICE_ID { + UINT WASI[10]; //10 16-bit wide area service IDs + + INT OperatingMode; // 0 = ignore WASI, + // 1 = Require WASI from list, + // 2 = prefer WASI from list + // 3 = exclude WASI from list. + +} WW_CDPD_WIDE_AREA_SERVICE_ID, *PWW_CDPD_WIDE_AREA_SERVICE_ID; + +// +// OID_WW_CDPD_AREA_COLOR +// +typedef INT WW_CDPD_AREA_COLOR; +// +// OID_WW_CDPD_TX_POWER_LEVEL +// +typedef UINT WW_CDPD_TX_POWER_LEVEL; +// +// OID_WW_CDPD_EID +// +typedef NDIS_VAR_DATA_DESC WW_CDPD_EID; +// +// OID_WW_CDPD_HEADER_COMPRESSION +// +typedef INT WW_CDPD_HEADER_COMPRESSION; // 0 = no header compression, + // 1 = always compress headers, + // 2 = compress headers if MD-IS does + // -1 = unknown +// +// OID_WW_CDPD_DATA_COMPRESSION +// + +typedef INT WW_CDPD_DATA_COMPRESSION; // 0 = no data compression, + // 1 = data compression enabled + // -1 = unknown +// +// OID_WW_CDPD_CHANNEL_SELECT +// + +typedef struct _WW_CDPD_CHANNEL_SELECT { + UINT ChannelID; // channel number + + UINT fixedDuration; // duration in seconds + +} WW_CDPD_CHANNEL_SELECT, *PWW_CDPD_CHANNEL_SELECT; + +// +// OID_WW_CDPD_CHANNEL_STATE +// +typedef enum _WW_CDPD_CHANNEL_STATE { + CDPDChannelNotAvail, + CDPDChannelScanning, + CDPDChannelInitAcquired, + CDPDChannelAcquired, + CDPDChannelSleeping, + CDPDChannelWaking, + CDPDChannelCSDialing, + CDPDChannelCSRedial, + CDPDChannelCSAnswering, + CDPDChannelCSConnected, + CDPDChannelCSSuspended +} WW_CDPD_CHANNEL_STATE, *PWW_CDPD_CHANNEL_STATE; + +// +// OID_WW_CDPD_NEI +// +typedef enum _WW_CDPD_NEI_FORMAT { + CDPDNeiIPv4, + CDPDNeiCLNP, + CDPDNeiIPv6 +} WW_CDPD_NEI_FORMAT, *PWW_CDPD_NEI_FORMAT; +typedef enum _WW_CDPD_NEI_TYPE { + CDPDNeiIndividual, + CDPDNeiMulticast, + CDPDNeiBroadcast +} WW_CDPD_NEI_TYPE; +typedef struct _WW_CDPD_NEI { + UINT uNeiIndex; + WW_CDPD_NEI_FORMAT NeiFormat; + WW_CDPD_NEI_TYPE NeiType; + WORD NeiGmid; // group member identifier, only + // meaningful if NeiType == + // CDPDNeiMulticast + + NDIS_VAR_DATA_DESC NeiAddress; +} WW_CDPD_NEI; + +// +// OID_WW_CDPD_NEI_STATE +// +typedef enum _WW_CDPD_NEI_STATE { + CDPDUnknown, + CDPDRegistered, + CDPDDeregistered +} WW_CDPD_NEI_STATE, *PWW_CDPD_NEI_STATE; +typedef enum _WW_CDPD_NEI_SUB_STATE { + CDPDPending, // Registration pending + CDPDNoReason, // Registration denied - no reason given + CDPDMDISNotCapable, // Registration denied - MD-IS not capable of + // handling M-ES at this time + CDPDNEINotAuthorized, // Registration denied - NEI is not authorized to + // use this subnetwork + CDPDInsufficientAuth, // Registration denied - M-ES gave insufficient + // authentication credentials + CDPDUnsupportedAuth, // Registration denied - M-ES gave unsupported + // authentication credentials + CDPDUsageExceeded, // Registration denied - NEI has exceeded usage + // limitations + CDPDDeniedThisNetwork // Registration denied on this network, service + // may be obtained on alternate Service Provider + // network +} WW_CDPD_NEI_SUB_STATE; +typedef struct _WW_CDPD_NEI_REG_STATE { + UINT uNeiIndex; + WW_CDPD_NEI_STATE NeiState; + WW_CDPD_NEI_SUB_STATE NeiSubState; +} WW_CDPD_NEI_REG_STATE, *PWW_CDPD_NEI_REG_STATE; + +// +// OID_WW_CDPD_SERVICE_PROVIDER_IDENTIFIER +// +typedef struct _WW_CDPD_SERVICE_PROVIDER_ID { + UINT SPI[10]; //10 16-bit service provider IDs + + INT OperatingMode; // 0 = ignore SPI, + // 1 = require SPI from list, + // 2 = prefer SPI from list. + // 3 = exclude SPI from list. + +} WW_CDPD_SERVICE_PROVIDER_ID, *PWW_CDPD_SERVICE_PROVIDER_ID; + +// +// OID_WW_CDPD_SLEEP_MODE +// +typedef INT WW_CDPD_SLEEP_MODE; +// +// OID_WW_CDPD_TEI +// +typedef ULONG WW_CDPD_TEI; +// +// OID_WW_CDPD_CIRCUIT_SWITCHED +// +typedef struct _WW_CDPD_CIRCUIT_SWITCHED { + INT service_preference; // -1 = unknown, + // 0 = always use packet switched CDPD, + // 1 = always use CS CDPD via AMPS, + // 2 = always use CS CDPD via PSTN, + // 3 = use circuit switched via AMPS only + // when packet switched is not available. + // 4 = use packet switched only when circuit + // switched via AMPS is not available. + // 5 = device manuf. defined service + // preference. + // 6 = device manuf. defined service + // preference. + + INT service_status; // -1 = unknown, + // 0 = packet switched CDPD, + // 1 = circuit switched CDPD via AMPS, + // 2 = circuit switched CDPD via PSTN. + + INT connect_rate; // CS connection bit rate (bits per second). + // 0 = no active connection, + // -1 = unknown + // Dial code last used to dial. + + NDIS_VAR_DATA_DESC dial_code[20]; + + UINT sid; // Current AMPS system ID + + INT a_b_side_selection; // -1 = unknown, + // 0 = no AMPS service + // 1 = AMPS "A" side channels selected + // 2 = AMPS "B" side channels selected + + INT AMPS_channel; // -1= unknown + // 0 = no AMPS service. + // 1-1023 = AMPS channel number in use + + UINT action; // 0 = no action + // 1 = suspend (hangup) + // 2 = dial + + // Default dial code for CS CDPD service + // encoded as specified in the CS CDPD + // implementor guidelines. + NDIS_VAR_DATA_DESC default_dial[20]; + + // Number for the CS CDPD network to call + // back the mobile, encoded as specified in + // the CS CDPD implementor guidelines. + NDIS_VAR_DATA_DESC call_back[20]; + + UINT sid_list[10]; // List of 10 16-bit preferred AMPS + // system IDs for CS CDPD. + + UINT inactivity_timer; // Wait time after last data before dropping + // call. + // 0-65535 = inactivity time limit (seconds). + + UINT receive_timer; // secs. per CS-CDPD Implementor Guidelines. + + UINT conn_resp_timer; // secs. per CS-CDPD Implementor Guidelines. + + UINT reconn_resp_timer; // secs. per CS-CDPD Implementor Guidelines. + + UINT disconn_timer; // secs. per CS-CDPD Implementor Guidelines. + + UINT NEI_reg_timer; // secs. per CS-CDPD Implementor Guidelines. + + UINT reconn_retry_timer; // secs. per CS-CDPD Implementor Guidelines. + + UINT link_reset_timer; // secs. per CS-CDPD Implementor Guidelines. + + UINT link_reset_ack_timer; // secs. per CS-CDPD Implementor Guidelines. + + UINT n401_retry_limit; // per CS-CDPD Implementor Guidelines. + + UINT n402_retry_limit; // per CS-CDPD Implementor Guidelines. + + UINT n404_retry_limit; // per CS-CDPD Implementor Guidelines. + + UINT n405_retry_limit; // per CS-CDPD Implementor Guidelines. + +} WW_CDPD_CIRCUIT_SWITCHED, *WW_PCDPD_CIRCUIT_SWITCHED; +typedef UINT WW_CDPD_RSSI; +// +// OID_WW_PIN_LOC_AUTHORIZE +// +typedef INT WW_PIN_AUTHORIZED; // 0 = unauthorized + // 1 = authorized + // -1 = unknown +// +// OID_WW_PIN_LAST_LOCATION +// OID_WW_PIN_LOC_FIX +// + +typedef struct _WW_PIN_LOCATION { + INT Latitude; // Latitude in hundredths of a second + + INT Longitude; // Longitude in hundredths of a second + + INT Altitude; // Altitude in feet + + INT FixTime; // Time of the location fix, since midnight, local time (of the + // current day), in tenths of a second + + INT NetTime; // Current local network time of the current day, since midnight, + // in tenths of a second + + INT LocQuality; // 0-100 = location quality + + INT LatReg; // Latitude registration offset, in hundredths of a second + + INT LongReg; // Longitude registration offset, in hundredths of a second + + INT GMTOffset; // Offset in minutes of the local time zone from GMT + +} WW_PIN_LOCATION, *PWW_PIN_LOCATION; + +// +// The following is set on a per-packet basis as OOB data with NdisClassWirelessWanMbxMailbox +// +typedef ULONG WW_MBX_MAILBOX_FLAG; // 1 = set mailbox flag, 0 = do not set mailbox flag +// +// OID_WW_MBX_SUBADDR +// + +typedef struct _WW_MBX_PMAN { + BOOLEAN ACTION; // 0 = Login PMAN, 1 = Logout PMAN + + UINT MAN; + UCHAR PASSWORD[8]; // Password should be null for Logout and indications. + // Maximum length of password is 8 chars. + +} WW_MBX_PMAN, *PWW_MBX_PMAN; + +// +// OID_WW_MBX_FLEXLIST +// +typedef struct _WW_MBX_FLEXLIST { + INT count; // Number of MAN entries used. + // -1=unknown. + + UINT MAN[7]; // List of MANs. + +} WW_MBX_FLEXLIST; + +// +// OID_WW_MBX_GROUPLIST +// +typedef struct _WW_MBX_GROUPLIST { + INT count; // Number of MAN entries used. + // -1=unknown. + + UINT MAN[15]; // List of MANs. + +} WW_MBX_GROUPLIST; + +// +// OID_WW_MBX_TRAFFIC_AREA +// +typedef enum _WW_MBX_TRAFFIC_AREA { + unknown_traffic_area, // The driver has no information about the current traffic area. + in_traffic_area, // Mobile unit has entered a subscribed traffic area. + in_auth_traffic_area, // Mobile unit is outside traffic area but is authorized. + unauth_traffic_area // Mobile unit is outside traffic area but is un-authorized. +} WW_MBX_TRAFFIC_AREA; + +// +// OID_WW_MBX_LIVE_DIE +// +typedef INT WW_MBX_LIVE_DIE; // 0 = DIE last received + // 1 = LIVE last received + // -1 = unknown +// +// OID_WW_MBX_TEMP_DEFAULTLIST +// + +typedef struct _WW_MBX_CHANNEL_PAIR { + UINT Mobile_Tx; + UINT Mobile_Rx; +} WW_MBX_CHANNEL_PAIR, *PWW_MBX_CHANNEL_PAIR; +typedef struct _WW_MBX_TEMPDEFAULTLIST { + UINT Length; + WW_MBX_CHANNEL_PAIR ChannelPair[1]; +} WW_MBX_TEMPDEFAULTLIST, *WW_PMBX_TEMPDEFAULTLIST; + +#endif // WIRELESS_WAN +#endif // _NTDDNDIS_ diff --git a/winpcap/Common/Ntddpack.h b/winpcap/Common/Ntddpack.h new file mode 100644 index 0000000..30945c1 --- /dev/null +++ b/winpcap/Common/Ntddpack.h @@ -0,0 +1,26 @@ + +#ifndef __NTDDPACKET +#define __NTDDPACKET 1 +#include "devioctl.h" +/*#include */ +struct _PACKET_OID_DATA { + ULONG Oid; + ULONG Length; + UCHAR Data[1]; +}; + +typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA; + +/*#include */ +#define FILE_DEVICE_PROTOCOL 0x8000 +#define IOCTL_PROTOCOL_QUERY_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 0 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_SET_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 1 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_STATISTICS CTL_CODE(FILE_DEVICE_PROTOCOL, 2 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_RESET CTL_CODE(FILE_DEVICE_PROTOCOL, 3 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_READ CTL_CODE(FILE_DEVICE_PROTOCOL, 4 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_WRITE CTL_CODE(FILE_DEVICE_PROTOCOL, 5 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_MACNAME CTL_CODE(FILE_DEVICE_PROTOCOL, 6 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_OPEN CTL_CODE(FILE_DEVICE_PROTOCOL, 7 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_CLOSE CTL_CODE(FILE_DEVICE_PROTOCOL, 8 , METHOD_BUFFERED, FILE_ANY_ACCESS) + +#endif diff --git a/winpcap/Common/Packet32.h b/winpcap/Common/Packet32.h new file mode 100644 index 0000000..04630a0 --- /dev/null +++ b/winpcap/Common/Packet32.h @@ -0,0 +1,405 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** @ingroup packetapi + * @{ + */ + +/** @defgroup packet32h Packet.dll definitions and data structures + * Packet32.h contains the data structures and the definitions used by packet.dll. + * The file is used both by the Win9x and the WinNTx versions of packet.dll, and can be included + * by the applications that use the functions of this library + * @{ + */ + +#ifndef __PACKET32 +#define __PACKET32 + +#include + +#include "devioctl.h" + +#ifdef HAVE_AIRPCAP_API +#include +#else +#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) +#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ +typedef struct _AirpcapHandle *PAirpcapHandle; +#endif /* AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ */ +#endif /* HAVE_AIRPCAP_API */ + +#ifdef HAVE_DAG_API +#include +#endif /* HAVE_DAG_API */ + +// Working modes +#define PACKET_MODE_CAPT 0x0 ///< Capture mode +#define PACKET_MODE_STAT 0x1 ///< Statistical mode +#define PACKET_MODE_MON 0x2 ///< Monitoring mode +#define PACKET_MODE_DUMP 0x10 ///< Dump mode +#define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT ///< Statistical dump Mode + +// ioctls +#define FILE_DEVICE_PROTOCOL 0x8000 + +#define IOCTL_PROTOCOL_STATISTICS CTL_CODE(FILE_DEVICE_PROTOCOL, 2 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_RESET CTL_CODE(FILE_DEVICE_PROTOCOL, 3 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_READ CTL_CODE(FILE_DEVICE_PROTOCOL, 4 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_WRITE CTL_CODE(FILE_DEVICE_PROTOCOL, 5 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_MACNAME CTL_CODE(FILE_DEVICE_PROTOCOL, 6 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_OPEN CTL_CODE(FILE_DEVICE_PROTOCOL, 7 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_CLOSE CTL_CODE(FILE_DEVICE_PROTOCOL, 8 , METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define pBIOCSETBUFFERSIZE 9592 ///< IOCTL code: set kernel buffer size. +#define pBIOCSETF 9030 ///< IOCTL code: set packet filtering program. +#define pBIOCGSTATS 9031 ///< IOCTL code: get the capture stats. +#define pBIOCSRTIMEOUT 7416 ///< IOCTL code: set the read timeout. +#define pBIOCSMODE 7412 ///< IOCTL code: set working mode. +#define pBIOCSWRITEREP 7413 ///< IOCTL code: set number of physical repetions of every packet written by the app. +#define pBIOCSMINTOCOPY 7414 ///< IOCTL code: set minimum amount of data in the kernel buffer that unlocks a read call. +#define pBIOCSETOID 2147483648U ///< IOCTL code: set an OID value. +#define pBIOCQUERYOID 2147483652U ///< IOCTL code: get an OID value. +#define pATTACHPROCESS 7117 ///< IOCTL code: attach a process to the driver. Used in Win9x only. +#define pDETACHPROCESS 7118 ///< IOCTL code: detach a process from the driver. Used in Win9x only. +#define pBIOCSETDUMPFILENAME 9029 ///< IOCTL code: set the name of a the file used by kernel dump mode. +#define pBIOCEVNAME 7415 ///< IOCTL code: get the name of the event that the driver signals when some data is present in the buffer. +#define pBIOCSENDPACKETSNOSYNC 9032 ///< IOCTL code: Send a buffer containing multiple packets to the network, ignoring the timestamps associated with the packets. +#define pBIOCSENDPACKETSSYNC 9033 ///< IOCTL code: Send a buffer containing multiple packets to the network, respecting the timestamps associated with the packets. +#define pBIOCSETDUMPLIMITS 9034 ///< IOCTL code: Set the dump file limits. See the PacketSetDumpLimits() function. +#define pBIOCISDUMPENDED 7411 ///< IOCTL code: Get the status of the kernel dump process. See the PacketIsDumpEnded() function. +#define pBIOCISETLOBBEH 7410 ///< IOCTL code: Set the loopback behavior of the driver with packets sent by itself: capture or drop. +#define pBIOCSETEVENTHANDLE 7920 ///< IOCTL code: Passes the read event HANDLE allocated by the user (packet.dll) to the kernel level driver. + +#define pBIOCSTIMEZONE 7471 ///< IOCTL code: set time zone. Used in Win9x only. + + +/// Alignment macro. Defines the alignment size. +#define Packet_ALIGNMENT sizeof(int) +/// Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT. +#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) + +#define NdisMediumNull -1 ///< Custom linktype: NDIS doesn't provide an equivalent +#define NdisMediumCHDLC -2 ///< Custom linktype: NDIS doesn't provide an equivalent +#define NdisMediumPPPSerial -3 ///< Custom linktype: NDIS doesn't provide an equivalent +#define NdisMediumBare80211 -4 ///< Custom linktype: NDIS doesn't provide an equivalent +#define NdisMediumRadio80211 -5 ///< Custom linktype: NDIS doesn't provide an equivalent + +// Loopback behaviour definitions +#define NPF_DISABLE_LOOPBACK 1 ///< Drop the packets sent by the NPF driver +#define NPF_ENABLE_LOOPBACK 2 ///< Capture the packets sent by the NPF driver + +/*! + \brief Network type structure. + + This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed. +*/ +typedef struct NetType +{ + UINT LinkType; ///< The MAC of the current network adapter (see function PacketGetNetType() for more information) + ULONGLONG LinkSpeed; ///< The speed of the network in bits per second +}NetType; + + +//some definitions stolen from libpcap + +#ifndef BPF_MAJOR_VERSION + +/*! + \brief A BPF pseudo-assembly program. + + The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet. +*/ +struct bpf_program +{ + UINT bf_len; ///< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow. + struct bpf_insn *bf_insns; ///< A pointer to the first instruction of the program. +}; + +/*! + \brief A single BPF pseudo-instruction. + + bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver. +*/ +struct bpf_insn +{ + USHORT code; ///< Instruction type and addressing mode. + UCHAR jt; ///< Jump if true + UCHAR jf; ///< Jump if false + int k; ///< Generic field used for various purposes. +}; + +/*! + \brief Structure that contains a couple of statistics values on the current capture. + + It is used by packet.dll to return statistics about a capture session. +*/ +struct bpf_stat +{ + UINT bs_recv; ///< Number of packets that the driver received from the network adapter + ///< from the beginning of the current capture. This value includes the packets + ///< lost by the driver. + UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture. + ///< Basically, a packet is lost when the the buffer of the driver is full. + ///< In this situation the packet cannot be stored and the driver rejects it. + UINT ps_ifdrop; ///< drops by interface. XXX not yet supported + UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and + ///< thus reach the application. +}; + +/*! + \brief Packet header. + + This structure defines the header associated with every packet delivered to the application. +*/ +struct bpf_hdr +{ + struct timeval bh_tstamp; ///< The timestamp associated with the captured packet. + ///< It is stored in a TimeVal structure. + UINT bh_caplen; ///< Length of captured portion. The captured portion can be different + ///< from the original packet, because it is possible (with a proper filter) + ///< to instruct the driver to capture only a portion of the packets. + UINT bh_datalen; ///< Original length of packet + USHORT bh_hdrlen; ///< Length of bpf header (this struct plus alignment padding). In some cases, + ///< a padding could be added between the end of this structure and the packet + ///< data for performance reasons. This filed can be used to retrieve the actual data + ///< of the packet. +}; + +/*! + \brief Dump packet header. + + This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets(). + It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a + packet in a dump file. This makes straightforward sending WinPcap dump files to the network. +*/ +struct dump_bpf_hdr{ + struct timeval ts; ///< Time stamp of the packet + UINT caplen; ///< Length of captured portion. The captured portion can smaller than the + ///< the original packet, because it is possible (with a proper filter) to + ///< instruct the driver to capture only a portion of the packets. + UINT len; ///< Length of the original packet (off wire). +}; + + +#endif + +struct bpf_stat; + +#define DOSNAMEPREFIX TEXT("Packet_") ///< Prefix added to the adapters device names to create the WinPcap devices +#define MAX_LINK_NAME_LENGTH 64 //< Maximum length of the devices symbolic links +#define NMAX_PACKET 65535 + +/*! + \brief Addresses of a network adapter. + + This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with + an adapter. +*/ +typedef struct npf_if_addr { + struct sockaddr_storage IPAddress; ///< IP address. + struct sockaddr_storage SubnetMask; ///< Netmask for that address. + struct sockaddr_storage Broadcast; ///< Broadcast address. +}npf_if_addr; + + +#define ADAPTER_NAME_LENGTH 256 + 12 ///< Maximum length for the name of an adapter. The value is the same used by the IP Helper API. +#define ADAPTER_DESC_LENGTH 128 ///< Maximum length for the description of an adapter. The value is the same used by the IP Helper API. +#define MAX_MAC_ADDR_LENGTH 8 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. +#define MAX_NETWORK_ADDRESSES 16 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. + + +typedef struct WAN_ADAPTER_INT WAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API +typedef WAN_ADAPTER *PWAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API + +#define INFO_FLAG_NDIS_ADAPTER 0 ///< Flag for ADAPTER_INFO: this is a traditional ndis adapter +#define INFO_FLAG_NDISWAN_ADAPTER 1 ///< Flag for ADAPTER_INFO: this is a NdisWan adapter, and it's managed by WANPACKET +#define INFO_FLAG_DAG_CARD 2 ///< Flag for ADAPTER_INFO: this is a DAG card +#define INFO_FLAG_DAG_FILE 6 ///< Flag for ADAPTER_INFO: this is a DAG file +#define INFO_FLAG_DONT_EXPORT 8 ///< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones. +#define INFO_FLAG_AIRPCAP_CARD 16 ///< Flag for ADAPTER_INFO: this is an airpcap card +#define INFO_FLAG_NPFIM_DEVICE 32 +/*! + \brief Contains comprehensive information about a network adapter. + + This structure is filled with all the accessory information that the user can need about an adapter installed + on his system. +*/ +typedef struct _ADAPTER_INFO +{ + struct _ADAPTER_INFO *Next; ///< Pointer to the next adapter in the list. + CHAR Name[ADAPTER_NAME_LENGTH + 1]; ///< Name of the device representing the adapter. + CHAR Description[ADAPTER_DESC_LENGTH + 1]; ///< Human understandable description of the adapter + UINT MacAddressLen; ///< Length of the link layer address. + UCHAR MacAddress[MAX_MAC_ADDR_LENGTH]; ///< Link layer address. + NetType LinkLayer; ///< Physical characteristics of this adapter. This NetType structure contains the link type and the speed of the adapter. + INT NNetworkAddresses; ///< Number of network layer addresses of this adapter. + npf_if_addr *NetworkAddresses; ///< Pointer to an array of npf_if_addr, each of which specifies a network address of this adapter. + UINT Flags; ///< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. +} +ADAPTER_INFO, *PADAPTER_INFO; + +/*! + \brief Describes an opened network adapter. + + This structure is the most important for the functioning of packet.dll, but the great part of its fields + should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters +*/ +typedef struct _ADAPTER { + HANDLE hFile; ///< \internal Handle to an open instance of the NPF driver. + CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; ///< \internal A string containing the name of the network adapter currently opened. + int NumWrites; ///< \internal Number of times a packets written on this adapter will be repeated + ///< on the wire. + HANDLE ReadEvent; ///< A notification event associated with the read calls on the adapter. + ///< It can be passed to standard Win32 functions (like WaitForSingleObject + ///< or WaitForMultipleObjects) to wait until the driver's buffer contains some + ///< data. It is particularly useful in GUI applications that need to wait + ///< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy() + ///< function can be used to define the minimum amount of data in the kernel buffer + ///< that will cause the event to be signalled. + + UINT ReadTimeOut; ///< \internal The amount of time after which a read on the driver will be released and + ///< ReadEvent will be signaled, also if no packets were captured + CHAR Name[ADAPTER_NAME_LENGTH]; + PWAN_ADAPTER pWanAdapter; + UINT Flags; ///< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. + +#ifdef HAVE_AIRPCAP_API + PAirpcapHandle AirpcapAd; +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_NPFIM_API + void* NpfImHandle; +#endif // HAVE_NPFIM_API + +#ifdef HAVE_DAG_API + dagc_t *pDagCard; ///< Pointer to the dagc API adapter descriptor for this adapter + PCHAR DagBuffer; ///< Pointer to the buffer with the packets that is received from the DAG card + struct timeval DagReadTimeout; ///< Read timeout. The dagc API requires a timeval structure + unsigned DagFcsLen; ///< Length of the frame check sequence attached to any packet by the card. Obtained from the registry + DWORD DagFastProcess; ///< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps). +#endif // HAVE_DAG_API +} ADAPTER, *LPADAPTER; + +/*! + \brief Structure that contains a group of packets coming from the driver. + + This structure defines the header associated with every packet delivered to the application. +*/ +typedef struct _PACKET { + HANDLE hEvent; ///< \deprecated Still present for compatibility with old applications. + OVERLAPPED OverLapped; ///< \deprecated Still present for compatibility with old applications. + PVOID Buffer; ///< Buffer with containing the packets. See the PacketReceivePacket() for + ///< details about the organization of the data in this buffer + UINT Length; ///< Length of the buffer + DWORD ulBytesReceived; ///< Number of valid bytes present in the buffer, i.e. amount of data + ///< received by the last call to PacketReceivePacket() + BOOLEAN bIoComplete; ///< \deprecated Still present for compatibility with old applications. +} PACKET, *LPPACKET; + +/*! + \brief Structure containing an OID request. + + It is used by the PacketRequest() function to send an OID to the interface card driver. + It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address, + the list of the multicast groups defined on it, and so on. +*/ +struct _PACKET_OID_DATA { + ULONG Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h + ///< for a complete list of valid codes. + ULONG Length; ///< Length of the data field + UCHAR Data[1]; ///< variable-lenght field that contains the information passed to or received + ///< from the adapter. +}; +typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @} + */ + +/* +BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName, + CHAR *Value, + UINT *pValueLen, + CHAR *DefaultVal); + +BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName, + WCHAR *Value, + UINT *pValueLen, + WCHAR *DefaultVal); +*/ + +//--------------------------------------------------------------------------- +// EXPORTED FUNCTIONS +//--------------------------------------------------------------------------- + +PCHAR PacketGetVersion(); +PCHAR PacketGetDriverVersion(); +BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes); +BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites); +BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode); +BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout); +BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp); +BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior); +INT PacketSetSnapLen(LPADAPTER AdapterObject,int snaplen); +BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s); +BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s); +BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim); +BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type); +LPADAPTER PacketOpenAdapter(PCHAR AdapterName); +BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET pPacket,BOOLEAN Sync); +INT PacketSendPackets(LPADAPTER AdapterObject,PVOID PacketBuff,ULONG Size, BOOLEAN Sync); +LPPACKET PacketAllocatePacket(void); +VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length); +VOID PacketFreePacket(LPPACKET lpPacket); +BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync); +BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter); +BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize); +BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries); +BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData); +HANDLE PacketGetReadEvent(LPADAPTER AdapterObject); +BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len); +BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks); +BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync); +BOOL PacketStopDriver(); +VOID PacketCloseAdapter(LPADAPTER lpAdapter); +BOOLEAN PacketStartOem(PCHAR errorString, UINT errorStringLength); +PAirpcapHandle PacketGetAirPcapHandle(LPADAPTER AdapterObject); +#ifdef __cplusplus +} +#endif + +#endif //__PACKET32 diff --git a/winpcap/Common/WpcapNames.h b/winpcap/Common/WpcapNames.h new file mode 100644 index 0000000..0e34901 --- /dev/null +++ b/winpcap/Common/WpcapNames.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2005 CACE Technologies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of CACE Technologies nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef __WPCAPNAMES_H_EED6D131C6DB4dd696757D219977A7E5 +#define __WPCAPNAMES_H_EED6D131C6DB4dd696757D219977A7E5 + + +// +// Original names +// +// NOTE: +// - please do not use prefix names longer than 70 chars. +// - the following characters are surely accepted in the prefixes: "[A-Z][a-z][0-9]_-'," +// +#define NPF_DRIVER_NAME "NPF" ///< (HHH) Packet.dll +#define NPF_DRIVER_NAME_WIDECHAR L"NPF" ///< (HHH) Packet.dll + +// +// Derived strings +// +#define NPF_DEVICE_NAMES_PREFIX NPF_DRIVER_NAME "_" ///< (AAA) packet.dll +#define NPF_DEVICE_NAMES_PREFIX_WIDECHAR NPF_DRIVER_NAME_WIDECHAR L"_" ///< (AAA) used by the NPF driver, that does not accept the TEXT(a) macro correctly. +#define NPF_EVENTS_NAMES NPF_DRIVER_NAME ///< (BBB) +#define NPF_EVENTS_NAMES_WIDECHAR NPF_DRIVER_NAME_WIDECHAR ///< (BBB) used by the NPF driver, that does not accept the TEXT(a) macro correctly. +#define FAKE_NDISWAN_ADAPTER_NAME "\\Device\\" NPF_DRIVER_NAME "_GenericDialupAdapter" ///< (CCC) Name of a fake ndiswan adapter that is always available on 2000/XP/2003, used to capture NCP/LCP packets +#define FAKE_NDISWAN_ADAPTER_DESCRIPTION "Adapter for generic dialup and VPN capture" ///< (DDD) Description of a fake ndiswan adapter that is always available on 2000/XP/2003, used to capture NCP/LCP packets +#define NPF_SERVICE_DESC "WinPcap Packet Driver (" NPF_DRIVER_NAME ")" ///< (FFF) packet.dll +#define NPF_DRIVER_COMPLETE_DEVICE_PREFIX "\\Device\\" NPF_DRIVER_NAME "_" ///< (III) packet.dll +#define NPF_DRIVER_COMPLETE_PATH "system32\\drivers\\" NPF_DRIVER_NAME ".sys" ///< (LLL) packet.dll + + +// +// WinPcap Global Registry Key +// +#define WINPCAP_GLOBAL_KEY "SOFTWARE\\CaceTech\\WinPcapOem" +#define WINPCAP_GLOBAL_KEY_WIDECHAR L"SOFTWARE\\CaceTech\\WinPcapOem" +#define WINPCAP_INSTANCE_KEY WINPCAP_GLOBAL_KEY "\\" NPF_DRIVER_NAME +#define WINPCAP_INSTANCE_KEY_WIDECHAR WINPCAP_GLOBAL_KEY_WIDECHAR L"\\" NPF_DRIVER_NAME_WIDECHAR +#define MAX_WINPCAP_KEY_CHARS 512 + +// +// Subkeys names +// +#define NPF_DEVICES_PREFIX_REG_KEY "NpfDeviceNamesPrefix" ///< (AAA) +#define NPF_DEVICES_PREFIX_REG_KEY_WC L"NpfDeviceNamesPrefix" ///< (AAA) used by the NPF driver, that does not accept the TEXT(a) macro correctly. +#define NPF_EVENTS_NAMES_REG_KEY "NpfEventsNames" ///< (BBB) +#define NPF_EVENTS_NAMES_REG_KEY_WC L"NpfEventsNames" ///< (BBB) used by the NPF driver, that does not accept the TEXT(a) macro correctly. +#define NPF_FAKE_NDISWAN_ADAPTER_NAME_REG_KEY "NdiswanAdapterName" ///< (CCC) packet.dll +#define NPF_FAKE_NDISWAN_ADAPTER_DESC_REG_KEY "NdiswanAdapterDescription" ///< (DDD) packet.dll +#define NPF_SERVICE_DESC_REG_KEY "NpfServiceDescription" ///< (FFF) packet.dll +#define NPF_DRIVER_NAME_REG_KEY "NpfDriverName" ///< (HHH) packet.dll +#define NPF_DRIVER_COMPLETE_DEVICE_PREFIX_REG_KEY "NpfCompleteDriverPrefix" ///< (III) packet.dll +#define NPF_DRIVER_COMPLETE_PATH_REG_KEY "NpfDriverCompletePath" ///< (LLL) + +#endif //__WPCAPNAMES_H_EED6D131C6DB4dd696757D219977A7E5 + diff --git a/winpcap/Common/dagc.h b/winpcap/Common/dagc.h new file mode 100644 index 0000000..6162c4a --- /dev/null +++ b/winpcap/Common/dagc.h @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define DAGC_ERRBUF_SIZE 512 +#define FILEBUFSIZE 65536 +#define MAXDAGCARDS 32 + +#ifndef _WIN32 + +typedef long long long_long; +typedef long long ull_t; +#define TRUE 1 +#define devicestring "/dev/dag%d" +#define dagc_sleepms(_MS) usleep(_MS * 1000) +#else /* _WIN32 */ + +typedef LONGLONG long_long; +typedef ULONGLONG ull_t; +#define dagc_sleepms(_MS) Sleep(_MS) +#define devicestring "\\\\.\\dag%d" + +#endif /* _WIN32 */ + +#define MIN_DAG_SNAPLEN 12 +#define MAX_DAG_SNAPLEN 2040 + +#define erffilestring "erffile://" + + +#define ATM_SNAPLEN 48 +/* Size of ATM payload */ +#define ATM_WLEN(h) ATM_SNAPLEN +#define ATM_SLEN(h) ATM_SNAPLEN + +/* Size Ethernet payload */ +#define ETHERNET_WLEN(h, b) ((u_int)ntohs((h)->wlen) - ((b) >> 3)) +#define ETHERNET_SLEN(h, b) min(ETHERNET_WLEN(h, b), \ + (u_int)ntohs((h)->rlen) - dag_record_size - 2) + +/* Size of HDLC payload */ +#define HDLC_WLEN(h, b) ((u_int)ntohs((h)->wlen) - ((b) >> 3)) +#define HDLC_SLEN(h, b) min(HDLC_WLEN(h, b), \ + (u_int)ntohs((h)->rlen) - dag_record_size) + +/* Flags for dagc_open */ +#define DAGC_OPEN_SHARED 1 +#define DAGC_OPEN_EXCLUSIVE 2 + +#define TYPE_LEGACY 0 +#define TYPE_HDLC_POS 1 +#define TYPE_ETH 2 +#define TYPE_ATM 3 +#define TYPE_AAL5 4 + +/* + * Card statistics. + */ +typedef struct dagc_stats_t +{ + ull_t received; /* (NOT IMPLEMENTED) total number of frames received by the DAG */ + ull_t dropped; /* number of frames dropped for buffer full */ + ull_t captured; /* (NOT IMPLEMENTED) number of frames that actually reach the + application, i.e that are not filtered or dropped */ +} dagc_stats_t; + +/* + * Descriptor of an open session. + * Note: the dagc_t descriptor is completely opaque to the application. It can be compared + * to a file descriptor. + */ +typedef struct dagc dagc_t; + +/* + * Card description. + */ +typedef struct dagc_if_t +{ + struct dagc_if_t *next; + char *name; /* pointer to a string to pass to dagc_open*/ + char *description; /* human-understandable description (e.g. Endace 3.5e Fast + Ethernet Card) */ +} dagc_if_t; + + + +/* + * returns a string with last dagc lib error + */ +#define dagc_getlasterror(dagcfd) dagcfd->errbuf + +/* + * returns a linked list with the cards available on the systems. For every card, it scans the + * card type and converts it to a human-understandable string, in order to provide a description + * useful for example when a system has more than one card + */ +int dagc_finddevs (dagc_if_t **alldevsp, char *ebuf); + + +/* + * frees the card list. + */ +void dagc_freedevs (dagc_if_t *alldevsp); + + +/* + * Opens a card (or a file) for capture. Snaplen is the portion of packet delivered to the + * application, flags can contain specific settings (for example promisc mode??), minbufsize + * is the smallest buffer that the API can provide to the application (to limit CPU waste + * with several small buffers under moderated network throughputs) + */ +dagc_t* dagc_open(const char *source, unsigned flags, char *ebuf); + +/* + * Sets the snaplen of a card + * Returns -1 on failure. On success, the actual snaplen is returned (snap len has to be a multiple of 4 + * with DAG cards). + */ +int dagc_setsnaplen(dagc_t *dagcfd, unsigned snaplen); + +/* + * closes a capture instance + */ +void dagc_close(dagc_t *dagcfd); + + +/* + * returns the linktype of a card + */ +int dagc_getlinktype(dagc_t *dagcfd); + + +/* + * returns the link speed of the adapter, in MB/s. + * If the link speed of the card is unknown, -1 is returned. + * XXX NOTE: Currently, there is no consistent way to get linkspeed querying the card. + * As a consequence, we determine this value statically from the card model. For cards that can run at + * different speeds, we report only the *maximum* speed. + */ +int dagc_getlinkspeed(dagc_t *dagcfd); + + +/* + * Returns the length of the CRC checksum that the card associates with any packet in the hole. This + * information will be used to understand the actual length of the packet on the wire. + * Note: this information is not provided consistently by DAG cards, so we gather it from an environment + * variable in Unix and from a registry key in Windows. + */ +unsigned dagc_getfcslen(dagc_t *dagcfd); + +/* + * provides a buffer with the new packets (from the board or from the file) and its size. + * On success, the return value is 0. If an error has occurred, the return value is -1. + * If EOF has reached, the return value is -2. Note that this function always returns + * immediately, eventually with an empty buffer, so it is possible to have a success (0) + * return value and bufsize = 0. + */ +int dagc_receive(dagc_t *dagcfd, u_char **buffer, u_int *bufsize); + + +/* + * returns nonzero if any data is available from dagcfd, -1 if an error occurred. Waits until almost the time + * specified by timeout has past or any data is available. If timeout=0, returns immediately. + * If timeout=NULL, blocks until a packet arrives. + */ +int dagc_wait(dagc_t *dagcfd, struct timeval *timeout); + + +/* + * returns statistics about current capture session + */ +int dagc_stats(dagc_t *dagcfd, dagc_stats_t *ps); + + +/* + * Opens a dump file to store the data of this capture. + * Returns 0 on success. + * NOTE: currently, dagc_dumpfile_open, dagc_dumpfile_close and dagc_dump are simply wrappers + * for open, close and write. However, if the programmer uses these functions, he is more protected + * against file format changes (for example if the file format will have an header in the future). + * Moreover, assuming that the user knows the file format is a bad practice: providing + * simple simple save functionality is more intutive and user-friendly. + */ +int dagc_dumpfile_open(dagc_t *dagcfd, char* name); + + +/* + * Closes a dump file + */ +int dagc_dumpfile_close(dagc_t *dagcfd); + + +/* + * Writes a buffer of packets to a dump file + * Returns 0 on success. + */ +int dagc_dump(dagc_t *dagcfd, u_char *buffer, u_int bufsize); diff --git a/winpcap/Examples-pcap/GNUmakefile b/winpcap/Examples-pcap/GNUmakefile new file mode 100644 index 0000000..a62b3fb --- /dev/null +++ b/winpcap/Examples-pcap/GNUmakefile @@ -0,0 +1,10 @@ +# Makefile for cygwin gcc +# Nate Lawson + +SUBDIRS = basic_dump basic_dump_ex iflist pcap_filter pktdump_ex readfile readfile_ex savedump sendpack UDPdump + +all clean install uninstall: ${SUBDIRS} + for subdir in ${SUBDIRS}; do \ + echo "Entering $$subdir"; \ + (cd $$subdir && ${MAKE} $@) \ + done; diff --git a/winpcap/Examples-pcap/MakeaAll.dsw b/winpcap/Examples-pcap/MakeaAll.dsw new file mode 100644 index 0000000..68075d3 --- /dev/null +++ b/winpcap/Examples-pcap/MakeaAll.dsw @@ -0,0 +1,137 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "UDPdump"=.\UDPdump\UDPdump.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "basic_dump"=.\basic_dump\basic_dump.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "basic_dump_ex"=.\basic_dump_ex\basic_dump_ex.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "iflist"=.\iflist\iflist.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "pcap_filter"=.\pcap_filter\pcap_filter.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "pktdump_ex"=.\pktdump_ex\pktdump_ex.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "readfile"=.\readfile\readfile.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "readfile_ex"=.\readfile_ex\readfile_ex.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "savedump"=.\savedump\savedump.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "sendpack"=.\sendpack\sendpack.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples-pcap/UDPdump/GNUmakefile b/winpcap/Examples-pcap/UDPdump/GNUmakefile new file mode 100644 index 0000000..21f42ad --- /dev/null +++ b/winpcap/Examples-pcap/UDPdump/GNUmakefile @@ -0,0 +1,17 @@ +# Makefile for cygwin gcc +# Loris Degioanni + +PCAP_PATH = ../../lib +CFLAGS = -g -O -mno-cygwin -I ../../include + +OBJS = udpdump.o +LIBS = -L ${PCAP_PATH} -lwpcap -lwsock32 + +all: ${OBJS} + ${CC} ${CFLAGS} -o udpdump.exe ${OBJS} ${LIBS} + +clean: + rm -f ${OBJS} udpdump.exe + +.c.o: + ${CC} ${CFLAGS} -c -o $*.o $< diff --git a/winpcap/Examples-pcap/UDPdump/UDPdump.dsp b/winpcap/Examples-pcap/UDPdump/UDPdump.dsp new file mode 100644 index 0000000..40e3806 --- /dev/null +++ b/winpcap/Examples-pcap/UDPdump/UDPdump.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="UDPdump" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=UDPdump - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "UDPdump.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "UDPdump.mak" CFG="UDPdump - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "UDPdump - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "UDPdump - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "UDPdump - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "UDPdump - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "UDPdump - Win32 Release" +# Name "UDPdump - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\udpdump.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples-pcap/UDPdump/UDPdump.dsw b/winpcap/Examples-pcap/UDPdump/UDPdump.dsw new file mode 100644 index 0000000..0def709 --- /dev/null +++ b/winpcap/Examples-pcap/UDPdump/UDPdump.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "UDPdump"=.\UDPdump.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples-pcap/UDPdump/udpdump.c b/winpcap/Examples-pcap/UDPdump/udpdump.c new file mode 100644 index 0000000..a661ab5 --- /dev/null +++ b/winpcap/Examples-pcap/UDPdump/udpdump.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "pcap.h" + +/* 4 bytes IP address */ +typedef struct ip_address +{ + u_char byte1; + u_char byte2; + u_char byte3; + u_char byte4; +}ip_address; + +/* IPv4 header */ +typedef struct ip_header +{ + u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits) + u_char tos; // Type of service + u_short tlen; // Total length + u_short identification; // Identification + u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits) + u_char ttl; // Time to live + u_char proto; // Protocol + u_short crc; // Header checksum + ip_address saddr; // Source address + ip_address daddr; // Destination address + u_int op_pad; // Option + Padding +}ip_header; + +/* UDP header*/ +typedef struct udp_header +{ + u_short sport; // Source port + u_short dport; // Destination port + u_short len; // Datagram length + u_short crc; // Checksum +}udp_header; + +/* prototype of the packet handler */ +void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); + + +main() +{ + pcap_if_t *alldevs; + pcap_if_t *d; + int inum; + int i=0; + pcap_t *adhandle; + char errbuf[PCAP_ERRBUF_SIZE]; + u_int netmask; + char packet_filter[] = "ip and udp"; + struct bpf_program fcode; + + /* Retrieve the device list */ + if(pcap_findalldevs(&alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. %s", ++i, d->name); + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if(i==0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return -1; + } + + printf("Enter the interface number (1-%d):",i); + scanf("%d", &inum); + + /* Check if the user specified a valid adapter */ + if(inum < 1 || inum > i) + { + printf("\nAdapter number out of range.\n"); + + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Jump to the selected adapter */ + for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); + + /* Open the adapter */ + if ((adhandle= pcap_open_live(d->name, // name of the device + 65536, // portion of the packet to capture. + // 65536 grants that the whole packet will be captured on all the MACs. + 1, // promiscuous mode (nonzero means promiscuous) + 1000, // read timeout + errbuf // error buffer + )) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Check the link layer. We support only Ethernet for simplicity. */ + if(pcap_datalink(adhandle) != DLT_EN10MB) + { + fprintf(stderr,"\nThis program works only on Ethernet networks.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + if(d->addresses != NULL) + /* Retrieve the mask of the first address of the interface */ + netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; + else + /* If the interface is without addresses we suppose to be in a C class network */ + netmask=0xffffff; + + + //compile the filter + if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 ) + { + fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + //set the filter + if (pcap_setfilter(adhandle, &fcode)<0) + { + fprintf(stderr,"\nError setting the filter.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + printf("\nlistening on %s...\n", d->description); + + /* At this point, we don't need any more the device list. Free it */ + pcap_freealldevs(alldevs); + + /* start the capture */ + pcap_loop(adhandle, 0, packet_handler, NULL); + + return 0; +} + +/* Callback function invoked by libpcap for every incoming packet */ +void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + struct tm *ltime; + char timestr[16]; + ip_header *ih; + udp_header *uh; + u_int ip_len; + u_short sport,dport; + time_t local_tv_sec; + + /* convert the timestamp to readable format */ + local_tv_sec = header->ts.tv_sec; + ltime=localtime(&local_tv_sec); + strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); + + /* print timestamp and length of the packet */ + printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len); + + /* retireve the position of the ip header */ + ih = (ip_header *) (pkt_data + + 14); //length of ethernet header + + /* retireve the position of the udp header */ + ip_len = (ih->ver_ihl & 0xf) * 4; + uh = (udp_header *) ((u_char*)ih + ip_len); + + /* convert from network byte order to host byte order */ + sport = ntohs( uh->sport ); + dport = ntohs( uh->dport ); + + /* print ip addresses and udp ports */ + printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n", + ih->saddr.byte1, + ih->saddr.byte2, + ih->saddr.byte3, + ih->saddr.byte4, + sport, + ih->daddr.byte1, + ih->daddr.byte2, + ih->daddr.byte3, + ih->daddr.byte4, + dport); +} diff --git a/winpcap/Examples-pcap/basic_dump/GNUmakefile b/winpcap/Examples-pcap/basic_dump/GNUmakefile new file mode 100644 index 0000000..e10ff28 --- /dev/null +++ b/winpcap/Examples-pcap/basic_dump/GNUmakefile @@ -0,0 +1,17 @@ +# Makefile for cygwin gcc +# Nate Lawson + +PCAP_PATH = ../../lib +CFLAGS = -g -O -mno-cygwin -I ../../include + +OBJS = basic_dump.o +LIBS = -L ${PCAP_PATH} -lwpcap + +all: ${OBJS} + ${CC} ${CFLAGS} -o basic_dump.exe ${OBJS} ${LIBS} + +clean: + rm -f ${OBJS} basic_dump.exe + +.c.o: + ${CC} ${CFLAGS} -c -o $*.o $< diff --git a/winpcap/Examples-pcap/basic_dump/basic_dump.c b/winpcap/Examples-pcap/basic_dump/basic_dump.c new file mode 100644 index 0000000..9090c45 --- /dev/null +++ b/winpcap/Examples-pcap/basic_dump/basic_dump.c @@ -0,0 +1,95 @@ +#include "pcap.h" + +/* prototype of the packet handler */ +void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); + +main() +{ + pcap_if_t *alldevs; + pcap_if_t *d; + int inum; + int i=0; + pcap_t *adhandle; + char errbuf[PCAP_ERRBUF_SIZE]; + + /* Retrieve the device list */ + if(pcap_findalldevs(&alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. %s", ++i, d->name); + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if(i==0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return -1; + } + + printf("Enter the interface number (1-%d):",i); + scanf("%d", &inum); + + if(inum < 1 || inum > i) + { + printf("\nInterface number out of range.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Jump to the selected adapter */ + for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); + + /* Open the device */ + /* Open the adapter */ + if ((adhandle= pcap_open_live(d->name, // name of the device + 65536, // portion of the packet to capture. + // 65536 grants that the whole packet will be captured on all the MACs. + 1, // promiscuous mode (nonzero means promiscuous) + 1000, // read timeout + errbuf // error buffer + )) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + printf("\nlistening on %s...\n", d->description); + + /* At this point, we don't need any more the device list. Free it */ + pcap_freealldevs(alldevs); + + /* start the capture */ + pcap_loop(adhandle, 0, packet_handler, NULL); + + pcap_close(adhandle); + return 0; +} + + +/* Callback function invoked by libpcap for every incoming packet */ +void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + struct tm *ltime; + char timestr[16]; + time_t local_tv_sec; + + /* convert the timestamp to readable format */ + local_tv_sec = header->ts.tv_sec; + ltime=localtime(&local_tv_sec); + strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); + + printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len); + +} diff --git a/winpcap/Examples-pcap/basic_dump/basic_dump.dsp b/winpcap/Examples-pcap/basic_dump/basic_dump.dsp new file mode 100644 index 0000000..3e8bc02 --- /dev/null +++ b/winpcap/Examples-pcap/basic_dump/basic_dump.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="basic_dump" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=basic_dump - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "basic_dump.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "basic_dump.mak" CFG="basic_dump - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "basic_dump - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "basic_dump - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "basic_dump - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "basic_dump - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "basic_dump - Win32 Release" +# Name "basic_dump - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\basic_dump.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples-pcap/basic_dump/basic_dump.dsw b/winpcap/Examples-pcap/basic_dump/basic_dump.dsw new file mode 100644 index 0000000..1f6a6ff --- /dev/null +++ b/winpcap/Examples-pcap/basic_dump/basic_dump.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "basic_dump"=.\basic_dump.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples-pcap/basic_dump_ex/GNUmakefile b/winpcap/Examples-pcap/basic_dump_ex/GNUmakefile new file mode 100644 index 0000000..708acd4 --- /dev/null +++ b/winpcap/Examples-pcap/basic_dump_ex/GNUmakefile @@ -0,0 +1,17 @@ +# Makefile for cygwin gcc +# Nate Lawson + +PCAP_PATH = ../../lib +CFLAGS = -g -O -mno-cygwin -I ../../include + +OBJS = basic_dump_ex.o +LIBS = -L ${PCAP_PATH} -lwpcap + +all: ${OBJS} + ${CC} ${CFLAGS} -o basic_dump_ex.exe ${OBJS} ${LIBS} + +clean: + rm -f ${OBJS} basic_dump_ex.exe + +.c.o: + ${CC} ${CFLAGS} -c -o $*.o $< diff --git a/winpcap/Examples-pcap/basic_dump_ex/basic_dump_ex.c b/winpcap/Examples-pcap/basic_dump_ex/basic_dump_ex.c new file mode 100644 index 0000000..36e6f21 --- /dev/null +++ b/winpcap/Examples-pcap/basic_dump_ex/basic_dump_ex.c @@ -0,0 +1,99 @@ +#include "pcap.h" + + +int main() +{ + pcap_if_t *alldevs; + pcap_if_t *d; + int inum; + int i=0; + pcap_t *adhandle; + int res; + char errbuf[PCAP_ERRBUF_SIZE]; + struct tm *ltime; + char timestr[16]; + struct pcap_pkthdr *header; + const u_char *pkt_data; + time_t local_tv_sec; + + + /* Retrieve the device list */ + if(pcap_findalldevs(&alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); + return -1; + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. %s", ++i, d->name); + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if(i==0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return -1; + } + + printf("Enter the interface number (1-%d):",i); + scanf("%d", &inum); + + if(inum < 1 || inum > i) + { + printf("\nInterface number out of range.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Jump to the selected adapter */ + for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); + + /* Open the adapter */ + if ((adhandle= pcap_open_live(d->name, // name of the device + 65536, // portion of the packet to capture. + // 65536 grants that the whole packet will be captured on all the MACs. + 1, // promiscuous mode (nonzero means promiscuous) + 1000, // read timeout + errbuf // error buffer + )) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + printf("\nlistening on %s...\n", d->description); + + /* At this point, we don't need any more the device list. Free it */ + pcap_freealldevs(alldevs); + + /* Retrieve the packets */ + while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){ + + if(res == 0) + /* Timeout elapsed */ + continue; + + /* convert the timestamp to readable format */ + local_tv_sec = header->ts.tv_sec; + ltime=localtime(&local_tv_sec); + strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); + + printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len); + } + + if(res == -1){ + printf("Error reading the packets: %s\n", pcap_geterr(adhandle)); + return -1; + } + + pcap_close(adhandle); + return 0; +} diff --git a/winpcap/Examples-pcap/basic_dump_ex/basic_dump_ex.dsp b/winpcap/Examples-pcap/basic_dump_ex/basic_dump_ex.dsp new file mode 100644 index 0000000..e798f63 --- /dev/null +++ b/winpcap/Examples-pcap/basic_dump_ex/basic_dump_ex.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="basic_dump_ex" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=basic_dump_ex - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "basic_dump_ex.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "basic_dump_ex.mak" CFG="basic_dump_ex - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "basic_dump_ex - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "basic_dump_ex - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "basic_dump_ex - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "basic_dump_ex - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "basic_dump_ex - Win32 Release" +# Name "basic_dump_ex - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\basic_dump_ex.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples-pcap/basic_dump_ex/basic_dump_ex.dsw b/winpcap/Examples-pcap/basic_dump_ex/basic_dump_ex.dsw new file mode 100644 index 0000000..e336436 --- /dev/null +++ b/winpcap/Examples-pcap/basic_dump_ex/basic_dump_ex.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "basic_dump_ex"=.\basic_dump_ex.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples-pcap/iflist/GNUmakefile b/winpcap/Examples-pcap/iflist/GNUmakefile new file mode 100644 index 0000000..30c7013 --- /dev/null +++ b/winpcap/Examples-pcap/iflist/GNUmakefile @@ -0,0 +1,17 @@ +# Makefile for cygwin gcc +# Nate Lawson + +PCAP_PATH = ../../lib +CFLAGS = -g -O -mno-cygwin -I ../../include + +OBJS = iflist.o +LIBS = -L ${PCAP_PATH} -lwpcap + +all: ${OBJS} + ${CC} ${CFLAGS} -o iflist.exe ${OBJS} ${LIBS} + +clean: + rm -f ${OBJS} iflist.exe + +.c.o: + ${CC} ${CFLAGS} -c -o $*.o $< diff --git a/winpcap/Examples-pcap/iflist/iflist.c b/winpcap/Examples-pcap/iflist/iflist.c new file mode 100644 index 0000000..abd2e66 --- /dev/null +++ b/winpcap/Examples-pcap/iflist/iflist.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "pcap.h" + +#ifndef WIN32 + #include + #include +#else + #include +#endif + + +// Function prototypes +void ifprint(pcap_if_t *d); +char *iptos(u_long in); +char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen); + + +int main() +{ + pcap_if_t *alldevs; + pcap_if_t *d; + char errbuf[PCAP_ERRBUF_SIZE+1]; + + /* Retrieve the device list */ + if(pcap_findalldevs(&alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); + exit(1); + } + + /* Scan the list printing every entry */ + for(d=alldevs;d;d=d->next) + { + ifprint(d); + } + + /* Free the device list */ + pcap_freealldevs(alldevs); + + return 1; +} + + + +/* Print all the available information on the given interface */ +void ifprint(pcap_if_t *d) +{ + pcap_addr_t *a; + char ip6str[128]; + + /* Name */ + printf("%s\n",d->name); + + /* Description */ + if (d->description) + printf("\tDescription: %s\n",d->description); + + /* Loopback Address*/ + printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no"); + + /* IP addresses */ + for(a=d->addresses;a;a=a->next) { + printf("\tAddress Family: #%d\n",a->addr->sa_family); + + switch(a->addr->sa_family) + { + case AF_INET: + printf("\tAddress Family Name: AF_INET\n"); + if (a->addr) + printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr)); + if (a->netmask) + printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr)); + if (a->broadaddr) + printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr)); + if (a->dstaddr) + printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr)); + break; + + case AF_INET6: + printf("\tAddress Family Name: AF_INET6\n"); +#ifndef __MINGW32__ /* Cygnus doesn't have IPv6 */ + if (a->addr) + printf("\tAddress: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str))); +#endif + break; + + default: + printf("\tAddress Family Name: Unknown\n"); + break; + } + } + printf("\n"); +} + +/* From tcptraceroute, convert a numeric IP address to a string */ +#define IPTOSBUFFERS 12 +char *iptos(u_long in) +{ + static char output[IPTOSBUFFERS][3*4+3+1]; + static short which; + u_char *p; + + p = (u_char *)∈ + which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1); + sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + return output[which]; +} + +#ifndef __MINGW32__ /* Cygnus doesn't have IPv6 */ +char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen) +{ + socklen_t sockaddrlen; + + #ifdef WIN32 + sockaddrlen = sizeof(struct sockaddr_in6); + #else + sockaddrlen = sizeof(struct sockaddr_storage); + #endif + + + if(getnameinfo(sockaddr, + sockaddrlen, + address, + addrlen, + NULL, + 0, + NI_NUMERICHOST) != 0) address = NULL; + + return address; +} +#endif /* __MINGW32__ */ + diff --git a/winpcap/Examples-pcap/iflist/iflist.dsp b/winpcap/Examples-pcap/iflist/iflist.dsp new file mode 100644 index 0000000..b1a8c8c --- /dev/null +++ b/winpcap/Examples-pcap/iflist/iflist.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="iflist" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=iflist - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "iflist.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "iflist.mak" CFG="iflist - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "iflist - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "iflist - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "iflist - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "iflist - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "iflist - Win32 Release" +# Name "iflist - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\iflist.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples-pcap/iflist/iflist.dsw b/winpcap/Examples-pcap/iflist/iflist.dsw new file mode 100644 index 0000000..6bd686d --- /dev/null +++ b/winpcap/Examples-pcap/iflist/iflist.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "iflist"=.\iflist.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples-pcap/pcap_filter/GNUmakefile b/winpcap/Examples-pcap/pcap_filter/GNUmakefile new file mode 100644 index 0000000..ca84d01 --- /dev/null +++ b/winpcap/Examples-pcap/pcap_filter/GNUmakefile @@ -0,0 +1,17 @@ +# Makefile for cygwin gcc +# Nate Lawson + +PCAP_PATH = ../../lib +CFLAGS = -g -O -mno-cygwin -I ../../include + +OBJS = pcap_filter.o +LIBS = -L ${PCAP_PATH} -lwpcap + +all: ${OBJS} + ${CC} ${CFLAGS} -o pf.exe ${OBJS} ${LIBS} + +clean: + rm -f ${OBJS} pf.exe + +.c.o: + ${CC} ${CFLAGS} -c -o $*.o $< diff --git a/winpcap/Examples-pcap/pcap_filter/Makefile.unix b/winpcap/Examples-pcap/pcap_filter/Makefile.unix new file mode 100644 index 0000000..a7d7ead --- /dev/null +++ b/winpcap/Examples-pcap/pcap_filter/Makefile.unix @@ -0,0 +1,9 @@ + +CC = gcc +INCLDIR = -I /usr/src/sys +LIBS = -lpcap + +pktdump: pcap_filter.o + $(CC) $(INCLDIR) pcap_filter.o $(LIBS) -o pf + rm *.o + diff --git a/winpcap/Examples-pcap/pcap_filter/pcap_filter.c b/winpcap/Examples-pcap/pcap_filter/pcap_filter.c new file mode 100644 index 0000000..e910488 --- /dev/null +++ b/winpcap/Examples-pcap/pcap_filter/pcap_filter.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include + +#include + +#define MAX_PRINT 80 +#define MAX_LINE 16 + + +void usage(); + + +int main(int argc, char **argv) +{ + pcap_t *fp; + char errbuf[PCAP_ERRBUF_SIZE]; + char *source = NULL; + char *ofilename = NULL; + char *filter = NULL; + int i; + pcap_dumper_t *dumpfile; + struct bpf_program fcode; + bpf_u_int32 NetMask; + int res; + struct pcap_pkthdr *header; + const u_char *pkt_data; + + if (argc == 1) + { + usage(); + return -1; + } + + /* Parse parameters */ + for(i=1;i < argc; i+= 2) + { + switch (argv[i] [1]) + { + case 's': + { + source=argv[i+1]; + }; + break; + + case 'o': + { + ofilename=argv[i+1]; + }; + break; + + case 'f': + { + filter=argv[i+1]; + }; + break; + } + } + + // open a capture from the network + if (source != NULL) + { + if ((fp = pcap_open_live(source, // name of the device + 65536, // portion of the packet to capture. + // 65536 grants that the whole packet will be captured on all the MACs. + 1, // promiscuous mode (nonzero means promiscuous) + 1000, // read timeout + errbuf // error buffer + )) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter.\n"); + return -2; + } + } + else usage(); + + if (filter != NULL) + { + // We should loop through the adapters returned by the pcap_findalldevs_ex() + // in order to locate the correct one. + // + // Let's do things simpler: we suppose to be in a C class network ;-) + NetMask=0xffffff; + + //compile the filter + if(pcap_compile(fp, &fcode, filter, 1, NetMask) < 0) + { + fprintf(stderr,"\nError compiling filter: wrong syntax.\n"); + + pcap_close(fp); + return -3; + } + + //set the filter + if(pcap_setfilter(fp, &fcode)<0) + { + fprintf(stderr,"\nError setting the filter\n"); + + pcap_close(fp); + return -4; + } + + } + + //open the dump file + if (ofilename != NULL) + { + dumpfile= pcap_dump_open(fp, ofilename); + + if (dumpfile == NULL) + { + fprintf(stderr,"\nError opening output file\n"); + + pcap_close(fp); + return -5; + } + } + else usage(); + + //start the capture + while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0) + { + + if(res == 0) + /* Timeout elapsed */ + continue; + + //save the packet on the dump file + pcap_dump((unsigned char *) dumpfile, header, pkt_data); + + } + + pcap_close(fp); + pcap_dump_close(dumpfile); + + return 0; +} + + +void usage() +{ + + printf("\npf - Generic Packet Filter.\n"); + printf("\nUsage:\npf -s source -o output_file_name [-f filter_string]\n\n"); + exit(0); +} diff --git a/winpcap/Examples-pcap/pcap_filter/pcap_filter.dsp b/winpcap/Examples-pcap/pcap_filter/pcap_filter.dsp new file mode 100644 index 0000000..5bd65b5 --- /dev/null +++ b/winpcap/Examples-pcap/pcap_filter/pcap_filter.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="pcap_filter" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=pcap_filter - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pcap_filter.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pcap_filter.mak" CFG="pcap_filter - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "pcap_filter - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "pcap_filter - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "pcap_filter - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 /out:"Release/pf.exe" + +!ELSEIF "$(CFG)" == "pcap_filter - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/pf.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "pcap_filter - Win32 Release" +# Name "pcap_filter - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\pcap_filter.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples-pcap/pcap_filter/pcap_filter.dsw b/winpcap/Examples-pcap/pcap_filter/pcap_filter.dsw new file mode 100644 index 0000000..a903183 --- /dev/null +++ b/winpcap/Examples-pcap/pcap_filter/pcap_filter.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "pcap_filter"=.\pcap_filter.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples-pcap/pktdump_ex/GNUmakefile b/winpcap/Examples-pcap/pktdump_ex/GNUmakefile new file mode 100644 index 0000000..f649ce3 --- /dev/null +++ b/winpcap/Examples-pcap/pktdump_ex/GNUmakefile @@ -0,0 +1,14 @@ +PCAP_PATH = ../../lib +CFLAGS = -g -O -mno-cygwin -I ../../include + +OBJS = pktdump_ex.o +LIBS = -L ${PCAP_PATH} -lwpcap + +all: ${OBJS} + ${CC} ${CFLAGS} -o pktdump_ex.exe ${OBJS} ${LIBS} + +clean: + rm -f ${OBJS} pktdump_ex.exe + +.c.o: + ${CC} ${CFLAGS} -c -o $*.o $< diff --git a/winpcap/Examples-pcap/pktdump_ex/pktdump_ex.c b/winpcap/Examples-pcap/pktdump_ex/pktdump_ex.c new file mode 100644 index 0000000..e1af303 --- /dev/null +++ b/winpcap/Examples-pcap/pktdump_ex/pktdump_ex.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include + +#include + +#define LINE_LEN 16 + + +int main(int argc, char **argv) +{ + pcap_if_t *alldevs, *d; + pcap_t *fp; + u_int inum, i=0; + char errbuf[PCAP_ERRBUF_SIZE]; + int res; + struct pcap_pkthdr *header; + const u_char *pkt_data; + + printf("pktdump_ex: prints the packets of the network using WinPcap.\n"); + printf(" Usage: pktdump_ex [-s source]\n\n" + " Examples:\n" + " pktdump_ex -s file.acp\n" + " pktdump_ex -s \\Device\\NPF_{C8736017-F3C3-4373-94AC-9A34B7DAD998}\n\n"); + + if(argc < 3) + { + printf("\nNo adapter selected: printing the device list:\n"); + /* The user didn't provide a packet source: Retrieve the local device list */ + if(pcap_findalldevs(&alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. %s\n ", ++i, d->name); + + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if (i==0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return -1; + } + + printf("Enter the interface number (1-%d):",i); + scanf("%d", &inum); + + if (inum < 1 || inum > i) + { + printf("\nInterface number out of range.\n"); + + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Jump to the selected adapter */ + for (d=alldevs, i=0; i< inum-1 ;d=d->next, i++); + + /* Open the adapter */ + if ((fp = pcap_open_live(d->name, // name of the device + 65536, // portion of the packet to capture. + // 65536 grants that the whole packet will be captured on all the MACs. + 1, // promiscuous mode (nonzero means promiscuous) + 1000, // read timeout + errbuf // error buffer + )) == NULL) + { + fprintf(stderr,"\nError opening adapter\n"); + return -1; + } + } + else + { + /* Do not check for the switch type ('-s') */ + if ((fp = pcap_open_live(argv[2], // name of the device + 65536, // portion of the packet to capture. + // 65536 grants that the whole packet will be captured on all the MACs. + 1, // promiscuous mode (nonzero means promiscuous) + 1000, // read timeout + errbuf // error buffer + )) == NULL) + { + fprintf(stderr,"\nError opening adapter\n"); + return -1; + } + } + + /* Read the packets */ + while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0) + { + + if(res == 0) + /* Timeout elapsed */ + continue; + + /* print pkt timestamp and pkt len */ + printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len); + + /* Print the packet */ + for (i=1; (i < header->caplen + 1 ) ; i++) + { + printf("%.2x ", pkt_data[i-1]); + if ( (i % LINE_LEN) == 0) printf("\n"); + } + + printf("\n\n"); + } + + if(res == -1) + { + printf("Error reading the packets: %s\n", pcap_geterr(fp)); + return -1; + } + + pcap_close(fp); + return 0; +} diff --git a/winpcap/Examples-pcap/pktdump_ex/pktdump_ex.dsp b/winpcap/Examples-pcap/pktdump_ex/pktdump_ex.dsp new file mode 100644 index 0000000..85c062d --- /dev/null +++ b/winpcap/Examples-pcap/pktdump_ex/pktdump_ex.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="pktdump_ex" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=pktdump_ex - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pktdump_ex.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pktdump_ex.mak" CFG="pktdump_ex - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "pktdump_ex - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "pktdump_ex - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "pktdump_ex - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "pktdump_ex - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "pktdump_ex - Win32 Release" +# Name "pktdump_ex - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\pktdump_ex.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples-pcap/pktdump_ex/pktdump_ex.dsw b/winpcap/Examples-pcap/pktdump_ex/pktdump_ex.dsw new file mode 100644 index 0000000..b0f6812 --- /dev/null +++ b/winpcap/Examples-pcap/pktdump_ex/pktdump_ex.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "pktdump_ex"=.\pktdump_ex.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples-pcap/readfile/GNUmakefile b/winpcap/Examples-pcap/readfile/GNUmakefile new file mode 100644 index 0000000..fe4bae3 --- /dev/null +++ b/winpcap/Examples-pcap/readfile/GNUmakefile @@ -0,0 +1,17 @@ +# Makefile for cygwin gcc +# Nate Lawson + +PCAP_PATH = ../../lib +CFLAGS = -g -O -mno-cygwin -I ../../include + +OBJS = readfile.o +LIBS = -L ${PCAP_PATH} -lwpcap + +all: ${OBJS} + ${CC} ${CFLAGS} -o readfile.exe ${OBJS} ${LIBS} + +clean: + rm -f ${OBJS} readfile.exe + +.c.o: + ${CC} ${CFLAGS} -c -o $*.o $< diff --git a/winpcap/Examples-pcap/readfile/readfile.c b/winpcap/Examples-pcap/readfile/readfile.c new file mode 100644 index 0000000..34f6d69 --- /dev/null +++ b/winpcap/Examples-pcap/readfile/readfile.c @@ -0,0 +1,56 @@ +#include +#include + +#define LINE_LEN 16 + +void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *); + +main(int argc, char **argv) +{ + pcap_t *fp; + char errbuf[PCAP_ERRBUF_SIZE]; + + if(argc != 2) + { + printf("usage: %s filename", argv[0]); + return -1; + + } + + /* Open the capture file */ + if ((fp = pcap_open_offline(argv[1], // name of the device + errbuf // error buffer + )) == NULL) + { + fprintf(stderr,"\nUnable to open the file %s.\n", argv[1]); + return -1; + } + + /* read and dispatch packets until EOF is reached */ + pcap_loop(fp, 0, dispatcher_handler, NULL); + + pcap_close(fp); + return 0; +} + + + +void dispatcher_handler(u_char *temp1, + const struct pcap_pkthdr *header, + const u_char *pkt_data) +{ + u_int i=0; + + /* print pkt timestamp and pkt len */ + printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len); + + /* Print the packet */ + for (i=1; (i < header->caplen + 1 ) ; i++) + { + printf("%.2x ", pkt_data[i-1]); + if ( (i % LINE_LEN) == 0) printf("\n"); + } + + printf("\n\n"); + +} diff --git a/winpcap/Examples-pcap/readfile/readfile.dsp b/winpcap/Examples-pcap/readfile/readfile.dsp new file mode 100644 index 0000000..88972bb --- /dev/null +++ b/winpcap/Examples-pcap/readfile/readfile.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="readfile" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=readfile - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "readfile.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "readfile.mak" CFG="readfile - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "readfile - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "readfile - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "readfile - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "readfile - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "readfile - Win32 Release" +# Name "readfile - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\readfile.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples-pcap/readfile/readfile.dsw b/winpcap/Examples-pcap/readfile/readfile.dsw new file mode 100644 index 0000000..f971e0b --- /dev/null +++ b/winpcap/Examples-pcap/readfile/readfile.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "readfile"=.\readfile.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples-pcap/readfile_ex/GNUmakefile b/winpcap/Examples-pcap/readfile_ex/GNUmakefile new file mode 100644 index 0000000..3408721 --- /dev/null +++ b/winpcap/Examples-pcap/readfile_ex/GNUmakefile @@ -0,0 +1,17 @@ +# Makefile for cygwin gcc +# Nate Lawson + +PCAP_PATH = ../../lib +CFLAGS = -g -O -mno-cygwin -I ../../include + +OBJS = readfile_ex.o +LIBS = -L ${PCAP_PATH} -lwpcap + +all: ${OBJS} + ${CC} ${CFLAGS} -o readfile_ex.exe ${OBJS} ${LIBS} + +clean: + rm -f ${OBJS} readfile_ex.exe + +.c.o: + ${CC} ${CFLAGS} -c -o $*.o $< diff --git a/winpcap/Examples-pcap/readfile_ex/readfile_ex.c b/winpcap/Examples-pcap/readfile_ex/readfile_ex.c new file mode 100644 index 0000000..2324c06 --- /dev/null +++ b/winpcap/Examples-pcap/readfile_ex/readfile_ex.c @@ -0,0 +1,56 @@ +#include +#include + +#define LINE_LEN 16 + +int main(int argc, char **argv) +{ + pcap_t *fp; + char errbuf[PCAP_ERRBUF_SIZE]; + struct pcap_pkthdr *header; + const u_char *pkt_data; + u_int i=0; + int res; + + if(argc != 2) + { + printf("usage: %s filename", argv[0]); + return -1; + + } + + /* Open the capture file */ + if ((fp = pcap_open_offline(argv[1], // name of the device + errbuf // error buffer + )) == NULL) + { + fprintf(stderr,"\nUnable to open the file %s.\n", argv[1]); + return -1; + } + + /* Retrieve the packets from the file */ + while((res = pcap_next_ex(fp, &header, &pkt_data)) >= 0) + { + /* print pkt timestamp and pkt len */ + printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len); + + /* Print the packet */ + for (i=1; (i < header->caplen + 1 ) ; i++) + { + printf("%.2x ", pkt_data[i-1]); + if ( (i % LINE_LEN) == 0) printf("\n"); + } + + printf("\n\n"); + } + + + if (res == -1) + { + printf("Error reading the packets: %s\n", pcap_geterr(fp)); + } + + pcap_close(fp); + return 0; +} + diff --git a/winpcap/Examples-pcap/readfile_ex/readfile_ex.dsp b/winpcap/Examples-pcap/readfile_ex/readfile_ex.dsp new file mode 100644 index 0000000..2c1b488 --- /dev/null +++ b/winpcap/Examples-pcap/readfile_ex/readfile_ex.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="readfile_ex" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=readfile_ex - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "readfile_ex.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "readfile_ex.mak" CFG="readfile_ex - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "readfile_ex - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "readfile_ex - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "readfile_ex - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "readfile_ex - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "readfile_ex - Win32 Release" +# Name "readfile_ex - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\readfile_ex.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples-pcap/readfile_ex/readfile_ex.dsw b/winpcap/Examples-pcap/readfile_ex/readfile_ex.dsw new file mode 100644 index 0000000..2713b36 --- /dev/null +++ b/winpcap/Examples-pcap/readfile_ex/readfile_ex.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "readfile_ex"=.\readfile_ex.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples-pcap/savedump/GNUmakefile b/winpcap/Examples-pcap/savedump/GNUmakefile new file mode 100644 index 0000000..fd98a3a --- /dev/null +++ b/winpcap/Examples-pcap/savedump/GNUmakefile @@ -0,0 +1,17 @@ +# Makefile for cygwin gcc +# Nate Lawson + +PCAP_PATH = ../../lib +CFLAGS = -g -O -mno-cygwin -I ../../include + +OBJS = savedump.o +LIBS = -L ${PCAP_PATH} -lwpcap + +all: ${OBJS} + ${CC} ${CFLAGS} -o savedump.exe ${OBJS} ${LIBS} + +clean: + rm -f ${OBJS} savedump.exe + +.c.o: + ${CC} ${CFLAGS} -c -o $*.o $< diff --git a/winpcap/Examples-pcap/savedump/savedump.c b/winpcap/Examples-pcap/savedump/savedump.c new file mode 100644 index 0000000..8c7ead4 --- /dev/null +++ b/winpcap/Examples-pcap/savedump/savedump.c @@ -0,0 +1,103 @@ +#include "pcap.h" + +/* prototype of the packet handler */ +void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); + +main(int argc, char **argv) +{ + pcap_if_t *alldevs; + pcap_if_t *d; + int inum; + int i=0; + pcap_t *adhandle; + char errbuf[PCAP_ERRBUF_SIZE]; + pcap_dumper_t *dumpfile; + + + /* Check command line */ + if(argc != 2) + { + printf("usage: %s filename", argv[0]); + return -1; + } + + /* Retrieve the device list on the local machine */ + if (pcap_findalldevs(&alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. %s", ++i, d->name); + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if(i==0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return -1; + } + + printf("Enter the interface number (1-%d):",i); + scanf("%d", &inum); + + if(inum < 1 || inum > i) + { + printf("\nInterface number out of range.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Jump to the selected adapter */ + for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); + + + /* Open the adapter */ + if ((adhandle= pcap_open_live(d->name, // name of the device + 65536, // portion of the packet to capture. + // 65536 grants that the whole packet will be captured on all the MACs. + 1, // promiscuous mode (nonzero means promiscuous) + 1000, // read timeout + errbuf // error buffer + )) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Open the dump file */ + dumpfile = pcap_dump_open(adhandle, argv[1]); + + if(dumpfile==NULL) + { + fprintf(stderr,"\nError opening output file\n"); + return -1; + } + + printf("\nlistening on %s... Press Ctrl+C to stop...\n", d->description); + + /* At this point, we no longer need the device list. Free it */ + pcap_freealldevs(alldevs); + + /* start the capture */ + pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile); + + pcap_close(adhandle); + return 0; +} + +/* Callback function invoked by libpcap for every incoming packet */ +void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + /* save the packet on the dump file */ + pcap_dump(dumpfile, header, pkt_data); +} diff --git a/winpcap/Examples-pcap/savedump/savedump.dsp b/winpcap/Examples-pcap/savedump/savedump.dsp new file mode 100644 index 0000000..7d2e366 --- /dev/null +++ b/winpcap/Examples-pcap/savedump/savedump.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="savedump" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=savedump - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "savedump.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "savedump.mak" CFG="savedump - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "savedump - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "savedump - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "savedump - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "savedump - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "savedump - Win32 Release" +# Name "savedump - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\savedump.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples-pcap/savedump/savedump.dsw b/winpcap/Examples-pcap/savedump/savedump.dsw new file mode 100644 index 0000000..3247395 --- /dev/null +++ b/winpcap/Examples-pcap/savedump/savedump.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "savedump"=.\savedump.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples-pcap/sendpack/GNUmakefile b/winpcap/Examples-pcap/sendpack/GNUmakefile new file mode 100644 index 0000000..54939a6 --- /dev/null +++ b/winpcap/Examples-pcap/sendpack/GNUmakefile @@ -0,0 +1,17 @@ +# Makefile for cygwin gcc +# Nate Lawson + +PCAP_PATH = ../../lib +CFLAGS = -g -O -mno-cygwin -I ../../include + +OBJS = sendpack.o +LIBS = -L ${PCAP_PATH} -lwpcap + +all: ${OBJS} + ${CC} ${CFLAGS} -o sendpack.exe ${OBJS} ${LIBS} + +clean: + rm -f ${OBJS} sendpack.exe + +.c.o: + ${CC} ${CFLAGS} -c -o $*.o $< diff --git a/winpcap/Examples-pcap/sendpack/sendpack.c b/winpcap/Examples-pcap/sendpack/sendpack.c new file mode 100644 index 0000000..785f44b --- /dev/null +++ b/winpcap/Examples-pcap/sendpack/sendpack.c @@ -0,0 +1,68 @@ +#include +#include + +#include + + +int main(int argc, char **argv) +{ + pcap_t *fp; + char errbuf[PCAP_ERRBUF_SIZE]; + u_char packet[100]; + int i; + + /* Check the validity of the command line */ + if (argc != 2) + { + printf("usage: %s interface", argv[0]); + return 1; + } + + /* Open the adapter */ + if ((fp = pcap_open_live(argv[1], // name of the device + 65536, // portion of the packet to capture. It doesn't matter in this case + 1, // promiscuous mode (nonzero means promiscuous) + 1000, // read timeout + errbuf // error buffer + )) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", argv[1]); + return 2; + } + + /* Supposing to be on ethernet, set mac destination to 1:1:1:1:1:1 */ + packet[0]=1; + packet[1]=1; + packet[2]=1; + packet[3]=1; + packet[4]=1; + packet[5]=1; + + /* set mac source to 2:2:2:2:2:2 */ + packet[6]=2; + packet[7]=2; + packet[8]=2; + packet[9]=2; + packet[10]=2; + packet[11]=2; + + /* Fill the rest of the packet */ + for(i=12;i<100;i++) + { + packet[i]=i%256; + } + + /* Send down the packet */ + if (pcap_sendpacket(fp, // Adapter + packet, // buffer with the packet + 100 // size + ) != 0) + { + fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(fp)); + return 3; + } + + pcap_close(fp); + return 0; +} + diff --git a/winpcap/Examples-pcap/sendpack/sendpack.dsp b/winpcap/Examples-pcap/sendpack/sendpack.dsp new file mode 100644 index 0000000..982ce67 --- /dev/null +++ b/winpcap/Examples-pcap/sendpack/sendpack.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="sendpack" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=sendpack - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sendpack.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sendpack.mak" CFG="sendpack - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sendpack - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "sendpack - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sendpack - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "sendpack - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "sendpack - Win32 Release" +# Name "sendpack - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\sendpack.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples-pcap/sendpack/sendpack.dsw b/winpcap/Examples-pcap/sendpack/sendpack.dsw new file mode 100644 index 0000000..3e0424d --- /dev/null +++ b/winpcap/Examples-pcap/sendpack/sendpack.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "sendpack"=.\sendpack.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples-pcap/stats/stats.c b/winpcap/Examples-pcap/stats/stats.c new file mode 100644 index 0000000..cc3885f --- /dev/null +++ b/winpcap/Examples-pcap/stats/stats.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2006 + * CACE Technologies, Davis, California + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * This is a test for pcap_stats(). It opens an adapter, sets a filter that + * drops all the packets, and then cycles printing the result of pcap_stats(). + * The following two defines can be used to specify the time between two calls + * to pcap_stats(), and the kernel buffer size. + * + * Author: Loris Degioanni, April 2006 + * + */ + +#include "pcap.h" + +#define TIME_TO_SLEEP_MS 5000 +#define KERNEL_BUFFER_SIZE_BYTES 16000 + +main() +{ + pcap_if_t *alldevs; + pcap_if_t *d; + int inum; + int i = 0; + pcap_t *adhandle; + char errbuf[PCAP_ERRBUF_SIZE]; + struct pcap_stat stats; + unsigned int j; + u_int netmask; + char packet_filter[] = "greater 30000"; + struct bpf_program fcode; + + /* Retrieve the device list */ + if(pcap_findalldevs(&alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. %s", ++i, d->name); + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if(i==0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return -1; + } + + printf("Enter the interface number (1-%d):",i); + scanf("%d", &inum); + + /* Check if the user specified a valid adapter */ + if(inum < 1 || inum > i) + { + printf("\nAdapter number out of range.\n"); + + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Jump to the selected adapter */ + for(d = alldevs, i = 0; i < inum-1 ;d = d->next, i++); + + /* Open the adapter */ + if ((adhandle = pcap_open_live(d->name, // name of the device + 65536, // portion of the packet to capture. + // 65536 grants that the whole packet will be captured on all the MACs. + 1, // promiscuous mode (nonzero means promiscuous) + 1000, // read timeout + errbuf // error buffer + )) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + printf("\nlistening on %s...\n", d->description); + + if(d->addresses != NULL) + { + /* Retrieve the mask of the first address of the interface */ + netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; + } + else + { + /* If the interface is without addresses we suppose to be in a C class network */ + netmask=0xffffff; + } + + //compile the filter + if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 ) + { + fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* At this point, we don't need any more the device list. Free it */ + pcap_freealldevs(alldevs); + + /* set the filter */ + if (pcap_setfilter(adhandle, &fcode)<0) + { + fprintf(stderr,"\nError setting the filter.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + + /* Set the kernel capture buffer size*/ + if(pcap_setbuff(adhandle, KERNEL_BUFFER_SIZE_BYTES) != 0) + { + printf("Error setting the kernel buffer (%s)\n", pcap_geterr(adhandle)); + return -1; + + pcap_close(adhandle); + } + + /* cycle printing the statisctics from pcap_stats() */ + for(j = 0; ; j++) + { + pcap_stats(adhandle, &stats); + + printf("Recv: %u, Dropped:%u\n", + stats.ps_recv, + stats.ps_drop); + + if(j % 5 == 0) + { + Sleep(TIME_TO_SLEEP_MS); + } + } + + return 0; +} diff --git a/winpcap/Examples-pcap/stats/stats.dsp b/winpcap/Examples-pcap/stats/stats.dsp new file mode 100644 index 0000000..b26fe3c --- /dev/null +++ b/winpcap/Examples-pcap/stats/stats.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="stats" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=stats - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "stats.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "stats.mak" CFG="stats - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "stats - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "stats - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "stats - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "stats - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "stats - Win32 Release" +# Name "stats - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\stats.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples-pcap/stats/stats.dsw b/winpcap/Examples-pcap/stats/stats.dsw new file mode 100644 index 0000000..1d8ca31 --- /dev/null +++ b/winpcap/Examples-pcap/stats/stats.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "stats"=.\stats.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples-pcap/winpcap_stress/winpcap_stress.c b/winpcap/Examples-pcap/winpcap_stress/winpcap_stress.c new file mode 100644 index 0000000..0a8501b --- /dev/null +++ b/winpcap/Examples-pcap/winpcap_stress/winpcap_stress.c @@ -0,0 +1,498 @@ +/*============================================================================* + * FILE: winpcap_stress.c + *============================================================================* + * + * COPYRIGHT (C) 2006 BY + * CACE TECHNOLOGIES, INC., DAVIS, CALIFORNIA + * ALL RIGHTS RESERVED. + * + * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND + * COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH + * THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY + * OTHER COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE + * AVAILABLE TO ANY OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE + * SOFTWARE IS HEREBY TRANSFERRED. + * + * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT + * NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY CACE TECNOLOGIES + * + *===========================================================================* + * + * This program is a generic "stress test" for winpcap. It creates several threads + * each of which opens an adapter, captures some packets and then closes it. + * The user can specify: + * + * - the number of threads + * - the number of read operations that every thread performs before exiting + * + * The program prints statistics before exiting. + * + *===========================================================================*/ + +///////////////////////////////////////////////////////////////////// +// Program parameters +///////////////////////////////////////////////////////////////////// +#undef STRESS_AIRPCAP_TRANSMISSION +#define NUM_THREADS 16 +#define MAX_NUM_READS 500 +#define MAX_NUM_WRITES 10000 + +#define WRITES_FREQUENCY 2 // This constant specifies how often a thread will transmit instead of receiving + // packets. + // - 0 means no Tx threads + // - 1 means all threads are Tx + // - 2 means that 1 thread every 2 is Tx + // - 3 means that 1 thread every 3 is Tx + // ...and so on + +#undef INJECT_FILTERS + +///////////////////////////////////////////////////////////////////// + +#include +#include +#include + +#include + +#ifdef STRESS_AIRPCAP_TRANSMISSION +#include +#endif + +#define LINE_LEN 16 + + +#define FILTER "ether[80:1] < 128 || ether[81:1] > 127 || ether[82:1] < 180 || ether[83:1] > 181" \ + "|| ether[84:1] < 128 || ether[85:1] > 127 || ether[86:1] < 180 || ether[87:1] > 181" \ + "|| ether[88:1] < 128 || ether[89:1] > 127 || ether[90:1] < 180 || ether[91:1] > 181" \ + "|| ether[92:1] < 128 || ether[93:1] > 127 || ether[94:1] < 180 || ether[95:1] > 181" \ + "|| ether[96:1] < 128 || ether[97:1] > 127 || ether[98:1] < 180 || ether[99:1] > 181" \ + "|| ether[100:1] < 128 || ether[101:1] > 127 || ether[102:1] < 180 || ether[103:1] > 181" \ + "|| ether[104:1] < 128 || ether[105:1] > 127 || ether[106:1] < 180 || ether[107:1] > 181" \ + "|| ether[108:1] < 128 || ether[109:1] > 127 || ether[110:1] < 180 || ether[111:1] > 181" \ + + +u_int n_iterations = 0; +u_int n_packets = 0; +u_int n_timeouts = 0; +u_int n_open_errors = 0; +u_int n_read_errors = 0; +u_int n_write_errors = 0; +u_int n_findalldevs_errors = 0; +u_int n_setfilters = 0; +u_int thread_id = 0; + +CRITICAL_SECTION print_cs; + +#define MAX_TX_PACKET_SIZE 1604 +u_char pkt_to_send[MAX_TX_PACKET_SIZE]; + + +///////////////////////////////////////////////////////////////////// +// Radiotap header. Used for 802.11 transmission +///////////////////////////////////////////////////////////////////// + +#ifndef __MINGW32__ +#pragma pack(push) +#pragma pack(1) +#endif // __MINGW32__ +typedef struct _tx_ieee80211_radiotap_header +{ + u_int8_t it_version; + u_int8_t it_pad; + u_int16_t it_len; + u_int32_t it_present; + u_int8_t it_rate; +} +#ifdef __MINGW32__ +__attribute__((__packed__)) +#endif // __MINGW32__ +tx_ieee80211_radiotap_header; +#ifndef __MINGW32__ +#pragma pack(pop) +#endif // __MINGW32__ + +///////////////////////////////////////////////////////////////////// +// Table of legal radiotap Tx rates +///////////////////////////////////////////////////////////////////// +UCHAR TxRateInfoTable[] = +{ + 2, + 4, + 11, + 12, + 18, + 22, + 24, + 36, + 48, + 72, + 96, + 108 +}; + +///////////////////////////////////////////////////////////////////// + +void usage() +{ + printf("winpcap_stress: utility that stresses winpcap by opening and capturing from multiple adapters at the same time.\n"); + printf(" Usage: winpcap_stress \n\n" + " Examples:\n" + " winpcap_stress\n" + " winpcap_stress 10\n\n" + " winpcap_stress 10 \\Device\\NPF_{ \n"); +} + +///////////////////////////////////////////////////////////////////// + +void sigh(int val) +{ + EnterCriticalSection(&print_cs); + + printf("\nNumber of iterations:\t\t%u\n", n_iterations); + printf("Number of packets captured:\t\t%u\n", n_packets); + printf("Number of read timeouts:\t\t%u\n", n_timeouts); + printf("Number of open errors:\t\t%u\n", n_open_errors); + printf("Number of read errors:\t\t%u\n", n_read_errors); + printf("Number of setfilters:\t\t%u\n", n_setfilters); + + // + // Note: we don't release the critical section on purpose, so the user doesn't + // get crappy input when he presses CTRL+C + // + exit(0); +} + + + +///////////////////////////////////////////////////////////////////// + +DWORD WINAPI pcap_thread(LPVOID arg) +{ + pcap_t *fp; + char* AdName = (char*)arg; + char errbuf[PCAP_ERRBUF_SIZE]; + int res; + struct pcap_pkthdr *header; + const u_char *pkt_data; + u_int i; + u_int n_reads, n_writes; +#ifdef INJECT_FILTERS + struct bpf_program fcode; + int compile_result; +#endif +#ifdef STRESS_AIRPCAP_TRANSMISSION + PAirpcapHandle airpcap_handle; + tx_ieee80211_radiotap_header *radio_header; +#endif + u_int rate_index; + + srand( (unsigned)time( NULL ) ); + + // + // Open the adapter + // + if((fp = pcap_open_live(AdName, + 65535, + 0, // promiscuous mode + 1, // read timeout + errbuf)) == NULL) + { + EnterCriticalSection(&print_cs); + fprintf(stderr,"\nError opening adapter (%s)\n", errbuf); + LeaveCriticalSection(&print_cs); + n_open_errors++; + return -1; + } + + // + // Decide if this is going to be a read or write thread + // + + if((WRITES_FREQUENCY != 0) && ((thread_id++) % WRITES_FREQUENCY == 0)) + { + // + // Write thread + // + if(MAX_NUM_WRITES) + { + n_writes = rand() % MAX_NUM_READS; + } + else + { + n_writes = 0; + } + + // + // Get the airpcap handle so we can change wireless-specific settings + // +#ifdef STRESS_AIRPCAP_TRANSMISSION + airpcap_handle = pcap_get_airpcap_handle(fp); + + if(airpcap_handle != NULL) + { + // + // Configure the AirPcap adapter + // + + // Tell the adapter that the packets we'll send don't include the FCS + if(!AirpcapSetFcsPresence(airpcap_handle, FALSE)) + { + printf("Error setting the Fcs presence: %s\n", AirpcapGetLastError(airpcap_handle)); + pcap_close(fp); + return -1; + } + + // + // Set the link layer to 802.11 + radiotap + // + if(!AirpcapSetLinkType(airpcap_handle, AIRPCAP_LT_802_11_PLUS_RADIO)) + { + printf("Error setting the link layer: %s\n", AirpcapGetLastError(airpcap_handle)); + pcap_close(fp); + return -1; + } + + // + // Create the radiotap header + // + radio_header = (tx_ieee80211_radiotap_header*)pkt_to_send; + radio_header->it_version = 0; + radio_header->it_pad = 0; + radio_header->it_len = sizeof(tx_ieee80211_radiotap_header); + radio_header->it_present = 1 << 2; // bit 2 is the rate + rate_index = 18/*rand() % (sizeof(TxRateInfoTable) / sizeof(TxRateInfoTable[0]))*/; + radio_header->it_rate = 18/*TxRateInfoTable[rate_index]*/; + } +#endif + for(i = 0; i < n_writes; i++) + { + if(pcap_sendpacket(fp, pkt_to_send, (rand() % MAX_TX_PACKET_SIZE) + 10) != 0) + { +// EnterCriticalSection(&print_cs); +// printf("Write Error: %s\n", pcap_geterr(fp)); +// LeaveCriticalSection(&print_cs); + n_write_errors++; + } + } + } + else + { + + // + // Read Thread + // + if(MAX_NUM_READS) + { + n_reads = rand() % MAX_NUM_READS; + } + else + { + n_reads = 0; + } + + for(i = 0; i < n_reads; i++) + { + res = pcap_next_ex(fp, &header, &pkt_data); + + if(res < 0) + { + break; + } + +#ifdef INJECT_FILTERS + + EnterCriticalSection(&print_cs); + compile_result = pcap_compile(fp, &fcode, FILTER, 1, 0xFFFFFFFF); + LeaveCriticalSection(&print_cs); + + + + //compile the filter + if( compile_result < 0) + { + fprintf(stderr,"Error compiling filter: wrong syntax.\n"); + } + else + { + //set the filterf + if(pcap_setfilter(fp, &fcode)<0) + { + fprintf(stderr,"Error setting the filter\n"); + } + else + { + InterlockedIncrement(&n_setfilters); + } + pcap_freecode(&fcode); + } +#endif + + if(res == 0) + { + // Timeout elapsed + n_timeouts++; + continue; + } + + + // print pkt timestamp and pkt len + n_packets++; + } + + if(res == -1) + { + EnterCriticalSection(&print_cs); + printf("Read error: %s\n", pcap_geterr(fp)); + LeaveCriticalSection(&print_cs); + n_read_errors++; + } + } + + pcap_close(fp); + + return 1; +} + +///////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////// + +int main(int argc, char **argv) +{ + pcap_if_t *alldevs, *d; + u_int i; + char errbuf[PCAP_ERRBUF_SIZE]; + u_int n_threads; + HANDLE* hThreads; + char* string_to_match; + DWORD WaitRes; + + // + // Parse input + // + if(argc == 1) + { + n_threads = NUM_THREADS; + string_to_match = NULL; + } + else + if(argc == 2) + { + n_threads = atoi(argv[1]); + string_to_match = NULL; + } + else + if(argc == 3) + { + n_threads = atoi(argv[1]); + string_to_match = argv[2]; + } + else + { + usage(); + return 1; + } + + // + // Init the Tx packet + // + for(i = 0; i < MAX_TX_PACKET_SIZE; i++) + { + pkt_to_send[i] = i & 0xff; + } + + // + // Allocate storage for the threads list + // + hThreads = (HANDLE*)malloc(n_threads * sizeof(HANDLE)); + if(!hThreads) + { + printf("Memeory allocation failure\n"); + return -1; + } + + memset(hThreads, 0, n_threads * sizeof(HANDLE)); + + signal(SIGINT, sigh); + InitializeCriticalSection(&print_cs); + + // + // Scan the device list + // + if(pcap_findalldevs(&alldevs, errbuf) == -1) + { + EnterCriticalSection(&print_cs); + fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); + LeaveCriticalSection(&print_cs); + n_findalldevs_errors++; +// continue; + return -1; + } + + // + // Jump to the selected adapter + // + for(i = 0;;) + { + // + // Go through the list, feeding a thread with each adapter that contains our substring + // + for(d = alldevs; d; d = d->next) + { + if(string_to_match) + { + if(!strstr(d->name, string_to_match)) + { + continue; + } + } + + if(i == n_threads) + { + i= 0; + } + + // + // Check if the thread is done + // + WaitRes = WaitForSingleObject(hThreads[i], 1); + + if(WaitRes == WAIT_TIMEOUT) + { + // + // In case of timeout, we switch to the following thread + // + i++; + continue; + } + + // + // Create the child thread + // + printf("Thread %u, %s 0x%x\n", i, d->name, WaitRes); + + // + // Close the thread handle + // + if(hThreads[i]) + { + CloseHandle(hThreads[i]); + } + + hThreads[i] = CreateThread(NULL, 0, pcap_thread, d->name, 0, NULL); + + if(hThreads[i] == NULL) + { + printf("error creating thread. Quitting\n"); + sigh(42); + } + + n_iterations++; + i++; + } + } + + free(hThreads); + + return 0; +} diff --git a/winpcap/Examples-pcap/winpcap_stress/winpcap_stress.dsp b/winpcap/Examples-pcap/winpcap_stress/winpcap_stress.dsp new file mode 100644 index 0000000..cdec5dc --- /dev/null +++ b/winpcap/Examples-pcap/winpcap_stress/winpcap_stress.dsp @@ -0,0 +1,106 @@ +# Microsoft Developer Studio Project File - Name="winpcap_stress" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=winpcap_stress - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "winpcap_stress.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "winpcap_stress.mak" CFG="winpcap_stress - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "winpcap_stress - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "winpcap_stress - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "winpcap_stress - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "../../" /I "../../../../wpdpack/Include/" /I "../../include" /I "../../../WinPcap_Devpack/Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 wpcap.lib airpcap.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 /libpath:"../../debug" /libpath:"../../lib" /libpath:"../../../../wpdpack/lib/" /libpath:"../../../WinPcap_Devpack/lib/" + +!ELSEIF "$(CFG)" == "winpcap_stress - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "../../" /I "../../../../wpdpack/Include/" /I "../../include" /I "../../../WinPcap_Devpack/Include/" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 wpcap.lib airpcap.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../../debug" /libpath:"../../lib" /libpath:"../../../../wpdpack/lib/" /libpath:"../../../WinPcap_Devpack/lib/" + +!ENDIF + +# Begin Target + +# Name "winpcap_stress - Win32 Release" +# Name "winpcap_stress - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\winpcap_stress.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/winpcap/Examples-pcap/winpcap_stress/winpcap_stress.dsw b/winpcap/Examples-pcap/winpcap_stress/winpcap_stress.dsw new file mode 100644 index 0000000..87a2e5d --- /dev/null +++ b/winpcap/Examples-pcap/winpcap_stress/winpcap_stress.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "winpcap_stress"=.\winpcap_stress.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples/MakeaAll.dsw b/winpcap/Examples/MakeaAll.dsw new file mode 100644 index 0000000..1772c2a --- /dev/null +++ b/winpcap/Examples/MakeaAll.dsw @@ -0,0 +1,221 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "GetMacAddress"=".\PacketDriver\GetMacAddress\GetMacAddress.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "TestPacketCapture"=".\PacketDriver\TestPacketCapture\TestPacketCapture.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "TestPacketSend"=".\PacketDriver\TestPacketSend\TestPacketSend.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "UDPdump"=".\UDPdump\UDPdump.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "UserBridge"=".\UserLevelBridge\UserBridge.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "basic_dump"=".\misc\basic_dump.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "basic_dump_ex"=".\misc\basic_dump_ex.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "iflist"=".\iflist\iflist.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "pcap_filter"=".\pcap_filter\pcap_filter.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "pktdump_ex"=".\pktdump_ex\pktdump_ex.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "readfile"=".\misc\readfile.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "readfile_ex"=".\misc\readfile_ex.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "savedump"=".\misc\savedump.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "sendcap"=".\sendcap\sendcap.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "sendpack"=".\misc\sendpack.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "smp_1"=".\smp_1\smp_1.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "tcptop"=".\tcptop\tcptop.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples/NETMETER/CapDll.h b/winpcap/Examples/NETMETER/CapDll.h new file mode 100644 index 0000000..a504b4a --- /dev/null +++ b/winpcap/Examples/NETMETER/CapDll.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#if !defined(AFX_CapDll_H__03FA9206_C8EA_11D2_B729_0048540133F7__INCLUDED_) +#define AFX_CapDll_H__03FA9206_C8EA_11D2_B729_0048540133F7__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols +#define MaxCapPars 10 + +///////////////////////////////////////////////////////////////////////////// +// CCapDll: +// See CapDll.cpp for the implementation of this class +// +#ifdef _EXPORTING +#define CLASS_DECLSPEC __declspec(dllexport) +#else +#define CLASS_DECLSPEC __declspec(dllimport) +#endif + +void CLASS_DECLSPEC InitCapDll(const char* INI); + +class CLASS_DECLSPEC CCapDll +{ +public: + CCapDll(); + const char* GetFileName(); + char* SetFileName(const char* fn); + const char* GetAdapter(); + const char* GetPath(); + const char* GetFilter(); + char* SetPath(const char * p); + char* SetAdapter(const char* ad); + char* SetFilter(const char* ad); + int CaptureDialog(const char* Adapter,const char* P, CWnd* mw); + int ChooseAdapter(const char* Adapter, CWnd* mw); + const char* Capture(const char* file, CWnd* mw); + ~CCapDll(); +private: + char* Path; + char* Adapter; + char* FileName; + char* Filter; + int bufdim; + int ncapture; + int snaplen; + int promisquous; + void LoadCmds(); + CString RetrieveValue(CString keyval); +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_CapDll_H__03FA9206_C8EA_11D2_B729_0048540133F7__INCLUDED_) diff --git a/winpcap/Examples/NETMETER/CaptureThread.cpp b/winpcap/Examples/NETMETER/CaptureThread.cpp new file mode 100644 index 0000000..4d85718 --- /dev/null +++ b/winpcap/Examples/NETMETER/CaptureThread.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "stdafx.h" +#include "resource.h" +#include "capdll.h" +#include "console.h" + +HANDLE in,out,err; + +DWORD d; +CCapPars* pObject; +CRITICAL_SECTION Crit; + +// callback routine called by libpcap for every incoming packet +void dispatcher_handler(u_char *pParam,const struct pcap_pkthdr *header, const u_char *pkt_data) +{ +UINT delay; +LARGE_INTEGER Bps,Pps; +CCapPars* pObject; + + pObject=(CCapPars*)pParam; + //Calculate the delay in microseconds from the last sample. + //This value is obtained from the timestamp that the capture driver + //associates to the sample. + delay=(header->ts.tv_sec-pObject->lasttime.tv_sec)*1000000-pObject->lasttime.tv_usec+header->ts.tv_usec; + //get the number of Bits per second + Bps.QuadPart=(((LONGLONG)(*(LONGLONG*)(pkt_data+8))*80)/(delay)); + //get the number of Packets per second + Pps.QuadPart=(((LONGLONG)(*(LONGLONG*)(pkt_data))*100000000)/((LONGLONG)delay*14880)); + + //store current timestamp + pObject->lasttime.tv_sec=header->ts.tv_sec; + pObject->lasttime.tv_usec=header->ts.tv_usec; + + pObject->prg->DrawBoard(&(pObject->prg->DrawBuffer),pObject->prg->wrett,Bps.LowPart,Pps.LowPart); +} + +//main thread procedure: launches the capture and wait +UINT MyThreadProc( LPVOID pParam ) +{ + int i; + + if (pParam == NULL) + return -1; // illegal parameter + pObject=(CCapPars*)pParam; + + //reset the timer + pObject->lasttime.tv_sec=0; + pObject->lasttime.tv_usec=0; + + //start the capture loop + i = pcap_loop(pObject->fp, 0, dispatcher_handler, (PUCHAR)pParam); + + Sleep(INFINITE); + + return 0; +} + diff --git a/winpcap/Examples/NETMETER/Console.h b/winpcap/Examples/NETMETER/Console.h new file mode 100644 index 0000000..7c242fa --- /dev/null +++ b/winpcap/Examples/NETMETER/Console.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "..\..\include\pcap.h" +#include "netmeterDoc.h" +#include "netmeterView.h" + +UINT MyThreadProc( LPVOID pParam ); + +typedef struct CCapPars +{ + CNetmeterView* prg; //CNetmeterView class that launched the capture thread + pcap_t *fp; //libpcap adapter + struct timeval lasttime; //last capture time (internal) +}CCapPars; diff --git a/winpcap/Examples/NETMETER/LineColl.cpp b/winpcap/Examples/NETMETER/LineColl.cpp new file mode 100644 index 0000000..f34087a --- /dev/null +++ b/winpcap/Examples/NETMETER/LineColl.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "LineColl.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char THIS_FILE[]=__FILE__; +#define new DEBUG_NEW +#endif + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +LineCollection::LineCollection(CString *s,int skip) +{ + m_Skip=skip; + if(s==NULL) return; + *this=*s; +} + +LineCollection::LineCollection(CArchive &ar,int skip) +{ + if (ar.IsStoring()) + { + return; + } + else + { + m_Skip=skip; + CString s; + int i,j; + vect.SetSize(0); + for(i=0,j=0;ar.ReadString(s);i++) + { + if(m_Skip && s=="") continue; + vect.SetSize(j+1); + vect[j]=s; + j++; + } + } +} + +LineCollection::~LineCollection() +{ +} + +int LineCollection::GetSize() +{ + return vect.GetSize(); +} + +CString & LineCollection::operator =(CString &s) +{ + int i,l,n,t=0; + l=s.GetLength(); + vect.SetSize(0); + for(i=0,n=0;i0 && (s)[i-1]=='\n') continue; + vect.SetSize(t+1); + vect[t]=(s).Mid(n,i-n-1); + t++; + n=i+1; + } + } + return s; +} + +void LineCollection::clear() +{ + vect.SetSize(0); +} + diff --git a/winpcap/Examples/NETMETER/LineColl.h b/winpcap/Examples/NETMETER/LineColl.h new file mode 100644 index 0000000..39281a1 --- /dev/null +++ b/winpcap/Examples/NETMETER/LineColl.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#if !defined(AFX_LINECOLL_H__EE11D4A3_ED58_11D1_939A_000000000000__INCLUDED_) +#define AFX_LINECOLL_H__EE11D4A3_ED58_11D1_939A_000000000000__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include +#include + +class LineCollection +{ +public: + void clear(); + CString & operator =(CString &); + int GetSize(); + int getLineCount(){return GetSize();}; + const char* line(int i){if (i vect; +}; + +#endif // !defined(AFX_LINECOLL_H__EE11D4A3_ED58_11D1_939A_000000000000__INCLUDED_) diff --git a/winpcap/Examples/NETMETER/MainFrm.cpp b/winpcap/Examples/NETMETER/MainFrm.cpp new file mode 100644 index 0000000..ff3ea85 --- /dev/null +++ b/winpcap/Examples/NETMETER/MainFrm.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "stdafx.h" +#include "netmeter.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ +} + +CMainFrame::~CMainFrame() +{ +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ + if( !CFrameWnd::PreCreateWindow(cs) ) + return FALSE; + + cs.style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + cs.cx=260; + cs.cy=180; + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG diff --git a/winpcap/Examples/NETMETER/MainFrm.h b/winpcap/Examples/NETMETER/MainFrm.h new file mode 100644 index 0000000..0ec4f25 --- /dev/null +++ b/winpcap/Examples/NETMETER/MainFrm.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// MainFrm.h : interface of the CMainFrame class +// +///////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__3BF6CD27_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_) +#define AFX_MAINFRM_H__3BF6CD27_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +class CMainFrame : public CFrameWnd +{ + +protected: // create from serialization only + CMainFrame(); + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + public: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__3BF6CD27_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_) diff --git a/winpcap/Examples/NETMETER/NETMETER.CPP b/winpcap/Examples/NETMETER/NETMETER.CPP new file mode 100644 index 0000000..a572e29 --- /dev/null +++ b/winpcap/Examples/NETMETER/NETMETER.CPP @@ -0,0 +1,161 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "stdafx.h" +#include "netmeter.h" + +#include "MainFrm.h" +#include "netmeterDoc.h" +#include "netmeterView.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CNetmeterApp + +BEGIN_MESSAGE_MAP(CNetmeterApp, CWinApp) + //{{AFX_MSG_MAP(CNetmeterApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CNetmeterApp construction + +CNetmeterApp::CNetmeterApp() +{ +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CNetmeterApp object + +CNetmeterApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CNetmeterApp initialization + +BOOL CNetmeterApp::InitInstance() +{ + // Standard initialization + + // Change the registry key under which our settings are stored. + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register document templates + + CSingleDocTemplate* pDocTemplate; + pDocTemplate = new CSingleDocTemplate( + IDR_MAINFRAME, + RUNTIME_CLASS(CNetmeterDoc), + RUNTIME_CLASS(CMainFrame), // main SDI frame window + RUNTIME_CLASS(CNetmeterView)); + AddDocTemplate(pDocTemplate); + +// CNetmeterView + + // Parse command line for standard shell commands, DDE, file open + CCommandLineInfo cmdInfo; + ParseCommandLine(cmdInfo); + + // Dispatch commands specified on the command line + if (!ProcessShellCommand(cmdInfo)) + return FALSE; + m_pMainWnd->ShowWindow(SW_SHOW); + m_pMainWnd->UpdateWindow(); + + return TRUE; +} + + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CNetmeterApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CNetmeterApp message handlers diff --git a/winpcap/Examples/NETMETER/NETMETER.H b/winpcap/Examples/NETMETER/NETMETER.H new file mode 100644 index 0000000..51da8bb --- /dev/null +++ b/winpcap/Examples/NETMETER/NETMETER.H @@ -0,0 +1,80 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// netmeter.h : main header file for the NETMETER application +// + +#if !defined(AFX_NETMETER_H__3BF6CD23_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_) +#define AFX_NETMETER_H__3BF6CD23_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CNetmeterApp: +// See netmeter.cpp for the implementation of this class +// + +class CNetmeterApp : public CWinApp +{ +public: + CNetmeterApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CNetmeterApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + //{{AFX_MSG(CNetmeterApp) + afx_msg void OnAppAbout(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_NETMETER_H__3BF6CD23_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_) diff --git a/winpcap/Examples/NETMETER/ProgCaptDlg.h b/winpcap/Examples/NETMETER/ProgCaptDlg.h new file mode 100644 index 0000000..7ced629 --- /dev/null +++ b/winpcap/Examples/NETMETER/ProgCaptDlg.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#if !defined(AFX_PROGCAPTDLG_H__D79DA3C4_3B52_11D2_9482_0020AF2A4474__INCLUDED_) +#define AFX_PROGCAPTDLG_H__D79DA3C4_3B52_11D2_9482_0020AF2A4474__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// ProgCaptDlg.h : header file +// +#include "..\..\include\pcap-c.h" + +class CCapPars; + +///////////////////////////////////////////////////////////////////////////// +// CProgCaptDlg dialog + +class CProgCaptDlg : public CDialog +{ +// Construction +public: + CProgCaptDlg(CWnd* pParent = NULL); // standard constructor + CCapPars* m_Main; + int npc; + int init; + pcap_t *fp; + pcap_dumper_t *dumpfile; + + +// Dialog Data + //{{AFX_DATA(CProgCaptDlg) + enum { IDD = IDD_CAP_BUSY }; + CStatic m_Static; + CProgressCtrl m_Progress; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CProgCaptDlg) + public: + virtual BOOL PreTranslateMessage(MSG* pMsg); + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + int p; + int v; + + // Generated message map functions + //{{AFX_MSG(CProgCaptDlg) + virtual BOOL OnInitDialog(); + virtual void OnCancel(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PROGCAPTDLG_H__D79DA3C4_3B52_11D2_9482_0020AF2A4474__INCLUDED_) diff --git a/winpcap/Examples/NETMETER/SelectAdapter.cpp b/winpcap/Examples/NETMETER/SelectAdapter.cpp new file mode 100644 index 0000000..a377734 --- /dev/null +++ b/winpcap/Examples/NETMETER/SelectAdapter.cpp @@ -0,0 +1,245 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "stdafx.h" +#include "CapDll.h" +#include "SelectAdapter.h" +#include "LineColl.h" +#include "..\..\include\pcap.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define SA_ERR "Unable to choose Adaptors" +#define SA_ADS "Network Cards" +#define MFR_TCPDUMPERR "Unable to Capture on this operating system" + +///////////////////////////////////////////////////////////////////////////// +// CSelectAdapter dialog + + +CSelectAdapter::CSelectAdapter(CWnd* pParent /*=NULL*/) + : CDialog(CSelectAdapter::IDD, pParent) +{ + //{{AFX_DATA_INIT(CSelectAdapter) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void CSelectAdapter::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CSelectAdapter) + DDX_Control(pDX, IDC_ADAPTER, m_CAdapter); + DDX_Control(pDX, IDC_LIST1, m_ListCtrl); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CSelectAdapter, CDialog) + //{{AFX_MSG_MAP(CSelectAdapter) + ON_NOTIFY(HDN_ITEMCLICK, IDC_LIST1, OnSelectItem) + ON_NOTIFY(HDN_ITEMDBLCLICK, IDC_LIST1, Ondblclickitem) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSelectAdapter message handlers + +BOOL CSelectAdapter::OnInitDialog() +{ +char ebuf[PCAP_ERRBUF_SIZE]; +char devicelist[65000]; +pcap_if_t *alldevs, *d; +char *devicelistptr; + + + CDialog::OnInitDialog(); + + /* Retrieve the device list on the local machine */ + /* Don't check for errors */ + pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, ebuf); + + devicelistptr= devicelist; + devicelist[0]= 0; + + for(d=alldevs; d; d=d->next) + { + + strcat(devicelistptr, d->name); + devicelistptr+= strlen(d->name); + + strcat(devicelistptr, "\r\n"); + devicelistptr+= strlen("\r\n"); + } + + m_Cmd= devicelist; + + pcap_freealldevs(alldevs); + + LineCollection lc(&m_Cmd); + m_ListCtrl.InsertColumn(0,SA_ADS /*Adapters*/, LVCFMT_LEFT,200); + m_ctlImage.Create(IDB_CAP_WIZ,16,0,RGB(255,0,255)); + m_ListCtrl.SetImageList(&m_ctlImage,LVSIL_SMALL); + Update(lc); + m_ListCtrl.SetFocus(); + m_CAdapter.SetWindowText(m_Adapter); + return FALSE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CSelectAdapter::AddItem(int nItem,int nSubItem,LPCTSTR strItem,int nImageIndex) +{ + LV_ITEM lvItem; + lvItem.mask = LVIF_TEXT; + lvItem.iItem = nItem; + lvItem.iSubItem = nSubItem; + lvItem.pszText = (LPTSTR) strItem; + if(nImageIndex != -1){ + lvItem.mask |= LVIF_IMAGE; + lvItem.iImage = nImageIndex; + } + if(nSubItem == 0) + m_ListCtrl.InsertItem(&lvItem); + else m_ListCtrl.SetItem(&lvItem); +} + +void CSelectAdapter::SelectItem(int i) +{ + LV_FINDINFO it; + + it.flags=LVFI_PARAM; + it.lParam=i; + i=m_ListCtrl.FindItem(&it); + m_ListCtrl.SetItemState(i,0xFFFFFFFF,LVIS_SELECTED); +} + +void CSelectAdapter::Update(LineCollection &lc) +{ + m_ListCtrl.DeleteAllItems(); + int n=lc.getLineCount(); + CString t; + for(n--;n>=0;n--) + { + t=lc.line(n); + t.TrimLeft(); + t.TrimRight(); + if (strlen(t)>0) + AddItem(0,0,t,3); + } + m_ListCtrl.UpdateWindow(); + n=m_ListCtrl.GetItemCount(); + for (n--;n>=0;n--) + { + if (m_Adapter.CompareNoCase(m_ListCtrl.GetItemText(n,0))==0) + { + SelectItem(n); + return; + } + } + m_Adapter=m_ListCtrl.GetItemText(0,0); +} + + +void CSelectAdapter::OnOK() +{ + int i,n=m_ListCtrl.GetItemCount(); + for(i=0;i= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// SelectAdapter.h : header file +// + +#include "linecoll.h" +#include "resource.h" + +///////////////////////////////////////////////////////////////////////////// +// CSelectAdapter dialog + +int ExecuteApp(CString & s); + +class CSelectAdapter : public CDialog +{ +// Construction +public: + CSelectAdapter(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CSelectAdapter) + enum { IDD = IDD_ADAPTER }; + CStatic m_CAdapter; + CListCtrl m_ListCtrl; + //}}AFX_DATA + CString m_Adapter; + CString m_Cmd; + CImageList m_ctlImage; + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSelectAdapter) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + void Update(LineCollection &lc); + void AddItem(int nItem,int nSubItem,LPCTSTR strItem,int nImageIndex=-1); + void SelectItem(int i); + + // Generated message map functions + //{{AFX_MSG(CSelectAdapter) + virtual BOOL OnInitDialog(); + virtual void OnOK(); + afx_msg void OnSelectItem(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void Ondblclickitem(NMHDR* pNMHDR, LRESULT* pResult); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SELECTADAPTER_H__D41A3004_2B3D_11D0_9528_0020AF2A4474__INCLUDED_) diff --git a/winpcap/Examples/NETMETER/StdAfx.cpp b/winpcap/Examples/NETMETER/StdAfx.cpp new file mode 100644 index 0000000..c9d43db --- /dev/null +++ b/winpcap/Examples/NETMETER/StdAfx.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// stdafx.cpp : source file that includes just the standard includes +// netmeter.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + + + diff --git a/winpcap/Examples/NETMETER/StdAfx.h b/winpcap/Examples/NETMETER/StdAfx.h new file mode 100644 index 0000000..5bdc5e3 --- /dev/null +++ b/winpcap/Examples/NETMETER/StdAfx.h @@ -0,0 +1,26 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__3BF6CD25_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_) +#define AFX_STDAFX_H__3BF6CD25_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC support for Internet Explorer 4 Common Controls +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__3BF6CD25_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_) diff --git a/winpcap/Examples/NETMETER/netmeter.dsp b/winpcap/Examples/NETMETER/netmeter.dsp new file mode 100644 index 0000000..6588dbd --- /dev/null +++ b/winpcap/Examples/NETMETER/netmeter.dsp @@ -0,0 +1,238 @@ +# Microsoft Developer Studio Project File - Name="netmeter" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=netmeter - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "netmeter.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "netmeter.mak" CFG="netmeter - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "netmeter - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "netmeter - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "netmeter - Win32 Release" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 6 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" /d "_AFXDLL" +# ADD RSC /l 0x410 /d "NDEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 +# ADD LINK32 wsock32.lib ..\..\lib\wpcap.lib /nologo /subsystem:windows /machine:I386 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "netmeter - Win32 Debug" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 6 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" /d "_AFXDLL" +# ADD RSC /l 0x410 /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 wsock32.lib ..\..\lib\wpcap.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "netmeter - Win32 Release" +# Name "netmeter - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\CaptureThread.cpp +# End Source File +# Begin Source File + +SOURCE=.\LineColl.cpp +# End Source File +# Begin Source File + +SOURCE=.\MainFrm.cpp +# End Source File +# Begin Source File + +SOURCE=.\netmeter.cpp +# End Source File +# Begin Source File + +SOURCE=.\netmeter.rc +# End Source File +# Begin Source File + +SOURCE=.\netmeterDoc.cpp +# End Source File +# Begin Source File + +SOURCE=.\netmeterView.cpp +# End Source File +# Begin Source File + +SOURCE=.\SelectAdapter.cpp +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\Console.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Devioctl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\gnuc.h +# End Source File +# Begin Source File + +SOURCE=.\LineColl.h +# End Source File +# Begin Source File + +SOURCE=.\MainFrm.h +# End Source File +# Begin Source File + +SOURCE=.\netmeter.h +# End Source File +# Begin Source File + +SOURCE=.\netmeterDoc.h +# End Source File +# Begin Source File + +SOURCE=.\netmeterView.h +# End Source File +# Begin Source File + +SOURCE="..\..\include\Pcap-c++.h" +# End Source File +# Begin Source File + +SOURCE=.\Resource.h +# End Source File +# Begin Source File + +SOURCE=.\SelectAdapter.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\res\bitmap1.bmp +# End Source File +# Begin Source File + +SOURCE=.\res\bitmap2.bmp +# End Source File +# Begin Source File + +SOURCE=.\res\bmp00001.bmp +# End Source File +# Begin Source File + +SOURCE=.\res\cap_wizi.bmp +# End Source File +# Begin Source File + +SOURCE=.\res\ico00001.ico +# End Source File +# Begin Source File + +SOURCE=.\res\icon1.ico +# End Source File +# Begin Source File + +SOURCE=.\res\listbmp.bmp +# End Source File +# Begin Source File + +SOURCE=.\res\netmeter.ico +# End Source File +# Begin Source File + +SOURCE=.\res\netmeter.rc2 +# End Source File +# Begin Source File + +SOURCE=.\res\netmeter666.ico +# End Source File +# Begin Source File + +SOURCE=.\res\netmeterDoc.ico +# End Source File +# Begin Source File + +SOURCE=.\res\yellow.ico +# End Source File +# End Group +# End Target +# End Project diff --git a/winpcap/Examples/NETMETER/netmeter.dsw b/winpcap/Examples/NETMETER/netmeter.dsw new file mode 100644 index 0000000..39b37dd --- /dev/null +++ b/winpcap/Examples/NETMETER/netmeter.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "netmeter"=.\netmeter.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples/NETMETER/netmeter.rc b/winpcap/Examples/NETMETER/netmeter.rc new file mode 100644 index 0000000..6aa7936 --- /dev/null +++ b/winpcap/Examples/NETMETER/netmeter.rc @@ -0,0 +1,407 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral (Default) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUD) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_DEFAULT +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_CAP_WIZ BITMAP DISCARDABLE "res\\cap_wizi.bmp" +#endif // Neutral (Default) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON DISCARDABLE "res\\netmeter.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MAINFRAME MENU PRELOAD DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Select the Adapter", seladapter + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_APP_EXIT + END + POPUP "&Help" + BEGIN + MENUITEM "&About netmeter", ID_APP_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE +BEGIN + "N", ID_FILE_NEW, VIRTKEY, CONTROL + "O", ID_FILE_OPEN, VIRTKEY, CONTROL + "S", ID_FILE_SAVE, VIRTKEY, CONTROL + "Z", ID_EDIT_UNDO, VIRTKEY, CONTROL + "X", ID_EDIT_CUT, VIRTKEY, CONTROL + "C", ID_EDIT_COPY, VIRTKEY, CONTROL + "V", ID_EDIT_PASTE, VIRTKEY, CONTROL + VK_BACK, ID_EDIT_UNDO, VIRTKEY, ALT + VK_DELETE, ID_EDIT_CUT, VIRTKEY, SHIFT + VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL + VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT + VK_F6, ID_NEXT_PANE, VIRTKEY + VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 154 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About netmeter" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "NetMeter Version 2.0",IDC_STATIC,40,19,119,8, + SS_NOPREFIX + LTEXT "Copyright (C) 1999-2002 Loris Degioanni (loris@netgroup-serv.polito.it)", + IDC_STATIC,7,38,221,8 + DEFPUSHBUTTON "OK",IDOK,92,133,50,14,WS_GROUP + LTEXT "Shows the diagram of a 10Mbit Ethernet network's load in:", + IDC_STATIC,7,58,209,11 + LTEXT "This program is based on WinPcap",IDC_STATIC,7,114,111, + 8 + LTEXT "Each interval on the horizontal axis is approximately 5 seconds", + IDC_STATIC,8,100,196,8 + ICON IDR_MAINFRAME,IDC_STATIC,13,13,20,20 + CONTROL 135,IDC_STATIC,"Static",SS_BITMAP,15,71,8,7 + CONTROL 134,IDC_STATIC,"Static",SS_BITMAP,15,84,8,7 + LTEXT "Bits per second (Min=0, Max=10 mega)",IDC_STATIC,31,71, + 185,8 + LTEXT "Packets per second (Min=0, Max=14880)",IDC_STATIC,31,84, + 185,8 +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "\0" + VALUE "FileDescription", "netmeter MFC Application\0" + VALUE "FileVersion", "1, 0, 0, 1\0" + VALUE "InternalName", "netmeter\0" + VALUE "LegalCopyright", "Copyright (C) 1999\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "netmeter.EXE\0" + VALUE "ProductName", "netmeter Application\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 228 + TOPMARGIN, 7 + BOTTOMMARGIN, 147 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE PRELOAD DISCARDABLE +BEGIN + IDR_MAINFRAME "netmeter\n\nNetmet\n\n\nNetmeter.Document\nNetmet Document" +END + +STRINGTABLE PRELOAD DISCARDABLE +BEGIN + AFX_IDS_APP_TITLE "netmeter" + AFX_IDS_IDLEMESSAGE "Ready" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_INDICATOR_EXT "EXT" + ID_INDICATOR_CAPS "CAP" + ID_INDICATOR_NUM "NUM" + ID_INDICATOR_SCRL "SCRL" + ID_INDICATOR_OVR "OVR" + ID_INDICATOR_REC "REC" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_FILE_NEW "Create a new document\nNew" + ID_FILE_OPEN "Open an existing document\nOpen" + ID_FILE_CLOSE "Close the active document\nClose" + ID_FILE_SAVE "Save the active document\nSave" + ID_FILE_SAVE_AS "Save the active document with a new name\nSave As" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_APP_ABOUT "Display program information, version number and copyright\nAbout" + ID_APP_EXIT "Quit the application; prompts to save documents\nExit" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_FILE_MRU_FILE1 "Open this document" + ID_FILE_MRU_FILE2 "Open this document" + ID_FILE_MRU_FILE3 "Open this document" + ID_FILE_MRU_FILE4 "Open this document" + ID_FILE_MRU_FILE5 "Open this document" + ID_FILE_MRU_FILE6 "Open this document" + ID_FILE_MRU_FILE7 "Open this document" + ID_FILE_MRU_FILE8 "Open this document" + ID_FILE_MRU_FILE9 "Open this document" + ID_FILE_MRU_FILE10 "Open this document" + ID_FILE_MRU_FILE11 "Open this document" + ID_FILE_MRU_FILE12 "Open this document" + ID_FILE_MRU_FILE13 "Open this document" + ID_FILE_MRU_FILE14 "Open this document" + ID_FILE_MRU_FILE15 "Open this document" + ID_FILE_MRU_FILE16 "Open this document" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_NEXT_PANE "Switch to the next window pane\nNext Pane" + ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_WINDOW_SPLIT "Split the active window into panes\nSplit" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_EDIT_CLEAR "Erase the selection\nErase" + ID_EDIT_CLEAR_ALL "Erase everything\nErase All" + ID_EDIT_COPY "Copy the selection and put it on the Clipboard\nCopy" + ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut" + ID_EDIT_FIND "Find the specified text\nFind" + ID_EDIT_PASTE "Insert Clipboard contents\nPaste" + ID_EDIT_REPEAT "Repeat the last action\nRepeat" + ID_EDIT_REPLACE "Replace specific text with different text\nReplace" + ID_EDIT_SELECT_ALL "Select the entire document\nSelect All" + ID_EDIT_UNDO "Undo the last action\nUndo" + ID_EDIT_REDO "Redo the previously undone action\nRedo" +END + +STRINGTABLE DISCARDABLE +BEGIN + AFX_IDS_SCSIZE "Change the window size" + AFX_IDS_SCMOVE "Change the window position" + AFX_IDS_SCMINIMIZE "Reduce the window to an icon" + AFX_IDS_SCMAXIMIZE "Enlarge the window to full size" + AFX_IDS_SCNEXTWINDOW "Switch to the next document window" + AFX_IDS_SCPREVWINDOW "Switch to the previous document window" + AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents" +END + +STRINGTABLE DISCARDABLE +BEGIN + AFX_IDS_SCRESTORE "Restore the window to normal size" + AFX_IDS_SCTASKLIST "Activate Task List" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Italian (Italy) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA) +#ifdef _WIN32 +LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_YELL BITMAP DISCARDABLE "res\\bitmap1.bmp" +IDB_BLUE BITMAP DISCARDABLE "res\\bitmap2.bmp" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" + "#ifdef _WIN32\r\n" + "LANGUAGE 9, 1\r\n" + "#pragma code_page(1252)\r\n" + "#endif //_WIN32\r\n" + "#include ""res\\netmeter.rc2"" // non-Microsoft Visual C++ edited resources\r\n" + "#include ""afxres.rc"" // Standard components\r\n" + "#endif\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Italian (Italy) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.K.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ADAPTER DIALOG DISCARDABLE 0, 0, 186, 122 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Choose the Network Adapter" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 + CONTROL "List1",IDC_LIST1,"SysListView32",LVS_REPORT | WS_BORDER | + WS_TABSTOP,7,7,116,81 + LTEXT "Current network adapter",IDC_STATIC,7,92,164,10 + LTEXT "NONE",IDC_ADAPTER,8,106,168,12 +END + +#endif // English (U.K.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE 9, 1 +#pragma code_page(1252) +#endif //_WIN32 +#include "res\netmeter.rc2" // non-Microsoft Visual C++ edited resources +#include "afxres.rc" // Standard components +#endif + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/winpcap/Examples/NETMETER/netmeterDoc.cpp b/winpcap/Examples/NETMETER/netmeterDoc.cpp new file mode 100644 index 0000000..7461059 --- /dev/null +++ b/winpcap/Examples/NETMETER/netmeterDoc.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "stdafx.h" +#include "netmeter.h" + +#include "netmeterDoc.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CNetmeterDoc + +IMPLEMENT_DYNCREATE(CNetmeterDoc, CDocument) + +BEGIN_MESSAGE_MAP(CNetmeterDoc, CDocument) + //{{AFX_MSG_MAP(CNetmeterDoc) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CNetmeterDoc construction/destruction + +CNetmeterDoc::CNetmeterDoc() +{ +} + +CNetmeterDoc::~CNetmeterDoc() +{ +} + +BOOL CNetmeterDoc::OnNewDocument() +{ + if (!CDocument::OnNewDocument()) + return FALSE; + + return TRUE; +} + + + +///////////////////////////////////////////////////////////////////////////// +// CNetmeterDoc serialization + +void CNetmeterDoc::Serialize(CArchive& ar) +{ + if (ar.IsStoring()) + { + } + else + { + } +} + +///////////////////////////////////////////////////////////////////////////// +// CNetmeterDoc diagnostics + +#ifdef _DEBUG +void CNetmeterDoc::AssertValid() const +{ + CDocument::AssertValid(); +} + +void CNetmeterDoc::Dump(CDumpContext& dc) const +{ + CDocument::Dump(dc); +} +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CNetmeterDoc commands diff --git a/winpcap/Examples/NETMETER/netmeterDoc.h b/winpcap/Examples/NETMETER/netmeterDoc.h new file mode 100644 index 0000000..e16326d --- /dev/null +++ b/winpcap/Examples/NETMETER/netmeterDoc.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// netmeterDoc.h : interface of the CNetmeterDoc class +// +///////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_NETMETERDOC_H__3BF6CD29_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_) +#define AFX_NETMETERDOC_H__3BF6CD29_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + +class CNetmeterDoc : public CDocument +{ +protected: // create from serialization only + CNetmeterDoc(); + DECLARE_DYNCREATE(CNetmeterDoc) + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CNetmeterDoc) + public: + virtual BOOL OnNewDocument(); + virtual void Serialize(CArchive& ar); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CNetmeterDoc(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: + +// Generated message map functions +protected: + //{{AFX_MSG(CNetmeterDoc) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_NETMETERDOC_H__3BF6CD29_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_) diff --git a/winpcap/Examples/NETMETER/netmeterView.cpp b/winpcap/Examples/NETMETER/netmeterView.cpp new file mode 100644 index 0000000..5a7b56a --- /dev/null +++ b/winpcap/Examples/NETMETER/netmeterView.cpp @@ -0,0 +1,393 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include "stdafx.h" +#include "netmeter.h" + +#include "netmeterDoc.h" +#include "netmeterView.h" +#include "console.h" +#include "selectadapter.h" +#include "..\..\include\pcap.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +pcap_t *fp; +pcap_dumper_t *dumpfile; +struct _timeb OldTime; + +///////////////////////////////////////////////////////////////////////////// +// CNetmeterView + +IMPLEMENT_DYNCREATE(CNetmeterView, CView) + +BEGIN_MESSAGE_MAP(CNetmeterView, CView) + //{{AFX_MSG_MAP(CNetmeterView) + ON_COMMAND(seladapter, OnSelAdapter) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CNetmeterView construction/destruction + +CNetmeterView::CNetmeterView() +{ + //init the values + time=0; + TimeSlice=1000; + delta=5; + lastval1=0; + lastval2=0; + Adapter=""; + BytesCaptured=0; + gridpen.CreatePen(PS_SOLID,0,RGB(0,150,0)); + diagrampen1.CreatePen(PS_SOLID,0,RGB(255,255,0)); + diagrampen2.CreatePen(PS_SOLID,0,RGB(0,255,255)); + InitializeCriticalSection(&Crit); + + //begin the capture + + CString result; + if ((result=StartCapture())!=""){ + AfxMessageBox("Error initializing the capture:\n"+result); + exit(0); + } + +} + +CNetmeterView::~CNetmeterView() +{ +//stop the capture and close libpcap + StopCapture(); +} + +BOOL CNetmeterView::PreCreateWindow(CREATESTRUCT& cs) +{ + return CView::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// function that starts the capture + +CString CNetmeterView::StartCapture() +{ +char *ebuf; +char *myAdapter; +pcap_if_t *alldevs; + + + CCapPars *pars=new CCapPars; + + pars->prg=this; + + ebuf=(char*)malloc(PCAP_ERRBUF_SIZE); + + if (Adapter=="") + { + //If no adapter is defined choose the first + + /* Retrieve the device list on the local machine */ + /* Don't check for errors */ + pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, ebuf); + + myAdapter= alldevs->name; + + //open the adapter + //note: the snaplen is 1 byte because we don't need the data + //and the header of the packet, but only the length. + //Snaplen is not set to 0 because with this value the filter + //drops all the packet without copying them. Snaplen=0 can be + //used to count the packets with the minimun overhead on the system. + + if ( (fp= pcap_open((char*)myAdapter, 1, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, ebuf) ) == NULL) + { + return "PCAP error: Error opening the adapter"; + } + + pcap_freealldevs(alldevs); + } + else + { + if ( (fp= pcap_open(Adapter.GetBuffer(0), 1, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, ebuf) ) == NULL) + { + return "PCAP error: Error opening the adapter"; + } + } + + + + //this example shows a correct diagram only on 10Mbit Ethernets + if(pcap_datalink(fp)!=1/*Ether10*/) + { + AfxMessageBox("Warning: the nework adapter '"+Adapter+"' is not supported correctly by netmeter.\nNetmeter works correcly only with 10Mbit ethernet adapters."); + } + + + //set mode 1 (statistics mode). + //When set in this mode, the capture driver DOES'T capture anything. + //It only counts the packets and the number of bytes that satisfy the BPF filter, + //and returns to the application this values every Mon.delay milliseconds. + if(pcap_setmode(fp,MODE_STAT)==-1){ + pcap_close(fp); + return "PCAP error setting count mode"; + } + + + //We set a 256 bytes kernel buffer, big enough to contain the statistical summary created by the driver + if(pcap_setbuff(fp, 256)<0){ + pcap_close(fp); + return "Not enough memory to allocate the capture buffer\nTry to set a smaller buffer."; + } + + pars->fp=fp; + + //start the capture thread + thr=AfxBeginThread(MyThreadProc, pars); + if(!thr) { + pcap_close(fp); + return "Error launching the capture thread."; + } + + //get the time of the beginning of the capture + _ftime( &OldTime ); + return ""; + + +} + +///////////////////////////////////////////////////////////////////////////// +// function that stops the capture + +void CNetmeterView::StopCapture() +{ + + HANDLE thread=thr->m_hThread; + + //kill the capture thread. + BOOL res=TerminateThread(thread,0); + + if(res==false){ + AfxMessageBox("Fatal Error: cannot terminate the capture thread"); + exit(0); + } + //close the adapter + pcap_close(fp); + + //wait the end of the capture thread + WaitForSingleObject(thread,INFINITE); + +} + +///////////////////////////////////////////////////////////////////////////// +// Create a new blackboard + +void CNetmeterView::CreateBoard(CDC* pDC,CDC *DrawBuff,RECT rett) +{ + int i; + CDC dc; + + DrawBuff->CreateCompatibleDC(pDC); + + hBitmap=CreateCompatibleBitmap(*pDC,rett.right-rett.left,rett.bottom-rett.top); + DrawBuff->SelectObject(hBitmap); + + DrawBuff->FillSolidRect(0,0,rett.right-rett.left,rett.bottom-rett.top,0); + DrawBuff->SelectObject(gridpen); + + for(i=1;i<10;i++){ + DrawBuff->MoveTo(0,(rett.bottom-rett.top)*i/10); + DrawBuff->LineTo(rett.right-rett.left,(rett.bottom-rett.top)*i/10); + } + for(i=1;i<=10;i++){ + DrawBuff->MoveTo((rett.right-rett.left)*i/10-1,0); + DrawBuff->LineTo((rett.right-rett.left)*i/10-1,rett.bottom-rett.top); + } + + DrawBuff->LineTo(rett.right-rett.left,rett.bottom-rett.top); + + DrawBoard(DrawBuff,rett,0,0); + pDC->BitBlt( rett.left, rett.top, rett.right-rett.left, rett.bottom-rett.top, DrawBuff, 0, 0, SRCCOPY); + +} + +///////////////////////////////////////////////////////////////////////////// +// Scroll the blackboard and insert a new value + +void CNetmeterView::DrawBoard(CDC* pDC,RECT rett,int height1,int height2) +{ + int i; + int x,y; + + + + pDC->SelectObject(gridpen); + pDC->BitBlt( 0, 0, rett.right-rett.left, rett.bottom-rett.top, pDC, delta, 0, SRCCOPY); + pDC->FillSolidRect(rett.right-delta,0,rett.right,rett.bottom-rett.top,0); + + + + for(i=1;i<10;i++){ + pDC->MoveTo(rett.right-rett.left-delta,(rett.bottom-rett.top)*i/10); + pDC->LineTo(rett.right-rett.left,(rett.bottom-rett.top)*i/10); + } + + if(((time)*delta)/((rett.right-rett.left)/10) > ((time-1)*delta)/((rett.right-rett.left)/10)) + { + pDC->MoveTo((rett.right-rett.left)*i/10-1,0); + pDC->LineTo((rett.right-rett.left)*i/10-1,rett.bottom-rett.top); + } + + // draw the line for the new PPS + pDC->SelectObject(diagrampen2); + + x=rett.right-rett.left-delta-1; + y=rett.bottom-rett.top-lastval2*(rett.bottom-rett.top)/100-1; + pDC->MoveTo(x,y); + pDC->SetPixelV(x,y,RGB(255,255,255)); + x=rett.right-rett.left-1; + y=rett.bottom-rett.top-height2*(rett.bottom-rett.top)/100-1; + pDC->LineTo(x,y); + pDC->SetPixelV(x,y,RGB(255,255,255)); + lastval2=height2; + + // draw the line for the new BPS + pDC->SelectObject(diagrampen1); + + x=rett.right-rett.left-delta-1; + y=rett.bottom-rett.top-lastval1*(rett.bottom-rett.top)/100-1; + pDC->MoveTo(x,y); + pDC->SetPixelV(x,y,RGB(255,255,255)); + x=rett.right-rett.left-1; + y=rett.bottom-rett.top-height1*(rett.bottom-rett.top)/100-1; + pDC->LineTo(x,y); + pDC->SetPixelV(x,y,RGB(255,255,255)); + lastval1=height1; + + //redraw + if(time>0){ + Invalidate( FALSE ); + UpdateWindow(); + } + time++; +} +///////////////////////////////////////////////////////////////////////////// +// CNetmeterView drawing + +void CNetmeterView::OnDraw(CDC* pDC) +{ + CNetmeterDoc* pDoc = GetDocument(); + ASSERT_VALID(pDoc); + + CWnd* wind=pDC->GetWindow(); + wind->GetClientRect(&wrett); + + + if(time==0){ + + //write the name of the adapter in the title bar of the program's window + CWnd *pater=this->GetParent(); + CString titlestr; + CString tmpstr; + + tmpstr=Adapter.Right(12); + if(tmpstr.GetLength()==Adapter.GetLength()) + titlestr.Format("netmeter-%s",Adapter); + else + titlestr.Format("netmeter-...%s",tmpstr); + pater->SetWindowText(titlestr); + + CreateBoard(pDC,&DrawBuffer,wrett); + time++; + } + + if(time>0)pDC->BitBlt( wrett.left, wrett.top, wrett.right-wrett.left, wrett.bottom-wrett.top, &DrawBuffer, 0, 0, SRCCOPY); + +} + +///////////////////////////////////////////////////////////////////////////// +// CNetmeterView diagnostics + +#ifdef _DEBUG +void CNetmeterView::AssertValid() const +{ + CView::AssertValid(); +} + +void CNetmeterView::Dump(CDumpContext& dc) const +{ + CView::Dump(dc); +} + +CNetmeterDoc* CNetmeterView::GetDocument() // non-debug version is inline +{ + ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CNetmeterDoc))); + return (CNetmeterDoc*)m_pDocument; +} +#endif //_DEBUG + + + +void CNetmeterView::OnSelAdapter() +{ + CSelectAdapter dlg; + + //stop the current capture process + StopCapture(); + + //show the selectadapter dialog + dlg.m_Adapter=Adapter; + if (dlg.DoModal()==IDOK) Adapter=dlg.m_Adapter; + + //write the name of the adapter in the title bar of the program's window + CWnd *pater=this->GetParent(); + CString titlestr; + CString tmpstr; + + tmpstr=Adapter.Right(12); + if(tmpstr.GetLength()==Adapter.GetLength()) + titlestr.Format("netmeter-%s",Adapter); + else + titlestr.Format("netmeter-...%s",tmpstr); + pater->SetWindowText(titlestr); + + //start the new capture process + StartCapture(); +} diff --git a/winpcap/Examples/NETMETER/netmeterView.h b/winpcap/Examples/NETMETER/netmeterView.h new file mode 100644 index 0000000..42472f5 --- /dev/null +++ b/winpcap/Examples/NETMETER/netmeterView.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#if !defined(AFX_NETMETERVIEW_H__3BF6CD2B_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_) +#define AFX_NETMETERVIEW_H__3BF6CD2B_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +class CNetmeterView : public CView +{ +protected: // create from serialization only + CRITICAL_SECTION Crit; + CWinThread* thr; + CString StartCapture(); + void StopCapture(); + CNetmeterView(); + DECLARE_DYNCREATE(CNetmeterView) +// Attributes +public: + CPen gridpen; + CPen diagrampen1; + CPen diagrampen2; + UINT BytesCaptured; + int lastval1,lastval2; + CDC DrawBuffer; + int time; + int delta; + int TimeSlice; + CString Adapter; + RECT wrett; + HBITMAP hBitmap; + CNetmeterDoc* GetDocument(); + void DrawBoard(CDC* pDC,RECT rett,int height1,int height2); + void CreateBoard(CDC* pDC,CDC *DrawBuff,RECT rett); +// Operations +public: +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CNetmeterView) + public: + virtual void OnDraw(CDC* pDC); // overridden to draw this view + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + protected: + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CNetmeterView(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: + +// Generated message map functions +protected: + //{{AFX_MSG(CNetmeterView) + afx_msg void OnTimer(UINT nIDEvent); + afx_msg void OnSelAdapter(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +#ifndef _DEBUG // debug version in netmeterView.cpp +inline CNetmeterDoc* CNetmeterView::GetDocument() + { return (CNetmeterDoc*)m_pDocument; } +#endif + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_NETMETERVIEW_H__3BF6CD2B_6C2B_11D3_B76F_0080C8DF82B3__INCLUDED_) diff --git a/winpcap/Examples/NETMETER/res/BMP00001.BMP b/winpcap/Examples/NETMETER/res/BMP00001.BMP new file mode 100644 index 0000000000000000000000000000000000000000..e7a4a1db780dcec17579ad0a21d25bb5d67b8648 GIT binary patch literal 214 zcwTezy~Y3mWk9R}#5_>U$iM;?Phh|W8o-F5p#egHAdqq3zyTl)68R5C4FCT_C=dh* Qfe0wzdj|v$s7J#90An{rF#rGn literal 0 HcwPel00001 diff --git a/winpcap/Examples/NETMETER/res/bitmap1.bmp b/winpcap/Examples/NETMETER/res/bitmap1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cd338dcdcfbeefad41e26061ef28db9f3b59b416 GIT binary patch literal 214 zcwTezy~Y3mWk9R}#5_>U$iM;?Phh|W8o-F5p#egHAdqq3zyTl)68R5C4FCT_C=dh* wfe0|z+{nEf2sSt|Kn+a literal 0 HcwPel00001 diff --git a/winpcap/Examples/NETMETER/res/bitmap2.bmp b/winpcap/Examples/NETMETER/res/bitmap2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c2f29359cd569f0cbd9c926bb16a7dae6a086e0c GIT binary patch literal 214 zcwTezy~Y3mWk9R}#5_>U$iM;?Phh|W8o-F5p#egHAdqq3zyTl)68R5C4FCT_C=dh* tfe0|z+{pJ12p%{wKxhUi%><rBRpmrrvX~_654J+(YmPkr=KL zgR$M@bUK7n_iy~kcIrGlzZy_`W4~d)XGiu8TxtAk1OHgi2SQjy7Jtn1%qkJm2Z&aY zC84xeLOqgNR*Kx6mO%|=m!pX<)5QGf*&3wppIeP4<(k*i1h^bOd<}njXRUSC;fMHFUp5OM=@sIHMMiKKk-ZJwq@bp9a3La)gyCci*ocBg%3l$uN$6gKEH7N evz4=zrM&e5Mjj|a=IH|B{=6Yqr&J%#@_zv@jYZx7 literal 0 HcwPel00001 diff --git a/winpcap/Examples/NETMETER/res/listbmp.bmp b/winpcap/Examples/NETMETER/res/listbmp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..98cc5e9ad98ee303f9deedd73e9827d373f34a8a GIT binary patch literal 1318 zcwUv1y>7xV6op->742j(MMz8xRmBn{-k@UbyL76TO7WI#Me5SfAr%|2bY==u87lEA z7F`lC+}?X_r;-bbII(@O!Jm$Q!u`YTm0&$#y~Fx}RbssmmpuMy?T9oNp|v%7@IzUa z=rjUc1b{VqXo&h}YCoWM5Z5_*UifjJ1R#|>P^UM?=7-uZV{YnYfpeCHfgMoEtn}Hu z)f`~Bj_cI|V7B%=nYxVvBkY=|LKNga_9;geGm%A1BT7M~;r$#&%zHhIh-bc8vhinD z;}j5)xSrJlkzlU3S+$QN3nN^aOe zv!HRwYW)9wwjv%%XBkvB>iZkD(4z2t6L$9@fw0|csjl%x}pU=I&t$EJX EFNI4+ivR!s literal 0 HcwPel00001 diff --git a/winpcap/Examples/NETMETER/res/netmeter.ico b/winpcap/Examples/NETMETER/res/netmeter.ico new file mode 100644 index 0000000000000000000000000000000000000000..39395703677693c5bb7d92830a3149f2c172da5a GIT binary patch literal 1078 zcwWVlJB|V|42J(v0)LPzaZ1?}c1~tjJ#OJ!@=FfVe1O1MEi{EvVH6Qj4)bIcR literal 0 HcwPel00001 diff --git a/winpcap/Examples/NETMETER/resource.h b/winpcap/Examples/NETMETER/resource.h new file mode 100644 index 0000000..51107b9 --- /dev/null +++ b/winpcap/Examples/NETMETER/resource.h @@ -0,0 +1,26 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by netmeter.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_NETMETTYPE 129 +#define IDB_YELLOW 133 +#define IDB_BLUE 134 +#define IDB_YELL 135 +#define IDB_CAP_WIZ 175 +#define IDD_ADAPTER 180 +#define IDC_ADAPTER 1000 +#define IDC_LIST1 3109 +#define seladapter 32771 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 137 +#define _APS_NEXT_COMMAND_VALUE 32772 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/winpcap/Examples/PacketDriver/GetMacAddress/GetMacAddress.c b/winpcap/Examples/PacketDriver/GetMacAddress/GetMacAddress.c new file mode 100644 index 0000000..393c966 --- /dev/null +++ b/winpcap/Examples/PacketDriver/GetMacAddress/GetMacAddress.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include "..\..\..\Include\packet32.h" +#include "..\..\..\Include\ntddndis.h" + +#define Max_Num_Adapter 10 +char AdapterList[Max_Num_Adapter][1024]; + +int main() +{ + LPADAPTER lpAdapter = 0; + int i; + DWORD dwErrorCode; + char AdapterName[8192]; + char *temp,*temp1; + int AdapterNum=0,Open; + ULONG AdapterLength; + PPACKET_OID_DATA OidData; + BOOLEAN Status; + + // + // Obtain the name of the adapters installed on this machine + // + + printf("Packet.dll test application. Library version:%s\n", PacketGetVersion()); + + printf("Adapters installed:\n"); + i=0; + + AdapterLength = sizeof(AdapterName); + + if(PacketGetAdapterNames(AdapterName,&AdapterLength)==FALSE){ + printf("Unable to retrieve the list of the adapters!\n"); + return -1; + } + temp=AdapterName; + temp1=AdapterName; + + while ((*temp!='\0')||(*(temp-1)!='\0')) + { + if (*temp=='\0') + { + memcpy(AdapterList[i],temp1,temp-temp1); + temp1=temp+1; + i++; + } + temp++; + } + + AdapterNum=i; + for (i=0;iAdapterNum) printf("\nThe number must be smaller than %d",AdapterNum); + } while (Open>AdapterNum); + + + // + // Open the selected adapter + // + + lpAdapter = PacketOpenAdapter(AdapterList[Open-1]); + + if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE)) + { + dwErrorCode=GetLastError(); + printf("Unable to open the adapter, Error Code : %lx\n",dwErrorCode); + + return -1; + } + + // + // Allocate a buffer to get the MAC adress + // + + OidData = malloc(6 + sizeof(PACKET_OID_DATA)); + if (OidData == NULL) + { + printf("error allocating memory!\n"); + PacketCloseAdapter(lpAdapter); + return -1; + } + + // + // Retrieve the adapter MAC querying the NIC driver + // + + OidData->Oid = OID_802_3_CURRENT_ADDRESS; + + OidData->Length = 6; + ZeroMemory(OidData->Data, 6); + + Status = PacketRequest(lpAdapter, FALSE, OidData); + if(Status) + { + printf("The MAC address of the adapter is %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", + (PCHAR)(OidData->Data)[0], + (PCHAR)(OidData->Data)[1], + (PCHAR)(OidData->Data)[2], + (PCHAR)(OidData->Data)[3], + (PCHAR)(OidData->Data)[4], + (PCHAR)(OidData->Data)[5]); + } + else + { + printf("error retrieving the MAC address of the adapter!\n"); + } + + free(OidData); + PacketCloseAdapter(lpAdapter); + return (0); +} + diff --git a/winpcap/Examples/PacketDriver/GetMacAddress/GetMacAddress.dsp b/winpcap/Examples/PacketDriver/GetMacAddress/GetMacAddress.dsp new file mode 100644 index 0000000..1f3210e --- /dev/null +++ b/winpcap/Examples/PacketDriver/GetMacAddress/GetMacAddress.dsp @@ -0,0 +1,105 @@ +# Microsoft Developer Studio Project File - Name="GetMacAddress" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=GetMacAddress - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "GetMacAddress.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "GetMacAddress.mak" CFG="GetMacAddress - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "GetMacAddress - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "GetMacAddress - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "GetMacAddress - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "GetMacAddress - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "GetMacAddress - Win32 Release" +# Name "GetMacAddress - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\GetMacAddress.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\..\lib\Packet.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/PacketDriver/TestPacketCapture/TestPacketCapture.c b/winpcap/Examples/PacketDriver/TestPacketCapture/TestPacketCapture.c new file mode 100644 index 0000000..7944409 --- /dev/null +++ b/winpcap/Examples/PacketDriver/TestPacketCapture/TestPacketCapture.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include + + +#include "..\..\..\Include\packet32.h" +#include "..\..\..\Include\ntddndis.h" + +#define Max_Num_Adapter 10 + +// Prototypes + +void PrintPackets(LPPACKET lpPacket); + +char AdapterList[Max_Num_Adapter][1024]; + +int main() +{ +//define a pointer to an ADAPTER structure + +LPADAPTER lpAdapter = 0; + +//define a pointer to a PACKET structure + +LPPACKET lpPacket; + +int i; +DWORD dwErrorCode; + +//ascii strings +char AdapterName[8192]; // string that contains a list of the network adapters +char *temp,*temp1; + + +int AdapterNum=0,Open; +ULONG AdapterLength; + +char buffer[256000]; // buffer to hold the data coming from the driver + +struct bpf_stat stat; + + // + // Obtain the name of the adapters installed on this machine + // + printf("Packet.dll test application. Library version:%s\n", PacketGetVersion()); + + printf("Adapters installed:\n"); + i=0; + + AdapterLength = sizeof(AdapterName); + + if(PacketGetAdapterNames(AdapterName,&AdapterLength)==FALSE){ + printf("Unable to retrieve the list of the adapters!\n"); + return -1; + } + temp=AdapterName; + temp1=AdapterName; + + while ((*temp!='\0')||(*(temp-1)!='\0')) + { + if (*temp=='\0') + { + memcpy(AdapterList[i],temp1,temp-temp1); + temp1=temp+1; + i++; + } + temp++; + } + + AdapterNum=i; + for (i=0;iAdapterNum) printf("\nThe number must be smaller than %d",AdapterNum); + } while (Open>AdapterNum); + + + + + lpAdapter = PacketOpenAdapter(AdapterList[Open-1]); + + if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE)) + { + dwErrorCode=GetLastError(); + printf("Unable to open the adapter, Error Code : %lx\n",dwErrorCode); + + return -1; + } + + // set the network adapter in promiscuous mode + + if(PacketSetHwFilter(lpAdapter,NDIS_PACKET_TYPE_PROMISCUOUS)==FALSE){ + printf("Warning: unable to set promiscuous mode!\n"); + } + + // set a 512K buffer in the driver + if(PacketSetBuff(lpAdapter,512000)==FALSE){ + printf("Unable to set the kernel buffer!\n"); + return -1; + } + + // set a 1 second read timeout + if(PacketSetReadTimeout(lpAdapter,1000)==FALSE){ + printf("Warning: unable to set the read tiemout!\n"); + } + + //allocate and initialize a packet structure that will be used to + //receive the packets. + if((lpPacket = PacketAllocatePacket())==NULL){ + printf("\nError: failed to allocate the LPPACKET structure."); + return (-1); + } + PacketInitPacket(lpPacket,(char*)buffer,256000); + + //main capture loop + while(!kbhit()) + { + // capture the packets + if(PacketReceivePacket(lpAdapter,lpPacket,TRUE)==FALSE){ + printf("Error: PacketReceivePacket failed"); + return (-1); + } + + PrintPackets(lpPacket); + } + + + //print the capture statistics + if(PacketGetStats(lpAdapter,&stat)==FALSE){ + printf("Warning: unable to get stats from the kernel!\n"); + } + else + printf("\n\n%d packets received.\n%d Packets lost",stat.bs_recv,stat.bs_drop); + + PacketFreePacket(lpPacket); + + // close the adapter and exit + + PacketCloseAdapter(lpAdapter); + return (0); +} + +// this function prints the content of a block of packets received from the driver + +void PrintPackets(LPPACKET lpPacket) +{ + + ULONG i, j, ulLines, ulen, ulBytesReceived; + char *pChar, *pLine, *base; + char *buf; + u_int off=0; + u_int tlen,tlen1; + struct bpf_hdr *hdr; + + ulBytesReceived = lpPacket->ulBytesReceived; + + + buf = lpPacket->Buffer; + + off=0; + + while(offbh_datalen; + tlen=hdr->bh_caplen; + printf("Packet length, captured portion: %ld, %ld\n", tlen1, tlen); + off+=hdr->bh_hdrlen; + + ulLines = (tlen + 15) / 16; + + pChar =(char*)(buf+off); + base=pChar; + off=Packet_WORDALIGN(off+tlen); + + for ( i=0; i 16 ) ? 16 : ulen; + tlen -= ulen; + + for ( j=0; j +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=TestPacketCapture - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "TestPacketCapture.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "TestPacketCapture.mak" CFG="TestPacketCapture - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "TestPacketCapture - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "TestPacketCapture - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "TestPacketCapture - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "TestPacketCapture - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "TestPacketCapture - Win32 Release" +# Name "TestPacketCapture - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\TestPacketCapture.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\..\lib\Packet.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/PacketDriver/TestPacketSend/TestPacketSend.c b/winpcap/Examples/PacketDriver/TestPacketSend/TestPacketSend.c new file mode 100644 index 0000000..ea3f6e8 --- /dev/null +++ b/winpcap/Examples/PacketDriver/TestPacketSend/TestPacketSend.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include "..\..\..\Include\packet32.h" + + +#define Max_Num_Adapter 10 + +// Prototypes + +void PrintPackets(LPPACKET lpPacket); + +char AdapterList[Max_Num_Adapter][8192]; + + + +int main(int argc, char **argv) +{ +char packetbuff[5000]; + +// define a pointer to a ADAPTER structure + +LPADAPTER lpAdapter = 0; + +// define a pointer to a PACKET structure + +LPPACKET lpPacket; + +int i,npacks,Snaplen; +DWORD dwErrorCode; + +//ascii strings +char AdapterName[8192]; // string that contains a list of the network adapters +char *temp,*temp1; + +int AdapterNum=0,Open; +ULONG AdapterLength; + +float cpu_time; + + printf("Traffic Generator v 0.9999\nCopyright 1999 Loris Degioanni (loris@netgroup-serv.polito.it)"); + printf("\nSends a set of packets to the network using packet.dll API.\n"); + + if (argc == 1){ + printf("\n\n Usage: TestpacketSend [-i adapter] -n npacks -s size"); + printf("\n size is between 60 and 1514\n\n"); + return -1; + } + + + AdapterName[0]=0; + + //get the command line parameters + for(i=1;iAdapterNum) printf("\nThe number must be smaller than %d",AdapterNum); + } while (Open>AdapterNum); + + + + + lpAdapter = PacketOpenAdapter(AdapterList[Open-1]); + + if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE)) + { + dwErrorCode=GetLastError(); + printf("Unable to open the driver, Error Code : %lx\n",dwErrorCode); + + return(-1); + } + + } + else{ + + lpAdapter = PacketOpenAdapter(AdapterName); + + if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE)) + { + dwErrorCode=GetLastError(); + printf("Unable to open the driver, Error Code : %lx\n",dwErrorCode); + + return(-1); + } + + } + + if((lpPacket = PacketAllocatePacket())==NULL){ + printf("\nError:failed to allocate the LPPACKET structure."); + return (-1); + } + + packetbuff[0]=1; + packetbuff[1]=1; + packetbuff[2]=1; + packetbuff[3]=1; + packetbuff[4]=1; + packetbuff[5]=1; + + packetbuff[6]=2; + packetbuff[7]=2; + packetbuff[8]=2; + packetbuff[9]=2; + packetbuff[10]=2; + packetbuff[11]=2; + + for(i=12;i<1514;i++){ + packetbuff[i]=i%256; + } + + PacketInitPacket(lpPacket,packetbuff,Snaplen); + // capture the packet + + + if(PacketSetNumWrites(lpAdapter,npacks)==FALSE){ + printf("warning: Unable to send more than one packet in a single write!\n"); + } + + printf("\n\nGenerating %d packets...",npacks); + + cpu_time = (float)clock (); + + if(PacketSendPacket(lpAdapter,lpPacket,TRUE)==FALSE){ + printf("Error sending the packets!\n"); + return -1; + } + + cpu_time = (clock() - cpu_time)/CLK_TCK; + + printf ("\n\nElapsed time: %5.3f\n", cpu_time); + printf ("\nTotal packets generated = %d", npacks); + printf ("\nTotal bytes generated = %d", (Snaplen+24)*npacks); + printf ("\nTotal bits generated = %d", (Snaplen+24)*npacks*8); + printf ("\nAverage packets per second = %d", (int)((double)npacks/cpu_time)); + printf ("\nAverage bytes per second = %d", (int)((double)((Snaplen+24)*npacks)/cpu_time)); + printf ("\nAverage bits per second = %d", (int)((double)((Snaplen+24)*npacks*8)/cpu_time)); + printf ("\n"); + + PacketFreePacket(lpPacket); + + // close the adapter and exit + + PacketCloseAdapter(lpAdapter); + return (0); +} diff --git a/winpcap/Examples/PacketDriver/TestPacketSend/TestPacketSend.dsp b/winpcap/Examples/PacketDriver/TestPacketSend/TestPacketSend.dsp new file mode 100644 index 0000000..7228a8d --- /dev/null +++ b/winpcap/Examples/PacketDriver/TestPacketSend/TestPacketSend.dsp @@ -0,0 +1,107 @@ +# Microsoft Developer Studio Project File - Name="TestPacketSend" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=TestPacketSend - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "TestPacketSend.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "TestPacketSend.mak" CFG="TestPacketSend - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "TestPacketSend - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "TestPacketSend - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "TestPacketSend - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:"Release/TestPacketSend.exe" /machine:I386 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "TestPacketSend - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "TestPacketSend - Win32 Release" +# Name "TestPacketSend - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\TestPacketSend.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\..\lib\Packet.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/PacketDriver/readme.txt b/winpcap/Examples/PacketDriver/readme.txt new file mode 100644 index 0000000..8937c43 --- /dev/null +++ b/winpcap/Examples/PacketDriver/readme.txt @@ -0,0 +1,2 @@ +These files use the packet.dll API instead of wpcap.dll. +The use of packet.dll API is strongly discouraged. diff --git a/winpcap/Examples/UDPdump/UDPdump.dsp b/winpcap/Examples/UDPdump/UDPdump.dsp new file mode 100644 index 0000000..40e3806 --- /dev/null +++ b/winpcap/Examples/UDPdump/UDPdump.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="UDPdump" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=UDPdump - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "UDPdump.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "UDPdump.mak" CFG="UDPdump - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "UDPdump - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "UDPdump - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "UDPdump - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "UDPdump - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "UDPdump - Win32 Release" +# Name "UDPdump - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\udpdump.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/UDPdump/UDPdump.dsw b/winpcap/Examples/UDPdump/UDPdump.dsw new file mode 100644 index 0000000..0def709 --- /dev/null +++ b/winpcap/Examples/UDPdump/UDPdump.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "UDPdump"=.\UDPdump.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples/UDPdump/udpdump.c b/winpcap/Examples/UDPdump/udpdump.c new file mode 100644 index 0000000..1d621d7 --- /dev/null +++ b/winpcap/Examples/UDPdump/udpdump.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "pcap.h" + +/* 4 bytes IP address */ +typedef struct ip_address{ + u_char byte1; + u_char byte2; + u_char byte3; + u_char byte4; +}ip_address; + +/* IPv4 header */ +typedef struct ip_header{ + u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits) + u_char tos; // Type of service + u_short tlen; // Total length + u_short identification; // Identification + u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits) + u_char ttl; // Time to live + u_char proto; // Protocol + u_short crc; // Header checksum + ip_address saddr; // Source address + ip_address daddr; // Destination address + u_int op_pad; // Option + Padding +}ip_header; + +/* UDP header*/ +typedef struct udp_header{ + u_short sport; // Source port + u_short dport; // Destination port + u_short len; // Datagram length + u_short crc; // Checksum +}udp_header; + +/* prototype of the packet handler */ +void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); + + +main() +{ +pcap_if_t *alldevs; +pcap_if_t *d; +int inum; +int i=0; +pcap_t *adhandle; +char errbuf[PCAP_ERRBUF_SIZE]; +u_int netmask; +char packet_filter[] = "ip and udp"; +struct bpf_program fcode; + + /* Retrieve the device list */ + if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. %s", ++i, d->name); + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if(i==0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return -1; + } + + printf("Enter the interface number (1-%d):",i); + scanf("%d", &inum); + + if(inum < 1 || inum > i) + { + printf("\nInterface number out of range.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Jump to the selected adapter */ + for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); + + /* Open the adapter */ + if ( (adhandle= pcap_open(d->name, // name of the device + 65536, // portion of the packet to capture. + // 65536 grants that the whole packet will be captured on all the MACs. + PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode + 1000, // read timeout + NULL, // remote authentication + errbuf // error buffer + ) ) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Check the link layer. We support only Ethernet for simplicity. */ + if(pcap_datalink(adhandle) != DLT_EN10MB) + { + fprintf(stderr,"\nThis program works only on Ethernet networks.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + if(d->addresses != NULL) + /* Retrieve the mask of the first address of the interface */ + netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; + else + /* If the interface is without addresses we suppose to be in a C class network */ + netmask=0xffffff; + + + //compile the filter + if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 ) + { + fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + //set the filter + if (pcap_setfilter(adhandle, &fcode)<0) + { + fprintf(stderr,"\nError setting the filter.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + printf("\nlistening on %s...\n", d->description); + + /* At this point, we don't need any more the device list. Free it */ + pcap_freealldevs(alldevs); + + /* start the capture */ + pcap_loop(adhandle, 0, packet_handler, NULL); + + return 0; +} + +/* Callback function invoked by libpcap for every incoming packet */ +void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + struct tm *ltime; + char timestr[16]; + ip_header *ih; + udp_header *uh; + u_int ip_len; + u_short sport,dport; + time_t local_tv_sec; + + /* convert the timestamp to readable format */ + local_tv_sec = header->ts.tv_sec; + ltime=localtime(&local_tv_sec); + strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); + + /* print timestamp and length of the packet */ + printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len); + + /* retireve the position of the ip header */ + ih = (ip_header *) (pkt_data + + 14); //length of ethernet header + + /* retireve the position of the udp header */ + ip_len = (ih->ver_ihl & 0xf) * 4; + uh = (udp_header *) ((u_char*)ih + ip_len); + + /* convert from network byte order to host byte order */ + sport = ntohs( uh->sport ); + dport = ntohs( uh->dport ); + + /* print ip addresses and udp ports */ + printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n", + ih->saddr.byte1, + ih->saddr.byte2, + ih->saddr.byte3, + ih->saddr.byte4, + sport, + ih->daddr.byte1, + ih->daddr.byte2, + ih->daddr.byte3, + ih->daddr.byte4, + dport); +} \ No newline at end of file diff --git a/winpcap/Examples/UserLevelBridge/UserBridge.c b/winpcap/Examples/UserLevelBridge/UserBridge.c new file mode 100644 index 0000000..d0ffa1b --- /dev/null +++ b/winpcap/Examples/UserLevelBridge/UserBridge.c @@ -0,0 +1,466 @@ +/* + * Copyright (c) 2005 - 2006 + * CACE Technologies, Davis, CA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of CACE Technologies nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * This simple program implements a user-level bridge. + * It opens two adapters specified by the user and starts two threads. + * The first thread receives packets from adapter 1 and sends them down to + * adapter 2. The second thread does the same, but in the opposite + * direction. + */ + +#include +#include "pcap.h" + +/* Storage data structure used to pass parameters to the threads */ +typedef struct _in_out_adapters +{ + unsigned int state; /* Some simple state information */ + pcap_t *input_adapter; + pcap_t *output_adapter; +}in_out_adapters; + +/* Prototypes */ +DWORD WINAPI CaptureAndForwardThread(LPVOID lpParameter); +void ctrlc_handler(int sig); + +/* This prevents the two threads to mess-up when they do printfs */ +CRITICAL_SECTION print_cs; + +/* Thread handlers. Global because we wait on the threads from the CTRL+C handler */ +HANDLE threads[2]; + +/* This global variable tells the forwarder threads they must terminate */ +volatile int kill_forwaders = 0; + + +/*******************************************************************/ + +int main() +{ + pcap_if_t *alldevs; + pcap_if_t *d; + int inum1, inum2; + int i=0; + pcap_t *adhandle1, *adhandle2; + char errbuf[PCAP_ERRBUF_SIZE]; + u_int netmask1, netmask2; + char packet_filter[256]; + struct bpf_program fcode; + in_out_adapters couple0, couple1; + + /* + * Retrieve the device list + */ + + if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. ", ++i); + if (d->description) + printf("%s\n", d->description); + else + printf("\n"); + } + + if(i==0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return -1; + } + + + /* + * Get input from the user + */ + + /* Get the filter*/ + printf("\nSpecify filter (hit return for no filter):"); + + gets(packet_filter); + if(strcmp(packet_filter, "") == 0) + { + sprintf(packet_filter, ""); + } + + /* Get the first interface number*/ + printf("\nEnter the number of the first interface to use (1-%d):",i); + scanf("%d", &inum1); + + if(inum1 < 1 || inum1 > i) + { + printf("\nInterface number out of range.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Get the second interface number*/ + printf("Enter the number of the first interface to use (1-%d):",i); + scanf("%d", &inum2); + + if(inum2 < 1 || inum2 > i) + { + printf("\nInterface number out of range.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + if(inum1 == inum2 ) + { + printf("\nCannot bridge packets on the same interface.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + + /* + * Open the specified couple of adapters + */ + + /* Jump to the first selected adapter */ + for(d = alldevs, i = 0; i< inum1 - 1 ;d = d->next, i++); + + /* + * Open the first adapter. + * *NOTICE* the flags we are using, they are important for the behavior of the prgram: + * - PCAP_OPENFLAG_PROMISCUOUS: tells the adapter to go in promiscuous mode. + * This means that we are capturing all the traffic, not only the one to or from + * this machine. + * - PCAP_OPENFLAG_NOCAPTURE_LOCAL: prevents the adapter from capturing again the packets + * transmitted by itself. This avoids annoying loops. + * - PCAP_OPENFLAG_MAX_RESPONSIVENESS: configures the adapter to provide minimum latency, + * at the cost of higher CPU usage. + */ + if((adhandle1 = pcap_open(d->name, // name of the device + 65536, // portion of the packet to capture. + // 65536 grants that the whole packet will be captured on every link layer. + PCAP_OPENFLAG_PROMISCUOUS | // flags. We specify that we don't want to capture loopback packets, and that the driver should deliver us the packets as fast as possible + PCAP_OPENFLAG_NOCAPTURE_LOCAL | + PCAP_OPENFLAG_MAX_RESPONSIVENESS, + 500, // read timeout + NULL, // remote authentication + errbuf // error buffer + )) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->description); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + if(d->addresses != NULL) + { + /* Retrieve the mask of the first address of the interface */ + netmask1 = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; + } + else + { + /* If the interface is without addresses we suppose to be in a C class network */ + netmask1 = 0xffffff; + } + + /* Jump to the second selected adapter */ + for(d = alldevs, i = 0; i< inum2 - 1 ;d = d->next, i++); + + /* Open the second adapter */ + if((adhandle2 = pcap_open(d->name, // name of the device + 65536, // portion of the packet to capture. + // 65536 grants that the whole packet will be captured on every link layer. + PCAP_OPENFLAG_PROMISCUOUS | // flags. We specify that we don't want to capture loopback packets, and that the driver should deliver us the packets as fast as possible + PCAP_OPENFLAG_NOCAPTURE_LOCAL | + PCAP_OPENFLAG_MAX_RESPONSIVENESS, + 500, // read timeout + NULL, // remote authentication + errbuf // error buffer + )) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->description); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + if(d->addresses != NULL) + { + /* Retrieve the mask of the first address of the interface */ + netmask2 = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; + } + else + { + /* If the interface is without addresses we suppose to be in a C class network */ + netmask2 = 0xffffff; + } + + + /* + * Compile and set the filters + */ + + /* compile the filter for the first adapter */ + if (pcap_compile(adhandle1, &fcode, packet_filter, 1, netmask1) <0 ) + { + fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n"); + + /* Close the adapters */ + pcap_close(adhandle1); + pcap_close(adhandle2); + + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* set the filter for the first adapter*/ + if (pcap_setfilter(adhandle1, &fcode)<0) + { + fprintf(stderr,"\nError setting the filter.\n"); + + /* Close the adapters */ + pcap_close(adhandle1); + pcap_close(adhandle2); + + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* compile the filter for the second adapter */ + if (pcap_compile(adhandle2, &fcode, packet_filter, 1, netmask2) <0 ) + { + fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n"); + + /* Close the adapters */ + pcap_close(adhandle1); + pcap_close(adhandle2); + + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* set the filter for the second adapter*/ + if (pcap_setfilter(adhandle2, &fcode)<0) + { + fprintf(stderr,"\nError setting the filter.\n"); + + /* Close the adapters */ + pcap_close(adhandle1); + pcap_close(adhandle2); + + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* At this point, we don't need the device list any more. Free it */ + pcap_freealldevs(alldevs); + + /* + * Start the threads that will forward the packets + */ + + /* Initialize the critical section that will be used by the threads for console output */ + InitializeCriticalSection(&print_cs); + + /* Init input parameters of the threads */ + couple0.state = 0; + couple0.input_adapter = adhandle1; + couple0.output_adapter = adhandle2; + couple1.state = 1; + couple1.input_adapter = adhandle2; + couple1.output_adapter = adhandle1; + + /* Start first thread */ + if((threads[0] = CreateThread( + NULL, + 0, + CaptureAndForwardThread, + &couple0, + 0, + NULL)) == NULL) + { + fprintf(stderr, "error creating the first forward thread"); + + /* Close the adapters */ + pcap_close(adhandle1); + pcap_close(adhandle2); + + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Start second thread */ + if((threads[1] = CreateThread( + NULL, + 0, + CaptureAndForwardThread, + &couple1, + 0, + NULL)) == NULL) + { + fprintf(stderr, "error creating the second forward thread"); + + /* Kill the first thread. Not very gentle at all...*/ + TerminateThread(threads[0], 0); + + /* Close the adapters */ + pcap_close(adhandle1); + pcap_close(adhandle2); + + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* + * Install a CTRL+C handler that will do the cleanups on exit + */ + signal(SIGINT, ctrlc_handler); + + /* + * Done! + * Wait for the Greek calends... + */ + printf("\nStart bridging the two adapters...\n", d->description); + Sleep(INFINITE); + return 0; +} + +/******************************************************************* + * Forwarding thread. + * Gets the packets from the input adapter and sends them to the output one. + *******************************************************************/ +DWORD WINAPI CaptureAndForwardThread(LPVOID lpParameter) +{ + struct pcap_pkthdr *header; + const u_char *pkt_data; + int res; + in_out_adapters* ad_couple = lpParameter; + unsigned int n_fwd = 0; + + /* + * Loop receiving packets from the first input adapter + */ + + while((!kill_forwaders) && (res = pcap_next_ex(ad_couple->input_adapter, &header, &pkt_data)) >= 0) + { + if(res != 0) /* Note: res=0 means "read timeout elapsed"*/ + { + /* + * Print something, just to show when we have activity. + * BEWARE: acquiring a critical section and printing strings with printf + * is something inefficient that you seriously want to avoid in your packet loop! + * However, since this is a *sample program*, we privilege visual output to efficiency. + */ + EnterCriticalSection(&print_cs); + + if(ad_couple->state == 0) + printf(">> Len: %u\n", header->caplen); + else + printf("<< Len: %u\n", header->caplen); + + LeaveCriticalSection(&print_cs); + + /* + * Send the just received packet to the output adaper + */ + if(pcap_sendpacket(ad_couple->output_adapter, pkt_data, header->caplen) != 0) + { + EnterCriticalSection(&print_cs); + + printf("Error sending a %u bytes packets on interface %u: %s\n", + header->caplen, + ad_couple->state, + pcap_geterr(ad_couple->output_adapter)); + + LeaveCriticalSection(&print_cs); + } + else + { + n_fwd++; + } + } + } + + /* + * We're out of the main loop. Check the reason. + */ + if(res < 0) + { + EnterCriticalSection(&print_cs); + + printf("Error capturing the packets: %s\n", pcap_geterr(ad_couple->input_adapter)); + fflush(stdout); + + LeaveCriticalSection(&print_cs); + } + else + { + EnterCriticalSection(&print_cs); + + printf("End of bridging on interface %u. Forwarded packets:%u\n", + ad_couple->state, + n_fwd); + fflush(stdout); + + LeaveCriticalSection(&print_cs); + } + + return 0; +} + +/******************************************************************* + * CTRL+C hanlder. + * We order the threads to die and then we patiently wait for their + * suicide. + *******************************************************************/ +void ctrlc_handler(int sig) +{ + kill_forwaders = 1; + + WaitForMultipleObjects(2, + threads, + TRUE, /* Wait for all the handles */ + 5000); /* Timeout */ + + exit(0); +} \ No newline at end of file diff --git a/winpcap/Examples/UserLevelBridge/UserBridge.dsp b/winpcap/Examples/UserLevelBridge/UserBridge.dsp new file mode 100644 index 0000000..da652d7 --- /dev/null +++ b/winpcap/Examples/UserLevelBridge/UserBridge.dsp @@ -0,0 +1,106 @@ +# Microsoft Developer Studio Project File - Name="UserBridge" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=UserBridge - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "UserBridge.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "UserBridge.mak" CFG="UserBridge - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "UserBridge - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "UserBridge - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "UserBridge - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "UserBridge - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "UserBridge - Win32 Release" +# Name "UserBridge - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\UserBridge.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/UserLevelBridge/UserBridge.dsw b/winpcap/Examples/UserLevelBridge/UserBridge.dsw new file mode 100644 index 0000000..d656a86 --- /dev/null +++ b/winpcap/Examples/UserLevelBridge/UserBridge.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "UserBridge"=.\UserBridge.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples/iflist/iflist.c b/winpcap/Examples/iflist/iflist.c new file mode 100644 index 0000000..69fdf01 --- /dev/null +++ b/winpcap/Examples/iflist/iflist.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "pcap.h" + +#ifndef WIN32 + #include + #include +#else + #include +#endif + + +// Function prototypes +void ifprint(pcap_if_t *d); +char *iptos(u_long in); +char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen); + + +int main() +{ + pcap_if_t *alldevs; + pcap_if_t *d; + char errbuf[PCAP_ERRBUF_SIZE+1]; + char source[PCAP_ERRBUF_SIZE+1]; + + printf("Enter the device you want to list:\n" + "rpcap:// ==> lists interfaces in the local machine\n" + "rpcap://hostname:port ==> lists interfaces in a remote machine\n" + " (rpcapd daemon must be up and running\n" + " and it must accept 'null' authentication)\n" + "file://foldername ==> lists all pcap files in the give folder\n\n" + "Enter your choice: "); + + fgets(source, PCAP_ERRBUF_SIZE, stdin); + source[PCAP_ERRBUF_SIZE] = '\0'; + + /* Retrieve the interfaces list */ + if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf); + exit(1); + } + + /* Scan the list printing every entry */ + for(d=alldevs;d;d=d->next) + { + ifprint(d); + } + + pcap_freealldevs(alldevs); + + return 1; +} + + + +/* Print all the available information on the given interface */ +void ifprint(pcap_if_t *d) +{ + pcap_addr_t *a; + char ip6str[128]; + + /* Name */ + printf("%s\n",d->name); + + /* Description */ + if (d->description) + printf("\tDescription: %s\n",d->description); + + /* Loopback Address*/ + printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no"); + + /* IP addresses */ + for(a=d->addresses;a;a=a->next) { + printf("\tAddress Family: #%d\n",a->addr->sa_family); + + switch(a->addr->sa_family) + { + case AF_INET: + printf("\tAddress Family Name: AF_INET\n"); + if (a->addr) + printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr)); + if (a->netmask) + printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr)); + if (a->broadaddr) + printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr)); + if (a->dstaddr) + printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr)); + break; + + case AF_INET6: + printf("\tAddress Family Name: AF_INET6\n"); + if (a->addr) + printf("\tAddress: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str))); + break; + + default: + printf("\tAddress Family Name: Unknown\n"); + break; + } + } + printf("\n"); +} + + + +/* From tcptraceroute, convert a numeric IP address to a string */ +#define IPTOSBUFFERS 12 +char *iptos(u_long in) +{ + static char output[IPTOSBUFFERS][3*4+3+1]; + static short which; + u_char *p; + + p = (u_char *)∈ + which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1); + sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + return output[which]; +} + +char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen) +{ + socklen_t sockaddrlen; + + #ifdef WIN32 + sockaddrlen = sizeof(struct sockaddr_in6); + #else + sockaddrlen = sizeof(struct sockaddr_storage); + #endif + + + if(getnameinfo(sockaddr, + sockaddrlen, + address, + addrlen, + NULL, + 0, + NI_NUMERICHOST) != 0) address = NULL; + + return address; +} + + diff --git a/winpcap/Examples/iflist/iflist.dsp b/winpcap/Examples/iflist/iflist.dsp new file mode 100644 index 0000000..b1a8c8c --- /dev/null +++ b/winpcap/Examples/iflist/iflist.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="iflist" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=iflist - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "iflist.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "iflist.mak" CFG="iflist - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "iflist - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "iflist - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "iflist - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "iflist - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "iflist - Win32 Release" +# Name "iflist - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\iflist.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/iflist/iflist.dsw b/winpcap/Examples/iflist/iflist.dsw new file mode 100644 index 0000000..6bd686d --- /dev/null +++ b/winpcap/Examples/iflist/iflist.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "iflist"=.\iflist.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples/kdump/kdump.c b/winpcap/Examples/kdump/kdump.c new file mode 100644 index 0000000..aaadf56 --- /dev/null +++ b/winpcap/Examples/kdump/kdump.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include + +#error At the moment the kernel dump feature is not supported in the driver + +main(int argc, char **argv) { + + pcap_if_t *alldevs, *d; + pcap_t *fp; + u_int inum, i=0; + char errbuf[PCAP_ERRBUF_SIZE]; + + printf("kdump: saves the network traffic to file using WinPcap kernel-level dump faeature.\n"); + printf("\t Usage: %s [adapter] | dump_file_name max_size max_packs\n", argv[0]); + printf("\t Where: max_size is the maximum size that the dump file will reach (0 means no limit)\n"); + printf("\t Where: max_packs is the maximum number of packets that will be saved (0 means no limit)\n\n"); + + + if(argc < 5){ + + /* The user didn't provide a packet source: Retrieve the device list */ + if (pcap_findalldevs(&alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. %s", ++i, d->name); + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if(i==0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return -1; + } + + printf("Enter the interface number (1-%d):",i); + scanf("%d", &inum); + + if(inum < 1 || inum > i) + { + printf("\nInterface number out of range.\n"); + /* Free the device list */ + return -1; + } + + /* Jump to the selected adapter */ + for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); + + /* Open the device */ + if ( (fp = pcap_open_live(d->name, 100, 1, 20, errbuf) ) == NULL) + { + fprintf(stderr,"\nError opening adapter\n"); + return -1; + } + + /* Free the device list */ + pcap_freealldevs(alldevs); + + /* Start the dump */ + if(pcap_live_dump(fp, argv[1], atoi(argv[2]), atoi(argv[3]))==-1){ + printf("Unable to start the dump, %s\n", pcap_geterr(fp)); + return -1; + } + } + else{ + + /* Open the device */ + if ( (fp= pcap_open_live(argv[1], 100, 1, 20, errbuf) ) == NULL) + { + fprintf(stderr,"\nError opening adapter\n"); + return -1; + } + + /* Start the dump */ + if(pcap_live_dump(fp, argv[0], atoi(argv[1]), atoi(argv[2]))==-1){ + printf("Unable to start the dump, %s\n", pcap_geterr(fp)); + return -1; + } + } + + /* Wait until the dump finishes, i.e. when max_size or max_packs is reached*/ + pcap_live_dump_ended(fp, TRUE); + + /* Close the adapter, so that the file is correctly flushed */ + pcap_close(fp); + + return 0; +} diff --git a/winpcap/Examples/kdump/kdump.dsp b/winpcap/Examples/kdump/kdump.dsp new file mode 100644 index 0000000..9506ebb --- /dev/null +++ b/winpcap/Examples/kdump/kdump.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="kdump" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=kdump - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "kdump.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "kdump.mak" CFG="kdump - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "kdump - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "kdump - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "kdump - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "kdump - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "kdump - Win32 Release" +# Name "kdump - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\kdump.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/kdump/kdump.dsw b/winpcap/Examples/kdump/kdump.dsw new file mode 100644 index 0000000..bcd2f3e --- /dev/null +++ b/winpcap/Examples/kdump/kdump.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "kdump"=.\kdump.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples/kdump/kdump.exe b/winpcap/Examples/kdump/kdump.exe new file mode 100644 index 0000000000000000000000000000000000000000..06d1fc22fbfe176d5448ea70470d100e13bc300d GIT binary patch literal 32768 zcwX&&4Ompywdfw^3>;wKj0%w$O~#11F&ImNCXmrM1O_p2%pfu&Q9vp~V1hv59Dfop zV-C~D;baxaZ(bT}a%-D@@8;d6);2Z)$ATs{@$cT!=+|ItlS2+oFd7&Ga^70| zoI%J>U*G%gd*Aoo_28bp&)RFRz4qFBuf5jZdq(#odx)73!a&e8LJkuBagzV}a{@x@ zEx$}9uO|Lx{z224-^^cMSKn%HZfSb7rFyGH)I zm!za5Wg0YYvZT+cs(E5{Ed2b5=GB!DpW7jabjlCy$GeH6}B8`JW$J5rYj7&XjD5hfFfrux07+VS})l=s=tP&KPB4F?qqj zgU3uiZN|H85^f{co)>BeSx){BJevtQ`WLd7@ctb<#5b%ZIzt{ZoiTXqKxIiwO*LOl zNR%ad+b3mk?Qz1tB{~|}0EI}if!F*6yl!&+x&B;#u0PkG>(BM)`g8rc{#<{qKi8lC zC!XCytcj3Pudi-#i<9JN%E#dO%Fkum0Vb{4mlbBkLsXoN($XpC~ z;*qrQn#?pYYANBu4*?*&KGU{NvBY5(D@HZp=5S$Vnx}3q6s+rpdX(qQm}d=`ls5oN z<}pgrSO<$owW`XEyN_T4Bfh#lm^Fi;+-0n*dm3LSu$5~v?cx!ec*WGR!|~2`UM|eE zt_~gBW|7HiVNCWg*tU{DTEG;jS*P5AC5EBJP~|Okd~>WpzcCs+wN9kuQ9c1F%MV#g zly73uQfLwDS*Prza$`Jl0pn2{>paK}Z~h|Raw!w5`d`SGSH14bsxDwXN;+2f5QEi} zC$aFNooPNNktd6k<0#j9|%m^G*STBf$Jd$W^h z3lGuHgY@%N`uPg|{0aTs51*xFUZ30s!(>I;b|*3I;b9Az<8DK>I9Pa>V=!d0R{@EgqeQ| zZz?*01=M%Mt9Qx~A#Sw4s|T*}Hy^lK_=C z?L=J~N}5IKybbNIWAK&W>l?ZhBLNa1K*Fk|>+(T>i2@h{;0u_l@>Y1Ba1vn#R;H!j z4ifQb>6s9TZJAb5DsRe6lUA$&l+Jm@h`4;ON9W;IIb{u`yy0(*JBC|k$?-a0;zx{Q z8KSiQxw6iVOl2TbcMz0D-R%g-M8J&{5IVb2uwm5_WkXB1L(NqYFHAkw0j##BOw#RT z)IV27%H$!hPZL<>`zbi=!Y-Rf6RZf>kV*)|a@4EXQn7s*avz8_ve$`R2GT;^l|sTn z0wYO{cl5R=$i4e8C%|}=Q?r4WeYXd(UFE`j=sjr}<|)6Jmca(*DBEFlmFFBgh}|Nm zV~)hk5WDSS53_1cpA!CZN?F-Hb9{<|H+HQImRVq=guZLpD&Sl3&r%vjHRLRM#0P-46B1M|Yps z06|Kb3vWH=S@WAxN(Lqs+rBi214McFW@t4q&IaZx|A-wY`p1bfoCXq4UkudtWr84- z(Yb`|+W;k$7v>P6`~kXHdGM;H?ac<*zNJs#&{}pocJs1K#G3t?rok|jTo*jb!+o+~VO;N(c5*A%SeQ-l5q z(&--WbX^U^sfj`VRnqAi512ND-ASMaK}aQ@uxs1{OUEHQ_Q_ljSKP4(_j6a$0+;nz z}tob`3ZOBLfC-BQJIuH$?n43lkSDi%;^Mq3Yb>k7>g;qTGh z<33>C=TR0Wq0|8xV(vhZsmP<0-%6DQ%)(RyvI-#O>PNx*7jmKBvB=L`5EKZ55I%u$ z5yFSCYzO^gM5?$TRSZZKmwR28Oi~4CzDiTk6y_p01M4TIGZ&%Ep~9RgyDn?4fiM#c z7Z#k5T$fe9IJWl5`}s<7><<2Jajb}6FOIF|lfy0EbdPB&)9V^D z$rV=aK#usfU7To?gd_az;=~p{O`Ldw=Ri^6Xi3$8ZJ9 zd>E@7MSea$R>w3p`LQo!bLM1itj?zT8qUvBr3I)Uhvns5$B0GmTQ1~=l;%1fyp4oI z*k>N@b=M_LI8zME_>LV;oVtUH00%~tkfgaT_qhh3bLgnu1*7ys(;K$~M}x^|hxLj| zGuN>XhmvCEIuyVwF6KJE8v{g83oB+mlRIE`xQ4jUN+3MpR&`DyXd1f?!Q>b`$V{z4 zZnv(I+O5Hrm0akDD9*m{4%6U2P%&o-w?bnDD;-1ey{?NUb%rq;>MWB|8_VWGt~k2B zW6oMVCpfkPGWo9s$2RbHh!Z>dTod5)ml( z1BJj2^_?m5u!B5;Zbb{&!>;E7#G`0)b?dYJ$P+?paAk#%_^%bKdR;%XtLCn{_np{2pF03X<8am|Me>{SVex#z zPfb0F`P3i7g_h^oj0e^V%H5~bSGfa6yH3bGpU+nRDYy~_Cba^Q2{T9&=AA5@!I7Z} zLy~YpDP^#cRF0{!A;fh&hsz$0!8uqss-b$}cgaTsCaB~Q?)3`g^dID-Jy*=!>uXY; z%XuqwlHZKoDXa^&e@MXhp$fUvbrcqik-~gakWbOaKU%k)u4CFV9MECcQCR&Bdz3`5 z$YHV`265F&@kK?d8D@qgoEfYEMGA^|a1+LETx#}F`#4WH!FAkjj*aFg zHqrv^o-ZNSIU>3^R82)*2DCuDPAT;}&!Mgk0Xuo)p0NK&sN$zulM@UQ@|Ei0F zUnx#B^Y=|_L}cX48nF!%NVQS?z{v~Hs*);d0J^gVH+NMJ<&1)}Tnw~0Qoghg~zoglmoMw9IB zmsk*iRLrQhVEZLH!Wb!6HP=eH6E0PAS;4weAD|=sJfYQc2jYty5vUwZfwD3(2OY#-7D8(2z$TXtE4J4}s2p*-9b-_gy5ydV%YTWFho*jN zm{#yU%@-Bo#rNM6KLSUnG9s_fWV8pF9f@)hcfgb{B}LXLKST>W0&XCqfx&|AAp|9G zBelz^hvox_O^a7vhu)B*K4nP;brZ^k5770}akOnVC1VcubUD9$_XK)00+Z9NChwlW zZ31Bn*wC6~Js9n^qeWJ$NmwT?57nR_RO$=ssn_t7U$B=dn{K3Zqy%ABxF{_UCl#?$ z{06BgLn>m_6nUjonIY|BrTe8yrgryQYupT=UA3_?lG9yD+d;hGwSreUQj}uj7kQNr z!O9KRrhFvUW)SfeivYNLUhzLEhj&T4*)DBnURRJqR}V%;4B|F7yJz-B;Pczo%u#ZG+#^6ZXLnX05zO zNDDq`S}LTjS_ODPko#Z*WJqNv^w|i)nVgU}hFwD*m|7qxkMbm7b=?9>5?UcsGioh# zVIN#*(M1}4lzV0_8aq)x7yd5Jx9A4$8I_>ny@MJ-1zgAXsa3=`Lue2cD;FAsm8Evn zHJ;513^qU(hQ$d@u;8qCl1k<|i;iJq%jKhzJIZz74qxaP_%pZ8b+_N$=juoD>LO8j1l%emk^eQAehR<_S!kfr zkLE=uEeZxcqUv-cS9I_LkPU6oFi7;lh4G&%P!MoGA$oO(VYxUexerno>=1UO z(W0>HAQ-*PVD!quxOgOO_xrfSfXCH7OoUVeNlR}7gmR=lGc+;<%u_HG>zzUhh|U!L z)i1Dt?V#D((xLT(_Tg{{Ksi^$b2kiw(21Z_j|2LPlKUL6ALOdEzU& zTxY;q&1Oo#>ILb6iKeQ>1_qYl9nge0bs6oKo6NMdy&UW)**#P%;U&xcPZ9ZFW^D8jiny8l64s2rl{pLeUDOd_z#4{5;x z<@*@toWdObrqHP;XSc!H(>eppk5k}}kG_kNmOoP&d074o>lMu62L!vUJ<;fW6&CdI zQMos{PhZ-@uAjp=kzK=@dpOknWIX2Z4zPLuVV%e4m0aCY*%9TAbhPx3$o*mj*4S>J zSJ|J24o4o=v&(F*I3v5FnmgK=q5cdAX2FXq3iZdqDCKXI-O*rPwt%Z-3LrV*z1Nft zSz>!X*hrUgOjeAKM4bF>BYh?`H9x#lO&f{m$t*Q-BofCbL(*{K3wuvt52noABL~B5};8E_@p(7EPJ|hukN{MXcPccK_9N6b#`(?5V+b&l` z!#lKE*<9d3YrH@yoTV?uyY3FVhf1I`0Yo zbh+5hIL!neg_?|vDVJtZ*Ch(%Y=T8(wTg&FDk5}aUgvbzd>J=BarYBKn(`BkZXJsE zYkUGlc=C^6aNusWRgOI5^+Ac-pzvHMW#e9t_Z2~@xgJF@imk+Ak%yqzA8_Loci%+9 z$OKf1@xscioFA1-#;;}8Vy-w;h$jYhxNoQ&hp8wJmxCH%12-v~R4}xpWw_VdXR!yJ z#Ewexn~3QcZk-dXWr&!n^%hx@_9Bkh%UUo`{X@7g(*_F236?-Dm?;l{(*HFMnZnFM z^frEh>FjVFbC9q|Dm-^dTbw+cw+!oOU-w4lleqJb{4BTW>Ni)^>z5M3owWL%){Nk0 zsGik&ot7k-15LWShgN<;>|=CFZLg{EGEL=Zp^;rhvKhCl@9A=rkscGjWTb}`l7Y+R zo9XWV&2pdo4(@NCkL_=VnWJ*D!~%Y2F|*1gMi|FL+b?s@>Wy9AuZ5TP3+~X_-XdnV zUoEVUQzdZ$d${a9NioKlp{&0>4 z(Cv3P=IsH^zdfZ?sk#9K9W4)OLY6ncYRkxzNV1Uf1;AUy6&-C((5yFlmC#IG(rM~1 zN(02FoU_uk6wTg^U~Z~WuP%3%x}ZU;l%oDvW}*V%I_UB61~zn->%db+am*rE#my`MKVUG00!&=T2+pUJh9_|4 z1#8_Z(KJ{r;uV$)9i_PkVO^Hf55cGTq}TCgdwO{3>a3IDr9UeM5V{Jz)(3@AP#DXO z0AK}JEZu^&&w?)^u2{`0_DlioMo`6yZ%+ZC#h^a8;yY77Aq3sKB0L536oN8WJTnFK zO$5zY@wW&{(m`DS(kLS^YEOd-!en`+%3{+?03y5Ceb`3y6ch2dEWH>8^~MV7_Q@&T zfS#A`gir55{N%B<&{j-~-Bw3$E0bpvJ`Gz}SB9-&gn~i=5DzX)q%`Mj-n?QwV)F?W zMY$QIw+zpKa ztGTxb$0{_+g!11~aYua~rlp&!D*G&jz$vcBbnujvOy~X%;QsYyz^!8d$6KnUuK_vj z#ltOWnG*-eL~aHQzGxWCRNTKWE%hmG957&xxW~gxr$;%MMCfsNhT{@&$SOt1VGLh( z0n#@;UY|0XmO?AFSfXcQRh9ejPz=^mx>jb$uC!9GI3ElL8@il*M7M+4kjAspy`Z&m zM>Y3Wp|Hziat1%Um0#3xieJbbI5qOr`F2>0d8=j$jqveZw$2-hoHYG!G_Af(Uzp%+ zqzDNVIn@FRvC!-;o0B{6?ua;*h@~r|^X4L`#m*-}Es4R;5{2U(rv!7c%2HCb8d&og zB#8dX0PxvmLtG2up*2h4II*TOFPEihaeXd4t|vKXgSndo##x|_B1?h$VhMerXtPskZ`HX27Ep! zwr3DnD}a@izzTn#*v=Au2_W7$rHS#ne014xQv_%RsAh5wZU9Xb6PRWioQ6_@P;uzyP zJ_LxKhZ=P78ML&bCN6|Z1ICb5FVA%xhWFaMo8?|U)#j}nm7MPq7HMtB- z?oahq1lDs8mhQz(4_uzh%V9+dki5c7whlLUxM#b;0;r*D{ytoG`E+GPGAea}i><>1 zazWpKDvumLj+)==E5mcwy4InU7(*Y%k; zDefSCVFni}8SSpXM4b}|)Ic@x7>DJMV~2G_ZnlCa&o6O+y!hM0OSj3^pGs>oS*h46 zwt=rJ%&arvic|PgR&k;dUjI{8jnq72K^o9*-598mQ}BKFP6jIyY;uWJUT4iKVFe52 zEmB(Y+Hp{-YLbzV-K_KwD-|%(W7hJGhZ%DGxVPZ$>~e8n^hEXQTovlx3j+WXVgPQTNhsW~p;&OVo5E z9?(ja=k@Xx6ddc6GUydnUL@zw^~m`d9%ZM21TEZ)r}i-H`4s5#JH!=?08>SnUpEfL zl??dUy8|XjxpDOcZ9>D|pgVIfVkeZbImZqT;NoQClfl5vUx7OTZ5O@r#h&-gj_+a? z7n%#GvC8xlE_CsX3b~HoVn=<3wQ?O73GQ)h0w(El;0X|YJ%9qU47k0<3G3KO>b~e8 zpC|k)jFksr5IDi7S-x$Np5syO#bc|e{w6ApfY}_an+p_tO86$-2@GupG1n1Fb#NwD zj{u)X8Jc{l8{dMtX91ucxBzX^!5-xpKf1TO2QH|~HyRC&y}M&hjbifbep`ZbchZO|b(XF|&6q#ni11sait+GrBKL{i=FD-$ z4#I{8$d@JIoUhcYpwS4ERZT|KBKs9o-J*M31Esx469&9G{eWqbDv$(7n#YTNGi@#E zwXpxV>>jR>=wzo(F;!CZng)$%PJK9LFbF?clcz{x^8DnreS!HNhKtPsKOk_LN1&BLr<* zhPI8KR4l)djs>X*54IZ60e)2WT1O5)B`lTK+I->_jZc%W^k~%YUH&WT_bz`&wY-sw zcKE|gRq*^%!7ERJullxK@>+NA%D`1!NR!us=fm>WkzX@HLSIn^E_!lmG1NnkTT&|{ z`rx&R-L}LcE4o(HnZq3oRvgp3d_HbvU=vLO3+~w6`{RTq;x3j530|cQCV9CW?oW3 zr!9d>-l@L|7wKXvn|`TH zOzbkB5Qnv#!(tEfBVsb`<`p@A9B}XMxWH%r2oxsaXF&ulj8lIT&exD?R!=0HKQWoQ zI++?bQfQ8Y+1)L~Rlsn?i3;m}E%=SKyRT?udtSiQ$!@5Kgx##@2X_nGhhrM-eb5=6 zI(r;CXZp0-pex3BYKNvwn~W9HFNlHOD9p@A?iMnDi!?M;a!!q2q&LH?5T91_<)e5t z6D=Bqog6%Q_T+~r`;(6emq#zj!=p8s8GuoknKt^q`D9C~1Ms%9EeQ_5-DX;wb4u>5 z#5-k^^&zTJ9VJMs!^>wE<-<9rR1dArM%4g7KUdvRysY+Z_^=suS)r~}sEggkW&!Uv ztLbr^#%M>gP9PCQ~{O+LQH*zX7zo1|2E zZN}=5Caq<5*?gW-<+Vgz1-Ptg4$M6M200?X_4%DH)p8JL{D_mW^C^M204Y@*`f&U@V_)M>|lh7SpFQ4R5 zzDMU{W#roQX`s_*Z?KJyDLkNMv=g`u#NavxQ>o4g3)}SR2G;fXE)b0=A}+iP2_i0x zViYj#8{UQ6mI{30`ND?CUd#wvgL}tm+zBo}jy5LCW8M83e($;^LF`Ub6{v_BrD<}R z71l54(0rTxN!B;4@+0Ho;c;KjN1Xh&{P=kNF$QMBLsI*A_-PZK_DdC)CHJswoi);9 zlH5_@$(}1rVCCv6$!&GKvyEPHSu=}qteM3M#W34MQ2ulAYIE@P$Kf?5X7so7+g>T0 zNEEW5*745{8mw<<*Szpq^&r z)vWX&E0;yZ_8}r9=HXGagmc9`9JXGGVPYE4B*1@=k$}R3jN?I8*wVEofe|%(r<4bFa!eBc`gw)rN5&50dDpZ?zE40RDjvV|WWpgB5LIRo#p-szxxC+5l^ zRM)UHN7^)NTw}Qq3>&f+haH-L?;)EhL+~cAsN0Mek2!O(^)(U%E0(~JEG+>CmgdtU zhHw%+EPXXfI&I>MomiQU1n(2Y1$wgB7Tj3?G7&d36BHuuU^Stk6edKoRr@UkY0b9j z^N9|6Ih_u9CfG9&Cm*GVSx3WbW(<{ti_=Ox%J3|@5d#xiOF?{x1yQz{MI}v6!J<+M zPA0sQ!S2H>X&EvbGYMg;OsS^S3l;go%bx;doEycn#q+~3FJP#xhC$PwD!#3q{z!C3 zHA%Rv+F+P~p2!(Ft>EPYS9CAdB=*|ESKT`-aSj*u)y(i|1zkkRr1 z#KKPbT}MBnrB6e%0Gj%~qhBZoq}CbY6JS!X00T_*&sgrZSh*CMNAW)b{8S|uCbZli zIt!V6TB-7G99kg{*(8%(U=wpSAt9%GkOQDJk8)XHlWpQ>np8FpHq_I5u-oLeJ%uqw z?v-^=bK!!r=mOy~UNH|B7bgF^EL;|5%iqQwQ_VFFnXtUe6ASW^f6EWbFfZTC(RAe! zQ!MVw@*1G~wvb{}6R<-iRiR^TmXqgKsiQI=tiQs@Nm-zOE`sjqnPAq66DxPY#IJOW zaviu;Y)q1Bm>}(0Q)a|?xGk3%JuOuXE!fmqC_$Lu1Q_b9>>iq*tll+sUQpcd({zN6 zo}Pc>1c#SJlMUpD7#JdugbDmOBeq8gY9*MjkF%hVxQ=J(JiaWqU1Y-6i_+uFmrUWB zt~K$DH~~{QxqZ<@Pq00ibOJ<3rc+UV`}D_&j>#nOli1c-sD5nzY}zJ1!63(n zD7OH9oq|6~ycbkW=op_YB}r>$j04M{d4yr}$?#eeg613Z&qA9%6YV9I5B*&dD)2`S07(3 z>WdRyz>LzEtUHnq9n8Wk(hG!_?$*~jN1s$=;7|lYfD6)yHCihlV>R%eb_01=L!zSmmIcG!NFrEeqU_3$;pV_?1Lblu>jNa0cYN6rMq2qsN@V@@JkgiqX)l(LjQaGDHF$M z+n0w|*~H?gCUy>SFzCab;}G>Z$A=*T5q6G$tZ7m)(-*|AJ|WP8WW&Y7jyJdU;U4qD zR!bBYe^V8pN%?H}L90~EO8Jaf^L!zZ4n2>3+*MT2b#$VqqZ?FD=h_0noVbIbYF2*h z^oOwgcv$+il4HhQFYz4>-47={W>W9lFY-&h%KkrTnpci0M{qj={HMg3ME|lty9Myo znR3xwFiw&^%ED1i6Km&!g6I=#t)L9282+s*z`8sEM!)!nTMWB@r0^tT;um@p+bp_G zk-o=}m6rar;cw$r>3!BG&}u`ey%-uA(=-_DSzySxZLNzS33{t5F?c0ONYGrvy(Goi$vWku;lD%7 ztT%UGA;53jaoiiCkZ9O-Ie-^+@XhCu&DzpzeR~EPT_C$In_N*xUt2PCb(YKO0QbHt zN0Sl8h4A`dUOUTI1uPr#T&%F>ns}(R27{-LeuoR=0Xk93am`MA;7LEL2Es39;$kjS&&+2ye4Os^IbsgqU-tDDfUh@4_w`b*`FcAwH6^@rLS@4{ zud3$oPIT_92K^hmX5h{3n$Fp)j4D1-Ez)eUkD>L*CZi^K#$;XR0e@-72>&;uhiOeS zF{V}ZNwf9sjaog?yDE-MzEnjzjhNa2xRZtw?ZmM;T<%zQ2)DEZ(ER}%i)V4y-;1eJ z2lssT;W}`M3cEk%hGc?m)iA9XRDU%>5TsMZr#b2I5pdx<>NS z%i*Q#q>AyL_n9AupFap31sz0wi(lMTV$#o^Ox%Ib9DUot6&UaO+ZOT=XhWL#!iTBdW$r^Dv#$O{u;7^2=&U-n>po@~H}5GgI)k zGbny@Y(&!A9t#lzq&gwk`YfFWEp6d*RMc0e1HVUs;{r!FB(LRAN_V~pFPlm-${04Bu7jTvXtGcj%Y%opbvJYE98wYKuGL#%%t#l1} zVZl5^w-+Xd!VNfRx?e{=Iy)>wFfpBu-j>T(y|a^2x{ z89T^Fw>I21{GvvWeA3+OnApZTqTEwE0AsX|Dw;G9viJwHc!h0Qbm=86^Y2&>7#)4T z#7uFJX|aj}X7f=kGh}}lWStq#fb2aGKL@XSvf*PBgdl_kC%fW16S|5_ovTb;MR7p3 zb5)$!YZm(`@#B-k!>h01QY@3$8z=U~A=W=nV(rm!iU4C3<~%*Myax3RLAU_n9E39v zjzc&C;SdD5@LLz8!e=f(tU#rtUs>k{gH+JvEM`c1CjR}gmgay0xw-f<^?A^SDDuW;fImzfhlB> zFC+h2AAJ-jeoUqR^c2iJQ}6)kT3>x+7C%OIxu+h1sWYASdWbebsDaP`frrorp##F- zm(YHh3v!+daR$U05T`+$2C)rd8^l(Ktq`*ivk)^7Gt>J;m(MHkc@V-;2YzVBIx_U_TQ#%|C~pqI+0?tNAVSV|FM+$E%;6l|O}>Y~%jTgQ*1 zdEf)D=W%bT{5vpz(?)x74B&l4Ap!bAXj12Q#TVh32fq-s=^{N}P^sP&O2j{!`4k-i za=-SFa0&NtH&#|f^pVHU#G+gWUfnUq;zxSX2FQ3w_-tdPZYWSYWHtXUx+xMLGevF? zdks_M_ptOX22xf_Io(nM(ift@ zun>yzc>H+D3hGg;$z)s7b`N6uPW%X&D7!^GrWRlOztn6ewkwBbMc^H4UfZ8=y z+|^}$4tgh#6Mv27O)ps8V0(kbZP?z%UaGmb%fo^ zUZ!8OKBW|D2;WZ^g00lh#~WlGWgs4JdEbWon&q;~rm|>wO*TUv1TgobP&99pxX$>jb}KkU;9UF#GhYAx4)tx7gLvPG9u;+ z&QF630L7u8@>#K(A(DxjOQpI$==HU>f=4)v9wGQ@%fm5WjTajs zF9djXRqm5Vzqkj3TFk`P`;_@6eO~j+Ma{%pL@iFZ0T!1ex|t;_3SPG=cl^4XpX*aT zCHmHoZJKhF6`1FL_9+!unYkQiI0^lkPb^d7u&kO63;b71^@@#CE)wwb_Otwr+BQ}R zTmaW&cdd1F3_M{e9=~*0#8lEFX|KM)22|$;?gD>oK5(mrM#cuY26^PY#QM@v%WuAB?b9;tf4zIIBWai&q1k`;9i0r;{ z2w*KUcVBsv#HiypjUJ{?_lWlp(XWY@3A;Md77INsC0Wsj#f z%uV_gqhF0^8eTCvBDv1tRU&m(>~4`JwNr>(aUrk$9A8^XzvGQH-~}Ul?CK5ghQ`t? zol6vjJS++Qj#2*Z5mySsJM-G-avivR;SlCNd9&WM&lkZvJb0lLZzmo7-0h@37k-_M zgqeGEo)Zn8&q);nl;@d~Jm;LHEJN+@@vnNJk_%s`hkp+E@%aSC=TqZ#X1t~PHQ>kWQ8-(;_Etmo^i8|okT+w1(*&3ZY+yBG2BzgO@#HVKc`*;|{d zxA^U~PED$%z1>aCejwb`*xCf|HU4e&Tc+R|GVTF<%&4>ehz1=(7@O8buIqt8j#SI$3Bn$)p9Wk;s1vK=qX9nUvF$`*$M)P z{XZAHzh!HE<8*mt=Y1tTeXt_ZL~M=8H~VhHt!-$6>KY%l zH#gNc^0X*GYWy{N{qFiLElsUWwY=S1--=yTkdVKeVM?Mi+{Vh3nFR5v0(CM7qGQ+@v-kQYPjv(4iFB2Ec zT^J)b^Mr{mu6-Plq)7GukjWuiP8~ypD53#)dmR6WE zgnSlP>gS6gv%z1`1mlsA=P|#OuhD_fL-<})-{4=rv)NCc({rmq4>hlDtZm9CADfCn z2jn-v%q9<*%Npxwxf<7wE&gVlmrxX>LWmzrx|?c*20v0;3u8K;kUx?l5Q^*Cye#Eg zV0N|UlM7#w<0JKEUww_gpsu=QeUlq?%L6-kKUsl8 z>01FP93VzEn7z8LMJC9nG><09e~(+oH@%Zt8uNaMF*x)*!p#Ui@izU z?M=1zmg>ew{Y$8Sl0>Zt>f@mkQ(aTt3}uqYLa<_8Se#O=|2(1F@49ng&7%9D{Mx2# zxvk(R35_-L?e6Nw{PtG#P{GykfW>OBZv`}9vjI#&tl54$6s+;LZfU8fR-wImTXlT{ zwr3IL%YOU9R!l9dSpuyAUMQROjrPx*#P{iqO|<*!{4M_b>|3jMRDsX-SSwbEyaS+q ztFU!a1hsa|_Vbuq&D*!vH#Fe?i`ZJd4P4XPv+Y~`)s3y-$Jra|x7PEEz%iRfyA}Qa z&yl7uN-fp}_F6EOblPA*ZmIh+!a%nS{V!~ReWM}y3VRzRP=y4lsG~Po>txfQy^kT% zeUxjRmqtIoy{Y9fJKs`WTU);cM+N0UXvKbwb;D!+mPUWWoelnN{sx25YA|r2r=U}u zL4Ay2jAss$kL~j#kI;?hsVHBTANLpXuRqtH&p&0e^owLO1t$%l1-|fi`{dsj^S=03 z3`6%X{dIiF-*k-KQ~peU<=@ouPfhuY`z!xqW$k}iT>mK^91ly3*q(T23Z8Ica8^4> zHUxZdkBTJW7XnCkvQcgxq!}aq-6?7Op&`~te``wmnJMW#Q_|m_lK$H%>F-QQnKQ|0+(N8DWLyYCJx9HzNWFVda@tLo~9Dw*0h-X3E z0Wtn0#2Sc^a3;iaARYo4+ywEf)%q3mry;tg(s)1M_w0LjpPhX9 zvwK31oksk#zY;&+hz|h%J3qMagE{0+KTv+K@hkD2yY|vl2@I5ycPrnuld5+E@811I z{L}rvAGkuuUAtl>^#{iwp7X}mHnS1q*uuWSFJ|@xTO1QsLTG+N7;^?)n*qb|Fw+PKpKrjI8SnYVdx7!pG0Lnn;H5_FGw7EabvGFBtq|-)|1X7c z47CuQ*LVXzNOYce8}U;{zG&ok7 + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "basic_dump_ex"=.\basic_dump_ex.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "readfile"=.\readfile.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "readfile_ex"=.\readfile_ex.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "savedump"=.\savedump.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "sendpack"=.\sendpack.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples/misc/basic_dump.c b/winpcap/Examples/misc/basic_dump.c new file mode 100644 index 0000000..333f1c8 --- /dev/null +++ b/winpcap/Examples/misc/basic_dump.c @@ -0,0 +1,94 @@ +#include "pcap.h" + +/* prototype of the packet handler */ +void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); + +main() +{ +pcap_if_t *alldevs; +pcap_if_t *d; +int inum; +int i=0; +pcap_t *adhandle; +char errbuf[PCAP_ERRBUF_SIZE]; + + /* Retrieve the device list on the local machine */ + if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. %s", ++i, d->name); + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if(i==0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return -1; + } + + printf("Enter the interface number (1-%d):",i); + scanf("%d", &inum); + + if(inum < 1 || inum > i) + { + printf("\nInterface number out of range.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Jump to the selected adapter */ + for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); + + /* Open the device */ + if ( (adhandle= pcap_open(d->name, // name of the device + 65536, // portion of the packet to capture + // 65536 guarantees that the whole packet will be captured on all the link layers + PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode + 1000, // read timeout + NULL, // authentication on the remote machine + errbuf // error buffer + ) ) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + printf("\nlistening on %s...\n", d->description); + + /* At this point, we don't need any more the device list. Free it */ + pcap_freealldevs(alldevs); + + /* start the capture */ + pcap_loop(adhandle, 0, packet_handler, NULL); + + return 0; +} + + +/* Callback function invoked by libpcap for every incoming packet */ +void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + struct tm *ltime; + char timestr[16]; + time_t local_tv_sec; + + /* convert the timestamp to readable format */ + local_tv_sec = header->ts.tv_sec; + ltime=localtime(&local_tv_sec); + strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); + + printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len); + +} diff --git a/winpcap/Examples/misc/basic_dump.dsp b/winpcap/Examples/misc/basic_dump.dsp new file mode 100644 index 0000000..3e8bc02 --- /dev/null +++ b/winpcap/Examples/misc/basic_dump.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="basic_dump" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=basic_dump - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "basic_dump.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "basic_dump.mak" CFG="basic_dump - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "basic_dump - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "basic_dump - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "basic_dump - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "basic_dump - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "basic_dump - Win32 Release" +# Name "basic_dump - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\basic_dump.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/misc/basic_dump_ex.c b/winpcap/Examples/misc/basic_dump_ex.c new file mode 100644 index 0000000..aa4f3c8 --- /dev/null +++ b/winpcap/Examples/misc/basic_dump_ex.c @@ -0,0 +1,99 @@ +#include "pcap.h" + + +main() +{ +pcap_if_t *alldevs; +pcap_if_t *d; +int inum; +int i=0; +pcap_t *adhandle; +int res; +char errbuf[PCAP_ERRBUF_SIZE]; +struct tm *ltime; +char timestr[16]; +struct pcap_pkthdr *header; +const u_char *pkt_data; +time_t local_tv_sec; + + + /* Retrieve the device list on the local machine */ + if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. %s", ++i, d->name); + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if(i==0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return -1; + } + + printf("Enter the interface number (1-%d):",i); + scanf("%d", &inum); + + if(inum < 1 || inum > i) + { + printf("\nInterface number out of range.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Jump to the selected adapter */ + for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); + + /* Open the device */ + if ( (adhandle= pcap_open(d->name, // name of the device + 65536, // portion of the packet to capture. + // 65536 guarantees that the whole packet will be captured on all the link layers + PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode + 1000, // read timeout + NULL, // authentication on the remote machine + errbuf // error buffer + ) ) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + printf("\nlistening on %s...\n", d->description); + + /* At this point, we don't need any more the device list. Free it */ + pcap_freealldevs(alldevs); + + /* Retrieve the packets */ + while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){ + + if(res == 0) + /* Timeout elapsed */ + continue; + + /* convert the timestamp to readable format */ + local_tv_sec = header->ts.tv_sec; + ltime=localtime(&local_tv_sec); + strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); + + printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len); + } + + if(res == -1){ + printf("Error reading the packets: %s\n", pcap_geterr(adhandle)); + return -1; + } + + return 0; +} \ No newline at end of file diff --git a/winpcap/Examples/misc/basic_dump_ex.dsp b/winpcap/Examples/misc/basic_dump_ex.dsp new file mode 100644 index 0000000..e798f63 --- /dev/null +++ b/winpcap/Examples/misc/basic_dump_ex.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="basic_dump_ex" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=basic_dump_ex - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "basic_dump_ex.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "basic_dump_ex.mak" CFG="basic_dump_ex - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "basic_dump_ex - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "basic_dump_ex - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "basic_dump_ex - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "basic_dump_ex - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "basic_dump_ex - Win32 Release" +# Name "basic_dump_ex - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\basic_dump_ex.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/misc/readfile.c b/winpcap/Examples/misc/readfile.c new file mode 100644 index 0000000..480b07d --- /dev/null +++ b/winpcap/Examples/misc/readfile.c @@ -0,0 +1,73 @@ +#include +#include + +#define LINE_LEN 16 + +void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *); + +main(int argc, char **argv) +{ +pcap_t *fp; +char errbuf[PCAP_ERRBUF_SIZE]; +char source[PCAP_BUF_SIZE]; + + if(argc != 2){ + + printf("usage: %s filename", argv[0]); + return -1; + + } + + /* Create the source string according to the new WinPcap syntax */ + if ( pcap_createsrcstr( source, // variable that will keep the source string + PCAP_SRC_FILE, // we want to open a file + NULL, // remote host + NULL, // port on the remote host + argv[1], // name of the file we want to open + errbuf // error buffer + ) != 0) + { + fprintf(stderr,"\nError creating a source string\n"); + return -1; + } + + /* Open the capture file */ + if ( (fp= pcap_open(source, // name of the device + 65536, // portion of the packet to capture + // 65536 guarantees that the whole packet will be captured on all the link layers + PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode + 1000, // read timeout + NULL, // authentication on the remote machine + errbuf // error buffer + ) ) == NULL) + { + fprintf(stderr,"\nUnable to open the file %s.\n", source); + return -1; + } + + // read and dispatch packets until EOF is reached + pcap_loop(fp, 0, dispatcher_handler, NULL); + + return 0; +} + + + +void dispatcher_handler(u_char *temp1, + const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + u_int i=0; + + /* print pkt timestamp and pkt len */ + printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len); + + /* Print the packet */ + for (i=1; (i < header->caplen + 1 ) ; i++) + { + printf("%.2x ", pkt_data[i-1]); + if ( (i % LINE_LEN) == 0) printf("\n"); + } + + printf("\n\n"); + +} diff --git a/winpcap/Examples/misc/readfile.dsp b/winpcap/Examples/misc/readfile.dsp new file mode 100644 index 0000000..88972bb --- /dev/null +++ b/winpcap/Examples/misc/readfile.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="readfile" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=readfile - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "readfile.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "readfile.mak" CFG="readfile - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "readfile - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "readfile - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "readfile - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "readfile - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "readfile - Win32 Release" +# Name "readfile - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\readfile.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/misc/readfile_ex.c b/winpcap/Examples/misc/readfile_ex.c new file mode 100644 index 0000000..d4eefa5 --- /dev/null +++ b/winpcap/Examples/misc/readfile_ex.c @@ -0,0 +1,73 @@ +#include +#include + +#define LINE_LEN 16 + +main(int argc, char **argv) +{ +pcap_t *fp; +char errbuf[PCAP_ERRBUF_SIZE]; +char source[PCAP_BUF_SIZE]; +struct pcap_pkthdr *header; +const u_char *pkt_data; +u_int i=0; +int res; + + if(argc != 2) + { + printf("usage: %s filename", argv[0]); + return -1; + } + + /* Create the source string according to the new WinPcap syntax */ + if ( pcap_createsrcstr( source, // variable that will keep the source string + PCAP_SRC_FILE, // we want to open a file + NULL, // remote host + NULL, // port on the remote host + argv[1], // name of the file we want to open + errbuf // error buffer + ) != 0) + { + fprintf(stderr,"\nError creating a source string\n"); + return -1; + } + + /* Open the capture file */ + if ( (fp= pcap_open(source, // name of the device + 65536, // portion of the packet to capture + // 65536 guarantees that the whole packet will be captured on all the link layers + PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode + 1000, // read timeout + NULL, // authentication on the remote machine + errbuf // error buffer + ) ) == NULL) + { + fprintf(stderr,"\nUnable to open the file %s.\n", source); + return -1; + } + + /* Retrieve the packets from the file */ + while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0) + { + /* print pkt timestamp and pkt len */ + printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len); + + /* Print the packet */ + for (i=1; (i < header->caplen + 1 ) ; i++) + { + printf("%.2x ", pkt_data[i-1]); + if ( (i % LINE_LEN) == 0) printf("\n"); + } + + printf("\n\n"); + } + + + if (res == -1) + { + printf("Error reading the packets: %s\n", pcap_geterr(fp)); + } + + return 0; +} + diff --git a/winpcap/Examples/misc/readfile_ex.dsp b/winpcap/Examples/misc/readfile_ex.dsp new file mode 100644 index 0000000..2c1b488 --- /dev/null +++ b/winpcap/Examples/misc/readfile_ex.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="readfile_ex" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=readfile_ex - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "readfile_ex.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "readfile_ex.mak" CFG="readfile_ex - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "readfile_ex - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "readfile_ex - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "readfile_ex - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "readfile_ex - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "readfile_ex - Win32 Release" +# Name "readfile_ex - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\readfile_ex.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/misc/savedump.c b/winpcap/Examples/misc/savedump.c new file mode 100644 index 0000000..4f75e26 --- /dev/null +++ b/winpcap/Examples/misc/savedump.c @@ -0,0 +1,104 @@ +#include "pcap.h" + +/* prototype of the packet handler */ +void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); + +main(int argc, char **argv) +{ +pcap_if_t *alldevs; +pcap_if_t *d; +int inum; +int i=0; +pcap_t *adhandle; +char errbuf[PCAP_ERRBUF_SIZE]; +pcap_dumper_t *dumpfile; + + + + /* Check command line */ + if(argc != 2) + { + printf("usage: %s filename", argv[0]); + return -1; + } + + /* Retrieve the device list on the local machine */ + if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. %s", ++i, d->name); + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if(i==0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return -1; + } + + printf("Enter the interface number (1-%d):",i); + scanf("%d", &inum); + + if(inum < 1 || inum > i) + { + printf("\nInterface number out of range.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Jump to the selected adapter */ + for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); + + + /* Open the device */ + if ( (adhandle= pcap_open(d->name, // name of the device + 65536, // portion of the packet to capture + // 65536 guarantees that the whole packet will be captured on all the link layers + PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode + 1000, // read timeout + NULL, // authentication on the remote machine + errbuf // error buffer + ) ) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Open the dump file */ + dumpfile = pcap_dump_open(adhandle, argv[1]); + + if(dumpfile==NULL) + { + fprintf(stderr,"\nError opening output file\n"); + return -1; + } + + printf("\nlistening on %s... Press Ctrl+C to stop...\n", d->description); + + /* At this point, we no longer need the device list. Free it */ + pcap_freealldevs(alldevs); + + /* start the capture */ + pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile); + + return 0; +} + +/* Callback function invoked by libpcap for every incoming packet */ +void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + /* save the packet on the dump file */ + pcap_dump(dumpfile, header, pkt_data); +} diff --git a/winpcap/Examples/misc/savedump.dsp b/winpcap/Examples/misc/savedump.dsp new file mode 100644 index 0000000..7d2e366 --- /dev/null +++ b/winpcap/Examples/misc/savedump.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="savedump" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=savedump - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "savedump.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "savedump.mak" CFG="savedump - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "savedump - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "savedump - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "savedump - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "savedump - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "savedump - Win32 Release" +# Name "savedump - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\savedump.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/misc/sendpack.c b/winpcap/Examples/misc/sendpack.c new file mode 100644 index 0000000..91d83b6 --- /dev/null +++ b/winpcap/Examples/misc/sendpack.c @@ -0,0 +1,64 @@ +#include +#include + +#include + + +void main(int argc, char **argv) +{ +pcap_t *fp; +char errbuf[PCAP_ERRBUF_SIZE]; +u_char packet[100]; +int i; + + /* Check the validity of the command line */ + if (argc != 2) + { + printf("usage: %s interface (e.g. 'rpcap://eth0')", argv[0]); + return; + } + + /* Open the output device */ + if ( (fp= pcap_open(argv[1], // name of the device + 100, // portion of the packet to capture (only the first 100 bytes) + PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode + 1000, // read timeout + NULL, // authentication on the remote machine + errbuf // error buffer + ) ) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", argv[1]); + return; + } + + /* Supposing to be on ethernet, set mac destination to 1:1:1:1:1:1 */ + packet[0]=1; + packet[1]=1; + packet[2]=1; + packet[3]=1; + packet[4]=1; + packet[5]=1; + + /* set mac source to 2:2:2:2:2:2 */ + packet[6]=2; + packet[7]=2; + packet[8]=2; + packet[9]=2; + packet[10]=2; + packet[11]=2; + + /* Fill the rest of the packet */ + for(i=12;i<100;i++) + { + packet[i]=i%256; + } + + /* Send down the packet */ + if (pcap_sendpacket(fp, packet, 100 /* size */) != 0) + { + fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(fp)); + return; + } + + return; +} diff --git a/winpcap/Examples/misc/sendpack.dsp b/winpcap/Examples/misc/sendpack.dsp new file mode 100644 index 0000000..982ce67 --- /dev/null +++ b/winpcap/Examples/misc/sendpack.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="sendpack" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=sendpack - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sendpack.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sendpack.mak" CFG="sendpack - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sendpack - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "sendpack - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sendpack - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "sendpack - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /I "D:/Program Files/Microsoft Platform SDK/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ws2_32.lib Iphlpapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "sendpack - Win32 Release" +# Name "sendpack - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\sendpack.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/pcap_filter/pcap_filter.c b/winpcap/Examples/pcap_filter/pcap_filter.c new file mode 100644 index 0000000..9c1c3f6 --- /dev/null +++ b/winpcap/Examples/pcap_filter/pcap_filter.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include + +#include + +#define MAX_PRINT 80 +#define MAX_LINE 16 + + +void usage(); + + +void main(int argc, char **argv) +{ +pcap_t *fp; +char errbuf[PCAP_ERRBUF_SIZE]; +char *source=NULL; +char *ofilename=NULL; +char *filter=NULL; +int i; +pcap_dumper_t *dumpfile; +struct bpf_program fcode; +bpf_u_int32 NetMask; +int res; +struct pcap_pkthdr *header; +const u_char *pkt_data; + + if (argc == 1) + { + usage(); + return; + } + + for(i=1;i < argc; i+= 2) + { + + switch (argv[i] [1]) + { + case 's': + { + source=argv[i+1]; + }; + break; + + case 'o': + { + ofilename=argv[i+1]; + }; + break; + + case 'f': + { + filter=argv[i+1]; + }; + break; + } + } + + // open a capture from the network + if (source != NULL) + { + if ( (fp= pcap_open(source, + 1514 /*snaplen*/, + PCAP_OPENFLAG_PROMISCUOUS /*flags*/, + 20 /*read timeout*/, + NULL /* remote authentication */, + errbuf) + ) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter.\n"); + return; + } + } + + else usage(); + + if (filter != NULL) + { + // We should loop through the adapters returned by the pcap_findalldevs_ex() + // in order to locate the correct one. + // + // Let's do things simpler: we suppose to be in a C class network ;-) + NetMask=0xffffff; + + //compile the filter + if(pcap_compile(fp, &fcode, filter, 1, NetMask) < 0) + { + fprintf(stderr,"\nError compiling filter: wrong syntax.\n"); + return; + } + + //set the filter + if(pcap_setfilter(fp, &fcode)<0) + { + fprintf(stderr,"\nError setting the filter\n"); + return; + } + + } + + //open the dump file + if (ofilename != NULL) + { + dumpfile= pcap_dump_open(fp, ofilename); + + if (dumpfile == NULL) + { + fprintf(stderr,"\nError opening output file\n"); + return; + } + } + else usage(); + + //start the capture + while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0) + { + + if(res == 0) + /* Timeout elapsed */ + continue; + + //save the packet on the dump file + pcap_dump((unsigned char *) dumpfile, header, pkt_data); + + } +} + + +void usage() +{ + + printf("\npf - Generic Packet Filter.\n"); + printf("\nUsage:\npf -s source -o output_file_name [-f filter_string]\n\n"); + exit(0); +} \ No newline at end of file diff --git a/winpcap/Examples/pcap_filter/pcap_filter.dsp b/winpcap/Examples/pcap_filter/pcap_filter.dsp new file mode 100644 index 0000000..5bd65b5 --- /dev/null +++ b/winpcap/Examples/pcap_filter/pcap_filter.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="pcap_filter" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=pcap_filter - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pcap_filter.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pcap_filter.mak" CFG="pcap_filter - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "pcap_filter - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "pcap_filter - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "pcap_filter - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 /out:"Release/pf.exe" + +!ELSEIF "$(CFG)" == "pcap_filter - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/pf.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "pcap_filter - Win32 Release" +# Name "pcap_filter - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\pcap_filter.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/pcap_filter/pcap_filter.dsw b/winpcap/Examples/pcap_filter/pcap_filter.dsw new file mode 100644 index 0000000..a903183 --- /dev/null +++ b/winpcap/Examples/pcap_filter/pcap_filter.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "pcap_filter"=.\pcap_filter.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples/pktdump_ex/pktdump_ex.c b/winpcap/Examples/pktdump_ex/pktdump_ex.c new file mode 100644 index 0000000..a0d3fa9 --- /dev/null +++ b/winpcap/Examples/pktdump_ex/pktdump_ex.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include + +// +// NOTE: remember to include WPCAP and HAVE_REMOTE among your +// preprocessor definitions. +// + +#include + +#define LINE_LEN 16 + +main(int argc, char **argv) +{ +pcap_if_t *alldevs, *d; +pcap_t *fp; +u_int inum, i=0; +char errbuf[PCAP_ERRBUF_SIZE]; +int res; +struct pcap_pkthdr *header; +const u_char *pkt_data; + + printf("pktdump_ex: prints the packets of the network using WinPcap.\n"); + printf(" Usage: pktdump_ex [-s source]\n\n" + " Examples:\n" + " pktdump_ex -s file://c:/temp/file.acp\n" + " pktdump_ex -s rpcap://\\Device\\NPF_{C8736017-F3C3-4373-94AC-9A34B7DAD998}\n\n"); + + if(argc < 3) + { + + printf("\nNo adapter selected: printing the device list:\n"); + /* The user didn't provide a packet source: Retrieve the local device list */ + if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); + return -1; + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. %s\n ", ++i, d->name); + + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if (i==0) + { + fprintf(stderr,"No interfaces found! Exiting.\n"); + return -1; + } + + printf("Enter the interface number (1-%d):",i); + scanf("%d", &inum); + + if (inum < 1 || inum > i) + { + printf("\nInterface number out of range.\n"); + + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Jump to the selected adapter */ + for (d=alldevs, i=0; i< inum-1 ;d=d->next, i++); + + /* Open the device */ + if ( (fp= pcap_open(d->name, + 100 /*snaplen*/, + PCAP_OPENFLAG_PROMISCUOUS /*flags*/, + 20 /*read timeout*/, + NULL /* remote authentication */, + errbuf) + ) == NULL) + { + fprintf(stderr,"\nError opening adapter\n"); + return -1; + } + } + else + { + // Do not check for the switch type ('-s') + if ( (fp= pcap_open(argv[2], + 100 /*snaplen*/, + PCAP_OPENFLAG_PROMISCUOUS /*flags*/, + 20 /*read timeout*/, + NULL /* remote authentication */, + errbuf) + ) == NULL) + { + fprintf(stderr,"\nError opening source: %s\n", errbuf); + return -1; + } + } + + /* Read the packets */ + while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0) + { + + if(res == 0) + /* Timeout elapsed */ + continue; + + /* print pkt timestamp and pkt len */ + printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len); + + /* Print the packet */ + for (i=1; (i < header->caplen + 1 ) ; i++) + { + printf("%.2x ", pkt_data[i-1]); + if ( (i % LINE_LEN) == 0) printf("\n"); + } + + printf("\n\n"); + } + + if(res == -1) + { + fprintf(stderr, "Error reading the packets: %s\n", pcap_geterr(fp)); + return -1; + } + + return 0; +} diff --git a/winpcap/Examples/pktdump_ex/pktdump_ex.dsp b/winpcap/Examples/pktdump_ex/pktdump_ex.dsp new file mode 100644 index 0000000..85c062d --- /dev/null +++ b/winpcap/Examples/pktdump_ex/pktdump_ex.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="pktdump_ex" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=pktdump_ex - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pktdump_ex.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pktdump_ex.mak" CFG="pktdump_ex - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "pktdump_ex - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "pktdump_ex - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "pktdump_ex - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "pktdump_ex - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "pktdump_ex - Win32 Release" +# Name "pktdump_ex - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\pktdump_ex.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/pktdump_ex/pktdump_ex.dsw b/winpcap/Examples/pktdump_ex/pktdump_ex.dsw new file mode 100644 index 0000000..b0f6812 --- /dev/null +++ b/winpcap/Examples/pktdump_ex/pktdump_ex.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "pktdump_ex"=.\pktdump_ex.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples/sendcap/sencap.dsw b/winpcap/Examples/sendcap/sencap.dsw new file mode 100644 index 0000000..5c40d67 --- /dev/null +++ b/winpcap/Examples/sendcap/sencap.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "sendcap"=.\sendcap.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples/sendcap/sendcap.c b/winpcap/Examples/sendcap/sendcap.c new file mode 100644 index 0000000..ef1ee47 --- /dev/null +++ b/winpcap/Examples/sendcap/sendcap.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include +#include + +void usage(); + +void main(int argc, char **argv) +{ + pcap_t *indesc,*outdesc; + char errbuf[PCAP_ERRBUF_SIZE]; + char source[PCAP_BUF_SIZE]; + FILE *capfile; + int caplen, sync; + u_int res; + pcap_send_queue *squeue; + struct pcap_pkthdr *pktheader; + u_char *pktdata; + float cpu_time; + u_int npacks = 0; + + /* Check the validity of the command line */ + if (argc <= 2 || argc >= 5) + { + usage(); + return; + } + + /* Retrieve the length of the capture file */ + capfile=fopen(argv[1],"rb"); + if(!capfile){ + printf("Capture file not found!\n"); + return; + } + + fseek(capfile , 0, SEEK_END); + caplen= ftell(capfile)- sizeof(struct pcap_file_header); + fclose(capfile); + + /* Chek if the timestamps must be respected */ + if(argc == 4 && argv[3][0] == 's') + sync = TRUE; + else + sync = FALSE; + + /* Open the capture */ + /* Create the source string according to the new WinPcap syntax */ + if ( pcap_createsrcstr( source, // variable that will keep the source string + PCAP_SRC_FILE, // we want to open a file + NULL, // remote host + NULL, // port on the remote host + argv[1], // name of the file we want to open + errbuf // error buffer + ) != 0) + { + fprintf(stderr,"\nError creating a source string\n"); + return; + } + + /* Open the capture file */ + if ( (indesc= pcap_open(source, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL) + { + fprintf(stderr,"\nUnable to open the file %s.\n", source); + return; + } + + /* Open the output adapter */ + if ( (outdesc= pcap_open(argv[2], 100, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL) + { + fprintf(stderr,"\nUnable to open adapter %s.\n", source); + return; + } + + /* Check the MAC type */ + if (pcap_datalink(indesc) != pcap_datalink(outdesc)) + { + printf("Warning: the datalink of the capture differs from the one of the selected interface.\n"); + printf("Press a key to continue, or CTRL+C to stop.\n"); + getchar(); + } + + /* Allocate a send queue */ + squeue = pcap_sendqueue_alloc(caplen); + + /* Fill the queue with the packets from the file */ + while ((res = pcap_next_ex( indesc, &pktheader, &pktdata)) == 1) + { + if (pcap_sendqueue_queue(squeue, pktheader, pktdata) == -1) + { + printf("Warning: packet buffer too small, not all the packets will be sent.\n"); + break; + } + + npacks++; + } + + if (res == -1) + { + printf("Corrupted input file.\n"); + pcap_sendqueue_destroy(squeue); + return; + } + + /* Transmit the queue */ + + cpu_time = (float)clock (); + + if ((res = pcap_sendqueue_transmit(outdesc, squeue, sync)) < squeue->len) + { + printf("An error occurred sending the packets: %s. Only %d bytes were sent\n", pcap_geterr(outdesc), res); + } + + cpu_time = (clock() - cpu_time)/CLK_TCK; + + printf ("\n\nElapsed time: %5.3f\n", cpu_time); + printf ("\nTotal packets generated = %d", npacks); + printf ("\nAverage packets per second = %d", (int)((double)npacks/cpu_time)); + printf ("\n"); + + /* free the send queue */ + pcap_sendqueue_destroy(squeue); + + /* Close the input file */ + pcap_close(indesc); + + /* + * lose the output adapter + * IMPORTANT: remember to close the adapter, otherwise there will be no guarantee that all the + * packets will be sent! + */ + pcap_close(outdesc); + + + return; +} + + +void usage() +{ + + printf("\nSendcap, sends a libpcap/tcpdump capture file to the net. Copyright (C) 2002 Loris Degioanni.\n"); + printf("\nUsage:\n"); + printf("\t sendcap file_name adapter [s]\n"); + printf("\nParameters:\n"); + printf("\nfile_name: the name of the dump file that will be sent to the network\n"); + printf("\nadapter: the device to use. Use \"WinDump -D\" for a list of valid devices\n"); + printf("\ns: if present, forces the packets to be sent synchronously, i.e. respecting the timestamps in the dump file. This option will work only under Windows NTx.\n\n"); + + exit(0); +} \ No newline at end of file diff --git a/winpcap/Examples/sendcap/sendcap.dsp b/winpcap/Examples/sendcap/sendcap.dsp new file mode 100644 index 0000000..f453aa2 --- /dev/null +++ b/winpcap/Examples/sendcap/sendcap.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="sendcap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=sendcap - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sendcap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sendcap.mak" CFG="sendcap - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sendcap - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "sendcap - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sendcap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "PCAP_DONT_INCLUDE_PCAP_BPF_H" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "sendcap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "PCAP_DONT_INCLUDE_PCAP_BPF_H" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "sendcap - Win32 Release" +# Name "sendcap - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\sendcap.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/smp_1/smp_1.c b/winpcap/Examples/smp_1/smp_1.c new file mode 100644 index 0000000..46be604 --- /dev/null +++ b/winpcap/Examples/smp_1/smp_1.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include + +#include + + +main(int argc, char **argv) +{ +pcap_if_t *alldevs, *d; +pcap_t *fp; +u_int inum, i=0; +char errbuf[PCAP_ERRBUF_SIZE]; +int res; +struct pcap_pkthdr *header; +const u_char *pkt_data; +struct pcap_pkthdr old; + +char a[11]; + + printf("SMP_1\n"); + printf("\nThis program tests the WinPcap kernel driver on SMP machines.\n"); + printf("The program tests that timestamps on the captured packets are consistent,\n"); + printf("and that the caplen is equal to the packet length.\n"); + printf("If there is an error, it will print out a message saying \"Inconsistent XXX\"\n"); + + if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for(d=alldevs; d; d=d->next) + { + printf("%d. %s", ++i, d->name); + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if(i==0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return -1; + } + + printf("Enter the interface number (1-%d):",i); + scanf("%d", &inum); + + if(inum < 1 || inum > i) + { + printf("\nInterface number out of range.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + /* Jump to the selected adapter */ + for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); + + /* Open the device */ + if ( (fp= pcap_open(d->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL) + { + fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + old.ts.tv_sec=0; + old.ts.tv_usec=0; + + + /* Read the packets */ + while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0){ + + if(res == 0) + continue; + + //check that caplen is equal to packet length + if (header->caplen!=header->len) + printf("Inconsistent header: CapLen %d\t Len %d\n",header->caplen,header->len); + + //check that timestamps always grow + if ( old.ts.tv_sec > header->ts.tv_sec || (old.ts.tv_sec == header->ts.tv_sec && old.ts.tv_usec > header->ts.tv_usec)) + printf("Inconsistent Timestamps! Old was %d.%.06d - New is %d.%.06d\n",old.ts.tv_sec,old.ts.tv_usec, header->ts.tv_sec,header->ts.tv_usec); + + old=*header; + + } + + if(res == -1){ + printf("Error reading the packets: %s\n", pcap_geterr(fp)); + return -1; + } + + scanf("%s",a); + + return 0; +} diff --git a/winpcap/Examples/smp_1/smp_1.dsp b/winpcap/Examples/smp_1/smp_1.dsp new file mode 100644 index 0000000..55c1753 --- /dev/null +++ b/winpcap/Examples/smp_1/smp_1.dsp @@ -0,0 +1,102 @@ +# Microsoft Developer Studio Project File - Name="smp_1" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=smp_1 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "smp_1.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "smp_1.mak" CFG="smp_1 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "smp_1 - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "smp_1 - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "smp_1 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wpcap.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\lib" + +!ELSEIF "$(CFG)" == "smp_1 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wpcap.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\lib" + +!ENDIF + +# Begin Target + +# Name "smp_1 - Win32 Release" +# Name "smp_1 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\SMP_1.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/winpcap/Examples/smp_1/smp_1.dsw b/winpcap/Examples/smp_1/smp_1.dsw new file mode 100644 index 0000000..cc63468 --- /dev/null +++ b/winpcap/Examples/smp_1/smp_1.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "smp_1"=.\smp_1.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Examples/tcptop/tcptop.c b/winpcap/Examples/tcptop/tcptop.c new file mode 100644 index 0000000..2ea2222 --- /dev/null +++ b/winpcap/Examples/tcptop/tcptop.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include + +void usage(); + +void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *); + + +void main(int argc, char **argv) +{ +pcap_t *fp; +char errbuf[PCAP_ERRBUF_SIZE]; +struct timeval st_ts; +u_int netmask; +struct bpf_program fcode; + + /* Check the validity of the command line */ + if (argc != 2) + { + usage(); + return; + } + + /* Open the output adapter */ + if ( (fp= pcap_open(argv[1], 100, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL) + { + fprintf(stderr,"\nUnable to open adapter %s.\n", errbuf); + return; + } + + /* Don't care about netmask, it won't be used for this filter */ + netmask=0xffffff; + + //compile the filter + if (pcap_compile(fp, &fcode, "tcp", 1, netmask) <0 ) + { + fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n"); + /* Free the device list */ + return; + } + + //set the filter + if (pcap_setfilter(fp, &fcode)<0) + { + fprintf(stderr,"\nError setting the filter.\n"); + pcap_close(fp); + /* Free the device list */ + return; + } + + /* Put the interface in statstics mode */ + if (pcap_setmode(fp, MODE_STAT)<0) + { + fprintf(stderr,"\nError setting the mode.\n"); + pcap_close(fp); + /* Free the device list */ + return; + } + + + printf("TCP traffic summary:\n"); + + /* Start the main loop */ + pcap_loop(fp, 0, dispatcher_handler, (PUCHAR)&st_ts); + + pcap_close(fp); + return; +} + +void dispatcher_handler(u_char *state, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + struct timeval *old_ts = (struct timeval *)state; + u_int delay; + LARGE_INTEGER Bps,Pps; + struct tm *ltime; + char timestr[16]; + time_t local_tv_sec; + + /* Calculate the delay in microseconds from the last sample. */ + /* This value is obtained from the timestamp that the associated with the sample. */ + delay=(header->ts.tv_sec - old_ts->tv_sec) * 1000000 - old_ts->tv_usec + header->ts.tv_usec; + /* Get the number of Bits per second */ + Bps.QuadPart=(((*(LONGLONG*)(pkt_data + 8)) * 8 * 1000000) / (delay)); + /* ^ ^ + | | + | | + | | + converts bytes in bits -- | + | + delay is expressed in microseconds -- + */ + + /* Get the number of Packets per second */ + Pps.QuadPart=(((*(LONGLONG*)(pkt_data)) * 1000000) / (delay)); + + /* Convert the timestamp to readable format */ + local_tv_sec = header->ts.tv_sec; + ltime=localtime(&local_tv_sec); + strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); + + /* Print timestamp*/ + printf("%s ", timestr); + + /* Print the samples */ + printf("BPS=%I64u ", Bps.QuadPart); + printf("PPS=%I64u\n", Pps.QuadPart); + + //store current timestamp + old_ts->tv_sec=header->ts.tv_sec; + old_ts->tv_usec=header->ts.tv_usec; +} + + +void usage() +{ + + printf("\nShows the TCP traffic load, in bits per second and packets per second.\nCopyright (C) 2002 Loris Degioanni.\n"); + printf("\nUsage:\n"); + printf("\t tcptop adapter\n"); + printf("\t You can use \"WinDump -D\" if you don't know the name of your adapters.\n"); + + exit(0); +} \ No newline at end of file diff --git a/winpcap/Examples/tcptop/tcptop.dsp b/winpcap/Examples/tcptop/tcptop.dsp new file mode 100644 index 0000000..ab7ee25 --- /dev/null +++ b/winpcap/Examples/tcptop/tcptop.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="tcptop" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=tcptop - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "tcptop.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "tcptop.mak" CFG="tcptop - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "tcptop - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "tcptop - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "tcptop - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "tcptop - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../lbl/" /I "../../Include/" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_UNICODE" /D "WPCAP" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "tcptop - Win32 Release" +# Name "tcptop - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\tcptop.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pcap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\lib\Wpcap.lib +# End Source File +# End Target +# End Project diff --git a/winpcap/Examples/tcptop/tcptop.dsw b/winpcap/Examples/tcptop/tcptop.dsw new file mode 100644 index 0000000..4abe52e --- /dev/null +++ b/winpcap/Examples/tcptop/tcptop.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "tcptop"=.\tcptop.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Packet9x/DLL/Packet.def b/winpcap/Packet9x/DLL/Packet.def new file mode 100644 index 0000000..609d62d --- /dev/null +++ b/winpcap/Packet9x/DLL/Packet.def @@ -0,0 +1,41 @@ +LIBRARY Packet.dll + +DESCRIPTION 'Packet driver dll' + +EXPORTS + PacketLibraryVersion + PacketGetVersion + PacketGetDriverVersion + PacketOpenAdapter + PacketInitPacket + PacketAllocatePacket + PacketSendPacket + PacketResetAdapter + PacketReceivePacket + PacketWaitPacket + PacketCloseAdapter + PacketSetHwFilter + PacketFreePacket + PacketGetAdapterNames + PacketRequest + StartPacketDriver + StopPacketDriver + PacketSetBuff + PacketSetBpf + PacketGetStats + PacketGetStatsEx + PacketGetNetType + PacketSetReadTimeout + PacketSetMode + PacketSetNumWrites + PacketGetNetInfo + PacketGetNetInfoEx + PacketSetMinToCopy + PacketGetReadEvent + PacketSetDumpName + PacketSetDumpLimits + PacketIsDumpEnded + PacketSendPackets + PacketSetSnapLen + PacketSetLoopbackBehavior + PacketGetAirPcapHandle \ No newline at end of file diff --git a/winpcap/Packet9x/DLL/Packet32.c b/winpcap/Packet9x/DLL/Packet32.c new file mode 100644 index 0000000..8c77f51 --- /dev/null +++ b/winpcap/Packet9x/DLL/Packet32.c @@ -0,0 +1,1234 @@ +/* + * Copyright (c) 1999 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include +#include +#include +#include +#ifdef __MINGW32__ +#ifdef DBG +#include +#define _ASSERTE assert +#else +#define _ASSERTE +#endif /* DBG */ +#else +#include +#endif /* __MINGW32__ */ + +#include "../../version.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +TCHAR szWindowTitle[] = TEXT ("PACKET.DLL"); +LPADAPTER lpTheAdapter = NULL; + +#if _DBG +#define ODS(_x) OutputDebugString(TEXT(_x)) +#define ODSEx(_x, _y) +#else +#ifdef _DEBUG_TO_FILE +#include +// Macro to print a debug string. The behavior differs depending on the debug level +#define ODS(_x) { \ + FILE *f; \ + f = fopen("winpcap_debug.txt", "a"); \ + fprintf(f, "%s", _x); \ + fclose(f); \ +} +// Macro to print debug data with the printf convention. The behavior differs depending on */ +#define ODSEx(_x, _y) { \ + FILE *f; \ + f = fopen("winpcap_debug.txt", "a"); \ + fprintf(f, _x, _y); \ + fclose(f); \ +} + +#else +#define ODS(_x) +#define ODSEx(_x, _y) +#endif +#endif + +typedef DWORD(CALLBACK* OPENVXDHANDLE)(HANDLE); + +BOOLEAN StartPacketDriver (LPTSTR ServiceName); +BOOLEAN StopPacketDriver (void); +BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject); + +char PacketLibraryVersion[] = WINPCAP_PACKET9x_STRING_VERSION; + +//--------------------------------------------------------------------------- + +PCHAR PacketGetVersion() +{ + return PacketLibraryVersion; +} + +//--------------------------------------------------------------------------- + +PCHAR PacketGetDriverVersion() +{ + return PacketLibraryVersion; +} + +//--------------------------------------------------------------------------- +BOOL APIENTRY DllMain (HANDLE hModule, + DWORD dwReason, + LPVOID lpReserved) +{ + BOOL Status; + + ODS ("Packet32: DllEntry\n"); + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + Status = StartPacketDriver (TEXT ("PACKET")); + break; + case DLL_PROCESS_DETACH: + Status = StopPacketDriver (); + break; + default: + Status = TRUE; + break; + } + return Status; +} + +//--------------------------------------------------------------------------- +BOOL PacketDeviceIoControl (LPADAPTER lpAdapterObject, + LPPACKET lpPacket, + ULONG ulIoctl, + BOOLEAN bSync) +{ + BOOLEAN Result; + DWORD Error; + + ODS ("Packet32: PacketDeviceIoControl\n"); + _ASSERTE (lpAdapterObject != NULL); + _ASSERTE (lpPacket != NULL); + lpPacket->OverLapped.Offset = 0; + lpPacket->OverLapped.OffsetHigh = 0; + lpPacket->ulBytesReceived = 0; + if (!ResetEvent (lpPacket->OverLapped.hEvent)) + { + lpPacket->bIoComplete = FALSE; + return FALSE; + } + + Result = DeviceIoControl (lpAdapterObject->hFile, + ulIoctl, + lpPacket->Buffer, + lpPacket->Length, + lpPacket->Buffer, + lpPacket->Length, + &(lpPacket->ulBytesReceived), + &(lpPacket->OverLapped)); + Error=GetLastError () ; + + if (!Result && bSync) + { + if (Error == ERROR_IO_PENDING) + { + Result = GetOverlappedResult (lpAdapterObject->hFile, + &(lpPacket->OverLapped), + &(lpPacket->ulBytesReceived), + TRUE); + } + else + ODS ("Packet32: unsupported API call return error!\n"); + } + + lpPacket->bIoComplete = Result; + + return Result; +} + + +//--------------------------------------------------------------------------- + +LPADAPTER PacketOpenAdapter (LPTSTR AdapterName) +{ + LPPACKET lpSupport; + LPADAPTER nAdapter; + DWORD error; + BOOL res; + OPENVXDHANDLE OpenVxDHandle; + DWORD KernEvent; + UINT BytesReturned; + struct _timeb time; + + ODSEx ("Packet32: PacketOpenAdapter, opening %s\n", AdapterName); + + nAdapter = (LPADAPTER) GlobalAllocPtr (GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof (ADAPTER)); + if (nAdapter == NULL) + { + error=GetLastError(); + ODS ("Packet32: PacketOpenAdapter GlobalAlloc Failed\n"); + ODSEx("Error=%d\n",error); + //set the error to the one on which we failed + SetLastError(error); + return NULL; + } + wsprintf (nAdapter->SymbolicLink, + TEXT ("\\\\.\\%s"), + TEXT ("NPF.VXD")); + nAdapter->hFile = CreateFile (nAdapter->SymbolicLink, + GENERIC_WRITE | GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE, + 0); + + if (nAdapter->hFile == INVALID_HANDLE_VALUE) + { + error=GetLastError(); + ODS ("Packet32: PacketOpenAdapter Could not open adapter, 1\n"); + ODSEx("Error=%d\n",error); + GlobalFreePtr (nAdapter); + //set the error to the one on which we failed + SetLastError(error); + return NULL; + } + + lpSupport=PacketAllocatePacket(); + + PacketInitPacket(lpSupport,AdapterName,strlen(AdapterName)); + if (nAdapter && (nAdapter->hFile != INVALID_HANDLE_VALUE)) + { + res=PacketDeviceIoControl(nAdapter, + lpSupport, + (ULONG) IOCTL_OPEN, + TRUE); + if (res==FALSE || ((char*)lpSupport->Buffer)[0]=='\0'){ + SetLastError(ERROR_FILE_NOT_FOUND); + goto err; + } + PacketFreePacket(lpSupport); + + // Set the time zone + _ftime(&time); + if(DeviceIoControl(nAdapter->hFile,pBIOCSTIMEZONE,&time.timezone,2,NULL,0,&BytesReturned,NULL)==FALSE){ + error=GetLastError(); + ODS ("Packet32: PacketOpenAdapter Could not open adapter, 2\n"); + ODSEx("Error=%d\n",error); + GlobalFreePtr (nAdapter); + //set the error to the one on which we failed + SetLastError(error); + return NULL; + } + + // create the read event + nAdapter->ReadEvent=CreateEvent(NULL, TRUE, FALSE, NULL); + // obtain the pointer of OpenVxDHandle in KERNEL32.DLL. + // It is not possible to reference statically this function, because it is present only in Win9x + OpenVxDHandle = (OPENVXDHANDLE) GetProcAddress(GetModuleHandle("KERNEL32"),"OpenVxDHandle"); + // map the event to kernel mode + KernEvent=(DWORD)(OpenVxDHandle)(nAdapter->ReadEvent); + // pass the event to the driver + if(DeviceIoControl(nAdapter->hFile,pBIOCEVNAME,&KernEvent,4,NULL,0,&BytesReturned,NULL)==FALSE){ + error=GetLastError(); + ODS("Packet32: PacketOpenAdapter Could not open adapter, 3\n"); + ODSEx("Error=%d\n",error); + GlobalFreePtr (nAdapter); + //set the error to the one on which we failed + SetLastError(error); + return NULL; + } + + //set the maximum lookhahead size allowable with this NIC driver + PacketSetMaxLookaheadsize(nAdapter); + + //set the number of times a single write will be repeated + PacketSetNumWrites(nAdapter,1); + + return nAdapter; + } +err: + error=GetLastError(); + ODS ("Packet32: PacketOpenAdapter Could not open adapter, 4\n"); + ODSEx("Error=%d\n",error); + //set the error to the one on which we failed + SetLastError(error); + return NULL; +} + +//--------------------------------------------------------------------------- +/* Function to set the working mode of the driver +mode working mode +*/ + +BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode) +{ + int BytesReturned; + + return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL); +} + +//--------------------------------------------------------------------------- +/* Function to get the the read event*/ + +HANDLE PacketGetReadEvent(LPADAPTER AdapterObject) +{ + return AdapterObject->ReadEvent; +} + +//--------------------------------------------------------------------------- +/* Function to set the the number of times a write will be repeated*/ + +BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites) +{ + AdapterObject->NumWrites=nwrites; + return TRUE; +} + +//--------------------------------------------------------------------------- +/* This function is used to set the read timeout +timeout value of timeout(milliseconds). 0 means infinite. +*/ + +BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout) +{ + int BytesReturned; + return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&timeout,4,NULL,0,&BytesReturned,NULL); +} + +//--------------------------------------------------------------------------- +/* This function allows to set the dimension of the packet buffer in the driver +parameters: +dim dimension of the buffer (kilobytes) +*/ + +BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim) +{ + int BytesReturned; + return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL); +} + +//--------------------------------------------------------------------------- +/* Function to set the minimum amount of bytes that will be copied by the driver*/ + +BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes) +{ + // not yet implemented in Windows 9x + return TRUE; +} + +//--------------------------------------------------------------------------- +/* Function to set a bpf filter in the driver +parameters: +fp the pointer to the beginning of the filtering program +*/ + +BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp) +{ + int BytesReturned; + + return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL); +} + + + +//--------------------------------------------------------------------------- + +BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s) +{ + int BytesReturned; + + return DeviceIoControl(AdapterObject->hFile,pBIOCGSTATS,NULL,0,s,sizeof(struct bpf_stat),&BytesReturned,NULL); +} + +//--------------------------------------------------------------------------- + +BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s) +{ + int BytesReturned; + + return DeviceIoControl(AdapterObject->hFile,pBIOCGSTATS,NULL,0,s,sizeof(struct bpf_stat),&BytesReturned,NULL); +} + +//--------------------------------------------------------------------------- +VOID PacketCloseAdapter (LPADAPTER lpAdapter) +{ + + ODS ("Packet32: PacketCloseAdapter\n"); + + // close the capture handle + CloseHandle (lpAdapter->hFile); + + // close the read event + CloseHandle (lpAdapter->ReadEvent); + + GlobalFreePtr (lpAdapter); + lpAdapter = NULL; + +} + +//--------------------------------------------------------------------------- +LPPACKET PacketAllocatePacket (void) +{ + LPPACKET lpPacket; + + lpPacket = (LPPACKET) GlobalAllocPtr ( + GMEM_MOVEABLE | GMEM_ZEROINIT, + sizeof (PACKET)); + if (lpPacket == NULL) + { + ODS ("Packet32: PacketAllocatePacket: GlobalAlloc Failed\n"); + return NULL; + } + lpPacket->OverLapped.hEvent = CreateEvent (NULL, + FALSE, + FALSE, + NULL); + if (lpPacket->OverLapped.hEvent == NULL) + { + ODS ("Packet32: PacketAllocatePacket: CreateEvent Failed\n"); + GlobalFreePtr (lpPacket); + return NULL; + } + lpPacket->Buffer=NULL; + lpPacket->Length=0; + lpPacket->ulBytesReceived = 0; + lpPacket->bIoComplete = FALSE; + + return lpPacket; +} + +//--------------------------------------------------------------------------- +VOID PacketFreePacket (LPPACKET lpPacket) +{ + CloseHandle (lpPacket->OverLapped.hEvent); + GlobalFreePtr (lpPacket); +} + +//--------------------------------------------------------------------------- +VOID PacketInitPacket (LPPACKET lpPacket, + PVOID Buffer, + UINT Length) +{ + lpPacket->Buffer = Buffer; + lpPacket->Length = Length; +} + +//--------------------------------------------------------------------------- +BOOLEAN PacketSendPacket (LPADAPTER AdapterObject, + LPPACKET lpPacket, + BOOLEAN Sync) +{ + int i; + for(i=0;iNumWrites;i++){ + if(PacketDeviceIoControl (AdapterObject,lpPacket,(ULONG) IOCTL_PROTOCOL_WRITE,Sync)==FALSE) + return FALSE; + } + + return TRUE; +} + +//--------------------------------------------------------------------------- +// Emulated at user-level under Win9x + +INT PacketSendPackets(LPADAPTER AdapterObject, + PVOID PacketBuff, + ULONG Size, + BOOLEAN Sync) +{ + struct dump_bpf_hdr *winpcap_hdr; + PCHAR EndOfUserBuff = (PCHAR)PacketBuff + Size; + LPPACKET PacketToSend; + BOOLEAN res; + + // Start from the first packet + winpcap_hdr = (struct dump_bpf_hdr*)PacketBuff; + + if( (PCHAR)winpcap_hdr + winpcap_hdr->caplen + sizeof(struct dump_bpf_hdr) > EndOfUserBuff ) + { + // Malformed buffer + return 0; + } + + while( TRUE ){ + + if(winpcap_hdr->caplen ==0 || winpcap_hdr->caplen > 65536) + { + // Malformed header + return 0; + } + + // Set up the LPPACKET structure + PacketToSend=PacketAllocatePacket(); + PacketInitPacket(PacketToSend, + (PCHAR)winpcap_hdr + sizeof(struct dump_bpf_hdr), + winpcap_hdr->caplen); + + // Send the packet + res = PacketSendPacket (AdapterObject, PacketToSend, TRUE); + + // Free the just used LPPACKET structure + PacketFreePacket(PacketToSend); + + if(res == FALSE){ + // Error sending the packet + return (PCHAR)winpcap_hdr - (PCHAR)PacketBuff; + } + + + // Step to the next packet in the buffer + (PCHAR)winpcap_hdr += winpcap_hdr->caplen + sizeof(struct dump_bpf_hdr); + + // Check if the end of the user buffer has been reached + if( (PCHAR)winpcap_hdr >= EndOfUserBuff ) + { + return (PCHAR)winpcap_hdr - (PCHAR)PacketBuff; + } + } +} + +//--------------------------------------------------------------------------- +BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject, + LPPACKET lpPacket, + BOOLEAN Sync) +{ + return PacketDeviceIoControl(AdapterObject, + lpPacket, + (ULONG) IOCTL_PROTOCOL_READ, + Sync); + +} + + +//--------------------------------------------------------------------------- +BOOLEAN PacketWaitPacket (LPADAPTER AdapterObject, + LPPACKET lpPacket) +{ + lpPacket->bIoComplete = GetOverlappedResult( AdapterObject->hFile, + &lpPacket->OverLapped, + &lpPacket->ulBytesReceived, + TRUE ); + + return lpPacket->bIoComplete; + +} + +//--------------------------------------------------------------------------- +BOOLEAN PacketResetAdapter (LPADAPTER AdapterObject) +{ + UINT BytesReturned; + DeviceIoControl ( + AdapterObject->hFile, + (DWORD) IOCTL_PROTOCOL_RESET, + NULL, + 0, + NULL, + 0, + &BytesReturned, + NULL); + return TRUE; +} + +//--------------------------------------------------------------------------- +BOOLEAN PacketRequest (LPADAPTER AdapterObject, + BOOLEAN Set, + PPACKET_OID_DATA OidData) +{ + UINT BytesReturned; + BOOLEAN Result; + OVERLAPPED Overlap; + + ODS ("Packet32: PacketRequest\n"); + _ASSERTE (AdapterObject != NULL); + _ASSERTE (OidData != NULL); + _ASSERTE (OidData->Data != NULL); + Overlap.Offset = 0; + Overlap.OffsetHigh = 0; + Overlap.hEvent = CreateEvent (NULL, + FALSE, + FALSE, + NULL); + if (Overlap.hEvent == NULL) + { + ODS ("Packet32: PacketRequestPacket: CreateEvent Failed\n"); + return FALSE; + } + if (!ResetEvent(Overlap.hEvent)) + { + ODS ("Packet32: PacketRequestPacket: ResetEvent Failed\n"); + CloseHandle(Overlap.hEvent); + return FALSE; + } + Result = DeviceIoControl ( + AdapterObject->hFile, + (DWORD) Set ? pBIOCSETOID : pBIOCQUERYOID, + OidData, + sizeof (PACKET_OID_DATA) - 1 + OidData->Length, + OidData, + sizeof (PACKET_OID_DATA) - 1 + OidData->Length, + &BytesReturned, + &Overlap); + if (!Result) + { + if (GetLastError() == ERROR_IO_PENDING) + { + Result = GetOverlappedResult(AdapterObject->hFile, + &Overlap, + &BytesReturned, + TRUE); + } + else + { + ODS("Packet32: Unssupported API call return error!\n"); + } + } + if (BytesReturned == 0) + { + // There was an ndis error + ODS ("Packet32: Ndis returned error to OID\n"); + Result = FALSE; + } + + CloseHandle(Overlap.hEvent); + return Result; +} + +//--------------------------------------------------------------------------- +BOOLEAN PacketSetHwFilter (LPADAPTER AdapterObject, + ULONG Filter) +{ + BOOLEAN Status; + ULONG IoCtlBufferLength = (sizeof (PACKET_OID_DATA) + sizeof (ULONG) - 1); + PPACKET_OID_DATA OidData; + + ODS ("Packet32: PacketSetFilter\n"); + _ASSERTE (AdapterObject != NULL); + OidData = GlobalAllocPtr ( + GMEM_MOVEABLE | GMEM_ZEROINIT, + IoCtlBufferLength + ); + if (OidData == NULL) + { + return FALSE; + } + OidData->Oid = OID_GEN_CURRENT_PACKET_FILTER; + OidData->Length = sizeof (ULONG); + *((PULONG) OidData->Data) = Filter; + Status = PacketRequest ( + AdapterObject, + TRUE, + OidData + ); + GlobalFreePtr (OidData); + return Status; +} +//--------------------------------------------------------------------------- +BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type) +{ + BOOLEAN Status; + ULONG IoCtlBufferLength = (sizeof (PACKET_OID_DATA) + sizeof (ULONG) - 1); + PPACKET_OID_DATA OidData; + + ODS ("Packet32: PacketSetFilter\n"); + _ASSERTE (AdapterObject != NULL); + OidData = GlobalAllocPtr ( + GMEM_MOVEABLE | GMEM_ZEROINIT, + IoCtlBufferLength + ); + if (OidData == NULL) + { + return FALSE; + } + //get the link-layer type + OidData->Oid = OID_GEN_MEDIA_IN_USE; + OidData->Length = sizeof (ULONG); + Status = PacketRequest(AdapterObject,FALSE,OidData); + if(Status==FALSE)return FALSE; + + type->LinkType=*((UINT*)OidData->Data); + + //get the link-layer speed + OidData->Oid = OID_GEN_LINK_SPEED; + OidData->Length = sizeof (ULONG); + Status = PacketRequest(AdapterObject,FALSE,OidData); + type->LinkSpeed=*((UINT*)OidData->Data)*100; + GlobalFreePtr (OidData); + return Status; +} + +//--------------------------------------------------------------------------- +BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject) +{ + BOOLEAN Status; + ULONG IoCtlBufferLength = (sizeof (PACKET_OID_DATA) + sizeof (ULONG) - 1); + PPACKET_OID_DATA OidData; + + ODS ("Packet32: PacketSetFilter\n"); + _ASSERTE (AdapterObject != NULL); + OidData = GlobalAllocPtr ( + GMEM_MOVEABLE | GMEM_ZEROINIT, + IoCtlBufferLength + ); + if (OidData == NULL) + { + return FALSE; + } + //set the size of the lookahead buffer to the maximum available by the the NIC driver + OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD; + OidData->Length=sizeof(ULONG); + Status=PacketRequest(AdapterObject,FALSE,OidData); + OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD; + Status=PacketRequest(AdapterObject,TRUE,OidData); + GlobalFreePtr(OidData); + return Status; +} + +//--------------------------------------------------------------------------- + +BOOLEAN StartPacketDriver (LPTSTR lpstrServiceName) +{ + + ODS ("Packet32: StartPacketDriver\n"); + + return TRUE; +} + +//--------------------------------------------------------------------------- +BOOLEAN StopPacketDriver(void) +{ + + ODS ("Packet32: StopPacketDriver\n"); + + return TRUE; +} + +//--------------------------------------------------------------------------- + +INT PacketSetSnapLen(LPADAPTER AdapterObject, int snaplen) +{ + ODS ("Packet32: PacketSetSnapLen\n"); + + return 0; +} + +//--------------------------------------------------------------------------- + +BOOLEAN PacketGetAdapterNames (PTSTR pStr, + PULONG BufferSize) +{ + ULONG Result,i; + LONG Status; + char* pStrInternal; + + ULONG RemainingBytes; + + LPADAPTER adapter; + PPACKET_OID_DATA OidData; + HKEY Key; + char NdisName[80]; + ULONG NeededBytes; + ULONG NeededBytesForString; + char TempBuffer[1024]; + BOOLEAN retVal; + + OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,256); + if (OidData == NULL) + { + return FALSE; + } + + Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\class\\net",0,KEY_READ,&Key); + + if (Status != ERROR_SUCCESS) + { + GlobalFree(OidData); + return FALSE; + } + + NeededBytes = 0; + + //first we calculate the needed bytes + i=0; + while((Result=RegEnumKey(Key,i,NdisName,sizeof(NdisName) - sizeof("\\NDIS") - 1))==ERROR_SUCCESS) + { + HKEY hKeyNdisName; + strcat(NdisName,"\\NDIS"); + + Status=RegOpenKeyEx(Key,NdisName,0,KEY_READ,&hKeyNdisName); + + if (Status != ERROR_SUCCESS) + { + i++; + continue; + } + + //we need to tell RegOpenKeyEx the length of the buffer passed as argument + NeededBytesForString = sizeof(TempBuffer); + + Status=RegQueryValueEx(hKeyNdisName,"LOGDRIVERNAME",NULL,NULL,(LPBYTE)TempBuffer,&NeededBytesForString); + + if (Status != ERROR_SUCCESS) + { + RegCloseKey(hKeyNdisName); + i++; + continue; + } + + NeededBytes += NeededBytesForString; + + //we try to open the adapter and retrieve its name + adapter=PacketOpenAdapter(TempBuffer); + if(adapter==NULL) + { + NeededBytes += sizeof("Unknown") + 1; + } + else + { + //we retrieve its name by performing a PacketRequest, + //the buffer that will contain the name is at the end of the OidData structure + OidData->Oid = OID_GEN_VENDOR_DESCRIPTION; + OidData->Length = 256 - sizeof(PACKET_OID_DATA); + Status = PacketRequest(adapter,FALSE,OidData); + if(Status==0) + { + NeededBytes += sizeof("Unknown") + 1; + } + else + { + NeededBytes += strlen((char*) OidData->Data) + 1; + } + + PacketCloseAdapter(adapter); + + } + + i++; + RegCloseKey(hKeyNdisName); + } + + NeededBytes += 1 + 1; //the two nulls at the end of each block of strings + + if (NeededBytes > *BufferSize || pStr == NULL || Result != ERROR_NO_MORE_ITEMS) + { + *BufferSize = NeededBytes; + GlobalFree(OidData); + RegCloseKey(Key); + + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + + //now we copy the strings + + retVal = TRUE; + NeededBytes = 0; + i = 0; + pStrInternal = pStr; + RemainingBytes = *BufferSize; + while((Result=RegEnumKey(Key,i,NdisName,sizeof(NdisName) - sizeof("\\NDIS") - 1))==ERROR_SUCCESS) + { + HKEY hKeyNdisName; + strcat(NdisName,"\\NDIS"); + NeededBytesForString = sizeof(TempBuffer); + + Status=RegOpenKeyEx(Key,NdisName,0,KEY_READ,&hKeyNdisName); + + if (Status != ERROR_SUCCESS) + { + i++; + continue; + } + + Status=RegQueryValueEx(hKeyNdisName,"LOGDRIVERNAME",NULL,NULL,(LPBYTE)TempBuffer,&NeededBytesForString); + + if (Status == ERROR_SUCCESS && NeededBytesForString <= RemainingBytes) + { + //this copy is safe, since we have checked that the available space will fit the string + strcpy(pStrInternal, TempBuffer); + pStrInternal += NeededBytesForString; + RemainingBytes -= NeededBytesForString; + } + + NeededBytes += NeededBytesForString; //just in case the second scan returns a larger number of adapters!! + + i++; + RegCloseKey(hKeyNdisName); + } + + RegCloseKey(Key); + + //we need to properly terminate the list of adapter names with another \0 + if (RemainingBytes > 0) + { + pStrInternal[0] = 0; + pStrInternal++; + RemainingBytes--; + } + NeededBytes++; + + while (*pStr != 0) //now we scan again the list of adapters in pStr to retrieve their names + { + adapter=PacketOpenAdapter(pStr); + if(adapter==NULL) + { + if ( RemainingBytes < sizeof("Unknown") + 1 ) + retVal = FALSE; //we do not copy anything, we simply skip this adapter, and return failure + else + { //this copy is safe as we have checked that the remaining bytes will fit the source string + strcpy(pStrInternal, "Unknown"); + //we move the pointer of the list of adapter names + pStrInternal += sizeof("Unknown") + 1; + RemainingBytes -= sizeof("Unknown") + 1; + } + + //we continue to keep track of available bytes. This is used if we fail in this phase + NeededBytes += sizeof("Unknown") + 1; + } + else + { + OidData->Oid = OID_GEN_VENDOR_DESCRIPTION; + OidData->Length = 256 - sizeof(PACKET_OID_DATA); + Status = PacketRequest(adapter,FALSE,OidData); + if(Status==0) + { + if ( RemainingBytes < sizeof("Unknown") + 1 ) + retVal = FALSE; //we do not copy anything, we simply skip this adapter, and return failure + else + { //this copy is safe as we have checked that the remaining bytes will fit the source string + strcpy(pStrInternal, "Unknown"); + //we move the pointer of the list of adapter names + pStrInternal += sizeof("Unknown") + 1; + RemainingBytes -= sizeof("Unknown") + 1; + } + + //we continue to keep track of available bytes. This is used if we fail in this phase + NeededBytes += sizeof("Unknown") + 1; + } + else + { + if ( RemainingBytes < strlen((char*) OidData->Data) + 1 ) + retVal = FALSE; //we do not copy anything, we simply skip this adapter, and return failure + else + { + //this copy is safe as we have checked that the remaining bytes will fit the source string + strcpy(pStrInternal, (char*)OidData->Data); + //we move the pointer of the list of adapter names + pStrInternal += strlen((char*) OidData->Data) + 1; + RemainingBytes -= strlen((char*) OidData->Data) + 1; + } + + //we continue to keep track of available bytes. This is used if we fail in this phase + NeededBytes += strlen((char*) OidData->Data) + 1; + } + + PacketCloseAdapter(adapter); + + } + + //we move to the next adapter in the list. We end when we reach the double \0 + pStr += strlen(pStr) + 1; + + } + + + //we need to properly terminate the list of adapter descriptions with another \0 + if (RemainingBytes > 0) + { + pStrInternal[0] = 0; + pStrInternal++; + RemainingBytes--; + } + else + retVal = FALSE; + + NeededBytes++; + + *BufferSize = NeededBytes; + + GlobalFree(OidData); + + return retVal; +} + +//--------------------------------------------------------------------------- + +BOOLEAN PacketGetNetInfo(LPTSTR AdapterName, PULONG netp, PULONG maskp) +{ + struct hostent* h; + char szBuff[80]; + + if(gethostname(szBuff, 79)) + { + if(WSAGetLastError()==WSANOTINITIALISED){ + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD( 1, 1); + if(WSAStartup( wVersionRequested, &wsaData )!=0) return FALSE; + + if(gethostname(szBuff, 79)) + { + return FALSE; + } + h=gethostbyname(szBuff); + *netp=((h->h_addr_list[0][0]<<24))+ + ((h->h_addr_list[0][1]<<16))+ + ((h->h_addr_list[0][2]<<8))+ + ((h->h_addr_list[0][3])); + if (((*netp)&0x80000000)==0) *maskp=0xFF000000; + else if (((*netp)&0xC0000000)==0x80000000) *maskp=0xFFFF0000; + else if (((*netp)&0xE0000000)==0xC0000000) *maskp=0xFFFFFF00; + else return FALSE; + (*netp)&=*maskp; + return TRUE; + + } + else + { + return FALSE; + } + } + + h=gethostbyname(szBuff); + *netp=((h->h_addr_list[0][0]<<24))+ + ((h->h_addr_list[0][1]<<16))+ + ((h->h_addr_list[0][2]<<8))+ + ((h->h_addr_list[0][3])); + if (((*netp)&0x80000000)==0) *maskp=0xFF000000; + else if (((*netp)&0xC0000000)==0x80000000) *maskp=0xFFFF0000; + else if (((*netp)&0xE0000000)==0xC0000000) *maskp=0xFFFFFF00; + else return FALSE; + (*netp)&=*maskp; + + return TRUE; + +} + +//--------------------------------------------------------------------------- + +/* Convert a ASCII dotted-quad to a 32-bit IP address. + Doesn't check to make sure it's valid. */ + +ULONG inet_addrU(const char *cp) +{ + ULONG val, part; + WCHAR c; + int i; + + val = 0; + for (i = 0; i < 4; i++) { + part = 0; + while ((c = *cp++) != '\0' && c != '.' && c != ',') { + if (c < '0' || c > '9') + return -1; + part = part*10 + (c - '0'); + } + if (part > 255) + return -1; + val = val | (part << i*8); + if (i == 3) { + if (c != '\0' && c != ',') + return -1; // extra gunk at end of string + } else { + if (c == '\0' || c == ',') + return -1; // string ends early + } + } + return val; +} + +//--------------------------------------------------------------------------- + +BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterName, npf_if_addr* buffer, PLONG NEntries) +{ + HKEY InterfaceKey,CycleKey,NdisKey; + LONG status; + TCHAR String[1024+1]; + DWORD RegType; + ULONG BufLen; + struct sockaddr_in *TmpAddr, *TmpBroad; + LONG naddrs,nmasks; + ULONG StringPos; + char CurAdapName[256]; + char NdisName[256]; + ULONG IIndex; + ULONG Result; + + // Reach the class\net registry key + status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\class\\net",0,KEY_READ,&InterfaceKey); + if (status != ERROR_SUCCESS) return FALSE; + + // Scan the subkeys to determine the index of the current adapter + IIndex=0; + while((Result=RegEnumKey(InterfaceKey,IIndex,NdisName,sizeof NdisName))==ERROR_SUCCESS) + { + status=RegOpenKeyEx(InterfaceKey,NdisName,0,KEY_READ,&CycleKey); + status=RegOpenKeyEx(CycleKey,"NDIS",0,KEY_READ,&NdisKey); + BufLen=256; + status=RegQueryValueEx(NdisKey,"LOGDRIVERNAME",NULL,NULL,CurAdapName,&BufLen); + RegCloseKey(CycleKey); + RegCloseKey(NdisKey); + if(!strcmp(AdapterName, CurAdapName)) + break; + IIndex++; + } + + RegCloseKey(InterfaceKey); + + // Reach the Enum\Network\MSTCP registry key and open the key at position IIndex + status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Enum\\Network\\MSTCP",0,KEY_READ,&InterfaceKey); + status=RegEnumKey(InterfaceKey,IIndex,NdisName,sizeof NdisName); + status=RegOpenKeyEx(InterfaceKey,NdisName,0,KEY_READ,&CycleKey); + + if (status != ERROR_SUCCESS) return FALSE; + + BufLen=sizeof NdisName; + status=RegQueryValueEx(CycleKey,"Driver",NULL,NULL,NdisName,&BufLen); + + RegCloseKey(InterfaceKey); + RegCloseKey(CycleKey); + + // Now go to the just obtained NetTrans Entry + status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\class",0,KEY_READ,&InterfaceKey); + status=RegOpenKeyEx(InterfaceKey,NdisName,0,KEY_READ,&CycleKey); + + if (status != ERROR_SUCCESS) return FALSE; + + BufLen = sizeof String; + // Open the key with the addresses + status = RegQueryValueEx(CycleKey,"IPAddress",NULL,&RegType,String,&BufLen); + if (status != ERROR_SUCCESS){ + RegCloseKey(InterfaceKey); + RegCloseKey(CycleKey); + return FALSE; + } + + // scan the key to obtain the addresses + StringPos = 0; + for(naddrs = 0;naddrs < *NEntries;naddrs++){ + TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress); + + if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ + TmpAddr->sin_family = AF_INET; + + TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast); + TmpBroad->sin_family = AF_INET; + // Don't know where to find the broadcast adrr under Win9x, default to 255.255.255.255 + TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; + + while(*(String + StringPos) != '\0' && *(String + StringPos) != ',')StringPos++; + StringPos++; + + if(*(String + StringPos) == 0 || StringPos >= BufLen) + break; + } + else break; + } + + BufLen = sizeof String; + // Open the key with the addresses + status = RegQueryValueEx(CycleKey,"IPMask",NULL,&RegType,String,&BufLen); + if (status != ERROR_SUCCESS){ + RegCloseKey(InterfaceKey); + RegCloseKey(CycleKey); + return FALSE; + } + + // scan the key to obtain the masks + StringPos = 0; + for(nmasks = 0;nmasks <* NEntries;nmasks++){ + TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask); + + if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ + TmpAddr->sin_family = AF_INET; + + while(*(String + StringPos) != '\0' && *(String + StringPos) != ',')StringPos++; + StringPos++; + + if(*(String + StringPos) == 0 || StringPos >= BufLen) + break; + } + else break; + } + + RegCloseKey(InterfaceKey); + RegCloseKey(CycleKey); + + // The number of masks MUST be equal to the number of adresses + if(nmasks != naddrs){ + return FALSE; + } + + *NEntries = naddrs + 1; + + return TRUE; +} + +// not supported in Win9x +BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len) +{ + return FALSE; +} + +// not supported in Win9x +BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks) +{ + return FALSE; +} + +// not supported in Win9x +BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync) +{ + return FALSE; +} + +// not supported in Win9x +BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior) +{ + return FALSE; +} + +// not supported in Win9x +PAirpcapHandle PacketGetAirPcapHandle(LPADAPTER AdapterObject) +{ + return NULL; +} + +//--------------------------------------------------------------------------- + +#ifdef __cplusplus +} +#endif diff --git a/winpcap/Packet9x/DLL/Project/GNUmakefile b/winpcap/Packet9x/DLL/Project/GNUmakefile new file mode 100644 index 0000000..a77c200 --- /dev/null +++ b/winpcap/Packet9x/DLL/Project/GNUmakefile @@ -0,0 +1,23 @@ +# Makefile for cygwin gcc +# Nate Lawson + +# OPTFLAGS = -g -DDBG +OPTFLAGS = -O +# I am suspicious of -O2 since it hosed wpcap.dll. To be safe, use -O only + +CFLAGS = -I ../../../common -shared -mno-cygwin ${OPTFLAGS} +LDFLAGS = -Wl,--out-implib,Packet.a +OBJS = ../Packet32.o +LIBS = -lwsock32 + +Packet.dll: ${OBJS} + ${CC} ${CFLAGS} ${LDFLAGS} -o Packet.dll ../Packet.def ${OBJS} ${LIBS} + +.c.o: + ${CC} ${CFLAGS} -o $*.o -c $< + +clean: + rm -f ${OBJS} Packet.a Packet.dll + +install: Packet.dll + cp Packet.dll c:/windows/system diff --git a/winpcap/Packet9x/DLL/Project/Packet.dsp b/winpcap/Packet9x/DLL/Project/Packet.dsp new file mode 100644 index 0000000..97f543a --- /dev/null +++ b/winpcap/Packet9x/DLL/Project/Packet.dsp @@ -0,0 +1,161 @@ +# Microsoft Developer Studio Project File - Name="Packet" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Packet - Win32 Debug LOG TO FILE +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Packet.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Packet.mak" CFG="Packet - Win32 Debug LOG TO FILE" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Packet - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Packet - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Packet - Win32 Debug LOG TO FILE" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Packet - Win32 Release LOG TO FILE" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Packet - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../../common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /machine:I386 + +!ELSEIF "$(CFG)" == "Packet - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "Packet - Win32 Debug LOG TO FILE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Packet___Win32_Debug__LOG_TO_FILE" +# PROP BASE Intermediate_Dir "Packet___Win32_Debug__LOG_TO_FILE" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_LOG_TO_FILE" +# PROP Intermediate_Dir "Debug_LOG_TO_FILE" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_DEBUG_TO_FILE" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "Packet - Win32 Release LOG TO FILE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Packet___Win32_Release_LOG_TO_FILE" +# PROP BASE Intermediate_Dir "Packet___Win32_Release_LOG_TO_FILE" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_LOG_TO_FILE" +# PROP Intermediate_Dir "Release_LOG_TO_FILE" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "../../../common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../../common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_DEBUG_TO_FILE" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /machine:I386 + +!ENDIF + +# Begin Target + +# Name "Packet - Win32 Release" +# Name "Packet - Win32 Debug" +# Name "Packet - Win32 Debug LOG TO FILE" +# Name "Packet - Win32 Release LOG TO FILE" +# Begin Source File + +SOURCE=..\Packet.def +# End Source File +# Begin Source File + +SOURCE=..\PACKET32.C +# End Source File +# Begin Source File + +SOURCE=..\version.rc +# End Source File +# End Target +# End Project diff --git a/winpcap/Packet9x/DLL/Project/Packet.dsw b/winpcap/Packet9x/DLL/Project/Packet.dsw new file mode 100644 index 0000000..2d69060 --- /dev/null +++ b/winpcap/Packet9x/DLL/Project/Packet.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Packet"=".\Packet.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/Packet9x/DLL/version.rc b/winpcap/Packet9x/DLL/version.rc new file mode 100644 index 0000000..2ef755d --- /dev/null +++ b/winpcap/Packet9x/DLL/version.rc @@ -0,0 +1,64 @@ +// Microsoft Visual C++ generated resource script. +// + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#include ""version.rc2""\r\n" + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "Version.rc2" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/winpcap/Packet9x/DLL/version.rc2 b/winpcap/Packet9x/DLL/version.rc2 new file mode 100644 index 0000000..47e132a --- /dev/null +++ b/winpcap/Packet9x/DLL/version.rc2 @@ -0,0 +1,45 @@ +// +// WinPcapOem.rc2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +#include "..\..\version.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION WINPCAP_MAJOR,WINPCAP_MINOR,WINPCAP_REV,WINPCAP_BUILD + PRODUCTVERSION WINPCAP_MAJOR,WINPCAP_MINOR,WINPCAP_REV,WINPCAP_BUILD + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", WINPCAP_COMPANY_NAME + VALUE "FileDescription", "packet.dll (9x) Dynamic Link Library" + VALUE "FileVersion", WINPCAP_VER_STRING + VALUE "InternalName", "packet.dll" + VALUE "LegalCopyright", WINPCAP_COPYRIGHT_STRING + VALUE "LegalTrademarks", "" + VALUE "OriginalFilename", "packet.dll" + VALUE "ProductName", WINPCAP_PRODUCT_NAME + VALUE "ProductVersion", WINPCAP_VER_STRING + VALUE "Build Description", WINPCAP_BUILD_DESCRIPTION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/winpcap/Packet9x/VXD/DEVIOCTL.H b/winpcap/Packet9x/VXD/DEVIOCTL.H new file mode 100644 index 0000000..af8784b --- /dev/null +++ b/winpcap/Packet9x/VXD/DEVIOCTL.H @@ -0,0 +1,90 @@ +/*++ BUILD Version: 0004 // Increment this if a change has global effects + Copyright (c) 1992-1993 Microsoft Corporation + Module Name: + devioctl.h + Revision History: + -- */ +// begin_winioctl +#ifndef _DEVIOCTL_ +#define _DEVIOCTL_ +// begin_ntddk begin_nthal begin_ntifs +// +// Define the various device type values. Note that values used by Microsoft +// Corporation are in the range 0-32767, and 32768-65535 are reserved for use +// by customers. +// +#define DEVICE_TYPE ULONG +#define FILE_DEVICE_BEEP 0x00000001 +#define FILE_DEVICE_CD_ROM 0x00000002 +#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 +#define FILE_DEVICE_CONTROLLER 0x00000004 +#define FILE_DEVICE_DATALINK 0x00000005 +#define FILE_DEVICE_DFS 0x00000006 +#define FILE_DEVICE_DISK 0x00000007 +#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 +#define FILE_DEVICE_FILE_SYSTEM 0x00000009 +#define FILE_DEVICE_INPORT_PORT 0x0000000a +#define FILE_DEVICE_KEYBOARD 0x0000000b +#define FILE_DEVICE_MAILSLOT 0x0000000c +#define FILE_DEVICE_MIDI_IN 0x0000000d +#define FILE_DEVICE_MIDI_OUT 0x0000000e +#define FILE_DEVICE_MOUSE 0x0000000f +#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 +#define FILE_DEVICE_NAMED_PIPE 0x00000011 +#define FILE_DEVICE_NETWORK 0x00000012 +#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 +#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 +#define FILE_DEVICE_NULL 0x00000015 +#define FILE_DEVICE_PARALLEL_PORT 0x00000016 +#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 +#define FILE_DEVICE_PRINTER 0x00000018 +#define FILE_DEVICE_SCANNER 0x00000019 +#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a +#define FILE_DEVICE_SERIAL_PORT 0x0000001b +#define FILE_DEVICE_SCREEN 0x0000001c +#define FILE_DEVICE_SOUND 0x0000001d +#define FILE_DEVICE_STREAMS 0x0000001e +#define FILE_DEVICE_TAPE 0x0000001f +#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 +#define FILE_DEVICE_TRANSPORT 0x00000021 +#define FILE_DEVICE_UNKNOWN 0x00000022 +#define FILE_DEVICE_VIDEO 0x00000023 +#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 +#define FILE_DEVICE_WAVE_IN 0x00000025 +#define FILE_DEVICE_WAVE_OUT 0x00000026 +#define FILE_DEVICE_8042_PORT 0x00000027 +#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 +#define FILE_DEVICE_BATTERY 0x00000029 +#define FILE_DEVICE_BUS_EXTENDER 0x0000002a +#define FILE_DEVICE_MODEM 0x0000002b +#define FILE_DEVICE_VDM 0x0000002c +#define FILE_DEVICE_MASS_STORAGE 0x0000002d +// +// Macro definition for defining IOCTL and FSCTL function control codes. Note +// that function codes 0-2047 are reserved for Microsoft Corporation, and +// 2048-4095 are reserved for customers. +// +#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ +) +// +// Define the method codes for how buffers are passed for I/O and FS controls +// +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 +// +// Define the access check value for any access +// +// +// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in +// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these +// constants *MUST* always be in sync. +// +#define FILE_ANY_ACCESS 0 +#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe +#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe +// end_ntddk end_nthal end_ntifs +#endif // _DEVIOCTL_ +// end_winioctl diff --git a/winpcap/Packet9x/VXD/Debug.h b/winpcap/Packet9x/VXD/Debug.h new file mode 100644 index 0000000..9b75392 --- /dev/null +++ b/winpcap/Packet9x/VXD/Debug.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1999 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#if DEBUG +#define IF_PACKETDEBUG(f) if ( PacketTraceImpt & (f) ) +extern ULONG PacketTraceImpt; +#define PACKET_TRACE_IMPT 0x00000001 +#define PACKET_DEBUG_VERY_LOUD 0x00000002 +#define PACKET_DEBUG_INIT 0x00000100 +#define PACKET_DEBUG_BREAK 0x00000200 + +#define IF_BREAK_SET IF_PACKETDEBUG( PACKET_DEBUG_BREAK ) DbgBreakPoint(); +#define IF_INIT_TRACE(A) IF_PACKETDEBUG( PACKET_DEBUG_INIT ) { DbgPrint("Packet: %s\r\n", A); DbgBreakPoint(); } +#define IF_TRACE(A) IF_PACKETDEBUG( PACKET_TRACE_IMPT ) { DbgPrint("Packet: %s\r\n", A); IF_BREAK_SET } +#define IF_VERY_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) { DbgPrint("Packet: %s\r\n", A); IF_BREAK_SET } +#define IF_TRACE_MSG(A,B) IF_PACKETDEBUG( PACKET_TRACE_IMPT ) { DbgPrint("Packet: "); DbgPrint(A,B); DbgPrint("\r\n"); IF_BREAK_SET } +#define IF_TRACE_MSG2(A,B,C) IF_PACKETDEBUG( PACKET_TRACE_IMPT ) { DbgPrint("Packet: "); DbgPrint(A,B,C); DbgPrint("\r\n"); IF_BREAK_SET } +#define IF_TRACE_MSG3(A,B,C,D) IF_PACKETDEBUG( PACKET_TRACE_IMPT ) { DbgPrint("Packet: "); DbgPrint(A,B,C,D); DbgPrint("\r\n"); IF_BREAK_SET } +#define IF_TRACE_MSG4(A,B,C,D,E) IF_PACKETDEBUG( PACKET_TRACE_IMPT ) { DbgPrint("Packet: "); DbgPrint(A,B,C,D,E); DbgPrint("\r\n"); IF_BREAK_SET } +#define INIT_ENTER(A) IF_PACKETDEBUG( PACKET_DEBUG_INIT ) { DbgPrint("==> Packet: %s\r\n", A); DbgBreakPoint();} +#define INIT_LEAVE(A) IF_PACKETDEBUG( PACKET_DEBUG_INIT ) { DbgPrint("<== Packet: %s\r\n", A); IF_BREAK_SET} +#define TRACE_ENTER(A) IF_PACKETDEBUG( PACKET_TRACE_IMPT ) { DbgPrint("==> Packet: %s\r\n", A); IF_BREAK_SET} +#define TRACE_LEAVE(A) IF_PACKETDEBUG( PACKET_TRACE_IMPT ) { DbgPrint("<== Packet: %s\r\n", A); IF_BREAK_SET} +#else +#define IF_PACKETDEBUG(f) +#define IF_BREAK_SET +#define IF_INIT_TRACE(A) +#define IF_TRACE(A) +#define IF_VERY_LOUD(A) +#define IF_TRACE_MSG(A,B) +#define IF_TRACE_MSG2(A,B) +#define IF_TRACE_MSG3(A,B) +#define IF_TRACE_MSG4(A,B) +#define INIT_ENTER(A) +#define INIT_LEAVE(A) +#define TRACE_ENTER(A) +#define TRACE_LEAVE(A) +#endif diff --git a/winpcap/Packet9x/VXD/Functs.asm b/winpcap/Packet9x/VXD/Functs.asm new file mode 100644 index 0000000..848cdf6 --- /dev/null +++ b/winpcap/Packet9x/VXD/Functs.asm @@ -0,0 +1,84 @@ +.LALL + +; +; Copyright (c) 1999, 2000 +; Politecnico di Torino. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that: (1) source code distributions +; retain the above copyright notice and this paragraph in its entirety, (2) +; distributions including binary code include the above copyright notice and +; this paragraph in its entirety in the documentation or other materials +; provided with the distribution, and (3) all advertising materials mentioning +; features or use of this software display the following acknowledgement: +; ``This product includes software developed by the netgroup of Politecnico +; di Torino, and its contributors.'' Neither the name of +; the University nor the names of its contributors may be used to endorse +; or promote products derived from this software without specific prior +; written permission. +; THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +; WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +; + + TITLE $PACKET + .386P +INCLUDE VMM.INC +INCLUDE NDIS.INC +INCLUDE NETVXD.INC ; Net VxD initialization oredr +include vtd.inc + +; the following equate makes the VXD dynamically loadable. +%DEVICE_DYNAMIC EQU 1 + +VxD_LOCKED_DATA_SEG + +VxD_LOCKED_DATA_ENDS + + +VxD_LOCKED_CODE_SEG + + +BeginProc _SetReadTimeOut@12, PUBLIC + +push esi + +mov eax, [esp+12] ;number of ms +mov edx, [esp+16] ;data returned to the procedure +mov esi, [esp+8] +VMMcall Set_Global_Time_Out +mov eax, esi + +pop esi +ret 3*4 + +_SetReadTimeOut@12 EndP + + +BeginProc _CancelReadTimeOut@0, PUBLIC + + VMMcall Cancel_Time_Out + +ret + +_CancelReadTimeOut@0 EndP + + +BeginProc _QuerySystemTime@0, PUBLIC + + VxdCall VTD_Get_Real_Time + ret + +_QuerySystemTime@0 EndP + + +BeginProc _GetDate@0, PUBLIC + + VxdCall VTD_Get_Date_And_Time + ret + +_GetDate@0 EndP + +VxD_LOCKED_CODE_ENDS + +END diff --git a/winpcap/Packet9x/VXD/Lock.c b/winpcap/Packet9x/VXD/Lock.c new file mode 100644 index 0000000..5e08d7a --- /dev/null +++ b/winpcap/Packet9x/VXD/Lock.c @@ -0,0 +1,274 @@ +/* + * Copyright (c) 1999 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define WANTVXDWRAPS +#include +#include +#include +#include +#include +#include +#include "debug.h" +#pragma VxD_LOCKED_CODE_SEG +#pragma VxD_LOCKED_DATA_SEG +DWORD _stdcall PacketPageLock(DWORD, DWORD); +void _stdcall PacketPageUnlock(DWORD, DWORD); +DWORD VXDINLINE +_PageCheckLinRange( DWORD Page, DWORD nPages, DWORD Flags ) +{ + DWORD dw; + + _asm push [Flags] + _asm push [nPages] + _asm push [Page] + VMMCall( _PageCheckLinRange ) + _asm add esp, 0Ch + _asm mov [dw], eax + return (dw); +} + +DWORD _stdcall PacketPageLock(DWORD lpMem, DWORD cbSize) +{ + + DWORD LinOffset, nCommittedPages, nPages; + if ( lpMem && cbSize ) + { + LinOffset = lpMem & PAGEMASK; + nPages = ((lpMem + cbSize) >> PAGESHIFT) - PAGE(lpMem) + 1; + + nCommittedPages = _PageCheckLinRange( PAGE( lpMem ), nPages, 0 ); + if ( nCommittedPages >= nPages ) + { + lpMem = _LinPageLock( PAGE( lpMem ), nPages, PAGEMAPGLOBAL ); + lpMem += (( lpMem ) ? LinOffset : 0); + return lpMem; + } + } + return NULL; +} + +void _stdcall PacketPageUnlock( DWORD lpMem, DWORD cbSize ) +{ + DWORD nPages; + + if ( lpMem && cbSize ) + { + nPages = ((lpMem + cbSize) >> PAGESHIFT) - PAGE(lpMem) + 1; + +#ifdef W95 + //The damn name of this function changes from Win95 to Win98 + _LinPageUnlock( PAGE(lpMem) , nPages, PAGEMAPGLOBAL ); +#else + _LinPageUnLock( PAGE(lpMem) , nPages, PAGEMAPGLOBAL ); +#endif + } +} + + +#if DEBUG +#include +#include "packet.h" +ULONG PacketTraceImpt = PACKET_TRACE_IMPT; +VOID DumpReceiveEntries( PLIST_ENTRY pListHead ) +{ + PLIST_ENTRY pListEntry; + PPACKET_RESERVED pReserved; + if ( !IsListEmpty( pListHead ) ) + { + pListEntry = pListHead->Flink; + while ( pListEntry != pListHead ) + { + pReserved = CONTAINING_RECORD( pListEntry, PACKET_RESERVED, ListElement ); + DbgPrint( " Entry %lx\n\r", pListEntry ); + DbgPrint( " lpBuffer %lx\n\r", pReserved->lpBuffer ); + DbgPrint( " cbBuffer %ld\n\r", pReserved->cbBuffer ); + DbgPrint( " lpcbBytesReturned %lx\n\r", pReserved->lpcbBytesReturned ); + DbgPrint( " lpoOverlapped %lx\n\r", pReserved->lpoOverlapped ); + pListEntry = pListEntry->Flink; + } + } +} +VOID DumpRequestEntries( PLIST_ENTRY pList ) +{ + PLIST_ENTRY pEntry; + PPACKET_RESERVED pReserved; + PINTERNAL_REQUEST pRequest; + if ( !IsListEmpty( pList ) ) + { + pEntry = pList->Flink; + while ( pEntry != pList ) + { + pReserved = CONTAINING_RECORD( pEntry, PACKET_RESERVED, ListElement ); + pRequest = CONTAINING_RECORD( pReserved, INTERNAL_REQUEST, Reserved ); + DbgPrint( " Entry %lx Request %lx\n\r", pEntry, pRequest ); + pEntry = pEntry->Flink; + } + } +} +VOID DumpList( char n ) +{ + PLIST_ENTRY pEntry, pList; + POPEN_INSTANCE pOpen; + + + if ( GlobalDeviceExtension ) + { + pList = &GlobalDeviceExtension->OpenList; + if ( !IsListEmpty( pList ) ) + { + pEntry = pList->Flink; + + while ( pEntry != pList ) + { + pOpen = CONTAINING_RECORD( pEntry, OPEN_INSTANCE, ListElement ); + + DbgPrint( " Adapter %lx\n\r", pOpen ); + switch ( n ) + { + case '1': + DumpReceiveEntries( &pOpen->RcvList ); + break; + case '2': + DumpRequestEntries( &pOpen->RequestList ); + break; + case '3': + DumpRequestEntries( &pOpen->ResetIrpList ); + break; + } + pEntry = pEntry->Flink; + } + } + } + return; +} +DWORD _stdcall PacketDebugQuery( void ) +{ + char outList = 1; + Out_Debug_String( "Packet Debug Services:\n\r" ); + while ( 1 ) + { + char c; + Out_Debug_String( "\n\r" ); + + if ( outList ) + { + outList = 0; + Out_Debug_String( "[0] Adapter List\n\r" ); + Out_Debug_String( "[1] Receive List\n\r" ); + Out_Debug_String( "[2] Request List\n\r" ); + Out_Debug_String( "[3] Reset List\n\r\n\r" ); + Out_Debug_String( "[4] Turn OFF Trace Information\n\r" ); + IF_PACKETDEBUG( PACKET_TRACE_IMPT ) + Out_Debug_String( "[5] TOGGLE Normal Trace OFF\n\r" ); + else + Out_Debug_String( "[5] TOGGLE Normal Trace ON\n\r" ); + IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) + Out_Debug_String( "[6] TOGGLE Trace ALL OFF\n\r" ); + else + Out_Debug_String( "[6] TOGGLE Trace ALL ON\n\r" ); + + IF_PACKETDEBUG( PACKET_DEBUG_INIT ) + Out_Debug_String( "[7] TOGGLE Trace Init OFF\n\r" ); + else + Out_Debug_String( "[7] TOGGLE Trace Init ON\n\r" ); + + IF_PACKETDEBUG( PACKET_DEBUG_BREAK ) + Out_Debug_String( "[8] TOGGLE Break on Trace OFF\n\r" ); + else + Out_Debug_String( "[8] TOGGLE Break on Trace ON\n\r" ); + Out_Debug_String( "\r\n[h] Reprint Commands\r\n" ); + } + Out_Debug_String( "Enter selection or Press ESC to Exit: " ); + + VxDCall( In_Debug_Chr ); + _asm jz Debug_Exit + _asm mov c, al + Out_Debug_String( "\n\r" ); + switch ( c ) + { + case '0': + Out_Debug_String( "\n\rAdapter List:\n\r" ); + DumpList( c ); + break; + case '1': + Out_Debug_String( "\n\rRecieve List:\n\r" ); + DumpList( c ); + break; + case '2': + Out_Debug_String( "\n\rRequest List:\n\r" ); + DumpList( c ); + break; + case '3': + Out_Debug_String( "\n\rReset List:\n\r" ); + DumpList( c ); + break; + case '4': + PacketTraceImpt = 0; + break; + case '5': + IF_PACKETDEBUG( PACKET_TRACE_IMPT ) + { + PacketTraceImpt &= ~(PACKET_TRACE_IMPT | PACKET_DEBUG_VERY_LOUD); + } + else + { + PacketTraceImpt |= PACKET_TRACE_IMPT; + PacketTraceImpt &= ~PACKET_DEBUG_VERY_LOUD; + } + break; + case '6': + IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) + PacketTraceImpt &= ~PACKET_DEBUG_VERY_LOUD; + else + PacketTraceImpt |= PACKET_DEBUG_VERY_LOUD | PACKET_TRACE_IMPT; + break; + case '7': + IF_PACKETDEBUG( PACKET_DEBUG_INIT ) + PacketTraceImpt &= ~PACKET_DEBUG_INIT; + else + PacketTraceImpt |= PACKET_DEBUG_INIT; + break; + case '8': + IF_PACKETDEBUG( PACKET_DEBUG_BREAK ) + PacketTraceImpt &= ~PACKET_DEBUG_BREAK; + else + PacketTraceImpt |= PACKET_DEBUG_BREAK; + break; + default: + outList = 1; + break; + } + } +Debug_Exit: + return( VXD_SUCCESS ); +} +#endif diff --git a/winpcap/Packet9x/VXD/MAKEFILE b/winpcap/Packet9x/VXD/MAKEFILE new file mode 100644 index 0000000..47fb187 --- /dev/null +++ b/winpcap/Packet9x/VXD/MAKEFILE @@ -0,0 +1,39 @@ +################################################################## +# +# Microsoft Confidential +# Copyright (C) Microsoft Corporation 1993-95 +# All Rights Reserved. +# +# This document is provided for informational purposes only and Microsoft +# Corporation makes no warranties, either expressed or implied, in this document. +# Information in this document may be substantially changed without notice in +# subsequent versions of windows and does not represent a commitment on the +# part of Microsoft Corporation. This information is for internal use only for +# development purposes. +# +# INPUT: +# BIN: Where to put the stuff +# DEB: Flags to control debug level +# +################################################################## + +DEVICE=NPF + +BIN = debug +#SDK = $(SDKROOT) +#DDK = $(DDKROOT) + +OBJS=\ +$(BIN)\openclos.obj\ +$(BIN)\packet.obj\ +$(BIN)\request.obj\ +$(BIN)\win_bpf_filter.obj\ +$(BIN)\read.obj\ +$(BIN)\write.obj\ +$(BIN)\lock.obj\ +$(BIN)\functs.obj\ +$(BIN)\ndisdev.obj\ +# this is needed by 64 bit math operations +$(MSVCDIR)\lib\msvcrt.lib\ + +!include ndis.mk diff --git a/winpcap/Packet9x/VXD/NPF.def b/winpcap/Packet9x/VXD/NPF.def new file mode 100644 index 0000000..dd0a710 --- /dev/null +++ b/winpcap/Packet9x/VXD/NPF.def @@ -0,0 +1,31 @@ + +VXD NPF DYNAMIC +DESCRIPTION 'winpcap packet driver' + +SEGMENTS + _LPTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE + _TEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _DATA CLASS 'LCODE' PRELOAD NONDISCARDABLE + CONST CLASS 'LCODE' PRELOAD NONDISCARDABLE + _TLS CLASS 'LCODE' PRELOAD NONDISCARDABLE + _BSS CLASS 'LCODE' PRELOAD NONDISCARDABLE + _MSGTABLE CLASS 'MCODE' PRELOAD NONDISCARDABLE IOPL + _MSGDATA CLASS 'MCODE' PRELOAD NONDISCARDABLE IOPL + _IMSGTABLE CLASS 'MCODE' PRELOAD DISCARDABLE IOPL + _IMSGDATA CLASS 'MCODE' PRELOAD DISCARDABLE IOPL + _ITEXT CLASS 'ICODE' DISCARDABLE + _IDATA CLASS 'ICODE' DISCARDABLE + _PTEXT CLASS 'PCODE' NONDISCARDABLE + _PDATA CLASS 'PDATA' NONDISCARDABLE SHARED + _STEXT CLASS 'SCODE' RESIDENT + _SDATA CLASS 'SCODE' RESIDENT + _DBOCODE CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _DBODATA CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE + _RCODE CLASS 'RCODE' + +EXPORTS + + NPF_DDB @1 diff --git a/winpcap/Packet9x/VXD/NPF.rc b/winpcap/Packet9x/VXD/NPF.rc new file mode 100644 index 0000000..56d2ea7 --- /dev/null +++ b/winpcap/Packet9x/VXD/NPF.rc @@ -0,0 +1,43 @@ +#include +#define Not_VxD +#include +#include + +/*-----------------------------------------------*/ +/* the following lines are specific to this file */ +/*-----------------------------------------------*/ + +/* VER_FILETYPE, VER_FILESUBTYPE, VER_FILEDESCRIPTION_STR + * and VER_INTERNALNAME_STR must be defined before including COMMON.VER + * The strings don't need a '\0', since common.ver has them. + */ + + +#define VER_FILEVERSION 1,00,00,000 +#define VER_PRODUCTVERSION 1,00,00,000 + +#define VER_FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + #define VER_FILEFLAGS 0x1L +#else + #define VER_FILEFLAGS 0x0L +#endif + +#define VER_FILEOS VOS_DOS_WINDOWS32 +#define VER_FILETYPE VFT_VXD +#define VER_FILESUBTYPE UNDEFINED_DEVICE_ID //VFT2_UNKNOWN + + +#define VER_FILEDESCRIPTION_STR "WinPcap NPF Packet Driver for Win95/98" +#define VER_INTERNALNAME_STR "NPF" +#define VER_PRODUCTNAME_STR "NPF Driver" +#define VER_LEGALCOPYRIGHT_YEARS "1999-2002" +#define VER_LEGALCOPYRIGHT_STR "Copyright \251 NetGroup, Politecnico di Torino " VER_LEGALCOPYRIGHT_YEARS +#define VER_COMPANYNAME_STR "Politecnico di Torino" +#define VER_ORIGINALFILENAME_STR "npf.Vxd" + +#define VER_PRODUCTVERSION_STR "1.00" +#define VER_FILEVERSION_STR "1.00" + + +#include diff --git a/winpcap/Packet9x/VXD/Ndis.mk b/winpcap/Packet9x/VXD/Ndis.mk new file mode 100644 index 0000000..17b8652 --- /dev/null +++ b/winpcap/Packet9x/VXD/Ndis.mk @@ -0,0 +1,181 @@ +################################################################## +# +# Microsoft Confidential +# Copyright (C) Microsoft Corporation 1993-95 +# All Rights Reserved. +# +# Master Makefile for packet driver +# +# This document is provided for informational purposes only and Microsoft +# Corporation makes no warranties, either expressed or implied, in this document. +# Information in this document may be substantially changed without notice in +# subsequent versions of windows and does not represent a commitment on the +# part of Microsoft Corporation. This information is for internal use only for +# development purposes. +# +# INPUT: +# BIN: Where to put the stuff +# DEB: Flags to control debug level +# +################################################################## + +NDIS_STDCALL=1 + +!IFNDEF DEBLEVEL +DEBLEVEL=1 +!ENDIF + +DDEB = -DDEBUG -DDBG=1 -DDEBLEVEL=$(DEBLEVEL) -DCHICAGO -Zi +RDEB = -DDEBLEVEL=0 -DCHICAGO + +!IFNDEF BIN +BIN = retail +DEB = $(RDEB) +LDEB = NONE +!ELSE +DEB = $(DDEB) +LDEB = FULL +!ENDIF + + +WIN32 = $(DDKROOT) +NETROOT = $(DDKROOT)\net +NDISROOT = $(NETROOT)\ndis3 +LIBDIR = $(NDISROOT)\lib +INCLUDE = ..\..\common;$(INCLUDE);. + +DDKTOOLS = $(WIN32)\bin + +i386 = TRUE +VXD = TRUE +ASM = ml.exe +CL = cl.exe -bzalign +CHGNAM = chgnam.exe +CHGNAMSRC = $(DDKTOOLS)\chgnam.vxd +INCLUDES = $(NETROOT)\bin\includes.exe +MAPSYM = mapsym + +LIBNDIS = $(LIBDIR)\$(BIN)\libndis.clb +LINK = link.exe /DEBUG /DEBUGTYPE:CV +LIBWRAPS = $(DDKROOT)\lib\vxdwraps.clb + + +LFLAGS = /m /NOD /MA /LI /NOLOGO /NOI + +CFLAGS = -Zp -Gs -c -DIS_32 -Zl -DWIN32 -DW95 +AFLAGS = -DIS_32 -W2 -Cx -DMASM6 -DVMMSYS -Zm -DSEGNUM=3 + +#AFLAGS = $(AFLAGS) -DNDIS_WIN -c -coff -DBLD_COFF +AFLAGS = $(AFLAGS) -c -coff -DBLD_COFF -DDEVICE=$(DEVICE) + +!ifdef NDIS_STDCALL +CFLAGS = $(CFLAGS) -Gz -DNDIS_STDCALL +AFLAGS = $(AFLAGS) -DNDIS_STDCALL +!endif + +.asm{$(BIN)}.obj: + set INCLUDE=$(INCLUDE) + set ML= $(AFLAGS) $(DEB) + $(ASM) -Fo$*.obj $< + +.asm{$(BIN)}.lst: + set INCLUDE=$(INCLUDE) + set ML= $(AFLAGS) $(DEB) + $(ASM) -Fl$*.obj $< + +.c{$(BIN)}.obj: + set INCLUDE=$(INCLUDE) + set CL= $(CFLAGS) $(DEB) + $(CL) -Fo$*.obj $< + +target: $(BIN) $(BIN)\$(DEVICE).VXD $(BIN)\$(DEVICE).RES + +$(BIN): + if not exist $(BIN)\nul md $(BIN) + +dbg: depend + $(MAKE) BIN=debug DEB="$(DDEB)" + +rtl: depend + $(MAKE) BIN=retail DEB="$(RDEB)" + +all: rtl dbg + +!if EXIST (depend.mk) +!include depend.mk +!endif + +VERSION = 4.0 + +!ifdef OMB + +$(BIN)\$(DEVICE).VXD: $(OBJS) $(DEVICE).def $(LIBNDIS) + $(LINK) @<< +$(OBJS: =+^ +) +$(BIN)\$(DEVICE).VXD $(LFLAGS) +$(BIN)\$(DEVICE).map +$(LIBNDIS) +$(DEVICE).def +<< + +!else + +$(BIN)\$(DEVICE).VXD: $(OBJS) $(DEVICE).def $(LIBNDIS) $(LIBWRAPS) + $(LINK) @<< +-MACHINE:i386 +-DEBUG:$(LDEB) +-DEBUGTYPE:CV +-PDB:NONE +-DEF:$(DEVICE).def +-OUT:$(BIN)\$(DEVICE).VXD +-MAP:$(BIN)\$(DEVICE).map +-VXD +$(LIBNDIS) +$(LIBWRAPS) +$(OBJS: =^ +) + + +<< +!endif + cd $(BIN) + $(MAPSYM) $(DEVICE) + + cd .. + + +$(BIN)\$(DEVICE).RES: + $(SDKROOT)\bin\rc -r -i$(DDKROOT)\inc32 $(DEVICE).RC + + move $(DEVICE).RES $(BIN) + cd $(BIN) + + adrc2vxd $(DEVICE).vxd $(DEVICE).res + + cd .. + + + +depend: +# -mkdir debug +# -mkdir retail + set INCLUDE=$(INCLUDE) +# $(INCLUDES) -i -L$$(BIN) -S$$(BIN) *.asm *.c > depend.mk +# $(INCLUDES) -i -L$$(BIN) -S$$(BIN) $(NDISSRC)\ndisdev.asm >> depend.mk + + +clean : + - del debug\*.obj + - del debug\*.sym + - del debug\*.VXD + - del debug\*.map + - del debug\*.lst + - del retail\*.obj + - del retail\*.sym + - del retail\*.VXD + - del retail\*.map + - del retail\*.lst + - del depend.mk + + diff --git a/winpcap/Packet9x/VXD/Ndisdev.asm b/winpcap/Packet9x/VXD/Ndisdev.asm new file mode 100644 index 0000000..9b20bbc --- /dev/null +++ b/winpcap/Packet9x/VXD/Ndisdev.asm @@ -0,0 +1,79 @@ +.LALL +;***************************************************************************** +; +; (C) Copyright MICROSOFT Corp, 1995 +; +; Title: NDISDEV.ASM sourced from: +; Title: NDISLNK.ASM - Assembly linkage to NDIS Wrapper for MACs +; and Protocols +; +; This document is provided for informational purposes only and Microsoft +; Corporation makes no warranties, either expressed or implied, in this document. +; Information in this document may be substantially changed without notice in +; subsequent versions of windows and does not represent a commitment on the +; part of Microsoft Corporation. This information is for internal use only for +; development purposes. +; +; Version: 3.00 +; +; Date: 05-Nov-1991 +; +;============================================================================= + TITLE $PACKET + .386P +INCLUDE VMM.INC +INCLUDE NDIS.INC +INCLUDE NETVXD.INC ; Net VxD initialization oredr +include vtd.inc + + +; the following equate makes the VXD dynamically loadable. +%DEVICE_DYNAMIC EQU 1 +DECLARE_VIRTUAL_DEVICE %DEVICE, 3, 10, <%DEVICE>_Control, Undefined_Device_Id, PROTOCOL_Init_Order +VxD_LOCKED_DATA_SEG +Public bInitAlready + bInitAlready DB 0 + +VxD_LOCKED_DATA_ENDS +VxD_LOCKED_CODE_SEG +BeginProc C_Device_Init +IFDEF NDIS_STDCALL + extern _DriverEntry@8:NEAR +ELSE + extern _DriverEntry:NEAR +ENDIF + mov al, bInitAlready + cmp al, 0 ; Make sure we' haven't been called already. + jnz Succeed_Init_Phase + inc bInitAlready ; Set the "Called Already" Flag +; Make sure the wrapper (Ndis.386) is loaded + VxDcall NdisGetVersion + jc Fail_Init_Phase + push 0 + push 0 +IFDEF NDIS_STDCALL + call _DriverEntry@8 +ELSE + call _DriverEntry + add esp,8 +ENDIF + cmp eax, NDIS_STATUS_SUCCESS + jne Fail_Init_Phase +Succeed_Init_Phase: + clc + ret +Fail_Init_Phase: + stc + ret +EndProc C_Device_Init + + +Begin_Control_Dispatch %DEVICE + Control_Dispatch Sys_Dynamic_Device_Init, C_Device_Init + Control_Dispatch W32_DEVICEIOCONTROL, PacketIOControl, sCall, +IFDEF DEBUG + Control_Dispatch DEBUG_QUERY, PacketDebugQuery, sCall +ENDIF +End_Control_Dispatch %DEVICE +VxD_LOCKED_CODE_ENDS + END diff --git a/winpcap/Packet9x/VXD/Ntddpack.h b/winpcap/Packet9x/VXD/Ntddpack.h new file mode 100644 index 0000000..30945c1 --- /dev/null +++ b/winpcap/Packet9x/VXD/Ntddpack.h @@ -0,0 +1,26 @@ + +#ifndef __NTDDPACKET +#define __NTDDPACKET 1 +#include "devioctl.h" +/*#include */ +struct _PACKET_OID_DATA { + ULONG Oid; + ULONG Length; + UCHAR Data[1]; +}; + +typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA; + +/*#include */ +#define FILE_DEVICE_PROTOCOL 0x8000 +#define IOCTL_PROTOCOL_QUERY_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 0 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_SET_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 1 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_STATISTICS CTL_CODE(FILE_DEVICE_PROTOCOL, 2 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_RESET CTL_CODE(FILE_DEVICE_PROTOCOL, 3 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_READ CTL_CODE(FILE_DEVICE_PROTOCOL, 4 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_WRITE CTL_CODE(FILE_DEVICE_PROTOCOL, 5 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_MACNAME CTL_CODE(FILE_DEVICE_PROTOCOL, 6 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_OPEN CTL_CODE(FILE_DEVICE_PROTOCOL, 7 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_CLOSE CTL_CODE(FILE_DEVICE_PROTOCOL, 8 , METHOD_BUFFERED, FILE_ANY_ACCESS) + +#endif diff --git a/winpcap/Packet9x/VXD/Openclos.c b/winpcap/Packet9x/VXD/Openclos.c new file mode 100644 index 0000000..56f397e --- /dev/null +++ b/winpcap/Packet9x/VXD/Openclos.c @@ -0,0 +1,668 @@ +/* + * Copyright (c) 1999 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include +#include +#include +#include "debug.h" +#include "packet.h" +#pragma VxD_LOCKED_CODE_SEG +#pragma VxD_LOCKED_DATA_SEG + + +void YieldExecution( void ) +{ + VMMCall(Release_Time_Slice); + VMMCall(Begin_Nest_Exec); + VMMCall(Resume_Exec); + VMMCall(End_Nest_Exec); +} + +/************************************************************ +Function called when the user level application performs a open +IOCTL. Opens the adapter. +************************************************************/ + +static NDIS_MEDIUM MediumArray[] = { + NdisMedium802_3, + NdisMediumWan, + NdisMediumFddi, + NdisMediumArcnet878_2, + NdisMedium802_5 +}; + +#define NUM_NDIS_MEDIA (sizeof MediumArray / sizeof MediumArray[0]) + +DWORD PacketOpen(PNDIS_STRING AdapterName,DWORD dwDDB,DWORD hDevice,PDIOCPARAMETERS pDiocParms) +{ + + LARGE_INTEGER SystemTime; + __int64 ltime1; + PDEVICE_EXTENSION pde; + POPEN_INSTANCE oiNew; + NDIS_STATUS nsErrorStatus, nsOpenStatus; + UINT i; + UINT uiMedium; + NDIS_STRING NameStr; + NDIS_STATUS Status; + + + pde = GlobalDeviceExtension; + /*Allocate an element that describe an adapter*/ + NdisAllocateMemory( (PVOID *)&oiNew, sizeof( OPEN_INSTANCE ), 0, -1 ); + if ( oiNew == NULL ) + { + return NDIS_STATUS_FAILURE; + } + NdisZeroMemory( (PVOID)oiNew, sizeof( OPEN_INSTANCE ) ); + /*allocate a pool for the packet headers*/ + + NdisAllocatePacketPool( &nsErrorStatus, + &(oiNew->PacketPool), + TRANSMIT_PACKETS, + sizeof(PACKET_RESERVED) ); + + IF_TRACE_MSG( "PACKET_RESERVED_a :%lx",sizeof(PACKET_RESERVED)); + if ( nsErrorStatus != NDIS_STATUS_SUCCESS ) + { + IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus ); + NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); + TRACE_LEAVE( "BindAdapter" ); + return NDIS_STATUS_FAILURE; + } + + + /*allocate a buffer pool for the packet data*/ + NdisAllocateBufferPool( &nsErrorStatus, + &(oiNew->BufferPool), + TRANSMIT_PACKETS ); + if ( nsErrorStatus != NDIS_STATUS_SUCCESS ) + { + IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus ); + NdisFreePacketPool( oiNew->PacketPool ); + NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); + TRACE_LEAVE( "BindAdapter" ); + return NDIS_STATUS_FAILURE; + } + NdisAllocateSpinLock( &(oiNew->ResetSpinLock) ); + InitializeListHead( &(oiNew->ResetIrpList) ); + NdisAllocateSpinLock( &(oiNew->RcvQSpinLock) ); + InitializeListHead( &(oiNew->RcvList) ); + NdisAllocateSpinLock( &(oiNew->RequestSpinLock) ); + InitializeListHead( &(oiNew->RequestList) ); + + for ( i=0;iRequestList), &(oiNew->Requests[i].Reserved.ListElement) ); + } + + oiNew->Status = NDIS_STATUS_PENDING; + + /*initialize the timer variables for this session*/ + + SystemTime=GetDate(); + + ltime1=((__int64)SystemTime.HighPart*86400); + ltime1+=(__int64)(SystemTime.LowPart/1000); //current time from 1980 in seconds + ltime1+=(__int64)315532800; //current time from 1970 (Unix format) in seconds + ltime1*=1193182; + ltime1+=(SystemTime.LowPart%1000)*1193182/1000; //current time from 1970 in ticks + ltime1-=QuerySystemTime(); //boot time from 1970 in ticks + oiNew->StartTime=ltime1; + + + oiNew->Dropped=0; //reset the dropped packets counter + oiNew->Received=0; //reset the received packets counter + oiNew->bpfprogram=NULL; //set an accept-all filter + oiNew->bpfprogramlen=0; + oiNew->BufSize=0; //set an empty buffer + oiNew->Buffer=NULL; //reset the buffer + oiNew->Bhead=0; + oiNew->Btail=0; + oiNew->BLastByte=0; + oiNew->TimeOut=0; //reset the timeouts + oiNew->ReadTimeoutTimer=0; + oiNew->mode=0; //set capture mode + oiNew->Nbytes=0; //reset the counters + oiNew->Npackets=0; + oiNew->hDevice=hDevice; + oiNew->tagProcess=pDiocParms->tagProcess; + oiNew->ReadEvent=0; //reset the read event + + NdisAllocateSpinLock( &(oiNew->CountersLock) ); + /*open the MAC driver calling NDIS*/ + NdisOpenAdapter( &nsOpenStatus, + &nsErrorStatus, + &oiNew->AdapterHandle, + &uiMedium, + MediumArray, + NUM_NDIS_MEDIA, + pde->NdisProtocolHandle, + oiNew, + AdapterName, + 0, + NULL ); + + IF_TRACE_MSG( "Open Status : %lx", nsOpenStatus ); + IF_TRACE_MSG( "Error Status : %lx", nsErrorStatus ); + IF_TRACE_MSG( "Completion Status : %lx", oiNew->Status ); + + if ( nsOpenStatus == NDIS_STATUS_PENDING ) + { + while ( oiNew->Status == NDIS_STATUS_PENDING ) + YieldExecution(); + } + else + { + PacketOpenAdapterComplete( oiNew, nsOpenStatus, nsErrorStatus ); + } + + Status = oiNew->Status; + if ( Status != NDIS_STATUS_SUCCESS ) + { + NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); + return NDIS_STATUS_FAILURE; + } + else + { + + } + + TRACE_LEAVE( "BindAdapter" ); + + /*return succesfully*/ + return STATUS_SUCCESS; + +} + +/************************************************************ +Function called when the user level application performs a Close +IOCTL. Closes the adapter and free the reources associated with it +************************************************************/ + +DWORD PacketClose(POPEN_INSTANCE Open,DWORD dwDDB,DWORD hDevice,PDIOCPARAMETERS pDiocParms) +{ + + NDIS_STATUS Status; + NDIS_STATUS nsErrorStatus; + UINT to; + DWORD TEvent; + + TRACE_ENTER( "PacketClose" ); + + Open->BufSize=0; + + to=Open->ReadTimeoutTimer; + Open->ReadTimeoutTimer=0; + if(to!=0){ + _asm push esi; + _asm mov esi,to; + CancelReadTimeOut(); + _asm pop esi; + } + + // Free the read event + TEvent=Open->ReadEvent; + _asm mov eax,TEvent; + VxDCall(_VWIN32_CloseVxDHandle); + + //close the adapter + NdisCloseAdapter(&nsErrorStatus,Open->AdapterHandle); + if ( nsErrorStatus == NDIS_STATUS_PENDING ) + { + while ( Open->Status == NDIS_STATUS_PENDING ) + YieldExecution(); + + if(Open->Status!=NDIS_STATUS_SUCCESS){ + TRACE_LEAVE( "PacketClose" ); + return NDIS_STATUS_FAILURE; + } + } + else + { + PacketUnbindAdapterComplete( Open, nsErrorStatus ); + if(nsErrorStatus!=NDIS_STATUS_SUCCESS){ + TRACE_LEAVE( "PacketClose" ); + return NDIS_STATUS_FAILURE; + } + } + + Status = Open->Status; + + if(Open->Buffer!=NULL)NdisFreeMemory(Open->Buffer,Open->BufSize,0); + Open->Buffer=NULL; + if(Open->bpfprogram!=NULL)NdisFreeMemory(Open->bpfprogram,Open->bpfprogramlen,0); + + //remove this adapter from the list of open adapters + NdisAcquireSpinLock( &GlobalDeviceExtension->OpenSpinLock ); + RemoveEntryList(&(Open->ListElement)); + NdisReleaseSpinLock( &GlobalDeviceExtension->OpenSpinLock ); + + NdisFreeMemory( Open, sizeof( OPEN_INSTANCE ) , 0 ); + + if(pDiocParms!=NULL) + *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; + + TRACE_LEAVE( "PacketClose" ); + return Status; + +} + +/************************************************************ +Function used by NDIS to update the VXD when a new MAC driver +is added +************************************************************/ +VOID NDIS_API PacketBindAdapter( OUT PNDIS_STATUS Status, + IN NDIS_HANDLE BindAdapterContext, + IN PNDIS_STRING AdapterName, + IN PVOID SystemSpecific1, + IN PVOID SystemSpecific2 ) +{ + PDEVICE_EXTENSION pde; + POPEN_INSTANCE oiNew; + NDIS_STATUS nsErrorStatus, nsOpenStatus; + UINT uiMedium; + UINT i; + PWRAPPER_PROTOCOL_BLOCK pWPBlock; + PNDIS_PROTOCOL_CHARACTERISTICS pNPChar; + PADAPTER_NAME AName; + PWRAPPER_MAC_BLOCK pWMBlock; + PNDIS_MAC_CHARACTERISTICS pNMChar; + BYTE *lpzName; + + + TRACE_ENTER( "BindAdapter" ); + pde = GlobalDeviceExtension; + /*Allocate an element that describe an adapter*/ + NdisAllocateMemory( (PVOID *)&AName, sizeof(ADAPTER_NAME), 0, -1 ); + if ( AName == NULL ) + { + *Status = NDIS_STATUS_RESOURCES; + return; + } + + NdisAllocateMemory( (PVOID *)&oiNew, sizeof( OPEN_INSTANCE ), 0, -1 ); + if ( oiNew == NULL ) + { + *Status = NDIS_STATUS_RESOURCES; + return; + } + NdisZeroMemory( (PVOID)oiNew, sizeof( OPEN_INSTANCE ) ); + + /*Save Binding Context*/ + oiNew->BindAdapterContext = BindAdapterContext; + + /*Save the device handle*/ + + oiNew->hDevice = (DWORD) SystemSpecific1; + + /*allocate a pool for the packet headers*/ + + NdisAllocatePacketPool( &nsErrorStatus, + &(oiNew->PacketPool), + TRANSMIT_PACKETS, + sizeof(PACKET_RESERVED) ); + + IF_TRACE_MSG( "PACKET_RESERVED_b :%lx",sizeof(PACKET_RESERVED)); + if ( nsErrorStatus != NDIS_STATUS_SUCCESS ) + { + IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus ); + NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); + *Status = NDIS_STATUS_RESOURCES; + TRACE_LEAVE( "BindAdapter" ); + return; + } + + + /*allocate a pool for the packet data*/ + + NdisAllocateBufferPool( &nsErrorStatus, + &(oiNew->BufferPool), + TRANSMIT_PACKETS ); + if ( nsErrorStatus != NDIS_STATUS_SUCCESS ) + { + IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus ); + NdisFreePacketPool( oiNew->PacketPool ); + NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); + *Status = NDIS_STATUS_RESOURCES; + TRACE_LEAVE( "BindAdapter" ); + return; + } + NdisAllocateSpinLock( &(oiNew->ResetSpinLock) ); + InitializeListHead( &(oiNew->ResetIrpList) ); + NdisAllocateSpinLock( &(oiNew->RcvQSpinLock) ); + InitializeListHead( &(oiNew->RcvList) ); + NdisAllocateSpinLock( &(oiNew->RequestSpinLock) ); + InitializeListHead( &(oiNew->RequestList) ); + + for ( i=0;iRequestList), &(oiNew->Requests[i].Reserved.ListElement) ); + } + oiNew->Status = NDIS_STATUS_PENDING; + oiNew->BindAdapterContext = BindAdapterContext; + + /*open the MAC driver calling NDIS*/ + + oiNew->hDevice=0; + oiNew->tagProcess=0; + + NdisOpenAdapter( &nsOpenStatus, + &nsErrorStatus, + &oiNew->AdapterHandle, + &uiMedium, + MediumArray, + NUM_NDIS_MEDIA, + pde->NdisProtocolHandle, + oiNew, + AdapterName, + 0, + NULL ); + IF_TRACE_MSG( "Open Status : %lx", nsOpenStatus ); + IF_TRACE_MSG( "Error Status : %lx", nsErrorStatus ); + IF_TRACE_MSG( "Completion Status : %lx", oiNew->Status ); + if ( nsOpenStatus == NDIS_STATUS_PENDING ) + { + while ( oiNew->Status == NDIS_STATUS_PENDING ) + YieldExecution(); + } + else + { + PacketOpenAdapterComplete( oiNew, nsOpenStatus, nsErrorStatus ); + } + + pWPBlock = ((PWRAPPER_OPEN_BLOCK)(oiNew->AdapterHandle))->ProtocolHandle; + pNPChar = &pWPBlock->ProtocolCharacteristics; + IF_TRACE_MSG( "Protocol : %s", pNPChar->Name.Buffer ); + IF_TRACE_MSG( "Protocol Handle : %lx", pde->NdisProtocolHandle ); + IF_TRACE_MSG( "PWRAPPER_OPEN_BLOCK : %lx", oiNew->AdapterHandle ); + IF_TRACE_MSG( "PWRAPPER_PROTOCOL_BLOCK : %lx", pWPBlock ); + IF_TRACE_MSG( "NDIS_PROTOCOL_CHARACTERISTICS : %lx", pNPChar ); + IF_TRACE_MSG( "Name : %lx", &pNPChar->Name ); + IF_TRACE_MSG( "Adapter Name : %s", AdapterName->Buffer ); + *Status = oiNew->Status; + + if ( *Status != NDIS_STATUS_SUCCESS ) + { + NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); + IF_TRACE( "Bind Operation FAILED!" ); + } + else + { + AName->realnamestr.Length=AdapterName->Length; + AName->realnamestr.MaximumLength=AdapterName->MaximumLength; + AName->realnamestr.Buffer=AName->realname; + for(i=0;i<32;i++)AName->realname[i]=AdapterName->Buffer[i]; + + pWMBlock = ((PWRAPPER_OPEN_BLOCK)(oiNew->AdapterHandle))->MacHandle; + pNMChar = &pWMBlock->MacCharacteristics; + lpzName = pNMChar->Name.Buffer; + for(i=0;i<32;i++)AName->devicename[i]=lpzName[i]; + InsertTailList( &GlobalDeviceExtension->AdapterNames, &AName->ListElement); + + //close the adapter + NdisCloseAdapter(&nsErrorStatus,oiNew->AdapterHandle); + + if ( nsErrorStatus == NDIS_STATUS_PENDING ) + { + while ( oiNew->Status == NDIS_STATUS_PENDING ) + YieldExecution(); + } + else + { + PacketUnbindAdapterComplete( oiNew, nsErrorStatus ); + } + *Status = oiNew->Status; + if ( *Status == NDIS_STATUS_SUCCESS ) + { + //remove this adapter from the list of open adapters + RemoveEntryList(&(oiNew->ListElement)); + //free the memory + NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); + } + else + { + IF_TRACE( "Close Operation FAILED!" ); + } + + } + + TRACE_LEAVE( "BindAdapter" ); + return; +} + +/************************************************************ +Function called by NDIS to indicate the completion of a bind +************************************************************/ +VOID NDIS_API +PacketOpenAdapterComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN NDIS_STATUS OpenErrorStatus ) +{ + POPEN_INSTANCE Open; + + TRACE_ENTER( "BindAdapterComplete" ); + IF_TRACE_MSG2( "ErrorStatus=%x Status=%x", OpenErrorStatus, Status ); + Open = (POPEN_INSTANCE)ProtocolBindingContext; + if ( Status == NDIS_STATUS_SUCCESS ) + { + /*Insert the just opened NIC in the list of initialized NICs*/ + NdisAcquireSpinLock( &GlobalDeviceExtension->OpenSpinLock ); + InsertHeadList( &GlobalDeviceExtension->OpenList, &Open->ListElement ); + NdisReleaseSpinLock( &GlobalDeviceExtension->OpenSpinLock ); + } + else + { + /*free resources.*/ + PacketFreeResources( Open ); + return; + } + Open->Status = Status; + /*complete the binding*/ + NdisCompleteBindAdapter( Open->BindAdapterContext, Status, OpenErrorStatus ); + TRACE_LEAVE( "BindAdapterComplete" ); + return; +} + +/************************************************************ +Start the unbind of a network driver from the protocol driver +************************************************************/ +VOID NDIS_API +PacketUnbindAdapter( OUT PNDIS_STATUS Status, + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_HANDLE UnbindContext ) +{ + POPEN_INSTANCE Open; + NDIS_STATUS nsCloseStatus; + + TRACE_ENTER( "UnbindAdapter" ); + + + Open = (POPEN_INSTANCE)ProtocolBindingContext; + Open->BindAdapterContext = UnbindContext; + /*clean the pending requests*/ + PacketCleanUp( Status, Open ); + Open->Status = NDIS_STATUS_PENDING; + /*Calls NDIS to close the selected adapter*/ + + NdisCloseAdapter( &nsCloseStatus, Open->AdapterHandle ); + if ( nsCloseStatus == NDIS_STATUS_PENDING ) + { + while ( Open->Status == NDIS_STATUS_PENDING ) + YieldExecution(); + } + else + { + PacketUnbindAdapterComplete( Open, nsCloseStatus ); + } + *Status = Open->Status; + if ( *Status == NDIS_STATUS_SUCCESS ) + { + NdisFreeMemory( Open, sizeof( OPEN_INSTANCE ) , 0 ); + } + else + { + IF_TRACE( "Unbind Operation FAILED!" ); + } + TRACE_LEAVE( "CloseAdapter" ); + + return; +} + +/************************************************************ +Complete the unbind of a network driver from the protocol driver +************************************************************/ +VOID NDIS_API +PacketUnbindAdapterComplete( IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status ) +{ + POPEN_INSTANCE Open; + + TRACE_ENTER( "UnbindAdapterComplete" ); + Open = (POPEN_INSTANCE)ProtocolBindingContext; + if ( Status == NDIS_STATUS_SUCCESS ) + { + PacketFreeResources( Open ); + } + Open->Status = Status; + + TRACE_LEAVE( "UnbindAdapterComplete" ); + return; +} + +/************************************************************ +free the resources allocated by an adapter +************************************************************/ +VOID PacketFreeResources( POPEN_INSTANCE Open ) +{ + NdisFreeSpinLock( &Open->RequestSpinLock ); + NdisFreeSpinLock( &Open->RcvQSpinLock ); + NdisFreeSpinLock( &Open->ResetSpinLock ); + NdisFreeBufferPool( Open->BufferPool ); + NdisFreePacketPool( Open->PacketPool ); +} + +/************************************************************ +Function that frees the pending requests +************************************************************/ +VOID +PacketCleanUp( PNDIS_STATUS Status, + POPEN_INSTANCE Open ) +{ + PLIST_ENTRY PacketListEntry; + PNDIS_PACKET pPacket; + PPACKET_RESERVED Reserved; + + TRACE_ENTER( "Cleanup" ); + /*clean all the pending requests*/ + NdisAcquireSpinLock( &(Open->RcvQSpinLock) ); + while( (PacketListEntry = PacketRemoveHeadList( &(Open->RcvList) )) != NULL ) + { + IF_VERY_LOUD( "CleanUp - Completing read" ); + Reserved = CONTAINING_RECORD( PacketListEntry, PACKET_RESERVED, ListElement ); + pPacket = CONTAINING_RECORD( Reserved, NDIS_PACKET, ProtocolReserved ); + /*emulate the end of a transfer to wake the processes that + are waiting on a request */ + PacketTransferDataComplete( Open, pPacket, NDIS_STATUS_SUCCESS, 0 ); + } + NdisReleaseSpinLock( &(Open->RcvQSpinLock) ); + TRACE_LEAVE( "Cleanup" ); + return; +} + +/************************************************************ +Start the reset of a instance of the driver +************************************************************/ +VOID +PacketReset( PNDIS_STATUS pStatus, + POPEN_INSTANCE pOpen ) +{ + PLIST_ENTRY ResetListEntry; + + TRACE_ENTER( "PacketReset" ); + + NdisAcquireSpinLock( &pOpen->RequestSpinLock ); + ResetListEntry = PacketRemoveHeadList( &pOpen->RequestList ); + NdisReleaseSpinLock( &pOpen->RequestSpinLock ); + if ( ResetListEntry == NULL ) + { + *pStatus = NDIS_STATUS_RESOURCES; + TRACE_LEAVE( "PacketReset" ); + return; + } + NdisAcquireSpinLock( &pOpen->ResetSpinLock ); + InsertTailList( &pOpen->ResetIrpList, ResetListEntry ); + NdisReleaseSpinLock( &pOpen->ResetSpinLock ); + + /*Call NDIS to reset the adapter*/ + NdisReset( pStatus, pOpen->AdapterHandle ); + if ( *pStatus != NDIS_STATUS_PENDING ) + { + /*synchronous reset of the adapter*/ + PacketResetComplete( pOpen, *pStatus ); + } + TRACE_LEAVE( "PacketReset" ); + return; +} + +/************************************************************ +complete the reset of a instance of the driver +************************************************************/ +VOID NDIS_API +PacketResetComplete( IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status ) +{ + POPEN_INSTANCE Open; + PLIST_ENTRY ResetListEntry; + + TRACE_ENTER( "PacketResetComplete" ); + Open = (POPEN_INSTANCE)ProtocolBindingContext; + + NdisAcquireSpinLock( &Open->ResetSpinLock ); + ResetListEntry = PacketRemoveHeadList( &Open->ResetIrpList ); + NdisReleaseSpinLock( &Open->ResetSpinLock ); + if ( ResetListEntry == NULL ) + { + IF_VERY_LOUD( "Reset List Empty Error" ); + TRACE_LEAVE( "PacketResetComplete" ); + return; + } + + NdisAcquireSpinLock( &Open->RequestSpinLock ); + InsertTailList( &Open->RequestList, ResetListEntry ); + NdisReleaseSpinLock( &Open->RequestSpinLock ); + TRACE_LEAVE( "PacketResetComplete" ); + return; +} diff --git a/winpcap/Packet9x/VXD/Packet.c b/winpcap/Packet9x/VXD/Packet.c new file mode 100644 index 0000000..026ca58 --- /dev/null +++ b/winpcap/Packet9x/VXD/Packet.c @@ -0,0 +1,709 @@ +/* + * Copyright (c) 1999 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include +#include +#include +#include "debug.h" +#include "packet.h" +#include +#include +#pragma VxD_LOCKED_CODE_SEG +#pragma VxD_LOCKED_DATA_SEG + +/*head of the open instances*/ +PDEVICE_EXTENSION GlobalDeviceExtension = 0; +UINT nOpen = 0; +POPEN_INSTANCE InstToClose[128]; + +/*number of processes attached to this driver*/ +int Instances=0; + + +/************************************************************ + This routine initializes the Packet driver. +Arguments: + DriverObject - Pointer to driver object created by system. + RegistryPath - Pointer to the Unicode name of the registry path + for this driver. +Return Value: + The function value is the final status from the initialization operation. +************************************************************/ +NTSTATUS +DriverEntry( IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +{ + NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar; + NDIS_STRING ProtoName = NDIS_STRING_CONST("PACKET"); + NDIS_HANDLE NdisProtocolHandle; + NDIS_STATUS Status; + TRACE_ENTER( "DriverEntry" ); + + + NdisAllocateMemory( (PVOID *)&GlobalDeviceExtension, sizeof( DEVICE_EXTENSION ), 0, -1 ); + if ( GlobalDeviceExtension != NULL ) + { + NdisZeroMemory( (UCHAR*)GlobalDeviceExtension, sizeof(DEVICE_EXTENSION) ); + NdisZeroMemory( (UCHAR*)&ProtocolChar, sizeof(NDIS_PROTOCOL_CHARACTERISTICS) ); + ProtocolChar.MajorNdisVersion = 0x03; + ProtocolChar.MinorNdisVersion = 0x0A; + ProtocolChar.Reserved = 0; + ProtocolChar.OpenAdapterCompleteHandler = PacketOpenAdapterComplete; + ProtocolChar.CloseAdapterCompleteHandler = PacketUnbindAdapterComplete; + ProtocolChar.SendCompleteHandler = PacketSendComplete; + ProtocolChar.TransferDataCompleteHandler = PacketTransferDataComplete; + ProtocolChar.ResetCompleteHandler = PacketResetComplete; + ProtocolChar.RequestCompleteHandler = PacketRequestComplete; + ProtocolChar.ReceiveHandler = Packet_tap; + ProtocolChar.ReceiveCompleteHandler = PacketReceiveComplete; + ProtocolChar.StatusHandler = PacketStatus; + ProtocolChar.StatusCompleteHandler = PacketStatusComplete; + ProtocolChar.BindAdapterHandler = PacketBindAdapter; + ProtocolChar.UnbindAdapterHandler = PacketUnbindAdapter; + ProtocolChar.UnloadProtocolHandler = PacketUnload; + ProtocolChar.Name = ProtoName; + NdisRegisterProtocol( &Status, + &GlobalDeviceExtension->NdisProtocolHandle, + &ProtocolChar, + sizeof(NDIS_PROTOCOL_CHARACTERISTICS) ); + if (Status != NDIS_STATUS_SUCCESS) + { + NdisFreeMemory( GlobalDeviceExtension, sizeof( DEVICE_EXTENSION ) , 0 ); + IF_TRACE( "Failed to register protocol with NDIS" ); + INIT_LEAVE( "DriverEntry" ); + return Status; + } + /*initializes the list of the open instances*/ + NdisAllocateSpinLock( &(GlobalDeviceExtension->OpenSpinLock) ); + InitializeListHead( &GlobalDeviceExtension->OpenList ); + GlobalDeviceExtension->DriverObject = DriverObject; + + if(Bind_Names() != NDIS_STATUS_SUCCESS) return NDIS_STATUS_FAILURE; + + IF_TRACE( "protocol registered with NDIS!!!" ); + INIT_LEAVE( "DriverEntry" ); + return Status; + } + IF_TRACE( "Memory Failure" ); + + TRACE_LEAVE( "DriverEntry" ); + + return NDIS_STATUS_RESOURCES; + +} + +/************************************************************ +Function used to associate the names of the network devices +with the internal NDIS names +INPUT: +OUTPUT: NDIS_STATUS_SUCCESS if succesful, otherwise NDIS_STATUS_FAILURE +************************************************************/ +DWORD Bind_Names(void){ + DWORD res; + VMMHKEY Key,Key1; + DWORD Klen,Klen1; + char NdisName[64]; + char DevName[64]; + int i=0; + PADAPTER_NAME AName; + + TRACE_ENTER( "Bind_Names" ); + + // initialize the list of adapter names + InitializeListHead( &GlobalDeviceExtension->AdapterNames); + + // change to HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\Net + res=VMM_RegOpenKey(HKEY_LOCAL_MACHINE,"SYSTEM",&Key); + res=VMM_RegOpenKey(Key,"CURRENTCONTROLSET",&Key); + res=VMM_RegOpenKey(Key,"SERVICES",&Key); + res=VMM_RegOpenKey(Key,"CLASS",&Key); + res=VMM_RegOpenKey(Key,"NET",&Key); + + if(res!=ERROR_SUCCESS) return NDIS_STATUS_FAILURE; + + Klen=64; + // Scan the list of the adapters + while(VMM_RegEnumKey(Key,i,NdisName,Klen)==ERROR_SUCCESS) + { + res=VMM_RegOpenKey(Key,NdisName,&Key1); + res=VMM_RegOpenKey(Key1,"NDIS",&Key1); + Klen1=64; + res=VMM_RegQueryValueEx(Key1,"LOGDRIVERNAME",NULL,NULL, DevName,&Klen1); + if(res!=ERROR_SUCCESS){ + Klen=64; + i++; + continue; + } + + NdisAllocateMemory( (PVOID *)&AName, sizeof(ADAPTER_NAME), 0, -1 ); + if ( AName == NULL ) + { + return NDIS_STATUS_FAILURE; + } + + NdisMoveMemory(AName->realname,NdisName,Klen); + NdisMoveMemory(AName->devicename,DevName,Klen1); + AName->realnamestr.Length=strlen(NdisName); + AName->realnamestr.MaximumLength=Klen; + AName->realnamestr.Buffer=AName->realname; + + InsertHeadList( &GlobalDeviceExtension->AdapterNames, &AName->ListElement); + + Klen=64; + i++; + } + + TRACE_LEAVE( "Bind_Names" ); + + if(i==0) return NDIS_STATUS_FAILURE; + else return NDIS_STATUS_SUCCESS; + +} + +/************************************************************ +Callback function called by NDIS when the last insatnce of +the packet driver is closed by the capture driver, +i.e. when the driver is unloaded +INPUT: +OUTPUT: +************************************************************/ +VOID NDIS_API PacketUnload() +{ + TRACE_ENTER( "Unload" ); + + TRACE_LEAVE( "Unload" ); + return; +} +/************************************************************ +this function returns the descriptor of the adapter from +the device ID and process tag +INPUT: Name of the adapter to open +OUTPUT: instance of the driver +************************************************************/ +POPEN_INSTANCE GetRunningAdapter(DWORD hDevice,DWORD tagProcess) +{ + DWORD dwBytes = 0; + DWORD dwSec_Counter=1000; // Or something like that + BYTE *lpzName; + POPEN_INSTANCE pOpen; + PWRAPPER_MAC_BLOCK pWMBlock; + PNDIS_MAC_CHARACTERISTICS pNMChar; + PLIST_ENTRY pEntry; + PLIST_ENTRY pHead; + + NdisAcquireSpinLock(&GlobalDeviceExtension->OpenSpinLock); + + pHead = &(GlobalDeviceExtension->OpenList); + pOpen = 0; + + pEntry=pHead->Flink; + + do + { + pOpen = CONTAINING_RECORD( pEntry, OPEN_INSTANCE, ListElement ); + if((pOpen->hDevice==hDevice)&&(pOpen->tagProcess==tagProcess)){ + NdisReleaseSpinLock( &GlobalDeviceExtension->OpenSpinLock ); + return pOpen; + } + pEntry=pEntry->Flink; + dwSec_Counter--; + + }while ((pEntry != pHead)&&(dwSec_Counter)); + + NdisReleaseSpinLock( &GlobalDeviceExtension->OpenSpinLock ); + return NULL; +} + +/************************************************************ +this function returns the NDIS name of an adapter given its +device name +INPUT: Name of the adapter to open +OUTPUT: instance of the driver +************************************************************/ + +PNDIS_STRING GetNDISAdapterName(BYTE* DeviceName) +{ + PADAPTER_NAME pAdap; + UINT count=0; + PLIST_ENTRY pHead = &(GlobalDeviceExtension->AdapterNames); + PLIST_ENTRY pEntry; + + TRACE_ENTER( "GetNDISAdapterName" ); + + pEntry=pHead->Flink; + + if(IsListEmpty(pHead)){ + if(Bind_Names()==NDIS_STATUS_FAILURE) + return NULL; + } + + do { + pAdap = CONTAINING_RECORD( pEntry, ADAPTER_NAME, ListElement ); + if(compare(pAdap->devicename,DeviceName)==1)return &(pAdap->realnamestr); + pEntry=pEntry->Flink; + }while (pEntry != pHead || count++>32); + + TRACE_LEAVE( "GetNDISAdapterName" ); + + return NULL; +} + +/************************************************************ +This function evaluates the length of a string. +Useful to avoid the string library functions that are not +defined at this level +************************************************************/ +ULONG +strlen( BYTE *s ) +{ + ULONG len = 0; + while ( *s++ ) len++; + return len; +} + + +/************************************************************ +This function compares two strings +************************************************************/ +BYTE compare(BYTE *s1,BYTE *s2) +{ + TRACE_ENTER( "compare" ); + + while (*s1 && *s2) + { + if (*s1!=*s2) return (BYTE) 0; + + s1++; + s2++; + + } + + TRACE_LEAVE( "compare" ); + + if ((*s1==0) && (*s2==0)) return (BYTE) 1; + else return (BYTE) 0; +} + +/************************************************************ +Return the names of all the MAC drivers on which the driver +is attached +INPUT: dwDDB e hDevice - parameters coming from the + DeviceIOControl procedure, not used here. +OUTPUT: pDiocParms - structure containing the returned buffer +************************************************************/ + +DWORD PacketGetMacNameList( DWORD dwDDB, + DWORD hDevice, + PDIOCPARAMETERS pDiocParms ) +{ + DWORD dwBytes = 0; + BYTE *lpzName; + PADAPTER_NAME pAdap; + PWRAPPER_MAC_BLOCK pWMBlock; + PNDIS_MAC_CHARACTERISTICS pNMChar; + ULONG uLength; + + PLIST_ENTRY pHead = &(GlobalDeviceExtension->AdapterNames); + PLIST_ENTRY pEntry; + + TRACE_ENTER( "PacketGetMacNameList" ); + + pEntry=pHead->Flink; + do { + pAdap = CONTAINING_RECORD( pEntry, ADAPTER_NAME, ListElement ); + uLength = strlen( pAdap->devicename ); + + if ( uLength < pDiocParms->cbOutBuffer - dwBytes - 1 ) + { + strcat( (BYTE*)(pDiocParms->lpvOutBuffer), pAdap->devicename ); + strcat( (BYTE*)(pDiocParms->lpvOutBuffer), " " ); + dwBytes += (uLength + 1); + } + else break; + + pEntry=pEntry->Flink; + }while (pEntry != pHead); + + *(ULONG*)(pDiocParms->lpcbBytesReturned) = dwBytes; + IF_TRACE_MSG( " Bytes Returned: %lu", *(ULONG*)(pDiocParms->lpcbBytesReturned) ); + + TRACE_LEAVE( "PacketGetMacNameList" ); + + return NDIS_STATUS_SUCCESS; + +} + +/************************************************************ +This is the dispatch routine for create/open and close requests. +These requests complete successfully. +INPUT: dwDDB e hDevice - parameters sent by the DeviceIOControl procedure + dwService - requested service + pDiocParms - structure containing the parameters of the call +OUTPUT: the status of the operation +************************************************************/ + +DWORD _stdcall PacketIOControl( DWORD dwService, + DWORD dwDDB, + DWORD hDevice, + PDIOCPARAMETERS pDiocParms ) +{ + PUCHAR tpointer; + int *StatsBuf; + PUCHAR prog; + ULONG dim,timeout; + NDIS_STATUS Status; + PPACKET_OID_DATA reqbuff; + POPEN_INSTANCE Open,tOpen; + PNDIS_STRING str; + ULONG mode; + PLIST_ENTRY pEntry; + PLIST_ENTRY pHead; + PADAPTER_NAME AName; + UINT i; + SHORT timezone; + + TRACE_ENTER( "DeviceIoControl" ); + + if(!(dwService==IOCTL_PROTOCOL_MACNAME || + dwService==IOCTL_OPEN || + dwService==0)){ + Open=GetRunningAdapter(hDevice,pDiocParms->tagProcess); + if(Open==NULL) return NDIS_STATUS_FAILURE; + } + + switch ( dwService ) + { + case IOCTL_OPEN: //open message + + Instances++; + + //get the NDIS name of current adapter + str=GetNDISAdapterName((BYTE*)pDiocParms->lpvInBuffer); + + if(str==NULL) return NDIS_STATUS_FAILURE; + //try to open an instance of the adapter + Status = PacketOpen( str, dwDDB, hDevice, pDiocParms); + + return Status; + + + break; + + + case BIOCGSTATS: //fuction to obtain the capture stats + + StatsBuf=(int*)pDiocParms->lpvOutBuffer; + StatsBuf[0]=Open->Received; + StatsBuf[1]=Open->Dropped; + *(DWORD *)(pDiocParms->lpcbBytesReturned) = 8; + return NDIS_STATUS_SUCCESS; + + break; + + + case BIOCEVNAME: //fuction to set the shared Event + + Open->ReadEvent=((DWORD*)pDiocParms->lpvInBuffer)[0]; + *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; + + return NDIS_STATUS_SUCCESS; + + break; + + + case BIOCSETF: //fuction to set a new bpf filter + + /*free the previous buffer if it was present*/ + if(Open->bpfprogram!=NULL){ + NdisFreeMemory(Open->bpfprogram,Open->bpfprogramlen,0); + Open->bpfprogram=NULL; //NULL means accept all + Open->bpfprogramlen=0; + } + + /*get the pointer to the new program*/ + prog=(PUCHAR)pDiocParms->lpvInBuffer; + + /*before accepting the program we must check that it's valid + Otherwise, a bogus program could easily crash the system*/ + + Open->bpfprogramlen=pDiocParms->cbInBuffer; + if(bpf_validate((struct bpf_insn*)prog,Open->bpfprogramlen/sizeof(struct bpf_insn))==0) + { + Open->bpfprogramlen=0; + Open->bpfprogram=NULL; + return NDIS_STATUS_FAILURE; // filter not accepted + } + + /*allocate the memory to contain the new filter program*/ + if(NdisAllocateMemory(&Open->bpfprogram,Open->bpfprogramlen, 0, -1 )==NDIS_STATUS_FAILURE) + { + // no memory + Open->bpfprogramlen=0; + Open->bpfprogram=NULL; + return NDIS_STATUS_FAILURE; + } + + /*copy the program in the new buffer*/ + NdisMoveMemory(Open->bpfprogram,prog,Open->bpfprogramlen); + + /*reset the buffer that could contain packets that don't match the filter*/ + Open->Bhead=0; + Open->Btail=0; + Open->BLastByte=0; + Open->Received=0; + Open->Dropped=0; + + *(DWORD *)(pDiocParms->lpcbBytesReturned) = Open->bpfprogramlen; + + break; + + + case BIOCSETBUFFERSIZE: //function to set the dimension of the buffer for the packets + + /*get the size to allocate*/ + dim=((PULONG)pDiocParms->lpvInBuffer)[0]; + /*free the old buffer*/ + if(Open->Buffer!=NULL) + NdisFreeMemory(Open->Buffer,Open->BufSize,0); + + Open->Buffer=NULL; + /*allocate the new buffer*/ + + if(dim>0){ + NdisAllocateMemory( (PVOID *)&tpointer,dim, 0, -1 ); + if (tpointer==NULL) + { + // no memory + Open->BufSize=0; + return NDIS_STATUS_FAILURE; + } + + Open->Buffer=tpointer; + } + + Open->Bhead=0; + Open->Btail=0; + Open->BLastByte=0; + Open->BufSize=(UINT)dim; + + *(DWORD *)(pDiocParms->lpcbBytesReturned) = dim; + + break; + + case BIOCSMODE: + + mode=((PULONG)pDiocParms->lpvInBuffer)[0]; + if(mode==MODE_STAT){ + Open->mode=MODE_STAT; + Open->Nbytes=0; + Open->Npackets=0; + + if(Open->TimeOut==0)Open->TimeOut=1000; + } + else if(mode==MODE_CAPT){ + Open->mode=MODE_CAPT; + return NDIS_STATUS_SUCCESS; + } + else{ + return NDIS_STATUS_FAILURE; + } + + break; + + case BIOCSRTIMEOUT: + + timeout=((PULONG)pDiocParms->lpvInBuffer)[0]; + Open->TimeOut=timeout; + + *(DWORD *)(pDiocParms->lpcbBytesReturned) = timeout; + + break; + + case BIOCSTIMEZONE: + + timezone=((PSHORT)pDiocParms->lpvInBuffer)[0]; + + Open->StartTime+=((__int64)timezone)*(__int64)1193182*60; + + *(DWORD *)(pDiocParms->lpcbBytesReturned) = timezone; + + break; + + case BIOCSWRITEREP: //set the writes repetition number + + Open->Nwrites=((PULONG)pDiocParms->lpvInBuffer)[0]; + + *(DWORD *)(pDiocParms->lpcbBytesReturned) = Open->Nwrites; + + break; + + case DIOC_CLOSEHANDLE: + Status=PacketClose( Open, dwDDB, hDevice, pDiocParms ); + + Instances--; + + if(Instances<=0) + if ( GlobalDeviceExtension ) + { + //If any instance is still opened we must close it + NdisAcquireSpinLock(&GlobalDeviceExtension->OpenSpinLock); + + nOpen=0; + + pHead = &(GlobalDeviceExtension->OpenList); + if(pHead!=NULL && !IsListEmpty(pHead)) + { + //count the number of open instances + pEntry=pHead->Flink; + do { + tOpen = CONTAINING_RECORD( pEntry, OPEN_INSTANCE, ListElement ); + + pEntry=pEntry->Flink; + if(tOpen!=NULL) + InstToClose[nOpen++]=tOpen; + + }while (pEntry != pHead); + + for(i=0;ihDevice,NULL); + } + } + + NdisReleaseSpinLock( &GlobalDeviceExtension->OpenSpinLock ); + + //free the names' list + pHead = &(GlobalDeviceExtension->AdapterNames); + if(pHead!=NULL) + { + while((pEntry=PacketRemoveHeadList(pHead))!=NULL){ + AName= CONTAINING_RECORD( pEntry, ADAPTER_NAME, ListElement); + NdisFreeMemory(AName,sizeof(ADAPTER_NAME),0); + } + } + + //unregister the protocol from NDIS + NdisDeregisterProtocol( &Status, GlobalDeviceExtension->NdisProtocolHandle ); + + //free the global device extension + NdisFreeMemory(GlobalDeviceExtension,sizeof( DEVICE_EXTENSION ),0); + } + + break; + + case IOCTL_PROTOCOL_RESET: + + PacketReset( &Status, Open ); + + break; + + case BIOCQUERYOID: + case BIOCSETOID: + case IOCTL_PROTOCOL_STATISTICS: + + return PacketRequest( Open, dwService, dwDDB, hDevice, pDiocParms ); + + case IOCTL_PROTOCOL_READ: + + return PacketRead( Open, dwDDB, hDevice, pDiocParms ); + + case IOCTL_PROTOCOL_WRITE: + + return PacketWrite( Open, dwDDB, hDevice, pDiocParms ); + + case IOCTL_PROTOCOL_MACNAME: + + PacketGetMacNameList( dwDDB, hDevice, pDiocParms ); + break; + + default: + /*unknown function*/ + *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; + break; + } + TRACE_LEAVE( "DeviceIoControl" ); + + return NDIS_STATUS_SUCCESS; +} + + + +/************************************************************ +Function called by NDIS when there is something to communicate +to the upper level +************************************************************/ +VOID +PacketStatus( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN PVOID StatusBuffer, + IN UINT StatusBufferSize + ) +{ + TRACE_ENTER( "Status Indication" ); + TRACE_LEAVE( "Status Indication" ); + return; +} + +/************************************************************ +Complete the previous call +************************************************************/ +VOID NDIS_API +PacketStatusComplete( + IN NDIS_HANDLE ProtocolBindingContext + ) +{ + + TRACE_ENTER( "StatusIndicationComplete" ); + TRACE_LEAVE( "StatusIndicationComplete" ); + return; +} + +/************************************************************ +Removes an element from a list. +Performs a check to see if the list is empty +************************************************************/ +PLIST_ENTRY +PacketRemoveHeadList( + IN PLIST_ENTRY pListHead + ) +{ + if ( !IsListEmpty( pListHead ) ) + { + PLIST_ENTRY pLE = RemoveHeadList( pListHead ); + return pLE; + } + + return NULL; +} diff --git a/winpcap/Packet9x/VXD/Packet.h b/winpcap/Packet9x/VXD/Packet.h new file mode 100644 index 0000000..c6fbc90 --- /dev/null +++ b/winpcap/Packet9x/VXD/Packet.h @@ -0,0 +1,375 @@ +/* + * Copyright (c) 1999 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + + +struct timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; + +// OID definitions +#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F +// IOCTLs +#define BIOCSETBUFFERSIZE 9592 +#define BIOCSETF 9030 +#define BIOCGSTATS 9031 +#define BIOCSRTIMEOUT 7416 +#define BIOCSMODE 7412 +#define BIOCSWRITEREP 7413 +#define BIOATTACHPROCESS 7117 +#define BIODETACHPROCESS 7118 +#define BIOCEVNAME 7415 +#define BIOCSETOID 2147483648 +#define BIOCQUERYOID 2147483652 + +#define BIOCSTIMEZONE 7471 + +// working modes +#define MODE_CAPT 0 +#define MODE_STAT 1 + +// +// Alignment macros. Packet_WORDALIGN rounds up to the next +// even multiple of Packet_ALIGNMENT. +// +#define Packet_ALIGNMENT sizeof(int) +#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) + +// from BPF +struct bpf_program { + UINT bf_len; + struct bpf_insn *bf_insns; +}; + +// from BPF +struct bpf_insn { + USHORT code; + UCHAR jt; + UCHAR jf; + int k; +}; + +// from BPF +struct bpf_hdr { + struct timeval bh_tstamp; /* time stamp */ + UINT bh_caplen; /* length of captured portion */ + UINT bh_datalen; /* original length of packet */ + USHORT bh_hdrlen; /* length of bpf header (this struct plus alignment padding) */ +}; + +#define MAX_BUFFER_SPACE MAX_PACKET_LENGTH+sizeof(struct bpf_hdr) + + + +#define MAX_REQUESTS 4 +#ifdef DEBUG +#define PACKETASSERT(a) if( !(a) ) { DbgPrint( "Packet: ASSERTION FAILED!\r\n" ); DbgBreakPoint(); } +#else +#define PACKETASSERT(a) +#endif +struct _PACKET_RESERVED +{ + LIST_ENTRY ListElement; + char* lpBuffer; + DWORD cbBuffer; + DWORD* lpcbBytesReturned; + OVERLAPPED* lpoOverlapped; +}; +typedef struct _PACKET_RESERVED PACKET_RESERVED, *PPACKET_RESERVED; + +struct _INTERNAL_REQUEST +{ + PACKET_RESERVED Reserved; + NDIS_REQUEST Request; +}; +typedef struct _INTERNAL_REQUEST INTERNAL_REQUEST, *PINTERNAL_REQUEST; + + +struct _OPEN_ADAPTER +{ + LIST_ENTRY ListElement; + NDIS_STATUS Status; + NDIS_HANDLE AdapterHandle; + NDIS_HANDLE BindAdapterContext; +}; + +typedef struct _OPEN_ADAPTER OPEN_ADAPTER, *POPEN_ADAPTER; + + +typedef struct _OPEN_INSTANCE +{ + LIST_ENTRY ListElement; + NDIS_STATUS Status; + NDIS_HANDLE AdapterHandle; + NDIS_HANDLE BindAdapterContext; + + NDIS_HANDLE BufferPool; + NDIS_SPIN_LOCK RcvQSpinLock; + LIST_ENTRY RcvList; + NDIS_SPIN_LOCK RequestSpinLock; + LIST_ENTRY RequestList; + NDIS_SPIN_LOCK ResetSpinLock; + LIST_ENTRY ResetIrpList; + INTERNAL_REQUEST Requests[MAX_REQUESTS]; + DWORD hDevice; + DWORD tagProcess; + + NDIS_HANDLE PacketPool; + PUCHAR Buffer; + NDIS_SPIN_LOCK BufferLock; + UINT Dropped; + UINT Received; + PUCHAR bpfprogram; + UINT bpfprogramlen; + __int64 StartTime; + UINT Bhead; + UINT Btail; + UINT BufSize; + UINT BLastByte; + UINT TimeOut; + UINT ReadTimeoutTimer; + int mode; + __int64 Nbytes; + __int64 Npackets; + NDIS_SPIN_LOCK CountersLock; + UINT Nwrites; + UINT Multiple_Write_Counter; + DWORD ReadEvent; + +} OPEN_INSTANCE, *POPEN_INSTANCE; + +typedef struct ADAPTER_NAME +{ +LIST_ENTRY ListElement; +char realname[32]; +char devicename[32]; +NDIS_STRING realnamestr; +}ADAPTER_NAME, *PADAPTER_NAME; + +struct _DEVICE_EXTENSION +{ + PDRIVER_OBJECT DriverObject; + NDIS_HANDLE NdisProtocolHandle; + LIST_ENTRY OpenList; + NDIS_SPIN_LOCK OpenSpinLock; + LIST_ENTRY AdapterNames; +}; + +typedef struct _DEVICE_EXTENSION DEVICE_EXTENSION, *PDEVICE_EXTENSION; +extern PDEVICE_EXTENSION GlobalDeviceExtension; +#define ETHERNET_HEADER_LENGTH 14 +#define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) +#define TRANSMIT_PACKETS 32 +extern void YieldExecution( void ); + + +DWORD Bind_Names(void); + +VOID _cdecl ReadTimeout(void); + +__int64 QuerySystemTime(void); + +LARGE_INTEGER GetDate(void); + +void EchoStr(void); + + +int bpf_validate(struct bpf_insn *f,int len); +UINT bpf_filter(register struct bpf_insn *pc, + register UCHAR *p, + UINT wirelen, + register UINT buflen); + +UINT bpf_filter_with_2_buffers(register struct bpf_insn *pc, + register UCHAR *p, + register UCHAR *pd, + register int headersize, + UINT wirelen, + register UINT buflen); + +PLIST_ENTRY +PacketRemoveHeadList( + IN PLIST_ENTRY pListHead + ); +VOID NDIS_API + +PacketOpenAdapterComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN NDIS_STATUS OpenErrorStatus + ); +VOID NDIS_API +PacketUnbindAdapterComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status + ); +NDIS_STATUS NDIS_API +Packet_tap( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_HANDLE MacReceiveContext, + IN PVOID HeaderBuffer, + IN UINT HeaderBufferSize, + IN PVOID LookAheadBuffer, + IN UINT LookaheadBufferSize, + IN UINT PacketSize + ); +VOID NDIS_API +PacketReceiveComplete( + IN NDIS_HANDLE ProtocolBindingContext + ); +DWORD +PacketRequest( POPEN_INSTANCE pOpen, + DWORD FunctionCode, + DWORD dwDDB, + DWORD hDevice, + PDIOCPARAMETERS pDiocParms + ); +VOID NDIS_API +PacketRequestComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_REQUEST pRequest, + IN NDIS_STATUS Status + ); +VOID NDIS_API +PacketSendComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET pPacket, + IN NDIS_STATUS Status + ); +VOID +PacketReset( PNDIS_STATUS pStatus, + POPEN_INSTANCE pOpen ); +VOID NDIS_API +PacketResetComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status + ); +VOID NDIS_API +PacketStatus( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN PVOID StatusBuffer, + IN UINT StatusBufferSize + ); +VOID NDIS_API +PacketStatusComplete( + IN NDIS_HANDLE ProtocolBindingContext + ); +VOID +PacketAllocatePacketBuffer( PNDIS_STATUS pStatus, + POPEN_INSTANCE pOpen, + PNDIS_PACKET *lplpPacket, + PDIOCPARAMETERS pDiocParms, + DWORD FunctionCode ); +VOID NDIS_API +PacketTransferDataComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET Packet, + IN NDIS_STATUS Status, + IN UINT BytesTransferred + ); +VOID +PacketRemoveReference( + IN PDEVICE_EXTENSION DeviceExtension + ); +VOID +PacketFreeResources( POPEN_INSTANCE Open ); +VOID +PacketCleanUp( PNDIS_STATUS Status, + POPEN_INSTANCE Open ); +NTSTATUS NDIS_API +PacketShutdown( + IN PDEVICE_OBJECT DeviceObject + ); + +VOID NDIS_API PacketUnload(); + + +VOID NDIS_API +PacketBindAdapter( OUT PNDIS_STATUS Status, + IN NDIS_HANDLE BindAdapterContext, + IN PNDIS_STRING AdapterName, + IN PVOID SystemSpecific1, + IN PVOID SystemSpecific2 + ); +VOID NDIS_API +PacketUnbindAdapter( OUT PNDIS_STATUS Status, + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_HANDLE UnbindContext + ); +DWORD +PacketWrite( POPEN_INSTANCE Open, + DWORD dwDDB, + DWORD hDevice, + PDIOCPARAMETERS pDiocParms + ); + +DWORD PacketOpen(PNDIS_STRING AdapterName,DWORD dwDDB,DWORD hDevice,PDIOCPARAMETERS pDiocParms/*, int CloseMode*/); + +DWORD +PacketClose( POPEN_INSTANCE Open, + DWORD dwDDB, + DWORD hDevice, + PDIOCPARAMETERS pDiocParms + ); + + +DWORD +PacketRead( POPEN_INSTANCE Open, + DWORD dwDDB, + DWORD hDevice, + PDIOCPARAMETERS pDiocParms + ); +DWORD _stdcall PacketIOControl( DWORD dwService, + DWORD dwDDB, + DWORD hDevice, + PDIOCPARAMETERS lpDIOCParms ); +void VXDINLINE +VWIN32_DIOCCompletionRoutine( DWORD hEvent ) +{ + _asm mov ebx, hEvent + VxDCall( VWIN32_DIOCCompletionRoutine ); +} + +ULONG strlen( BYTE *s ); +BYTE compare(BYTE *, BYTE *); +#define strcat( d, s ) NdisMoveMemory( d+strlen(d), s, strlen(s) ) +#define memset( _S, _C, _N )\ +{\ + UCHAR* _pS = _S;\ + ULONG _I = _N;\ + while ( _I-- )\ + {\ + *_pS++ = _C;\ + }\ +} diff --git a/winpcap/Packet9x/VXD/Read.c b/winpcap/Packet9x/VXD/Read.c new file mode 100644 index 0000000..3bdfae8 --- /dev/null +++ b/winpcap/Packet9x/VXD/Read.c @@ -0,0 +1,769 @@ +/* + * Copyright (c) 1999 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include +#include +#include +#include +#include "debug.h" +#include "packet.h" +#include +#pragma VxD_LOCKED_CODE_SEG +#pragma VxD_LOCKED_DATA_SEG +DWORD _stdcall MyPageLock(DWORD, DWORD); +void _stdcall MyPageUnlock(DWORD, DWORD); + +/************************************************************ +Allocates the space for a packet, extracting it from the +buffer reserved for the driver +************************************************************/ +VOID +PacketAllocatePacketBuffer( PNDIS_STATUS pStatus, + POPEN_INSTANCE pOpen, + PNDIS_PACKET *lplpPacket, + PDIOCPARAMETERS pDiocParms, + DWORD FunctionCode ) +{ + PNDIS_BUFFER pNdisBuffer; + PPACKET_RESERVED pReserved; + + + TRACE_ENTER( "PacketAllocatePacket" ); + NdisAllocatePacket( pStatus, lplpPacket, pOpen->PacketPool ); + if ( *pStatus != NDIS_STATUS_SUCCESS ) + { + IF_VERY_LOUD( "Read- No free packets" ); + *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; + return; + } + InitializeListHead( &(RESERVED(*lplpPacket)->ListElement) ); + pReserved = RESERVED(*lplpPacket); + switch ( FunctionCode ) + { + case IOCTL_PROTOCOL_READ: + pReserved->lpBuffer = (PVOID)PacketPageLock( (PVOID)pDiocParms->lpvOutBuffer, + pDiocParms->cbOutBuffer ); + pReserved->cbBuffer = pDiocParms->cbOutBuffer; + break; + case IOCTL_PROTOCOL_WRITE: + pReserved->lpBuffer = (PVOID)PacketPageLock( pDiocParms->lpvInBuffer, + pDiocParms->cbInBuffer ); + pReserved->cbBuffer = pDiocParms->cbInBuffer; + break; + default: + /*function not valid, free the resource*/ + IF_TRACE_MSG( "Allocate- Invalid FunctionCode %x", FunctionCode ); + NdisReinitializePacket( *lplpPacket ); + NdisFreePacket( *lplpPacket ); + *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; + *pStatus = NDIS_STATUS_NOT_ACCEPTED; + return; + } + pReserved->lpcbBytesReturned = + (PVOID)PacketPageLock( (PVOID)pDiocParms->lpcbBytesReturned, sizeof(DWORD) ); + pReserved->lpoOverlapped = + + (PVOID)PacketPageLock( (PVOID)pDiocParms->lpoOverlapped, sizeof(OVERLAPPED) ); + + NdisAllocateBuffer( pStatus, + &pNdisBuffer, + pOpen->BufferPool, + (PVOID)pReserved->lpBuffer, + pDiocParms->cbOutBuffer ); + if ( *pStatus != NDIS_STATUS_SUCCESS ) + { + IF_TRACE( "Read- No free buffers" ); + NdisReinitializePacket(*lplpPacket); + NdisFreePacket(*lplpPacket); + *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; + return; + } + NdisChainBufferAtFront( *lplpPacket, pNdisBuffer ); + IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) + { + IF_TRACE_MSG( " lplpPacket : %lx", lplpPacket ); + IF_TRACE_MSG( " lpPacket : %lx", *lplpPacket ); + IF_TRACE_MSG3( "pNdisBuffer : %lx %lx %lx", pNdisBuffer, (*lplpPacket)->Private.Head, (*lplpPacket)->Private.Tail ); + IF_TRACE_MSG( " Reserved : %lx", pReserved ); + IF_TRACE_MSG4( " lpBuffer : %lx %lx %lx %lx", pReserved->lpBuffer, pNdisBuffer->VirtualAddress, pDiocParms->lpvOutBuffer, pDiocParms->lpvInBuffer ); + IF_TRACE_MSG3( " cbBuffer : %lx %lx %lx", pReserved->cbBuffer, pDiocParms->cbOutBuffer, pDiocParms->cbInBuffer ); + IF_TRACE_MSG2( " lpcbBytes : %lx %lx", pReserved->lpcbBytesReturned, pDiocParms->lpcbBytesReturned ); + IF_TRACE_MSG2( " lpoOverlap : %lx %lx", pReserved->lpoOverlapped, pDiocParms->lpoOverlapped ); + } + PACKETASSERT( pReserved->lpBuffer ); + PACKETASSERT( pReserved->cbBuffer ); + PACKETASSERT( pReserved->lpcbBytesReturned ); + PACKETASSERT( pReserved->lpoOverlapped ); + PACKETASSERT( pNdisBuffer == (*lplpPacket)->Private.Head ); + PACKETASSERT( pNdisBuffer->VirtualAddress == pReserved->lpBuffer ); + TRACE_LEAVE( "PacketAllocatePacket" ); + return; +} + +/************************************************************ +Move a portion of the circular buffer +updating the head every 1024 bytes +************************************************************/ + +void PacketMoveMem(PVOID Destination, + PVOID Source, + ULONG Length, + UINT *Bhead) +{ +ULONG WordLength; +UINT n,i,NBlocks; + + WordLength=Length>>2; + NBlocks=WordLength>>8; + + for(n=0;ncbOutBuffer < ETHERNET_HEADER_LENGTH ) + { + /*the application's buffer if too small to contain the packet*/ + *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; + IF_VERY_LOUD( "Read- Buffer too small" ); + TRACE_LEAVE( "ReadPacket" ); + return NDIS_STATUS_FAILURE; + } + + /*See if there are packets in the buffer*/ + + Thead=Open->Bhead; + Ttail=Open->Btail; + TLastByte=Open->BLastByte; + + if (Thead == Ttail) + { + + /*there aren't buffered packet but there is no timeout */ + if(Open->TimeOut == -1){ + *(DWORD *)(pDiocParms->lpcbBytesReturned)=0; + return(NDIS_STATUS_SUCCESS); + } + + /*there aren't buffered packet and there is a timeout: the application must wait*/ + PacketAllocatePacketBuffer( &Status, Open, &pPacket, pDiocParms, IOCTL_PROTOCOL_READ ); + if ( Status == NDIS_STATUS_SUCCESS ) + { + PACKETASSERT( Open != NULL ); + PACKETASSERT( pPacket != NULL ); + + NdisAcquireSpinLock( &Open->RcvQSpinLock ); + InsertTailList( &Open->RcvList, &RESERVED(pPacket)->ListElement ); + NdisReleaseSpinLock( &Open->RcvQSpinLock ); + + /*set the timeout on the read*/ + Open->ReadTimeoutTimer=SetReadTimeOut(ReadTimeout,Open->TimeOut,Open); + + IF_TRACE_MSG2( "RcvList Link : %lx %lx", Open->RcvList.Blink, &RESERVED(pPacket)->ListElement ); + PACKETASSERT( Open->RcvList.Blink == &RESERVED(pPacket)->ListElement ); + PACKETASSERT( &(Open->RcvList) == RESERVED(pPacket)->ListElement.Flink ); + } + + TRACE_LEAVE( "PacketRead" ); + return(-1); /*Communicate that the operation is asynchronous*/ + } + + /*there is at least a buffered packet: the read call can be completed*/ + + Input_Buffer_Length=pDiocParms->cbOutBuffer; + packp=(PUCHAR)pDiocParms->lpvOutBuffer; + i=0; + /*get the address of the buffer*/ + CurrBuff=Open->Buffer; + + /*fill the application buffer*/ + + /*first of all see if it we can copy all the buffer in one time*/ + if(Ttail>Thead){ + if((Ttail-Thead)Bhead)); + *(DWORD *)(pDiocParms->lpcbBytesReturned)=Ttail-Thead; + + // The buffer is empty: reset the read event + TEvent=Open->ReadEvent; + _asm mov eax,TEvent; + VxDCall(_VWIN32_ResetWin32Event); + + return(NDIS_STATUS_SUCCESS); + } + } + else if((TLastByte-Thead)Bhead)); + Open->BLastByte=Ttail; + Open->Bhead=0; + *(DWORD *)(pDiocParms->lpcbBytesReturned)=TLastByte-Thead; + return(NDIS_STATUS_SUCCESS); + } + + /*scan the buffer*/ + CpStart=Thead; + while(TRUE){ + if(Thead==Ttail)break; + if(Thead==TLastByte){ + PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead)); + packp+=(Thead-CpStart); + Open->Bhead=0; + Thead=0; + CpStart=0; + } + cplen=((struct bpf_hdr*)(CurrBuff+Thead))->bh_caplen+sizeof(struct bpf_hdr); + if((i+cplen > Input_Buffer_Length))break; //no more space in the application buffer + cplen=Packet_WORDALIGN(cplen); + i+=cplen; + Thead+=cplen; + } + + PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead)); + + *(DWORD *)(pDiocParms->lpcbBytesReturned)=i; + return(NDIS_STATUS_SUCCESS); + +} + +/************************************************************ +Callback routine called by NDIS when the adapter receives a +packet +************************************************************/ +NDIS_STATUS NDIS_API +Packet_tap ( IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_HANDLE MacReceiveContext, + IN PVOID pvHeaderBuffer, + IN UINT uiHeaderBufferSize, + IN PVOID pvLookAheadBuffer, + IN UINT uiLookaheadBufferSize, + IN UINT uiPacketSize + ) +#define pOpen ((POPEN_INSTANCE)ProtocolBindingContext) +{ + PLIST_ENTRY PacketListEntry; + PNDIS_PACKET pPacket; + ULONG ulSizeToTransfer; + NDIS_STATUS Status; + UINT uiBytesTransferred; + PPACKET_RESERVED pReserved; + PNDIS_BUFFER pNdisBuffer; + PVOID pvActualVirtualAddress; + UINT uiActualLength; + PUCHAR CurrBuff; + UINT Thead; + UINT Ttail; + UINT TLastByte; + PNDIS_PACKET pPacketb; + struct bpf_hdr *header; + LARGE_INTEGER CapTime; + __int64 lCapTime; + UINT fres; //filter result + UINT maxbufspace; + UINT to; + DWORD TEvent; + + TRACE_ENTER( "Packet_tap" ); + + PACKETASSERT( (pOpen != NULL) ); + + + pOpen->Received++; /*number of packets received by filter ++*/ + + /* + Check if the lookahead buffer follows the mac header. + If the data follow the header (i.e. there is only a buffer) a normal bpf_filter() is + executed on the packet. + Otherwise if there are 2 separate buffers (this could be the case of LAN emulation or + stuff like this) bpf_filter_with_2_buffers() is executed. + */ + + if((int)pvLookAheadBuffer-(int)pvHeaderBuffer != uiHeaderBufferSize) + fres=bpf_filter_with_2_buffers((struct bpf_insn*)(pOpen->bpfprogram), + pvHeaderBuffer, + pvLookAheadBuffer, + uiHeaderBufferSize, + uiPacketSize+uiHeaderBufferSize, + uiLookaheadBufferSize+uiHeaderBufferSize); + else + fres=bpf_filter((struct bpf_insn*)(pOpen->bpfprogram), + pvHeaderBuffer, + uiPacketSize+uiHeaderBufferSize, + uiLookaheadBufferSize+uiHeaderBufferSize); + + if(fres==0)return NDIS_STATUS_NOT_ACCEPTED; + if( fres==-1)fres=uiPacketSize+uiHeaderBufferSize; //if the filter returns -1 the whole packet must be accepted + + + if(pOpen->mode==1){ + /*statistics mode*/ + NdisAcquireSpinLock( &pOpen->CountersLock ); + + pOpen->Npackets++; + + if(uiPacketSize+uiHeaderBufferSize<60) + pOpen->Nbytes+=60; + else + pOpen->Nbytes+=uiPacketSize+uiHeaderBufferSize; + + /*add preamble+SFD+FCS to the packet + these values must be considered because are not part of the packet received from NDIS*/ + pOpen->Nbytes+=12; + + NdisReleaseSpinLock( &pOpen->CountersLock ); + + return NDIS_STATUS_NOT_ACCEPTED; //it should be quicker + } + + + /*see if there are pending requests*/ + NdisAcquireSpinLock( &pOpen->RcvQSpinLock ); + PacketListEntry = PacketRemoveHeadList( &pOpen->RcvList ); + NdisReleaseSpinLock( &pOpen->RcvQSpinLock ); + + if ( PacketListEntry == NULL ) + { + /*no requests. This means that the application is not performing a read in this + moment: the packet must go in the buffer*/ + + TRACE_ENTER( "IndicateReceive" ); + + if(pOpen->BufSize==0)return NDIS_STATUS_NOT_ACCEPTED; + + Thead=pOpen->Bhead; + Ttail=pOpen->Btail; + TLastByte=pOpen->BLastByte; + + + maxbufspace=fres+sizeof(struct bpf_hdr); + if(Ttail+maxbufspace>=pOpen->BufSize){ + if(Thead<=maxbufspace) + { + /*the buffer is full: the packet is lost*/ + pOpen->Dropped++; + return NDIS_STATUS_NOT_ACCEPTED; + } + else{ + Ttail=0; + } + } + + if((Ttail=Thead)) + { + /*the buffer is full: the packet is lost*/ + pOpen->Dropped++; + return NDIS_STATUS_NOT_ACCEPTED; + } + CurrBuff=pOpen->Buffer+Ttail; + + + /*allocate the ndis buffer*/ + NdisAllocateBuffer( &Status, + &pNdisBuffer, + pOpen->BufferPool, + CurrBuff+sizeof(struct bpf_hdr), + fres); + + if (Status != NDIS_STATUS_SUCCESS) + { + pOpen->Dropped++; + return NDIS_STATUS_NOT_ACCEPTED; + } + + /*allocate the packet from NDIS*/ + NdisAllocatePacket(&Status,&pPacketb,pOpen->PacketPool); + if (Status != NDIS_STATUS_SUCCESS) + { + NdisFreeBuffer( pNdisBuffer ); + pOpen->Dropped++; + return NDIS_STATUS_NOT_ACCEPTED; + } + /*link the buffer to the packet*/ + NdisChainBufferAtFront(pPacketb,pNdisBuffer); + + if ( uiHeaderBufferSize > 0 ) + { + if ( uiHeaderBufferSize > pNdisBuffer->Length ) + uiHeaderBufferSize = pNdisBuffer->Length; + /*copy the header*/ + NdisMoveMemory(pNdisBuffer->VirtualAddress, pvHeaderBuffer, uiHeaderBufferSize ); + uiBytesTransferred = uiHeaderBufferSize; + (BYTE *)(pNdisBuffer->VirtualAddress) += uiHeaderBufferSize; + pNdisBuffer->Length -= uiHeaderBufferSize; + } + + ulSizeToTransfer = uiPacketSize; + if ( ulSizeToTransfer > pNdisBuffer->Length ) + ulSizeToTransfer = pNdisBuffer->Length; + + /*Copy the remaining part of the packet*/ + NdisTransferData( &Status, + pOpen->AdapterHandle, + MacReceiveContext, + 0, + ulSizeToTransfer, + pPacketb, + &uiBytesTransferred ); + + uiBytesTransferred+=uiHeaderBufferSize; + + + /*get the capture time*/ + lCapTime=QuerySystemTime(); + + /*fill the bpf header for this packet*/ + if( fres>uiBytesTransferred )fres=uiBytesTransferred; + lCapTime+=pOpen->StartTime; + header=(struct bpf_hdr*)CurrBuff; + header->bh_tstamp.tv_usec=(long)((lCapTime%1193182)*1000000/1193182); + header->bh_tstamp.tv_sec=(long)((lCapTime)/1193182); + header->bh_caplen=(UINT)fres; + header->bh_datalen=(UINT)uiPacketSize+uiHeaderBufferSize; + header->bh_hdrlen=sizeof(struct bpf_hdr); + + /*update the buffer*/ + Ttail+=Packet_WORDALIGN(fres+sizeof(struct bpf_hdr)); + if(Ttail>Thead)TLastByte=Ttail; + pOpen->Btail=Ttail; + pOpen->BLastByte=TLastByte; + + /*free the allocated buffer*/ + NdisFreeBuffer( pNdisBuffer ); + /*recylcle the packet*/ + NdisReinitializePacket(pPacketb); + /*Put the packet on the free queue*/ + NdisFreePacket(pPacketb); + + TEvent=pOpen->ReadEvent; + _asm mov eax,TEvent; + VxDCall(_VWIN32_SetWin32Event); + + TRACE_LEAVE( "Packet_tap" ); + return NDIS_STATUS_SUCCESS; + + + } + + /*cancel the timeout on this read call*/ + to=pOpen->ReadTimeoutTimer; + _asm push esi; + _asm mov esi,to; + CancelReadTimeOut(); + _asm pop esi; + pOpen->ReadTimeoutTimer=0; + + + pReserved = CONTAINING_RECORD( PacketListEntry, PACKET_RESERVED, ListElement ); + pPacket = CONTAINING_RECORD( pReserved, NDIS_PACKET, ProtocolReserved ); + IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) + { + IF_TRACE_MSG( " Reserved : %lx", pReserved ); + IF_TRACE_MSG( " pPacket : %lx", pPacket ); + IF_TRACE_MSG2( " Header : %lx %lx", pvHeaderBuffer, uiHeaderBufferSize ); + IF_TRACE_MSG2( " LookAhead : %lx %lx", pvLookAheadBuffer, uiLookaheadBufferSize ); + IF_TRACE_MSG( " PacketSize : %lx", uiPacketSize ); + } + PACKETASSERT( (pReserved != NULL) ); + PACKETASSERT( (pPacket != NULL) ); + + pNdisBuffer = pPacket->Private.Head; + /*virtual address of the buffer that will contain the packet*/ + pvActualVirtualAddress = pNdisBuffer->VirtualAddress; + uiActualLength = pNdisBuffer->Length; + + CurrBuff=pNdisBuffer->VirtualAddress; + (BYTE *)(pNdisBuffer->VirtualAddress) += sizeof(struct bpf_hdr); + + + if ( uiHeaderBufferSize > 0 ) + { + if ( uiHeaderBufferSize > pNdisBuffer->Length ) + uiHeaderBufferSize = pNdisBuffer->Length; + /*copy the header*/ + NdisMoveMemory(pNdisBuffer->VirtualAddress, pvHeaderBuffer, uiHeaderBufferSize ); + uiBytesTransferred = uiHeaderBufferSize; + (BYTE *)(pNdisBuffer->VirtualAddress) += uiHeaderBufferSize; + pNdisBuffer->Length -= uiHeaderBufferSize; + } + + ulSizeToTransfer = uiPacketSize/*uiPacketSize - uiLookaheadBufferSize*/; + if ( ulSizeToTransfer > pNdisBuffer->Length ) + ulSizeToTransfer = pNdisBuffer->Length; + + /*Copy the remaining part of the packet*/ + NdisTransferData( &Status, + pOpen->AdapterHandle, + MacReceiveContext, + 0, + ulSizeToTransfer, + pPacket, + &uiBytesTransferred ); + + uiBytesTransferred+=uiHeaderBufferSize; + + + pNdisBuffer->VirtualAddress = pvActualVirtualAddress; + pNdisBuffer->Length = uiActualLength; + if ( Status != NDIS_STATUS_PENDING ) + { + + /*store the capture time*/ + lCapTime=QuerySystemTime(); + + /*fill the bpf header for this packet*/ + if( fres>uiBytesTransferred )fres=uiBytesTransferred; + lCapTime+=pOpen->StartTime; + header=(struct bpf_hdr*)CurrBuff; + header->bh_tstamp.tv_usec=(long)((lCapTime%1193182)*1000000/1193182); + header->bh_tstamp.tv_sec=(long)((lCapTime)/1193182); + header->bh_caplen=(UINT)fres; + header->bh_datalen=(UINT)uiPacketSize+uiHeaderBufferSize; + header->bh_hdrlen=sizeof(struct bpf_hdr); + /*call the completion routine*/ + PacketTransferDataComplete( pOpen, + pPacket, + Status, + fres); + + } + else + { + Status = NDIS_STATUS_SUCCESS; + PacketTransferDataComplete( pOpen, + pPacket, + Status, + 0 ); + + } + TRACE_LEAVE( "Packet_tap" ); + return NDIS_STATUS_SUCCESS; +} + +/*Ends the transfer started with the Packet_tap function*/ +VOID NDIS_API +PacketTransferDataComplete ( IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET pPacket, + IN NDIS_STATUS Status, + IN UINT uiBytesTransferred + ) +{ + PPACKET_RESERVED pReserved; + OVERLAPPED* pOverlap; + PNDIS_BUFFER pNdisBuffer; + TRACE_ENTER( "TransferDataComplete" ); + pReserved = (PPACKET_RESERVED) pPacket->ProtocolReserved; + pOverlap = (OVERLAPPED *) pReserved->lpoOverlapped; + PACKETASSERT( (pOpen != NULL) ); + PACKETASSERT( (pReserved != NULL) ); + PACKETASSERT( (pOverlap != NULL) ); + + IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) + { + IF_TRACE_MSG( " Status : %lx", Status ); + IF_TRACE_MSG( "BytesXfered : %lx", uiBytesTransferred ); + IF_TRACE_MSG( "Byte Offset : %lx", *(pReserved->lpcbBytesReturned) ); + } + + NdisUnchainBufferAtFront( pPacket, &pNdisBuffer ); + PACKETASSERT( (pNdisBuffer != NULL) ); + if ( pNdisBuffer ) + NdisFreeBuffer( pNdisBuffer ); + + *(pReserved->lpcbBytesReturned) = uiBytesTransferred+sizeof(struct bpf_hdr); + pOverlap->O_InternalHigh = *(pReserved->lpcbBytesReturned); + /*wakes the application process*/ + VWIN32_DIOCCompletionRoutine( pOverlap->O_Internal ); + + PacketPageUnlock( pReserved->lpBuffer, pReserved->cbBuffer ); + PacketPageUnlock( pReserved->lpcbBytesReturned, sizeof(DWORD) ); + PacketPageUnlock( pReserved->lpoOverlapped, sizeof(OVERLAPPED) ); + + NdisReinitializePacket( pPacket ); + + NdisFreePacket( pPacket ); + TRACE_LEAVE( "TransferDataComplete" ); + return; +} + +VOID NDIS_API +PacketReceiveComplete( IN NDIS_HANDLE ProtocolBindingContext ) +{ + IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) + { + TRACE_ENTER( "ReceiveComplete" ); + TRACE_LEAVE( "ReceiveComplete" ); + } + return; +} + +/************************************************************ +Routine called by the kernel when the timeout set in the +PacketRead function expires +************************************************************/ +void _cdecl ReadTimeout(void) +{ + POPEN_INSTANCE Open; + PLIST_ENTRY PacketListEntry; + PNDIS_PACKET pPacket; + PPACKET_RESERVED Reserved; + OVERLAPPED* pOverlap; + PNDIS_BUFFER pNdisBuffer; + PUCHAR CurrBuff; + struct bpf_hdr *header; + UINT to; + __int64 lCapTime; + + //the parameter is in edx + _asm{ + mov Open,edx + } + + NdisAcquireSpinLock( &Open->RcvQSpinLock ); + PacketListEntry = PacketRemoveHeadList( &Open->RcvList ); + NdisReleaseSpinLock( &Open->RcvQSpinLock ); + Open->ReadTimeoutTimer=0; + + if (PacketListEntry == NULL) + { + return; + } + + Reserved=CONTAINING_RECORD(PacketListEntry,PACKET_RESERVED,ListElement); + pPacket=CONTAINING_RECORD(Reserved,NDIS_PACKET,ProtocolReserved); + + Reserved = (PPACKET_RESERVED) pPacket->ProtocolReserved; + pOverlap = (OVERLAPPED *) Reserved->lpoOverlapped; + + if(Open->mode==1){ + //count mode + pNdisBuffer = pPacket->Private.Head; + CurrBuff=pNdisBuffer->VirtualAddress; + + /*get system time*/ + lCapTime=QuerySystemTime(); + /*fill the bpf header for this packet*/ + lCapTime+=Open->StartTime; + header=(struct bpf_hdr*)CurrBuff; + header->bh_tstamp.tv_usec=(long)((lCapTime%1193182)*1000000/1193182); + header->bh_tstamp.tv_sec=(long)((lCapTime)/1193182); + header->bh_caplen=(UINT)16; + header->bh_datalen=(UINT)16; + header->bh_hdrlen=sizeof(struct bpf_hdr); + + *(__int64*)(CurrBuff+sizeof(struct bpf_hdr))=Open->Npackets; + *(__int64*)(CurrBuff+sizeof(struct bpf_hdr)+8)=Open->Nbytes; + + //reset the countetrs + Open->Npackets=0; + Open->Nbytes=0; + + NdisUnchainBufferAtFront( pPacket, &pNdisBuffer ); + if ( pNdisBuffer ) + NdisFreeBuffer( pNdisBuffer ); + + *(Reserved->lpcbBytesReturned) = 16 + sizeof(struct bpf_hdr); + pOverlap->O_InternalHigh = 16 + sizeof(struct bpf_hdr); + VWIN32_DIOCCompletionRoutine( pOverlap->O_Internal ); + + PacketPageUnlock( Reserved->lpBuffer, Reserved->cbBuffer ); + PacketPageUnlock( Reserved->lpcbBytesReturned, sizeof(DWORD) ); + PacketPageUnlock( Reserved->lpoOverlapped, sizeof(OVERLAPPED) ); + + NdisReinitializePacket( pPacket ); + + NdisFreePacket( pPacket ); + + return; + } + + NdisUnchainBufferAtFront( pPacket, &pNdisBuffer ); + if ( pNdisBuffer ) + NdisFreeBuffer( pNdisBuffer ); + + //wakes the application process + *(Reserved->lpcbBytesReturned) = 0; + pOverlap->O_InternalHigh = *(Reserved->lpcbBytesReturned); + + VWIN32_DIOCCompletionRoutine( pOverlap->O_Internal ); + + PacketPageUnlock( Reserved->lpBuffer, Reserved->cbBuffer ); + PacketPageUnlock( Reserved->lpcbBytesReturned, sizeof(DWORD) ); + PacketPageUnlock( Reserved->lpoOverlapped, sizeof(OVERLAPPED) ); + + NdisReinitializePacket( pPacket ); + + NdisFreePacket( pPacket ); + + return; + +} diff --git a/winpcap/Packet9x/VXD/Request.c b/winpcap/Packet9x/VXD/Request.c new file mode 100644 index 0000000..962bb80 --- /dev/null +++ b/winpcap/Packet9x/VXD/Request.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 1999 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include +#include +#include +#include "debug.h" +#include "packet.h" +#include +#pragma VxD_LOCKED_CODE_SEG +#pragma VxD_LOCKED_DATA_SEG + +/************************************************************ +Function that allows to perform a query on a network driver +or to set the parameters of an adapter. +************************************************************/ +DWORD +PacketRequest( POPEN_INSTANCE Open, + DWORD FunctionCode, + DWORD dwDDB, + DWORD hDevice, + PDIOCPARAMETERS pDiocParms ) +{ + PLIST_ENTRY RequestListEntry; + PINTERNAL_REQUEST pRequest; + PPACKET_RESERVED pReserved; + PPACKET_OID_DATA OidData; + NDIS_STATUS Status; + TRACE_ENTER( "Request Packet" ); + /*extract a request from the list*/ + NdisAcquireSpinLock( &Open->RequestSpinLock ); + RequestListEntry = PacketRemoveHeadList(&Open->RequestList); + NdisReleaseSpinLock( &Open->RequestSpinLock ); + if ( RequestListEntry == NULL ) + { + IF_TRACE( "Request List Error" ); + *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; + TRACE_LEAVE( "Request Packet" ); + return NDIS_STATUS_FAILURE/*NDIS_STATUS_SUCCESS*/; + } + pReserved = CONTAINING_RECORD( RequestListEntry, PACKET_RESERVED, ListElement ); + pRequest = CONTAINING_RECORD( pReserved, INTERNAL_REQUEST, Reserved ); + OidData = (PPACKET_OID_DATA)(pDiocParms->lpvInBuffer); + if ( ( pDiocParms->cbInBuffer == pDiocParms->cbOutBuffer ) && + ( pDiocParms->cbInBuffer >= sizeof(PACKET_OID_DATA) - 1 + OidData->Length) ) + { + pReserved->lpBuffer = (PVOID)PacketPageLock( pDiocParms->lpvInBuffer, + pDiocParms->cbInBuffer ); + pReserved->lpcbBytesReturned= (PVOID)PacketPageLock( (PVOID)pDiocParms->lpcbBytesReturned, + sizeof(DWORD) ); + pReserved->lpoOverlapped = (PVOID)PacketPageLock( (PVOID)pDiocParms->lpoOverlapped, + sizeof(OVERLAPPED) ); + pReserved->cbBuffer = pDiocParms->cbInBuffer; + if ( FunctionCode == BIOCSETOID ) + { + pRequest->Request.RequestType = NdisRequestSetInformation; + pRequest->Request.DATA.SET_INFORMATION.Oid = OidData->Oid; + pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength = OidData->Length; + pRequest->Request.DATA.SET_INFORMATION.InformationBuffer = OidData->Data; + IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) + { + IF_TRACE_MSG2( "Request Set: Oid=%08lx, Length=%08lx", + OidData->Oid, + OidData->Length ); + } + } + else if ( FunctionCode == BIOCQUERYOID ) + { + pRequest->Request.RequestType = NdisRequestQueryInformation; + pRequest->Request.DATA.QUERY_INFORMATION.Oid = OidData->Oid; + pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength= OidData->Length; + pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer = OidData->Data; + IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) + { + IF_TRACE_MSG3( "Request Query: Type:%d Oid=%08lx, Length=%08lx", + NdisRequestQueryInformation, + OidData->Oid, + OidData->Length ); + } + } + else + { + pRequest->Request.RequestType = NdisRequestGeneric1; + pRequest->Request.DATA.QUERY_INFORMATION.Oid = OidData->Oid; + pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength= OidData->Length; + pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer = OidData->Data; + IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) + { + IF_TRACE_MSG3( "Request Statistic: Type:%d Oid=%08lx, Length=%08lx", + NdisRequestGeneric1, + OidData->Oid, + OidData->Length ); + } + } + + NdisRequest( &Status, Open->AdapterHandle, &pRequest->Request ); + + if ( Status != NDIS_STATUS_PENDING ) + { + PacketRequestComplete( Open, &pRequest->Request, Status ); + TRACE_LEAVE( "Request Packet" ); + return /*NDIS_STATUS_FAILURE*/NDIS_STATUS_SUCCESS; + } + TRACE_LEAVE( "Request Packet" ); + return (-1); /*Return ERROR_IO_PENDING and block the application*/ + } + else + { + IF_TRACE_MSG4( "Request Buffer Error: In=%lx Out=%lx Size=%lx Length=%lx", + pDiocParms->cbInBuffer, + pDiocParms->cbOutBuffer, + sizeof( PACKET_OID_DATA ), + OidData->Length + ); + *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; + } + TRACE_LEAVE( "Request Packet" ); + return NDIS_STATUS_FAILURE/*NDIS_STATUS_SUCCESS*/; +} + + +/************************************************************ +Function called by NDIS to complete asynchornously a +request +INPUT: ProtocolBindingContext - Structure describing the + current adapter + NdisRequest - Queue of NDIS internal requests + Status - Status of the operation reported by NDIS +************************************************************/ +VOID NDIS_API +PacketRequestComplete( IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_REQUEST NdisRequest, + IN NDIS_STATUS Status ) +{ + POPEN_INSTANCE Open; + PINTERNAL_REQUEST pRequest; + PPACKET_RESERVED pReserved; + OVERLAPPED* pOverlap; + PPACKET_OID_DATA oidData; + + TRACE_ENTER( "RequestComplete" ); + Open = (POPEN_INSTANCE)ProtocolBindingContext; + pRequest = CONTAINING_RECORD( NdisRequest, INTERNAL_REQUEST, Request ); + pReserved = &pRequest->Reserved; + pOverlap = (OVERLAPPED *) pReserved->lpoOverlapped; + oidData = (PPACKET_OID_DATA)(pReserved->lpBuffer); + #if DEBUG + IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) + { + ULONG i; + UCHAR* pcData = oidData->Data; + DbgPrint( "Packet: OID=%lx Status=%lx Buffer Length=%ld Buffer=%lx", + oidData->Oid, Status, oidData->Length, pcData ); + for ( i=0; iLength; i++, pcData++ ) + { + if ( i%16 == 0 ) + DbgPrint( "\r\nPacket: " ); + DbgPrint( "%02x ", *pcData ); + } + DbgPrint( "\r\n" ); + IF_BREAK_SET; + } + #endif + if ( Status == NDIS_STATUS_SUCCESS ) + { + /*if the operation was succesful*/ + *(pReserved->lpcbBytesReturned) = oidData->Length + sizeof(PACKET_OID_DATA) - 1; + pOverlap->O_InternalHigh = *(pReserved->lpcbBytesReturned); + } + else + { + /*if there is an error length contains the type of error*/ + *(pReserved->lpcbBytesReturned) = 0; + pOverlap->O_InternalHigh = 0; + oidData->Length = Status; + } + /*wakes the suspended process */ + VWIN32_DIOCCompletionRoutine( pOverlap->O_Internal ); + PacketPageUnlock( pReserved->lpBuffer, pReserved->cbBuffer ); + PacketPageUnlock( pReserved->lpcbBytesReturned, sizeof(DWORD) ); + PacketPageUnlock( pReserved->lpoOverlapped, sizeof(OVERLAPPED) ); + /*reinsert the request in the queue*/ + NdisAcquireSpinLock( &Open->RequestSpinLock ); + InsertTailList( &Open->RequestList, &pReserved->ListElement ); + NdisReleaseSpinLock( &Open->RequestSpinLock ); + TRACE_LEAVE( "RequestComplete" ); + return; +} diff --git a/winpcap/Packet9x/VXD/Vpacket.rc b/winpcap/Packet9x/VXD/Vpacket.rc new file mode 100644 index 0000000..8547aed --- /dev/null +++ b/winpcap/Packet9x/VXD/Vpacket.rc @@ -0,0 +1,43 @@ +#include +#define Not_VxD +#include +#include + +/*-----------------------------------------------*/ +/* the following lines are specific to this file */ +/*-----------------------------------------------*/ + +/* VER_FILETYPE, VER_FILESUBTYPE, VER_FILEDESCRIPTION_STR + * and VER_INTERNALNAME_STR must be defined before including COMMON.VER + * The strings don't need a '\0', since common.ver has them. + */ + + +#define VER_FILEVERSION 1,00,00,000 +#define VER_PRODUCTVERSION 1,00,00,000 + +#define VER_FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + #define VER_FILEFLAGS 0x1L +#else + #define VER_FILEFLAGS 0x0L +#endif + +#define VER_FILEOS VOS_DOS_WINDOWS32 +#define VER_FILETYPE VFT_VXD +#define VER_FILESUBTYPE UNDEFINED_DEVICE_ID //VFT2_UNKNOWN + + +#define VER_FILEDESCRIPTION_STR "NDIS Packet Capture Driver for Win95/98" +#define VER_INTERNALNAME_STR "VPacket" +#define VER_PRODUCTNAME_STR "Vpacket Virtual Device Driver" +#define VER_LEGALCOPYRIGHT_YEARS "1997-1998-1999" +#define VER_LEGALCOPYRIGHT_STR "Copyright \251 NetGroup, Politecnico di Torino " VER_LEGALCOPYRIGHT_YEARS +#define VER_COMPANYNAME_STR "Politecnico di Torino" +#define VER_ORIGINALFILENAME_STR "VPacket.Vxd" + +#define VER_PRODUCTVERSION_STR "1.00" +#define VER_FILEVERSION_STR "1.00" + + +#include diff --git a/winpcap/Packet9x/VXD/Write.c b/winpcap/Packet9x/VXD/Write.c new file mode 100644 index 0000000..85c9216 --- /dev/null +++ b/winpcap/Packet9x/VXD/Write.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1999 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include "debug.h" +#include "packet.h" +#include +#pragma VxD_LOCKED_CODE_SEG +#pragma VxD_LOCKED_DATA_SEG +DWORD _stdcall MyPageLock(DWORD, DWORD); +void _stdcall MyPageUnlock(DWORD, DWORD); + +/************************************************************ +Start the sending of a packet +************************************************************/ +DWORD +PacketWrite(POPEN_INSTANCE Open, + DWORD dwDDB, + DWORD hDevice, + PDIOCPARAMETERS pDiocParms + ) +{ + PNDIS_PACKET pPacket; + PNDIS_BUFFER pNdisBuffer; + NDIS_STATUS Status; + TRACE_ENTER( "SendPacket" ); + + PacketAllocatePacketBuffer( &Status, Open, &pPacket, pDiocParms, IOCTL_PROTOCOL_WRITE ); + if ( Status != NDIS_STATUS_SUCCESS ) + { + return 0; + } + NdisSend( &Status, Open->AdapterHandle, pPacket ); + if ( Status != NDIS_STATUS_PENDING ) + { + PacketSendComplete( Open, pPacket, Status ); + } + TRACE_LEAVE( "SendPacket" ); + return(-1); +} + +/************************************************************ +Function called by NDIS to indicate that the data transfer +is finished +************************************************************/ +VOID NDIS_API +PacketSendComplete( IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET pPacket, + IN NDIS_STATUS Status + ) +{ + PNDIS_BUFFER pNdisBuffer; + PPACKET_RESERVED Reserved = (PPACKET_RESERVED) pPacket->ProtocolReserved; + + TRACE_ENTER( "SendComplete" ); + + NdisUnchainBufferAtFront( pPacket, &pNdisBuffer ); + if ( pNdisBuffer ) + NdisFreeBuffer( pNdisBuffer ); + + VWIN32_DIOCCompletionRoutine( Reserved->lpoOverlapped->O_Internal ); + + PacketPageUnlock( Reserved->lpBuffer, Reserved->cbBuffer ); + PacketPageUnlock( Reserved->lpcbBytesReturned, sizeof(DWORD) ); + PacketPageUnlock( Reserved->lpoOverlapped, sizeof(OVERLAPPED) ); + + NdisReinitializePacket(pPacket); + + NdisFreePacket(pPacket); + + TRACE_LEAVE( "SendComplete" ); + return; +} diff --git a/winpcap/Packet9x/VXD/win_Bpf.h b/winpcap/Packet9x/VXD/win_Bpf.h new file mode 100644 index 0000000..71e55bd --- /dev/null +++ b/winpcap/Packet9x/VXD/win_Bpf.h @@ -0,0 +1,353 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)bpf.h 7.1 (Berkeley) 5/7/91 + * + * @(#) $Header: /usr/cvsroot_private/winpcap/Packet9x/VXD/win_Bpf.h,v 1.2 2005/12/02 22:31:27 gianlucav Exp $ (LBL) + */ + +#ifndef BPF_MAJOR_VERSION + +/* BSD style release date */ +#define BPF_RELEASE 199606 + +#ifndef NTKERNEL +#include +typedef int bpf_int32; +typedef u_int bpf_u_int32; +#else +typedef UCHAR u_char; +typedef USHORT u_short; +typedef UINT u_int; +typedef INT bpf_int32; +typedef UINT bpf_u_int32; +#endif + +/* + * Alignment macros. BPF_WORDALIGN rounds up to the next + * even multiple of BPF_ALIGNMENT. + */ +#ifndef __NetBSD__ +#define BPF_ALIGNMENT sizeof(bpf_int32) +#else +#define BPF_ALIGNMENT sizeof(long) +#endif +#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) + +#define BPF_MAXINSNS 512 +#define BPF_MAXBUFSIZE 0x8000 +#define BPF_MINBUFSIZE 32 + +/* + * Structure for BIOCSETF. + */ +struct bpf_program { + u_int bf_len; + struct bpf_insn *bf_insns; +}; + +/* + * Struct returned by BIOCGSTATS. + */ +struct bpf_stat { + u_int bs_recv; /* number of packets received */ + u_int bs_drop; /* number of packets dropped */ +}; + +/* + * Struct return by BIOCVERSION. This represents the version number of + * the filter language described by the instruction encodings below. + * bpf understands a program iff kernel_major == filter_major && + * kernel_minor >= filter_minor, that is, if the value returned by the + * running kernel has the same major number and a minor number equal + * equal to or less than the filter being downloaded. Otherwise, the + * results are undefined, meaning an error may be returned or packets + * may be accepted haphazardly. + * It has nothing to do with the source code version. + */ +struct bpf_version { + u_short bv_major; + u_short bv_minor; +}; +/* Current version number of filter architecture. */ +#define BPF_MAJOR_VERSION 1 +#define BPF_MINOR_VERSION 1 + + +/* + * Structure prepended to each packet. + */ +struct bpf_hdr { + struct timeval bh_tstamp; /* time stamp */ + bpf_u_int32 bh_caplen; /* length of captured portion */ + bpf_u_int32 bh_datalen; /* original length of packet */ + u_short bh_hdrlen; /* length of bpf header (this struct + plus alignment padding) */ +}; +/* + * Because the structure above is not a multiple of 4 bytes, some compilers + * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work. + * Only the kernel needs to know about it; applications use bh_hdrlen. + */ +#if defined(KERNEL) || defined(_KERNEL) +#define SIZEOF_BPF_HDR 18 +#endif + +/* + * Data-link level type codes. + */ + +/* + * These are the types that are the same on all platforms; on other + * platforms, a should be supplied that defines the additional + * DLT_* codes appropriately for that platform (the BSDs, for example, + * should not just pick up this version of "bpf.h"; they should also define + * the additional DLT_* codes used by their kernels, as well as the values + * defined here - and, if the values they use for particular DLT_ types + * differ from those here, they should use their values, not the ones + * here). + */ +#define DLT_NULL 0 /* no link-layer encapsulation */ +#define DLT_EN10MB 1 /* Ethernet (10Mb) */ +#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ +#define DLT_AX25 3 /* Amateur Radio AX.25 */ +#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ +#define DLT_CHAOS 5 /* Chaos */ +#define DLT_IEEE802 6 /* IEEE 802 Networks */ +#define DLT_ARCNET 7 /* ARCNET */ +#define DLT_SLIP 8 /* Serial Line IP */ +#define DLT_PPP 9 /* Point-to-point Protocol */ +#define DLT_FDDI 10 /* FDDI */ + +/* + * These are values from the traditional libpcap "bpf.h". + * Ports of this to particular platforms should replace these definitions + * with the ones appropriate to that platform, if the values are + * different on that platform. + */ +#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ +#define DLT_RAW 12 /* raw IP */ + +/* + * These are values from BSD/OS's "bpf.h". + * These are not the same as the values from the traditional libpcap + * "bpf.h"; however, these values shouldn't be generated by any + * OS other than BSD/OS, so the correct values to use here are the + * BSD/OS values. + * + * Platforms that have already assigned these values to other + * DLT_ codes, however, should give these codes the values + * from that platform, so that programs that use these codes will + * continue to compile - even though they won't correctly read + * files of these types. + */ +#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ + +#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + +/* + * This value is defined by NetBSD; other platforms should refrain from + * using it for other purposes, so that NetBSD savefiles with a link + * type of 50 can be read as this type on all platforms. + */ +#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ + +/* + * This value was defined by libpcap 0.5; platforms that have defined + * it with a different value should define it here with that value - + * a link type of 104 in a save file will be mapped to DLT_C_HDLC, + * whatever value that happens to be, so programs will correctly + * handle files with that link type regardless of the value of + * DLT_C_HDLC. + * + * The name DLT_C_HDLC was used by BSD/OS; we use that name for source + * compatibility with programs written for BSD/OS. + * + * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, + * for source compatibility with programs written for libpcap 0.5. + */ +#define DLT_C_HDLC 104 /* Cisco HDLC */ +#define DLT_CHDLC DLT_C_HDLC + +/* + * Reserved for future use. + * Do not pick other numerical value for these unless you have also + * picked up the tcpdump.org top-of-CVS-tree version of "savefile.c", + * which will arrange that capture files for these DLT_ types have + * the same "network" value on all platforms, regardless of what + * value is chosen for their DLT_ type (thus allowing captures made + * on one platform to be read on other platforms, even if the two + * platforms don't use the same numerical values for all DLT_ types). + */ +#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + +/* + * Values between 106 and 107 are used in capture file headers as + * link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ new types. + */ + +/* + * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except + * that the AF_ type in the link-layer header is in network byte order. + * + * OpenBSD defines it as 12, but that collides with DLT_RAW, so we + * define it as 108 here. If OpenBSD picks up this file, it should + * define DLT_LOOP as 12 in its version, as per the comment above - + * and should not use 108 for any purpose. + */ +#define DLT_LOOP 108 + +/* + * Values between 109 and 112 are used in capture file headers as + * link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ new types. + */ + +/* + * This is for Linux cooked sockets. + */ +#define DLT_LINUX_SLL 113 + +/* + * The instruction encodings. + */ +/* instruction classes */ +#define BPF_CLASS(code) ((code) & 0x07) +#define BPF_LD 0x00 +#define BPF_LDX 0x01 +#define BPF_ST 0x02 +#define BPF_STX 0x03 +#define BPF_ALU 0x04 +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 + +/* ld/ldx fields */ +#define BPF_SIZE(code) ((code) & 0x18) +#define BPF_W 0x00 +#define BPF_H 0x08 +#define BPF_B 0x10 +#define BPF_MODE(code) ((code) & 0xe0) +#define BPF_IMM 0x00 +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 + +/* alu/jmp fields */ +#define BPF_OP(code) ((code) & 0xf0) +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 +#define BPF_SRC(code) ((code) & 0x08) +#define BPF_K 0x00 +#define BPF_X 0x08 + +/* ret - BPF_K and BPF_X also apply */ +#define BPF_RVAL(code) ((code) & 0x18) +#define BPF_A 0x10 + +/* misc */ +#define BPF_MISCOP(code) ((code) & 0xf8) +#define BPF_TAX 0x00 +#define BPF_TXA 0x80 + +/* + * The instruction data structure. + */ +struct bpf_insn { + u_short code; + u_char jt; + u_char jf; + bpf_u_int32 k; +}; + +/* + * Macros for insn array initializers. + */ +#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } +#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } + +/** + * @} + */ + +#if defined(BSD) && (defined(KERNEL) || defined(_KERNEL)) +/* + * Systems based on non-BSD kernels don't have ifnet's (or they don't mean + * anything if it is in ) and won't work like this. + */ +# if __STDC__ +extern void bpf_tap(struct ifnet *, u_char *, u_int); +extern void bpf_mtap(struct ifnet *, struct mbuf *); +extern void bpfattach(struct ifnet *, u_int, u_int); +extern void bpfilterattach(int); +# else +extern void bpf_tap(); +extern void bpf_mtap(); +extern void bpfattach(); +extern void bpfilterattach(); +# endif /* __STDC__ */ +#endif /* BSD && (_KERNEL || KERNEL) */ +#if __STDC__ +extern int bpf_validate(struct bpf_insn *, int); +extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); +#else +extern int bpf_validate(); +extern u_int bpf_filter(); +#endif + +/* + * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). + */ +#define BPF_MEMWORDS 16 + +#endif diff --git a/winpcap/Packet9x/VXD/win_bpf_filter.c b/winpcap/Packet9x/VXD/win_bpf_filter.c new file mode 100644 index 0000000..3fa012e --- /dev/null +++ b/winpcap/Packet9x/VXD/win_bpf_filter.c @@ -0,0 +1,758 @@ +/* + * Copyright (c) 1999 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * @(#)bpf.c 7.5 (Berkeley) 7/15/91 + */ + + +/** @ingroup NPF + * @{ + */ + +/** @defgroup win_bpf win_bpf.c + * XXX todo. + * @{ + */ + +#if !(defined(lint) || defined(KERNEL)) +static const char rcsid[] = + "@(#) $Header: /usr/cvsroot_private/winpcap/Packet9x/VXD/win_bpf_filter.c,v 1.5 2005/12/02 22:31:26 gianlucav Exp $ (LBL)"; +#endif + +#ifndef WIN32 +#include +#include +#else +#include +#endif +#include +#include "win_bpf.h" + +#define int32 bpf_int32 +#define u_int32 bpf_u_int32 + + +#ifndef LBL_ALIGN +#if defined(sparc) || defined(mips) || defined(ibm032) || \ + defined(__alpha) || defined(__hpux) +#define LBL_ALIGN +#endif +#endif + +#ifndef LBL_ALIGN +#ifndef WIN32 +#include +#endif + +#define EXTRACT_SHORT(p)\ + ((u_short)\ + ((u_short)*((u_char *)p+0)<<8|\ + (u_short)*((u_char *)p+1)<<0)) +#define EXTRACT_LONG(p)\ + ((u_int32)*((u_char *)p+0)<<24|\ + (u_int32)*((u_char *)p+1)<<16|\ + (u_int32)*((u_char *)p+2)<<8|\ + (u_int32)*((u_char *)p+3)<<0) +#endif + +/* + * Execute the filter program starting at pc on the packet p + * wirelen is the length of the original packet + * buflen is the amount of data present + */ +u_int bpf_filter(pc, p, wirelen, buflen) + register struct bpf_insn *pc; + register u_char *p; + u_int wirelen; + register u_int buflen; +{ + register u_int32 A, X; + register int k; + int32 mem[BPF_MEMWORDS]; + + if (pc == 0) + /* + * No filter means accept all. + */ + return (u_int)-1; + A = 0; + X = 0; + --pc; + while (1) { + ++pc; + switch (pc->code) { + + default: + + return 0; + + case BPF_RET|BPF_K: + return (u_int)pc->k; + + case BPF_RET|BPF_A: + return (u_int)A; + + case BPF_LD|BPF_W|BPF_ABS: + k = pc->k; + if (k + sizeof(int32) > buflen) { + return 0; + } + A = EXTRACT_LONG(&p[k]); + continue; + + case BPF_LD|BPF_H|BPF_ABS: + k = pc->k; + if (k + sizeof(short) > buflen) { + return 0; + } + A = EXTRACT_SHORT(&p[k]); + continue; + + case BPF_LD|BPF_B|BPF_ABS: + k = pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + A = p[k]; + continue; + + case BPF_LD|BPF_W|BPF_LEN: + A = wirelen; + continue; + + case BPF_LDX|BPF_W|BPF_LEN: + X = wirelen; + continue; + + case BPF_LD|BPF_W|BPF_IND: + k = X + pc->k; + if (k + sizeof(int32) > buflen) { + return 0; + } + A = EXTRACT_LONG(&p[k]); + continue; + + case BPF_LD|BPF_H|BPF_IND: + k = X + pc->k; + if (k + sizeof(short) > buflen) { + return 0; + } + A = EXTRACT_SHORT(&p[k]); + continue; + + case BPF_LD|BPF_B|BPF_IND: + k = X + pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + A = p[k]; + continue; + + case BPF_LDX|BPF_MSH|BPF_B: + k = pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + X = (p[pc->k] & 0xf) << 2; + continue; + + case BPF_LD|BPF_IMM: + A = pc->k; + continue; + + case BPF_LDX|BPF_IMM: + X = pc->k; + continue; + + case BPF_LD|BPF_MEM: + A = mem[pc->k]; + continue; + + case BPF_LDX|BPF_MEM: + X = mem[pc->k]; + continue; + + case BPF_ST: + mem[pc->k] = A; + continue; + + case BPF_STX: + mem[pc->k] = X; + continue; + + case BPF_JMP|BPF_JA: + pc += pc->k; + continue; + + case BPF_JMP|BPF_JGT|BPF_K: + pc += ((int)A > (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_K: + pc += ((int)A >= (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_K: + pc += ((int)A == (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_K: + pc += (A & pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGT|BPF_X: + pc += (A > X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_X: + pc += (A >= X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_X: + pc += (A == X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_X: + pc += (A & X) ? pc->jt : pc->jf; + continue; + + case BPF_ALU|BPF_ADD|BPF_X: + A += X; + continue; + + case BPF_ALU|BPF_SUB|BPF_X: + A -= X; + continue; + + case BPF_ALU|BPF_MUL|BPF_X: + A *= X; + continue; + + case BPF_ALU|BPF_DIV|BPF_X: + if (X == 0) + return 0; + A /= X; + continue; + + case BPF_ALU|BPF_AND|BPF_X: + A &= X; + continue; + + case BPF_ALU|BPF_OR|BPF_X: + A |= X; + continue; + + case BPF_ALU|BPF_LSH|BPF_X: + A <<= X; + continue; + + case BPF_ALU|BPF_RSH|BPF_X: + A >>= X; + continue; + + case BPF_ALU|BPF_ADD|BPF_K: + A += pc->k; + continue; + + case BPF_ALU|BPF_SUB|BPF_K: + A -= pc->k; + continue; + + case BPF_ALU|BPF_MUL|BPF_K: + A *= pc->k; + continue; + + case BPF_ALU|BPF_DIV|BPF_K: + A /= pc->k; + continue; + + case BPF_ALU|BPF_AND|BPF_K: + A &= pc->k; + continue; + + case BPF_ALU|BPF_OR|BPF_K: + A |= pc->k; + continue; + + case BPF_ALU|BPF_LSH|BPF_K: + A <<= pc->k; + continue; + + case BPF_ALU|BPF_RSH|BPF_K: + A >>= pc->k; + continue; + + case BPF_ALU|BPF_NEG: + (int)A = -((int)A); + continue; + + case BPF_MISC|BPF_TAX: + X = A; + continue; + + case BPF_MISC|BPF_TXA: + A = X; + continue; + } + } +} + + +/* + * Execute the filter program starting at pc on the packet whose header is + * pointed by p and whose data is pointed by pd. + * headersize is the size of the the header + * wirelen is the length of the original packet + * buflen is the amount of data present + */ + +u_int bpf_filter_with_2_buffers(pc, p, pd, headersize, wirelen, buflen) + register struct bpf_insn *pc; + register u_char *p; + register u_char *pd; + register int headersize; + u_int wirelen; + register u_int buflen; +{ + register u_int32 A, X; + register int k; + int32 mem[BPF_MEMWORDS]; + + if (pc == 0) + /* + * No filter means accept all. + */ + return (u_int)-1; + A = 0; + X = 0; + --pc; + while (1) { + ++pc; + switch (pc->code) { + + default: + + return 0; + + case BPF_RET|BPF_K: + return (u_int)pc->k; + + case BPF_RET|BPF_A: + return (u_int)A; + + case BPF_LD|BPF_W|BPF_ABS: + k = pc->k; + if (k + sizeof(int32) > buflen) { + return 0; + } + + if(k + (int)sizeof(int32) < headersize) A = EXTRACT_LONG(&p[k]); + else if(k + 2 == headersize){ + A=(u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)p+k+1)<<16| + (u_int32)*((u_char *)p+k+2)<<8| + (u_int32)*((u_char *)pd+k-headersize); + } + else if(k == headersize-1){ + A=(u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)p+k+1)<<16| + (u_int32)*((u_char *)pd+k-headersize)<<8| + (u_int32)*((u_char *)pd+k-headersize+1); + } + else if(k == headersize){ + A=(u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)pd+k-headersize+1)<<16| + (u_int32)*((u_char *)pd+k-headersize+2)<<8| + (u_int32)*((u_char *)pd+k-headersize+3); + } + A = EXTRACT_LONG(&pd[k-headersize]); + + continue; + + case BPF_LD|BPF_H|BPF_ABS: + k = pc->k; + if (k + sizeof(short) > buflen) { + return 0; + } + + if(k + (int)sizeof(short) < headersize) A = EXTRACT_SHORT(&p[k]); + else if(k == headersize){ + A=(u_short)*((u_char *)p+k)<<8| + (u_short)*((u_char *)pd+k-headersize); + } + A = EXTRACT_SHORT(&pd[k-headersize]); + + continue; + + case BPF_LD|BPF_B|BPF_ABS: + k = pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + + if(kk; + if (k + sizeof(int32) > buflen) { + return 0; + } + + if(k + (int)sizeof(int32) < headersize) A = EXTRACT_LONG(&p[k]); + else if(k + (int)sizeof(int32) == headersize+2){ + A=(u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)p+k+1)<<16| + (u_int32)*((u_char *)p+k+2)<<8| + (u_int32)*((u_char *)pd+k-headersize); + } + else if(k + (int)sizeof(int32) == headersize+3){ + A=(u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)p+k+1)<<16| + (u_int32)*((u_char *)pd+k-headersize)<<8| + (u_int32)*((u_char *)pd+k-headersize+1); + } + else if(k + (int)sizeof(int32) == headersize+4){ + A=(u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)pd+k-headersize+1)<<16| + (u_int32)*((u_char *)pd+k-headersize+2)<<8| + (u_int32)*((u_char *)pd+k-headersize+3); + } + A = EXTRACT_LONG(&pd[k-headersize]); + + continue; + + case BPF_LD|BPF_H|BPF_IND: + k = X + pc->k; + if (k + sizeof(short) > buflen) { + return 0; + } + + if(k + (int)sizeof(short) < headersize) A = EXTRACT_SHORT(&p[k]); + else if(k == headersize){ + A=(u_short)*((u_char *)p+k)<<8| + (u_short)*((u_char *)pd+k-headersize); + } + A = EXTRACT_SHORT(&pd[k-headersize]); + + continue; + + case BPF_LD|BPF_B|BPF_IND: + k = X + pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + + if(kk; + if ((int)k >= (int)buflen) { + return 0; + } + + if((pc->k)k] & 0xf) << 2; + else X = (pd[(pc->k)-headersize] & 0xf) << 2; + + continue; + + case BPF_LD|BPF_IMM: + A = pc->k; + continue; + + case BPF_LDX|BPF_IMM: + X = pc->k; + continue; + + case BPF_LD|BPF_MEM: + A = mem[pc->k]; + continue; + + case BPF_LDX|BPF_MEM: + X = mem[pc->k]; + continue; + + case BPF_ST: + mem[pc->k] = A; + continue; + + case BPF_STX: + mem[pc->k] = X; + continue; + + case BPF_JMP|BPF_JA: + pc += pc->k; + continue; + + case BPF_JMP|BPF_JGT|BPF_K: + pc += ((int)A > (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_K: + pc += ((int)A >= (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_K: + pc += ((int)A == (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_K: + pc += (A & pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGT|BPF_X: + pc += (A > X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_X: + pc += (A >= X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_X: + pc += (A == X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_X: + pc += (A & X) ? pc->jt : pc->jf; + continue; + + case BPF_ALU|BPF_ADD|BPF_X: + A += X; + continue; + + case BPF_ALU|BPF_SUB|BPF_X: + A -= X; + continue; + + case BPF_ALU|BPF_MUL|BPF_X: + A *= X; + continue; + + case BPF_ALU|BPF_DIV|BPF_X: + if (X == 0) + return 0; + A /= X; + continue; + + case BPF_ALU|BPF_AND|BPF_X: + A &= X; + continue; + + case BPF_ALU|BPF_OR|BPF_X: + A |= X; + continue; + + case BPF_ALU|BPF_LSH|BPF_X: + A <<= X; + continue; + + case BPF_ALU|BPF_RSH|BPF_X: + A >>= X; + continue; + + case BPF_ALU|BPF_ADD|BPF_K: + A += pc->k; + continue; + + case BPF_ALU|BPF_SUB|BPF_K: + A -= pc->k; + continue; + + case BPF_ALU|BPF_MUL|BPF_K: + A *= pc->k; + continue; + + case BPF_ALU|BPF_DIV|BPF_K: + A /= pc->k; + continue; + + case BPF_ALU|BPF_AND|BPF_K: + A &= pc->k; + continue; + + case BPF_ALU|BPF_OR|BPF_K: + A |= pc->k; + continue; + + case BPF_ALU|BPF_LSH|BPF_K: + A <<= pc->k; + continue; + + case BPF_ALU|BPF_RSH|BPF_K: + A >>= pc->k; + continue; + + case BPF_ALU|BPF_NEG: + (int)A = -((int)A); + continue; + + case BPF_MISC|BPF_TAX: + X = A; + continue; + + case BPF_MISC|BPF_TXA: + A = X; + continue; + } + } +} + + +/* + * Return true if the 'fcode' is a valid filter program. + * The constraints are that each jump be forward and to a valid + * code, that memory accesses are within valid ranges (to the + * extent that this can be checked statically; loads of packet + * data have to be, and are, also checked at run time), and that + * the code terminates with either an accept or reject. + * + * The kernel needs to be able to verify an application's filter code. + * Otherwise, a bogus program could easily crash the system. + */ +int +bpf_validate(f, len) + struct bpf_insn *f; + int len; +{ + register u_int32 i, from; + register struct bpf_insn *p; + + if (len < 1) + return 0; + + for (i = 0; i < len; ++i) { + p = &f[i]; + switch (BPF_CLASS(p->code)) { + /* + * Check that memory operations use valid addresses. + */ + case BPF_LD: + case BPF_LDX: + switch (BPF_MODE(p->code)) { + case BPF_IMM: + break; + case BPF_ABS: + case BPF_IND: + case BPF_MSH: + break; + case BPF_MEM: + if (p->k >= BPF_MEMWORDS) + return 0; + break; + case BPF_LEN: + break; + default: + return 0; + } + break; + case BPF_ST: + case BPF_STX: + if (p->k >= BPF_MEMWORDS) + return 0; + break; + case BPF_ALU: + switch (BPF_OP(p->code)) { + case BPF_ADD: + case BPF_SUB: + case BPF_OR: + case BPF_AND: + case BPF_LSH: + case BPF_RSH: + case BPF_NEG: + break; + case BPF_DIV: + /* + * Check for constant division by 0. + */ + if (BPF_RVAL(p->code) == BPF_K && p->k == 0) + return 0; + default: + return 0; + } + break; + case BPF_JMP: + /* + * Check that jumps are within the code block, + * and that unconditional branches don't go + * backwards as a result of an overflow. + * Unconditional branches have a 32-bit offset, + * so they could overflow; we check to make + * sure they don't. Conditional branches have + * an 8-bit offset, and the from address is <= + * BPF_MAXINSNS, and we assume that BPF_MAXINSNS + * is sufficiently small that adding 255 to it + * won't overflow. + * + * We know that len is <= BPF_MAXINSNS, and we + * assume that BPF_MAXINSNS is < the maximum size + * of a u_int, so that i + 1 doesn't overflow. + */ + from = i + 1; + switch (BPF_OP(p->code)) { + case BPF_JA: + if (from + p->k < from || from + p->k >= len) + return 0; + break; + case BPF_JEQ: + case BPF_JGT: + case BPF_JGE: + case BPF_JSET: + if (from + p->jt >= len || from + p->jf >= len) + return 0; + break; + default: + return 0; + } + IF_LOUD(DbgPrint("Validating program: no wrong JUMPS");) + break; + case BPF_RET: + break; + case BPF_MISC: + break; + default: + return 0; + } + } + return BPF_CLASS(f[len - 1].code) == BPF_RET; +} diff --git a/winpcap/build_wpdpack.bat b/winpcap/build_wpdpack.bat new file mode 100644 index 0000000..4561838 --- /dev/null +++ b/winpcap/build_wpdpack.bat @@ -0,0 +1,11 @@ +@echo off + +call create_include.bat %1 %2 +PAUSE +call create_lib.bat %1 %2 +PAUSE +call create_examples.bat %1 %2 +PAUSE +call create_docs.bat %1 %2 + + diff --git a/winpcap/build_wpdpack.txt b/winpcap/build_wpdpack.txt new file mode 100644 index 0000000..d5ba0aa --- /dev/null +++ b/winpcap/build_wpdpack.txt @@ -0,0 +1,16 @@ +In order to build the developers' pack, you need to compile the various DLLs and then call build_wpdpack.bat +This batch file, in turn, calls the four batches +- create_includes.bat creates the include folder +- create_lib.bat creates the lib folder +- create_examples.bat copies the examples folder to the developers' pack. The examples can be compiled only under the developers' pack folder. +- create_docs.bat calls createdoc.bat to create the documentation (via doxygen), and then copies the generated files under the developers' pack folder. + +The syntax for the various scripts is + + winpcap_folder developer_folder + +winpcap_folder The winpcap sources folder. It is defaulted to .\ +developer_folder The developers' pack folder. It is defaulted to .\wpdpack. + +HINT: just call build_wpdpack.bat without any parameter! + diff --git a/winpcap/create_docs.bat b/winpcap/create_docs.bat new file mode 100644 index 0000000..8384e7c --- /dev/null +++ b/winpcap/create_docs.bat @@ -0,0 +1,25 @@ +@echo off + +IF "%2"=="" (set WPDPACKDESTDIR=.\WpdPack\) ELSE (set WPDPACKDESTDIR=%2) + +IF ""=="%1" (set WINPCAPSOURCEDIR=.\) ELSE (set WINPCAPSOURCEDIR=%1) + +echo Creating \docs folder +mkdir %WPDPACKDESTDIR% >nul 2>nul +mkdir %WPDPACKDESTDIR%\docs >nul 2>nul +mkdir %WPDPACKDESTDIR%\docs\html >nul 2>nul + +pushd %CD% + +chdir %WINPCAPSOURCEDIR% +call createdoc.bat + +popd + +xcopy /v /Y %WINPCAPSOURCEDIR%\dox\WinPcap_docs.html %WPDPACKDESTDIR%\docs\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\dox\prj\docs\*.* %WPDPACKDESTDIR%\docs\html\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\dox\*.gif %WPDPACKDESTDIR%\docs\html\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\dox\pics\*.gif %WPDPACKDESTDIR%\docs\html\ >nul +echo Folder \docs created successfully +set WPDPACKDESTDIR= +set WINPCAPSOURCEDIR= diff --git a/winpcap/create_examples.bat b/winpcap/create_examples.bat new file mode 100644 index 0000000..8052ea5 --- /dev/null +++ b/winpcap/create_examples.bat @@ -0,0 +1,37 @@ +@echo off + +IF "%2"=="" (set WPDPACKDESTDIR=.\WpdPack\) ELSE (set WPDPACKDESTDIR=%2) + +IF ""=="%1" (set WINPCAPSOURCEDIR=.\) ELSE (set WINPCAPSOURCEDIR=%1) + +echo Creating \Examples folder +mkdir %WPDPACKDESTDIR% >nul 2>nul +mkdir %WPDPACKDESTDIR%\Examples-pcap >nul 2>nul +mkdir %WPDPACKDESTDIR%\Examples-remote >nul 2>nul + +xcopy /s/e/v /Y %WINPCAPSOURCEDIR%\Examples %WPDPACKDESTDIR%\Examples-remote >nul + +rem *** Delete Netmeter since it's no more part of the Developer's pack *** +rd /S /Q %WPDPACKDESTDIR%\Examples-remote\NetMeter\ + +rem *** Delete kdump since the feature is not available at the moment *** +rd /S /Q %WPDPACKDESTDIR%\Examples-remote\kdump\ + +xcopy /s/e/v /Y %WINPCAPSOURCEDIR%\Examples-pcap %WPDPACKDESTDIR%\Examples-pcap >nul + +rem *** Delete WinPcapStress, since it's not a real example *** +rd /S /Q %WPDPACKDESTDIR%\Examples-pcap\winpcap_stress + +rem *** Delete stats, since it's not a real example *** +rd /S /Q %WPDPACKDESTDIR%\Examples-pcap\stats + + +echo Folder \Examples created successfully +set WPDPACKDESTDIR= +set WINPCAPSOURCEDIR= + +echo ******************************************************************** +echo * * +echo * Now you can build the examples from the developers' pack folder! * +echo * * +echo ******************************************************************** diff --git a/winpcap/create_include.bat b/winpcap/create_include.bat new file mode 100644 index 0000000..5f40193 --- /dev/null +++ b/winpcap/create_include.bat @@ -0,0 +1,34 @@ +@echo off + +IF "%2"=="" (set WPDPACKDESTDIR=.\WpdPack\) ELSE (set WPDPACKDESTDIR=%2) + +IF ""=="%1" (set WINPCAPSOURCEDIR=.\) ELSE (set WINPCAPSOURCEDIR=%1) + +echo Creating \Include folder +mkdir %WPDPACKDESTDIR% 2>nul >nul +mkdir %WPDPACKDESTDIR%\Include 2>nul >nul + +xcopy /v /Y %WINPCAPSOURCEDIR%\wpcap\libpcap\Win32\Include\bittypes.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\wpcap\libpcap\Win32\Include\Gnuc.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\wpcap\libpcap\Win32\Include\ip6_misc.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\wpcap\libpcap\PCAP-INT.H %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\wpcap\libpcap\pcap-bpf.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\wpcap\libpcap\pcap-stdinc.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\wpcap\libpcap\PCAP.H %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\wpcap\libpcap\remote-ext.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\wpcap\Win32-Extensions\Win32-Extensions.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\packetNtx\driver\bucket_lookup.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\packetNtx\driver\count_packets.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\packetNtx\driver\memory_t.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\packetNtx\driver\normal_lookup.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\packetNtx\driver\tcp_session.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\packetNtx\driver\time_calls.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\packetNtx\driver\tme.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\Common\Packet32.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\Common\Devioctl.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\Common\Ntddndis.h %WPDPACKDESTDIR%\Include\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\Common\Ntddpack.h %WPDPACKDESTDIR%\Include\ >nul + +echo Folder \Include created successfully +set WPDPACKDESTDIR= +set WINPCAPSOURCEDIR= diff --git a/winpcap/create_lib.bat b/winpcap/create_lib.bat new file mode 100644 index 0000000..b5c864d --- /dev/null +++ b/winpcap/create_lib.bat @@ -0,0 +1,20 @@ +@echo off + +IF "%2"=="" (set WPDPACKDESTDIR=.\WpdPack\) ELSE (set WPDPACKDESTDIR=%2) + +IF ""=="%1" (set WINPCAPSOURCEDIR=.\) ELSE (set WINPCAPSOURCEDIR=%1) + +echo Creating \Lib folder +mkdir %WPDPACKDESTDIR% >nul 2>nul +mkdir %WPDPACKDESTDIR%\Lib >nul 2>nul + +xcopy /v /Y %WINPCAPSOURCEDIR%\wpcap\PRJ\Release_REMOTE\wpcap.lib %WPDPACKDESTDIR%\Lib\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\packetNtx\Dll\Project\Release\packet.lib %WPDPACKDESTDIR%\Lib\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\packetNtx\Dll\Project\libpacket.a %WPDPACKDESTDIR%\Lib\ >nul +xcopy /v /Y %WINPCAPSOURCEDIR%\wpcap\LIB\libwpcap.a %WPDPACKDESTDIR%\Lib\ >nul + +echo Folder \Lib created successfully + +set WPDPACKDESTDIR= +set WINPCAPSOURCEDIR= + diff --git a/winpcap/createdoc.bat b/winpcap/createdoc.bat new file mode 100644 index 0000000..38de651 --- /dev/null +++ b/winpcap/createdoc.bat @@ -0,0 +1,12 @@ +@echo off +cd dox\prj\ +@echo #### Delete existing WinPcap documentation +del /q docs\*.* +@echo #### Create new documentation +doxygen winpcap_noc.dox >nul +@echo #### Copy all gif files +xcopy ..\pics\*.gif docs\. /v /y /q >nul +xcopy ..\*.gif docs\. /v /y /q >nul +cd .. +cd .. + diff --git a/winpcap/dox/WinPcap_docs.html b/winpcap/dox/WinPcap_docs.html new file mode 100644 index 0000000..2ca3177 --- /dev/null +++ b/winpcap/dox/WinPcap_docs.html @@ -0,0 +1,9 @@ + + + + + + + diff --git a/winpcap/dox/compile.htm b/winpcap/dox/compile.htm new file mode 100644 index 0000000..66f41b2 --- /dev/null +++ b/winpcap/dox/compile.htm @@ -0,0 +1,243 @@ + + + + + + + + + + +

This section explains how to compile WinPcap, both the kernel level and +the user-level portion, on the various Win32 platforms. The source code can be +found on the WinPcap website.

+

Compiling the driver

+

Two main NPF source trees are available for compilation:  Windows NTx and Windows 9x. Note that, since the NPF Driver is platform-dependent, it is +STRONGLY suggested to compile it on the OS where it will be used, in order to +link the correct DDK libraries. For example, if you compile the +driver with the Windows NT 4 DDK, it will not work properly on Windows 2000 and +vice versa.

+

Compiling the driver on Windows NT4

+

Software requirements:

+
    +
  • Microsoft Driver Developer Kit (DDK) for Windows NT4
  • +
  • A recent version of the Microsoft Platform Software Development Kit + (SDK) that is compatible with Visual Studio 6 (the latest compatible one is + Platform SDK February 2003). This version of the PSDK is available on the + Microsoft web site at + + http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm. + It can be ordered online at + + http://www.qmedia.ca/launch/psdk.htm, and it's also available to + Microsoft MSDN subscribers on the Subscribers Downloads web site.
  • Microsoft Visual C++ 6.0 + with Service Pack 5 or 6 (both the service packs are available online on the + Microsoft web site).
+

If your system satisfies these requirements, follow these steps:

+
    +
  1. From the Windows NT Start menu, select the folder Programs and + then Development Kits, then Windows NT4 DDK. From here select the voice + Checked Build + Environment if you want to build a debug version, or Free Build + Environment if you want to build a release version. +
  2. A command prompt will be opened. Move to the directory PacketNTx inside the + WinPcap source folder and type the command

    CompileDriver
    +
    This script will generate the driver (npf.sys). The binary will be put in + one of these folders
      +
    • Free Build Environment: winpcap\PacketNTx\driver\bin\NT4\i386\free
    • +
    • Checked Build Environment: winpcap\PacketNTx\driver\bin\NT4\i386\checked
    • +
    +
+

Warning: sometimes, during the compilation of the driver, a lot of +'last line incomplete' errors are generated. Ignore these errors and let the +compilation process continue, they are due to bugs in some DDK versions.

+

Compiling the driver on Windows 2000/XP/2003/Vista (32bit and +64bit AMD64)

+

Software requirements:

+
    +
  • Microsoft Driver Developer Kit (DDK) for Windows Windows + XP or Windows Server 2003. As of WinPcap 4.0, the preferred DDK + environment is "DDK for Windows Server 2003SP1", also known as DDK + 3790.1830.
  • +
+

NOTE: it is possible to use older DDKs for Windows 2000, but you will need to +manually modify the compilation scripts in order to disable PREfast (PREfast is +a static code analysis tool shipped with recent versions of the DDK).

+

If your system satisfies these requirements, follow these steps:

+
    +
  1. From the Windows Start menu, select the folder Programs and + then Development Kits, then Windows XXX DDK, where XXX is + the target system, then Build Environments.
      +
    • 32bit driver: Choose Windows 2000 and then Windows 2000 Free Build + Environmentif you want to build a release version or Windows 2000 + Checked Build Environment if you want to build a debug version .
    • +
    • 64bit AMD64 driver: Choose Windows Server 2003 and then Windows + Server 2003 Free  x64 Build Environment if you want to build a release version or + Windows Server 2003 + Checked x64 Build Environment if you want to build a debug version .
    • +
    +
  2. A command prompt will be opened. Move to the directory PacketNTx inside the + WinPcap source folder and type the command

    CompileDriver
    +
    This script will generate the driver (npf.sys). The binary will be put in + one of these folders
      +
    • 32bit driver (both Free and Checked Build): winpcap\PacketNTx\driver\bin\2k\i386
    • +
    • 64bit AMD64 driver (both Free and Checked Build): winpcap\PacketNTx\driver\bin\xp\amd64
    • +
    +
+

Compiling the driver on Windows 9x

+

NOTE: this Windows platform is no longer supported by +WinPcap. However, the sources for these operating systems are still available in +the sources package.

+

To compile the driver for Windows 9x you will need:

+
    +
  • Driver Developer Kit (DDK) for Windows 95/98/ME +
  • A recent version of the Microsoft Platform Software Development Kit (SDK) + that is compatible with Visual Studio 6 (the latest compatible one is + Platform SDK February 2003). This version of the PSDK is available on the + Microsoft web site at + + http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm. + It can be ordered online at + + http://www.qmedia.ca/launch/psdk.htm, and it's also available to + Microsoft MSDN subscribers on the Subscribers Downloads web site.
  • Microsoft Visual C++ 6.0 + with Service Pack 5 or 6 (both the service packs are available online on the + Microsoft web site).
+

The steps to follow are:

+
    +
  1. Open a DOS shell +
  2. Go to the VisualC++ BIN directory (for example C:\DEVSTUDIO\VC\BIN) and + execute the command
    +
    + Vcvars32
    +
    +
  3. Go to the SDK directory (for example C:\MSSDK) and execute the command
    +
    + Setenv sdk_path
    +
    + where sdk_path is the directory of SDK (for example Setenv C:\MSSDK) +
  4. Go to the DDK directory (for example C:\DDK) and execute the command
    +
    + Ddkenv 32 net
    +
    +
  5. Move to the directory whit the driver's source code and type the command
    +
    + nmake rtl
    +
    +
    to obtain a release version, or
    +
    + nmake
    +
    +
    to obtain a debug version.
    The release version of packet.vxd will be placed in the + retail + directory, the debug version in the debug directory.
  6. +
+

Warning: On some systems the NMAKE utility is not able to +launch ADRC2VXD, this means that the driver binary is generated correctly, but +without the copyright information. We don't know the cause of this problem.

+

Compiling packet.dll

+

The source tree for this DLL is located in PacketNTx\dll\.

+

NOTE: the 9x family of Windows operating systems is no longer supported +by WinPcap. However, the sources for these operating systems are still available +in the sources package.

+

Software requirements:

+
    +
  • A recent version of the Microsoft Platform Software Development Kit + (SDK) that is compatible with Visual Studio 6 (the latest compatible one is + Platform SDK February 2003). This version of the PSDK is available on the + Microsoft web site at + + http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm. + It can be ordered online at + http://www.qmedia.ca/launch/psdk.htm, and it's also available to + Microsoft MSDN subscribers on the Subscribers Downloads web site.
    Note: if you use Microsoft Visual Studio .NET the platform SDK is + not + needed to compile packet.dll.
  • Microsoft Visual C++ 6.0 with Service Pack + 5 or 6 (both the service packs are available online on the Microsoft web + site).
  • If you want to build WinPcap with the support for the CACE + Technologies AirPcap wireless capture library, you will need to download the + AirPcap developer's pack from + + http://www.cacetech.com/products/airpcap.htm. The AirPcap developer's + pack needs to be unzipped in a folder in the same folder where the WinPcap + sources have been unzipped.
+

To compile the PACKET.DLL, load the project contained in the directory PacketNTx\dll\project +in the Visual C++ IDE. There are several project +configurations:

+
    +
  • PacketNT - Win32 Release: standard release configuration
  • +
  • PacketNT - Win32 Debug: standard debug configuration
  • +
  • PacketNT - Win32 Release No AirPcap: standard release configuration, + without AirPcap support
  • +
  • PacketNT - Win32 Debug No AirPcap: standard debug configuration, + without AirPcap support
  • +
  • PacketNT - Win32 NT4 Release: release configuration able to run on + NT4 does not include Wan and IP helper API support.
  • +
  • PacketNT - Win32 NT4 Debug: debug configuration able to run on NT4 + does not include Wan and IP helper API support.
  • +
  • PacketNT - Win32 Release Vista: release configuration able to run on + Vista. It + does not include Wan support (with the NetMon API).
  • +
  • PacketNT - Win32 Debug Vista: debug configuration able to run on + Vista. It + does not include Wan support (with the NetMon API).
  • +
  • WanPacket - Win32 Release: release version of the WanPacket + library, used to interface with NetMon API for Wan capture
  • +
  • WanPacket - Win32 Debug: debug version of the WanPacket library, + used to interface with NetMon API for Wan capture
  • +
+

Choose the desired configuration and build the project to obtain the binary +files.

+

Compiling wpcap.dll

+

wpcap.dll can be compiled on any Win32 platform and the generated dll is system independent.

+

System Requirements:

+
    +
  • Microsoft Visual C++ 6.0 with Service Pack 5 or 6 (both the service packs + are available online on the Microsoft web site).
  • +
  • A recent version of the Microsoft Platform Software Development Kit + (SDK) that is compatible with Visual Studio 6 (the latest compatible one is + Platform SDK February 2003). This version of the PSDK is available on the + Microsoft web site at + + http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm. + It can be ordered online at + + http://www.qmedia.ca/launch/psdk.htm, and it's also available to + Microsoft MSDN subscribers on the Subscribers Downloads web site.
    + Note: if you use Microsoft Visual Studio .Net the platform SDK is not + needed to compile wpcap.dll.
  • +
  • Project files are in the directory winpcap\wpcap\prj of the WinPcap source +code distribution. Load wpcap.dsw from the Visual C++ IDE and build the program.
  • +
  • If you want to build WinPcap with the support for the CACE Technologies + AirPcap wireless capture library, you will need to download the AirPcap + developer's pack from + http://www.cacetech.com/products/airpcap.htm. The AirPcap developer's + pack needs to be unzipped in the same folder where the WinPcap sources have been unzipped.
    +
    + There are eight build project configurations:

    No support for Remore Capture, + support for AirPcap, no support for DAG
  • +
  • Wpcap debug: output folder winpcap\wpcap\prj\Debug
  • +
  • Wpcap release: output folder winpcap\wpcap\prj\Release
    +
    + Support for Remore Capture, no support for AirPcap, no support for + DAG
  • +
  • Wpcap debug REMOTE NO AIRPCAP: output folder winpcap\wpcap\prj\Debug_REMOTE_NO_AIRPCAP
  • +
  • Wpcap release REMOTE NO AIRPCAP: output folder winpcap\wpcap\prj\Release_REMOTE_NO_AIRPCAP

    + Support for Remore Capture, support for AirPcap, no support for DAG

  • +
  • Wpcap debug REMOTE: output folder winpcap\wpcap\prj\Debug_REMOTE
  • +
  • Wpcap release REMOTE: output folder winpcap\wpcap\prj\Release_REMOTE

    + Support for Remore Capture, support for AirPcap, support for DAG
  • +
  • Wpcap debug REMOTE DAG: output folder winpcap\wpcap\prj\Debug_REMOTE_DAG
  • +
  • Wpcap release REMOTE DAG: output folder winpcap\wpcap\prj\Release_REMOTE_DAG
  • +
+

Note: wpcap.dll contains the source code of libpcap from +www.tcpdump.org, with some modifications +for remote capture. You will be able to include and build a different libpcap +version simply copying it in the directory winpcap\wpcap\prj of the +WinPcap source code distribution, but you must use the "Debug" or "Release" +build configurations.

+ + + + diff --git a/winpcap/dox/doxygen_groups.txt b/winpcap/dox/doxygen_groups.txt new file mode 100644 index 0000000..399f7e8 --- /dev/null +++ b/winpcap/dox/doxygen_groups.txt @@ -0,0 +1,105 @@ +/*! + \defgroup internals WinPcap internals + \htmlinclude internals.htm +*/ + +/*! + \ingroup internals + \defgroup NPF NPF driver internals manual + \htmlinclude npf.htm +*/ + + + +/*! + \ingroup internals + \defgroup compilation How to compile WinPcap + \htmlinclude compile.htm +*/ + + + +/*! + \ingroup internals + \defgroup packetapi Packet.dll -- Packet Driver API + \htmlinclude packet.htm +*/ + +/*! + \defgroup wpcap WinPcap user's manual + \htmlinclude wpcap.htm +*/ + +/*! + \ingroup wpcap + \defgroup language Filtering expression syntax + \htmlinclude language.htm +*/ + + +/*! + \ingroup wpcap + \defgroup wpcapsamps Using WinPcap in your programs + \htmlinclude wpcap_samp.htm + + \htmlinclude wpcap_samp1.htm + \include pktdump_ex\pktdump_ex.c + + \htmlinclude wpcap_samp2.htm + \include pcap_filter/pcap_filter.c +*/ + + + + + +/*! + \defgroup remote Remote Capture + \htmlinclude wpcap_remote.htm +*/ + +/*! + \ingroup remote + \defgroup remote_struct Exported Structures and Definitions +*/ + +/*! + \ingroup remote + \defgroup remotefunc Exported Functions +*/ + +/*! + \ingroup remote + \defgroup remote_pri_func Internal Functions +*/ + +/*! + \ingroup remote + \defgroup remote_pri_struct Internal Structures and Definitions +*/ + + +/*! + \ingroup remote_struct + \defgroup remote_source_string Strings related to the new source syntax +*/ + +/*! + \ingroup remote_struct + \defgroup remote_source_ID Identifiers related to the new source syntax +*/ + +/*! + \ingroup remote_struct + \defgroup remote_open_flags Flags defined in the pcap_open() function +*/ + +/*! + \ingroup remote_struct + \defgroup remote_samp_methods Sampling methods defined in the pcap_setsampling() function +*/ + +/*! + \ingroup remote_struct + \defgroup remote_auth_methods Authentication methods supported by the RPCAP protocol +*/ diff --git a/winpcap/dox/doxygen_groups_packetdll.txt b/winpcap/dox/doxygen_groups_packetdll.txt new file mode 100644 index 0000000..5e805d3 --- /dev/null +++ b/winpcap/dox/doxygen_groups_packetdll.txt @@ -0,0 +1,114 @@ +/*! + \defgroup internals WinPcap internals + \htmlinclude internals.htm +*/ + +/*! + \ingroup internals + \defgroup NPF NPF driver internals manual + \htmlinclude npf.htm +*/ + + + +/*! + \ingroup internals + \defgroup compilation How to compile WinPcap + \htmlinclude compile.htm +*/ + + + +/*! + \ingroup internals + \defgroup packetapi Packet Driver API developer's manual + \htmlinclude packet.htm +*/ + + +/*! + \ingroup packetapi + \defgroup packetsamps Packet.dll samples + \htmlinclude packet_samp.htm +*/ + + + +/*! + \defgroup wpcap WinPcap user's manual + \htmlinclude wpcap.htm +*/ + +/*! + \ingroup wpcap + \defgroup language Filtering expression syntax + \htmlinclude language.htm +*/ + + +/*! + \ingroup wpcap + \defgroup wpcapsamps Using WinPcap in your programs + \htmlinclude wpcap_samp.htm + + \htmlinclude wpcap_samp1.htm + \include pktdump_ex\pktdump_ex.c + + \htmlinclude wpcap_samp2.htm + \include pcap_filter/pcap_filter.c +*/ + + + + + +/*! + \defgroup remote Remote Capture + \htmlinclude wpcap_remote.htm +*/ + +/*! + \ingroup remote + \defgroup remote_struct Exported Structures and Definitions +*/ + +/*! + \ingroup remote + \defgroup remotefunc Exported Functions +*/ + +/*! + \ingroup remote + \defgroup remote_pri_func Internal Functions +*/ + +/*! + \ingroup remote + \defgroup remote_pri_struct Internal Structures and Definitions +*/ + + +/*! + \ingroup remote_struct + \defgroup remote_source_string Strings related to the new source syntax +*/ + +/*! + \ingroup remote_struct + \defgroup remote_source_ID Identifiers related to the new source syntax +*/ + +/*! + \ingroup remote_struct + \defgroup remote_open_flags Flags defined in the pcap_open() function +*/ + +/*! + \ingroup remote_struct + \defgroup remote_samp_methods Sampling methods defined in the pcap_setsampling() function +*/ + +/*! + \ingroup remote_struct + \defgroup remote_auth_methods Authentication methods supported by the RPCAP protocol +*/ diff --git a/winpcap/dox/footer.htm b/winpcap/dox/footer.htm new file mode 100644 index 0000000..09addc7 --- /dev/null +++ b/winpcap/dox/footer.htm @@ -0,0 +1,5 @@ + +
+

+documentation. Copyright (c) 2002-2005 Politecnico di Torino. Copyright (c) 2005-2007 +CACE Technologies. All rights reserved.

diff --git a/winpcap/dox/internals-arch.gif b/winpcap/dox/internals-arch.gif new file mode 100644 index 0000000000000000000000000000000000000000..37b7ea6758d56cb8d94879309d1ecc26b0a624e5 GIT binary patch literal 4650 zcwX(32R9oE!+=Azv})XHYn5tmuX&A@x5Vfzy)A-jwQ3c$SE<%YD3Ta4V#bJwEo6w1 z7_qB*6|t$ks`dyqV>Eg1_cOk8-sha>oaYZb`i4(5fDR%YP8>%70N@r#PEQZy=Vc87 zSzCjwL$DzoHECoVHY5a#4Z-%Y$+M#!H8mY8?7r=P?PIU3u(!9_>^?Soh0Xpq{>T6L zf6Sl%E&%wy7XUmgfCA4AgUbB23p_&duRALX+7W`kgRllwh5y9!@p(>nRuz3sl6n+( zHTD^-3nlx4__~XNqi3o(bz=>wCEY0+e(Td+eoltj4ZLbBuy~Y-r%UD`_@$750Rn zgG*ubql)kC56=nMmDQ*$d`-5IcQu9(esrSmnwIxKR+f751>P}?F^dxe_?t;ey$wHB zMk>FR`tb)D<?X1>ob3 zh?sPDM>|+nUWm?dK`xCdp;{2j_;;%@?I(vZl|CtNE zCCPNoC95qI{QU>f{S{KrlTeJZGbi8>ju?VVJcTQ&6)@f z=vM7?i@AN>e01YT;zEWO!(cL(#Ap!5(HV`K4ZPb;OWj7>&C`?d+bu2Y^zGKX6W*Oq z!IzA8+N8yhJD=%tJv;5yz{^z?SB+I*T-WWfcRQ~8mA(Hej<~$rc{6kKXV>j)?7a>^ zGLk}9_4-XXmhXsA-CfGz~92&YJev)J#$aWhL~K@wPv4X9NEG7IjBQ$i8l;(};1}_UXu5d#Hae zr-`dWp+&o`M&POT{y#zX_CGiI*gE|K2!Z{hVT(NG!8!HqrlT2DtIoksebZlO?GdId zRti4uQ>r~zRBaI#t0#>6HI~gqO=^BEMvYtm^Dcfq88oc?o!np;zdRpJBxD2X+DtOP0>-k z(|qG%mp&-fF1=^*kG03pr@_0Z{L465eZy`u%x)Uq7$q?J<*o)u)(Jr}nKDEb1lA6_bLt3rqnC@ZbmpR(BtVkvF zT795qgJS_)x25_%WcXoM?yP7G);|rvP;=IhGTJN0eZdrJE`a4*s=c+=7ji<)1I(=a zbzW>BpwA2|Xn@xf?jDHN+%FJJ!2c}+8jQ2vFBEZ+J?AXf#|_>ulHwy6=!1q*G5f`` zCIpa0_fSUMRgQ{HypbDd7&EzFqM;+lc>($;Yk9x)As_LXcf)Y5-W$Au3DGRw`X%ky zpYSY!_|kmxB~>SYXxY2|lGIQ`@;o5D;gh$>TmDvwIVe+-@apT18?9|fFZRq4v6%yn z)pcBR^dpn(dV|LhO92(oUQc_`!?90d*NG9fmJR~+@dD}V4)HnbiQ_-a0QeD#^gm^; zTiq{8B@f8xU+(V8Mw30k{#2jP&9>VL-v%GNsn)u}QgkupHR~N+sjed{x;)>oZV4PE z<^_!1h zr`PLiOtwFSh>tS(HyfY1Y`^zVnBAacHto$YtY&ysm`dg?OE{mvJuR~{$GWD|U)~lG zQ?CH(V=b#Q z5Xrmyy<-wwqUd9xtM)NnRH(Q^o&TP>auZ6}53Qpgm|2T#a=JrDw{vyjlDIjYZ`srr z1D`A>7WDMU1X*>QTvAO-?{QH!wURP#p|CKz7?%i@<6iq&3buE1NuzY5=bFJDW^8&H z_*JwgNZKN&Xwy|!8Q2{y9iMyjap{53$)L@3YPO7ohe0M#A>Oq*S%S|4l9JUE(NdlB zn9oz&&3agUS*@^r)A?aMCJPl+Q_9QdNydtOOE5oZ^hwxgU&q)sF#_I%_bOfBIUV=? zV|Q5a)26G|>BK-{ZFQ;1mZ#0>KgRnb%?%d=3!t-{$6vB<(|zPyF@zo9DgNjZ)%Rxq5heJyc4S0G|MZnO}xeM zjg`SJT(`9WHgE*0*6!C#S1)wWa4bnS^++s(=*ExV?w zA%9`7Vt?;iv2fh&Q=IXGbNpKQTRC{>?py!JZA2-%d^>+2SzTh`b#B1K7;9bANMa*=d2H~V|G}NH<_+Pb#@4gY)h0x+y`SlLQ2^tR zh6vt9g*ALPW$c5f%{$4$nzL-??mz-D%Y|ky#Cy) z{*%#0)513-Ufv(HvdTMy6gbZ?N@zjl&Z&sI#?JG@c= z4gc_8NBwNpsXgl`Gn{uPoXZk=!5zxMqka+uy*v)(cMrShexH{Ky=n;)5P{jK!miU` zH^#$7m}+9cE4NKThG6LpksyeYu@R%O&07z{U(Rh zUyCw?L|g-=nbfD=pGew9r#sWq9lK!9vJ}i98G;5Gp6(fMC*mDMGg%s${>QOC$I-r! zOg?l5^>(@%A?&GK7|bwDeKnKJiI!V~+KR?N3=tt#;Zj{G2M+1d1k_8btau>m0wFcQ zBiXz@C4!I`Xb3}fp)%!CG_p`H>$C1!rRT1tkS}KQFwqc^towHCF^3(S z#TA>6j?HIX#A+>Ixis?gC>bBS;42d`Ymfp-bU`Yu;D&s@WN@sMSmC~YL6&2IG$vG5 zQ%=62@WMc0+-{+Qd=Xr)NZPX~7+!RXSmgS-=*D`H1!u9ae6fLE@kfthb$D?Qp;-EJ zvHx1}RZiS{IUHLT_tpcq1jD%za1(7f$2Ap7l)@U#yECaL4Ds@N_&L+lKF0#iw%++GGi7 zx`ZZo0un~3!xQ4$2$WSq1P75UON8qZ@$ST67_kUXgtQTJSBYQ_QkE>qSC^FLPI?C; zCE-avZKSwWk_$&!lx&%^ZW+|Q%n4RT)hOIFD^&4}>T6Kq79^L;8gV9*CmYDqljPYG z^1N92f@b-mb@_5|`RY1(xLb*1pqz11z9Uw#t68ycU2zy(0r0IjX{b1x{I`SSpT7g} zsx$9by8iIJaH__eS$T1BNCn1IC|uRj;&&f~KpuMq z>U%*X6#{jZjr2k&7<~_8gb5!BY=lsHYExqy6riRBu^I~s52`XUa!XP7e4ZKj`l#AK zz1AZ;(CN_mwSKKH$;gu~p0^wnG!>L?Q7JH0>2?|fQK)+_UZ=ZJSLs@d;SO@~G77K} zf0qG?Q}99w*NSFW8+g@25%nNaJ$9--_q0A=yrEF5p_o+3Gxgh*VOpVh4c^EYXGF=l zP;W=C`Oj$sxgapes5XKgNQ|%NJ*|5ePm6bJ#NJX_Om#@MF#<_felZe_;coKM2e(f( q1^;Zal_WKO=7o%GG`(_jjhlL(+St6H)v{>QvK-Qa78e8nwEhb%kM9=% literal 0 HcwPel00001 diff --git a/winpcap/dox/internals.htm b/winpcap/dox/internals.htm new file mode 100644 index 0000000..6f160e8 --- /dev/null +++ b/winpcap/dox/internals.htm @@ -0,0 +1,63 @@ + + + + + + + + + + +This portion of the manual describes the internal structure and interfaces of WinPcap, +starting from the lowest-level module. It is targeted at people that must extend +or modify this software, or to the ones interested in how it works. Therefore, +developers who just want to use WinPcap in their software don't need to read it. + +

WinPcap structure

+

Quoted from the home page of winpcap:

+

WinPcap is an architecture for packet capture and network analysis for the +Win32 platforms. It includes a kernel-level packet filter, a +low-level dynamic link library (packet.dll), and a high-level and +system-independent library (wpcap.dll).

+

Why we use the term "architecture" rather than "library"? Because packet capture is a low level mechanism +that requires a strict interaction with the network adapter and with the +operating system, in particular with its networking implementation, so a simple +library is not sufficient.

+

The following figure shows the various components of WinPcap:

+

+ +

+Main components of WinPcap. +

First, a capture system needs to bypass the operating systems's protocol stack in order to access +the raw data transiting on the network. This requires a portion +running inside the kernel of OS, interacting directly with the network interface +drivers. This portion is very system dependent, and in +our solution it is realized as a device driver, called Netgroup Packet Filter (NPF); +we provide different versions of the driver for Windows 95, Windows 98, Windows ME, +Windows NT 4, +Windows 2000 and Windows XP. These drivers offer both basic features like packet capture +and injection, as well as more advanced ones like a programmable filtering system and a +monitoring engine. The first one can be used to restrict a capture session to a +subset of the network traffic (e.g. it is possible to capture only the ftp +traffic generated by a particular host), the second one provides a powerful but +simple to use mechanism to obtain statistics on the traffic (e.g. it is possible +to obtain the network load or the amount of data exchanged between two hosts).

+

Second, the capture system must export an interface that user-level +applications will use to take advantage of the features provided by the kernel +driver. WinPcap provides two different libraries: packet.dll and wpcap.dll

+

+The first one offers a low-level API that can be used to directly access the +functions of the driver, with a programming interface independent from the +Microsoft OS. 

+

The second one exports a more powerful set of high level capture +primitives that are compatible with libpcap, the well known Unix capture +library. These functions enable packet capture in a manner that is independent +of the +underlying network hardware and operating system.

+

Throughout this documentation we will refer to the Packet Driver API or +packet.dll as the first set of functions, whereas wpcap, wpcap.dll or libpcap + will refer to the to the second one.

+ + + + diff --git a/winpcap/dox/intro.htm b/winpcap/dox/intro.htm new file mode 100644 index 0000000..fa03aa3 --- /dev/null +++ b/winpcap/dox/intro.htm @@ -0,0 +1,157 @@ + + + + + + + + + + +
+ +

Introduction

+ + +

This Manual describes the +programming interface and the source code of WinPcap. It provides detailed +descriptions of the functions and structures exported to programmers, along +with complete documentation of the WinPcap internals. Several tutorials and +examples are provided as well.  + +

+

You can follow the links at the top of this page or use the tree control at +the left to reach sections of interest. + +

+

This documentation was created using the Doxygen documentation system, that can +be found at http://www.doxygen.org. + +

+

What is WinPcap

+

WinPcap is an open source library for packet capture and network analysis for +the Win32 platforms.

+

Most networking applications access the network through widely used operating +system primitives such as sockets.  It is easy to access data on the +network with this approach since the operating system copes with the low level +details (protocol handling, packet reassembly, etc.) and provides a familiar +interface that is similar to the one used to read and write files. + +

+

Sometimes, however, the 'easy way' is not up to the task, since some +applications require direct access to packets on the network.  That is, they +need access to the "raw" data on the network without the interposition of +protocol processing by the operating system.

+

The purpose of WinPcap is to give this kind of access to Win32 applications; +it provides facilities to:

+
    +
  • capture + raw packets, both the ones destined to the machine where it's running and + the ones exchanged by other hosts (on shared media)
  • +
  • filter + the packets according to user-specified rules before dispatching them to the + application
  • +
  • transmit raw packets to the network
  • +
  • gather statistical information on the network traffic
  • +
+

This set of capabilities is obtained by means of a device driver, that is +installed inside the networking portion of Win32 kernels, plus a couple of DLLs.

+

All these features are exported through a powerful programming interface, +easily exploitable by the applications and available on different OSes. The main +goal of this manual is to document this interface, with the help of several +examples.  If you are interested in starting your exploration right away +you can go directly to the WinPcap user's manual.

+ +

What kind of programs use WinPcap

+

The WinPcap programming interface can be used by many types of network tools +for analysis, troubleshooting, security and +monitoring. In particular, classical tools that rely on WinPcap are:

+ +
    +
  • network and protocol analyzers
  • +
  • network monitors
  • +
  • traffic loggers
  • +
  • traffic generators
  • +
  • user-level bridges and routers
  • +
  • network intrusion detection systems (NIDS)
  • +
  • network scanners
  • +
  • security tools
  • +
+

What WinPcap can't do

+

WinPcap receives and sends the packets independently from the host +protocols, like TCP-IP. This means that it isn't able to block, filter or +manipulate the traffic generated by other programs on the same machine: it +simply "sniffs" the packets that transit on the wire. Therefore, it does not +provide the appropriate support for applications like traffic shapers, QoS +schedulers and personal firewalls.

+ +

Purpose of this manual

+

The purpose of this manual is to provide a comprehensive and easy way to +browse the documentation of the WinPcap architecture. You will find two main +sections: WinPcap user's manual and WinPcap Internals.

+

The first one can be used by a programmer who needs to exploit WinPcap from +an application: it contains all the information about functions and data +structures exported by the WinPcap API, a manual that explains how to write +packet filters and a page that explains how to include it in an application. A +tutorial with several code samples is provided as well; it can be used to learn +the basics of the WinPcap API using a step-by-step approach, but it also offers +code snippets that demonstrate advanced features.  

+

The second section is intended for WinPcap developers and maintainers, or for +people who are curious about how this system works: it provides a general +description of the WinPcap architecture and explains how it works. Additionally, +it documents the complete device driver structure, the source code, the packet.dll +interface and the low-level WinPcap API. +If you want to understand what happens inside WinPcap or if you need to extend +it, this is the section you will want to read.

+

Additional Documentation

+

For additional and up-to-date documentation, we suggest that you look at  http://www.winpcap.org/docs/ +

+

In particular, if you are interested in +the structure and the internals of WinPcap, we suggest reading the +following documents:

+ + +

Terminology

+
    +
  • For consistency with the literature, we will use the term packet even + though frame is more accurate since the capture process is done at + the data-link layer and the data-link header is included in the captured + data.
  • +
  • The term Win9x will be used in this documentation to indicate the family of + Microsoft OSes made up of Windows 95 and its derivatives, i.e. Windows 98 and + Windows ME. The term WinNTx will indicate the OSes built upon the NT kernel, + starting from Windows NT 4 and including Windows 2000, Windows XP, + Windows Server 2003 and so on.
  • +
+ +

Note

+

Our development and documentation efforts focus primarily on the +Windows NT/2000/XP/2003 version of WinPcap. This choice is based on the fact that the +majority of the WinPcap users work on NTx systems, but also because the 9x technology +has been abandoned by Microsoft. Moreover, we assume that a person who needs to +use a PC for an advanced task like network analysis will install an advanced OS +on the machine. For this reason, the documentation will refer to the WinNTx +drivers and APIs. Win9x versions are very similar in the concept but sometimes +differ in the implementation and, occasionally, the Win9x version of the API +lacks some of the more advanced functionality. This manual describes the +complete API and will indicate when a function is present only in Windows NTx.

+ +

 

+ + + + diff --git a/winpcap/dox/language.htm b/winpcap/dox/language.htm new file mode 100644 index 0000000..c5704b5 --- /dev/null +++ b/winpcap/dox/language.htm @@ -0,0 +1,600 @@ + + + + + + + + + + +
+
Note: this document has been drawn from the tcpdump man page. The original version can + be found at  www.tcpdump.org. +
 
+
wpcap filters are based on a declarative predicate syntax. A filter is + an ASCII string containing a filtering expression. pcap_compile() + takes the expression and translates it in a program for the kernel-level + packet filter. +
+

The expression selects which packets will be dumped. +If no expression +is given, all packets on the net will be accepted by the kernel-level filtering +engine. +Otherwise, +only packets for which expression is `true' will be accepted.

+

+ +The expression consists of one or more +primitives. + +Primitives usually consist of an +id + +(name or number) preceded by one or more qualifiers. +There are three +different kinds of qualifier: +

+
type
+qualifiers say what kind of thing the id name or number refers to. +Possible types are +host, + +net + +and +port. + +E.g., `host foo', `net 128.3', `port 20'. +If there is no type +qualifier, +host + +is assumed. +
dir
+qualifiers specify a particular transfer direction to and/or from +id. + +Possible directions are +src, + +dst, + +src or dst + +and +src and + +dst. + +E.g., `src foo', `dst net 128.3', `src or dst port ftp-data'. +If +there is no dir qualifier, +src or dst + +is assumed. +For `null' link layers (i.e. point to point protocols such as slip) the +inbound + +and +outbound + +qualifiers can be used to specify a desired direction. +
proto
+qualifiers restrict the match to a particular protocol. +Possible +protos are: +ether, + +fddi, + +tr, + +ip, + +ip6, + +arp, + +rarp, + +decnet, + +tcp + +and +udp. + +E.g., `ether src foo', `arp net 128.3', `tcp port 21'. +If there is +no proto qualifier, all protocols consistent with the type are +assumed. +E.g., `src foo' means `(ip or arp or rarp) src foo' +(except the latter is not legal syntax), `net bar' means `(ip or +arp or rarp) net bar' and `port 53' means `(tcp or udp) port 53'. +
+

+ +[`fddi' is actually an alias for `ether'; the parser treats them +identically as meaning ``the data link level used on the specified +network interface.'' FDDI headers contain Ethernet-like source +and destination addresses, and often contain Ethernet-like packet +types, so you can filter on these FDDI fields just as with the +analogous Ethernet fields. +FDDI headers also contain other fields, +but you cannot name them explicitly in a filter expression. +

+ +Similarly, `tr' is an alias for `ether'; the previous paragraph's +statements about FDDI headers also apply to Token Ring headers.] +

+ +In addition to the above, there are some special `primitive' keywords +that don't follow the pattern: +gateway, + +broadcast, + +less, + +greater + +and arithmetic expressions. +All of these are described below. +

+ +More complex filter expressions are built up by using the words +and, + +or + +and +not + +to combine primitives. +E.g., `host foo and not port ftp and not port ftp-data'. +To save typing, identical qualifier lists can be omitted. +E.g., +`tcp dst port ftp or ftp-data or domain' is exactly the same as +`tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'. +

+ +Allowable primitives are: +

+
dst host host
+True if the IPv4/v6 destination field of the packet is host, +which may be either an address or a name. +
src host host
+True if the IPv4/v6 source field of the packet is host. +
host host
+True if either the IPv4/v6 source or destination of the packet is host. +Any of the above host expressions can be prepended with the keywords, +ip, arp, rarp, or ip6 as in: +
+
+ +
ip host host
+ + +
+
+ + +which is equivalent to: +
+
+ +
ether proto \ip and host host
+ + +
+
+ + +If host is a name with multiple IP addresses, each address will +be checked for a match. +
ether dst ehost
+True if the ethernet destination address is ehost. +Ehost +may be either a name from /etc/ethers or a number (see +ethers(3N) + +for numeric format). +
ether src ehost
+True if the ethernet source address is ehost. +
ether host ehost
+True if either the ethernet source or destination address is ehost. +
gateway host
+True if the packet used host as a gateway. +I.e., the ethernet +source or destination address was host but neither the IP source +nor the IP destination was host. +Host must be a name and +must be found both by the machine's host-name-to-IP-address resolution +mechanisms (host name file, DNS, NIS, etc.) and by the machine's +host-name-to-Ethernet-address resolution mechanism (/etc/ethers, etc.). +(An equivalent expression is +
+
+ +
ether host ehost and not host host
+ + +
+
+ + +which can be used with either names or numbers for host / ehost.) +This syntax does not work in IPv6-enabled configuration at this moment. +
dst net net
+True if the IPv4/v6 destination address of the packet has a network +number of net. +Net may be either a name from /etc/networks +or a network number (see networks(4) for details). +
src net net
+True if the IPv4/v6 source address of the packet has a network +number of net. +
net net
+True if either the IPv4/v6 source or destination address of the packet has a network +number of net. +
net net mask netmask
+True if the IP address matches net with the specific netmask. +May be qualified with src or dst. +Note that this syntax is not valid for IPv6 net. +
net net/len
+True if the IPv4/v6 address matches net with a netmask len +bits wide. +May be qualified with src or dst. +
dst port port
+True if the packet is ip/tcp, ip/udp, ip6/tcp or ip6/udp and has a +destination port value of port. +The port can be a number or a name used in /etc/services (see +tcp(4P) + +and +udp(4P)). + +If a name is used, both the port +number and protocol are checked. +If a number or ambiguous name is used, +only the port number is checked (e.g., dst port 513 will print both +tcp/login traffic and udp/who traffic, and port domain will print +both tcp/domain and udp/domain traffic). +
src port port
+True if the packet has a source port value of port. +
port port
+True if either the source or destination port of the packet is port. +Any of the above port expressions can be prepended with the keywords, +tcp or udp, as in: +
+
+ +
tcp src port port
+ + +
+
+ + +which matches only tcp packets whose source port is port. +
less length
+True if the packet has a length less than or equal to length. +This is equivalent to: +
+
+ +
len <= length.
+ + +
+
+ + +
greater length
+True if the packet has a length greater than or equal to length. +This is equivalent to: +
+
+ +
len >= length.
+ + +
+
+ + +
ip proto protocol
+True if the packet is an IP packet (see +ip(4P)) + +of protocol type protocol. +Protocol can be a number or one of the names +icmp, icmp6, igmp, igrp, pim, ah, +esp, vrrp, udp, or tcp. +Note that the identifiers tcp, udp, and icmp are also +keywords and must be escaped via backslash (\), which is \\ in the C-shell. +Note that this primitive does not chase the protocol header chain. +
ip6 proto protocol
+True if the packet is an IPv6 packet of protocol type protocol. +Note that this primitive does not chase the protocol header chain. +
ip6 protochain protocol
+True if the packet is IPv6 packet, +and contains protocol header with type protocol +in its protocol header chain. +For example, +
+
+ +
ip6 protochain 6
+ + +
+
+ + +matches any IPv6 packet with TCP protocol header in the protocol header chain. +The packet may contain, for example, +authentication header, routing header, or hop-by-hop option header, +between IPv6 header and TCP header. +The BPF code emitted by this primitive is complex and +cannot be optimized by BPF optimizer code in tcpdump, +so this can be somewhat slow. +
ip protochain protocol
+Equivalent to ip6 protochain protocol, but this is for IPv4. +
ether broadcast
+True if the packet is an ethernet broadcast packet. +The ether +keyword is optional. +
ip broadcast
+True if the packet is an IP broadcast packet. +It checks for both +the all-zeroes and all-ones broadcast conventions, and looks up +the local subnet mask. +
ether multicast
+True if the packet is an ethernet multicast packet. +The ether +keyword is optional. +This is shorthand for `ether[0] & 1 != 0'. +
ip multicast
+True if the packet is an IP multicast packet. +
ip6 multicast
+True if the packet is an IPv6 multicast packet. +
ether proto protocol
+True if the packet is of ether type protocol. +Protocol can be a number or one of the names +ip, ip6, arp, rarp, atalk, aarp, +decnet, sca, lat, mopdl, moprc, +iso, stp, ipx, or netbeui. +Note these identifiers are also keywords +and must be escaped via backslash (\). +
+[In the case of FDDI (e.g., `fddi protocol arp') and Token Ring +(e.g., `tr protocol arp'), for most of those protocols, the +protocol identification comes from the 802.2 Logical Link Control (LLC) +header, which is usually layered on top of the FDDI or Token Ring +header. +
+When filtering for most protocol identifiers on FDDI or Token Ring, +tcpdump checks only the protocol ID field of an LLC header in +so-called SNAP format with an Organizational Unit Identifier (OUI) of +0x000000, for encapsulated Ethernet; it doesn't check whether the packet +is in SNAP format with an OUI of 0x000000. +
+The exceptions are iso, for which it checks the DSAP (Destination +Service Access Point) and SSAP (Source Service Access Point) fields of +the LLC header, stp and netbeui, where it checks the DSAP of +the LLC header, and atalk, where it checks for a SNAP-format +packet with an OUI of 0x080007 and the Appletalk etype. +
+In the case of Ethernet, tcpdump checks the Ethernet type field +for most of those protocols; the exceptions are iso, sap, +and netbeui, for which it checks for an 802.3 frame and then +checks the LLC header as it does for FDDI and Token Ring, atalk, +where it checks both for the Appletalk etype in an Ethernet frame and +for a SNAP-format packet as it does for FDDI and Token Ring, aarp, +where it checks for the Appletalk ARP etype in either an Ethernet frame +or an 802.2 SNAP frame with an OUI of 0x000000, and ipx, where it +checks for the IPX etype in an Ethernet frame, the IPX DSAP in the LLC +header, the 802.3 with no LLC header encapsulation of IPX, and the IPX +etype in a SNAP frame.] +
decnet src host
+True if the DECNET source address is +host, + +which may be an address of the form ``10.123'', or a DECNET host +name. +[DECNET host name support is only available on Ultrix systems +that are configured to run DECNET.] +
decnet dst host
+True if the DECNET destination address is +host. + +
decnet host host
+True if either the DECNET source or destination address is +host. + +
ip, ip6, arp, rarp, atalk, aarp, decnet, iso, stp, ipx, netbeui
+Abbreviations for: +
+
+ +
ether proto p
+ + +
+
+ + +where p is one of the above protocols. +
lat, moprc, mopdl
+Abbreviations for: +
+
+ +
ether proto p
+ + +
+
+ + +where p is one of the above protocols. +Note that +tcpdump does not currently know how to parse these protocols. +
vlan [vlan_id]
+True if the packet is an IEEE 802.1Q VLAN packet. +If [vlan_id] is specified, only true is the packet has the specified +vlan_id. +Note that the first vlan keyword encountered in expression +changes the decoding offsets for the remainder of expression +on the assumption that the packet is a VLAN packet. +
tcp, udp, icmp
+Abbreviations for: +
+
+ +
ip proto p or ip6 proto p
+ + +
+
+ + +where p is one of the above protocols. +
iso proto protocol
+True if the packet is an OSI packet of protocol type protocol. +Protocol can be a number or one of the names +clnp, esis, or isis. +
clnp, esis, isis
+Abbreviations for: +
+
+ +
iso proto p
+ + +
+
+ + +where p is one of the above protocols. +Note that tcpdump does an incomplete job of parsing these protocols. +
expr relop expr
+True if the relation holds, where relop is one of >, <, >=, <=, =, !=, +and expr is an arithmetic expression composed of integer constants +(expressed in standard C syntax), the normal binary operators +[+, -, *, /, &, |], a length operator, and special packet data accessors. +To access +data inside the packet, use the following syntax: + +
+proto [ expr : size ]
+
+ + +Proto is one of ether, fddi, tr, +ip, arp, rarp, tcp, udp, icmp or ip6, and +indicates the protocol layer for the index operation. +Note that tcp, udp and other upper-layer protocol types only +apply to IPv4, not IPv6 (this will be fixed in the future). +The byte offset, relative to the indicated protocol layer, is +given by expr. +Size is optional and indicates the number of bytes in the +field of interest; it can be either one, two, or four, and defaults to one. +The length operator, indicated by the keyword len, gives the +length of the packet. +

+For example, `ether[0] & 1 != 0' catches all multicast traffic. +The expression `ip[0] & 0xf != 5' +catches all IP packets with options. +The expression +`ip[6:2] & 0x1fff = 0' +catches only unfragmented datagrams and frag zero of fragmented datagrams. +This check is implicitly applied to the tcp and udp +index operations. +For instance, tcp[0] always means the first +byte of the TCP header, and never means the first byte of an +intervening fragment. +

+Some offsets and field values may be expressed as names rather than +as numeric values. +The following protocol header field offsets are +available: icmptype (ICMP type field), icmpcode (ICMP +code field), and tcpflags (TCP flags field). +

+The following ICMP type field values are available: icmp-echoreply, +icmp-unreach, icmp-sourcequench, icmp-redirect, +icmp-echo, icmp-routeradvert, icmp-routersolicit, +icmp-timxceed, icmp-paramprob, icmp-tstamp, +icmp-tstampreply, icmp-ireq, icmp-ireqreply, +icmp-maskreq, icmp-maskreply. +

+The following TCP flags field values are available: tcp-fin, +tcp-syn, tcp-rst, tcp-push, tcp-push, +tcp-ack, tcp-urg. +

+

+ +Primitives may be combined using: +

+
+A parenthesized group of primitives and operators +(parentheses are special to the Shell and must be escaped). +
+Negation (`!' or `not'). +
+Concatenation (`&&' or `and'). +
+Alternation (`||' or `or'). +
+

+ +Negation has highest precedence. +Alternation and concatenation have equal precedence and associate +left to right. +Note that explicit and tokens, not juxtaposition, +are now required for concatenation. +

+ +If an identifier is given without a keyword, the most recent keyword +is assumed. +For example, + +

+ +
not host vs and ace
+ + +
+ + +is short for +
+ +
not host vs and host ace
+ + +
+ + +which should not be confused with +
+ +
not ( host vs or ace )
+ + +
+ + +

+ +Expression arguments can be passed to tcpdump as either a single +argument or as multiple arguments, whichever is more convenient. +Generally, if the expression contains Shell metacharacters, it is +easier to pass it as a single, quoted argument. +Multiple arguments are concatenated with spaces before being parsed. +

+ + + + diff --git a/winpcap/dox/libpcap/funcs/pcap.h b/winpcap/dox/libpcap/funcs/pcap.h new file mode 100644 index 0000000..e065071 --- /dev/null +++ b/winpcap/dox/libpcap/funcs/pcap.h @@ -0,0 +1,1250 @@ +/** @defgroup wpcapfunc Exported functions + * @ingroup wpcap + * Functions exported by wpcap.dll + * @{ + */ + + +/** \name Unix-compatible Functions + + These functions are part of the libpcap library, and therefore work + both on Windows and on Linux. + \note errbuf in pcap_open_live(), pcap_open_dead(), pcap_open_offline(), + pcap_setnonblock(), pcap_getnonblock(), pcap_findalldevs(), + pcap_lookupdev(), and pcap_lookupnet() is assumed to be able to hold at + least PCAP_ERRBUF_SIZE chars. + */ +//\{ + +/*! \brief Prototype of the callback function that receives the packets. + +When pcap_dispatch() or pcap_loop() are called by the user, the packets are passed to the application +by means of this callback. user is a user-defined parameter that contains the state of the +capture session, it corresponds to the \e user parameter of pcap_dispatch() and pcap_loop(). pkt_header is +the header associated by the capture driver to the packet. It is NOT a protocol header. pkt_data +points to the data of the packet, including the protocol headers. +*/ +typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *pkt_header, + const u_char *pkt_data); + +/*! \brief Open a live capture from the network. + + pcap_open_live() is used to obtain a packet capture descriptor to + look at packets on the network. device is a string that specifies + the network device to open; on Linux systems with 2.2 or later kernels, + a device argument of "any" or NULL can be used to capture packets + from all interfaces. snaplen specifies the maximum number of + bytes to capture. If this value is less than the size of a packet + that is captured, only the first snaplen bytes of that packet will be + captured and provided as packet data. A value of 65535 should be + sufficient, on most if not all networks, to capture all the data + available from the packet. promisc specifies if the interface is to + be put into promiscuous mode. (Note that even if this parameter is + false, the interface could well be in promiscuous mode for some other + reason.) For now, this doesn't work on the "any" device; if an argument + of "any" or NULL is supplied, the promisc flag is ignored. + to_ms specifies the read timeout in milliseconds. The read timeout + is used to arrange that the read not necessarily return immediately + when a packet is seen, but that it wait for some amount of time to + allow more packets to arrive and to read multiple packets from the OS + kernel in one operation. Not all platforms support a read timeout; + on platforms that don't, the read timeout is ignored. A zero value + for to_ms, on platforms that support a read timeout, will cause a + read to wait forever to allow enough packets to arrive, with no timeout. + errbuf is used to return error or warning text. It will be set + to error text when pcap_open_live() fails and returns NULL. errbuf + may also be set to warning text when pcap_open_live() succeds; to + detect this case the caller should store a zero-length string in + errbuf before calling pcap_open_live() and display the warning to the + user if errbuf is no longer a zero-length string. + +\sa pcap_open_offline(), pcap_open_dead(), pcap_findalldevs(), pcap_close() +*/ +pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf); + + +/*! \brief Create a pcap_t structure without starting a capture. + + pcap_open_dead() is used for creating a pcap_t structure + to use when calling the other functions in libpcap. It is + typically used when just using libpcap for compiling BPF + code. + +\sa pcap_open_offline(), pcap_open_live(), pcap_findalldevs(), pcap_compile(), pcap_setfilter(), pcap_close() +*/ +pcap_t *pcap_open_dead(int linktype, int snaplen); + + +/*! \brief Open a savefile in the tcpdump/libpcap format to read packets. + + pcap_open_offline() is called to open a "savefile" for reading. + fname specifies the name of the file to open. The file has the same + format as those used by tcpdump(1) and tcpslice(1). The name "-" in + a synonym for stdin. Alternatively, you may call + pcap_fopen_offline() to read dumped data from an existing open stream + fp. Note that on Windows, that stream should be opened in binary + mode. errbuf is used to return error text and is only set when + pcap_open_offline() or pcap_fopen_offline() fails and returns NULL. + +\sa pcap_open_live(), pcap_dump_open(), pcap_findalldevs(), pcap_close() +*/ +pcap_t *pcap_open_offline(const char *fname, char *errbuf); + +/*! \brief Open a file to write packets. + + pcap_dump_open() is called to open a "savefile" for writing. The + name "-" in a synonym for stdout. NULL is returned on failure. p is + a pcap struct as returned by pcap_open_offline() or pcap_open_live(). + fname specifies the name of the file to open. Alternatively, you may + call pcap_dump_fopen() to write data to an existing open stream fp. + Note that on Windows, that stream should be opened in binary mode. + If NULL is returned, pcap_geterr() can be used to get the error text. + +\sa pcap_dump_close(), pcap_dump() +*/ +pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname); + +/*! \brief Switch between blocking and nonblocking mode. + + pcap_setnonblock() puts a capture descriptor, opened with + pcap_open_live(), into "non-blocking" mode, or takes it + out of "non-blocking" mode, depending on whether the + nonblock argument is non-zero or zero. It has no effect + on "savefiles". If there is an error, -1 is returned + and errbuf is filled in with an appropriate error message; + otherwise, 0 is returned. In "non-blocking" mode, an + attempt to read from the capture descriptor with pcap_dispatch() + will, if no packets are currently available to be + read, return 0 immediately rather than blocking waiting + for packets to arrive. pcap_loop() and pcap_next() will + not work in "non-blocking" mode. + +\sa pcap_getnonblock(), pcap_dispatch() +*/ +int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf); + + +/*! \brief Get the "non-blocking" state of an interface. + + pcap_getnonblock() returns the current "non-blocking" + state of the capture descriptor; it always returns 0 on + "savefiles". If there is an error, -1 is returned and + errbuf is filled in with an appropriate error message. + +\sa pcap_setnonblock() +*/ +int pcap_getnonblock(pcap_t *p, char *errbuf); + +/*! \brief Construct a list of network devices that can be + opened with pcap_open_live(). + + \note that there may be network devices that cannot be opened with + pcap_open_live() by the process calling pcap_findalldevs(), because, + for example, that process might not have sufficient privileges to open + them for capturing; if so, those devices will not appear on the list.) + alldevsp is set to point to the first element of the list; each element + of the list is of type \ref pcap_if_t, + + -1 is returned on failure, in which case errbuf is filled in with an + appropriate error message; 0 is returned on success. + +\sa struct pcap_if, pcap_freealldevs(), pcap_open_live(), pcap_lookupdev(), pcap_lookupnet() +*/ +int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf); + +/*! \brief Free an interface list returned by pcap_findalldevs(). + + pcap_freealldevs() is used to free a list allocated by pcap_findalldevs(). + +\sa pcap_findalldevs() +*/ +void pcap_freealldevs(pcap_if_t *alldevsp); + +/*! \brief Return the first valid device in the system. +\deprecated Use \ref pcap_findalldevs() or \ref pcap_findalldevs_ex() instead. + + pcap_lookupdev() returns a pointer to a network device + suitable for use with pcap_open_live() and pcap_lookupnet(). + If there is an error, NULL is returned and errbuf + is filled in with an appropriate error message. + +\sa pcap_findalldevs(), pcap_open_live() +*/ +char *pcap_lookupdev(char *errbuf); + + +/*! \brief Return the subnet and netmask of an interface. +\deprecated Use \ref pcap_findalldevs() or \ref pcap_findalldevs_ex() instead. + + pcap_lookupnet() is used to determine the network number + and mask associated with the network device device. Both + netp and maskp are bpf_u_int32 pointers. A return of -1 + indicates an error in which case errbuf is filled in with + an appropriate error message. + +\sa pcap_findalldevs() +*/ +int pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf); + +/*! \brief Collect a group of packets. + + pcap_dispatch() is used to collect and process packets. cnt specifies the maximum + number of packets to process before returning. This is not a minimum number; when + reading a live capture, only one bufferful of packets is read at a time, so fewer + than cnt packets may be processed. A cnt of -1 processes all the packets received + in one buffer when reading a live capture, or all the packets in the file when + reading a ``savefile''. callback specifies a routine to be called with three + arguments: a u_char pointer which is passed in from pcap_dispatch(), a const + struct \ref pcap_pkthdr pointer, + and a const u_char pointer to the first caplen (as given in the struct pcap_pkthdr + a pointer to which is passed to the callback routine) bytes of data from the packet + (which won't necessarily be the entire packet; to capture the entire packet, you + will have to provide a value for snaplen in your call to pcap_open_live() that is + sufficiently large to get all of the packet's data - a value of 65535 should be + sufficient on most if not all networks). + + The number of packets read is returned. 0 is returned if no packets were read from + a live capture (if, for example, they were discarded because they didn't pass the + packet filter, or if, on platforms that support a read timeout that starts before + any packets arrive, the timeout expires before any packets arrive, or if the file + descriptor for the capture device is in non-blocking mode and no packets were + available to be read) or if no more packets are available in a ``savefile.'' A return + of -1 indicates an error in which case pcap_perror() or pcap_geterr() may be used + to display the error text. A return of -2 indicates that the loop terminated due to + a call to pcap_breakloop() before any packets were processed. If your application + uses pcap_breakloop(), make sure that you explicitly check for -1 and -2, rather + than just checking for a return value < 0. + + \note when reading a live capture, pcap_dispatch() will not necessarily return when + the read times out; on some platforms, the read timeout isn't supported, and, on + other platforms, the timer doesn't start until at least one packet arrives. This + means that the read timeout should NOT be used in, for example, an interactive + application, to allow the packet capture loop to ``poll'' for user input periodically, + as there's no guarantee that pcap_dispatch() will return after the timeout expires. + +\sa pcap_loop(), pcap_next(), pcap_open_live(), pcap_open_offline(), pcap_handler +*/ +int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user); + + +/*! \brief Collect a group of packets. + + pcap_loop() is similar to pcap_dispatch() except it keeps reading packets until cnt + packets are processed or an error occurs. It does not return when live read timeouts + occur. Rather, specifying a non-zero read timeout to pcap_open_live() and then calling + pcap_dispatch() allows the reception and processing of any packets that arrive when + the timeout occurs. A negative cnt causes pcap_loop() to loop forever (or at least + until an error occurs). -1 is returned on an error; 0 is returned if cnt is exhausted; + -2 is returned if the loop terminated due to a call to pcap_breakloop() before any packets + were processed. If your application uses pcap_breakloop(), make sure that you explicitly + check for -1 and -2, rather than just checking for a return value < 0. + +\sa pcap_dispatch(), pcap_next(), pcap_open_live(), pcap_open_offline(), pcap_handler +*/ +int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user); + + +/*! \brief Return the next available packet. + + pcap_next() reads the next packet (by calling pcap_dispatch() with a cnt of 1) and returns + a u_char pointer to the data in that packet. (The pcap_pkthdr struct for that packet is not + supplied.) NULL is returned if an error occured, or if no packets were read from a live + capture (if, for example, they were discarded because they didn't pass the packet filter, + or if, on platforms that support a read timeout that starts before any packets arrive, the + timeout expires before any packets arrive, or if the file descriptor for the capture device + is in non-blocking mode and no packets were available to be read), or if no more packets are + available in a ``savefile.'' Unfortunately, there is no way to determine whether an error + occured or not. +\sa pcap_dispatch(), pcap_loop() +*/ + +u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h); + +/*! \brief Read a packet from an interface or from an offline capture. + +This function is used to retrieve the next available packet, bypassing the callback method traditionally +provided by libpcap. + +pcap_next_ex fills the pkt_header and pkt_data parameters (see pcap_handler()) with the pointers to the +header and to the data of the next captured packet. + +The return value can be: +- 1 if the packet has been read without problems +- 0 if the timeout set with pcap_open_live() has elapsed. In this case pkt_header and pkt_data don't point to a valid packet +- -1 if an error occurred +- -2 if EOF was reached reading from an offline capture + +\sa pcap_open_live(), pcap_loop(), pcap_dispatch(), pcap_handler() +*/ +int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, const u_char **pkt_data); + +/*! \brief set a flag that will force pcap_dispatch() or pcap_loop() to return rather than looping. + + They will return the number of packets that have been processed so far, or -2 if no packets have been processed so far. + This routine is safe to use inside a signal handler on UNIX or a console control handler on Windows, as it merely sets + a flag that is checked within the loop. + The flag is checked in loops reading packets from the OS - a signal by itself will not necessarily terminate those + loops - as well as in loops processing a set of packets returned by the OS. Note that if you are catching signals on + UNIX systems that support restarting system calls after a signal, and calling pcap_breakloop() in the signal handler, + you must specify, when catching those signals, that system calls should NOT be restarted by that signal. Otherwise, + if the signal interrupted a call reading packets in a live capture, when your signal handler returns after calling + pcap_breakloop(), the call will be restarted, and the loop will not terminate until more packets arrive and the call + completes. + \note pcap_next() will, on some platforms, loop reading packets from the OS; that loop will not necessarily be + terminated by a signal, so pcap_breakloop() should be used to terminate packet processing even if pcap_next() is + being used. + pcap_breakloop() does not guarantee that no further packets will be processed by pcap_dispatch() or pcap_loop() after + it is called; at most one more packet might be processed. + If -2 is returned from pcap_dispatch() or pcap_loop(), the flag is cleared, so a subsequent call will resume reading + packets. If a positive number is returned, the flag is not cleared, so a subsequent call will return -2 and clear + the flag. +*/ +void pcap_breakloop(pcap_t *); + +/*! \brief Send a raw packet. + +This function allows to send a raw packet to the network. p is the interface that +will be used to send the packet, buf contains the data of the packet to send (including the various +protocol headers), size is the dimension of the buffer pointed by buf, i.e. the size of the packet to send. +The MAC CRC doesn't need to be included, because it is transparently calculated and added by the network +interface driver. +The return value is 0 if the packet is succesfully sent, -1 otherwise. + +\sa pcap_open_live() +*/ +int pcap_sendpacket(pcap_t *p, u_char *buf, int size); + +/*! \brief Save a packet to disk. + + pcap_dump() outputs a packet to the "savefile" opened + with pcap_dump_open(). Note that its calling arguments + are suitable for use with pcap_dispatch() or pcap_loop(). + If called directly, the user parameter is of type + pcap_dumper_t as returned by pcap_dump_open(). + +\sa pcap_dump_open(), pcap_dump_close(), pcap_dispatch(), pcap_loop() +*/ +void pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp); + +/*! \brief Return the file position for a "savefile". + + pcap_dump_ftell() returns the current file position for the "savefile", representing the number of bytes written by + pcap_dump_open() and pcap_dump() . + -1 is returned on error. + +\sa pcap_dump_open(), pcap_dump() +*/ +long pcap_dump_ftell(pcap_dumper_t *); + +/*! \brief Compile a packet filter, converting an high level filtering expression +(see \ref language) in a program that can be interpreted by the kernel-level +filtering engine. + + pcap_compile() is used to compile the string str into a filter program. program + is a pointer to a bpf_program struct and is filled in by pcap_compile(). optimize + controls whether optimization on the resulting code is performed. netmask + specifies the IPv4 netmask of the network on which packets are being captured; + it is used only when checking for IPv4 broadcast addresses in the filter program. + If the netmask of the network on which packets are being captured isn't known to + the program, or if packets are being captured on the Linux "any" pseudo-interface + that can capture on more than one network, a value of 0 can be supplied; tests for + IPv4 broadcast addreses won't be done correctly, but all other tests in the filter + program will be OK. A return of -1 indicates an error in which case pcap_geterr() + may be used to display the error text. + +\sa pcap_open_live(), pcap_setfilter(), pcap_freecode(), pcap_snapshot() +*/ +int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask); + +/*!\brief Compile a packet filter without the need of opening an adapter. This function converts an high level filtering expression +(see \ref language) in a program that can be interpreted by the kernel-level filtering engine. + + pcap_compile_nopcap() is similar to pcap_compile() except + that instead of passing a pcap structure, one passes the + snaplen and linktype explicitly. It is intended to be + used for compiling filters for direct BPF usage, without + necessarily having called pcap_open(). A return of -1 + indicates an error; the error text is unavailable. + (pcap_compile_nopcap() is a wrapper around + pcap_open_dead(), pcap_compile(), and pcap_close(); the + latter three routines can be used directly in order to get + the error text for a compilation error.) + + Look at the \ref language section for details on the + str parameter. + +\sa pcap_open_live(), pcap_setfilter(), pcap_freecode(), pcap_snapshot() +*/ +int pcap_compile_nopcap(int snaplen_arg, int linktype_arg, struct bpf_program *program, char *buf, int optimize, bpf_u_int32 mask); + + +/*! \brief Associate a filter to a capture. + + pcap_setfilter() is used to specify a filter program. fp + is a pointer to a bpf_program struct, usually the result + of a call to pcap_compile(). -1 is returned on failure, + in which case pcap_geterr() may be used to display the + error text; 0 is returned on success. + +\sa pcap_compile(), pcap_compile_nopcap() +*/ +int pcap_setfilter(pcap_t *p, struct bpf_program *fp); + + +/*! \brief Free a filter. + + pcap_freecode() is used to free up allocated memory + pointed to by a bpf_program struct generated by pcap_compile() + when that BPF program is no longer needed, for + example after it has been made the filter program for a + pcap structure by a call to pcap_setfilter(). + +\sa pcap_compile(), pcap_compile_nopcap() +*/ +void pcap_freecode(struct bpf_program *fp); + +/*! \brief Return the link layer of an adapter. + +returns the link layer type; link layer types it can return include: + + - DLT_NULL BSD loopback encapsulation; the link layer header is a 4-byte field, in host byte order, containing a PF_ value from socket.h for the network-layer protocol of the packet. + Note that ``host byte order'' is the byte order of the machine on which the packets are captured, and the PF_ values are for the OS of the machine on which the packets are captured; if a live capture is being done, ``host byte order'' is the byte order of the machine capturing the packets, and the PF_ values are those of the OS of the machine capturing the packets, but if a ``savefile'' is being read, the byte order and PF_ values are not necessarily those of the machine reading the capture file. + - DLT_EN10MB Ethernet (10Mb, 100Mb, 1000Mb, and up) + - DLT_IEEE802: IEEE 802.5 Token Ring + - DLT_ARCNET: ARCNET + - DLT_SLIP: SLIP; the link layer header contains, in order: + -# a 1-byte flag, which is 0 for packets received by the machine and 1 for packets sent by the machine; + -# a 1-byte field, the upper 4 bits of which indicate the type of packet, as per RFC 1144: + - 0x40: an unmodified IP datagram (TYPE_IP); + - 0x70: an uncompressed-TCP IP datagram (UNCOMPRESSED_TCP), with that byte being the first byte of the raw IP header on the wire, containing the connection number in the protocol field; + - 0x80: a compressed-TCP IP datagram (COMPRESSED_TCP), with that byte being the first byte of the compressed TCP/IP datagram header; + -# for UNCOMPRESSED_TCP, the rest of the modified IP header, and for COMPRESSED_TCP, the compressed TCP/IP datagram header; + -# for a total of 16 bytes; the uncompressed IP datagram follows the header. + + - DLT_PPP: PPP; if the first 2 bytes are 0xff and 0x03, it's PPP in HDLC-like framing, with the PPP header following those two bytes, otherwise it's PPP without framing, and the packet begins with the PPP header. + - DLT_FDDI: FDDI + - DLT_ATM_RFC1483: RFC 1483 LLC/SNAP-encapsulated ATM; the packet begins with an IEEE 802.2 LLC header. + - DLT_RAW: raw IP; the packet begins with an IP header. + - DLT_PPP_SERIAL: PPP in HDLC-like framing, as per RFC 1662, or Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547; the first byte will be 0xFF for PPP in HDLC-like framing, and will be 0x0F or 0x8F for Cisco PPP with HDLC framing. + - DLT_PPP_ETHER: PPPoE; the packet begins with a PPPoE header, as per RFC 2516. + - DLT_C_HDLC: Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547. + - DLT_IEEE802_11: IEEE 802.11 wireless LAN + - DLT_FRELAY: Frame Relay + - DLT_LOOP: OpenBSD loopback encapsulation; the link layer header is a 4-byte field, in network byte order, containing a PF_ value from OpenBSD's socket.h for the network-layer protocol of the packet. + Note that, if a ``savefile'' is being read, those PF_ values are not necessarily those of the machine reading the capture file. + - DLT_LINUX_SLL: Linux "cooked" capture encapsulation; the link layer header contains, in order: + - a 2-byte "packet type", in network byte order, which is one of: + -# packet was sent to us by somebody else + -# packet was broadcast by somebody else + -# packet was multicast, but not broadcast, by somebody else + -# packet was sent by somebody else to somebody else + -# packet was sent by us + - a 2-byte field, in network byte order, containing a Linux ARPHRD_ value for the link layer device type; + - a 2-byte field, in network byte order, containing the length of the link layer address of the sender of the packet (which could be 0); + - an 8-byte field containing that number of bytes of the link layer header (if there are more than 8 bytes, only the first 8 are present); + - 2-byte field containing an Ethernet protocol type, in network byte order, or containing 1 for Novell 802.3 frames without an 802.2 LLC header or 4 for frames beginning with an 802.2 LLC header. + - DLT_LTALK: Apple LocalTalk; the packet begins with an AppleTalk LLAP header. + - DLT_PFLOG: OpenBSD pflog; the link layer header contains, in order: + - a 4-byte PF_ value, in network byte order; + - a 16-character interface name; + - a 2-byte rule number, in network byte order; + - a 2-byte reason code, in network byte order, which is one of: + -# match + -# bad offset + -# fragment + -# short + -# normalize + -# memory + -a 2-byte action code, in network byte order, which is one of: + -# passed + -# dropped + -# scrubbed + - a 2-byte direction, in network byte order, which is one of: + -# incoming or outgoing + -# incoming + -# outgoing + - DLT_PRISM_HEADER: Prism monitor mode information followed by an 802.11 header. + - DLT_IP_OVER_FC: RFC 2625 IP-over-Fibre Channel, with the link-layer header being the Network_Header as described in that RFC. + - DLT_SUNATM: SunATM devices; the link layer header contains, in order: + - a 1-byte flag field, containing a direction flag in the uppermost bit, which is set for packets transmitted by the machine and clear for packets received by the machine, and a 4-byte traffic type in the low-order 4 bits, which is one of: + -# raw traffic + -# LANE traffic + -# LLC-encapsulated traffic + -# MARS traffic + -# IFMP traffic + -# ILMI traffic + -# Q.2931 traffic + - a 1-byte VPI value; + - a 2-byte VCI field, in network byte order. + - DLT_IEEE802_11_RADIO: link-layer information followed by an 802.11 header - see http://www.shaftnet.org/~pizza/software/capturefrm.txt for a description of the link-layer information. + - DLT_ARCNET_LINUX: ARCNET, with no exception frames, reassembled packets rather than raw frames, and an extra 16-bit offset field between the destination host and type bytes. + - DLT_LINUX_IRDA: Linux-IrDA packets, with a DLT_LINUX_SLL header followed by the IrLAP header. + +\sa pcap_list_datalinks(), pcap_set_datalink(), pcap_datalink_name_to_val() +*/ +int pcap_datalink(pcap_t *p); + +/*! \brief list datalinks + + pcap_list_datalinks() is used to get a list of the supported data link types of the + interface associated with the pcap descriptor. pcap_list_datalinks() allocates an array + to hold the list and sets *dlt_buf. The caller is responsible for freeing the array. -1 + is returned on failure; otherwise, the number of data link types in the array is returned. + +\sa pcap_datalink(), pcap_set_datalink(), pcap_datalink_name_to_val() +*/ +int pcap_list_datalinks(pcap_t *p, int **dlt_buf); + +/*! \brief Set the current data link type of the pcap + descriptor to the type specified by dlt. -1 is returned on failure. */ +int pcap_set_datalink(pcap_t *p, int dlt); + +/*! \brief Translates a data link type name, which is a DLT_ name + with the DLT_ removed, to the corresponding data link type value. The translation is + case-insensitive. -1 is returned on failure. +*/ +int pcap_datalink_name_to_val(const char *name); + +/*! \brief Translates a data link type value to the corresponding data +link type name. NULL is returned on failure. +*/ +const char *pcap_datalink_val_to_name(int dlt); + +/*! \brief Translates a data link type value to a short +description of that data link type. NULL is returned on failure. +*/ +const char *pcap_datalink_val_to_description(int dlt); + + +/*! \brief Return the dimension of the packet portion (in bytes) that is delivered to the application. + + pcap_snapshot() returns the snapshot length specified when + pcap_open_live was called. + +\sa pcap_open_live(), pcap_compile(), pcap_compile_nopcap() +*/ +int pcap_snapshot(pcap_t *p); + + +/*! \brief returns true if the current savefile +uses a different byte order than the current system. +*/ +int pcap_is_swapped(pcap_t *p); + + +/*! \brief return the major version number of the pcap library used to write the savefile. + +\sa pcap_minor_version() +*/ +int pcap_major_version(pcap_t *p); + + +/*! \brief return the minor version number of the pcap library used to write the savefile. + +\sa pcap_major_version() +*/ +int pcap_minor_version(pcap_t *p); + +/*! \brief Return the standard stream of an offline capture. + + pcap_file() returns the standard I/O stream of the "savefile", + if a "savefile" was opened with + pcap_open_offline(), or NULL, if a network device was + opened with pcap_open_live(). + \deprecated Due to incompatibilities between the C Runtime (CRT) used to + compile WinPcap and the one used by WinPcap-based applications, this function + may return an invalid FILE pointer, i.e. a descriptor that causes all the standard I/O stream + functions (ftell, fseek, fclose...) to fail. The function is still available for + backwards binary compatibility, only. + +\sa pcap_open_offline(), pcap_open_live() +*/ +FILE *pcap_file(pcap_t *p); + +/*! \brief Return statistics on current capture. + + pcap_stats() returns 0 and fills in a pcap_stat struct. + The values represent packet statistics from the start of + the run to the time of the call. If there is an error or + the underlying packet capture doesn't support packet + statistics, -1 is returned and the error text can be + obtained with pcap_perror() or pcap_geterr(). + pcap_stats() is supported only on live captures, not on + "savefiles"; no statistics are stored in "savefiles", + so no statistics are available when reading from a "savefile". + +\sa pcap_stats_ex(), pcap_open_live() +*/ +int pcap_stats(pcap_t *p, struct pcap_stat *ps); + +/*! \brief print the text of the last pcap library error on stderr, prefixed by prefix. + +\sa pcap_geterr() +*/ +void pcap_perror(pcap_t *p, char *prefix); + + +/*! \brief return the error text pertaining to the + last pcap library error. + + \note the pointer Return will no longer point to a valid + error message string after the pcap_t passed to it is closed; + you must use or copy the string before closing the pcap_t. + +\sa pcap_perror() +*/ +char *pcap_geterr(pcap_t *p); + + +/*! \brief Provided in case strerror() isn't + available. + +\sa pcap_perror(), pcap_geterr() +*/ +char *pcap_strerror(int error); + +/*! \brief Returns a pointer to a string giving information about the + version of the libpcap library being used; note that it contains more information than + just a version number. +*/ +const char *pcap_lib_version(void); + +/*! \brief + close the files associated with p and deallocates resources. + +\sa pcap_open_live(), pcap_open_offline(), pcap_open_dead() +*/ +void pcap_close(pcap_t *p); + +/*! \brief return the standard I/O stream of the 'savefile' opened by pcap_dump_open(). */ +FILE *pcap_dump_file(pcap_dumper_t *p); + +/*! \brief Flushes the output buffer to the ``savefile,'' so that any + packets written with pcap_dump() but not yet written to the ``savefile'' will be + written. -1 is returned on error, 0 on success. +*/ +int pcap_dump_flush(pcap_dumper_t *p); + +/*! \brief Closes a savefile. + +\sa pcap_dump_open(), pcap_dump() +*/ +void pcap_dump_close(pcap_dumper_t *p); + +//\} +// End of Unix-compatible functions + + + + + + + +/** \name Windows-specific Extensions + + The functions in this section extend libpcap to offer advanced functionalities (like remote packet + capture, packet buffer size variation or high-precision packet injection). Howerver, at the moment + they can be used only in Windows. + */ +//\{ + +/*! \brief Returns the AirPcap handler associated with an adapter. This handler can be used to change + the wireless-related settings of the CACE Technologies AirPcap wireless capture adapters. + +\note THIS FUNCTION SHOULD BE CONSIDERED PROVISIONAL, AND MAY BE REPLACED IN THE FUTURE BY A MORE COMPLETE SET +OF FUNCTIONS FOR WIRELESS SUPPORT. + +pcap_get_airpcap_handle() allows to obtain the airpcap handle of an open adapter. This handle can be used with +the AirPcap API functions to perform wireless-releated operations, e.g. changing the channel or enabling +WEP decryption. For more details about the AirPcap wireless capture adapters, see +http://www.cacetech.com/products/airpcap.htm + +\param p: handle to an open libpcap adapter + +\return a pointer to an open AirPcap handle, used internally by the libpcap open adapter. NULL if the libpcap + adapter doesn't have wireless support through AirPcap. +*/ +PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p); + +/*! \brief Returns if a given filter applies to an offline packet. + +This function is used to apply a filter to a packet that is currently in memory. +This process does not need to open an adapter; we need just to create the proper filter (by settings +parameters like the snapshot length, or the link-layer type) by means of the pcap_compile_nopcap(). + +The current API of libpcap does not allow to receive a packet and to filter the packet after it has been +received. However, this can be useful in case you want to filter packets in the application, instead of into +the receiving process. This function allows you to do the job. + +\param prog: bpf program (created with the pcap_compile_nopcap() ) +\param header: header of the packet that has to be filtered +\param pkt_data: buffer containing the packet, in network-byte order. + +\return the length of the bytes that are currently available into the packet if the packet satisfies the filter, +0 otherwise. +*/ +bool pcap_offline_filter(struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data); + +/*! \brief Save a capture to file. + + \note: this function does not work in current version of WinPcap. + +pcap_live_dump() dumps the network traffic from an interface to +a file. Using this function the dump is performed at kernel level, therefore it is more efficient than using +pcap_dump(). + +The parameters of this function are an interface descriptor (obtained with pcap_open_live()), a string with +the name of the dump file, the maximum size of the file (in bytes) and the maximum number of packets that the file +will contain. Setting maxsize or maxpacks to 0 means no limit. When maxsize or maxpacks are reached, +the dump ends. + +pcap_live_dump() is non-blocking, threfore Return immediately. pcap_live_dump_ended() can be used to +check the status of the dump process or to wait until it is finished. pcap_close() can instead be used to +end the dump process. + +Note that when one of the two limits is reached, the dump is stopped, but the file remains opened. In order +to correctly flush the data and put the file in a consistent state, the adapter must be closed with +pcap_close(). + + +\sa pcap_live_dump_ended(), pcap_open_live(), pcap_close(), pcap_dump_open(), pcap_dump() +*/ +int pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks); + + +/*! \brief Return the status of the kernel dump process, i.e. tells if one of the limits defined with pcap_live_dump() has been reached. + + \note: this function does not work in current version of WinPcap. + +pcap_live_dump_ended() informs the user about the limits that were set with a previous call to +pcap_live_dump() on the interface pointed by p: if the return value is nonzero, one of the limits has been +reched and the dump process is currently stopped. + +If sync is nonzero, the function blocks until the dump is finished, otherwise Return immediately. + +\warning if the dump process has no limits (i.e. if the maxsize and maxpacks arguments of pcap_live_dump() +were both 0), the dump process will never stop, therefore setting sync to TRUE will block the application +on this call forever. + +\sa pcap_live_dump() +*/ +int pcap_live_dump_ended(pcap_t *p, int sync); + + +/*! \brief Return statistics on current capture. + +pcap_stats_ex() extends the pcap_stats() allowing to return more statistical parameters than the old call. +One of the advantages of this new call is that the pcap_stat structure is not allocated by the user; instead, +it is returned back by the system. This allow to extend the pcap_stat structure without affecting backward compatibility +on older applications. These will simply check at the values of the members at the beginning of the structure, +while only newest applications are able to read new statistical values, which are appended in tail. + +To be sure not to read a piece of mamory which has not been allocated by the system, the variable pcap_stat_size +will return back the size of the structure pcap_stat allocated by the system. + +\param p: pointer to the pcap_t currently in use. +\param pcap_stat_size: pointer to an integer that will contain (when the function returns back) the size of the +structure pcap_stat as it has been allocated by the system. + +\return: a pointer to a pcap_stat structure, that will contain the statistics related to the current device. +The return value is NULL in case of errors, and the error text can be obtained with pcap_perror() or pcap_geterr(). + +\warning pcap_stats_ex() is supported only on live captures, not on "savefiles"; no statistics are stored in +"savefiles", so no statistics are available when reading from a "savefile". + +\sa pcap_stats() +*/ +struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size); + +/*! \brief Set the size of the kernel buffer associated with an adapter. + +\e dim specifies the size of the buffer in bytes. +The return value is 0 when the call succeeds, -1 otherwise. If an old buffer was already created +with a previous call to pcap_setbuff(), it is deleted and its content is discarded. +pcap_open_live() creates a 1 MByte buffer by default. + +\sa pcap_open_live(), pcap_loop(), pcap_dispatch() +*/ +int pcap_setbuff(pcap_t *p, int dim); + + +/*! \brief Set the working mode of the interface p to mode. + +Valid values for mode are +MODE_CAPT (default capture mode) and MODE_STAT (statistical mode). See the tutorial "\ref wpcap_tut9" +for details about statistical mode. +*/ +int pcap_setmode(pcap_t *p, int mode); + + +/*! \brief Set the minumum amount of data received by the kernel in a single call. + +pcap_setmintocopy() changes the minimum amount of data in the kernel buffer that causes a read from +the application to return (unless the timeout expires). If the value of \e size is large, the kernel +is forced to wait the arrival of several packets before copying the data to the user. This guarantees +a low number of system calls, i.e. low processor usage, and is a good setting for applications like +packet-sniffers and protocol analyzers. Vice versa, in presence of a small value for this variable, +the kernel will copy the packets as soon as the application is ready to receive them. This is useful +for real time applications that need the best responsiveness from the kernel. + +\sa pcap_open_live(), pcap_loop(), pcap_dispatch() +*/ +int pcap_setmintocopy(pcap_t *p, int size); + + + +/*! \brief Return the handle of the event associated with the interface p. + + This event can be passed to functions like WaitForSingleObject() or WaitForMultipleObjects() to wait + until the driver's buffer contains some data without performing a read. + + We disourage the use of this function because it is not portable. + +\sa pcap_open_live() +*/ +HANDLE pcap_getevent(pcap_t *p); + +/*! \brief Allocate a send queue. + +This function allocates a send queue, i.e. a buffer containing a set of raw packets that will be transimtted +on the network with pcap_sendqueue_transmit(). + +memsize is the size, in bytes, of the queue, therefore it determines the maximum amount of data that the +queue will contain. + +Use pcap_sendqueue_queue() to insert packets in the queue. + +\sa pcap_sendqueue_queue(), pcap_sendqueue_transmit(), pcap_sendqueue_destroy() +*/ +pcap_send_queue* pcap_sendqueue_alloc(u_int memsize); + +/*! \brief Destroy a send queue. + +Deletes a send queue and frees all the memory associated with it. + +\sa pcap_sendqueue_alloc(), pcap_sendqueue_queue(), pcap_sendqueue_transmit() +*/ +void pcap_sendqueue_destroy(pcap_send_queue* queue); + +/*! \brief Add a packet to a send queue. + +pcap_sendqueue_queue() adds a packet at the end of the send queue pointed by the queue parameter. +pkt_header points to a pcap_pkthdr structure with the timestamp and the length of the packet, pkt_data +points to a buffer with the data of the packet. + +The pcap_pkthdr structure is the same used by WinPcap and libpcap to store the packets in a file, +therefore sending a capture file is straightforward. +'Raw packet' means that the sending application will have to include the protocol headers, since every packet +is sent to the network 'as is'. The CRC of the packets needs not to be calculated, because it will be +transparently added by the network interface. + +\sa pcap_sendqueue_alloc(), pcap_sendqueue_transmit(), pcap_sendqueue_destroy() +*/ +int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data); + + +/*! \brief Send a queue of raw packets to the network. + +This function transmits the content of a queue to the wire. p is a +pointer to the adapter on which the packets will be sent, queue points to a pcap_send_queue structure +containing the packets to send (see pcap_sendqueue_alloc() and pcap_sendqueue_queue()), sync determines if the +send operation must be synchronized: if it is non-zero, the packets are sent respecting the timestamps, +otherwise they are sent as fast as possible. + +The return value is the amount of bytes actually sent. If it is smaller than the size parameter, an +error occurred during the send. The error can be caused by a driver/adapter problem or by an inconsistent/bogus +send queue. + +\note Using this function is more efficient than issuing a series of pcap_sendpacket(), because the packets are +buffered in the kernel driver, so the number of context switches is reduced. Therefore, expect a better +throughput when using pcap_sendqueue_transmit. + +\note When Sync is set to TRUE, the packets are synchronized in the kernel with a high precision timestamp. +This requires a non-negligible amount of CPU, but allows normally to send the packets with a precision of some +microseconds (depending on the accuracy of the performance counter of the machine). Such a precision cannot +be reached sending the packets with pcap_sendpacket(). + +\sa pcap_sendqueue_alloc(), pcap_sendqueue_queue(), pcap_sendqueue_destroy() +*/ +u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync); + + +/*! \brief Create a list of network devices that can be opened with pcap_open(). + + This function is a superset of the old 'pcap_findalldevs()', which is obsolete, and which + allows listing only the devices present on the local machine. + Vice versa, pcap_findalldevs_ex() allows listing the devices present on a remote + machine as well. Additionally, it can list all the pcap files available into a given folder. + Moreover, pcap_findalldevs_ex() is platform independent, since it + relies on the standard pcap_findalldevs() to get addresses on the local machine. + + In case the function has to list the interfaces on a remote machine, it opens a new control + connection toward that machine, it retrieves the interfaces, and it drops the connection. + However, if this function detects that the remote machine is in 'active' mode, + the connection is not dropped and the existing socket is used. + + The 'source' is a parameter that tells the function where the lookup has to be done and + it uses the same syntax of the pcap_open(). + + Differently from the pcap_findalldevs(), the interface names (pointed by the alldevs->name + and the other ones in the linked list) are already ready to be used in the pcap_open() call. + Vice versa, the output that comes from pcap_findalldevs() must be formatted with the new + pcap_createsrcstr() before passing the source identifier to the pcap_open(). + + \param source: a char* buffer that keeps the 'source localtion', according to the new WinPcap + syntax. This source will be examined looking for adapters (local or remote) (e.g. source + can be 'rpcap://' for local adapters or 'rpcap://host:port' for adapters on a remote host) + or pcap files (e.g. source can be 'file://c:/myfolder/').
+ The strings that must be prepended to the 'source' in order to define if we want + local/remote adapters or files is defined in the new \link remote_source_string Source + Specification Syntax \endlink. + + \param auth: a pointer to a pcap_rmtauth structure. This pointer keeps the information + required to authenticate the RPCAP connection to the remote host. + This parameter is not meaningful in case of a query to the local host: in that case + it can be NULL. + + \param alldevs: a 'struct pcap_if_t' pointer, which will be properly allocated inside + this function. When the function returns, it is set to point to the first element + of the interface list; each element of the list is of type 'struct pcap_if_t'. + + \param errbuf: a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) + that will contain the error message (in case there is one). + + \return '0' if everything is fine, '-1' if some errors occurred. The list of the devices + is returned in the 'alldevs' variable. + When the function returns correctly, 'alldevs' cannot be NULL. In other words, this + function returns '-1' also in case the system does not have any interface to list. + + The error message is returned in the 'errbuf' variable. An error could be due to + several reasons: + - libpcap/WinPcap was not installed on the local/remote host + - the user does not have enough privileges to list the devices / files + - a network problem + - the RPCAP version negotiation failed + - other errors (not enough memory and others). + + \warning There may be network devices that cannot be opened with pcap_open() by the process + calling pcap_findalldevs(), because, for example, that process might not have + sufficient privileges to open them for capturing; if so, those devices will not + appear on the list. + + \warning The interface list must be deallocated manually by using the pcap_freealldevs(). +*/ +int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf); + + +/*! \brief Accept a set of strings (host name, port, ...), and it returns the complete + source string according to the new format (e.g. 'rpcap://1.2.3.4/eth0'). + + This function is provided in order to help the user creating the source string + according to the new format. + An unique source string is used in order to make easy for old applications to use the + remote facilities. Think about tcpdump, for example, which has only one way to specify + the interface on which the capture has to be started. + However, GUI-based programs can find more useful to specify hostname, port and + interface name separately. In that case, they can use this function to create the + source string before passing it to the pcap_open() function. + + \param source: a user-allocated buffer that will contain the complete source string + wen the function returns.
+ The source will start with an identifier according to the new \link remote_source_string + Source Specification Syntax \endlink.
+ This function assumes that the allocated buffer is at least PCAP_BUF_SIZE bytes. + + \param type: its value tells the type of the source we want to create. It can assume + the values defined in the \link remote_source_ID Source identification + Codes \endlink.
+ + \param host: an user-allocated buffer that keeps the host (e.g. "foo.bar.com") we + want to connect to. + It can be NULL in case we want to open an interface on a local host. + + \param port: an user-allocated buffer that keeps the network port (e.g. "2002") we + want to use for the RPCAP protocol. + It can be NULL in case we want to open an interface on a local host. + + \param name: an user-allocated buffer that keeps the interface name we want to use + (e.g. "eth0"). + It can be NULL in case the return string (i.e. 'source') has to be used with the + pcap_findalldevs_ex(), which does not require the interface name. + + \param errbuf: a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) + that will contain the error message (in case there is one). + + \return '0' if everything is fine, '-1' if some errors occurred. The string containing + the complete source is returned in the 'source' variable. + + \warning If the source is longer than PCAP_BUF_SIZE, the excess characters are truncated. +*/ +int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf); + + +/*! \brief Parse the source string and returns the pieces in which the source can be split. + + This call is the other way round of pcap_createsrcstr(). + It accepts a null-terminated string and it returns the parameters related + to the source. This includes: + - the type of the source (file, winpcap on a remote adapter, winpcap on local adapter), + which is determined by the source prefix (PCAP_SRC_IF_STRING and so on) + - the host on which the capture has to be started (only for remote captures) + - the 'raw' name of the source (file name, name of the remote adapter, name + of the local adapter), without the source prefix. The string returned does not + include the type of the source itself (i.e. the string returned does not include "file://" + or rpcap:// or such). + + The user can omit some parameters in case it is not interested in them. + + \param source: a null-terminated string containing the WinPcap source. This source starts + with an identifier according to the new \link remote_source_string Source Specification Syntax + \endlink. + + \param type: pointer to an integer, which is used to return the code corrisponding to the + selected source. The code will be one defined in the \link remote_source_ID Source identification + Codes \endlink.
+ In case the source string does not exists (i.e. 'source == NULL') or it is empty + ('*source == NULL'), it returns PCAP_SRC_IF_LOCAL (i.e. you are ready to + call pcap_open_live() ). This behavior is kept only for compatibility with older + applications (e.g. tcpdump); therefore we suggest to move to the new syntax for sources.
+ This parameter can be NULL in case the user is not interested in that. + + \param host: user-allocated buffer (of size PCAP_BUF_SIZE) that is used to return + the host name on which the capture has to be started. + This value is meaningful only in case of remote capture; otherwise, the returned + string will be empty (""). + This parameter can be NULL in case the user is not interested in that. + + \param port: user-allocated buffer (of size PCAP_BUF_SIZE) that is used to return + the port that has to be used by the RPCAP protocol to contact the other host. + This value is meaningful only in case of remote capture and if the user wants to use + a non-standard port; otherwise, the returned string will be empty (""). + In case of remote capture, an emply string means "use the standard RPCAP port". + This parameter can be NULL in case the user is not interested in that. + + \param name: user-allocated buffer (of size PCAP_BUF_SIZE) that is used to return + the source name, without the source prefix. + If the name does not exist (for example because source contains 'rpcap://' that means + 'default local adapter'), it returns NULL. + This parameter can be NULL in case the user is not interested in that. + + \param errbuf: pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) + that will contain the error message (in case there is one). + This parameter can be NULL in case the user is not interested in that. + + \return '0' if everything is fine, '-1' if some errors occurred. The requested values + (host name, network port, type of the source) are returned into the proper variables + passed by reference. +*/ +int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf); + +/*! \brief Open a generic source in order to capture / send (WinPcap only) traffic. + + The pcap_open() replaces all the pcap_open_xxx() functions with a single call. + + This function hides the differences between the different pcap_open_xxx() functions + so that the programmer does not have to manage different opening function. + In this way, the 'true' open function is decided according to the source type, + which is included into the source string (in the form of source prefix). + + This function can rely on the pcap_createsrcstr() to create the string that keeps + the capture device according to the new syntax, and the pcap_parsesrcstr() for the + other way round. + + \param source: zero-terminated string containing the source name to open. + The source name has to include the format prefix according to the new + \link remote_source_string Source Specification Syntax\endlink and it cannot be NULL.
+ On on Linux systems with 2.2 or later kernels, a device argument of "any" + (i.e. rpcap://any) can be used to capture packets from all interfaces. +
+ In order to makes the source syntax easier, please remember that: + - the adapters returned by the pcap_findalldevs_ex() can be used immediately by the pcap_open() + - in case the user wants to pass its own source string to the pcap_open(), the + pcap_createsrcstr() helps in creating the correct source identifier. + + \param snaplen: length of the packet that has to be retained. + For each packet received by the filter, only the first 'snaplen' bytes are stored + in the buffer and passed to the user application. For instance, snaplen equal to + 100 means that only the first 100 bytes of each packet are stored. + + \param flags: keeps several flags that can be needed for capturing packets. + The allowed flags are defined in the \link remote_open_flags pcap_open() flags \endlink. + + \param read_timeout: read timeout in milliseconds. + The read timeout is used to arrange that the read not necessarily return + immediately when a packet is seen, but that it waits for some amount of + time to allow more packets to arrive and to read multiple packets from + the OS kernel in one operation. Not all platforms support a read timeout; + on platforms that don't, the read timeout is ignored. + + \param auth: a pointer to a 'struct pcap_rmtauth' that keeps the information required to + authenticate the user on a remote machine. In case this is not a remote capture, this + pointer can be set to NULL. + + \param errbuf: a pointer to a user-allocated buffer which will contain the error + in case this function fails. The pcap_open() and findalldevs() are the only two + functions which have this parameter, since they do not have (yet) a pointer to a + pcap_t structure, which reserves space for the error string. Since these functions + do not have (yet) a pcap_t pointer (the pcap_t pointer is NULL in case of errors), + they need an explicit 'errbuf' variable. + 'errbuf' may also be set to warning text when pcap_open_live() succeds; + to detect this case the caller should store a zero-length string in + 'errbuf' before calling pcap_open_live() and display the warning to the user + if 'errbuf' is no longer a zero-length string. + + \return A pointer to a 'pcap_t' which can be used as a parameter to the following + calls (pcap_compile() and so on) and that specifies an opened WinPcap session. In case of + problems, it returns NULL and the 'errbuf' variable keeps the error message. + + \warning The source cannot be larger than PCAP_BUF_SIZE. + + \warning The following formats are not allowed as 'source' strings: + - rpcap:// [to open the first local adapter] + - rpcap://hostname/ [to open the first remote adapter] + +*/ +pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf); + +/*! \brief Define a sampling method for packet capture. + + This function allows applying a sampling method to the packet capture process. + The currently sampling methods (and the way to set them) are described into the + struct pcap_samp. In other words, the user must set the appropriate parameters + into it; these will be applied as soon as the capture starts. + + \warning Sampling parameters cannot be changed when a capture is + active. These parameters must be applied before starting the capture. + If they are applied when the capture is in progress, the new settings are ignored. + + \warning Sampling works only when capturing data on Win32 or reading from a file. + It has not been implemented on other platforms. Sampling works on remote machines + provided that the probe (i.e. the capturing device) is a Win32 workstation. +*/ +struct pcap_samp *pcap_setsampling(pcap_t *p); + +/*! \brief Block until a network connection is accepted (active mode only). + + This function has been defined to allow the client dealing with the 'active mode'. + In other words, in the 'active mode' the server opens the connection toward the + client, so that the client has to open a socket in order to wait for connections. + When a new connection is accepted, the RPCAP protocol starts as usual; the only + difference is that the connection is initiated by the server. + + This function accepts only ONE connection, then it closes the waiting socket. This means + that if some error occurs, the application has to call it again in order to accept another + connection. + + This function returns when a new connection (coming from a valid host 'connectinghost') + is accepted; it returns error otherwise. + + \param address: a string that keeps the network address we have to bind to; + usually it is NULL (it means 'bind on all local addresses'). + + \param port: a string that keeps the network port on which we have to bind to; usually + it is NULL (it means 'bind on the predefined port', i.e. RPCAP_DEFAULT_NETPORT_ACTIVE). + + \param hostlist: a string that keeps the host name of the host from whom we are + expecting a connection; it can be NULL (it means 'accept connection from everyone'). + Host names are separated by a whatever character in the RPCAP_HOSTLIST_SEP list. + + \param connectinghost: a user-allocated buffer that will contain the name of the host + is trying to connect to us. + This variable must be at least RPCAP_HOSTLIST_SIZE bytes.. + + \param auth: a pointer to a pcap_rmtauth structure. This pointer keeps the information + required to authenticate the RPCAP connection to the remote host. + + \param errbuf: a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) + that will contain the error message (in case there is one). + + \return The SOCKET identifier of the new control connection if everything is fine, + a negative number if some errors occurred. The error message is returned into the errbuf variable. + In case it returns '-1', this means 'everything is fine', but the host cannot be admitted. + In case it returns '-2', in means 'unrecoverable error' (for example it is not able to bind the + socket, or something like that). + In case it returns '-3', it means 'authentication failed'. The authentication check is performed + only if the connecting host is among the ones that are allowed to connect to this host. + + The host that is connecting to us is returned into the hostlist variable, which ust be allocated + by the user. This variable contains the host name both in case the host is allowed, + and in case the connection is refused. + + \warning Although this function returns the socket established by the new control connection, + this value should not be used. This value will be stored into some libpcap internal + variables and it will be managed automatically by the library. In other words, all the + following calls to findalldevs() and pcap_open() will check if the host is among one that + already has a control connection in place; if so, that one will be used. + + \warning This function has several problems if used inside a thread, which is stopped + when this call is blocked into the accept(). In this case, the socket on which we accept + connections is not freed (thread termination is a very dirty job), so that we are no + longer able to accept other connections until the program (i.e. the process) stops. + In order to solve the problem, call the pcap_remoteact_cleanup(). +*/ +SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf); + +/*! \brief Drop an active connection (active mode only). + + This function has been defined to allow the client dealing with the 'active mode'. + This function closes an active connection that is still in place and it purges + the host name from the 'activeHost' list. + From this point on, the client will not have any connection with that host in place. + + \param host: a string that keeps the host name of the host for which we want to + close the active connection. + + \param errbuf: a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) + that will contain the error message (in case there is one). + + \return '0' if everything is fine, '-1' if some errors occurred. The error message is + returned into the errbuf variable. +*/ +int pcap_remoteact_close(const char *host, char *errbuf); + +/*! \brief Clean the socket that is currently used in waiting active connections. + + This function does a very dirty job. The fact is that is the waiting socket is not + freed if the pcap_remoteaccept() is killed inside a new thread. This function is + able to clean the socket in order to allow the next calls to pcap_remoteact_accept() to work. + + This function is useful *only* if you launch pcap_remoteact_accept() inside a new thread, + and you stops (not very gracefully) the thread (for example because the user changed idea, + and it does no longer want to wait for an active connection). + So, basically, the flow should be the following: + - launch a new thread + - call the pcap_remoteact_accept + - if this new thread is killed, call pcap_remoteact_cleanup(). + + This function has no effects in other cases. + + \return None. +*/ +void pcap_remoteact_cleanup(); + +/*! \brief Return the hostname of the host that have an active connection with us (active mode only). + + This function has been defined to allow the client dealing with the 'active mode'. + This function returns the list of hosts that are currently having an active connection + with us. This function is useful in order to delete an active connection that is still + in place. + + \param hostlist: a user-allocated string that will keep the list of host that are + currently connected with us. + + \param sep: the character that has to be sued as a separator between the hosts (',' for example). + + \param size: size of the hostlist buffer. + + \param errbuf: a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) + that will contain the error message (in case there is one). + + \return '0' if everything is fine, '-1' if some errors occurred. The error message is + returned into the errbuf variable. +*/ +int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf); + +//\} +// End of Windows-specific extensions + + + +/*@}*/ \ No newline at end of file diff --git a/winpcap/dox/libpcap/incs/pcap.h b/winpcap/dox/libpcap/incs/pcap.h new file mode 100644 index 0000000..db76405 --- /dev/null +++ b/winpcap/dox/libpcap/incs/pcap.h @@ -0,0 +1,185 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#) $Header: /usr/cvsroot_private/winpcap/dox/libpcap/incs/pcap.h,v 1.5 2005/11/30 21:48:23 gianlucav Exp $ (LBL) + */ + + +/** @defgroup wpcap_def Definitions + * @ingroup wpcap + * Definitions for wpcap.dll + * @{ + */ + +#ifndef lib_pcap_h +#define lib_pcap_h + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PCAP_VERSION_MAJOR 2 ///< Major libpcap dump file version. +#define PCAP_VERSION_MINOR 4 ///< Minor libpcap dump file version. + +#define PCAP_ERRBUF_SIZE 256 ///< Size to use when allocating the buffer that contains the libpcap errors. + +/*! + * Compatibility for systems that have a bpf.h that + * predates the bpf typedefs for 64-bit support. + */ +#if BPF_RELEASE - 0 < 199406 +typedef int bpf_int32; ///< 32-bit integer +typedef u_int bpf_u_int32; ///< 32-bit unsigned integer +#endif + +typedef struct pcap pcap_t; ///< Descriptor of an open capture instance. This structure is \b opaque to the user, that handles its content through the functions provided by wpcap.dll. +typedef struct pcap_dumper pcap_dumper_t; ///< libpcap savefile descriptor. +typedef struct pcap_if pcap_if_t; ///< Item in a list of interfaces, see pcap_if +typedef struct pcap_addr pcap_addr_t; ///< Representation of an interface address, see pcap_addr + +/*! \brief Header of a libpcap dump file. + * + * The first record in the file contains saved values for some + * of the flags used in the printout phases of tcpdump. + * Many fields here are 32 bit ints so compilers won't insert unwanted + * padding; these files need to be interchangeable across architectures. + * + * Do not change the layout of this structure, in any way (this includes + * changes that only affect the length of fields in this structure). + * + * Also, do not change the interpretation of any of the members of this + * structure, in any way (this includes using values other than + * LINKTYPE_ values, as defined in "savefile.c", in the "linktype" + * field). + * + * Instead: + * + * introduce a new structure for the new format, if the layout + * of the structure changed; + * + * send mail to "tcpdump-workers@tcpdump.org", requesting a new + * magic number for your new capture file format, and, when + * you get the new magic number, put it in "savefile.c"; + * + * use that magic number for save files with the changed file + * header; + * + * make the code in "savefile.c" capable of reading files with + * the old file header as well as files with the new file header + * (using the magic number to determine the header format). + * + * Then supply the changes to "patches@tcpdump.org", so that future + * versions of libpcap and programs that use it (such as tcpdump) will + * be able to read your new capture file format. + */ +struct pcap_file_header { + bpf_u_int32 magic; + u_short version_major; ///< Libpcap major version. + u_short version_minor; ///< Libpcap minor version. + bpf_int32 thiszone; ///< gmt to local correction + bpf_u_int32 sigfigs; ///< accuracy of timestamps + bpf_u_int32 snaplen; ///< max length saved portion of each pkt + bpf_u_int32 linktype; ///< data link type (LINKTYPE_*) +}; + +/*! \brief Header of a packet in the dump file. + * + * Each packet in the dump file is prepended with this generic header. + * This gets around the problem of different headers for different + * packet interfaces. + */ +struct pcap_pkthdr { + struct timeval ts; ///< time stamp + bpf_u_int32 caplen; ///< length of portion present + bpf_u_int32 len; ///< length this packet (off wire) +}; + +/*! \brief Structure that keeps statistical values on an interface. + * + * As returned by the pcap_stats() + */ +struct pcap_stat { + u_int ps_recv; ///< number of packets transited on the network + u_int ps_drop; ///< number of packets dropped by the driver + u_int ps_ifdrop; ///< drops by interface, not yet supported +#ifdef WIN32 + u_int bs_capt; ///< Win32 specific. number of packets captured, i.e number of packets that are accepted by the filter, that find place in the kernel buffer and therefore that actually reach the application. For backward compatibility, pcap_stats() does not fill this member, so use pcap_stats_ex() to get it. +#endif /* WIN32 */ +}; + +/*! \brief + * Item in a list of interfaces, used by pcap_findalldevs(). + */ +struct pcap_if { + struct pcap_if *next; ///< if not NULL, a pointer to the next element in the list; NULL for the last element of the list + char *name; ///< a pointer to a string giving a name for the device to pass to pcap_open_live() + char *description; ///< if not NULL, a pointer to a string giving a human-readable description of the device + struct pcap_addr *addresses; ///< a pointer to the first element of a list of addresses for the interface + u_int flags; ///< PCAP_IF_ interface flags. Currently the only possible flag is \b PCAP_IF_LOOPBACK, that is set if the interface is a loopback interface. +}; + +#define PCAP_IF_LOOPBACK 0x00000001 ///< interface is loopback + +/*! \brief + * Representation of an interface address, used by pcap_findalldevs(). + */ +struct pcap_addr { + struct pcap_addr *next; ///< if not NULL, a pointer to the next element in the list; NULL for the last element of the list + struct sockaddr *addr; ///< a pointer to a struct sockaddr containing an address + struct sockaddr *netmask; ///< if not NULL, a pointer to a struct sockaddr that contains the netmask corresponding to the address pointed to by addr. + struct sockaddr *broadaddr; ///< if not NULL, a pointer to a struct sockaddr that contains the broadcast address corre­ sponding to the address pointed to by addr; may be null if the interface doesn't support broadcasts + struct sockaddr *dstaddr; ///< if not NULL, a pointer to a struct sockaddr that contains the destination address corre­ sponding to the address pointed to by addr; may be null if the interface isn't a point- to-point interface +}; + +#if defined(WIN32) + + +#define MODE_CAPT 0 ///< Capture mode, to be used when calling pcap_setmode() +#define MODE_STAT 1 ///< Statistical mode, to be used when calling pcap_setmode() + +#endif /* WIN32 */ + +#ifdef __cplusplus +} +#endif + +#endif + +/** + * @} + */ diff --git a/winpcap/dox/main.txt b/winpcap/dox/main.txt new file mode 100644 index 0000000..c12555d --- /dev/null +++ b/winpcap/dox/main.txt @@ -0,0 +1,51 @@ +/*! + +\mainpage WinPcap Documentation + +\image html winpcap.gif + +\htmlonly + +

+
Authors:
+
The WinPcap Team
+
Home page:
+
http://www.winpcap.org
+
+
+ +

Modules

+ +\endhtmlonly + +- \ref wpcap + - \ref wpcap_def + - \ref wpcapfunc + - \ref language + - \ref wpcapsamps + - \ref wpcap_tut + - \ref wpcap_tut1 + - \ref wpcap_tut2 + - \ref wpcap_tut3 + - \ref wpcap_tut4 + - \ref wpcap_tut5 + - \ref wpcap_tut6 + - \ref wpcap_tut7 + - \ref wpcap_tut8 + - \ref wpcap_tut9 +- \ref internals + - \ref NPF + - \ref NPF_include + - \ref NPF_code + - \ref packetapi + - \ref compilation +- \ref remote + - \ref remote_struct + - Exported Functions. For a reference of the functions that support remote capture, see the "Windows-specific Extensions" in the WinPcap \ref wpcapfunc section. + - \ref remote_pri_struct + +\htmlinclude intro.htm + + +*/ + diff --git a/winpcap/dox/main_packetdll.txt b/winpcap/dox/main_packetdll.txt new file mode 100644 index 0000000..82c6dd0 --- /dev/null +++ b/winpcap/dox/main_packetdll.txt @@ -0,0 +1,55 @@ +/*! + +\mainpage WinPcap Documentation + +\image html winpcap.gif + +\htmlonly + +
+
Authors:
+
The WinPcap Team
+
Home page:
+
http://www.winpcap.org
+
+
+ +

Modules

+ +\endhtmlonly + +- \ref wpcap + - \ref wpcap_def + - \ref wpcapfunc + - \ref language + - \ref wpcapsamps + - \ref wpcap_tut + - \ref wpcap_tut1 + - \ref wpcap_tut2 + - \ref wpcap_tut3 + - \ref wpcap_tut4 + - \ref wpcap_tut5 + - \ref wpcap_tut6 + - \ref wpcap_tut7 + - \ref wpcap_tut8 + - \ref wpcap_tut9 +- \ref internals + - \ref NPF + - \ref NPF_include + - \ref NPF_code + - \ref packetapi + - \ref packet32h + - \ref packet32 + - \ref packetsamps + - \ref compilation +- \ref remote + - \ref remote_struct + - \ref remotefunc + - \ref remote_pri_struct + - \ref remote_pri_struct + +\htmlinclude intro.htm + + +*/ + diff --git a/winpcap/dox/note.txt b/winpcap/dox/note.txt new file mode 100644 index 0000000..c01212f --- /dev/null +++ b/winpcap/dox/note.txt @@ -0,0 +1,27 @@ +per far linkare correttamente gli esempi di libpcap: + - editare il file funcs\pcap.h + - cambiare il blocco a inizio file: + /** @defgroup wpcapfunc Exported functions + * @ingroup wpcap + * Functions exported by wpcap.dll + * @{ + */ + + in + + /** @ingroup wpcapfunc + * @{ + */ + - generare la documentazione + - salvare il file "funcs_2pcap_8h.html" + - rimettere tutto a posto + - rigenerare la documentazione + - sovrascrivere il file salvato su quello nuovo + +per far si' che gli esempi puntino al manuale in maniera corretta: + - generare la documentazione winpcap_noc.dox + - backuppare i vari group__wpcap__tutXXX.html, pcap__filter_8c-source.html, Pktdump_8c-source.html, group__wpcapsampsXXX.html + - generare la documentazione winpcap_c.dox + - copiare i file backuppati sui nuovi + +l'immagine nella pagina principale e' da mettere: al centro \ No newline at end of file diff --git a/winpcap/dox/npf-dump.gif b/winpcap/dox/npf-dump.gif new file mode 100644 index 0000000000000000000000000000000000000000..c24189c9a6b26ea52c99ec43c3de5dd91112f341 GIT binary patch literal 4656 zcwX(+bz2h*!v*lENDLE^29b~wxltrX>ensV~iR#YRpM9nvJoI5R@B` zRvJXfQHrRDFls#a^L~u?dVYVMFL2IvboF(VRi0;_YX=+v{tw(1Fp9N>V_i4;uy8mQ zYl|H{>)SXx0|3rON6$9?P1v)uzO(=NpZ|C6{$B6 zF|o>+1rP@m1d;G#WqLW%4uhoXiQ-3P2)F9ynyFfF^8!t(rB)B%_)p5IDtY^HjqOB@ z!_Yp!x;c;~F5O^e`*WMa82QT(MQ)e^eZO$|+3dzrxAdPQhheacbC20oE!?xbU{G)R z17GstEDq#MU%vJh`9`90)gai#E=Fyh|EchPw)P_-7Fh*ac>IqL-w)EA zK9N5^+GWc*{nhDT+$S$K=df`o!5w}1@Q*!|g>`K_?uq(rHsp#Tc-iE#5%@WRpV)FM z?mRE+xHFUHO_5lZ^X@KiDRRFESVl8ZBqoF~D}wZtDkwp4*v^(g)JB@yZmTm!kKCG<%}P8# zr~ka{jzgQYZHnW{mU+cr7)hr{#>eY;)HD$l#rAZ=7#i^q*Bi>F1SzSifDBXqV6|2&~SuW5AgdS0tx1{EWI z&@}J^TXjQSiWP08^E;d zWJ#wLus9wLq5{58t-3tL9d1SibWX38=lCD3bc8eR_sEyvVC$8&;>X+Q_MWyE#Y&&s ztxH#p+Sj@>I#nkdbeYwjQ4H>JUicvD2)7*(Wkl>H-C7LaeRPV;f0lUFU40R7>4O!0 zmfexD@NHvMWne*zKiZ;{vKY0rUlg#|E}Lk~SU&s*yTA1Q&5rC3afa*S83V$(?{F3N zy+{Z;85YB&84wG6A_8iXL>XZMeat+Q<#6AZGY$|b!tR>yWmH>TcHO2iuB2Cg&Uo;v!ytKi4GR(AM1POM%175t z)m5P`ukNlE`J~X=GKb)cO*(NtP6leG$tSeNyIV5mSprr<@2Hx*SLBl;M9T~%S+&$* z!I?g8&Re1R@=uw+n=gLNYpGn9jqw|BoWh8AQLS)C$pPtJ=;a%)`T?fX3DKuoD{Lyr zL3iTM%sOq1410DA6KgqUhE#c>snyW$UV?Uhc17-b;*ia_WM14#MOd8m-vhi8(o?SJQ3@r(WPnf|D-`k0kL zER|`x9>&v-P~8g^8gW!;<{JB8xaZhb=T*&m^dapEXT_Uw8%-@$W5hVA@~VTKz7s_B z+4<0Xt6^)E2RFq*%->M?g#(5UDftyEp%2H=Ws}U>y#;3JcbNNYtSEz14X{78wrlL* z_aLh#6lbYf7}f-0BSB_ne-apP@p)l#khJqrOz$b%=S&srHl5tpkkjFFQ{yF_HSUnm zAm2L|j&D^G648kCNvDfFU^MNIn5UMto4A2lyVbOMd_{(bQqj$xzNZAM(-*F6@$!wl zi6meVV_V5G6=zUw-UM?PVt;N&Xgi-r7MK1F~5&)py(rw zQH3scd@8|sjTYKdf|rwBE;sdJrJTQRZ(}+P@;0E?Anv9B=|Ya5PmyX(!_v?~_p^d- zX6B$oR|Q9wMYE3VgyE#8C->Q#3#??Kf)4EOx(f7C`(BsGqvR@G`xc<@g&FdhV-u^l z%clBYO5M-?)=C2^wGL=T5rfco*T%J52N%ol=c$LR$?6&mIpUt>|5GP*e+D}2f$(Nv z;xDb!O2S9F>iwJ-UU;Zpm@EDyc-?n?TUG4`6)%>RcW|=puK7B=9V}w`mML$D69Vbb zM>M-1-tCGynz817V`cgvZQ~Hc*N8^QCvTIsbdP1;^1R7@C35O5LQ%Dyg;mFROBv~n zsuD_YJ`G)a=4mc4*GFqVHCZ2TyYL^+_8Yx4$sXDEP&=Och$53RF6UnaAAg!1C6g(F zXg~Pz{L&Q)^}XTFi&O;YOh7W`fv;VD4-v#vbsX%teB8gW<5DZJab;WzHsenU23cgXkNZw&wG=4oduIG7QF zJ3HAj$$);$|2q`JEw}~#&;~#YaaA6F-ZH(~K6~@8Ffr@Mb?cdiT$6v4y z?=<$?jytw>G}MMC8urN(^WP(@{+&t@$g7DjJ4jEJzO2!Mx2tOFyD#CL;*SE}vd4VS z@9J3lt`4o{?4;@GcWj!X4sL%Fq@_bn7H>Bm4ti?rHbEl4u6;SgM+oid@V?oRaD)lJ zW~??_pMGf%;qfItq+jXOW z#c|TgFyVd|7`L&4dt9t%jJhdQfyWHN5+o-Hlb3XPuxa7y7Vnc3FI^I^4OW#oh-cY| zV`hmA<4zD(OfcX9>EOfk3OGQ}M7S%!kQ!)0k2hisv(S5PwVBAAnP@{vlpIU+nN85X zo*1f!FsDNI$?-xhh!@CEe<(*FG|?F!>^>V8rkuoZg&=@=h`8CLC}bRKRnp~$NGWTi zD{DLy9FXm$H_QZz`zHwn4vF^Sh()T*tR`b_ATC)av05V^RU!A>6T94$wZzm*yh6*s z98=|ioAD`#e=kjWikfbcEIuZ=AbHQ@iQisow_7SjFQiqEV~Ui@Qk4c^N*iyEF=k2K z5>HL+d8`ww&5hPBrl$#Wr;Ey`Pk04ROFmnhc-*yzx?Y~%h)nxEjjBY0V6@~Zv4B%a zz!^^_+fv2_w#?;F|Y`MbBYvEZ(p*ft%If`?Jyf%h|Olc!DR1Z`3 z?P};fNI;wz`iKWr;fi{Ygc2FcVJimc7iOFj(;3o3KeY)KWwT$<({oPF*4jcVdUEmF zq=Uk<@d@d@q+Aj2j9shT{Tt|=f?T(7l!t!0mv`t7x0pl>H$sBtwR`-MdU zgf}>ony)>kIZV^{CFMDJLCutd8t8etg-MR|#MFTTzW&r#b9o8MX$8D5}ci5%|^SVR1cA$<|ijw*jySJ%Afp5-?K`vQgxkgyir^>jkGVc#8|e zOJj3OeRbpR+Q!`TDZI^A=2BG#=`A}^jD3`n`b0WuPp|wbsN}S&+yIzv2tt}*pf-GA zI&E5dH32%N6;?2;A*CXAF2uq1u~SOGbLmQV{Yod#O3#`?&G%5Qua(8gA^eh6AwK9Z zSg1xy6&6y#$nCF+9LzOqi-JhwKkMV!yzoh&An!qSUtneGAii-6&(2p3p%&_J;|oA= z%wS38V6|C3-kh)IR({DPLP?8FO=S(v(xa*dQ{_siBJfpMasfI%)pj1$zCEgaa=os{ zwyqCW*N>?i1l9$a0!EMOKJwL%^VL6*ub+n1&tmF7wbg%?u5VOyU*xlI=V~y0?gjQ} zpbffisfw(&HK?pNECCxerW;JO8h5|?9DoG(F^x`yMqygxNsSPo{jW{Frj7?qyJk(y z?EI{D-t6BzF3b2_o%g&hqj^(}(3C*%sU-XvB&4qseAWm+b|Ouj$UQ_5ZFiG0AcnkT z5bNDI?|xIecT6njXy!;ISh+P{No{^u+uWhptf(cSaol`|oy6Ww)IpH6WO#IZ9~c~y zO!!;O)LJa;TKt(?4AtCJ>@0)G?sh{DZQ!2O6^;(@2KPK8FW;7W0=TKK#bb!PSwUuB z7YQYLE$zz5iIAc_>?Fw!!R_QX*}jjLNoJ|=)*aL4B?aNjTo#y8k}7B0&bn8*uZ`bOYjP^}w1q+o zmB{69fA_GRqC+LKQ$+6AqkO3yc4T!+pS(L%9)#QC#TRLul=lYYT6X7Lv3UxL?4v*5 jj3)W-K76yp-?^gJNwe!*hj(rkb$)H{EWLgW08sl6UQ(!2 literal 0 HcwPel00001 diff --git a/winpcap/dox/npf-ndis.gif b/winpcap/dox/npf-ndis.gif new file mode 100644 index 0000000000000000000000000000000000000000..8c151bc4a2ce3f45077d46efb073b4c05ec42062 GIT binary patch literal 3572 zcwX(+i9ZvJ1IKY!LOm*S)(|CEsN{^NkTZltu96TH<|CaD?6C8YO4t~CiW*HoDa6VzBC)9>F-HB)AEO1E;MITedZ-PsyjU|2Q zGRokK=ETzeECqWmzAj?fCyct+0M5LroR+W6&0*Fb>NQk&2QC1pZmRfFVwNTJ#GF($ zTA>rJbZg*z^;pfLGVAXH%{6xk9^C?CYt7ycjiAxq%PuXoF0X)N16H5*et)Ed(x2A) zlj~jILb>%8*Bxa%-Y3C@R0kv0fA(YqsqV3~i9Wem7yQeitxXFwOZ^mlt^~=isl>ih z<*0?YMkQ1bQ=_Mg*C$YZn2uDJ21sd>KV#v$%jRZXPs*^qb#u|fOx`n+nhM_`a&gPI4%t7QQc=rAuu(-U97iT1dAv7%R3=!#CSy**lw+zBX5_ z^3JdlXc$CP^j{J-w&Xld4VBQzPTX={PH1cf)bZ= z1E#Ay^WcI46@Jkh<}3LLqHW_PDBbDTg|T3ahhat-^y+<_Y+FS!<|$=0v%pTbBF}V9 zv9gS<;hR^5OCMjWF0G0=Sj#W#%`Ga)E=JW>na0J0#J?_cRCSK{ zB8jC`a-LR-=lOHxNt*0zWl1xySHAlPIeu6}&#vuZLxgO|p;|n5->L0{=&h47C^>`E zc^~B_N`p;Q$oHK)EssnA5yu^WWet8p4c>IsQ2yr8J<2aeAFg4dpF2tB-zW8%sQp2z zw`(%ZH53#}oe!0E?7)n;(envJPk0&K)hAYe4`b>W-4f_0OwpVP2A&A}E;9s>Vb5C6 z(#UA&=23XF@)_%hxnN}J{x5Vm!gD^uRFyfC2| zbOznFR9(MuKyd1WFb#X)+wg)AN99Ccf)L-SA85%Q?;~)NEc|wJ@X~fR~k3a(X%`OzN?i|bN}-6eocVxRhM=5r`+UfM{EIwlg5k$BrxmPIl9a%&_loyYa^ zqIUm~LkL>adqLo2WUG~72poqiSlyd!dl0sbh`m^*s2pxSUOS?al~Sexz)&7fZ|CG1 zOLOpaeR4b4#&n%7S5Gt_d@4!DQqObjgyjzU>e6#RqkWYD!ZffmJ#VDvtR}gi1~~}H zBW{&z_wmzwUeR$Ym*urbvxdUj>~p7K6}S6Zt^cCY@!#1RR}C0`G$>bMA;&e~ZElOt zUI(LhPFR7i?^bh227|+|zCQJ2H^6|^x6cPH0E2dYT z`K_oP*fts^Fs8CeP;w}<_)-|9qD6+;ahR8||brHKY)~nNw4ZXVr7;Vk1Nx-Spu$gc_u)=BTV61yUq|(Yk*=x&r zyiiKB(esLmzE1ns;*dx6d4GVt!ug%+T5|BkBJ2u}Yb?hYHxbqRE5BXO`HxLPN9#!X z{?0FQT}tsSE%n*8L3D|+xiHb@o{rULj+!lVRV^J9ITh7(I9d zLA)2pQA3bdJ+M~T52xP!t*(4g{tx%2E-6igc%#GnXS19NTRP}C%1IQ+wn4u z5>{^|^^6}4)!k_71KzQ+xiHw&7WSs5Ht=p}`-~P_lj5kj5v-OUxFoMd8vVXL+sGQ5 ziqVptxVHIlq?jdc2==`gm!=hCN^;eUzW|Zj8S$dM`!l zQmQ+Paaf(X9elnA+74^d7U{)$ate_kJmC?qt; zA2JT?k4SPcLEFhok5F&DT9I-b2akZz6CiN!BiR}gV2NB(!IB@9H!)^BuC>>9&MdVn z2fa`UKK$a_&YOD69^I*swo?hI0j1GE;E$A-QA;T=mhNs+Qqbq+FWZ5i^s0l+lFv$H T3h88?f1D}GwBY>b-|GDj7iFk2 literal 0 HcwPel00001 diff --git a/winpcap/dox/npf-npf.gif b/winpcap/dox/npf-npf.gif new file mode 100644 index 0000000000000000000000000000000000000000..7f0e4bc90898b120e3a3d74225dc61d69c851c4d GIT binary patch literal 8463 zcwX(7^;;7FqlFPc8VQjS6cr@}R9Y;$yHlDG1|TpP-5cG5(Xhej8r?NubPPs!2uSz5 z-*^9wd*2_<`3v6XIY(YmPE7pU>Aj457X<%h`0(HGzl?twLjQ?>!^8jnxBmS<|Ihyc z`2K6ae_bFT#S_qyK2fO1?g%2Krz2{w$mt5Bd7+e{P?_5UW@6=;7Zc3ui+Lt(w%)Iq zk51s?k2gVA6%3{bTGbK#$S%aBi@EO3qpRT~S)YU037%EwjpivN@SG{ua1lb4^ORr% z)kPCXgK9t$SyJ&#xrL+A21{MZY_Wb*rm5raKhvlmYqq+Bb!Da~!JWB)w%haHA%M+Y9{(Buh9!#E;3Iym5Ec1PSwHvaE;6#do~F zHdadI<(gUC|`FJc!`+ww1v-$llt_W1}WJR(P@hS(qJz!=%p3SDw$Kq$M1lN2w~I zo+n9}?c^t09&FFX*+-_lOtE@kSZJX|ZoLU%Y9(7wGOlY_OqmZsZ^FD56|JGcy~11S zRQRoDp?`|bo*DoASZfwV_F&gCI8g+>oe{?#IS~}Wle!Wc^V?v%$klyw#|Spw_b3`~ zw%gB?V9G=07=qa3;dLsb?y)N;Ty5O57f>=tsw~_sc5-YlzILoe#}hjT4C)!r)u5!n z&e5`^jr;KF(55)ll3by4!#WIn;JaFfWH%T=8<>~Q6iJr5p3XrJv%Ai(GNUfyk@-zT z>V_Qc7kCOoB#4|*AmjYle$jW7LFI4pmp8@BF}WYRj|#ibkUG6=-y*8A1vqVFkY!D5^fp=<;oBkLBI^*jHuTuh|4gqvH|k+?L-fSuP9W7#0zh zcbidCYNE)36x>CJFQMd3e(eRYdhc0hreqx|=t>gQLBCM%+;q|kZQqMl0G=cZQQZv; z>q(Sj^)d}@H-QJ z03`y-Yyyt>~@H6ZYJ$@#TszJX;(GO&Fs6DVXtWyeI3fG=CBaw40WIipB0{BrM;9Hd+jyK*0omX&<{mVPJdS6o zDR@I6IAD5xoYGFo$seRRWZC*FwKs$F4P(5Dp2$hs=m*ZXd5RcowQ6X#%1cu32#or# z>hxtwxL6;0;CsAw!rY&1aXUlBn2ZzHUkLpDjMuPRv}Q5^p2q*<1$xBy`Xq~h3i0_& zQQeE>G@FzYE+t@~p|k0lO%sKXxtkpgCalhVjIozWnWgnnJI#AW#U&>U7>tWQ&7U&a zW|U$XPp+HH=aRBjv6E0s0>l=)!4%1SQ<~5@u7P829h91|iJw@=;Svn(()X@M3nJaJ zz7q3r=kZKgXfZ%Vq`qmQJ$2n)F%+xo^2jg~P8CDXO49xSG$MFjBT0`+<%X!$(v>u- zrq9Z5ok+jzUDGtr31=zm@*0uws&%luL#}Y-SfU!S@O=4-fCZ#>56?7O>v2W=!k!H` zgmvL){?l%_FaaGxKg~6t-#Hk?*oyVdd$9&HWtgpB3#Rv zhO`yl(-|B;tMA4jod=7J9Yih~v~7@9IKbREp@)eAsMPdoz!2ers>>k$ZkI&9pv6+x zEXBs}@Q-w6ahRycJnFmI7_Z8;*<|jn`!Zl-(0p?am9TXuAaOLPDc*r7K#8#AxF`Yw?f8Yd%MFm}w{{P9)d8KWg5LgNfU0*}g}o zUGZC`583RlG9?_kDJ0oQ*q#6$4W^F0#ozl>zsV8Sz+n@80xI{hLRFv!jUHgqSNOI* zvZf7l4xPAZVzB~SS~)aF)w${5&A|_qEt>gn5*=CMWQ`>XONUM+SnulDZcfK-AGk}& z7da3}V<)H?+(EigD`t%nV-B*fvYrxJ2&F(1GBR0raPK+Mv(CVyf0fH#Ihv5L&JKy#6*V~TTP?A4 zt%Sa=?YpybHD_JeI~QqB~v>p zlG7b1a}ybUsdfVQOyozG9`hKS}7tmz^#Mw(MvKtWV^rxl5@@RqBoaJIXTOm3p)N zvRns3+cKpqU-$iiax_tm9k_88gF>DBZnW1IWgGV-4t|puFJ26LOr75y>hU!$lc-;I zvbJu!6MZIlJaXA9i9d>sX`ID!5Q(yWYybefU^dGGDdxZ7J zg!xXt2C*{*?2!bX*#!s%2QZ6)l3s%tumO=50k5$>0tn!*mw`QuK|NbEkQo|rMBsnT!!t$wlrF=d_Ca6- zGi*B|RWve=F%pP~6flTf%>k8!M|R4Cv$rC>v7sZP;5sbW0vp-b@6)^u?lyoVlYm2o zApZ7{AuOaS3=)z9L2X0Y6ry@aqkeHjP1!}|hk@t0B0D^N=Ip_X+mJO+-v|%S-TLT1 z*yw|BTK_GNZ`Ss^k797vF#~~7=ZKg~Y|PnO3_;QFTc%i|2)A$gv7~8_Neq9Jk;zju z{H7{0e@Ny*i~dGWCVijGlX+I2b=HH;Fzy*QJBN6D@M)aamv}BTDk@dPh;f|x^s=uX0CW`!@}i7MR*GG2*J?_(60&+d9PQc_lNP%0RlMnYxpwIAx=WQ(U=I z+^?jSPm^7CjKySRof}eqrWtu%rFbf)_@Yw)wkbgosm-ekGFy_?L z%OoR1I+LR0e=m}(*3+`mlKHry!BuG*!O-t;XrW?k$t;xM3R*E6Q+1VG?ch=CknZl0 z4!nwPy-IIq&JeQY`kZ2*cp0_g5&Zy>vGe*Xfd#=RGi+QOHfac(_JZ;BWc1;~GyD;- z+b!7AR>q8Y=DK0#SQ@Mk4com6Z{^C|yvqDb2HV~V-80NO+sQmi%UTo98YRg*zskA@ z%eofNo`V@gYab8l+d8iuh}#_um?O4Qt}}BZ9j@R-;K*qLYAES5;>~|Ifd{b zONCq=`<$h#DAvYMw%wd7vfOS_Fnf3|ze1iGX%I6ID9#cn2@QU@n@dEVM?&gFpX2=) z7$Fjw&s3Z%6&d)6JpYTOF47IW^yOE_)Z1YmUv;0Ay6$@>YGVQLtrRxiQA`2{);Qn(N>OeUDFbz&bN&tc)d|42X zYgmvHV#5JJgFqw#3S4=>DRYRP3q)*VR_|<9xKU9ew1`WgxM~~pQz9y}uLuT!#Yg(& z@DxV?iklRWJ6^@2jSys`bSa=Piw8nPgLJy4iJU7m0)}a)`upvM7aHYBiUp5Cv)?r$ z*(Z^4*GM5ik&i@V=RlzhG-wHm8~`9sBZ__i!Wwo<(9p;dKq*~hDG8z!Fc1i8^l{-S z{oU0ftIS0WEB-!aN1wuc|^Wc}sw%b6>EVo;tapL+q!Usfu+Rmw3TFEayFrpZ?j z-xOC|WIPz90Yf7xl|yNbtA0cV(MeVc0V)Yt@o<8{vSy=-GGGOfL3X%={{pnYd^h-^ zciBs1)#oNJmc6nk;Owa@xVU4Hia`jMa-KwLm9bKk1`@u{Q!UF1lIN{?fdgwdRrQM1 zOap6wq}CekmF}aXOeq3%n=0Q^1X%BR;glc_k_8`jBU8C*9F=RF!QSk~+3SobJI5%E z^x{v*Y%kV2Z?Mnz^h$r$nrLw4?sZVSXUSWG(zo6<5ysvi-W(gpx|o~#B>SqO##{>= z(h>&*BfX7p8ouDFKkU`S8U%znHl`_irw=wjaP{l`jdhMy<*XG6VD1c;hw|8c*cXJt_ToG9_!&SQ})&etX znFhmXg^)x2Ei|dEi#IJ#SzA{rvNl*tnsIFljt%FI72-jG0>#aE?{?DS*4Tko17uq! zxV^NgWD4FMJkU<%RM^SWMq`4~1r#MB^B(!YA3p)1yldEo+J@3Qmr-qoJRO}B?e{)( zk{Wexp=q9iJ9(b8t$20j?sm$sblUKAu_<@ian)~o`&I$k=}p>}c)LXn@_B&WRH@yw zP2GY{ZEBRrO5Pp`KCn(nx94DYcY2RcQwPsrr=nB6rB8!3#K(51++L;Uxk2M3xD9pP z>p##*f3MA-v|D4Y7vIv9$?~LMvA<6S(7%qVqvFUp-pTb{G2=;Od*PXd!})LU`rfbx z5aCc6^Zo4C{iY&}@j|Ge5Ba9^S;y$EBM&qRTZX#H08Jqpjmr z{0dZ1@MbWbQGpmmZ{PL+@h-ZCa&RkcAagF&W79^x*VcG?kVOgI!3UYV>OdOwG=>d9 zZYwkSh93$IzoWqLPTI!HVd7_Lp~&cDA5T(8Pyf`$zHLljb8mUc5XPjljfSH`{FMGk3 z4)$<3%tEf|Ap79ZQ^ziGsnu$q)y*f1iDctDPbSw*msMJp8~3%y@r$KNIO{1RKiS#J z(lwm>B9Z582-VU7)skdSCWf(y`e)bWlc|N4p%)*ApAV0%&yVO)j~ZIrP2GN~YLg;@@#&-;2%M`k*=*G`%_{yX^O7A%Gg|n7OhI+6;5qj$vxb zGwrI}?fQJVt*N#n?mWTCzOSLS*Ro?>c$OmNjOk(Aef)7V$akt^SVxW>%bmR0Pqpi} zKk8f-*~h*iN)a{`-D9)wl}D``lDViS^=Bt~5!U{f^OfO!q4M#~%*hMTIH~c)f^&7%lhx6W`&_LP1$P^rF6Sy#N5P*? zx#h0j`}&)W6jguR)5Y(~lw9=nU%V(k35c1&7ybE(U%^pcS2|T!_zlOj?Zqu!z)KHN z0NID`TJ58U_3kcLTQXl>O5=M){vfI{seq zKPGY-0wQWkjnU;V!DRG=pGQYmq{C@BC5SBAS7jm0!Y=FBxD}aL4%tYe?9p|_L~h;O zm!3Z?&`Clz!}-kBHmVuo?kqmD^qXqgUqBDs#mDWtBiWMP*Z_{!G!dHIbOlP<%jitq zS{F>?6z_1(2R~m(3zhu1EFQbq`wpZL4MA z%*}GVVQG;X2COrmZqvVh94+j5)Y$C`{hguX;j-Br#Uo#a`r%%J)n=brTqtpi9C4Q? zc^cp7(KH{D^{KN7w18TAB(n;Bm9I%-rJwH1kd4f6GJm$F2^PA=IUL%%kL zC=KwH^3rj=wd<@>;qRgQ1CL*RN&4zM8=pa;Le&$@qbedPS*^^nTlX5WENvv#2KC@|dC)BROf5yO{ViHwepy8IIjt4gOg_n(da`-K_p z;3MNHA3_U)Uufa!LY@x(YU8oGjmL94ll!jozxLQH##}d4lT77NHXa{A)%i1vz$9hS zWv^Oy#ymew>C`H#Y8 z<_Br{VOvDPyf!b?#y7*k{33?>coMzYc}LSl{gqVK-?ZN{ISL``@GR;nhwu>wHvnRd zwb3FkDpcGSZYxs0DW*uh$CIAZD$$*t-U{6NC411=QQn~k9Ll;NWD)pjT=pJNT%?9` zsQK=zJzNamBy(xlVrO=UIb1xkYmD8;{ROc7nRU|0(_{UK{36g~SBi3(Kf1?ZZg6bB z;N*Q+Eg#5Qafy3GaT{F-T&cjc9YQaWoai2e|g?DyIUfU0ZPFeEF zUyu5cabE?0xdpvnJm`nV6F!rPg@3&H*6UB!Jaxg< zdW%3(jXQbIS1*xvZB<1k{V+YUvbYbg`uf;+l#e5kszPpw+X6_hU(iQX!kY*xuu zPTB~lzv$omJD$>o@6H#D@KPa}rb`>NF2q7+hx7>Pp%eL=Lz#xE!b_IGeqlTyaCW}xz?><$U(v|x*hifwt)K0 zo4Vzs#dxIY#kGF>1HCdUki8+Xw?X%-$LhiEh;Ixx2K{m(Dj*QViqqS0$Sk>%s@BO? z>SngxMI;AC?ChY*sz3HTu?7x$1d6xJ4*1MdH*d*rq3u07H9f6J=mpkhn#L_%>!BiA zNivp4Jn{udzYS^1!Ek^SpMk&bAs4~~hZKIFmGfj(B<-bwNvjfl> zmsZm^t_~C?$5r|zpu{rZPNZ4GlbP0hLl^HoilQw-R3p>)p>Ix*`FCam-(POueTe^9 z{8gH1BQN6!)Rg{4^&s_IGlmqD#=3GP!PKQu^EX7^$MVrhZ8x#fPq3*8l%e{v=bf(* z{`Wm23zjXW8j*w7(eAfam|jnn&##Vsy_(gZG8&=-rK&zAG+T4+)uOL_ekGQEFyJ^u z7aMQ>N@=;Z5tJ4lw0h;5hM^pL2RFpPO;;PA@lva`OIWxR%~aA7Jle zJO);V9McC)wxll}OK(4MPUxE7{&?Y8r%C=jUIw<^BI7mWcXyI)2ig$?kq6{T|4h+m z!}4W`&jz@-SCq#;uYctpHtzz+lmzX%s*lYrQ8PC;Eo}epyXm=7^Jov_! + + + + + + + + + + +

This section documents the internals of the Netgroup Packet Filter (NPF), the kernel +portion of WinPcap. Normal users are probably interested in how to use WinPcap +and not in its internal structure. Therefore +the information present in this module is destined mainly to WinPcap developers and maintainers, or to +the people interested in how the driver works. In particular, a good knowledge +of OSes, networking and Win32 kernel programming and device drivers development +is required to profitably read this section. 

+

NPF is the WinPcap component that does the hard work, processing the packets +that transit on the network and exporting capture, injection and analysis +capabilities to user-level.

+

The following paragraphs will describe the interaction of NPF with the +OS and its basic structure.

+

NPF and NDIS

+

NDIS (Network Driver Interface Specification) is a standard that defines the +communication between a network adapter (or, better, the driver that manages it) +and the protocol drivers (that implement for example TCP/IP). Main NDIS purpose +is to act as a wrapper that allows protocol drivers to send and receive packets +onto a network (LAN or WAN) without caring either the particular adapter or the +particular Win32 operating system.

+

NDIS supports three types of network drivers:

+
    +
  1. Network interface card or NIC drivers. NIC drivers + directly manage network interface cards, referred to as NICs. The NIC + drivers interface directly to the hardware at their lower edge and at their + upper edge present an interface to allow upper layers to send packets on the + network, to handle interrupts, to reset the NIC, to halt the NIC and to + query and set the operational characteristics of the driver. NIC drivers can + be either miniports or legacy full NIC drivers. +
      +
    • Miniport drivers implement only the hardware-specific operations + necessary to manage a NIC, including sending and receiving data on the + NIC. Operations common to all lowest level NIC drivers, such as + synchronization, is provided by NDIS. Miniports do not call operating + system routines directly; their interface to the operating system is + NDIS.
      + A miniport does not keep track of bindings. It merely passes packets up + to NDIS and NDIS makes sure that these packets are passed to the correct + protocols. +
    • Full NIC drivers have been written to perform both hardware-specific + operations and all the synchronization and queuing operations usually + done by NDIS. Full NIC drivers, for instance, maintain their own binding + information for indicating received data. 
    • +
    +
  2. Intermediate drivers. Intermediate drivers interface + between an upper-level driver such as a protocol driver and a miniport. To + the upper-level driver, an intermediate driver looks like a miniport. To a + miniport, the intermediate driver looks like a protocol driver. An + intermediate protocol driver can layer on top of another intermediate driver + although such layering could have a negative effect on system performance. A + typical reason for developing an intermediate driver is to perform media + translation between an existing legacy protocol driver and a miniport that + manages a NIC for a new media type unknown to the protocol driver. For + instance, an intermediate driver could translate from LAN protocol to ATM + protocol. An intermediate driver cannot communicate with user-mode + applications, but only with other NDIS drivers. +
  3. Transport drivers or protocol drivers. A protocol driver implements + a network protocol stack such as IPX/SPX or TCP/IP, offering its services + over one or more network interface cards. A protocol driver services + application-layer clients at its upper edge and connects to one or more NIC + driver(s) or intermediate NDIS driver(s) at its lower edge.
  4. +
+

NPF is implemented as a protocol driver. This is not the best possible choice +from the performance point of view, but allows reasonable independence from the +MAC layer and as well as complete access to the raw traffic.

+

Notice that the various Win32 operating systems have different versions of +NDIS: NPF is NDIS 5 compliant under Windows 2000 and its derivations (like +Windows XP), NDIS 3 +compliant on the other Win32 platforms. 

+

Next figure shows the position of NPF inside the NDIS stack:

+

+

Figure 1: NPF inside NDIS.

+

The interaction with the OS is normally asynchronous. This means that the +driver provides a set of callback functions that are invoked by the system when +some operation is required to NPF. NPF exports callback functions for all the I/O operations of the +applications: open, close, read, write, ioctl, etc.

+

The interaction with NDIS is asynchronous as well: events +like the arrival of a new packet are notified to NPF through a callback +function (Packet_tap() in this case). Furthermore, the interaction with NDIS and +the NIC +driver takes always place by means of non blocking functions: when NPF invokes a +NDIS function, the call returns immediately; when the processing ends, NDIS invokes +a specific NPF +callback to inform that the function has finished. The +driver exports a callback for any low-level operation, like sending packets, +setting or requesting parameters on the NIC, etc.

+ +

NPF structure basics

+ +

Next figure shows the structure of WinPcap, with particular reference to the +NPF driver.

+ +

+ +

Figure 2: NPF device driver. + +

NPF is able to +perform a number of different operations: capture, monitoring, dump to disk, +packet injection. The following paragraphs will describe shortly each of these +operations.

+

Packet Capture

+

The most important operation of NPF is packet capture. +During a capture, the driver sniffs the packets using a network interface and delivers them intact to the +user-level applications.  +

+

The capture process relies on two main components:

+
    +
  • +

    A packet filter that decides if an + incoming packet has to be accepted and copied to the listening application. + Most applications using NPF reject far more packets than those accepted, + therefore a versatile and efficient packet filter is critical for good + over-all performance. A packet filter is a function with boolean output + that is applied to a packet. If the value of the function is true the + capture driver copies + the packet to the application; if it is false the packet is discarded. NPF + packet filter is a bit more complex, because it determines not only if the + packet should be kept, but also the amount of bytes to keep. The filtering + system adopted by NPF derives from the BSD Packet Filter (BPF), a + virtual processor able to execute filtering programs expressed in a + pseudo-assembler and created at user level. The application takes a user-defined filter (e.g. “pick up all UDP packets”) + and, using wpcap.dll, compiles them into a BPF program (e.g. “if the + packet is IP and the protocol type field is equal to 17, then return + true”). Then, the application uses the BIOCSETF + IOCTL to inject the filter in the kernel. At this point, the program + is executed for every incoming packet, and only the conformant packets are + accepted. Unlike traditional solutions, NPF does not interpret + the filters, but it executes them. For performance reasons, before using the + filter NPF feeds it to a JIT compiler that translates it into a native 80x86 + function. When a packet is captured, NPF calls this native function instead + of invoking the filter interpreter, and this makes the process very fast. + The concept behind this optimization is very similar to the one of Java + jitters.

  • +
  • +

    A circular buffer to store the + packets and avoid loss. A packet is stored in the buffer with a header that + maintains information like the timestamp and the size of the packet. + Moreover, an alignment padding is inserted between the packets in order to + speed-up the access to their data by the applications. Groups of  packets can be copied + with a single operation from the NPF buffer to the applications. This + improves performances because it minimizes the number of reads. If the + buffer is full when a new packet arrives, the packet is discarded and + hence it's lost. Both kernel and user buffer can be +changed at runtime for maximum versatility: packet.dll and wpcap.dll provide functions for this purpose.

  • +
+

The size of the user buffer is very +important because it determines the maximum amount of data that can be +copied from kernel space to user space within a single system call. On the other +hand, it can be noticed that also the minimum amount of data that can be copied +in a single call is extremely important. In presence of a large value for this +variable, the kernel waits for the arrival of several packets before copying the +data to the user. This guarantees a low number of system calls, i.e. low +processor usage, which is a good setting for applications like sniffers. On the +other side, a small value means that the kernel will copy the packets as soon as +the application is ready to receive them. This is excellent for real time +applications (like, for example, ARP redirectors or bridges) that need the better +responsiveness from the kernel. +From this point of view, NPF has a configurable behavior, that allows users to choose between +best efficiency or best responsiveness (or any intermediate situation). 

+

The wpcap library includes a couple of system calls that can be used both to set the timeout after +which a read expires and the minimum amount of data that can be transferred to +the application. By default, the read timeout is 1 second, and the minimum +amount of data copied between the kernel and the application is 16K.

+

Packet injection

+

NPF allows to write raw packets to the network. To send data, a +user-level application performs a WriteFile() system call on the NPF device file. The data is sent to the network as is, without encapsulating it in +any protocol, therefore the application will have to build the various headers +for each packet. The application usually does not need to generate the FCS +because it is calculated by the network adapter hardware and it is attached +automatically at the end of a packet before sending it to the network.

+

In normal situations, the sending rate of the packets to the network is not +very high because of the need of a system call for each packet. For this reason, +the possibility to send a single packet more than once with a single write +system call has been added. The user-level application can set, with an IOCTL +call (code pBIOCSWRITEREP), the number of times a single packet will be +repeated: for example, if this value is set to 1000, every raw packet written by +the application on the driver's device file will be sent 1000 times. This +feature can be used to generate high speed traffic for testing purposes: the +overload of context switches is no longer present, so performance is remarkably +better. 

+ +

Network monitoring

+

WinPcap offers a kernel-level programmable monitoring +module, able to calculate simple statistics on the network traffic. The +idea behind this module is shown in Figure +2: the statistics can be gathered without the need to copy the packets to +the application, that simply receives and displays the results obtained from the +monitoring engine. This allows to avoid great part of the capture overhead in +terms of memory and CPU clocks.

+

The monitoring engine is +made of a classifier followed by a counter. The packets are +classified using the filtering engine of NPF, that provides a configurable way +to select a subset of the traffic. The data that pass the filter go to the +counter, that keeps some variables like the number of packets and +the amount of bytes accepted by the filter and updates them with the data of the +incoming packets. These variables are passed to the user-level application at +regular intervals whose period can be configured by the user. No buffers are +allocated at kernel and user level.

+

Dump to disk

+

The dump to disk +capability can be used to save the network data to disk directly from kernel +mode. +

+

+

+

Figure 3: packet capture versus kernel-level dump. +

+

In +traditional systems, the path covered by the packets that are saved to disk is +the one followed by the black arrows in Figure +3: every packet is copied several times, and normally 4 buffers are +allocated: the one of the capture driver, the one in the application that keeps +the captured data, the one of the stdio functions (or similar) that are used by +the application to write on file, and finally the one of the file system. + +

+

When the +kernel-level traffic logging feature of NPF is enabled, the capture driver +addresses the file system directly, hence the path covered by the packets is the +one of the red dotted arrow: only two buffers and a single copy are necessary, +the number of system call is drastically reduced, therefore the performance is +considerably better. + +

+

Current +implementation dumps the to disk in the widely used libpcap format. It gives +also the possibility to filter the traffic before the dump process in order to +select the packet that will go to the disk. +

+

Further reading

+

The structure of NPF and its filtering engine derive directly from the one of +the BSD Packet Filter (BPF), so if you are interested the subject you can read +the following papers:

+

- S. McCanne and V. Jacobson, The +BSD Packet Filter: A New Architecture for User-level Packet Capture. +Proceedings of the 1993 Winter USENIX Technical Conference (San Diego, CA, Jan. +1993), USENIX. 

+

- A. Begel, S. McCanne, S.L.Graham, BPF+: Exploiting +Global Data-flow Optimization in a Generalized Packet Filter Architecture, +Proceedings of ACM SIGCOMM '99, pages 123-134, Conference on Applications, +technologies, architectures, and protocols for computer communications, August +30 - September 3, 1999, Cambridge, USA

+

Note

+

The code documented in this manual is the one of the Windows NTx version of +NPF. The Windows 9x code is very similar, but it is less efficient and +lacks advanced features like kernel-mode dump.

+

+ + + + + diff --git a/winpcap/dox/packet.htm b/winpcap/dox/packet.htm new file mode 100644 index 0000000..cf86763 --- /dev/null +++ b/winpcap/dox/packet.htm @@ -0,0 +1,54 @@ + + + + + + + + + + +Packet.dll is a dynamic link library that offers a set of low level functions +to: +

    +
  • install, start and stop the NPF device driver
  • +
  • Receive packets from the NPF driver
  • +
  • send packets to the NPF driver
  • +
  • obtain the list of the available network adapters
  • +
  • retrieve various information about an adapter, like the description and + the list of addresses and netmasks
  • +
  • query and set various low-level parameters of an adapter
  • +
+

There are two versions of packet.dll: the first one runs under Windows 95/98/ME, the second +one is for  Windows +NT/2000/XP.

+

Packet.dll was created to provide a layer to access the low level +functionalities of WinPcap in a system independent way. This library handles all +the system-dependent details (like managing the devices, interacting with the OS +to manage the adapters, looking for the information in the registry and so on), +and exports an API that is uniform across all Windows OSes. In this way, +applications or libraries based on it can run without being recompiled +under any Windows operating system.

+

However, not all of the packet.dll API is totally portable: some advanced features, like kernel-mode dump, are present only in the WinNTx version of WinPcap, +while packet.dll for Win9x does not provide them. On the other side, the NTx +version is a superset of the 9x one, in other words all the function present in +the Win9x version are present in WinNTx too.

+

The other important feature of this library is its ability to handle NPF driver. +Packet.dll transparently installs and starts the driver when an application +attempts to access an adapter. This avoids the manual installation of the driver +through the control panel.

+

Important note, read carefully!

+

The source code of Packet.dll is freely available and completely documented. +However, packet.dll should be considered an internal API, because its purpose +inside WinPcap is to be a building block for the real public API: wpcap.dll.

+

As a consequence, since the normal and suggested way for an +application to use WinPcap is through wpcap.dll, we don't guarantee that the packet.dll +API will not be changed in future releases of winpcap, and we don't provide +support for this API. For the same reason, this manual doesn't contain +any more the Doxygen-generated documentation of Packet.dll: the user will +have to run Doxygen on his own to create it, or read the comments in the source +code.

+ + + + diff --git a/winpcap/dox/packet_samp.htm b/winpcap/dox/packet_samp.htm new file mode 100644 index 0000000..b3c565b --- /dev/null +++ b/winpcap/dox/packet_samp.htm @@ -0,0 +1,59 @@ + + + + + + + + + + +

How to create an application that uses packet.dll

+

The creation of an application that uses packet.dll requires the following +steps:

+
    +
  • Include the file packet32.h at the beginning of every source file + that uses the functions exported by the dll. Packet32.h is + distributed both with the packet.dll source code and with the WinPcap + developer's pack. It is platform-independent. +
  • Include packet.lib in the project. Packet.lib is generated + compiling the packet driver and can be found in the developer's pack.
  • +
+

Remember that:

+
    +
  • To add a new library to the project with Microsoft Visual C++, you must + select Settings from the Project menu, then select Link + from the tab control, and then add the name of the new library in the Objcet/library + modules editbox. +
  • To add a new path where Microsoft Visual C++ will look for the libraries, + you must select Options from the Tools menu, then Link + from the tab control, library files from the show directories + for combobox, and the add the path in the directories box. +
  • To add a new path where Microsoft Visual C++ will look for the include + files, you must select Options from the Tools menu, then Link + from the tab control, include files from the show directories + for combobox, and the add the path in the directories box.
  • +
+

Sample programs

+

A couple of sample programs are provided to show how to use packet.dll. The +source code of the examples, along with all the files needed to compile and run +them, can be found in the Developer's +Pack.

+

TestPacketCapture

+

This is a very simple capture program that tests packet.dll. It is a console +application that once complied can be executed both under Win9x and under WinNTx. +When executed, TestPacketCapture gives to the user the opportunity to choose one of the +adapters installed on the machine, then it captures packets from the specified +network adapter until a key is pressed, dumping the contents of each packet on +the screen. 

+

Traffic Generator (TestPacketSend)

+

This example shows how to use packet.dll to send packets to the network. It +receives three input parameters: the interface that will be used, the number of +packets to send and their size. The generated packets will have 1:1:1:1:1:1 as +source MAC address, and 2:2:2:2:2:2 as destination address. The 'multiple write' +feature of the driver is used to obtain a higher transmit rate.

+

+ + + + diff --git a/winpcap/dox/pics/dump.gif b/winpcap/dox/pics/dump.gif new file mode 100644 index 0000000000000000000000000000000000000000..dfc0af8710ebd421e94f20cf015adf014495cec6 GIT binary patch literal 6353 zcwX((i9ZvLb$PR z8+x%K1~vITU}*~|^W*G-zO;KTy>Nrt!hV>l@5XFTZIM|T(+e(3gSz6Oycb~Ei#b^djp|p&An%)z_I>r`-Gy$;y_rT6?lxuKyBl+8 zKJPhf#D%xbacPx{9nsI}e7MGH7xYusI|$>9t);H?2M<#1l6{E-*~cHmOz4&Gb8;+7 z@j<9M^294MIR_JTeeZacFL_+%xO{WIRd0!4f>Fg0TK<)D)ShkJo$LO2H;W5H+a*`z zJt)9u*85Wy9xy!T3C$;KTZ<+i+dB40k^IT7luXI;niv zrimO~f3V?MlV5mrCp(AVNVc@dx$$G|IzM+-=J*C1vLb|z0uucdGI*bWCtL7v>)P)cV}fVy_hXUcqTyL?G>CQSS6L^kmWd-+{giR+wl!v>O# zet9MuoHC;?bs*gDZa?rEje8>(dI9j$0pHq#G(W?+!1~0!w5f_~hs9=~cFmo*{ zO`vIg0OX+lh4&YgPOj=wJf^S+wFG^sTdO#xVh-_1n++CU)Hgay#4wY;eZ5cqj!F5@ zc5pK)nB9x##Y1;T<+x7wOHHy)J!gEgpojBm{4Gb>AV-GBTApJDogDYR`54(Ie&(_{ zl9hgXIHQVXkjPoHJ1mbow#_2GNxVCE`1vt2bTynEZhS%Xg}_DqL4|Ai*>>_@b?aTt z|7Co8$HH0s>pR8R*jB>{@>yU0-IST(?RK7FRn;ezkG%lWo{MEn^$H=M%6%C2Bi4ye zt@N5_lbnd>1?mXO%0FILeO9%+&KV~S6_em`66ttVlG|7dPocQm`B~(?`>G_`85wQ) zv5)5yeb*?ID%iDv(q7;FChlI@TIO`o z_7CR!T7`Flv6DFaRI5sAEvOvn`sm5n;O&FjO#49(vr^t{o76`t7)HOlMW6Lh?s#3< zYX!I0M$=PJ|N5ezWUB%adP(@OvD^QJl=2S${P_uFRP&~<*@N+6!k;=UMA7FZd)7+O zA$ozB$r&iiyY?ZiY^}h{%-VBqz+IrOwA{8H;BW<@8yQd_L>QQIKj`gbz>i`UL7K^3B( zR-8X9B^6rzx#99DPL1v?XomdN$64*nS<@;!GbwvNwL~`D7!F}WB|nWcO-hvSzxDP? zzOhOX*vVy38XVATSziLFj3-h&0{gyh-UlE#-2G#wLL3!q8Hr$H_j{EY-Cl&6=&umd zYe;hm*}h#xnGd(M^*mHvLvE+^otWo1D8=sDtX!|m$VO<%c^`4q35-zO^=gMw42`YO zem#I!y&EG+x7@{L6y6(ku}68k)-^Or1Hu9+V|$jay*3IPimP6OKRP|~?k0SQ9kX%U zp*+l4u`+gZXHC=u7eD%|2C!Re$_v$ecr|g)Q@?9xB%#brrPj+xZ+d#5OX3&AdX((a zR5R1JGJgBz8$$`P8T`2m{wiN&sM28DX$%7Tpi+Ti)1ndc=|oWaliF68T;J3H(6Vkf z6kto$$e1?fzpn?7j%v^VS;2jqGjNh0pym)TZBd6OtK!i# z+?LUlnDYnmNd8%uDW-~D$cHmnb`WWD2J+}ou4BQV@`-XkJ_#Av>svLF~ zByLG8N~S&Z*OtmTdqp|}(Pe&x3HvbicJH>w-~;&ca#9l3d}ruGTeqy2_WD0=TJQ`W z9ULmn*#GmaG$=j0v#}xE`s{WSHhR13A84{3(DI)W6~!_B&vAv}?5YpP{BG7X1aqi{ zUGVVw$*X_#=%X65-jM$e0lsIH$wBju70!j*X=ic~(oSoZ-v{lP8puV=c^;?g&t7h!ydhR&)_Ts;(g zqXB{GpQiI8t)soXy2JPzeq2fa=0B;+u!5DpAkx>h#gaw)B_N zx(-K^cFAv(E|KiDq>?U_2%aBI;-V#S3xTexfq1P!{DC0B43IDiBr*jOBPE?iCo*k= zZdoVa4osHLNS0*T3MAlNYp^;BtT_ed4+N9a!P;smPpwnr zSW{M{Q}j_O##1ResHE-1lvipHi53F-Q-}0B5s8(}bWQJ?Zjl&~HGutDpw@Y!>Uk5i%*mKM zt)^U9Ob(KkO9$oH(^B_IX*MzWOh^QP1TpJPjW<9TH|6sn5wGbGBg2A=hWUAtq!lUDJ2ROU4bCwdJ9g3G9{q--LWuc z8>Fc)!cZ96-o=WR+TLD$>W5p?we6Shh_^(xKY>~qLU9IA>;$~}uU zKUWG{vw>>U^SXkn4w1Prfz^Da;4!58wd-(XY^8`C;<0e$Zfwm-5Tj;nVMN*NhinxnT1H$6vWJ$lgRHoBy;kmA4I3MRlO18)TgNk9XI`3(gI2GxX1@)B zp{EP<`;wrth1RwZ+ZiEy@~;W?LMJ(1m+OU&au5l!JHQC?d!x`x?!Av~gO*yuvU@|2 zE%>Xa4-2g!LeAm6QPMZt#>g4%;VroijbTQ`ngjVcZ~wEq9zzGn)i@<~q|Px_OR_Vg@x& zc{Yy+Hw_rM?2%E6U`QJwxK)VK%5%~tifa`UX=23$v1>L9bF_(T zwoAa<_$VkIT&TTHa4i*JpQ6M22o;u7CsF4DT( z_uD@H_g?Am08HCU`DTHWP7ULB0FIa8DUY3GZ&T;!d>D`MvulZz$LizS9Zr77Yj(Uk z>3YrA9RqI{)@+Arw(*Dj&eZHo*X)3owX27;hT=L>K8kyCV0}2+VP$`0LV7Fgn!j-L zRoivsYxd?)x=J{13EhW#xYs!_)0!dV6a4l`%W4Szuie1*EWYdg06iXm zgb6u586eCK46qC`hxVV>3Z=ktzdSqogFB}*2Si?B5@%a(;RY)`ho0f^+~tZ_6Z+o7 z581|}Yeagm!GjYMLnb1Ot_=*%{bQR(NGA^W=hzdcWZ#VrLEml;mGu$sK49JhTpAK@Lj#YV%==8V2j7QwO#@?5Y>lt_dbK39IJmS|p@uxyCb2v9V(>&T4cJl$ltOkLRh>)9TO8GJFUe9XhOT{_@zaB*(zNwXI=3=kyc7Lq1{xN*AVYD%;+-O!+})H#rAwTT$9 zl^ZP^VczS_itEYV%UPzRM(T1?7$t~G!L(3bRcsvgZ%iz26onDg3FK<(Cc$(wI*f>K z*&GwwEKytpc~jnLQ+5*861CSU1kw-ce2dstVa3L_=@y)@zOP8}3EhOZP#1s{ImT9@ z*e1xEdU1YhK5UKRz4 zsw81YabSUWKy#Y0^U!fO1;3+`wX1$*UMXDj0d`l!hy2)VQA=D?M`!QF*3PqVjptc= zrdx|fSap-LJxj;MmyYTdj{7!Oc2%+a4rWXCXFIp%7ka7d4&nP*;C(LOHXCsJs@c9r zmf8oi11_@#5A8!0@k1Tuy<`U}l)5s)AiY3P-f|s1soV(^KX^EQ2v9uQP&^`<9vL%^ zl7NR^l}FCu+nrpr1T)%B*x`jOntJ77f(y;7lIE#MKf@nbAm~zO2a=}rC>Q!A{Lz&G zT0mrCc}+N%*)t#e$+7N<5j(mYL1av9qpi8MoWSxm) z885DIGqG{pvKm~_{lUto=sG#Ls29y6Wtwj_bR*)Nkh1s6tFY^rpL%{tDOD-rEJG3)^&isOUz6f{|A-8!QcP@ literal 0 HcwPel00001 diff --git a/winpcap/dox/pics/encoding.gif b/winpcap/dox/pics/encoding.gif new file mode 100644 index 0000000000000000000000000000000000000000..62a29ffb620c837940c27284b8c78cdf7dc1ae1a GIT binary patch literal 2777 zcwX(*i9Ztz1Hf_7iX8O_<%k^7Y(&W&wFyyK;X|&75i!@?b3ATl?#!KYm}|@(c_`P+ zRk@j*YjeHHOk$q*dH;>~`Th^T&(GkIzPg4(7TcLKOt$|S%|DF}IX%rk{nx+#&w&34 z;GY)QI9Y6GIK>PJMLkiRm*s5+3B@1dE=iorHf$*ALtnk)wlLUGI*@W5>MwA!v1};g zrYW9m=u@W(WE6d#d$mT{wgF!)jJe$ain(Ks+x<*Qlvx+8dX$_GtQ zZP7}uYjq1r{&h`0zsmi3fURq4LoW#rD&leoN_{)PC#q02%t~-;{H)1Mtqwg90TZxu zbcM!-WNweQ^?thbPD_C78${dhskz;*HK`gx z6X5bOt$BeR?A^>q=Bz-D>pw|{Y;6veTP5w0s_^8!;j|8(pX3)M z#&<}nOIvS7HS0;fW2Gz}m44_IOwEKoH)g-jnB&R%7np$p!D_k%LSsG4g`&QZ8-P%!7RFK3zL#JTYBYpgrsf8R!(s=`rj*hG zArcjtn}jzC?^m1ZF(F&;W`1p zEY$LhXqgsdL}D$Ng2&!seOt`y8vnJb75?FPeoR;Q4j|;uKUzG zC43$I?u36(heI|Q^#xSKeo?*W#5^_PM7oe;w?&&VSs%>lR0Mb!-^0s39__dJ?F^K& z7og}BeG9xyg&C>|CKF-=WR_38;-NioFL#!zm_6&T6)G946sHKj&a2U;*X^ws3d*FM zlyO33Aj)34dZOQT)b*%;j-w$?McfwgdSKPGAYN@p-pTlW0TSU)5A6lPk*fxuYCU89 z$feBvK?7z(LrN%F>bis6;DfBX)K~$E#ARUvz1z=ylTmByHTpwFR(t8$Rd z53umqDIigX#2eF?DGY%pKdmAa5*puX1>FD_-x(GjYRqCv-cU@)l(eI`BCIaqYu2=+4h;$7=EawgHh{+0qNy#sN_scy7+g!8Q;TOlra39jeb`b zvx8=kf(P*Edo|66c+0T6LM}<6TXiz;iG#9k_K}}oyt??XdPIms1QJ2cAnO+sk*cr? z+sgyz%)uA{kG1SP%WS~LxN#1bWs=3n7>w{E#Jhr8D*=c?$dpo=pKDX{+wGpPHw(GV z{`E_}SfsV_0<|C1(apg2N~t!?@IUSlaGdFFLt7+al3Ha%J%hV`FS`2GSQ5MHg3Qeq zw|D#`|w0?Q-R7t6Rc}o_2n92`IWr)ZC=~L1Sr%VgI9g<-ty9vqW)i-?Opo zxtDpRH4O#Z_pjv5<2F^=g4A{dvDU~H9cI(yVmp$kHMtvG*0kEye{nv~?Y{%p`Wy44 B1{weW literal 0 HcwPel00001 diff --git a/winpcap/dox/pics/stats.gif b/winpcap/dox/pics/stats.gif new file mode 100644 index 0000000000000000000000000000000000000000..5c44ba356944837b2622bb2ebbd231ecb326c9d5 GIT binary patch literal 5431 zcwX(7bwd-1!-cU>M7`LI6hx_sh$5|*tD+k%JwQdIQ&3?rMFpi}gY_7U-Uw+}Fk<9J zN(l^*W|T@u&-dQX@&2B3KEiqaI1fPvnp#e{0~Zc#3j7D5^AF+Q{MY~SKmLCqvwir0 zfWTn^;D09k=Y+s9zQBQF5|4`0>%)(oRdQ%8Cb1$#E`tfSN$;CtMUOt`ww7eJBwo4~ zBLOPSYD-qI$T+N;p3On4I%eolldrF=}6mZZf~wx zCO8$m;bNA25bZh2uE@6`S+Qay4J*An^5uKpIdUos?cv59>{P?5BI63%@r6-Nm6rqk z{UPC^7!AL1R@B+#J)P>3sg|JF3)V(dwWrNVH@$pyhl*#q(ubap8PUpzIq<!4S^#4y8zpQ;eHe$6qGSuQ4$)q(ThoDBb> z*3dR<2Fv)dgWR`Un``N;#HU>V59s<&D#guod}TLbb80c@X>Hi-p7??4@%M@yEr4f& zJ8sC(!?zX0OohI#Ln0!aZYLRC{4M|efw=bkgue(_eZo0Y=vH#Hj^o1#OUX0claZe zCz;6hy-2Y#*_K0URBXv6Noj9pA)a6G$g=V;)q0-nV!8Py9DNiIhGl!yta3=Q8 zXYz{!g3#Hpfd$39^f7S0J{}S^9iLUIy-1D*LzXCoG3}yd|1c$3yp`6o{=e;~P_%SJ`uL*QYf5ApS+ktYE=x z{?dhltHdZ*$Xvy5**$X3HUz(1NaAyTBtR3yT&O}n^7CR2Ut|>F9M6D&%t*1=dDLrE zoDbf~HDm_yJw|yJqbc1NkfDD0Vrgs1YToy5$ij=O-Lk^Q>tFS9l>uJ`uV1S$H8$M2 z+2^jLr*0{9#5DkGRex8VblmEWyiA;(OiJ6Toa!?0-Tv7ASSoW8T{c)fdnjORJ2)-;$@V-P z?W+wtSFy6QSlptryL8l;Nee2UE81OQY<4CsS6RqwFMK0Q>8>>1^WFQ^AYZ$++J0Sw zvDU0F{no$NLR#|Y;1sInH_dK*-)B5r8oxDFWzF2qA*Jy>7t2g>yFYT}!$#Hz{p|KO z|FqQbe=nwu@sHN+3;DmtDyOfXs;<~m6uGhI{Qa54Rvq)c*~cfBpB<5j($Dem55KTv ztk1oF^E$j3tgVA(GpyBf*NwoIyO)mD-xT*af6^>u68%NBxuF<#GLr9*JaJ*rvTpo#7UZsJ4K=sg1p`hT$!?IkVixl=pVZLZ ze*-8)F>^RP#c1Am5DV~hd9wg1HqaE8$#{9q(jl`HGSmDHYGh}`n37T+XpV)ybbG5i zC4Kj7D|$aa&hAA<-RGIy2V*@iW+&xD?T_6CnUty_+xyEWgYQWZh2e&BgICWFfzPe} zN-B;>k~US8R)+*21KP9YpL#qpIJIWWI+raOT4wmf^MP-z=S*b|z(`r845zVYA!&ZT z!|V&Rv2#Lm+sz35GVB!Jh<)VzefH$U&9rvJ zv%93T58f|Wr0-@K>Yo(rX7Ea459xLO15m=AIU0_01LaYsyJl1`{BFlE?^Tyx38ETf5lrB09vm zELyJagC??>z&Wcnxs7zAE2GxhDM*6ni`;uXJTu|m{(RVLwR_}NyB1G4zOo|c7*rWD zpfs4JqMi?jxhApMGR)uSRs5|C?dFE966!Vz0g6jze}=6aRR&5Dk@>L__WhS8taNSk zl$>N1t;S!WO5lawFJyFvyK%?@{1qSbL-c-*>m0?~kq`2`YdHKSd!RgBy}-Uc=Hjpc zvNF@r=K+yNpA_4yZhal)eqY&&J%*wZ-mdt(WDj#EE6WE@`uaKP3`~b?(!ckQ2C&$v zL*R?W=|@yvNpnU7ur^h^^Gk1P18fHQhbw)X*dDuLDZfz~RpFz4bi#=31Q=D?saFUa z<&Xx3H?^>DA@BAfHmQP|B}*NC&!HnvPo^P@SFQZL+w7f=-mMN<{UscPwHZH~>z@C_ z?uVlN(sLG1y;=E=RJ@l17|njj>Qiq$6x8l)v%QslLuJ+1HD>y#qTOvpAGJ$qCuS}i z4mDb;7^i$$LIb^8*bded^vGtHYL!*010(AP@nb#{93w)gY zLY?M{vQK?#Tvic+IETHFqnT$Ln*1gHxcD=MUca#nZPAHsIDSRFf%Qcpse0{#fK2HYcGH)O@ou?bOda9fO|Ks{!~Drh8#p zb42P?NM)f(2I9-mqVokEdfU6#Wq82y6Ki_g(3n)Nh2;HL7vs2H#Go3wUb}zS>e%?$ z=856`l`TcxkNnP=It%E}_cn~TqG2;XA^cTL;<1@*!ggmUe=W(6F}-+Zhn@I@g!e0* zN^=P5OnawNXtTdKb0$>o%agW>Fy3-3Ar!enY^jmw{qU05OFT8+)HFE%%aj0%QTbEf z;WodvEdDm!WW1vP=={cYK7JqOEB$3udTz5!?48?lMcz|GT2EEun!b7HK3ICH@JHd2 zM$D)0V4KGaK53qwA9i~ZUKwjgcs5uD?xVfc<=$f}!)SwHvKQaW+V~8e10L24P>y^r zI&TTL_Z%4D*gUbff&E5(a_Z9h%k_s^CD3E}{$BW4x4j+M% z7D_r%eww{Ly{L!Jg1iSlYgt4Fo4LJbKEKiTIh;0dOYEqL`6HvTMt_Mwe^E@>PEhb8 zQ8%z{m^#L=`;EIq(5E9&hJWNE((ec6eSYXRCFY0`yXmehqwrbK=EJe7aEoKUa*sZG zZUu@5d)fy_ybN}Is^HJxxbWe)`}<3ghDD8$I@6ICM59z&KYe_lOq={u^{VR8L;bm!B@N}WV6T}L z!>Ja_dQIoDAh8?nu$HLDZF#W1H8ZKK7)Q;xJ63VY_v3H4#D_)11GD4Z8{_4htUgtn zb2KkZY9@ee6YgH|o>x#_s7`S2P2g=M_?}H%oljV|O*|5ixQ0p8x4fif5X^Ts*l9|9 zb|VQ|Au31}O&?4;742{WkTi5v;G7-&0u(Nag^N+)5<_sQZTKYsLRJeQXNNcs692n0 ziR**_4k1*w5vl-wvKkbAMk_%;HCYpztW8bUZG)>rqxAqO|7fM$--h3%#yr5LfT=0k z(3IZR6f*$wF#ur_9igFxw8bKA?T}GHNXRzw87Rd88uUa9A=m?V0l|ex@FOJD!E}*3 zLTEpbNMN+cYp96m5XujVcB7)yv{064l&c~J3c>_>zz>>ZqOcfGJ5(G19m~VWLlIBx zunAaHq8&Pgiop+IRfRC7ZkS70tTzZ34@yRpF}cwgDJ)iF8-wIwQJ`c(G>*tanRw&Bl35|VhyIKBtIN+`7= zI+aQ$bYkHhP-Is$VX7^4f`=H`_WN#!bEgtvP+}nnovDb;Z6oYxiS$z8Apq>2R`Rlz z_YV+}sfFiy;If9$vmoTw5N5|Cy&6kcQ%n_tq#KYC_7(V}A*e=b`e_>O2M-5VBvC+V zy;!1j49T5L>S`pFYhh_Zcm-O<4P5G3rL-mxiA*L6E8&3)$tuS!Rh97jJe)cX{|J&+ z0L?rnM!d9;sYlBk10fDAc|{d7o5+~-a7Dy74~k|qsdNXC zzw@SWC(9@#trnY|y+hH5=D$bhw_qtEkOCBs-~i6(_9*b76*O(9J;kLl!AO!4ppizH zjZS0ZGDpPxWU zu4tBBbP!T{Rfi%On)8TO7)>oeYn8LLD~$0uLWYIbp*aBi!p!J$k6&abtx^c6jBvCP z&#nN2Dk*N2PZcZe$d#2Xm4063sD%n!nW|u&vNw1!=tz~0P!(-6>7!0HwXEtis5%N? zea5N!pVI;fyVXhJRD=#S#h!`^{dfIT9GyxSp%QngiNe*)qqHo0T23e}4^N|rQ!|ud z`Mb1YaeAo^9W_F0en_vz(`j@%){D+=q1TBs8pP?$MHnlT(TZo_?HONl8J)X~E)HYh zC{6GsRe*nqDx^<6GEqI4FH*5sbD+3pOqiKOubB{M4&iGk$~D6_w1Xe0KXj+T%t`meYFG|qPOEjD*sFU%gEiJzN%ezL>p+OQ@e+gDE;y~T8ul*&?Qt_@6fw83G zSl{gHw3n#zz;}ucbp8nI${y=1g9X@YP?xATDQJ`ivTk`dg5qfU-tX=KS>|!IhxD7q zN1AXtth3&%7blv567{aIIuGxrlkJjrz*;Lpql#|Bq)wC5UhQF{W>W&|jzbIAu!;X@ zk7@&q^W(B+?VDchHR{4zL}7I?4)w5tR%7paWf(17*ZEUi%S&zp+^Fp`qcIHDjAS$k zEj6X>)qmhp(Xe1C4v3CotCJ}DFrrUOEi%g44?LMefiA8^-ZH*OctTV z)rjdHClX)KEMCBD-D_`msNsvV{@&xT4%7@YI_l``k=Bmy5}l2)9m}$vv#`z;!_KV_ zoqxeZmUJ0od+|SXyVilV3*NRHgsu&VuE#GrcJ{hP+Pm&ecL_Llvz5DV-tQKy>28Sa zzLeEnD%?>f+|x>LW-NA#-|snH!?`cfK3c#QJ4qLH)R(#Tm0D19#fM+3XiTdCvS~VB z?^*Yh>bAGHH+dG+4=|eBPBc3LJMI|QU%U2oQ{s|ZA;*Zp`JvMm=G}7(SO*&I+v2n( z71Uj*p{o}Dtz5(GJHe{fth=N5`waF6GGXoggyvV013^CD@UR|Ohs?Xt{sbTPLvCAi;h@iQo0m^p z?5K6T-r%Fr2C0I+1mgjsV`GZm@UHT=e{ZbH!7gvKwyNps>*(gz da7RW*zt;?63#+Fc$7(Z&=Orlz4hRV7{2$4Ao^t>I literal 0 HcwPel00001 diff --git a/winpcap/dox/pics/stats_wpcap.gif b/winpcap/dox/pics/stats_wpcap.gif new file mode 100644 index 0000000000000000000000000000000000000000..f65263185cae5433b2e49e312c3515f6ab39ae4f GIT binary patch literal 5267 zcwX((`6CmK5=j?Wl*@oPknPX$d9H}=p zcdq8jkvAcgNNhFV&*$&>ejY!(et7->S#t#S|#bUM7C@x6Sw_)dz5lEuz{ZnK<=?tPJKLudnpMWIDg z^+e`+>r*fGIt@8Mqpl7=x)P|oiH-0bAwJ|uS-0Ns7*lvc zF0#g}27X|C=o?}%=^-P{5u&TpJg=>JmW;UP&@Q-pdBj)P*T$eK;_!#Ez-G7hxF^|D z&3r`hMtj@n#$qoyUw5vJH@NVje|3icCvInZyOR=9%y9qB6$DDZiaDMtmt_5ypL_h_ zn`WnzB7G_rEK99HvR2acqpwpGPjsINlnaI|CY^nG%RW}A(r?!Kw6u2OohtzhIpmd7 z+GQx+32<(bpoNBahMv9OS+v$Q;!;-PqC<&|Asp+3{@WhllVr8RdHVRSi?dg*t#piP z_TwTyCDcRHy-z-t(ImC}8$~)5NPlX}LjIFUxycwCD(qie$cq089zc>?%ygy0#v##a za65?g`dX!B7{5iWAXB%xB3E7&N-QN@b9q+eUfNPo9-GYiwT_AckOb3)o`~aWL6FL!~RsPmRK7bm2N<=0$&${fZiWm^gD2GoNtsE7&9oKRITT?UV{^fu}tEwVL4>)DnadM=M3=h1j^v z=3cSTjmsSCotiD!R&)KNA6213bEctNK}gqB?zaTd%WcN=gJ9n3Tk#CNxxP*t{Vl9h zi0neQ=Bxeh4Qs(lY;XJOPwpMIof;tN8^iG%vsccvg?(#&74xYnr^tX;WqIZgciP+Y z&stMNex=0`qKgkQ=(fKHPufgx=aBd-c8>DrWtrQ69wG47nB|e5y`2McLva?Wk4w15 z)S<1xr0izMFgs_u!hN!(Y;#Sfd-^ z8EH3{&p3nvO>P8d!ms^yE;KQrxprxaP!{zA#9>q8iESfc9)m) zGZG01yP=Y5e6K!?xINk&cruSP>qJSTlqBxGNbv^0LrD`u&3^;TgDi z2P<6|$@VK18E`CPKDk%l%PTW)H)Z}yjj)l=Zb;UM(fL1c-}V6Ah?n(RZfZsq{U;Ao zojvt2k4Gh$-MKVWlHSx!@AE8+M{D^DQn|%Pqq8Ga)$nWlWxOs-lAfS1K6MChzTE&Htf2e*4Jz2Wl6hND!+5cbR~(_RG@x34cU@!rXHn*U}1w70)LO z2@g8bgK=ZXei&+1r|*fF z&%>Iki6)A=>AKs2RK6B9^g-O_Mk(NX zT+b$P56APgmeC7m7nx6ARp8uP;!YhG+O;zQd~8vJayax0;_tW%D?e`KpI(^*U*E_J zC7o_w?0!?&dy3%HB`{TjvhBpo}_pF*&J%Q{2O5&)I>X3 z8<=JbWN+;(zggTLCMM&T%&A~~{vn%>uR`J-3Jig)lGgDU?k~ptP6b8x7kR@nVVyqJ)D(n{@(wJV zE85V7b)rED2zRTex4@j?A*UpYjoBCN?^Yalc;iH!PvFYBd+#(Y{@l)w zCEjGrhd6`%kD-4b&Z&QSNxyEe7Hoi~%^2Kndn(Gh(&A(|T$iL*V!^+-Jv6nAk%@1< zQgopzLjThRPu}XozP(=I+3z(O1_{2lam^{Wwzb7e`fY7vK0Zt!2zS44Nl}W7EAiNB zc&V_^pq$WT{c3$e9Ut+XU$gTiE{NCjEnzxcIqy5-)$gmCo%`J=KK0wnKXDlA)%o3XmGj@$W_uT9n498xtHz%bUejM zPXs|B90>odHZ+|9MVdjZ1d~!Z&}<;geh(@x3(LjAvi)EupfKDX48npP{|tLz20yGK zQDG+W5F}v(mT&?}P#Ey4JqZ#3L1V$2p>S^vxR@Wj!7QzH5Aha=u+xBa0FWL~Se6;I zTo&2DK~^vjPJ*yHD6;Bv+IuL9%1Mj&Lw4_>ra`bt4fG--t&Ne`3qXAUBIiJ9y$sX_ z3%LM9{tL|5-9ux5sC*D=hJ#-8gV(Y$wy>ywKf?w5CBA5&lFd+#L^Pj){sKVk0W-u~ zkVj*(s)=X`cG@a2aSf2M<%jsWhh%~>cQi7V_fUfx*|WrqLXFHOKR!adC5r>hI_jS# zt&^>7p8ee~r{Z&V86ZckB}+pNWq1JzjLG-}%CU^etpen>Yvk&!p>7rA&H}TC%yQrO zVJ?_wfH+ylu;>~h@}XQ#q-^F_BBBVJLxE zVhAz@pmE*@bi7gr$`V8!>niX2w7`7I@&W7!I=c}J>CmAJ)v z{>6WbAXP;a4I!sT$Gz|FTAk{%4>Lo5I96;*Dx4`m?y`~d`$g9a%4OEkHv-Cn9X+cW zz3Xxe55~&8w#%eo1h?uuVfojG;N=c2*~hqficj7vC(x_TPP%tDda0i!rs8mrK6|LVm&&g9xpm(R z9O<|m$?G~vSK1rX_e7zBRF2Dt;VO)eE0D&$9!0x|KdP?B;j6e0qLy{qZur=(R7c8_ z%XO`oY%*@0eC1e8SG92=HkE~|0hAO=l-Vtm){Mwgu2zs&garxIaadpGKZne}3bx;nXl&Sc+>>3S*Gh81pobkijp=>X}O24x;aR!@f5SEG~q zOp@22!E5+SLH>6OUmj)Ry(V({f*wtoNfjTZdYjnwL_A%Hr2^upf?brm3If9KX@|oo zhKNREp2U=HqY1O|$otxx3cA*GnvRIe)R^nwvhzr)_4L%Gvm`!Mi%uW?1O&*R;)COw`aIMN4YOv*S*zbD!p;Yx=yDFK0u z2+igYJOgRjoXcb^$2Lb*K8fWu$GMX7jOMJTA_oc*-@*|gtBal)@%n`w&TejO%_k5`b}qC zjgF|c4I>)u$ZZxI?diSV?t`&}WJ4**^&Qss>T>T0kol*sweo3b}^Ier@v!WLB+${a(Z(1eq-5oLN zJwl7;%~E|)>Rr8V=Xm;`xVA`3dL5$s6XH$SK&PBo@7?EbMHMR+?WLWpXfNaI_}G5s z*!ateyx!Hm9>|y4BrR4cUiB27l_^$__#Km=$j;NM%^}3*x3PcX*dx8{*EOss`f(V= zzP|{pqM8>Kip@l;-f#kyr2m49>=JVA+Yo6v8(-fr5KR;7I2zcm8{Z|$?Dzf9&nEY< z;#vP7-q?`4BYt=J%?#Y(^&R{DdPk(L*{!XLIcOQ!@zL#F*g%I+&ESGoA6T(q3paRc zwoCO(zp_{hW1wScc4*gPU>!dARqXA6CiD45+xME*A2kCIl= z7?{=?8rc|__#NMk96muAHV|vxj_=s88dfNLFXu^#ico{R-TgElAClW9E1 eiLkkb-n$dEP{ z0UnMX9>+a#+=u{=fPj<61e}Nn2#ARYh=@2TCE`R(L7z*X2 zIg}Hr6w2`^NTsBvQgTv{$BCTO)ZdKqzPR2mpiRQYx&bqpR=DOzQy3Xd4G2VQl zv$=Voxp};^xwEr*pz~zRbe>TgxoEhjG80Z`yI36d)2L_JE%J{(e_`uBg@i;Lv zKE5(DJ~MON6UW_JnORvm?up~>Z>?-?9rwik{_&mo`SbWr{P*AS{lEVM3`17W$^d6` z*-8y<w(F*d406D<1lQ#zdX8<%2LPiZm zbTXV%)_JI*xHkbQW>R3(Skj-ur{uph)L1&0f!0eFGJaY%oGoo#?L7Rne1wMecvWEh ztYR!*CF0}K@UzO-k95e)!X`~slch%4vMx6xtt-rEib2Uk!#m}s4{|>*ZG3w?`{Y5Z zzi>?^=bIYeb73y(+-s6%eosuiVkY)%&4Ms5@8#2KaW!FJrU8my@YSxw-G>H$q^XZC z-r=*Yru=NEG!GM#VgB}kt$3Ky&%U9YTelgTGAY1Q#~r$0oWP!xXa3^4pe|(sb)lfO zMQ7AkEbOz{-?1VCs`S=!%v+SGdcXQlT)oEryivxxIZH_UQ>Ui54~$xe_k$eU&8DQ% z!Z($p>B6e(Bd^^`U#1D1_ul56l6YPA;$GngL90-gIG4!&X5irI6zQ#D_i>E9kWe%q z2;mCmPb?CS$0roye0CI8qJ0X0i3zpbr8bb>^^Ca5s8PzDGSidWelww*WFf{B>kF+$p;wJNwLNyz&aM;V;G zkR+ttapaz=H068xj_NwRxA5|Yn{kv3Ool7;z6N4b@bXd-M8K!y{8Ev39~QzF?L5ch zjQ1zOMA&Z1P$g*)QOP9FVmL0`!wKFb|6;~y&K6bhP%afAyr9-sIqWM151b2w%nmZI5iIFi&3xC z_m{By)JwG6A6%xL;x7H{1tk3${pFa+`T($Mq`oKNP3MiGe@OBDeMP+JW`H5H!>N@R z3%ekW-?KG62i-f>SG#d=$=U{8)`J&au?P&Mn+_G7yQBX3Y=e$rTox#A-}wuV(FO*I z+8sT`N@x<)*>!b(Ou-0=6~nnM2c-Te?eNK6Ie2eu*4Iwp%QE8KRtQrH zCxu1!u?>ea1TD|e$&Ow1wLG$iE4U?XU;6;TY|~%YM)I54=yK4eU6B>M10NAoNxWb2 zwyQp=>tBHV#Z+CM2>=uG+8Q;10v4D6#LFEWz!b0~gm>CEdTdi#WLNZ=G^mcb{C{En7N1wwA_&EUQuUpNoZZ+w37s50xEu_ z1LHIjWD|xyRw_2eT)8GD&RYByV-NIpWs_o;9k}we-t(OAZL*{7k>Kd)GZlqRFY_P) z1<3sQG#Hd2?F=!IEPjB4G>OmIdpvD1=*BQ##M1xyN1uiNj;syHl=Gq&QIv0S7KqxC zz=bVNuVW#y#a@83#(xA`c%+yV%l$5UrM%kKAr%pZYFx|hofg-xM-+}BxF(Ar=$HG& zdA017Q|}u2M2c&in&1ogpR<9d~bRq^v+F`9f%O8p7(nBLn zbS^E6P^=~=cQm8C7FbI|)7~$n2%2~M=noJYW#43AG!VO+}Tar~x2AJ@orR_3%u0dp>e zEmRoQ`nLZ8SvxW@4NY+x?i zZzR*IwSR>efNhG5?QvS4s!8S1gGd2&_pwO>AajB3CCiKjF{^?GMD$Goi@4_`!Iif) zrKQV!fEmSSl1)KuozuQh@AFPO`{a5>g!rhBm)2_Sv&C)Wv*LnKk-pvNN17;c-b=&3 zwb;CMO-Wt9RrGF1TC^CXwm9%USn5cXa^%B>nc{5*&Uj|Nc&F+2HJI!&PYwF7ZRqKT^& z=)brt>1gKt7cVL$()T^mT59HSRoRa;VAuT81krSQDx&oeRxhCfA zMk~5GH+YlnThKBSYF5cD#m8-Sz@)N8CUGk!e)bLxd&`5WVt+yRC+!vY&I^ex4d=xba ziVRA)>wEw%=e0B1w0b=&FWnH@Jd5ncgO&0 zcU4y$8yDnkN3jc|99Fv6dtJw~QY~muqssq>zXVL}G}(O8iO-+2@<5 z)(@ibhs%;iNS|_v@A{-a12SoZ1dju7wEZP20Dfx-DnKycj^>QPBxYBD&Op7QzWEl+ z#J%ECrzZNP=5qMY@vBe7A6_FDX2xtqCH1et9&>_#2|k61lt+niLyhq03Fy!u)L;T= z5TPueXoIIGA7z5mtzzF=+6H7I^uiIdmr~@0{I_T+JeZ_@1*oNc5;*hPH%jU)Lsi5U zESQ-5=lYeb1d0^E*Zw;b0Sh_P4Qza-mSs(R7==hc2D+p9P%?a^25@0TU^I=qH^dQx z!K{_XrA9OJ*1z zWeq0AYm4HdyPfqWz^cl!K8jJ7H>mU<@&{Jx;Su_;`@QEXL2MIB2K`h^ehyqbx-&Zb z{$wT`mGM5D8(WzXj0SaW#qW9}&gD^lQh5Em%_$I_jJKScZHkdQihtglo620fbt5h0 zdAf!Sx5rv~p90L5=I;!#zAKFsRT4_yfg!9Dp+MfWgRG(|%G8&usoocbMWaIbX%xVN zeRrB6g;vgQ!A3CC_(8@s^4Z)g=wg6VL$Gq1Oj)6P!dgh|%)HCToO}b1dr*v`{BUZ$ zQ4(L4bGE{x_AgSjh63SBv}=Cq_i|{H{jmf3a;tMUsuOwqbRdpc1aD{7`Mpz6I&Yh|8C4YlJYAWs zoQwK+UBV6rIkgI4p8!UcdR_djo=AgqJhofnSDBCIj-wX0?VL-#!H4HSocjgcajY(gI9)8CEDE?^&E)n z1f~SM<-2Tw`NwvTIe2SGCA$(8kv$*|ERZV{=v4}Qs#f#N@xt@uDF0Hm^IWze2*vua zO3Ffdxj*^_zV=2a9H#hK<0F7=0w61Sc0)RIz_E6xOt7^A6~mz^htCJZMSC3B8Nzro zvhxF0p|;E^%K{1*W>9plG7T%9T6D_}4NEsfUJv7@bVHqrm~JU@XAFoYPQd)J4J0BQ z5F5tLQSnO^EQJN!$x&JjMQbDq2()KR^<8~_buf!Yx; zZCL^&G|U*^Vn~1(P+JV}Oqm4ltB!#`{lqR#HTdf3?THyD=C>yAY8~|6w>+pd^g$Nj z)5DMuGyo(*Z4+*2JBx&6PCPl4`P82X=0XEeNT9snv+5V6F|r``^Vo;t238Y57C_T; z^(G%Opgjg4v)UG8^+*ztgt_?GK2EjMdg!bANE+nPw~6~7ym7UCKM zlk^yWx>U;`Ai3^X2#kh`QcudT<6u$@ZKKt+6TL2gVAQcK9ZyI3tMPPqE5QjG- zX8GlazJw*2bX8INeDV#9Vi*72x2EOG128*azokaM9Uk&TP$qQ;>U8U+IT50Ve4ee- z;!yyJN@?+ygS=sd{s;EH_?I^*RcwD4o7QiZ#xuUYWLA`qOu;aT0)|KhZDg|{;RfJ= z9JGMHnvQEvt)-{44x@#7kQ4Qx$jkQ&dd{#m<+Jt{{vCeQ0ZwQbWFIP&Lb_W?J1wT5 zEmGny*JdnDy*`|??p9!Gb?(e-H_@uOIjWawS6T@WbCD-5p>q$;;LgQ_f3}E9hzEe=ogn4XB)j7$D_|es0=hin4@0 zpm=)G?OxO6Hx_4yEYH3@NCoHC$)q$w9F~XD1A$)FKyD)NJQ{p%q}}x_)h%?`!+ZiU z0l@C|z|QvircI~-bP%;EHcGQ0I-omg7eyIdn!~$&3pKN1puDDA#f4ucXLfVmSR>-u zMpcW_GrH%}KEXPL<|mxN!Uq5Z9w?zRe=lghMl;Ioqdczj_W9~KUj?X`&H{-Q)cO|S zi9}pR(+@g;{8SLy&g$dZ!jrVu0y;pS?3z=+xhXfraVUKfHqZVHF*fRJbHF{{TyUl0<*qsqf^Lc zEnyFZd!eDJ1SYFsFe`rZo(?=UZPR=emfXFm>;k?T+?vG&3dg^DpG{b5LH=@)Dr8%K zo6Z3hWfDVfg|mai2p1ImLFvS;syCz=-X}4Ap>81i#LgoN07vLMll;qFC}DkUGwQcte^mw{P}Rd~3A@L>}WcK^E*q{R|5HsS}&oy5c z;>efL4kRJg25G5>y z+;?M~{%*aG5AVpkTjVWRzc|LMUTt6!?0GTrbdwJ!Fi+cPX2VFw6U1>a44pWDU;(1Y zBcWf`f4(V~iWg@#lx2Q|tt&|StRAv}k$Mw+)fB&MsmpotF1pIzqr8c(9aTmL#NITy zXf*#4s5+z<0P48oqARPQvu;Dr- zWT;Dl{F?lhz>+G!CR*nB_G5)9#XE4bdfoGt_Pq8zG zYZf0MRZ{xWzr%N|M4*i~B#XLMczlqAaj<)(%S2o=j(n`(stbg4L9lUu}JZpnn z)=by9JWT^6Bl*DJT~w-o;=8KFd2{H~sWI8cP!2uRV=;I|!K<};(iL*LY;DuJ|CuK+ z)___Lr&`%YqlNI@I@CtV846!)PcL$e=NFjmw7m+B!o=6$+h(BgVgorKKsHl+wbx^M zQBS3JL1C~g63()?(Lk)xc`7mjqfl8H5y zjjTTexL?fo?``Sm;`G-SV<$dqqFm}c*}t&6fHl8usO?xitq4kdY210_Hu)DBf3EJo zs%;yC5KYv*ihRCNIx$(d757$F^`rc%=|^g_49^w3sQ%rtp7XO@4EocrSDSdMafSjn z)WUt3O&L{VnBYXWIKhM8;l+Ab-!I0mo}14&eeMyaHHCNDq^Z}=1V!03bUI}}(YC$D441t09TDw0RR(gp~C3X~*7zG9NFHV~3ia7YD z52!iNts=tFhl_xB>_Pi{ZNCzPY?`k1J-W>Lds^qKyeYekNeg@*Miaj%X9`O2&goExK3*YDMC_`{yP=l=aFi_fi5!mn!GZhCd_k+u+&U2l?Ak}Dihcm9JT znPb%juH3Y9+fdo_nTUVGCDBif0YT#AcZ1Gea6>uF)yNp4+vgv+Z--LIyoQJRruT{ROG^q8>r7^Zrq zGDqa)R-4I~s)^!tbZZK$z73%T^+Snv5IzjsFqpr!_G$wQX2QMAw3^R6N=U5owOV+2 zY@`L|_Rw0ha)XFCLNRf@`l0M(oW7lWX1?ag8;MZD2#`PwtEFt&YJd!Ww5=g#Aa6?t z63u$^)|3f4qoqf@=1F)UNYibJ7nj?nX5p64oVq2U(=w=KAxERy81WZm;Y2o8K|Vj?Dd_}8;+%AcqO$d*FY+K=l+w`}(uO;^KR4_*{3=wdEX186~v6cfxKcQ`Jqb5=%dxz{2RBVRmj=*OQKJHSDEfz!lX=M zJh>{Lk##Qx>dUzY3q$kmdcM?d+MLnHgyt7s`6f$tgrI*YKWvW&vS&xzh_6i8CI0*V zBxswCCd4Qhd$AH-V%{-T8YJfG0-3MTjqCzU913!}Gxjo>#ix55UVqVnfUU%NLaGut z=>XVSVxawsiE`Yw1&o%shUTMJhj{7sxZScjZ9@cdZ_st^*(9K4NN^3mC@OcNuf@?wMZ?5IyeXBHok*jLI$a_RE_`NU(J zY`h6*8%q0Wc+R?1{&BV4a8e+%H9myb3`yQtKSarRP@OG$mHxB1X`eyiTJ&!{txZ>Ml2vpVT8{k9|?0AZ{_+w6`dryMoukD&j2=aNnPeY_7t?x_f# z)^VK9EFy+U5f@8jXG`P}kVxSf_)E7a7TyMO))@AYB$K<=+P`;?KgQNx?BW`MFFn2a zwg!e@^m`g()^lpY$mX=v2CDiG?#_*g*kX|4>s(XUddT0{(*P2AnsF%Z^Nj~dQHNWh zql5rq!I6V&h}}E7Fb4a-VAdm|s#!S7Q<@0T+E73B=R;K2zs?YTn`ZxSkwZm! zqFliI?91n|yj~afG#?W3>VhVv)OY8Fn^vbyjK(%a`V&R%|18YS(6I`4&X~bd?AI#P z;2NtWc2AdG2PQMv5?hGg2%6c!9>V@HC?v)d4GKumSzKoPID7aUcy0(RY=vrl2ct>B zb-ICnKSzNft_OWd(_F)|fD}&6HzgvT60E?4^yw#0bXO5zK6EUj`0qxOR$z`!ZB~H) z4^*$wU5o{D9VL4{^4-HPD6MNh*zI+8$R5E>MsakOTmQxK92IGT#un{m z6~OLEMIWzp{hn!N&+R7un~I=Cj-#tE5USn9u;YJYdqUhn2j%;M9??@A3wqQSx9dZ*;E zJiykG+Ap?&64bsm4zhz%tqcI@ z-%bnyc7kGs&#yKs6{zy(R{1=Q)pREcXC-NLB%2{Iz+FAzOOp?}C<{N0>dh@{=KiJa*#C&9c9gXEr#$fTWXLMxFMU!5==!p(|@N1ExPgVVH z5-ULH7F`8ceUvo=P-KRZM01JSB{~{O5dS5TgNBm9mpm!FS_njoqlpFdO0GoVr9lx* z1et{*Xc;)`^S)_k&Sepsyf4JToGJw3nIkqm8;p6=*SOYq+l*U>zh_>$=bMs&jSv7z z1i%h7D%LKvgJ;Z=H^^dA38h~p5B_N~4tkfi*-v|yqs{#^Q zB_g6tALasBj{w{g#Qrtjj#6!-=nm;^5_c%igASrz4A17R`=X5+BQZp#IfeUwJA~=T zs-#i&ZlVwUrAZTRIyzOPspCCrENucp)EHsH17N;HCSUdG=+{4;)qm~j_x{yj4%6La z7Qym?PIm)&h~wK3L*xicrZbO9BIxuSkiQ!MsADbKHr*kqQHMb5tiTE9ai28+wyY>a zWkS#%$f;wN5;%r4Gm(VH3K4)UwFTIG*+DW`Lb{cuAMbnk;2mUqQ1IcY^FS6`i=)4m zn;QT&w#koYB*vrjQ~yqgbP`VoSxMb~%~S-4@?-$ubB*`qUVmLuha08$k;bKhrdTyc znb^cj3q~lv5>F>hu5(TGHub-RujAmZLOQ}6FC-N#2e+z0g$;V=}eq+v#m)Q&`BH* zeq&=v#@w`w#oNAhinI;M%aiiwTx|u~3WMIybHLS2K73@u4#nQY*oCLXHfHzPHp(i0 zXTwql>!)nW`p9zdbmO`QR*pvPdvC%R26lJ<*+mAu&2^hG4`S2XW>e;yy@?Tt53*m! z*@fSpG$%QqWUUhLm2obr#%*F!EwJC!_yAJGmJ3_Wwe*s6c(%KAOlrOfKFXsMpRC19gODv2|I5_yTv4%N|G*aQ*j<*(A z$Cj7If}C1{5F@rr;kwrRpall_&qMR6)UnMn3zSO(+v5EL)0x8M`M1s^omr#)+~qoZ6fnU63$^0hNrD+ODB>HHGi2QO{*i5|@zTCe&Kf0Vc(R^+{ae48c>zp6A z+^?1Wt{To1=ohP{^i_f}#+SAX=o#6s=%gRcHM-)Qb~^+z-E@7UFUV^_Q6k}C_D zpJ`}scBYxeuKc_AZai;gwm&PR?cP5E;d6gBXZ|XW%+=_dgp5SjsR9D~ovWI=1a^5X zq=*}53h&>04*{?xrO8nNF*oQ191DX6yW=Kse~q)oO=x_Lg?)`jZv|Xr-13DWEaEOI z?=Gh0E`EXjb>js%5io7SaF30$zXTI4<0xXPhAmrZN>}r zm!-O{o`%62dAHe`GypI*_e=GjrY}9!;y1Llh-P3&KBv1GyO(AB`=)tM3s=<5$LH`O zURQ#>9njYE>5iM>ceVm7 zSh~J{fQ62fCuv4^kNez)6&tC{dt4w66Y^wIWTRGm$k)Bha<@F{TXW{g>Dz=A zibmoFSf%t2(6En{nOD{~iLq@WlEQN2@xw+SXnx!4xg*teC-8Hk0T$ThF~03-Tx9>D z&&#hMeJe$mjFBD}Xr3}u`;uUPH_10^VGjQ0gvxq<=Zbj? zZr4#G=Zxq6PtrYF*2?}%TYVxQpgXg?`^o>A>#lMI;rX3_*7Sh3hXL*NyS(gh06_hJ D9X7K5 literal 0 HcwPel00001 diff --git a/winpcap/dox/pics/winpcap_small.gif b/winpcap/dox/pics/winpcap_small.gif new file mode 100644 index 0000000000000000000000000000000000000000..42b3adb6584302f3ba39bd8b002b04b72408a076 GIT binary patch literal 2160 zcwX((k5kk49mnx+en1iyAo43wDGiVx5Sa}qEzvTP@GD87g_I&9vLt|rFasn?SX>*z zSCY`!3tebbzF1&xlAs{3Sg}&mzS4g1+dmvl~+|^1+Z%BtLp1P_4RshvR&1bltKDuz?AQPhyB!-&#Eu|#6amAH z04Rbu5yXumP88IG0!|clqo~J;I-RK735MSZxSdXq)9H6R-EODH4MxBXc-(Hk+a2(@ zJs!8;1IC;O@OwM~k7v&B@%udiKQ@4X-;a%jfIkrM&jqjn%mo4qbAh=ztN_;Kg}H?V ztN_;4<%Q*Ctib9jcEI!J*a0tIVE2FjgZOP;wmer<@|OGnv*dUUGhbR*#MLlM@bAXE7S$AaB!t?rb(mPU<5E&exhrELV>SDIHN)_X z_4J%&Kv38|58HhoUkraSeV$K@_@PhN;VSB9Icq!UZ)`-H*GGj{VmrrD6Y*gUrt@oC zK5g;`p$`bDx$=H|K)s^w+@@Z(bWJKAsrMq!Cu0Nby#0xl#uEc0!UA5={Ms)s_22(x z<><_XvhOKVm&jJ#!yx)!a-V(}N>56k;cV{w$2Z~|(b3bpxm)o?oNs$;{S1n?pGn^n zg~k+^LbcL&|9#Y~{C)2x+#ywep?qlmTy%AUn7KxZEpSBDv09SKk`l$8<5${EgUUfz zM!()v#;LNV;tsvn=j%RG>??8{+kEy6$*vVI-8rs8SETVLU3_-_;SSp@TlvrYB2L{H z<4#G{RX)zP{D*0&IIr>v^ebkKs`}$#%e{e@)msV)=j5=@&~k~GmKTv(q4Gx`DQKZY z6+PAFM&v~)&9-gFl-5TZ<@M*py!WY&LS|}be19egWFjIh>ajPdG3TlQAHp(tai%E; zEsv}HXcxm#&Fka#Sl4s$ibmg!=&YnB-e->CuTSg{ANT!sc;6HxWp^u7uQWK!kdgG| z$;ArEnIe9}6|HkihMqeLj$#_w6` zyh+H)IwKu9aL8z)5~&8#V7ElDzN>V1Uyf%%zC%10dvra$ki~sy80Wq7WHMYac*^pC zbTegwaNIB|i9uV6MflkLD;7eV=D~39{C3wy=#SB(lthN0g(9zQXq}~3x+-VcC1;$o z_oc5JS|z``q4?%Iz8Cq4%!YLHoC{?_AF-MO|EwD0dJq29K`j#f6s&xdH*}hL%4c@y z9tROTsTTSW6!cp6SJ1B?NsjC_Tz^BWJbj%1NOqY?KT)Qt?5h|Z%) V=5O(+=T_jW$+tVhSWE~y_+QdsUAX`N literal 0 HcwPel00001 diff --git a/winpcap/dox/prj/winpcap_c.dox b/winpcap/dox/prj/winpcap_c.dox new file mode 100644 index 0000000..108ab59 --- /dev/null +++ b/winpcap/dox/prj/winpcap_c.dox @@ -0,0 +1,228 @@ +# Doxyfile 1.2.13-20020210 + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = WinPcap +PROJECT_NUMBER = 3.1 +OUTPUT_DIRECTORY = ./ +OUTPUT_LANGUAGE = English +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +INTERNAL_DOCS = YES +STRIP_CODE_COMMENTS = YES +CASE_SENSE_NAMES = YES +SHORT_NAMES = NO +HIDE_SCOPE_NAMES = YES +VERBATIM_HEADERS = YES +SHOW_INCLUDE_FILES = YES +JAVADOC_AUTOBRIEF = NO +INHERIT_DOCS = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 4 +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +ALIASES = +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +OPTIMIZE_OUTPUT_FOR_C = YES +SHOW_USED_FILES = YES +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_FORMAT = +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ../../packetNtx/driver/Packet.h \ + ../../packetNtx/driver/jitter.c \ + ../../packetNtx/driver/jitter.h \ + ../../packetNtx/driver/dump.c \ + ../../packetNtx/driver/Openclos.c \ + ../../packetNtx/driver/Packet.c \ + ../../packetNtx/driver/Read.c \ + ../../packetNtx/driver/Write.c \ + ../libpcap/incs/pcap.h \ + ../libpcap/funcs/pcap.h \ + ../../wpcap/libpcap/bpf_dump.c \ + ../../wpcap/libpcap/bpf_image.c \ + ../../wpcap/libpcap/etherent.c \ + ../../wpcap/libpcap/gencode.c \ + ../../wpcap/libpcap/inet.c \ + ../../wpcap/libpcap/pcap.c \ + ../../wpcap/libpcap/Pcap-win32.c \ + ../../wpcap/libpcap/savefile.c \ + ../../wpcap/Win32-Extensions/Win32-Extensions.c \ + ../../wpcap/Win32-Extensions/Win32-Extensions.h \ + ../../Examples/pcap_filter/pcap_filter.c \ + ../../Examples/misc/basic_dump.c \ + ../main.txt \ + ../wpcap_tut.txt \ + ../wpcap_tut1.txt \ + ../wpcap_tut2.txt \ + ../wpcap_tut3.txt \ + ../wpcap_tut4.txt \ + ../wpcap_tut5.txt \ + ../wpcap_tut6.txt \ + ../wpcap_tut7.txt \ + ../wpcap_tut8.txt \ + ../wpcap_tut9.txt \ + ../doxygen_groups.txt \ + ../wpcap_remote.htm \ + ../../wpcap/libpcap/pcap-remote.h \ + ../../wpcap/libpcap/remote-ext.h \ + ../../wpcap/libpcap/pcap-remote.c \ + ../../wpcap/libpcap/pcap-new.c \ + ../../wpcap/libpcap/rpcapd/fileconf.h \ + ../../wpcap/libpcap/rpcapd/fileconf.c \ + ../../wpcap/libpcap/rpcapd/utils.c \ + ../../wpcap/libpcap/rpcapd/utils.h \ + ../../wpcap/libpcap/rpcapd/daemon.h \ + ../../wpcap/libpcap/rpcapd/daemon.c \ + ../../wpcap/libpcap/rpcapd/rpcapd.h \ + ../../wpcap/libpcap/rpcapd/rpcapd.c \ + ../../wpcap/libpcap/rpcapd/win32-svc.h \ + ../../wpcap/libpcap/rpcapd/win32-svc.c +FILE_PATTERNS = *.cpp \ + *.c \ + *.h \ + *.txt \ + *.htm +RECURSIVE = YES +EXCLUDE = test +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = ../../Examples/ \ + ../ +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = ../pics/ +INPUT_FILTER = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = docs +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = ../footer.htm +HTML_STYLESHEET = ../style.css +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = YES +GENERATE_CHI = NO +BINARY_TOC = YES +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = +MAN_EXTENSION = +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = WIN32 \ + _DEBUG_TO_FILE \ + EXPAND_AS_DEFINED \ + EXPAND_AS_DEFINED \ + = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +TEMPLATE_RELATIONS = YES +HIDE_UNDOC_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DOT_IMAGE_FORMAT = gif +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/winpcap/dox/prj/winpcap_c_packetdll.dox b/winpcap/dox/prj/winpcap_c_packetdll.dox new file mode 100644 index 0000000..ef0a1ac --- /dev/null +++ b/winpcap/dox/prj/winpcap_c_packetdll.dox @@ -0,0 +1,244 @@ +# Doxyfile 1.2.13-20020210 + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = WinPcap +PROJECT_NUMBER = 3.1 +OUTPUT_DIRECTORY = ./ +OUTPUT_LANGUAGE = English +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +INTERNAL_DOCS = YES +STRIP_CODE_COMMENTS = YES +CASE_SENSE_NAMES = YES +SHORT_NAMES = NO +HIDE_SCOPE_NAMES = YES +VERBATIM_HEADERS = YES +SHOW_INCLUDE_FILES = YES +JAVADOC_AUTOBRIEF = NO +INHERIT_DOCS = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 4 +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +ALIASES = +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +OPTIMIZE_OUTPUT_FOR_C = YES +SHOW_USED_FILES = YES +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_FORMAT = +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ../../Common/Packet32.h \ + ../../packetNtx/driver/Packet.h \ + ../../packetNtx/DLL/Packet32.c \ + ../../packetNtx/driver/jitter.c \ + ../../packetNtx/driver/jitter.h \ + ../../packetNtx/driver/dump.c \ + ../../packetNtx/driver/Openclos.c \ + ../../packetNtx/driver/Packet.c \ + ../../packetNtx/driver/Read.c \ + ../../packetNtx/driver/Write.c \ + ../libpcap/incs/pcap.h \ + ../libpcap/funcs/pcap.h \ + ../../wpcap/libpcap/bpf_dump.c \ + ../../wpcap/libpcap/bpf_image.c \ + ../../wpcap/libpcap/etherent.c \ + ../../wpcap/libpcap/gencode.c \ + ../../wpcap/libpcap/inet.c \ + ../../wpcap/libpcap/pcap.c \ + ../../wpcap/libpcap/Pcap-win32.c \ + ../../wpcap/libpcap/savefile.c \ + ../../wpcap/Win32-Extensions/Win32-Extensions.c \ + ../../wpcap/Win32-Extensions/Win32-Extensions.h \ + ../../Examples/pcap_filter/pcap_filter.c \ + ../../Examples/misc/basic_dump.c \ + ../../Examples/PacketDriver/TestPacketCapture/TestPacketCapture.c \ + ../../Examples/PacketDriver/TestPacketSend/TestPacketSend.c \ + ../main_packetdll.txt \ + ../wpcap_tut.txt \ + ../wpcap_tut1.txt \ + ../wpcap_tut2.txt \ + ../wpcap_tut3.txt \ + ../wpcap_tut4.txt \ + ../wpcap_tut5.txt \ + ../wpcap_tut6.txt \ + ../wpcap_tut7.txt \ + ../wpcap_tut8.txt \ + ../wpcap_tut9.txt \ + ../doxygen_groups_packetdll.txt \ + ../wpcap_remote.htm \ + ../../wpcap/libpcap/pcap-remote.h \ + ../../wpcap/libpcap/remote-ext.h \ + ../../wpcap/libpcap/sockutils.h \ + ../../wpcap/libpcap/sockutils.c \ + ../../wpcap/libpcap/pcap-remote.c \ + ../../wpcap/libpcap/pcap-new.c \ + ../../wpcap/libpcap/rpcapd/fileconf.h \ + ../../wpcap/libpcap/rpcapd/fileconf.c \ + ../../wpcap/libpcap/rpcapd/utils.c \ + ../../wpcap/libpcap/rpcapd/utils.h \ + ../../wpcap/libpcap/rpcapd/daemon.h \ + ../../wpcap/libpcap/rpcapd/daemon.c \ + ../../wpcap/libpcap/rpcapd/rpcapd.h \ + ../../wpcap/libpcap/rpcapd/rpcapd.c \ + ../../wpcap/libpcap/rpcapd/win32-svc.h \ + ../../wpcap/libpcap/rpcapd/win32-svc.c +FILE_PATTERNS = *.cpp \ + *.c \ + *.h \ + *.txt \ + *.htm +RECURSIVE = YES +EXCLUDE = test +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = ../../Examples/ \ + ../ +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = ../pics/ +INPUT_FILTER = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = docs +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = ../footer.htm +HTML_STYLESHEET = ../style.css +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = YES +GENERATE_CHI = NO +BINARY_TOC = YES +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = +MAN_EXTENSION = +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = WIN32 \ + _DEBUG_TO_FILE \ + EXPAND_AS_DEFINED \ + EXPAND_AS_DEFINED \ + = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +TEMPLATE_RELATIONS = YES +HIDE_UNDOC_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DOT_IMAGE_FORMAT = gif +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO +CGI_NAME = +CGI_URL = +DOC_URL = +DOC_ABSPATH = +BIN_ABSPATH = +EXT_DOC_PATHS = diff --git a/winpcap/dox/prj/winpcap_noc.dox b/winpcap/dox/prj/winpcap_noc.dox new file mode 100644 index 0000000..6de5fb8 --- /dev/null +++ b/winpcap/dox/prj/winpcap_noc.dox @@ -0,0 +1,204 @@ +# Doxyfile 1.2.13-20020210 + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = WinPcap +PROJECT_NUMBER = "4.0.2" +OUTPUT_DIRECTORY = ./ +OUTPUT_LANGUAGE = English +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +INTERNAL_DOCS = YES +STRIP_CODE_COMMENTS = YES +CASE_SENSE_NAMES = YES +SHORT_NAMES = NO +HIDE_SCOPE_NAMES = YES +VERBATIM_HEADERS = YES +SHOW_INCLUDE_FILES = YES +JAVADOC_AUTOBRIEF = NO +INHERIT_DOCS = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 4 +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +ALIASES = +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +OPTIMIZE_OUTPUT_FOR_C = YES +SHOW_USED_FILES = YES +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_FORMAT = +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ../../packetNtx/driver/Packet.h \ + ../../packetNtx/driver/jitter.h \ + ../libpcap/incs/pcap.h \ + ../libpcap/funcs/pcap.h \ + ../../wpcap/Win32-Extensions/Win32-Extensions.h \ + ../main.txt \ + ../wpcap_tut.txt \ + ../wpcap_tut1.txt \ + ../wpcap_tut2.txt \ + ../wpcap_tut3.txt \ + ../wpcap_tut4.txt \ + ../wpcap_tut5.txt \ + ../wpcap_tut6.txt \ + ../wpcap_tut7.txt \ + ../wpcap_tut8.txt \ + ../wpcap_tut9.txt \ + ../doxygen_groups.txt \ + ../wpcap_remote.htm \ + ../../wpcap/libpcap/pcap-remote.h \ + ../../wpcap/libpcap/remote-ext.h \ + ../../wpcap/libpcap/rpcapd/fileconf.h \ + ../../wpcap/libpcap/rpcapd/utils.h \ + ../../wpcap/libpcap/rpcapd/daemon.h \ + ../../wpcap/libpcap/rpcapd/rpcapd.h \ + ../../wpcap/libpcap/rpcapd/win32-svc.h +FILE_PATTERNS = *.cpp \ + *.c \ + *.h \ + *.txt \ + *.htm +RECURSIVE = YES +EXCLUDE = test +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = ../../Examples/ \ + ../ +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = ../pics/ +INPUT_FILTER = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = docs +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = ../footer.htm +HTML_STYLESHEET = ../style.css +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = YES +GENERATE_CHI = NO +BINARY_TOC = YES +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = +MAN_EXTENSION = +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = WIN32 \ + _DEBUG_TO_FILE \ + EXPAND_AS_DEFINED \ + EXPAND_AS_DEFINED \ + = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +TEMPLATE_RELATIONS = YES +HIDE_UNDOC_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DOT_IMAGE_FORMAT = gif +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/winpcap/dox/slides.ppt b/winpcap/dox/slides.ppt new file mode 100644 index 0000000000000000000000000000000000000000..cbb8d4b4ffa00a3a90360f242531779b8ce3f639 GIT binary patch literal 31744 zcwX&Y3wTu3wO;$oB$=5!W(W}@;W4JDpooDWq9TOw6d~pcR%=^HOeSO`WO9=UC{m3S zt+&@&YAY41f)6TH%SC)EmY`J;QB&&!d1%^Ns?^#MZA)t*_g{OT*SwO+B=)<#pC{j% zv(LZxS$nOu*IxT^=43iv8_;>zLxX=qF~?+b(9te8W!f;IlRSJxL-gyTU0q!U-1X)0 zZ*?32orQLDfSjNV5Vv_2$OUqPJfLh)4k#Ct2l6TxpaGzK&_GZD=oru-(6OLG&~c!_ zpd!%OqNfKC9N2s#Ng5;O{QGUyc0Xwa#kF`&~xC7`jOaiCJr zc+lyf37|7T6ZQHGnxtQUd058<6vAH^Z83uyac-t7sW-udXQKKN9pBK@*-IZdMmaf-f9T-;)`rg8=~KjMjt3sweR}*CUOMF1B)A{$ z@N!%zq1U}mJ>N@jX1y3&jpa0wQE7kR^Yr0XZAbRh;D|2L(rbhGlg)V{|+9rG$3EBlNTwTJ2QA23B-&I0`KjC}2y4F(Ht}a@Oa~Tc$ghvfdb9pZJ zHw1>^6!8v`@_gzj(CfDyZT#V-j;u2Tj~oR~RrVMsmwjqz>qoTnwzJ1oyz&yCAqc$l zAC5(`%u$Cl0!wwWDoL833B4s%z z$y`;(@j7qgyy=?UlEOWTcj5RW6o2G{$G|8awK0?$k1oS}&Kz3~o6`#uPn1{6#KwRx z4|7(h@|?CjVdfo_mh{qL#{n1f{IjD_zg1{iZo@vtQALp~zf5(J5tsOcmX`@e)~s1$ zmNUw;Ie{@@F8Nt2e;wwZn*e4iH2)KXc*{!Lk18H(|Nuw_IJo2qG9@`@*^^kXyD4% zPm?c01rvX_A#9kQN+v^&E<beCT;O&ioASfm+1F zRwGx0dmT^LGo6e(B6rKPQwDWG?ud`#4~;zXK4#7marr+I#}9>TTq#DYA0pWEEa@6> z%76|J29MBpq}0*jUtkengn!hjhky8}ii zOEcrxh+ znKCn15hedWlFFZ%ME==V^;UkrucIJderE4VLw+qv{@qdX&n8QLxq`~ED2ZSSuK*4#P13piuJoxTIZAu zZk_Wo+3&8GmW}p19&4JaYZeE>V`>{3*xN>s+JYq0+qjJ3ZF#!4@o~SGS5L+krt&nQ zBb;_5%yGMv&To;WvrE_cQ|NpN*>rw9TIX%V_f8Sa3D(}l{cZ^6zlQ#KET7bWipKSB z(*(+QX@js{yT-xy4y58wSc+{9T8Tg1N`KTkv^L)p&ctKhU0!4LMfz9~+v7ZXzQS3% z2W;B8b?uCp+eYi3jE^DRd5+Q3%JO{$ksOxtyf`U0dO1d%AFdBH=QcHm!l9Z_LvBkL zZQH^s@XqicT?N&wgG?pzq{uJWME1mqT=h&^BIkB!RbHN@<;pIV$o(qLo#vn3j7d^+ za`!XjR0dXq-2F0Wa<1WUhHJ7m_mibfcAPewx5ss+6ts!B{m!aPUp8wqN7fXr4a-p% zYzQk&Mv}23WoW|r(P5iWP8(r)oGx*WE^*?p+=T^pPqKcHJ^B6euF z_=O_~jXVX6o`RCiLnz*xy@#_VdN%vmn=g{JM|(5-ZlxR=T8#Ooi;P31RHx*w$ho?+ zOD9!nBi7s9WMCiMguI3BLU+W=JRis9-8qV9fo_<4z>|0O+Ng4;)xl-F@3ndMWtU`@ zyKhe#Z8=C)1j5Tg&5QjDs+)}1Wo!m|P#qVE9XK_;x4&!?|Cl)ONBpd>;vdQ0s%>@- z&1LZyCJ>+PT2VRE5L>|@lPbH({a;ebu0W+HsK57gsi;y+-ie(eZU%i0Dl(~Ksh{g=%i_A)vbe4evZ8pAu9r0%sq9Q=Hd5qhcTnbD2e(F(G;w@)XhmzB zdRc2-U7&fa(beO-gE5s=omtZ-wfy8qZ#$WjsLOK@HuM^*>-8}7Dkp1nn)v&^`dw$% zjTx0$y2^s zb&^=7bz)*$Be*QDPbxBi<0~^od;|E*Ifs>oa z?!e>w&4K;7O?mMSe0raoz?Z$r?awWdYphquYJv$#9C+m4(sSU|Ih8);!0JhRbVG2E zm>XKOD2ewLD2b)_M(-OM%@MsKp7WNb?ns@nA4Xuhk4pJ63=w~E4MAr za(&U;miFFscAtCGHJ-A(vEDXM?7U)ZD3GQcW@y;p76`y{;JwHRwXBh_Q`A%CtTblQHxXi!=_cO%PRGuJ>Opwo- zGjA?4DnUNCGRw}7w#FpL=Sa%a2Ohu1C&>5e{J9K|o|!TEKK*`UHpwn^@xy1jqDs1^9Q?>Cyyj6=Eol9Bf=c( z5#dW@dqkK+35Uem)2yz|KGIW!)n^mhYDb4FBG+>@vi|7q%+{M9Zf>m!`@_K{fu+?A zezh}KNNP<$`Y5l`4$@>wjq!YQ;xT@(ussb-qEP3FA85T-DB@s+Ix<+HM-nK+a$nX| zx3G0#urXXZZhh{w>ZXQ3qyHTL*a?PS$Jz8cE=I2sGP)<9jmbf#i5Oq7kJk8*m}er{&0{E~nTXN*dTXYx7&H0En!B$w9+~Q9G9q`hX_5_biTVV(rhBv8Lpeyc zhoniGVaFwL&9JNIhomKLZU(i~StWIfZU+9^&fKXN%$l+A+=>M=X3e<3pF6dtCeRcP z)Y>-4*OyB2A*P^TJq-*QVfjzHAw5fQDc9Evl)5KqVBRciM zblx%Pfmd;F-ZANk*BAMYi6G@`+;C1x{Qe)mGnY+YzB~8-@i^MWZLU%5A^qabSKhpR zOp))0KX%b6qyN5%W6Wrc^sNP=8+5-}O==bPi0(sg=svVh_apA7>`Nb!@~6*8_4j|0 z+QxPY{rys*cozsY%^f0CTpc0Q_&i#u)#Bqq`Rw~n^)4Mx!7G~sErG^x_3~h-G2m}$ zmEVnSUJ~LL2Dl9KsSGs)!-1N{U`@zh8}u*Wy>;}&5bMD21M+#au9MLxD9QOxd2aJL zRI>9hpB}?O3$Qq9@mBUyA3NFIvA;nwDAe^YayHc%IA z42G-atJcvfLV?QAvOsfX2($1W^K*1j*c3dLO~Vit#t0VduKhc&TX*R1=hyol_yOAg zq=(<(_HRF(^luQ5j7EHCJ*jrTkyJb1ORAmu(L2w&c93dso;h;+ar@`$mB`h*P)osr zn0D<+DK5jdor{KS@lOvd3Wlm18-v~A+;(HfQqVBOykJdps3lYvwll`540#=&tEkySmPoTj=vJX1S!DxwJ=? zVtan(h~~)>dUd2gmU5ck`%(vw0oj_7%F!T~gHujn%##198M6j%_fv&x_kU;^CJ%)R zGoNJ`nt41$SWAahA~8Qro+Bn-G7sY}wj66PNVg=vE|P zx5t~v|JI}8jiTui1iyDNqxxgz_~Jkm*2+P z0q6a`*|y#h-Rm5d2d%Ya&X6%^gkvymz)1R2I$3O_k>Wu*L2Skd`v}fY;QDFgZKV>N z$K!gUc#O_M-q}dc06tB$Q<-?4&J-`A%=0MUPJZzu6@kZb;8!Hpw*OV;MDc;VM zdmFdfIL}TRE1!F-ukEXT=0eoZ=u=O2>%6Pv)fjU2iCd1&tyYfQwG9nkw~PU)^?&|i zf2z^=ZbbdsG^25Xnr(jFQ_W9{O^7@pEuEU9J!iG5AjWe(c6$c(*Eqnlka3=i#8tAK zd`SRpWW?mYwDds9IVf7>`%=b>2h7!_^LLS>Pc78~TUO1)p95J@xF^QIz+5TakYb=yqYv z%ncdTVaUKTW=a`3T8?lyc{CJfiCZxvxC-G57?BMi0Y(9>rL0=xEfQSXV>-r)Uo5H)WU=%uZYW zJ8``dw29O{MQ^RVjz)>QK=)x4y#W+&iua*IYGQ5 zCWyV_dTlG{sRX`oowi-vgq&5{V`HRgXTS?ykiW>%SebWv%#TFZ4gq z(@5IZUtX$a<&TMg+!m^+oH=|T4S?sRqi2g)i0JR{g`PdOb8&yQvzjq{O`IfW4C)(v zM%(f_B$>Xc@K!VF#bUI?)Qc`|a`(WwJ4=q&uAsr%sVP}9RVh_G8m*l!>o8s@iuUq! zWc@LHl`f~$T0K=+bET}`qLU>zet#%iS~IgB+Uff=GL3eMjm0ByJpdU)L4&m3kCG=+ zzIGyH9V01UGw|_9j|VnMl7*KeT@GxHBnz)Zx)RvMk}UjEq%Q?lC&|JakZu4LmSo|} zkzNjLr6dc#0qGlnt(IirYmi<8>`qA*elODZ0((%Bg>ON63$UjoS$I3r?Z9?OvhY`t zeihhTk}P~5())nDFUi6WB7G3pAxRc~80o|86N1UYGm*{&mM6)=3y>}VHbjzz7b9H^ z>|{w6UV?N9u!)i^d@|CLfz6a;;d7Cm3v7WT3%>;EOMqP_$-?WAt_Rj6$-M=wo#IWZ$f$#u*W1>_*SI10{f*T3*U+KPGGM~ zvhdwV?*`T>$-)mHeE`_Uk}Ui)q(1}pPe~T8Y5AI_6=)tw7VbmZ2dq$1zNUH__hKUs z+2c|w^Iz`SM@jW;he)SqcY%Z$BdN>8$0I!+*d$37UXFA*usM<}yb|e3U>8fW@Jo@t z6j+@k3vWQW0a#d)g)c{XIk1(IEc^zfZveJhl7+89dJV8UC0Y2rNZ$+WK}ib35A!!)1e1klA`K4^ zd6F!=0O*i1Lnm>1qd|FV<7MM~hb^Z}lpZn~dkOsqUfnrf*#( z7K!;{aMW&1s(mX}t<-wHMjS7AJ#Txd`VKca$$0wApZ#UQ7IBJv_NLx>RZllkd9ocl z@0g5&{7*%A|MjbB%sZyQwo@gYC#HZ5yiCjx<&w@3WgrVb1K1g2nm7&joMz%v#VBB- z#B|uO9Ax0-q6iq%K;Q#Se45Awccu*7mtn)ZXa;De_!~_J8TfSZ2{5J)k^a!cXNcd? zEJ=Hj-fP3(1okG)hNsR18Td@`BCr?fT(J%L+f00xcoG=XLr6bl;>@CI)+gqcvEi2(7hV9pC`yo5V&X4gg|q|ok|;)Av5D`%ifSil zmnguwz{Fq13hWiot0EJ5nI`@UR&1|cdm6=dMAVTJcA(67ZooDZ7#>*DwH2Ix(( zA9?#t{0;Foy#;z(yoS8jO#ChJ64oX!(H^lK=j|r`j(D2(g7%4rk@v8P?-f6%{h)Wn z2IOrp@%>^wy$AY@xE1GHO}tawOuq&FPJ9=6-!<{yidFPJ==Wj;@>ZDm`(i29L`&%d z(TH=SiT^>=(}$pgq6&FcCjO!LI{gv!5ypjs3CD&{#MkI!j131cf~495W4(&Ugr%V8 zK=-8KRdd8TF-P1bp1?Zw39%x<*zg2KjCPC-kBTe5;IUzh=BJ;3p>e|a-sG?4^E~~( zYY5e+d+ODx@HfVUo&7QqWxzIn~W4o0GYx?)ts#EzMTWsI^D+*2koq*JAEtX+ij*Kxg24ArWT zS1pEVi-8BliCUdF1^B7jS8=Yu^(>St7lX7i@GBQtxORe{Kwfk|i~W{nW{;8RDDIsn z)Kl$HD%#rS5Sj89%SJc`NNqjZg`lsA9PJyBa-kRijd(}B2s9j;9j7gUC6*xna%fN| z9LOhFfV2fdOGA^MG>6i5(bkBA20f+j~qb&?pH z>T~+3VycGKdDOQT`?wQwTL12ZV7{zJ0Xc}d8ar>yIvekDbl7Yr;0p3 z7MU{gEC~5Gy85hpuFi9?Y<2#>FdWS?dmLY4{hXhH)}rtUIR94~u(^%?E8)|eLm z29N!Se&dIE81Jsd9{yJTWs&8}G0w{}O#E&X&o$%-zcD!aUB$aEzcJV|k1zf=2KgUODBXQj%kQ|x W{F8|?V7E+AEY% h3 { margin-top: 0; } +.directory p { margin: 0px; white-space: nowrap; } +.directory div { display: none; margin: 0px; } +.directory img { vertical-align: -30%; } diff --git a/winpcap/dox/wpcap.htm b/winpcap/dox/wpcap.htm new file mode 100644 index 0000000..9989c0b --- /dev/null +++ b/winpcap/dox/wpcap.htm @@ -0,0 +1,45 @@ + + + + + + + + + + +

This section contains the user manual of wpcap.dll, the +dynamic library that contains the public WinPcap API. +wpcap.dll exports a set of +system-independent functions for packet capture and network analysis. These +functions can be used to:

+
    +
  • obtain the list of the available network adapters +
  • retrieve various information about an adapter, like the description and the list of addresses
  • +
  • sniff the packets using one of the network interface cards of the PC
  • +
  • send packets to the network +
  • efficiently save packets to disk and load them with an interface similar to the one of + live capture
  • +
  • create packet filters using a high level language and apply them to the captured + packets
  • +
+

wpcap.dll is compatible with libpcap, the well known packet capture library +for Unix. This compatibility means that one can develop portable network tools +that will run on the Win32 OS family and on all of the major Unix flavors.

+

Several portions of the manual present in this section derive directly from the man pages of tcpdump and libpcap, maintained by the tcpdump.org developers. Therefore, if you +are looking for updated docs, you can consult the web site www.tcpdump.org.

+

Note

+

Some functions are marked deprecated +or discouraged. The meanings of these labels are:

+
    +
  • discouraged: the use of another function with similar purpose is + suggested, however this one is still valid.
  • +
  • deprecated: the function is present only for portability and + backward compatibility. It should be avoided, and it is strongly suggested + to use another equivalent function instead.
    +
  • +
+

+ + + diff --git a/winpcap/dox/wpcap_remote.htm b/winpcap/dox/wpcap_remote.htm new file mode 100644 index 0000000..3a6d893 --- /dev/null +++ b/winpcap/dox/wpcap_remote.htm @@ -0,0 +1,350 @@ + + + + + + +Using WinPcap Remote Capture + + + + +


+ +
+

WinPcap comes with Remote Capture capabilities. This is an highly +experimental feature that allows to interact to a remote machine and capture +packets that are being transmitted on the remote network.

+

This requires a remote daemon (called rpcapd) which +performs the capture and sends data back and a local client that sends +the appropriate commands and receives the captured data.

+

WinPcap extends the standard WinPcap code in such a way that all +WinPcap-based tools can expoit remote capture capabilities. For instance, the +capabillity to interact with a remote daemon are added to the client software +without any explicit modification to it. Vice versa, the remote daemon must be +explicitely installed (and configured) on the remote machine.

+

Remote Capture Running Modes

+

The Remote Capture Protocol (RPCAP) can work in two modes:

+
    +
  • Passive Mode (default): the client (e.g. a network sniffer) + connects to the remote daemon, it sends them the appropriate commands, and + it starts the capture.
  • +
  • Active Mode: the remote daemon try to establish a connection toward + the client (e.g. the network sniffer); then, the client sends the + appropriate commands to the daemon and it starts the capture. This name is + due to the fact thet the daemon becomes active instead of waiting + for new connections.
  • +
+

The Active Mode is useful in case the remote daemon is behind a firewall and +it cannot receive connections from the external world. In this case, the daemon +can be configured to establish the connection to a given host, which will have +been configured in order to wait for that connection. After establishing +the connection, the protocol continues its job in almost the same way in both +Active and Passive Mode.

+

Analyzer (http://analyzer.polito.it/30alpha/) +has a set of commands (in the Capture menu) that allows you to accept a +remote connection and then start the capture on the remote device. Currently, +Analyzer is the only tool that is able to work in active mode, since it requires +some modifications to the application code.

+

Configuring the Remote Daemon (rpcapd)

+

The Remote Daemon is a standard Win32 executable running either in console +mode or as a service. The executable can be found in the WinPcap +folder and it has the following syntax:

+
        rpcapd [-b <address>] [-p <port>] [-6] [-l <host_list>] [-a <host,port>] 
+               [-n] [-v] [-d] [-s <file>] [-f <file>]
+

The daemon can be compiled and it is actually working on Linux as well.

+

Here there is a brief description of the allowed commands:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SwitchDescription
+
-b <address>
+
It sets the address the daemon has to bind to (either numeric or + literal). Default: it binds to all local IPv4 and IPv6 addresses.
+
-p <port>
+
It sets the port the daemon has to bind to. Default: it binds to port + 2002.
+
-4
+
It binds only to IPv4 addresses. Default: both IPv4 and IPv6 waiting + sockets are used.
+
-l <host_list_file>
+
It specifies a file that keeps the list of the hosts which are allowed + to connect to this daemon (if more than one, the file keeps them one per + line). We suggest to use literal names (instead of numeric ones) in + order to avoid problems with different address families (IPv4 and IPv6).
+
-n
+
It permits NULL authentication (usually used with '-l', that + guarantees that only the allowed hosts can connect to the daemon). + Default: the username/password authentication mechanism is required.
+
-a <host, port>
+
It forces the daemon to run in active mode and to connect to 'host' on + port 'port'. This does not exclude that the daemon is still able to + accept passive connections.
+
-v
+
It forces the daemon to run in active mode only (default: the daemon + always accepts active connections, even if the '-a' switch is + specified).
+
-d
+
Forces the daemon to run in background, i.e. as a daemon (UNIX only) + or as a service (Win32 only). Warning (Win32): this switch is + provided automatically when WinPcap installs this daemon into the Win32 + services (control panel - administrative tools - services).
+
-s <file>
+
It saves the current configuration to file.
+
-f <file>
+
It loads the current configuration from file; all the switches + specified from the command line are ignored and the file settings are + used instead.
+
-h
+
It prints an help screen.
+
+

Installing the remote daemon

+

The remote daemon is installed automatically when installing WinPcap. The +installation process places the rpcapd file into the WinPcap +folder. This file can be executed either from the command line, or as a service. +For instance, the installation process updates the list of available services +list and it creates a new item (Remote Packet Capture Protocol v.0 +(experimental) ). To avoid security problems, the service is inactive and it +has to be started manually (control panel - administrative tools - services - +start).

+

The service has a set of "standard" parameters, i.e. it it launched +with the "-d" flag (in orde to make it running as a +service) and the "-f rpcapd.ini" flag. The user can +create a file called rpcapd.ini in the same folder of the +executable, and put the configuration commands in there. In order for the +service to execute the commands, you have to stop and restart it again (i.e. the +initialization file is parsed only at the beginning). Viceversa, the UNIX +version of rpcapd is able to read the configuration file when +sending a kill -HUP signal to it. In that case, all the existing connections +remain in place, while the new connections will be created according to the new +parameters.

+

In case the user does not want to create the configuration file manually, it +can launch rpcapd with the requested parameters plus the "-s +filename" one. The daemon will parse all the parameters and save +them into the specified configuration file.

+

Starting the remote daemon as a standard executable

+

The rpcapd executable can be launched directly, i.e. it can run +in the foreground as well (not as a daemon/service). The procedure is quite +simple: you have to invoke the executable from the command line with all the +requested parameters but the "-d" flag. The capture +server will start in the foreground.

+

Starting a capture on a remote machine

+

If you are using a tool that is already aware of the remote capture (like +Analyzer), everything is simple. The capture wizard will help you to locate the +appropriate interface on the remote machine.

+

If your preferred tool is not aware of the remote capture, you can still use +the remote capture. In this case you have to read the next Section.

+

Be carefully: the capture server (rpcapd) must be up and +running on the remote machine.

+

New string specifiers for interface selection

+

If your preferred tool is not aware of the remote capture, the only thing you +must do is to insert, as interface specifier, the indication of the remote +machine you want to contact. The following forms are allowed:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Adapter StringDescription
+
file://filename
+
It opens a local file.
+
rpcap://host.foo.bar/adaptername
+
It opens a remote adapter; the host is specified by means of the + literal name, without port number (i.e. it uses the RPCAP default port).
+
rpcap://host.foo.bar:1234/adaptername
+
It is the same as before, but it uses a different port number.
+
rpcap://10.11.12.13/adaptername
+
It opens a remote adapter, but the host is specified by means of an + IPv4 numeric address, without port number (i.e. it uses the RPCAP + default port).
+
rpcap://10.11.12.13:1234/adaptername
+
It is the same as before, but it uses a different port number.
+
rpcap://[10.11.12.13]:1234/adaptername
+
It is the same as before, but the numeric address is specified within + square brackets (like IPv6 addresses).
+
rpcap://[1:2:3::4]/adaptername
+
It opens a remote adapter, but the host is specified by means of an + IPv6 numeric address, without port number (i.e. it uses the RPCAP + default port). In case of IPv6 addresses you MUST use the square + brackets.
+
rpcap://[1:2:3::4]:1234/adaptername
+
It is the same as before, but it uses a different port number.
+
rpcap://adaptername
+
It opens a local adapter, without using the RPCAP protocol.
+
adaptername
+
It opens a local adapter; it is kept for compability, but it is + strongly discouraged.
+
(NULL)
+
It opens the first local adapter; it is kept for compability, but it + is strongly discouraged.
+
+

The following formats are not allowed:

+ + + + + + + + + + + + + +
Adapter StringDescription
+
rpcap://
+
It cannot be used to open the first local adapter.
+
rpcap://hostname/
+
It cannot be used to open the first remote adapter.
+

Installing the Remote Capture Daemon in UNIX

+

The WinPcap source archive can be compiled in UNIX as well. Currently, remote +capture has been tested on Linux and BSD. What you have to do is:

+
    +
  • download the WinPcap sources
  • +
  • unpack the sources +
      +
    • we suggest to use the unzip -a command in order to + convert DOS files to UNIX ones
    • +
    +
  • +
  • move to the libpcap folder
  • +
  • type: +
      +
    • ./configure
    • +
    • Warning: in case the previous step reports an error, please + regenerate the configure file using automake + (version 2.50 or higher required)
    • +
    • make
    • +
    +
  • +
  • move to the rpcapd folder
  • +
  • type make
  • +
+

The remote capture capabilities are turned on by default on Linux and +FreeBSD. In case you do not want remote capture capabilities in libpcap, you can +type

+
    ./configure --disable-remote
+

at the "configure" step. All the possible flags are +listed when typing ./configure --help.

+

What you obtained right now, is:

+
    +
  • a library file (libpcap.a), which can be linked to other + applications (like tcpdump) in order to enable the remote + capture for them.
  • +
  • an executable (rpcapd) that is the remote daemon
  • +
+

Warning: in order to run the rpcapd daemon, the program +must either

+
    +
  • run as root (or)
  • +
  • run as user, but it must be owned by root and must be SUID root (chmod + u+s rpcapd)
  • +
+

Known bugs

+

FreeBSD: the first time you call the pcap_stat(), the +function takes several seconds to return. Therefore, programs like Analyzer seem +to hang up for 20-30 seconds at the beginning of the capture (if this is done +with BSD as a remote probe). We're investigating to solve this issue.

+

For any question, please refer to the WinPcap help page.

+ + + + diff --git a/winpcap/dox/wpcap_samp.htm b/winpcap/dox/wpcap_samp.htm new file mode 100644 index 0000000..cd61000 --- /dev/null +++ b/winpcap/dox/wpcap_samp.htm @@ -0,0 +1,59 @@ + + + + + + + + + + +

Creating an application that uses wpcap.dll

+

To create an application that uses wpcap.dll with Microsoft Visual C++, +follow these +steps:

+
    +
  • Include the file pcap.h at the beginning of every source file that + uses the functions exported by library.
  • +
  • If your program uses Win32 specific functions of WinPcap, remember to include WPCAP + among the preprocessor definitions.
  • +
  • If your program uses the remote capture capabilities of WinPcap, add + HAVE_REMOTE among the preprocessor definitions. Do not include + remote-ext.h directly in your source files.
  • Set the options of the linker to include the wpcap.lib library + file. wpcap.lib can + be found in the WinPcap developer's pack. +
  • Set the options of the linker to include the winsock library file + ws2_32.lib. This file is distributed with the C compiler + and contains the socket functions for Windows. It is needed by some + functions used by the samples in the tutorial.
  • +
+

Remember that:

+
    +
  • To add a preprocessor definition, you must select Settings from the Project menu, then select C/C++ + from the tab control, and under the category General, you must add + the definition under the Preprocessor Definitions text box. +
  • To add a new library to the project with Microsoft Visual C++ 6.0, you must + select Settings from the Project menu, then select Link + from the tab control, and then add the name of the new library in the Object/library + modules edit box. +
  • To add a new path where Microsoft Visual C++ 6.0 will look for the libraries, + you must select Options from the Tools menu, then + Directories + from the tab control, Library files from the Show directories + for combo box, and the add the path in the Directories box. +
  • To add a new path where Microsoft Visual C++ 6.0 will look for include files, you must select Options from the Tools menu, then + Directories + from the tab control, Include files from the Show directories + for combo box, and the add the path in the Directories box.
  • +
+

Sample programs

+

A couple of sample programs are provided to show the usage of the WinPcap API. The +source of the examples, along with all the files needed to compile and run them, can be found in the Developer's +Pack.  For didactic purpose we provide here a browsable version of the +code: it is possible to click on the variables and functions to jump the +documentation of each of them. For a more complete set of samples, try WinPcap +Tutorial Section.

+ + + + diff --git a/winpcap/dox/wpcap_samp1.htm b/winpcap/dox/wpcap_samp1.htm new file mode 100644 index 0000000..9ababcb --- /dev/null +++ b/winpcap/dox/wpcap_samp1.htm @@ -0,0 +1,22 @@ + + + + + + + + + + + +

Packet Dump

+

This program reads packets from a file or a network adapter, depending on +a command line switch. If a source is not provided, the program shows a list of +available adapters, one of which can be selected. Once the +capture is started, the program prints the timestamp, the length and the raw +contents of the packets. Once compiled, it will run on all the Win32 platforms. It +can be compiled to run on Unix as well (the makefile is provided).

+ + + + diff --git a/winpcap/dox/wpcap_samp2.htm b/winpcap/dox/wpcap_samp2.htm new file mode 100644 index 0000000..f231e7d --- /dev/null +++ b/winpcap/dox/wpcap_samp2.htm @@ -0,0 +1,29 @@ + + + + + + + + + + + +

Packet Filter

+ +

This is a more complete example of libpcap usage. It shows, among other +things, how to create and set filters and how to save a capture to disk. It can +be compiled under Win32 or Unix (projects and makefiles are provided). +Pcap_filter (pf.exe) is a general-purpose packet filtering application: its +input parameters are a source of packets (it can be a physical interface or a +file), a filter and an output file. It takes packets from the source until +CTRL+C is pressed or the whole file is processed, applies the filter to the +incoming packets and saves them to the output file if they satisfy the filter. +Pcap_filter can be used to dump network data according to a particular filter, +but also to extract a set of packets from a previously saved file. The format of +both input and output files is the format used by libpcap, i.e. same of WinDump, tcpdump +and many other network tools.

+ + + + diff --git a/winpcap/dox/wpcap_tut.txt b/winpcap/dox/wpcap_tut.txt new file mode 100644 index 0000000..2f594b5 --- /dev/null +++ b/winpcap/dox/wpcap_tut.txt @@ -0,0 +1,17 @@ +/** @ingroup wpcap + */ + + +/** @defgroup wpcap_tut WinPcap tutorial: a step by step guide to using WinPcap + * @{ + + +This section shows how to use the features of the WinPcap API. It is organized as a tutorial, subdivided into a set of lessons that will introduce the reader, in a step-by-step fashion, to program development using WinPcap, from the basic functions (obtaining the adapter list, starting a capture, etc.) to the most advanced ones (handling send queues and gathering statistics about network traffic). + +Several code snippets, as well as simple but complete programs are provided as a reference: all of the source code contains links to the rest of the manual, making it is possible to click on functions and data structures to jump to the corresponding documentation. + +The samples are written in plain C, so a basic knowledge of C programming is required. Also, since this is a tutorial about a library dealing with "raw" networking packets, good knowledge of networks and network protocols is assumed. + +\ref wpcap_tut1 "Next >>>" + +@}*/ diff --git a/winpcap/dox/wpcap_tut1.txt b/winpcap/dox/wpcap_tut1.txt new file mode 100644 index 0000000..79d2878 --- /dev/null +++ b/winpcap/dox/wpcap_tut1.txt @@ -0,0 +1,77 @@ +/** @ingroup wpcap_tut + */ + + +/** @defgroup wpcap_tut1 Obtaining the device list + * @{ + +Typically, the first thing that a WinPcap-based application does is get a list of attached network adapters. Both libpcap and WinPcap provide the pcap_findalldevs_ex() function for this purpose: this function returns a linked list of pcap_if structures, each of which contains comprehensive information about an attached adapter. In particular, the fields \e name and \e description contain the name and a human readable description, respectively, of the corresponding device. + +The following code retrieves the adapter list and shows it on the screen, printing an error if no adapters are found. + +\code +#include "pcap.h" + +main() +{ + pcap_if_t *alldevs; + pcap_if_t *d; + int i=0; + char errbuf[PCAP_ERRBUF_SIZE]; + + /* Retrieve the device list from the local machine */ + if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL /* auth is not needed */, &alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for(d= alldevs; d != NULL; d= d->next) + { + printf("%d. %s", ++i, d->name); + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + } + + if (i == 0) + { + printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); + return; + } + + /* We don't need any more the device list. Free it */ + pcap_freealldevs(alldevs); +} +\endcode + +Some comments about this code. + +First of all, pcap_findalldevs_ex(), like other libpcap functions, has an \e errbuf parameter. This parameter points to a string filled by libpcap with a description of the error if something goes wrong. + +Second, remember that not all the OSes supported by libpcap provide a description of the network interfaces, therefore if we want to write a portable application, we must consider the case in which \e description is null: we print the string "No description available" in that situation. + +Note finally that we free the list with pcap_freealldevs() once when we have finished with it. + +Let's try to compile and run the code of this first sample. In order to compile it under Unix or Cygwin, simply type: + +
+  gcc -o testprog testprog.c -lpcap
+
+ +On Windows, you will need to create a project, following the instructions in the \ref wpcapsamps section of this manual. However, we suggest that you use the WinPcap developer's pack (available at the WinPcap website, http://www.winpcap.org ), since it provides many examples already configured as projects including all the code presented in this tutorial and the \e includes and \e libraries needed to compile and run the examples. + +Assuming we have compiled the program, let's try to run it. On a particular WinXP workstation, the result we optained is + +
+   1. \\Device\\NPF_{4E273621-5161-46C8-895A-48D0E52A0B83} (Realtek RTL8029(AS) Ethernet Adapter)
+   2. \\Device\\NPF_{5D24AE04-C486-4A96-83FB-8B5EC6C7F430} (3Com EtherLink PCI) 
+
+ +As you can see, the name of the network adapters (that will be passed to libpcap when opening the devices) under Windows are quite unreadable, so the parenthetical descriptions can be very helpful. + +\ref wpcap_tut "<<< Previous" \ref wpcap_tut2 "Next >>>" + +@}*/ diff --git a/winpcap/dox/wpcap_tut2.txt b/winpcap/dox/wpcap_tut2.txt new file mode 100644 index 0000000..111f634 --- /dev/null +++ b/winpcap/dox/wpcap_tut2.txt @@ -0,0 +1,21 @@ +/** @ingroup wpcap_tut + */ + +/** @defgroup wpcap_tut2 Obtaining advanced information about installed devices + * @{ + +Lesson 1 (\ref wpcap_tut1) demonstrated how to get basic information (i.e. device name and description) about available adapters. Actually, WinPcap provides also other advanced information. In particular, every pcap_if structure returned by pcap_findalldevs_ex() contains also a list of pcap_addr structures, with: +- a list of addresses for that interface. +- a list of netmasks (each of which corresponds to an entry in the addresses list). +- a list of broadcast addresses (each of which corresponds to an entry in the addresses list). +- a list of destination addresses (each of which corresponds to an entry in the addresses list). + +Additionally, pcap_findalldevs_ex() can also return remote adapters and a list of pcap files that are located in a given local folder. + +The following sample provides an ifprint() function that prints the complete contents of a pcap_if structure. It is invoked by the program for every entry returned by pcap_findalldevs_ex(). + +\include iflist/iflist.c + +\ref wpcap_tut1 "<<< Previous" \ref wpcap_tut3 "Next >>>" + +@}*/ diff --git a/winpcap/dox/wpcap_tut3.txt b/winpcap/dox/wpcap_tut3.txt new file mode 100644 index 0000000..3e0d481 --- /dev/null +++ b/winpcap/dox/wpcap_tut3.txt @@ -0,0 +1,31 @@ +/** @ingroup wpcap_tut + */ + + +/** @defgroup wpcap_tut3 Opening an adapter and capturing the packets + * @{ + +Now that we've seen how to obtain an adapter to play with, let's start the real job, opening an adapter and capturing some traffic. In this lesson we'll write a program that prints some information about each packet flowing through the adapter. + +The function that opens a capture device is pcap_open(). The parameters, \e snaplen, \e flags and \e to_ms deserve some explanation. + +\e snaplen specifies the portion of the packet to capture. On some OSes (like xBSD and Win32), the packet driver can be configured to capture only the initial part of any packet: this decreases the amount of data to copy to the application and therefore improves the efficiency of the capture. In this case we use the value 65536 which is higher than the greatest MTU that we could encounter. In this manner we ensure that the application will always receive the whole packet. + +\e flags: the most important flag is the one that indicates if the adapter will be put in promiscuous mode. In normal operation, an adapter only captures packets from the network that are destined to it; the packets exchanged by other hosts are therefore ignored. Instead, when the adapter is in promiscuous mode it captures all packets whether they are destined to it or not. This means that on shared media (like non-switched Ethernet), WinPcap will be able to capture the packets of other hosts. Promiscuous mode is the default for most capture applications, so we enable it in the following example. + +\e to_ms specifies the read timeout, in milliseconds. A read on the adapter (for example, with pcap_dispatch() or pcap_next_ex()) will always return after \e to_ms milliseconds, even if no packets are available from the network. \e to_ms also defines the interval between statistical reports if the adapter is in statistical mode (see the lesson "\ref wpcap_tut9" for information about statistical mode). Setting \e to_ms to 0 means no timeout, a read on the adapter never returns if no packets arrive. A -1 timeout on the other side causes a read on the adapter to always return immediately. + + +\include misc/basic_dump.c + +Once the adapter is opened, the capture can be started with pcap_dispatch() or pcap_loop(). These two functions are very similar, the difference is that pcap_ dispatch() returns (although not guaranteed) when the timeout expires while pcap_loop() doesn't return until \e cnt packets have been captured, so it can block for an arbitrary period on an under-utilized network. pcap_loop() is enough for the purpose of this sample, while pcap_dispatch() is normally used in a more complex program. + +Both of these functions have a \e callback parameter, \e packet_handler, pointing to a function that will receive the packets. This function is invoked by libpcap for every new packet coming from the network and receives a generic status (corresponding to the \e user parameter of pcap_loop() and pcap_dispatch()), a header with some information on the packet like the timestamp and the length and the actual data of the packet including all the protocol headers. Note that the frame CRC is normally not present, because it is removed by the network adapter after frame validation. Note also that most adapters discard packets with wrong CRCs, therefore WinPcap is normally not able to capture them. + +The above example extracts the timestamp and the length of every packet from the pcap_pkthdr header and prints them on the screen. + +Please note that there may be a drawback using pcap_loop() mainly related to the fact that the handler is called by the packet capture driver; therefore the user application does not have direct control over it. Another approach (and to have more readable programs) is to use the pcap_next_ex() function, which is presented in the next example (\ref wpcap_tut4). + +\ref wpcap_tut2 "<<< Previous" \ref wpcap_tut4 "Next >>>" + +@}*/ diff --git a/winpcap/dox/wpcap_tut4.txt b/winpcap/dox/wpcap_tut4.txt new file mode 100644 index 0000000..ac1677a --- /dev/null +++ b/winpcap/dox/wpcap_tut4.txt @@ -0,0 +1,27 @@ +/** @ingroup wpcap_tut + */ + + +/** @defgroup wpcap_tut4 Capturing the packets without the callback + * @{ + +The example program in this lesson behaves exactly like the previous program (\ref wpcap_tut3), but it uses pcap_next_ex() instead of pcap_loop(). + +The callback-based capture mechanism of pcap_loop() is elegant and it could be a good choice in some situations. However, handling a callback is sometimes not practical -- it often makes the program more complex especially in situations with multithreaded applications or C++ classes. + +In these cases, pcap_next_ex() retrievs a packet with a direct call -- using pcap_next_ex() packets are received only when the programmer wants them. + +The parameters of this function are the same as a capture callback -- it takes an adapter descriptor and a couple of pointers that will be initialized and returned to the user (one to a pcap_pkthdr structure and another to a buffer with the packet data). + +In the following program, we recycle the callback code of the previous lesson's example and move it inside main() right after the call to pcap_next_ex(). + + +\include misc/basic_dump_ex.c + +Why do we use pcap_next_ex() instead of the old pcap_next()? Because pcap_next() has some drawbacks. First of all, it is inefficient because it hides the callback method but still relies on pcap_dispatch(). Second, it is not able to detect EOF, so it's not very useful when gathering packets from a file. + +Notice also that pcap_next_ex() returns different values for success, timeout elapsed, error and EOF conditions. + +\ref wpcap_tut3 "<<< Previous" \ref wpcap_tut5 "Next >>>" + +@}*/ diff --git a/winpcap/dox/wpcap_tut5.txt b/winpcap/dox/wpcap_tut5.txt new file mode 100644 index 0000000..b11cca9 --- /dev/null +++ b/winpcap/dox/wpcap_tut5.txt @@ -0,0 +1,50 @@ +/** @ingroup wpcap_tut + */ + + +/** @defgroup wpcap_tut5 Filtering the traffic + * @{ + +One of the most powerful features offered by WinPcap (and by libpcap as well) is the filtering engine. It provides a very efficient way to receive subsets of the network traffic, and is (usually) integrated with the capture mechanism provided by WinPcap. The functions used to filter packets are pcap_compile() and pcap_setfilter(). + +pcap_compile() takes a string containing a high-level Boolean (filter) expression and produces a low-level byte code that can be interpreted by the fileter engine in the packet driver. The syntax of the boolean expression can be found in the \ref language section of this documentation. + +pcap_setfilter() associates a filter with a capture session in the kernel driver. Once pcap_setfilter() is called, the associated filter will be applied to all the packets coming from the network, and all the conformant packets (i.e., packets for which the Boolean expression evaluates to true) will be actually copied to the application. + +The following code shows how to compile and set a filter. Note that we must retrieve the netmask from the pcap_if structure that describes the adapter, because some filters created by pcap_compile() require it. + +The filter passed to pcap_compile() in this code snippet is "ip and tcp", which means to "keep only the packets that are both IPv4 and TCP and deliver them to the application". + +\code + if (d->addresses != NULL) + /* Retrieve the mask of the first address of the interface */ + netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; + else + /* If the interface is without an address we suppose to be in a C class network */ + netmask=0xffffff; + + + //compile the filter + if (pcap_compile(adhandle, &fcode, "ip and tcp", 1, netmask) < 0) + { + fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } + + //set the filter + if (pcap_setfilter(adhandle, &fcode) < 0) + { + fprintf(stderr,"\nError setting the filter.\n"); + /* Free the device list */ + pcap_freealldevs(alldevs); + return -1; + } +\endcode + +If you want to see some code that uses the filtering functions shown in this lesson, look at the example presented in the next Lesson, \ref wpcap_tut6. + +\ref wpcap_tut4 "<<< Previous" \ref wpcap_tut6 "Next >>>" + +@}*/ diff --git a/winpcap/dox/wpcap_tut6.txt b/winpcap/dox/wpcap_tut6.txt new file mode 100644 index 0000000..246a5b0 --- /dev/null +++ b/winpcap/dox/wpcap_tut6.txt @@ -0,0 +1,48 @@ +/** @ingroup wpcap_tut + */ + +/** @defgroup wpcap_tut6 Interpreting the packets + * @{ + +Now that we are able to capture and filter network traffic, we want to put our knowledge to work with a simple "real world" application. + +In this lesson we will take code from the previous lessons and use these pieces to build a more useful program. the main purpose of the current program is to show how the protocol headers of a captured packet can be parsed and interpreted. +The resulting application, called UDPdump, prints a summary of the UDP traffic on our network. + +We have chosen to parse and display the UDP protocol because it is more accessible than other protocols such as TCP and consequently is an excellent initial example. Let's look at the code: + +\include UDPdump/udpdump.c + +First of all, we set the filter to "ip and udp". In this way we are sure that packet_handler() will receive only UDP packets over IPv4: this simplifies the parsing and increases the efficiency of the program. + +We have also created a couple of structs that describe the IP and UDP headers. These structs are used by packet_handler() to properly locate the various header fields. + +packet_handler(), although limited to a single protocol dissector (UDP over IPv4), shows how complex "sniffers" like tcpdump/WinDump decode the network traffic. Since we aren't interested in the MAC header, we skip it. +For simplicity and before starting the capture, we check the MAC layer with pcap_datalink() to make sure that +we are dealing with an Ethernet network. This way we can be sure that the MAC header is exactly 14 bytes. + +The IP header is located just after the MAC header. We will extract the IP source and destination addresses from the +IP header. + +Reaching the UDP header is a bit more complicated, because the IP header doesn't have a fixed length. +Therefore, we use the IP header's length field to know its size. +Once we know the location of the UDP header, we extract the source and destination ports. + +The extracted values are printed on the screen, and the result is something like: + + +1. \\Device\\Packet_{A7FD048A-5D4B-478E-B3C1-34401AC3B72F} (Xircom +t 10/100 Adapter) \n +Enter the interface number (1-2):1\n + +listening on Xircom CardBus Ethernet 10/100 Adapter... \n +16:13:15.312784 len:87 130.192.31.67.2682 -> 130.192.3.21.53 \n +16:13:15.314796 len:137 130.192.3.21.53 -> 130.192.31.67.2682 \n +16:13:15.322101 len:78 130.192.31.67.2683 -> 130.192.3.21.53 \n + + +Each of the final 3 lines represents a different packet. + +\ref wpcap_tut5 "<<< Previous" \ref wpcap_tut7 "Next >>>" + +@}*/ diff --git a/winpcap/dox/wpcap_tut7.txt b/winpcap/dox/wpcap_tut7.txt new file mode 100644 index 0000000..ae17977 --- /dev/null +++ b/winpcap/dox/wpcap_tut7.txt @@ -0,0 +1,67 @@ +/** @ingroup wpcap_tut + */ + +/** @defgroup wpcap_tut7 Handling offline dump files + * @{ + +In this lession we are going to learn how to handle packet capture to a file (dump to file). +WinPcap offers a wide range of functions to save the network traffic to a file and to read the content of dumps -- this lesson will teach how to use all of these functions. We'll see also how to use the kernel dump feature of WinPcap to obtain high-performance dumps +(NOTE: At the moment, due to some problems with the new kernel buffer, this feature has been disabled). + +The format for dump files is the libpcap one. This format contains the data of the captured packets in binary form and is a standard used by many network tools including WinDump, Ethereal and Snort. + +Saving packets to a dump file + +First of all, let's see how to write packets in libpcap format. + +The following example captures the packets from the selected interface and saves them on a file +whose name is provided by the user. + +\include misc\savedump.c + +As you can see, the structure of the program is very similar to the ones we have seen in the previous lessons. +The differences are: +- a call to pcap_dump_open() is issued once the interface is opened. This call opens a dump file and associates it with the interface. +- the packets are written to this file with a pcap_dump() from the packet_handler() callback. The parameters of +pcap_dump() are in 1-1 correspondence with the parameters of pcap_handler(). + +Reading packets from a dump file + +Now that we have a dump file available, we can try to read its content. +The following code opens a WinPcap/libpcap dump file and displays every packet contained in the file. +The file is opened with pcap_open_offline(), then the usual pcap_loop() is used to sequence through the packets. +As you can see, reading packets from an offline capture is nearly identical to receiving them from a physical interface. + +This example introduces another function: pcap_createsrcsrc(). +This function is required to create a source string that begins with a marker used to tell WinPcap the type of the source, +e.g. "rpcap://" if we are going to open an adapter, or "file://" if we are going to open a file. +This step is not required when pcap_findalldevs_ex() is used (the returned values already contain these strings). +However, it is required in this example because the name of the file is read from the user input. + +\include misc\readfile.c + +The following example has the same purpose of the last one, but pcap_next_ex() is used instead of the pcap_loop() callback method. + +\include misc\readfile_ex.c + +Writing packets to a dump file with pcap_live_dump + +NOTE: At the moment, due to some problems with the new kernel buffer, this feature has been disabled. + +Recent versions of WinPcap provide a further way to save network traffic to disk, the pcap_live_dump() function. pcap_live_dump() takes three parameters: a file name, the maximum size (in bytes) that this file is allowed to reach and the maximum amount of packets that the file is allowed to contain. Zero means no limit for both these values. Notice that the program can set a filter (with pcap_setfilter(), see the tutorial \ref wpcap_tut5) before calling pcap_live_dump() to define the subset of the traffic that will be saved. + +pcap_live_dump() is non-blocking, therefore it starts the dump and returns immediately: The dump process goes on asynchronously until the maximum file size or the maximum amount of packets has been reached. + +The application can wait or check the end of the dump with pcap_live_dump_ended(). +\b Beware that if the \e sync parameter is nonzero, this function will block your application forever if the limits are both 0. + +\include kdump\kdump.c + +The difference between pcap_live_dump() and pcap_dump(), apart from the possibility to set limits, is performance. pcap_live_dump() exploits the ability of the WinPcap NPF driver (see \ref NPF) to write dumps from kernel level, minimizing the number of context switches and memory copies. + +Obviously, since this feature is currently not available on other operating systems, +pcap_live_dump() is WinPcap specific and is present only under Win32. + +\ref wpcap_tut6 "<<< Previous" \ref wpcap_tut8 "Next >>>" + +@}*/ diff --git a/winpcap/dox/wpcap_tut8.txt b/winpcap/dox/wpcap_tut8.txt new file mode 100644 index 0000000..42cce9a --- /dev/null +++ b/winpcap/dox/wpcap_tut8.txt @@ -0,0 +1,59 @@ +/** @ingroup wpcap_tut + */ + +/** @defgroup wpcap_tut8 Sending Packets + * @{ + +Although the name \e WinPcap indicates clearly that the purpose of the library is packet capture, other useful features for raw networking are provided. Among them, the user can find a complete set of functions to send packets. + +Note that the original libpcap library at the moment doesn't provide any way to send packets, therefore all the functions shown here are WinPcap extensions and will not work under Unix. + +Sending a single packet with pcap_sendpacket() + +The simplest way to send a packet is shown in the following code snippet. After opening an adapter, pcap_sendpacket() is called to send a hand-crafted packet. +pcap_sendpacket() takes as arguments a buffer containing the data to send, the length of the buffer +and the adapter that will send it. +Notice that the buffer is sent to the net as is, without any manipulation. This means that the application has to create the correct protocol headers in order to send something meaningful. + +\include misc/sendpack.c + +Send queues + +While pcap_sendpacket() offers a simple and immediate way to send a single packet, send queues provides an advanced, powerful and optimized mechanism to send a collection of packets. +A send queue is a container for a variable number of packets that will be sent to the network. +It has a size, that represents the maximum amount of bytes it can store. + +A send queue is created calling the pcap_sendqueue_alloc() function, specifying the size of the new send queue. + +Once the send queue is created, pcap_sendqueue_queue() can be used to add a packet to the send queue. +This function takes a pcap_pkthdr with the timestamp and the length and a buffer with the data of the packet. +These parameters are the same as those received by pcap_next_ex() and pcap_handler(), therefore queuing a packet that was +just captured or read from a file is a matter of passing these parameters to pcap_sendqueue_queue(). + +To transmit a send queue, WinPcap provides the pcap_sendqueue_transmit() function. +Note the third parameter: if nonzero, the send will be \e synchronized, +i.e. the relative timestamps of the packets will be respected. +This operation requires a remarkable amount of CPU, because the synchronization takes place in the +kernel driver using "busy wait" loops. Although this operation is quite CPU intensive, +it often results in very high precision +packet transmissions (often around few microseconds or less). + +Note that transmitting a send queue with pcap_sendqueue_transmit() is much more efficient than performing a series of pcap_sendpacket(), because the send queue is buffered at kernel level drastically decreasing the number of context switches. + +When a queue is no longer needed, +it can be deleted with pcap_sendqueue_destroy() that frees all the buffers associated with the send queue. + +The next program shows how to use send queues. +It opens a capture file with pcap_open_offline(), +then it moves the packets from the file to a properly allocated send queue. +At his point it transmits the queue, synchronizing it if requested by the user. + +Note that the link-layer of the dumpfile is compared with the one of the interface that will send the packets using pcap_datalink(), and a warning is printed if they are different -- it is important that the capture-file link-layer be the +same as the adapter's link layer for otherwise the tranmission is pointless. + +\include sendcap/sendcap.c + +\ref wpcap_tut7 "<<< Previous" \ref wpcap_tut9 "Next >>>" + + +@}*/ diff --git a/winpcap/dox/wpcap_tut9.txt b/winpcap/dox/wpcap_tut9.txt new file mode 100644 index 0000000..c467374 --- /dev/null +++ b/winpcap/dox/wpcap_tut9.txt @@ -0,0 +1,52 @@ +/** @ingroup wpcap_tut + */ + +/** @defgroup wpcap_tut9 Gathering Statistics on the network traffic + * @{ + +This lesson shows another advanced feature of WinPcap: the ability to collect statistics about network traffic. The statistical engine makes use of the kernel-level packet filter to efficiently classify the incoming packet. +You can take a look at the \ref NPF if you want to know more details. + +In order to use this feature, the programmer must open an adapter and put it in \e statistical \e mode. +This can be done with pcap_setmode(). In particular, MODE_STAT must be used as the \e mode argument of this function. + +With statistical mode, making an application that monitors the TCP traffic load is a matter of few lines of code. +The following sample shows how to do it. + +\include tcptop/tcptop.c + +Before enabling statistical mode, the user has the option to set a filter that defines the subset of network traffic that will be monitored. See the paragraph on the \ref language for details. +If no filter has been set, all of the traffic will be monitored. + +Once + +- the filter is set +- pcap_setmode() is called +- callback invocation is enabled with pcap_loop() + +the interface descriptor starts to work in statistical mode. +Notice the fourth parameter (\e to_ms) of pcap_open(): it defines the interval among the statistical samples. +The callback function receives the samples calculated by the driver every \e to_ms milliseconds. These samples are encapsulated in the second and third parameters of the callback function, as shown in the following figure: + +\image html stats_wpcap.gif + + +Two 64-bit counters are provided: the number of packets and the amount of bytes received during the last interval. + +In the example, the adapter is opened with a timeout of 1000 ms. +This means that dispatcher_handler() is called once per second. +At this point a filter that keeps only tcp packets is compiled and set. +Then pcap_setmode() and pcap_loop() are called. +Note that a struct timeval pointer is passed to pcap_loop() as the \e user parameter. +This structure will be used to store a timestamp in order to calculate the interval between two samples. +dispatcher_handler()uses this interval to obtain the bits per second and the +packets per second and then prints these values on the screen. + +Note finally that this example is by far more efficient than a program that captures the packets in the traditional way and calculates statistics at user-level. +Statistical mode requires the minumum amount of data copies and context switches and therefore the CPU is optimized. Moreover, a very small amount of memory is required. + +\ref wpcap_tut8 "<<< Previous" + +@}*/ + + diff --git a/winpcap/packetNtx/Compile2k.bat b/winpcap/packetNtx/Compile2k.bat new file mode 100644 index 0000000..ef0374f --- /dev/null +++ b/winpcap/packetNtx/Compile2k.bat @@ -0,0 +1,28 @@ +@echo off + +echo ************************************************************ +echo * +echo * This compilation script has been OBSOLETED. +echo * +echo * Please use CompileDriver.bat to compile the driver +echo * for all the supported platforms (NT4,2k,xp,2k3,vista,x64) +echo * +echo ************************************************************ + +goto end + + +mkdir driver\bin 2> nul +mkdir driver\bin\2k 2> nul + +set USER_C_DEFINES=-DNDIS50 +set TARGETPATH=driver\bin\2k + +copy driver\NPF_NT5.RC driver\NPF.RC + +prefast build -cefw + +set TARGETPATH= +set USER_C_DEFINES= + +:end \ No newline at end of file diff --git a/winpcap/packetNtx/CompileDriver.bat b/winpcap/packetNtx/CompileDriver.bat new file mode 100644 index 0000000..d259cdc --- /dev/null +++ b/winpcap/packetNtx/CompileDriver.bat @@ -0,0 +1,118 @@ +@echo off + +if "%_BUILDARCH%"=="x86" goto x86_build +if "%_BUILDARCH%"=="AMD64" goto amd64_build +if "%_BUILDARCH%"=="IA64" goto ia64_build +if "%_BUILDARCH%"=="" goto nt4_build + +echo ****************************************************** +echo ERROR: unknown build architecture (%_BUILDARCH%) +echo ****************************************************** + +goto end + +:x86_build + +echo ****************************************************** +echo * Compiling the driver for Windows NT5.x 32 bit * +echo ****************************************************** + +mkdir driver\bin 2> nul +mkdir driver\bin\2k 2> nul +rem mkdir driver\bin\2k\%DDKBUILDENV% 2> nul + +set TARGETPATH=bin\2k +set NPF_C_DEFINES=-DNDIS50 + +rem ** enable the following line to enable the TME extensions ** +rem set NPF_TME_FILES=tme.c count_packets.c tcp_session.c functions.c bucket_lookup.c normal_lookup.c win_bpf_filter_init.c +rem set NPF_C_DEFINES=%NPF_C_DEFINES% -DHAVE_BUGGY_TME_SUPPORT + +set NPF_JIT_FILES=jitter.c + +prefast build -cefw + +set TARGETPATH= +set NPF_C_DEFINES= +set NPF_TME_FILES= +set NPF_JIT_FILES= + +goto end + +:amd64_build + +echo ******************************************************* +echo * Compiling the driver for Windows NT5.x x64 (AMD64) * +echo ******************************************************* + +mkdir driver\bin 2> nul +mkdir driver\bin\xp 2> nul + +set TARGETPATH=bin\xp +set NPF_C_DEFINES=-DNDIS50 + +rem +rem The TME extensions and the JIT is not supported on x64, at the moment +rem +set NPF_TME_FILES= +set NPF_JIT_FILES= + +build -cefw + +set TARGETPATH= +set NPF_C_DEFINES= +set NPF_TME_FILES= +set NPF_JIT_FILES= + +goto end + +:ia64_build + +echo ******************************************************* +echo * Compiling the driver for Windows NT5.x IA64 * +echo ******************************************************* + +echo .. +echo ERROR: IA64 is not supported by WinPcap. +echo .. + +goto end + +:nt4_build + +echo ******************************************************* +echo * Compiling the driver for Windows NT4 * +echo * * +echo * NOTE: the script didn't detect the actual BUILD env * +echo * so it assumed NT4 DDK. * +echo ******************************************************* + +mkdir driver\bin 2> nul +mkdir driver\bin\NT4\i386 2> nul +mkdir driver\bin\NT4\i386\free 2> nul +mkdir driver\bin\NT4\i386\checked 2> nul + +set TARGETPATH=bin\NT4 +set NPF_C_DEFINES=-DNDIS30 -D__NPF_NT4__ + +rem ** enable the following line to enable the TME extensions ** +rem set NPF_TME_FILES=tme.c count_packets.c tcp_session.c functions.c bucket_lookup.c normal_lookup.c win_bpf_filter_init.c +rem set NPF_C_DEFINES=%NPF_C_DEFINES% -DHAVE_BUGGY_TME_SUPPORT + +set NPF_JIT_FILES=jitter.c + +if NOT "%NPF_COMPILED%" == "1" ( + set Include=%BASEDIR%\src\network\inc;%BASEDIR%\inc;%Include% + set NPF_COMPILED=1 + ) + +build -cefw + +set TARGETPATH= +set NPF_C_DEFINES= +set NPF_TME_FILES= +set NPF_JIT_FILES= + +goto end + +:end \ No newline at end of file diff --git a/winpcap/packetNtx/CompileNT4.bat b/winpcap/packetNtx/CompileNT4.bat new file mode 100644 index 0000000..0328fdf --- /dev/null +++ b/winpcap/packetNtx/CompileNT4.bat @@ -0,0 +1,24 @@ +@echo off + +echo ************************************************************ +echo * +echo * This compilation script has been OBSOLETED. +echo * +echo * Please use CompileDriver.bat to compile the driver +echo * for all the supported platforms (NT4,2k,xp,2k3,vista,x64) +echo * +echo ************************************************************ + +goto end + +if NOT "%NPF_COMPILED%" == "1" ( + set Include=%BASEDIR%\src\network\inc;%BASEDIR%\inc;%Include% + set NPF_COMPILED=1 + ) +set USER_C_DEFINES=-D__NPF_NT4__ -DNDIS30 +md \i386\free >nul 2>nul +md \i386\checked >nul 2>nul +build -cefw +set USER_C_DEFINES= + +:end \ No newline at end of file diff --git a/winpcap/packetNtx/DIRS b/winpcap/packetNtx/DIRS new file mode 100644 index 0000000..5976a6f --- /dev/null +++ b/winpcap/packetNtx/DIRS @@ -0,0 +1,2 @@ +DIRS=driver \ + diff --git a/winpcap/packetNtx/Dll/AdInfo.c b/winpcap/packetNtx/Dll/AdInfo.c new file mode 100644 index 0000000..304351b --- /dev/null +++ b/winpcap/packetNtx/Dll/AdInfo.c @@ -0,0 +1,2157 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + This file contains the support functions used by packet.dll to retrieve information about installed + adapters, like + + - the adapter list + - the device associated to any adapter and the description of the adapter + - physical parameters like the linkspeed or the link layer type + - the IP and link layer addresses */ + +#define UNICODE 1 + +#pragma warning (disable : 4127) //conditional expression is constant. Used for do{}while(FALSE) loops. + +#if (MSC_VER < 1300) +#pragma warning (disable : 4710) // inline function not expanded. used for strsafe functions +#endif + +#include +#include "Packet32-Int.h" +#include "debug.h" + +#ifdef HAVE_WANPACKET_API +#include "wanpacket/wanpacket.h" +#endif //HAVE_WANPACKET_API + +#include +#include +#include + + + +#include + +#include + +#include + +static BOOLEAN PacketAddFakeNdisWanAdapter(); + +PADAPTER_INFO g_AdaptersInfoList = NULL; ///< Head of the adapter information list. This list is populated when packet.dll is linked by the application. +HANDLE g_AdaptersInfoMutex = NULL; ///< Mutex that protects the adapter information list. NOTE: every API that takes an ADAPTER_INFO as parameter assumes that it has been called with the mutex acquired. + +extern FARPROC g_GetAdaptersAddressesPointer; + +#ifdef HAVE_AIRPCAP_API +extern AirpcapGetLastErrorHandler g_PAirpcapGetLastError; +extern AirpcapGetDeviceListHandler g_PAirpcapGetDeviceList; +extern AirpcapFreeDeviceListHandler g_PAirpcapFreeDeviceList; +extern AirpcapOpenHandler g_PAirpcapOpen; +extern AirpcapCloseHandler g_PAirpcapClose; +extern AirpcapGetLinkTypeHandler g_PAirpcapGetLinkType; +extern AirpcapSetKernelBufferHandler g_PAirpcapSetKernelBuffer; +extern AirpcapSetFilterHandler g_PAirpcapSetFilter; +extern AirpcapGetMacAddressHandler g_PAirpcapGetMacAddress; +extern AirpcapSetMinToCopyHandler g_PAirpcapSetMinToCopy; +extern AirpcapGetReadEventHandler g_PAirpcapGetReadEvent; +extern AirpcapReadHandler g_PAirpcapRead; +extern AirpcapGetStatsHandler g_PAirpcapGetStats; +#endif /* HAVE_AIRPCAP_API */ + +#ifdef HAVE_DAG_API +extern dagc_open_handler g_p_dagc_open; +extern dagc_close_handler g_p_dagc_close; +extern dagc_getlinktype_handler g_p_dagc_getlinktype; +extern dagc_getlinkspeed_handler g_p_dagc_getlinkspeed; +extern dagc_finddevs_handler g_p_dagc_finddevs; +extern dagc_freedevs_handler g_p_dagc_freedevs; +#endif /* HAVE_DAG_API */ + +/// Title of error windows +TCHAR szWindowTitle[] = TEXT("PACKET.DLL"); + +ULONG inet_addrU(const WCHAR *cp); + +extern HKEY WinpcapKey; +extern WCHAR *WinPcapKeyBuffer; + + +/*! + \brief Gets the link layer of an adapter, querying the registry. + \param AdapterObject Handle to an open adapter. + \param type Pointer to a NetType structure that will be filled by the function. + \return If the function succeeds, the return value is nonzero, otherwise the return value is zero. + + This function retrieves from the registry the link layer and the speed (in bps) of an opened adapter. + These values are copied in the NetType structure provided by the user. + The LinkType field of the type parameter can have one of the following values: + + - NdisMedium802_3: Ethernet (802.3) + - NdisMediumWan: WAN + - NdisMedium802_5: Token Ring (802.5) + - NdisMediumFddi: FDDI + - NdisMediumAtm: ATM + - NdisMediumArcnet878_2: ARCNET (878.2) +*/ +static BOOLEAN PacketGetLinkLayerFromRegistry(LPADAPTER AdapterObject, NetType *type) +{ + BOOLEAN Status; + ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); + PPACKET_OID_DATA OidData; + + TRACE_ENTER("PacketGetLinkLayerFromRegistry"); + + OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); + if (OidData == NULL) { + TRACE_PRINT("PacketGetLinkLayerFromRegistry failed"); + TRACE_EXIT("PacketGetLinkLayerFromRegistry"); + return FALSE; + } + //get the link-layer type + OidData->Oid = OID_GEN_MEDIA_IN_USE; + OidData->Length = sizeof (ULONG); + Status = PacketRequest(AdapterObject,FALSE,OidData); + type->LinkType=*((UINT*)OidData->Data); + + //get the link-layer speed + OidData->Oid = OID_GEN_LINK_SPEED; + OidData->Length = sizeof (ULONG); + Status = PacketRequest(AdapterObject,FALSE,OidData); + + if (Status == TRUE) + { + type->LinkSpeed=*((UINT*)OidData->Data)*100; + } + + GlobalFreePtr (OidData); + + TRACE_PRINT2("Media:%.010d" "\t" "Speed=%0.10I64u", + type->LinkType, + type->LinkSpeed); + + TRACE_EXIT("PacketGetLinkLayerFromRegistry"); + return Status; +} + + +/*! + \brief Scan the registry to retrieve the IP addresses of an adapter. + \param AdapterName String that contains the name of the adapter. + \param buffer A user allocated array of npf_if_addr that will be filled by the function. + \param NEntries Size of the array (in npf_if_addr). + \return If the function succeeds, the return value is nonzero. + + This function grabs from the registry information like the IP addresses, the netmasks + and the broadcast addresses of an interface. The buffer passed by the user is filled with + npf_if_addr structures, each of which contains the data for a single address. If the buffer + is full, the reaming addresses are dropeed, therefore set its dimension to sizeof(npf_if_addr) + if you want only the first address. +*/ +static BOOLEAN PacketGetAddressesFromRegistry(LPCSTR AdapterNameA, npf_if_addr* buffer, PLONG NEntries) +{ + WCHAR *IfNameW; + WCHAR AdapterNameW[ADAPTER_NAME_LENGTH]; + HKEY SystemKey; + HKEY InterfaceKey; + HKEY ParametersKey; + HKEY TcpIpKey; + HKEY UnderTcpKey; + LONG status; + WCHAR String[1024+1]; + DWORD RegType; + ULONG BufLen; + DWORD DHCPEnabled; + struct sockaddr_in *TmpAddr, *TmpBroad; + LONG naddrs,nmasks,StringPos; + DWORD ZeroBroadcast; +// +// Old registry based WinPcap names +// +// UINT RegQueryLen; +// WCHAR npfDeviceNamesPrefix[MAX_WINPCAP_KEY_CHARS]; + WCHAR npfDeviceNamesPrefix[MAX_WINPCAP_KEY_CHARS] = NPF_DEVICE_NAMES_PREFIX_WIDECHAR; + + TRACE_ENTER("PacketGetAddressesFromRegistry"); + + StringCchPrintfW(AdapterNameW, ADAPTER_NAME_LENGTH, L"%S", AdapterNameA); + + IfNameW = wcsrchr(AdapterNameW, L'\\'); + if (IfNameW == NULL) + IfNameW = AdapterNameW; + else + IfNameW++; + +// +// Old registry based WinPcap names +// +// RegQueryLen = sizeof(npfDeviceNamesPrefix)/sizeof(npfDeviceNamesPrefix[0]); +// +// if (QueryWinPcapRegistryStringW(TEXT(NPF_DEVICES_PREFIX_REG_KEY), npfDeviceNamesPrefix, &RegQueryLen, NPF_DEVICE_NAMES_PREFIX_WIDECHAR) == FALSE && RegQueryLen == 0) +// return FALSE; +// +// if (wcsncmp(ifname, npfDeviceNamesPrefix, RegQueryLen) == 0) +// ifname += RegQueryLen; + + if (wcsncmp(IfNameW, npfDeviceNamesPrefix, wcslen(npfDeviceNamesPrefix)) == 0) + IfNameW += wcslen(npfDeviceNamesPrefix); + + if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"), 0, KEY_READ, &UnderTcpKey) == ERROR_SUCCESS) + { + status = RegOpenKeyEx(UnderTcpKey,IfNameW,0,KEY_READ,&TcpIpKey); + if (status != ERROR_SUCCESS) { + RegCloseKey(UnderTcpKey); + goto fail; + } + } + else + { + // Query the registry key with the interface's adresses + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey); + if (status != ERROR_SUCCESS) + goto fail; + status = RegOpenKeyEx(SystemKey,IfNameW,0,KEY_READ,&InterfaceKey); + if (status != ERROR_SUCCESS) { + RegCloseKey(SystemKey); + RegCloseKey(UnderTcpKey); + goto fail; + } + RegCloseKey(SystemKey); + status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey); + if (status != ERROR_SUCCESS) { + RegCloseKey(InterfaceKey); + RegCloseKey(UnderTcpKey); + goto fail; + } + RegCloseKey(InterfaceKey); + status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey); + if (status != ERROR_SUCCESS) { + RegCloseKey(ParametersKey); + RegCloseKey(UnderTcpKey); + goto fail; + } + RegCloseKey(ParametersKey); + BufLen = sizeof String; + } + + BufLen = 4; + /* Try to detect if the interface has a zero broadcast addr */ + status=RegQueryValueEx(TcpIpKey,TEXT("UseZeroBroadcast"),NULL,&RegType,(LPBYTE)&ZeroBroadcast,&BufLen); + if (status != ERROR_SUCCESS) + ZeroBroadcast=0; + + BufLen = 4; + /* See if DHCP is used by this system */ + status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen); + if (status != ERROR_SUCCESS) + DHCPEnabled=0; + + + /* Retrieve the adrresses */ + if(DHCPEnabled){ + + BufLen = sizeof String; + // Open the key with the addresses + status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen); + if (status != ERROR_SUCCESS) { + RegCloseKey(TcpIpKey); + RegCloseKey(UnderTcpKey); + goto fail; + } + + // scan the key to obtain the addresses + StringPos = 0; + for(naddrs = 0;naddrs <* NEntries;naddrs++){ + TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress); + + if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ + TmpAddr->sin_family = AF_INET; + + TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast); + TmpBroad->sin_family = AF_INET; + if(ZeroBroadcast==0) + TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255 + else + TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0 + + while(*(String + StringPos) != 0)StringPos++; + StringPos++; + + if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen) + break; + } + else break; + } + + BufLen = sizeof String; + // Open the key with the netmasks + status = RegQueryValueEx(TcpIpKey,TEXT("DhcpSubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen); + if (status != ERROR_SUCCESS) { + RegCloseKey(TcpIpKey); + RegCloseKey(UnderTcpKey); + goto fail; + } + + // scan the key to obtain the masks + StringPos = 0; + for(nmasks = 0;nmasks < *NEntries;nmasks++){ + TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask); + + if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ + TmpAddr->sin_family = AF_INET; + + while(*(String + StringPos) != 0)StringPos++; + StringPos++; + + if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen) + break; + } + else break; + } + + // The number of masks MUST be equal to the number of adresses + if(nmasks != naddrs){ + RegCloseKey(TcpIpKey); + RegCloseKey(UnderTcpKey); + goto fail; + } + + } + else{ + + BufLen = sizeof String; + // Open the key with the addresses + status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen); + if (status != ERROR_SUCCESS) { + RegCloseKey(TcpIpKey); + RegCloseKey(UnderTcpKey); + goto fail; + } + + // scan the key to obtain the addresses + StringPos = 0; + for(naddrs = 0;naddrs < *NEntries;naddrs++){ + TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress); + + if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ + TmpAddr->sin_family = AF_INET; + + TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast); + TmpBroad->sin_family = AF_INET; + if(ZeroBroadcast==0) + TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255 + else + TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0 + + while(*(String + StringPos) != 0)StringPos++; + StringPos++; + + if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen) + break; + } + else break; + } + + BufLen = sizeof String; + // Open the key with the netmasks + status = RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen); + if (status != ERROR_SUCCESS) { + RegCloseKey(TcpIpKey); + RegCloseKey(UnderTcpKey); + goto fail; + } + + // scan the key to obtain the masks + StringPos = 0; + for(nmasks = 0;nmasks <* NEntries;nmasks++){ + TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask); + + if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ + TmpAddr->sin_family = AF_INET; + + while(*(String + StringPos) != 0)StringPos++; + StringPos++; + + if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen) + break; + } + else break; + } + + // The number of masks MUST be equal to the number of adresses + if(nmasks != naddrs){ + RegCloseKey(TcpIpKey); + RegCloseKey(UnderTcpKey); + goto fail; + } + + } + + *NEntries = naddrs + 1; + + RegCloseKey(TcpIpKey); + RegCloseKey(UnderTcpKey); + + if (status != ERROR_SUCCESS) { + goto fail; + } + + TRACE_PRINT("Successfully retrieved the addresses from the registry."); + TRACE_EXIT("PacketGetAddressesFromRegistry"); + return TRUE; + +fail: + + TRACE_PRINT("Failed retrieving the addresses from the registry."); + TRACE_EXIT("PacketGetAddressesFromRegistry"); + return FALSE; +} + +#ifdef HAVE_IPHELPER_API +/*! + \brief Adds the IPv6 addresses of an adapter to the ADAPTER_INFO structure that describes it. + \param AdInfo Pointer to the ADAPTER_INFO structure that keeps the information about the adapter. + \return If the function succeeds, the function returns TRUE. + + \note the structure pointed by AdInfo must be initialized the an properly filled. In particular, AdInfo->Name + must be a valid capture device name. + \note uses the GetAdaptersAddresses() Ip Helper API function, so it works only on systems where IP Helper API + provides it (WinXP and successive). + \note we suppose that we are called after having acquired the g_AdaptersInfoMutex mutex +*/ +static BOOLEAN PacketAddIP6Addresses(PADAPTER_INFO AdInfo) +{ + ULONG BufLen; + PIP_ADAPTER_ADDRESSES AdBuffer, TmpAddr; + PCHAR OrName; + PIP_ADAPTER_UNICAST_ADDRESS UnicastAddr; + struct sockaddr_storage *Addr; + INT AddrLen; +// +// Old registry based WinPcap names +// +// UINT RegQueryLen; +// CHAR npfDeviceNamesPrefix[MAX_WINPCAP_KEY_CHARS]; + CHAR npfDeviceNamesPrefix[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_COMPLETE_DEVICE_PREFIX; + + TRACE_ENTER("PacketAddIP6Addresses"); + + if(g_GetAdaptersAddressesPointer == NULL) + { + TRACE_PRINT("GetAdaptersAddressesPointer not available on the system, simply returning success..."); + + TRACE_EXIT("PacketAddIP6Addresses"); + return TRUE; // GetAdaptersAddresses() not present on this system, + } // return immediately. + + if(g_GetAdaptersAddressesPointer(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST| GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_FRIENDLY_NAME, NULL, NULL, &BufLen) != ERROR_BUFFER_OVERFLOW) + { + TRACE_PRINT("PacketAddIP6Addresses: GetAdaptersAddresses Failed while retrieving the needed buffer size"); + + TRACE_EXIT("PacketAddIP6Addresses"); + return FALSE; + } + + TRACE_PRINT("PacketAddIP6Addresses, retrieved needed storage for the call"); + + AdBuffer = GlobalAllocPtr(GMEM_MOVEABLE, BufLen); + if (AdBuffer == NULL) + { + TRACE_PRINT("PacketAddIP6Addresses: GlobalAlloc Failed"); + TRACE_EXIT("PacketAddIP6Addresses"); + return FALSE; + } + + if(g_GetAdaptersAddressesPointer(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST| GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_FRIENDLY_NAME, NULL, AdBuffer, &BufLen) != ERROR_SUCCESS) + { + TRACE_PRINT("PacketGetIP6Addresses: GetAdaptersAddresses Failed while retrieving the addresses"); + GlobalFreePtr(AdBuffer); + TRACE_EXIT("PacketAddIP6Addresses"); + return FALSE; + } + + TRACE_PRINT("PacketAddIP6Addresses, retrieved addresses, scanning the list"); + + // + // Scan the list of adddresses obtained from the IP helper API + // + for(TmpAddr = AdBuffer; TmpAddr != NULL; TmpAddr = TmpAddr->Next) + { +// +// Old registry based WinPcap names +// +// RegQueryLen = sizeof(npfDeviceNamesPrefix)/sizeof(npfDeviceNamesPrefix[0]); +// +// if (QueryWinPcapRegistryStringA(NPF_DRIVER_COMPLETE_DEVICE_PREFIX_REG_KEY, npfDeviceNamesPrefix, &RegQueryLen, NPF_DRIVER_COMPLETE_DEVICE_PREFIX) == FALSE && RegQueryLen == 0) +// continue; +// +// OrName = AdInfo->Name + RegQueryLen - 1; + + OrName = AdInfo->Name + strlen(npfDeviceNamesPrefix); + + TRACE_PRINT("PacketAddIP6Addresses, external loop"); + if(strcmp(TmpAddr->AdapterName, OrName) == 0) + { + // Found a corresponding adapter, scan its address list + for(UnicastAddr = TmpAddr->FirstUnicastAddress; UnicastAddr != NULL; UnicastAddr = UnicastAddr->Next) + { + TRACE_PRINT("PacketAddIP6Addresses, internal loop"); + + AddrLen = UnicastAddr->Address.iSockaddrLength; + Addr = (struct sockaddr_storage *)UnicastAddr->Address.lpSockaddr; + if(Addr->ss_family == AF_INET6) + { + // Be sure not to overflow the addresses buffer of this adapter + if(AdInfo->NNetworkAddresses >= MAX_NETWORK_ADDRESSES) + { + GlobalFreePtr(AdBuffer); + TRACE_PRINT("The space in AdInfo->NNetworkAddresses is not large enough, failing"); + TRACE_EXIT("PacketAddIP6Addresses"); + return FALSE; + } + + memcpy(&(AdInfo->NetworkAddresses[AdInfo->NNetworkAddresses].IPAddress), Addr, AddrLen); + memset(&(AdInfo->NetworkAddresses[AdInfo->NNetworkAddresses].SubnetMask), 0, sizeof(struct sockaddr_storage)); + memset(&(AdInfo->NetworkAddresses[AdInfo->NNetworkAddresses].Broadcast), 0, sizeof(struct sockaddr_storage)); + AdInfo->NNetworkAddresses ++; + } + } + } + } + + TRACE_PRINT("PacketAddIP6Addresses, finished parsing the addresses"); + + GlobalFreePtr(AdBuffer); + + TRACE_EXIT("PacketAddIP6Addresses"); + return TRUE; +} +#endif // HAVE_IPHELPER_API + +/*! + \brief Check if a string contains the "1394" substring + + We prevent opening of firewire adapters since they have non standard behaviors that can cause + problems with winpcap + + \param AdapterDesc NULL-terminated ASCII string with the adapter's description + \return TRUE if the input string contains "1394" +*/ +BOOLEAN IsFireWire(TCHAR *AdapterDesc) +{ + TRACE_ENTER("IsFireWire"); + if(wcsstr(AdapterDesc, FIREWIRE_SUBSTR) != NULL) + { + TRACE_EXIT("IsFireWire"); + return TRUE; + } + + TRACE_EXIT("IsFireWire"); + return FALSE; +} + +#ifdef HAVE_IPHELPER_API + +/*! + \brief Adds an entry to the adapter description list, gathering its values from the IP Helper API. + \param IphAd PIP_ADAPTER_INFO IP Helper API structure containing the parameters of the adapter that must be added to the list. + \return If the function succeeds, the return value is TRUE. + \note we suppose that we are called after having acquired the g_AdaptersInfoMutex mutex +*/ +static BOOLEAN PacketAddAdapterIPH(PIP_ADAPTER_INFO IphAd) +{ + PADAPTER_INFO TmpAdInfo, SAdInfo; + PIP_ADDR_STRING TmpAddrStr; + UINT i; + struct sockaddr_in *TmpAddr; + CHAR TName[256]; + LPADAPTER adapter; +// +// Old registry based WinPcap names +// +// UINT RegQueryLen; +// CHAR npfCompleteDriverPrefix[MAX_WINPCAP_KEY_CHARS]; + CHAR npfCompleteDriverPrefix[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_COMPLETE_DEVICE_PREFIX; + + TRACE_ENTER("PacketAddAdapterIPH"); + +// Create the NPF device name from the original device name + +// +// Old registry based WinPcap names +// +// RegQueryLen = sizeof(npfCompleteDriverPrefix)/sizeof(npfCompleteDriverPrefix[0]); +// +// if (QueryWinPcapRegistryStringA(NPF_DRIVER_COMPLETE_DEVICE_PREFIX_REG_KEY, npfCompleteDriverPrefix, &RegQueryLen, NPF_DRIVER_COMPLETE_DEVICE_PREFIX) == FALSE && RegQueryLen == 0) +// return FALSE; +// +// // Create the NPF device name from the original device name +// _snprintf(TName, +// sizeof(TName) - 1 - RegQueryLen - 1, +// "%s%s", +// npfCompleteDriverPrefix, +// IphAd->AdapterName); + + // Create the NPF device name from the original device name + StringCchPrintfA(TName, + sizeof(TName) - strlen(npfCompleteDriverPrefix), + "%s%s", + npfCompleteDriverPrefix, + IphAd->AdapterName); + + // Scan the adapters list to see if this one is already present + for(SAdInfo = g_AdaptersInfoList; SAdInfo != NULL; SAdInfo = SAdInfo->Next) + { + if(strcmp(TName, SAdInfo->Name) == 0) + { + TRACE_PRINT1("PacketAddAdapterIPH: Adapter %s already present in the list", TName); + goto SkipAd; + } + } + + if(IphAd->Type == IF_TYPE_PPP || IphAd->Type == IF_TYPE_SLIP) + { +#ifdef HAVE_WANPACKET_API + if (!WanPacketTestAdapter()) + goto SkipAd; +#else + goto SkipAd; +#endif + + } + else + { + + TRACE_PRINT1("Trying to open adapter %s to see if it's available...", TName); + adapter = PacketOpenAdapterNPF(TName); + + if(adapter == NULL) + { + // We are not able to open this adapter. Skip to the next one. + TRACE_PRINT1("PacketAddAdapterIPH: unable to open the adapter %s", TName); + goto SkipAd; + } + else + { + TRACE_PRINT1("PacketAddAdapterIPH: adapter %s is available", TName); + PacketCloseAdapter(adapter); + } + } + + // + // Adapter valid and not yet present in the list. Allocate the ADAPTER_INFO structure + // + TRACE_PRINT1("Adapter %s is available and should be added to the global list...", TName); + + TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO)); + if (TmpAdInfo == NULL) + { + TRACE_PRINT("PacketAddAdapterIPH: GlobalAlloc Failed allocating memory for the AdInfo"); + TRACE_EXIT("PacketAddAdapterIPH"); + return FALSE; + } + + // Copy the device name + StringCchCopyA(TmpAdInfo->Name,ADAPTER_NAME_LENGTH, TName); + + // Copy the description + StringCchCopyA(TmpAdInfo->Description, ADAPTER_DESC_LENGTH, IphAd->Description); + + // Copy the MAC address + TmpAdInfo->MacAddressLen = IphAd->AddressLength; + + memcpy(TmpAdInfo->MacAddress, + IphAd->Address, + (MAX_MAC_ADDR_LENGTHIpAddressList, i = 0; TmpAddrStr != NULL; TmpAddrStr = TmpAddrStr->Next, i++) + { + + } + + TmpAdInfo->NetworkAddresses = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, MAX_NETWORK_ADDRESSES * sizeof(npf_if_addr)); + if (TmpAdInfo->NetworkAddresses == NULL) { + TRACE_PRINT("PacketAddAdapterIPH: GlobalAlloc Failed allocating the memory for the IP addresses in AdInfo."); + GlobalFreePtr(TmpAdInfo); + TRACE_EXIT("PacketAddAdapterIPH"); + return FALSE; + } + + TRACE_PRINT1("Adding the IPv4 addresses to the adapter %s...", TName); + // Scan the addresses, convert them to addrinfo structures and put each of them in the list + for(TmpAddrStr = &IphAd->IpAddressList, i = 0; TmpAddrStr != NULL; TmpAddrStr = TmpAddrStr->Next) + { + TmpAddr = (struct sockaddr_in *)&(TmpAdInfo->NetworkAddresses[i].IPAddress); + if((TmpAddr->sin_addr.S_un.S_addr = inet_addr(TmpAddrStr->IpAddress.String))!= INADDR_NONE) + { + TmpAddr->sin_family = AF_INET; + TmpAddr = (struct sockaddr_in *)&(TmpAdInfo->NetworkAddresses[i].SubnetMask); + TmpAddr->sin_addr.S_un.S_addr = inet_addr(TmpAddrStr->IpMask.String); + TmpAddr->sin_family = AF_INET; + TmpAddr = (struct sockaddr_in *)&(TmpAdInfo->NetworkAddresses[i].Broadcast); + TmpAddr->sin_addr.S_un.S_addr = 0xffffffff; // Consider 255.255.255.255 as broadcast address since IP Helper API doesn't provide information about it + TmpAddr->sin_family = AF_INET; + i++; + } + } + + TmpAdInfo->NNetworkAddresses = i; + + + TRACE_PRINT1("Adding the IPv6 addresses to the adapter %s...", TName); + // Now Add IPv6 Addresses + PacketAddIP6Addresses(TmpAdInfo); + + if(IphAd->Type == IF_TYPE_PPP || IphAd->Type == IF_TYPE_SLIP) + { + TRACE_PRINT("Flagging the adapter as NDISWAN."); + // NdisWan adapter + TmpAdInfo->Flags = INFO_FLAG_NDISWAN_ADAPTER; + } + + // Update the AdaptersInfo list + TmpAdInfo->Next = g_AdaptersInfoList; + g_AdaptersInfoList = TmpAdInfo; + +SkipAd: + + TRACE_EXIT("PacketAddAdapterIPH"); + return TRUE; +} + +/*! + \brief Updates the list of the adapters querying the IP Helper API. + \return If the function succeeds, the return value is nonzero. + + This function populates the list of adapter descriptions, retrieving the information from a query to + the IP Helper API. The IP Helper API is used as a support of the standard registry query method to obtain + adapter information, so PacketGetAdaptersIPH() add only information about the adapters that were not + found by PacketGetAdapters(). +*/ +static BOOLEAN PacketGetAdaptersIPH() +{ + PIP_ADAPTER_INFO AdList = NULL; + PIP_ADAPTER_INFO TmpAd; + ULONG OutBufLen=0; + + TRACE_ENTER("PacketGetAdaptersIPH"); + + // Find the size of the buffer filled by GetAdaptersInfo + if(GetAdaptersInfo(AdList, &OutBufLen) == ERROR_NOT_SUPPORTED) + { + TRACE_PRINT("IP Helper API not supported on this system!"); + TRACE_EXIT("PacketGetAdaptersIPH"); + return FALSE; + } + + TRACE_PRINT("PacketGetAdaptersIPH: retrieved needed bytes for IPH"); + + // Allocate the buffer + AdList = GlobalAllocPtr(GMEM_MOVEABLE, OutBufLen); + if (AdList == NULL) + { + TRACE_PRINT("PacketGetAdaptersIPH: GlobalAlloc Failed allocating the buffer for GetAdaptersInfo"); + TRACE_EXIT("PacketGetAdaptersIPH"); + return FALSE; + } + + // Retrieve the adapters information using the IP helper API + GetAdaptersInfo(AdList, &OutBufLen); + + TRACE_PRINT("PacketGetAdaptersIPH: retrieved list from IPH. Adding adapters to the global list."); + + // Scan the list of adapters obtained from the IP helper API, create a new ADAPTER_INFO + // structure for every new adapter and put it in our global list + for(TmpAd = AdList; TmpAd != NULL; TmpAd = TmpAd->Next) + { + PacketAddAdapterIPH(TmpAd); + } + + GlobalFreePtr(AdList); + + TRACE_EXIT("PacketGetAdaptersIPH"); + return TRUE; +} + +#endif // HAVE_IPHELPER_API + + +/*! + \brief Adds an entry to the adapter description list. + \param AdName Name of the adapter to add + \return If the function succeeds, the return value is nonzero. + + Used by PacketGetAdapters(). Queries the registry to fill the PADAPTER_INFO describing the new adapter. +*/ +static BOOLEAN PacketAddAdapterNPF(PCHAR AdName, UINT flags) +{ + //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter + LONG Status; + LPADAPTER adapter = NULL; + PPACKET_OID_DATA OidData = NULL; + PADAPTER_INFO TmpAdInfo; + PADAPTER_INFO TAdInfo; + + TRACE_ENTER("PacketAddAdapterNPF"); + TRACE_PRINT1("Trying to add adapter %s", AdName); + + // + // let's check that the adapter name will fit in the space available within ADAPTER_INFO::Name + // If not, simply fail, since we cannot properly save the adapter name + // + if (strlen(AdName) + 1 > sizeof(TmpAdInfo->Name)) + { + TRACE_PRINT("PacketAddAdapterNPF: adapter name is too long to be stored into ADAPTER_INFO::Name, simply skip it"); + return FALSE; + } + + WaitForSingleObject(g_AdaptersInfoMutex, INFINITE); + + for(TAdInfo = g_AdaptersInfoList; TAdInfo != NULL; TAdInfo = TAdInfo->Next) + { + if(strcmp(AdName, TAdInfo->Name) == 0) + { + TRACE_PRINT("PacketAddAdapterNPF: Adapter already present in the list"); + ReleaseMutex(g_AdaptersInfoMutex); + TRACE_EXIT("PacketAddAdapterNPF"); + return TRUE; + } + } + + //here we could have released the mutex, but what happens if two threads try to add the same adapter? + //The adapter would be duplicated on the linked list + + if(flags != INFO_FLAG_DONT_EXPORT) + { + TRACE_PRINT("Trying to open the NPF adapter and see if it's available..."); + + // Try to Open the adapter + adapter = PacketOpenAdapterNPF(AdName); + + if(adapter != NULL) + { + + // Allocate a buffer to get the vendor description from the driver + OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,512); + if (OidData == NULL) + { + TRACE_PRINT("PacketAddAdapterNPF: GlobalAlloc Failed allocating the buffer for the OID request to obtain the NIC description. Returning."); + PacketCloseAdapter(adapter); + ReleaseMutex(g_AdaptersInfoMutex); + TRACE_EXIT("PacketAddAdapterNPF"); + return FALSE; + } + } + else + { + TRACE_PRINT("NPF Adapter not available, do not add it to the global list"); + // We are not able to open this adapter. Skip to the next one. + ReleaseMutex(g_AdaptersInfoMutex); + TRACE_EXIT("AddAdapter"); + return FALSE; + } + } + + + // + // PacketOpenAdapter was succesful. Consider this a valid adapter and allocate an entry for it + // In the adapter list + // + + TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO)); + if (TmpAdInfo == NULL) + { + TRACE_PRINT("AddAdapter: GlobalAlloc Failed"); + + if(flags != INFO_FLAG_DONT_EXPORT) + { + TRACE_PRINT("AddAdapter: GlobalAlloc Failed allocating the buffer for the AdInfo to be added to the global list. Returning."); + if (OidData != NULL) GlobalFreePtr(OidData); + PacketCloseAdapter(adapter); + } + + ReleaseMutex(g_AdaptersInfoMutex); + TRACE_EXIT("AddAdapter"); + return FALSE; + } + + // Copy the device name + strncpy(TmpAdInfo->Name, AdName, sizeof(TmpAdInfo->Name)/ sizeof(TmpAdInfo->Name[0]) - 1); + + //we do not need to terminate the string TmpAdInfo->Name, since we have left a char at the end, and + //the memory for TmpAdInfo was zeroed upon allocation + + if(flags != INFO_FLAG_DONT_EXPORT) + { + // Retrieve the adapter description querying the NIC driver + OidData->Oid = OID_GEN_VENDOR_DESCRIPTION; + OidData->Length = 256; + ZeroMemory(OidData->Data, 256); + + Status = PacketRequest(adapter, FALSE, OidData); + + if(Status==0 || ((char*)OidData->Data)[0]==0) + { + TRACE_PRINT("AddAdapter: unable to get a valid adapter description from the NIC driver"); + } + + TRACE_PRINT1("Adapter Description = %s",OidData->Data); + + // Copy the description + strncpy(TmpAdInfo->Description, (PCHAR)OidData->Data, sizeof(TmpAdInfo->Description)/ sizeof(TmpAdInfo->Description[0]) - 1); + //we do not need to terminate the string TmpAdInfo->Description, since we have left a char at the end, and + //the memory for TmpAdInfo was zeroed upon allocation + + Status = PacketGetLinkLayerFromRegistry(adapter, &(TmpAdInfo->LinkLayer)); + + if (Status == FALSE) + { + TRACE_PRINT("AddAdapter: PacketGetLinkLayerFromRegistry failed. Returning."); + PacketCloseAdapter(adapter); + GlobalFreePtr(OidData); + GlobalFreePtr(TmpAdInfo); + ReleaseMutex(g_AdaptersInfoMutex); + TRACE_EXIT("AddAdapter"); + return FALSE; + } + + // Retrieve the adapter MAC address querying the NIC driver + OidData->Oid = OID_802_3_CURRENT_ADDRESS; // XXX At the moment only Ethernet is supported. + // Waiting a patch to support other Link Layers + OidData->Length = 256; + ZeroMemory(OidData->Data, 256); + + TRACE_PRINT("Trying to obtain the MAC address for the NIC..."); + Status = PacketRequest(adapter, FALSE, OidData); + if(Status) + { + memcpy(TmpAdInfo->MacAddress, OidData->Data, 6); + TmpAdInfo->MacAddressLen = 6; + + TRACE_PRINT6("Successfully obtained the MAC address, it's " + "%.02x:%.02x:%.02x:%.02x:%.02x:%.02x", + TmpAdInfo->MacAddress[0], + TmpAdInfo->MacAddress[1], + TmpAdInfo->MacAddress[2], + TmpAdInfo->MacAddress[3], + TmpAdInfo->MacAddress[4], + TmpAdInfo->MacAddress[5]); + + + } + else + { + TRACE_PRINT("Failed obtaining the MAC address, put a fake 00:00:00:00:00:00"); + memset(TmpAdInfo->MacAddress, 0, 6); + TmpAdInfo->MacAddressLen = 0; + } + + // Retrieve IP addresses + TmpAdInfo->NetworkAddresses = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, MAX_NETWORK_ADDRESSES * sizeof(npf_if_addr)); + if (TmpAdInfo->NetworkAddresses == NULL) { + TRACE_PRINT("AddAdapter: GlobalAlloc Failed to allocate the buffer for the IP addresses in the AdInfo structure. Returning."); + PacketCloseAdapter(adapter); + GlobalFreePtr(OidData); + GlobalFreePtr(TmpAdInfo); + ReleaseMutex(g_AdaptersInfoMutex); + TRACE_EXIT("AddAdapter"); + return FALSE; + } + + TmpAdInfo->NNetworkAddresses = MAX_NETWORK_ADDRESSES; + if(!PacketGetAddressesFromRegistry(TmpAdInfo->Name, TmpAdInfo->NetworkAddresses, (long*)&TmpAdInfo->NNetworkAddresses)) + { +#ifdef HAVE_IPHELPER_API + // Try to see if the interface has some IPv6 addresses + TmpAdInfo->NNetworkAddresses = 0; // We have no addresses because PacketGetAddressesFromRegistry() failed + + if(!PacketAddIP6Addresses(TmpAdInfo)) + { +#endif // HAVE_IPHELPER_API + GlobalFreePtr(TmpAdInfo->NetworkAddresses); + TmpAdInfo->NetworkAddresses = NULL; + TmpAdInfo->NNetworkAddresses = 0; +#ifdef HAVE_IPHELPER_API + } +#endif // HAVE_IPHELPER_API + } + +#ifdef HAVE_IPHELPER_API + // Now Add IPv6 Addresses + PacketAddIP6Addresses(TmpAdInfo); +#endif // HAVE_IPHELPER_API + + TmpAdInfo->Flags = INFO_FLAG_NDIS_ADAPTER; // NdisWan adapters are not exported by the NPF driver, + // therefore it's impossible to see them here + + // Free storage + PacketCloseAdapter(adapter); + GlobalFreePtr(OidData); + } + else + { + // Write in the flags that this adapter is firewire + // This will block it in all successive calls + TmpAdInfo->Flags = INFO_FLAG_DONT_EXPORT; + } + + // Update the AdaptersInfo list + TmpAdInfo->Next = g_AdaptersInfoList; + g_AdaptersInfoList = TmpAdInfo; + + ReleaseMutex(g_AdaptersInfoMutex); + + TRACE_EXIT("AddAdapter"); + return TRUE; +} + + +/*! + \brief Updates the list of the adapters querying the registry. + \return If the function succeeds, the return value is nonzero. + + This function populates the list of adapter descriptions, retrieving the information from the registry. +*/ +static BOOLEAN PacketGetAdaptersNPF() +{ + HKEY LinkageKey,AdapKey, OneAdapKey; + DWORD RegKeySize=0; + LONG Status; + ULONG Result; + INT i; + DWORD dim; + DWORD RegType; + WCHAR TName[256]; + CHAR TAName[256]; + TCHAR AdapName[256]; + CHAR *TcpBindingsMultiString; + UINT FireWireFlag; +// +// Old registry based WinPcap names +// +// CHAR npfCompleteDriverPrefix[MAX_WINPCAP_KEY_CHARS]; +// UINT RegQueryLen; + + CHAR npfCompleteDriverPrefix[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_COMPLETE_DEVICE_PREFIX; + CHAR DeviceGuidName[256]; + + TRACE_ENTER("PacketGetAdaptersNPF"); + +// +// Old registry based WinPcap names +// +// // Get device prefixes from the registry +// RegQueryLen = sizeof(npfCompleteDriverPrefix)/sizeof(npfCompleteDriverPrefix[0]); +// +// if (QueryWinPcapRegistryStringA(NPF_DRIVER_COMPLETE_DEVICE_PREFIX_REG_KEY, npfCompleteDriverPrefix, &RegQueryLen, NPF_DRIVER_COMPLETE_DEVICE_PREFIX) == FALSE && RegQueryLen == 0) +// return FALSE; + + Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE, + TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"), + 0, + KEY_READ, + &AdapKey); + + if ( Status != ERROR_SUCCESS ){ + TRACE_PRINT("PacketGetAdaptersNPF: RegOpenKeyEx ( Class\\{networkclassguid} ) Failed"); + goto tcpip_linkage; + } + + i = 0; + + TRACE_PRINT("PacketGetAdaptersNPF: RegOpenKeyEx ( Class\\{networkclassguid} ) was successful"); + TRACE_PRINT("PacketGetAdaptersNPF: Cycling through the adapters in the registry:"); + + // + // Cycle through the entries inside the {4D36E972-E325-11CE-BFC1-08002BE10318} key + // To get the names of the adapters + // + while((Result = RegEnumKey(AdapKey, i, AdapName, sizeof(AdapName)/2)) == ERROR_SUCCESS) + { + i++; + FireWireFlag = 0; + + // + // Get the adapter name from the registry key + // + Status=RegOpenKeyEx(AdapKey, AdapName, 0, KEY_READ, &OneAdapKey); + if ( Status != ERROR_SUCCESS ) + { + TRACE_PRINT1("%d) RegOpenKey( OneAdapKey ) Failed, skipping the adapter.",i); + continue; + } + + // + // + // Check if this is a FireWire adapter, looking for "1394" in its ComponentId string. + // We prevent listing FireWire adapters because winpcap can open them, but their interface + // with the OS is broken and they can cause blue screens. + // + dim = sizeof(TName); + Status = RegQueryValueEx(OneAdapKey, + TEXT("ComponentId"), + NULL, + NULL, + (PBYTE)TName, + &dim); + + if(Status == ERROR_SUCCESS) + { + if(IsFireWire(TName)) + { + FireWireFlag = INFO_FLAG_DONT_EXPORT; + } + } + + Status=RegOpenKeyEx(OneAdapKey, TEXT("Linkage"), 0, KEY_READ, &LinkageKey); + if (Status != ERROR_SUCCESS) + { + RegCloseKey(OneAdapKey); + TRACE_PRINT1("%d) RegOpenKeyEx ( LinkageKey ) Failed, skipping the adapter",i); + continue; + } + + dim = sizeof(DeviceGuidName); + Status=RegQueryValueExA(LinkageKey, + "Export", + NULL, + NULL, + (PBYTE)DeviceGuidName, + &dim); + + if(Status != ERROR_SUCCESS) + { + RegCloseKey(OneAdapKey); + RegCloseKey(LinkageKey); + TRACE_PRINT1("%d) Name = SKIPPED (error reading the key)", i); + continue; + } + + if (strlen(DeviceGuidName) >= strlen("\\Device\\")) + { + // Put the \Device\NPF_ string at the beginning of the name + StringCchPrintfA(TAName, sizeof(TAName), "%s%s", + npfCompleteDriverPrefix, + DeviceGuidName + strlen("\\Device\\")); + } + else + continue; + + //terminate the string, just in case + TAName[sizeof(TAName) - 1] = '\0'; + + TRACE_PRINT2("%d) Successfully retrieved info for adapter %s, trying to add it to the global list...", i, TAName); + // If the adapter is valid, add it to the list. + PacketAddAdapterNPF(TAName, FireWireFlag); + + RegCloseKey(OneAdapKey); + RegCloseKey(LinkageKey); + + } // while enum reg keys + + RegCloseKey(AdapKey); + +tcpip_linkage: + // + // no adapters were found under {4D36E972-E325-11CE-BFC1-08002BE10318}. This means with great probability + // that we are under Windows NT 4, so we try to look under the tcpip bindings. + // + + TRACE_PRINT("Adapters not found under SYSTEM\\CurrentControlSet\\Control\\Class. Using the TCP/IP bindings."); + + Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage"), + 0, + KEY_READ, + &LinkageKey); + + if (Status == ERROR_SUCCESS) + { + // Retrieve the length of th binde key + // This key contains the name of the devices as \device\foo + //in ASCII, separated by a single '\0'. The list is terminated + //by another '\0' + Status=RegQueryValueExA(LinkageKey, + "bind", + NULL, + &RegType, + NULL, + &RegKeySize); + + // Allocate the buffer + TcpBindingsMultiString = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, RegKeySize + 2); + + if (TcpBindingsMultiString == NULL) + { + TRACE_PRINT("GlobalAlloc failed allocating memory for the registry key, returning."); + TRACE_EXIT("PacketGetAdaptersNPF"); + return FALSE; + } + + // Query the key again to get its content + Status = RegQueryValueExA(LinkageKey, + "bind", + NULL, + &RegType, + (LPBYTE)TcpBindingsMultiString, + &RegKeySize); + + RegCloseKey(LinkageKey); + + // Scan the buffer with the device names + for(i = 0;;) + { + if (TcpBindingsMultiString[i] == '\0') + break; + + StringCchPrintfA(TAName, sizeof(TAName), "%s%s", + npfCompleteDriverPrefix, + TcpBindingsMultiString + i + strlen("\\Device\\")); + + // + // TODO GV: this cast to avoid a compilation warning is + // actually stupid. We shouls check not to go over the buffer boundary! + // + i += (INT)strlen(&TcpBindingsMultiString[i]) + 1; + + TRACE_PRINT1("Successfully retrieved info for adapter %s, trying to add it to the global list...", TAName); + + + // If the adapter is valid, add it to the list. + PacketAddAdapterNPF(TAName, 0); + } + + GlobalFreePtr(TcpBindingsMultiString); + } + + else{ +#ifdef _WINNT4 + MessageBox(NULL,TEXT("Can not find TCP/IP bindings.\nIn order to run the packet capture driver you must install TCP/IP."),szWindowTitle,MB_OK); + TRACE_PRINT("Cannot find the TCP/IP bindings on NT4, no adapters."); + TRACE_EXIT("PacketGetAdaptersNPF"); + return FALSE; +#endif + } + + TRACE_EXIT("PacketGetAdaptersNPF"); + return TRUE; +} + +#ifdef HAVE_AIRPCAP_API +/*! + \brief Add an airpcap adapter to the adapters info list, gathering information from the airpcap dll + \param name Name of the adapter. + \param description description of the adapter. + \return If the function succeeds, the return value is nonzero. +*/ +static BOOLEAN PacketAddAdapterAirpcap(PCHAR name, PCHAR description) +{ + //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter + CHAR ebuf[AIRPCAP_ERRBUF_SIZE]; + PADAPTER_INFO TmpAdInfo; + PAirpcapHandle AirpcapAdapter; + BOOL GllRes; + AirpcapLinkType AirpcapLinkLayer; + BOOLEAN Result = TRUE; + + TRACE_ENTER("PacketAddAdapterAirpcap"); + //XXX what about checking if the adapter already exists??? + + WaitForSingleObject(g_AdaptersInfoMutex, INFINITE); + + do + { + + // + // check if the adapter is already there, and remove it + // + for (TmpAdInfo = g_AdaptersInfoList; TmpAdInfo != NULL; TmpAdInfo = TmpAdInfo->Next) + { + if (TmpAdInfo->Flags == INFO_FLAG_AIRPCAP_CARD) + { + if (strcmp(TmpAdInfo->Name, name) == 0) + break; + } + } + + if (TmpAdInfo != NULL) + { + // + // we already have it in the list. Just return + // + Result = TRUE; + break; + } + + // + // Allocate a descriptor for this adapter + // + //here we do not acquire the mutex, since we are not touching the list, yet. + TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO)); + if (TmpAdInfo == NULL) + { + TRACE_PRINT("PacketAddAdapterDag: GlobalAlloc Failed"); + Result = FALSE; + break; + } + + // Copy the device name and description + StringCchCopyA(TmpAdInfo->Name, + sizeof(TmpAdInfo->Name), + name); + + StringCchCopyA(TmpAdInfo->Description, + sizeof(TmpAdInfo->Description), + description); + + TmpAdInfo->Flags = INFO_FLAG_AIRPCAP_CARD; + + if(g_PAirpcapOpen) + { + AirpcapAdapter = g_PAirpcapOpen(name, ebuf); + } + else + { + AirpcapAdapter = NULL; + } + + if(!AirpcapAdapter) + { + GlobalFreePtr(TmpAdInfo); + Result = FALSE; + break; + } + + GllRes = g_PAirpcapGetLinkType(AirpcapAdapter, &AirpcapLinkLayer); + if(!GllRes) + { + g_PAirpcapClose(AirpcapAdapter); + GlobalFreePtr(TmpAdInfo); + Result = FALSE; + break; + } + + switch(AirpcapLinkLayer) + { + case AIRPCAP_LT_802_11: + TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumBare80211; + break; + case AIRPCAP_LT_802_11_PLUS_RADIO: + TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumRadio80211; + break; + default: + TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumNull; // Note: custom linktype, NDIS doesn't provide an equivalent + break; + } + + // + // For the moment, we always set the speed to 54Mbps, since the speed is not channel-specific, + // but per packet + // + TmpAdInfo->LinkLayer.LinkSpeed = 54000000; + + g_PAirpcapClose(AirpcapAdapter); + + // Update the AdaptersInfo list + TmpAdInfo->Next = g_AdaptersInfoList; + g_AdaptersInfoList = TmpAdInfo; + } + while(FALSE); + + ReleaseMutex(g_AdaptersInfoMutex); + + TRACE_EXIT("PacketAddAdapterAirpcap"); + return Result; +} + +/*! + \brief Updates the list of the adapters using the airpcap dll. + \return If the function succeeds, the return value is nonzero. + + This function populates the list of adapter descriptions, looking for DAG cards on the system. +*/ +static BOOLEAN PacketGetAdaptersAirpcap() +{ + CHAR Ebuf[AIRPCAP_ERRBUF_SIZE]; + AirpcapDeviceDescription *Devs = NULL, *TmpDevs; + UINT i; + + TRACE_ENTER("PacketGetAdaptersAirpcap"); + + if(!g_PAirpcapGetDeviceList(&Devs, Ebuf)) + { + // No airpcap cards found on this system + TRACE_PRINT("No AirPcap adapters found"); + TRACE_EXIT("PacketGetAdaptersAirpcap"); + return FALSE; + } + else + { + for(TmpDevs = Devs, i = 0; TmpDevs != NULL; TmpDevs = TmpDevs->next) + { + PacketAddAdapterAirpcap(TmpDevs->Name, TmpDevs->Description); + } + } + + g_PAirpcapFreeDeviceList(Devs); + + TRACE_EXIT("PacketGetAdaptersAirpcap"); + return TRUE; +} +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_NPFIM_API + +static BOOLEAN PacketAddAdapterNpfIm(PNPF_IM_DEVICE pDevice) +{ + //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter + PADAPTER_INFO TmpAdInfo; + NPF_IM_DEV_HANDLE handle = NULL; + BYTE mac[6]; + DWORD macSize = 0; + NDIS_MEDIUM medium = NdisMediumNull; + ULONGLONG linkSpeed = 0; + BOOL bResult = TRUE; + PNPF_IM_ADDRESS pAddresses = NULL; + DWORD addressesSize = 0; + DWORD returnedBytes = 0; + npf_if_addr *pnpf_if_addresses = NULL; + DWORD numAddresses; + DWORD i; + + TRACE_ENTER("PacketAddAdapterNpfIm"); + + WaitForSingleObject(g_AdaptersInfoMutex, INFINITE); + + do + { + // + // check if the adapter is already there, and remove it + // + for (TmpAdInfo = g_AdaptersInfoList; TmpAdInfo != NULL; TmpAdInfo = TmpAdInfo->Next) + { + if (TmpAdInfo->Flags == INFO_FLAG_NPFIM_DEVICE) + { + if (strcmp(TmpAdInfo->Name, pDevice->Name) == 0) + break; + } + } + + if (TmpAdInfo != NULL) + { + // + // we already have it in the list. Just return + // + + // + // NOTE in this case we do not refresh the IP list + // + bResult = TRUE; + break; + } + + do + { + // + // We suppose that the DLL has been loaded successfully + // + bResult = g_NpfImHandlers.NpfImOpenDevice(pDevice->Name, &handle); + if (bResult == FALSE) break; + + bResult = g_NpfImHandlers.NpfImGetMedium(handle, &medium); + if (bResult == FALSE) break; + + if (medium == NdisMedium802_3 || medium == NdisMediumWan) + { + DWORD bufferSize = sizeof(mac); + + if (g_NpfImHandlers.NpfImIssueQueryOid(handle, OID_802_3_CURRENT_ADDRESS, mac, &bufferSize) == FALSE) + { + macSize = 0; + } + } + + bResult = g_NpfImHandlers.NpfImGetLinkSpeed(handle, &linkSpeed); + + if (bResult == FALSE) + { + break; + } + + bResult = g_NpfImHandlers.NpfImGetIpAddresses(handle, NULL, 0, &returnedBytes); + + if (bResult == TRUE) + { + // + // no ip addresses, return + // + break; + } + + if (GetLastError() == ERROR_MORE_DATA) + { + pAddresses = (PNPF_IM_ADDRESS)LocalAlloc(LPTR, returnedBytes); + if (pAddresses == NULL) + { + bResult = FALSE; + break; + } + + addressesSize = returnedBytes; + + bResult = g_NpfImHandlers.NpfImGetIpAddresses(handle, pAddresses, addressesSize, &returnedBytes); + } + else + { + // + //unknown error listing the IP addresses + // + break; + } + + } + while (FALSE); + + if (handle != NULL) + g_NpfImHandlers.NpfImCloseDevice(handle); + + if (bResult == FALSE) + { + break; + } + + numAddresses = returnedBytes / sizeof(NPF_IM_ADDRESS); + + // + // Allocate a descriptor for this adapter + // + //here we do not acquire the mutex, since we are not touching the list, yet. + TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO)); + if (TmpAdInfo == NULL) + { + TRACE_PRINT("PacketAddAdapterNpfIm: GlobalAlloc Failed"); + bResult = FALSE; + break; + } + + if (numAddresses > 0) + { + pnpf_if_addresses = (npf_if_addr*)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(npf_if_addr) * numAddresses); + + if (pnpf_if_addresses == NULL) + { + GlobalFreePtr(TmpAdInfo); + TRACE_PRINT("PacketAddAdapteNpfIm: GlobalAlloc failed"); + bResult = FALSE; + break; + } + + for (i = 0; i < numAddresses; i++) + { + DWORD ipAddr, netMask, broadCast; + + CopyMemory(&(pnpf_if_addresses[i].IPAddress), &(pAddresses[i].IPAddress), sizeof(struct sockaddr_storage)); + + // + // generate the broadcast addr + switch(pAddresses[i].IPAddress.ss_family) + { + case AF_INET: + CopyMemory(&(pnpf_if_addresses[i].SubnetMask), &(pAddresses[i].SubnetMask), sizeof(struct sockaddr_storage)); + CopyMemory(&(pnpf_if_addresses[i].Broadcast), &(pAddresses[i].SubnetMask), sizeof(struct sockaddr_storage)); + ipAddr = ((struct sockaddr_in*)(&pnpf_if_addresses[i].IPAddress))->sin_addr.S_un.S_addr; + netMask = ((struct sockaddr_in*)(&pnpf_if_addresses[i].SubnetMask))->sin_addr.S_un.S_addr; + broadCast = ipAddr | (~netMask); + ((struct sockaddr_in*)(&pnpf_if_addresses[i].Broadcast))->sin_addr.S_un.S_addr = broadCast; + break; + + case AF_INET6: + default: + ZeroMemory(&(pnpf_if_addresses[i].SubnetMask), sizeof(struct sockaddr_storage)); + ZeroMemory(&(pnpf_if_addresses[i].Broadcast), sizeof(struct sockaddr_storage)); + break; + } + } + + // + // put the ip addresses + // + TmpAdInfo->NetworkAddresses = pnpf_if_addresses; + TmpAdInfo->NNetworkAddresses = numAddresses; + + } + + + + // Copy the device name and description + StringCchCopyA(TmpAdInfo->Name, + sizeof(TmpAdInfo->Name), + pDevice->Name); + + StringCchCopyA(TmpAdInfo->Description, + sizeof(TmpAdInfo->Description), + pDevice->Description); + + CopyMemory(TmpAdInfo->MacAddress, mac, macSize); + TmpAdInfo->LinkLayer.LinkType = medium; + + TmpAdInfo->Flags = INFO_FLAG_NPFIM_DEVICE; + + TmpAdInfo->LinkLayer.LinkSpeed = linkSpeed; + + // Update the AdaptersInfo list + TmpAdInfo->Next = g_AdaptersInfoList; + g_AdaptersInfoList = TmpAdInfo; + } + while(FALSE); + + if (pAddresses != NULL) LocalFree(pAddresses); + + ReleaseMutex(g_AdaptersInfoMutex); + + TRACE_EXIT("PacketAddAdapterNpfIm"); + return (BOOLEAN)bResult; +} + + +/*! + \brief Updates the list of the adapters using the NpfIm dll. + \return If the function succeeds, the return value is nonzero. + + This function populates the list of adapter descriptions, looking for NpfIm adapters on the system. +*/ +static BOOLEAN PacketGetAdaptersNpfIm() +{ + PNPF_IM_DEVICE pDevices = NULL, pDevCursor; + + TRACE_ENTER("PacketGetAdaptersNpfIm"); + // + // We suppose that the DLL has been loaded successfully + // + if (g_NpfImHandlers.NpfImGetDeviceList(&pDevices) == FALSE) + { + TRACE_EXIT("PacketGetAdaptersNpfIm"); + return FALSE; + } + + for (pDevCursor = pDevices; pDevCursor != NULL; pDevCursor = pDevCursor->pNext) + { + PacketAddAdapterNpfIm(pDevCursor); + } + + g_NpfImHandlers.NpfImFreeDeviceList(pDevices); + + TRACE_EXIT("PacketGetAdaptersNpfIm"); + return TRUE; +} + +/*! + \brief Add an npfim adapter to the adapters info list, gathering information from the npfim dll + \param + \param description description of the adapter. + \return If the function succeeds, the return value is nonzero. +*/ +#endif // HAVE_NPFIM_API + + + +#ifdef HAVE_DAG_API +/*! + \brief Add a dag adapter to the adapters info list, gathering information from the dagc API + \param name Name of the adapter. + \param description description of the adapter. + \return If the function succeeds, the return value is nonzero. +*/ +BOOLEAN PacketAddAdapterDag(PCHAR name, PCHAR description, BOOLEAN IsAFile) +{ + //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter + CHAR ebuf[DAGC_ERRBUF_SIZE]; + PADAPTER_INFO TmpAdInfo; + dagc_t *dagfd; + + TRACE_ENTER("PacketAddAdapterDag"); + + //XXX what about checking if the adapter already exists??? + + // + // Allocate a descriptor for this adapter + // + //here we do not acquire the mutex, since we are not touching the list, yet. + TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO)); + if (TmpAdInfo == NULL) + { + TRACE_PRINT("PacketAddAdapterDag: GlobalAlloc Failed allocating memory for the AdInfo structure."); + TRACE_EXIT("PacketAddAdapterDag"); + return FALSE; + } + + // Copy the device name and description + StringCchCopyA(TmpAdInfo->Name, + sizeof(TmpAdInfo->Name), + name); + + StringCchCopyA(TmpAdInfo->Description, + sizeof(TmpAdInfo->Description), + description); + + if(IsAFile) + TmpAdInfo->Flags = INFO_FLAG_DAG_FILE; + else + TmpAdInfo->Flags = INFO_FLAG_DAG_CARD; + + if(g_p_dagc_open) + dagfd = g_p_dagc_open(name, 0, ebuf); + else + dagfd = NULL; + + if(!dagfd) + { + GlobalFreePtr(TmpAdInfo); + TRACE_EXIT("PacketAddAdapterDag"); + return FALSE; + } + + TmpAdInfo->LinkLayer.LinkType = g_p_dagc_getlinktype(dagfd); + + switch(g_p_dagc_getlinktype(dagfd)) + { + case TYPE_HDLC_POS: + TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumCHDLC; // Note: custom linktype, NDIS doesn't provide an equivalent + break; + case -TYPE_HDLC_POS: + TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumPPPSerial; // Note: custom linktype, NDIS doesn't provide an equivalent + break; + case TYPE_ETH: + TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMedium802_3; + break; + case TYPE_ATM: + TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumAtm; + break; + default: + TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumNull; // Note: custom linktype, NDIS doesn't provide an equivalent + break; + } + + TmpAdInfo->LinkLayer.LinkSpeed = (g_p_dagc_getlinkspeed(dagfd) == -1)? + 100000000: // Unknown speed, default to 100Mbit + g_p_dagc_getlinkspeed(dagfd) * 1000000; + + g_p_dagc_close(dagfd); + + WaitForSingleObject(g_AdaptersInfoMutex, INFINITE); + + // Update the AdaptersInfo list + TmpAdInfo->Next = g_AdaptersInfoList; + g_AdaptersInfoList = TmpAdInfo; + + ReleaseMutex(g_AdaptersInfoMutex); + + TRACE_EXIT("PacketAddAdapterDag"); + return TRUE; +} + +/*! + \brief Updates the list of the adapters using the DAGC API. + \return If the function succeeds, the return value is nonzero. + + This function populates the list of adapter descriptions, looking for DAG cards on the system. +*/ +BOOLEAN PacketGetAdaptersDag() +{ + CHAR ebuf[DAGC_ERRBUF_SIZE]; + dagc_if_t *devs = NULL, *tmpdevs; + UINT i; + + if(g_p_dagc_finddevs(&devs, ebuf)) + // No dag cards found on this system + return FALSE; + else + { + for(tmpdevs = devs, i=0; tmpdevs != NULL; tmpdevs = tmpdevs->next) + { + PacketAddAdapterDag(tmpdevs->name, tmpdevs->description, FALSE); + } + } + + g_p_dagc_freedevs(devs); + + return TRUE; +} +#endif // HAVE_DAG_API + +/*! +\brief Find the information about an adapter scanning the global ADAPTER_INFO list. + \param AdapterName Name of the adapter whose information has to be retrieved. + \return If the function succeeds, the return value is non-null. +*/ +PADAPTER_INFO PacketFindAdInfo(PCHAR AdapterName) +{ + //this function should NOT acquire the g_AdaptersInfoMutex, since it does return an ADAPTER_INFO structure + PADAPTER_INFO TAdInfo; + + TRACE_ENTER("PacketFindAdInfo"); + + if (g_AdaptersInfoList == NULL) + { + TRACE_PRINT("Repopulating the adapters info list..."); + PacketPopulateAdaptersInfoList(); + } + + TAdInfo = g_AdaptersInfoList; + + while(TAdInfo != NULL) + { + if(strcmp(TAdInfo->Name, AdapterName) == 0) + { + TRACE_PRINT1("Found AdInfo for adapter %s", AdapterName); + break; + } + + TAdInfo = TAdInfo->Next; + } + + if (TAdInfo == NULL) + { + TRACE_PRINT1("NOT found AdInfo for adapter %s", AdapterName); + } + + TRACE_EXIT("PacketFindAdInfo"); + return TAdInfo; +} + + + +/*! + \brief Updates information about an adapter in the global ADAPTER_INFO list. + \param AdapterName Name of the adapter whose information has to be retrieved. + \return If the function succeeds, the return value is TRUE. A false value means that the adapter is no + more valid or that it is disconnected. +*/ +BOOLEAN PacketUpdateAdInfo(PCHAR AdapterName) +{ + //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter + PADAPTER_INFO TAdInfo, PrevAdInfo; + +#ifdef HAVE_WANPACKET_API + CHAR FakeNdisWanAdapterName[MAX_WINPCAP_KEY_CHARS] = FAKE_NDISWAN_ADAPTER_NAME; +#endif + +// +// Old registry based WinPcap names +// +// UINT RegQueryLen; +// CHAR FakeNdisWanAdapterName[MAX_WINPCAP_KEY_CHARS]; +// +// // retrieve the name for the fake ndis wan adapter +// RegQueryLen = sizeof(FakeNdisWanAdapterName)/sizeof(FakeNdisWanAdapterName[0]); +// if (QueryWinPcapRegistryStringA(NPF_FAKE_NDISWAN_ADAPTER_NAME_REG_KEY, FakeNdisWanAdapterName, &RegQueryLen, FAKE_NDISWAN_ADAPTER_NAME) == FALSE && RegQueryLen == 0) +// return FALSE; + + TRACE_ENTER("PacketUpdateAdInfo"); + + TRACE_PRINT1("Updating adapter info for adapter %s", AdapterName); + + WaitForSingleObject(g_AdaptersInfoMutex, INFINITE); + + PrevAdInfo = TAdInfo = g_AdaptersInfoList; + + // + // If an entry for this adapter is present in the list, we destroy it + // + while(TAdInfo != NULL) + { + if(strcmp(TAdInfo->Name, AdapterName) == 0) + { +#ifdef HAVE_WANPACKET_API + if (strcmp(AdapterName, FakeNdisWanAdapterName) == 0) + { + ReleaseMutex(g_AdaptersInfoMutex); + TRACE_EXIT("PacketUpdateAdInfo"); + return TRUE; + } +#endif + if(TAdInfo == g_AdaptersInfoList) + { + g_AdaptersInfoList = TAdInfo->Next; + } + else + { + PrevAdInfo->Next = TAdInfo->Next; + } + + if (TAdInfo->NetworkAddresses != NULL) + GlobalFreePtr(TAdInfo->NetworkAddresses); + GlobalFreePtr(TAdInfo); + + break; + } + + PrevAdInfo = TAdInfo; + + TAdInfo = TAdInfo->Next; + } + + ReleaseMutex(g_AdaptersInfoMutex); + + // + // Now obtain the information about this adapter + // + if(PacketAddAdapterNPF(AdapterName, 0) == TRUE) + { + TRACE_EXIT("PacketUpdateAdInfo"); + return TRUE; + } + +#ifdef HAVE_IPHELPER_API + PacketGetAdaptersIPH(); +#endif //HAVE_IPHELPER_API + +#ifdef HAVE_NPFIM_API + if (g_hNpfImDll != NULL) + { + PacketGetAdaptersNpfIm(); + } + else + { + TRACE_PRINT("NpfIm extension not available"); + } +#endif //HAVE_NPFIM_API + +#ifdef HAVE_AIRPCAP_API + if (g_PAirpcapGetDeviceList != NULL) + { + PacketGetAdaptersAirpcap(); + } + else + { + TRACE_PRINT("AirPcap extension not available"); + } +#endif + +#ifdef HAVE_WANPACKET_API + PacketAddFakeNdisWanAdapter(); +#endif //HAVE_WANPACKET_API + +#ifdef HAVE_DAG_API + if(g_p_dagc_open != NULL) + { + PacketGetAdaptersDag(); + } + else + { + TRACE_PRINT("Dag extension not available"); + } +#endif // HAVE_DAG_API + + TRACE_EXIT("PacketUpdateAdInfo"); + return TRUE; +} + +/*! + \brief Populates the list of the adapters. + + This function populates the list of adapter descriptions, invoking first PacketGetAdapters() and then + PacketGetAdaptersIPH(). +*/ +void PacketPopulateAdaptersInfoList() +{ + //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter + PADAPTER_INFO TAdInfo; + PVOID Mem1, Mem2; + + TRACE_ENTER("PacketPopulateAdaptersInfoList"); + + WaitForSingleObject(g_AdaptersInfoMutex, INFINITE); + + if(g_AdaptersInfoList) + { + // Free the old list + TAdInfo = g_AdaptersInfoList; + while(TAdInfo != NULL) + { + Mem1 = TAdInfo->NetworkAddresses; + Mem2 = TAdInfo; + + TAdInfo = TAdInfo->Next; + + if (Mem1 != NULL) + GlobalFreePtr(Mem1); + GlobalFreePtr(Mem2); + } + + g_AdaptersInfoList = NULL; + } + + // + // Fill the new list + // + if(!PacketGetAdaptersNPF()) + { + // No info about adapters in the registry. (NDIS adapters, i.e. exported by NPF) + TRACE_PRINT("PacketPopulateAdaptersInfoList: registry scan for adapters failed!"); + } + +#ifdef HAVE_IPHELPER_API + if(!PacketGetAdaptersIPH()) + { + // IP Helper API not present. We are under WinNT 4 or TCP/IP is not installed + TRACE_PRINT("PacketPopulateAdaptersInfoList: failed to get adapters from the IP Helper API!"); + } +#endif //HAVE_IPHELPER_API + +#ifdef HAVE_WANPACKET_API + if (!PacketAddFakeNdisWanAdapter()) + { + TRACE_PRINT("PacketPopulateAdaptersInfoList: adding fake NdisWan adapter failed."); + } +#endif // HAVE_WANPACKET_API + +#ifdef HAVE_AIRPCAP_API + if(g_PAirpcapGetDeviceList) // Ensure that the airpcap dll is present + { + if(!PacketGetAdaptersAirpcap()) + { + TRACE_PRINT("PacketPopulateAdaptersInfoList: lookup of airpcap adapters failed!"); + } + } +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_NPFIM_API + if (g_hNpfImDll != NULL) + { + if (!PacketGetAdaptersNpfIm()) // Ensure that the npfim dll is present + { + TRACE_PRINT("PacketPopulateAdaptersInfoList: lookup of NpfIm adapters failed!"); + } + } +#endif //HAVE_NPFIM_API + +#ifdef HAVE_DAG_API + if(g_p_dagc_open != NULL) + { + if(!PacketGetAdaptersDag()) + { + // No info about adapters in the registry. + TRACE_PRINT("PacketPopulateAdaptersInfoList: lookup of dag cards failed!"); + } + } +#endif // HAVE_DAG_API + + ReleaseMutex(g_AdaptersInfoMutex); + TRACE_EXIT("PacketPopulateAdaptersInfoList"); +} + +#ifdef HAVE_WANPACKET_API + +static BOOLEAN PacketAddFakeNdisWanAdapter() +{ + //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter + PADAPTER_INFO TmpAdInfo, SAdInfo; +// +// Old registry based WinPcap names +// +// CHAR DialupName[MAX_WINPCAP_KEY_CHARS]; +// CHAR DialupDesc[MAX_WINPCAP_KEY_CHARS]; +// UINT RegQueryLen; + CHAR DialupName[MAX_WINPCAP_KEY_CHARS] = FAKE_NDISWAN_ADAPTER_NAME; + CHAR DialupDesc[MAX_WINPCAP_KEY_CHARS] = FAKE_NDISWAN_ADAPTER_DESCRIPTION; + + TRACE_ENTER("PacketAddFakeNdisWanAdapter"); + +// +// Old registry based WinPcap names +// +// // +// // Get name and description of the wan adapter from the registry +// // +// RegQueryLen = sizeof(DialupName)/sizeof(DialupName[0]); +// if (QueryWinPcapRegistryStringA(NPF_FAKE_NDISWAN_ADAPTER_NAME_REG_KEY, DialupName, &RegQueryLen, FAKE_NDISWAN_ADAPTER_NAME) == FALSE && RegQueryLen == 0) +// return FALSE; +// +// RegQueryLen = sizeof(DialupDesc)/sizeof(DialupDesc[0]); +// if (QueryWinPcapRegistryStringA(NPF_FAKE_NDISWAN_ADAPTER_DESC_REG_KEY, DialupDesc, &RegQueryLen, FAKE_NDISWAN_ADAPTER_DESCRIPTION) == FALSE && RegQueryLen == 0) +// return FALSE; + + // Scan the adapters list to see if this one is already present + if (!WanPacketTestAdapter()) + { + TRACE_PRINT("Cannot add the wan adapter, since it cannot be opened."); + //the adapter cannot be opened, we do not list it, but we return t + TRACE_EXIT("PacketAddFakeNdisWanAdapter"); + return FALSE; + } + + WaitForSingleObject(g_AdaptersInfoMutex, INFINITE); + + for(SAdInfo = g_AdaptersInfoList; SAdInfo != NULL; SAdInfo = SAdInfo->Next) + { + if(strcmp(DialupName, SAdInfo->Name) == 0) + { + TRACE_PRINT("PacketAddFakeNdisWanAdapter: Adapter already present in the list"); + ReleaseMutex(g_AdaptersInfoMutex); + TRACE_EXIT("PacketAddFakeNdisWanAdapter"); + return TRUE; + } + } + + TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO)); + if (TmpAdInfo == NULL) + { + TRACE_PRINT("PacketAddFakeNdisWanAdapter: GlobalAlloc Failed allocating memory for the AdInfo structure"); + ReleaseMutex(g_AdaptersInfoMutex); + TRACE_EXIT("PacketAddFakeNdisWanAdapter"); + return FALSE; + } + + strncpy(TmpAdInfo->Name, DialupName, sizeof(TmpAdInfo->Name) - 1); + strncpy(TmpAdInfo->Description, DialupDesc, sizeof(TmpAdInfo->Description) - 1); + TmpAdInfo->LinkLayer.LinkType = NdisMedium802_3; + TmpAdInfo->LinkLayer.LinkSpeed = 10 * 1000 * 1000; //we emulate a fake 10MBit Ethernet + TmpAdInfo->Flags = INFO_FLAG_NDISWAN_ADAPTER; + memset(TmpAdInfo->MacAddress,'0',6); + TmpAdInfo->MacAddressLen = 6; + TmpAdInfo->NetworkAddresses = NULL; + TmpAdInfo->NNetworkAddresses = 0; + + TmpAdInfo->Next = g_AdaptersInfoList; + g_AdaptersInfoList = TmpAdInfo; + ReleaseMutex(g_AdaptersInfoMutex); + + TRACE_EXIT("PacketAddFakeNdisWanAdapter"); + return TRUE; +} + +#endif //HAVE_WANPACKET_API diff --git a/winpcap/packetNtx/Dll/NpfImExt.c b/winpcap/packetNtx/Dll/NpfImExt.c new file mode 100644 index 0000000..01d720e --- /dev/null +++ b/winpcap/packetNtx/Dll/NpfImExt.c @@ -0,0 +1,96 @@ +#include "NpfImExt.h" +#include + +#include "debug.h" + +#ifdef HAVE_NPFIM_API + +NPF_IM_HANDLERS g_NpfImHandlers; +HMODULE g_hNpfImDll; + +BOOL LoadNpfImDll() +{ + TRACE_ENTER("LoadNpfImDll"); + + if (g_hNpfImDll != NULL) + { + TRACE_EXIT("LoadNpfImDll"); + return TRUE; + } + + g_hNpfImDll = LoadLibraryA("NpfIm.dll"); + + if (g_hNpfImDll == NULL) + { + TRACE_EXIT("LoadNpfImDll"); + return FALSE; + } + + g_NpfImHandlers.NpfImFreeDeviceList = (NpfImFreeDeviceListHandler) GetProcAddress(g_hNpfImDll,"NpfImFreeDeviceList"); + g_NpfImHandlers.NpfImGetCaptureReadEvent = (NpfImGetCaptureReadEventHandler) GetProcAddress(g_hNpfImDll,"NpfImGetCaptureReadEvent"); + g_NpfImHandlers.NpfImGetCaptureStatistics = (NpfImGetCaptureStatisticsHandler) GetProcAddress(g_hNpfImDll,"NpfImGetCaptureStatistics"); + g_NpfImHandlers.NpfImGetDeviceList = (NpfImGetDeviceListHandler) GetProcAddress(g_hNpfImDll,"NpfImGetDeviceList"); + g_NpfImHandlers.NpfImGetIpAddresses = (NpfImGetIpAddressesHandler) GetProcAddress(g_hNpfImDll,"NpfImGetIpAddresses"); + g_NpfImHandlers.NpfImGetLinkSpeed = (NpfImGetLinkSpeedHandler) GetProcAddress(g_hNpfImDll,"NpfImGetLinkSpeed"); +// g_NpfImHandlers.NpfImGetMacAddress = (NpfImGetMacAddressHandler) GetProcAddress(g_hNpfImDll,"NpfImGetMacAddress"); + g_NpfImHandlers.NpfImGetMedium = (NpfImGetMediumHandler) GetProcAddress(g_hNpfImDll,"NpfImGetMedium"); + g_NpfImHandlers.NpfImGetRunningDriverVersion= (NpfImGetRunningDriverVersionHandler) GetProcAddress(g_hNpfImDll,"NpfImGetRunningDriverVersion"); + g_NpfImHandlers.NpfImIssueQueryOid = (NpfImIssueQueryOidHandler) GetProcAddress(g_hNpfImDll,"NpfImIssueQueryOid"); +// g_NpfImHandlers.NpfImIssueSetOid = (NpfImIssueSetOidHandler) GetProcAddress(g_hNpfImDll,"NpfImIssueSetOid"); + g_NpfImHandlers.NpfImOpenDevice = (NpfImOpenDeviceHandler) GetProcAddress(g_hNpfImDll,"NpfImOpenDevice"); + g_NpfImHandlers.NpfImReceivePackets = (NpfImReceivePacketsHandler) GetProcAddress(g_hNpfImDll,"NpfImReceivePackets"); + g_NpfImHandlers.NpfImSetBpfFilter = (NpfImSetBpfFilterHandler) GetProcAddress(g_hNpfImDll,"NpfImSetBpfFilter"); + g_NpfImHandlers.NpfImSetCaptureBufferSize = (NpfImSetCaptureBufferSizeHandler) GetProcAddress(g_hNpfImDll,"NpfImSetCaptureBufferSize"); + g_NpfImHandlers.NpfImSetMinToCopy = (NpfImSetMinToCopyHandler) GetProcAddress(g_hNpfImDll,"NpfImSetMinToCopy"); + g_NpfImHandlers.NpfImSetReadTimeout = (NpfImSetReadTimeoutHandler) GetProcAddress(g_hNpfImDll,"NpfImSetReadTimeout"); + g_NpfImHandlers.NpfImCloseDevice = (NpfImCloseDeviceHandler) GetProcAddress(g_hNpfImDll, "NpfImCloseDevice"); + + if ( + g_NpfImHandlers.NpfImCloseDevice == NULL + || g_NpfImHandlers.NpfImFreeDeviceList == NULL + || g_NpfImHandlers.NpfImGetCaptureReadEvent == NULL + || g_NpfImHandlers.NpfImGetCaptureStatistics == NULL + || g_NpfImHandlers.NpfImGetDeviceList == NULL + || g_NpfImHandlers.NpfImGetIpAddresses == NULL + || g_NpfImHandlers.NpfImGetLinkSpeed == NULL +// || g_NpfImHandlers.NpfImGetMacAddress == NULL + || g_NpfImHandlers.NpfImGetMedium == NULL + || g_NpfImHandlers.NpfImGetRunningDriverVersion == NULL + || g_NpfImHandlers.NpfImIssueQueryOid == NULL +// || g_NpfImHandlers.NpfImIssueSetOid == NULL + || g_NpfImHandlers.NpfImOpenDevice == NULL + || g_NpfImHandlers.NpfImReceivePackets == NULL + || g_NpfImHandlers.NpfImSetBpfFilter == NULL + || g_NpfImHandlers.NpfImSetCaptureBufferSize == NULL + || g_NpfImHandlers.NpfImSetMinToCopy == NULL + || g_NpfImHandlers.NpfImSetReadTimeout == NULL + ) + { + UnloadNpfImDll(); + TRACE_EXIT("LoadNpfImDll"); + return FALSE; + } + + TRACE_EXIT("LoadNpfImDll"); + return TRUE; +} + +BOOL UnloadNpfImDll() +{ + TRACE_ENTER("UnloadNpfImDll"); + + if (g_hNpfImDll == NULL) + { + TRACE_EXIT("UnloadNpfImDll"); + return FALSE; + } + + FreeLibrary(g_hNpfImDll); + g_hNpfImDll = NULL; + ZeroMemory(&g_NpfImHandlers, sizeof(g_NpfImHandlers)); + + TRACE_EXIT("UnloadNpfImDll"); + return TRUE; +} + +#endif //HAVE_NPFIM_API diff --git a/winpcap/packetNtx/Dll/NpfImExt.h b/winpcap/packetNtx/Dll/NpfImExt.h new file mode 100644 index 0000000..01fee5b --- /dev/null +++ b/winpcap/packetNtx/Dll/NpfImExt.h @@ -0,0 +1,164 @@ +#ifndef __NPF_IM_EXT_H___ +#define __NPF_IM_EXT_H___ + +#ifdef HAVE_NPFIM_API + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef BOOL (NPF_IM_CALLCONV *NpfImGetDeviceListHandler) +( + IN OUT PNPF_IM_DEVICE *ppDevices +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImFreeDeviceListHandler) +( + IN PNPF_IM_DEVICE pDevices +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImOpenDeviceHandler) +( + IN PCHAR name, + OUT NPF_IM_DEV_HANDLE *pHandle +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImCloseDeviceHandler) +( + IN NPF_IM_DEV_HANDLE handle +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImReceivePacketsHandler) +( + IN NPF_IM_DEV_HANDLE handle, + IN OUT PVOID buffer, + IN DWORD bufferSize, + OUT PDWORD pReadBytes +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImSetBpfFilterHandler) +( + IN NPF_IM_DEV_HANDLE handle, + IN PVOID buffer, + IN DWORD bufferSize +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImSetCaptureBufferSizeHandler) +( + IN NPF_IM_DEV_HANDLE handle, + IN DWORD bufferSize +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImGetMediumHandler) +( + IN NPF_IM_DEV_HANDLE handle, + OUT PNDIS_MEDIUM pMedium +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImGetMacAddressHandler) +( + IN NPF_IM_DEV_HANDLE handle, + OUT BYTE macAddress[6] +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImSetMinToCopyHandler) +( + IN NPF_IM_DEV_HANDLE handle, + IN DWORD minToCopy +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImGetCaptureReadEventHandler) +( + IN NPF_IM_DEV_HANDLE handle, + OUT PHANDLE pReadEvent +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImSetReadTimeoutHandler) +( + IN NPF_IM_DEV_HANDLE handle, + IN DWORD readTimeout +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImIssueQueryOidHandler) +( + IN NPF_IM_DEV_HANDLE handle, + IN ULONG Oid, + OUT PBYTE pBuffer, + IN OUT PDWORD pBufferSize + ); + +typedef BOOL (NPF_IM_CALLCONV *NpfImIssueSetOidHandler) +( + IN NPF_IM_DEV_HANDLE handle, + IN ULONG Oid, + IN PBYTE pBuffer, + IN OUT PDWORD pBufferSize + ); + +typedef BOOL (NPF_IM_CALLCONV *NpfImGetCaptureStatisticsHandler) +( + IN NPF_IM_DEV_HANDLE handle, + OUT PULONGLONG Statistics, + IN DWORD bufferSize, + OUT PDWORD pNeededOrWrittenBytes +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImGetRunningDriverVersionHandler) +( + OUT PULONGLONG Version +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImGetLinkSpeedHandler) +( + IN NPF_IM_DEV_HANDLE handle, + OUT PULONGLONG pLinkSpeed +); + +typedef BOOL (NPF_IM_CALLCONV *NpfImGetIpAddressesHandler) +( + IN NPF_IM_DEV_HANDLE handle, + IN OUT PNPF_IM_ADDRESS pAddresses, + IN DWORD bufferSize, + OUT PDWORD pNeededOrWrittenBytes +); + +typedef struct _NPF_IM_HANDLERS +{ + NpfImCloseDeviceHandler NpfImCloseDevice; + NpfImFreeDeviceListHandler NpfImFreeDeviceList; + NpfImGetCaptureReadEventHandler NpfImGetCaptureReadEvent; + NpfImGetCaptureStatisticsHandler NpfImGetCaptureStatistics; + NpfImGetDeviceListHandler NpfImGetDeviceList; + NpfImGetIpAddressesHandler NpfImGetIpAddresses; + NpfImGetLinkSpeedHandler NpfImGetLinkSpeed; +// NpfImGetMacAddressHandler NpfImGetMacAddress; + NpfImGetMediumHandler NpfImGetMedium; + NpfImGetRunningDriverVersionHandler NpfImGetRunningDriverVersion; + NpfImIssueQueryOidHandler NpfImIssueQueryOid; +// NpfImIssueSetOidHandler NpfImIssueSetOid; + NpfImOpenDeviceHandler NpfImOpenDevice; + NpfImReceivePacketsHandler NpfImReceivePackets; + NpfImSetBpfFilterHandler NpfImSetBpfFilter; + NpfImSetCaptureBufferSizeHandler NpfImSetCaptureBufferSize; + NpfImSetMinToCopyHandler NpfImSetMinToCopy; + NpfImSetReadTimeoutHandler NpfImSetReadTimeout; +} + NPF_IM_HANDLERS; + +extern NPF_IM_HANDLERS g_NpfImHandlers; +extern HMODULE g_hNpfImDll; + +BOOL LoadNpfImDll(); +BOOL UnloadNpfImDll(); + +#ifdef __cplusplus +} +#endif + +#endif //#ifdef HAVE_NPFIM_API + + +#endif //__NPF_IM_EXT_H___ \ No newline at end of file diff --git a/winpcap/packetNtx/Dll/Packet.def b/winpcap/packetNtx/Dll/Packet.def new file mode 100644 index 0000000..75f7a4f --- /dev/null +++ b/winpcap/packetNtx/Dll/Packet.def @@ -0,0 +1,35 @@ +LIBRARY packet + +EXPORTS + PacketLibraryVersion + PacketGetVersion + PacketGetDriverVersion + PacketOpenAdapter + PacketSendPacket + PacketSendPackets + PacketAllocatePacket + PacketInitPacket + PacketFreePacket + PacketReceivePacket + PacketCloseAdapter + PacketSetHwFilter + PacketGetAdapterNames + PacketRequest + PacketSetBuff + PacketSetBpf + PacketSetSnapLen + PacketGetStats + PacketGetStatsEx + PacketGetNetType + PacketSetReadTimeout + PacketSetMode + PacketSetNumWrites + PacketGetNetInfoEx + PacketSetMinToCopy + PacketGetReadEvent + PacketStopDriver + PacketSetDumpName + PacketSetDumpLimits + PacketIsDumpEnded + PacketSetLoopbackBehavior + PacketGetAirPcapHandle diff --git a/winpcap/packetNtx/Dll/Packet32-Int.h b/winpcap/packetNtx/Dll/Packet32-Int.h new file mode 100644 index 0000000..1fe02f4 --- /dev/null +++ b/winpcap/packetNtx/Dll/Packet32-Int.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2006 + * CACE Technologies LLC, Davis (CA) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the company (CACE Technologies LLC) nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// +// Internal constants +// + +// The following is used to check the adapter name in PacketOpenAdapterNPF and prevent +// opening of firewire adapters +#define FIREWIRE_SUBSTR L"1394" + +#ifdef HAVE_NPFIM_API +#include "NpfImExt.h" +#endif //HAVE_NPFIM_API + +// +// Internal functions +// +VOID PacketLoadLibrariesDynamically(); +void PacketPopulateAdaptersInfoList(); +BOOL PacketGetFileVersion(LPTSTR FileName, PCHAR VersionBuff, UINT VersionBuffLen); +PADAPTER_INFO PacketFindAdInfo(PCHAR AdapterName); +BOOLEAN PacketUpdateAdInfo(PCHAR AdapterName); +BOOLEAN IsFireWire(TCHAR *AdapterDesc); +LPADAPTER PacketOpenAdapterNPF(PCHAR AdapterName); + +// +// Definitions and functions specific to the CACETech airpcap API +// +#ifdef HAVE_AIRPCAP_API +typedef PCHAR (*AirpcapGetLastErrorHandler)(PAirpcapHandle Handle); +typedef BOOL (*AirpcapGetDeviceListHandler)(AirpcapDeviceDescription **AllDevsP, PCHAR Ebuf); ///< prototype used to dynamically load the dag dll +typedef VOID (*AirpcapFreeDeviceListHandler)(AirpcapDeviceDescription *AllDevsP); ///< prototype used to dynamically load the dag dll +typedef PAirpcapHandle (*AirpcapOpenHandler)(PCHAR DeviceName, PCHAR Ebuf); ///< prototype used to dynamically load the dag dll +typedef VOID (*AirpcapCloseHandler)(PAirpcapHandle Handle); ///< prototype used to dynamically load the dag dll +typedef BOOL (*AirpcapGetLinkTypeHandler)(PAirpcapHandle Handle, AirpcapLinkType* LinkLayer); ///< prototype used to dynamically load the dag dll +typedef BOOL (*AirpcapSetKernelBufferHandler)(PAirpcapHandle Handle, ULONG Size); ///< prototype used to dynamically load the dag dll +typedef BOOL (*AirpcapSetFilterHandler)(PAirpcapHandle Handle, void *Instructions, UINT Len); ///< prototype used to dynamically load the dag dll +typedef BOOL (*AirpcapGetMacAddressHandler)(PAirpcapHandle Handle, CHAR **MacAddress); ///< prototype used to dynamically load the dag dll +typedef BOOL (*AirpcapSetMinToCopyHandler)(PAirpcapHandle Handle, ULONG Bytes); ///< prototype used to dynamically load the dag dll +typedef BOOL (*AirpcapGetReadEventHandler)(PAirpcapHandle Handle, HANDLE* PReadEvent); ///< prototype used to dynamically load the dag dll +typedef BOOL (*AirpcapReadHandler)(PAirpcapHandle Handle, PUCHAR BufferToFill, ULONG BufSize, PULONG ReceievedBytes); ///< prototype used to dynamically load the dag dll +typedef BOOL (*AirpcapGetStatsHandler)(PAirpcapHandle Handle, AirpcapStats *Stats); ///< prototype used to dynamically load the dag dll +typedef BOOL (*AirpcapWriteHandler)(PAirpcapHandle Handle, PCHAR TxPacket, ULONG PacketLen); ///< prototype used to dynamically load the dag dll + +#endif // HAVE_AIRPCAP_API + + +// +// Definitions and functions specific to the Endace Dag API +// +#ifdef HAVE_DAG_API +typedef dagc_t* (*dagc_open_handler)(const char *source, unsigned flags, char *ebuf); ///< prototype used to dynamically load the dag dll +typedef void (*dagc_close_handler)(dagc_t *dagcfd); ///< prototype used to dynamically load the dag dll +typedef int (*dagc_getlinktype_handler)(dagc_t *dagcfd); ///< prototype used to dynamically load the dag dll +typedef int (*dagc_getlinkspeed_handler)(dagc_t *dagcfd); ///< prototype used to dynamically load the dag dll +typedef int (*dagc_setsnaplen_handler)(dagc_t *dagcfd, unsigned snaplen); ///< prototype used to dynamically load the dag dll +typedef unsigned (*dagc_getfcslen_handler)(dagc_t *dagcfd); ///< prototype used to dynamically load the dag dll +typedef int (*dagc_receive_handler)(dagc_t *dagcfd, u_char **buffer, u_int *bufsize); ///< prototype used to dynamically load the dag dll +typedef int (*dagc_stats_handler)(dagc_t *dagcfd, dagc_stats_t *ps); ///< prototype used to dynamically load the dag dll +typedef int (*dagc_wait_handler)(dagc_t *dagcfd, struct timeval *timeout); ///< prototype used to dynamically load the dag dll +typedef int (*dagc_finddevs_handler)(dagc_if_t **alldevsp, char *ebuf); ///< prototype used to dynamically load the dag dll +typedef int (*dagc_freedevs_handler)(dagc_if_t *alldevsp); ///< prototype used to dynamically load the dag dll +#endif // HAVE_DAG_API diff --git a/winpcap/packetNtx/Dll/Packet32.c b/winpcap/packetNtx/Dll/Packet32.c new file mode 100644 index 0000000..866c3fe --- /dev/null +++ b/winpcap/packetNtx/Dll/Packet32.c @@ -0,0 +1,3862 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define UNICODE 1 + +#pragma warning (disable : 4127) //conditional expression is constant. Used for do{}while(FALSE) loops. + +#if (MSC_VER < 1300) +#pragma warning (disable : 4710) // inline function not expanded. used for strsafe functions +#endif + + +#include +#include + +#include "Packet32-Int.h" + +#ifdef HAVE_WANPACKET_API +#include "wanpacket/wanpacket.h" +#endif //HAVE_WANPACKET_API + +#include "debug.h" + +#ifdef _WINNT4 +#if (defined(HAVE_NPFIM_API) || defined(HAVE_WANPACKET_API) || defined (HAVE_AIRPCAP_API) || defined(HAVE_IPHELPER_API)) +#error Do not enable _WINNT4 with any other API +#endif +#endif //_WINNT4 + +#ifdef _WINNT4 +#pragma message ("Compiling Packet.dll for WINNT4 only") +#endif + +#ifdef HAVE_AIRPCAP_API +#pragma message ("Compiling Packet.dll with support for AirPcap") +#endif + +#ifdef HAVE_NPFIM_API +#pragma message ("Compiling Packet.dll with support for NpfIm driver") +#endif + +#ifdef HAVE_DAG_API +#pragma message ("Compiling Packet.dll with support for DAG cards") +#endif + +#ifdef HAVE_WANPACKET_API +#pragma message ("Compiling Packet.dll with support for WanPacket (aka Dialup thru NetMon)") +#endif + +#ifdef HAVE_IPHELPER_API +#pragma message ("Compiling Packet.dll with support from IP helper API for API addresses") +#endif + +#ifndef UNUSED +#define UNUSED(_x) (_x) +#endif + + +#ifdef _DEBUG_TO_FILE +LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName); +CHAR g_LogFileName[1024] = "winpcap_debug.txt"; +#endif //_DEBUG_TO_FILE + +#include +#include +#include +#include + +#include + +#include + +// +// Current packet.dll Version. It can be retrieved directly or through the PacketGetVersion() function. +// +char PacketLibraryVersion[64]; + +// +// Current NPF.sys Version. It can be retrieved directly or through the PacketGetVersion() function. +// +char PacketDriverVersion[64]; + +// +// WinPcap global registry key +// +//WCHAR g_WinPcapKeyBuffer[MAX_WINPCAP_KEY_CHARS]; +//HKEY g_WinpcapKey = NULL; + +// +// Global adapters list related variables +// +extern PADAPTER_INFO g_AdaptersInfoList; +extern HANDLE g_AdaptersInfoMutex; + +#ifdef HAVE_IPHELPER_API +typedef VOID (*GAAHandler)( + ULONG, + DWORD, + PVOID, + PIP_ADAPTER_ADDRESSES, + PULONG); +GAAHandler g_GetAdaptersAddressesPointer = NULL; +#endif // HAVE_IPHELPER_API + +// +// Dynamic dependencies variables and declarations +// +volatile LONG g_DynamicLibrariesLoaded = 0; +HANDLE g_DynamicLibrariesMutex; + +#ifdef HAVE_AIRPCAP_API +// We load dinamically the dag library in order link it only when it's present on the system +AirpcapGetLastErrorHandler g_PAirpcapGetLastError; +AirpcapGetDeviceListHandler g_PAirpcapGetDeviceList; +AirpcapFreeDeviceListHandler g_PAirpcapFreeDeviceList; +AirpcapOpenHandler g_PAirpcapOpen; +AirpcapCloseHandler g_PAirpcapClose; +AirpcapGetLinkTypeHandler g_PAirpcapGetLinkType; +AirpcapSetKernelBufferHandler g_PAirpcapSetKernelBuffer; +AirpcapSetFilterHandler g_PAirpcapSetFilter; +AirpcapGetMacAddressHandler g_PAirpcapGetMacAddress; +AirpcapSetMinToCopyHandler g_PAirpcapSetMinToCopy; +AirpcapGetReadEventHandler g_PAirpcapGetReadEvent; +AirpcapReadHandler g_PAirpcapRead; +AirpcapGetStatsHandler g_PAirpcapGetStats; +AirpcapWriteHandler g_PAirpcapWrite; +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_DAG_API +// We load dinamically the dag library in order link it only when it's present on the system +dagc_open_handler g_p_dagc_open = NULL; +dagc_close_handler g_p_dagc_close = NULL; +dagc_getlinktype_handler g_p_dagc_getlinktype = NULL; +dagc_getlinkspeed_handler g_p_dagc_getlinkspeed = NULL; +dagc_getfcslen_handler g_p_dagc_getfcslen = NULL; +dagc_receive_handler g_p_dagc_receive = NULL; +dagc_wait_handler g_p_dagc_wait = NULL; +dagc_stats_handler g_p_dagc_stats = NULL; +dagc_setsnaplen_handler g_p_dagc_setsnaplen = NULL; +dagc_finddevs_handler g_p_dagc_finddevs = NULL; +dagc_freedevs_handler g_p_dagc_freedevs = NULL; +#endif // HAVE_DAG_API + +BOOLEAN PacketAddAdapterDag(PCHAR name, PCHAR description, BOOLEAN IsAFile); + +// +// Additions for WinPcap OEM +// +#ifdef WPCAP_OEM_UNLOAD_H +typedef BOOL (*WoemLeaveDllHandler)(void); +WoemLeaveDllHandler g_WoemLeaveDllH = NULL; + +__declspec (dllexport) VOID PacketRegWoemLeaveHandler(PVOID Handler) +{ + g_WoemLeaveDllH = Handler; +} +#endif // WPCAP_OEM_UNLOAD_H + +//--------------------------------------------------------------------------- + +/*! + \brief The main dll function. +*/ + +BOOL APIENTRY DllMain(HANDLE DllHandle,DWORD Reason,LPVOID lpReserved) +{ + BOOLEAN Status=TRUE; + PADAPTER_INFO NewAdInfo; + TCHAR DllFileName[MAX_PATH]; + + UNUSED(lpReserved); + + switch(Reason) + { + case DLL_PROCESS_ATTACH: + + TRACE_PRINT_DLLMAIN("************Packet32: DllMain************"); + +#if 0 +#ifdef WPCAP_OEM +#ifdef HAVE_WANPACKET_API + LoadNdisNpp(Reason); +#endif // HAVE_WANPACKET_API +#endif // WPCAP_OEM +#endif + +#ifdef _DEBUG_TO_FILE + PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\" NPF_DRIVER_NAME,"npf.reg"); + + // dump a bunch of registry keys useful for debug to file + PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", + "adapters.reg"); + PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip", + "tcpip.reg"); + PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services", + "services.reg"); + +#endif + + // Create the mutex that will protect the adapter information list + g_AdaptersInfoMutex = CreateMutex(NULL, FALSE, NULL); + + // Create the mutex that will protect the PacketLoadLibrariesDynamically() function + g_DynamicLibrariesMutex = CreateMutex(NULL, FALSE, NULL); + + // + // Retrieve packet.dll version information from the file + // + // XXX We want to replace this with a constant. We leave it out for the moment + if(GetModuleFileName(DllHandle, DllFileName, sizeof(DllFileName) / sizeof(DllFileName[0])) > 0) + { + PacketGetFileVersion(DllFileName, PacketLibraryVersion, sizeof(PacketLibraryVersion)); + } + // + // Retrieve NPF.sys version information from the file + // + // XXX We want to replace this with a constant. We leave it out for the moment + // TODO fixme. Those hardcoded strings are terrible... + PacketGetFileVersion(TEXT("drivers\\") TEXT(NPF_DRIVER_NAME) TEXT(".sys"), PacketDriverVersion, sizeof(PacketDriverVersion)); + + break; + + case DLL_PROCESS_DETACH: + + CloseHandle(g_AdaptersInfoMutex); + + g_AdaptersInfoList; + + while(g_AdaptersInfoList != NULL) + { + + NewAdInfo = g_AdaptersInfoList->Next; + if (g_AdaptersInfoList->NetworkAddresses != NULL) + GlobalFreePtr(g_AdaptersInfoList->NetworkAddresses); + GlobalFreePtr(g_AdaptersInfoList); + + g_AdaptersInfoList = NewAdInfo; + } + +#ifdef WPCAP_OEM_UNLOAD_H + if(g_WoemLeaveDllH) + { + g_WoemLeaveDllH(); + } +#endif // WPCAP_OEM_UNLOAD_H + + break; + + default: + break; + } + + return Status; +} + + +/*! + \brief This function is used to dynamically load some of the libraries winpcap depends on, + and that are not guaranteed to be in the system + \param cp A string containing the address. + \return the converted 32-bit numeric address. + + Doesn't check to make sure the address is valid. +*/ +VOID PacketLoadLibrariesDynamically() +{ +#ifdef HAVE_IPHELPER_API + HMODULE IPHMod; +#endif // HAVE_IPHELPER_API + +#ifdef HAVE_AIRPCAP_API + HMODULE AirpcapLib; +#endif // HAVE_DAG_API + +#ifdef HAVE_DAG_API + HMODULE DagcLib; +#endif // HAVE_DAG_API + + TRACE_ENTER("PacketLoadLibrariesDynamically"); + + // + // Acquire the global mutex, so we wait until other threads are done + // + WaitForSingleObject(g_DynamicLibrariesMutex, INFINITE); + + // + // Only the first thread should do the initialization + // + g_DynamicLibrariesLoaded++; + + if(g_DynamicLibrariesLoaded != 1) + { + ReleaseMutex(g_DynamicLibrariesMutex); + TRACE_EXIT("PacketLoadLibrariesDynamically"); + return; + } + + // + // Locate GetAdaptersAddresses dinamically since it is not present in Win2k + // + +#ifdef HAVE_IPHELPER_API + IPHMod = GetModuleHandle(TEXT("Iphlpapi")); + if (IPHMod != NULL) + { + g_GetAdaptersAddressesPointer = (GAAHandler) GetProcAddress(IPHMod ,"GetAdaptersAddresses"); + } +#endif // HAVE_IPHELPER_API + +#ifdef HAVE_AIRPCAP_API + /* We dinamically load the airpcap library in order link it only when it's present on the system */ + if((AirpcapLib = LoadLibrary(TEXT("airpcap.dll"))) == NULL) + { + // Report the error but go on + TRACE_PRINT("AirPcap library not found on this system"); + } + else + { + // + // Find the exports + // + g_PAirpcapGetLastError = (AirpcapGetLastErrorHandler) GetProcAddress(AirpcapLib, "AirpcapGetLastError"); + g_PAirpcapGetDeviceList = (AirpcapGetDeviceListHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceList"); + g_PAirpcapFreeDeviceList = (AirpcapFreeDeviceListHandler) GetProcAddress(AirpcapLib, "AirpcapFreeDeviceList"); + g_PAirpcapOpen = (AirpcapOpenHandler) GetProcAddress(AirpcapLib, "AirpcapOpen"); + g_PAirpcapClose = (AirpcapCloseHandler) GetProcAddress(AirpcapLib, "AirpcapClose"); + g_PAirpcapGetLinkType = (AirpcapGetLinkTypeHandler) GetProcAddress(AirpcapLib, "AirpcapGetLinkType"); + g_PAirpcapSetKernelBuffer = (AirpcapSetKernelBufferHandler) GetProcAddress(AirpcapLib, "AirpcapSetKernelBuffer"); + g_PAirpcapSetFilter = (AirpcapSetFilterHandler) GetProcAddress(AirpcapLib, "AirpcapSetFilter"); + g_PAirpcapGetMacAddress = (AirpcapGetMacAddressHandler) GetProcAddress(AirpcapLib, "AirpcapGetMacAddress"); + g_PAirpcapSetMinToCopy = (AirpcapSetMinToCopyHandler) GetProcAddress(AirpcapLib, "AirpcapSetMinToCopy"); + g_PAirpcapGetReadEvent = (AirpcapGetReadEventHandler) GetProcAddress(AirpcapLib, "AirpcapGetReadEvent"); + g_PAirpcapRead = (AirpcapReadHandler) GetProcAddress(AirpcapLib, "AirpcapRead"); + g_PAirpcapGetStats = (AirpcapGetStatsHandler) GetProcAddress(AirpcapLib, "AirpcapGetStats"); + g_PAirpcapWrite = (AirpcapWriteHandler) GetProcAddress(AirpcapLib, "AirpcapWrite"); + + // + // Make sure that we found everything + // + if(g_PAirpcapGetLastError == NULL || + g_PAirpcapGetDeviceList == NULL || + g_PAirpcapFreeDeviceList == NULL || + g_PAirpcapClose == NULL || + g_PAirpcapGetLinkType == NULL || + g_PAirpcapSetKernelBuffer == NULL || + g_PAirpcapSetFilter == NULL || + g_PAirpcapGetMacAddress == NULL || + g_PAirpcapSetMinToCopy == NULL || + g_PAirpcapGetReadEvent == NULL || + g_PAirpcapRead == NULL || + g_PAirpcapGetStats == NULL) + { + // No, something missing. A NULL g_PAirpcapOpen will disable airpcap adapters check + g_PAirpcapOpen = NULL; + } + } +#endif // HAVE_DAG_API + +#ifdef HAVE_DAG_API + /* We dinamically load the dag library in order link it only when it's present on the system */ + if((DagcLib = LoadLibrary(TEXT("dagc.dll"))) == NULL) + { + // Report the error but go on + TRACE_PRINT("dag capture library not found on this system"); + } + else + { + g_p_dagc_open = (dagc_open_handler) GetProcAddress(DagcLib, "dagc_open"); + g_p_dagc_close = (dagc_close_handler) GetProcAddress(DagcLib, "dagc_close"); + g_p_dagc_setsnaplen = (dagc_setsnaplen_handler) GetProcAddress(DagcLib, "dagc_setsnaplen"); + g_p_dagc_getlinktype = (dagc_getlinktype_handler) GetProcAddress(DagcLib, "dagc_getlinktype"); + g_p_dagc_getlinkspeed = (dagc_getlinkspeed_handler) GetProcAddress(DagcLib, "dagc_getlinkspeed"); + g_p_dagc_getfcslen = (dagc_getfcslen_handler) GetProcAddress(DagcLib, "dagc_getfcslen"); + g_p_dagc_receive = (dagc_receive_handler) GetProcAddress(DagcLib, "dagc_receive"); + g_p_dagc_wait = (dagc_wait_handler) GetProcAddress(DagcLib, "dagc_wait"); + g_p_dagc_stats = (dagc_stats_handler) GetProcAddress(DagcLib, "dagc_stats"); + g_p_dagc_finddevs = (dagc_finddevs_handler) GetProcAddress(DagcLib, "dagc_finddevs"); + g_p_dagc_freedevs = (dagc_freedevs_handler) GetProcAddress(DagcLib, "dagc_freedevs"); + } +#endif /* HAVE_DAG_API */ + +#ifdef HAVE_NPFIM_API + if (LoadNpfImDll() == FALSE) + { + TRACE_PRINT("Failed loading NpfIm extension"); + } +#endif //HAVE_NPFIM_API + + + // + // Done. Release the mutex and return + // + ReleaseMutex(g_DynamicLibrariesMutex); + + TRACE_EXIT("PacketLoadLibrariesDynamically"); + return; +} + +/* +BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName, + CHAR *Value, + UINT *pValueLen, + CHAR *DefaultVal) +{ +#ifdef WPCAP_OEM + DWORD Type; + LONG QveRes; + HKEY hWinPcapKey; + + if (QveRes = RegOpenKeyExA(HKEY_LOCAL_MACHINE, + WINPCAP_INSTANCE_KEY, + 0, + KEY_ALL_ACCESS, + &hWinPcapKey) != ERROR_SUCCESS) + { + *pValueLen = 0; + + SetLastError(QveRes); + + return FALSE; + } + + // + // Query the requested value + // + QveRes = RegQueryValueExA(hWinPcapKey, + SubKeyName, + NULL, + &Type, + Value, + pValueLen); + + RegCloseKey(hWinPcapKey); + + if (QveRes == ERROR_SUCCESS) + { + //let's check that the key is text + if (Type != REG_SZ) + { + *pValueLen = 0; + + SetLastError(ERROR_INVALID_DATA); + return FALSE; + } + else + { + //success! + return TRUE; + } + } + else + if (QveRes == ERROR_MORE_DATA) + { + // + //the needed bytes are already set by RegQueryValueExA + // + + SetLastError(QveRes); + return FALSE; + } + else + { + // + //print the error + // + ODSEx("QueryWinpcapRegistryKey, RegQueryValueEx failed, code %d",QveRes); + // + //JUST CONTINUE WITH THE DEFAULT VALUE + // + } + +#endif // WPCAP_OEM + + if ((*pValueLen) < strlen(DefaultVal) + 1) + { + memcpy(Value, DefaultVal, *pValueLen - 1); + Value[*pValueLen - 1] = '\0'; + *pValueLen = strlen(DefaultVal) + 1; + SetLastError(ERROR_MORE_DATA); + return FALSE; + } + else + { + strcpy(Value, DefaultVal); + *pValueLen = strlen(DefaultVal) + 1; + return TRUE; + } + +} + +BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName, + WCHAR *Value, + UINT *pValueLen, + WCHAR *DefaultVal) +{ +#ifdef WPCAP_OEM + DWORD Type; + LONG QveRes; + HKEY hWinPcapKey; + DWORD InternalLenBytes; + + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, + WINPCAP_INSTANCE_KEY_WIDECHAR, + 0, + KEY_ALL_ACCESS, + &hWinPcapKey) != ERROR_SUCCESS) + { + *pValueLen = 0; + return FALSE; + } + + InternalLenBytes = *pValueLen * 2; + + // + // Query the requested value + // + QveRes = RegQueryValueExW(hWinPcapKey, + SubKeyName, + NULL, + &Type, + (LPBYTE)Value, + &InternalLenBytes); + + RegCloseKey(hWinPcapKey); + + if (QveRes == ERROR_SUCCESS) + { + //let's check that the key is text + if (Type != REG_SZ) + { + *pValueLen = 0; + SetLastError(ERROR_INVALID_DATA); + return FALSE; + } + else + { + //success! + *pValueLen = wcslen(Value) + 1; + + return TRUE; + } + } + else + if (QveRes == ERROR_MORE_DATA) + { + // + //the needed bytes are not set by RegQueryValueExW + // + + //the +1 is needed to round the needed buffer size (in WCHARs) to a number of WCHARs that will fit + //the number of needed bytes. In any case if it's a W string, the number of needed bytes should always be even! + + *pValueLen = (InternalLenBytes + 1) / 2; + + SetLastError(ERROR_MORE_DATA); + return FALSE; + } + else + { + // + //print the error + // + ODSEx("QueryWinpcapRegistryKey, RegQueryValueEx failed, code %d\n",QveRes); + // + //JUST CONTINUE WITH THE DEFAULT VALUE + // + } + +#endif // WPCAP_OEM + + if (*pValueLen < wcslen(DefaultVal) + 1) + { + memcpy(Value, DefaultVal, (*pValueLen - 1) * 2); + Value[*pValueLen - 1] = '\0'; + *pValueLen = wcslen(DefaultVal) + 1; + SetLastError(ERROR_MORE_DATA); + return FALSE; + } + else + { + wcscpy(Value, DefaultVal); + *pValueLen = wcslen(DefaultVal) + 1; + return TRUE; + } + +} + +*/ + +/*! + \brief Convert a Unicode dotted-quad to a 32-bit IP address. + \param cp A string containing the address. + \return the converted 32-bit numeric address. + + Doesn't check to make sure the address is valid. +*/ +ULONG inet_addrU(const WCHAR *cp) +{ + ULONG val, part; + WCHAR c; + int i; + + val = 0; + for (i = 0; i < 4; i++) { + part = 0; + while ((c = *cp++) != '\0' && c != '.') { + if (c < '0' || c > '9') + return (ULONG)-1; + part = part*10 + (c - '0'); + } + if (part > 255) + return (ULONG)-1; + val = val | (part << i*8); + if (i == 3) { + if (c != '\0') + return (ULONG)-1; // extra gunk at end of string + } else { + if (c == '\0') + return (ULONG)-1; // string ends early + } + } + return val; +} + +/*! + \brief Converts an ASCII string to UNICODE. Uses the MultiByteToWideChar() system function. + \param string The string to convert. + \return The converted string. +*/ +static PWCHAR SChar2WChar(PCHAR string) +{ + PWCHAR TmpStr; + TmpStr = (WCHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (DWORD)(strlen(string)+2)*sizeof(WCHAR)); + + MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (DWORD)(strlen(string)+2)); + + return TmpStr; +} + +/*! + \brief Converts an UNICODE string to ASCII. Uses the WideCharToMultiByte() system function. + \param string The string to convert. + \return The converted string. +*/ +static PCHAR WChar2SChar(PWCHAR string) +{ + PCHAR TmpStr; + TmpStr = (CHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (DWORD)(wcslen(string)+2)); + + // Conver to ASCII + WideCharToMultiByte( + CP_ACP, + 0, + string, + -1, + TmpStr, + (DWORD)(wcslen(string)+2), // size of buffer + NULL, + NULL); + + return TmpStr; +} + +/*! + \brief Sets the maximum possible lookahead buffer for the driver's Packet_tap() function. + \param AdapterObject Handle to the service control manager. + \return If the function succeeds, the return value is nonzero. + + The lookahead buffer is the portion of packet that Packet_tap() can access from the NIC driver's memory + without performing a copy. This function tries to increase the size of that buffer. + + NOTE: this function is used for NPF adapters, only. +*/ + +BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject) +{ + BOOLEAN Status; + ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); + PPACKET_OID_DATA OidData; + + TRACE_ENTER("PacketSetMaxLookaheadsize"); + + OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); + if (OidData == NULL) { + TRACE_PRINT("PacketSetMaxLookaheadsize failed"); + Status = FALSE; + } + else + { + //set the size of the lookahead buffer to the maximum available by the the NIC driver + OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD; + OidData->Length=sizeof(ULONG); + Status=PacketRequest(AdapterObject,FALSE,OidData); + OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD; + Status=PacketRequest(AdapterObject,TRUE,OidData); + GlobalFreePtr(OidData); + } + + TRACE_EXIT("PacketSetMaxLookaheadsize"); + return Status; +} + +/*! + \brief Allocates the read event associated with the capture instance, passes it down to the kernel driver + and stores it in an _ADAPTER structure. + \param AdapterObject Handle to the adapter. + \return If the function succeeds, the return value is nonzero. + + This function is used by PacketOpenAdapter() to allocate the read event and pass it to the driver by means of an ioctl + call and set it in the _ADAPTER structure pointed by AdapterObject. + + NOTE: this function is used for NPF adapters, only. +*/ +BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject) +{ + DWORD BytesReturned; + HANDLE hEvent; + + TRACE_ENTER("PacketSetReadEvt"); + + if (AdapterObject->ReadEvent != NULL) + { + SetLastError(ERROR_INVALID_FUNCTION); + return FALSE; + } + + hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + if (hEvent == NULL) + { + //SetLastError done by CreateEvent + TRACE_EXIT("PacketSetReadEvt"); + return FALSE; + } + + if(DeviceIoControl(AdapterObject->hFile, + pBIOCSETEVENTHANDLE, + &hEvent, + sizeof(hEvent), + NULL, + 0, + &BytesReturned, + NULL)==FALSE) + { + DWORD dwLastError = GetLastError(); + + CloseHandle(hEvent); + + SetLastError(dwLastError); + + TRACE_EXIT("PacketSetReadEvt"); + return FALSE; + } + + AdapterObject->ReadEvent = hEvent; + AdapterObject->ReadTimeOut=0; + + TRACE_EXIT("PacketSetReadEvt"); + return TRUE; +} + +/*! + \brief Installs the NPF device driver. + \return If the function succeeds, the return value is nonzero. + + This function installs the driver's service in the system using the CreateService function. +*/ + +BOOLEAN PacketInstallDriver() +{ + BOOLEAN result = FALSE; + ULONG err = 0; + SC_HANDLE svcHandle; + SC_HANDLE scmHandle; +// +// Old registry based WinPcap names +// +// CHAR driverName[MAX_WINPCAP_KEY_CHARS]; +// CHAR driverDesc[MAX_WINPCAP_KEY_CHARS]; +// CHAR driverLocation[MAX_WINPCAP_KEY_CHARS; +// UINT len; + + CHAR driverName[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_NAME; + CHAR driverDesc[MAX_WINPCAP_KEY_CHARS] = NPF_SERVICE_DESC; + CHAR driverLocation[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_COMPLETE_PATH; + + TRACE_ENTER("PacketInstallDriver"); + +// +// Old registry based WinPcap names +// +// len = sizeof(driverName)/sizeof(driverName[0]); +// if (QueryWinPcapRegistryStringA(NPF_DRIVER_NAME_REG_KEY, driverName, &len, NPF_DRIVER_NAME) == FALSE && len == 0) +// return FALSE; +// +// len = sizeof(driverDesc)/sizeof(driverDesc[0]); +// if (QueryWinPcapRegistryStringA(NPF_SERVICE_DESC_REG_KEY, driverDesc, &len, NPF_SERVICE_DESC) == FALSE && len == 0) +// return FALSE; +// +// len = sizeof(driverLocation)/sizeof(driverLocation[0]); +// if (QueryWinPcapRegistryStringA(NPF_DRIVER_COMPLETE_PATH_REG_KEY, driverLocation, &len, NPF_DRIVER_COMPLETE_PATH) == FALSE && len == 0) +// return FALSE; + + scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + + if(scmHandle == NULL) + return FALSE; + + svcHandle = CreateServiceA(scmHandle, + driverName, + driverDesc, + SERVICE_ALL_ACCESS, + SERVICE_KERNEL_DRIVER, + SERVICE_DEMAND_START, + SERVICE_ERROR_NORMAL, + driverLocation, + NULL, NULL, NULL, NULL, NULL); + if (svcHandle == NULL) + { + err = GetLastError(); + if (err == ERROR_SERVICE_EXISTS) + { + TRACE_PRINT("Service npf.sys already exists"); + //npf.sys already existed + err = 0; + result = TRUE; + } + } + else + { + TRACE_PRINT("Created service for npf.sys"); + //Created service for npf.sys + result = TRUE; + } + + if (svcHandle != NULL) + CloseServiceHandle(svcHandle); + + if(result == FALSE) + { + TRACE_PRINT1("PacketInstallDriver failed, Error=%u",err); + } + + CloseServiceHandle(scmHandle); + SetLastError(err); + TRACE_EXIT("PacketInstallDriver"); + return result; + +} + +/*! + \brief Dumps a registry key to disk in text format. Uses regedit. + \param KeyName Name of the ket to dump. All its subkeys will be saved recursively. + \param FileName Name of the file that will contain the dump. + \return If the function succeeds, the return value is nonzero. + + For debugging purposes, we use this function to obtain some registry keys from the user's machine. +*/ + +#ifdef _DEBUG_TO_FILE + +LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName) +{ + CHAR Command[256]; + + TRACE_ENTER("PacketDumpRegistryKey"); + StringCchPrintfA(Command, sizeof(Command), "regedit /e %s %s", FileName, KeyName); + + /// Let regedit do the dirty work for us + system(Command); + + TRACE_EXIT("PacketDumpRegistryKey"); + return TRUE; +} +#endif + +/*! + \brief Returns the version of a dll or exe file + \param FileName Name of the file whose version has to be retrieved. + \param VersionBuff Buffer that will contain the string with the file version. + \param VersionBuffLen Length of the buffer poited by VersionBuff. + \return If the function succeeds, the return value is TRUE. + + \note uses the GetFileVersionInfoSize() and GetFileVersionInfo() WIN32 API functions +*/ +BOOL PacketGetFileVersion(LPTSTR FileName, PCHAR VersionBuff, UINT VersionBuffLen) +{ + DWORD dwVerInfoSize; // Size of version information block + DWORD dwVerHnd=0; // An 'ignored' parameter, always '0' + LPSTR lpstrVffInfo; + UINT cbTranslate, dwBytes; + TCHAR SubBlock[64]; + PVOID lpBuffer; + PCHAR TmpStr; + + // Structure used to store enumerated languages and code pages. + struct LANGANDCODEPAGE { + WORD wLanguage; + WORD wCodePage; + } *lpTranslate; + + TRACE_ENTER("PacketGetFileVersion"); + + // Now lets dive in and pull out the version information: + dwVerInfoSize = GetFileVersionInfoSize(FileName, &dwVerHnd); + if (dwVerInfoSize) + { + lpstrVffInfo = GlobalAllocPtr(GMEM_MOVEABLE, dwVerInfoSize); + if (lpstrVffInfo == NULL) + { + TRACE_PRINT("PacketGetFileVersion: failed to allocate memory"); + TRACE_EXIT("PacketGetFileVersion"); + return FALSE; + } + + if(!GetFileVersionInfo(FileName, dwVerHnd, dwVerInfoSize, lpstrVffInfo)) + { + TRACE_PRINT("PacketGetFileVersion: failed to call GetFileVersionInfo"); + GlobalFreePtr(lpstrVffInfo); + TRACE_EXIT("PacketGetFileVersion"); + return FALSE; + } + + // Read the list of languages and code pages. + if(!VerQueryValue(lpstrVffInfo, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate)) + { + TRACE_PRINT("PacketGetFileVersion: failed to call VerQueryValue"); + GlobalFreePtr(lpstrVffInfo); + TRACE_EXIT("PacketGetFileVersion"); + return FALSE; + } + + // Create the file version string for the first (i.e. the only one) language. + StringCchPrintf(SubBlock, + sizeof(SubBlock)/sizeof(SubBlock[0]), + TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"), + (*lpTranslate).wLanguage, + (*lpTranslate).wCodePage); + + // Retrieve the file version string for the language. + if(!VerQueryValue(lpstrVffInfo, SubBlock, &lpBuffer, &dwBytes)) + { + TRACE_PRINT("PacketGetFileVersion: failed to call VerQueryValue"); + GlobalFreePtr(lpstrVffInfo); + TRACE_EXIT("PacketGetFileVersion"); + return FALSE; + } + + // Convert to ASCII + TmpStr = WChar2SChar(lpBuffer); + + if(strlen(TmpStr) >= VersionBuffLen) + { + TRACE_PRINT("PacketGetFileVersion: Input buffer too small"); + GlobalFreePtr(lpstrVffInfo); + GlobalFreePtr(TmpStr); + TRACE_EXIT("PacketGetFileVersion"); + return FALSE; + } + + StringCchCopyA(VersionBuff, VersionBuffLen, TmpStr); + + GlobalFreePtr(lpstrVffInfo); + GlobalFreePtr(TmpStr); + + } + else + { + TRACE_PRINT1("PacketGetFileVersion: failed to call GetFileVersionInfoSize, LastError = %8.8x", GetLastError()); + TRACE_EXIT("PacketGetFileVersion"); + return FALSE; + + } + + TRACE_EXIT("PacketGetFileVersion"); + return TRUE; +} + +/*! + \brief Opens an adapter using the NPF device driver. + \param AdapterName A string containing the name of the device to open. + \return If the function succeeds, the return value is the pointer to a properly initialized ADAPTER object, + otherwise the return value is NULL. + + \note internal function used by PacketOpenAdapter() and AddAdapter() +*/ +LPADAPTER PacketOpenAdapterNPF(PCHAR AdapterNameA) +{ + LPADAPTER lpAdapter; + BOOL Result; + DWORD error; + SC_HANDLE svcHandle = NULL; + SC_HANDLE scmHandle = NULL; + LONG KeyRes; + HKEY PathKey; + SERVICE_STATUS SStat; + BOOL QuerySStat; + CHAR SymbolicLinkA[MAX_PATH]; +// +// Old registry based WinPcap names +// +// CHAR NpfDriverName[MAX_WINPCAP_KEY_CHARS]; +// UINT RegQueryLen; + + CHAR NpfDriverName[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_NAME; + CHAR NpfServiceLocation[MAX_WINPCAP_KEY_CHARS]; + + // Create the NPF device name from the original device name + TRACE_ENTER("PacketOpenAdapterNPF"); + + TRACE_PRINT1("Trying to open adapter %s", AdapterNameA); + + scmHandle = OpenSCManager(NULL, NULL, GENERIC_READ); + + if(scmHandle == NULL) + { + error = GetLastError(); + TRACE_PRINT1("OpenSCManager failed! LastError=%8.8x", error); + } + else + { +// +// Old registry based WinPcap names +// +// RegQueryLen = sizeof(NpfDriverName)/sizeof(NpfDriverName[0]); +// if (QueryWinPcapRegistryStringA(NPF_DRIVER_NAME_REG_KEY, NpfDriverName, &RegQueryLen, NPF_DRIVER_NAME) == FALSE && RegQueryLen == 0) +// { +// //just use an empty string string for the service name +// NpfDriverName[0] = '\0'; +// } + + // + // Create the name of the registry key containing the service. + // + StringCchPrintfA(NpfServiceLocation, sizeof(NpfServiceLocation), "SYSTEM\\CurrentControlSet\\Services\\%s", NpfDriverName); + + // check if the NPF registry key is already present + // this means that the driver is already installed and that we don't need to call PacketInstallDriver + KeyRes=RegOpenKeyExA(HKEY_LOCAL_MACHINE, + NpfServiceLocation, + 0, + KEY_READ, + &PathKey); + + if(KeyRes != ERROR_SUCCESS) + { + TRACE_PRINT("NPF registry key not present, trying to install the driver."); + Result = PacketInstallDriver(); + } + else + { + TRACE_PRINT("NPF registry key present, driver is installed."); + Result = TRUE; + RegCloseKey(PathKey); + } + + if (Result) + { + TRACE_PRINT("Trying to see if the NPF service is running..."); + svcHandle = OpenServiceA(scmHandle, NpfDriverName, SERVICE_START | SERVICE_QUERY_STATUS ); + + if (svcHandle != NULL) + { + QuerySStat = QueryServiceStatus(svcHandle, &SStat); + +#ifdef _DBG + switch (SStat.dwCurrentState) + { + case SERVICE_CONTINUE_PENDING: + TRACE_PRINT("The status of the driver is: SERVICE_CONTINUE_PENDING"); + break; + case SERVICE_PAUSE_PENDING: + TRACE_PRINT("The status of the driver is: SERVICE_PAUSE_PENDING"); + break; + case SERVICE_PAUSED: + TRACE_PRINT("The status of the driver is: SERVICE_PAUSED"); + break; + case SERVICE_RUNNING: + TRACE_PRINT("The status of the driver is: SERVICE_RUNNING"); + break; + case SERVICE_START_PENDING: + TRACE_PRINT("The status of the driver is: SERVICE_START_PENDING"); + break; + case SERVICE_STOP_PENDING: + TRACE_PRINT("The status of the driver is: SERVICE_STOP_PENDING"); + break; + case SERVICE_STOPPED: + TRACE_PRINT("The status of the driver is: SERVICE_STOPPED"); + break; + + default: + TRACE_PRINT("The status of the driver is: unknown"); + break; + } +#endif + + if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING) + { + TRACE_PRINT("Driver NPF not running. Calling startservice"); + if (StartService(svcHandle, 0, NULL)==0) + { + error = GetLastError(); + if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS) + { + SetLastError(error); + if (scmHandle != NULL) + CloseServiceHandle(scmHandle); + error = GetLastError(); + TRACE_PRINT1("PacketOpenAdapterNPF: StartService failed, LastError=%8.8x",error); + TRACE_EXIT("PacketOpenAdapterNPF"); + SetLastError(error); + return NULL; + } + } + } + + CloseServiceHandle( svcHandle ); + svcHandle = NULL; + + } + else + { + error = GetLastError(); + TRACE_PRINT1("OpenService failed! Error=%8.8x", error); + SetLastError(error); + } + } + else + { + if(KeyRes != ERROR_SUCCESS) + Result = PacketInstallDriver(); + else + Result = TRUE; + + if (Result) { + + svcHandle = OpenServiceA(scmHandle, + NpfDriverName, + SERVICE_START); + if (svcHandle != NULL) + { + + QuerySStat = QueryServiceStatus(svcHandle, &SStat); + +#ifdef _DBG + switch (SStat.dwCurrentState) + { + case SERVICE_CONTINUE_PENDING: + TRACE_PRINT("The status of the driver is: SERVICE_CONTINUE_PENDING"); + break; + case SERVICE_PAUSE_PENDING: + TRACE_PRINT("The status of the driver is: SERVICE_PAUSE_PENDING"); + break; + case SERVICE_PAUSED: + TRACE_PRINT("The status of the driver is: SERVICE_PAUSED"); + break; + case SERVICE_RUNNING: + TRACE_PRINT("The status of the driver is: SERVICE_RUNNING"); + break; + case SERVICE_START_PENDING: + TRACE_PRINT("The status of the driver is: SERVICE_START_PENDING"); + break; + case SERVICE_STOP_PENDING: + TRACE_PRINT("The status of the driver is: SERVICE_STOP_PENDING"); + break; + case SERVICE_STOPPED: + TRACE_PRINT("The status of the driver is: SERVICE_STOPPED"); + break; + + default: + TRACE_PRINT("The status of the driver is: unknown"); + break; + } +#endif + + if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){ + + TRACE_PRINT("Calling startservice"); + + if (StartService(svcHandle, 0, NULL)==0){ + error = GetLastError(); + if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS) + { + if (scmHandle != NULL) CloseServiceHandle(scmHandle); + TRACE_PRINT1("PacketOpenAdapterNPF: StartService failed, LastError=%8.8x",error); + TRACE_EXIT("PacketOpenAdapterNPF"); + SetLastError(error); + return NULL; + } + } + } + + CloseServiceHandle( svcHandle ); + svcHandle = NULL; + + } + else{ + error = GetLastError(); + TRACE_PRINT1("OpenService failed! LastError=%8.8x", error); + SetLastError(error); + } + } + } + } + + if (scmHandle != NULL) CloseServiceHandle(scmHandle); + + lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER)); + if (lpAdapter==NULL) + { + TRACE_PRINT("PacketOpenAdapterNPF: GlobalAlloc Failed to allocate the ADAPTER structure"); + error=GetLastError(); + //set the error to the one on which we failed + TRACE_EXIT("PacketOpenAdapterNPF"); + SetLastError(error); + return NULL; + } + + lpAdapter->NumWrites=1; + +#define DEVICE_PREFIX "\\Device\\" + + if (LOWORD(GetVersion()) == 4) + { + if (strlen(AdapterNameA) > strlen(DEVICE_PREFIX)) + { + StringCchPrintfA(SymbolicLinkA, MAX_PATH, "\\\\.\\%s", AdapterNameA + strlen(DEVICE_PREFIX)); + } + else + { + ZeroMemory(SymbolicLinkA, sizeof(SymbolicLinkA)); + } + } + else + { + if (strlen(AdapterNameA) > strlen(DEVICE_PREFIX)) + { + StringCchPrintfA(SymbolicLinkA, MAX_PATH, "\\\\.\\Global\\%s", AdapterNameA + strlen(DEVICE_PREFIX)); + } + else + { + ZeroMemory(SymbolicLinkA, sizeof(SymbolicLinkA)); + } + } + + // + // NOTE GV 20061114 This is a sort of breaking change. In the past we were putting what + // we could fit inside this variable. Now we simply put NOTHING. It's just useless + // + ZeroMemory(lpAdapter->SymbolicLink, sizeof(lpAdapter->SymbolicLink)); + + //try if it is possible to open the adapter immediately + lpAdapter->hFile=CreateFileA(SymbolicLinkA,GENERIC_WRITE | GENERIC_READ, + 0,NULL,OPEN_EXISTING,0,0); + + if (lpAdapter->hFile != INVALID_HANDLE_VALUE) + { + + if(PacketSetReadEvt(lpAdapter)==FALSE){ + error=GetLastError(); + TRACE_PRINT("PacketOpenAdapterNPF: Unable to open the read event"); + CloseHandle(lpAdapter->hFile); + GlobalFreePtr(lpAdapter); + //set the error to the one on which we failed + + TRACE_PRINT1("PacketOpenAdapterNPF: PacketSetReadEvt failed, LastError=%8.8x",error); + TRACE_EXIT("PacketOpenAdapterNPF"); + + + SetLastError(error); + return NULL; + } + + PacketSetMaxLookaheadsize(lpAdapter); + + // + // Indicate that this is a device managed by NPF.sys + // + lpAdapter->Flags = INFO_FLAG_NDIS_ADAPTER; + + + StringCchCopyA(lpAdapter->Name, ADAPTER_NAME_LENGTH, AdapterNameA); + + TRACE_PRINT("Successfully opened adapter"); + TRACE_EXIT("PacketOpenAdapterNPF"); + return lpAdapter; + } + + error=GetLastError(); + GlobalFreePtr(lpAdapter); + //set the error to the one on which we failed + TRACE_PRINT1("PacketOpenAdapterNPF: CreateFile failed, LastError= %8.8x",error); + TRACE_EXIT("PacketOpenAdapterNPF"); + SetLastError(error); + return NULL; +} + +#ifdef HAVE_WANPACKET_API +static LPADAPTER PacketOpenAdapterWanPacket(PCHAR AdapterName) +{ + LPADAPTER lpAdapter = NULL; + DWORD dwLastError = ERROR_SUCCESS; + + TRACE_ENTER("PacketOpenAdapterWanPacket"); + + TRACE_PRINT("Opening a NDISWAN adapter..."); + + do + { + // + // This is a wan adapter. Open it using the netmon API + // + lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, + sizeof(ADAPTER)); + + if (lpAdapter == NULL) + { + TRACE_PRINT("GlobalAlloc failed allocating memory for the ADAPTER structure. Failing (BAD_UNIT)."); + dwLastError = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + lpAdapter->Flags = INFO_FLAG_NDISWAN_ADAPTER; + + TRACE_PRINT("Trying to open the Wan Adapter through WanPacket.dll..."); + + // Open the adapter + lpAdapter->pWanAdapter = WanPacketOpenAdapter(); + + if (lpAdapter->pWanAdapter == NULL) + { + TRACE_PRINT("WanPacketOpenAdapter failed. Failing. (BAD_UNIT)"); + dwLastError = ERROR_BAD_UNIT; + break; + } + + StringCchCopyA(lpAdapter->Name, ADAPTER_NAME_LENGTH, AdapterName); + + lpAdapter->ReadEvent = WanPacketGetReadEvent(lpAdapter->pWanAdapter); + + TRACE_PRINT("Successfully opened the Wan Adapter."); + + }while(FALSE); + + if (dwLastError == ERROR_SUCCESS) + { + TRACE_EXIT("PacketOpenAdapterWanPacket"); + return lpAdapter; + } + else + { + if (lpAdapter != NULL) GlobalFree(lpAdapter); + + TRACE_EXIT("PacketOpenAdapterWanPacket"); + SetLastError(dwLastError); + return NULL; + } +} +#endif //HAVE_WANPACKET_API + +/*! + \brief Opens an adapter using the aircap dll. + \param AdapterName A string containing the name of the device to open. + \return If the function succeeds, the return value is the pointer to a properly initialized ADAPTER object, + otherwise the return value is NULL. + + \note internal function used by PacketOpenAdapter() +*/ +#ifdef HAVE_AIRPCAP_API +static LPADAPTER PacketOpenAdapterAirpcap(PCHAR AdapterName) +{ + CHAR Ebuf[AIRPCAP_ERRBUF_SIZE]; + LPADAPTER lpAdapter; + + // + // Make sure that the airpcap API has been linked + // + if(!g_PAirpcapOpen) + { + return NULL; + } + + lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, + sizeof(ADAPTER)); + if (lpAdapter == NULL) + { + return NULL; + } + + // + // Indicate that this is a aircap card + // + lpAdapter->Flags = INFO_FLAG_AIRPCAP_CARD; + + // + // Open the adapter + // + lpAdapter->AirpcapAd = g_PAirpcapOpen(AdapterName, Ebuf); + + if(lpAdapter->AirpcapAd == NULL) + { + GlobalFreePtr(lpAdapter); + return NULL; + } + + StringCchCopyA(lpAdapter->Name, ADAPTER_NAME_LENGTH, AdapterName); + + return lpAdapter; +} +#endif // HAVE_AIRPCAP_API + + +#ifdef HAVE_NPFIM_API +static LPADAPTER PacketOpenAdapterNpfIm(PCHAR AdapterName) +{ + LPADAPTER lpAdapter; + + lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, + sizeof(ADAPTER)); + if (lpAdapter == NULL) + { + return NULL; + } + + // + // Indicate that this is a aircap card + // + lpAdapter->Flags = INFO_FLAG_NPFIM_DEVICE; + + // + // Open the adapter + // + + if (g_NpfImHandlers.NpfImOpenDevice(AdapterName, (NPF_IM_DEV_HANDLE*)&lpAdapter->NpfImHandle) == FALSE) + { + GlobalFreePtr(lpAdapter); + return NULL; + } + + StringCchCopyA(lpAdapter->Name, ADAPTER_NAME_LENGTH, AdapterName); + + return lpAdapter; +} +#endif // HAVE_NpfIm_API + + +/*! + \brief Opens an adapter using the DAG capture API. + \param AdapterName A string containing the name of the device to open. + \return If the function succeeds, the return value is the pointer to a properly initialized ADAPTER object, + otherwise the return value is NULL. + + \note internal function used by PacketOpenAdapter() +*/ +#ifdef HAVE_DAG_API +static LPADAPTER PacketOpenAdapterDAG(PCHAR AdapterName, BOOLEAN IsAFile) +{ + CHAR DagEbuf[DAGC_ERRBUF_SIZE]; + LPADAPTER lpAdapter; + LONG status; + HKEY dagkey; + DWORD lptype; + DWORD fpc; + DWORD lpcbdata = sizeof(fpc); + WCHAR keyname[512]; + PWCHAR tsn; + + TRACE_ENTER("PacketOpenAdapterDAG"); + + + lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, + sizeof(ADAPTER)); + if (lpAdapter == NULL) + { + TRACE_PRINT("GlobalAlloc failed allocating memory for the ADAPTER structure"); + TRACE_EXIT("PacketOpenAdapterDAG"); + return NULL; + } + + if(IsAFile) + { + // We must add an entry to the adapter description list, otherwise many function will not + // be able to work + if(!PacketAddAdapterDag(AdapterName, "DAG file", IsAFile)) + { + TRACE_PRINT("Failed adding the Dag file to the list of adapters"); + TRACE_EXIT("PacketOpenAdapterDAG"); + GlobalFreePtr(lpAdapter); + return NULL; + } + + // Flag that this is a DAG file + lpAdapter->Flags = INFO_FLAG_DAG_FILE; + } + else + { + // Flag that this is a DAG card + lpAdapter->Flags = INFO_FLAG_DAG_CARD; + } + + // + // See if the user is asking for fast capture with this device + // + + lpAdapter->DagFastProcess = FALSE; + + tsn = (strstr(strlwr((char*)AdapterName), "dag") != NULL)? + SChar2WChar(strstr(strlwr((char*)AdapterName), "dag")): + L""; + + StringCchPrintfW(keyname, sizeof(keyname)/sizeof(keyname[0]), L"%s\\CardParams\\%ws", + L"SYSTEM\\CurrentControlSet\\Services\\DAG", + tsn); + + GlobalFreePtr(tsn); + + do + { + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0 , KEY_READ, &dagkey); + if(status != ERROR_SUCCESS) + break; + + status = RegQueryValueEx(dagkey, + L"FastCap", + NULL, + &lptype, + (LPBYTE)&fpc, + &lpcbdata); + + if(status == ERROR_SUCCESS) + lpAdapter->DagFastProcess = fpc; + + RegCloseKey(dagkey); + } + while(FALSE); + + + TRACE_PRINT("Trying to open the DAG device..."); + // + // Open the card + // + lpAdapter->pDagCard = g_p_dagc_open(AdapterName, + 0, + DagEbuf); + + if(lpAdapter->pDagCard == NULL) + { + TRACE_PRINT("Failed opening the DAG device"); + TRACE_EXIT("PacketOpenAdapterDAG"); + GlobalFreePtr(lpAdapter); + return NULL; + } + + lpAdapter->DagFcsLen = g_p_dagc_getfcslen(lpAdapter->pDagCard); + + StringCchCopyA(lpAdapter->Name, ADAPTER_NAME_LENGTH, AdapterName); + + // XXX we could create the read event here + TRACE_PRINT("Successfully opened the DAG device"); + TRACE_EXIT("PacketOpenAdapterDAG"); + + return lpAdapter; +} +#endif // HAVE_DAG_API + + +//--------------------------------------------------------------------------- +// PUBLIC API +//--------------------------------------------------------------------------- + +/** @ingroup packetapi + * @{ + */ + +/** @defgroup packet32 Packet.dll exported functions and variables + * @{ + */ + +/*! + \brief Return a string with the dll version. + \return A char pointer to the version of the library. +*/ +PCHAR PacketGetVersion() +{ + TRACE_ENTER("PacketGetVersion"); + TRACE_EXIT("PacketGetVersion"); + return PacketLibraryVersion; +} + +/*! + \brief Return a string with the version of the NPF.sys device driver. + \return A char pointer to the version of the driver. +*/ +PCHAR PacketGetDriverVersion() +{ + TRACE_ENTER("PacketGetDriverVersion"); + TRACE_EXIT("PacketGetDriverVersion"); + return PacketDriverVersion; +} + +/*! + \brief Stops and unloads the WinPcap device driver. + \return If the function succeeds, the return value is nonzero, otherwise it is zero. + + This function can be used to unload the driver from memory when the application no more needs it. + Note that the driver is physically stopped and unloaded only when all the files on its devices + are closed, i.e. when all the applications that use WinPcap close all their adapters. +*/ +BOOL PacketStopDriver() +{ + SC_HANDLE scmHandle; + SC_HANDLE schService; + BOOL ret; + SERVICE_STATUS serviceStatus; + CHAR NpfDriverName[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_NAME; + +// +// Old registry based WinPcap names +// +// CHAR NpfDriverName[MAX_WINPCAP_KEY_CHARS]; +// UINT RegQueryLen; + + TRACE_ENTER("PacketStopDriver"); + + ret = FALSE; + +// +// Old registry based WinPcap names +// +// // Create the NPF device name from the original device name +// RegQueryLen = sizeof(NpfDriverName)/sizeof(NpfDriverName[0]); +// +// if (QueryWinPcapRegistryStringA(NPF_DRIVER_NAME_REG_KEY, NpfDriverName, &RegQueryLen, NPF_DRIVER_NAME) == FALSE && RegQueryLen == 0) +// return FALSE; + + scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + + if(scmHandle != NULL){ + + TRACE_PRINT("Opened the SCM"); + + schService = OpenServiceA (scmHandle, + NpfDriverName, + SERVICE_ALL_ACCESS + ); + + if (schService != NULL) + { + TRACE_PRINT("Opened the NPF service in the SCM"); + + ret = ControlService (schService, + SERVICE_CONTROL_STOP, + &serviceStatus + ); + if (!ret) + { + TRACE_PRINT("Failed to stop the NPF service"); + } + else + { + TRACE_PRINT("NPF service stopped"); + } + + CloseServiceHandle (schService); + + CloseServiceHandle(scmHandle); + + } + } + + TRACE_EXIT("PacketStopDriver"); + return ret; +} + +/*! + \brief Opens an adapter. + \param AdapterName A string containing the name of the device to open. + Use the PacketGetAdapterNames() function to retrieve the list of available devices. + \return If the function succeeds, the return value is the pointer to a properly initialized ADAPTER object, + otherwise the return value is NULL. +*/ +LPADAPTER PacketOpenAdapter(PCHAR AdapterNameWA) +{ + LPADAPTER lpAdapter = NULL; + PCHAR AdapterNameA = NULL; + BOOL bFreeAdapterNameA; +#ifndef _WINNT4 + PADAPTER_INFO TAdInfo; +#endif //_WINNT4 + + DWORD dwLastError = ERROR_SUCCESS; + + TRACE_ENTER("PacketOpenAdapter"); + + TRACE_PRINT_OS_INFO(); + + TRACE_PRINT2("Packet DLL version %s, Driver version %s", PacketLibraryVersion, PacketDriverVersion); + + // + // Check the presence on some libraries we rely on, and load them if we found them + // + PacketLoadLibrariesDynamically(); + + // + // Ugly heuristic to detect if the adapter is ASCII + // + if(AdapterNameWA[1]!=0) + { + // + // ASCII + // + bFreeAdapterNameA = FALSE; + AdapterNameA = AdapterNameWA; + } + else + { + // + // Unicode + // + size_t bufferSize = wcslen((PWCHAR)AdapterNameWA) + 1; + + AdapterNameA = GlobalAllocPtr(GPTR, bufferSize); + + if (AdapterNameA == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + StringCchPrintfA(AdapterNameA, bufferSize, "%ws", (PWCHAR)AdapterNameWA); + bFreeAdapterNameA = TRUE; + } + +#ifndef _WINNT4 + WaitForSingleObject(g_AdaptersInfoMutex, INFINITE); +#endif // not WINNT4 + + do + { + +#ifndef _WINNT4 + // + // Windows NT4 does not have support for the various nifty + // adapters supported from 2000 on (airpcap, ndiswan, npfim...) + // so we just skip all the magic of the global adapter list, + // and try to open the adapter with PacketOpenAdapterNPF at + // the end of this big function! + // + + // + // If we are here it's because we need to update the list + // + + + TRACE_PRINT("Looking for the adapter in our list 1st time..."); + + // Find the PADAPTER_INFO structure associated with this adapter + TAdInfo = PacketFindAdInfo(AdapterNameA); + if(TAdInfo == NULL) + { + TRACE_PRINT("Adapter not found in our list. Try to refresh the list."); + + PacketUpdateAdInfo(AdapterNameA); + TAdInfo = PacketFindAdInfo(AdapterNameA); + + TRACE_PRINT("Looking for the adapter in our list 2nd time..."); + } + + if(TAdInfo == NULL) + { +#ifdef HAVE_DAG_API + TRACE_PRINT("Adapter not found in our list. Try to open it as a DAG/ERF file..."); + + //can be an ERF file? + lpAdapter = PacketOpenAdapterDAG(AdapterNameA, TRUE); +#endif // HAVE_DAG_API + + if (lpAdapter == NULL) + { + TRACE_PRINT("Failed to open it as a DAG/ERF file, failing with ERROR_BAD_UNIT"); + dwLastError = ERROR_BAD_UNIT; //this is the best we can do.... + } + else + { + TRACE_PRINT("Opened the adapter as a DAG/ERF file."); + } + + break; + } + + TRACE_PRINT("Adapter found in our list. Check adapter type and see if it's actually supported."); + +#ifdef HAVE_WANPACKET_API + if(TAdInfo->Flags == INFO_FLAG_NDISWAN_ADAPTER) + { + lpAdapter = PacketOpenAdapterWanPacket(AdapterNameA); + + if (lpAdapter == NULL) + { + dwLastError = GetLastError(); + } + + break; + } +#endif //HAVE_WANPACKET_API + +#ifdef HAVE_AIRPCAP_API + if(TAdInfo->Flags == INFO_FLAG_AIRPCAP_CARD) + { + // + // This is an airpcap card. Open it using the airpcap api + // + lpAdapter = PacketOpenAdapterAirpcap(AdapterNameA); + + if(lpAdapter == NULL) + { + dwLastError = ERROR_BAD_UNIT; + break; + } + + // + // Airpcap provides a read event + // + if(!g_PAirpcapGetReadEvent(lpAdapter->AirpcapAd, &lpAdapter->ReadEvent)) + { + PacketCloseAdapter(lpAdapter); + dwLastError = ERROR_BAD_UNIT; + } + else + { + dwLastError = ERROR_SUCCESS; + } + + break; + } +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_NPFIM_API + if(TAdInfo->Flags == INFO_FLAG_NPFIM_DEVICE) + { + // + // This is an airpcap card. Open it using the airpcap api + // + lpAdapter = PacketOpenAdapterNpfIm(AdapterNameA); + + if(lpAdapter == NULL) + { + dwLastError = ERROR_BAD_UNIT; + break; + } + + // + // NpfIm provides a read event + // + if(!g_NpfImHandlers.NpfImGetCaptureReadEvent((NPF_IM_DEV_HANDLE)lpAdapter->NpfImHandle, &lpAdapter->ReadEvent)) + { + dwLastError = GetLastError(); + PacketCloseAdapter(lpAdapter); + } + else + { + dwLastError = ERROR_SUCCESS; + } + + break; + } +#endif // HAVE_NPFIM_API + +#ifdef HAVE_DAG_API + if(TAdInfo->Flags == INFO_FLAG_DAG_CARD) + { + TRACE_PRINT("Opening a DAG adapter..."); + // + // This is a Dag card. Open it using the dagc API + // + lpAdapter = PacketOpenAdapterDAG(AdapterNameA, FALSE); + if (lpAdapter == NULL) + { + TRACE_PRINT("Failed opening the DAG adapter with PacketOpenAdapterDAG. Failing. (BAD_UNIT)"); + dwLastError = ERROR_BAD_UNIT; + } + else + { + dwLastError = ERROR_SUCCESS; + } + + break; + } +#endif // HAVE_DAG_API + + if(TAdInfo->Flags == INFO_FLAG_DONT_EXPORT) + { + // + // The adapter is flagged as not exported, probably because it's broken + // or incompatible with WinPcap. We end here with an error. + // + TRACE_PRINT1("Trying to open the adapter %s which is flagged as not exported. Failing (BAD_UNIT)", AdapterNameA); + dwLastError = ERROR_BAD_UNIT; + + break; + } + + if (TAdInfo->Flags != INFO_FLAG_NDIS_ADAPTER) + { + TRACE_PRINT1("Trying to open the adapter with an unknown flag type %u", TAdInfo->Flags); + dwLastError = ERROR_BAD_UNIT; + + break; + } + +#endif // not _WINNT4 + + // + // This is the only code executed on NT4 + // + // Windows NT4 does not have support for the various nifty + // adapters supported from 2000 on (airpcap, ndiswan, npfim...) + // so we just skip all the magic of the global adapter list, + // and try to open the adapter with PacketOpenAdapterNPF at + // the end of this big function! + // + TRACE_PRINT("Normal NPF adapter, trying to open it..."); + lpAdapter = PacketOpenAdapterNPF(AdapterNameA); + if (lpAdapter == NULL) + { + dwLastError = GetLastError(); + } + + }while(FALSE); + +#ifndef _WINNT4 + ReleaseMutex(g_AdaptersInfoMutex); +#endif + + if (bFreeAdapterNameA) GlobalFree(AdapterNameA); + + + if (dwLastError != ERROR_SUCCESS) + { + TRACE_EXIT("PacketOpenAdapter"); + SetLastError(dwLastError); + + return NULL; + } + else + { + TRACE_EXIT("PacketOpenAdapter"); + + return lpAdapter; + } + +} + +/*! + \brief Closes an adapter. + \param lpAdapter the pointer to the adapter to close. + + PacketCloseAdapter closes the given adapter and frees the associated ADAPTER structure +*/ +VOID PacketCloseAdapter(LPADAPTER lpAdapter) +{ + TRACE_ENTER("PacketCloseAdapter"); + if(!lpAdapter) + { + TRACE_PRINT("PacketCloseAdapter: attempt to close a NULL adapter"); + TRACE_EXIT("PacketCloseAdapter"); + return; + } + +#ifdef HAVE_WANPACKET_API + if (lpAdapter->Flags == INFO_FLAG_NDISWAN_ADAPTER) + { + TRACE_PRINT("Closing a WAN adapter through WanPacket..."); + WanPacketCloseAdapter(lpAdapter->pWanAdapter); + GlobalFreePtr(lpAdapter); + return; + } +#endif + +#ifdef HAVE_AIRPCAP_API + if(lpAdapter->Flags == INFO_FLAG_AIRPCAP_CARD) + { + g_PAirpcapClose(lpAdapter->AirpcapAd); + GlobalFreePtr(lpAdapter); + return; + } +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_NPFIM_API + if(lpAdapter->Flags == INFO_FLAG_NPFIM_DEVICE) + { + g_NpfImHandlers.NpfImCloseDevice(lpAdapter->NpfImHandle); + GlobalFreePtr(lpAdapter); + return; + } +#endif + +#ifdef HAVE_DAG_API + if(lpAdapter->Flags & INFO_FLAG_DAG_FILE || lpAdapter->Flags & INFO_FLAG_DAG_CARD) + { + TRACE_PRINT("Closing a DAG file..."); + if(lpAdapter->Flags & INFO_FLAG_DAG_FILE & ~INFO_FLAG_DAG_CARD) + { + // This is a file. We must remove the entry in the adapter description list + PacketUpdateAdInfo(lpAdapter->Name); + } + g_p_dagc_close(lpAdapter->pDagCard); + GlobalFreePtr(lpAdapter); + return; + } +#endif // HAVE_DAG_API + + if (lpAdapter->Flags != INFO_FLAG_NDIS_ADAPTER) + { + TRACE_PRINT1("Trying to close an unknown adapter type (%u)", lpAdapter->Flags); + } + else + { + SetEvent(lpAdapter->ReadEvent); + CloseHandle(lpAdapter->ReadEvent); + CloseHandle(lpAdapter->hFile); + GlobalFreePtr(lpAdapter); + TRACE_EXIT("PacketCloseAdapter"); + } + +} + +/*! + \brief Allocates a _PACKET structure. + \return On succeess, the return value is the pointer to a _PACKET structure otherwise the + return value is NULL. + + The structure returned will be passed to the PacketReceivePacket() function to receive the + packets from the driver. + + \warning The Buffer field of the _PACKET structure is not set by this function. + The buffer \b must be allocated by the application, and associated to the PACKET structure + with a call to PacketInitPacket. +*/ +LPPACKET PacketAllocatePacket(void) +{ + LPPACKET lpPacket; + + TRACE_ENTER("PacketAllocatePacket"); + + lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET)); + if (lpPacket==NULL) + { + TRACE_PRINT("PacketAllocatePacket: GlobalAlloc Failed"); + } + + TRACE_EXIT("PacketAllocatePacket"); + + return lpPacket; +} + +/*! + \brief Frees a _PACKET structure. + \param lpPacket The structure to free. + + \warning the user-allocated buffer associated with the _PACKET structure is not deallocated + by this function and \b must be explicitly deallocated by the programmer. + +*/ +VOID PacketFreePacket(LPPACKET lpPacket) + +{ + TRACE_ENTER("PacketFreePacket"); + GlobalFreePtr(lpPacket); + TRACE_EXIT("PacketFreePacket"); +} + +/*! + \brief Initializes a _PACKET structure. + \param lpPacket The structure to initialize. + \param Buffer A pointer to a user-allocated buffer that will contain the captured data. + \param Length the length of the buffer. This is the maximum buffer size that will be + transferred from the driver to the application using a single read. + + \note the size of the buffer associated with the PACKET structure is a parameter that can sensibly + influence the performance of the capture process, since this buffer will contain the packets received + from the the driver. The driver is able to return several packets using a single read call + (see the PacketReceivePacket() function for details), and the number of packets transferable to the + application in a call is limited only by the size of the buffer associated with the PACKET structure + passed to PacketReceivePacket(). Therefore setting a big buffer with PacketInitPacket can noticeably + decrease the number of system calls, reducing the impcat of the capture process on the processor. +*/ + +VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length) + +{ + TRACE_ENTER("PacketInitPacket"); + + lpPacket->Buffer = Buffer; + lpPacket->Length = Length; + lpPacket->ulBytesReceived = 0; + lpPacket->bIoComplete = FALSE; + + TRACE_EXIT("PacketInitPacket"); +} + +/*! + \brief Read data (packets or statistics) from the NPF driver. + \param AdapterObject Pointer to an _ADAPTER structure identifying the network adapter from which + the data is received. + \param lpPacket Pointer to a PACKET structure that will contain the data. + \param Sync This parameter is deprecated and will be ignored. It is present for compatibility with + older applications. + \return If the function succeeds, the return value is nonzero. + + The data received with this function can be a group of packets or a static on the network traffic, + depending on the working mode of the driver. The working mode can be set with the PacketSetMode() + function. Give a look at that function if you are interested in the format used to return statistics + values, here only the normal capture mode will be described. + + The number of packets received with this function is variable. It depends on the number of packets + currently stored in the driver’s buffer, on the size of these packets and on the size of the buffer + associated to the lpPacket parameter. The following figure shows the format used by the driver to pass + packets to the application. + + \image html encoding.gif "method used to encode the packets" + + Packets are stored in the buffer associated with the lpPacket _PACKET structure. The Length field of + that structure is updated with the amount of data copied in the buffer. Each packet has a header + consisting in a bpf_hdr structure that defines its length and contains its timestamp. A padding field + is used to word-align the data in the buffer (to speed up the access to the packets). The bh_datalen + and bh_hdrlen fields of the bpf_hdr structures should be used to extract the packets from the buffer. + + Examples can be seen either in the TestApp sample application (see the \ref packetsamps page) provided + in the developer's pack, or in the pcap_read() function of wpcap. +*/ +BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync) +{ + BOOLEAN res; + + UNUSED(Sync); + + TRACE_ENTER("PacketReceivePacket"); +#ifdef HAVE_WANPACKET_API + + if (AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) + { + lpPacket->ulBytesReceived = WanPacketReceivePacket(AdapterObject->pWanAdapter, lpPacket->Buffer, lpPacket->Length); + + TRACE_EXIT("PacketReceivePacket"); + return TRUE; + } +#endif //HAVE_WANPACKET_API + +#ifdef HAVE_AIRPCAP_API + if(AdapterObject->Flags == INFO_FLAG_AIRPCAP_CARD) + { + // + // Wait for data, only if the user requested us to do that + // + if((int)AdapterObject->ReadTimeOut != -1) + { + WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)? INFINITE: AdapterObject->ReadTimeOut); + } + + // + // Read the data. + // g_PAirpcapRead always returns immediately. + // + res = (BOOLEAN)g_PAirpcapRead(AdapterObject->AirpcapAd, + lpPacket->Buffer, + lpPacket->Length, + &lpPacket->ulBytesReceived); + + TRACE_EXIT("PacketReceivePacket"); + + return res; + } +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_NPFIM_API + if(AdapterObject->Flags == INFO_FLAG_NPFIM_DEVICE) + { + // + // Read the data. + // NpfImReceivePacket performs its own wait internally. + // + + res = (BOOLEAN)g_NpfImHandlers.NpfImReceivePackets(AdapterObject->NpfImHandle, + lpPacket->Buffer, + lpPacket->Length, + &lpPacket->ulBytesReceived); + + TRACE_EXIT("PacketReceivePacket"); + + return res; + } +#endif // HAVE_NPFIM_API + +#ifdef HAVE_DAG_API + if((AdapterObject->Flags & INFO_FLAG_DAG_CARD) || (AdapterObject->Flags & INFO_FLAG_DAG_FILE)) + { + g_p_dagc_wait(AdapterObject->pDagCard, &AdapterObject->DagReadTimeout); + + res = (BOOLEAN)(g_p_dagc_receive(AdapterObject->pDagCard, (u_char**)&AdapterObject->DagBuffer, (u_int*)&lpPacket->ulBytesReceived) == 0); + + TRACE_EXIT("PacketReceivePacket"); + return res; + } +#endif // HAVE_DAG_API + + if (AdapterObject->Flags == INFO_FLAG_NDIS_ADAPTER) + { + if((int)AdapterObject->ReadTimeOut != -1) + WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut); + + res = (BOOLEAN)ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL); + } + else + { + TRACE_PRINT1("Request to read on an unknown device type (%u)", AdapterObject->Flags); + res = FALSE; + } + + TRACE_EXIT("PacketReceivePacket"); + return res; +} + +/*! + \brief Sends one (or more) copies of a packet to the network. + \param AdapterObject Pointer to an _ADAPTER structure identifying the network adapter that will + send the packets. + \param lpPacket Pointer to a PACKET structure with the packet to send. + \param Sync This parameter is deprecated and will be ignored. It is present for compatibility with + older applications. + \return If the function succeeds, the return value is nonzero. + + This function is used to send a raw packet to the network. 'Raw packet' means that the programmer + will have to include the protocol headers, since the packet is sent to the network 'as is'. + The CRC needs not to be calculated and put at the end of the packet, because it will be transparently + added by the network interface. + + The behavior of this function is influenced by the PacketSetNumWrites() function. With PacketSetNumWrites(), + it is possible to change the number of times a single write must be repeated. The default is 1, + i.e. every call to PacketSendPacket() will correspond to one packet sent to the network. If this number is + greater than 1, for example 1000, every raw packet written by the application will be sent 1000 times on + the network. This feature mitigates the overhead of the context switches and therefore can be used to generate + high speed traffic. It is particularly useful for tools that test networks, routers, and servers and need + to obtain high network loads. + The optimized sending process is still limited to one packet at a time: for the moment it cannot be used + to send a buffer with multiple packets. + + \note The ability to write multiple packets is currently present only in the Windows NTx version of the + packet driver. In Windows 95/98/ME it is emulated at user level in packet.dll. This means that an application + that uses the multiple write method will run in Windows 9x as well, but its performance will be very low + compared to the one of WindowsNTx. +*/ +BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync) +{ + DWORD BytesTransfered; + BOOLEAN Result; + TRACE_ENTER("PacketSendPacket"); + + UNUSED(Sync); + +#ifdef HAVE_AIRPCAP_API + if(AdapterObject->Flags == INFO_FLAG_AIRPCAP_CARD) + { + if(g_PAirpcapWrite) + { + Result = (BOOLEAN)g_PAirpcapWrite(AdapterObject->AirpcapAd, lpPacket->Buffer, lpPacket->Length); + TRACE_EXIT("PacketSetMinToCopy"); + + return Result; + } + else + { + TRACE_EXIT("PacketSetMinToCopy"); + TRACE_PRINT("Transmission not supported with this version of AirPcap"); + + return FALSE; + } + } +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_WANPACKET_API + if(AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) + { + TRACE_PRINT("PacketSendPacket: packet sending not allowed on wan adapters"); + + TRACE_EXIT("PacketSendPacket"); + return FALSE; + } +#endif // HAVE_WANPACKET_API + +#ifdef HAVE_NPFIM_API + if(AdapterObject->Flags == INFO_FLAG_NPFIM_DEVICE) + { + TRACE_PRINT("PacketSendPacket: packet sending not allowed on NPFIM adapters"); + + TRACE_EXIT("PacketSendPacket"); + return FALSE; + } +#endif //HAVE_NPFIM_API + + if (AdapterObject->Flags == INFO_FLAG_NDIS_ADAPTER) + { + Result = (BOOLEAN)WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL); + } + else + { + TRACE_PRINT1("Request to write on an unknown device type (%u)", AdapterObject->Flags); + Result = FALSE; + } + + TRACE_EXIT("PacketSendPacket"); + return Result; +} + +/*! + \brief Sends a buffer of packets to the network. + \param AdapterObject Pointer to an _ADAPTER structure identifying the network adapter that will + send the packets. + \param PacketBuff Pointer to buffer with the packets to send. + \param Size Size of the buffer pointed by the PacketBuff argument. + \param Sync if TRUE, the packets are sent respecting the timestamps. If FALSE, the packets are sent as + fast as possible + \return The amount of bytes actually sent. If the return value is smaller than the Size parameter, an + error occurred during the send. The error can be caused by a driver/adapter problem or by an + inconsistent/bogus packet buffer. + + This function is used to send a buffer of raw packets to the network. The buffer can contain an arbitrary + number of raw packets, each of which preceded by a dump_bpf_hdr structure. The dump_bpf_hdr is the same used + by WinPcap and libpcap to store the packets in a file, therefore sending a capture file is straightforward. + 'Raw packets' means that the sending application will have to include the protocol headers, since every packet + is sent to the network 'as is'. The CRC of the packets needs not to be calculated, because it will be + transparently added by the network interface. + + \note Using this function if more efficient than issuing a series of PacketSendPacket(), because the packets are + buffered in the kernel driver, so the number of context switches is reduced. + + \note When Sync is set to TRUE, the packets are synchronized in the kerenl with a high precision timestamp. + This requires a remarkable amount of CPU, but allows to send the packets with a precision of some microseconds + (depending on the precision of the performance counter of the machine). Such a precision cannot be reached + sending the packets separately with PacketSendPacket(). +*/ +INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync) +{ + BOOLEAN Res; + DWORD BytesTransfered, TotBytesTransfered=0; + struct timeval BufStartTime; + LARGE_INTEGER StartTicks, CurTicks, TargetTicks, TimeFreq; + + + TRACE_ENTER("PacketSendPackets"); + +#ifdef HAVE_WANPACKET_API + if(AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) + { + TRACE_PRINT("PacketSendPackets: packet sending not allowed on wan adapters"); + TRACE_EXIT("PacketSendPackets"); + return 0; + } +#endif // HAVE_WANPACKET_API + +#ifdef HAVE_NPFIM_API + if(AdapterObject->Flags == INFO_FLAG_NPFIM_DEVICE) + { + TRACE_PRINT("PacketSendPackets: packet sending not allowed on npfim adapters"); + TRACE_EXIT("PacketSendPackets"); + return 0; + } +#endif // HAVE_NPFIM_API + +#ifdef HAVE_AIRPCAP_API + if(AdapterObject->Flags == INFO_FLAG_AIRPCAP_CARD) + { + TRACE_PRINT("PacketSendPackets: packet sending not allowed on airpcap adapters"); + TRACE_EXIT("PacketSendPackets"); + return 0; + } +#endif // HAVE_AIRPCAP_API + + if (AdapterObject->Flags == INFO_FLAG_NDIS_ADAPTER) + { + // Obtain starting timestamp of the buffer + BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec; + BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec; + + // Retrieve the reference time counters + QueryPerformanceCounter(&StartTicks); + QueryPerformanceFrequency(&TimeFreq); + + CurTicks.QuadPart = StartTicks.QuadPart; + + do{ + // Send the data to the driver + //TODO Res is NEVER checked, this is REALLY bad. + Res = (BOOLEAN)DeviceIoControl(AdapterObject->hFile, + (Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC, + (PCHAR)PacketBuff + TotBytesTransfered, + Size - TotBytesTransfered, + NULL, + 0, + &BytesTransfered, + NULL); + + TotBytesTransfered += BytesTransfered; + + // Exit from the loop on termination or error + if(TotBytesTransfered >= Size || Res != TRUE) + break; + + // calculate the time interval to wait before sending the next packet + TargetTicks.QuadPart = StartTicks.QuadPart + + (LONGLONG) + ((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 + + (((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) * + (TimeFreq.QuadPart) / 1000000; + + // Wait until the time interval has elapsed + while( CurTicks.QuadPart <= TargetTicks.QuadPart ) + QueryPerformanceCounter(&CurTicks); + + } + while(TRUE); + } + else + { + TRACE_PRINT1("Request to write on an unknown device type (%u)", AdapterObject->Flags); + TotBytesTransfered = 0; + } + + TRACE_EXIT("PacketSendPackets"); + + return TotBytesTransfered; +} + +/*! + \brief Defines the minimum amount of data that will be received in a read. + \param AdapterObject Pointer to an _ADAPTER structure + \param nbytes the minimum amount of data in the kernel buffer that will cause the driver to + release a read on this adapter. + \return If the function succeeds, the return value is nonzero. + + In presence of a large value for nbytes, the kernel waits for the arrival of several packets before + copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage, + i.e. better performance, which is a good setting for applications like sniffers. Vice versa, a small value + means that the kernel will copy the packets as soon as the application is ready to receive them. This is + suggested for real time applications (like, for example, a bridge) that need the better responsiveness from + the kernel. + + \b note: this function has effect only in Windows NTx. The driver for Windows 9x doesn't offer + this possibility, therefore PacketSetMinToCopy is implemented under these systems only for compatibility. +*/ + +BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes) +{ + DWORD BytesReturned; + BOOLEAN Result; + TRACE_ENTER("PacketSetMinToCopy"); + +#ifdef HAVE_WANPACKET_API + if (AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) + { + Result = WanPacketSetMinToCopy(AdapterObject->pWanAdapter, nbytes); + TRACE_EXIT("PacketSetMinToCopy"); + + return Result; + } +#endif //HAVE_WANPACKET_API + +#ifdef HAVE_NPFIM_API + if(AdapterObject->Flags == INFO_FLAG_NPFIM_DEVICE) + { + Result = (BOOLEAN)g_NpfImHandlers.NpfImSetMinToCopy(AdapterObject->NpfImHandle, nbytes); + TRACE_EXIT("PacketSetMinToCopy"); + + return Result; + } +#endif // HAVE_NPFIM_API + +#ifdef HAVE_AIRPCAP_API + if(AdapterObject->Flags == INFO_FLAG_AIRPCAP_CARD) + { + Result = (BOOLEAN)g_PAirpcapSetMinToCopy(AdapterObject->AirpcapAd, nbytes); + TRACE_EXIT("PacketSetMinToCopy"); + + return Result; + } +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_DAG_API + if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) + { + TRACE_EXIT("PacketSetMinToCopy"); + // No mintocopy with DAGs + return TRUE; + } +#endif // HAVE_DAG_API + + if (AdapterObject->Flags == INFO_FLAG_NDIS_ADAPTER) + { + Result = (BOOLEAN)DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL); + } + else + { + TRACE_PRINT1("Request to set mintocopy on an unknown device type (%u)", AdapterObject->Flags); + Result = FALSE; + } + + TRACE_EXIT("PacketSetMinToCopy"); + + return Result; +} + +/*! + \brief Sets the working mode of an adapter. + \param AdapterObject Pointer to an _ADAPTER structure. + \param mode The new working mode of the adapter. + \return If the function succeeds, the return value is nonzero. + + The device driver of WinPcap has 4 working modes: + - Capture mode (mode = PACKET_MODE_CAPT): normal capture mode. The packets transiting on the wire are copied + to the application when PacketReceivePacket() is called. This is the default working mode of an adapter. + - Statistical mode (mode = PACKET_MODE_STAT): programmable statistical mode. PacketReceivePacket() returns, at + precise intervals, statics values on the network traffic. The interval between the statistic samples is + by default 1 second but it can be set to any other value (with a 1 ms precision) with the + PacketSetReadTimeout() function. The data returned by PacketReceivePacket() when the adapter is in statistical + mode is shown in the following figure:

+ \image html stats.gif "data structure returned by statistical mode" + Two 64-bit counters are provided: the number of packets and the amount of bytes that satisfy a filter + previously set with PacketSetBPF(). If no filter has been set, all the packets are counted. The counters are + encapsulated in a bpf_hdr structure, so that they will be parsed correctly by wpcap. Statistical mode has a + very low impact on system performance compared to capture mode. + - Dump mode (mode = PACKET_MODE_DUMP): the packets are dumped to disk by the driver, in libpcap format. This + method is much faster than saving the packets after having captured them. No data is returned + by PacketReceivePacket(). If the application sets a filter with PacketSetBPF(), only the packets that satisfy + this filter are dumped to disk. + - Statitical Dump mode (mode = PACKET_MODE_STAT_DUMP): the packets are dumped to disk by the driver, in libpcap + format, like in dump mode. PacketReceivePacket() returns, at precise intervals, statics values on the + network traffic and on the amount of data saved to file, in a way similar to statistical mode. + The data returned by PacketReceivePacket() when the adapter is in statistical dump mode is shown in + the following figure:

+ \image html dump.gif "data structure returned by statistical dump mode" + Three 64-bit counters are provided: the number of packets accepted, the amount of bytes accepted and the + effective amount of data (including headers) dumped to file. If no filter has been set, all the packets are + dumped to disk. The counters are encapsulated in a bpf_hdr structure, so that they will be parsed correctly + by wpcap. + Look at the NetMeter example in the + WinPcap developer's pack to see how to use statistics mode. +*/ +BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode) +{ + DWORD BytesReturned; + BOOLEAN Result; + + TRACE_ENTER("PacketSetMode"); + +#ifdef HAVE_WANPACKET_API + if (AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) + { + Result = WanPacketSetMode(AdapterObject->pWanAdapter, mode); + TRACE_EXIT("PacketSetMode"); + + return Result; + } +#endif // HAVE_WANPACKET_API + +#ifdef HAVE_AIRPCAP_API + if (AdapterObject->Flags == INFO_FLAG_AIRPCAP_CARD) + { + if (mode == PACKET_MODE_CAPT) + { + Result = TRUE; + } + else + { + Result = FALSE; + } + + TRACE_EXIT("PacketSetMode"); + + return Result; + } +#endif //HAVE_AIRPCAP_API + +#ifdef HAVE_NPFIM_API + if (AdapterObject->Flags == INFO_FLAG_NPFIM_DEVICE) + { + if (mode == PACKET_MODE_CAPT) + { + Result = TRUE; + } + else + { + Result = FALSE; + } + + TRACE_EXIT("PacketSetMode"); + + return Result; + } +#endif //HAVE_NPFIM_API + + if (AdapterObject->Flags == INFO_FLAG_NDIS_ADAPTER) + { + Result = (BOOLEAN)DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL); + } + else + { + TRACE_PRINT1("Request to set mode on an unknown device type (%u)", AdapterObject->Flags); + Result = FALSE; + } + + TRACE_EXIT("PacketSetMode"); + + return Result; + +} + +/*! + \brief Sets the name of the file that will receive the packet when the adapter is in dump mode. + \param AdapterObject Pointer to an _ADAPTER structure. + \param name the file name, in ASCII or UNICODE. + \param len the length of the buffer containing the name, in bytes. + \return If the function succeeds, the return value is nonzero. + + This function defines the file name that the driver will open to store the packets on disk when + it works in dump mode. The adapter must be in dump mode, i.e. PacketSetMode() should have been + called previously with mode = PACKET_MODE_DUMP. otherwise this function will fail. + If PacketSetDumpName was already invoked on the adapter pointed by AdapterObject, the driver + closes the old file and opens the new one. +*/ + +BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len) +{ + DWORD BytesReturned; + WCHAR *FileName; + BOOLEAN res; + WCHAR NameWithPath[1024]; + int TStrLen; + WCHAR *NamePos; + + TRACE_ENTER("PacketSetDumpName"); + + if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) + { + TRACE_PRINT("PacketSetDumpName: not allowed on non-NPF adapters"); + TRACE_EXIT("PacketSetDumpName"); + return FALSE; + } + + if(((PUCHAR)name)[1]!=0 && len>1){ //ASCII + FileName=SChar2WChar(name); + len*=2; + } + else { //Unicode + FileName=name; + } + + TStrLen=GetFullPathName(FileName,1024,NameWithPath,&NamePos); + + len=TStrLen*2+2; //add the terminating null character + + // Try to catch malformed strings + if(len>2048){ + if(((PUCHAR)name)[1]!=0 && len>1) free(FileName); + + TRACE_EXIT("PacketSetDumpName"); + + return FALSE; + } + + res = (BOOLEAN)DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL); + free(FileName); + + TRACE_EXIT("PacketSetDumpName"); + return res; +} + +/* + \brief Set the dump mode limits. + \param AdapterObject Pointer to an _ADAPTER structure. + \param maxfilesize The maximum dimension of the dump file, in bytes. 0 means no limit. + \param maxnpacks The maximum number of packets contained in the dump file. 0 means no limit. + \return If the function succeeds, the return value is nonzero. + + This function sets the limits after which the NPF driver stops to save the packets to file when an adapter + is in dump mode. This allows to limit the dump file to a precise number of bytes or packets, avoiding that + very long dumps fill the disk space. If both maxfilesize and maxnpacks are set, the dump is stopped when + the first of the two is reached. + + \note When a limit is reached, the dump is stopped, but the file remains opened. In order to flush + correctly the data and access the file consistently, you need to close the adapter with PacketCloseAdapter(). +*/ +BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks) +{ + DWORD BytesReturned; + UINT valbuff[2]; + BOOLEAN Result; + + TRACE_ENTER("PacketSetDumpLimits"); + + if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) + { + TRACE_PRINT("PacketSetDumpLimits: not allowed on non-NPF adapters"); + TRACE_EXIT("PacketSetDumpLimits"); + return FALSE; + } + + valbuff[0] = maxfilesize; + valbuff[1] = maxnpacks; + + Result = (BOOLEAN)DeviceIoControl(AdapterObject->hFile, + pBIOCSETDUMPLIMITS, + valbuff, + sizeof valbuff, + NULL, + 0, + &BytesReturned, + NULL); + + TRACE_EXIT("PacketSetDumpLimits"); + + return Result; + +} + +/*! + \brief Returns the status of the kernel dump process, i.e. tells if one of the limits defined with PacketSetDumpLimits() was reached. + \param AdapterObject Pointer to an _ADAPTER structure. + \param sync if TRUE, the function blocks until the dump is finished, otherwise it returns immediately. + \return TRUE if the dump is ended, FALSE otherwise. + + PacketIsDumpEnded() informs the user about the limits that were set with a previous call to + PacketSetDumpLimits(). + + \warning If no calls to PacketSetDumpLimits() were performed or if the dump process has no limits + (i.e. if the arguments of the last call to PacketSetDumpLimits() were both 0), setting sync to TRUE will + block the application on this call forever. +*/ +BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync) +{ + DWORD BytesReturned; + int IsDumpEnded; + BOOLEAN res; + + TRACE_ENTER("PacketIsDumpEnded"); + + if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) + { + TRACE_PRINT("PacketIsDumpEnded: not allowed on non-NPF adapters"); + + TRACE_EXIT("PacketIsDumpEnded"); + + return FALSE; + } + + if(sync) + WaitForSingleObject(AdapterObject->ReadEvent, INFINITE); + + res = (BOOLEAN)DeviceIoControl(AdapterObject->hFile, + pBIOCISDUMPENDED, + NULL, + 0, + &IsDumpEnded, + 4, + &BytesReturned, + NULL); + + TRACE_EXIT("PacketIsDumpEnded"); + + if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished + + return (BOOLEAN)IsDumpEnded; +} + +/*! + \brief Returns the notification event associated with the read calls on an adapter. + \param AdapterObject Pointer to an _ADAPTER structure. + \return The handle of the event that the driver signals when some data is available in the kernel buffer. + + The event returned by this function is signaled by the driver if: + - The adapter pointed by AdapterObject is in capture mode and an amount of data greater or equal + than the one set with the PacketSetMinToCopy() function is received from the network. + - the adapter pointed by AdapterObject is in capture mode, no data has been received from the network + but the the timeout set with the PacketSetReadTimeout() function has elapsed. + - the adapter pointed by AdapterObject is in statics mode and the the timeout set with the + PacketSetReadTimeout() function has elapsed. This means that a new statistic sample is available. + + In every case, a call to PacketReceivePacket() will return immediately. + The event can be passed to standard Win32 functions (like WaitForSingleObject or WaitForMultipleObjects) + to wait until the driver's buffer contains some data. It is particularly useful in GUI applications that + need to wait concurrently on several events. + +*/ +HANDLE PacketGetReadEvent(LPADAPTER AdapterObject) +{ + TRACE_ENTER("PacketGetReadEvent"); + TRACE_EXIT("PacketGetReadEvent"); + return AdapterObject->ReadEvent; +} + +/*! + \brief Sets the number of times a single packet written with PacketSendPacket() will be repeated on the network. + \param AdapterObject Pointer to an _ADAPTER structure. + \param nwrites Number of copies of a packet that will be physically sent by the interface. + \return If the function succeeds, the return value is nonzero. + + See PacketSendPacket() for details. +*/ +BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites) +{ + DWORD BytesReturned; + BOOLEAN Result; + + TRACE_ENTER("PacketSetNumWrites"); + + if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) + { + TRACE_PRINT("PacketSetNumWrites: not allowed on non-NPF adapters"); + TRACE_EXIT("PacketSetNumWrites"); + return FALSE; + } + + Result = (BOOLEAN)DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL); + + TRACE_EXIT("PacketSetNumWrites"); + + return Result; +} + +/*! + \brief Sets the timeout after which a read on an adapter returns. + \param AdapterObject Pointer to an _ADAPTER structure. + \param timeout indicates the timeout, in milliseconds, after which a call to PacketReceivePacket() on + the adapter pointed by AdapterObject will be released, also if no packets have been captured by the driver. + Setting timeout to 0 means no timeout, i.e. PacketReceivePacket() never returns if no packet arrives. + A timeout of -1 causes PacketReceivePacket() to always return immediately. + \return If the function succeeds, the return value is nonzero. + + \note This function works also if the adapter is working in statistics mode, and can be used to set the + time interval between two statistic reports. +*/ +BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout) +{ + BOOLEAN Result; + + TRACE_ENTER("PacketSetReadTimeout"); + + AdapterObject->ReadTimeOut = timeout; + +#ifdef HAVE_WANPACKET_API + if (AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) + { + Result = WanPacketSetReadTimeout(AdapterObject->pWanAdapter,timeout); + + TRACE_EXIT("PacketSetReadTimeout"); + + return Result; + } +#endif // HAVE_WANPACKET_API + +#ifdef HAVE_NPFIM_API + if (AdapterObject->Flags == INFO_FLAG_NPFIM_DEVICE) + { + // + // convert the timestamps to Windows like format (0 = immediate, -1(INFINITE) = infinite) + // + if (timeout == -1) timeout = 0; + else if (timeout == 0) timeout = INFINITE; + + Result = (BOOLEAN)g_NpfImHandlers.NpfImSetReadTimeout(AdapterObject->NpfImHandle, timeout); + TRACE_EXIT("PacketSetReadTimeout"); + return Result; + } +#endif // HAVE_NPFIM_API + +#ifdef HAVE_AIRPCAP_API + // + // Timeout with AirPcap is handled at user level + // + if(AdapterObject->Flags == INFO_FLAG_AIRPCAP_CARD) + { + TRACE_EXIT("PacketSetReadTimeout"); + return TRUE; + } +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_DAG_API + // Under DAG, we simply store the timeout value and then + if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) + { + if(timeout == -1) + { + // tell DAG card to return immediately + AdapterObject->DagReadTimeout.tv_sec = 0; + AdapterObject->DagReadTimeout.tv_usec = 0; + } + else + { + if(timeout == 0) + { + // tell the DAG card to wait forvever + AdapterObject->DagReadTimeout.tv_sec = -1; + AdapterObject->DagReadTimeout.tv_usec = -1; + } + else + { + // Set the timeout for the DAG card + AdapterObject->DagReadTimeout.tv_sec = timeout / 1000; + AdapterObject->DagReadTimeout.tv_usec = (timeout * 1000) % 1000000; + } + } + + TRACE_EXIT("PacketSetReadTimeout"); + return TRUE; + } +#endif // HAVE_DAG_API + + if(AdapterObject->Flags == INFO_FLAG_NDIS_ADAPTER) + { + Result = TRUE; + } + else + { + // + // if we are here, it's an unsupported ADAPTER type! + // + TRACE_PRINT1("Request to set read timeout on an unknown device type (%u)", AdapterObject->Flags); + Result = FALSE; + } + + TRACE_EXIT("PacketSetReadTimeout"); + return Result; + +} + +/*! + \brief Sets the size of the kernel-level buffer associated with a capture. + \param AdapterObject Pointer to an _ADAPTER structure. + \param dim New size of the buffer, in \b kilobytes. + \return The function returns TRUE if successfully completed, FALSE if there is not enough memory to + allocate the new buffer. + + When a new dimension is set, the data in the old buffer is discarded and the packets stored in it are + lost. + + Note: the dimension of the kernel buffer affects heavily the performances of the capture process. + An adequate buffer in the driver is able to keep the packets while the application is busy, compensating + the delays of the application and avoiding the loss of packets during bursts or high network activity. + The buffer size is set to 0 when an instance of the driver is opened: the programmer should remember to + set it to a proper value. As an example, wpcap sets the buffer size to 1MB at the beginning of a capture. +*/ +BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim) +{ + DWORD BytesReturned; + BOOLEAN Result; + + TRACE_ENTER("PacketSetBuff"); + +#ifdef HAVE_WANPACKET_API + if (AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) + { + Result = WanPacketSetBufferSize(AdapterObject->pWanAdapter, dim); + + TRACE_EXIT("PacketSetBuff"); + return Result; + } +#endif + +#ifdef HAVE_AIRPCAP_API + if(AdapterObject->Flags == INFO_FLAG_AIRPCAP_CARD) + { + Result = (BOOLEAN)g_PAirpcapSetKernelBuffer(AdapterObject->AirpcapAd, dim); + + TRACE_EXIT("PacketSetBuff"); + return Result; + } +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_NPFIM_API + if(AdapterObject->Flags == INFO_FLAG_NPFIM_DEVICE) + { + Result = (BOOLEAN)g_NpfImHandlers.NpfImSetCaptureBufferSize(AdapterObject->NpfImHandle, dim); + + TRACE_EXIT("PacketSetBuff"); + return Result; + } +#endif // HAVE_NPFIM_API + +#ifdef HAVE_DAG_API + if(AdapterObject->Flags == INFO_FLAG_DAG_CARD) + { + // We can't change DAG buffers + TRACE_EXIT("PacketSetBuff"); + return TRUE; + } +#endif // HAVE_DAG_API + + if (AdapterObject->Flags == INFO_FLAG_NDIS_ADAPTER) + { + Result = (BOOLEAN)DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,sizeof(dim),NULL,0,&BytesReturned,NULL); + } + else + { + TRACE_PRINT1("Request to set buf size on an unknown device type (%u)", AdapterObject->Flags); + Result = FALSE; + } + + TRACE_EXIT("PacketSetBuff"); + + return Result; +} + +/*! + \brief Sets a kernel-level packet filter. + \param AdapterObject Pointer to an _ADAPTER structure. + \param fp Pointer to a filtering program that will be associated with this capture or monitoring + instance and that will be executed on every incoming packet. + \return This function returns TRUE if the filter is set successfully, FALSE if an error occurs + or if the filter program is not accepted after a safeness check by the driver. The driver performs + the check in order to avoid system crashes due to buggy or malicious filters, and it rejects non + conformat filters. + + This function associates a new BPF filter to the adapter AdapterObject. The filter, pointed by fp, is a + set of bpf_insn instructions. + + A filter can be automatically created by using the pcap_compile() function of wpcap. This function + converts a human readable text expression with the tcpdump/libpcap syntax (see the manual of WinDump at + http://www.winpcap.org/windump for details) into a BPF program. If your program doesn't link wpcap, but + you need to know the code of a particular filter, you can run WinDump with the -d or -dd or -ddd + flags to obtain the pseudocode. + +*/ +BOOLEAN PacketSetBpf(LPADAPTER AdapterObject, struct bpf_program *fp) +{ + DWORD BytesReturned; + BOOLEAN Result; + + TRACE_ENTER("PacketSetBpf"); + +#ifdef HAVE_WANPACKET_API + if (AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) + { + Result = WanPacketSetBpfFilter(AdapterObject->pWanAdapter, (PUCHAR)fp->bf_insns, fp->bf_len * sizeof(struct bpf_insn)); + TRACE_EXIT("PacketSetBpf"); + return Result; + } +#endif + +#ifdef HAVE_AIRPCAP_API + if(AdapterObject->Flags == INFO_FLAG_AIRPCAP_CARD) + { + Result = (BOOLEAN)g_PAirpcapSetFilter(AdapterObject->AirpcapAd, + (char*)fp->bf_insns, + fp->bf_len * sizeof(struct bpf_insn)); + + TRACE_EXIT("PacketSetBpf"); + return Result; + } +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_NPFIM_API + if(AdapterObject->Flags == INFO_FLAG_NPFIM_DEVICE) + { + Result = (BOOLEAN)g_NpfImHandlers.NpfImSetBpfFilter(AdapterObject->NpfImHandle, + fp->bf_insns, + fp->bf_len * sizeof(struct bpf_insn)); + + TRACE_EXIT("PacketSetBpf"); + return TRUE; + } +#endif // HAVE_NPFIM_API + +#ifdef HAVE_DAG_API + if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) + { + // Delegate the filtering to higher layers since it's too expensive here + TRACE_EXIT("PacketSetBpf"); + return TRUE; + } +#endif // HAVE_DAG_API + + if (AdapterObject->Flags == INFO_FLAG_NDIS_ADAPTER) + { + Result = (BOOLEAN)DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL); + } + else + { + TRACE_PRINT1("Request to set BPF filter on an unknown device type (%u)", AdapterObject->Flags); + Result = FALSE; + } + + TRACE_EXIT("PacketSetBpf"); + + return Result; +} + +/*! + \brief Sets the behavior of the NPF driver with packets sent by itself: capture or drop. + \param AdapterObject Pointer to an _ADAPTER structure. + \param LoopbackBehavior Can be one of the following: + - \ref NPF_ENABLE_LOOPBACK + - \ref NPF_DISABLE_LOOPBACK + \return If the function succeeds, the return value is nonzero. + + \note: when opened, adapters have loopback capture \b enabled. +*/ +BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior) +{ + DWORD BytesReturned; + BOOLEAN result; + + TRACE_ENTER("PacketSetLoopbackBehavior"); + + if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) + { + TRACE_PRINT("PacketSetLoopbackBehavior: not allowed on non-NPF adapters"); + + TRACE_EXIT("PacketSetLoopbackBehavior"); + + return FALSE; + } + + + result = (BOOLEAN)DeviceIoControl(AdapterObject->hFile, + pBIOCISETLOBBEH, + &LoopbackBehavior, + sizeof(UINT), + NULL, + 0, + &BytesReturned, + NULL); + + TRACE_EXIT("PacketSetLoopbackBehavior"); + + return result; +} + +/*! + \brief Sets the snap len on the adapters that allow it. + \param AdapterObject Pointer to an _ADAPTER structure. + \param snaplen Desired snap len for this capture. + \return If the function succeeds, the return value is nonzero and specifies the actual snaplen that + the card is using. If the function fails or if the card does't allow to set sna length, the return + value is 0. + + The snap len is the amount of packet that is actually captured by the interface and received by the + application. Some interfaces allow to capture only a portion of any packet for performance reasons. + + \note: the return value can be different from the snaplen parameter, for example some boards round the + snaplen to 4 bytes. +*/ +INT PacketSetSnapLen(LPADAPTER AdapterObject, int snaplen) +{ + INT Result; + + TRACE_ENTER("PacketSetSnapLen"); + + UNUSED(snaplen); + UNUSED(AdapterObject); + +#ifdef HAVE_DAG_API + if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) + Result = g_p_dagc_setsnaplen(AdapterObject->pDagCard, snaplen); + else +#endif // HAVE_DAG_API + Result = 0; + + TRACE_EXIT("PacketSetSnapLen"); + + return Result; + +} + +/*! + \brief Returns a couple of statistic values about the current capture session. + \param AdapterObject Pointer to an _ADAPTER structure. + \param s Pointer to a user provided bpf_stat structure that will be filled by the function. + \return If the function succeeds, the return value is nonzero. + + With this function, the programmer can know the value of two internal variables of the driver: + + - the number of packets that have been received by the adapter AdapterObject, starting at the + time in which it was opened with PacketOpenAdapter. + - the number of packets that have been dropped by the driver. A packet is dropped when the kernel + buffer associated with the adapter is full. +*/ +BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s) +{ + BOOLEAN Res; + DWORD BytesReturned; + struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications + + TRACE_ENTER("PacketGetStats"); + +#ifdef HAVE_AIRPCAP_API + if(AdapterObject->Flags == INFO_FLAG_AIRPCAP_CARD) + { + AirpcapStats tas; + + Res = (BOOLEAN)g_PAirpcapGetStats(AdapterObject->AirpcapAd, &tas); + + if (Res) + { + // + // Do NOT write this value. This function is probably called with a small structure, old style, containing only the first three fields recv, drop, ifdrop + // +// s->bs_capt = tas.Capt; + s->bs_drop = tas.Drops; + s->bs_recv = tas.Recvs; + s->ps_ifdrop = tas.IfDrops; + } + + TRACE_EXIT("PacketGetStats"); + return Res; + } +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_NPFIM_API + if(AdapterObject->Flags == INFO_FLAG_NPFIM_DEVICE) + { + ULONGLONG stats[7]; + DWORD neededBytes; + + Res = (BOOLEAN)g_NpfImHandlers.NpfImGetCaptureStatistics(AdapterObject->NpfImHandle, stats, sizeof(stats), &neededBytes); + + if (Res) + { +// if (stats[NPFIM_CAPTURE_STATS_RECEIVED] < 0xFFFFFFFF) +// s->bs_capt = (UINT)stats[NPFIM_CAPTURE_STATS_RECEIVED]; +// else +// s->bs_capt = 0xFFFFFFFF; + + if (stats[NPFIM_CAPTURE_STATS_DROPPED_FILTER] < 0xFFFFFFFF) + s->bs_drop = (UINT)stats[NPFIM_CAPTURE_STATS_DROPPED_FILTER]; + else + s->bs_drop = 0xFFFFFFFF; + + if (stats[NPFIM_CAPTURE_STATS_ACCEPTED] < 0xFFFFFFFF) + s->bs_recv = (UINT)stats[NPFIM_CAPTURE_STATS_ACCEPTED]; + else + s->bs_recv = 0xFFFFFFFF; + + s->ps_ifdrop = 0; + } + + TRACE_EXIT("PacketGetStats"); + return Res; + } +#endif // HAVE_AIRPCAP_API + + +#ifdef HAVE_DAG_API + if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) + { + dagc_stats_t DagStats; + + // Note: DAG cards are currently very limited from the statistics reporting point of view, + // so most of the values returned by dagc_stats() are zero at the moment + if(g_p_dagc_stats(AdapterObject->pDagCard, &DagStats) == 0) + { + // XXX: Only copy the dropped packets for now, since the received counter is not supported by + // DAGS at the moment + + s->bs_recv = (ULONG)DagStats.received; + s->bs_drop = (ULONG)DagStats.dropped; + TRACE_EXIT("PacketGetStats"); + return TRUE; + } + else + { + TRACE_EXIT("PacketGetStats"); + return FALSE; + } + } + +#endif // HAVE_DAG_API + +#ifdef HAVE_WANPACKET_API + if ( AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) + { + Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat); + + // Copy only the first two values retrieved from the driver + s->bs_recv = tmpstat.bs_recv; + s->bs_drop = tmpstat.bs_drop; + + TRACE_EXIT("PacketGetStats"); + + return Res; + } + +#endif // HAVE_WANPACKET_API + + if (AdapterObject->Flags == INFO_FLAG_NDIS_ADAPTER) + { + Res = (BOOLEAN)DeviceIoControl(AdapterObject->hFile, + pBIOCGSTATS, + NULL, + 0, + &tmpstat, + sizeof(struct bpf_stat), + &BytesReturned, + NULL); + + + if (Res) + { + // Copy only the first two values retrieved from the driver + s->bs_recv = tmpstat.bs_recv; + s->bs_drop = tmpstat.bs_drop; + } + + } + else + { + TRACE_PRINT1("Request to obtain statistics on an unknown device type (%u)", AdapterObject->Flags); + Res = FALSE; + } + TRACE_EXIT("PacketGetStats"); + return Res; + +} + +/*! + \brief Returns statistic values about the current capture session. Enhanced version of PacketGetStats(). + \param AdapterObject Pointer to an _ADAPTER structure. + \param s Pointer to a user provided bpf_stat structure that will be filled by the function. + \return If the function succeeds, the return value is nonzero. + + With this function, the programmer can retireve the sname values provided by PacketGetStats(), plus: + + - the number of drops by interface (not yet supported, always 0). + - the number of packets that reached the application, i.e that were accepted by the kernel filter and + that fitted in the kernel buffer. +*/ +BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s) +{ + BOOLEAN Res; + DWORD BytesReturned; + struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications + + TRACE_ENTER("PacketGetStatsEx"); + +#ifdef HAVE_DAG_API + if(AdapterObject->Flags == INFO_FLAG_DAG_CARD) + { + dagc_stats_t DagStats; + + // Note: DAG cards are currently very limited from the statistics reporting point of view, + // so most of the values returned by dagc_stats() are zero at the moment + g_p_dagc_stats(AdapterObject->pDagCard, &DagStats); + s->bs_recv = (ULONG)DagStats.received; + s->bs_drop = (ULONG)DagStats.dropped; + s->ps_ifdrop = 0; + s->bs_capt = (ULONG)DagStats.captured; + + TRACE_EXIT("PacketGetStatsEx"); + return TRUE; + + } +#endif // HAVE_DAG_API + +#ifdef HAVE_WANPACKET_API + if(AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) + { + Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat); + TRACE_EXIT("PacketGetStatsEx"); + return Res; + } +#endif // HAVE_WANPACKET_API + +#ifdef HAVE_AIRPCAP_API + if(AdapterObject->Flags == INFO_FLAG_AIRPCAP_CARD) + { + AirpcapStats tas; + + Res = (BOOLEAN)g_PAirpcapGetStats(AdapterObject->AirpcapAd, &tas); + + if (Res) + { + s->bs_capt = tas.Capt; + s->bs_drop = tas.Drops; + s->bs_recv = tas.Recvs; + s->ps_ifdrop = tas.IfDrops; + } + + TRACE_EXIT("PacketGetStatsEx"); + return Res; + } +#endif // HAVE_AIRPCAP_API + + if (AdapterObject->Flags == INFO_FLAG_NDIS_ADAPTER) + { + Res = (BOOLEAN)DeviceIoControl(AdapterObject->hFile, + pBIOCGSTATS, + NULL, + 0, + &tmpstat, + sizeof(struct bpf_stat), + &BytesReturned, + NULL); + + + if (Res) + { + s->bs_recv = tmpstat.bs_recv; + s->bs_drop = tmpstat.bs_drop; + s->ps_ifdrop = tmpstat.ps_ifdrop; + s->bs_capt = tmpstat.bs_capt; + } + } + else + { + TRACE_PRINT1("Request to obtain statistics on an unknown device type (%u)", AdapterObject->Flags); + Res = FALSE; + } + TRACE_EXIT("PacketGetStatsEx"); + return Res; + +} + +/*! + \brief Performs a query/set operation on an internal variable of the network card driver. + \param AdapterObject Pointer to an _ADAPTER structure. + \param Set Determines if the operation is a set (Set=TRUE) or a query (Set=FALSE). + \param OidData A pointer to a _PACKET_OID_DATA structure that contains or receives the data. + \return If the function succeeds, the return value is nonzero. + + \note not all the network adapters implement all the query/set functions. There is a set of mandatory + OID functions that is granted to be present on all the adapters, and a set of facultative functions, not + provided by all the cards (see the Microsoft DDKs to see which functions are mandatory). If you use a + facultative function, be careful to enclose it in an if statement to check the result. +*/ +BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData) +{ + DWORD BytesReturned; + BOOLEAN Result; + + TRACE_ENTER("PacketRequest"); + +#ifdef HAVE_NPFIM_API + if(AdapterObject->Flags == INFO_FLAG_NPFIM_DEVICE) + { + if (Set) + { + TRACE_PRINT("PacketRequest SET not supported on NPFIM devices"); + TRACE_EXIT("PacketRequest"); + return FALSE; + } + + Result = (BOOLEAN)g_NpfImHandlers.NpfImIssueQueryOid(AdapterObject->NpfImHandle, + OidData->Oid, + OidData->Data, + &OidData->Length); + + TRACE_EXIT("PacketRequest"); + return Result; + } +#endif + + if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) + { + TRACE_PRINT("PacketRequest not supported on non-NPF/NPFIM adapters."); + TRACE_EXIT("PacketRequest"); + return FALSE; + } + + Result=(BOOLEAN)DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? (DWORD)pBIOCSETOID : (DWORD)pBIOCQUERYOID, + OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData, + sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL); + + // output some debug info + TRACE_PRINT4("PacketRequest, OID=%.08x Length=%.05d Set=%.04d Res=%.04d", + OidData->Oid, + OidData->Length, + Set, + Result); + + TRACE_EXIT("PacketRequest"); + return Result; +} + +/*! + \brief Sets a hardware filter on the incoming packets. + \param AdapterObject Pointer to an _ADAPTER structure. + \param Filter The identifier of the filter. + \return If the function succeeds, the return value is nonzero. + + The filter defined with this filter is evaluated by the network card, at a level that is under the NPF + device driver. Here is a list of the most useful hardware filters (A complete list can be found in ntddndis.h): + + - NDIS_PACKET_TYPE_PROMISCUOUS: sets promiscuous mode. Every incoming packet is accepted by the adapter. + - NDIS_PACKET_TYPE_DIRECTED: only packets directed to the workstation's adapter are accepted. + - NDIS_PACKET_TYPE_BROADCAST: only broadcast packets are accepted. + - NDIS_PACKET_TYPE_MULTICAST: only multicast packets belonging to groups of which this adapter is a member are accepted. + - NDIS_PACKET_TYPE_ALL_MULTICAST: every multicast packet is accepted. + - NDIS_PACKET_TYPE_ALL_LOCAL: all local packets, i.e. NDIS_PACKET_TYPE_DIRECTED + NDIS_PACKET_TYPE_BROADCAST + NDIS_PACKET_TYPE_MULTICAST +*/ +BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter) +{ + BOOLEAN Status; + ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); + PPACKET_OID_DATA OidData; + + TRACE_ENTER("PacketSetHwFilter"); + +#ifdef HAVE_AIRPCAP_API + if(AdapterObject->Flags == INFO_FLAG_AIRPCAP_CARD) + { + // Airpcap for the moment is always in promiscuous mode, and ignores any other filters + return TRUE; + } +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_NPFIM_API + if(AdapterObject->Flags == INFO_FLAG_NPFIM_DEVICE) + { + return TRUE; + } +#endif // HAVE_NPFIM_API + +#ifdef HAVE_WANPACKET_API + if(AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) + { + TRACE_EXIT("PacketSetHwFilter"); + return TRUE; + } +#endif // HAVE_WANPACKET_API + + if (AdapterObject->Flags == INFO_FLAG_NDIS_ADAPTER) + { + OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); + if (OidData == NULL) { + TRACE_PRINT("PacketSetHwFilter: GlobalAlloc Failed"); + TRACE_EXIT("PacketSetHwFilter"); + return FALSE; + } + OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER; + OidData->Length=sizeof(ULONG); + *((PULONG)OidData->Data)=Filter; + Status=PacketRequest(AdapterObject,TRUE,OidData); + GlobalFreePtr(OidData); + } + else + { + TRACE_PRINT1("Setting HW filter not supported on this adapter type (%u)", AdapterObject->Flags); + Status = FALSE; + } + + TRACE_EXIT("PacketSetHwFilter"); + return Status; +} + +/*! + \brief Retrieve the list of available network adapters and their description. + \param pStr User allocated string that will be filled with the names of the adapters. + \param BufferSize Length of the buffer pointed by pStr. If the function fails, this variable contains the + number of bytes that are needed to contain the adapter list. + \return If the function succeeds, the return value is nonzero. If the return value is zero, BufferSize contains + the number of bytes that are needed to contain the adapter list. + + Usually, this is the first function that should be used to communicate with the driver. + It returns the names of the adapters installed on the system and supported by WinPcap. + After the names of the adapters, pStr contains a string that describes each of them. + + After a call to PacketGetAdapterNames pStr contains, in succession: + - a variable number of ASCII strings, each with the names of an adapter, separated by a "\0" + - a double "\0" + - a number of ASCII strings, each with the description of an adapter, separated by a "\0". The number + of descriptions is the same of the one of names. The fisrt description corresponds to the first name, and + so on. + - a double "\0". +*/ + +BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize) +{ + PADAPTER_INFO TAdInfo; + ULONG SizeNeeded = 0; + ULONG SizeNames = 0; + ULONG SizeDesc; + ULONG OffDescriptions; + + TRACE_ENTER("PacketGetAdapterNames"); + + TRACE_PRINT_OS_INFO(); + + TRACE_PRINT2("Packet DLL version %s, Driver version %s", PacketLibraryVersion, PacketDriverVersion); + + TRACE_PRINT1("PacketGetAdapterNames: BufferSize=%u", *BufferSize); + + + // + // Check the presence on some libraries we rely on, and load them if we found them + //f + PacketLoadLibrariesDynamically(); + + //d + // Create the adapter information list + // + TRACE_PRINT("Populating the adapter list..."); + + PacketPopulateAdaptersInfoList(); + + WaitForSingleObject(g_AdaptersInfoMutex, INFINITE); + + if(!g_AdaptersInfoList) + { + ReleaseMutex(g_AdaptersInfoMutex); + *BufferSize = 0; + + TRACE_PRINT("No adapters found in the system. Failing."); + + SetLastError(ERROR_INSUFFICIENT_BUFFER); + + TRACE_EXIT("PacketGetAdapterNames"); + return FALSE; // No adapters to return + } + + // + // First scan of the list to calculate the offsets and check the sizes + // + for(TAdInfo = g_AdaptersInfoList; TAdInfo != NULL; TAdInfo = TAdInfo->Next) + { + if(TAdInfo->Flags != INFO_FLAG_DONT_EXPORT) + { + // Update the size variables + SizeNeeded += (ULONG)strlen(TAdInfo->Name) + (ULONG)strlen(TAdInfo->Description) + 2; + SizeNames += (ULONG)strlen(TAdInfo->Name) + 1; + } + } + + // Check that we don't overflow the buffer. + // Note: 2 is the number of additional separators needed inside the list + if(SizeNeeded + 2 > *BufferSize || pStr == NULL) + { + ReleaseMutex(g_AdaptersInfoMutex); + + TRACE_PRINT1("PacketGetAdapterNames: input buffer too small, we need %u bytes", *BufferSize); + + *BufferSize = SizeNeeded + 2; // Report the required size + + TRACE_EXIT("PacketGetAdapterNames"); + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + + OffDescriptions = SizeNames + 1; + + // + // Second scan of the list to copy the information + // + for(TAdInfo = g_AdaptersInfoList, SizeNames = 0, SizeDesc = 0; TAdInfo != NULL; TAdInfo = TAdInfo->Next) + { + if(TAdInfo->Flags != INFO_FLAG_DONT_EXPORT) + { + // Copy the data + StringCchCopyA( + ((PCHAR)pStr) + SizeNames, + *BufferSize - SizeNames, + TAdInfo->Name); + StringCchCopyA( + ((PCHAR)pStr) + OffDescriptions + SizeDesc, + *BufferSize - OffDescriptions - SizeDesc, + TAdInfo->Description); + + // Update the size variables + SizeNames += (ULONG)strlen(TAdInfo->Name) + 1; + SizeDesc += (ULONG)strlen(TAdInfo->Description) + 1; + } + } + + // Separate the two lists + ((PCHAR)pStr)[SizeNames] = 0; + + // End the list with a further \0 + ((PCHAR)pStr)[SizeNeeded + 1] = 0; + + + ReleaseMutex(g_AdaptersInfoMutex); + TRACE_EXIT("PacketGetAdapterNames"); + return TRUE; +} + +/*! + \brief Returns comprehensive information the addresses of an adapter. + \param AdapterName String that contains the name of the adapter. + \param buffer A user allocated array of npf_if_addr that will be filled by the function. + \param NEntries Size of the array (in npf_if_addr). + \return If the function succeeds, the return value is nonzero. + + This function grabs from the registry information like the IP addresses, the netmasks + and the broadcast addresses of an interface. The buffer passed by the user is filled with + npf_if_addr structures, each of which contains the data for a single address. If the buffer + is full, the reaming addresses are dropeed, therefore set its dimension to sizeof(npf_if_addr) + if you want only the first address. +*/ +BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries) +{ + PADAPTER_INFO TAdInfo; + PCHAR Tname; + BOOLEAN Res, FreeBuff; + + TRACE_ENTER("PacketGetNetInfoEx"); + + // Provide conversion for backward compatibility + if(AdapterName[1] != 0) + { //ASCII + Tname = AdapterName; + FreeBuff = FALSE; + } + else + { + Tname = WChar2SChar((PWCHAR)AdapterName); + FreeBuff = TRUE; + } + + // + // Update the information about this adapter + // + if(!PacketUpdateAdInfo(Tname)) + { + TRACE_PRINT("PacketGetNetInfoEx. Failed updating the adapter list. Failing."); + if(FreeBuff) + GlobalFreePtr(Tname); + + TRACE_EXIT("PacketGetNetInfoEx"); + + return FALSE; + } + + WaitForSingleObject(g_AdaptersInfoMutex, INFINITE); + // Find the PADAPTER_INFO structure associated with this adapter + TAdInfo = PacketFindAdInfo(Tname); + + if(TAdInfo != NULL) + { + TRACE_PRINT("Adapter found."); + *NEntries = (TAdInfo->NNetworkAddresses < *NEntries)? TAdInfo->NNetworkAddresses: *NEntries; + //TODO what if nentries = 0? + if (*NEntries > 0) + memcpy(buffer, TAdInfo->NetworkAddresses, *NEntries * sizeof(npf_if_addr)); + Res = TRUE; + } + else + { + TRACE_PRINT("PacketGetNetInfoEx: Adapter not found"); + Res = FALSE; + } + + ReleaseMutex(g_AdaptersInfoMutex); + + if(FreeBuff)GlobalFreePtr(Tname); + + TRACE_EXIT("PacketGetNetInfoEx"); + return Res; +} + +/*! + \brief Returns information about the MAC type of an adapter. + \param AdapterObject The adapter on which information is needed. + \param type Pointer to a NetType structure that will be filled by the function. + \return If the function succeeds, the return value is nonzero, otherwise the return value is zero. + + This function return the link layer and the speed (in bps) of an opened adapter. + The LinkType field of the type parameter can have one of the following values: + + - NdisMedium802_3: Ethernet (802.3) + - NdisMediumWan: WAN + - NdisMedium802_5: Token Ring (802.5) + - NdisMediumFddi: FDDI + - NdisMediumAtm: ATM + - NdisMediumArcnet878_2: ARCNET (878.2) +*/ +BOOLEAN PacketGetNetType(LPADAPTER AdapterObject, NetType *type) +{ + PADAPTER_INFO TAdInfo; + BOOLEAN ret; + TRACE_ENTER("PacketGetNetType"); + + WaitForSingleObject(g_AdaptersInfoMutex, INFINITE); + // Find the PADAPTER_INFO structure associated with this adapter + TAdInfo = PacketFindAdInfo(AdapterObject->Name); + + if(TAdInfo != NULL) + { + TRACE_PRINT("Adapter found"); + // Copy the data + memcpy(type, &(TAdInfo->LinkLayer), sizeof(struct NetType)); + ret = TRUE; + } + else + { + TRACE_PRINT("PacketGetNetType: Adapter not found"); + ret = FALSE; + } + + ReleaseMutex(g_AdaptersInfoMutex); + + TRACE_EXIT("PacketGetNetType"); + return ret; +} + +/*! + \brief Returns the AirPcap handler associated with an adapter. This handler can be used to change + the wireless-related settings of the CACE Technologies AirPcap wireless capture adapters. + \param AdapterObject the open adapter whose AirPcap handler is needed. + \return a pointer to an open AirPcap handle, used internally by the adapter pointed by AdapterObject. + NULL if the libpcap adapter doesn't have wireless support through AirPcap. + + PacketGetAirPcapHandle() allows to obtain the airpcap handle of an open adapter. This handle can be used with + the AirPcap API functions to perform wireless-releated operations, e.g. changing the channel or enabling + WEP decryption. For more details about the AirPcap wireless capture adapters, see + http://www.cacetech.com/products/airpcap.htm. +*/ +PAirpcapHandle PacketGetAirPcapHandle(LPADAPTER AdapterObject) +{ + PAirpcapHandle handle = NULL; + TRACE_ENTER("PacketGetAirPcapHandle"); + +#ifdef HAVE_AIRPCAP_API + if (AdapterObject->Flags == INFO_FLAG_AIRPCAP_CARD) + { + handle = AdapterObject->AirpcapAd; + } +#else + UNUSED(AdapterObject); +#endif // HAVE_AIRPCAP_API + + TRACE_EXIT("PacketGetAirPcapHandle"); + return handle; +} + +/* @} */ diff --git a/winpcap/packetNtx/Dll/Project/GNUmakefile b/winpcap/packetNtx/Dll/Project/GNUmakefile new file mode 100644 index 0000000..a85b768 --- /dev/null +++ b/winpcap/packetNtx/Dll/Project/GNUmakefile @@ -0,0 +1,23 @@ +# Makefile for cygwin gcc +# Nate Lawson + +# OPTFLAGS = -g -DDBG +OPTFLAGS = -O -D_WINNT4 +# I am suspicious of -O2 since it hosed wpcap.dll. To be safe, use -O only + +CFLAGS = -I ../../../common -shared -mno-cygwin ${OPTFLAGS} -I.. +LDFLAGS = -Wl,--out-implib,libpacket.a +OBJS = ../Packet32.o ../AdInfo.o +LIBS = -lws2_32 -lversion + +Packet.dll: ${OBJS} + ${CC} ${CFLAGS} ${LDFLAGS} -o Packet.dll ../Packet.def ${OBJS} ${LIBS} + +.c.o: + ${CC} ${CFLAGS} -o $*.o -c $< + +clean: + ${RM} ${OBJS} libpacket.a Packet.dll + +install: Packet.dll + cp Packet.dll c:/winnt/system32 diff --git a/winpcap/packetNtx/Dll/Project/Packet.dsp b/winpcap/packetNtx/Dll/Project/Packet.dsp new file mode 100644 index 0000000..91463f4 --- /dev/null +++ b/winpcap/packetNtx/Dll/Project/Packet.dsp @@ -0,0 +1,590 @@ +# Microsoft Developer Studio Project File - Name="PacketNT" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=PacketNT - Win32 Debug Vista +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Packet.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Packet.mak" CFG="PacketNT - Win32 Debug Vista" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "PacketNT - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 NT4 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 NT4 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 Debug LOG_TO_FILE" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 Release LOG_TO_FILE" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 NT4 Debug LOG_TO_FILE" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 NT4 Release LOG_TO_FILE" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 Debug No AirPcap" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 Release No AirPcap" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 Debug NpfIm" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 Release NpfIm" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 Debug Vista" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 Release Vista" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PacketNT - Win32 Release Vista LOG_TO_FILE" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "PacketNT - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "NDEBUG" /D "HAVE_AIRPCAP_API" /D "WIN32" /D "_WINDOWS" /D "HAVE_IPHELPER_API" /D "HAVE_WANPACKET_API" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 Ws2_32.lib ..\wanpacket\release\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /libpath:"../../../../Airpcap_Devpack/lib/" /opt:ref +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\Release +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "HAVE_AIRPCAP_API" /D "WIN32" /D "_WINDOWS" /D "HAVE_IPHELPER_API" /D "HAVE_WANPACKET_API" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 wsock32.lib ..\wanpacket\debug\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../../Airpcap_Devpack/lib/" +# SUBTRACT LINK32 /pdb:none /incremental:no +# Begin Special Build Tool +OutDir=.\Debug +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 NT4 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "NT4_Debug" +# PROP BASE Intermediate_Dir "NT4_Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "NT4_Debug" +# PROP Intermediate_Dir "NT4_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../common" /D "WIN32" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "WIN32" /D "_WINDOWS" /D "_WINNT4" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /D "_WINNT4" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" /d "_WINNT4" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# SUBTRACT BASE LINK32 /pdb:none /incremental:no +# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../../Airpcap_Devpack/lib/" +# SUBTRACT LINK32 /pdb:none /incremental:no +# Begin Special Build Tool +OutDir=.\NT4_Debug +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 NT4 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "NT4_Release" +# PROP BASE Intermediate_Dir "NT4_Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "NT4_Release" +# PROP Intermediate_Dir "NT4_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "../../../common" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINNT4" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /D "_WINNT4" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" /d "_WINNT4" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib Ws2_32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib Ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /libpath:"../../../../Airpcap_Devpack/lib/" /opt:ref +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\NT4_Release +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 Debug LOG_TO_FILE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_LOG_TO_FILE" +# PROP BASE Intermediate_Dir "Debug_LOG_TO_FILE" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_LOG_TO_FILE" +# PROP Intermediate_Dir "Debug_LOG_TO_FILE" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../common" /I "../../../dag/include" /I "../../../dag/drv/windows" /D "WIN32" /D "_WINDOWS" /D "HAVE_DAG_API" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "HAVE_AIRPCAP_API" /D "_DEBUG_TO_FILE" /D "WIN32" /D "_WINDOWS" /D "HAVE_WANPACKET_API" /D "HAVE_IPHELPER_API" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 wsock32.lib ..\wanpacket\debug\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# SUBTRACT BASE LINK32 /pdb:none /incremental:no +# ADD LINK32 wsock32.lib ..\wanpacket\debug\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../../Airpcap_Devpack/lib/" +# SUBTRACT LINK32 /pdb:none /incremental:no +# Begin Special Build Tool +OutDir=.\Debug_LOG_TO_FILE +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 Release LOG_TO_FILE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_LOG_TO_FILE" +# PROP BASE Intermediate_Dir "Release_LOG_TO_FILE" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_LOG_TO_FILE" +# PROP Intermediate_Dir "Release_LOG_TO_FILE" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "../../../common" /I "../../../dag/include" /I "../../../dag/drv/windows" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_DAG_API" /YX /FD /c +# ADD CPP /nologo /MT /W4 /GX /Zi /O2 /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "NDEBUG" /D "HAVE_AIRPCAP_API" /D "_DEBUG_TO_FILE" /D "WIN32" /D "_WINDOWS" /D "HAVE_WANPACKET_API" /D "HAVE_IPHELPER_API" /FR /YX /FD /c +# SUBTRACT CPP /u +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Ws2_32.lib ..\wanpacket\release\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 Ws2_32.lib ..\wanpacket\release\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /libpath:"../../../../Airpcap_Devpack/lib/" /opt:ref +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\Release_LOG_TO_FILE +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 NT4 Debug LOG_TO_FILE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "NT4_Debug_LOG_TO_FILE" +# PROP BASE Intermediate_Dir "NT4_Debug_LOG_TO_FILE" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "NT4_Debug_LOG_TO_FILE" +# PROP Intermediate_Dir "NT4_Debug_LOG_TO_FILE" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../common" /D "WIN32" /D "_WINDOWS" /D "_WINNT4" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "WIN32" /D "_WINDOWS" /D "_WINNT4" /D "_DEBUG_TO_FILE" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /D "_WINNT4" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" /d "_WINNT4" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# SUBTRACT BASE LINK32 /pdb:none /incremental:no +# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../../Airpcap_Devpack/lib/" +# SUBTRACT LINK32 /pdb:none /incremental:no +# Begin Special Build Tool +OutDir=.\NT4_Debug_LOG_TO_FILE +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 NT4 Release LOG_TO_FILE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "NT4_Release_LOG_TO_FILE" +# PROP BASE Intermediate_Dir "NT4_Release_LOG_TO_FILE" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "NT4_Release_LOG_TO_FILE" +# PROP Intermediate_Dir "NT4_Release_LOG_TO_FILE" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "../../../common" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINNT4" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINNT4" /D "_DEBUG_TO_FILE" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /D "_WINNT4" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" /d "_WINNT4" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib Ws2_32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib Ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /libpath:"../../../../Airpcap_Devpack/lib/" /opt:ref +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\NT4_Release_LOG_TO_FILE +SOURCE="$(InputPath)" +PostBuild_Desc=Copy packet.lib into Common +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 Debug No AirPcap" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_No_AirPcap" +# PROP BASE Intermediate_Dir "Debug_No_AirPcap" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_No_AirPcap" +# PROP Intermediate_Dir "Debug_No_AirPcap" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../z1211u/airpcap/" /D "WIN32" /D "_WINDOWS" /D "HAVE_AIRPCAP_API" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "WIN32" /D "_WINDOWS" /D "HAVE_WANPACKET_API" /D "HAVE_IPHELPER_API" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 wsock32.lib ..\wanpacket\debug\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# SUBTRACT BASE LINK32 /pdb:none /incremental:no +# ADD LINK32 wsock32.lib ..\wanpacket\debug\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../../Airpcap_Devpack/lib/" +# SUBTRACT LINK32 /pdb:none /incremental:no +# Begin Special Build Tool +OutDir=.\Debug_No_AirPcap +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 Release No AirPcap" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_No_AirPcap" +# PROP BASE Intermediate_Dir "Release_No_AirPcap" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_No_AirPcap" +# PROP Intermediate_Dir "Release_No_AirPcap" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../z1211u/airpcap/" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_AIRPCAP_API" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_WANPACKET_API" /D "HAVE_IPHELPER_API" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Ws2_32.lib ..\wanpacket\release\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 Ws2_32.lib ..\wanpacket\release\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /libpath:"../../../../Airpcap_Devpack/lib/" /opt:ref +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\Release_No_AirPcap +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 Debug NpfIm" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_No_NpfIm" +# PROP BASE Intermediate_Dir "Debug_No_NpfIm" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_No_NpfIm" +# PROP Intermediate_Dir "Debug_No_NpfIm" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "HAVE_AIRPCAP_API" /D "WIN32" /D "_WINDOWS" /D "HAVE_WANPACKET_API" /D "HAVE_IPHELPER_API" /D "HAVE_NPFIM_API" /D "_DBG" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /I "../../../../NpfIm_DevPack" /D "HAVE_AIRPCAP_API" /D "WIN32" /D "_WINDOWS" /D "HAVE_WANPACKET_API" /D "HAVE_IPHELPER_API" /D "HAVE_NPFIM_API" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 wsock32.lib ..\wanpacket\debug\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../../Airpcap_Devpack/lib/" +# SUBTRACT BASE LINK32 /pdb:none /incremental:no +# ADD LINK32 wsock32.lib ..\wanpacket\debug\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib NpfIm.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../../Airpcap_Devpack/lib/ ../../../../NpfIm_DevPack" +# SUBTRACT LINK32 /pdb:none /incremental:no +# Begin Special Build Tool +OutDir=.\Debug_No_NpfIm +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 Release NpfIm" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_No_NpfIm" +# PROP BASE Intermediate_Dir "Release_No_NpfIm" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_No_NpfIm" +# PROP Intermediate_Dir "Release_No_NpfIm" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "NDEBUG" /D "HAVE_AIRPCAP_API" /D "WIN32" /D "_WINDOWS" /D "HAVE_WANPACKET_API" /D "HAVE_IPHELPER_API" /D "HAVE_NPFIM_API" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /I "../../../../NpfIm_DevPack" /D "NDEBUG" /D "HAVE_AIRPCAP_API" /D "WIN32" /D "_WINDOWS" /D "HAVE_WANPACKET_API" /D "HAVE_IPHELPER_API" /D "HAVE_NPFIM_API" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Ws2_32.lib ..\wanpacket\release\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /machine:I386 /libpath:"../../../../Airpcap_Devpack/lib/" +# ADD LINK32 Ws2_32.lib ..\wanpacket\release\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib NpfIm.lib /nologo /subsystem:windows /dll /debug /machine:I386 /libpath:"../../../../Airpcap_Devpack/lib/ ../../../../NpfIm_DevPack" /opt:ref +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\Release_No_NpfIm +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 Debug Vista" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_Vista" +# PROP BASE Intermediate_Dir "Debug_Vista" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_Vista" +# PROP Intermediate_Dir "Debug_Vista" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "HAVE_AIRPCAP_API" /D "WIN32" /D "_WINDOWS" /D "HAVE_IPHELPER_API" /D "HAVE_NPFIM_API" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "HAVE_AIRPCAP_API" /D "WIN32" /D "_WINDOWS" /D "HAVE_IPHELPER_API" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" /d "_WINVISTA" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 wsock32.lib ..\wanpacket\debug\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../../Airpcap_Devpack/lib/" +# SUBTRACT BASE LINK32 /pdb:none /incremental:no +# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../../Airpcap_Devpack/lib/" +# SUBTRACT LINK32 /pdb:none /incremental:no +# Begin Special Build Tool +OutDir=.\Debug_Vista +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 Release Vista" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_Vista" +# PROP BASE Intermediate_Dir "Release_Vista" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_Vista" +# PROP Intermediate_Dir "Release_Vista" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /Zi /O2 /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "NDEBUG" /D "HAVE_AIRPCAP_API" /D "WIN32" /D "_WINDOWS" /D "HAVE_IPHELPER_API" /D "HAVE_NPFIM_API" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "NDEBUG" /D "HAVE_AIRPCAP_API" /D "WIN32" /D "_WINDOWS" /D "HAVE_IPHELPER_API" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" /d "_WINVISTA" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Ws2_32.lib ..\wanpacket\release\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /libpath:"../../../../Airpcap_Devpack/lib/" /opt:ref +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 Ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /libpath:"../../../../Airpcap_Devpack/lib/" /opt:ref +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\Release_Vista +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "PacketNT - Win32 Release Vista LOG_TO_FILE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_Vista_LOG_TO_FILE" +# PROP BASE Intermediate_Dir "Release_Vista_LOG_TO_FILE" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_Vista_LOG_TO_FILE" +# PROP Intermediate_Dir "Release_Vista_LOG_TO_FILE" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W4 /GX /Zi /O2 /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "NDEBUG" /D "HAVE_AIRPCAP_API" /D "_DEBUG_TO_FILE" /D "WIN32" /D "_WINDOWS" /D "HAVE_WANPACKET_API" /D "HAVE_IPHELPER_API" /D "HAVE_NPFIM_API" /FR /YX /FD /c +# SUBTRACT BASE CPP /u +# ADD CPP /nologo /MT /W4 /GX /Zi /O2 /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../common" /I "../../../../Airpcap_Devpack/include/" /D "NDEBUG" /D "HAVE_AIRPCAP_API" /D "_DEBUG_TO_FILE" /D "WIN32" /D "_WINDOWS" /D "HAVE_IPHELPER_API" /FR /YX /FD /c +# SUBTRACT CPP /u +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" /d "_WINVISTA" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Ws2_32.lib ..\wanpacket\release\wanpacket.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /libpath:"../../../../Airpcap_Devpack/lib/" /opt:ref +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 Ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Iphlpapi.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /libpath:"../../../../Airpcap_Devpack/lib/" /opt:ref +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\Release_Vista_LOG_TO_FILE +SOURCE="$(InputPath)" +PostBuild_Cmds=copy $(OutDir)\packet.lib ..\..\..\Common\ +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "PacketNT - Win32 Release" +# Name "PacketNT - Win32 Debug" +# Name "PacketNT - Win32 NT4 Debug" +# Name "PacketNT - Win32 NT4 Release" +# Name "PacketNT - Win32 Debug LOG_TO_FILE" +# Name "PacketNT - Win32 Release LOG_TO_FILE" +# Name "PacketNT - Win32 NT4 Debug LOG_TO_FILE" +# Name "PacketNT - Win32 NT4 Release LOG_TO_FILE" +# Name "PacketNT - Win32 Debug No AirPcap" +# Name "PacketNT - Win32 Release No AirPcap" +# Name "PacketNT - Win32 Debug NpfIm" +# Name "PacketNT - Win32 Release NpfIm" +# Name "PacketNT - Win32 Debug Vista" +# Name "PacketNT - Win32 Release Vista" +# Name "PacketNT - Win32 Release Vista LOG_TO_FILE" +# Begin Source File + +SOURCE=..\AdInfo.c +# End Source File +# Begin Source File + +SOURCE=..\NpfImExt.c +# End Source File +# Begin Source File + +SOURCE=..\Packet.def +# End Source File +# Begin Source File + +SOURCE=..\PACKET32.C +# End Source File +# Begin Source File + +SOURCE=..\version.rc +# End Source File +# End Target +# End Project diff --git a/winpcap/packetNtx/Dll/Project/Packet.dsw b/winpcap/packetNtx/Dll/Project/Packet.dsw new file mode 100644 index 0000000..4fcd754 --- /dev/null +++ b/winpcap/packetNtx/Dll/Project/Packet.dsw @@ -0,0 +1,44 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "PacketNT"=.\Packet.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name WanPacket + End Project Dependency +}}} + +############################################################################### + +Project: "WanPacket"=..\WanPacket\WanPacket.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/packetNtx/Dll/WanPacket/WanPacket.cpp b/winpcap/packetNtx/Dll/WanPacket/WanPacket.cpp new file mode 100644 index 0000000..8df7662 --- /dev/null +++ b/winpcap/packetNtx/Dll/WanPacket/WanPacket.cpp @@ -0,0 +1,979 @@ +/* + * Copyright (c) 2003 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#define _WIN32_DCOM + +#include +#include +#include +#include +#include + +HMODULE g_hModule = NULL; + +#include + +#include "win_bpf.h" +#include "win_bpf_filter_init.h" + +#include +#include "wanpacket.h" + +/*! + \brief Describes an opened wan (dialup, VPN...) network adapter using the NetMon API + + This structure is the most important for the functioning of WanPacket.dll. + This structure should be considered opaque by users. +*/ +struct WAN_ADAPTER_INT +{ + HBLOB hCaptureBlob; ///< Handle to the BLOB (the network adapter in the NetMon world) used to capture + CRITICAL_SECTION CriticalSection; ///< Used to synchronize access to this structure. + PUCHAR Buffer; ///< Pointer to the ring buffer used to capture packets. + DWORD C; ///< Zero-based index of the consumer in the ring buffer. It indicates the first free byte to be read. + DWORD P; ///< Zero-based index of the producer in the ring buffer. It indicates the first free byte to be written. + DWORD Free; ///< Number of the free bytes in the ring buffer. + DWORD Size; ///< Size of the ring buffer used to capture packets. + DWORD Dropped; ///< Number of packets that the current instance had to drop, from its opening. A packet is dropped if there is no more space to store it in the ring buffer. + DWORD Accepted; ///< Number of packets that the current capture instance has accepted, from its opening. A packet is accepted if it passes the bpf filter and fits in the ring buffer. Accepted packets are the ones that reach the application. + DWORD Received; ///< Number of packets received by current instance from its opening. + DWORD MinToCopy; ///< Minimum amount of data in the ring buffer that unlocks a read. + DWORD ReadTimeout; ///< Timeout after which a read is released, also if the amount of data in the ring buffer is less than MinToCopy. + HANDLE hReadEvent; ///< Pointer to the event on which the read calls on this instance must wait. + bpf_insn *FilterCode; ///< Pointer to the filtering pseudo-code associated with current instance of capture. + DWORD Mode; ///< Working mode of the driver. See PacketSetMode() for details. + LARGE_INTEGER Nbytes; ///< Amount of bytes accepted by the filter when this instance is in statistical mode. + LARGE_INTEGER Npackets; ///< Number of packets accepted by the filter when this instance is in statistical mode. + MEM_TYPE MemEx; ///< Memory used by the TME virtual co-processor + TME_CORE Tme; ///< Data structure containing the virtualization of the TME co-processor + IRTC *pIRTC; ///< Pointer to the NetMon IRTC COM interface used to capture packets. +}; + +#define ALIGN_TO_WORD(x) (((x) + 3)&~(3)) + +BOOLEAN WanPacketAddPacketToRingBuffer(PWAN_ADAPTER pWanAdapter, LPFRAME_DESCRIPTOR lpFrameDesc, DWORD SnapToCopy, struct timeval PacketTime); +DWORD WanPacketRemovePacketsFromRingBuffer(PWAN_ADAPTER pWanAdapter, PUCHAR Buffer, DWORD BuffSize); +BOOLEAN IsWindows2000(); + +#if 0 +/*! + \brief The main dll function. +*/ +#ifdef WPCAP_OEM +BOOLEAN LoadNdisNpp(DWORD Reason) +#else +BOOLEAN APIENTRY DllMain( HANDLE hModule, DWORD Reason, LPVOID lpReserved) +#endif // WPCAP_OEM +{ + switch(Reason) + { + case DLL_PROCESS_ATTACH: + g_hModule = LoadLibrary("npp\\ndisnpp.dll"); + break; + + case DLL_PROCESS_DETACH: + if (g_hModule != NULL) + FreeLibrary(g_hModule); + break; + } + + return TRUE; +} + +#endif + +/*! + \brief It returns the current time formatted as a timeval structure. + \return The current time formatted as a timeval structure. +*/ +struct timeval WanPacketGetCurrentTime() +{ + struct timeval tvReturn; + FILETIME FileTime; + GetSystemTimeAsFileTime(&FileTime); + tvReturn.tv_sec = (LONG)(((LARGE_INTEGER*)&FileTime)->QuadPart / 10000000); + tvReturn.tv_usec = (LONG)(((LARGE_INTEGER*)&FileTime)->QuadPart % 10000000 / 10); + + return tvReturn; +} + +/*! + \brief This is the callback used by the NetMon IRTC interface to pass the packets to the user. + \param Event. An UPDATE_EVENT structure containing the packets. + \return Not clearly defined by the NetMon IRTC MSDN documentation. +*/ +DWORD WINAPI WanPacketReceiverCallback(UPDATE_EVENT Event) +{ + DWORD i; + LPFRAMETABLE lpFrameTable; + LPFRAME_DESCRIPTOR lpFrameDesc; + PWAN_ADAPTER pWanAdapter; + u_int FilterResult; + struct time_conv TimeConv; + struct timeval PacketTime; + + pWanAdapter = (PWAN_ADAPTER)Event.lpUserContext; + lpFrameTable = Event.lpFrameTable; + + // the frame table can wrap the indices + for (i = lpFrameTable->StartIndex; i != lpFrameTable->EndIndex; (i == lpFrameTable->FrameTableLength) ? i=0: i ++ ) + { + lpFrameDesc = &lpFrameTable->Frames[i]; + + PacketTime.tv_sec = (ULONG) (lpFrameDesc->TimeStamp / (__int64)1000000 - 11644473600); + PacketTime.tv_usec= (ULONG) (lpFrameDesc->TimeStamp % (__int64)1000000); + + FORCE_TIME(&PacketTime, &TimeConv); + + EnterCriticalSection( &pWanAdapter->CriticalSection ); + pWanAdapter->Received ++; + + FilterResult = bpf_filter(pWanAdapter->FilterCode, + lpFrameDesc->FramePointer, + lpFrameDesc->FrameLength, + lpFrameDesc->nBytesAvail, + &pWanAdapter->MemEx, + &pWanAdapter->Tme, + &TimeConv); + + if ( pWanAdapter->Mode == PACKET_MODE_MON && FilterResult == 1 ) + SetEvent( pWanAdapter->hReadEvent ); + + if (FilterResult == (u_int) -1 || FilterResult > lpFrameDesc->nBytesAvail ) + FilterResult = lpFrameDesc->nBytesAvail; + + if ( pWanAdapter->Mode == PACKET_MODE_STAT ) + { + pWanAdapter->Npackets.QuadPart ++; + if ( lpFrameDesc->FrameLength < 60 ) + pWanAdapter->Nbytes.QuadPart += 60; + else + pWanAdapter->Nbytes.QuadPart += lpFrameDesc->FrameLength; + // add preamble+SFD+FCS to the packet + // these values must be considered because are not part of the packet received from NDIS + pWanAdapter->Nbytes.QuadPart += 12; + } + + if ( pWanAdapter->Mode == PACKET_MODE_CAPT && FilterResult > 0 ) + { + if ( WanPacketAddPacketToRingBuffer(pWanAdapter, lpFrameDesc, FilterResult, PacketTime ) ) + pWanAdapter->Accepted++; + else + pWanAdapter->Dropped++; + } + + LeaveCriticalSection( &pWanAdapter->CriticalSection ); + } + + return NOERROR; +} + +/*! + \brief Tries to open the wan (dialup, vpn...) adapter, and immediately closes it. + \return TRUE on success. +*/ +BOOLEAN WanPacketTestAdapter() +{ + PBLOB_TABLE pBlobTable = NULL; + HBLOB hFilterBlob = NULL; + BOOLEAN retVal; + DWORD i; + HRESULT hResult; + + if ( g_hModule == NULL) + { + g_hModule = LoadLibrary("npp\\ndisnpp.dll"); + } + + if ( g_hModule == NULL) + { + return FALSE; + } + + hResult = CoInitialize(NULL); + + // + // if the calling thread has already initialized COM with a + // different threading model, we have this error + // however, we are able to support another threading model, + // so we try to initialize COM with another threading model. + // This new call should succeed with S_FALSE. + // + if (hResult == RPC_E_CHANGED_MODE) + { + hResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + //MULTITHREADED threading is only supported on Windows 2000 + if (hResult == RPC_E_CHANGED_MODE && IsWindows2000()) + { + hResult = CoInitializeEx(NULL, COINIT_MULTITHREADED); + } + } + + if (hResult != S_OK && hResult != S_FALSE) + return FALSE; + + if ( CreateBlob(&hFilterBlob) != NMERR_SUCCESS ) + { + CoUninitialize(); + return FALSE; + } + + if ( SetBoolInBlob(hFilterBlob, OWNER_NPP, CATEGORY_CONFIG, TAG_INTERFACE_REALTIME_CAPTURE, TRUE) != NMERR_SUCCESS ) + { + DestroyBlob( hFilterBlob); + CoUninitialize(); + return FALSE; + } + + if ( SetBoolInBlob(hFilterBlob, OWNER_NPP, CATEGORY_LOCATION, TAG_RAS, TRUE) != NMERR_SUCCESS ) + { + DestroyBlob( hFilterBlob); + CoUninitialize(); + return FALSE; + } + + if ( GetNPPBlobTable(hFilterBlob, &pBlobTable) != NMERR_SUCCESS ) + { + DestroyBlob( hFilterBlob); + CoUninitialize(); + return FALSE; + } + + DestroyBlob (hFilterBlob); + + if (pBlobTable->dwNumBlobs == 1) + retVal = TRUE; + else + retVal = FALSE; + + for ( i = 0 ; i < pBlobTable->dwNumBlobs ; i++ ) + DestroyBlob(pBlobTable->hBlobs[i]); + + GlobalFree(pBlobTable); + CoUninitialize(); + + return retVal; +} + +/*! + \brief Returns true if the system is running windows 2000 + \return TRUE if the system is running windows 2000. FALSE otherwise. +*/ +BOOLEAN IsWindows2000() +{ + OSVERSIONINFOEX osvi; + BOOL bOsVersionInfoEx; + + // Try calling GetVersionEx using the OSVERSIONINFOEX structure. + // If that fails, try using the OSVERSIONINFO structure. + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi); + if( !bOsVersionInfoEx ) + { + osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) + return FALSE; + } + + if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) + //windows 2000 + return TRUE; + return FALSE; + +} + +/*! + \brief Opens the wan (dialup, vpn...) adapter. + \return If the function succeeds, the return value is the pointer to a properly initialized WAN_ADAPTER structure, + otherwise the return value is NULL. +*/ +PWAN_ADAPTER WanPacketOpenAdapter() +{ + PWAN_ADAPTER pWanAdapter = NULL; + PBLOB_TABLE pBlobTable = NULL; + HBLOB hFilterBlob = NULL; + HRESULT hResult; + DWORD i; + + if ( g_hModule == NULL) + { + g_hModule = LoadLibrary("npp\\ndisnpp.dll"); + } + + if ( g_hModule == NULL) + { + return NULL; + } + + hResult = CoInitialize(NULL); + + // + // if the calling thread has already initialized COM with a + // different threading model, we have this error + // however, we are able to support another threading model, + // so we try to initialize COM with another threading model. + // This new call should succeed with S_FALSE. + // + if (hResult == RPC_E_CHANGED_MODE) + { + hResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + //MULTITHREADED threading is only supported on Windows 2000 + if (hResult == RPC_E_CHANGED_MODE && IsWindows2000()) + { + hResult = CoInitializeEx(NULL, COINIT_MULTITHREADED); + } + } + + if (hResult != S_OK && hResult != S_FALSE) + return NULL; + + pWanAdapter = (PWAN_ADAPTER)GlobalAlloc(GPTR, sizeof (WAN_ADAPTER)); + + if ( pWanAdapter == NULL ) + goto error; + + memset(pWanAdapter, 0, sizeof(WAN_ADAPTER)); + + if ( CreateBlob(&hFilterBlob) != NMERR_SUCCESS ) + { + goto error; + } + + if ( SetBoolInBlob(hFilterBlob, OWNER_NPP, CATEGORY_CONFIG, TAG_INTERFACE_REALTIME_CAPTURE, TRUE) != NMERR_SUCCESS ) + { + DestroyBlob( hFilterBlob); + goto error; + } + + if ( SetBoolInBlob(hFilterBlob, OWNER_NPP, CATEGORY_LOCATION, TAG_RAS, TRUE) != NMERR_SUCCESS ) + { + DestroyBlob( hFilterBlob); + goto error; + } + + if ( GetNPPBlobTable(hFilterBlob, &pBlobTable) != NMERR_SUCCESS ) + { + DestroyBlob( hFilterBlob); + goto error; + } + + DestroyBlob (hFilterBlob); + + if ( pBlobTable->dwNumBlobs == 0 || pBlobTable->dwNumBlobs > 1) + { + ///fixme..... + for ( i = 0 ; i < pBlobTable->dwNumBlobs ; i++ ) + DestroyBlob(pBlobTable->hBlobs[i]); + + GlobalFree(pBlobTable); + goto error; + } + + pWanAdapter->hCaptureBlob = pBlobTable->hBlobs[0]; + + GlobalFree(pBlobTable); + + InitializeCriticalSection(&pWanAdapter->CriticalSection); + + pWanAdapter->hReadEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + if ( pWanAdapter->hReadEvent == NULL ) + goto error; + + pWanAdapter->MemEx.buffer = (PUCHAR)GlobalAlloc(GPTR, DEFAULT_MEM_EX_SIZE); + if (pWanAdapter->MemEx.buffer == NULL) + goto error; + + pWanAdapter->MemEx.size = DEFAULT_MEM_EX_SIZE; + pWanAdapter->Tme.active = TME_NONE_ACTIVE; + + if (CreateNPPInterface(pWanAdapter->hCaptureBlob, IID_IRTC, (void**) &pWanAdapter->pIRTC) == NMERR_SUCCESS && pWanAdapter->pIRTC != NULL) + { + //create OK + if (pWanAdapter->pIRTC->Connect(pWanAdapter->hCaptureBlob, NULL, WanPacketReceiverCallback, (LPVOID)pWanAdapter , NULL) == NMERR_SUCCESS) + { + //connect OK + if (pWanAdapter->pIRTC->Start() == NMERR_SUCCESS) + { + return pWanAdapter; + } + else + { + pWanAdapter->pIRTC->Disconnect(); + pWanAdapter->pIRTC->Release(); + goto error; + } + } + else + { + pWanAdapter->pIRTC->Release(); + goto error; + } + } + else + { + goto error; + } + + //awfully never reached +// return NULL; + +error: + + if (pWanAdapter != NULL) + { + if (pWanAdapter->hReadEvent != NULL) + CloseHandle(pWanAdapter->hReadEvent); + + DeleteCriticalSection(&pWanAdapter->CriticalSection); + if (pWanAdapter->hCaptureBlob) + DestroyBlob(pWanAdapter->hCaptureBlob); + + GlobalFree(pWanAdapter); + } + + CoUninitialize(); + + return NULL; +} + +/*! + \brief Closes a wan (dialup, vpn...) adapter. + \param lpWanAdapter the pointer to the wan adapter to close. + + WanPacketCloseAdapter closes the given adapter and frees the associated WAN_ADAPTER structure +*/ +BOOLEAN WanPacketCloseAdapter(PWAN_ADAPTER pWanAdapter) +{ + if (pWanAdapter->pIRTC->Stop() != NMERR_SUCCESS) + OutputDebugString("WanPacketCloseAdapter: Severe error, IRTC::Stop failed\n"); + if (pWanAdapter->pIRTC->Disconnect() != NMERR_SUCCESS) + OutputDebugString("WanPacketCloseAdapter: Severe error, IRTC::Disconnect failed\n"); + if (pWanAdapter->pIRTC->Release() != NMERR_SUCCESS) + OutputDebugString("WanPacketCloseAdapter: Severe error, IRTC::Release failed\n"); + Sleep(0); //Just a stupid hack to make all the stuff work. I don't why it's necessary. + + + //setting a NULL filter will actually deallocate the in-use filter + WanPacketSetBpfFilter(pWanAdapter, NULL, 0); + //setting a zero-sized buffer will deallocate any in-use ring buffer + WanPacketSetBufferSize(pWanAdapter, 0); + + CloseHandle(pWanAdapter->hReadEvent); + + //destroy the BLOB used to capture + DestroyBlob(pWanAdapter->hCaptureBlob); + + DeleteCriticalSection(&pWanAdapter->CriticalSection); + + //deallocate the extended memory, if any. + if (pWanAdapter->MemEx.size > 0) + GlobalFree(pWanAdapter->MemEx.buffer); + + GlobalFree(pWanAdapter); + //uninitialize COM + CoUninitialize(); + + return TRUE; +} + +/*! + \brief Sets the working mode of a wan (dialup, vpn...) adapter. + \param pWanAdapter Pointer to a WAN_ADAPTER structure. + \param mode The new working mode of the adapter. + \return If the function succeeds, the return value is true. + + For more information, see the documentation of PacketSetMode +*/ + + +BOOLEAN WanPacketSetMode(PWAN_ADAPTER pWanAdapter, DWORD Mode) +{ + if (Mode != PACKET_MODE_CAPT && Mode != PACKET_MODE_STAT && Mode != PACKET_MODE_MON) + return FALSE; + pWanAdapter->Mode = Mode; + return TRUE; +} + +/*! + \brief Sets the bpf packet filter. + \param pWanAdapter Pointer to a WAN_ADAPTER structure. + \param FilterCode Pointer to the BPF filtering code that will be associated with this capture or monitoring + instance and that will be executed on every incoming packet. + \param Length Length, in bytes, of the BPF filter code. + \return This function returns TRUE if the filter is set successfully, FALSE if an error occurs + or if the filter program is not accepted after a safeness check. This API + performs the check in order to avoid unexpected behavior due to buggy or malicious filters, and it rejects non + conformant filters. + + For more information, see the documentation of PacketSetBpf +*/ +BOOLEAN WanPacketSetBpfFilter(PWAN_ADAPTER pWanAdapter, PUCHAR FilterCode, DWORD Length) +{ + PUCHAR NewFilterCode = NULL; + DWORD NumberOfInstructions; + DWORD Counter; + struct bpf_insn *InitializationCode; + struct time_conv TimeConv; + if ( Length < 0) + return FALSE; + + EnterCriticalSection(&pWanAdapter->CriticalSection); + if (Length > 0) + { + NumberOfInstructions = Length/sizeof(struct bpf_insn); + for(Counter = 0; + Counter < NumberOfInstructions && ((struct bpf_insn*)FilterCode)[Counter].code != BPF_SEPARATION ; + Counter++); + + if ( Counter != NumberOfInstructions && + NumberOfInstructions != Counter + 1 && + ((struct bpf_insn*)FilterCode)[Counter].code == BPF_SEPARATION ) + { + //we need to initialize the TME + InitializationCode = &((struct bpf_insn*)FilterCode)[Counter+1]; + + //FIXME, just an hack, this structure is never used here. + TimeConv.start[0].tv_sec = 0; + TimeConv.start[0].tv_usec = 0; + + if ( bpf_filter_init(InitializationCode, + &pWanAdapter->MemEx, + &pWanAdapter->Tme, + &TimeConv) != INIT_OK ) + { + LeaveCriticalSection(&pWanAdapter->CriticalSection); + return FALSE; + } + } + + NumberOfInstructions = Counter; + + if ( bpf_validate((struct bpf_insn*)FilterCode, Counter, pWanAdapter->MemEx.size) == 0) + { + //filter not validated + //FIXME: the machine has been initialized(?), but the operative code is wrong. + //we have to reset the machine! + //something like: reallocate the mem_ex, and reset the tme_core + LeaveCriticalSection(&pWanAdapter->CriticalSection); + return FALSE; + } + + + NewFilterCode = (PUCHAR)GlobalAlloc( GMEM_FIXED, Counter * sizeof(struct bpf_insn) ); + if (NewFilterCode == NULL) + { + LeaveCriticalSection(&pWanAdapter->CriticalSection); + return FALSE; + } + + RtlCopyMemory(NewFilterCode, FilterCode, Counter * sizeof(struct bpf_insn)); + } + + if ( pWanAdapter->FilterCode != NULL ) + GlobalFree(pWanAdapter->FilterCode); + + pWanAdapter->FilterCode = (struct bpf_insn*)NewFilterCode; + //we reset all the ring buffer related counters. + pWanAdapter->C = 0; + pWanAdapter->P = 0; + pWanAdapter->Free = pWanAdapter->Size; + pWanAdapter->Accepted = 0; + pWanAdapter->Dropped = 0; + pWanAdapter->Received = 0; + pWanAdapter->Nbytes.QuadPart = 0; + pWanAdapter->Npackets.QuadPart = 0; + + LeaveCriticalSection(&pWanAdapter->CriticalSection); + + return TRUE; +} + +/*! + \brief Sets the size of the ring buffer associated with this instance. + \param pWanAdapter Pointer to a WAN_ADAPTER structure. + \param BufferSize New size of the buffer, in \b kilobytes. + \return The function returns TRUE if successfully completed, FALSE if there is not enough memory to + allocate the new buffer. + + For more information, see the documentation of PacketSetBuff + +*/ +BOOLEAN WanPacketSetBufferSize(PWAN_ADAPTER pWanAdapter, DWORD BufferSize) +{ + PUCHAR NewBuffer = NULL; + + if ( BufferSize < 0 || ( BufferSize > 0 && BufferSize < sizeof (struct bpf_hdr) ) ) + return FALSE; + + if ( BufferSize > 0 ) + { + NewBuffer = (PUCHAR)GlobalAlloc( GMEM_FIXED, BufferSize ); + if (NewBuffer == NULL) + return FALSE; + } + + EnterCriticalSection(&pWanAdapter->CriticalSection); + + if ( pWanAdapter->Buffer != NULL ) + GlobalFree(pWanAdapter->Buffer); + + pWanAdapter->Buffer = NewBuffer; + pWanAdapter->Size = BufferSize; + pWanAdapter->C = 0; + pWanAdapter->P = 0; + pWanAdapter->Free = BufferSize; + + LeaveCriticalSection(&pWanAdapter->CriticalSection); + + return TRUE; +} + +/*! + \brief Read data (packets or statistics) from this wan (dialup, vpn...) instance. + \param pWanAdapter Pointer to a WAN_ADAPTER structure. + \param Buffer Buffer that will receive the data. + \param BufferSize Size of receiving buffer. + \return It returns the number of written bytes in the buffer. + + For more information, see the documentation of PacketReceivePacket + */ +DWORD WanPacketReceivePacket(PWAN_ADAPTER pWanAdapter, PUCHAR Buffer, DWORD BufferSize) +{ + DWORD ReadBytes = 0; + //first of all, we wait for either the ReadTimeout to expire, or enough data + //in the buffer (i.e. hReadEvent gets set). + WaitForSingleObject(pWanAdapter->hReadEvent, pWanAdapter->ReadTimeout); + + //we have to prevent other entities from modifying the pWanAdapter structure + EnterCriticalSection(&pWanAdapter->CriticalSection); + + if ( pWanAdapter->Mode == PACKET_MODE_CAPT ) + { //capture mode, we have an ad-hoc fcn + ReadBytes = WanPacketRemovePacketsFromRingBuffer(pWanAdapter, Buffer, BufferSize); + } + + if ( pWanAdapter->Mode == PACKET_MODE_STAT ) + { + if ( BufferSize < sizeof(LONGLONG) * 2 + sizeof(struct bpf_hdr)) + ReadBytes = 0; //not enough space in the dest buffer + else + { + //insert tthe bpf header + ((struct bpf_hdr*)Buffer)->bh_caplen = 2*sizeof(LONGLONG); + ((struct bpf_hdr*)Buffer)->bh_datalen = 2*sizeof(LONGLONG); + ((struct bpf_hdr*)Buffer)->bh_hdrlen = sizeof(struct bpf_hdr); + ((struct bpf_hdr*)Buffer)->bh_tstamp = WanPacketGetCurrentTime(); + //copy the counters + ((LONGLONG*)(Buffer + sizeof(struct bpf_hdr)))[0] = pWanAdapter->Npackets.QuadPart; + ((LONGLONG*)(Buffer + sizeof(struct bpf_hdr)))[1] = pWanAdapter->Nbytes.QuadPart; + ReadBytes = sizeof(struct bpf_hdr) + 2 + sizeof(LONGLONG); + //reset the counters + pWanAdapter->Nbytes.QuadPart = 0; + pWanAdapter->Npackets.QuadPart = 0; + } + } + + + if ( pWanAdapter->Mode == PACKET_MODE_MON ) + { + PTME_DATA pTmeData; + DWORD ByteCopy; + struct bpf_hdr *pHeader; + + if ( + !IS_VALIDATED(pWanAdapter->Tme.validated_blocks, pWanAdapter->Tme.active_read) + || BufferSize < sizeof(struct bpf_hdr) + ) + { //the TME is either not active, or no tme block has been set to be used for passing data to the user + ReadBytes = 0; + } + else + { + //insert the bpf header + pHeader = (struct bpf_hdr*)Buffer; + pHeader->bh_tstamp = WanPacketGetCurrentTime(); + pHeader->bh_hdrlen = sizeof(struct bpf_hdr); + + pTmeData = &pWanAdapter->Tme.block_data[pWanAdapter->Tme.active_read]; + + if ( pTmeData->last_read.tv_sec != 0 ) + pTmeData->last_read = pHeader->bh_tstamp; + + //check the amount of data that must be copied + ByteCopy = pTmeData->block_size * pTmeData->filled_blocks; + + if ( BufferSize - sizeof(struct bpf_hdr) < ByteCopy ) + ByteCopy = BufferSize - sizeof(struct bpf_hdr); //we copy only the data that fit in the buffer + else + ByteCopy = pTmeData->filled_blocks * pTmeData->block_size; //we copy all the data + + //actual copy of data + RtlCopyMemory(Buffer + sizeof(struct bpf_hdr), pTmeData->shared_memory_base_address, ByteCopy); + + //fix the bpf header + pHeader->bh_caplen = ByteCopy; + pHeader->bh_datalen = pHeader->bh_caplen; + + ReadBytes = ByteCopy + sizeof(struct bpf_hdr); + } + } + //done with the pWanAdapter data + LeaveCriticalSection(&pWanAdapter->CriticalSection); + + return ReadBytes; +} + +/*! + \brief Defines the minimum amount of data that will be received in a read. + \param pWanAdapter Pointer to a WAN_ADAPTER structure + \param MinToCopy The minimum amount of data in the ring buffer that will cause the instance to release a read on this adapter. + \return If the function succeeds, the return value is TRUE. + + For more information, see the documentation of PacketSetMinToCopy +*/ +BOOLEAN WanPacketSetMinToCopy(PWAN_ADAPTER pWanAdapter, DWORD MinToCopy) +{ + EnterCriticalSection( &pWanAdapter->CriticalSection ); + + pWanAdapter->MinToCopy = MinToCopy; + + LeaveCriticalSection( &pWanAdapter->CriticalSection ); + + return TRUE; +} + +/*! + \brief Returns statistic values about the current capture session. + \param pWanAdapter Pointer to a WAN_ADAPTER structure. + \param s Pointer to a user provided bpf_stat structure that will be filled by the function. + \return If the function succeeds, the return value is TRUE. + + For more information, see the documentation of PacketGetStats and PacketGetStatsEx +*/ +BOOLEAN WanPacketGetStats(PWAN_ADAPTER pWanAdapter, struct bpf_stat *s) +{ + EnterCriticalSection (&pWanAdapter->CriticalSection); + + s->bs_drop = pWanAdapter->Dropped; + s->bs_recv = pWanAdapter->Received; + s->bs_capt = pWanAdapter->Accepted; + s->ps_ifdrop = 0; + + LeaveCriticalSection (&pWanAdapter->CriticalSection); + + return TRUE; +} + +/*! + \brief Sets the timeout after which a read on an wan adapter returns. + \param pWanAdapter Pointer to a WAN_ADAPTER structure. + \param ReadTimeout indicates the timeout, in milliseconds, after which a call to WanPacketReceivePacket() on + the adapter pointed by pWanAdapter will be released, even if no packets have been captured by NetMon IRTC. + Setting timeout to 0 means no timeout, i.e. PacketReceivePacket() never returns if no packet arrives. + A timeout of -1 causes PacketReceivePacket() to always return immediately. + \return If the function succeeds, the return value is TRUE. + + \note This function works also if the adapter is working in statistics mode, and can be used to set the + time interval between two statistic reports. +*/ +BOOLEAN WanPacketSetReadTimeout(PWAN_ADAPTER pWanAdapter, DWORD ReadTimeout) +{ + + if (ReadTimeout == 0) + ReadTimeout = INFINITE; + else + if (ReadTimeout == -1) + ReadTimeout = 0; + + EnterCriticalSection( &pWanAdapter->CriticalSection ); + + pWanAdapter->ReadTimeout = ReadTimeout; + + LeaveCriticalSection( &pWanAdapter->CriticalSection ); + + return TRUE; +} + + +/*! + \brief Returns the notification event associated with the read calls on the wan adapter. + \param pWanAdapter Pointer to a WAN_ADAPTER structure. + \return The handle of the event that the the IRTC receive callback signals when some data is available in the ring buffer. + + For more information, see the documentation of PacketGetReadEvent +*/ +HANDLE WanPacketGetReadEvent(PWAN_ADAPTER pWanAdapter) +{ + return pWanAdapter->hReadEvent; +} + +/*! + \brief Moves the packets from the ring buffer to a given buffer. + \param pWanAdapter Pointer to WAN_ADAPTER structure associated with this instance. + \param Buffer Pointer to the destination, user allocated, buffer. + \param BuffSize Size of the buffer. + \return It returns the number of bytes correctly written to the destination buffer +*/ +DWORD WanPacketRemovePacketsFromRingBuffer(PWAN_ADAPTER pWanAdapter, PUCHAR Buffer, DWORD BuffSize) +{ + DWORD Copied; + struct bpf_hdr *Header; + Copied = 0; + DWORD ToCopy; + DWORD Increment; + + ResetEvent(pWanAdapter->hReadEvent); + + while (BuffSize > Copied) + { + if ( pWanAdapter->Free < pWanAdapter->Size ) + { //there are some packets in the selected (aka LocalData) buffer + Header = (struct bpf_hdr*)(pWanAdapter->Buffer + pWanAdapter->C); + + if (Header->bh_caplen + sizeof (struct bpf_hdr) > BuffSize - Copied) + { //if the packet does not fit into the user buffer, we've ended copying packets + return Copied; + } + + *((struct bpf_hdr*)(Buffer + Copied)) = *Header; + + Copied += sizeof(struct bpf_hdr); + pWanAdapter->C += sizeof(struct bpf_hdr); + + if ( pWanAdapter->C == pWanAdapter->Size ) + pWanAdapter->C = 0; + + if ( pWanAdapter->Size - pWanAdapter->C < (DWORD)Header->bh_caplen ) + { + //the packet is fragmented in the buffer (i.e. it skips the buffer boundary) + ToCopy = pWanAdapter->Size - pWanAdapter->C; + CopyMemory(Buffer + Copied,pWanAdapter->Buffer + pWanAdapter->C, ToCopy); + CopyMemory(Buffer + Copied + ToCopy, pWanAdapter->Buffer + 0, Header->bh_caplen - ToCopy); + pWanAdapter->C = Header->bh_caplen - ToCopy; + } + else + { + //the packet is not fragmented + CopyMemory(Buffer + Copied ,pWanAdapter->Buffer + pWanAdapter->C ,Header->bh_caplen); + pWanAdapter->C += Header->bh_caplen; + // if (c==size) inutile, contemplato nell "header atomico" + // c=0; + } + + Copied += ALIGN_TO_WORD(Header->bh_caplen); + + Increment = Header->bh_caplen + sizeof(struct bpf_hdr); + if ( pWanAdapter->Size - pWanAdapter->C < sizeof(struct bpf_hdr) ) + { //the next packet would be saved at the end of the buffer, but the NewHeader struct would be fragmented + //so the producer (--> the consumer) skips to the beginning of the buffer + Increment += pWanAdapter->Size - pWanAdapter->C; + pWanAdapter->C = 0; + } + pWanAdapter->Free += Increment; + } + else + return Copied; + } + return Copied; +} + +/*! + \brief Adds a packet to the ring buffer. + \param pWanAdapter Pointer to WAN_ADAPTER structure associated with this instance. + \param lpFrameDesc Pointer to a packet as received by the IRTC receiver callback. + \param SnapToCopy Number of bytes to be copied from the packet to the ring buffer. + \param PacketTime Timestamp of the packet. + \return It returns TRUE if the copy was successful, FALSE if the packet did not fit in the ring buffer. +*/ +BOOLEAN WanPacketAddPacketToRingBuffer(PWAN_ADAPTER pWanAdapter, LPFRAME_DESCRIPTOR lpFrameDesc, DWORD SnapToCopy, struct timeval PacketTime) +{ + struct bpf_hdr *Header; + DWORD ToCopy; + DWORD increment; + + if (SnapToCopy + sizeof(struct bpf_hdr) > pWanAdapter->Free) + return FALSE; + + Header = (struct bpf_hdr*)(pWanAdapter->Buffer + pWanAdapter->P); + + // We need to change reference from January, 1st 1601 to January, 1st 1970 = 11644473600 seconds if I'm right!! + Header->bh_tstamp = PacketTime; + + if (SnapToCopy > lpFrameDesc->FrameLength) + SnapToCopy = lpFrameDesc->FrameLength; + + Header->bh_caplen = SnapToCopy; + Header->bh_datalen = lpFrameDesc->FrameLength; + Header->bh_hdrlen = sizeof(struct bpf_hdr); + + pWanAdapter->P += sizeof(struct bpf_hdr); + if ( pWanAdapter->P == pWanAdapter->Size ) + pWanAdapter->P = 0; + + if ( pWanAdapter->Size - pWanAdapter->P < SnapToCopy ) + { + //the packet will be fragmented in the buffer (aka, it will skip the buffer boundary) + //two copies!! + ToCopy = pWanAdapter->Size - pWanAdapter->P; + CopyMemory(pWanAdapter->Buffer + pWanAdapter->P, lpFrameDesc->FramePointer, ToCopy); + CopyMemory(pWanAdapter->Buffer + 0 , (PUCHAR)lpFrameDesc->FramePointer + ToCopy, SnapToCopy - ToCopy); + pWanAdapter->P = SnapToCopy - ToCopy; + } + else + { + //the packet does not need to be fragmented in the buffer (aka, it doesn't skip the buffer boundary) + // ;-)))))) only ONE copy + CopyMemory(pWanAdapter->Buffer + pWanAdapter->P, lpFrameDesc->FramePointer, SnapToCopy); + pWanAdapter->P += SnapToCopy; + } + increment = SnapToCopy + sizeof(struct bpf_hdr); + if ( pWanAdapter->Size - pWanAdapter->P < sizeof(struct bpf_hdr) ) //we check that the available, AND contiguous, space in the buffer will fit + { //the bpf_hdr structure, at least, otherwise we skip the producer + increment += pWanAdapter->Size - pWanAdapter->P; //at the beginning of the buffer (p = 0), and decrement the free bytes appropriately + pWanAdapter->P = 0; + } + + pWanAdapter->Free -= increment; + + if( pWanAdapter-> Size - pWanAdapter->Free >= pWanAdapter->MinToCopy ) + { + SetEvent(pWanAdapter->hReadEvent); + } + + return TRUE; +} diff --git a/winpcap/packetNtx/Dll/WanPacket/WanPacket.def b/winpcap/packetNtx/Dll/WanPacket/WanPacket.def new file mode 100644 index 0000000..2562d0c --- /dev/null +++ b/winpcap/packetNtx/Dll/WanPacket/WanPacket.def @@ -0,0 +1,13 @@ +LIBRARY WanPacket +EXPORTS + WanPacketOpenAdapter + WanPacketCloseAdapter + WanPacketReceivePacket + WanPacketSetBufferSize + WanPacketSetBpfFilter + WanPacketSetMinToCopy + WanPacketSetReadTimeout + WanPacketGetStats + WanPacketGetReadEvent + WanPacketSetMode + WanPacketTestAdapter \ No newline at end of file diff --git a/winpcap/packetNtx/Dll/WanPacket/WanPacket.dsp b/winpcap/packetNtx/Dll/WanPacket/WanPacket.dsp new file mode 100644 index 0000000..f1446a8 --- /dev/null +++ b/winpcap/packetNtx/Dll/WanPacket/WanPacket.dsp @@ -0,0 +1,202 @@ +# Microsoft Developer Studio Project File - Name="WanPacket" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=WANPACKET - WIN32 DEBUG +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "WanPacket.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "WanPacket.mak" CFG="WANPACKET - WIN32 DEBUG" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "WanPacket - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "WanPacket - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "WanPacket - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WANPACKET_EXPORTS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\..\..\Common" /I "..\..\driver" /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../../z1211u/airpcap/" /D "NDEBUG" /D "_MBCS" /D "_USRDLL" /D "WANPACKET_EXPORTS" /D "WIN32" /D "_WINDOWS" /D "HAVE_DAG_API" /D "__NPF_x86__" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 npptools.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /libpath:"..\..\WanPacket\Release\\" /opt:ref +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "WanPacket - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WANPACKET_EXPORTS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\Common" /I "..\..\driver" /I "../../../dag/include" /I "../../../dag/drv/windows" /I "../../../../z1211u/airpcap/" /D "_DEBUG" /D "_MBCS" /D "_USRDLL" /D "WANPACKET_EXPORTS" /D "WIN32" /D "_WINDOWS" /D "HAVE_DAG_API" /D "__NPF_x86__" /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib npptools.lib /nologo /dll /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "WanPacket - Win32 Release" +# Name "WanPacket - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\driver\bucket_lookup.c +# End Source File +# Begin Source File + +SOURCE=..\..\driver\count_packets.c +# End Source File +# Begin Source File + +SOURCE=..\..\driver\functions.c +# End Source File +# Begin Source File + +SOURCE=..\..\driver\normal_lookup.c +# End Source File +# Begin Source File + +SOURCE=..\..\driver\tcp_session.c +# End Source File +# Begin Source File + +SOURCE=..\..\driver\tme.c +# End Source File +# Begin Source File + +SOURCE=.\version.rc +# End Source File +# Begin Source File + +SOURCE=.\WanPacket.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\driver\win_bpf_filter.c +# End Source File +# Begin Source File + +SOURCE=..\..\driver\win_bpf_filter_init.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\driver\bucket_lookup.h +# End Source File +# Begin Source File + +SOURCE=..\..\driver\count_packets.h +# End Source File +# Begin Source File + +SOURCE=..\..\driver\DEBUG.H +# End Source File +# Begin Source File + +SOURCE=..\..\driver\functions.h +# End Source File +# Begin Source File + +SOURCE=..\..\driver\memory_t.h +# End Source File +# Begin Source File + +SOURCE=..\..\driver\normal_lookup.h +# End Source File +# Begin Source File + +SOURCE=..\..\driver\tcp_session.h +# End Source File +# Begin Source File + +SOURCE=..\..\driver\time_calls.h +# End Source File +# Begin Source File + +SOURCE=..\..\driver\tme.h +# End Source File +# Begin Source File + +SOURCE=..\..\driver\valid_insns.h +# End Source File +# Begin Source File + +SOURCE=..\..\driver\win_bpf.h +# End Source File +# Begin Source File + +SOURCE=..\..\driver\win_bpf_filter_init.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# Begin Source File + +SOURCE=.\WanPacket.def +# End Source File +# End Target +# End Project diff --git a/winpcap/packetNtx/Dll/WanPacket/WanPacket.dsw b/winpcap/packetNtx/Dll/WanPacket/WanPacket.dsw new file mode 100644 index 0000000..0b38b77 --- /dev/null +++ b/winpcap/packetNtx/Dll/WanPacket/WanPacket.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "WanPacket"=.\WanPacket.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/packetNtx/Dll/WanPacket/WanPacket.h b/winpcap/packetNtx/Dll/WanPacket/WanPacket.h new file mode 100644 index 0000000..27db452 --- /dev/null +++ b/winpcap/packetNtx/Dll/WanPacket/WanPacket.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2003 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#if !defined(AFX_WANPACKET_H__C87BC2BD_187D_4A72_A5FF_537A9F4B588F__INCLUDED_) +#define AFX_WANPACKET_H__C87BC2BD_187D_4A72_A5FF_537A9F4B588F__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +// Insert your headers here +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +//BOOLEAN LoadNdisNpp(DWORD Reason); +BOOLEAN WanPacketSetBpfFilter(PWAN_ADAPTER pWanAdapter, PUCHAR FilterCode, DWORD Length); +PWAN_ADAPTER WanPacketOpenAdapter(); +BOOLEAN WanPacketCloseAdapter(PWAN_ADAPTER pWanAdapter); +BOOLEAN WanPacketSetBufferSize(PWAN_ADAPTER pWanAdapter, DWORD BufferSize); +DWORD WanPacketReceivePacket(PWAN_ADAPTER pWanAdapter, PUCHAR Buffer, DWORD BufferSize); +BOOLEAN WanPacketSetMinToCopy(PWAN_ADAPTER pWanAdapter, DWORD MinToCopy); +BOOLEAN WanPacketGetStats(PWAN_ADAPTER pWanAdapter, struct bpf_stat *s); +BOOLEAN WanPacketSetReadTimeout(PWAN_ADAPTER pWanAdapter, DWORD ReadTimeout); +BOOLEAN WanPacketSetMode(PWAN_ADAPTER pWanAdapter, DWORD Mode); +HANDLE WanPacketGetReadEvent(PWAN_ADAPTER pWanAdapter); +BOOLEAN WanPacketTestAdapter(); + +#ifdef __cplusplus +} +#endif + + +#endif // !defined(AFX_WANPACKET_H__C87BC2BD_187D_4A72_A5FF_537A9F4B588F__INCLUDED_) + + diff --git a/winpcap/packetNtx/Dll/WanPacket/version.rc b/winpcap/packetNtx/Dll/WanPacket/version.rc new file mode 100644 index 0000000..2ef755d --- /dev/null +++ b/winpcap/packetNtx/Dll/WanPacket/version.rc @@ -0,0 +1,64 @@ +// Microsoft Visual C++ generated resource script. +// + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#include ""version.rc2""\r\n" + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "Version.rc2" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/winpcap/packetNtx/Dll/WanPacket/version.rc2 b/winpcap/packetNtx/Dll/WanPacket/version.rc2 new file mode 100644 index 0000000..d25ab6e --- /dev/null +++ b/winpcap/packetNtx/Dll/WanPacket/version.rc2 @@ -0,0 +1,45 @@ +// +// WinPcapOem.rc2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +#include "..\..\..\version.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION WINPCAP_MAJOR,WINPCAP_MINOR,WINPCAP_REV,WINPCAP_BUILD + PRODUCTVERSION WINPCAP_MAJOR,WINPCAP_MINOR,WINPCAP_REV,WINPCAP_BUILD + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", WINPCAP_COMPANY_NAME + VALUE "FileDescription", "WinPcap low level NetMon wrapper library" + VALUE "FileVersion", WINPCAP_VER_STRING + VALUE "InternalName", "WanPacket.dll" + VALUE "LegalCopyright", WINPCAP_WANPACKET_COPYRIGHT_STRING + VALUE "LegalTrademarks", "" + VALUE "OriginalFilename", "WanPacket.dll" + VALUE "ProductName", WINPCAP_PRODUCT_NAME + VALUE "ProductVersion", WINPCAP_VER_STRING + VALUE "Build Description", WINPCAP_BUILD_DESCRIPTION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/winpcap/packetNtx/Dll/debug.h b/winpcap/packetNtx/Dll/debug.h new file mode 100644 index 0000000..d6055ff --- /dev/null +++ b/winpcap/packetNtx/Dll/debug.h @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2005 - 2006 + * CACE Technologies LLC, Davis (CA) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the company (CACE Technologies LLC) nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __PACKET_DEBUG_393073863432093179878957 +#define __PACKET_DEBUG_393073863432093179878957 + +#ifdef _DEBUG_TO_FILE + +#include +#include + +extern CHAR g_LogFileName[1024]; + +#pragma warning(push) +#pragma warning(disable : 4127) + +static VOID OutputDebugStringVA(LPCSTR Format, ...) +{ + FILE *f; + SYSTEMTIME LocalTime; + va_list Marker; + DWORD dwThreadId; + int loops = 0; + DWORD dwLastError = GetLastError(); + + dwThreadId = GetCurrentThreadId(); + + va_start( Marker, Format ); /* Initialize variable arguments. */ + + GetLocalTime(&LocalTime); + + do + { + + f = fopen(g_LogFileName, "a"); + + if (f != NULL) + break; + + Sleep(0); + loops++; + + if (loops > 10) + { + SetLastError(dwLastError); + return; + } + } + while(1); + + fprintf(f, "[%.08X] %.04u-%.02u-%.02u %.02u:%02u:%02u ", + dwThreadId, + LocalTime.wYear, + LocalTime.wMonth, + LocalTime.wDay, + LocalTime.wHour, + LocalTime.wMinute, + LocalTime.wSecond); + vfprintf(f, Format, Marker); + + fclose(f); + + + SetLastError(dwLastError); +} + +#pragma warning(pop) + +#elif defined (_DBG) + +#include + +static VOID OutputDebugStringVA(LPCSTR Format, ...) +{ + va_list Marker; + CHAR string[1024]; + DWORD dwLastError = GetLastError(); + + va_start( Marker, Format ); /* Initialize variable arguments. */ + + StringCchVPrintfA(string, sizeof(string), Format, Marker); + + OutputDebugStringA(string); + + va_end(Marker); + + SetLastError(dwLastError); +} +#endif + + +#if defined(_DBG) || defined(_DEBUG_TO_FILE) + +#ifdef _DBG +#define TRACE_PRINT_DLLMAIN(_x) OutputDebugStringVA (" " _x "\n") +#else +#define TRACE_PRINT_DLLMAIN(_x) //we cannot use the _DEBUG_TO_FILE stuff from DllMain!! +#endif + +#define TRACE_ENTER(_x) OutputDebugStringVA ("--> " _x "\n") +#define TRACE_EXIT(_x) OutputDebugStringVA ("<-- " _x "\n") +#define TRACE_PRINT(_x) OutputDebugStringVA (" " _x "\n") +#define TRACE_PRINT1(_x, _y) OutputDebugStringVA(" " _x "\n", _y) +#define TRACE_PRINT2(_x, _p1, _p2) OutputDebugStringVA(" " _x "\n", _p1, _p2) +#define TRACE_PRINT4(_x, _p1, _p2, _p3, _p4) OutputDebugStringVA(" " _x "\n", _p1, _p2, _p3, _p4) +#define TRACE_PRINT6(_x, _p1, _p2, _p3, _p4, _p5, _p6) OutputDebugStringVA(" " _x "\n", _p1, _p2, _p3, _p4, _p5, _p6 ) + +static __forceinline void TRACE_PRINT_OS_INFO() +{ + HKEY hKey; + CHAR buffer[1024]; + DWORD size = sizeof(buffer); + DWORD type; + DWORD dwLastError; + + dwLastError = GetLastError(); + + TRACE_PRINT("********************* OS info.*********************"); + buffer[size-1] = 0; + size = sizeof(buffer); + if( RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + if (RegQueryValueExA(hKey, "PROCESSOR_ARCHITECTURE", 0, &type, (LPBYTE)buffer, &size) == ERROR_SUCCESS && type == REG_SZ) + { + OutputDebugStringVA("Architecture = %s\n", buffer); + } + else + { + OutputDebugStringVA("Architecture = \n"); + } + + RegCloseKey(hKey); + } + else + { + OutputDebugStringVA("Architecture = \n"); + } + + buffer[size-1] = 0; + size = sizeof(buffer); + + if( RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + if (RegQueryValueExA(hKey, "CurrentVersion", 0, &type, (LPBYTE)buffer, &size) == ERROR_SUCCESS && type == REG_SZ) + { + OutputDebugStringVA("Windows version = %s\n", buffer); + } + else + { + OutputDebugStringVA("Windows version = \n"); + } + + RegCloseKey(hKey); + } + else + { + OutputDebugStringVA("Windows version = \n"); + } + + buffer[size-1] = 0; + size = sizeof(buffer); + if( RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + if (RegQueryValueExA(hKey, "CurrentType", 0, &type, (LPBYTE)buffer, &size) == ERROR_SUCCESS && type == REG_SZ) + { + OutputDebugStringVA("Windows CurrentType = %s\n", buffer); + } + else + { + OutputDebugStringVA("Windows CurrentType = \n"); + } + + RegCloseKey(hKey); + } + else + { + OutputDebugStringVA("Windows CurrentType = \n"); + } + + OutputDebugStringVA("*************************************************** \n"); + + SetLastError(dwLastError); +} +#else + +#define TRACE_ENTER(_x) +#define TRACE_PRINT_DLLMAIN(_x) +#define TRACE_EXIT(_x) +#define TRACE_PRINT(_x) +#define TRACE_PRINT1(_x, _y) +#define TRACE_PRINT2(_x, _p1, _p2) +#define TRACE_PRINT4(_x, _p1, _p2, _p3, _p4) +#define TRACE_PRINT6(_x, _p1, _p2, _p3, _p4, _p5, _p6) +#define TRACE_PRINT_OS_INFO() + +#endif + + + +#endif //__PACKET_DEBUG_393073863432093179878957 diff --git a/winpcap/packetNtx/Dll/strsafe.h b/winpcap/packetNtx/Dll/strsafe.h new file mode 100644 index 0000000..2a3be0e --- /dev/null +++ b/winpcap/packetNtx/Dll/strsafe.h @@ -0,0 +1,78 @@ +#ifndef __STRSAFE_GCC__383773443 +#define __STRSAFE_GCC__383773443 + +#include +#include +#include + +#ifdef _MSC_VER +#error Trying to use strsafe.h for GCC within Visual Studio +#endif + +static int vsnprintf(char *buffer,size_t count, const char *format, va_list argptr ) +{ + return vsprintf(buffer, format, argptr); +} + + +static void StringCchPrintfA(char *pszDest,size_t cbDest, char *pszFormat, ...) + { + va_list marker; + va_start( marker, pszFormat ); /* Initialize variable arguments. */ + + if (cbDest == 0 || pszDest == NULL || pszFormat == NULL) + return; + + + pszDest[cbDest - 1] = '\0'; + vsnprintf(pszDest, cbDest - 1, pszFormat, marker); + + va_end(marker); +} + +static void StringCchPrintfW( WCHAR *pszDest,size_t cbDest, WCHAR *pszFormat, ...) + { + va_list marker; + va_start( marker, pszFormat ); /* Initialize variable arguments. */ + + if (cbDest == 0 || pszDest == NULL || pszFormat == NULL) + return; + + + pszDest[cbDest - 1] = L'\0'; + _vsnwprintf(pszDest, cbDest - 1, pszFormat, marker); + + va_end(marker); +} + + +static void StringCchCopyA(char *pszDest,size_t cbDest, const char* pszSrc) +{ + if (cbDest == 0 || pszDest == NULL || pszSrc == NULL) + return; + + pszDest[cbDest - 1] = '\0'; + + strncpy(pszDest, pszSrc, cbDest - 1); + +} + +static void StringCchCatA(char* pszDest, size_t cbDest,const char* pszSrc) +{ + if (cbDest == 0 || pszDest == NULL || pszSrc == NULL) + return; + + pszDest[cbDest - 1] = '\0'; + + strncat(pszDest, pszSrc, cbDest - 1); + +} + +#ifdef UNICODE +#define StringCchPrintf StringCchPrintfW +#else +#define StringCchPrintf StringCchPrintfA +#endif + + +#endif diff --git a/winpcap/packetNtx/Dll/version.rc b/winpcap/packetNtx/Dll/version.rc new file mode 100644 index 0000000..2ef755d --- /dev/null +++ b/winpcap/packetNtx/Dll/version.rc @@ -0,0 +1,64 @@ +// Microsoft Visual C++ generated resource script. +// + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#include ""version.rc2""\r\n" + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "Version.rc2" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/winpcap/packetNtx/Dll/version.rc2 b/winpcap/packetNtx/Dll/version.rc2 new file mode 100644 index 0000000..8c81f6e --- /dev/null +++ b/winpcap/packetNtx/Dll/version.rc2 @@ -0,0 +1,51 @@ +// +// WinPcapOem.rc2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +#include "..\..\version.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION WINPCAP_MAJOR,WINPCAP_MINOR,WINPCAP_REV,WINPCAP_BUILD + PRODUCTVERSION WINPCAP_MAJOR,WINPCAP_MINOR,WINPCAP_REV,WINPCAP_BUILD + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", WINPCAP_COMPANY_NAME +#ifdef _WINNT4 + VALUE "FileDescription", "packet.dll (NT4) Dynamic Link Library" +#elif defined(_WINVISTA) + VALUE "FileDescription", "packet.dll (Vista) Dynamic Link Library" +#else + VALUE "FileDescription", "packet.dll (NT5) Dynamic Link Library" +#endif + VALUE "FileVersion", WINPCAP_VER_STRING + VALUE "InternalName", "packet.dll" + VALUE "LegalCopyright", WINPCAP_COPYRIGHT_STRING + VALUE "LegalTrademarks", "" + VALUE "OriginalFilename", "packet.dll" + VALUE "ProductName", WINPCAP_PRODUCT_NAME + VALUE "ProductVersion", WINPCAP_VER_STRING + VALUE "Build Description", WINPCAP_BUILD_DESCRIPTION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/winpcap/packetNtx/driver/DEBUG.H b/winpcap/packetNtx/driver/DEBUG.H new file mode 100644 index 0000000..790c32c --- /dev/null +++ b/winpcap/packetNtx/driver/DEBUG.H @@ -0,0 +1,108 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __DEBUG_INCLUDE +#define __DEBUG_INCLUDE + + +#if DBG + +#define IF_PACKETDEBUG(f) if (PacketDebugFlag & (f)) +extern ULONG PacketDebugFlag; + +#define PACKET_DEBUG_LOUD 0x00000001 // debugging info +#define PACKET_DEBUG_VERY_LOUD 0x00000002 // excessive debugging info + +#define PACKET_DEBUG_INIT 0x00000100 // init debugging info + +// +// unfortunately, NT4 does not have the __FUNCTION__ macro, so we define it as null +// +#ifndef __FUNCTION__ +#define __FUNCTION__ +#endif + +// +// Macro for deciding whether to dump lots of debugging information. +// + +#define IF_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_LOUD ) { A } +#define IF_VERY_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) { A } +#define IF_INIT_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_INIT ) { A } + +#define TRACE_ENTER() DbgPrint("--> " __FUNCTION__) +#define TRACE_EXIT() DbgPrint("<-- " __FUNCTION__) +#define TRACE_MESSAGE(__level__, __message__) do{ if (PacketDebugFlag & (__level__)) DbgPrint(" " __FUNCTION__ ": " __message__);} while(FALSE) + +#define TRACE_MESSAGE1(__level__, __message__, __p1__) do \ + { \ + if (PacketDebugFlag & (__level__)) \ + DbgPrint(" " __FUNCTION__ ": " __message__, __p1__); \ + } while(FALSE) + +#define TRACE_MESSAGE2(__level__, __message__, __p1__, __p2__) do \ + { \ + if (PacketDebugFlag & (__level__)) \ + DbgPrint(" " __FUNCTION__ ": " __message__, __p1__, __p2__); \ + } while(FALSE) + +#define TRACE_MESSAGE3(__level__, __message__, __p1__, __p2__, __p3__) do \ + { \ + if (PacketDebugFlag & (__level__)) \ + DbgPrint(" " __FUNCTION__ ": " __message__, __p1__, __p2__, __p3__); \ + } while(FALSE) + +#define TRACE_MESSAGE4(__level__, __message__, __p1__, __p2__, __p3__, __p4__) do \ + { \ + if (PacketDebugFlag & (__level__)) \ + DbgPrint(" " __FUNCTION__ ": " __message__, __p1__, __p2__, __p3__, __p4__ ); \ + } while(FALSE) + + +#else //DBG + +#define IF_LOUD(A) +#define IF_VERY_LOUD(A) +#define IF_INIT_LOUD(A) + +#define TRACE_ENTER() +#define TRACE_EXIT() +#define TRACE_MESSAGE(__level__, __message__) +#define TRACE_MESSAGE1(__level__, __message__, __p1__) +#define TRACE_MESSAGE2(__level__, __message__, __p1__, __p2__) +#define TRACE_MESSAGE3(__level__, __message__, __p1__, __p2__, __p3__) +#define TRACE_MESSAGE4(__level__, __message__, __p1__, __p2__, __p3__, __p4__) + +#endif + +#endif /*#define __DEBUG_INCLUDE*/ diff --git a/winpcap/packetNtx/driver/MAKEFILE b/winpcap/packetNtx/driver/MAKEFILE new file mode 100644 index 0000000..9c985f5 --- /dev/null +++ b/winpcap/packetNtx/driver/MAKEFILE @@ -0,0 +1,7 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the driver components of the Windows NT DDK +# + +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/winpcap/packetNtx/driver/NPF.RC b/winpcap/packetNtx/driver/NPF.RC new file mode 100644 index 0000000..e499335 --- /dev/null +++ b/winpcap/packetNtx/driver/NPF.RC @@ -0,0 +1,48 @@ +#include "windows.h" +#include "..\..\version.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// +VS_VERSION_INFO VERSIONINFO + FILEVERSION WINPCAP_MAJOR,WINPCAP_MINOR,WINPCAP_REV,WINPCAP_BUILD + PRODUCTVERSION WINPCAP_MAJOR,WINPCAP_MINOR,WINPCAP_REV,WINPCAP_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x3L + FILESUBTYPE 0x7L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", WINPCAP_COMPANY_NAME +#ifdef __NPF_NT4__ + VALUE "FileDescription", "npf.sys (NT4) Kernel Driver" +#elif defined(_AMD64_) + VALUE "FileDescription", "npf.sys (NT5/6 AMD64) Kernel Driver" +#else + VALUE "FileDescription", "npf.sys (NT5/6 x86) Kernel Driver" +#endif + VALUE "FileVersion", WINPCAP_VER_STRING + VALUE "InternalName", "NPF + TME" + VALUE "LegalCopyright", WINPCAP_COPYRIGHT_STRING + VALUE "LegalTrademarks", "" + VALUE "OriginalFilename", "npf.sys" + VALUE "ProductName", WINPCAP_PRODUCT_NAME + VALUE "ProductVersion", WINPCAP_VER_STRING + VALUE "Build Description", WINPCAP_BUILD_DESCRIPTION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + diff --git a/winpcap/packetNtx/driver/Openclos.c b/winpcap/packetNtx/driver/Openclos.c new file mode 100644 index 0000000..82e5a6e --- /dev/null +++ b/winpcap/packetNtx/driver/Openclos.c @@ -0,0 +1,894 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2007 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include "debug.h" +#include "packet.h" +#include "..\..\Common\WpcapNames.h" + + +static NDIS_MEDIUM MediumArray[] = { + NdisMedium802_3, +// NdisMediumWan, + NdisMediumFddi, + NdisMediumArcnet878_2, + NdisMediumAtm, + NdisMedium802_5 +}; + +#define NUM_NDIS_MEDIA (sizeof MediumArray / sizeof MediumArray[0]) + +//Itoa. Replaces the buggy RtlIntegerToUnicodeString +void PacketItoa(UINT n,PUCHAR buf){ +int i; + + for(i=0;i<20;i+=2){ + buf[18-i]=(n%10)+48; + buf[19-i]=0; + n/=10; + } + +} + +/// Global start time. Used as an absolute reference for timestamp conversion. +struct time_conv G_Start_Time = { + 0, + {0, 0}, +}; + +ULONG g_NumOpenedInstances = 0; + +BOOLEAN NPF_StartUsingBinding( + IN POPEN_INSTANCE pOpen) +{ + ASSERT(pOpen != NULL); + ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); + + NdisAcquireSpinLock(&pOpen->AdapterHandleLock); + + if (pOpen->AdapterBindingStatus != ADAPTER_BOUND) + { + NdisReleaseSpinLock(&pOpen->AdapterHandleLock); + return FALSE; + } + + pOpen->AdapterHandleUsageCounter++; + + NdisReleaseSpinLock(&pOpen->AdapterHandleLock); + + return TRUE; +} + +VOID NPF_StopUsingBinding( + IN POPEN_INSTANCE pOpen) +{ + ASSERT(pOpen != NULL); +// +// There is no risk in calling this function from abobe passive level +// (i.e. DISPATCH, in this driver) as we acquire a spinlock and decrement a +// counter. +// +// ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); + + NdisAcquireSpinLock(&pOpen->AdapterHandleLock); + + ASSERT(pOpen->AdapterHandleUsageCounter > 0); + ASSERT(pOpen->AdapterBindingStatus == ADAPTER_BOUND); + + pOpen->AdapterHandleUsageCounter--; + + NdisReleaseSpinLock(&pOpen->AdapterHandleLock); +} + +VOID +NPF_CloseBinding( + IN POPEN_INSTANCE pOpen) +{ + NDIS_EVENT Event; + NDIS_STATUS Status; + + ASSERT(pOpen != NULL); + ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); + + NdisInitializeEvent(&Event); + NdisResetEvent(&Event); + + NdisAcquireSpinLock(&pOpen->AdapterHandleLock); + + while(pOpen->AdapterHandleUsageCounter > 0) + { + NdisReleaseSpinLock(&pOpen->AdapterHandleLock); + NdisWaitEvent(&Event,1); + NdisAcquireSpinLock(&pOpen->AdapterHandleLock); + } + + // + // now the UsageCounter is 0 + // + + while(pOpen->AdapterBindingStatus == ADAPTER_UNBINDING) + { + NdisReleaseSpinLock(&pOpen->AdapterHandleLock); + NdisWaitEvent(&Event,1); + NdisAcquireSpinLock(&pOpen->AdapterHandleLock); + } + + // + // now the binding status is either bound or unbound + // + + if (pOpen->AdapterBindingStatus == ADAPTER_UNBOUND) + { + NdisReleaseSpinLock(&pOpen->AdapterHandleLock); + return; + } + + ASSERT(pOpen->AdapterBindingStatus == ADAPTER_BOUND); + + pOpen->AdapterBindingStatus = ADAPTER_UNBINDING; + + NdisReleaseSpinLock(&pOpen->AdapterHandleLock); + + // + // do the release procedure + // + NdisResetEvent(&pOpen->NdisOpenCloseCompleteEvent); + + // Close the adapter + NdisCloseAdapter( + &Status, + pOpen->AdapterHandle + ); + + if (Status == NDIS_STATUS_PENDING) + { + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Pending NdisCloseAdapter"); + NdisWaitEvent(&pOpen->NdisOpenCloseCompleteEvent, 0); + } + else + { + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Not Pending NdisCloseAdapter"); + } + + NdisAcquireSpinLock(&pOpen->AdapterHandleLock); + pOpen->AdapterBindingStatus = ADAPTER_UNBOUND; + NdisReleaseSpinLock(&pOpen->AdapterHandleLock); +} + +//------------------------------------------------------------------- + +NTSTATUS NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) +{ + + PDEVICE_EXTENSION DeviceExtension; + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + NDIS_STATUS Status; + NDIS_STATUS ErrorStatus; + UINT i; + PUCHAR tpointer; + PLIST_ENTRY PacketListEntry; + NTSTATUS returnStatus; + +// +// Old registry based WinPcap names +// +// WCHAR EventPrefix[MAX_WINPCAP_KEY_CHARS]; +// UINT RegStrLen; + + TRACE_ENTER(); + + DeviceExtension = DeviceObject->DeviceExtension; + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + // allocate some memory for the open structure + Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), '0OWA'); + + if (Open==NULL) { + // no memory + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory( + Open, + sizeof(OPEN_INSTANCE) + ); + +// +// Old registry based WinPcap names +// +// // +// // Get the Event names base from the registry +// // +// RegStrLen = sizeof(EventPrefix)/sizeof(EventPrefix[0]); +// +// NPF_QueryWinpcapRegistryString(NPF_EVENTS_NAMES_REG_KEY_WC, +// EventPrefix, +// RegStrLen, +// NPF_EVENTS_NAMES_WIDECHAR); +// + + Open->DeviceExtension=DeviceExtension; + + // Allocate a packet pool for our xmit and receive packets + NdisAllocatePacketPool( + &Status, + &Open->PacketPool, + TRANSMIT_PACKETS, + sizeof(PACKET_RESERVED)); + + if (Status != NDIS_STATUS_SUCCESS) { + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Failed to allocate packet pool"); + + ExFreePool(Open); + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + NdisInitializeEvent(&Open->WriteEvent); + NdisInitializeEvent(&Open->NdisRequestEvent); + NdisInitializeEvent(&Open->NdisWriteCompleteEvent); + NdisInitializeEvent(&Open->DumpEvent); + NdisAllocateSpinLock(&Open->MachineLock); + NdisAllocateSpinLock(&Open->WriteLock); + Open->WriteInProgress = FALSE; + + for (i = 0; i < NCpu; i++) + { + NdisAllocateSpinLock(&Open->CpuData[i].BufferLock); + } + + NdisInitializeEvent(&Open->NdisOpenCloseCompleteEvent); + + // list to hold irp's want to reset the adapter + InitializeListHead(&Open->ResetIrpList); + + // Initialize the request list + KeInitializeSpinLock(&Open->RequestSpinLock); + InitializeListHead(&Open->RequestList); + + // Initializes the extended memory of the NPF machine + Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, '2OWA'); + if((Open->mem_ex.buffer) == NULL) + { + // + // no memory + // + ExFreePool(Open); + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Open->mem_ex.size = DEFAULT_MEM_EX_SIZE; + RtlZeroMemory(Open->mem_ex.buffer, DEFAULT_MEM_EX_SIZE); + + // + // Initialize the open instance + // + Open->bpfprogram = NULL; //reset the filter + Open->mode = MODE_CAPT; + Open->Nbytes.QuadPart = 0; + Open->Npackets.QuadPart = 0; + Open->Nwrites = 1; + Open->Multiple_Write_Counter = 0; + Open->MinToCopy = 0; + Open->TimeOut.QuadPart = (LONGLONG)1; + Open->DumpFileName.Buffer = NULL; + Open->DumpFileHandle = NULL; + Open->tme.active = TME_NONE_ACTIVE; + Open->DumpLimitReached = FALSE; + Open->MaxFrameSize = 0; + Open->WriterSN=0; + Open->ReaderSN=0; + Open->Size=0; + Open->SkipSentPackets = FALSE; + Open->ReadEvent = NULL; + + // + //allocate the spinlock for the statistic counters + // + NdisAllocateSpinLock(&Open->CountersLock); + + // + // link up the request stored in our open block + // + for (i = 0 ; i < MAX_REQUESTS ; i++ ) + { + NdisInitializeEvent(&Open->Requests[i].InternalRequestCompletedEvent); + + ExInterlockedInsertTailList( + &Open->RequestList, + &Open->Requests[i].ListElement, + &Open->RequestSpinLock); + } + + NdisResetEvent(&Open->NdisOpenCloseCompleteEvent); + + // + // set the proper binding flags before trying to open the MAC + // + Open->AdapterBindingStatus = ADAPTER_BOUND; + Open->AdapterHandleUsageCounter = 0; + NdisAllocateSpinLock(&Open->AdapterHandleLock); + + // + // Try to open the MAC + // + TRACE_MESSAGE2(PACKET_DEBUG_LOUD,"Opening the device %ws, BindingContext=%p",DeviceExtension->AdapterName.Buffer, Open); + + returnStatus = STATUS_SUCCESS; + + NdisOpenAdapter( + &Status, + &ErrorStatus, + &Open->AdapterHandle, + &Open->Medium, + MediumArray, + NUM_NDIS_MEDIA, + DeviceExtension->NdisProtocolHandle, + Open, + &DeviceExtension->AdapterName, + 0, + NULL); + + TRACE_MESSAGE1(PACKET_DEBUG_LOUD,"Opened the device, Status=%x",Status); + + if (Status == NDIS_STATUS_PENDING) + { + NdisWaitEvent(&Open->NdisOpenCloseCompleteEvent, 0); + + if (!NT_SUCCESS(Open->OpenCloseStatus)) + { + returnStatus = Open->OpenCloseStatus; + } + else + { + returnStatus = STATUS_SUCCESS; + } + } + else + { + // + // request not pending, we know the result, and OpenComplete has not been called. + // + if (Status == NDIS_STATUS_SUCCESS) + { + returnStatus = STATUS_SUCCESS; + } + else + { + // + // this is not completely correct, as we are converting an NDIS_STATUS to a NTSTATUS + // + returnStatus = Status; + + } + } + + if (returnStatus == STATUS_SUCCESS) + { + ULONG localNumOpenedInstances; + // + // complete the open + // + localNumOpenedInstances = InterlockedIncrement(&g_NumOpenedInstances); + + TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Opened Instances: %u", localNumOpenedInstances); + + // Get the absolute value of the system boot time. + // This is used for timestamp conversion. + TIME_SYNCHRONIZE(&G_Start_Time); + + returnStatus = NPF_GetDeviceMTU(Open, Irp, &Open->MaxFrameSize); + + if (!NT_SUCCESS(returnStatus)) + { + // + // Close the binding + // + NPF_CloseBinding(Open); + } + } + + if (!NT_SUCCESS(returnStatus)) + { + NPF_CloseOpenInstance(Open); + } + else + { + // Save or open here + IrpSp->FileObject->FsContext=Open; + } + + Irp->IoStatus.Status = returnStatus; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + TRACE_EXIT(); + return returnStatus; +} + +VOID +NPF_CloseOpenInstance(POPEN_INSTANCE pOpen) +{ + PKEVENT pEvent; + UINT i; + + TRACE_ENTER(); + + ASSERT(pOpen != NULL); + ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); + + TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Open= %p", pOpen); + + NdisFreePacketPool(pOpen->PacketPool); + + // + // free mem_ex + // + pOpen->mem_ex.size = 0; + if(pOpen->mem_ex.buffer != NULL) + ExFreePool(pOpen->mem_ex.buffer); + + // + // Free the filter if it's present + // + if(pOpen->bpfprogram != NULL) + ExFreePool(pOpen->bpfprogram); + +// +// Jitted filters are supported on x86 (32bit) only +// +#ifdef _X86_ + // Free the jitted filter if it's present + if(pOpen->Filter != NULL) + BPF_Destroy_JIT_Filter(pOpen->Filter); +#endif //_X86_ + + // + // Dereference the read event. + // + + if (pOpen->ReadEvent != NULL) + ObDereferenceObject(pOpen->ReadEvent); + + // + // free the buffer + // NOTE: the buffer is fragmented among the various CPUs, but the base pointer of the + // allocated chunk of memory is stored in the first slot (pOpen->CpuData[0]) + // + if (pOpen->Size > 0) + ExFreePool(pOpen->CpuData[0].Buffer); + + // + // free the per CPU spinlocks + // + for (i = 0; i < NCpu; i++) + { + NdisFreeSpinLock(&Open->CpuData[i].BufferLock); + } + + // + // Free the string with the name of the dump file + // + if(pOpen->DumpFileName.Buffer!=NULL) + ExFreePool(pOpen->DumpFileName.Buffer); + + // + // Free the open instance itself + // + ExFreePool(pOpen); + + TRACE_EXIT(); +} + + +//------------------------------------------------------------------- + +VOID NPF_OpenAdapterComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN NDIS_STATUS OpenErrorStatus) +{ + + POPEN_INSTANCE Open; + PLIST_ENTRY RequestListEntry; + PINTERNAL_REQUEST MaxSizeReq; + NDIS_STATUS ReqStatus; + + TRACE_ENTER(); + + Open = (POPEN_INSTANCE)ProtocolBindingContext; + + ASSERT(Open != NULL); + + if (Status != NDIS_STATUS_SUCCESS) + { + // + // this is not completely correct, as we are converting an NDIS_STATUS to a NTSTATUS + // + Open->OpenCloseStatus = Status; + } + else + { + Open->OpenCloseStatus = STATUS_SUCCESS; + } + + // + // wake up the caller of NdisOpen, that is NPF_Open + // + NdisSetEvent(&Open->NdisOpenCloseCompleteEvent); + + TRACE_EXIT(); +} + +NTSTATUS +NPF_GetDeviceMTU( + IN POPEN_INSTANCE pOpen, + IN PIRP pIrp, + OUT PUINT pMtu) +{ + PLIST_ENTRY RequestListEntry; + PINTERNAL_REQUEST MaxSizeReq; + NDIS_STATUS ReqStatus; + + TRACE_ENTER(); + + ASSERT(pOpen != NULL); + ASSERT(pIrp != NULL); + ASSERT(pMtu != NULL); + + // Extract a request from the list of free ones + RequestListEntry = ExInterlockedRemoveHeadList(&pOpen->RequestList, &pOpen->RequestSpinLock); + + if (RequestListEntry == NULL) + { + // + // THIS IS WRONG + // + + // + // Assume Ethernet + // + *pMtu = 1514; + TRACE_EXIT(); + return STATUS_SUCCESS; + } + + MaxSizeReq = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement); + + MaxSizeReq->Request.RequestType = NdisRequestQueryInformation; + MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE; + + MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBuffer = pMtu; + MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(*pMtu); + + NdisResetEvent(&MaxSizeReq->InternalRequestCompletedEvent); + + // submit the request + NdisRequest( + &ReqStatus, + pOpen->AdapterHandle, + &MaxSizeReq->Request); + + if (ReqStatus == NDIS_STATUS_PENDING) + { + NdisWaitEvent(&MaxSizeReq->InternalRequestCompletedEvent, 0); + ReqStatus = MaxSizeReq->RequestStatus; + } + + // + // Put the request in the list of the free ones + // + ExInterlockedInsertTailList(&pOpen->RequestList, &MaxSizeReq->ListElement, &pOpen->RequestSpinLock); + + if (ReqStatus == NDIS_STATUS_SUCCESS) + { + TRACE_EXIT(); + return STATUS_SUCCESS; + } + else + { + // + // THIS IS WRONG + // + + // + // Assume Ethernet + // + *pMtu = 1514; + + TRACE_EXIT(); + return STATUS_SUCCESS; + + // return ReqStatus; + } +} + + +//------------------------------------------------------------------- +NTSTATUS +NPF_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) +{ + TRACE_ENTER(); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + TRACE_EXIT(); + return STATUS_SUCCESS; +} + +//------------------------------------------------------------------- +NTSTATUS +NPF_Cleanup(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) +{ + + POPEN_INSTANCE Open; + NDIS_STATUS Status; + PIO_STACK_LOCATION IrpSp; + LARGE_INTEGER ThreadDelay; + ULONG localNumOpenInstances; + + TRACE_ENTER(); + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + Open = IrpSp->FileObject->FsContext; + + TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Open = %p\n", Open); + + ASSERT(Open != NULL); + + if (Open->ReadEvent != NULL) + KeSetEvent(Open->ReadEvent,0,FALSE); + + NPF_CloseBinding(Open); + + // NOTE: + // code commented out because the kernel dump feature is disabled + // + //if (AdapterAlreadyClosing == FALSE) + //{ + + // + // Unfreeze the consumer + // + // if(Open->mode & MODE_DUMP) + // NdisSetEvent(&Open->DumpEvent); + // else + // KeSetEvent(Open->ReadEvent,0,FALSE); + + // // + // // If this instance is in dump mode, complete the dump and close the file + // // + // if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL) + // { + // NTSTATUS wres; + + // ThreadDelay.QuadPart = -50000000; + + // // + // // Wait the completion of the thread + // // + // wres = KeWaitForSingleObject(Open->DumpThreadObject, + // UserRequest, + // KernelMode, + // TRUE, + // &ThreadDelay); + + // ObDereferenceObject(Open->DumpThreadObject); + + // // + // // Flush and close the dump file + // // + // NPF_CloseDumpFile(Open); + // } + //} + + + // + // release all the resources + // + NPF_CloseOpenInstance(Open); + + IrpSp->FileObject->FsContext = NULL; + + // + // Decrease the counter of open instances + // + localNumOpenInstances = InterlockedDecrement(&g_NumOpenedInstances); + TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Opened Instances: %u", localNumOpenInstances); + + if(localNumOpenInstances == 0) + { + // + // Force a synchronization at the next NPF_Open(). + // This hopefully avoids the synchronization issues caused by hibernation or standby. + // + TIME_DESYNCHRONIZE(&G_Start_Time); + } + + + // + // and complete the IRP with status success + // + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + TRACE_EXIT(); + + return(STATUS_SUCCESS); +} + +//------------------------------------------------------------------- + +VOID +NPF_CloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status) +{ + POPEN_INSTANCE Open; + PIRP Irp; + + TRACE_ENTER(); + + Open = (POPEN_INSTANCE)ProtocolBindingContext; + + ASSERT(Open != NULL); + + TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Open= %p", Open); + + NdisSetEvent(&Open->NdisOpenCloseCompleteEvent); + + TRACE_EXIT(); + return; + +} +//------------------------------------------------------------------- + +#ifdef NDIS50 +NDIS_STATUS +NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent) +{ + TRACE_ENTER(); + + TIME_DESYNCHRONIZE(&G_Start_Time); + TIME_SYNCHRONIZE(&G_Start_Time); + + TRACE_EXIT(); + return STATUS_SUCCESS; +} +#endif + +//------------------------------------------------------------------- + +VOID +NPF_BindAdapter( + OUT PNDIS_STATUS Status, + IN NDIS_HANDLE BindContext, + IN PNDIS_STRING DeviceName, + IN PVOID SystemSpecific1, + IN PVOID SystemSpecific2 + ) +{ + TRACE_ENTER(); + TRACE_EXIT(); +} + +//------------------------------------------------------------------- + +VOID +NPF_UnbindAdapter( + OUT PNDIS_STATUS Status, + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_HANDLE UnbindContext + ) +{ + POPEN_INSTANCE Open =(POPEN_INSTANCE)ProtocolBindingContext; + + TRACE_ENTER(); + + ASSERT(Open != NULL); + + // + // The following code has been disabled bcause the kernel dump feature has been disabled. + // + //// + //// Awake a possible pending read on this instance + //// TODO should be ok. + //// + // if(Open->mode & MODE_DUMP) + // NdisSetEvent(&Open->DumpEvent); + // else + if (Open->ReadEvent != NULL) + KeSetEvent(Open->ReadEvent,0,FALSE); + + // + // The following code has been disabled bcause the kernel dump feature has been disabled. + // + //// + //// If this instance is in dump mode, complete the dump and close the file + //// TODO needs to be checked again. + //// + // if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL) + // NPF_CloseDumpFile(Open); + + *Status = NDIS_STATUS_SUCCESS; + + NPF_CloseBinding(Open); + + TRACE_EXIT(); + return; +} + +//------------------------------------------------------------------- + +VOID +NPF_ResetComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status) + +{ + POPEN_INSTANCE Open; + PIRP Irp; + + PLIST_ENTRY ResetListEntry; + + TRACE_ENTER(); + + Open = (POPEN_INSTANCE)ProtocolBindingContext; + + // + // remove the reset IRP from the list + // + ResetListEntry=ExInterlockedRemoveHeadList( + &Open->ResetIrpList, + &Open->RequestSpinLock + ); + + Irp=CONTAINING_RECORD(ResetListEntry,IRP,Tail.Overlay.ListEntry); + + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + TRACE_EXIT(); + + return; + +} diff --git a/winpcap/packetNtx/driver/Packet.c b/winpcap/packetNtx/driver/Packet.c new file mode 100644 index 0000000..6671c9e --- /dev/null +++ b/winpcap/packetNtx/driver/Packet.c @@ -0,0 +1,2071 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2007 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include "debug.h" +#include "packet.h" +#include "win_bpf.h" +#include "win_bpf_filter_init.h" +#include "..\..\Common\WpcapNames.h" + + +#if DBG +// Declare the global debug flag for this driver. +ULONG PacketDebugFlag = PACKET_DEBUG_LOUD; + +#endif + +PDEVICE_EXTENSION GlobalDeviceExtension; + +// +// Global strings +// +WCHAR g_NPF_PrefixBuffer[MAX_WINPCAP_KEY_CHARS] = NPF_DEVICE_NAMES_PREFIX_WIDECHAR; +// +// Old registry based WinPcap names +// +//WCHAR g_NPF_PrefixBuffer[MAX_WINPCAP_KEY_CHARS]; +NDIS_STRING g_NPF_Prefix; +NDIS_STRING devicePrefix = NDIS_STRING_CONST("\\Device\\"); +NDIS_STRING symbolicLinkPrefix = NDIS_STRING_CONST("\\DosDevices\\"); +NDIS_STRING tcpLinkageKeyName = NDIS_STRING_CONST("\\Registry\\Machine\\System" + L"\\CurrentControlSet\\Services\\Tcpip\\Linkage"); +NDIS_STRING AdapterListKey = NDIS_STRING_CONST("\\Registry\\Machine\\System" + L"\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"); +NDIS_STRING bindValueName = NDIS_STRING_CONST("Bind"); +NDIS_STRING g_WinpcapGlobalKey = NDIS_STRING_CONST("\\Registry\\Machine\\" WINPCAP_INSTANCE_KEY_WIDECHAR); +//NDIS_STRING g_WinpcapGlobalKey = NDIS_STRING_CONST("\\Registry\\Machine\\" WINPCAP_GLOBAL_KEY_WIDECHAR); + +/// Global variable that points to the names of the bound adapters +WCHAR* bindP = NULL; + +extern struct time_conv G_Start_Time; // from openclos.c + +ULONG NCpu; + +ULONG TimestampMode; +UINT g_SendPacketFlags = 0; + +static VOID NPF_ResetBufferContents(POPEN_INSTANCE Open); + +// +// Packet Driver's entry routine. +// +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +{ + NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar; + UNICODE_STRING MacDriverName; + UNICODE_STRING UnicodeDeviceName; + PDEVICE_OBJECT DeviceObject = NULL; + PDEVICE_EXTENSION DeviceExtension = NULL; + NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS ErrorCode = STATUS_SUCCESS; + NDIS_STRING ProtoName = NDIS_STRING_CONST("PacketDriver"); + ULONG DevicesCreated=0; + PWSTR BindString; + PWSTR ExportString; + PWSTR BindStringSave; + PWSTR ExportStringSave; + NDIS_HANDLE NdisProtocolHandle; + WCHAR* bindT; + PKEY_VALUE_PARTIAL_INFORMATION tcpBindingsP; + UNICODE_STRING macName; +// +// Old registry based WinPcap names +// +// UINT RegStrLen; + ULONG OsMajorVersion, OsMinorVersion; + + TRACE_ENTER(); + +#ifndef __NPF_NT4__ + + TRACE_MESSAGE(PACKET_DEBUG_INIT, "DriverEntry -- NT4"); + + // + // Get OS version and store it in a global variable. + // For the moment we use the deprecated PsGetVersion() because the suggested + // RtlGetVersion() doesn't seem to exist in Windows 2000, and we don't want + // to have two separated drivers just for this call. + // Morever, the NT4 version of the driver just excludes this, since those flags + // are not available. + // + // Note: both RtlGetVersion() and PsGetVersion() are documented to always return success. + // + // OsVersion.dwOSVersionInfoSize = sizeof(OsVersion); + // RtlGetVersion(&OsVersion); + PsGetVersion(&OsMajorVersion, &OsMinorVersion, NULL, NULL); + TRACE_MESSAGE2(PACKET_DEBUG_INIT, "OS Version: %d.%d\n", OsMajorVersion, OsMinorVersion); + + // + // Define the correct flag to skip the loopback packets, according to the OS + // + if((OsMajorVersion == 5) && (OsMinorVersion == 0)) + { + // Windows 2000 wants both NDIS_FLAGS_DONT_LOOPBACK and NDIS_FLAGS_SKIP_LOOPBACK + g_SendPacketFlags = NDIS_FLAGS_DONT_LOOPBACK | NDIS_FLAGS_SKIP_LOOPBACK_W2K; + } + else + { + // Windows XP, 2003 and follwing want only NDIS_FLAGS_DONT_LOOPBACK + g_SendPacketFlags = NDIS_FLAGS_DONT_LOOPBACK; + } +#endif //__NPF_NT4__ + + // + // Set timestamp gathering method getting it from the registry + // + ReadTimeStampModeFromRegistry(RegistryPath); + + TRACE_MESSAGE1(PACKET_DEBUG_INIT,"%ws",RegistryPath->Buffer); + +// +// Old registry based WinPcap names +// +// // +// // Get the device names prefix from the registry +// // +// RegStrLen = sizeof(g_NPF_PrefixBuffer) / sizeof(g_NPF_PrefixBuffer[0]); +// +// NPF_QueryWinpcapRegistryString(NPF_DEVICES_PREFIX_REG_KEY_WC, +// g_NPF_PrefixBuffer, +// RegStrLen, +// NPF_DEVICE_NAMES_PREFIX_WIDECHAR); +// + NdisInitUnicodeString(&g_NPF_Prefix, g_NPF_PrefixBuffer); + + + // + // Get number of CPUs and save it + // + NCpu = NdisSystemProcessorCount(); + + RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); + + // + // Register as a protocol with NDIS + // +#ifdef NDIS50 + ProtocolChar.MajorNdisVersion = 5; +#else + ProtocolChar.MajorNdisVersion = 3; +#endif + ProtocolChar.MinorNdisVersion = 0; + ProtocolChar.Reserved = 0; + ProtocolChar.OpenAdapterCompleteHandler = NPF_OpenAdapterComplete; + ProtocolChar.CloseAdapterCompleteHandler = NPF_CloseAdapterComplete; + ProtocolChar.SendCompleteHandler = NPF_SendComplete; + ProtocolChar.TransferDataCompleteHandler = NPF_TransferDataComplete; + ProtocolChar.ResetCompleteHandler = NPF_ResetComplete; + ProtocolChar.RequestCompleteHandler = NPF_RequestComplete; + ProtocolChar.ReceiveHandler = NPF_tap; + ProtocolChar.ReceiveCompleteHandler = NPF_ReceiveComplete; + ProtocolChar.StatusHandler = NPF_Status; + ProtocolChar.StatusCompleteHandler = NPF_StatusComplete; +#ifdef NDIS50 + ProtocolChar.BindAdapterHandler = NPF_BindAdapter; + ProtocolChar.UnbindAdapterHandler = NPF_UnbindAdapter; + ProtocolChar.PnPEventHandler = NPF_PowerChange; + ProtocolChar.ReceivePacketHandler = NULL; +#endif + ProtocolChar.Name = ProtoName; + + NdisRegisterProtocol( + &Status, + &NdisProtocolHandle, + &ProtocolChar, + sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); + + if (Status != NDIS_STATUS_SUCCESS) { + + TRACE_MESSAGE(PACKET_DEBUG_INIT,"Failed to register protocol with NDIS"); + + TRACE_EXIT(); + return Status; + + } + + // + // Standard device driver entry points stuff. + // + DriverObject->MajorFunction[IRP_MJ_CREATE] = NPF_Open; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = NPF_Close; + DriverObject->MajorFunction[IRP_MJ_CLEANUP]= NPF_Cleanup; + DriverObject->MajorFunction[IRP_MJ_READ] = NPF_Read; + DriverObject->MajorFunction[IRP_MJ_WRITE] = NPF_Write; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NPF_IoControl; + DriverObject->DriverUnload = NPF_Unload; + + bindP = getAdaptersList(); + + if (bindP == NULL) + { + TRACE_MESSAGE(PACKET_DEBUG_INIT, "Adapters not found in the registry, try to copy the bindings of TCP-IP."); + + tcpBindingsP = getTcpBindings(); + + if (tcpBindingsP == NULL) + { + TRACE_MESSAGE(PACKET_DEBUG_INIT, "TCP-IP not found, quitting."); + goto RegistryError; + } + + bindP = (WCHAR*)tcpBindingsP; + bindT = (WCHAR*)(tcpBindingsP->Data); + + } + else + { + bindT = bindP; + } + + for (; *bindT != UNICODE_NULL; bindT += (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR)) + { + RtlInitUnicodeString(&macName, bindT); + createDevice(DriverObject, &macName, NdisProtocolHandle); + } + + TRACE_EXIT(); + return STATUS_SUCCESS; + +RegistryError: + + NdisDeregisterProtocol( + &Status, + NdisProtocolHandle + ); + + Status=STATUS_UNSUCCESSFUL; + + TRACE_EXIT(); + return(Status); +} + +//------------------------------------------------------------------- + +PWCHAR getAdaptersList(void) +{ + PKEY_VALUE_PARTIAL_INFORMATION result = NULL; + OBJECT_ATTRIBUTES objAttrs; + NTSTATUS status; + HANDLE keyHandle; + UINT BufPos=0; + UINT BufLen=4096; + + + PWCHAR DeviceNames = (PWCHAR) ExAllocatePoolWithTag(PagedPool, BufLen, '0PWA'); + + if (DeviceNames == NULL) { + IF_LOUD(DbgPrint("Unable the allocate the buffer for the list of the network adapters\n");) + return NULL; + } + + InitializeObjectAttributes(&objAttrs, &AdapterListKey, + OBJ_CASE_INSENSITIVE, NULL, NULL); + status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs); + if (!NT_SUCCESS(status)) { + IF_LOUD(DbgPrint("\n\nStatus of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);) + } + else { //OK + + ULONG resultLength; + KEY_VALUE_PARTIAL_INFORMATION valueInfo; + CHAR AdapInfo[1024]; + UINT i=0; + + IF_LOUD(DbgPrint("getAdaptersList: scanning the list of the adapters in the registry, DeviceNames=%p\n",DeviceNames);) + + // Scan the list of the devices + while((status=ZwEnumerateKey(keyHandle,i,KeyBasicInformation,AdapInfo,sizeof(AdapInfo),&resultLength))==STATUS_SUCCESS) + { + WCHAR ExportKeyName [512]; + PWCHAR ExportKeyPrefix = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\"; + UINT ExportKeyPrefixSize = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"); + PWCHAR LinkageKeyPrefix = L"\\Linkage"; + UINT LinkageKeyPrefixSize = sizeof(L"\\Linkage"); + NDIS_STRING FinalExportKey = NDIS_STRING_CONST("Export"); + PKEY_BASIC_INFORMATION tInfo= (PKEY_BASIC_INFORMATION)AdapInfo; + UNICODE_STRING AdapterKeyName; + HANDLE ExportKeyHandle; + + RtlCopyMemory(ExportKeyName, + ExportKeyPrefix, + ExportKeyPrefixSize); + + RtlCopyMemory((PCHAR)ExportKeyName+ExportKeyPrefixSize, + tInfo->Name, + tInfo->NameLength+2); + + RtlCopyMemory((PCHAR)ExportKeyName+ExportKeyPrefixSize+tInfo->NameLength, + LinkageKeyPrefix, + LinkageKeyPrefixSize); + + IF_LOUD(DbgPrint("Key name=%ws\n", ExportKeyName);) + + RtlInitUnicodeString(&AdapterKeyName, ExportKeyName); + + InitializeObjectAttributes(&objAttrs, &AdapterKeyName, + OBJ_CASE_INSENSITIVE, NULL, NULL); + + status=ZwOpenKey(&ExportKeyHandle,KEY_READ,&objAttrs); + + if (!NT_SUCCESS(status)) { + IF_LOUD(DbgPrint("OpenKey Failed, %d!\n",status);) + i++; + continue; + } + + status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey, + KeyValuePartialInformation, &valueInfo, + sizeof(valueInfo), &resultLength); + + if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW)) { + IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);) + } + else { // We know how big it needs to be. + ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]); + PKEY_VALUE_PARTIAL_INFORMATION valueInfoP = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePoolWithTag(PagedPool, valueInfoLength, '1PWA'); + if (valueInfoP != NULL) { + status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey, + KeyValuePartialInformation, + valueInfoP, + valueInfoLength, &resultLength); + if (!NT_SUCCESS(status)) { + IF_LOUD(DbgPrint("Status of %x querying key value\n", status);) + } + else{ + IF_LOUD(DbgPrint("Device %d = %ws\n", i, valueInfoP->Data);) + if( BufPos + valueInfoP->DataLength > BufLen ) { + // double the buffer size + PWCHAR DeviceNames2 = (PWCHAR) ExAllocatePoolWithTag(PagedPool, BufLen + << 1, '0PWA'); + if( DeviceNames2 ) { + RtlCopyMemory((PCHAR)DeviceNames2, (PCHAR)DeviceNames, BufLen); + BufLen <<= 1; + ExFreePool(DeviceNames); + DeviceNames = DeviceNames2; + } + } + if( BufPos + valueInfoP->DataLength < BufLen ) { + RtlCopyMemory((PCHAR)DeviceNames+BufPos, + valueInfoP->Data, + valueInfoP->DataLength); + BufPos+=valueInfoP->DataLength-2; + } + } + + ExFreePool(valueInfoP); + } + else { + IF_LOUD(DbgPrint("Error Allocating the buffer for the device name\n");) + } + + } + + // terminate the buffer + DeviceNames[BufPos/2]=0; + DeviceNames[BufPos/2+1]=0; + + ZwClose (ExportKeyHandle); + i++; + + } + + ZwClose (keyHandle); + + } + if(BufPos==0){ + ExFreePool(DeviceNames); + return NULL; + } + return DeviceNames; +} + +//------------------------------------------------------------------- + +PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(void) +{ + PKEY_VALUE_PARTIAL_INFORMATION result = NULL; + OBJECT_ATTRIBUTES objAttrs; + NTSTATUS status; + HANDLE keyHandle; + + InitializeObjectAttributes(&objAttrs, &tcpLinkageKeyName, + OBJ_CASE_INSENSITIVE, NULL, NULL); + status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs); + if (!NT_SUCCESS(status)) { + IF_LOUD(DbgPrint("\n\nStatus of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);) + } + else { + ULONG resultLength; + KEY_VALUE_PARTIAL_INFORMATION valueInfo; + + IF_LOUD(DbgPrint("\n\nOpened %ws\n", tcpLinkageKeyName.Buffer);) + + status = ZwQueryValueKey(keyHandle, &bindValueName, + KeyValuePartialInformation, &valueInfo, + sizeof(valueInfo), &resultLength); + if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW)) { + IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);) + } + else { // We know how big it needs to be. + ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]); + PKEY_VALUE_PARTIAL_INFORMATION valueInfoP = + (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(PagedPool, valueInfoLength, '2PWA'); + + if (valueInfoP != NULL) { + status = ZwQueryValueKey(keyHandle, &bindValueName, + KeyValuePartialInformation, + valueInfoP, + valueInfoLength, &resultLength); + + if (!NT_SUCCESS(status)) { + IF_LOUD(DbgPrint("\n\nStatus of %x querying key value\n", status);) + } + else if (valueInfoLength != resultLength) { + IF_LOUD(DbgPrint("\n\nQuerying key value result len = %u " + "but previous len = %u\n", + resultLength, valueInfoLength);) + } + else if (valueInfoP->Type != REG_MULTI_SZ) { + IF_LOUD(DbgPrint("\n\nTcpip bind value not REG_MULTI_SZ but %u\n", + valueInfoP->Type);) + } + else { // It's OK +#if DBG + ULONG i; + WCHAR* dataP = (WCHAR*)(&valueInfoP->Data[0]); + IF_LOUD(DbgPrint("\n\nBind value:\n");) + for (i = 0; *dataP != UNICODE_NULL; i++) { + UNICODE_STRING macName; + RtlInitUnicodeString(&macName, dataP); + IF_LOUD(DbgPrint("\n\nMac %u = %ws\n", i, macName.Buffer);) + dataP += + (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR); + } +#endif // DBG + result = valueInfoP; + } + } + } + ZwClose(keyHandle); + } + return result; +} + +//------------------------------------------------------------------- + +BOOLEAN createDevice(IN OUT PDRIVER_OBJECT adriverObjectP, + IN PUNICODE_STRING amacNameP, NDIS_HANDLE aProtoHandle) +{ + NTSTATUS status; + PDEVICE_OBJECT devObjP; + UNICODE_STRING deviceName; + UNICODE_STRING deviceSymLink; + + IF_LOUD(DbgPrint("\n\ncreateDevice for MAC %ws\n", amacNameP->Buffer);); + if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer, + devicePrefix.Length) < devicePrefix.Length) + { + return FALSE; + } + + deviceName.Length = 0; + deviceName.MaximumLength = (USHORT)(amacNameP->Length + g_NPF_Prefix.Length + sizeof(UNICODE_NULL)); + deviceName.Buffer = ExAllocatePoolWithTag(PagedPool, deviceName.MaximumLength, '3PWA'); + + if (deviceName.Buffer == NULL) + return FALSE; + + deviceSymLink.Length = 0; + deviceSymLink.MaximumLength =(USHORT)(amacNameP->Length-devicePrefix.Length + + symbolicLinkPrefix.Length + + g_NPF_Prefix.Length + + sizeof(UNICODE_NULL)); + + deviceSymLink.Buffer = ExAllocatePoolWithTag(NonPagedPool, deviceSymLink.MaximumLength, '3PWA'); + + if (deviceSymLink.Buffer == NULL) + { + ExFreePool(deviceName.Buffer); + return FALSE; + } + + RtlAppendUnicodeStringToString(&deviceName, &devicePrefix); + RtlAppendUnicodeStringToString(&deviceName, &g_NPF_Prefix); + RtlAppendUnicodeToString(&deviceName, amacNameP->Buffer + + devicePrefix.Length / sizeof(WCHAR)); + + RtlAppendUnicodeStringToString(&deviceSymLink, &symbolicLinkPrefix); + RtlAppendUnicodeStringToString(&deviceSymLink, &g_NPF_Prefix); + RtlAppendUnicodeToString(&deviceSymLink, amacNameP->Buffer + + devicePrefix.Length / sizeof(WCHAR)); + + IF_LOUD(DbgPrint("Creating device name: %ws\n", deviceName.Buffer);) + + status = IoCreateDevice(adriverObjectP, + sizeof(DEVICE_EXTENSION), + &deviceName, + FILE_DEVICE_TRANSPORT, + 0, + FALSE, + &devObjP); + + if (NT_SUCCESS(status)) + { + PDEVICE_EXTENSION devExtP = (PDEVICE_EXTENSION)devObjP->DeviceExtension; + + IF_LOUD(DbgPrint("Device created successfully\n");); + + devObjP->Flags |= DO_DIRECT_IO; + RtlInitUnicodeString(&devExtP->AdapterName,amacNameP->Buffer); + devExtP->NdisProtocolHandle=aProtoHandle; + + IF_LOUD(DbgPrint("Trying to create SymLink %ws\n",deviceSymLink.Buffer);); + + if (IoCreateSymbolicLink(&deviceSymLink,&deviceName) != STATUS_SUCCESS) + { + IF_LOUD(DbgPrint("\n\nError creating SymLink %ws\nn", deviceSymLink.Buffer);); + + ExFreePool(deviceName.Buffer); + ExFreePool(deviceSymLink.Buffer); + + devExtP->ExportString = NULL; + + return FALSE; + } + + IF_LOUD(DbgPrint("SymLink %ws successfully created.\n\n", deviceSymLink.Buffer);); + + devExtP->ExportString = deviceSymLink.Buffer; + + ExFreePool(deviceName.Buffer); + + return TRUE; + } + + else + { + IF_LOUD(DbgPrint("\n\nIoCreateDevice status = %x\n", status);); + + ExFreePool(deviceName.Buffer); + ExFreePool(deviceSymLink.Buffer); + + return FALSE; + } +} +//------------------------------------------------------------------- + +VOID NPF_Unload(IN PDRIVER_OBJECT DriverObject) +{ + PDEVICE_OBJECT DeviceObject; + PDEVICE_OBJECT OldDeviceObject; + PDEVICE_EXTENSION DeviceExtension; + + NDIS_HANDLE NdisProtocolHandle = NULL; + NDIS_STATUS Status; + + NDIS_STRING SymLink; + + TRACE_ENTER(); + + DeviceObject = DriverObject->DeviceObject; + + while (DeviceObject != NULL) { + OldDeviceObject = DeviceObject; + + DeviceObject = DeviceObject->NextDevice; + + DeviceExtension = OldDeviceObject->DeviceExtension; + + NdisProtocolHandle=DeviceExtension->NdisProtocolHandle; + + TRACE_MESSAGE4(PACKET_DEBUG_LOUD,"Deleting Adapter %ws, Protocol Handle=%p, Device Obj=%p (%p)", + DeviceExtension->AdapterName.Buffer, + NdisProtocolHandle, + DeviceObject, + OldDeviceObject); + + if (DeviceExtension->ExportString) + { + RtlInitUnicodeString(&SymLink , DeviceExtension->ExportString); + + TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Deleting SymLink at %p", SymLink.Buffer); + + IoDeleteSymbolicLink(&SymLink); + ExFreePool(DeviceExtension->ExportString); + } + + IoDeleteDevice(OldDeviceObject); + } + + NdisDeregisterProtocol( + &Status, + NdisProtocolHandle + ); + + // Free the adapters names + ExFreePool( bindP ); + + TRACE_EXIT(); + + // Free the device names string that was allocated in the DriverEntry +// NdisFreeString(g_NPF_Prefix); +} + +#define SET_FAILURE_BUFFER_SMALL() do{\ + Information = 0; \ + Status = STATUS_BUFFER_TOO_SMALL; \ +} while(FALSE) + +#define SET_RESULT_SUCCESS(__a__) do{\ + Information = __a__; \ + Status = STATUS_SUCCESS; \ +} while(FALSE) + +#define SET_FAILURE_INVALID_REQUEST() do{\ + Information = 0; \ + Status = STATUS_INVALID_DEVICE_REQUEST; \ +} while(FALSE) + +#define SET_FAILURE_UNSUCCESSFUL() do{\ + Information = 0; \ + Status = STATUS_UNSUCCESSFUL; \ +} while(FALSE) + +#define SET_FAILURE_NOMEM() do{\ + Information = 0; \ + Status = STATUS_INSUFFICIENT_RESOURCES; \ +} while(FALSE) + +//------------------------------------------------------------------- + +NTSTATUS NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PLIST_ENTRY RequestListEntry; + PINTERNAL_REQUEST pRequest; + ULONG FunctionCode; + NDIS_STATUS Status; + ULONG Information = 0; + PLIST_ENTRY PacketListEntry; + UINT i; + PUCHAR tpointer; + ULONG dim,timeout; + struct bpf_insn* NewBpfProgram; + PPACKET_OID_DATA OidData; + int *StatsBuf; + PNDIS_PACKET pPacket; + ULONG mode; + PWSTR DumpNameBuff; + PUCHAR TmpBPFProgram; + INT WriteRes; + BOOLEAN SyncWrite = FALSE; + struct bpf_insn *initprogram; + ULONG insns; + ULONG cnt; + BOOLEAN IsExtendedFilter=FALSE; + ULONG StringLength; + ULONG NeededBytes; + BOOLEAN Flag; + PUINT pStats; + + HANDLE hUserEvent; + PKEVENT pKernelEvent; +#ifdef _AMD64_ + VOID*POINTER_32 hUserEvent32Bit; +#endif //_AMD64_ + PMDL mdl; + + TRACE_ENTER(); + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode; + Open=IrpSp->FileObject->FsContext; + + Irp->IoStatus.Status = STATUS_SUCCESS; + + TRACE_MESSAGE3(PACKET_DEBUG_LOUD, + "Function code is %08lx Input size=%08lx Output size %08lx", + FunctionCode, + IrpSp->Parameters.DeviceIoControl.InputBufferLength, + IrpSp->Parameters.DeviceIoControl.OutputBufferLength); + + switch (FunctionCode){ + + case BIOCGSTATS: //function to get the capture stats + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCGSTATS"); + + if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < 4*sizeof(UINT)) + { + SET_FAILURE_BUFFER_SMALL(); + break; + } + + if (Irp->UserBuffer == NULL) + { + SET_FAILURE_UNSUCCESSFUL(); + break; + } + + // + // temp fix to a GIANT bug from LD. The CTL code has been defined as METHOD_NEITHER, so it + // might well be a dangling pointer. We need to probe and lock the address. + // + + mdl = NULL; + pStats = NULL; + + __try + { + mdl = IoAllocateMdl( + Irp->UserBuffer, + IrpSp->Parameters.DeviceIoControl.OutputBufferLength, + FALSE, + TRUE, + NULL); + + if (mdl == NULL) + { + SET_FAILURE_UNSUCCESSFUL(); + break; + } + + MmProbeAndLockPages( + mdl, + UserMode, + IoWriteAccess); + + pStats = (PUINT)(Irp->UserBuffer); + } + __except(GetExceptionCode() == STATUS_ACCESS_VIOLATION) + { + pStats = NULL; + } + + if (pStats == NULL) + { + if (mdl != NULL) + { + IoFreeMdl(mdl); + } + + SET_FAILURE_UNSUCCESSFUL(); + break; + } + + pStats[3] = 0; + pStats[0] = 0; + pStats[1] = 0; + pStats[2] = 0; // Not yet supported + + for(i = 0 ; i < NCpu ; i++) + { + + pStats[3] += Open->CpuData[i].Accepted; + pStats[0] += Open->CpuData[i].Received; + pStats[1] += Open->CpuData[i].Dropped; + pStats[2] += 0; // Not yet supported + } + + MmUnlockPages(mdl); + IoFreeMdl(mdl); + + SET_RESULT_SUCCESS(4*sizeof(UINT)); + + break; + + case BIOCGEVNAME: //function to get the name of the event associated with the current instance + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCGEVNAME"); + + // + // Since 20060405, the event handling has been changed: + // we no longer use named events, instead the user level app creates an event, + // and passes it back to the kernel, that references it (ObReferenceObjectByHandle), and + // signals it. + // For the time being, we still leave this ioctl code here, and we simply fail. + // + SET_FAILURE_INVALID_REQUEST(); + break; + + case BIOCSENDPACKETSSYNC: + + SyncWrite = TRUE; + + case BIOCSENDPACKETSNOSYNC: + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSENDPACKETSNOSYNC"); + + NdisAcquireSpinLock(&Open->WriteLock); + if(Open->WriteInProgress) + { + NdisReleaseSpinLock(&Open->WriteLock); + // + // Another write operation is currently in progress + // + SET_FAILURE_UNSUCCESSFUL(); + break; + } + else + { + Open->WriteInProgress = TRUE; + } + NdisReleaseSpinLock(&Open->WriteLock); + + WriteRes = NPF_BufferedWrite(Irp, + (PUCHAR)Irp->AssociatedIrp.SystemBuffer, + IrpSp->Parameters.DeviceIoControl.InputBufferLength, + SyncWrite); + + NdisAcquireSpinLock(&Open->WriteLock); + Open->WriteInProgress = FALSE; + NdisReleaseSpinLock(&Open->WriteLock); + + if( WriteRes != -1) + { + SET_RESULT_SUCCESS(WriteRes); + } + else + { + SET_FAILURE_UNSUCCESSFUL(); + } + break; + + case BIOCSETF: + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSETF"); + + // + // Get the pointer to the new program + // + NewBpfProgram = (struct bpf_insn*)Irp->AssociatedIrp.SystemBuffer; + + if(NewBpfProgram == NULL) + { + SET_FAILURE_BUFFER_SMALL(); + break; + } + + // + // Lock the machine. After this call we are at DISPATCH level + // + NdisAcquireSpinLock(&Open->MachineLock); + + do + { + + // Free the previous buffer if it was present + if(Open->bpfprogram != NULL) + { + TmpBPFProgram = Open->bpfprogram; + Open->bpfprogram = NULL; + ExFreePool(TmpBPFProgram); + } + +// +// Jitted filters are supported on x86 (32bit) only +// +#ifdef _X86_ + if (Open->Filter != NULL) + { + BPF_Destroy_JIT_Filter(Open->Filter); + Open->Filter = NULL; + } +#endif // _X86_ + + insns = (IrpSp->Parameters.DeviceIoControl.InputBufferLength)/sizeof(struct bpf_insn); + + //count the number of operative instructions + for (cnt = 0 ; (cnt < insns) &&(NewBpfProgram[cnt].code != BPF_SEPARATION); cnt++); + + TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Operative instructions=%u", cnt); + +#ifdef HAVE_BUGGY_TME_SUPPORT + if ( (cnt != insns) && (insns != cnt+1) && (NewBpfProgram[cnt].code == BPF_SEPARATION)) + { + TRACE_MESSAGE1(PACKET_DEBUG_LOUD,"Initialization instructions = %u",insns-cnt-1); + + IsExtendedFilter = TRUE; + + initprogram = &NewBpfProgram[cnt+1]; + + if(bpf_filter_init(initprogram,&(Open->mem_ex),&(Open->tme), &G_Start_Time)!=INIT_OK) + { + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Error initializing NPF machine (bpf_filter_init)"); + + SET_FAILURE_INVALID_REQUEST(); + break; + } + } +#else // HAVE_BUGGY_TME_SUPPORT + if ( cnt != insns) + { + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Error installing the BPF filter. The filter contains TME extensions," + " not supported on 64bit platforms."); + + SET_FAILURE_INVALID_REQUEST(); + break; + } +#endif // HAVE_BUGGY_TME_SUPPORT + + //the NPF processor has been initialized, we have to validate the operative instructions + insns = cnt; + + //NOTE: the validation code checks for TME instructions, and fails if a TME instruction is + //encountered on 64 bit machines + if(bpf_validate(NewBpfProgram, cnt, Open->mem_ex.size) == 0) + { + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Error validating program"); + //FIXME: the machine has been initialized(?), but the operative code is wrong. + //we have to reset the machine! + //something like: reallocate the mem_ex, and reset the tme_core + SET_FAILURE_INVALID_REQUEST(); + break; + } + + // Allocate the memory to contain the new filter program + // We could need the original BPF binary if we are forced to use bpf_filter_with_2_buffers() + TmpBPFProgram = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, cnt*sizeof(struct bpf_insn), '4PWA'); + if (TmpBPFProgram == NULL) + { + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Error - No memory for filter"); + // no memory + + SET_FAILURE_NOMEM(); + break; + } + + // + // At the moment the JIT compiler works on x86 (32 bit) only + // +#ifdef _X86_ + // Create the new JIT filter function + if(!IsExtendedFilter) + { + if((Open->Filter = BPF_jitter(NewBpfProgram, cnt)) == NULL) + { + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Error jittering filter"); + + ExFreePool(TmpBPFProgram); + + SET_FAILURE_UNSUCCESSFUL(); + break; + } + } +#endif //_X86_ + + //copy the program in the new buffer + RtlCopyMemory(TmpBPFProgram,NewBpfProgram,cnt*sizeof(struct bpf_insn)); + Open->bpfprogram = TmpBPFProgram; + + SET_RESULT_SUCCESS(0); + } + while(FALSE); + + // + // release the machine lock and then reset the buffer + // + NdisReleaseSpinLock(&Open->MachineLock); + + NPF_ResetBufferContents(Open); + + break; + + case BIOCSMODE: //set the capture mode + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSMODE"); + + if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG)) + { + SET_FAILURE_BUFFER_SMALL(); + break; + } + + mode=*((PULONG)Irp->AssociatedIrp.SystemBuffer); + +///////kernel dump does not work at the moment////////////////////////////////////////// + if (mode & MODE_DUMP) + { + SET_FAILURE_INVALID_REQUEST(); + break; + } +///////kernel dump does not work at the moment////////////////////////////////////////// + + if(mode == MODE_CAPT) + { + Open->mode = MODE_CAPT; + + SET_RESULT_SUCCESS(0); + break; + } + else if (mode == MODE_MON) + { + // + // The MONITOR_MODE (aka TME extensions) is not supported on + // 64 bit architectures + // + +#ifdef HAVE_BUGGY_TME_SUPPORT + Open->mode = MODE_MON; + SET_RESULT_SUCCESS(0); +#else // HAVE_BUGGY_TME_SUPPORT + SET_FAILURE_INVALID_REQUEST(); +#endif // HAVE_BUGGY_TME_SUPPORT + + break; + } + else{ + if(mode & MODE_STAT){ + Open->mode = MODE_STAT; + NdisAcquireSpinLock(&Open->CountersLock); + Open->Nbytes.QuadPart = 0; + Open->Npackets.QuadPart = 0; + NdisReleaseSpinLock(&Open->CountersLock); + + if(Open->TimeOut.QuadPart==0)Open->TimeOut.QuadPart = -10000000; + + } + + if(mode & MODE_DUMP){ + + Open->mode |= MODE_DUMP; +// Open->MinToCopy=(Open->BufSize<2000000)?Open->BufSize/2:1000000; + + } + + SET_RESULT_SUCCESS(0); + break; + } + + SET_FAILURE_INVALID_REQUEST(); + + break; + + case BIOCSETDUMPFILENAME: + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSETDUMPFILENAME"); + +///////kernel dump does not work at the moment////////////////////////////////////////// + SET_FAILURE_INVALID_REQUEST(); + break; +///////kernel dump does not work at the moment////////////////////////////////////////// + + //if(Open->mode & MODE_DUMP) + //{ + // + // // Close current dump file + // if(Open->DumpFileHandle != NULL) + // { + // NPF_CloseDumpFile(Open); + // Open->DumpFileHandle = NULL; + // } + // + // if(IrpSp->Parameters.DeviceIoControl.InputBufferLength == 0){ + // EXIT_FAILURE(0); + // } + // + // // Allocate the buffer that will contain the string + // DumpNameBuff=ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.DeviceIoControl.InputBufferLength, '5PWA'); + // if(DumpNameBuff==NULL || Open->DumpFileName.Buffer!=NULL){ + // IF_LOUD(DbgPrint("NPF: unable to allocate the dump filename: not enough memory or name already set\n");) + // EXIT_FAILURE(0); + // } + // + // // Copy the buffer + // RtlCopyBytes((PVOID)DumpNameBuff, + // Irp->AssociatedIrp.SystemBuffer, + // IrpSp->Parameters.DeviceIoControl.InputBufferLength); + // + // // Force a \0 at the end of the filename to avoid that malformed strings cause RtlInitUnicodeString to crash the system + // ((PSHORT)DumpNameBuff)[IrpSp->Parameters.DeviceIoControl.InputBufferLength/2-1]=0; + // + // // Create the unicode string + // RtlInitUnicodeString(&Open->DumpFileName, DumpNameBuff); + // + // IF_LOUD(DbgPrint("NPF: dump file name set to %ws, len=%d\n", + // Open->DumpFileName.Buffer, + // IrpSp->Parameters.DeviceIoControl.InputBufferLength);) + // + // // Try to create the file + // if ( NT_SUCCESS( NPF_OpenDumpFile(Open,&Open->DumpFileName,FALSE)) && + // NT_SUCCESS( NPF_StartDump(Open))) + // { + // EXIT_SUCCESS(0); + // } + //} + // + //EXIT_FAILURE(0); + // + //break; + + case BIOCSETDUMPLIMITS: + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSETDUMPLIMITS"); + +///////kernel dump does not work at the moment////////////////////////////////////////// + SET_FAILURE_INVALID_REQUEST(); + break; +///////kernel dump does not work at the moment////////////////////////////////////////// + + //if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < 2*sizeof(ULONG)) + //{ + // EXIT_FAILURE(0); + //} + // + //Open->MaxDumpBytes = *(PULONG)Irp->AssociatedIrp.SystemBuffer; + //Open->MaxDumpPacks = *((PULONG)Irp->AssociatedIrp.SystemBuffer + 1); + // + //IF_LOUD(DbgPrint("NPF: Set dump limits to %u bytes, %u packs\n", Open->MaxDumpBytes, Open->MaxDumpPacks);) + // + //EXIT_SUCCESS(0); + // + //break; + + case BIOCISDUMPENDED: + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCISDUMPENDED"); + +///////kernel dump does not work at the moment////////////////////////////////////////// + SET_FAILURE_INVALID_REQUEST(); + break; +///////kernel dump does not work at the moment////////////////////////////////////////// + + //if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(UINT)) + //{ + // EXIT_FAILURE(0); + //} + + //*((UINT*)Irp->UserBuffer) = (Open->DumpLimitReached)?1:0; + + //EXIT_SUCCESS(4); + + //break; + + case BIOCISETLOBBEH: + + if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(INT)) + { + SET_FAILURE_BUFFER_SMALL(); + break; + } + +#ifdef __NPF_NT4__ + + // NT4 doesn't support loopback inhibition / activation + SET_FAILURE_INVALID_REQUEST(); + break; + +#else //not __NPF_NT4__ + // + // win2000/xp/2003/vista + // + if(*(PINT)Irp->AssociatedIrp.SystemBuffer == NPF_DISABLE_LOOPBACK) + { + Open->SkipSentPackets = TRUE; + + // + // Reset the capture buffers, since they could contain loopbacked packets + // + + NPF_ResetBufferContents(Open); + + SET_RESULT_SUCCESS(0); + break; + + } + else + if(*(PINT)Irp->AssociatedIrp.SystemBuffer == NPF_ENABLE_LOOPBACK) + { + Open->SkipSentPackets = FALSE; + + SET_RESULT_SUCCESS(0); + break; + } + else + { + // Unknown operation + SET_FAILURE_INVALID_REQUEST(); + break; + } + +#endif // !__NPF_NT4__ + break; + + case BIOCSETEVENTHANDLE: + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSETEVENTHANDLE"); + +#ifdef _AMD64_ + if (IoIs32bitProcess(Irp)) + { + // + // validate the input + // + if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (hUserEvent32Bit)) + { + SET_FAILURE_INVALID_REQUEST(); + break; + } + + hUserEvent32Bit = *(VOID*POINTER_32*)Irp->AssociatedIrp.SystemBuffer; + hUserEvent = hUserEvent32Bit; + } + else +#endif //_AMD64_ + { + // + // validate the input + // + if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (hUserEvent)) + { + SET_FAILURE_INVALID_REQUEST(); + break; + } + + hUserEvent = *(PHANDLE)Irp->AssociatedIrp.SystemBuffer; + } + + // + // NT4 doesn't seem to have EVENT_MODIFY_STATE, so on NT4 we request a wider set + // of privileges for the event handle + // +#ifdef __NPF_NT4__ + Status = ObReferenceObjectByHandle(hUserEvent, + OBJECT_TYPE_ALL_ACCESS, *ExEventObjectType, Irp->RequestorMode, + (PVOID*) &pKernelEvent, NULL); +#else //__NPF_NT4__ + Status = ObReferenceObjectByHandle(hUserEvent, + EVENT_MODIFY_STATE, *ExEventObjectType, Irp->RequestorMode, + (PVOID*) &pKernelEvent, NULL); +#endif //__NPF_NT4__ + + if (!NT_SUCCESS(Status)) + { + // Status = ??? already set + Information = 0; + break; + } + + + // + // NT4 does not have InterlockedCompareExchangePointer + // InterlockedCompareExchange on NT4 has the same prototype of InterlockedCompareExchange + // on NT5x, so we use this one. + // +#ifdef __NPF_NT4__ + if (InterlockedCompareExchange(&Open->ReadEvent, pKernelEvent, NULL) != NULL) +#else + if (InterlockedCompareExchangePointer(&Open->ReadEvent, pKernelEvent, NULL) != NULL) +#endif + { + // + // dereference the new pointer + // + + ObDereferenceObject(pKernelEvent); + SET_FAILURE_INVALID_REQUEST(); + break; + } + + KeResetEvent(Open->ReadEvent); + + SET_RESULT_SUCCESS(0); + break; + + case BIOCSETBUFFERSIZE: + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSETBUFFERSIZE"); + + + if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG)) + { + SET_FAILURE_BUFFER_SMALL(); + break; + } + + // Get the number of bytes to allocate + dim = *((PULONG)Irp->AssociatedIrp.SystemBuffer); + + if (dim / NCpu < sizeof(struct PacketHeader)) + { + dim = 0; + } + else + { + tpointer = ExAllocatePoolWithTag(NonPagedPool, dim, '6PWA'); + if (tpointer == NULL) + { + // no memory + SET_FAILURE_NOMEM(); + break; + } + } + + // + // acquire the locks for all the buffers + // + for (i = 0; i < NCpu ; i++) + { +#pragma prefast(suppress:8103, "There's no Spinlock leak here, as it's released some lines below.") + NdisAcquireSpinLock(&Open->CpuData[i].BufferLock); + } + + // + // free the old buffer, if any + // + if (Open->CpuData[0].Buffer != NULL) + { + ExFreePool(Open->CpuData[0].Buffer); + } + + for (i = 0 ; i < NCpu ; i++) + { + if (dim > 0) + Open->CpuData[i].Buffer=(PUCHAR)tpointer + (dim/NCpu)*i; + else + Open->CpuData[i].Buffer = NULL; + Open->CpuData[i].Free = dim/NCpu; + Open->CpuData[i].P = 0; + Open->CpuData[i].C = 0; + Open->CpuData[i].Accepted = 0; + Open->CpuData[i].Dropped = 0; + Open->CpuData[i].Received = 0; + } + + Open->ReaderSN=0; + Open->WriterSN=0; + + Open->Size = dim/NCpu; + + // + // acquire the locks for all the buffers + // + i = NCpu; + + do + { + i--; + +#pragma prefast(suppress:8107, "There's no Spinlock leak here, as it's acquired some lines above.") + NdisReleaseSpinLock(&Open->CpuData[i].BufferLock); + }while(i != 0); + + SET_RESULT_SUCCESS(0); + break; + + case BIOCSRTIMEOUT: //set the timeout on the read calls + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSRTIMEOUT"); + + if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG)) + { + SET_FAILURE_BUFFER_SMALL(); + break; + } + + timeout = *((PULONG)Irp->AssociatedIrp.SystemBuffer); + if(timeout == (ULONG)-1) + Open->TimeOut.QuadPart=(LONGLONG)IMMEDIATE; + else + { + Open->TimeOut.QuadPart = (LONGLONG)timeout; + Open->TimeOut.QuadPart *= 10000; + Open->TimeOut.QuadPart = -Open->TimeOut.QuadPart; + } + + TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Read timeout set to %I64d",Open->TimeOut.QuadPart); + + SET_RESULT_SUCCESS(0); + break; + + case BIOCSWRITEREP: //set the writes repetition number + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSWRITEREP"); + + if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG)) + { + SET_FAILURE_BUFFER_SMALL(); + break; + } + + Open->Nwrites = *((PULONG)Irp->AssociatedIrp.SystemBuffer); + + SET_RESULT_SUCCESS(0); + break; + + case BIOCSMINTOCOPY: //set the minimum buffer's size to copy to the application + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSMINTOCOPY"); + + if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG)) + { + SET_FAILURE_BUFFER_SMALL(); + break; + } + + Open->MinToCopy = (*((PULONG)Irp->AssociatedIrp.SystemBuffer))/NCpu; //An hack to make the NCPU-buffers behave like a larger one + + SET_RESULT_SUCCESS(0); + break; + + case IOCTL_PROTOCOL_RESET: + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "IOCTL_PROTOCOL_RESET"); + + IoMarkIrpPending(Irp); + Irp->IoStatus.Status = STATUS_SUCCESS; + + ExInterlockedInsertTailList(&Open->ResetIrpList,&Irp->Tail.Overlay.ListEntry,&Open->RequestSpinLock); + NdisReset(&Status,Open->AdapterHandle); + if (Status != NDIS_STATUS_PENDING) + { + IF_LOUD(DbgPrint("NPF: IoControl - ResetComplete being called\n");) + NPF_ResetComplete(Open,Status); + } + + break; + + case BIOCSETOID: + case BIOCQUERYOID: + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSETOID - BIOCQUERYOID"); + + // + // gain ownership of the Ndis Handle + // + if (NPF_StartUsingBinding(Open) == FALSE) + { + // + // MAC unbindind or unbound + // + SET_FAILURE_INVALID_REQUEST(); + break; + } + + + // Extract a request from the list of free ones + RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList,&Open->RequestSpinLock); + if (RequestListEntry == NULL) + { + // + // Release ownership of the Ndis Handle + // + NPF_StopUsingBinding(Open); + + SET_FAILURE_NOMEM(); + break; + } + + pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement); + + // + // See if it is an Ndis request + // + OidData=Irp->AssociatedIrp.SystemBuffer; + + if ((IrpSp->Parameters.DeviceIoControl.InputBufferLength == IrpSp->Parameters.DeviceIoControl.OutputBufferLength) + && + (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)) + && + (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)-1+OidData->Length)) { + + TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "BIOCSETOID|BIOCQUERYOID Request: Oid=%08lx, Length=%08lx",OidData->Oid,OidData->Length); + + // + // The buffer is valid + // + if (FunctionCode == BIOCSETOID){ + + pRequest->Request.RequestType=NdisRequestSetInformation; + pRequest->Request.DATA.SET_INFORMATION.Oid=OidData->Oid; + + pRequest->Request.DATA.SET_INFORMATION.InformationBuffer=OidData->Data; + pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength=OidData->Length; + + + } + else{ + + pRequest->Request.RequestType=NdisRequestQueryInformation; + pRequest->Request.DATA.QUERY_INFORMATION.Oid=OidData->Oid; + + pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer=OidData->Data; + pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength=OidData->Length; + + } + + NdisResetEvent(&pRequest->InternalRequestCompletedEvent); + + // + // submit the request + // + NdisRequest( + &Status, + Open->AdapterHandle, + &pRequest->Request + ); + + } else { + // + // Release ownership of the Ndis Handle + // + NPF_StopUsingBinding(Open); + + // + // buffer too small + // + SET_FAILURE_BUFFER_SMALL(); + break; + } + + if (Status == NDIS_STATUS_PENDING) + { + NdisWaitEvent(&pRequest->InternalRequestCompletedEvent, 0); + Status = pRequest->RequestStatus; + } + + // + // Release ownership of the Ndis Handle + // + NPF_StopUsingBinding(Open); + + // + // Complete the request + // + if (FunctionCode == BIOCSETOID) + { + OidData->Length = pRequest->Request.DATA.SET_INFORMATION.BytesRead; + TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "BIOCSETOID completed, BytesRead = %u",OidData->Length); + } + else + { + if (FunctionCode == BIOCQUERYOID) + { + OidData->Length = pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten; + + if (Status == NDIS_STATUS_SUCCESS) + { + // + // check for the stupid bug of the Nortel driver ipsecw2k.sys v. 4.10.0.0 that doesn't set the BytesWritten correctly + // The driver is the one shipped with Nortel client Contivity VPN Client V04_65.18, and the MD5 for the buggy (unsigned) driver + // is 3c2ff8886976214959db7d7ffaefe724 *ipsecw2k.sys (there are multiple copies of this binary with the same exact version info!) + // + // The (certified) driver shipped with Nortel client Contivity VPN Client V04_65.320 doesn't seem affected by the bug. + // + if (pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten > pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength) + { + TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "Bogus return from NdisRequest (query): Bytes Written (%u) > InfoBufferLength (%u)!!", + pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten, + pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength); + + Status = NDIS_STATUS_INVALID_DATA; + } + } + + TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "BIOCQUERYOID completed, BytesWritten = %u",OidData->Length); + } + } + + + ExInterlockedInsertTailList( + &Open->RequestList, + &pRequest->ListElement, + &Open->RequestSpinLock); + + if (Status == NDIS_STATUS_SUCCESS) + { + SET_RESULT_SUCCESS(sizeof(PACKET_OID_DATA) - 1 + OidData->Length); + } + else + { + SET_FAILURE_INVALID_REQUEST(); + } + + break; + + + default: + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Unknown IOCTL code"); + SET_FAILURE_INVALID_REQUEST(); + break; + } + + // + // complete the IRP + // + Irp->IoStatus.Information = Information; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + TRACE_EXIT(); + + return Status; +} + +//------------------------------------------------------------------- + +VOID +NPF_RequestComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_REQUEST NdisRequest, + IN NDIS_STATUS Status + ) + +{ + PINTERNAL_REQUEST pRequest; + + TRACE_ENTER(); + + pRequest = CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request); + + // + // Set the request result + // + pRequest->RequestStatus = Status; + + // + // and awake the caller + // + NdisSetEvent(&pRequest->InternalRequestCompletedEvent); + + TRACE_EXIT(); + return; + +} + +//------------------------------------------------------------------- + +VOID +NPF_Status( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN PVOID StatusBuffer, + IN UINT StatusBufferSize + ) + +{ + + IF_LOUD(DbgPrint("NPF: Status Indication\n");) + + return; + +} + +//------------------------------------------------------------------- + +VOID +NPF_StatusComplete( + IN NDIS_HANDLE ProtocolBindingContext + ) + +{ + + IF_LOUD(DbgPrint("NPF: StatusIndicationComplete\n");) + + return; + +} + +//------------------------------------------------------------------- + +NTSTATUS +NPF_ReadRegistry( + IN PWSTR *MacDriverName, + IN PWSTR *PacketDriverName, + IN PUNICODE_STRING RegistryPath + ) + +{ + NTSTATUS Status; + + RTL_QUERY_REGISTRY_TABLE ParamTable[4]; + + PWSTR Bind = L"Bind"; + PWSTR Export = L"Export"; + PWSTR Parameters = L"Parameters"; + PWSTR Linkage = L"Linkage"; + + PWCHAR Path; + + + + Path=ExAllocatePoolWithTag(PagedPool, RegistryPath->Length+sizeof(WCHAR), '7PWA'); + + if (Path == NULL) { + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory( + Path, + RegistryPath->Length+sizeof(WCHAR) + ); + + RtlCopyMemory( + Path, + RegistryPath->Buffer, + RegistryPath->Length + ); + + IF_LOUD(DbgPrint("NPF: Reg path is %ws\n",RegistryPath->Buffer);) + + RtlZeroMemory( + ParamTable, + sizeof(ParamTable) + ); + + + + // + // change to the linkage key + // + + ParamTable[0].QueryRoutine = NULL; + ParamTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY; + ParamTable[0].Name = Linkage; + + + // + // Get the name of the mac driver we should bind to + // + + ParamTable[1].QueryRoutine = NPF_QueryRegistryRoutine; + ParamTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED | + RTL_QUERY_REGISTRY_NOEXPAND; + + ParamTable[1].Name = Bind; + ParamTable[1].EntryContext = (PVOID)MacDriverName; + ParamTable[1].DefaultType = REG_MULTI_SZ; + + // + // Get the name that we should use for the driver object + // + + ParamTable[2].QueryRoutine = NPF_QueryRegistryRoutine; + ParamTable[2].Flags = RTL_QUERY_REGISTRY_REQUIRED | + RTL_QUERY_REGISTRY_NOEXPAND; + + ParamTable[2].Name = Export; + ParamTable[2].EntryContext = (PVOID)PacketDriverName; + ParamTable[2].DefaultType = REG_MULTI_SZ; + + + Status=RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE, + Path, + ParamTable, + NULL, + NULL + ); + + + ExFreePool(Path); + + return Status; +} + +//------------------------------------------------------------------- + +NTSTATUS +NPF_QueryRegistryRoutine( + IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext + ) + +{ + + PUCHAR Buffer; + + IF_LOUD(DbgPrint("Perf: QueryRegistryRoutine\n");) + + if (ValueType != REG_MULTI_SZ) { + + return STATUS_OBJECT_NAME_NOT_FOUND; + + } + + Buffer=ExAllocatePoolWithTag(NonPagedPool, ValueLength, '8PWA'); + + if (Buffer==NULL) { + + return STATUS_INSUFFICIENT_RESOURCES; + + } + + RtlCopyMemory( + Buffer, + ValueData, + ValueLength + ); + + *((PUCHAR *)EntryContext)=Buffer; + + return STATUS_SUCCESS; + +} + +VOID NPF_ResetBufferContents(POPEN_INSTANCE Open) +{ + UINT i; + + // + // lock all the buffers + // + for (i = 0 ; i < NCpu ; i++) + { +//#pragma prefast(suppress:8103, "There's no Spinlock leak here, as it's released some lines below.") + NdisAcquireSpinLock(&Open->CpuData[i].BufferLock); + } + + Open->ReaderSN = 0; + Open->WriterSN = 0; + + // + // reset their pointers + // + for (i = 0 ; i < NCpu ; i++) + { + Open->CpuData[i].C=0; + Open->CpuData[i].P=0; + Open->CpuData[i].Free = Open->Size; + Open->CpuData[i].Accepted = 0; + Open->CpuData[i].Dropped = 0; + Open->CpuData[i].Received = 0; + } + + // + // release the locks in reverse order + // + i = NCpu; + + do + { + i--; +#pragma prefast(suppress:8107, "There's no Spinlock leak here, as it's allocated some lines above.") + NdisReleaseSpinLock(&Open->CpuData[i].BufferLock); + + } + while (i != 0); +} + +#if 0 +// +// Old registry based WinPcap names +// + +//------------------------------------------------------------------- + +//NOTE: ValueLen is the length of Value in characters + +VOID NPF_QueryWinpcapRegistryString(PWSTR SubKeyName, + WCHAR *Value, + UINT ValueLen, + WCHAR *DefaultValue) +{ + UINT CharsToCopy; + +#ifdef WPCAP_OEM + OBJECT_ATTRIBUTES objAttrs; + NTSTATUS status; + HANDLE keyHandle; + UNICODE_STRING SubKeyToQueryU; + CHAR kvpiBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(WCHAR) * MAX_WINPCAP_KEY_CHARS]; + ULONG QvkResultLength; + PKEY_VALUE_PARTIAL_INFORMATION pKeyValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)kvpiBuffer; + PWCHAR pResultingKeyValue; + + // + // Create subkey string + // + RtlInitUnicodeString(&SubKeyToQueryU, SubKeyName); + + // + // Init Attributes + // + InitializeObjectAttributes(&objAttrs, + &g_WinpcapGlobalKey, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + // + // Open the key + // + status = ZwOpenKey(&keyHandle, + KEY_QUERY_VALUE, + &objAttrs); + + if(!NT_SUCCESS(status)) + { + IF_LOUD(DbgPrint("NPF_QueryWinpcapRegistryKey: ZwOpenKey error %x\n", status);) + + //copy the default value and return + CharsToCopy = wcslen(DefaultValue) + 1; + if (CharsToCopy > ValueLen) + { + RtlCopyMemory(Value, DefaultValue, ValueLen * 2); + Value[ValueLen - 1] = 0; + } + else + { + RtlCopyMemory(Value, DefaultValue, CharsToCopy * 2); + } + return; + } + + // + // Query the requested value + // + status = ZwQueryValueKey(keyHandle, + &SubKeyToQueryU, + KeyValuePartialInformation, + pKeyValuePartialInformation, + sizeof(kvpiBuffer), + &QvkResultLength); + + if(!NT_SUCCESS(status)) + { + IF_LOUD(DbgPrint("NPF_QueryWinpcapRegistryKey: Status of %x querying key value %ws\n", + status, + SubKeyToQueryU.Buffer);) + + ZwClose(keyHandle); + + //copy the default value and return + CharsToCopy = wcslen(DefaultValue) + 1; + if (CharsToCopy > ValueLen) + { + RtlCopyMemory(Value, DefaultValue, ValueLen * 2); + Value[ValueLen - 1] = 0; + } + else + { + RtlCopyMemory(Value, DefaultValue, CharsToCopy * 2); + } + return; + } + + // + // Check that the resulting value is of the correct type + // + if (pKeyValuePartialInformation->Type != REG_SZ) + { + IF_LOUD(DbgPrint("NPF_QueryWinpcapRegistryKey: the reg key has the wrong type (%u)\n", pKeyValuePartialInformation->Type);) + + ZwClose(keyHandle); + + //copy the default value and return + CharsToCopy = wcslen(DefaultValue) + 1; + if (CharsToCopy > ValueLen) + { + RtlCopyMemory(Value, DefaultValue, ValueLen * 2); + Value[ValueLen - 1] = 0; + } + else + { + RtlCopyMemory(Value, DefaultValue, CharsToCopy * 2); + } + return; + } + + pResultingKeyValue = (PWCHAR)pKeyValuePartialInformation->Data; + + // + // Check we have enough space for the result. We include 1 to account for the UNICODE NULL terminator + // + if(wcslen(pResultingKeyValue) + 1 > ValueLen) + { + IF_LOUD(DbgPrint("NPF_QueryWinpcapRegistryKey: storage buffer too small\n");) + + ZwClose(keyHandle); + + //copy the default value and return + CharsToCopy = wcslen(DefaultValue) + 1; + if (CharsToCopy > ValueLen) + { + RtlCopyMemory(Value, DefaultValue, ValueLen * 2); + Value[ValueLen - 1] = 0; + } + else + { + RtlCopyMemory(Value, DefaultValue, CharsToCopy * 2); + } + return; + } + + // + // Copy the value to the user-provided values + // + wcscpy(Value, pResultingKeyValue); + + // + // Free the key + // + ZwClose(keyHandle); + + return; + +#else // WPCAP_OEM + + //copy the default value and return + CharsToCopy = wcslen(DefaultValue) + 1; + if (CharsToCopy > ValueLen) + { + RtlCopyMemory(Value, DefaultValue, ValueLen * 2); + Value[ValueLen - 1] = 0; + } + else + { + RtlCopyMemory(Value, DefaultValue, CharsToCopy * 2); + } + return; + +#endif // WPCAP_OEM +} + +#endif \ No newline at end of file diff --git a/winpcap/packetNtx/driver/Packet.h b/winpcap/packetNtx/driver/Packet.h new file mode 100644 index 0000000..eb6b519 --- /dev/null +++ b/winpcap/packetNtx/driver/Packet.h @@ -0,0 +1,1042 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** @addtogroup NPF + * @{ + */ + +/** @defgroup NPF_include NPF structures and definitions + * @{ + */ + +#ifndef __PACKET_INCLUDE______ +#define __PACKET_INCLUDE______ + +#ifdef _X86_ +#define NTKERNEL ///< Forces the compilation of the jitter with kernel calls +#include "jitter.h" +#endif + +#ifdef HAVE_BUGGY_TME_SUPPORT +#ifndef _X86_ +#error TME support is available only on x86 architectures +#endif // _X86_ +#endif //HAVE_BUGGY_TME_SUPPORT + + +// +// Needed to disable a warning due to the #pragma prefast directives, +// that are ignored by the normal DDK compiler +// +#ifndef _PREFAST_ +#pragma warning(disable:4068) +#endif + +#include "win_bpf.h" + +#define MAX_REQUESTS 32 ///< Maximum number of simultaneous IOCTL requests. + +#define Packet_ALIGNMENT sizeof(int) ///< Alignment macro. Defines the alignment size. +#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) ///< Alignment macro. Rounds up to the next + ///< even multiple of Packet_ALIGNMENT. + +#define KERNEL_EVENT_NAMESPACE L"\\BaseNamedObjects\\" + +/***************************/ +/* IOCTLs */ +/***************************/ + +/*! + \brief IOCTL code: set kernel buffer size. + + This IOCTL is used to set a new size of the circular buffer associated with an instance of NPF. + When a BIOCSETBUFFERSIZE command is received, the driver frees the old buffer, allocates the new one + and resets all the parameters associated with the buffer in the OPEN_INSTANCE structure. The currently + buffered packets are lost. +*/ +#define BIOCSETBUFFERSIZE 9592 + +/*! + \brief IOCTL code: set packet filtering program. + + This IOCTL sets a new packet filter in the driver. Before allocating any memory for the new filter, the + bpf_validate() function is called to check the correctness of the filter. If this function returns TRUE, + the filter is copied to the driver's memory, its address is stored in the bpfprogram field of the + OPEN_INSTANCE structure associated with current instance of the driver, and the filter will be applied to + every incoming packet. This command also empties the circular buffer used by current instance + to store packets. This is done to avoid the presence in the buffer of packets that do not match the filter. +*/ +#define BIOCSETF 9030 + +/*! + \brief IOCTL code: get the capture stats + + This command returns to the application the number of packets received and the number of packets dropped by + an instance of the driver. +*/ +#define BIOCGSTATS 9031 + +/*! + \brief IOCTL code: set the read timeout + + This command sets the maximum timeout after which a read is released, also if no data packets were received. +*/ +#define BIOCSRTIMEOUT 7416 + +/*! + \brief IOCTL code: set working mode + + This IOCTL can be used to set the working mode of a NPF instance. The new mode, received by the driver in the + buffer associated with the IOCTL command, can be #MODE_CAPT for capture mode (the default), #MODE_STAT for + statistical mode or #MODE_DUMP for dump mode. +*/ +#define BIOCSMODE 7412 + +/*! + \brief IOCTL code: set number of physical repetions of every packet written by the app + + Sets the number of times a single write call must be repeated. This command sets the OPEN_INSTANCE::Nwrites + member, and is used to implement the 'multiple write' feature of the driver. +*/ +#define BIOCSWRITEREP 7413 + +/*! + \brief IOCTL code: set minimum amount of data in the kernel buffer that unlocks a read call + + This command sets the OPEN_INSTANCE::MinToCopy member. +*/ +#define BIOCSMINTOCOPY 7414 + +/*! + \brief IOCTL code: set an OID value + + This IOCTL is used to perform an OID set operation on the NIC driver. +*/ +#define BIOCSETOID 2147483648 + +/*! + \brief IOCTL code: get an OID value + + This IOCTL is used to perform an OID get operation on the NIC driver. +*/ +#define BIOCQUERYOID 2147483652 + +/*! + \brief IOCTL code: set the name of a the file used by kernel dump mode + + This command opens a file whose name is contained in the IOCTL buffer and associates it with current NPf instance. + The dump thread uses it to copy the content of the circular buffer to file. + If a file was already opened, the driver closes it before opening the new one. +*/ +#define BIOCSETDUMPFILENAME 9029 + +/*! + \brief IOCTL code: get the name of the event that the driver signals when some data is present in the buffer + + Command used by the application to retrieve the name of the global event associated with a NPF instance. + The event is signaled by the driver when the kernel buffer contains enough data for a transfer. +*/ +#define BIOCGEVNAME 7415 + +/*! + \brief IOCTL code: Send a buffer containing multiple packets to the network, ignoring the timestamps. + + Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by + a sf_pkthdr structure. The timestamps of the packets are ignored, i.e. the packets are sent as fast as + possible. The NPF_BufferedWrite() function is invoked to send the packets. +*/ +#define BIOCSENDPACKETSNOSYNC 9032 + +/*! + \brief IOCTL code: Send a buffer containing multiple packets to the network, considering the timestamps. + + Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by + a sf_pkthdr structure. The timestamps of the packets are used to synchronize the write, i.e. the packets + are sent to the network respecting the intervals specified in the sf_pkthdr structure assiciated with each + packet. NPF_BufferedWrite() function is invoked to send the packets. +*/ +#define BIOCSENDPACKETSSYNC 9033 + +/*! + \brief IOCTL code: Set the dump file limits. + + This IOCTL sets the limits (maximum size and maximum number of packets) of the dump file created when the + driver works in dump mode. +*/ +#define BIOCSETDUMPLIMITS 9034 + +/*! + \brief IOCTL code: Get the status of the kernel dump process. + + This command returns TRUE if the kernel dump is ended, i.e if one of the limits set with BIOCSETDUMPLIMITS + (amount of bytes or number of packets) has been reached. +*/ +#define BIOCISDUMPENDED 7411 + +/*! + \brief IOCTL code: set the loopback behavior. + + This IOCTL sets the loopback behavior of the driver with packets sent by itself: capture or drop. +*/ +#define BIOCISETLOBBEH 7410 + +/*! + \brief This IOCTL passes the read event HANDLE allocated by the user (packet.dll) to kernel level + + Parameter: HANDLE + Parameter size: sizeof(HANDLE). If the caller is 32 bit, the parameter size is 4 bytes, even if sizeof(HANDLE) at kernel level + is 8 bytes. That's why in this IOCTL code handler we detect a 32bit calling process and do the necessary thunking. + + TODO GV:I will go to hell for this ugly IOCTL definition. We should use CTL_CODE!! +*/ +#define BIOCSETEVENTHANDLE 7920 + +// Working modes +#define MODE_CAPT 0x0 ///< Capture working mode +#define MODE_STAT 0x1 ///< Statistical working mode +#define MODE_MON 0x2 ///< Kernel monitoring mode +#define MODE_DUMP 0x10 ///< Kernel dump working mode + + +#define IMMEDIATE 1 ///< Immediate timeout. Forces a read call to return immediately. + +#define NDIS_FLAGS_SKIP_LOOPBACK_W2K 0x400 ///< This is an undocumented flag for NdisSetPacketFlags() that allows to disable loopback reception. + +// The following definitions are used to provide compatibility +// of the dump files with the ones of libpcap +#define TCPDUMP_MAGIC 0xa1b2c3d4 ///< Libpcap magic number. Used by programs like tcpdump to recognize a driver's generated dump file. +#define PCAP_VERSION_MAJOR 2 ///< Major libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file. +#define PCAP_VERSION_MINOR 4 ///< Minor libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file. + +// Loopback behaviour definitions +#define NPF_DISABLE_LOOPBACK 1 ///< Tells the driver to drop the packets sent by itself. This is usefult when building applications like bridges. +#define NPF_ENABLE_LOOPBACK 2 ///< Tells the driver to capture the packets sent by itself. + +/*! + \brief Header of a libpcap dump file. + + Used when a driver instance is set in dump mode to create a libpcap-compatible file. +*/ +struct packet_file_header +{ + UINT magic; ///< Libpcap magic number + USHORT version_major; ///< Libpcap major version + USHORT version_minor; ///< Libpcap minor version + UINT thiszone; ///< Gmt to local correction + UINT sigfigs; ///< Accuracy of timestamps + UINT snaplen; ///< Length of the max saved portion of each packet + UINT linktype; ///< Data link type (DLT_*). See win_bpf.h for details. +}; + +/*! + \brief Header associated to a packet in the driver's buffer when the driver is in dump mode. + Similar to the bpf_hdr structure, but simpler. +*/ +struct sf_pkthdr { + struct timeval ts; ///< time stamp + UINT caplen; ///< Length of captured portion. The captured portion can be different from + ///< the original packet, because it is possible (with a proper filter) to + ///< instruct the driver to capture only a portion of the packets. + UINT len; ///< Length of the original packet (off wire). +}; + +/*! + \brief Stores an OID request. + + This structure is used by the driver to perform OID query or set operations on the underlying NIC driver. + The OID operations be performed usually only by network drivers, but NPF exports this mechanism to user-level + applications through an IOCTL interface. The driver uses this structure to wrap a NDIS_REQUEST structure. + This allows to handle correctly the callback structure of NdisRequest(), handling multiple requests and + maintaining information about the IRPs to complete. +*/ +typedef struct _INTERNAL_REQUEST { + LIST_ENTRY ListElement; ///< Used to handle lists of requests. +// PIRP Irp; ///< Irp that performed the request +// BOOLEAN Internal; ///< True if the request is for internal use of npf.sys. False if the request is performed by the user through an IOCTL. + NDIS_EVENT InternalRequestCompletedEvent; + NDIS_REQUEST Request; ///< The structure with the actual request, that will be passed to NdisRequest(). + NDIS_STATUS RequestStatus; + +} INTERNAL_REQUEST, *PINTERNAL_REQUEST; + +/*! + \brief Contains a NDIS packet. + + The driver uses this structure to wrap a NDIS_PACKET structure. + This allows to handle correctly the callback structure of NdisTransferData(), handling multiple requests and + maintaining information about the IRPs to complete. +*/ +typedef struct _PACKET_RESERVED { + LIST_ENTRY ListElement; ///< Used to handle lists of packets. + PIRP Irp; ///< Irp that performed the request + PMDL pMdl; ///< MDL mapping the buffer of the packet. + BOOLEAN FreeBufAfterWrite; ///< True if the memory buffer associated with the packet must be freed + ///< after a call to NdisSend(). + ULONG Cpu; ///< The CPU on which the packet was pulled out of the linked list of free packets +} PACKET_RESERVED, *PPACKET_RESERVED; + +#define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) ///< Macro to obtain a NDIS_PACKET from a PACKET_RESERVED + +/*! + \brief Port device extension. + + Structure containing some data relative to every adapter on which NPF is bound. +*/ +typedef struct _DEVICE_EXTENSION { + NDIS_HANDLE NdisProtocolHandle; ///< NDIS handle of NPF. + NDIS_STRING AdapterName; ///< Name of the adapter. + PWSTR ExportString; ///< Name of the exported device, i.e. name that the applications will use + ///< to open this adapter through WinPcap. +} DEVICE_EXTENSION, *PDEVICE_EXTENSION; + +/*! + \brief Kernel buffer of each CPU. + + Structure containing the kernel buffer (and other CPU related fields) used to capture packets. +*/ +typedef struct __CPU_Private_Data +{ + ULONG P; ///< Zero-based index of the producer in the buffer. It indicates the first free byte to be written. + ULONG C; ///< Zero-based index of the consumer in the buffer. It indicates the first free byte to be read. + ULONG Free; ///< Number of the free bytes in the buffer + PUCHAR Buffer; ///< Pointer to the kernel buffer used to capture packets. + ULONG Accepted; ///< Number of packet that current capture instance acepted, from its opening. A packet + ///< is accepted if it passes the filter and fits in the buffer. Accepted packets are the + ///< ones that reach the application. + ///< This number is related to the particular CPU this structure is referring to. + ULONG Received; ///< Number of packets received by current instance from its opening, i.e. number of + ///< packet received by the network adapter since the beginning of the + ///< capture/monitoring/dump session. + ///< This number is related to the particular CPU this structure is referring to. + ULONG Dropped; ///< Number of packet that current instance had to drop, from its opening. A packet + ///< is dropped if there is no more space to store it in the circular buffer that the + ///< driver associates to current instance. + ///< This number is related to the particular CPU this structure is referring to. + NDIS_SPIN_LOCK BufferLock; ///< It protects the buffer associated with this CPU. + PMDL TransferMdl1; ///< MDL used to map the portion of the buffer that will contain an incoming packet. + PMDL TransferMdl2; ///< Second MDL used to map the portion of the buffer that will contain an incoming packet. + ULONG NewP; ///< Used by NdisTransferData() (when we call NdisTransferData, p index must be updated only in the TransferDataComplete. +} + CpuPrivateData; + + +/*! + \brief Contains the state of a running instance of the NPF driver. + + This is the most important structure of NPF: it is used by almost all the functions of the driver. An + _OPEN_INSTANCE structure is associated with every user-level session, allowing concurrent access + to the driver. +*/ +typedef struct _OPEN_INSTANCE +{ + PDEVICE_EXTENSION DeviceExtension; ///< Pointer to the _DEVICE_EXTENSION structure of the device on which + ///< the instance is bound. + NDIS_HANDLE AdapterHandle; ///< NDIS idetifier of the adapter used by this instance. + UINT Medium; ///< Type of physical medium the underlying NDIS driver uses. See the + ///< documentation of NdisOpenAdapter in the MS DDK for details. + NDIS_HANDLE PacketPool; ///< Pool of NDIS_PACKET structures used to transfer the packets from and to the NIC driver. + KSPIN_LOCK RequestSpinLock; ///< SpinLock used to synchronize the OID requests. + LIST_ENTRY RequestList; ///< List of pending OID requests. + LIST_ENTRY ResetIrpList; ///< List of pending adapter reset requests. + INTERNAL_REQUEST Requests[MAX_REQUESTS]; ///< Array of structures that wrap every single OID request. + PMDL BufferMdl; ///< Pointer to a Memory descriptor list (MDL) that maps the circular buffer's memory. + PKEVENT ReadEvent; ///< Pointer to the event on which the read calls on this instance must wait. + PUCHAR bpfprogram; ///< Pointer to the filtering pseudo-code associated with current instance of the driver. + ///< This code is used only in particular situations (for example when the packet received + ///< from the NIC driver is stored in two non-consecutive buffers. In normal situations + ///< the filtering routine created by the JIT compiler and pointed by the next field + ///< is used. See \ref NPF for details on the filtering process. +#ifdef _X86_ + JIT_BPF_Filter *Filter; ///< Pointer to the native filtering function created by the jitter. + ///< See BPF_jitter() for details. +#endif //_X86_ + UINT MinToCopy; ///< Minimum amount of data in the circular buffer that unlocks a read. Set with the + ///< BIOCSMINTOCOPY IOCTL. + LARGE_INTEGER TimeOut; ///< Timeout after which a read is released, also if the amount of data in the buffer is + ///< less than MinToCopy. Set with the BIOCSRTIMEOUT IOCTL. + + int mode; ///< Working mode of the driver. See PacketSetMode() for details. + LARGE_INTEGER Nbytes; ///< Amount of bytes accepted by the filter when this instance is in statistical mode. + LARGE_INTEGER Npackets; ///< Number of packets accepted by the filter when this instance is in statistical mode. + NDIS_SPIN_LOCK CountersLock; ///< SpinLock that protects the statistical mode counters. + UINT Nwrites; ///< Number of times a single write must be physically repeated. See \ref NPF for an + ///< explanation + ULONG Multiple_Write_Counter; ///< Counts the number of times a single write has already physically repeated. + NDIS_EVENT WriteEvent; ///< Event used to synchronize the multiple write process. + BOOLEAN WriteInProgress; ///< True if a write is currently in progress. NPF currently allows a single wite on + ///< the same open instance. + NDIS_SPIN_LOCK WriteLock; ///< SpinLock that protects the WriteInProgress variable. + NDIS_EVENT NdisRequestEvent; ///< Event used to synchronize I/O requests with the callback structure of NDIS. + BOOLEAN SkipSentPackets; ///< True if this instance should not capture back the packets that it transmits. + NDIS_STATUS IOStatus; ///< Maintains the status of and OID request call, that will be passed to the application. + HANDLE DumpFileHandle; ///< Handle of the file used in dump mode. + PFILE_OBJECT DumpFileObject; ///< Pointer to the object of the file used in dump mode. + PKTHREAD DumpThreadObject; ///< Pointer to the object of the thread used in dump mode. + HANDLE DumpThreadHandle; ///< Handle of the thread created by dump mode to asynchronously move the buffer to disk. + NDIS_EVENT DumpEvent; ///< Event used to synchronize the dump thread with the tap when the instance is in dump mode. + LARGE_INTEGER DumpOffset; ///< Current offset in the dump file. + UNICODE_STRING DumpFileName; ///< String containing the name of the dump file. + UINT MaxDumpBytes; ///< Maximum dimension in bytes of the dump file. If the dump file reaches this size it + ///< will be closed. A value of 0 means unlimited size. + UINT MaxDumpPacks; ///< Maximum number of packets that will be saved in the dump file. If this number of + ///< packets is reached the dump will be closed. A value of 0 means unlimited number of + ///< packets. + BOOLEAN DumpLimitReached; ///< TRUE if the maximum dimension of the dump file (MaxDumpBytes or MaxDumpPacks) is + ///< reached. + MEM_TYPE mem_ex; ///< Memory used by the TME virtual co-processor + TME_CORE tme; ///< Data structure containing the virtualization of the TME co-processor + NDIS_SPIN_LOCK MachineLock; ///< SpinLock that protects the BPF filter and the TME engine, if in use. + UINT MaxFrameSize; ///< Maximum frame size that the underlying MAC acceptes. Used to perform a check on the + ///< size of the frames sent with NPF_Write() or NPF_BufferedWrite(). + CpuPrivateData CpuData[32]; ///< Pool of kernel buffer structures, one for each CPU. + ULONG ReaderSN; ///< Sequence number of the next packet to be read from the pool of kernel buffers. + ULONG WriterSN; ///< Sequence number of the next packet to be written in the pool of kernel buffers. + ///< These two sequence numbers are unique for each capture instance. + ULONG Size; ///< Size of each kernel buffer contained in the CpuData field. + ULONG AdapterHandleUsageCounter; + NDIS_SPIN_LOCK AdapterHandleLock; + ULONG AdapterBindingStatus; ///< Specifies if NPF is still bound to the adapter used by this instance, it's unbinding or it's not bound. + + NDIS_EVENT NdisOpenCloseCompleteEvent; + NDIS_EVENT NdisWriteCompleteEvent; ///< Event that is signalled when all the packets have been successfully sent by NdisSend (and corresponfing sendComplete has been called) + NTSTATUS OpenCloseStatus; + ULONG TransmitPendingPackets; ///< Specifies the number of packets that are pending to be transmitted, i.e. have been submitted to NdisSendXXX but the SendComplete has not been called yet. +} +OPEN_INSTANCE, *POPEN_INSTANCE; + +enum ADAPTER_BINDING_STATUS +{ + ADAPTER_UNBOUND, + ADAPTER_BOUND, + ADAPTER_UNBINDING, +}; + +/*! + \brief Structure prepended to each packet in the kernel buffer pool. + + Each packet in one of the kernel buffers is prepended by this header. It encapsulates the bpf_header, + which will be passed to user level programs, as well as the sequence number of the packet, set by the producer (the tap function), + and used by the consumer (the read function) to "reorder" the packets contained in the various kernel buffers. +*/ +struct PacketHeader +{ + ULONG SN; ///< Sequence number of the packet. + struct bpf_hdr header; ///< bpf header, created by the tap, and copied unmodified to user level programs. +}; + +extern ULONG NCpu; + + +#define TRANSMIT_PACKETS 256 ///< Maximum number of packets in the transmit packet pool. This value is an upper bound to the number + ///< of packets that can be transmitted at the same time or with a single call to NdisSendPackets. + + +/// Macro used in the I/O routines to return the control to user-mode with a success status. +#define EXIT_SUCCESS(quantity) Irp->IoStatus.Information=quantity;\ + Irp->IoStatus.Status = STATUS_SUCCESS;\ + IoCompleteRequest(Irp, IO_NO_INCREMENT);\ + return STATUS_SUCCESS;\ + +/// Macro used in the I/O routines to return the control to user-mode with a failure status. +#define EXIT_FAILURE(quantity) Irp->IoStatus.Information=quantity;\ + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;\ + IoCompleteRequest(Irp, IO_NO_INCREMENT);\ + return STATUS_UNSUCCESSFUL;\ + +/** + * @} + */ + + +/***************************/ +/* Prototypes */ +/***************************/ + +/** @defgroup NPF_code NPF functions + * @{ + */ + + +/*! + \brief The initialization routine of the driver. + \param DriverObject The driver object of NPF created by the system. + \param RegistryPath The registry path containing the keys related to the driver. + \return A string containing a list of network adapters. + + DriverEntry is a mandatory function in a device driver. Like the main() of a user level program, it is called + by the system when the driver is loaded in memory and started. Its purpose is to initialize the driver, + performing all the allocations and the setup. In particular, DriverEntry registers all the driver's I/O + callbacks, creates the devices, defines NPF as a protocol inside NDIS. +*/ +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ); + +/*! + \brief Returns the list of the MACs available on the system. + \return A string containing a list of network adapters. + + The list of adapters is retrieved from the + SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318} registry key. + NPF tries to create its bindings from this list. In this way it is possible to be loaded + and unloaded dynamically without passing from the control panel. +*/ +PWCHAR getAdaptersList(VOID); + +/*! + \brief Returns the MACs that bind to TCP/IP. + \return Pointer to the registry key containing the list of adapters on which TCP/IP is bound. + + If getAdaptersList() fails, NPF tries to obtain the TCP/IP bindings through this function. +*/ +PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(VOID); + +/*! + \brief Creates a device for a given MAC. + \param adriverObjectP The driver object that will be associated with the device, i.e. the one of NPF. + \param amacNameP The name of the network interface that the device will point. + \param aProtoHandle NDIS protocol handle of NPF. + \return If the function succeeds, the return value is nonzero. + + NPF creates a device for every valid network adapter. The new device points to the NPF driver, but contains + information about the original device. In this way, when the user opens the new device, NPF will be able to + determine the correct adapter to use. +*/ +BOOLEAN createDevice( + IN OUT PDRIVER_OBJECT adriverObjectP, + IN PUNICODE_STRING amacNameP, + NDIS_HANDLE aProtoHandle); + +/*! + \brief Opens a new instance of the driver. + \param DeviceObject Pointer to the device object utilized by the user. + \param Irp Pointer to the IRP containing the user request. + \return The status of the operation. See ntstatus.h in the DDK. + + This function is called by the OS when a new instance of the driver is opened, i.e. when a user application + performs a CreateFile on a device created by NPF. NPF_Open allocates and initializes variables, objects + and buffers needed by the new instance, fills the OPEN_INSTANCE structure associated with it and opens the + adapter with a call to NdisOpenAdapter. +*/ +NTSTATUS +NPF_Open( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +/*! + \brief Ends the opening of an adapter. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + \param Status Status of the opening operation performed by NDIS. + \param OpenErrorStatus not used by NPF. + + Callback function associated with the NdisOpenAdapter() NDIS function. It is invoked by NDIS when the NIC + driver has finished an open operation that was previously started by NPF_Open(). +*/ +VOID +NPF_OpenAdapterComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN NDIS_STATUS OpenErrorStatus + ); + +/*! + \brief Closes an instance of the driver. + \param DeviceObject Pointer to the device object utilized by the user. + \param Irp Pointer to the IRP containing the user request. + \return The status of the operation. See ntstatus.h in the DDK. + + This function is called when a running instance of the driver is closed by the user with a CloseHandle(). + It stops the capture/monitoring/dump process, deallocates the memory and the objects associated with the + instance and closing the files. The network adapter is then closed with a call to NdisCloseAdapter. +*/ +NTSTATUS +NPF_Cleanup( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +NTSTATUS +NPF_Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + + + +/*! + \brief Ends the closing of an adapter. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + \param Status Status of the close operation performed by NDIS. + + Callback function associated with the NdisCloseAdapter() NDIS function. It is invoked by NDIS when the NIC + driver has finished a close operation that was previously started by NPF_Close(). +*/ +VOID +NPF_CloseAdapterComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status + ); + +/*! + \brief Callback invoked by NDIS when a packet arrives from the network. + \param ProtocolBindingContext Context of the function. Points to a OPEN_INSTANCE structure that identifies + the NPF instance to which the packets are destined. + \param MacReceiveContext Handle that identifies the underlying NIC driver that generated the request. + This value must be used when the packet is transferred from the NIC driver with NdisTransferData(). + \param HeaderBuffer Pointer to the buffer in the NIC driver memory that contains the header of the packet. + \param HeaderBufferSize Size in bytes of the header. + \param LookAheadBuffer Pointer to the buffer in the NIC driver's memory that contains the incoming packet's + data available to NPF. This value does not necessarily coincide with the actual size of the packet, + since only a portion can be available at this time. The remaining portion can be obtained with the + NdisTransferData() NDIS function. + \param LookaheadBufferSize Size in bytes of the lookahead buffer. + \param PacketSize Total size of the incoming packet, excluded the header. + \return The status of the operation. See ntstatus.h in the DDK. + + NPF_tap() is called by the underlying NIC for every incoming packet. It is the most important and one of + the most complex functions of NPF: it executes the filter, runs the statistical engine (if the instance is in + statistical mode), gathers the timestamp, moves the packet in the buffer. NPF_tap() is the only function, + along with the filtering ones, that is executed for every incoming packet, therefore it is carefully + optimized. +*/ +NDIS_STATUS +NPF_tap( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_HANDLE MacReceiveContext, + IN PVOID HeaderBuffer, + IN UINT HeaderBufferSize, + IN PVOID LookAheadBuffer, + IN UINT LookaheadBufferSize, + IN UINT PacketSize + ); + +/*! + \brief Ends the transfer of a packet. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + \param Packet Pointer to the NDIS_PACKET structure that received the packet data. + \param Status Status of the transfer operation. + \param BytesTransferred Amount of bytes transferred. + + Callback function associated with the NdisTransferData() NDIS function. It is invoked by NDIS when the NIC + driver has finished the transfer of a packet from the NIC driver memory to the NPF circular buffer. +*/ +VOID +NPF_TransferDataComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET Packet, + IN NDIS_STATUS Status, + IN UINT BytesTransferred + ); + +/*! + \brief Callback function that signals the end of a packet reception. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + + does nothing in NPF +*/ +VOID +NPF_ReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext); + +/*! + \brief Handles the IOCTL calls. + \param DeviceObject Pointer to the device object utilized by the user. + \param Irp Pointer to the IRP containing the user request. + \return The status of the operation. See ntstatus.h in the DDK. + + Once the packet capture driver is opened it can be configured from user-level applications with IOCTL commands + using the DeviceIoControl() system call. NPF_IoControl receives and serves all the IOCTL calls directed to NPF. + The following commands are recognized: + - #BIOCSETBUFFERSIZE + - #BIOCSETF + - #BIOCGSTATS + - #BIOCSRTIMEOUT + - #BIOCSMODE + - #BIOCSWRITEREP + - #BIOCSMINTOCOPY + - #BIOCSETOID + - #BIOCQUERYOID + - #BIOCSETDUMPFILENAME + - #BIOCGEVNAME + - #BIOCSENDPACKETSSYNC + - #BIOCSENDPACKETSNOSYNC +*/ +NTSTATUS +NPF_IoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +VOID + +/*! + \brief Ends an OID request. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + \param pRequest Pointer to the completed OID request. + \param Status Status of the operation. + + Callback function associated with the NdisRequest() NDIS function. It is invoked by NDIS when the NIC + driver has finished an OID request operation that was previously started by NPF_IoControl(). +*/ +NPF_RequestComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_REQUEST pRequest, + IN NDIS_STATUS Status + ); + +/*! + \brief Writes a raw packet to the network. + \param DeviceObject Pointer to the device object on which the user wrote the packet. + \param Irp Pointer to the IRP containing the user request. + \return The status of the operation. See ntstatus.h in the DDK. + + This function is called by the OS in consequence of user WriteFile() call, with the data of the packet that must + be sent on the net. The data is contained in the buffer associated with Irp, NPF_Write takes it and + delivers it to the NIC driver via the NdisSend() function. The Nwrites field of the OPEN_INSTANCE structure + associated with Irp indicates the number of copies of the packet that will be sent: more than one copy of the + packet can be sent for performance reasons. +*/ +NTSTATUS +NPF_Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + + +/*! + \brief Writes a buffer of raw packets to the network. + \param Irp Pointer to the IRP containing the user request. + \param UserBuff Pointer to the buffer containing the packets to send. + \param UserBuffSize Size of the buffer with the packets. + \param sync If set to TRUE, the packets are transmitted respecting their timestamps. + \return The amount of bytes actually sent. If the return value is smaller than the Size parameter, an + error occurred during the send. The error can be caused by an adapter problem or by an + inconsistent/bogus user buffer. + + This function is called by the OS in consequence of a BIOCSENDPACKETSNOSYNC or a BIOCSENDPACKETSSYNC IOCTL. + The buffer received as input parameter contains an arbitrary number of packets, each of which preceded by a + sf_pkthdr structure. NPF_BufferedWrite() scans the buffer and sends every packet via the NdisSend() function. + When Sync is set to TRUE, the packets are synchronized with the KeQueryPerformanceCounter() function. + This requires a remarkable amount of CPU, but allows to respect the timestamps associated with packets with a precision + of some microseconds (depending on the precision of the performance counter of the machine). + If Sync is false, the timestamps are ignored and the packets are sent as fat as possible. +*/ + +INT NPF_BufferedWrite(IN PIRP Irp, + IN PCHAR UserBuff, + IN ULONG UserBuffSize, + BOOLEAN sync); + +/*! + \brief Waits the completion of all the sends performed by NPF_BufferedWrite. + + \param Open Pointer to open context structure + + Used by NPF_BufferedWrite to wait the completion of all the sends before returning the control to the user. +*/ +VOID NPF_WaitEndOfBufferedWrite(POPEN_INSTANCE Open); + +/*! + \brief Ends a send operation. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + \param pPacket Pointer to the NDIS PACKET structure used by NPF_Write() to send the packet. + \param Status Status of the operation. + + Callback function associated with the NdisSend() NDIS function. It is invoked by NDIS when the NIC + driver has finished an OID request operation that was previously started by NPF_Write(). +*/ +VOID +NPF_SendComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET pPacket, + IN NDIS_STATUS Status + ); + +/*! + \brief Ends a reset of the adapter. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + \param Status Status of the operation. + + Callback function associated with the NdisReset() NDIS function. It is invoked by NDIS when the NIC + driver has finished an OID request operation that was previously started by NPF_IoControl(), in an IOCTL_PROTOCOL_RESET + command. +*/ +VOID +NPF_ResetComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status + ); + +/*! + \brief Callback for NDIS StatusHandler. Not used by NPF +*/ +VOID +NPF_Status( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN PVOID StatusBuffer, + IN UINT StatusBufferSize + ); + + +/*! + \brief Callback for NDIS StatusCompleteHandler. Not used by NPF +*/ +VOID +NPF_StatusComplete(IN NDIS_HANDLE ProtocolBindingContext); + +/*! + \brief Function called by the OS when NPF is unloaded. + \param DriverObject The driver object of NPF created by the system. + + This is the last function executed when the driver is unloaded from the system. It frees global resources, + delete the devices and deregisters the protocol. The driver can be unloaded by the user stopping the NPF + service (from control panel or with a console 'net stop npf'). +*/ +VOID +NPF_Unload(IN PDRIVER_OBJECT DriverObject); + + +/*! + \brief Function that serves the user's reads. + \param DeviceObject Pointer to the device used by the user. + \param Irp Pointer to the IRP containing the user request. + \return The status of the operation. See ntstatus.h in the DDK. + + This function is called by the OS in consequence of user ReadFile() call. It moves the data present in the + kernel buffer to the user buffer associated with Irp. + First of all, NPF_Read checks the amount of data in kernel buffer associated with current NPF instance. + - If the instance is in capture mode and the buffer contains more than OPEN_INSTANCE::MinToCopy bytes, + NPF_Read moves the data in the user buffer and returns immediatly. In this way, the read performed by the + user is not blocking. + - If the buffer contains less than MinToCopy bytes, the application's request isn't + satisfied immediately, but it's blocked until at least MinToCopy bytes arrive from the net + or the timeout on this read expires. The timeout is kept in the OPEN_INSTANCE::TimeOut field. + - If the instance is in statistical mode or in dump mode, the application's request is blocked until the + timeout kept in OPEN_INSTANCE::TimeOut expires. +*/ +NTSTATUS +NPF_Read( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +/*! + \brief Reads the registry keys associated woth NPF if the driver is manually installed via the control panel. + + Normally not used in recent versions of NPF. +*/ +NTSTATUS +NPF_ReadRegistry( + IN PWSTR *MacDriverName, + IN PWSTR *PacketDriverName, + IN PUNICODE_STRING RegistryPath + ); + +/*! + \brief Function used by NPF_ReadRegistry() to quesry the registry keys associated woth NPF if the driver + is manually installed via the control panel. + + Normally not used in recent versions of NPF. +*/ +NTSTATUS +NPF_QueryRegistryRoutine( + IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext + ); + +/*! + \brief Callback for NDIS BindAdapterHandler. Not used by NPF. + + Function called by NDIS when a new adapter is installed on the machine With Plug and Play. +*/ +VOID NPF_BindAdapter( + OUT PNDIS_STATUS Status, + IN NDIS_HANDLE BindContext, + IN PNDIS_STRING DeviceName, + IN PVOID SystemSpecific1, + IN PVOID SystemSpecific2 + ); + +/*! + \brief Callback for NDIS UnbindAdapterHandler. + \param Status out variable filled by NPF_UnbindAdapter with the status of the unbind operation. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with current instance. + \param UnbindContext Specifies a handle, supplied by NDIS, that NPF can use to complete the opration. + + Function called by NDIS when a new adapter is removed from the machine without shutting it down. + NPF_UnbindAdapter closes the adapter calling NdisCloseAdapter() and frees the memory and the structures + associated with it. It also releases the waiting user-level app and closes the dump thread if the instance + is in dump mode. +*/ +VOID +NPF_UnbindAdapter( + OUT PNDIS_STATUS Status, + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_HANDLE UnbindContext + ); + + +/*! + \brief Creates the file that will receive the packets when the driver is in dump mode. + \param Open The NPF instance that opens the file. + \param fileName Pointer to a UNICODE string containing the name of the file. + \param append Boolean value that specifies if the data must be appended to the file. + \return The status of the operation. See ntstatus.h in the DDK. +*/ +NTSTATUS NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN append); + +/*! + \brief Starts dump to file. + \param Open The NPF instance that opens the file. + \return The status of the operation. See ntstatus.h in the DDK. + + This function performs two operations. First, it writes the libpcap header at the beginning of the file. + Second, it starts the thread that asynchronously dumps the network data to the file. +*/ +NTSTATUS NPF_StartDump(POPEN_INSTANCE Open); + +/*! + \brief The dump thread. + \param Open The NPF instance that creates the thread. + + This function moves the content of the NPF kernel buffer to file. It runs in the user context, so at lower + priority than the TAP. +*/ +VOID NPF_DumpThread(PVOID Open); + +/*! + \brief Saves the content of the packet buffer to the file associated with current instance. + \param Open The NPF instance that creates the thread. + + Used by NPF_DumpThread() and NPF_CloseDumpFile(). +*/ +NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open); + +/*! + \brief Writes a block of packets on the dump file. + \param FileObject The file object that will receive the packets. + \param Offset The offset in the file where the packets will be put. + \param Length The amount of bytes to write. + \param Mdl MDL mapping the memory buffer that will be written to disk. + \param IoStatusBlock Used by the function to return the status of the operation. + \return The status of the operation. See ntstatus.h in the DDK. + + NPF_WriteDumpFile addresses directly the file system, creating a custom IRP and using it to send a portion + of the NPF circular buffer to disk. This function is used by NPF_DumpThread(). +*/ +VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject, + PLARGE_INTEGER Offset, + ULONG Length, + PMDL Mdl, + PIO_STATUS_BLOCK IoStatusBlock); + + + +/*! + \brief Closes the dump file associated with an instance of the driver. + \param Open The NPF instance that closes the file. + \return The status of the operation. See ntstatus.h in the DDK. +*/ +NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open); + +VOID +NPF_CloseOpenInstance(POPEN_INSTANCE pOpen); + +BOOLEAN +NPF_StartUsingBinding( + IN POPEN_INSTANCE pOpen); + +VOID +NPF_StopUsingBinding( + IN POPEN_INSTANCE pOpen); + +VOID +NPF_CloseBinding( + IN POPEN_INSTANCE pOpen); + +NTSTATUS +NPF_GetDeviceMTU( + IN POPEN_INSTANCE pOpen, + IN PIRP pIrp, + OUT PUINT pMtu); + +/*! + \brief Returns the amount of bytes present in the packet buffer. + \param Open The NPF instance that closes the file. +*/ +UINT GetBuffOccupation(POPEN_INSTANCE Open); + +/*! + \brief Called by NDIS to notify us of a PNP event. The most significant one for us is power state change. + + \param ProtocolBindingContext Pointer to open context structure. This is NULL for global reconfig + events. + \param pNetPnPEvent Pointer to the PnP event + + If there is a power state change, the driver is forced to resynchronize the global timer. + This hopefully avoids the synchronization issues caused by hibernation or standby. + This function is excluded from the NT4 driver, where PnP is not supported +*/ +#ifdef NDIS50 +NDIS_STATUS NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent); +#endif + +// +// Old registry based WinPcap names +// +///*! +// \brief Helper function to query a value from the global WinPcap registry key +//*/ +//VOID NPF_QueryWinpcapRegistryString(PWSTR SubKeyName, +// WCHAR *Value, +// UINT ValueLen, +// WCHAR *DefaultValue); +// + + +/** + * @} + */ + +/** + * @} + */ + +#endif /*main ifndef/define*/ \ No newline at end of file diff --git a/winpcap/packetNtx/driver/Read.c b/winpcap/packetNtx/driver/Read.c new file mode 100644 index 0000000..861d147 --- /dev/null +++ b/winpcap/packetNtx/driver/Read.c @@ -0,0 +1,987 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2007 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include "debug.h" +#include "packet.h" +#include "win_bpf.h" +#include "time_calls.h" + +#ifdef HAVE_BUGGY_TME_SUPPORT +#include "tme.h" +#endif //HAVE_BUGGY_TME_SUPPORT + +extern struct time_conv G_Start_Time; // from openclos.c + +extern ULONG NCpu; //from packet.c + +NTSTATUS NPF_Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PUCHAR packp; + ULONG Input_Buffer_Length; + UINT Thead; + UINT Ttail; + UINT TLastByte; + PUCHAR CurrBuff; + LARGE_INTEGER CapTime; + LARGE_INTEGER TimeFreq; + struct bpf_hdr *header; + KIRQL Irql; + PUCHAR UserPointer; + ULONG bytecopy; + UINT SizeToCopy; + UINT PktLen; + ULONG copied,count,current_cpu,av,plen,increment,ToCopy,available; + CpuPrivateData *LocalData; + ULONG i; + ULONG Occupation; + + IF_LOUD(DbgPrint("NPF: Read\n");) + + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + Open=IrpSp->FileObject->FsContext; + + // + // we need to test if the device is still bound to the Network adapter, + // so we perform a start/stop using binding. + // This is not critical, since we just want to have a quick way to have the + // dispatch read fail in case the adapter has been unbound + + if(NPF_StartUsingBinding(Open) == FALSE) + { + // The Network adapter has been removed or diasabled + EXIT_FAILURE(0); + } + NPF_StopUsingBinding(Open); + + if (Open->Size == 0) + { + EXIT_FAILURE(0); + } + + if( Open->mode & MODE_DUMP && Open->DumpFileHandle == NULL ){ + // this instance is in dump mode, but the dump file has still not been opened + EXIT_FAILURE(0); + } + + Occupation=0; + + for(i=0;iSize - Open->CpuData[i].Free); + + //See if the buffer is full enough to be copied + if( Occupation <= Open->MinToCopy*NCpu || Open->mode & MODE_DUMP ) + { + if (Open->ReadEvent != NULL) + { + //wait until some packets arrive or the timeout expires + if(Open->TimeOut.QuadPart != (LONGLONG)IMMEDIATE) + KeWaitForSingleObject(Open->ReadEvent, + UserRequest, + KernelMode, + TRUE, + (Open->TimeOut.QuadPart == (LONGLONG)0)? NULL: &(Open->TimeOut)); + + KeClearEvent(Open->ReadEvent); + } + + if(Open->mode & MODE_STAT) + { //this capture instance is in statistics mode +#ifdef NDIS50 + CurrBuff=(PUCHAR)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); +#else + CurrBuff=(PUCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress); +#endif + + if (CurrBuff == NULL) + { + EXIT_FAILURE(0); + } + + + //fill the bpf header for this packet + header=(struct bpf_hdr*)CurrBuff; + GET_TIME(&header->bh_tstamp,&G_Start_Time); + + if(Open->mode & MODE_DUMP){ + *(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr)+16)=Open->DumpOffset.QuadPart; + header->bh_caplen=24; + header->bh_datalen=24; + Irp->IoStatus.Information = 24 + sizeof(struct bpf_hdr); + } + else{ + header->bh_caplen=16; + header->bh_datalen=16; + header->bh_hdrlen=sizeof(struct bpf_hdr); + Irp->IoStatus.Information = 16 + sizeof(struct bpf_hdr); + } + + *(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr))=Open->Npackets.QuadPart; + *(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr)+8)=Open->Nbytes.QuadPart; + + //reset the countetrs + NdisAcquireSpinLock( &Open->CountersLock ); + Open->Npackets.QuadPart=0; + Open->Nbytes.QuadPart=0; + NdisReleaseSpinLock( &Open->CountersLock ); + + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; + } + +// +// The MONITOR_MODE (aka TME extensions) is not supported on +// 64 bit architectures +// +#ifdef HAVE_BUGGY_TME_SUPPORT + + if(Open->mode==MODE_MON) //this capture instance is in monitor mode + { + PTME_DATA data; + ULONG cnt; + ULONG block_size; + PUCHAR tmp; + +#ifdef NDIS50 + UserPointer=MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); +#else + UserPointer=MmGetSystemAddressForMdl(Irp->MdlAddress); +#endif + + if (UserPointer == NULL) + { + EXIT_FAILURE(0); + } + + if ((!IS_VALIDATED(Open->tme.validated_blocks,Open->tme.active_read))||(IrpSp->Parameters.Read.Lengthbh_tstamp,&G_Start_Time); + + + header->bh_hdrlen=sizeof(struct bpf_hdr); + + + //moves user memory pointer + UserPointer+=sizeof(struct bpf_hdr); + + //calculus of data to be copied + //if the user buffer is smaller than data to be copied, + //only some data will be copied + data=&Open->tme.block_data[Open->tme.active_read]; + + if (data->last_read.tv_sec!=0) + data->last_read=header->bh_tstamp; + + + bytecopy=data->block_size*data->filled_blocks; + + if ((IrpSp->Parameters.Read.Length-sizeof(struct bpf_hdr))Parameters.Read.Length-sizeof(struct bpf_hdr))/ data->block_size; + else + bytecopy=data->filled_blocks; + + tmp=data->shared_memory_base_address; + block_size=data->block_size; + + for (cnt=0;cntMachineLock); + RtlCopyMemory(UserPointer,tmp,block_size); + NdisReleaseSpinLock(&Open->MachineLock); + tmp+=block_size; + UserPointer+=block_size; + } + + bytecopy*=block_size; + + header->bh_caplen=bytecopy; + header->bh_datalen=header->bh_caplen; + + EXIT_SUCCESS(bytecopy+sizeof(struct bpf_hdr)); + } + + Occupation=0; + + for(i=0;iSize - Open->CpuData[i].Free); + + + if ( Occupation == 0 || Open->mode & MODE_DUMP) + // The timeout has expired, but the buffer is still empty (or the packets must be written to file). + // We must awake the application, returning an empty buffer. + { + EXIT_SUCCESS(0); + } + +#else // not HAVE_BUGGY_TME_SUPPORT + if(Open->mode==MODE_MON) //this capture instance is in monitor mode + { + EXIT_FAILURE(0); + } +#endif // HAVE_BUGGY_TME_SUPPORT + + } + + + +//------------------------------------------------------------------------------ + copied=0; + count=0; + current_cpu=0; + available = IrpSp->Parameters.Read.Length; +#ifdef NDIS50 + packp=(PUCHAR)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); +#else + packp=(PUCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress); +#endif + + if (packp == NULL) + { + EXIT_FAILURE(0); + } + + if (Open->ReadEvent != NULL) + KeClearEvent(Open->ReadEvent); + + while (count < NCpu) //round robin on the CPUs, if count = NCpu there are no packets left to be copied + { + if (available == copied) + { + EXIT_SUCCESS(copied); + } + + LocalData = &Open->CpuData[current_cpu]; + + if (LocalData->Free < Open->Size) + { //there are some packets in the selected (aka LocalData) buffer + struct PacketHeader *Header = (struct PacketHeader*)(LocalData->Buffer + LocalData->C); + + if ( Header->SN == Open->ReaderSN) + { //check if it the next one to be copied + plen = Header->header.bh_caplen; + if (plen + sizeof (struct bpf_hdr) > available - copied) + { //if the packet does not fit into the user buffer, we've ended copying packets + EXIT_SUCCESS(copied); + } + +// FIX_TIMESTAMPS(&Header->header.bh_tstamp); + + *((struct bpf_hdr*)(&packp[copied]))=Header->header; + + copied += sizeof(struct bpf_hdr); + LocalData->C += sizeof(struct PacketHeader); + + if (LocalData->C == Open->Size) + LocalData->C = 0; + + if (Open->Size - LocalData->C < plen) + { + //the packet is fragmented in the buffer (i.e. it skips the buffer boundary) + ToCopy = Open->Size - LocalData->C; + RtlCopyMemory(packp + copied,LocalData->Buffer + LocalData->C,ToCopy); + RtlCopyMemory(packp + copied + ToCopy,LocalData->Buffer,plen-ToCopy); + LocalData->C = plen-ToCopy; + } + else + { + //the packet is not fragmented + RtlCopyMemory(packp + copied ,LocalData->Buffer + LocalData->C ,plen); + LocalData->C += plen; + // if (c==size) inutile, contemplato nell "header atomico" + // c=0; + } + + Open->ReaderSN++; + copied+=Packet_WORDALIGN(plen); + + increment = plen + sizeof(struct PacketHeader); + if ( Open->Size - LocalData->C < sizeof(struct PacketHeader)) + { //the next packet would be saved at the end of the buffer, but the NewHeader struct would be fragmented + //so the producer (--> the consumer) skips to the beginning of the buffer + increment += Open->Size-LocalData->C; + LocalData->C=0; + } + InterlockedExchangeAdd(&Open->CpuData[current_cpu].Free,increment); + count=0; + } + else + { + current_cpu=(current_cpu+1)%NCpu; + count++; + } + + } + else + { + current_cpu=(current_cpu+1)%NCpu; + count++; + } + } + + {EXIT_SUCCESS(copied);} + +//------------------------------------------------------------------------------ + +} + +NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacReceiveContext, + IN PVOID HeaderBuffer,IN UINT HeaderBufferSize,IN PVOID LookaheadBuffer, + IN UINT LookaheadBufferSize,IN UINT PacketSize) +{ + POPEN_INSTANCE Open; + PNDIS_PACKET pPacket; + ULONG SizeToTransfer; + NDIS_STATUS Status; + UINT BytesTransfered; + ULONG BufferLength; + PMDL pMdl1,pMdl2; + LARGE_INTEGER CapTime; + LARGE_INTEGER TimeFreq; + UINT fres; + USHORT NPFHdrSize; + + CpuPrivateData *LocalData; + ULONG Cpu; + struct PacketHeader *Header; + ULONG ToCopy; + ULONG increment; + ULONG i; + BOOLEAN ShouldReleaseBufferLock; + + IF_VERY_LOUD(DbgPrint("NPF: tap\n");) + IF_VERY_LOUD(DbgPrint("HeaderBufferSize=%u, LookAheadBuffer=%p, LookaheadBufferSize=%u, PacketSize=%u\n", + HeaderBufferSize, + LookaheadBuffer, + LookaheadBufferSize, + PacketSize);) + + Open= (POPEN_INSTANCE)ProtocolBindingContext; + + Cpu = KeGetCurrentProcessorNumber(); + LocalData = &Open->CpuData[Cpu]; + + LocalData->Received++; + IF_LOUD(DbgPrint("Received on CPU %d \t%d\n",Cpu,LocalData->Received);) +// Open->Received++; // Number of packets received by filter ++ + + NdisAcquireSpinLock(&Open->MachineLock); + + // + //Check if the lookahead buffer follows the mac header. + //If the data follow the header (i.e. there is only a buffer) a normal bpf_filter() is + //executed on the packet. + //Otherwise if there are 2 separate buffers (this could be the case of LAN emulation or + //things like this) bpf_filter_with_2_buffers() is executed. + // + if((UINT)((PUCHAR)LookaheadBuffer-(PUCHAR)HeaderBuffer) != HeaderBufferSize) + fres=bpf_filter_with_2_buffers((struct bpf_insn*)(Open->bpfprogram), + HeaderBuffer, + LookaheadBuffer, + HeaderBufferSize, + PacketSize+HeaderBufferSize, + LookaheadBufferSize+HeaderBufferSize, + &Open->mem_ex, + &Open->tme, + &G_Start_Time); + + + else +// +// the jit filter is available on x86 (32 bit) only +// +#ifdef _X86_ + + if(Open->Filter != NULL) + { + if (Open->bpfprogram != NULL) + { + fres=Open->Filter->Function(HeaderBuffer, + PacketSize+HeaderBufferSize, + LookaheadBufferSize+HeaderBufferSize); + } + else + fres = -1; + } + else +#endif //_X86_ + fres=bpf_filter((struct bpf_insn*)(Open->bpfprogram), + HeaderBuffer, + PacketSize+HeaderBufferSize, + LookaheadBufferSize+HeaderBufferSize, + &Open->mem_ex, + &Open->tme, + &G_Start_Time); + + NdisReleaseSpinLock(&Open->MachineLock); + +// +// The MONITOR_MODE (aka TME extensions) is not supported on +// 64 bit architectures +// +#ifdef HAVE_BUGGY_TME_SUPPORT + if(Open->mode==MODE_MON) + // we are in monitor mode + { + if (fres==1) + { + if (Open->ReadEvent != NULL) + { + KeSetEvent(Open->ReadEvent,0,FALSE); + } + } + return NDIS_STATUS_NOT_ACCEPTED; + + } +#endif //HAVE_BUGGY_TME_SUPPORT + + if(fres==0) + { + // Packet not accepted by the filter, ignore it. + return NDIS_STATUS_NOT_ACCEPTED; + } + + //if the filter returns -1 the whole packet must be accepted + if(fres == -1 || fres > PacketSize+HeaderBufferSize) + fres = PacketSize+HeaderBufferSize; + + if(Open->mode & MODE_STAT) + { + // we are in statistics mode + NdisAcquireSpinLock( &Open->CountersLock ); + + Open->Npackets.QuadPart++; + + if(PacketSize+HeaderBufferSize<60) + Open->Nbytes.QuadPart+=60; + else + Open->Nbytes.QuadPart+=PacketSize+HeaderBufferSize; + // add preamble+SFD+FCS to the packet + // these values must be considered because are not part of the packet received from NDIS + Open->Nbytes.QuadPart+=12; + + NdisReleaseSpinLock( &Open->CountersLock ); + + if(!(Open->mode & MODE_DUMP)) + { + return NDIS_STATUS_NOT_ACCEPTED; + } + } + + if(Open->Size == 0) + { + LocalData->Dropped++; + return NDIS_STATUS_NOT_ACCEPTED; + } + + if(Open->mode & MODE_DUMP && Open->MaxDumpPacks) + { + ULONG Accepted=0; + for(i=0;iCpuData[i].Accepted; + + if( Accepted > Open->MaxDumpPacks) + { + // Reached the max number of packets to save in the dump file. Discard the packet and stop the dump thread. + Open->DumpLimitReached = TRUE; // This stops the thread + // Awake the dump thread + NdisSetEvent(&Open->DumpEvent); + + // Awake the application + if (Open->ReadEvent != NULL) + KeSetEvent(Open->ReadEvent,0,FALSE); + + return NDIS_STATUS_NOT_ACCEPTED; + } + } + + //////////////////////////////COPIA.C//////////////////////////////////////////77 + + ShouldReleaseBufferLock = TRUE; + NdisDprAcquireSpinLock(&LocalData->BufferLock); + + do + { + + if (fres + sizeof(struct PacketHeader) > LocalData->Free) + { + LocalData->Dropped++; + break; + } + + if (LocalData->TransferMdl1 != NULL) + { + // + //if TransferMdl is not NULL, there is some TransferData pending (i.e. not having called TransferDataComplete, yet) + //in order to avoid buffer corruption, we drop the packet + // + LocalData->Dropped++; + break; + } + + + if (LookaheadBufferSize + HeaderBufferSize >= fres) + { + + // + // we do not need to call NdisTransferData, either because we need only the HeaderBuffer, or because the LookaheadBuffer + // contains what we need + // + + Header = (struct PacketHeader*)(LocalData->Buffer + LocalData->P); + LocalData->Accepted++; + GET_TIME(&Header->header.bh_tstamp,&G_Start_Time); + Header->SN = InterlockedIncrement(&Open->WriterSN) - 1; + + Header->header.bh_caplen = fres; + Header->header.bh_datalen = PacketSize + HeaderBufferSize; + Header->header.bh_hdrlen=sizeof(struct bpf_hdr); + + LocalData->P +=sizeof(struct PacketHeader); + if (LocalData->P == Open->Size) + LocalData->P = 0; + + if ( fres <= HeaderBufferSize || (UINT)( (PUCHAR)LookaheadBuffer - (PUCHAR)HeaderBuffer ) == HeaderBufferSize ) + { + // + //we can consider the buffer contiguous, either because we use only the data + //present in the HeaderBuffer, or because HeaderBuffer and LookaheadBuffer are contiguous + // ;-)))))) + // + if (Open->Size - LocalData->P < fres) + { + //the packet will be fragmented in the buffer (aka, it will skip the buffer boundary) + //two copies!! + ToCopy = Open->Size - LocalData->P; + NdisMoveMappedMemory(LocalData->Buffer + LocalData->P,HeaderBuffer, ToCopy); + NdisMoveMappedMemory(LocalData->Buffer + 0 , (PUCHAR)HeaderBuffer + ToCopy, fres - ToCopy); + LocalData->P = fres-ToCopy; + } + else + { + //the packet does not need to be fragmented in the buffer (aka, it doesn't skip the buffer boundary) + // ;-)))))) only ONE copy + NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, HeaderBuffer, fres); + LocalData->P += fres; + } + } + else + { + //HeaderBuffer and LookAhead buffer are NOT contiguous, + //AND, we need some bytes from the LookaheadBuffer, too + if (Open->Size - LocalData->P < fres) + { + //the packet will be fragmented in the buffer (aka, it will skip the buffer boundary) + if (Open->Size - LocalData->P >= HeaderBufferSize) + { + //HeaderBuffer is NOT fragmented + NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, HeaderBuffer, HeaderBufferSize); + LocalData->P += HeaderBufferSize; + + if (LocalData->P == Open->Size) + { + //the fragmentation of the packet in the buffer is the same fragmentation + //in HeaderBuffer+LookaheadBuffer + LocalData->P=0; + NdisMoveMappedMemory(LocalData->Buffer + 0, LookaheadBuffer, fres - HeaderBufferSize); + LocalData->P += (fres - HeaderBufferSize); + } + else + { + //LookAheadBuffer is fragmented, two copies + ToCopy = Open->Size - LocalData->P; + NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, LookaheadBuffer, ToCopy); + LocalData->P=0; + NdisMoveMappedMemory(LocalData->Buffer + 0, (PUCHAR)LookaheadBuffer+ ToCopy, fres - HeaderBufferSize - ToCopy); + LocalData->P = fres - HeaderBufferSize - ToCopy; + } + } + else + { + //HeaderBuffer is fragmented in the buffer (aka, it will skip the buffer boundary) + //two copies to copy the HeaderBuffer + ToCopy = Open->Size - LocalData->P; + NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, HeaderBuffer, ToCopy); + LocalData->P = 0; + NdisMoveMappedMemory(LocalData->Buffer + 0, (PUCHAR)HeaderBuffer + ToCopy, HeaderBufferSize - ToCopy); + LocalData->P = HeaderBufferSize - ToCopy; + + //only one copy to copy the LookaheadBuffer + NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, LookaheadBuffer, fres- HeaderBufferSize); + LocalData->P += (fres - HeaderBufferSize); + } + } + else + { + //the packet won't be fragmented in the destination buffer (aka, it won't skip the buffer boundary) + //two copies, the former to copy the HeaderBuffer, the latter to copy the LookaheadBuffer + NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, HeaderBuffer, HeaderBufferSize); + LocalData->P += HeaderBufferSize; + NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, LookaheadBuffer, fres - HeaderBufferSize); + LocalData->P += (fres - HeaderBufferSize); + } + } + + increment = fres + sizeof(struct PacketHeader); + if (Open->Size - LocalData->P < sizeof(struct PacketHeader)) //we check that the available, AND contiguous, space in the buffer will fit + { //the NewHeader structure, at least, otherwise we skip the producer + increment += Open->Size-LocalData->P; //at the beginning of the buffer (p = 0), and decrement the free bytes appropriately + LocalData->P = 0; + } + + InterlockedExchangeAdd(&LocalData->Free, (ULONG)(-(LONG)increment)); + if(Open->Size - LocalData->Free >= Open->MinToCopy) + { + if(Open->mode & MODE_DUMP) + NdisSetEvent(&Open->DumpEvent); + else + { + if (Open->ReadEvent != NULL) + { + KeSetEvent(Open->ReadEvent,0,FALSE); + } + } + } + + break; + } + else + { + IF_LOUD(DbgPrint("TransferData!!\n");) + //ndisTransferData required + LocalData->NewP = LocalData->P; + + LocalData->NewP +=sizeof(struct PacketHeader); + if (LocalData->NewP == Open->Size) + LocalData->NewP = 0; + + //first of all, surely the header must be copied + if (Open->Size-LocalData->NewP >= HeaderBufferSize) + { + //1 copy! + NdisMoveMappedMemory(LocalData->Buffer + LocalData->NewP, HeaderBuffer, HeaderBufferSize); + LocalData->NewP += HeaderBufferSize; + if (LocalData->NewP == Open->Size) + LocalData->NewP = 0; + } + else + { + ToCopy = Open->Size - LocalData->NewP; + NdisMoveMappedMemory(LocalData->Buffer + LocalData->NewP, HeaderBuffer, ToCopy); + NdisMoveMappedMemory(LocalData->Buffer + 0, (PUCHAR)HeaderBuffer + ToCopy, HeaderBufferSize - ToCopy); + LocalData->NewP = HeaderBufferSize - ToCopy; + } + + //then we copy the Lookahead buffer + + if (Open->Size-LocalData->NewP >= LookaheadBufferSize) + { + //1 copy! + NdisMoveMappedMemory(LocalData->Buffer + LocalData->NewP, LookaheadBuffer, LookaheadBufferSize); + LocalData->NewP += LookaheadBufferSize; + if (LocalData->NewP == Open->Size) + LocalData->NewP = 0; + } + else + { + ToCopy = Open->Size - LocalData->NewP; + NdisMoveMappedMemory(LocalData->Buffer + LocalData->NewP, LookaheadBuffer, ToCopy); + NdisMoveMappedMemory(LocalData->Buffer + 0, (PUCHAR)LookaheadBuffer + ToCopy, LookaheadBufferSize - ToCopy); + LocalData->NewP = LookaheadBufferSize - ToCopy; + } + + //Now we must prepare the buffer(s) for the NdisTransferData + if ((Open->Size - LocalData->NewP) >= (fres - HeaderBufferSize - LookaheadBufferSize)) + { + //only 1 buffer + pMdl1 = IoAllocateMdl( + LocalData->Buffer + LocalData->NewP, + fres - HeaderBufferSize - LookaheadBufferSize, + FALSE, + FALSE, + NULL); + + if (pMdl1 == NULL) + { + IF_LOUD(DbgPrint("Error allocating Mdl1\n");) + LocalData->Dropped++; + break; + } + + MmBuildMdlForNonPagedPool(pMdl1); + pMdl2=NULL; + LocalData->NewP += fres - HeaderBufferSize - LookaheadBufferSize; + + + } + else + { + //2 buffers + pMdl1 = IoAllocateMdl( + LocalData->Buffer + LocalData->NewP, + Open->Size - LocalData->NewP, + FALSE, + FALSE, + NULL); + + if (pMdl1 == NULL) + { + IF_LOUD(DbgPrint("Error allocating Mdl1\n");) + LocalData->Dropped++; + break; + } + + pMdl2 = IoAllocateMdl( + LocalData->Buffer + 0, + fres - HeaderBufferSize - LookaheadBufferSize - (Open->Size - LocalData->NewP), + FALSE, + FALSE, + NULL); + + if (pMdl2 == NULL) + { + IF_LOUD(DbgPrint("Error allocating Mdl2\n");) + IoFreeMdl(pMdl1); + LocalData->Dropped++; + break; + } + + LocalData->NewP = fres - HeaderBufferSize - LookaheadBufferSize - (Open->Size - LocalData->NewP); + + MmBuildMdlForNonPagedPool(pMdl1); + MmBuildMdlForNonPagedPool(pMdl2); + } + + + NdisAllocatePacket(&Status, &pPacket, Open->PacketPool); + + if (Status != NDIS_STATUS_SUCCESS) + { + IF_LOUD(DbgPrint("NPF: Tap - No free packets\n");) + IoFreeMdl(pMdl1); + if (pMdl2 != NULL) + IoFreeMdl(pMdl2); + LocalData->Dropped++; + break; + } + + if (pMdl2 != NULL) + NdisChainBufferAtFront(pPacket,pMdl2); + + NdisChainBufferAtFront(pPacket,pMdl1); + + RESERVED(pPacket)->Cpu = Cpu; + + LocalData->TransferMdl1 = pMdl1; + LocalData->TransferMdl2 = pMdl2; + + + Header = (struct PacketHeader*)(LocalData->Buffer + LocalData->P); + Header->header.bh_caplen = fres; + Header->header.bh_datalen = PacketSize + HeaderBufferSize; + Header->header.bh_hdrlen=sizeof(struct bpf_hdr); + + NdisTransferData( + &Status, + Open->AdapterHandle, + MacReceiveContext, + LookaheadBufferSize, + fres - HeaderBufferSize - LookaheadBufferSize, + pPacket, + &BytesTransfered); + + if (Status != NDIS_STATUS_PENDING) + { + IF_LOUD(DbgPrint("NdisTransferData, not pending!\n");) + LocalData->TransferMdl1 = NULL; + LocalData->TransferMdl2 = NULL; + + IoFreeMdl(pMdl1); + if ( pMdl2 != NULL ) + IoFreeMdl(pMdl2); + + NdisReinitializePacket(pPacket); + // Put the packet on the free queue + NdisFreePacket(pPacket); + + LocalData->P = LocalData->NewP; + + LocalData->Accepted++; + GET_TIME(&Header->header.bh_tstamp,&G_Start_Time); + Header->SN = InterlockedIncrement(&Open->WriterSN) - 1; + + increment = fres + sizeof(struct PacketHeader); + if (Open->Size - LocalData->P < sizeof(struct PacketHeader)) + { + increment += Open->Size-LocalData->P; + LocalData->P = 0; + } + + InterlockedExchangeAdd(&LocalData->Free, (ULONG)(-(LONG)increment)); + + if(Open->Size - LocalData->Free >= Open->MinToCopy) + { + if(Open->mode & MODE_DUMP) + NdisSetEvent(&Open->DumpEvent); + else + { + if (Open->ReadEvent != NULL) + { + KeSetEvent(Open->ReadEvent,0,FALSE); + } + } + } + + break; + } + else + { + IF_LOUD(DbgPrint("NdisTransferData, pending!\n");) + ShouldReleaseBufferLock = FALSE; + } + } + } + while(FALSE); + + if (ShouldReleaseBufferLock) + { + NdisDprReleaseSpinLock(&LocalData->BufferLock); + } + + return NDIS_STATUS_NOT_ACCEPTED; + +} + +//------------------------------------------------------------------- + +VOID NPF_TransferDataComplete (IN NDIS_HANDLE ProtocolBindingContext,IN PNDIS_PACKET pPacket, + IN NDIS_STATUS Status,IN UINT BytesTransfered) +{ + POPEN_INSTANCE Open; + ULONG Cpu; + CpuPrivateData *LocalData; + struct PacketHeader* Header; + ULONG increment; + + IF_LOUD(DbgPrint("NPF: TransferDataComplete\n");) + + Open = (POPEN_INSTANCE)ProtocolBindingContext; + + Cpu = RESERVED(pPacket)->Cpu; + + LocalData = &Open->CpuData[Cpu]; + + IoFreeMdl(LocalData->TransferMdl1); + if ( LocalData->TransferMdl2 != NULL ) + IoFreeMdl(LocalData->TransferMdl2); + + NdisReinitializePacket(pPacket); + // Put the packet on the free queue + NdisFreePacket(pPacket); + + //the packet has been successfully copied to the kernel buffer, we can prepend it with the PacketHeader, + //and obtain the sequence number and the timestamp + + LocalData->Accepted++; + Header = (struct PacketHeader*)(LocalData->Buffer + LocalData->P); + GET_TIME(&Header->header.bh_tstamp,&G_Start_Time); + Header->SN = InterlockedIncrement(&Open->WriterSN) - 1; + + LocalData->P = LocalData->NewP; + + increment = Header->header.bh_caplen + sizeof(struct PacketHeader); + if (Open->Size - LocalData->P < sizeof(struct PacketHeader)) + { + increment += Open->Size-LocalData->P; + LocalData->P = 0; + } + + InterlockedExchangeAdd(&LocalData->Free, (ULONG)(-(LONG)increment)); + + if(Open->Size - LocalData->Free >= Open->MinToCopy) + { + if(Open->mode & MODE_DUMP) + NdisSetEvent(&Open->DumpEvent); + else + { + if (Open->ReadEvent != NULL) + { + KeSetEvent(Open->ReadEvent,0,FALSE); + } + } + } + + LocalData->TransferMdl1 = NULL; + LocalData->TransferMdl2 = NULL; + +// +// NOTE: this is really bad practice. +// a better approach would be performing the entire copy here. +// +#pragma prefast(suppress:8107, "There's no Spinlock leak here, as it's acquired by the tap.") + NdisDprReleaseSpinLock(&LocalData->BufferLock); + +// Unfreeze the consumer + if(Open->Size - LocalData->Free > Open->MinToCopy) + { + if(Open->mode & MODE_DUMP) + NdisSetEvent(&Open->DumpEvent); + else + { + if (Open->ReadEvent != NULL) + { + KeSetEvent(Open->ReadEvent,0,FALSE); + } + } + } + return; +} + +//------------------------------------------------------------------- + +VOID NPF_ReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext) +{ + IF_VERY_LOUD(DbgPrint("NPF: NPF_ReceiveComplete\n");) + return; +} diff --git a/winpcap/packetNtx/driver/Sources b/winpcap/packetNtx/driver/Sources new file mode 100644 index 0000000..6616817 --- /dev/null +++ b/winpcap/packetNtx/driver/Sources @@ -0,0 +1,20 @@ +TARGETNAME=npf + +TARGETPATH=$(TARGETPATH) + +TARGETTYPE=DRIVER + +TARGETLIBS=$(DDK_LIB_PATH)\ndis.lib + +C_DEFINES=$(C_DEFINES) -DWIN_NT_DRIVER -DWIN32_EXT $(NPF_C_DEFINES) + +INCLUDES=..\..\common + +SOURCES=packet.c \ + openclos.c \ + read.c \ + write.c \ + dump.c \ + win_bpf_filter.c \ + NPF.rc \ + $(NPF_TME_FILES) $(NPF_JIT_FILES) diff --git a/winpcap/packetNtx/driver/WinPcap NTx Driver_2003.vcproj b/winpcap/packetNtx/driver/WinPcap NTx Driver_2003.vcproj new file mode 100644 index 0000000..ee7b383 --- /dev/null +++ b/winpcap/packetNtx/driver/WinPcap NTx Driver_2003.vcproj @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/winpcap/packetNtx/driver/Write.c b/winpcap/packetNtx/driver/Write.c new file mode 100644 index 0000000..a3303bc --- /dev/null +++ b/winpcap/packetNtx/driver/Write.c @@ -0,0 +1,597 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2007 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include "debug.h" +#include "packet.h" + +extern UINT g_SendPacketFlags; + +//------------------------------------------------------------------- + +NTSTATUS +NPF_Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ) + +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PNDIS_PACKET pPacket; + NDIS_STATUS Status; + ULONG NumSends; + ULONG numSentPackets; + + TRACE_ENTER(); + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + Open=IrpSp->FileObject->FsContext; + + NumSends = Open->Nwrites; + + // + // validate the send parameters set by the IOCTL + // + if (NumSends == 0) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + TRACE_EXIT(); + return STATUS_SUCCESS; + } + + // + // Validate input parameters: + // 1. The packet size should be greater than 0, + // 2. less-equal than max frame size for the link layer and + // 3. the maximum frame size of the link layer should not be zero. + // + if(IrpSp->Parameters.Write.Length == 0 || // Check that the buffer provided by the user is not empty + Open->MaxFrameSize == 0 || // Check that the MaxFrameSize is correctly initialized + Irp->MdlAddress == NULL || + IrpSp->Parameters.Write.Length > Open->MaxFrameSize) // Check that the fame size is smaller that the MTU + { + TRACE_MESSAGE(PACKET_DEBUG_LOUD,"Frame size out of range, or maxFrameSize = 0. Send aborted"); + + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + TRACE_EXIT(); + return STATUS_UNSUCCESSFUL; + } + + // + // Increment the ref counter of the binding handle, if possible + // + if(NPF_StartUsingBinding(Open) == FALSE) + { + TRACE_MESSAGE(PACKET_DEBUG_LOUD,"Adapter is probably unbinding, cannot send packets"); + + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + TRACE_EXIT(); + return STATUS_INVALID_DEVICE_REQUEST; + } + + NdisAcquireSpinLock(&Open->WriteLock); + if(Open->WriteInProgress) + { + // Another write operation is currently in progress + NdisReleaseSpinLock(&Open->WriteLock); + + NPF_StopUsingBinding(Open); + + TRACE_MESSAGE(PACKET_DEBUG_LOUD,"Another Send operation is in progress, aborting."); + + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + TRACE_EXIT(); + + return STATUS_UNSUCCESSFUL; + } + else + { + Open->WriteInProgress = TRUE; + NdisResetEvent(&Open->NdisWriteCompleteEvent); + } + + NdisReleaseSpinLock(&Open->WriteLock); + + TRACE_MESSAGE2(PACKET_DEBUG_LOUD,"Max frame size = %u, packet size = %u", Open->MaxFrameSize, IrpSp->Parameters.Write.Length); + + // + // reset the number of packets pending the SendComplete + // + Open->TransmitPendingPackets = 0; + + NdisResetEvent(&Open->WriteEvent); + + numSentPackets = 0; + + while( numSentPackets < NumSends ) + { + NdisAllocatePacket( + &Status, + &pPacket, + Open->PacketPool + ); + + if (Status == NDIS_STATUS_SUCCESS) + { + // + // packet is available, prepare it and send it with NdisSend. + // + + // + // If asked, set the flags for this packet. + // Currently, the only situation in which we set the flags is to disable the reception of loopback + // packets, i.e. of the packets sent by us. + // + if(Open->SkipSentPackets) + { + NdisSetPacketFlags( + pPacket, + g_SendPacketFlags); + } + + + // The packet hasn't a buffer that needs not to be freed after every single write + RESERVED(pPacket)->FreeBufAfterWrite = FALSE; + +// // Save the IRP associated with the packet +// RESERVED(pPacket)->Irp=Irp; + + // Attach the writes buffer to the packet + NdisChainBufferAtFront(pPacket,Irp->MdlAddress); + + InterlockedIncrement(&Open->TransmitPendingPackets); + + NdisResetEvent(&Open->NdisWriteCompleteEvent); + + // + // Call the MAC + // + NdisSend( + &Status, + Open->AdapterHandle, + pPacket); + + if (Status != NDIS_STATUS_PENDING) + { + // The send didn't pend so call the completion handler now + NPF_SendComplete( + Open, + pPacket, + Status + ); + } + + numSentPackets ++; + } + else + { + // + // no packets are available in the Transmit pool, wait some time. The + // event gets signalled when at least half of the TX packet pool packets + // are available + // + NdisWaitEvent(&Open->WriteEvent,1); + } + } + + // + // when we reach this point, all the packets have been enqueued to NdisSend, + // we just need to wait for all the packets to be completed by the SendComplete + // (if any of the NdisSend requests returned STATUS_PENDING) + // + NdisWaitEvent(&Open->NdisWriteCompleteEvent, 0); + + // + // all the packets have been transmitted, release the use of the adapter binding + // + NPF_StopUsingBinding(Open); + + // + // no more writes are in progress + // + NdisAcquireSpinLock(&Open->WriteLock); + Open->WriteInProgress = FALSE; + NdisReleaseSpinLock(&Open->WriteLock); + + // + // Complete the Irp and return success + // + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = IrpSp->Parameters.Write.Length; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + TRACE_EXIT(); + + return STATUS_SUCCESS; +} + +//------------------------------------------------------------------- + +INT +NPF_BufferedWrite( + IN PIRP Irp, + IN PCHAR UserBuff, + IN ULONG UserBuffSize, + BOOLEAN Sync) +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PNDIS_PACKET pPacket; + UINT i; + NDIS_STATUS Status; + LARGE_INTEGER StartTicks, CurTicks, TargetTicks; + LARGE_INTEGER TimeFreq; + struct timeval BufStartTime; + struct sf_pkthdr *winpcap_hdr; + PMDL TmpMdl; + PCHAR CurPos; + PCHAR EndOfUserBuff = UserBuff + UserBuffSize; + + IF_LOUD(DbgPrint("NPF: BufferedWrite, UserBuff=%p, Size=%u\n", UserBuff, UserBuffSize);) + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + Open=IrpSp->FileObject->FsContext; + + if( NPF_StartUsingBinding(Open) == FALSE) + { + // The Network adapter was removed. + return 0; + } + + // Sanity check on the user buffer + if(UserBuff == NULL) + { + // + // release ownership of the NdisAdapter binding + // + NPF_StopUsingBinding(Open); + + return 0; + } + + // Check that the MaxFrameSize is correctly initialized + if(Open->MaxFrameSize == 0) + { + IF_LOUD(DbgPrint("BufferedWrite: Open->MaxFrameSize not initialized, probably because of a problem in the OID query\n");) + + // + // release ownership of the NdisAdapter binding + // + NPF_StopUsingBinding(Open); + return 0; + } + + // Reset the event used to synchronize packet allocation + NdisResetEvent(&Open->WriteEvent); + + // Reset the pending packets counter + Open->Multiple_Write_Counter = 0; + + // Start from the first packet + winpcap_hdr = (struct sf_pkthdr*)UserBuff; + + // Retrieve the time references + StartTicks = KeQueryPerformanceCounter(&TimeFreq); + BufStartTime.tv_sec = winpcap_hdr->ts.tv_sec; + BufStartTime.tv_usec = winpcap_hdr->ts.tv_usec; + + // Chech the consistency of the user buffer + if( (PCHAR)winpcap_hdr + winpcap_hdr->caplen + sizeof(struct sf_pkthdr) > EndOfUserBuff ) + { + IF_LOUD(DbgPrint("Buffered Write: bogus packet buffer\n");) + + // + // release ownership of the NdisAdapter binding + // + NPF_StopUsingBinding(Open); + return -1; + } + + // Save the current time stamp counter + CurTicks = KeQueryPerformanceCounter(NULL); + + // + // Main loop: send the buffer to the wire + // + while(TRUE) + { + + if(winpcap_hdr->caplen ==0 || winpcap_hdr->caplen > Open->MaxFrameSize) + { + // Malformed header + IF_LOUD(DbgPrint("NPF_BufferedWrite: malformed or bogus user buffer, aborting write.\n");) + + // + // release ownership of the NdisAdapter binding + // + NPF_StopUsingBinding(Open); + return -1; + } + + // Allocate an MDL to map the packet data + TmpMdl = IoAllocateMdl((PCHAR)winpcap_hdr + sizeof(struct sf_pkthdr), + winpcap_hdr->caplen, + FALSE, + FALSE, + NULL); + + if (TmpMdl == NULL) + { + // Unable to map the memory: packet lost + IF_LOUD(DbgPrint("NPF_BufferedWrite: unable to allocate the MDL.\n");) + + // + // release ownership of the NdisAdapter binding + // + NPF_StopUsingBinding(Open); + return -1; + } + + MmBuildMdlForNonPagedPool(TmpMdl); // XXX can this line be removed? + + // Allocate a packet from our free list + NdisAllocatePacket( &Status, &pPacket, Open->PacketPool); + + if (Status != NDIS_STATUS_SUCCESS) + { + // No more free packets + IF_LOUD(DbgPrint("NPF_BufferedWrite: no more free packets, returning.\n");) + + NdisResetEvent(&Open->WriteEvent); + + NdisWaitEvent(&Open->WriteEvent, 1000); + + // Try again to allocate a packet + NdisAllocatePacket( &Status, &pPacket, Open->PacketPool); + + if (Status != NDIS_STATUS_SUCCESS) + { + // Second failure, report an error + IoFreeMdl(TmpMdl); + + // + // release ownership of the NdisAdapter binding + // + NPF_StopUsingBinding(Open); + return -1; + } + + } + + // If asked, set the flags for this packet. + // Currently, the only situation in which we set the flags is to disable the reception of loopback + // packets, i.e. of the packets sent by us. + if(Open->SkipSentPackets) + { + NdisSetPacketFlags( + pPacket, + g_SendPacketFlags); + } + + // The packet has a buffer that needs to be freed after every single write + RESERVED(pPacket)->FreeBufAfterWrite = TRUE; + + TmpMdl->Next = NULL; + + // Attach the MDL to the packet + NdisChainBufferAtFront(pPacket, TmpMdl); + + // Increment the number of pending sends + InterlockedIncrement(&Open->Multiple_Write_Counter); + + // Call the MAC + NdisSend( &Status, Open->AdapterHandle, pPacket); + + if (Status != NDIS_STATUS_PENDING) { + // The send didn't pend so call the completion handler now + NPF_SendComplete( + Open, + pPacket, + Status + ); + } + + // Step to the next packet in the buffer + (PCHAR)winpcap_hdr += winpcap_hdr->caplen + sizeof(struct sf_pkthdr); + + // Check if the end of the user buffer has been reached + if( (PCHAR)winpcap_hdr >= EndOfUserBuff ) + { + IF_LOUD(DbgPrint("NPF_BufferedWrite: End of buffer.\n");) + + // Wait the completion of pending sends + NPF_WaitEndOfBufferedWrite(Open); + + // + // release ownership of the NdisAdapter binding + // + NPF_StopUsingBinding(Open); + + return (INT)((PCHAR)winpcap_hdr - UserBuff); + } + + if( Sync ){ + + // Release the application if it has been blocked for approximately more than 1 seconds + if( winpcap_hdr->ts.tv_sec - BufStartTime.tv_sec > 1 ) + { + IF_LOUD(DbgPrint("NPF_BufferedWrite: timestamp elapsed, returning.\n");) + + // Wait the completion of pending sends + NPF_WaitEndOfBufferedWrite(Open); + + // + // release ownership of the NdisAdapter binding + // + NPF_StopUsingBinding(Open); + return (INT)((PCHAR)winpcap_hdr - UserBuff); + } + + // Calculate the time interval to wait before sending the next packet + TargetTicks.QuadPart = StartTicks.QuadPart + + (LONGLONG)((winpcap_hdr->ts.tv_sec - BufStartTime.tv_sec) * 1000000 + + winpcap_hdr->ts.tv_usec - BufStartTime.tv_usec) * + (TimeFreq.QuadPart) / 1000000; + + // Wait until the time interval has elapsed + while( CurTicks.QuadPart <= TargetTicks.QuadPart ) + CurTicks = KeQueryPerformanceCounter(NULL); + } + + } + + // + // release ownership of the NdisAdapter binding + // + NPF_StopUsingBinding(Open); + + return (INT)((PCHAR)winpcap_hdr - UserBuff); +} + +//------------------------------------------------------------------- + +VOID NPF_WaitEndOfBufferedWrite(POPEN_INSTANCE Open) +{ + UINT i; + + NdisResetEvent(&Open->WriteEvent); + + for(i=0; Open->Multiple_Write_Counter > 0 && i < TRANSMIT_PACKETS; i++) + { + NdisWaitEvent(&Open->WriteEvent, 100); + NdisResetEvent(&Open->WriteEvent); + } + + return; +} + +//------------------------------------------------------------------- + +VOID +NPF_SendComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET pPacket, + IN NDIS_STATUS Status + ) + +{ + POPEN_INSTANCE Open; + PMDL TmpMdl; + + TRACE_ENTER(); + + Open= (POPEN_INSTANCE)ProtocolBindingContext; + + if( RESERVED(pPacket)->FreeBufAfterWrite ) + { + // + // Packet sent by NPF_BufferedWrite() + // + + + // Free the MDL associated with the packet + NdisUnchainBufferAtFront(pPacket, &TmpMdl); + + IoFreeMdl(TmpMdl); + + // recyle the packet + // NdisReinitializePacket(pPacket); + + NdisFreePacket(pPacket); + + // Increment the number of pending sends + InterlockedDecrement(&Open->Multiple_Write_Counter); + + NdisSetEvent(&Open->WriteEvent); + + TRACE_EXIT(); + return; + } + else + { + // + // Packet sent by NPF_Write() + // + + ULONG stillPendingPackets = InterlockedDecrement(&Open->TransmitPendingPackets); + + // + // Put the packet back on the free list + // + NdisFreePacket(pPacket); + + // + // if the number of packets submitted to NdisSend and not acknoledged is less than half the + // packets in the TX pool, wake up any transmitter waiting for available packets in the TX + // packet pool + // + if (stillPendingPackets < TRANSMIT_PACKETS/2) + { + NdisSetEvent(&Open->WriteEvent); + } + else + { + // + // otherwise, reset the event, so that we are sure that the NPF_Write will eventually block to + // waitg for availability of packets in the TX packet pool + // + NdisResetEvent(&Open->WriteEvent); + } + + if(stillPendingPackets == 0) + { + NdisSetEvent(&Open->NdisWriteCompleteEvent); + } + + TRACE_EXIT(); + return; + } + +} diff --git a/winpcap/packetNtx/driver/bucket_lookup.c b/winpcap/packetNtx/driver/bucket_lookup.c new file mode 100644 index 0000000..1d64faf --- /dev/null +++ b/winpcap/packetNtx/driver/bucket_lookup.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2001 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifdef WIN32 +#include "tme.h" +#include "bucket_lookup.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#include +#else +#include +#include +#endif + +#endif + +#ifndef UNUSED +#define UNUSED(_x) (_x) +#endif + + +/* the key is represented by the initial and final value */ +/* of the bucket. At the moment bucket_lookup is able to */ +/* manage values of 16, 32 bits. */ +uint32 bucket_lookup(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref) +{ + uint32 value; + uint32 i,j; + int found=-1; + uint32 blocks; + uint32 block_size; + uint8 *temp; + + UNUSED(mem_ex); + + if ((data->key_len!=1)&& /*16 bit value*/ + (data->key_len!=2)) /*32 bit value*/ + return TME_ERROR; + + /*32 bit values*/ + blocks=data->filled_blocks-1; + block_size=data->block_size; + i=blocks/2; /*relative shift*/ + j=i; + temp=data->shared_memory_base_address+block_size; + + if (data->key_len==2) + { + value=SW_ULONG_AT(key,0); + + if((valueSW_ULONG_AT(temp+block_size*(blocks-1),4))) + { + uint32 *key32=(uint32*) key; + key32[0]=key32[1]=0; + + GET_TIME((struct timeval *)(data->shared_memory_base_address+8),time_ref); + + data->last_found=NULL; + return TME_FALSE; + } + + while(found==-1) /* search routine */ + { + i=(i==1)? 1:i>>1; + if (SW_ULONG_AT(temp+block_size*j,0)>value) + if (SW_ULONG_AT(temp+block_size*(j-1),4)value) + found=-2; + else + j+=i; + else found=j; + } + if (found<0) + { + uint32 *key32=(uint32*) key; + key32[0]=key32[1]=0; + + GET_TIME((struct timeval *)(data->shared_memory_base_address+8),time_ref); + + data->last_found=NULL; + return TME_FALSE; + } + + data->last_found=data->lut_base_address+found*sizeof(RECORD); + + COPY_MEMORY(key,temp+block_size*found,8); + + GET_TIME((struct timeval *)(temp+block_size*found+8),time_ref); + + return TME_TRUE; + } + else + { + value=SW_USHORT_AT(key,0); + + if((valueSW_USHORT_AT(temp+block_size*(blocks-1),2))) + { + uint16 *key16=(uint16*) key; + key16[0]=key16[1]=0; + + GET_TIME((struct timeval *)(data->shared_memory_base_address+4),time_ref); + + data->last_found=NULL; + return TME_FALSE; + } + + while(found==-1) /* search routine */ + { + i=(i==1)? 1:i>>1; + if (SW_USHORT_AT(temp+block_size*j,0)>value) + if (SW_USHORT_AT(temp+block_size*(j-1),2)value) + found=-2; + else + j+=i; + else found=j; + } + + if (found<0) + { + uint16 *key16=(uint16*) key; + key16[0]=key16[1]=0; + + GET_TIME((struct timeval *)(data->shared_memory_base_address+4),time_ref); + + data->last_found=NULL; + return TME_FALSE; + } + + data->last_found=data->lut_base_address+found*sizeof(RECORD); + + GET_TIME((struct timeval *)(temp+block_size*found+4),time_ref); + + COPY_MEMORY(key,temp+block_size*found,4); + + return TME_TRUE; + } + +} + +uint32 bucket_lookup_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref) +{ + RECORD *records=(RECORD*)data->lut_base_address; + + if ((data->key_len!=1)&& /*16 bit value*/ + (data->key_len!=2)) /*32 bit value*/ + return TME_ERROR; + + if(data->key_len==2) + { + uint32 start,stop; + uint8 *tmp; + + start=SW_ULONG_AT(key,0); + stop=SW_ULONG_AT(key,4); + + if (start>stop) + return TME_ERROR; + if (data->filled_entries>0) + { + tmp=mem_ex->buffer+SW_ULONG_AT(&records[data->filled_entries-1].block,0); + /*check if it is coherent with the previous block*/ + if (SW_ULONG_AT(tmp,4)>=start) + return TME_ERROR; + } + + if (data->filled_blocks==data->shared_memory_blocks) + return TME_ERROR; + + if (data->filled_entries==data->lut_entries) + return TME_ERROR; + + tmp=data->shared_memory_base_address+data->block_size*data->filled_blocks; + + COPY_MEMORY(tmp,key,8); + + SW_ULONG_ASSIGN(&records[data->filled_entries].block,tmp-mem_ex->buffer); + SW_ULONG_ASSIGN(&records[data->filled_entries].exec_fcn,data->default_exec); + + GET_TIME((struct timeval *)(tmp+8),time_ref); + + data->filled_blocks++; + data->filled_entries++; + + return TME_TRUE; + } + else + { + uint16 start,stop; + uint8 *tmp; + + start=SW_USHORT_AT(key,0); + stop=SW_USHORT_AT(key,2); + + if (start>stop) + return TME_ERROR; + if (data->filled_entries>0) + { + tmp=mem_ex->buffer+SW_ULONG_AT(&records[data->filled_entries-1].block,0); + /*check if it is coherent with the previous block*/ + if (SW_USHORT_AT(tmp,2)>=start) + return TME_ERROR; + } + + if (data->filled_blocks==data->shared_memory_blocks) + return TME_ERROR; + + if (data->filled_entries==data->lut_entries) + return TME_ERROR; + + tmp=mem_ex->buffer+SW_ULONG_AT(&records[data->filled_entries].block,0); + + COPY_MEMORY(tmp,key,4); + + SW_ULONG_ASSIGN(&records[data->filled_entries].block,tmp-mem_ex->buffer); + SW_ULONG_ASSIGN(&records[data->filled_entries].exec_fcn,data->default_exec); + + GET_TIME((struct timeval *)(tmp+4),time_ref); + + data->filled_blocks++; + data->filled_entries++; + + return TME_TRUE; + } +} \ No newline at end of file diff --git a/winpcap/packetNtx/driver/bucket_lookup.h b/winpcap/packetNtx/driver/bucket_lookup.h new file mode 100644 index 0000000..b178436 --- /dev/null +++ b/winpcap/packetNtx/driver/bucket_lookup.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2001 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __bucket_lookup +#define __bucket_lookup +#ifdef WIN32 +#include "tme.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#else +#include +#endif + +#endif + +#define BUCKET_LOOKUP_INSERT 0x00000011 +uint32 bucket_lookup_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); +#define BUCKET_LOOKUP 0x00000010 +uint32 bucket_lookup(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); + +#endif \ No newline at end of file diff --git a/winpcap/packetNtx/driver/count_packets.c b/winpcap/packetNtx/driver/count_packets.c new file mode 100644 index 0000000..352d721 --- /dev/null +++ b/winpcap/packetNtx/driver/count_packets.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2001 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifdef WIN32 +#include "tme.h" +#include "count_packets.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#include +#else +#include +#include +#endif + +#endif + +#ifndef UNUSED +#define UNUSED(_x) (_x) +#endif + + +uint32 count_packets(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data) +{ + c_p_data *counters; + + UNUSED(mem_data); + UNUSED(mem_ex); + + counters = (c_p_data*)(block+data->key_len*4); + + counters->bytes+=pkt_size; + counters->packets++; + + return TME_SUCCESS; + +} diff --git a/winpcap/packetNtx/driver/count_packets.h b/winpcap/packetNtx/driver/count_packets.h new file mode 100644 index 0000000..9853bda --- /dev/null +++ b/winpcap/packetNtx/driver/count_packets.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2001 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __count_packets +#define __count_packets + +#ifdef WIN32 +#include "tme.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#else +#include +#endif + +#endif + +typedef struct __c_p_data +{ + struct timeval timestamp; + uint64 packets; + uint64 bytes; +} + c_p_data; + +#define COUNT_PACKETS 0x00000000 +uint32 count_packets(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data); + +#endif + diff --git a/winpcap/packetNtx/driver/dump.c b/winpcap/packetNtx/driver/dump.c new file mode 100644 index 0000000..8ec72f7 --- /dev/null +++ b/winpcap/packetNtx/driver/dump.c @@ -0,0 +1,588 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2007 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include "debug.h" +#include "packet.h" +#include "win_bpf.h" + +//------------------------------------------------------------------- + +NTSTATUS +NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN Append) +{ + NTSTATUS ntStatus; + IO_STATUS_BLOCK IoStatus; + OBJECT_ATTRIBUTES ObjectAttributes; + PWCHAR PathPrefix; + USHORT PathLen; + UNICODE_STRING FullFileName; + ULONG FullFileNameLength; + PDEVICE_OBJECT fsdDevice; + + FILE_STANDARD_INFORMATION StandardInfo; + + IF_LOUD(DbgPrint("NPF: OpenDumpFile.\n");) + + if(fileName->Buffer[0] == L'\\' && + fileName->Buffer[1] == L'?' && + fileName->Buffer[2] == L'?' && + fileName->Buffer[3] == L'\\' + ){ + PathLen = 0; + } + else{ + PathPrefix = L"\\??\\"; + PathLen = 8; + } + + // Insert the correct path prefix. + FullFileNameLength = PathLen + fileName->MaximumLength; + + FullFileName.Buffer = ExAllocatePoolWithTag(NonPagedPool, + FullFileNameLength, + '0DWA'); + + if (FullFileName.Buffer == NULL) { + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + return ntStatus; + } + + FullFileName.Length = PathLen; + FullFileName.MaximumLength = (USHORT)FullFileNameLength; + + if(PathLen) + RtlMoveMemory (FullFileName.Buffer, PathPrefix, PathLen); + + RtlAppendUnicodeStringToString (&FullFileName, fileName); + + IF_LOUD(DbgPrint( "Packet: Attempting to open %wZ\n", &FullFileName);) + + InitializeObjectAttributes ( &ObjectAttributes, + &FullFileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL ); + + // Create the dump file + ntStatus = ZwCreateFile( &Open->DumpFileHandle, + SYNCHRONIZE | FILE_WRITE_DATA, + &ObjectAttributes, + &IoStatus, + NULL, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ, + (Append)?FILE_OPEN_IF:FILE_SUPERSEDE, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0 ); + + if ( !NT_SUCCESS( ntStatus ) ) + { + IF_LOUD(DbgPrint("NPF: Error opening file %x\n", ntStatus);) + + ExFreePool(FullFileName.Buffer); + Open->DumpFileHandle=NULL; + ntStatus = STATUS_NO_SUCH_FILE; + return ntStatus; + } + + ExFreePool(FullFileName.Buffer); + + ntStatus = ObReferenceObjectByHandle(Open->DumpFileHandle, + FILE_WRITE_ACCESS, + *IoFileObjectType, + KernelMode, + &Open->DumpFileObject, + 0); + + if ( !NT_SUCCESS( ntStatus ) ) + { + IF_LOUD(DbgPrint("NPF: Error creating file, status=%x\n", ntStatus);) + + ZwClose( Open->DumpFileHandle ); + Open->DumpFileHandle=NULL; + + ntStatus = STATUS_NO_SUCH_FILE; + return ntStatus; + } + + fsdDevice = IoGetRelatedDeviceObject(Open->DumpFileObject); + + IF_LOUD(DbgPrint("NPF: Dump: write file created succesfully, status=%d \n",ntStatus);) + + return ntStatus; +} + +//------------------------------------------------------------------- + +NTSTATUS +NPF_StartDump(POPEN_INSTANCE Open) +{ + NTSTATUS ntStatus; + struct packet_file_header hdr; + IO_STATUS_BLOCK IoStatus; + NDIS_REQUEST pRequest; + ULONG MediaType; + OBJECT_ATTRIBUTES ObjectAttributes; + + IF_LOUD(DbgPrint("NPF: StartDump.\n");) + + // Init the file header + hdr.magic = TCPDUMP_MAGIC; + hdr.version_major = PCAP_VERSION_MAJOR; + hdr.version_minor = PCAP_VERSION_MINOR; + hdr.thiszone = 0; /*Currently not set*/ + hdr.snaplen = 1514; + hdr.sigfigs = 0; + + // Detect the medium type + switch (Open->Medium){ + + case NdisMediumWan: + hdr.linktype = DLT_EN10MB; + break; + + case NdisMedium802_3: + hdr.linktype = DLT_EN10MB; + break; + + case NdisMediumFddi: + hdr.linktype = DLT_FDDI; + break; + + case NdisMedium802_5: + hdr.linktype = DLT_IEEE802; + break; + + case NdisMediumArcnet878_2: + hdr.linktype = DLT_ARCNET; + break; + + case NdisMediumAtm: + hdr.linktype = DLT_ATM_RFC1483; + break; + + default: + hdr.linktype = DLT_EN10MB; + } + + // Write the header. + // We can use ZwWriteFile because we are in the context of the application + ntStatus = ZwWriteFile(Open->DumpFileHandle, + NULL, + NULL, + NULL, + &IoStatus, + &hdr, + sizeof(hdr), + NULL, + NULL ); + + + if ( !NT_SUCCESS( ntStatus ) ) + { + IF_LOUD(DbgPrint("NPF: Error dumping file %x\n", ntStatus);) + + ZwClose( Open->DumpFileHandle ); + Open->DumpFileHandle=NULL; + + ntStatus = STATUS_NO_SUCH_FILE; + return ntStatus; + } + + Open->DumpOffset.QuadPart=24; + + ntStatus = PsCreateSystemThread(&Open->DumpThreadHandle, + THREAD_ALL_ACCESS, + (ACCESS_MASK)0L, + 0, + 0, + NPF_DumpThread, + Open); + + if ( !NT_SUCCESS( ntStatus ) ) + { + IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);) + + ZwClose( Open->DumpFileHandle ); + Open->DumpFileHandle=NULL; + + return ntStatus; + } + + ntStatus = ObReferenceObjectByHandle(Open->DumpThreadHandle, + THREAD_ALL_ACCESS, + NULL, + KernelMode, + &Open->DumpThreadObject, + 0); + + if ( !NT_SUCCESS( ntStatus ) ) + { + IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);) + + ObDereferenceObject(Open->DumpFileObject); + ZwClose( Open->DumpFileHandle ); + Open->DumpFileHandle=NULL; + + return ntStatus; + } + + + return ntStatus; + +} + +//------------------------------------------------------------------- +// Dump Thread +//------------------------------------------------------------------- + +VOID NPF_DumpThread(POPEN_INSTANCE Open) +{ + ULONG FrozenNic; + + IF_LOUD(DbgPrint("NPF: In the work routine. Parameter = 0x%p\n",Open);) + + while(TRUE){ + + // Wait until some packets arrive or the timeout expires + NdisWaitEvent(&Open->DumpEvent, 5000); + + IF_LOUD(DbgPrint("NPF: Worker Thread - event signalled\n");) + + if(Open->DumpLimitReached || + Open->Size==0){ // BufSize=0 means that this instance was closed, or that the buffer is too + // small for any capture. In both cases it is better to end the dump + + IF_LOUD(DbgPrint("NPF: Worker Thread - Exiting happily\n");) + IF_LOUD(DbgPrint("Thread: Dumpoffset=%I64d\n",Open->DumpOffset.QuadPart);) + + PsTerminateSystemThread(STATUS_SUCCESS); + return; + } + + NdisResetEvent(&Open->DumpEvent); + + // Write the content of the buffer to the file + if(NPF_SaveCurrentBuffer(Open) != STATUS_SUCCESS){ + PsTerminateSystemThread(STATUS_SUCCESS); + return; + } + + } + +} + +//------------------------------------------------------------------- + +NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open) +{ + UINT Thead; + UINT Ttail; + UINT TLastByte; + PUCHAR CurrBuff; + NTSTATUS ntStatus; + IO_STATUS_BLOCK IoStatus; + PMDL lMdl; + UINT SizeToDump; + +#if 0 + + Thead=Open->Bhead; + Ttail=Open->Btail; + TLastByte=Open->BLastByte; + + IF_LOUD(DbgPrint("NPF: NPF_SaveCurrentBuffer.\n");) + + // Get the address of the buffer + CurrBuff=Open->Buffer; + // + // Fill the application buffer + // + if( Ttail < Thead ) + { + if(Open->MaxDumpBytes && + (UINT)Open->DumpOffset.QuadPart /*+ GetBuffOccupation(Open)*/ > Open->MaxDumpBytes) + { + // Size limit reached + UINT PktLen; + + SizeToDump = 0; + + // Scan the buffer to detect the exact amount of data to save + while(TRUE){ + PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr); + + if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes) + break; + + SizeToDump += PktLen; + } + + } + else + SizeToDump = TLastByte-Thead; + + lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL); + if (lMdl == NULL) + { + // No memory: stop dump + IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");) + return STATUS_UNSUCCESSFUL; + } + + MmBuildMdlForNonPagedPool(lMdl); + + // Write to disk + NPF_WriteDumpFile(Open->DumpFileObject, + &Open->DumpOffset, + SizeToDump, + lMdl, + &IoStatus); + + IoFreeMdl(lMdl); + + if(!NT_SUCCESS(IoStatus.Status)){ + // Error + return STATUS_UNSUCCESSFUL; + } + + if(SizeToDump != TLastByte-Thead){ + // Size limit reached. + Open->DumpLimitReached = TRUE; + + // Awake the application + KeSetEvent(Open->ReadEvent,0,FALSE); + + return STATUS_UNSUCCESSFUL; + } + + // Update the packet buffer + Open->DumpOffset.QuadPart+=(TLastByte-Thead); + Open->BLastByte=Ttail; + Open->Bhead=0; + } + + if( Ttail > Thead ){ + + if(Open->MaxDumpBytes && + (UINT)Open->DumpOffset.QuadPart /* +GetBuffOccupation(Open)*/ > Open->MaxDumpBytes) + { + // Size limit reached + UINT PktLen; + + SizeToDump = 0; + + // Scan the buffer to detect the exact amount of data to save + while(Thead + SizeToDump < Ttail){ + + PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr); + + if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes) + break; + + SizeToDump += PktLen; + } + + } + else + SizeToDump = Ttail-Thead; + + lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL); + if (lMdl == NULL) + { + // No memory: stop dump + IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");) + return STATUS_UNSUCCESSFUL; + } + + MmBuildMdlForNonPagedPool(lMdl); + + // Write to disk + NPF_WriteDumpFile(Open->DumpFileObject, + &Open->DumpOffset, + SizeToDump, + lMdl, + &IoStatus); + + IoFreeMdl(lMdl); + + if(!NT_SUCCESS(IoStatus.Status)){ + // Error + return STATUS_UNSUCCESSFUL; + } + + if(SizeToDump != Ttail-Thead){ + // Size limit reached. + Open->DumpLimitReached = TRUE; + + // Awake the application + KeSetEvent(Open->ReadEvent,0,FALSE); + + return STATUS_UNSUCCESSFUL; + } + + // Update the packet buffer + Open->DumpOffset.QuadPart+=(Ttail-Thead); + Open->Bhead=Ttail; + + } +#endif + return STATUS_SUCCESS; +} + +//------------------------------------------------------------------- + +NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open){ + NTSTATUS ntStatus; + IO_STATUS_BLOCK IoStatus; + PMDL WriteMdl; + PUCHAR VMBuff; + UINT VMBufLen; + +#if 0 + IF_LOUD(DbgPrint("NPF: NPF_CloseDumpFile.\n");) + IF_LOUD(DbgPrint("Dumpoffset=%d\n",Open->DumpOffset.QuadPart);) + +DbgPrint("1\n"); + // Consistency check + if(Open->DumpFileHandle == NULL) + return STATUS_UNSUCCESSFUL; + +DbgPrint("2\n"); + ZwClose( Open->DumpFileHandle ); + + ObDereferenceObject(Open->DumpFileObject); +/* + if(Open->DumpLimitReached == TRUE) + // Limit already reached: don't save the rest of the buffer. + return STATUS_SUCCESS; +*/ +DbgPrint("3\n"); + + NPF_OpenDumpFile(Open,&Open->DumpFileName, TRUE); + + // Flush the buffer to file + NPF_SaveCurrentBuffer(Open); + + // Close The file + ObDereferenceObject(Open->DumpFileObject); + ZwClose( Open->DumpFileHandle ); + + Open->DumpFileHandle = NULL; + + ObDereferenceObject(Open->DumpFileObject); +#endif + return STATUS_SUCCESS; +} + +//------------------------------------------------------------------- + +static NTSTATUS PacketDumpCompletion(PDEVICE_OBJECT DeviceObject, + PIRP Irp, + PVOID Context) +{ + + // Copy the status information back into the "user" IOSB + *Irp->UserIosb = Irp->IoStatus; + + // Wake up the mainline code + KeSetEvent(Irp->UserEvent, 0, FALSE); + + return STATUS_MORE_PROCESSING_REQUIRED; +} + +//------------------------------------------------------------------- + +VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject, + PLARGE_INTEGER Offset, + ULONG Length, + PMDL Mdl, + PIO_STATUS_BLOCK IoStatusBlock) +{ + PIRP irp; + KEVENT event; + PIO_STACK_LOCATION ioStackLocation; + PDEVICE_OBJECT fsdDevice = IoGetRelatedDeviceObject(FileObject); + NTSTATUS Status; + + // Set up the event we'll use + KeInitializeEvent(&event, SynchronizationEvent, FALSE); + + // Allocate and build the IRP we'll be sending to the FSD + irp = IoAllocateIrp(fsdDevice->StackSize, FALSE); + + if (!irp) { + // Allocation failed, presumably due to memory allocation failure + IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES; + IoStatusBlock->Information = 0; + + return; + } + + irp->MdlAddress = Mdl; + irp->UserEvent = &event; + irp->UserIosb = IoStatusBlock; + irp->Tail.Overlay.Thread = PsGetCurrentThread(); + irp->Tail.Overlay.OriginalFileObject= FileObject; + irp->RequestorMode = KernelMode; + + // Indicate that this is a WRITE operation + irp->Flags = IRP_WRITE_OPERATION; + + // Set up the next I/O stack location + ioStackLocation = IoGetNextIrpStackLocation(irp); + ioStackLocation->MajorFunction = IRP_MJ_WRITE; + ioStackLocation->MinorFunction = 0; + ioStackLocation->DeviceObject = fsdDevice; + ioStackLocation->FileObject = FileObject; + IoSetCompletionRoutine(irp, PacketDumpCompletion, 0, TRUE, TRUE, TRUE); + ioStackLocation->Parameters.Write.Length = Length; + ioStackLocation->Parameters.Write.ByteOffset = *Offset; + + + // Send it on. Ignore the return code + (void) IoCallDriver(fsdDevice, irp); + + // Wait for the I/O to complete. + KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0); + + // Free the IRP now that we are done with it + IoFreeIrp(irp); + + return; + +} diff --git a/winpcap/packetNtx/driver/functions.c b/winpcap/packetNtx/driver/functions.c new file mode 100644 index 0000000..08bad41 --- /dev/null +++ b/winpcap/packetNtx/driver/functions.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1999 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifdef WIN32 +#include "tme.h" +#include "functions.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#include +#include +#else +#include +#include +#include +#endif + +#endif + + + +lut_fcn lut_fcn_mapper(uint32 index) +{ + + switch (index) + { + case NORMAL_LUT_W_INSERT: + return (lut_fcn) normal_lut_w_insert; + + case NORMAL_LUT_WO_INSERT: + return (lut_fcn) normal_lut_wo_insert; + + case BUCKET_LOOKUP: + return (lut_fcn) bucket_lookup; + + case BUCKET_LOOKUP_INSERT: + return (lut_fcn) bucket_lookup_insert; + + default: + return NULL; + } + +} + +exec_fcn exec_fcn_mapper(uint32 index) +{ + switch (index) + { + case COUNT_PACKETS: + return (exec_fcn) count_packets; + + case TCP_SESSION: + return (exec_fcn) tcp_session; + default: + return NULL; + } +} diff --git a/winpcap/packetNtx/driver/functions.h b/winpcap/packetNtx/driver/functions.h new file mode 100644 index 0000000..4ec15fe --- /dev/null +++ b/winpcap/packetNtx/driver/functions.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1999 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __FUNCTIONS +#define __FUNCTIONS + +#ifdef WIN32 +#include "tme.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#else +#include +#endif + +#endif +/*function mappers */ + +lut_fcn lut_fcn_mapper(uint32 index); +exec_fcn exec_fcn_mapper(uint32 index); + +/* lookup functions */ + +#ifdef WIN32 +#include "bucket_lookup.h" +#include "normal_lookup.h" +#endif + +#ifdef __FreeBSD__ +#include +#include +#endif + +/* execution functions */ + +#ifdef WIN32 +#include "count_packets.h" +#include "tcp_session.h" +#endif + +#ifdef __FreeBSD__ +#include +#include +#endif + +#endif \ No newline at end of file diff --git a/winpcap/packetNtx/driver/jitter.c b/winpcap/packetNtx/driver/jitter.c new file mode 100644 index 0000000..a3fd8d9 --- /dev/null +++ b/winpcap/packetNtx/driver/jitter.c @@ -0,0 +1,684 @@ +/* + * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2007 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "stdarg.h" +#include "ntddk.h" +#include "ntiologc.h" +#include "ndis.h" + +#include "packet.h" +#include "win_bpf.h" + +// +// emit routine to update the jump table +// +void emit_lenght(binary_stream *stream, ULONG value, UINT len) +{ + (stream->refs)[stream->bpf_pc]+=len; + stream->cur_ip+=len; +} + +// +// emit routine to output the actual binary code +// +void emit_code(binary_stream *stream, ULONG value, UINT len) +{ + + switch (len){ + + case 1: + stream->ibuf[stream->cur_ip]=(UCHAR)value; + stream->cur_ip++; + break; + + case 2: + *((USHORT*)(stream->ibuf+stream->cur_ip))=(USHORT)value; + stream->cur_ip+=2; + break; + + case 4: + *((ULONG*)(stream->ibuf+stream->cur_ip))=value; + stream->cur_ip+=4; + break; + + default:; + + } + + return; + +} + +// +// Function that does the real stuff +// +BPF_filter_function BPFtoX86(struct bpf_insn *prog, UINT nins, INT *mem) +{ + struct bpf_insn *ins; + UINT i, pass; + binary_stream stream; + + //NOTE: do not modify the name of this variable, as it's used by the macros to emit code. + emit_func emitm; + + + // Allocate the reference table for the jumps +#ifdef NTKERNEL + stream.refs=(UINT *)ExAllocatePoolWithTag(NonPagedPool, (nins + 1)*sizeof(UINT), '0JWA'); +#else + stream.refs=(UINT *)malloc((nins + 1)*sizeof(UINT)); +#endif + if(stream.refs==NULL) + { + return NULL; + } + + // Reset the reference table + for(i=0; i< nins + 1; i++) + stream.refs[i]=0; + + stream.cur_ip=0; + stream.bpf_pc=0; + + // the first pass will emit the lengths of the instructions + // to create the reference table + emitm=emit_lenght; + + for(pass=0;;){ + + ins = prog; + + /* create the procedure header */ + PUSH(EBP) + MOVrd(EBP,ESP) + PUSH(EBX) + PUSH(ECX) + PUSH(EDX) + PUSH(ESI) + PUSH(EDI) + MOVodd(EBX, EBP, 8) + + for(i=0;icode) { + + default: + + return NULL; + + case BPF_RET|BPF_K: + + MOVid(EAX,ins->k) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + RET() + + break; + + + case BPF_RET|BPF_A: + + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + RET() + + break; + + + case BPF_LD|BPF_W|BPF_ABS: + + MOVid(ECX,ins->k) + MOVrd(ESI,ECX) + ADDib(ECX,sizeof(INT)) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) //this can be optimized with xor eax,eax + RET() + MOVobd(EAX, EBX, ESI) + BSWAP(EAX) + + break; + + case BPF_LD|BPF_H|BPF_ABS: + + MOVid(ECX,ins->k) + MOVrd(ESI,ECX) + ADDib(ECX,sizeof(SHORT)) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EAX,0) + MOVobw(AX, EBX, ESI) + SWAP_AX() + + break; + + case BPF_LD|BPF_B|BPF_ABS: + + MOVid(ECX,ins->k) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EAX,0) + MOVobb(AL,EBX,ECX) + + break; + + case BPF_LD|BPF_W|BPF_LEN: + + MOVodd(EAX, EBP, 0xc) + + break; + + case BPF_LDX|BPF_W|BPF_LEN: + + MOVodd(EDX, EBP, 0xc) + + break; + + case BPF_LD|BPF_W|BPF_IND: + + MOVid(ECX,ins->k) + ADDrd(ECX,EDX) + MOVrd(ESI,ECX) + ADDib(ECX,sizeof(INT)) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVobd(EAX, EBX, ESI) + BSWAP(EAX) + + break; + + case BPF_LD|BPF_H|BPF_IND: + + MOVid(ECX,ins->k) + ADDrd(ECX,EDX) + MOVrd(ESI,ECX) + ADDib(ECX,sizeof(SHORT)) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EAX,0) + MOVobw(AX, EBX, ESI) + SWAP_AX() + + break; + + case BPF_LD|BPF_B|BPF_IND: + + MOVid(ECX,ins->k) + ADDrd(ECX,EDX) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EAX,0) + MOVobb(AL,EBX,ECX) + + break; + + case BPF_LDX|BPF_MSH|BPF_B: + + MOVid(ECX,ins->k) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EDX,0) + MOVobb(DL,EBX,ECX) + ANDib(DL, 0xf) + SHLib(EDX, 2) + + break; + + case BPF_LD|BPF_IMM: + + MOVid(EAX,ins->k) + + break; + + case BPF_LDX|BPF_IMM: + + MOVid(EDX,ins->k) + + break; + + case BPF_LD|BPF_MEM: + + MOVid(ECX,(INT)mem) + MOVid(ESI,ins->k*4) + MOVobd(EAX, ECX, ESI) + + break; + + case BPF_LDX|BPF_MEM: + + MOVid(ECX,(INT)mem) + MOVid(ESI,ins->k*4) + MOVobd(EDX, ECX, ESI) + + break; + + case BPF_ST: + + // XXX: this command and the following could be optimized if the previous + // instruction was already of this type + MOVid(ECX,(INT)mem) + MOVid(ESI,ins->k*4) + MOVomd(ECX, ESI, EAX) + + break; + + case BPF_STX: + + MOVid(ECX,(INT)mem) + MOVid(ESI,ins->k*4) + MOVomd(ECX, ESI, EDX) + break; + + case BPF_JMP|BPF_JA: + + JMP(stream.refs[stream.bpf_pc+ins->k]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_JMP|BPF_JGT|BPF_K: + + CMPid(EAX, ins->k) + JG(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) // 5 is the size of the following JMP + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + break; + + case BPF_JMP|BPF_JGE|BPF_K: + + CMPid(EAX, ins->k) + JGE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_JMP|BPF_JEQ|BPF_K: + + CMPid(EAX, ins->k) + JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_JMP|BPF_JSET|BPF_K: + + MOVrd(ECX,EAX) + ANDid(ECX,ins->k) + JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_JMP|BPF_JGT|BPF_X: + + CMPrd(EAX, EDX) + JA(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + break; + + case BPF_JMP|BPF_JGE|BPF_X: + + CMPrd(EAX, EDX) + JAE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_JMP|BPF_JEQ|BPF_X: + + CMPrd(EAX, EDX) + JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_JMP|BPF_JSET|BPF_X: + + MOVrd(ECX,EAX) + ANDrd(ECX,EDX) + JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_ALU|BPF_ADD|BPF_X: + + ADDrd(EAX,EDX) + + break; + + case BPF_ALU|BPF_SUB|BPF_X: + + SUBrd(EAX,EDX) + + break; + + case BPF_ALU|BPF_MUL|BPF_X: + + MOVrd(ECX,EDX) + MULrd(EDX) + MOVrd(EDX,ECX) + break; + + case BPF_ALU|BPF_DIV|BPF_X: + + CMPid(EDX, 0) + JNEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVrd(ECX,EDX) + MOVid(EDX,0) + DIVrd(ECX) + MOVrd(EDX,ECX) + + break; + + case BPF_ALU|BPF_AND|BPF_X: + + ANDrd(EAX,EDX) + + break; + + case BPF_ALU|BPF_OR|BPF_X: + + ORrd(EAX,EDX) + + break; + + case BPF_ALU|BPF_LSH|BPF_X: + + MOVrd(ECX,EDX) + SHL_CLrb(EAX) + + break; + + case BPF_ALU|BPF_RSH|BPF_X: + + MOVrd(ECX,EDX) + SHR_CLrb(EAX) + + break; + + case BPF_ALU|BPF_ADD|BPF_K: + + ADD_EAXi(ins->k) + + break; + + case BPF_ALU|BPF_SUB|BPF_K: + + SUB_EAXi(ins->k) + + break; + + case BPF_ALU|BPF_MUL|BPF_K: + + MOVrd(ECX,EDX) + MOVid(EDX,ins->k) + MULrd(EDX) + MOVrd(EDX,ECX) + + break; + + case BPF_ALU|BPF_DIV|BPF_K: + + MOVrd(ECX,EDX) + MOVid(EDX,0) + MOVid(ESI,ins->k) + DIVrd(ESI) + MOVrd(EDX,ECX) + + break; + + case BPF_ALU|BPF_AND|BPF_K: + + ANDid(EAX, ins->k) + + break; + + case BPF_ALU|BPF_OR|BPF_K: + + ORid(EAX, ins->k) + + break; + + case BPF_ALU|BPF_LSH|BPF_K: + + SHLib(EAX, (ins->k) & 255) + + break; + + case BPF_ALU|BPF_RSH|BPF_K: + + SHRib(EAX, (ins->k) & 255) + + break; + + case BPF_ALU|BPF_NEG: + + NEGd(EAX) + + break; + + case BPF_MISC|BPF_TAX: + + MOVrd(EDX,EAX) + + break; + + case BPF_MISC|BPF_TXA: + + MOVrd(EAX,EDX) + + break; + + + + } + + ins++; + } + + pass++; + if(pass == 2) break; + +#ifdef NTKERNEL + stream.ibuf=(CHAR*)ExAllocatePoolWithTag(NonPagedPool, stream.cur_ip, '1JWA'); +#else + stream.ibuf=(CHAR*)malloc(stream.cur_ip); +#endif + if(stream.ibuf==NULL) + { +#ifdef NTKERNEL + ExFreePool(stream.refs); +#else + free(stream.refs); +#endif + return NULL; + } + + // modify the reference table to contain the offsets and not the lengths of the instructions + for(i=1; i< nins + 1; i++) + stream.refs[i]+=stream.refs[i-1]; + + // Reset the counters + stream.cur_ip=0; + stream.bpf_pc=0; + // the second pass creates the actual code + emitm=emit_code; + + } + + // the reference table is needed only during compilation, now we can free it +#ifdef NTKERNEL + ExFreePool(stream.refs); +#else + free(stream.refs); +#endif + return (BPF_filter_function)stream.ibuf; + +} + + +JIT_BPF_Filter* BPF_jitter(struct bpf_insn *fp, INT nins) +{ + JIT_BPF_Filter *Filter; + + + // Allocate the filter structure +#ifdef NTKERNEL + Filter=(struct JIT_BPF_Filter*)ExAllocatePoolWithTag(NonPagedPool, sizeof(struct JIT_BPF_Filter), '2JWA'); +#else + Filter=(struct JIT_BPF_Filter*)malloc(sizeof(struct JIT_BPF_Filter)); +#endif + if(Filter==NULL) + { + return NULL; + } + + // Allocate the filter's memory +#ifdef NTKERNEL + Filter->mem=(INT*)ExAllocatePoolWithTag(NonPagedPool, BPF_MEMWORDS*sizeof(INT), '3JWA'); +#else + Filter->mem=(INT*)malloc(BPF_MEMWORDS*sizeof(INT)); +#endif + if(Filter->mem==NULL) + { +#ifdef NTKERNEL + ExFreePool(Filter); +#else + free(Filter); +#endif + return NULL; + } + + // Create the binary + if((Filter->Function = BPFtoX86(fp, nins, Filter->mem))==NULL) + { +#ifdef NTKERNEL + ExFreePool(Filter->mem); + ExFreePool(Filter); +#else + free(Filter->mem); + free(Filter); +#endif + return NULL; + } + + return Filter; + +} + +////////////////////////////////////////////////////////////// + +void BPF_Destroy_JIT_Filter(JIT_BPF_Filter *Filter){ + +#ifdef NTKERNEL + ExFreePool(Filter->mem); + ExFreePool(Filter->Function); + ExFreePool(Filter); +#else + free(Filter->mem); + free(Filter->Function); + free(Filter); +#endif + +} diff --git a/winpcap/packetNtx/driver/jitter.h b/winpcap/packetNtx/driver/jitter.h new file mode 100644 index 0000000..0df2c68 --- /dev/null +++ b/winpcap/packetNtx/driver/jitter.h @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** @addtogroup NPF + * @{ + */ + +// +// Registers +// +#define EAX 0 +#define ECX 1 +#define EDX 2 +#define EBX 3 +#define ESP 4 +#define EBP 5 +#define ESI 6 +#define EDI 7 + +#define AX 0 +#define CX 1 +#define DX 2 +#define BX 3 +#define SP 4 +#define BP 5 +#define SI 6 +#define DI 7 + +#define AL 0 +#define CL 1 +#define DL 2 +#define BL 3 + +/*! \brief A stream of X86 binary code.*/ +typedef struct binary_stream{ + INT cur_ip; ///< Current X86 instruction pointer. + INT bpf_pc; ///< Current BPF instruction pointer, i.e. position in the BPF program reached by the jitter. + PCHAR ibuf; ///< Instruction buffer, contains the X86 generated code. + PUINT refs; ///< Jumps reference table. +}binary_stream; + + +/*! \brief Prototype of a filtering function created by the jitter. + + The syntax and the meaning of the parameters is analogous to the one of bpf_filter(). Notice that the filter + is not among the parameters, because it is hardwired in the function. +*/ +typedef UINT (__cdecl *BPF_filter_function)( PVOID *, ULONG, UINT); + +/*! \brief Prototype of the emit functions. + + Different emit functions are used to create the reference table and to generate the actual filtering code. + This allows to have simpler instruction macros. + The first parameter is the stream that will receive the data. The secon one is a variable containing + the data, the third one is the length, that can be 1,2 or 4 since it is possible to emit a byte, a short + or a work at a time. +*/ +typedef void (*emit_func)(binary_stream *stream, ULONG value, UINT n); + +/*! \brief Structure describing a x86 filtering program created by the jitter.*/ +typedef struct JIT_BPF_Filter{ + BPF_filter_function Function; ///< The x86 filtering binary, in the form of a BPF_filter_function. + PINT mem; +} +JIT_BPF_Filter; + + + + +/**************************/ +/* X86 INSTRUCTION MACROS */ +/**************************/ + +/// mov r32,i32 +#define MOVid(r32, i32) \ + emitm(&stream, 11 << 4 | 1 << 3 | r32 & 0x7, 1); emitm(&stream, i32, 4); + +/// mov dr32,sr32 +#define MOVrd(dr32, sr32) \ + emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1); + +/// mov dr32,sr32[off] +#define MOVodd(dr32, sr32, off) \ + emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); \ + emitm(&stream, 1 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);\ + emitm(&stream, off, 1); + +/// mov dr32,sr32[or32] +#define MOVobd(dr32, sr32, or32) \ + emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); \ + emitm(&stream, (dr32 & 0x7) << 3 | 4 , 1);\ + emitm(&stream, (or32 & 0x7) << 3 | (sr32 & 0x7) , 1); + +/// mov dr16,sr32[or32] +#define MOVobw(dr32, sr32, or32) \ + emitm(&stream, 0x66, 1); \ + emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); \ + emitm(&stream, (dr32 & 0x7) << 3 | 4 , 1);\ + emitm(&stream, (or32 & 0x7) << 3 | (sr32 & 0x7) , 1); + +/// mov dr8,sr32[or32] +#define MOVobb(dr8, sr32, or32) \ + emitm(&stream, 0x8a, 1); \ + emitm(&stream, (dr8 & 0x7) << 3 | 4 , 1);\ + emitm(&stream, (or32 & 0x7) << 3 | (sr32 & 0x7) , 1); + +/// mov [dr32][or32],sr32 +#define MOVomd(dr32, or32, sr32) \ + emitm(&stream, 0x89, 1); \ + emitm(&stream, (sr32 & 0x7) << 3 | 4 , 1);\ + emitm(&stream, (or32 & 0x7) << 3 | (dr32 & 0x7) , 1); + +/// bswap dr32 +#define BSWAP(dr32) \ + emitm(&stream, 0xf, 1); \ + emitm(&stream, 0x19 << 3 | dr32 , 1); + +/// xchg al,ah +#define SWAP_AX() \ + emitm(&stream, 0x86, 1); \ + emitm(&stream, 0xc4 , 1); + +/// push r32 +#define PUSH(r32) \ + emitm(&stream, 5 << 4 | 0 << 3 | r32 & 0x7, 1); + +/// pop r32 +#define POP(r32) \ + emitm(&stream, 5 << 4 | 1 << 3 | r32 & 0x7, 1); + +/// ret +#define RET() \ + emitm(&stream, 12 << 4 | 0 << 3 | 3, 1); + +/// add dr32,sr32 +#define ADDrd(dr32, sr32) \ + emitm(&stream, 0x03, 1);\ + emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | (sr32 & 0x7), 1); + +/// add eax,i32 +#define ADD_EAXi(i32) \ + emitm(&stream, 0x05, 1);\ + emitm(&stream, i32, 4); + +/// add r32,i32 +#define ADDid(r32, i32) \ + emitm(&stream, 0x81, 1);\ + emitm(&stream, 24 << 3 | r32, 1);\ + emitm(&stream, i32, 4); + +/// add r32,i8 +#define ADDib(r32, i8) \ + emitm(&stream, 0x83, 1);\ + emitm(&stream, 24 << 3 | r32, 1);\ + emitm(&stream, i8, 1); + +/// sub dr32,sr32 +#define SUBrd(dr32, sr32) \ + emitm(&stream, 0x2b, 1);\ + emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | (sr32 & 0x7), 1); + +/// sub eax,i32 +#define SUB_EAXi(i32) \ + emitm(&stream, 0x2d, 1);\ + emitm(&stream, i32, 4); + +/// mul r32 +#define MULrd(r32) \ + emitm(&stream, 0xf7, 1);\ + emitm(&stream, 7 << 5 | (r32 & 0x7), 1); + +/// div r32 +#define DIVrd(r32) \ + emitm(&stream, 0xf7, 1);\ + emitm(&stream, 15 << 4 | (r32 & 0x7), 1); + +/// and r8,i8 +#define ANDib(r8, i8) \ + emitm(&stream, 0x80, 1);\ + emitm(&stream, 7 << 5 | r8, 1);\ + emitm(&stream, i8, 1); + +/// and r32,i32 +#define ANDid(r32, i32) \ + if (r32 == EAX){ \ + emitm(&stream, 0x25, 1);\ + emitm(&stream, i32, 4);}\ + else{ \ + emitm(&stream, 0x81, 1);\ + emitm(&stream, 7 << 5 | r32, 1);\ + emitm(&stream, i32, 4);} + +/// and dr32,sr32 +#define ANDrd(dr32, sr32) \ + emitm(&stream, 0x23, 1);\ + emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1); + +/// or dr32,sr32 +#define ORrd(dr32, sr32) \ + emitm(&stream, 0x0b, 1);\ + emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1); + +/// or r32,i32 +#define ORid(r32, i32) \ + if (r32 == EAX){ \ + emitm(&stream, 0x0d, 1);\ + emitm(&stream, i32, 4);}\ + else{ \ + emitm(&stream, 0x81, 1);\ + emitm(&stream, 25 << 3 | r32, 1);\ + emitm(&stream, i32, 4);} + +/// shl r32,i8 +#define SHLib(r32, i8) \ + emitm(&stream, 0xc1, 1);\ + emitm(&stream, 7 << 5 | r32 & 0x7, 1);\ + emitm(&stream, i8, 1); + +/// shl dr32,cl +#define SHL_CLrb(dr32) \ + emitm(&stream, 0xd3, 1);\ + emitm(&stream, 7 << 5 | dr32 & 0x7, 1); + +/// shr r32,i8 +#define SHRib(r32, i8) \ + emitm(&stream, 0xc1, 1);\ + emitm(&stream, 29 << 3 | r32 & 0x7, 1);\ + emitm(&stream, i8, 1); + +/// shr dr32,cl +#define SHR_CLrb(dr32) \ + emitm(&stream, 0xd3, 1);\ + emitm(&stream, 29 << 3 | dr32 & 0x7, 1); + +/// neg r32 +#define NEGd(r32) \ + emitm(&stream, 0xf7, 1);\ + emitm(&stream, 27 << 3 | r32 & 0x7, 1); + +/// cmp dr32,sr32[off] +#define CMPodd(dr32, sr32, off) \ + emitm(&stream, 3 << 4 | 3 | 1 << 3, 1); \ + emitm(&stream, 1 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);\ + emitm(&stream, off, 1); + +/// cmp dr32,sr32 +#define CMPrd(dr32, sr32) \ + emitm(&stream, 0x3b, 1); \ + emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1); + +/// cmp dr32,i32 +#define CMPid(dr32, i32) \ + if (dr32 == EAX){ \ + emitm(&stream, 0x3d, 1); \ + emitm(&stream, i32, 4);} \ + else{ \ + emitm(&stream, 0x81, 1); \ + emitm(&stream, 0x1f << 3 | (dr32 & 0x7), 1);\ + emitm(&stream, i32, 4);} + +/// jne off32 +#define JNEb(off8) \ + emitm(&stream, 0x75, 1);\ + emitm(&stream, off8, 1); + +/// je off32 +#define JE(off32) \ + emitm(&stream, 0x0f, 1);\ + emitm(&stream, 0x84, 1);\ + emitm(&stream, off32, 4); + +/// jle off32 +#define JLE(off32) \ + emitm(&stream, 0x0f, 1);\ + emitm(&stream, 0x8e, 1);\ + emitm(&stream, off32, 4); + +/// jle off8 +#define JLEb(off8) \ + emitm(&stream, 0x7e, 1);\ + emitm(&stream, off8, 1); + +/// ja off32 +#define JA(off32) \ + emitm(&stream, 0x0f, 1);\ + emitm(&stream, 0x87, 1);\ + emitm(&stream, off32, 4); + +/// jae off32 +#define JAE(off32) \ + emitm(&stream, 0x0f, 1);\ + emitm(&stream, 0x83, 1);\ + emitm(&stream, off32, 4); + +/// jg off32 +#define JG(off32) \ + emitm(&stream, 0x0f, 1);\ + emitm(&stream, 0x8f, 1);\ + emitm(&stream, off32, 4); + +/// jge off32 +#define JGE(off32) \ + emitm(&stream, 0x0f, 1);\ + emitm(&stream, 0x8d, 1);\ + emitm(&stream, off32, 4); + +/// jmp off32 +#define JMP(off32) \ + emitm(&stream, 0xe9, 1);\ + emitm(&stream, off32, 4); + +/** + * @} + */ + +/**************************/ +/* Prototypes */ +/**************************/ + +/** @addtogroup NPF_code + * @{ + */ + +/*! + \brief BPF jitter, builds an x86 function from a BPF program. + \param fp The BPF pseudo-assembly filter that will be translated into x86 code. + \param nins Number of instructions of the input filter. + \return The JIT_BPF_Filter structure containing the x86 filtering binary. + + BPF_jitter allocates the buffers for the new native filter and then translates the program pointed by fp + calling BPFtoX86(). +*/ +JIT_BPF_Filter* BPF_jitter(struct bpf_insn *fp, INT nins); + +/*! + \brief Translates a set of BPF instructions in a set of x86 ones. + \param ins Pointer to the BPF instructions that will be translated into x86 code. + \param nins Number of instructions to translate. + \param mem Memory used by the x86 function to emulate the RAM of the BPF pseudo processor. + \return The x86 filtering function. + + This function does the hard work for the JIT compilation. It takes a group of BPF pseudo instructions and + through the instruction macros defined in jitter.h it is able to create an function directly executable + by NPF. +*/ +BPF_filter_function BPFtoX86(struct bpf_insn *ins, UINT nins, INT *mem); +/*! + \brief Deletes a filtering function that was previously created by BPF_jitter(). + \param Filter The filter to destroy. + + This function frees the variuos buffers (code, memory, etc.) associated with a filtering function. +*/ +void BPF_Destroy_JIT_Filter(JIT_BPF_Filter *Filter); + +/** + * @} + */ diff --git a/winpcap/packetNtx/driver/memory_t.h b/winpcap/packetNtx/driver/memory_t.h new file mode 100644 index 0000000..3f3fb52 --- /dev/null +++ b/winpcap/packetNtx/driver/memory_t.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2001 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __memory_t +#define __memory_t + +#define uint8 UCHAR +#define int8 CHAR +#define uint16 USHORT +#define int16 SHORT +#define uint32 ULONG +#define int32 LONG +#define uint64 ULONGLONG +#define int64 LONGLONG + +/*memory type*/ +typedef struct __MEM_TYPE +{ + uint8 *buffer; + uint32 size; +} MEM_TYPE, *PMEM_TYPE; + +#define LONG_AT(base,offset) (*(int32*)((uint8*)base+(uint32)offset)) + +#define ULONG_AT(base,offset) (*(uint32*)((uint8*)base+(uint32)offset)) + +#define SHORT_AT(base,offset) (*(int16*)((uint8*)base+(uint32)offset)) + +#define USHORT_AT(base,offset) (*(uint16*)((uint8*)base+(uint32)offset)) + +__inline int32 SW_LONG_AT(void *b, uint32 c) +{ + return ((int32)*((uint8 *)b+c)<<24| + (int32)*((uint8 *)b+c+1)<<16| + (int32)*((uint8 *)b+c+2)<<8| + (int32)*((uint8 *)b+c+3)<<0); +} + + +__inline uint32 SW_ULONG_AT(void *b, uint32 c) +{ + return ((uint32)*((uint8 *)b+c)<<24| + (uint32)*((uint8 *)b+c+1)<<16| + (uint32)*((uint8 *)b+c+2)<<8| + (uint32)*((uint8 *)b+c+3)<<0); +} + +__inline int16 SW_SHORT_AT(void *b, uint32 os) +{ + return ((int16) + ((int16)*((uint8 *)b+os+0)<<8| + (int16)*((uint8 *)b+os+1)<<0)); +} + +__inline uint16 SW_USHORT_AT(void *b, uint32 os) +{ + return ((uint16) + ((uint16)*((uint8 *)b+os+0)<<8| + (uint16)*((uint8 *)b+os+1)<<0)); +} + +__inline VOID SW_ULONG_ASSIGN(void *dst, uint32 src) +{ + *((uint8*)dst+0)=*((uint8*)&src+3); + *((uint8*)dst+1)=*((uint8*)&src+2); + *((uint8*)dst+2)=*((uint8*)&src+1); + *((uint8*)dst+3)=*((uint8*)&src+0); + +} + +#ifdef WIN_NT_DRIVER + +#define ALLOCATE_MEMORY(dest,type,amount) \ + (dest)=ExAllocatePoolWithTag(NonPagedPool,sizeof(type)*(amount), '0TWA'); +#define ALLOCATE_ZERO_MEMORY(dest,type,amount) \ + { \ + (dest)=ExAllocatePoolWithTag(NonPagedPool,sizeof(type)*(amount), '1TWA'); \ + if ((dest)!=NULL) \ + RtlZeroMemory((dest),sizeof(type)*(amount)); \ + } + +#define FREE_MEMORY(dest) ExFreePool(dest); +#define ZERO_MEMORY(dest,amount) RtlZeroMemory(dest,amount); +#define COPY_MEMORY(dest,src,amount) RtlCopyMemory(dest,src,amount); + +#else + +#define ALLOCATE_MEMORY(dest,type,amount) \ + (dest)=(type*)GlobalAlloc(GPTR, sizeof(type)*(amount)); +#define ALLOCATE_ZERO_MEMORY(dest,type,amount) \ + (dest)=(type*)GlobalAlloc(GPTR, sizeof(type)*(amount)); + +#define FREE_MEMORY(dest) GlobalFree(dest); +#define ZERO_MEMORY(dest,amount) RtlZeroMemory(dest,amount); +#define COPY_MEMORY(dest,src,amount) RtlCopyMemory(dest,src,amount); + + +#endif /*WIN_NT_DRIVER*/ + + + +#endif + diff --git a/winpcap/packetNtx/driver/normal_lookup.c b/winpcap/packetNtx/driver/normal_lookup.c new file mode 100644 index 0000000..cdd8e54 --- /dev/null +++ b/winpcap/packetNtx/driver/normal_lookup.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2001 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifdef WIN32 +#include "tme.h" +#include "normal_lookup.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#include +#else +#include +#include +#endif + +#endif + + +/* lookup in the table, seen as an hash */ +/* if not found, inserts an element */ +/* returns TME_TRUE if the entry is found or created, */ +/* returns TME_FALSE if no more blocks are available */ +uint32 normal_lut_w_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref) +{ + uint32 i; + uint32 tocs=0; + uint32 *key32=(uint32*) key; + uint32 shrinked_key=0; + uint32 index; + RECORD *records=(RECORD*)data->lut_base_address; + uint8 *offset; + uint32 key_len=data->key_len; + /*the key is shrinked into a 32-bit value */ + for (i=0; ilut_entries; + + while (tocs<=data->filled_entries) + { + + if (records[index].block==0) + { /*creation of a new entry*/ + + if (data->filled_blocks==data->shared_memory_blocks) + { + /*no more free blocks*/ + GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref); + data->last_found=NULL; + return TME_FALSE; + } + + /*offset=absolute pointer to the block associated*/ + /*with the newly created entry*/ + offset=data->shared_memory_base_address+ + data->block_size*data->filled_blocks; + + /*copy the key in the block*/ + COPY_MEMORY(offset,key32,key_len*4); + GET_TIME((struct timeval *)(offset+4*key_len),time_ref); + /*assign the block relative offset to the entry, in NBO*/ + SW_ULONG_ASSIGN(&records[index].block,offset-mem_ex->buffer); + + data->filled_blocks++; + + /*assign the exec function ID to the entry, in NBO*/ + SW_ULONG_ASSIGN(&records[index].exec_fcn,data->default_exec); + data->filled_entries++; + + data->last_found=(uint8*)&records[index]; + + return TME_TRUE; + } + /*offset contains the absolute pointer to the block*/ + /*associated with the current entry */ + offset=mem_ex->buffer+SW_ULONG_AT(&records[index].block,0); + + for (i=0; (ilast_found=(uint8*)&records[index]; + return TME_TRUE; + } + else + { + /* wrong entry, rehashing */ + if (IS_DELETABLE(offset+key_len*4,data)) + { + ZERO_MEMORY(offset,data->block_size); + COPY_MEMORY(offset,key32,key_len*4); + SW_ULONG_ASSIGN(&records[index].exec_fcn,data->default_exec); + GET_TIME((struct timeval*)(offset+key_len*4),time_ref); + data->last_found=(uint8*)&records[index]; + return TME_TRUE; + } + else + { + index=(index+data->rehashing_value) % data->lut_entries; + tocs++; + } + } + } + + /* nothing found, last found= out of lut */ + GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref); + data->last_found=NULL; + return TME_FALSE; + +} + +/* lookup in the table, seen as an hash */ +/* if not found, returns out of count entry index */ +/* returns TME_TRUE if the entry is found */ +/* returns TME_FALSE if the entry is not found */ +uint32 normal_lut_wo_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref) +{ + uint32 i; + uint32 tocs=0; + uint32 *key32=(uint32*) key; + uint32 shrinked_key=0; + uint32 index; + RECORD *records=(RECORD*)data->lut_base_address; + uint8 *offset; + uint32 key_len=data->key_len; + /*the key is shrinked into a 32-bit value */ + for (i=0; ilut_entries; + + while (tocs<=data->filled_entries) + { + + if (records[index].block==0) + { /*out of table, insertion is not allowed*/ + GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref); + data->last_found=NULL; + return TME_FALSE; + } + /*offset contains the absolute pointer to the block*/ + /*associated with the current entry */ + + offset=mem_ex->buffer+SW_ULONG_AT(&records[index].block,0); + + for (i=0; (ilast_found=(uint8*)&records[index]; + return TME_TRUE; + } + else + { + /*wrong entry, rehashing*/ + index=(index+data->rehashing_value) % data->lut_entries; + tocs++; + } + } + + /*nothing found, last found= out of lut*/ + GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref); + data->last_found=NULL; + return TME_FALSE; + +} diff --git a/winpcap/packetNtx/driver/normal_lookup.h b/winpcap/packetNtx/driver/normal_lookup.h new file mode 100644 index 0000000..f9fb00b --- /dev/null +++ b/winpcap/packetNtx/driver/normal_lookup.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2001 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __normal_lookup +#define __normal_lookup + +#ifdef WIN32 +#include "tme.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#else +#include +#endif + +#endif + +#define NORMAL_LUT_W_INSERT 0x00000000 +uint32 normal_lut_w_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); +#define NORMAL_LUT_WO_INSERT 0x00000001 +uint32 normal_lut_wo_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); +#define DUMMY_INSERT 1234 + +#endif \ No newline at end of file diff --git a/winpcap/packetNtx/driver/resource.h b/winpcap/packetNtx/driver/resource.h new file mode 100644 index 0000000..b84eba2 --- /dev/null +++ b/winpcap/packetNtx/driver/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by NPF.RC +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/winpcap/packetNtx/driver/tcp_session.c b/winpcap/packetNtx/driver/tcp_session.c new file mode 100644 index 0000000..be1f75d --- /dev/null +++ b/winpcap/packetNtx/driver/tcp_session.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2001 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifdef WIN32 +#include "tme.h" +#include "tcp_session.h" +#endif + +#ifdef __FreeBSD + +#ifdef _KERNEL +#include +#include +#else +#include +#include +#endif + +#endif + +uint32 tcp_session(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data) + +{ + + uint32 next_status; + uint32 direction=ULONG_AT(mem_data,12); + uint8 flags=mem_ex->buffer[25]; + tcp_data *session=(tcp_data*)(block+data->key_len*4); + + session->last_timestamp=session->timestamp_block; + session->timestamp_block.tv_sec=0x7fffffff; + + if (direction==session->direction) + { + session->pkts_cln_to_srv++; + session->bytes_cln_to_srv+=pkt_size; + } + else + { + session->pkts_srv_to_cln++; + session->bytes_srv_to_cln+=pkt_size; + } + /* we use only thes four flags, we don't need PSH or URG */ + flags&=(ACK|FIN|SYN|RST); + + switch (session->status) + { + case ERROR_TCP: + next_status=ERROR_TCP; + break; + + case UNKNOWN: + if (flags==SYN) + { + if (SW_ULONG_AT(mem_ex->buffer,20)!=0) + { + + next_status=ERROR_TCP; + break; + } + next_status=SYN_RCV; + session->syn_timestamp=session->last_timestamp; + + session->direction=direction; + session->seq_n_0_cln=SW_ULONG_AT(mem_ex->buffer,16); + } + else + next_status=UNKNOWN; + break; + + case SYN_RCV: + if ((flags&RST)&&(direction!=session->direction)) + { + next_status=CLOSED_RST; + break; + } + if ((flags==SYN)&&(direction==session->direction)) + { /* two syns... */ + next_status=SYN_RCV; + session->seq_n_0_cln=SW_ULONG_AT(mem_ex->buffer,16); + break; + } + + if ((flags==(SYN|ACK))&&(direction!=session->direction)) + { + if (SW_ULONG_AT(mem_ex->buffer,20)!=session->seq_n_0_cln+1) + { + next_status=ERROR_TCP; + break; + } + next_status=SYN_ACK_RCV; + + session->syn_ack_timestamp=session->last_timestamp; + + session->seq_n_0_srv=SW_ULONG_AT(mem_ex->buffer,16); + session->ack_cln=session->seq_n_0_cln+1; + } + else + { + next_status=ERROR_TCP; + } + break; + + case SYN_ACK_RCV: + if ((flags&ACK)&&(flags&RST)&&(direction==session->direction)) + { + next_status=CLOSED_RST; + session->ack_srv=SW_ULONG_AT(mem_ex->buffer,20); + break; + } + + if ((flags==ACK)&&(!(flags&(SYN|FIN|RST)))&&(direction==session->direction)) + { + if (SW_ULONG_AT(mem_ex->buffer,20)!=session->seq_n_0_srv+1) + { + next_status=ERROR_TCP; + break; + } + next_status=ESTABLISHED; + session->ack_srv=session->seq_n_0_srv+1; + break; + } + if ((flags&ACK)&&(flags&SYN)&&(direction!=session->direction)) + { + next_status=SYN_ACK_RCV; + break; + } + + next_status=ERROR_TCP; + break; + + case ESTABLISHED: + if (flags&SYN) + { + if ((flags&ACK)&& + (direction!=session->direction)&& + ((session->ack_cln-SW_ULONG_AT(mem_ex->buffer,20))direction)&& + (SW_ULONG_AT(mem_ex->buffer,16)==session->seq_n_0_cln)&& + (ULONG_AT(mem_ex->buffer,20)==0) + ) + { /* syn duplicato */ + next_status=ESTABLISHED; + break; + } + + next_status=ERROR_TCP; + break; + } + if (flags&ACK) + if (direction==session->direction) + { + uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20); + if (new_ack-session->ack_srvack_srv=new_ack; + } + else + { + uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20); + if (new_ack-session->ack_clnack_cln=new_ack; + } + if (flags&RST) + { + next_status=CLOSED_RST; + break; + } + if (flags&FIN) + if (direction==session->direction) + { /* an hack to make all things work */ + session->ack_cln=SW_ULONG_AT(mem_ex->buffer,16); + next_status=FIN_CLN_RCV; + break; + } + else + { + session->ack_srv=SW_ULONG_AT(mem_ex->buffer,16); + next_status=FIN_SRV_RCV; + break; + } + next_status=ESTABLISHED; + break; + + case CLOSED_RST: + next_status=CLOSED_RST; + break; + + case FIN_SRV_RCV: + if (flags&SYN) + { + next_status=ERROR_TCP; + break; + } + + next_status=FIN_SRV_RCV; + + if (flags&ACK) + { + uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20); + if (direction!=session->direction) + if ((new_ack-session->ack_cln)ack_cln=new_ack; + } + + if (flags&RST) + next_status=CLOSED_RST; + else + if ((flags&FIN)&&(direction==session->direction)) + { + session->ack_cln=SW_ULONG_AT(mem_ex->buffer,16); + next_status=CLOSED_FIN; + } + + break; + + case FIN_CLN_RCV: + if (flags&SYN) + { + next_status=ERROR_TCP; + break; + } + + next_status=FIN_CLN_RCV; + + if (flags&ACK) + { + uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20); + if (direction==session->direction) + if (new_ack-session->ack_srvack_srv=new_ack; + } + + if (flags&RST) + next_status=CLOSED_RST; + else + if ((flags&FIN)&&(direction!=session->direction)) + { + session->ack_srv=SW_ULONG_AT(mem_ex->buffer,16); + next_status=CLOSED_FIN; + } + + break; + + case CLOSED_FIN: + next_status=CLOSED_FIN; + break; + default: + next_status=ERROR_TCP; + + } + + session->status=next_status; + + if ((next_status==CLOSED_FIN)||(next_status==UNKNOWN)||(next_status==CLOSED_RST)||(next_status==ERROR_TCP)) + session->timestamp_block=session->last_timestamp; + + return TME_SUCCESS; +} \ No newline at end of file diff --git a/winpcap/packetNtx/driver/tcp_session.h b/winpcap/packetNtx/driver/tcp_session.h new file mode 100644 index 0000000..c7fb69a --- /dev/null +++ b/winpcap/packetNtx/driver/tcp_session.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2001 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __tcp_session +#define __tcp_session + +#ifdef WIN32 +#include "tme.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#else +#include +#endif + +#endif + +#define UNKNOWN 0 +#define SYN_RCV 1 +#define SYN_ACK_RCV 2 +#define ESTABLISHED 3 +#define CLOSED_RST 4 +#define FIN_CLN_RCV 5 +#define FIN_SRV_RCV 6 +#define CLOSED_FIN 7 +#define ERROR_TCP 8 +#define FIRST_IS_CLN 0 +#define FIRST_IS_SRV 0xffffffff +#define FIN_CLN 1 +#define FIN_SRV 2 + +#define MAX_WINDOW 65536 + +typedef struct __tcp_data +{ + struct timeval timestamp_block; /*DO NOT MOVE THIS VALUE*/ + struct timeval syn_timestamp; + struct timeval last_timestamp; + struct timeval syn_ack_timestamp; + uint32 direction; + uint32 seq_n_0_srv; + uint32 seq_n_0_cln; + uint32 ack_srv; /* acknowledge of (data sent by server) */ + uint32 ack_cln; /* acknowledge of (data sent by client) */ + uint32 status; + uint32 pkts_cln_to_srv; + uint32 pkts_srv_to_cln; + uint32 bytes_srv_to_cln; + uint32 bytes_cln_to_srv; + uint32 close_state; +} + tcp_data; + +#define FIN 1 +#define SYN 2 +#define RST 4 +#define PSH 8 +#define ACK 16 +#define URG 32 + +#define TCP_SESSION 0x00000800 +uint32 tcp_session(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data); + +#endif \ No newline at end of file diff --git a/winpcap/packetNtx/driver/time_calls.h b/winpcap/packetNtx/driver/time_calls.h new file mode 100644 index 0000000..09a6d69 --- /dev/null +++ b/winpcap/packetNtx/driver/time_calls.h @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2001 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _time_calls +#define _time_calls + +#ifdef WIN_NT_DRIVER + +#include "debug.h" +#include "ndis.h" + +#define DEFAULT_TIMESTAMPMODE 0 + +#define TIMESTAMPMODE_SINGLE_SYNCHRONIZATION 0 +#define TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_WITH_FIXUP 1 +#define TIMESTAMPMODE_QUERYSYSTEMTIME 2 +#define TIMESTAMPMODE_RDTSC 3 + +#define TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_NO_FIXUP 99 + +#define TIMESTAMPMODE_REGKEY L"TimestampMode" + +extern ULONG TimestampMode; + +/*! + \brief A microsecond precise timestamp. + + included in the sf_pkthdr or the bpf_hdr that NPF associates with every packet. +*/ + +struct timeval { + long tv_sec; ///< seconds + long tv_usec; ///< microseconds +}; + +#endif /*WIN_NT_DRIVER*/ + +struct time_conv +{ + ULONGLONG reference; + struct timeval start[32]; +}; + +#ifdef WIN_NT_DRIVER + +__inline void TIME_DESYNCHRONIZE(struct time_conv *data) +{ + data->reference = 0; +// data->start.tv_sec = 0; +// data->start.tv_usec = 0; +} + + +__inline void ReadTimeStampModeFromRegistry(PUNICODE_STRING RegistryPath) +{ + ULONG NewLength; + PWSTR NullTerminatedString; + RTL_QUERY_REGISTRY_TABLE Queries[2]; + ULONG DefaultTimestampMode = DEFAULT_TIMESTAMPMODE; + + NewLength = RegistryPath->Length/2; + + NullTerminatedString = ExAllocatePoolWithTag(PagedPool, (NewLength+1) *sizeof(WCHAR), '2TWA'); + + if (NullTerminatedString != NULL) + { + RtlCopyMemory(NullTerminatedString, RegistryPath->Buffer, RegistryPath->Length); + + NullTerminatedString[NewLength]=0; + + RtlZeroMemory(Queries, sizeof(Queries)); + + Queries[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + Queries[0].Name = TIMESTAMPMODE_REGKEY; + Queries[0].EntryContext = &TimestampMode; + Queries[0].DefaultType = REG_DWORD; + Queries[0].DefaultData = &DefaultTimestampMode; + Queries[0].DefaultLength = sizeof(ULONG); + + if(RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, NullTerminatedString, Queries, NULL, NULL) != STATUS_SUCCESS) + { + TimestampMode = DEFAULT_TIMESTAMPMODE; + } + + RtlWriteRegistryValue( RTL_REGISTRY_ABSOLUTE, NullTerminatedString, TIMESTAMPMODE_REGKEY, REG_DWORD, &TimestampMode,sizeof(ULONG)); + ExFreePool(NullTerminatedString); + } + else + TimestampMode = DEFAULT_TIMESTAMPMODE; +} + +#pragma optimize ("g",off) //Due to some weird behaviour of the optimizer of DDK build 2600 + +/* KeQueryPerformanceCounter TimeStamps */ +__inline void SynchronizeOnCpu(struct timeval *start) +{ +// struct timeval *start = (struct timeval*)Data; + + struct timeval tmp; + LARGE_INTEGER SystemTime; + LARGE_INTEGER i; + ULONG tmp2; + LARGE_INTEGER TimeFreq,PTime; + + // get the absolute value of the system boot time. + + PTime = KeQueryPerformanceCounter(&TimeFreq); + KeQuerySystemTime(&SystemTime); + + start->tv_sec = (LONG)(SystemTime.QuadPart/10000000-11644473600); + + start->tv_usec = (LONG)((SystemTime.QuadPart%10000000)/10); + + start->tv_sec -= (ULONG)(PTime.QuadPart/TimeFreq.QuadPart); + + start->tv_usec -= (LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); + + if (start->tv_usec < 0) + { + start->tv_sec --; + start->tv_usec += 1000000; + } +} + +// +// inline assembler is not supported with the current AMD64 compilers +// At the moment we simply disable this timestamping mode on AMD64. +// A solution would be to allocate a small memory from the non-paged +// pool, dump the instructions on that buffer, and then execute them. +// The non paged pool is needed since it's the only area of kernel +// data memory that is not subject to the NX protection. +// Or use some lower level trick, like using an assembler to assemble +// a small function for this. +// + +#ifdef _X86_ +/*RDTSC timestamps */ +/* callers must be at IRQL=PASSIVE_LEVEL*/ +__inline VOID TimeSynchronizeRDTSC(struct time_conv *data) +{ + struct timeval tmp; + LARGE_INTEGER system_time; + ULONGLONG curr_ticks; + KIRQL old; + LARGE_INTEGER start_kqpc,stop_kqpc,start_freq,stop_freq; + ULONGLONG start_ticks,stop_ticks; + ULONGLONG delta,delta2; + KEVENT event; + LARGE_INTEGER i; + ULONGLONG reference; + + if (data->reference!=0) + return; + + KeInitializeEvent(&event,NotificationEvent,FALSE); + + i.QuadPart=-3500000; + + KeRaiseIrql(HIGH_LEVEL,&old); + start_kqpc=KeQueryPerformanceCounter(&start_freq); + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, start_ticks + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } + + KeLowerIrql(old); + + KeWaitForSingleObject(&event,UserRequest,KernelMode,TRUE ,&i); + + KeRaiseIrql(HIGH_LEVEL,&old); + stop_kqpc=KeQueryPerformanceCounter(&stop_freq); + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, stop_ticks + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } + KeLowerIrql(old); + + delta=stop_ticks-start_ticks; + delta2=stop_kqpc.QuadPart-start_kqpc.QuadPart; + if (delta>10000000000) + { + delta/=16; + delta2/=16; + } + + reference=delta*(start_freq.QuadPart)/delta2; + + data->reference=reference/1000; + + if (reference%1000>500) + data->reference++; + + data->reference*=1000; + + reference=data->reference; + + KeQuerySystemTime(&system_time); + + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, curr_ticks + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } + + tmp.tv_sec=-(LONG)(curr_ticks/reference); + + tmp.tv_usec=-(LONG)((curr_ticks%reference)*1000000/reference); + + system_time.QuadPart-=116444736000000000; + + tmp.tv_sec+=(LONG)(system_time.QuadPart/10000000); + tmp.tv_usec+=(LONG)((system_time.QuadPart%10000000)/10); + + if (tmp.tv_usec<0) + { + tmp.tv_sec--; + tmp.tv_usec+=1000000; + } + + data->start[0] = tmp; + + IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data->reference);) +} +#endif //_X86_ + +#pragma optimize ("g",on) //Due to some weird behaviour of the optimizer of DDK build 2600 + +__inline VOID TIME_SYNCHRONIZE(struct time_conv *data) +{ + ULONG NumberOfCpus, i; + KAFFINITY AffinityMask; + + if (data->reference != 0) + return; + + NumberOfCpus = NdisSystemProcessorCount(); + + if ( TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_WITH_FIXUP || TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_NO_FIXUP) + { + for (i = 0 ; i < NumberOfCpus ; i++ ) + { + AffinityMask = (1 << i); + ZwSetInformationThread(NtCurrentThread(), ThreadAffinityMask, &AffinityMask, sizeof(KAFFINITY)); + SynchronizeOnCpu(&(data->start[i])); + } + AffinityMask = 0xFFFFFFFF; + ZwSetInformationThread(NtCurrentThread(), ThreadAffinityMask, &AffinityMask, sizeof(KAFFINITY)); + data->reference = 1; + } + else + if ( TimestampMode == TIMESTAMPMODE_QUERYSYSTEMTIME ) + { + //do nothing + data->reference = 1; + } + else +// +// This timestamp mode is supported on x86 (32 bit) only +// +#ifdef _X86_ + if ( TimestampMode == TIMESTAMPMODE_RDTSC ) + { + TimeSynchronizeRDTSC(data); + } + else +#endif // _X86_ + { //it should be only the normal case i.e. TIMESTAMPMODE_SINGLESYNCHRONIZATION + SynchronizeOnCpu(data->start); + data->reference = 1; + } + return; +} + + +#pragma optimize ("g",off) //Due to some weird behaviour of the optimizer of DDK build 2600 + +__inline void GetTimeKQPC(struct timeval *dst, struct time_conv *data) +{ + LARGE_INTEGER PTime, TimeFreq; + LONG tmp; + ULONG CurrentCpu; + static struct timeval old_ts={0,0}; + + + PTime = KeQueryPerformanceCounter(&TimeFreq); + tmp = (LONG)(PTime.QuadPart/TimeFreq.QuadPart); + + if (TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_WITH_FIXUP || TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_NO_FIXUP) + { + //actually this code is ok only if we are guaranteed that no thread scheduling will take place. + CurrentCpu = KeGetCurrentProcessorNumber(); + + dst->tv_sec = data->start[CurrentCpu].tv_sec + tmp; + dst->tv_usec = data->start[CurrentCpu].tv_usec + (LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); + + if (dst->tv_usec >= 1000000) + { + dst->tv_sec ++; + dst->tv_usec -= 1000000; + } + + if (TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_WITH_FIXUP) + { + if (old_ts.tv_sec > dst->tv_sec || (old_ts.tv_sec == dst->tv_sec && old_ts.tv_usec > dst->tv_usec) ) + *dst = old_ts; + + else + old_ts = *dst; + } + } + else + { //it should be only the normal case i.e. TIMESTAMPMODE_SINGLESYNCHRONIZATION + dst->tv_sec = data->start[0].tv_sec + tmp; + dst->tv_usec = data->start[0].tv_usec + (LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); + + if (dst->tv_usec >= 1000000) + { + dst->tv_sec ++; + dst->tv_usec -= 1000000; + } + } +} + +// +// inline assembler is not supported with the current AMD64 compilers +// At the moment we simply disable this timestamping mode on AMD64. +// A solution would be to allocate a small memory from the non-paged +// pool, dump the instructions on that buffer, and then execute them. +// The non paged pool is needed since it's the only area of kernel +// data memory that is not subject to the NX protection. +// Or use some lower level trick, like using an assembler to assemble +// a small function for this. +// + +#ifdef _X86_ +__inline void GetTimeRDTSC(struct timeval *dst, struct time_conv *data) +{ + + ULONGLONG tmp = 0; + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, tmp + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } + + if (data->reference==0) + { + return; + } + dst->tv_sec=(LONG)(tmp/data->reference); + + dst->tv_usec=(LONG)((tmp-dst->tv_sec*data->reference)*1000000/data->reference); + + dst->tv_sec+=data->start[0].tv_sec; + + dst->tv_usec+=data->start[0].tv_usec; + + if (dst->tv_usec>=1000000) + { + dst->tv_sec++; + dst->tv_usec-=1000000; + } + + +} +#endif //_X86_ + +__inline void GetTimeQST(struct timeval *dst, struct time_conv *data) +{ + LARGE_INTEGER SystemTime; + + KeQuerySystemTime(&SystemTime); + + dst->tv_sec = (LONG)(SystemTime.QuadPart/10000000-11644473600); + dst->tv_usec = (LONG)((SystemTime.QuadPart%10000000)/10); + +} + +#pragma optimize ("g",on) //Due to some weird behaviour of the optimizer of DDK build 2600 + + +__inline void GET_TIME(struct timeval *dst, struct time_conv *data) +{ + +// +// This timestamp mode is supported on x86 (32 bit) only +// +#ifdef _X86_ + if ( TimestampMode == TIMESTAMPMODE_RDTSC ) + { + GetTimeRDTSC(dst,data); + } + else +#endif // _X86_ + if ( TimestampMode == TIMESTAMPMODE_QUERYSYSTEMTIME ) + { + GetTimeQST(dst,data); + } + else + { + GetTimeKQPC(dst,data); + } +} + + +#else /*WIN_NT_DRIVER*/ + +__inline void FORCE_TIME(struct timeval *src, struct time_conv *dest) +{ + dest->start[0]=*src; +} + +__inline void GET_TIME(struct timeval *dst, struct time_conv *data) +{ + *dst=data->start[0]; +} + +#endif /*WIN_NT_DRIVER*/ + + +#endif /*_time_calls*/ diff --git a/winpcap/packetNtx/driver/tme.c b/winpcap/packetNtx/driver/tme.c new file mode 100644 index 0000000..cb14423 --- /dev/null +++ b/winpcap/packetNtx/driver/tme.c @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2001 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "tme.h" + +#ifndef UNUSED +#define UNUSED(_x) (_x) +#endif + +/* resizes extended memory */ +uint32 init_extended_memory(uint32 size, MEM_TYPE *mem_ex) +{ + uint8 *tmp; + + if ((mem_ex==NULL)||(mem_ex->buffer==NULL)||(size==0)) + return TME_ERROR; /* awfully never reached!!!! */ + + tmp=mem_ex->buffer; + mem_ex->buffer=NULL; + FREE_MEMORY(tmp); + + ALLOCATE_MEMORY(tmp,uint8,size); + if (tmp==NULL) + return TME_ERROR; /* no memory */ + + mem_ex->size=size; + mem_ex->buffer=tmp; + return TME_SUCCESS; + +} + +/* activates a block of the TME */ +uint32 set_active_tme_block(TME_CORE *tme, uint32 block) +{ + + if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block))) + return TME_ERROR; + tme->active=block; + tme->working=block; + return TME_SUCCESS; + +} + +/* simply inserts default values in a TME block */ +/* it DOESN'T initialize the block in the core!! */ +/* FIXME default values are defined at compile time, */ +/* it will be useful to store them in the registry */ +uint32 init_tme_block(TME_CORE *tme, uint32 block) +{ + + TME_DATA *data; + if (block>=MAX_TME_DATA_BLOCKS) + return TME_ERROR; + data=&(tme->block_data[block]); + tme->working=block; + + ZERO_MEMORY(data,sizeof(TME_DATA)); + + /* entries in LUT */ + data->lut_entries=TME_LUT_ENTRIES_DEFAULT; + /* blocks */ + data->shared_memory_blocks=TME_SHARED_MEMORY_BLOCKS_DEFAULT; + /* block size */ + data->block_size=TME_BLOCK_SIZE_DEFAULT; + /* lookup function */ + data->lookup_code=lut_fcn_mapper(TME_LOOKUP_CODE_DEFAULT); + /* rehashing value */ + data->rehashing_value=TME_REHASHING_VALUE_DEFAULT; + /* out lut function */ + data->out_lut_exec=TME_OUT_LUT_EXEC_DEFAULT; + /* default function */ + data->default_exec=TME_DEFAULT_EXEC_DEFAULT; + /* extra segment size */ + data->extra_segment_size=TME_EXTRA_SEGMENT_SIZE_DEFAULT; + + + data->enable_deletion=FALSE; + data->last_read.tv_sec=0; + data->last_read.tv_usec=0; + return TME_SUCCESS; + +} +/* it validates a TME block and */ +/* (on OK) inserts the block in the core */ +uint32 validate_tme_block(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 block, uint32 mem_ex_offset) +{ + uint32 required_memory; + uint8 *base=mem_ex_offset+mem_ex->buffer; + TME_DATA *data; + + /* FIXME soluzione un po' posticcia... */ + if (mem_ex_offset==0) + return TME_ERROR; + + if (block>=MAX_TME_DATA_BLOCKS) + return TME_ERROR; + data=&tme->block_data[block]; + + if (data->lut_entries==0) + return TME_ERROR; + + if (data->key_len==0) + return TME_ERROR; + + if (data->shared_memory_blocks==0) + return TME_ERROR; + + if (data->block_size==0) + return TME_ERROR; + + /* checks if the lookup function is valid */ + if (data->lookup_code==NULL) + return TME_ERROR; + + /* checks if the out lut exec function is valid */ + if (exec_fcn_mapper(data->out_lut_exec)==NULL) + return TME_ERROR; + + /* checks if the default exec function is valid */ + if (exec_fcn_mapper(data->default_exec)==NULL) + return TME_ERROR; + + /* let's calculate memory needed */ + required_memory=data->lut_entries*sizeof(RECORD); /*LUT*/ + required_memory+=data->block_size*data->shared_memory_blocks; /*shared segment*/ + required_memory+=data->extra_segment_size; /*extra segment*/ + + if (required_memory>(mem_ex->size-mem_ex_offset)) + return TME_ERROR; /*not enough memory*/ + + /* the TME block can be initialized */ + ZERO_MEMORY(base,required_memory); + + data->lut_base_address=base; + + data->shared_memory_base_address= + data->lut_base_address+ + data->lut_entries*sizeof(RECORD); + + data->extra_segment_base_address= + data->shared_memory_base_address+ + data->block_size*data->shared_memory_blocks; + data->filled_blocks=1; + VALIDATE(tme->validated_blocks,block); + tme->active=block; + tme->working=block; + return TME_SUCCESS; +} + +/* I/F between the bpf machine and the callbacks, just some checks */ +uint32 lookup_frontend(MEM_TYPE *mem_ex, TME_CORE *tme,uint32 mem_ex_offset, struct time_conv *time_ref) +{ + if (tme->active==TME_NONE_ACTIVE) + return TME_FALSE; + + return (tme->block_data[tme->active].lookup_code)(mem_ex_offset+mem_ex->buffer,&tme->block_data[tme->active],mem_ex, time_ref); +} + +/* I/F between the bpf machine and the callbacks, just some checks */ +uint32 execute_frontend(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 pkt_size, uint32 offset) +{ + + exec_fcn tmp; + TME_DATA *data; + uint8 *block; + uint8 *mem_data; + + if (tme->active==TME_NONE_ACTIVE) + return TME_ERROR; + + data=&tme->block_data[tme->active]; + + if (data->last_found==NULL) + { /*out lut exec */ + tmp=exec_fcn_mapper(data->out_lut_exec); + block=data->shared_memory_base_address; + } + else + { /*checks if last_found is valid */ + if ((data->last_foundlut_base_address)||(data->last_found>=data->shared_memory_base_address)) + return TME_ERROR; + else + { + tmp=exec_fcn_mapper(SW_ULONG_AT(&((RECORD*)data->last_found)->exec_fcn,0)); + if (tmp==NULL) + return TME_ERROR; + block=SW_ULONG_AT(&((RECORD*)data->last_found)->block,0)+mem_ex->buffer; + if ((blockshared_memory_base_address)||(block>=data->extra_segment_base_address)) + return TME_ERROR; + } + } + + if (offset>=mem_ex->size) + return TME_ERROR; + + mem_data=mem_ex->buffer+offset; + + return tmp(block,pkt_size,data,mem_ex,mem_data); +} + +/*resets all the TME core*/ +uint32 reset_tme(TME_CORE *tme) +{ + if (tme==NULL) + return TME_ERROR; + ZERO_MEMORY(tme, sizeof(TME_CORE)); + return TME_SUCCESS; +} + +/* returns a register value of the active TME block */ +/* FIXME last found in maniera elegante e veloce ?!?! */ +uint32 get_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 *rval) +{ + switch(rgstr) + { + case TME_LUT_ENTRIES: + *rval=data->lut_entries; + return TME_SUCCESS; + case TME_MAX_FILL_STATE: + *rval=data->max_fill_state; + return TME_SUCCESS; + case TME_REHASHING_VALUE: + *rval=data->rehashing_value; + return TME_SUCCESS; + case TME_KEY_LEN: + *rval=data->key_len; + return TME_SUCCESS; + case TME_SHARED_MEMORY_BLOCKS: + *rval=data->shared_memory_blocks; + return TME_SUCCESS; + case TME_FILLED_ENTRIES: + *rval=data->filled_entries; + return TME_SUCCESS; + case TME_BLOCK_SIZE: + *rval=data->block_size; + return TME_SUCCESS; + case TME_EXTRA_SEGMENT_SIZE: + *rval=data->extra_segment_size; + return TME_SUCCESS; + case TME_FILLED_BLOCKS: + *rval=data->filled_blocks; + return TME_SUCCESS; + case TME_DEFAULT_EXEC: + *rval=data->default_exec; + return TME_SUCCESS; + case TME_OUT_LUT_EXEC: + *rval=data->out_lut_exec; + return TME_SUCCESS; + case TME_SHARED_MEMORY_BASE_ADDRESS: + *rval=data->shared_memory_base_address-mem_ex->buffer; + return TME_SUCCESS; + case TME_LUT_BASE_ADDRESS: + *rval=data->lut_base_address-mem_ex->buffer; + return TME_SUCCESS; + case TME_EXTRA_SEGMENT_BASE_ADDRESS: + *rval=data->extra_segment_base_address-mem_ex->buffer; + return TME_SUCCESS; + case TME_LAST_FOUND_BLOCK: + if (data->last_found==NULL) + *rval=0; + else + *rval=data->last_found-mem_ex->buffer; + return TME_SUCCESS; + + default: + return TME_ERROR; + } +} + +/* sets a register value in the active block */ +/* FIXME last found in maniera elegante e veloce ?!?! */ +uint32 set_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 value, int32 init) +{ /* very very very dangerous!!!!!!!!!!! */ + lut_fcn tmp; + + UNUSED(mem_ex); + + switch(rgstr) + { + case TME_MAX_FILL_STATE: + data->max_fill_state=value; + return TME_SUCCESS; + case TME_REHASHING_VALUE: + data->rehashing_value=value; + return TME_SUCCESS; + case TME_FILLED_ENTRIES: + data->filled_entries=value; + return TME_SUCCESS; + case TME_FILLED_BLOCKS: + if (value<=data->shared_memory_blocks) + { + data->filled_blocks=value; + return TME_SUCCESS; + } + else + return TME_ERROR; + case TME_DEFAULT_EXEC: + data->default_exec=value; + return TME_SUCCESS; + case TME_OUT_LUT_EXEC: + data->out_lut_exec=value; + return TME_SUCCESS; + case TME_LOOKUP_CODE: + tmp=lut_fcn_mapper(value); + if (tmp==NULL) + return TME_ERROR; + else + data->lookup_code=tmp; + return TME_SUCCESS; + default: + break; + } + + if (init) + switch (rgstr) + { + + case TME_LUT_ENTRIES: + data->lut_entries=value; + return TME_SUCCESS; + case TME_KEY_LEN: + data->key_len=value; + return TME_SUCCESS; + case TME_SHARED_MEMORY_BLOCKS: + data->shared_memory_blocks=value; + return TME_SUCCESS; + case TME_BLOCK_SIZE: + data->block_size=value; + return TME_SUCCESS; + case TME_EXTRA_SEGMENT_SIZE: + data->extra_segment_size=value; + return TME_SUCCESS; + default: + return TME_ERROR; + } + else + return TME_ERROR; + +} + +/* chooses the TME block for read */ +uint32 set_active_read_tme_block(TME_CORE *tme, uint32 block) +{ + + if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block))) + return TME_ERROR; + tme->active_read=block; + return TME_SUCCESS; + +} + +/* chooses if the autodeletion must be used */ +uint32 set_autodeletion(TME_DATA *data, uint32 value) +{ + if (value==0) /* no autodeletion */ + data->enable_deletion=FALSE; + else + data->enable_deletion=TRUE; + + return TME_SUCCESS; +} \ No newline at end of file diff --git a/winpcap/packetNtx/driver/tme.h b/winpcap/packetNtx/driver/tme.h new file mode 100644 index 0000000..446903c --- /dev/null +++ b/winpcap/packetNtx/driver/tme.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2001 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __tme_include_ +#define __tme_include_ + +#ifdef WIN_NT_DRIVER +#include "ndis.h" +#else +#include +#endif /*WIN_NT_DRIVER*/ + +#include "memory_t.h" +#include "time_calls.h" + + +/* error codes */ +#define TME_ERROR 0 +#define TME_SUCCESS 1 +#define TME_TRUE 2 +#define TME_FALSE 3 + +/* some constants */ +#define DEFAULT_MEM_EX_SIZE 65536 +#define MAX_TME_DATA_BLOCKS 4 +#define TME_NONE_ACTIVE 0xffffffff +#define DELTA_READ 2 /* secs */ + +#define TME_LUT_ENTRIES 0x00000000 +#define TME_MAX_FILL_STATE 0x00000001 /*potrebbe servire per un thread a passive level!?!?! */ +#define TME_REHASHING_VALUE 0x00000002 +#define TME_KEY_LEN 0x00000003 +#define TME_SHARED_MEMORY_BLOCKS 0x00000004 +#define TME_FILLED_ENTRIES 0x00000005 +#define TME_BLOCK_SIZE 0x00000006 +#define TME_EXTRA_SEGMENT_SIZE 0x00000007 +#define TME_LOOKUP_CODE 0x00000008 +#define TME_OUT_LUT_EXEC 0x00000009 +#define TME_FILLED_BLOCKS 0x0000000a +#define TME_DEFAULT_EXEC 0x0000000b +#define TME_LUT_BASE_ADDRESS 0x0000000c +#define TME_SHARED_MEMORY_BASE_ADDRESS 0x0000000d +#define TME_EXTRA_SEGMENT_BASE_ADDRESS 0x0000000e +#define TME_LAST_FOUND 0x0000000f /* contains the offset of the last found entry */ +#define TME_LAST_FOUND_BLOCK 0x00000010 +/* TME default values */ +#define TME_LUT_ENTRIES_DEFAULT 32007 +#define TME_REHASHING_VALUE_DEFAULT 1 +#define TME_SHARED_MEMORY_BLOCKS_DEFAULT 16000 +#define TME_BLOCK_SIZE_DEFAULT 64 +#define TME_EXTRA_SEGMENT_SIZE_DEFAULT 0 +#define TME_LOOKUP_CODE_DEFAULT 0 +#define TME_OUT_LUT_EXEC_DEFAULT 0 +#define TME_DEFAULT_EXEC_DEFAULT 0 +#define TME_MAX_FILL_STATE_DEFAULT 15000 + +#define IS_VALIDATED(src,index) (src&(1<tv_sec=0x7fffffff; + +struct __TME_DATA; + +/* TME callback prototypes */ +typedef uint32 (*lut_fcn)(uint8 *key, struct __TME_DATA *data,MEM_TYPE *mem_ex, struct time_conv *time_ref ); +typedef uint32 (*exec_fcn)(uint8 *block, uint32 pkt_size, struct __TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data); + +/* DO NOT MODIFY THIS STRUCTURE!!!! GV */ +typedef struct __RECORD + +{ + uint32 block; + uint32 exec_fcn; +} + RECORD, *PRECORD; + +/* TME data registers */ +struct __TME_DATA +{ + uint32 lut_entries; + uint32 max_fill_state; + uint32 rehashing_value; + uint32 key_len; + uint32 shared_memory_blocks; + uint32 filled_entries; + uint32 block_size; + uint32 extra_segment_size; + uint32 filled_blocks; + lut_fcn lookup_code; + uint32 default_exec; + uint32 out_lut_exec; + uint8 *lut_base_address; + uint8 *shared_memory_base_address; + uint8 *extra_segment_base_address; + struct timeval last_read; + uint32 enable_deletion; + uint8 *last_found; +}; + +typedef struct __TME_DATA TME_DATA,*PTME_DATA; + + + +/* TME core */ +typedef struct __TME_CORE +{ + uint32 working; + uint32 active; + uint32 validated_blocks; + TME_DATA block_data[MAX_TME_DATA_BLOCKS]; + uint32 active_read; + +} TME_CORE, *PTME_CORE; + +static __inline int32 IS_DELETABLE(void *timestamp, TME_DATA *data) +{ + struct timeval *ts=(struct timeval*)timestamp; + + if (data->enable_deletion==FALSE) + return FALSE; + if (data->filled_entriesmax_fill_state) + return FALSE; + if ((ts->tv_sec+DELTA_READ)last_read.tv_sec) + return TRUE; + return FALSE; +} + +/* functions to manage TME */ +uint32 init_tme_block(TME_CORE *tme, uint32 block); +uint32 validate_tme_block(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 block, uint32 mem_ex_offset); +uint32 lookup_frontend(MEM_TYPE *mem_ex, TME_CORE *tme,uint32 mem_ex_offset, struct time_conv *time_ref); +uint32 execute_frontend(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 pkt_size,uint32 offset); +uint32 set_active_tme_block(TME_CORE *tme, uint32 block); +uint32 init_extended_memory(uint32 size, MEM_TYPE *mem_ex); +uint32 reset_tme(TME_CORE *tme); +uint32 get_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 *rval); +uint32 set_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 value, int32 init); +uint32 set_active_read_tme_block(TME_CORE *tme, uint32 block); +uint32 set_autodeletion(TME_DATA *data, uint32 value); + +/* function mappers */ +lut_fcn lut_fcn_mapper(uint32 index); +exec_fcn exec_fcn_mapper(uint32 index); + +#endif \ No newline at end of file diff --git a/winpcap/packetNtx/driver/valid_insns.h b/winpcap/packetNtx/driver/valid_insns.h new file mode 100644 index 0000000..83437a4 --- /dev/null +++ b/winpcap/packetNtx/driver/valid_insns.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2001 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +u_short valid_instructions[]= + { + BPF_RET|BPF_K, + BPF_RET|BPF_A, + BPF_LD|BPF_IMM, + BPF_LDX|BPF_IMM, + BPF_LD|BPF_MEM, + BPF_LDX|BPF_MEM, + +#ifdef HAVE_BUGGY_TME_SUPPORT + BPF_LD|BPF_MEM_EX_IMM|BPF_B, + BPF_LD|BPF_MEM_EX_IMM|BPF_H, + BPF_LD|BPF_MEM_EX_IMM|BPF_W, + BPF_LD|BPF_MEM_EX_IND|BPF_B, + BPF_LD|BPF_MEM_EX_IND|BPF_H, + BPF_LD|BPF_MEM_EX_IND|BPF_W, +#endif //HAVE_BUGGY_TME_SUPPORT + BPF_LD|BPF_W|BPF_ABS, + BPF_LD|BPF_H|BPF_ABS, + BPF_LD|BPF_B|BPF_ABS, + BPF_LDX|BPF_W|BPF_ABS, + BPF_LDX|BPF_H|BPF_ABS, + BPF_LDX|BPF_B|BPF_ABS, + BPF_LD|BPF_W|BPF_LEN, + BPF_LDX|BPF_W|BPF_LEN, + BPF_LD|BPF_W|BPF_IND, + BPF_LD|BPF_H|BPF_IND, + BPF_LD|BPF_B|BPF_IND, + BPF_LDX|BPF_MSH|BPF_B, + BPF_ST, + BPF_STX, + +#ifdef HAVE_BUGGY_TME_SUPPORT + BPF_ST|BPF_MEM_EX_IMM|BPF_B, + BPF_STX|BPF_MEM_EX_IMM|BPF_B, + BPF_ST|BPF_MEM_EX_IMM|BPF_W, + BPF_STX|BPF_MEM_EX_IMM|BPF_W, + BPF_ST|BPF_MEM_EX_IMM|BPF_H, + BPF_STX|BPF_MEM_EX_IMM|BPF_H, + BPF_ST|BPF_MEM_EX_IND|BPF_B, + BPF_ST|BPF_MEM_EX_IND|BPF_W, + BPF_ST|BPF_MEM_EX_IND|BPF_H, +#endif // HAVE_BUGGY_TME_SUPPORT + + BPF_JMP|BPF_JA, + BPF_JMP|BPF_JGT|BPF_K, + BPF_JMP|BPF_JGE|BPF_K, + BPF_JMP|BPF_JEQ|BPF_K, + BPF_JMP|BPF_JSET|BPF_K, + BPF_JMP|BPF_JGT|BPF_X, + BPF_JMP|BPF_JGE|BPF_X, + BPF_JMP|BPF_JEQ|BPF_X, + BPF_JMP|BPF_JSET|BPF_X, + BPF_ALU|BPF_ADD|BPF_X, + BPF_ALU|BPF_SUB|BPF_X, + BPF_ALU|BPF_MUL|BPF_X, + BPF_ALU|BPF_DIV|BPF_X, + BPF_ALU|BPF_AND|BPF_X, + BPF_ALU|BPF_OR|BPF_X, + BPF_ALU|BPF_LSH|BPF_X, + BPF_ALU|BPF_RSH|BPF_X, + BPF_ALU|BPF_ADD|BPF_K, + BPF_ALU|BPF_SUB|BPF_K, + BPF_ALU|BPF_MUL|BPF_K, + BPF_ALU|BPF_DIV|BPF_K, + BPF_ALU|BPF_AND|BPF_K, + BPF_ALU|BPF_OR|BPF_K, + BPF_ALU|BPF_LSH|BPF_K, + BPF_ALU|BPF_RSH|BPF_K, + BPF_ALU|BPF_NEG, + BPF_MISC|BPF_TAX, + BPF_MISC|BPF_TXA, + +#ifdef HAVE_BUGGY_TME_SUPPORT + BPF_MISC|BPF_TME|BPF_LOOKUP, + BPF_MISC|BPF_TME|BPF_EXECUTE, + BPF_MISC|BPF_TME|BPF_SET_ACTIVE, + BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE, + BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE +#endif //HAVE_BUGGY_TME_SUPPORT + + }; + +#define VALID_INSTRUCTIONS_LEN (sizeof(valid_instructions)/sizeof(u_short)) diff --git a/winpcap/packetNtx/driver/win_bpf.h b/winpcap/packetNtx/driver/win_bpf.h new file mode 100644 index 0000000..4d4f586 --- /dev/null +++ b/winpcap/packetNtx/driver/win_bpf.h @@ -0,0 +1,417 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)bpf.h 7.1 (Berkeley) 5/7/91 + * + * @(#) $Header: /usr/cvsroot_private/winpcap/packetNtx/driver/win_bpf.h,v 1.3 2005/12/02 22:41:52 gianlucav Exp $ (LBL) + */ + +#ifndef BPF_MAJOR_VERSION + +/* BSD style release date */ +#define BPF_RELEASE 199606 + +#ifdef WIN_NT_DRIVER +#include +#endif + + +#include "tme.h" +#include "time_calls.h" + +typedef UCHAR u_char; +typedef USHORT u_short; + +#ifdef WIN_NT_DRIVER +typedef ULONG u_int; +#endif + +typedef LONG bpf_int32; +typedef ULONG bpf_u_int32; +typedef ULONG u_int32; + +#define BPF_MAXINSNS 512 +#define BPF_MAXBUFSIZE 0x8000 +#define BPF_MINBUFSIZE 32 + +/* + * The instruction data structure. + */ +struct bpf_insn { + u_short code; + u_char jt; + u_char jf; + bpf_u_int32 k; +}; + +/* + * Structure for BIOCSETF. + */ +struct bpf_program { + u_int bf_len; + struct bpf_insn *bf_insns; +}; + +/* + * Struct returned by BIOCGSTATS. + */ +struct bpf_stat { + UINT bs_recv; ///< Number of packets that the driver received from the network adapter + ///< from the beginning of the current capture. This value includes the packets + ///< lost by the driver. + UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture. + ///< Basically, a packet is lost when the the buffer of the driver is full. + ///< In this situation the packet cannot be stored and the driver rejects it. + UINT ps_ifdrop; ///< drops by interface. XXX not yet supported + UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and + ///< thus reach the application. +}; + +/* + * Struct return by BIOCVERSION. This represents the version number of + * the filter language described by the instruction encodings below. + * bpf understands a program iff kernel_major == filter_major && + * kernel_minor >= filter_minor, that is, if the value returned by the + * running kernel has the same major number and a minor number equal + * equal to or less than the filter being downloaded. Otherwise, the + * results are undefined, meaning an error may be returned or packets + * may be accepted haphazardly. + * It has nothing to do with the source code version. + */ +struct bpf_version { + u_short bv_major; + u_short bv_minor; +}; +/* Current version number of filter architecture. */ +#define BPF_MAJOR_VERSION 1 +#define BPF_MINOR_VERSION 1 + + +/* + * Structure prepended to each packet. + */ +struct bpf_hdr { + struct timeval bh_tstamp; /* time stamp */ + bpf_u_int32 bh_caplen; /* length of captured portion */ + bpf_u_int32 bh_datalen; /* original length of packet */ + u_short bh_hdrlen; /* length of bpf header (this struct + plus alignment padding) */ +}; + +/* + * Data-link level type codes. + */ + +/* + * These are the types that are the same on all platforms; on other + * platforms, a should be supplied that defines the additional + * DLT_* codes appropriately for that platform (the BSDs, for example, + * should not just pick up this version of "bpf.h"; they should also define + * the additional DLT_* codes used by their kernels, as well as the values + * defined here - and, if the values they use for particular DLT_ types + * differ from those here, they should use their values, not the ones + * here). + */ +#define DLT_NULL 0 /* no link-layer encapsulation */ +#define DLT_EN10MB 1 /* Ethernet (10Mb) */ +#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ +#define DLT_AX25 3 /* Amateur Radio AX.25 */ +#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ +#define DLT_CHAOS 5 /* Chaos */ +#define DLT_IEEE802 6 /* IEEE 802 Networks */ +#define DLT_ARCNET 7 /* ARCNET */ +#define DLT_SLIP 8 /* Serial Line IP */ +#define DLT_PPP 9 /* Point-to-point Protocol */ +#define DLT_FDDI 10 /* FDDI */ + +/* + * These are values from the traditional libpcap "bpf.h". + * Ports of this to particular platforms should replace these definitions + * with the ones appropriate to that platform, if the values are + * different on that platform. + */ +#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ +#define DLT_RAW 12 /* raw IP */ + +/* + * These are values from BSD/OS's "bpf.h". + * These are not the same as the values from the traditional libpcap + * "bpf.h"; however, these values shouldn't be generated by any + * OS other than BSD/OS, so the correct values to use here are the + * BSD/OS values. + * + * Platforms that have already assigned these values to other + * DLT_ codes, however, should give these codes the values + * from that platform, so that programs that use these codes will + * continue to compile - even though they won't correctly read + * files of these types. + */ +#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ + +#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + +/* + * This value is defined by NetBSD; other platforms should refrain from + * using it for other purposes, so that NetBSD savefiles with a link + * type of 50 can be read as this type on all platforms. + */ +#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ + +/* + * This value was defined by libpcap 0.5; platforms that have defined + * it with a different value should define it here with that value - + * a link type of 104 in a save file will be mapped to DLT_C_HDLC, + * whatever value that happens to be, so programs will correctly + * handle files with that link type regardless of the value of + * DLT_C_HDLC. + * + * The name DLT_C_HDLC was used by BSD/OS; we use that name for source + * compatibility with programs written for BSD/OS. + * + * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, + * for source compatibility with programs written for libpcap 0.5. + */ +#define DLT_C_HDLC 104 /* Cisco HDLC */ +#define DLT_CHDLC DLT_C_HDLC + +/* + * Reserved for future use. + * Do not pick other numerical value for these unless you have also + * picked up the tcpdump.org top-of-CVS-tree version of "savefile.c", + * which will arrange that capture files for these DLT_ types have + * the same "network" value on all platforms, regardless of what + * value is chosen for their DLT_ type (thus allowing captures made + * on one platform to be read on other platforms, even if the two + * platforms don't use the same numerical values for all DLT_ types). + */ +#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + +/* + * Values between 106 and 107 are used in capture file headers as + * link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ new types. + */ + +/* + * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except + * that the AF_ type in the link-layer header is in network byte order. + * + * OpenBSD defines it as 12, but that collides with DLT_RAW, so we + * define it as 108 here. If OpenBSD picks up this file, it should + * define DLT_LOOP as 12 in its version, as per the comment above - + * and should not use 108 for any purpose. + */ +#define DLT_LOOP 108 + +/* + * Values between 109 and 112 are used in capture file headers as + * link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ new types. + */ + +/* + * This is for Linux cooked sockets. + */ +#define DLT_LINUX_SLL 113 + +/* + * The instruction encodings. + */ +/* instruction classes */ +#define BPF_CLASS(code) ((code) & 0x07) +#define BPF_LD 0x00 +#define BPF_LDX 0x01 +#define BPF_ST 0x02 +#define BPF_STX 0x03 +#define BPF_ALU 0x04 +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 + +/* ld/ldx fields */ +#define BPF_SIZE(code) ((code) & 0x18) +#define BPF_W 0x00 +#define BPF_H 0x08 +#define BPF_B 0x10 +#define BPF_MODE(code) ((code) & 0xe0) +#define BPF_IMM 0x00 +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 + +/* alu/jmp fields */ +#define BPF_OP(code) ((code) & 0xf0) +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 +#define BPF_SRC(code) ((code) & 0x08) +#define BPF_K 0x00 +#define BPF_X 0x08 + +/* ret - BPF_K and BPF_X also apply */ +#define BPF_RVAL(code) ((code) & 0x18) +#define BPF_A 0x10 + +/* misc */ +#define BPF_MISCOP(code) ((code) & 0xf8) +#define BPF_TAX 0x00 +#define BPF_TXA 0x80 + +/* TME instructions */ +#define BPF_TME 0x08 + +#define BPF_LOOKUP 0x90 +#define BPF_EXECUTE 0xa0 +#define BPF_INIT 0xb0 +#define BPF_VALIDATE 0xc0 +#define BPF_SET_ACTIVE 0xd0 +#define BPF_RESET 0xe0 +#define BPF_SET_MEMORY 0x80 +#define BPF_GET_REGISTER_VALUE 0x70 +#define BPF_SET_REGISTER_VALUE 0x60 +#define BPF_SET_WORKING 0x50 +#define BPF_SET_ACTIVE_READ 0x40 +#define BPF_SET_AUTODELETION 0x30 +#define BPF_SEPARATION 0xff + +#define BPF_MEM_EX_IMM 0xc0 +#define BPF_MEM_EX_IND 0xe0 +/*used for ST */ +#define BPF_MEM_EX 0xc0 + + +/* + * Macros for insn array initializers. + */ +#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } +#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } + +/* + * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). + */ +#define BPF_MEMWORDS 16 + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! + \brief Validates a filtering program arriving from the user-level app. + \param f The filter. + \param len Its length, in pseudo instructions. + \param mem_ex_size The length of the extended memory, used to validate LD/ST to that memory + \return true if f is a valid filter program.. + + The kernel needs to be able to verify an application's filter code. Otherwise, a bogus program could easily + crash the system. + This function returns true if f is a valid filter program. The constraints are that each jump be forward and + to a valid code. The code must terminate with either an accept or reject. +*/ +int32 bpf_validate(struct bpf_insn *f,int32 len, uint32 mem_ex_size); + +/*! + \brief The filtering pseudo-machine interpreter. + \param pc The filter. + \param p Pointer to a memory buffer containing the packet on which the filter will be executed. + \param wirelen Original length of the packet. + \param buflen Current length of the packet. In some cases (for example when the transfer of the packet to the RAM + has not yet finished), bpf_filter can be executed on a portion of the packet. + \param mem_ex The extended memory. + \param tme The virtualization of the TME co-processor + \param time_ref Data structure needed by the TME co-processor to timestamp data + \return The portion of the packet to keep, in bytes. 0 means that the packet must be rejected, -1 means that + the whole packet must be kept. + + \note this function is not used in normal situations, because the jitter creates a native filtering function + that is faster than the interpreter. +*/ +u_int bpf_filter(register struct bpf_insn *pc, + register UCHAR *p, + u_int wirelen, + register u_int buflen , + PMEM_TYPE mem_ex, + PTME_CORE tme , + struct time_conv *time_ref); + +/*! + \brief The filtering pseudo-machine interpreter with two buffers. This function is slower than bpf_filter(), + but works correctly also if the MAC header and the data of the packet are in two different buffers. + \param pc The filter. + \param p Pointer to a memory buffer containing the MAC header of the packet. + \param pd Pointer to a memory buffer containing the data of the packet. + \param wirelen Original length of the packet. + \param buflen Current length of the packet. In some cases (for example when the transfer of the packet to the RAM + has not yet finished), bpf_filter can be executed on a portion of the packet. + \param mem_ex The extended memory. + \param tme The virtualization of the TME co-processor + \param time_ref Data structure needed by the TME co-processor to timestamp data + \return The portion of the packet to keep, in bytes. 0 means that the packet must be rejected, -1 means that + the whole packet must be kept. + + This function is used when NDIS passes the packet to NPF_tap() in two buffers instaed than in a single one. +*/ +u_int bpf_filter_with_2_buffers(register struct bpf_insn *pc, + register u_char *p, + register u_char *pd, + register int headersize, + u_int wirelen, + register u_int buflen, + PMEM_TYPE mem_ex, + PTME_CORE tme, + struct time_conv *time_ref); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/winpcap/packetNtx/driver/win_bpf_filter.c b/winpcap/packetNtx/driver/win_bpf_filter.c new file mode 100644 index 0000000..3fea608 --- /dev/null +++ b/winpcap/packetNtx/driver/win_bpf_filter.c @@ -0,0 +1,1138 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2007 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef WIN_NT_DRIVER +#include +#else +#include +#endif + +#pragma warning(disable : 4131) //old style function declaration +#pragma warning(disable : 4127) // conditional expr is constant (used for while(1) loops) +#pragma warning(disable : 4213) //cast on l-value + +#ifndef UNUSED +#define UNUSED(_x) (_x) +#endif + +#include "win_bpf.h" + +#include "debug.h" + +#include "valid_insns.h" + +#define EXTRACT_SHORT(p)\ + ((((u_short)(((u_char*)p)[0])) << 8) |\ + (((u_short)(((u_char*)p)[1])) << 0)) + +#define EXTRACT_LONG(p)\ + ((((u_int32)(((u_char*)p)[0])) << 24) |\ + (((u_int32)(((u_char*)p)[1])) << 16) |\ + (((u_int32)(((u_char*)p)[2])) << 8 ) |\ + (((u_int32)(((u_char*)p)[3])) << 0 )) + +u_int bpf_filter(pc, p, wirelen, buflen,mem_ex,tme,time_ref) + register struct bpf_insn *pc; + register u_char *p; + u_int wirelen; + register u_int buflen; + PMEM_TYPE mem_ex; + PTME_CORE tme; + struct time_conv *time_ref; + +{ + register u_int32 A, X; + register int k; + +#ifdef HAVE_BUGGY_TME_SUPPORT + u_int32 j,tmp; + u_short tmp2; +#endif //HAVE_BUGGY_TME_SUPPORT + + int32 mem[BPF_MEMWORDS]; + +#ifndef HAVE_BUGGY_TME_SUPPORT + UNUSED(time_ref); + UNUSED(tme); + UNUSED(mem_ex); +#endif + + RtlZeroMemory(mem, sizeof(mem)); + + if (pc == 0) + /* + * No filter means accept all. + */ + return (u_int)-1; + A = 0; + X = 0; + --pc; + while (1) { + ++pc; + switch (pc->code) { + + default: + + return 0; + + case BPF_RET|BPF_K: + return (u_int)pc->k; + + case BPF_RET|BPF_A: + return (u_int)A; + + case BPF_LD|BPF_W|BPF_ABS: + k = pc->k; + if (k + sizeof(int32) > buflen) { + return 0; + } + A = EXTRACT_LONG(&p[k]); + continue; + + case BPF_LD|BPF_H|BPF_ABS: + k = pc->k; + if (k + sizeof(short) > buflen) { + return 0; + } + A = EXTRACT_SHORT(&p[k]); + continue; + + case BPF_LD|BPF_B|BPF_ABS: + k = pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + A = p[k]; + continue; + + case BPF_LD|BPF_W|BPF_LEN: + A = wirelen; + continue; + + case BPF_LDX|BPF_W|BPF_LEN: + X = wirelen; + continue; + + case BPF_LD|BPF_W|BPF_IND: + k = X + pc->k; + if (k + sizeof(int32) > buflen) { + return 0; + } + A = EXTRACT_LONG(&p[k]); + continue; + + case BPF_LD|BPF_H|BPF_IND: + k = X + pc->k; + if (k + sizeof(short) > buflen) { + return 0; + } + A = EXTRACT_SHORT(&p[k]); + continue; + + case BPF_LD|BPF_B|BPF_IND: + k = X + pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + A = p[k]; + continue; + + case BPF_LDX|BPF_MSH|BPF_B: + k = pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + X = (p[pc->k] & 0xf) << 2; + continue; + + case BPF_LD|BPF_IMM: + A = pc->k; + continue; + + case BPF_LDX|BPF_IMM: + X = pc->k; + continue; + + case BPF_LD|BPF_MEM: + A = mem[pc->k]; + continue; + + case BPF_LDX|BPF_MEM: + X = mem[pc->k]; + continue; + +#ifdef HAVE_BUGGY_TME_SUPPORT + // + // these instructions use the TME extensions, + // not supported on x86-64 and IA64 architectures. + // + + /* LD NO PACKET INSTRUCTIONS */ + + case BPF_LD|BPF_MEM_EX_IMM|BPF_B: + A= mem_ex->buffer[pc->k]; + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_B: + X= mem_ex->buffer[pc->k]; + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_H: + A = EXTRACT_SHORT(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_H: + X = EXTRACT_SHORT(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_W: + A = EXTRACT_LONG(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_W: + X = EXTRACT_LONG(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_B: + k = X + pc->k; + if ((int32)k>= (int32)mem_ex->size) { + return 0; + } + A= mem_ex->buffer[k]; + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_H: + k = X + pc->k; + if ((int32)(k+1)>= (int32)mem_ex->size) { + return 0; + } + A=EXTRACT_SHORT((uint32*)&mem_ex->buffer[k]); + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_W: + k = X + pc->k; + if ((int32)(k+3)>= (int32)mem_ex->size) { + return 0; + } + A=EXTRACT_LONG((uint32*)&mem_ex->buffer[k]); + continue; + /* END LD NO PACKET INSTRUCTIONS */ + +#endif //HAVE_BUGGY_TME_SUPPORT + + case BPF_ST: + mem[pc->k] = A; + continue; + + case BPF_STX: + mem[pc->k] = X; + continue; + +#ifdef HAVE_BUGGY_TME_SUPPORT + // + // these instructions use the TME extensions, + // not supported on x86-64 and IA64 architectures. + // + + /* STORE INSTRUCTIONS */ + + case BPF_ST|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)A; + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)X; + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_W: + tmp=A; + *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp); + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_W: + tmp=X; + *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp); + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16)A; + *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2); + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16)X; + *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2); + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_B: + mem_ex->buffer[pc->k+X]=(uint8)A; + + case BPF_ST|BPF_MEM_EX_IND|BPF_W: + tmp=A; + *(uint32*)&mem_ex->buffer[pc->k+X]=EXTRACT_LONG(&tmp); + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_H: + tmp2=(uint16)A; + *(uint16*)&mem_ex->buffer[pc->k+X]=EXTRACT_SHORT(&tmp2); + continue; + + /* END STORE INSTRUCTIONS */ + +#endif //HAVE_BUGGY_TME_SUPPORT + + case BPF_JMP|BPF_JA: + pc += pc->k; + continue; + + case BPF_JMP|BPF_JGT|BPF_K: + pc += ((int)A > (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_K: + pc += ((int)A >= (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_K: + pc += ((int)A == (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_K: + pc += (A & pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGT|BPF_X: + pc += (A > X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_X: + pc += (A >= X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_X: + pc += (A == X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_X: + pc += (A & X) ? pc->jt : pc->jf; + continue; + + case BPF_ALU|BPF_ADD|BPF_X: + A += X; + continue; + + case BPF_ALU|BPF_SUB|BPF_X: + A -= X; + continue; + + case BPF_ALU|BPF_MUL|BPF_X: + A *= X; + continue; + + case BPF_ALU|BPF_DIV|BPF_X: + if (X == 0) + return 0; + A /= X; + continue; + + case BPF_ALU|BPF_AND|BPF_X: + A &= X; + continue; + + case BPF_ALU|BPF_OR|BPF_X: + A |= X; + continue; + + case BPF_ALU|BPF_LSH|BPF_X: + A <<= X; + continue; + + case BPF_ALU|BPF_RSH|BPF_X: + A >>= X; + continue; + + case BPF_ALU|BPF_ADD|BPF_K: + A += pc->k; + continue; + + case BPF_ALU|BPF_SUB|BPF_K: + A -= pc->k; + continue; + + case BPF_ALU|BPF_MUL|BPF_K: + A *= pc->k; + continue; + + case BPF_ALU|BPF_DIV|BPF_K: + A /= pc->k; + continue; + + case BPF_ALU|BPF_AND|BPF_K: + A &= pc->k; + continue; + + case BPF_ALU|BPF_OR|BPF_K: + A |= pc->k; + continue; + + case BPF_ALU|BPF_LSH|BPF_K: + A <<= pc->k; + continue; + + case BPF_ALU|BPF_RSH|BPF_K: + A >>= pc->k; + continue; + + case BPF_ALU|BPF_NEG: + (int)A = -((int)A); + continue; + + case BPF_MISC|BPF_TAX: + X = A; + continue; + + case BPF_MISC|BPF_TXA: + A = X; + continue; + +#ifdef HAVE_BUGGY_TME_SUPPORT + // + // these instructions use the TME extensions, + // not supported on x86-64 and IA64 architectures. + // + + /* TME INSTRUCTIONS */ + + case BPF_MISC|BPF_TME|BPF_LOOKUP: + j=lookup_frontend(mem_ex,tme,pc->k,time_ref); + if (j==TME_ERROR) + return 0; + pc += (j == TME_TRUE) ? pc->jt : pc->jf; + continue; + + case BPF_MISC|BPF_TME|BPF_EXECUTE: + if (execute_frontend(mem_ex,tme,wirelen,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_ACTIVE: + if (set_active_tme_block(tme,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE: + if (get_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,&j)==TME_ERROR) + return 0; + A=j; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE: + if (set_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,A,FALSE)==TME_ERROR) + return 0; + continue; + + /* END TME INSTRUCTIONS */ +#endif //HAVE_BUGGY_TME_SUPPORT + + + } + } +} + +//------------------------------------------------------------------- + +u_int bpf_filter_with_2_buffers(pc, p, pd, headersize, wirelen, buflen, mem_ex,tme,time_ref) + register struct bpf_insn *pc; + register u_char *p; + register u_char *pd; + register int headersize; + u_int wirelen; + register u_int buflen; + PMEM_TYPE mem_ex; + PTME_CORE tme; + struct time_conv *time_ref; +{ + register u_int32 A, X; + register int k; + int32 mem[BPF_MEMWORDS]; +#ifdef HAVE_BUGGY_TME_SUPPORT + u_int32 j,tmp; + u_short tmp2; +#endif //HAVE_BUGGY_TME_SUPPORT + +#ifndef HAVE_BUGGY_TME_SUPPORT + UNUSED(tme); + UNUSED(time_ref); + UNUSED(mem_ex); +#endif //HAVE_BUGGY_TME_SUPPORT + + RtlZeroMemory(mem, sizeof(mem)); + + if (pc == 0) + /* + * No filter means accept all. + */ + return (u_int)-1; + A = 0; + X = 0; + --pc; + while (1) { + ++pc; + switch (pc->code) { + + default: + + return 0; + + case BPF_RET|BPF_K: + return (u_int)pc->k; + + case BPF_RET|BPF_A: + return (u_int)A; + + case BPF_LD|BPF_W|BPF_ABS: + k = pc->k; + if (k + 4 > (int)buflen) { + return 0; + } + + if(k + 4 <= headersize) + A = EXTRACT_LONG(&p[k]); + else if(k + 3 == headersize) + { + A= (u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)p+k+1)<<16| + (u_int32)*((u_char *)p+k+2)<<8| + (u_int32)*((u_char *)pd+k-headersize); + } + else if(k + 2 == headersize) + { + A= (u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)p+k+1)<<16| + (u_int32)*((u_char *)pd+k-headersize)<<8| + (u_int32)*((u_char *)pd+k-headersize+1); + } + else if(k + 1 == headersize){ + A= (u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)pd+k-headersize+1)<<16| + (u_int32)*((u_char *)pd+k-headersize+2)<<8| + (u_int32)*((u_char *)pd+k-headersize+3); + } + else + A = EXTRACT_LONG(&pd[k-headersize]); + + continue; + + case BPF_LD|BPF_H|BPF_ABS: + k = pc->k; + if (k + sizeof(short) > buflen) + { + return 0; + } + + if(k + 2 <= headersize) + A = EXTRACT_SHORT(&p[k]); + else if(k + 1 == headersize) + { + A= (u_short)*((u_char *)p+k)<<8| + (u_short)*((u_char *)pd+k-headersize); + } + else + A = EXTRACT_SHORT(&pd[k-headersize]); + + continue; + + case BPF_LD|BPF_B|BPF_ABS: + k = pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + + if(k +(int) sizeof(char) <= headersize) + A = p[k]; + else + A = pd[k-headersize]; + + continue; + + case BPF_LD|BPF_W|BPF_LEN: + A = wirelen; + continue; + + case BPF_LDX|BPF_W|BPF_LEN: + X = wirelen; + continue; + + case BPF_LD|BPF_W|BPF_IND: + k = X + pc->k; + if (k + sizeof(int32) > buflen) { + return 0; + } + + if(k + 4 <= headersize) + A = EXTRACT_LONG(&p[k]); + else if(k + 3 == headersize) + { + A= (u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)p+k+1)<<16| + (u_int32)*((u_char *)p+k+2)<<8| + (u_int32)*((u_char *)pd+k-headersize); + } + else if(k + 2 == headersize) + { + A= (u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)p+k+1)<<16| + (u_int32)*((u_char *)pd+k-headersize)<<8| + (u_int32)*((u_char *)pd+k-headersize+1); + } + else if(k + 1 == headersize) + { + A= (u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)pd+k-headersize+1)<<16| + (u_int32)*((u_char *)pd+k-headersize+2)<<8| + (u_int32)*((u_char *)pd+k-headersize+3); + } + else + A = EXTRACT_LONG(&pd[k-headersize]); + + continue; + + case BPF_LD|BPF_H|BPF_IND: + k = X + pc->k; + if (k + 2 > (int)buflen) { + return 0; + } + + if(k + 2 <= headersize) + A = EXTRACT_SHORT(&p[k]); + else if(k +1 == headersize) + { + A= (u_short)*((u_char *)p+k)<<8| + (u_short)*((u_char *)pd+k-headersize); + } + else + A = EXTRACT_SHORT(&pd[k-headersize]); + + continue; + + case BPF_LD|BPF_B|BPF_IND: + k = X + pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + + if(k <= headersize) + A = p[k]; + else + A = pd[k-headersize]; + + continue; + + case BPF_LDX|BPF_MSH|BPF_B: + k = pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + + if((int)(pc->k) <= headersize) + X = (p[pc->k] & 0xf) << 2; + else + X = (pd[(pc->k)-headersize] & 0xf) << 2; + + continue; + + case BPF_LD|BPF_IMM: + A = pc->k; + continue; + + case BPF_LDX|BPF_IMM: + X = pc->k; + continue; + + case BPF_LD|BPF_MEM: + A = mem[pc->k]; + continue; + + case BPF_LDX|BPF_MEM: + X = mem[pc->k]; + continue; + +#ifdef HAVE_BUGGY_TME_SUPPORT + // + // these instructions use the TME extensions, + // not supported on x86-64 and IA64 architectures. + // + + /* LD NO PACKET INSTRUCTIONS */ + + case BPF_LD|BPF_MEM_EX_IMM|BPF_B: + A= mem_ex->buffer[pc->k]; + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_B: + X= mem_ex->buffer[pc->k]; + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_H: + A = EXTRACT_SHORT(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_H: + X = EXTRACT_SHORT(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_W: + A = EXTRACT_LONG(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_W: + X = EXTRACT_LONG(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_B: + k = X + pc->k; + if ((int32)k>= (int32)mem_ex->size) { + return 0; + } + A= mem_ex->buffer[k]; + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_H: + k = X + pc->k; + if ((int32)(k+1)>= (int32)mem_ex->size) { + return 0; + } + A=EXTRACT_SHORT((uint32*)&mem_ex->buffer[k]); + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_W: + k = X + pc->k; + if ((int32)(k+3)>= (int32)mem_ex->size) { + return 0; + } + A=EXTRACT_LONG((uint32*)&mem_ex->buffer[k]); + continue; + + /* END LD NO PACKET INSTRUCTIONS */ + +#endif //HAVE_BUGGY_TME_SUPPORT + + case BPF_ST: + mem[pc->k] = A; + continue; + + case BPF_STX: + mem[pc->k] = X; + continue; + +#ifdef HAVE_BUGGY_TME_SUPPORT + // + // these instructions use the TME extensions, + // not supported on x86-64 and IA64 architectures. + // + + /* STORE INSTRUCTIONS */ + + case BPF_ST|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)A; + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)X; + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_W: + tmp=A; + *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp); + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_W: + tmp=X; + *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp); + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16)A; + *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2); + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16)X; + *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2); + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_B: + mem_ex->buffer[pc->k+X]=(uint8)A; + + case BPF_ST|BPF_MEM_EX_IND|BPF_W: + tmp=A; + *(uint32*)&mem_ex->buffer[pc->k+X]=EXTRACT_LONG(&tmp); + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_H: + tmp2=(uint16)A; + *(uint16*)&mem_ex->buffer[pc->k+X]=EXTRACT_SHORT(&tmp2); + continue; + + /* END STORE INSTRUCTIONS */ + +#endif //HAVE_BUGGY_TME_SUPPORT + + case BPF_JMP|BPF_JA: + pc += pc->k; + continue; + + case BPF_JMP|BPF_JGT|BPF_K: + pc += ((int)A > (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_K: + pc += ((int)A >= (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_K: + pc += ((int)A == (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_K: + pc += (A & pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGT|BPF_X: + pc += (A > X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_X: + pc += (A >= X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_X: + pc += (A == X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_X: + pc += (A & X) ? pc->jt : pc->jf; + continue; + + case BPF_ALU|BPF_ADD|BPF_X: + A += X; + continue; + + case BPF_ALU|BPF_SUB|BPF_X: + A -= X; + continue; + + case BPF_ALU|BPF_MUL|BPF_X: + A *= X; + continue; + + case BPF_ALU|BPF_DIV|BPF_X: + if (X == 0) + return 0; + A /= X; + continue; + + case BPF_ALU|BPF_AND|BPF_X: + A &= X; + continue; + + case BPF_ALU|BPF_OR|BPF_X: + A |= X; + continue; + + case BPF_ALU|BPF_LSH|BPF_X: + A <<= X; + continue; + + case BPF_ALU|BPF_RSH|BPF_X: + A >>= X; + continue; + + case BPF_ALU|BPF_ADD|BPF_K: + A += pc->k; + continue; + + case BPF_ALU|BPF_SUB|BPF_K: + A -= pc->k; + continue; + + case BPF_ALU|BPF_MUL|BPF_K: + A *= pc->k; + continue; + + case BPF_ALU|BPF_DIV|BPF_K: + A /= pc->k; + continue; + + case BPF_ALU|BPF_AND|BPF_K: + A &= pc->k; + continue; + + case BPF_ALU|BPF_OR|BPF_K: + A |= pc->k; + continue; + + case BPF_ALU|BPF_LSH|BPF_K: + A <<= pc->k; + continue; + + case BPF_ALU|BPF_RSH|BPF_K: + A >>= pc->k; + continue; + + case BPF_ALU|BPF_NEG: + (int)A = -((int)A); + continue; + + case BPF_MISC|BPF_TAX: + X = A; + continue; + + case BPF_MISC|BPF_TXA: + A = X; + continue; + +#ifdef HAVE_BUGGY_TME_SUPPORT + // + // these instructions use the TME extensions, + // not supported on x86-64 and IA64 architectures. + // + + /* TME INSTRUCTIONS */ + + case BPF_MISC|BPF_TME|BPF_LOOKUP: + j=lookup_frontend(mem_ex,tme,pc->k,time_ref); + if (j==TME_ERROR) + return 0; + pc += (j == TME_TRUE) ? pc->jt : pc->jf; + continue; + + case BPF_MISC|BPF_TME|BPF_EXECUTE: + if (execute_frontend(mem_ex,tme,wirelen,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_ACTIVE: + if (set_active_tme_block(tme,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE: + if (get_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,&j)==TME_ERROR) + return 0; + A=j; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE: + if (set_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,A,FALSE)==TME_ERROR) + return 0; + continue; + + /* END TME INSTRUCTIONS */ + +#endif //HAVE_BUGGY_TME_SUPPORT + + } + } +} + +int32 +bpf_validate(f, len,mem_ex_size) + struct bpf_insn *f; + int32 len; + uint32 mem_ex_size; +{ + register uint32 i, from; + register int32 j; + register struct bpf_insn *p; + int32 flag; + +#ifndef HAVE_BUGGY_TME_SUPPORT + UNUSED(mem_ex_size); +#endif //HAVE_BUGGY_TME_SUPPORT + + if (len < 1) + return 0; + + for (i = 0; i < (uint32)len; ++i) { + p = &f[i]; + + TRACE_MESSAGE(PACKET_DEBUG_LOUD,"Validating program"); + + flag=0; + for(j=0;jcode==valid_instructions[j]) + flag=1; + if (flag==0) + return 0; + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Validating program: no unknown instructions"); + + switch (BPF_CLASS(p->code)) { + /* + * Check that memory operations use valid addresses. + */ + case BPF_LD: + case BPF_LDX: + switch (BPF_MODE(p->code)) { + case BPF_IMM: + break; + case BPF_ABS: + case BPF_IND: + case BPF_MSH: + break; + case BPF_MEM: + if (p->k >= BPF_MEMWORDS) + return 0; + break; + case BPF_LEN: + break; + default: + return 0; + } + + TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Validating program: no wrong LD memory locations"); + break; + + case BPF_ST: + case BPF_STX: + +#ifdef HAVE_BUGGY_TME_SUPPORT + // + // these instructions use the TME extensions, + // not supported on x86-64 and IA64 architectures. + // + if ((p->code &BPF_MEM_EX_IMM) == BPF_MEM_EX_IMM) + { + /* + * Check if key stores use valid addresses + */ + switch (BPF_SIZE(p->code)) { + + case BPF_W: + if (p->k+3 >= mem_ex_size) + return 0; + break; + + case BPF_H: + if (p->k+1 >= mem_ex_size) + return 0; + break; + + case BPF_B: + if (p->k >= mem_ex_size) + return 0; + break; + } + } + else + { + if ((p->code & BPF_MEM_EX_IND) != BPF_MEM_EX_IND) + { + if (p->k >= BPF_MEMWORDS) + return 0; + } + } +#else // ! HAVE_BUGGY_TME_SUPPORT + if (p->k >= BPF_MEMWORDS) + return 0; +#endif // HAVE_BUGGY_TME_SUPPORT + + TRACE_MESSAGE(PACKET_DEBUG_LOUD,"Validating program: no wrong ST memory locations"); + break; + + case BPF_ALU: + switch (BPF_OP(p->code)) { + case BPF_ADD: + case BPF_SUB: + case BPF_OR: + case BPF_AND: + case BPF_LSH: + case BPF_RSH: + case BPF_NEG: + break; + case BPF_DIV: + /* + * Check for constant division by 0. + */ + if (BPF_RVAL(p->code) == BPF_K && p->k == 0) + return 0; + default: + return 0; + } + break; + case BPF_JMP: + /* + * Check that jumps are within the code block, + * and that unconditional branches don't go + * backwards as a result of an overflow. + * Unconditional branches have a 32-bit offset, + * so they could overflow; we check to make + * sure they don't. Conditional branches have + * an 8-bit offset, and the from address is <= + * BPF_MAXINSNS, and we assume that BPF_MAXINSNS + * is sufficiently small that adding 255 to it + * won't overflow. + * + * We know that len is <= BPF_MAXINSNS, and we + * assume that BPF_MAXINSNS is < the maximum size + * of a u_int, so that i + 1 doesn't overflow. + */ + from = i + 1; + switch (BPF_OP(p->code)) { + case BPF_JA: + if (from + p->k < from || from + p->k >= (uint32)len) + return 0; + break; + case BPF_JEQ: + case BPF_JGT: + case BPF_JGE: + case BPF_JSET: + if (from + p->jt >= (uint32)len || from + p->jf >= (uint32)len) + return 0; + break; + default: + return 0; + } + IF_LOUD(DbgPrint("Validating program: no wrong JUMPS");) + break; + case BPF_RET: + break; + case BPF_MISC: + break; + default: + return 0; + } + } + return BPF_CLASS(f[len - 1].code) == BPF_RET; +} \ No newline at end of file diff --git a/winpcap/packetNtx/driver/win_bpf_filter_init.c b/winpcap/packetNtx/driver/win_bpf_filter_init.c new file mode 100644 index 0000000..dbf51e9 --- /dev/null +++ b/winpcap/packetNtx/driver/win_bpf_filter_init.c @@ -0,0 +1,514 @@ +/* + * Copyright (c) 2001 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "tme.h" +#include "win_bpf.h" + +#pragma warning(disable : 4131) //old style function declaration +#pragma warning(disable : 4127) // conditional expr is constant (used for while(1) loops) +#pragma warning(disable : 4213) //cast on l-value + +/* + * Initialize the filter machine + */ +uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE *tme, struct time_conv *time_ref) +{ + register uint32 A, X; + int32 mem[BPF_MEMWORDS]; + register int32 k; + uint32 *tmp; + uint16 *tmp2; + uint32 j; + if (pc == 0) + /* + * No filter means accept all. + */ + return (uint32)-1; + + RtlZeroMemory(mem, sizeof(mem)); + + A = 0; + X = 0; + --pc; + while (1) { + ++pc; + switch (pc->code) { + + default: + return 0; + +/* RET INSTRUCTIONS */ + case BPF_RET|BPF_K: + return (uint32)pc->k; + + case BPF_RET|BPF_A: + return (uint32)A; +/* END RET INSTRUCTIONS */ + +/* LD NO PACKET INSTRUCTIONS */ + case BPF_LD|BPF_IMM: + A = pc->k; + continue; + + case BPF_LDX|BPF_IMM: + X = pc->k; + continue; + + case BPF_LD|BPF_MEM: + A = mem[pc->k]; + continue; + + case BPF_LDX|BPF_MEM: + X = mem[pc->k]; + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_B: + A= mem_ex->buffer[pc->k]; + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_B: + X= mem_ex->buffer[pc->k]; + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k]; + __asm + { + push eax + push ebx + mov ebx,tmp2 + xor eax, eax + mov ax, [ebx] + bswap eax + mov A, eax + pop ebx + pop eax + } + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k]; + __asm + { + push eax + push ebx + mov ebx,tmp2 + xor eax, eax + mov ax, [ebx] + bswap eax + mov X, eax + pop ebx + pop eax + } + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k]; + __asm + { + push eax + push ebx + mov ebx,tmp + mov eax, [ebx] + bswap eax + mov A, eax + pop ebx + pop eax + } + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k]; + __asm + { + push eax + push ebx + mov ebx,tmp + mov eax, [ebx] + bswap eax + mov X, eax + pop ebx + pop eax + } + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_B: + k = X + pc->k; + if ((int32)k>= (int32)mem_ex->size) { + return 0; + } + A= mem_ex->buffer[k]; + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_H: + k = X + pc->k; + if ((int32)(k+1)>= (int32)mem_ex->size) { + return 0; + } + tmp2=(uint16*)&mem_ex->buffer[k]; + __asm + { + push eax + push ebx + mov ebx,tmp2 + xor eax, eax + mov ax, [ebx] + bswap eax + mov A, eax + pop ebx + pop eax + } + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_W: + k = X + pc->k; + if ((int32)(k+3)>= (int32)mem_ex->size) { + return 0; + } + tmp=(uint32*)&mem_ex->buffer[k]; + __asm + { + push eax + push ebx + mov ebx,tmp + mov eax, [ebx] + bswap eax + mov A, eax + pop ebx + pop eax + } + continue; +/* END LD NO PACKET INSTRUCTIONS */ + +/* STORE INSTRUCTIONS */ + case BPF_ST: + mem[pc->k] = A; + continue; + + case BPF_STX: + mem[pc->k] = X; + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)A; + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)X; + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k]; + __asm + { + push eax + push ebx + mov ebx, tmp + mov eax, A + bswap eax + mov [ebx], eax + pop ebx + pop eax + } + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k]; + __asm + { + push eax + push ebx + mov ebx, tmp + mov eax, X + bswap eax + mov [ebx], eax + pop ebx + pop eax + } + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k]; + __asm + { + push eax + push ebx + mov ebx, tmp2 + mov eax, A + xchg ah, al + mov [ebx], ax + pop ebx + pop eax + } + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k]; + __asm + { + push eax + push ebx + mov ebx, tmp2 + mov eax, X + xchg ah, al + mov [ebx], ax + pop ebx + pop eax + } + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_B: + mem_ex->buffer[pc->k+X]=(uint8)A; + + case BPF_ST|BPF_MEM_EX_IND|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k+X]; + __asm + { + push eax + push ebx + mov ebx, tmp + mov eax, A + bswap eax + mov [ebx], eax + pop ebx + pop eax + } + + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k+X]; + __asm + { + push eax + push ebx + mov ebx, tmp2 + mov eax, A + xchg ah, al + mov [ebx], ax + pop ebx + pop eax + } + continue; +/* END STORE INSTRUCTIONS */ + +/* JUMP INSTRUCTIONS */ + case BPF_JMP|BPF_JA: + pc += pc->k; + continue; + + case BPF_JMP|BPF_JGT|BPF_K: + pc += ((int32)A > (int32)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_K: + pc += ((int32)A >= (int32)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_K: + pc += ((int32)A == (int32)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_K: + pc += (A & pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGT|BPF_X: + pc += (A > X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_X: + pc += (A >= X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_X: + pc += (A == X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_X: + pc += (A & X) ? pc->jt : pc->jf; + continue; +/* END JUMP INSTRUCTIONS */ + +/* ARITHMETIC INSTRUCTIONS */ + case BPF_ALU|BPF_ADD|BPF_X: + A += X; + continue; + + case BPF_ALU|BPF_SUB|BPF_X: + A -= X; + continue; + + case BPF_ALU|BPF_MUL|BPF_X: + A *= X; + continue; + + case BPF_ALU|BPF_DIV|BPF_X: + if (X == 0) + return 0; + A /= X; + continue; + + case BPF_ALU|BPF_AND|BPF_X: + A &= X; + continue; + + case BPF_ALU|BPF_OR|BPF_X: + A |= X; + continue; + + case BPF_ALU|BPF_LSH|BPF_X: + A <<= X; + continue; + + case BPF_ALU|BPF_RSH|BPF_X: + A >>= X; + continue; + + case BPF_ALU|BPF_ADD|BPF_K: + A += pc->k; + continue; + + case BPF_ALU|BPF_SUB|BPF_K: + A -= pc->k; + continue; + + case BPF_ALU|BPF_MUL|BPF_K: + A *= pc->k; + continue; + + case BPF_ALU|BPF_DIV|BPF_K: + A /= pc->k; + continue; + + case BPF_ALU|BPF_AND|BPF_K: + A &= pc->k; + continue; + + case BPF_ALU|BPF_OR|BPF_K: + A |= pc->k; + continue; + + case BPF_ALU|BPF_LSH|BPF_K: + A <<= pc->k; + continue; + + case BPF_ALU|BPF_RSH|BPF_K: + A >>= pc->k; + continue; + + case BPF_ALU|BPF_NEG: + (int32)A = -((int32)A); + continue; +/* ARITHMETIC INSTRUCTIONS */ + +/* MISC INSTRUCTIONS */ + case BPF_MISC|BPF_TAX: + X = A; + continue; + + case BPF_MISC|BPF_TXA: + A = X; + continue; +/* END MISC INSTRUCTIONS */ + +/* TME INSTRUCTIONS */ + case BPF_MISC|BPF_TME|BPF_LOOKUP: + j=lookup_frontend(mem_ex,tme,pc->k,time_ref); + if (j==TME_ERROR) + return 0; + pc += (j == TME_TRUE) ? pc->jt : pc->jf; + continue; + + case BPF_MISC|BPF_TME|BPF_EXECUTE: + if (execute_frontend(mem_ex,tme,0,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_INIT: + if (init_tme_block(tme,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_VALIDATE: + if (validate_tme_block(mem_ex,tme,A,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_MEMORY: + if (init_extended_memory(pc->k,mem_ex)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_ACTIVE: + if (set_active_tme_block(tme,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_ACTIVE_READ: + if (set_active_tme_block(tme,pc->k)==TME_ERROR) + return 0; + continue; + case BPF_MISC|BPF_TME|BPF_SET_WORKING: + if (pc->k>=MAX_TME_DATA_BLOCKS) + return 0; + tme->working=pc->k; + continue; + + + + case BPF_MISC|BPF_TME|BPF_RESET: + if (reset_tme(tme)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE: + if (get_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,&j)==TME_ERROR) + return 0; + A=j; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE: + if (set_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,A,TRUE)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_AUTODELETION: + set_autodeletion(&tme->block_data[tme->working],pc->k); + continue; + +/* END TME INSTRUCTIONS */ + + } + } +} + diff --git a/winpcap/packetNtx/driver/win_bpf_filter_init.h b/winpcap/packetNtx/driver/win_bpf_filter_init.h new file mode 100644 index 0000000..a1dcfe8 --- /dev/null +++ b/winpcap/packetNtx/driver/win_bpf_filter_init.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2001 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __FILTER_INIT +#define __FILTER_INIT + +#include "tme.h" + +#define INIT_OK 1 +#define INIT_ERROR 0 + +#ifdef __cplusplus +extern "C" +{ +#endif +uint32 bpf_filter_init(register struct bpf_insn *pc,MEM_TYPE *mem_ex, TME_CORE *tme, struct time_conv *time_ref); +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/winpcap/readme-cygwin b/winpcap/readme-cygwin new file mode 100644 index 0000000..0bdf9a3 --- /dev/null +++ b/winpcap/readme-cygwin @@ -0,0 +1,24 @@ +Makefile and patches provided by Nate Lawson (nate@rootlabs.com) + + +Only the Packet and WPCAP DLLs can be built under gcc. The drivers +themselves (packet.sys and packet.vxd) are too dependent on MSVC for +their tools and assembler. + +To build packet.dll, cd to Packet9x/DLL/Project (or packetNtx/...) and type +"make". To build wpcap.dll, cd to WPCAP/PRJ and type "make". +"make install" in either directory installs the DLL in c:/windows/system + +If you want to link with your programs, use libpacket.a and libwpcap.a. +These are the import libraries for gcc. You CANNOT use the MSVC-generated +.lib files with gcc. For help on how to link to them, see the developer's +pack examples. + +To remove all objects, type "make clean". + +TODO: +Make VXD and SYS build on non-VC platforms - NOT TRIVIAL. Possible routes +include: +Look into reactos.com and monitor cygwin.com/ml/cygwin for DDK equivalents. +Port *.asm to GNU as. + diff --git a/winpcap/readme-visualC b/winpcap/readme-visualC new file mode 100644 index 0000000..de87599 --- /dev/null +++ b/winpcap/readme-visualC @@ -0,0 +1,199 @@ +This readme explains how to compile WinPcap, both the kernel level and the +user-level portion, on the various Win32 platforms. The source code can be +found on the WinPcap website, at http://www.winpcap.org/install/. + +Compiling the driver +==================== + +Two main NPF source trees are available for compilation: Windows NTx and +Windows 9x. Note that, since the NPF Driver is platform-dependent, it is +STRONGLY suggested to compile it on the OS where it will be used, in order +to link the correct DDK libraries. For example, if you compile the driver +with the Windows NT 4 DDK, it will not work properly on Windows 2000 and +vice versa. + +Compiling the driver on Windows NT4 +----------------------------------- + +Software requirements: +- Microsoft Driver Developer Kit (DDK) for Windows NT4 +- A recent version of the Microsoft Platform Software Development Kit (SDK) + that is compatible with Visual Studio 6 (the latest compatible one is + Platform SDK February 2003). This version of the PSDK is available on the + Microsoft web site at + http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm. + It can be ordered online at http://www.qmedia.ca/launch/psdk.htm, and it's + also available to Microsoft MSDN subscribers on the Subscribers Downloads + web site. + - Microsoft Visual C++ 6.0 with Service Pack 5 or 6 (both the service packs + are available online on the Microsoft web site). + +If your system satisfies these requirements, follow these steps: +1. From the Windows NT Start menu, select the folder Programs and then + Development Kits, then Windows NT4 DDK. From here select the voice + Checked Build Environment if you want to build a debug version, or Free + Build Environment if you want to build a release version. +2. A command prompt will be opened. Move to the directory PacketNTx inside + the WinPcap source folder and type the command + + CompileNT4 + + This script will generate the driver (npf.sys), that will be put in the + DDK output directory (usually \i386). + +Warning: sometimes, during the compilation of the driver, a lot of 'last +line incomplete' errors are generated. Ignore these errors and let the +compilation process continue, they are due to bugs in some DDK versions. + + +Compiling the driver on Windows 2000/XP/2003 +-------------------------------------------- + +Software requirements: +- Microsoft Driver Developer Kit (DDK) for Windows 2000, Windows XP or + Windows Server 2003 + +If your system satisfies these requirements, follow these steps: +1. From the Windows Start menu, select the folder Programs and then + Development Kits, then Windows XXX DDK, where XXX is the target system. + From here select the voice Checked Build Environment if you want to build + a debug version, or Free Build Environment if you want to build a release + version. +2. A command prompt will be opened. Move to the directory PacketNTx inside + the WinPcap source folder and type the command + + Compile2k + + This script will generate the driver (npf.sys), that will be put in the + DDK output directory (usually \i386). + + +Compiling the driver on Windows 9x +---------------------------------- + +To compile the driver for Windows 9x you will need: +- Driver Developer Kit (DDK) for Windows 95/98/ME +- A recent version of the Microsoft Platform Software Development Kit (SDK) + that is compatible with Visual Studio 6 (the latest compatible one is + Platform SDK February 2003). This version of the PSDK is available on the + Microsoft web site at + http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm. + It can be ordered online at http://www.qmedia.ca/launch/psdk.htm, and it's + also available to Microsoft MSDN subscribers on the Subscribers Downloads + web site. +- Microsoft Visual C++ 6.0 with Service Pack 5 or 6 (both the service packs + are available online on the Microsoft web site). + +The steps to follow are: +1. Open a DOS shell +2. Go to the VisualC++ BIN directory (for example C:\DEVSTUDIO\VC\BIN) and + execute the command + + Vcvars32 + +3. Go to the SDK directory (for example C:\MSSDK) and execute the command + + Setenv sdk_path + + where sdk_path is the directory of SDK (for example Setenv C:\MSSDK) +4. Go to the DDK directory (for example C:\DDK) and execute the command + + Ddkenv 32 net + +5. Move to the directory whit the driver's source code and type the command + + nmake rtl + + to obtain a release version, or + + nmake + + to obtain a debug version. + The release version of packet.vxd will be placed in the retail directory, + the debug version in the debug directory. + +Warning: On some systems the NMAKE utility is not able to launch ADRC2VXD, +this means that the driver binary is generated correctly, but without the +copyright information. We don't know the cause of this problem. + + +Compiling packet.dll +==================== + +Like the NPF driver, two source trees are available for compilation: the +Windows NTx one and the Windows 9x one. They are located in PacketNTx\dll\ +and in Packet9x\dll\. +Software requirements: +- A recent version of the Microsoft Platform Software Development Kit (SDK) + that is compatible with Visual Studio 6 (the latest compatible one is + Platform SDK February 2003). This version of the PSDK is available on the + Microsoft web site at + http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm. + It can be ordered online at http://www.qmedia.ca/launch/psdk.htm, and it's + also available to Microsoft MSDN subscribers on the Subscribers Downloads + web site. + Note: if you use Microsoft Visual Studio .NET the platform SDK is not + needed to compile packet.dll. +- Microsoft Visual C++ 6.0 with Service Pack 5 or 6 (both the service packs + are available online on the Microsoft web site). + +To compile the PACKET.DLL, load the project contained in the directory +PacketNTx\dll\project (or Packet9x\dll\project) in the Visual C++ IDE. There +are four project configurations: +- PacketNT - Win32 Release: standard release configuration +- PacketNT - Win32 Debug: standard debug configuration +- PacketNT - Win32 NT4 Release: release configuration able to run on NT4 + does not include Wan and IP helper API support. +- PacketNT - Win32 NT4 Debug: debug configuration able to run on NT4 does + not include Wan and IP helper API support. +- WanPacket - Win32 Release: release version of the WanPacket library, used + to interface with NetMon API for Wan capture +- WanPacket - Win32 Debug: debug version of the WanPacket library, used to + interface with NetMon API for Wan capture +Choose the desired configuration and build the project to obtain the binary +files. + + +Compiling wpcap.dll +=================== + +wpcap.dll can be compiled on any Win32 platform and the generated dll is +system independent. +System Requirements: +- Microsoft Visual C++ 6.0 with Service Pack 5 or 6 (both the service packs + are available online on the Microsoft web site). +-- A recent version of the Microsoft Platform Software Development Kit (SDK) + that is compatible with Visual Studio 6 (the latest compatible one is + Platform SDK February 2003). This version of the PSDK is available on the + Microsoft web site at + http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm. + It can be ordered online at http://www.qmedia.ca/launch/psdk.htm, and it's + also available to Microsoft MSDN subscribers on the Subscribers Downloads + web site. + Note: if you use Microsoft Visual Studio .Net the platform SDK is not + needed to compile wpcap.dll. + +Project files are in the directory winpcap\wpcap\prj of the WinPcap source +code distribution. Load wpcap.dsw from the Visual C++ IDE and build the +program. + +There are six build project configurations: + +- No support for DAG cards and Remore Capture + + Wpcap debug: winpcap\wpcap\prj\Debug + + Wpcap release: winpcap\wpcap\prj\Release + +- Support for Remote capture, no support for DAG cards + + Wpcap debug REMOTE: winpcap\wpcap\prj\Debug_REMOTE + + Wpcap release REMOTE: winpcap\wpcap\prj\Release_REMOTE + +- Support for DAG cards and Remote Capture + + Wpcap debug REMOTE DAG: winpcap\wpcap\prj\Debug_REMOTE_DAG + + Wpcap release REMOTE DAG: winpcap\wpcap\prj\Release_REMOTE_DAG + +Note: wpcap.dll contains the source code of libpcap from www.tcpdump.org, +with some modifications for remote capture. You will be able to include and +build a different libpcap version simply copying it in the directory +winpcap\wpcap\prj of the WinPcap source code distribution, but you must use +the "Debug" or "Release" build configurations. + diff --git a/winpcap/todo.txt b/winpcap/todo.txt new file mode 100644 index 0000000..e910863 --- /dev/null +++ b/winpcap/todo.txt @@ -0,0 +1,3 @@ +- Implement the kernel dump with the new buffering mode +- Check the buffered write functionality, in particular with the new gigabit adapters that caused problems to some users +- Change the #define WIN32 with #define _WIN32 diff --git a/winpcap/version.h b/winpcap/version.h new file mode 100644 index 0000000..c1fcbea --- /dev/null +++ b/winpcap/version.h @@ -0,0 +1,35 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// + +// 3.1.0.24 --> WinPcap 3.1 beta4 +// 3.1.0.27 --> WinPcap 3.1 RTM +// 3.2.0.29 --> WinPcap 3.2 alpha1 +// 4.0.0.374 --> WinPcap 4.0 alpha1 +// 4.0.0.592 --> WinPcap 4.0 beta1 +// 4.0.0.655 --> WinPcap 4.0 beta2 +// 4.0.0.703 --> WinPcap 4.0 beta3 +// 4.0.0.755 --> WinPcap 4.0 RTM +// 4.0.0.901 --> WinPcap 4.0.1 RTM +// 4.0.0.1040 --> WinPcap 4.0.2 RTM + +#define WINPCAP_MAJOR 4 +#define WINPCAP_MINOR 0 +#define WINPCAP_REV 0 +#define WINPCAP_BUILD 1040 +#define WINPCAP_VER_STRING "4.0.0.1040" +#define WINPCAP_PACKET9x_STRING_VERSION "4.0.2" +#define WINPCAP_WPCAP_STRING_VERSION "4.0.2" + +#define WINPCAP_COMPANY_NAME "CACE Technologies" + +#define WINPCAP_PRODUCT_NAME "WinPcap" + +#define WINPCAP_COPYRIGHT_STRING "Copyright © 2005-2007 CACE Technologies. Copyright © 1999-2005 NetGroup, Politecnico di Torino." +#define WINPCAP_WANPACKET_COPYRIGHT_STRING "Copyright © 2005-2007 CACE Technologies. Copyright © 2003-2005 NetGroup, Politecnico di Torino." +#define WINPCAP_INSTALLERHELPER_COPYRIGHT_STRING "Copyright © 2007 CACE Technologies." +#define WINPCAP_RPCAPD_COPYRIGHT_STRING "Copyright © 2005-2007 CACE Technologies. Copyright © 2003-2005 NetGroup, Politecnico di Torino." + +#define WINPCAP_BUILD_DESCRIPTION "" +#define WINPCAP_PRIVATE_BUILD "" +#define WINPCAP_LIBPCAP_VERSION "0.9.5" diff --git a/winpcap/wpcap/PRJ/GNUmakefile b/winpcap/wpcap/PRJ/GNUmakefile new file mode 100644 index 0000000..b447990 --- /dev/null +++ b/winpcap/wpcap/PRJ/GNUmakefile @@ -0,0 +1,85 @@ +# Makefile for cygwin gcc +# Nate Lawson + +# Set according to your system type +SYSTYPE = "NT" +# SYSTYPE = "9x" + +# OPTFLAGS = -g +OPTFLAGS = -O +# DO _NOT_ USE -O2! Causes fault upon startup. + +# +# Flex and bison allow you to specify the prefixes of the global symbols +# used by the generated parser. This allows programs to use lex/yacc +# and link against libpcap. If you don't have flex or bison, get them. +# +LFLAGS = -Ppcap_ +YFLAGS = -y -p pcap_ + +PACKET_DIR = packetNTx +INSTALL_DIR = ${SYSTEMROOT}\system32 + +CFLAGS = -I ../libpcap -I ../libpcap/bpf -I ../libpcap/lbl \ + -I ../libpcap/Win32/Include -I../libpcap/Win32/Include/ipv6kit \ + -I ../../common -I ../Win32-Extensions \ + -I ../../../Airpcap_DevPack/include \ + -DLIBPCAP_EXPORTS -DYY_NEVER_INTERACTIVE -Dyylval=pcap_lval \ + -DHAVE_STRERROR -DNEED_ADDRINFO_H -DINET6 -DWIN32 \ + -DSIZEOF_CHAR=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG_LONG=8 -DWPCAP -D'_U_=' \ + -DHAVE_SNPRINTF -DHAVE_VSNPRINTF \ + -DSIZEOF_LONG_LONG=8 \ + -DHAVE_REMOTE -DHAVE_AIRPCAP_API \ + -mno-cygwin -shared ${OPTFLAGS} +LDFLAGS = -Wl,--out-implib,../lib/libwpcap.a +LIBS = -L ../../${PACKET_DIR}/DLL/Project -lPacket -lws2_32 +OBJS = ../libpcap/bpf/net/bpf_filter.o \ + ../libpcap/bpf_dump.o \ + ../libpcap/bpf_image.o \ + ../libpcap/etherent.o \ + ../libpcap/Win32/Src/ffs.o \ + ../libpcap/gencode.o\ + ../libpcap/Win32/Src/getaddrinfo.o \ + ../libpcap/Win32/Src/getnetbynm.o \ + ../libpcap/Win32/Src/getnetent.o \ + ../libpcap/Win32/Src/getservent.o \ + ../libpcap/grammar.o \ + ../libpcap/inet.o \ + ../libpcap/Win32/Src/inet_aton.o \ + ../libpcap/Win32/Src/inet_net.o \ + ../libpcap/Win32/Src/inet_pton.o \ + ../libpcap/nametoaddr.o \ + ../libpcap/optimize.o \ + ../libpcap/pcap-win32.o \ + ../libpcap/fad-win32.o \ + ../libpcap/pcap.o \ + ../libpcap/savefile.o \ + ../libpcap/scanner.o \ + ../libpcap/pcap-new.o \ + ../libpcap/pcap-remote.o \ + ../libpcap/sockutils.o \ + ../libpcap/Win32/Src/gai_strerror.o \ + ../Win32-Extensions/Win32-Extensions.o + +main: ${OBJS} + ${CC} ${CFLAGS} ${LDFLAGS} -o wpcap.dll wpcap.def ${OBJS} ${LIBS} + +install: + cp wpcap.dll ${INSTALL_DIR} + +clean: + ${RM} ${OBJS} ../libpcap/scanner.c ../libpcap/grammar.c wpcap.a wpcap.dll + +# Keeps intermediate .c files from being deleted +.SECONDARY: ../libpcap/scanner.c ../libpcap/grammar.c + +.y.c: + @${RM} ../libpcap/grammar.c ../libpcap/tokdefs.h + ${YACC} ${YFLAGS} -d $< + mv y.tab.c ../libpcap/grammar.c + mv y.tab.h ../libpcap/tokdefs.h +.l.c: + @${RM} $@ + ${LEX} ${LFLAGS} -t $< >$*.c +.c.o: + ${CC} ${CFLAGS} -o $*.o -c $< diff --git a/winpcap/wpcap/PRJ/WPCAP.DEF b/winpcap/wpcap/PRJ/WPCAP.DEF new file mode 100644 index 0000000..a18466e --- /dev/null +++ b/winpcap/wpcap/PRJ/WPCAP.DEF @@ -0,0 +1,86 @@ +LIBRARY wpcap.dll + +DESCRIPTION 'Win32 Packet Capture Library' + +EXPORTS + pcap_lookupdev + pcap_lookupnet + pcap_open_live + pcap_open_offline + pcap_close + pcap_getnonblock + pcap_setnonblock + pcap_loop + pcap_dispatch + pcap_read + pcap_setuserbuffer + pcap_offline_read + pcap_next + pcap_stats + pcap_stats_ex + pcap_setfilter + pcap_perror + pcap_strerror + pcap_geterr + pcap_compile + pcap_compile_nopcap + pcap_freecode + pcap_datalink + pcap_snapshot + pcap_is_swapped + pcap_major_version + pcap_minor_version + pcap_file + pcap_fileno + pcap_dump_open + pcap_dump_close + pcap_dump_flush + pcap_dump + pcap_dump_file + pcap_setbuff + pcap_setmode + pcap_sendpacket + pcap_sendqueue_alloc + pcap_sendqueue_destroy + pcap_sendqueue_queue + pcap_sendqueue_transmit + pcap_next_etherent + pcap_getevent + pcap_setmintocopy + pcap_open_dead + pcap_findalldevs + pcap_freealldevs + pcap_live_dump + pcap_live_dump_ended + bpf_filter + bpf_validate + bpf_image + bpf_dump + wsockinit + endservent + getservent + eproto_db + pcap_stats_ex + pcap_open + pcap_createsrcstr + pcap_parsesrcstr + pcap_findalldevs_ex + pcap_remoteact_accept + pcap_remoteact_list + pcap_remoteact_close + pcap_remoteact_cleanup + install_bpf_program + pcap_next_ex + pcap_offline_filter + pcap_setsampling + pcap_breakloop + pcap_list_datalinks + pcap_list_datalinks + pcap_set_datalink + pcap_datalink_name_to_val + pcap_datalink_val_to_name + pcap_datalink_val_to_description + pcap_lib_version + pcap_dump_file + pcap_dump_ftell + pcap_get_airpcap_handle \ No newline at end of file diff --git a/winpcap/wpcap/PRJ/WPCAP.dsw b/winpcap/wpcap/PRJ/WPCAP.dsw new file mode 100644 index 0000000..9f42285 --- /dev/null +++ b/winpcap/wpcap/PRJ/WPCAP.dsw @@ -0,0 +1,59 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "libpcap"=..\libpcap\Win32\Prj\libpcap.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "rpcapd"=..\libpcap\rpcapd\rpcapd.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name wpcap + End Project Dependency +}}} + +############################################################################### + +Project: "wpcap"=.\wpcap.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libpcap + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/wpcap/PRJ/Wpcap_no_extensions.def b/winpcap/wpcap/PRJ/Wpcap_no_extensions.def new file mode 100644 index 0000000..be18096 --- /dev/null +++ b/winpcap/wpcap/PRJ/Wpcap_no_extensions.def @@ -0,0 +1,77 @@ +LIBRARY wpcap.dll + +DESCRIPTION 'Win32 Packet Capture Library' + +EXPORTS + pcap_lookupdev + pcap_lookupnet + pcap_open_live + pcap_open_offline + pcap_close + pcap_getnonblock + pcap_setnonblock + pcap_loop + pcap_dispatch + pcap_read + pcap_setuserbuffer + pcap_offline_read + pcap_next + pcap_stats + pcap_stats_ex + pcap_setfilter + pcap_perror + pcap_strerror + pcap_geterr + pcap_compile + pcap_compile_nopcap + pcap_freecode + pcap_datalink + pcap_snapshot + pcap_is_swapped + pcap_major_version + pcap_minor_version + pcap_file + pcap_fileno + pcap_dump_open + pcap_dump_close + pcap_dump_flush + pcap_dump + pcap_dump_file + pcap_setbuff + pcap_setmode + pcap_sendpacket + pcap_sendqueue_alloc + pcap_sendqueue_destroy + pcap_sendqueue_queue + pcap_sendqueue_transmit + pcap_next_etherent + pcap_getevent + pcap_setmintocopy + pcap_open_dead + pcap_findalldevs + pcap_freealldevs + pcap_live_dump + pcap_live_dump_ended + bpf_filter + bpf_validate + bpf_image + bpf_dump + wsockinit + endservent + getservent + eproto_db + pcap_stats_ex + install_bpf_program + pcap_next_ex + pcap_offline_filter + pcap_breakloop + pcap_list_datalinks + pcap_list_datalinks + pcap_set_datalink + pcap_datalink_name_to_val + pcap_datalink_val_to_name + pcap_datalink_val_to_description + pcap_lib_version + pcap_dump_file + pcap_dump_ftell + pcap_get_airpcap_handle \ No newline at end of file diff --git a/winpcap/wpcap/PRJ/build_scanner_parser.bat b/winpcap/wpcap/PRJ/build_scanner_parser.bat new file mode 100644 index 0000000..31786d5 --- /dev/null +++ b/winpcap/wpcap/PRJ/build_scanner_parser.bat @@ -0,0 +1,26 @@ +@echo off + +echo Building the libpcap parser and scanner... +del /Q /F ..\libpcap\grammar.c > nul 2> nul +del /Q /F ..\libpcap\tokdefs.h > nul 2> nul + +bison -y -p pcap_ -d ../libpcap/GRAMMAR.Y > nul +if not %ERRORLEVEL% == 0 ( + echo failure in generating the grammar. + goto end + ) + +move y.tab.c ..\libpcap\grammar.c +move y.tab.h ..\libpcap\tokdefs.h + +del /Q /F ..\libpcap\scanner.c >/nul 2>/nul +flex -Ppcap_ -t ../libpcap/scanner.l > ../libpcap/scanner.c + +if not %ERRORLEVEL% == 0 ( + echo failure in generating the scanner. + goto end + ) + +echo --- Done! + +:end \ No newline at end of file diff --git a/winpcap/wpcap/PRJ/wpcap.dsp b/winpcap/wpcap/PRJ/wpcap.dsp new file mode 100644 index 0000000..6a66bf4 --- /dev/null +++ b/winpcap/wpcap/PRJ/wpcap.dsp @@ -0,0 +1,501 @@ +# Microsoft Developer Studio Project File - Name="wpcap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=wpcap - Win32 Debug REMOTE NO AIRPCAP +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "wpcap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "wpcap.mak" CFG="wpcap - Win32 Debug REMOTE NO AIRPCAP" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "wpcap - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "wpcap - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "wpcap - Win32 Debug REMOTE" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "wpcap - Win32 Debug REMOTE DAG" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "wpcap - Win32 Release REMOTE" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "wpcap - Win32 Release REMOTE DAG" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "wpcap - Win32 Release REMOTE NO AIRPCAP" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "wpcap - Win32 Debug REMOTE NO AIRPCAP" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "wpcap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBPCAP_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /I "../../../Airpcap_Devpack/include" /D HAVE_ADDRINFO=1 /D "NDEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /D "HAVE_AIRPCAP_API" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/release/libpcap.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"libcmtd.lib" /def:".\wpcap_no_extensions.def" /FORCE:MULTIPLE /WARN:0 /opt:ref +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBPCAP_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /I "../../../Airpcap_Devpack/include" /D "HAVE_ADDRINFO" /D "_DEBUG" /D "HAVE_DAG_API" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /D "HAVE_AIRPCAP_API" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/debug/libpcap.lib /nologo /dll /debug /machine:I386 /def:".\Wpcap_no_extensions.def" /pdbtype:sept /FORCE:MULTIPLE /WARN:0 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_REMOTE" +# PROP BASE Intermediate_Dir "Debug_REMOTE" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_REMOTE" +# PROP Intermediate_Dir "Debug_REMOTE" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /D "HAVE_ADDRINFO" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "_DEBUG" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /D "HAVE_REMOTE" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /I "../../../Airpcap_Devpack/include" /D "HAVE_ADDRINFO" /D "_DEBUG" /D "HAVE_REMOTE" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /D "HAVE_AIRPCAP_API" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/debug/libpcap.lib /nologo /dll /debug /machine:I386 /implib:"../lib/wpcap.lib" /pdbtype:sept /FORCE:MULTIPLE /WARN:0 +# SUBTRACT BASE LINK32 /pdb:none /incremental:no +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/debug_REMOTE/libpcap.lib /nologo /dll /debug /machine:I386 /def:".\wpcap.def" /pdbtype:sept /FORCE:MULTIPLE /WARN:0 +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\Debug_REMOTE +SOURCE="$(InputPath)" +PostBuild_Desc=copy wpcap.lib file +PostBuild_Cmds=mkdir $(OutDir)\..\..\LIB > nul copy $(OutDir)\wpcap.lib $(OutDir)\..\..\LIB\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE DAG" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_REMOTE_DAG" +# PROP BASE Intermediate_Dir "Debug_REMOTE_DAG" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_REMOTE_DAG" +# PROP Intermediate_Dir "Debug_REMOTE_DAG" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /D "HAVE_ADDRINFO" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "_DEBUG" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /D "HAVE_REMOTE" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /I "../../../Airpcap_Devpack/include" /D "HAVE_ADDRINFO" /D "_DEBUG" /D "HAVE_REMOTE" /D "HAVE_DAG_API" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /D "HAVE_AIRPCAP_API" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/Debug_REMOTE_DAG/libpcap.lib /nologo /dll /debug /machine:I386 /implib:"../lib/wpcap.lib" /pdbtype:sept /FORCE:MULTIPLE /WARN:0 +# SUBTRACT BASE LINK32 /pdb:none /incremental:no +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/debug_REMOTE_DAG/libpcap.lib /nologo /dll /debug /machine:I386 /def:".\wpcap.def" /pdbtype:sept /FORCE:MULTIPLE /WARN:0 +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\Debug_REMOTE_DAG +SOURCE="$(InputPath)" +PostBuild_Desc=copy wpcap.lib file +PostBuild_Cmds=mkdir $(OutDir)\..\..\LIB > nul copy $(OutDir)\wpcap.lib $(OutDir)\..\..\LIB\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_REMOTE" +# PROP BASE Intermediate_Dir "Release_REMOTE" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_REMOTE" +# PROP Intermediate_Dir "Release_REMOTE" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /D HAVE_ADDRINFO=1 /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "NDEBUG" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /D "HAVE_REMOTE" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /I "../../../Airpcap_Devpack/include" /D HAVE_ADDRINFO=1 /D "NDEBUG" /D "HAVE_REMOTE" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /D "HAVE_AIRPCAP_API" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/Release_REMOTE/libpcap.lib /nologo /dll /machine:I386 /nodefaultlib:"libcmtd.lib" /def:".\wpcap.def" /implib:"../lib/wpcap.lib" /FORCE:MULTIPLE /WARN:0 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/release_REMOTE/libpcap.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"libcmtd.lib" /def:".\wpcap.def" /FORCE:MULTIPLE /WARN:0 /opt:ref +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\Release_REMOTE +SOURCE="$(InputPath)" +PostBuild_Desc=copy wpcap.lib file +PostBuild_Cmds=mkdir $(OutDir)\..\..\LIB > nul copy $(OutDir)\wpcap.lib $(OutDir)\..\..\LIB\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE DAG" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_REMOTE_DAG" +# PROP BASE Intermediate_Dir "Release_REMOTE_DAG" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_REMOTE_DAG" +# PROP Intermediate_Dir "Release_REMOTE_DAG" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /D HAVE_ADDRINFO=1 /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "NDEBUG" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /D "HAVE_REMOTE" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /I "../../../Airpcap_Devpack/include" /D HAVE_ADDRINFO=1 /D "NDEBUG" /D "HAVE_REMOTE" /D "HAVE_DAG_API" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /D "HAVE_AIRPCAP_API" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/Release_REMOTE_DAG/libpcap.lib /nologo /dll /machine:I386 /nodefaultlib:"libcmtd.lib" /def:".\wpcap.def" /implib:"../lib/wpcap.lib" /FORCE:MULTIPLE /WARN:0 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/release_REMOTE_DAG/libpcap.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"libcmtd.lib" /def:".\wpcap.def" /FORCE:MULTIPLE /WARN:0 /opt:ref +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\Release_REMOTE_DAG +SOURCE="$(InputPath)" +PostBuild_Desc=copy wpcap.lib file +PostBuild_Cmds=mkdir $(OutDir)\..\..\LIB > nul copy $(OutDir)\wpcap.lib $(OutDir)\..\..\LIB\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE NO AIRPCAP" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "wpcap___Win32_Release_REMOTE_NO_AIRPCAP" +# PROP BASE Intermediate_Dir "wpcap___Win32_Release_REMOTE_NO_AIRPCAP" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_REMOTE_NO_AIRPCAP" +# PROP Intermediate_Dir "Release_REMOTE_NO_AIRPCAP" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /I "../../../Airpcap_Devpack/include" /D HAVE_ADDRINFO=1 /D "NDEBUG" /D "HAVE_REMOTE" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /I "../../../Airpcap_Devpack/include" /D HAVE_ADDRINFO=1 /D "NDEBUG" /D "HAVE_REMOTE" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/release_REMOTE/libpcap.lib /nologo /dll /machine:I386 /nodefaultlib:"libcmtd.lib" /def:".\wpcap.def" /FORCE:MULTIPLE /WARN:0 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/release_REMOTE/libpcap.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"libcmtd.lib" /def:".\wpcap.def" /FORCE:MULTIPLE /WARN:0 /opt:ref +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\Release_REMOTE_NO_AIRPCAP +SOURCE="$(InputPath)" +PostBuild_Desc=copy wpcap.lib file +PostBuild_Cmds=mkdir $(OutDir)\..\..\LIB > nul copy $(OutDir)\wpcap.lib $(OutDir)\..\..\LIB\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE NO AIRPCAP" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "wpcap___Win32_Debug_REMOTE_NO_AIRPCAP" +# PROP BASE Intermediate_Dir "wpcap___Win32_Debug_REMOTE_NO_AIRPCAP" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_REMOTE_NO_AIRPCAP" +# PROP Intermediate_Dir "Debug_REMOTE_NO_AIRPCAP" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /I "../../../Airpcap_Devpack/include" /D "HAVE_ADDRINFO" /D "_DEBUG" /D "HAVE_REMOTE" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /D "HAVE_AIRPCAP_API" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../libpcap/" /I "../libpcap/bpf" /I "../libpcap/lbl" /I "../libpcap/Win32/Include" /I "../../common" /I "../Win32-Extensions" /I "../../../Airpcap_Devpack/include" /D "HAVE_ADDRINFO" /D "_DEBUG" /D "HAVE_REMOTE" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "WPCAP" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "WIN32" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/debug_REMOTE/libpcap.lib /nologo /dll /debug /machine:I386 /def:".\wpcap.def" /pdbtype:sept /FORCE:MULTIPLE /WARN:0 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib ../libpcap/win32/prj/debug_REMOTE/libpcap.lib /nologo /dll /debug /machine:I386 /def:".\wpcap.def" /pdbtype:sept /FORCE:MULTIPLE /WARN:0 +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +OutDir=.\Debug_REMOTE_NO_AIRPCAP +SOURCE="$(InputPath)" +PostBuild_Desc=copy wpcap.lib file +PostBuild_Cmds=mkdir $(OutDir)\..\..\LIB > nul copy $(OutDir)\wpcap.lib $(OutDir)\..\..\LIB\ +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "wpcap - Win32 Release" +# Name "wpcap - Win32 Debug" +# Name "wpcap - Win32 Debug REMOTE" +# Name "wpcap - Win32 Debug REMOTE DAG" +# Name "wpcap - Win32 Release REMOTE" +# Name "wpcap - Win32 Release REMOTE DAG" +# Name "wpcap - Win32 Release REMOTE NO AIRPCAP" +# Name "wpcap - Win32 Debug REMOTE NO AIRPCAP" +# Begin Group "Extensions" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="..\Win32-Extensions\Win32-Extensions.c" +# End Source File +# End Group +# Begin Group "Libraries" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\common\Packet.lib +# End Source File +# End Group +# Begin Source File + +SOURCE="..\libpcap\pcap-new.c" + +!IF "$(CFG)" == "wpcap - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE DAG" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE DAG" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE NO AIRPCAP" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE NO AIRPCAP" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE="..\libpcap\pcap-remote.c" + +!IF "$(CFG)" == "wpcap - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE DAG" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE DAG" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE NO AIRPCAP" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE NO AIRPCAP" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\libpcap\sockutils.c + +!IF "$(CFG)" == "wpcap - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE DAG" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE DAG" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE NO AIRPCAP" + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE NO AIRPCAP" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE="..\Win32-Extensions\version.rc" +# End Source File +# Begin Source File + +SOURCE=.\wpcap.def + +!IF "$(CFG)" == "wpcap - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE DAG" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE DAG" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE NO AIRPCAP" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE NO AIRPCAP" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Wpcap_no_extensions.def + +!IF "$(CFG)" == "wpcap - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE DAG" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE DAG" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Release REMOTE NO AIRPCAP" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wpcap - Win32 Debug REMOTE NO AIRPCAP" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/winpcap/wpcap/Win32-Extensions/Win32-Extensions.c b/winpcap/wpcap/Win32-Extensions/Win32-Extensions.c new file mode 100644 index 0000000..b37a3d1 --- /dev/null +++ b/winpcap/wpcap/Win32-Extensions/Win32-Extensions.c @@ -0,0 +1,380 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "pcap-int.h" +#include + +#ifdef HAVE_REMOTE +#include +#endif + + +HANDLE +pcap_getevent(pcap_t *p) +{ + if (p->adapter==NULL) + { + sprintf(p->errbuf, "The read event cannot be retrieved while reading from a file"); + return NULL; + } + + return PacketGetReadEvent(p->adapter); +} + + + +/* +This way is definitely safer than passing the pcap_stat * from the userland. In fact, there could +happen than the user allocates a variable which is not big enough for the new structure, and the +library will write in a zone which is not allocated to this variable. +In this way, we're pretty sure we are writing on memory allocated to this variable. +*/ +struct pcap_stat * +pcap_stats_ex(pcap_t *p, int *pcap_stat_size) +{ + *pcap_stat_size= sizeof (struct pcap_stat); + +#ifdef HAVE_REMOTE + if (p->rmt_clientside) + { + /* We are on an remote capture */ + return pcap_stats_ex_remote(p); + } +#endif + if(PacketGetStatsEx(p->adapter, (struct bpf_stat*) (&p->md.stat) ) != TRUE){ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStatsEx error: %s", pcap_win32strerror()); + return NULL; + } + return (&p->md.stat); +} + + +pcap_send_queue* +pcap_sendqueue_alloc(u_int memsize) +{ + + pcap_send_queue *tqueue; + + /* Allocate the queue */ + tqueue = (pcap_send_queue*)malloc(sizeof(pcap_send_queue)); + if(tqueue == NULL){ + return NULL; + } + + /* Allocate the buffer */ + tqueue->buffer = (char*)malloc(memsize); + if(tqueue->buffer == NULL){ + free(tqueue); + return NULL; + } + + tqueue->maxlen = memsize; + tqueue->len = 0; + + return tqueue; +} + +void +pcap_sendqueue_destroy(pcap_send_queue* queue) +{ + free(queue->buffer); + free(queue); +} + +int +pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) +{ + + if(queue->len + sizeof(struct pcap_pkthdr) + pkt_header->caplen > queue->maxlen){ + return -1; + } + + /* Copy the pcap_pkthdr header*/ + memcpy(queue->buffer + queue->len, pkt_header, sizeof(struct pcap_pkthdr)); + queue->len += sizeof(struct pcap_pkthdr); + + /* copy the packet */ + memcpy(queue->buffer + queue->len, pkt_data, pkt_header->caplen); + queue->len += pkt_header->caplen; + + return 0; +} + +u_int +pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync){ + + u_int res; + DWORD error; + int errlen; + + if (p->adapter==NULL) + { + sprintf(p->errbuf, "Cannot transmit a queue to an offline capture"); + return -1; + } + + res = PacketSendPackets(p->adapter, + queue->buffer, + queue->len, + (BOOLEAN)sync); + + if(res != queue->len){ + error = GetLastError(); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,error,0,p->errbuf,PCAP_ERRBUF_SIZE,NULL); + /* + * "FormatMessage()" "helpfully" sticks CR/LF at the end of + * the message. Get rid of it. + */ + errlen = strlen(p->errbuf); + if (errlen >= 2) { + p->errbuf[errlen - 1] = '\0'; + p->errbuf[errlen - 2] = '\0'; + } + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", p->errbuf); + } + + return res; +} + + +#ifdef WE_HAVE_TO_DELETE_IT_ASAP +int +pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data) +{ + /* Check the capture type */ + +#ifdef HAVE_REMOTE + if (p->rmt_clientside) + { + /* We are on an remote capture */ + if (!p->rmt_capstarted) + { + // if the capture has not started yet, please start it + if (pcap_startcapture_remote(p) ) + return -1; + p->rmt_capstarted= 1; + } + return pcap_next_ex_remote(p, pkt_header, pkt_data); + } +#endif + + if (p->adapter!=NULL) + { + /* We are on a live capture */ + int cc; + int n = 0; + register u_char *bp, *ep; + + cc = p->cc; + if (p->cc == 0) + { + /* capture the packets */ + if(PacketReceivePacket(p->adapter, p->Packet, TRUE) == FALSE) + { + sprintf(p->errbuf, "read error: PacketReceivePacket failed"); + return (-1); + } + + cc = p->Packet->ulBytesReceived; + + bp = p->Packet->Buffer; + } + else + bp = p->bp; + + /* + * Loop through each packet. + */ + ep = bp + cc; + if (bp < ep) + { + register int caplen, hdrlen; + caplen = ((struct bpf_hdr *)bp)->bh_caplen; + hdrlen = ((struct bpf_hdr *)bp)->bh_hdrlen; + + /* + * XXX A bpf_hdr matches a pcap_pkthdr. + */ + *pkt_header = (struct pcap_pkthdr*)bp; + *pkt_data = bp + hdrlen; + bp += BPF_WORDALIGN(caplen + hdrlen); + + p->bp = bp; + p->cc = ep - bp; + return (1); + } + else{ + p->cc = 0; + return (0); + } + } + else + { + /* We are on an offline capture */ + struct bpf_insn *fcode = p->fcode.bf_insns; + int status; + int n = 0; + + struct pcap_pkthdr *h=(struct pcap_pkthdr*)(p->buffer+p->bufsize-sizeof(struct pcap_pkthdr)); + + while (1) + { + status = sf_next_packet(p, h, p->buffer, p->bufsize); + if (status==1) + /* EOF */ + return (-2); + if (status==-1) + /* Error */ + return (-1); + + if (fcode == NULL || + bpf_filter(fcode, p->buffer, h->len, h->caplen)) + { + *pkt_header = h; + *pkt_data = p->buffer; + return (1); + } + + } + } +} +#endif + + +int +pcap_setuserbuffer(pcap_t *p, int size) + +{ + unsigned char *new_buff; + + if (!p->adapter) { + sprintf(p->errbuf,"Impossible to set user buffer while reading from a file"); + return -1; + } + + if (size<=0) { + /* Bogus parameter */ + sprintf(p->errbuf,"Error: invalid size %d",size); + return -1; + } + + /* Allocate the buffer */ + new_buff=(unsigned char*)malloc(sizeof(char)*size); + + if (!new_buff) { + sprintf(p->errbuf,"Error: not enough memory"); + return -1; + } + + free(p->buffer); + + p->buffer=new_buff; + p->bufsize=size; + + /* Associate the buffer with the capture packet */ + PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize); + + return 0; + +} + +int +pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks){ + + BOOLEAN res; + + if (p->adapter==NULL) + { + sprintf(p->errbuf, "live dump needs a physical interface"); + return -1; + } + + /* Set the packet driver in dump mode */ + res = PacketSetMode(p->adapter, PACKET_MODE_DUMP); + if(res == FALSE){ + sprintf(p->errbuf, "Error setting dump mode"); + return -1; + } + + /* Set the name of the dump file */ + res = PacketSetDumpName(p->adapter, filename, strlen(filename)); + if(res == FALSE){ + sprintf(p->errbuf, "Error setting kernel dump file name"); + return -1; + } + + /* Set the limits of the dump file */ + res = PacketSetDumpLimits(p->adapter, maxsize, maxpacks); + + return 0; +} + +int +pcap_live_dump_ended(pcap_t *p, int sync){ + + if (p->adapter == NULL) + { + sprintf(p->errbuf, "wrong interface type. A physical interface is needed"); + return -1; + } + + return PacketIsDumpEnded(p->adapter, (BOOLEAN)sync); + +} + + +int pcap_offline_filter(struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + struct bpf_insn *fcode = prog->bf_insns; + + if (fcode != NULL) + return (bpf_filter(fcode, (u_char *) pkt_data, header->len, header->caplen)); + else + return 0; +} + +PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p) +{ +#ifdef HAVE_AIRPCAP_API + if (p->adapter == NULL) + { + sprintf(p->errbuf, "wrong interface type. A physical interface is needed"); + return NULL; + } + + return PacketGetAirPcapHandle(p->adapter); +#else + return NULL; +#endif /* HAVE_AIRPCAP_API */ +} \ No newline at end of file diff --git a/winpcap/wpcap/Win32-Extensions/Win32-Extensions.h b/winpcap/wpcap/Win32-Extensions/Win32-Extensions.h new file mode 100644 index 0000000..d3b063b --- /dev/null +++ b/winpcap/wpcap/Win32-Extensions/Win32-Extensions.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __WIN32_EXTENSIONS_H__ +#define __WIN32_EXTENSIONS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Definitions */ + +/*! + \brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit(). +*/ +struct pcap_send_queue +{ + u_int maxlen; ///< Maximum size of the the queue, in bytes. This variable contains the size of the buffer field. + u_int len; ///< Current size of the queue, in bytes. + char *buffer; ///< Buffer containing the packets to be sent. +}; + +typedef struct pcap_send_queue pcap_send_queue; + +/*! + \brief This typedef is a support for the pcap_get_airpcap_handle() function +*/ +#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) +#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ +typedef struct _AirpcapHandle *PAirpcapHandle; +#endif + +#define BPF_MEM_EX_IMM 0xc0 +#define BPF_MEM_EX_IND 0xe0 + +/*used for ST*/ +#define BPF_MEM_EX 0xc0 +#define BPF_TME 0x08 + +#define BPF_LOOKUP 0x90 +#define BPF_EXECUTE 0xa0 +#define BPF_INIT 0xb0 +#define BPF_VALIDATE 0xc0 +#define BPF_SET_ACTIVE 0xd0 +#define BPF_RESET 0xe0 +#define BPF_SET_MEMORY 0x80 +#define BPF_GET_REGISTER_VALUE 0x70 +#define BPF_SET_REGISTER_VALUE 0x60 +#define BPF_SET_WORKING 0x50 +#define BPF_SET_ACTIVE_READ 0x40 +#define BPF_SET_AUTODELETION 0x30 +#define BPF_SEPARATION 0xff + +/* Prototypes */ +pcap_send_queue* pcap_sendqueue_alloc(u_int memsize); + +void pcap_sendqueue_destroy(pcap_send_queue* queue); + +int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data); + +u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync); + +HANDLE pcap_getevent(pcap_t *p); + +struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size); + +int pcap_setuserbuffer(pcap_t *p, int size); + +int pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks); + +int pcap_live_dump_ended(pcap_t *p, int sync); + +int pcap_offline_filter(struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data); + +int pcap_start_oem(char* err_str, int flags); + +PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p); + +#ifdef __cplusplus +} +#endif + +#endif //__WIN32_EXTENSIONS_H__ diff --git a/winpcap/wpcap/Win32-Extensions/version.aps b/winpcap/wpcap/Win32-Extensions/version.aps new file mode 100644 index 0000000000000000000000000000000000000000..cf421007ac058deac1ddc34ac7a42f9b322b07e4 GIT binary patch literal 32508 zcwV)g36Ld8S;xQL-S9xr6%7xJ&;hRX)jwyIwD^f2;bn4N{z zVS1foS#2Llv*hAqhJvdFsQ2Lrf2<<-Gl zBqa6+m^7Wa{Vq(FO3}uH0duZ@y9PG)s@0w-tF*{hX+A3;fCs`xn#8NB4(l|A8*U7a z!*O|(JT{KXY87VbPQJ>-tcJl|G8q{>%tCdsKr&QhV39K2*_B6)6$>mD6?I+A5l$5x zS}@EHkjxYrH6$v^M3ikp27zP~o9UDch7xVss7=aXEa8?7yR;0Zl1^=^6Em1ewB4Y( zD6%?TR1#oPGI&G-X4yfc)<7HEDoWY|hoTVp)j&v~0Af!o2^BoO>3@f+>J7v09h_XrF zK$U&cu%b*wUaxkG@)X=)U;4Y9YkC}J_F-7#YU?n04e4>};v9z^`!HGVH}KQn%_BaJ zcWGO7vL^8}{L0`lO?Y0Yv*-*r87ms5YLh={wBj6xMR(yB{t~dN(s8)8(d&9gk5D1j zG4hvVv0|^(XbfM&P$^=KCfJ_a=tP)@nr*^Lu}Un$QZj5k&cH@EJGn{| z%=%)ns?$1?RbR-~??(+wlT6G-RfRhZ4dBNO-4)qlUL>|+2tVnGdnM+PND_TNplSp^ zZB*DqFR&7>@E&U-8N<&STtts)A~E+UY9{dWDqFJ@NiOzfC^lB`bQ4-EM6QDac!mj% zv!W6@dhrlw$TZhn1crK$ld<&k( zk4jR!vJIZX^EqCWVlQoTybUife7Q)%y2(TcFJzgBi^V~glL&s5V1ZraJWMmqV)!+~ z=H(JUl$B0TFn||xmWiNcFLBvWvjBeGWh2do@KTqJH5-tre+g(h0C@y z+k{uTY^vE7yvk+UnoZ%=p1cn<+=kb9U{f+7yw(GoqKV*j9@vyk46paVrf?E?g9kRH zBjAl5*c8tU-ekipY_ISP-mH*FQXC#-B2?{9FdV>JSa{PHAPeBFgke3?!9#c(30~?G z3`cN}37uh^rGv-tTPApc$UNmKRTr78D)9pEy(v3KSi~pHf;ava}%+_%lUha~(!S zbD72ixVH-yCmZoNfOo4<+4{@=Mx4~)LwJt~mlsv&YBL_edkt7tO&<`9$M8NCE(hRp zpe?y36L^1jgbvw+52%nt%t9R95wZmzR78!{u^Z6^H5tH%RIqF+NpJuk*0sJU=QvWF z6-^_&Ie?EUP-L>3sj$%6i-n_H_*lo(^_8`+(ky_F+YEEl7WojnmrpRdE3fk^MU_^J z;FGpuQDU!E)~RStFou8W1Q>C&>YCyqHa!2@c9U(NU^=%Eru)AfjAM{R(^ro$@%Ooc zW^gmY#KQ)s@_$Y7alu2IPHlwAzQ)0)iejGTnor76(OL@w_%s7c(S?uU(@l7|tP66>O))k1BT>%rW^b?16bt$OhGk*7BMif* zLBdjfU8dNqf2IjeM2-DwrO60Biyn{*Jvf+Rdw#tE(Lp;Dnqpi2*?h((yraU|&` z_km0pp0tEbte>OKgX0Sv;F`*`jm7%;l(gN!HWuj@P|#M8ZLA<)NI_dSwy|zJNCNw5 z_aSZS@UbbD4^C2x4}0*{6wHgg1_ba>3&?DDM-Aad3(Bl^a0E9|C=;yPJdMZjFp6ce zDaOu|;_iN$VU-LhDMf{YY0dDG4=Jm|>O@-~W_Z;{2F`JWzME!=Ml+Zgl!)p?7{@rA zE=tvb&XN$e4430s*vDJG0WPf#}^uJ!lMnA&)g~)@1d{_Uf?t2N|Yr&zJz;t(}YoT zEDk*qb8KEixoyAL#3RU^;+F!fHL+HVpfjN;R7S0LjlR1DWeclF2HP?G|Q9wP@;bIe>?3!T5| z08Sc(>I-Fmr&$08q(aAax`&TBgb(4A;Y}yoj1iHJ;IZUrZ2Wcb7*3N~5avrYW<)T7 zuQ6a&7N>;H;&c-pXWdt-c2}Bh!OFgQRQ5ER!WmMT)H52P+wgdHWLOa#!dZr!=QyH? z;5JfrI94MphI8!XI0ReCa&JfHdk))9YXK-j>l-BcbLHYIo zzSeLxbkg@E)dcW$B>i%(z`{c~PpXz2kUowy)eTbFJ6|V$Yb3uZcpKoE0Nc@PUlSmw&8NWq{8v3mW6Po zl`T4%yc*4TU?wLx?lO`YHj-FWb)mY3RZ_%S6u?t_B2{@h(Gb4Dh_JtE6`GFV8+}n= zuO};S7s(jzCNf!XaIB_>Nm?+0r+Sl8hh^Oj7-w>J%%k(5xD0g@EreibYsf^4Ua}7Y<9mhcmo1nT7#;ujjy3JK~+m z8JF+#9Zn@9cp8^fbt&79X7o0b6ENTJL=z@yv5J=1`s-}q5cUVSC_1Q{7&hStIb3#` z+=3tCklt5vLgt6LfZm&OQszgTE8X2#-EA)CHh#QUw+QQ9tqR~L995FytutF@y6ACe z@so~3kLhFq>r0P=i=XNf?U!j&G&sWeX*W&n0Ler)fuHG@k?1zzXN^ve%$tr_aqNG8 z!F$ISdERLP_(c+jDEH)4{Ib%8jlJ+M8QRq5NTU(_a*Ol;4qFg<@-h61@8qaVXHD!A zczS;ep(UH}3?pfpv~Efi`4&9W7X_6};aNTj-rqQ!*CU|-d+cZXL~>}slp#E)r%;<& z0@OtCT%*|$wLQSqni!r(3*M_q;Q3DOv3AB`*$4!@z?&G=rfbOzUg$`$Lr+!nr6ky& zzsN}1dqioH<|e@I{KfuQDZ@o;+1ToX~t5UdQ+@UUzH=G!EhQ3|GkYTpZ#E-oP;S zf+sp0!yBE%RVPg15_l8iqL^tU;LW5`me`kf*Et%%Z!$)&a}>Z^7?zD*k!QL=h=%Z1 z#<6x4v##W$5xk8FRC8!z7{fhGfQ8!5X(FG%Z@E0q!m84I6W;FfD&7_IPz$!;9jySL zdg6G6cVi}&d0OK*Ha#ga9Z@`h-!ZyoPOF)moDD|<_ya?mC2@iS_(Ov+?zl(_4R{=ri`dqXVfTbF6s%7*YE=gf&tA8|7^6K#FQ=gp6@`kZ5hkqf>m zKU%Z}|744rQb|N6@IO);@bUAX-P$n6!5voWO1^gB=3^T^=DYo@ZghxGqaU|bQBjYSf|EE*r-c#44*VjlFm{?68JY0OA_KRHs48e*{$N`!;bY-*iJYNvHQ5s z)+YElN}J?k_W{>fxS4g5scF0UA$B4gwhFHnHnDhz=;7HAdy!AE71+khv#1xllwu5@ zYAbYmx6G|s%prCspLR``?cKUIFJ8=sNdOOEP__-t%-t{fUNffb~8IkL7U(BKUDW?aNU$*JP6Xai?h zk*i%DJb|w?C#}P%eHBsD0o>41x#+SlXS0%Q2S$S}JoO_C)6=*O8N$t!2y6LF3P$iq zBhV|I&2yNfV|cWoy5!Z;l4KJI32Po;B-n(AoKw!uwJY$FZb59QoYvK=rxHyeF-Q*E zBH6zR#kN5hrXDdd6h}fc6ROiq7EGmL2)jH7dcIN75u~JM>4j%Cw=^1TZ*9Tcz>?j)I1cCH6U}|S%4;QR;{4ys<3?a$`sy$$F~@tC+kEmsHrr- zD3Al%b2c?-47Zy+$sw?;Ir@d)^EQx;LM2H6PqIl>A7mO0;Q~YHDNROjL~2W2rYD44 z)ehtW+8u^0Y#@8Q?<1#IFL?#Bt9x1-nyA>-D~{^yFd7agTks1k&ujDPSMnkKC<^jCT&jZbeaF5~YO-A`JpxAf-?_kV&4H6Xr z{C2BYv`LJ^ylx-l1rCjW&#Pz`E(G>4?{pOM(WqUl7C2P?eMccD@yv9Kz)|xb7>#Hr zBWKGzmIWH?7lmgc9KgG%4#&{tENdF5Fn~X{;Ib}edI4JVA^ZvDNxGNHW#Q=Hlqd@= z8Nr`AQRrLDbavqw{>&r7zK&=n@aI$$VRlpf#z9fy18~&bi{U2x1=T50QFjvqBHV(% z^hDIo(u!~jf5jsRGg-U`-Bk>?;jgWX4`<0#0LpoU&09fmZe2c z%VL^$^fHhLW4PBYWV56p7gyiyjewSjfcNy2oaQrlFXdR*jyopqU`3H-fv z1Ly@W)XB*fT?4gn6aK*?Tvno(dZANHM7HxdVWbEXn*!#}PO z%9nl*y7e6#Nx?^`8rwU}YB#SL%8A|fT>}wC@X2Es3sSp_uL8mvm2edwsjYs zfR9nl&f4_N;Nxq=N)r#@6V}CT(q>)YIDk)j$}rB-MO1`kLas|Zgn#iBH|gTz5&Wxt zN;NBIDqK8PP(6LjBwGOKAGXG?5O1C82x_srf!=uxC@%Hred={T>vhlEPul4^vif)6p{ED1%xUnmTYnpQK zUT1b4*adJ({%KQwo|~NWyi-mN)9sn4NR#4(+{z730x)nx?ixo)ESKBVrfzva7|At@ zk^TjTHaM6V>tE8HT)wG3(Z3yF_p_-#=7rp&EkEh^xTpFTH6^+&KkGZmo}4GaWODv$ zyYgY(rg|_@x-T}o#53ACpKH?HCl0QP}o%8*4#rwlnVQ-*}FDMLco zlp#IFo-(9YNI%`0DMN>mDMN>KQ-%&9Q-+?iwNr);qEm(rw5ALlYNiZ5iD{<{9mJ*# z9d1n-dMTMQ^l~$0=s!7`GV~sAO&NL>X3CIbGi69CgEM7l-2!yVkODeoNW$rqAw9jB zG9;m%Rjdu!ptx&iI+(4Ub%Av4tP8Z)&bqUDR>ufqt78`Nt&S0aXLXEFXLXD+YjupC z(_I}Sl&_8vR5-pt7DAP)iLYV z@XY-CIGOqPVSDDEr|WG!eia*rdHgB}?eVMF@Wk!Ry7ShJCjb$%5d*7;Rma-p@Ut&3M-uXRalJqRangNt8gjx ztFWl$SD}gHS7CywUxf~J{VGVf?N>p7b(E0YdgmFY&!Z;%?VH{DHFwTfe7)Qh4TD~g9ybh{8Lu0LRT_>P2EA^! z8wMfF4THzX+%VkY=WZB00@n?rN1^eigJ+f-2B*vogJatbgBFP24TC5gHw;>#eQp?p zd)zSS(Zmgd)&k27g8b1+%OzQ-7tIy+HM%$!)-SVN8)kAaHH|KVK^e{ zhT%Z!hT%Z&hT#af8-{zO{cafjI_ieusvI{ASK@KQ=oMLR7@jow+%VS2EH@0I^SWX9 z?|9n{gT~>yVGzpQFgn!ZhT%QA?S`?Yh0qc!i(WSjZxps0hF8MfFuWqK8%AHDQa22u z>2<@f3ckk;!_7T&!|*4@a>H;XjvEG%^toa5#6sOLs6=)g)D43(=7!-O%G@xxfV*LE z?sdc9BCi_;7x~;UxW?~>!ByN1!=!{C^?VQ|dcFxsHw;=Sxf=#& z%ngHM?uNm+h1{3$XVYoW48%A&Wa5oGl^toX$NuL`AldW~b z;AdUyhQY)=ZWx}7c-%1D;&a_Fc-dXW4Z~MF9ybj4%>8Z{OnVhK3|{bFHw;gvEH?~Z zpS^AvOtj7o!&4is=7!iHprh~a*aDmSa!xxFi4TH$~cEA!z z^Matg1J>cb9k7nb-2v;9&>gT2XFFiMobG^i6UukMIttGY*q&JE4%psk=nmMv)L1)U z`x9jCfb|ufwFA}>xI17S3EKhdJqhtXtbWJ767=vjetYL3h9s725$z z2;Biog6$o!OmFXiCD7dgOJM&F*j|x-T~4WH{VKKtmfrNf9k7ghcEEZRbO)>l+dE)A z0=@&*BcVHBoeNBM!1@^90ZTM|2doG29k6Z*(jBmV%6GuJD$fpBt6q6_!1nNN2Q1;v z4p`3I9k89EcL%IrL3hBq3cdr@Rk%A~iDvB%SWCxuz}nE=0c&yp4p=t|&kk6hi0^>4 zG;4OiS~?|SJ79eg(H*c(1fCtRcE)`>VEbaRcfj(r_;$duLbi9n`XjJ+!1k4#<};i7 zcEEaa>)8Qosrq)nI+@`+VC`7?cfdM2z5~|20oLq*^$DFFus)GYnY{zndrsdD*mXj8 z2dt&O+78%tVy$6SYW)saPjt=>SW9!Y9kA=fN)xjR*S7=KSB5=1V7A6wm`iAQOj;Vc$*LQytcmU?>hU>=oa}O$5;ZFf2 zeoCQ$9Dh&o=L|o~uh(7ok^fSE+!n5dF9PWPzom)iI{eq}e{8?L`&y~1;4)l zz}ODqJe>NhTQ>YkUa%c zdPeEwR}3M33(R+oA!p%&f{0 zS&aJ*jO|AJj_~s(RNsc5rREqOe~4)|ssY>t+xV?F>Q3SQY46Jw4?U4|Xh9>EnnO6G2%;yhHjI*VsG#GgkPej9$0 zXFh7`$`PJTetngy2PSVd@-wJDhvjevKYv|UD*$eW`=PdI(stOCSzGoOJY{zi#&jP4 z0X#&VXQ7V06PZk3gsGOt-qyswhc#Ynjxg*B#&OxIcl+v`i>@X-u_>ct>il=&_xY~A zTvVxlN|WyUJMr?G(pOJ(x+^@NEYCxgW1j8=_$+T-Q2r$pe3EgYVroEmr$U{vGuM*8d%K`FGCmf%SjqT>1{2e&l-J zfqU`$=0~mHyD!6&Th{MumwVD*aLf8V>9QX +- Building outside the source code tree fixed. +- Changed to write out time stamps with 32-bit seconds and microseconds + fields, regardless of whether those fields are 32 bits or 64 bits in + the OS's native "struct timeval". +- Changed "pcap_lookupdev()" to dynamically grow the buffer into which + the list of interfaces is read as necessary in order to hold the + entire list. + +Greg Troxel +- Added a new "pcap_compile_nopcap()", which lets you compile a filter + expression into a BPF program without having an open live capture or + capture file. + +v0.4 Sat Jul 25 12:40:09 PDT 1998 + +- Fix endian problem with DLT_NULL devices. From FreeBSD via Bill + Fenner (fenner@parc.xerox.com) + +- Fix alignment problem with FDDI under DLPI. This was causing core + dumps under Solaris. + +- Added configure options to disable flex and bison. Resulted from a + bug report by barnett@grymoire.crd.ge.com (Bruce Barnett). Also added + options to disable gcc and to force a particular packet capture type. + +- Added support for Fore ATM interfaces (qaa and fa) under IRIX. Thanks + to John Hawkinson (jhawk@mit.edu) + +- Change Linux PPP and SLIP to use DLT_RAW since the kernel does not + supply any "link layer" data. + +- Change Linux to use SIOCGIFHWADDR ioctl to determine link layer type. + Thanks to Thomas Sailer (sailer@ife.ee.ethz.ch) + +- Change IRIX PPP to use DLT_RAW since the kernel does not supply any + "link layer" data. + +- Modified to support the new BSD/OS 2.1 PPP and SLIP link layer header + formats. + +- Added some new SGI snoop interface types. Thanks to Steve Alexander + (sca@refugee.engr.sgi.com) + +- Fixes for HP-UX 10.20 (which is similar to HP-UX 9). Thanks to + Richard Allen (ra@hp.is) and Steinar Haug (sthaug@nethelp.no) + +- Fddi supports broadcast as reported by Jeff Macdonald + (jeff@iacnet.com). Also correct ieee802 and arcnet. + +- Determine Linux pcap buffer size at run time or else it might not be + big enough for some interface types (e.g. FDDI). Thanks to Jes + Sorensen (Jes.Sorensen@cern.ch) + +- Fix some linux alignment problems. + +- Document promisc argument to pcap_open_live(). Reported by Ian Marsh + (ianm@sics.se) + +- Support Metricom radio packets under Linux. Thanks to Kevin Lai + (laik@gunpowder.stanford.edu) + +- Bind to interface name under Linux to avoid packets from multiple + interfaces on multi-homed hosts. Thanks to Kevin Lai + (laik@gunpowder.stanford.edu) + +- Change L_SET to SEEK_SET for HP-UX. Thanks to Roland Roberts + (rroberts@muller.com) + +- Fixed an uninitialized memory reference found by Kent Vander Velden + (graphix@iastate.edu) + +- Fixed lex pattern for IDs to allow leading digits. As reported by + Theo de Raadt (deraadt@cvs.openbsd.org) + +- Fixed Linux include file problems when using GNU libc. + +- Ifdef ARPHRD_FDDI since not all versions of the Linux kernel have it. + Reported reported by Eric Jacksch (jacksch@tenebris.ca) + +- Fixed bug in pcap_dispatch() that kept it from returning on packet + timeouts. + +- Changed ISLOOPBACK() macro when IFF_LOOPBACK isn't available to check + for "lo" followed by an eos or digit (newer versions of Linux + apparently call the loopback "lo" instead of "lo0"). + +- Fixed Linux networking include files to use ints instead of longs to + avoid problems with 64 bit longs on the alpha. Thanks to Cristian + Gafton (gafton@redhat.com) + +v0.3 Sat Nov 30 20:56:27 PST 1996 + +- Added Linux support. + +- Fixed savefile bugs. + +- Solaris x86 fix from Tim Rylance (t.rylance@elsevier.nl) + +- Add support for bpf kernel port filters. + +- Remove duplicate atalk protocol table entry. Thanks to Christian + Hopps (chopps@water.emich.edu) + +- Fixed pcap_lookupdev() to ignore nonexistent devices. This was + reported to happen under BSD/OS by David Vincenzetti + (vince@cryptonet.it) + +- Avoid solaris compiler warnings. Thanks to Bruce Barnett + (barnett@grymoire.crd.ge.com) + +v0.2.1 Sun Jul 14 03:02:26 PDT 1996 + +- Fixes for HP-UX 10. Thanks in part to to Thomas Wolfram + (wolf@prz.tu-berlin.de) and Rick Jones (raj@hpisrdq.cup.hp.com) + +- Added support for SINIX. Thanks to Andrej Borsenkow + (borsenkow.msk@sni.de) + +- Fixes for AIX (although this system is not yet supported). Thanks to + John Hawkinson (jhawk@mit.edu) + +- Use autoconf's idea of the top level directory in install targets. + Thanks to John Hawkinson. + +- Add missing autoconf packet capture result message. Thanks to Bill + Fenner (fenner@parc.xerox.com) + +- Fixed padding problems in the pf module. + +- Fixed some more alignment problems on the alpha. + +- Added explicit netmask support. Thanks to Steve Nuchia + (steve@research.oknet.com) + +- Fixed to handle raw ip addresses such as 0.0.0.1 without "left + justifing" + +- Add "sca" keyword (for DEC cluster services) as suggested by Terry + Kennedy (terry@spcvxa.spc.edu) + +- Add "atalk" keyword as suggested by John Hawkinson. + +- Add "igrp" keyword. + +- Fixed HID definition in grammar.y to be a string, not a value. + +- Use $CC when checking gcc version. Thanks to Carl Lindberg + (carl_lindberg@blacksmith.com) + +- Removed obsolete reference to pcap_immediate() from the man page. + Michael Stolarchuk (mts@terminator.rs.itd.umich.edu) + +- DLT_NULL has a 4 byte family header. Thanks to Jeffrey Honig + (jch@bsdi.com) + +v0.2 Sun Jun 23 02:28:42 PDT 1996 + +- Add support for HP-UX. Resulted from code contributed by Tom Murray + (tmurray@hpindck.cup.hp.com) and Philippe-Andri Prindeville + (philipp@res.enst.fr) + +- Update INSTALL with a reminder to install include files. Thanks to + Mark Andrews (mandrews@aw.sgi.com) + +- Fix bpf compiler alignment bug on the alpha. + +- Use autoconf to detect architectures that can't handle misaligned + accesses. + +- Added loopback support for snoop. Resulted from report Steve + Alexander (sca@engr.sgi.com) + +v0.1 Fri Apr 28 18:11:03 PDT 1995 + +- Fixed compiler and optimizer bugs. The BPF filter engine uses unsigned + comparison operators, while the code generator and optimizer assumed + signed semantics in several places. Thanks to Charlie Slater + (cslater@imatek.com) for pointing this out. + +- Removed FDDI ifdef's, they aren't really needed. Resulted from report + by Gary Veum (veum@boa.gsfc.nasa.gov). + +- Add pcap-null.c which allows offline use of libpcap on systems that + don't support live package capture. This feature resulting from a + request from Jan van Oorschot (j.p.m.voorschot@et.tudelft.nl). + +- Make bpf_compile() reentrant. Fix thanks to Pascal Hennequin + (Pascal.Hennequin@hugo.int-evry.fr). + +- Port to GNU autoconf. + +- Fix pcap-dlpi.c to work with isdn. Resulted from report by Flemming + Johansen (fsj@csd.cri.dk). + +- Handle multi-digit interface unit numbers (aka ppa's) under dlpi. + Resulted from report by Daniel Ehrlich (ehrlich@cse.psu.edu). + +- Fix pcap-dlpi.c to work in non-promiscuous mode. Resulted from report + by Jeff Murphy (jcmurphy@acsu.buffalo.edu). + +- Add support for "long jumps". Thanks to Jeffrey Mogul + (mogul@pa.dec.com). + +- Fix minor problems when compiling with BDEBUG as noticed by Scott + Bertilson (scott@unet.umn.edu). + +- Declare sys_errlist "const char *const" to avoid problems under + FreeBSD. Resulted from report by jher@eden.com. + +v0.0.6 Fri Apr 28 04:07:13 PDT 1995 + +- Add missing variable declaration missing from 0.0.6 + +v0.0.5 Fri Apr 28 00:22:21 PDT 1995 + +- Workaround for problems when pcap_read() returns 0 due to the timeout + expiring. + +v0.0.4 Thu Apr 20 20:41:48 PDT 1995 + +- Change configuration to not use gcc v2 flags with gcc v1. + +- Fixed a bug in pcap_next(); if pcap_dispatch() returns 0, pcap_next() + should also return 0. Thanks to Richard Stevens (rstevens@noao.edu). + +- Fixed configure to test for snoop before dlpi to avoid problems under + IRIX 5. Thanks to J. Eric Townsend (jet@abulafia.genmagic.com). + +- Hack around deficiency in Ultrix's make. + +- Fix two bugs related to the Solaris pre-5.3.2 bufmod bug; handle + savefiles that have more than snapshot bytes of data in them (so we + can read old savefiles) and avoid writing such files. + +- Added checkioctl which is used with gcc to check that the + "fixincludes" script has been run. + +v0.0.3 Tue Oct 18 18:13:46 PDT 1994 + +- Fixed configure to test for snoop before dlpi to avoid problems under + IRIX 5. Thanks to J. Eric Townsend (jet@abulafia.genmagic.com). + +v0.0.2 Wed Oct 12 20:56:37 PDT 1994 + +- Implement timeout in the dlpi pcap_open_live(). Thanks to Richard + Stevens. + +- Determine pcap link type from dlpi media type. Resulted from report + by Mahesh Jethanandani (mahesh@npix.com). + +v0.0.1 Fri Jun 24 14:50:57 PDT 1994 + +- Fixed bug in nit_setflags() in pcap-snit.c. The streams ioctl timeout + wasn't being initialized sometimes resulting in an "NIOCSFLAGS: + Invalid argument" error under OSF/1. Reported by Matt Day + (mday@artisoft.com) and Danny Mitzel (dmitzel@whitney.hitc.com). + +- Turn on FDDI support by default. + +v0.0 Mon Jun 20 19:20:16 PDT 1994 + +- Initial release. + +- Fixed bug with greater/less keywords, reported by Mark Andrews + (mandrews@alias.com). + +- Fix bug where '|' was defined as BPF_AND instead of BPF_OR, reported + by Elan Amir (elan@leeb.cs.berkeley.edu). + +- Machines with little-endian byte ordering are supported thanks to + Jeff Mogul. + +- Add hack for version 2.3 savefiles which don't have caplen and len + swapped thanks to Vern Paxson. + +- Added "&&" and "||" aliases for "and" and "or" thanks to Vern Paxson. + +- Added length, inbound and outbound keywords. diff --git a/winpcap/wpcap/libpcap/CREDITS b/winpcap/wpcap/libpcap/CREDITS new file mode 100644 index 0000000..483482d --- /dev/null +++ b/winpcap/wpcap/libpcap/CREDITS @@ -0,0 +1,103 @@ +This file lists people who have contributed to libpcap: + +The current maintainers: + Bill Fenner + Fulvio Risso + Guy Harris + Hannes Gredler + Jun-ichiro itojun Hagino + Michael Richardson + +Additional people who have contributed patches: + + Alan Bawden + Alexey Kuznetsov + Albert Chin + Andrew Brown + Antti Kantee + Arkadiusz Miskiewicz + Armando L. Caro Jr. + Assar Westerlund + Brian Ginsbach + Charles M. Hannum + Chris G. Demetriou + Chris Lightfoot + Chris Pepper + Daniele Orlandi + Darren Reed + David Kaelbling + David Young + Dean Gaudet + Don Ebright + Dug Song + Eric Anderson + Erik de Castro Lopo + Franz Schaefer + Gianluca Varenni + Gilbert Hoyek + Gisle Vanem + Graeme Hewson + Greg Stark + Greg Troxel + Guillaume Pelat + Hyung Sik Yoon + Igor Khristophorov + Jan-Philip Velders + Jason R. Thorpe + Javier Achirica + Jean Tourrilhes + Jefferson Ogata + Jesper Peterson + John Bankier + Jon Lindgren + Juergen Schoenwaelder + Kazushi Sugyo + Klaus Klein + Koryn Grant + Krzysztof Halasa + Lorenzo Cavallaro + Loris Degioanni + Love Hörnquist-Åstrand + Maciej W. Rozycki + Marcus Felipe Pereira + Mark C. Brown + Mark Pizzolato + Martin Husemann + Matthew Luckie + Mike Kershaw + Mike Wiacek + Monroe Williams + Nicolas Dade + Octavian Cerna + Olaf Kirch + Ollie Wild + Onno van der Linden + Patrick Marie + Paul Mundt + Pavel Kankovsky + Pawel Pokrywka + Peter Fales + Peter Jeremy + Phil Wood + Rafal Maszkowski + Rick Jones + Scott Barron + Scott Gifford + Sebastian Krahmer + Shaun Clowes + Solomon Peachy + Stefan Hudson + Takashi Yamamoto + Tanaka Shin-ya + Tony Li + Torsten Landschoff + Uns Lider + Uwe Girlich + Xianjie Zhang + Yen Yen Lim + Yoann Vandoorselaere + +The original LBL crew: + Steve McCanne + Craig Leres + Van Jacobson diff --git a/winpcap/wpcap/libpcap/ChmodBPF/ChmodBPF b/winpcap/wpcap/libpcap/ChmodBPF/ChmodBPF new file mode 100644 index 0000000..ee37121 --- /dev/null +++ b/winpcap/wpcap/libpcap/ChmodBPF/ChmodBPF @@ -0,0 +1,33 @@ +#! /bin/sh + +. /etc/rc.common + +StartService () +{ + # + # Unfortunately, Mac OS X's devfs is based on the old FreeBSD + # one, not the current one, so there's no way to configure it + # to create BPF devices with particular owners or groups. + # This startup item will make it owned by the admin group, + # with permissions rw-rw----, so that anybody in the admin + # group can use programs that capture or send raw packets. + # + # Change this as appropriate for your site, e.g. to make + # it owned by a particular user without changing the permissions, + # so only that user and the super-user can capture or send raw + # packets, or give it the permissions rw-r-----, so that + # only the super-user can send raw packets but anybody in the + # admin group can capture packets. + # + chgrp admin /dev/bpf* + chmod g+rw /dev/bpf* +} + +StopService () +{ + return 0; +} + +RestartService () { StartService; } + +RunService "$1" diff --git a/winpcap/wpcap/libpcap/ChmodBPF/StartupParameters.plist b/winpcap/wpcap/libpcap/ChmodBPF/StartupParameters.plist new file mode 100644 index 0000000..545e2a6 --- /dev/null +++ b/winpcap/wpcap/libpcap/ChmodBPF/StartupParameters.plist @@ -0,0 +1,4 @@ +{ + Description = "Change BPF permissions"; + Provides = ("Non-root permission to capture or send raw packets"); +} diff --git a/winpcap/wpcap/libpcap/FILES b/winpcap/wpcap/libpcap/FILES new file mode 100644 index 0000000..879d74b --- /dev/null +++ b/winpcap/wpcap/libpcap/FILES @@ -0,0 +1,125 @@ +CHANGES +ChmodBPF/ChmodBPF +ChmodBPF/StartupParameters.plist +CREDITS +FILES +INSTALL.txt +LICENSE +Makefile.in +README +README.aix +README.dag +README.hpux +README.linux +README.macosx +README.septel +README.tru64 +README.Win32 +SUNOS4/nit_if.o.sparc +SUNOS4/nit_if.o.sun3 +SUNOS4/nit_if.o.sun4c.4.0.3c +TODO +VERSION +acconfig.h +aclocal.m4 +arcnet.h +atmuni31.h +bpf/net/bpf_filter.c +bpf_dump.c +bpf_image.c +config.guess +config.h.in +config.sub +configure +configure.in +etherent.c +ethertype.h +fad-getad.c +fad-gifc.c +fad-glifc.c +fad-null.c +fad-win32.c +gencode.c +gencode.h +grammar.y +inet.c +install-sh +lbl/os-aix4.h +lbl/os-hpux11.h +lbl/os-osf4.h +lbl/os-osf5.h +lbl/os-solaris2.h +lbl/os-sunos4.h +lbl/os-ultrix4.h +llc.h +missing/snprintf.c +mkdep +msdos/bin2c.c +msdos/common.dj +msdos/makefile +msdos/makefile.dj +msdos/makefile.wc +msdos/ndis2.c +msdos/ndis2.h +msdos/ndis_0.asm +msdos/pkt_rx0.asm +msdos/pkt_rx1.s +msdos/pktdrvr.c +msdos/pktdrvr.h +msdos/readme.dos +nametoaddr.c +nlpid.h +optimize.c +packaging/pcap.spec +packaging/pcap.spec.in +pcap-bpf.c +pcap-bpf.h +pcap-dag.c +pcap-dag.h +pcap-dlpi.c +pcap-dos.c +pcap-dos.h +pcap-enet.c +pcap-int.h +pcap-linux.c +pcap-namedb.h +pcap-nit.c +pcap-nit.h +pcap-null.c +pcap-pf.c +pcap-pf.h +pcap-septel.c +pcap-septel.h +pcap-stdinc.h +pcap-snit.c +pcap-snoop.c +pcap-win32.c +pcap.3 +pcap.c +pcap.h +pf.h +ppp.h +savefile.c +scanner.l +sll.h +sunatmpos.h +Win32/Include/Gnuc.h +Win32/Include/addrinfo.h +Win32/Include/bittypes.h +Win32/Include/cdecl_ext.h +Win32/Include/inetprivate.h +Win32/Include/ip6_misc.h +Win32/Include/sockstorage.h +Win32/Include/arpa/nameser.h +Win32/Include/net/if.h +Win32/Include/net/netdb.h +Win32/Include/net/paths.h +Win32/Src/ffs.c +Win32/Src/getaddrinfo.c +Win32/Src/getnetbynm.c +Win32/Src/getnetent.c +Win32/Src/getopt.c +Win32/Src/getservent.c +Win32/Src/inet_aton.c +Win32/Src/inet_net.c +Win32/Src/inet_pton.c diff --git a/winpcap/wpcap/libpcap/INSTALL.txt b/winpcap/wpcap/libpcap/INSTALL.txt new file mode 100644 index 0000000..d2c0180 --- /dev/null +++ b/winpcap/wpcap/libpcap/INSTALL.txt @@ -0,0 +1,383 @@ +@(#) $Header: /tcpdump/master/libpcap/INSTALL.txt,v 1.12.2.1 2005/06/20 21:30:14 guy Exp $ (LBL) + +To build libpcap, run "./configure" (a shell script). The configure +script will determine your system attributes and generate an +appropriate Makefile from Makefile.in. Next run "make". If everything +goes well you can su to root and run "make install". However, you need +not install libpcap if you just want to build tcpdump; just make sure +the tcpdump and libpcap directory trees have the same parent +directory. + +If configure says: + + configure: warning: cannot determine packet capture interface + configure: warning: (see INSTALL for more info) + +then your system either does not support packet capture or your system +does support packet capture but libpcap does not support that +particular type. (If you have HP-UX, see below.) If your system uses a +packet capture not supported by libpcap, please send us patches; don't +forget to include an autoconf fragment suitable for use in +configure.in. + +It is possible to override the default packet capture type, although +the circumstance where this works are limited. For example if you have +installed bpf under SunOS 4 and wish to build a snit libpcap: + + ./configure --with-pcap=snit + +Another example is to force a supported packet capture type in the case +where the configure scripts fails to detect it. + +You will need an ANSI C compiler to build libpcap. The configure script +will abort if your compiler is not ANSI compliant. If this happens, use +the GNU C compiler, available via anonymous ftp: + + ftp://ftp.gnu.org/pub/gnu/gcc/ + +If you use flex, you must use version 2.4.6 or higher. The configure +script automatically detects the version of flex and will not use it +unless it is new enough. You can use "flex -V" to see what version you +have (unless it's really old). The current version of flex is available +via anonymous ftp: + + ftp://ftp.ee.lbl.gov/flex-*.tar.Z + +As of this writing, the current version is 2.5.4. + +If you use bison, you must use flex (and visa versa). The configure +script automatically falls back to lex and yacc if both flex and bison +are not found. + +Sometimes the stock C compiler does not interact well with flex and +bison. The list of problems includes undefined references for alloca. +You can get around this by installing gcc or manually disabling flex +and bison with: + + ./configure --without-flex --without-bison + +If your system only has AT&T lex, this is okay unless your libpcap +program uses other lex/yacc generated code. (Although it's possible to +map the yy* identifiers with a script, we use flex and bison so we +don't feel this is necessary.) + +Some systems support the Berkeley Packet Filter natively; for example +out of the box OSF and BSD/OS have bpf. If your system does not support +bpf, you will need to pick up: + + ftp://ftp.ee.lbl.gov/bpf-*.tar.Z + +Note well: you MUST have kernel source for your operating system in +order to install bpf. An exception is SunOS 4; the bpf distribution +includes replacement kernel objects for some of the standard SunOS 4 +network device drivers. See the bpf INSTALL document for more +information. + +If you use Solaris, there is a bug with bufmod(7) that is fixed in +Solaris 2.3.2 (aka SunOS 5.3.2). Setting a snapshot length with the +broken bufmod(7) results in data be truncated from the FRONT of the +packet instead of the end. The work around is to not set a snapshot +length but this results in performance problems since the entire packet +is copied to user space. If you must run an older version of Solaris, +there is a patch available from Sun; ask for bugid 1149065. After +installing the patch, use "setenv BUFMOD_FIXED" to enable use of +bufmod(7). However, we recommend you run a more current release of +Solaris. + +If you use the SPARCompiler, you must be careful to not use the +/usr/ucb/cc interface. If you do, you will get bogus warnings and +perhaps errors. Either make sure your path has /opt/SUNWspro/bin +before /usr/ucb or else: + + setenv CC /opt/SUNWspro/bin/cc + +before running configure. (You might have to do a "make distclean" +if you already ran configure once). + +Also note that "make depend" won't work; while all of the known +universe uses -M, the SPARCompiler uses -xM to generate makefile +dependencies. + +If you are trying to do packet capture with a FORE ATM card, you may or +may not be able to. They usually only release their driver in object +code so unless their driver supports packet capture, there's not much +libpcap can do. + +If you get an error like: + + tcpdump: recv_ack: bind error 0x??? + +when using DLPI, look for the DL_ERROR_ACK error return values, usually +in /usr/include/sys/dlpi.h, and find the corresponding value. + +Under {DEC OSF/1, Digital UNIX, Tru64 UNIX}, packet capture must be +enabled before it can be used. For instructions on how to enable packet +filter support, see: + + ftp://ftp.digital.com/pub/Digital/dec-faq/Digital-UNIX + +Look for the "How do I configure the Berkeley Packet Filter and capture +tcpdump traces?" item. + +Once you enable packet filter support, your OSF system will support bpf +natively. + +Under Ultrix, packet capture must be enabled before it can be used. For +instructions on how to enable packet filter support, see: + + ftp://ftp.digital.com/pub/Digital/dec-faq/ultrix + +If you use HP-UX, you must have at least version 9 and either the +version of cc that supports ANSI C (cc -Aa) or else use the GNU C +compiler. You must also buy the optional streams package. If you don't +have: + + /usr/include/sys/dlpi.h + /usr/include/sys/dlpi_ext.h + +then you don't have the streams package. In addition, we believe you +need to install the "9.X LAN and DLPI drivers cumulative" patch +(PHNE_6855) to make the version 9 DLPI work with libpcap. + +The DLPI streams package is standard starting with HP-UX 10. + +The HP implementation of DLPI is a little bit eccentric. Unlike +Solaris, you must attach /dev/dlpi instead of the specific /dev/* +network pseudo device entry in order to capture packets. The PPA is +based on the ifnet "index" number. Under HP-UX 9, it is necessary to +read /dev/kmem and the kernel symbol file (/hp-ux). Under HP-UX 10, +DLPI can provide information for determining the PPA. It does not seem +to be possible to trace the loopback interface. Unlike other DLPI +implementations, PHYS implies MULTI and SAP and you get an error if you +try to enable more than one promiscuous mode at a time. + +It is impossible to capture outbound packets on HP-UX 9. To do so on +HP-UX 10, you will, apparently, need a late "LAN products cumulative +patch" (at one point, it was claimed that this would be PHNE_18173 for +s700/10.20; at another point, it was claimed that the required patches +were PHNE_20892, PHNE_20725 and PHCO_10947, or newer patches), and to do +so on HP-UX 11 you will, apparently, need the latest lancommon/DLPI +patches and the latest driver patch for the interface(s) in use on HP-UX +11 (at one point, it was claimed that patches PHNE_19766, PHNE_19826, +PHNE_20008, and PHNE_20735 did the trick). + +Furthermore, on HP-UX 10, you will need to turn on a kernel switch by +doing + + echo 'lanc_outbound_promisc_flag/W 1' | adb -w /stand/vmunix /dev/mem + +You would have to arrange that this happen on reboots; the right way to +do that would probably be to put it into an executable script file +"/sbin/init.d/outbound_promisc" and making +"/sbin/rc2.d/S350outbound_promisc" a symbolic link to that script. + +Finally, testing shows that there can't be more than one simultaneous +DLPI user per network interface. + +If you use Linux, this version of libpcap is known to compile and run +under Red Hat 4.0 with the 2.0.25 kernel. It may work with earlier 2.X +versions but is guaranteed not to work with 1.X kernels. Running more +than one libpcap program at a time, on a system with a 2.0.X kernel, can +cause problems since promiscuous mode is implemented by twiddling the +interface flags from the libpcap application; the packet capture +mechanism in the 2.2 and later kernels doesn't have this problem. Also, +packet timestamps aren't very good. This appears to be due to haphazard +handling of the timestamp in the kernel. + +Note well: there is rumoured to be a version of tcpdump floating around +called 3.0.3 that includes libpcap and is supposed to support Linux. +You should be advised that neither the Network Research Group at LBNL +nor the Tcpdump Group ever generated a release with this version number. +The LBNL Network Research Group notes with interest that a standard +cracker trick to get people to install trojans is to distribute bogus +packages that have a version number higher than the current release. +They also noted with annoyance that 90% of the Linux related bug reports +they got are due to changes made to unofficial versions of their page. +If you are having trouble but aren't using a version that came from +tcpdump.org, please try that before submitting a bug report! + +On Linux, libpcap will not work if the kernel does not have the packet +socket option enabled; see the README.linux file for information about +this. + +If you use AIX, you may not be able to build libpcap from this release. +We do not have an AIX system in house so it's impossible for us to test +AIX patches submitted to us. We are told that you must link against +/lib/pse.exp, that you must use AIX cc or a GNU C compiler newer than +2.7.2, and that you may need to run strload before running a libpcap +application. + +Read the README.aix file for information on installing libpcap and +configuring your system to be able to support libpcap. + +If you use NeXTSTEP, you will not be able to build libpcap from this +release. We hope to support this operating system in some future +release of libpcap. + +If you use SINIX, you should be able to build libpcap from this +release. It is known to compile and run on SINIX-Y/N 5.42 with the C-DS +V1.0 or V1.1 compiler. But note that in some releases of SINIX, yacc +emits incorrect code; if grammar.y fails to compile, change every +occurence of: + + #ifdef YYDEBUG + +to: + #if YYDEBUG + +Another workaround is to use flex and bison. + +If you use SCO, you might have trouble building libpcap from this +release. We do not have a machine running SCO and have not had reports +of anyone successfully building on it. Since SCO apparently supports +DLPI, it's possible the current version works. Meanwhile, SCO provides +a tcpdump binary as part of their "Network/Security Tools" package: + + http://www.sco.com/technology/internet/goodies/#SECURITY + +There is also a README that explains how to enable packet capture. + +If you use UnixWare, you will not be able to build libpcap from this +release. We hope to support this operating system in some future +release of libpcap. Meanwhile, there appears to be an UnixWare port of +libpcap 0.0 (and tcpdump 3.0) in: + + ftp://ftp1.freebird.org/pub/mirror/freebird/internet/systools/ + +UnixWare appears to use a hacked version of DLPI. + +If linking tcpdump fails with "Undefined: _alloca" when using bison on +a Sun4, your version of bison is broken. In any case version 1.16 or +higher is recommended (1.14 is known to cause problems 1.16 is known to +work). Either pick up a current version from: + + ftp://ftp.gnu.org/pub/gnu/bison + +or hack around it by inserting the lines: + + #ifdef __GNUC__ + #define alloca __builtin_alloca + #else + #ifdef sparc + #include + #else + char *alloca (); + #endif + #endif + +right after the (100 line!) GNU license comment in bison.simple, remove +grammar.[co] and fire up make again. + +If you use SunOS 4, your kernel must support streams NIT. If you run a +libpcap program and it dies with: + + /dev/nit: No such device + +You must add streams NIT support to your kernel configuration, run +config and boot the new kernel. + +If you are running a version of SunOS earlier than 4.1, you will need +to replace the Sun supplied /sys/sun{3,4,4c}/OBJ/nit_if.o with the +appropriate version from this distribution's SUNOS4 subdirectory and +build a new kernel: + + nit_if.o.sun3-sunos4 (any flavor of sun3) + nit_if.o.sun4c-sunos4.0.3c (SS1, SS1+, IPC, SLC, etc.) + nit_if.o.sun4-sunos4 (Sun4's not covered by + nit_if.o.sun4c-sunos4.0.3c) + +These nit replacements fix a bug that makes nit essentially unusable in +pre-SunOS 4.1. In addition, our sun4c-sunos4.0.3c nit gives you +timestamps to the resolution of the SS-1 clock (1 us) rather than the +lousy 20ms timestamps Sun gives you (tcpdump will print out the full +timestamp resolution if it finds it's running on a SS-1). + +FILES +----- +CHANGES - description of differences between releases +ChmodBPF/* - Mac OS X startup item to set ownership and permissions + on /dev/bpf* +CREDITS - people that have helped libpcap along +FILES - list of files exported as part of the distribution +INSTALL.txt - this file +LICENSE - the license under which tcpdump is distributed +Makefile.in - compilation rules (input to the configure script) +README - description of distribution +README.aix - notes on using libpcap on AIX +README.dag - notes on using libpcap to capture on Endace DAG devices +README.hpux - notes on using libpcap on HP-UX +README.linux - notes on using libpcap on Linux +README.macosx - notes on using libpcap on Mac OS X +README.septel - notes on using libpcap to capture on Intel/Septel devices +README.tru64 - notes on using libpcap on Digital/Tru64 UNIX +README.Win32 - notes on using libpcap on Win32 systems (with WinPcap) +SUNOS4 - pre-SunOS 4.1 replacement kernel nit modules +VERSION - version of this release +acconfig.h - support for post-2.13 autoconf +aclocal.m4 - autoconf macros +arcnet.h - ARCNET definitions +atmuni31.h - ATM Q.2931 definitions +bpf/net - copy of bpf_filter.c +bpf_dump.c - BPF program printing routines +bpf_filter.c - symlink to bpf/net/bpf_filter.c +bpf_image.c - BPF disassembly routine +config.guess - autoconf support +config.h.in - autoconf input +config.sub - autoconf support +configure - configure script (run this first) +configure.in - configure script source +etherent.c - /etc/ethers support routines +ethertype.h - Ethernet protocol types and names definitions +fad-getad.c - pcap_findalldevs() for systems with getifaddrs() +fad-gifc.c - pcap_findalldevs() for systems with only SIOCGIFLIST +fad-glifc.c - pcap_findalldevs() for systems with SIOCGLIFCONF +fad-null.c - pcap_findalldevs() for systems without capture support +fad-win32.c - pcap_findalldevs() for WinPcap +gencode.c - BPF code generation routines +gencode.h - BPF code generation definitions +grammar.y - filter string grammar +inet.c - network routines +install-sh - BSD style install script +lbl/os-*.h - OS-dependent defines and prototypes +llc.h - 802.2 LLC SAP definitions +missing/* - replacements for missing library functions +mkdep - construct Makefile dependency list +msdos/* - drivers for MS-DOS capture support +nametoaddr.c - hostname to address routines +nlpid.h - OSI network layer protocol identifier definitions +net - symlink to bpf/net +optimize.c - BPF optimization routines +packaging - packaging information for building libpcap RPMs +pcap-bpf.c - BSD Packet Filter support +pcap-bpf.h - BPF definitions +pcap-dag.c - Endace DAG device capture support +pcap-dag.h - Endace DAG device capture support +pcap-dlpi.c - Data Link Provider Interface support +pcap-dos.c - MS-DOS capture support +pcap-dos.h - headers for MS-DOS capture support +pcap-enet.c - enet support +pcap-int.h - internal libpcap definitions +pcap-linux.c - Linux packet socket support +pcap-namedb.h - public libpcap name database definitions +pcap-nit.c - SunOS Network Interface Tap support +pcap-nit.h - SunOS Network Interface Tap definitions +pcap-null.c - dummy monitor support (allows offline use of libpcap) +pcap-pf.c - Ultrix and Digital/Tru64 UNIX Packet Filter support +pcap-pf.h - Ultrix and Digital/Tru64 UNIX Packet Filter definitions +pcap-septel.c - INTEL/Septel device capture support +pcap-septel.h - INTEL/Septel device capture support +pcap-stdinc.h - includes and #defines for compiling on Win32 systems +pcap-snit.c - SunOS 4.x STREAMS-based Network Interface Tap support +pcap-snoop.c - IRIX Snoop network monitoring support +pcap-win32.c - WinPcap capture support +pcap.3 - manual entry +pcap.c - pcap utility routines +pcap.h - public libpcap definitions +pf.h - OpenBSD DLT_PFLOG definitions +ppp.h - Point to Point Protocol definitions +rawss7.h - information on DLT_ types for SS7 +savefile.c - offline support +scanner.l - filter string scanner +sll.h - definitions for Linux cooked mode fake link-layer header +sunatmpos.h - definitions for SunATM capturing +Win32 - headers and routines for building on Win32 systems diff --git a/winpcap/wpcap/libpcap/LICENSE b/winpcap/wpcap/libpcap/LICENSE new file mode 100644 index 0000000..dea5f7d --- /dev/null +++ b/winpcap/wpcap/libpcap/LICENSE @@ -0,0 +1,19 @@ +License: BSD + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/winpcap/wpcap/libpcap/Makefile.in b/winpcap/wpcap/libpcap/Makefile.in new file mode 100644 index 0000000..5e20b90 --- /dev/null +++ b/winpcap/wpcap/libpcap/Makefile.in @@ -0,0 +1,244 @@ +# Copyright (c) 1993, 1994, 1995, 1996 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that: (1) source code distributions +# retain the above copyright notice and this paragraph in its entirety, (2) +# distributions including binary code include the above copyright notice and +# this paragraph in its entirety in the documentation or other materials +# provided with the distribution, and (3) all advertising materials mentioning +# features or use of this software display the following acknowledgement: +# ``This product includes software developed by the University of California, +# Lawrence Berkeley Laboratory and its contributors.'' Neither the name of +# the University nor the names of its contributors may be used to endorse +# or promote products derived from this software without specific prior +# written permission. +# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +# +# @(#) $Header: /tcpdump/master/libpcap/Makefile.in,v 1.99 2003/12/15 01:35:03 guy Exp $ (LBL) + +# +# Various configurable paths (remember to edit Makefile.in, not Makefile) +# + +# Top level hierarchy +prefix = @prefix@ +exec_prefix = @exec_prefix@ +# Pathname of directory to install the include files +includedir = @includedir@ +# Pathname of directory to install the library +libdir = @libdir@ +# Pathname of directory to install the man page +mandir = @mandir@ + +# VPATH +srcdir = @srcdir@ +VPATH = @srcdir@ + +# +# You shouldn't need to edit anything below. +# + +CC = @CC@ +CCOPT = @V_CCOPT@ +INCLS = -I. @V_INCLS@ +# HAVE_REMOTE +DEFS = @DEFS@ @V_DEFS@ @V_HAVE_REMOTE@ +LIBS = @V_LIBS@ +DYEXT = @DYEXT@ + +# Standard CFLAGS +CFLAGS = $(CCOPT) $(INCLS) $(DEFS) + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +RANLIB = @RANLIB@ + +# +# Flex and bison allow you to specify the prefixes of the global symbols +# used by the generated parser. This allows programs to use lex/yacc +# and link against libpcap. If you don't have flex or bison, get them. +# +LEX = @V_LEX@ +YACC = @V_YACC@ + +# Explicitly define compilation rule since SunOS 4's make doesn't like gcc. +# Also, gcc does not remove the .o before forking 'as', which can be a +# problem if you don't own the file but can write to the directory. +.c.o: + @rm -f $@ + $(CC) $(CFLAGS) -c $(srcdir)/$*.c + +PSRC = pcap-@V_PCAP@.c +FSRC = fad-@V_FINDALLDEVS@.c +SSRC = @SSRC@ +CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c \ + etherent.c savefile.c bpf_filter.c bpf_image.c bpf_dump.c +GENSRC = scanner.c grammar.c version.c +# HAVE_REMOTE +REMOTESRC = @V_REMOTE_FILES@ +LIBOBJS = @LIBOBJS@ + +# HAVE_REMOTE +SRC = $(PSRC) $(FSRC) $(CSRC) $(SSRC) $(GENSRC) $(REMOTESRC) + +# We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot +# hack the extra indirection +# HAVE_REMOTE +OBJ = $(PSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(GENSRC:.c=.o) $(REMOTESRC:.c=.o) $(LIBOBJS) +HDR = pcap.h pcap-int.h pcap-namedb.h pcap-nit.h pcap-pf.h \ + ethertype.h gencode.h gnuc.h +GENHDR = \ + tokdefs.h version.h + +TAGHDR = \ + pcap-bpf.h + +TAGFILES = \ + $(SRC) $(HDR) $(TAGHDR) + +CLEANFILES = $(OBJ) libpcap.a $(GENSRC) $(GENHDR) lex.yy.c + +all: libpcap.a + +libpcap.a: $(OBJ) + @rm -f $@ + ar rc $@ $(OBJ) $(LIBS) + $(RANLIB) $@ + +shared: libpcap.$(DYEXT) + +# +# XXX - this works with GNU ld, but won't necessarily work with native +# ld on, for example, various SVR4-flavored platforms, or Digital UNIX. +# +libpcap.so: $(OBJ) + @rm -f $@ + ld -shared -o $@.`cat VERSION` $(OBJ) + +# the following rule succeeds, but the result is untested. +libpcap.dylib: $(OBJ) + rm -f libpcap*.dylib + $(CC) -dynamiclib -undefined error -o libpcap.`cat VERSION`.dylib $(OBJ) \ + -install_name $(libdir)/libpcap.0.dylib -compatibility_version `cat VERSION` \ + -current_version `cat VERSION` + + +scanner.c: $(srcdir)/scanner.l + @rm -f $@ + $(LEX) -t $< > $$$$.$@; mv $$$$.$@ $@ + +scanner.o: scanner.c tokdefs.h + $(CC) $(CFLAGS) -c scanner.c + +pcap.o: version.h + +tokdefs.h: grammar.c +grammar.c: $(srcdir)/grammar.y + @rm -f grammar.c tokdefs.h + $(YACC) -d $< + mv y.tab.c grammar.c + mv y.tab.h tokdefs.h + +grammar.o: grammar.c + @rm -f $@ + $(CC) $(CFLAGS) -Dyylval=pcap_lval -c grammar.c + +version.o: version.c + $(CC) $(CFLAGS) -c version.c + +snprintf.o: $(srcdir)/missing/snprintf.c + $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c + +version.c: $(srcdir)/VERSION + @rm -f $@ + sed -e 's/.*/char pcap_version[] = "&";/' $(srcdir)/VERSION > $@ + +# +# NOTE: this really is supposed to be static; importing a string +# from a shared library does not work very well on many +# versions of UNIX (Solaris, Linux, and the BSDs, for example), +# so we make the version string static and return it from +# a function, which does work. +# +version.h: $(srcdir)/VERSION + @rm -f $@ + sed -e 's/.*/static const char pcap_version_string[] = "libpcap version &";/' $(srcdir)/VERSION > $@ + +bpf_filter.c: $(srcdir)/bpf/net/bpf_filter.c + rm -f bpf_filter.c + ln -s $(srcdir)/bpf/net/bpf_filter.c bpf_filter.c + +bpf_filter.o: bpf_filter.c + $(CC) $(CFLAGS) -c bpf_filter.c + +install: libpcap.a + [ -d $(DESTDIR)$(libdir) ] || \ + (mkdir -p $(DESTDIR)$(libdir); chmod 755 $(DESTDIR)$(libdir)) + $(INSTALL_DATA) libpcap.a $(DESTDIR)$(libdir)/libpcap.a + $(RANLIB) $(DESTDIR)$(libdir)/libpcap.a + [ -d $(DESTDIR)$(includedir) ] || \ + (mkdir -p $(DESTDIR)$(includedir); chmod 755 $(DESTDIR)$(includedir)) + $(INSTALL_DATA) $(srcdir)/pcap.h $(DESTDIR)$(includedir)/pcap.h + $(INSTALL_DATA) $(srcdir)/pcap-bpf.h \ + $(DESTDIR)$(includedir)/pcap-bpf.h + $(INSTALL_DATA) $(srcdir)/pcap-namedb.h \ + $(DESTDIR)$(includedir)/pcap-namedb.h + [ -d $(DESTDIR)$(mandir)/man3 ] || \ + (mkdir -p $(DESTDIR)$(mandir)/man3; chmod 755 $(DESTDIR)$(mandir)/man3) + $(INSTALL_DATA) $(srcdir)/pcap.3 \ + $(DESTDIR)$(mandir)/man3/pcap.3 + +install-shared: install-shared-$(DYEXT) +install-shared-so: libpcap.so + $(INSTALL_PROGRAM) libpcap.so.`cat VERSION` $(DESTDIR)$(libdir)/libpcap.so.`cat VERSION` +install-shared-dylib: libpcap.dylib + $(INSTALL_PROGRAM) libpcap.`cat VERSION`.dylib $(DESTDIR)$(libdir)/libpcap.`cat VERSION`.dylib + VER=`cat VERSION`; cd $(DESTDIR)$(libdir) && ln -sf libpcap.$$VER.dylib libpcap.0.dylib; ln -sf libpcap.0.dylib libpcap.dylib + +uninstall: + rm -f $(DESTDIR)$(libdir)/libpcap.a + rm -f $(DESTDIR)$(includedir)/pcap.h + rm -f $(DESTDIR)$(includedir)/pcap-bpf.h + rm -f $(DESTDIR)$(includedir)/pcap-namedb.h + rm -f $(DESTDIR)$(mandir)/man3/pcap.3 + +clean: + rm -f $(CLEANFILES) libpcap*.dylib libpcap.so* + +distclean: clean + rm -f Makefile config.cache config.log config.status \ + config.h gnuc.h os-proto.h bpf_filter.c stamp-h stamp-h.in + rm -rf autom4te.cache + +tags: $(TAGFILES) + ctags -wtd $(TAGFILES) + +packaging/pcap.spec: packaging/pcap.spec.in VERSION + RPMVERSION=`cat VERSION | sed s/-.*//g`; \ + sed -e s/@VERSION@/$$RPMVERSION/ -e s/@NAME@/libpcap-`cat VERSION`/ $< > $@ + +tar: Makefile packaging/pcap.spec + @cwd=`pwd` ; dir=`basename $$cwd` ; name=libpcap-`cat VERSION` ; \ + list="" ; tar="tar chf" ; \ + for i in `cat FILES` ; do list="$$list $$name/$$i" ; done; \ + echo \ + "rm -f ../$$name; ln -s $$dir ../$$name" ; \ + rm -f ../$$name; ln -s $$dir ../$$name ; \ + echo \ + "(cd .. ; $$tar - [lots of files]) | gzip -c > /tmp/$$name.tar.gz" ; \ + (cd .. ; $$tar - $$list) | gzip -c > /tmp/$$name.tar.gz ; \ + echo \ + "rm -f ../$$name" ; \ + rm -f ../$$name + +depend: $(GENSRC) $(GENHDR) bpf_filter.c + ./mkdep -c $(CC) $(DEFS) $(INCLS) $(SRC) + +Makefile: Makefile.in config.status + ./config.status + @echo your Makefile was out of date, now run $(MAKE) again + exit 1 diff --git a/winpcap/wpcap/libpcap/README b/winpcap/wpcap/libpcap/README new file mode 100644 index 0000000..90571a1 --- /dev/null +++ b/winpcap/wpcap/libpcap/README @@ -0,0 +1,94 @@ +@(#) $Header: /tcpdump/master/libpcap/README,v 1.30 2004/10/12 02:02:28 guy Exp $ (LBL) + +LIBPCAP 0.9 +Now maintained by "The Tcpdump Group" +See www.tcpdump.org + +Please send inquiries/comments/reports to tcpdump-workers@tcpdump.org + +Anonymous CVS is available via: + cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master login + (password "anoncvs") + cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout libpcap + +Version 0.9 of LIBPCAP can be retrieved with the CVS tag "libpcap_0_9rel1": + cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_0_9rel1 libpcap + +Please send patches against the master copy to patches@tcpdump.org. + +formerly from Lawrence Berkeley National Laboratory + Network Research Group + ftp://ftp.ee.lbl.gov/libpcap.tar.Z (0.4) + +This directory contains source code for libpcap, a system-independent +interface for user-level packet capture. libpcap provides a portable +framework for low-level network monitoring. Applications include +network statistics collection, security monitoring, network debugging, +etc. Since almost every system vendor provides a different interface +for packet capture, and since we've developed several tools that +require this functionality, we've created this system-independent API +to ease in porting and to alleviate the need for several +system-dependent packet capture modules in each application. + +Note well: this interface is new and is likely to change. + +For some platforms there are README.{system} files that discuss issues +with the OS's interface for packet capture on those platforms, such as +how to enable support for that interface in the OS, if it's not built in +by default. + +The libpcap interface supports a filtering mechanism based on the +architecture in the BSD packet filter. BPF is described in the 1993 +Winter Usenix paper ``The BSD Packet Filter: A New Architecture for +User-level Packet Capture''. A compressed PostScript version can be +found at + + ftp://ftp.ee.lbl.gov/papers/bpf-usenix93.ps.Z + +or + + http://www.tcpdump.org/papers/bpf-usenix93.ps.Z + +and a gzipped version can be found at + + http://www.tcpdump.org/papers/bpf-usenix93.ps.gz + +A PDF version can be found at + + http://www.tcpdump.org/papers/bpf-usenix93.pdf + +Although most packet capture interfaces support in-kernel filtering, +libpcap utilizes in-kernel filtering only for the BPF interface. +On systems that don't have BPF, all packets are read into user-space +and the BPF filters are evaluated in the libpcap library, incurring +added overhead (especially, for selective filters). Ideally, libpcap +would translate BPF filters into a filter program that is compatible +with the underlying kernel subsystem, but this is not yet implemented. + +BPF is standard in 4.4BSD, BSD/OS, NetBSD, FreeBSD, and OpenBSD. DEC +OSF/1/Digital UNIX/Tru64 UNIX uses the packetfilter interface but has +been extended to accept BPF filters (which libpcap utilizes). Also, you +can add BPF filter support to Ultrix using the kernel source and/or +object patches available in: + + ftp://gatekeeper.dec.com/pub/DEC/net/bpfext42.tar.Z. + +Linux, in the 2.2 kernel and later kernels, has a "Socket Filter" +mechanism that accepts BPF filters; see the README.linux file for +information on configuring that option. + +Problems, bugs, questions, desirable enhancements, etc. should be sent +to the address "tcpdump-workers@tcpdump.org". Bugs, support requests, +and feature requests may also be submitted on the SourceForge site for +libpcap at + + http://sourceforge.net/projects/libpcap/ + +Source code contributions, etc. should be sent to the email address +"patches@tcpdump.org", or submitted as patches on the SourceForge site +for libpcap. + +Current versions can be found at www.tcpdump.org, or the SourceForge +site for libpcap. + + - The TCPdump team diff --git a/winpcap/wpcap/libpcap/README.Win32 b/winpcap/wpcap/libpcap/README.Win32 new file mode 100644 index 0000000..3116d5e --- /dev/null +++ b/winpcap/wpcap/libpcap/README.Win32 @@ -0,0 +1,46 @@ +Under Win32, libpcap is integrated in the WinPcap packet capture system. +WinPcap provides a framework that allows libpcap to capture the packets +under Windows 95, Windows 98, Windows ME, Windows NT 4, Windows 2000 +and Windows XP. +WinPcap binaries and source code can be found at http://winpcap.polito.it: +they include also a developer's pack with all the necessary to compile +libpcap-based applications under Windows. + +How to compile libpcap with Visual Studio +----------------------------------------- + +In order to compile libpcap you will need: + +- version 6 (or higher) of Microsoft Visual Studio +- The November 2001 (or later) edition of Microsoft Platform +Software Development Kit (SDK), that contains some necessary includes +for IPv6 support. You can download it from http://www.microsoft.com/sdk +- the latest WinPcap sources from http://winpcap.polito.it/install + +The WinPcap source code already contains a recent (usually the latest +stable) version of libpcap. If you need to compile a different one, +simply download it from www.tcpdump.org and copy the sources in the +winpcap\wpcap\libpcap folder of the WinPcap distribution. If you want to +compile a libpcap source retrieved from the tcpdump.org CVS, you will +have to create the scanner and the grammar by hand (with lex and yacc) +or with the cygnus makefile, since The Visual Studio project is not able +to build them. + +Open the project file winpcap\wpcap\prj\wpcap.dsw with Visual Studio and +build wpcap.dll. wpcap.lib, the library file to link with the applications, +will be generated in winpcap\wpcap\lib\. wpcap.dll will be generated in +winpcap\wpcap\prj\release or winpcap\wpcap\prj\debug depending on the type +of binary that is being created. + +How to compile libpcap with Cygnus +---------------------------------- + +To build wpcap.dll, cd to the directory WPCAP/PRJ of the WinPcap source code +distribution and type "make". libwpcap.a, the library file to link with the +applications, will be generated in winpcap\wpcap\lib\. wpcap.dll will be +generated in winpcap\wpcap\prj. + +Remember, you CANNOT use the MSVC-generated .lib files with gcc, use +libwpcap.a instead. + +"make install" installs wpcap.dll in the Windows system folder. diff --git a/winpcap/wpcap/libpcap/README.aix b/winpcap/wpcap/libpcap/README.aix new file mode 100644 index 0000000..dcddb61 --- /dev/null +++ b/winpcap/wpcap/libpcap/README.aix @@ -0,0 +1,78 @@ +Using BPF: + +(1) AIX 4.x's version of BPF is undocumented and somewhat unstandard; the + current BPF support code includes changes that should work around + that; it appears to compile and work on at least one AIX 4.3.3 + machine. + + Note that the BPF driver and the "/dev/bpf" devices might not exist + on your machine; AIX's tcpdump loads the driver and creates the + devices if they don't already exist. Our libpcap should do the + same, and the configure script should detect that it's on an AIX + system and choose BPF even if the devices aren't there. + +(2) If libpcap doesn't compile on your machine when configured to use + BPF, or if the workarounds fail to make it work correctly, you + should send to tcpdump-workers@tcpdump.org a detailed bug report (if + the compile fails, send us the compile error messages; if it + compiles but fails to work correctly, send us as detailed as + possible a description of the symptoms, including indications of the + network link-layer type being wrong or time stamps being wrong). + + If you fix the problems yourself, please send to patches@tcpdump.org + a patch, so we can incorporate them into the next release. + + If you don't fix the problems yourself, you can, as a workaround, + make libpcap use DLPI instead of BPF. + + This can be done by specifying the flag: + + --with-pcap=dlpi + + to the "configure" script for libpcap. + +If you use DLPI: + +(1) It is a good idea to have the latest version of the DLPI driver on + your system, since certain versions may be buggy and cause your AIX + system to crash. DLPI is included in the fileset bos.rte.tty. I + found that the DLPI driver that came with AIX 4.3.2 was buggy, and + had to upgrade to bos.rte.tty 4.3.2.4: + + lslpp -l bos.rte.tty + + bos.rte.tty 4.3.2.4 COMMITTED Base TTY Support and Commands + + Updates for AIX filesets can be obtained from: + ftp://service.software.ibm.com/aix/fixes/ + + These updates can be installed with the smit program. + +(2) After compiling libpcap, you need to make sure that the DLPI driver + is loaded. Type: + + strload -q -d dlpi + + If the result is: + + dlpi: yes + + then the DLPI driver is loaded correctly. + + If it is: + + dlpi: no + + Then you need to type: + + strload -f /etc/dlpi.conf + + Check again with strload -q -d dlpi that the dlpi driver is loaded. + + Alternatively, you can uncomment the lines for DLPI in + /etc/pse.conf and reboot the machine; this way DLPI will always + be loaded when you boot your system. + +(3) There appears to be a problem in the DLPI code in some versions of + AIX, causing a warning about DL_PROMISC_MULTI failing; this might + be responsible for DLPI not being able to capture outgoing packets. diff --git a/winpcap/wpcap/libpcap/README.dag b/winpcap/wpcap/libpcap/README.dag new file mode 100644 index 0000000..acf97ed --- /dev/null +++ b/winpcap/wpcap/libpcap/README.dag @@ -0,0 +1,114 @@ + +The following instructions apply if you have a Linux or FreeBSD platform and +want libpcap to support the DAG range of passive network monitoring cards from +Endace (http://www.endace.com, see below for further contact details). + +1) Install and build the DAG software distribution by following the +instructions supplied with that package. Current Endace customers can download +the DAG software distibution from https://www.endace.com + +2) Configure libcap. To allow the 'configure' script to locate the DAG +software distribution use the '--with-dag' option: + + ./configure --with-dag=DIR + +Where DIR is the root of the DAG software distribution, for example +/var/src/dag. If the DAG software is correctly detected 'configure' will +report: + + checking whether we have DAG API... yes + +If 'configure' reports that there is no DAG API, the directory may have been +incorrectly specified or the DAG software was not built before configuring +libpcap. + +See also the libpcap INSTALL.txt file for further libpcap configuration +options. + +Building libpcap at this stage will include support for both the native packet +capture stream (linux or bpf) and for capturing from DAG cards. To build +libpcap with only DAG support specify the capture type as 'dag' when +configuring libpcap: + + ./configure --with-dag=DIR --with-pcap=dag + +Applications built with libpcap configured in this way will only detect DAG +cards and will not capture from the native OS packet stream. + +---------------------------------------------------------------------- + +Libpcap when built for DAG cards against dag-2.5.1 or later releases: + +Timeouts are supported. pcap_dispatch() will return after to_ms milliseconds +regardless of how many packets are received. If to_ms is zero pcap_dispatch() +will block waiting for data indefinitely. + +pcap_dispatch() will block on and process a minimum of 64kB of data (before +filtering) for efficiency. This can introduce high latencies on quiet +interfaces unless a timeout value is set. The timeout expiring will override +the 64kB minimum causing pcap_dispatch() to process any available data and +return. + +pcap_setnonblock is supported. When nonblock is set, pcap_dispatch() will +check once for available data, process any data available up to count, then +return immediately. + +pcap_findalldevs() is supported, e.g. dag0, dag1... + +Some DAG cards can provide more than one 'stream' of received data. +This can be data from different physical ports, or separated by filtering +or load balancing mechanisms. Receive streams have even numbers, e.g. +dag0:0, dag0:2 etc. Specifying transmit streams for capture is not supported. + +pcap_setfilter() is supported, BPF programs run in userspace. + +pcap_setdirection() is not supported. Only received traffic is captured. +DAG cards normally do not have IP or link layer addresses assigned as +they are used to passively monitor links. + +pcap_breakloop() is supported. + +pcap_datalink() and pcap_list_datalinks() are supported. The DAG card does +not attempt to set the correct datalink type automatically where more than +one type is possible. + +pcap_stats() is supported. ps_drop is the number of packets dropped due to +RX stream buffer overflow, this count is before filters are applied (it will +include packets that would have been dropped by the filter). The RX stream +buffer size is user configurable outside libpcap, typically 16-512MB. + +pcap_get_selectable_fd() is not supported, as DAG cards do not support +poll/select methods. + +pcap_inject() and pcap_sendpacket() are not supported. + +Some DAG cards now support capturing to multiple virtual interfaces, called +streams. Capture streams have even numbers. These are available via libpcap +as separate interfaces, e.g. dag0:0, dag0:2, dag0:4 etc. dag0:0 is the same +as dag0. These are visible via pcap_findalldevs(). + +libpcap now does NOT set the card's hardware snaplen (slen). This must now be +set using the appropriate DAG coniguration program, e.g. dagthree, dagfour, +dagsix, dagconfig. This is because the snaplen is currently shared between +all of the streams. In future this may change if per-stream slen is +implemented. + +DAG cards by default capture entire packets including the L2 +CRC/FCS. If the card is not configured to discard the CRC/FCS, this +can confuse applications that use libpcap if they're not prepared for +packets to have an FCS. Libpcap now reads the environment variable +ERF_FCS_BITS to determine how many bits of CRC/FCS to strip from the +end of the captured frame. This defaults to 32 for use with +Ethernet. If the card is configured to strip the CRC/FCS, then set +ERF_FCS_BITS=0. If used with a HDLC/PoS/PPP/Frame Relay link with 16 +bit CRC/FCS, then set ERF_FCS_BITS=16. + +---------------------------------------------------------------------- + +Please submit bug reports via . + +Please also visit our Web site at: + + http://www.endace.com/ + +For more information about Endace DAG cards contact . diff --git a/winpcap/wpcap/libpcap/README.hpux b/winpcap/wpcap/libpcap/README.hpux new file mode 100644 index 0000000..88c27f8 --- /dev/null +++ b/winpcap/wpcap/libpcap/README.hpux @@ -0,0 +1,254 @@ +For HP-UX 11i (11.11) and later, there are no known issues with +promiscuous mode under HP-UX. If you are using a earlier version of +HP-UX and cannot upgrade, please continue reading. + +HP-UX patches to fix packet capture problems + +Note that packet-capture programs such as tcpdump may, on HP-UX, not be +able to see packets sent from the machine on which they're running. +Some articles on groups.google.com discussing this are: + + http://groups.google.com/groups?selm=82ld3v%2480i%241%40mamenchi.zrz.TU-Berlin.DE + +which says: + + Newsgroups: comp.sys.hp.hpux + Subject: Re: Did someone made tcpdump working on 10.20 ? + Date: 12/08/1999 + From: Lutz Jaenicke + + In article <82ks5i$5vc$1@news1.dti.ne.jp>, mtsat + wrote: + >Hello, + > + >I downloaded and compiled tcpdump3.4 a couple of week ago. I tried to use + >it, but I can only see incoming data, never outgoing. + >Someone (raj) explained me that a patch was missing, and that this patch + >must me "patched" (poked) in order to see outbound data in promiscuous mode. + >Many things to do .... So the question is : did someone has already this + >"ready to use" PHNE_**** patch ? + + Two things: + 1. You do need a late "LAN products cumulative patch" (e.g. PHNE_18173 + for s700/10.20). + 2. You must use +echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem + You can insert this e.g. into /sbin/init.d/lan + + Best regards, + Lutz + +and + + http://groups.google.com/groups?selm=88cf4t%24p03%241%40web1.cup.hp.com + +which says: + + Newsgroups: comp.sys.hp.hpux + Subject: Re: tcpdump only shows incoming packets + Date: 02/15/2000 + From: Rick Jones + + Harald Skotnes wrote: + > I am running HPUX 11.0 on a C200 hanging on a 100Mb switch. I have + > compiled libpcap-0.4 an tcpdump-3.4 and it seems to work. But at a + > closer look I only get to see the incoming packets not the + > outgoing. I have tried tcpflow-0.12 which also uses libpcap and the + > same thing happens. Could someone please give me a hint on how to + > get this right? + + Search/Read the archives ?-) + + What you are seeing is expected, un-patched, behaviour for an HP-UX + system. On 11.00, you need to install the latest lancommon/DLPI + patches, and then the latest driver patch for the interface(s) in use. + At that point, a miracle happens and you should start seeing outbound + traffic. + +[That article also mentions the patch that appears below.] + +and + + http://groups.google.com/groups?selm=38AA973E.96BE7DF7%40cc.uit.no + +which says: + + Newsgroups: comp.sys.hp.hpux + Subject: Re: tcpdump only shows incoming packets + Date: 02/16/2000 + From: Harald Skotnes + + Rick Jones wrote: + + ... + + > What you are seeing is expected, un-patched, behaviour for an HP-UX + > system. On 11.00, you need to install the latest lancommon/DLPI + > patches, and then the latest driver patch for the interface(s) in + > use. At that point, a miracle happens and you should start seeing + > outbound traffic. + + Thanks a lot. I have this problem on several machines running HPUX + 10.20 and 11.00. The machines where patched up before y2k so did not + know what to think. Anyway I have now installed PHNE_19766, + PHNE_19826, PHNE_20008, PHNE_20735 on the C200 and now I can see the + outbound traffic too. Thanks again. + +(although those patches may not be the ones to install - there may be +later patches). + +And another message to tcpdump-workers@tcpdump.org, from Rick Jones: + + Date: Mon, 29 Apr 2002 15:59:55 -0700 + From: Rick Jones + To: tcpdump-workers@tcpdump.org + Subject: Re: [tcpdump-workers] I Can't Capture the Outbound Traffic + + ... + + http://itrc.hp.com/ would be one place to start in a search for the most + up-to-date patches for DLPI and the lan driver(s) used on your system (I + cannot guess because 9000/800 is too generic - one hs to use the "model" + command these days and/or an ioscan command (see manpage) to guess what + the drivers (btlan[3456], gelan, etc) might be involved in addition to + DLPI. + + Another option is to upgrade to 11i as outbound promiscuous mode support + is there in the base OS, no patches required. + +Another posting: + + http://groups.google.com/groups?selm=7d6gvn%24b3%241%40ocean.cup.hp.com + +indicates that you need to install the optional STREAMS product to do +captures on HP-UX 9.x: + + Newsgroups: comp.sys.hp.hpux + Subject: Re: tcpdump HP/UX 9.x + Date: 03/22/1999 + From: Rick Jones + + Dave Barr (barr@cis.ohio-state.edu) wrote: + : Has anyone ported tcpdump (or something similar) to HP/UX 9.x? + + I'm reasonably confident that any port of tcpdump to 9.X would require + the (then optional) STREAMS product. This would bring DLPI, which is + what one uses to access interfaces in promiscuous mode. + + I'm not sure that HP even sells the 9.X STREAMS product any longer, + since HP-UX 9.X is off the pricelist (well, maybe 9.10 for the old 68K + devices). + + Your best bet is to be up on 10.20 or better if that is at all + possible. If your hardware is supported by it, I'd go with HP-UX 11. + If you want to see the system's own outbound traffic, you'll never get + that functionality on 9.X, but it might happen at some point for 10.20 + and 11.X. + + rick jones + +(as per other messages cited here, the ability to see the system's own +outbound traffic did happen). + +Rick Jones reports that HP-UX 11i needs no patches for outbound +promiscuous mode support. + +An additional note, from Jost Martin, for HP-UX 10.20: + + Q: How do I get ethereral on HPUX to capture the _outgoing_ packets + of an interface + A: You need to get PHNE_20892,PHNE_20725 and PHCO_10947 (or + newer, this is as of 4.4.00) and its dependencies. Then you can + enable the feature as descibed below: + + Patch Name: PHNE_20892 + Patch Description: s700 10.20 PCI 100Base-T cumulative patch + To trace the outbound packets, please do the following + to turn on a global promiscuous switch before running + the promiscuous applications like snoop or tcpdump: + + adb -w /stand/vmunix /dev/mem + lanc_outbound_promisc_flag/W 1 + (adb will echo the result showing that the flag has + been changed) + $quit + (Thanks for this part to HP-support, Ratingen) + + The attached hack does this and some security-related stuff + (thanks to hildeb@www.stahl.bau.tu-bs.de (Ralf Hildebrandt) who + posted the security-part some time ago) + + <> + + (Don't switch IP-forwarding off, if you need it !) + Install the hack as /sbin/init.d/hacl_ip_stack (adjust + permissions !) and make a sequencing-symlink + /sbin/rc2.d/S350hack_ip_stack pointing to this script. + Now all this is done on every reboot. + +According to Rick Jones, the global promiscuous switch also has to be +turned on for HP-UX 11.00, but not for 11i - and, in fact, the switch +doesn't even exist on 11i. + +Here's the "hack_ip_stack" script: + +-----------------------------------Cut Here------------------------------------- +#!/sbin/sh +# +# nettune: hack kernel parms for safety + +OKAY=0 +ERROR=-1 + +# /usr/contrib/bin fuer nettune auf Pfad +PATH=/sbin:/usr/sbin:/usr/bin:/usr/contrib/bin +export PATH + + +########## +# main # +########## + +case $1 in + start_msg) + print "Tune IP-Stack for security" + exit $OKAY + ;; + + stop_msg) + print "This action is not applicable" + exit $OKAY + ;; + + stop) + exit $OKAY + ;; + + start) + ;; # fall through + + *) + print "USAGE: $0 {start_msg | stop_msg | start | stop}" >&2 + exit $ERROR + ;; + esac + +########### +# start # +########### + +# +# tcp-Sequence-Numbers nicht mehr inkrementieren sondern random +# Syn-Flood-Protection an +# ip_forwarding aus +# Source-Routing aus +# Ausgehende Packets an ethereal/tcpdump etc. + +/usr/contrib/bin/nettune -s tcp_random_seq 2 || exit $ERROR +/usr/contrib/bin/nettune -s hp_syn_protect 1 || exit $ERROR +/usr/contrib/bin/nettune -s ip_forwarding 0 || exit $ERROR +echo 'ip_block_source_routed/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem || exit $ERROR +echo 'lanc_outbound_promisc_flag/W 1' | adb -w /stand/vmunix /dev/mem || exit $ERROR + +exit $OKAY +-----------------------------------Cut Here------------------------------------- diff --git a/winpcap/wpcap/libpcap/README.linux b/winpcap/wpcap/libpcap/README.linux new file mode 100644 index 0000000..dd95913 --- /dev/null +++ b/winpcap/wpcap/libpcap/README.linux @@ -0,0 +1,88 @@ +In order for libpcap to be able to capture packets on a Linux system, +the "packet" protocol must be supported by your kernel. If it is not, +you may get error messages such as + + modprobe: can't locate module net-pf-17 + +in "/var/adm/messages", or may get messages such as + + socket: Address family not supported by protocol + +from applications using libpcap. + +You must configure the kernel with the CONFIG_PACKET option for this +protocol; the following note is from the Linux "Configure.help" file for +the 2.0[.x] kernel: + + Packet socket + CONFIG_PACKET + The Packet protocol is used by applications which communicate + directly with network devices without an intermediate network + protocol implemented in the kernel, e.g. tcpdump. If you want them + to work, choose Y. + + This driver is also available as a module called af_packet.o ( = + code which can be inserted in and removed from the running kernel + whenever you want). If you want to compile it as a module, say M + here and read Documentation/modules.txt; if you use modprobe or + kmod, you may also want to add "alias net-pf-17 af_packet" to + /etc/modules.conf. + +and the note for the 2.2[.x] kernel says: + + Packet socket + CONFIG_PACKET + The Packet protocol is used by applications which communicate + directly with network devices without an intermediate network + protocol implemented in the kernel, e.g. tcpdump. If you want them + to work, choose Y. This driver is also available as a module called + af_packet.o ( = code which can be inserted in and removed from the + running kernel whenever you want). If you want to compile it as a + module, say M here and read Documentation/modules.txt. You will + need to add 'alias net-pf-17 af_packet' to your /etc/conf.modules + file for the module version to function automatically. If unsure, + say Y. + +In addition, there is an option that, in 2.2 and later kernels, will +allow packet capture filters specified to programs such as tcpdump to be +executed in the kernel, so that packets that don't pass the filter won't +be copied from the kernel to the program, rather than having all packets +copied to the program and libpcap doing the filtering in user mode. + +Copying packets from the kernel to the program consumes a significant +amount of CPU, so filtering in the kernel can reduce the overhead of +capturing packets if a filter has been specified that discards a +significant number of packets. (If no filter is specified, it makes no +difference whether the filtering isn't performed in the kernel or isn't +performed in user mode. :-)) + +The option for this is the CONFIG_FILTER option; the "Configure.help" +file says: + + Socket filtering + CONFIG_FILTER + The Linux Socket Filter is derived from the Berkeley Packet Filter. + If you say Y here, user-space programs can attach a filter to any + socket and thereby tell the kernel that it should allow or disallow + certain types of data to get through the socket. Linux Socket + Filtering works on all socket types except TCP for now. See the text + file linux/Documentation/networking/filter.txt for more information. + If unsure, say N. + + +Statistics: +Statistics reported by pcap are platform specific. The statistics +reported by pcap_stats on Linux are as follows: + +2.2.x +===== +ps_recv Number of packets that were accepted by the pcap filter +ps_drops Always 0, this statistic is not gatherd on this platform + +2.4.x +===== +ps_rec Number of packets that were accepted by the pcap filter +ps_drops Number of packets that had passed filtering but were not + passed on to pcap due to things like buffer shortage, etc. + This is useful because these are packets you are interested in + but won't be reported by, for example, tcpdump output. diff --git a/winpcap/wpcap/libpcap/README.macosx b/winpcap/wpcap/libpcap/README.macosx new file mode 100644 index 0000000..25794d8 --- /dev/null +++ b/winpcap/wpcap/libpcap/README.macosx @@ -0,0 +1,43 @@ +As with other systems using BPF, Mac OS X allows users with read access +to the BPF devices to capture packets with libpcap and allows users with +write access to the BPF devices to send packets with libpcap. + +On some systems that use BPF, the BPF devices live on the root file +system, and the permissions and/or ownership on those devices can be +changed to give users other than root permission to read or write those +devices. + +On newer versions of FreeBSD, the BPF devices live on devfs, and devfs +can be configured to set the permissions and/or ownership of those +devices to give users other than root permission to read or write those +devices. + +On Mac OS X, the BPF devices live on devfs, but the OS X version of +devfs is based on an older (non-default) FreeBSD devfs, and that version +of devfs cannot be configured to set the permissions and/or ownership of +those devices. + +Therefore, we supply a "startup item" for OS X that will change the +ownership of the BPF devices so that the "admin" group owns them, and +will change the permission of the BPF devices to rw-rw----, so that all +users in the "admin" group - i.e., all users with "Allow user to +administer this computer" turned on - have both read and write access to +them. + +The startup item is in the ChmodBPF directory in the source tree. A +/Library/StartupItems directory should be created if it doesn't already +exist, and the ChmodBPF directory should be copied to the +/Library/StartupItems directory (copy the entire directory, so that +there's a /Library/StartupItems/ChmodBPF directory, containing all the +files in the source tree's ChmodBPF directory; don't copy the individual +items in that directory to /Library/StartupItems). + +If you want to give a particular user permission to access the BPF +devices, rather than giving all administrative users permission to +access them, you can have the ChmodBPF/ChmodBPF script change the +ownership of /dev/bpf* without changing the permissions. If you want to +give a particular user permission to read and write the BPF devices and +give the administrative users permission to read but not write the BPF +devices, you can have the script change the owner to that user, the +group to "admin", and the permissions to rw-r-----. Other possibilities +are left as an exercise for the reader. diff --git a/winpcap/wpcap/libpcap/README.septel b/winpcap/wpcap/libpcap/README.septel new file mode 100644 index 0000000..fbc88df --- /dev/null +++ b/winpcap/wpcap/libpcap/README.septel @@ -0,0 +1,50 @@ +The following instructions apply if you have a Linux platform and want +libpcap to support the Septel range of passive network monitoring cards +from Intel (http://www.intel.com) + +1) Install and build the Septel software distribution by following the +instructions supplied with that package. + +2) Configure libcap. To allow the 'configure' script to locate the Septel +software distribution use the '--with-septel' option: + + ./configure --with-septel=DIR + +where DIR is the root of the Septel software distribution, for example +/var/src/septel. + +By default (if you write only ./configure --with-septel) it takes +./../septel as argument for DIR. + +If the Septel software is correctly detected 'configure' will +report: + + checking whether we have Septel API... yes + +If 'configure' reports that there is no Septel API, the directory may have been +incorrectly specified or the Septel software was not built before configuring +libpcap. + +See also the libpcap INSTALL.txt file for further libpcap configuration +options. + +Building libpcap at this stage will include support for both the native +packet capture stream and for capturing from Septel cards. To build +libpcap with only Septel support specify the capture type as 'septel' +when configuring libpcap: + + ./configure --with-septel=DIR --with-pcap=septel + +Applications built with libpcap configured in this way will only detect Septel +cards and will not capture from the native OS packet stream. + +Note: As mentioned in pcap-septel.c we should first edit the system.txt +file to change the user part example (UPE) module id to 0xdd instead of +0x2d for technical reason. So this change in system.txt is crutial and +things will go wrong if it's not done. System.txt along with config.txt +are configuration files that are edited by the user before running the +gctload program that uses these files for initialising modules and +configuring parameters. + +---------------------------------------------------------------------- +for more information please contact me : gil_hoyek@hotmail.com diff --git a/winpcap/wpcap/libpcap/README.tru64 b/winpcap/wpcap/libpcap/README.tru64 new file mode 100644 index 0000000..7fe1ef0 --- /dev/null +++ b/winpcap/wpcap/libpcap/README.tru64 @@ -0,0 +1,49 @@ +The following instructions are applicable to Tru64 UNIX +(formerly Digital UNIX (formerly DEC OSF/1)) version 4.0, and +probably to later versions as well; at least some options apply to +Digital UNIX 3.2 - perhaps all do. + +In order to use kernel packet filtering on this system, you have +to configure it in such a way: + +Kernel configuration +-------------------- + +The packet filtering kernel option must be enabled at kernel +installation. If it was not the case, you can rebuild the kernel with +"doconfig -c" after adding the following line in the kernel +configuration file (/sys/conf/): + + option PACKETFILTER + +or use "doconfig" without any arguments to add the packet filter driver +option via the kernel option menu (see the system administration +documentation for information on how to do this). + +Device configuration +-------------------- + +Devices used for packet filtering must be created thanks to +the following command (executed in the /dev directory): + + ./MAKEDEV pfilt + +Interface configuration +----------------------- + +In order to capture all packets on a network, you may want to allow +applications to put the interface on that network into "local copy" +mode, so that tcpdump can see packets sent by the host on which it's +running as well as packets received by that host, and to put the +interface into "promiscuous" mode, so that tcpdump can see packets on +the network segment not sent to the host on which it's running, by using +the pfconfig(1) command: + + pfconfig +c +p + +or allow application to put any interface into "local copy" or +"promiscuous" mode by using the command: + + pfconfig +c +p -a + +Note: all instructions given require root privileges. diff --git a/winpcap/wpcap/libpcap/SUNOS4/nit_if.o.sparc b/winpcap/wpcap/libpcap/SUNOS4/nit_if.o.sparc new file mode 100644 index 0000000000000000000000000000000000000000..d05073eac7666b6a880f01c53c7077581fc9fac9 GIT binary patch literal 5212 zcwVhoeQaCR6~FJh zMyc5J(lInaHkB$=6&hewsAUWxRH`cNkP=mB+aHr=MP3#~EP9kE%Sx!KEp)*x%YNtG zoA_&RFmoV{C#sKXv{6J^W+7`tfAtyPTOjW#X8>m zs%f-hq!q(}JSWP!$*6FE0x5b)heb!)I4xeT##J78L?Q_BN z5!-FCzT*a0PZ(S~Z+vadu-KC`JN8t;*9m#vTcHQE@6+D-W^?VV$98l|eYeqBTj(?P zLjPr8qQ!CUn8Epk!TjKjK~L9`&W+Os4@o@_E|Q+pQ@8A~m_|0fVQ@q4-M4@}mmd8; z^h~b(Ub)AR67g_Bwy~~ih+!JT@?l`;FWBTjeJc4Kc zRF4_OV_fesV|YhMHr}DLLUy}qu{H&?tC|@(2U}O}w!?MJ3?Uc2klk0^7iY&?Qr7f7 zGq4#69d9{h*Y=sA8O?+(to?*)M`pTBn_{;>h9j?qGg{Yr5C_DFXt2X8Y~_q>oklFC17;ZKn-HIety89g_icDL z{|@bLNxOq+Bn$fd=XFzsZGN(e=nE>3EQBg#Zwu^-5$#HwQ)ip8jw+7t z$_;wEYFE3u#STfm?a*P+{y5@zbuZoFAkUiaD^zdFudryAl) zY!$ISu9{x!j1x<(wa?#iTup{)4I2#Nsp@8k{K48eL-8Ls_|e*(W*9wuV5ZwP{wqd~ z-!8ci(K)O&xjx#;{j~PT^c}Qc-XD~ENWBM zc6$x^pc<{ImCz;K+(U74;s%@NHQRt+o2aH2Aj`&c3i6D}wNEeaw_)YXW zXiH1owv%7fkKxoMV(-eAAAKI8K1E+1t)frCr{Ub(G<3m^2x2ulb7v(C+MlK%YX!0< zVC#xj0k)X+iwgBx+ma4jw%A_CHE14U?nDsNCh#iOn5jUQPC6+saVC0pV-{I#^HuPZ zKd}EO*$;geR$+tnbElWXwC_4gb?B#gNAxQ=_cqQg-)+*lUsIgUHCHyh6JEP^74r!* zoMJvY-ePssu%;YP{J~oxpXT8c;x#(&u|vpFfTBKZ;yx}ax92QAX~^^^vx*wOm@H@Z+*MP zsGq2p!1pM6DMUR=^Keylazi<#Ss9zgePW%8N0I;5Rm{>F>IU=x^)2<=jLtEyZOUMt`r&<4+$5w#H=Ap}aL)cx{<7`3L-Lh`?BI?8%6L!@Aq)KG)#wj+m*@33`G6|qF!C^ScAN#2Xjy%q*fWEu5G z-%hW!+RXM$G4!C<-d_GfzeG$2$H^p#5kH;o-?zym! zs~2`{#58tJ#Iyr3^}zeN#x%akpfhx0>r@l> z2Os=0)=~7#UrEEOU(JjcWk>OpD8CYgS{z!Pw(zMeEhp2?TW z$$Tm;StE>vekO4g_(h4Ib3QGvctVRIdSvZGvB0q|7Gh*dk>HaHa!1pFu`oN}T;Hjz4v$oL5Y!rAn_n4LGT3#<6Q84Vb2PDWr(My!Z*lZIOA1? zJ?s&Im1W@XN*)gUgrKV@fr~EsVTn-}RFe*d4AHanCWl>ki_d|M{H+29$cA2lJ;(*S zS9h=@{~?J<=Hn8Rt|z5T_|Jx1@()Q&zauXE6Bo~z#1@{HUG&!_j^p{2>+HKOp7Sm| z>EijV3s+q{e|FjV7Z?3wiP7KeQ`gzgT=-^#U-5|eQ2dp!iym{~ZH==^uM6*W@!aRa z_q%w$A>;>|j&B@gOF`Eesw$_p-;<1YSRy69(Ics-t&KgtDPgZ~4W-yz^X z3c8M(Qsx9d{j1EoBaS9(g~Od(ayN}S8&2MZEEouMHw@UX!Bg+jTU$w5jkl^q;T z6G+fI=TM$Xmk+ZjoD`fCdV=WG256 zg`BWBGYF-*ObOCc$-Kjum)0R}10y0dsbV76pFLPglnVeOgD|d`%xAzgm>nq%9TK)W zTZ8EVhu5u;C5{ww{X%SJaKwoot-k%(X#Zp*~2s0du4-Kb_S%frQ9!d}Q4;PXHsU+A225`8PN|iDLtT#83W&Z|& CYBp^E literal 0 HcwPel00001 diff --git a/winpcap/wpcap/libpcap/SUNOS4/nit_if.o.sun3 b/winpcap/wpcap/libpcap/SUNOS4/nit_if.o.sun3 new file mode 100644 index 0000000000000000000000000000000000000000..c393fc6ec79182d5146b988eaece342d257e893c GIT binary patch literal 4267 zcwTK+eP~635a*UHWBO96vsrKsF!uh}}Ba$rZJ*k$S z6iLp9XFR1W2_$ppKf(rO4F9#5Bo2WM)~z8kfsOq!){epoC2P&tSeFIQ8zFc@t#;16 zSJt&N!F}g*n|+;gA6rFZ~ZDgf{fu%GJ=r%D7L;o;M@Cy@`2RW0TZvo%7Y<|i7sMYO=?t6KE#lM!=X}xl;5O)iNzl4p12u5NKiB1e7rX{O zzjPdYf({HW!A=}{*Q>A_sSk&SniU*ANqfcqiZKbk?K7Z5TL)_GzYo0!XWp$q>%p1e z3TQd{K=$?%!sDUmY>ARn`ngO0i#e-3;dS(NJr zpBGnb-MnUNgEu3ib&ejEpISBU{rT_g_MX>jRl})OJEIu=DvtKZMSxbFbB~SCo^gYs z3Uz~8Uo8N70}XG`WAfHl0NoF57%3=PQMq@?E*9JIIi^)m?1}~OOmJ#m9Ta;vc^?Xb zx9(eg*QLW}5+~RI_mNMNdGQVXOkQ(6V`~c}*MoAkDn7lnbt71-o~-nQYgj9_b-RcW zt&^`NdTLEjd}h@8Rw!6oCoL`N*a-4IwMehVZN($V_2dBRM2|4%B+V?Wp;Q&eQygo^ zvxYmt;rWq&f-K$Iz?3RrqsE}m@Mx8aT2Sp)t+H%n+AMJWz{Gk& z`c^&5SV3<>+w773uY&%3R$LD|bIecT^>(1v$Y{ueRW%8H+_(K<(9Jubqt0`Z&P%A% zK%E-u$ZnFqfK|CsKkS_B+~SLyd_lQ>JSo~{or8Cn#$9!d^iF%CwdxGC1#2}sY-T~V z)fpvj7(KjZtruBc^whH!9q9)1iru%_=Kf=3QF&OGvR@p$xmm{g{p{L%Sh+gdnccR0 z_0kg0^j6=LS=l$zN8CnbOKw!28zm}pcSSLmc=l~wTSBw#pij7G+p!bq&s!25XQL-z zomKIq0F!s4T|MqLjsi44!ku;25hrTv4pu{4r>*aKT4=_#pD^UH7kNG7-uUMCxV3^=Z&|KA66a)v&dK0ijO`*jP5nj}X!q`d z*Ycwt-CP9CZpAg58?c^z~8ey|H;_6VD-%XuSo zCIVr+6F^xcetgG^<{WY_beuqYf&XJKAZpGR3T&}=3wCyln%B_YHGA;EEj(pABB$yc z{;>HytDAV@ohYe4?+4>>GY&O~92D71`|=g+fU7e=GqkJNuILqkn{3xu9lHoqm4)1L zjp2FP@PNk$_odoVuy*QtJ7^tyn_gT0`hQ5`W$c#w(x8I+@;vQD7r9T&@~#Fq>#C@m zR>m4UE?Fbx&+vo#{vzF>IIq;XBd4ei>pll?HF6636~6^1MJ?S^N%eg5+ON>cstF{m~Mrr!W6y?yqw!Pt6(NcWEI#i?BBQF$&_OmE0{D61pE4p zfq_tOU#Rzp@k+jMv1lAPGH}>9G36M?Gs$8e;0yS5(2G6l@w*lLX4&*p`Z;a6C*}{~ zxnF&+Q9Y*T%a()*^v6m=*pQ^~`dP~p+!S}JCj{)`} zZ8AB36Momegj6-SJ@urZ&$vI$*EpYB6SSNA6^uyh zXCyqy?Rx2d#Cfsq!*NOAFpld2Q?vfQ!1Vi}q-R0mxh3)ZlJ{%GV@Z&s7-lsHF3o5>GSpNo2Pp7Wmf`@HXaZ|d=SbjAWV81pdkqr5BE{rF}6@}ud(TRo;>owJo@i?zM= zdDCdY!9~SnD_Vq28k||jS;uCJHCX39U}fEGx6T#)T^6gS{Y8UyIDDGzA->04v zMEeiLeqF!CG_w7Q!40YV{(0!G$-|F-k}SzYVCT5O`INzYIBSPr+JerFa|RDe*&SCQ z3trFpI?flmxv`@2AY?+z-KM$-or~QOw$c@0H@Z#VN*52|*;DK`!+4CF-DW%15ZS>R zyeRB!R4lfEvVL7NLlf|GX@}jgqM1SDw+FiWO1mTMWOLk_*=_pQz7q><6W!l&jo(GK$^V-geADb;NwY)N z3*3V|*3*5;oN6tCkBOYH4%$!AUF)kn0a~qBBXma;N5>T1u{=j!KczDVLtj}dvUSkm z=xgST_T_Hm0XZTX{7{9joRP0H$iwnNhH zCK~C2J>R5mD)7xmJ`sIh;i36pf&6WTU+qM@w!x{f_1K3!PV9Z#>W@T=~x5QJ@%^<~t{oAys{Er*_X!#zq0e!i*(q$X}m7_nC?J{yf^-)#|!OObY zPd++6gMUu54d`s5dYXqm8_!wjgzP&XZs!f?t0Pyp7aGo^=RliW=(3&M;_eKmCJ?tP zS3dMuka`3?akPXU0iOoB^E0poKSJ>HNadbF186T7p=$}crclF6S^?N%){hEQ=NlGu z_|j^t&}-0q!K?^DrXIW=>zL_*EuCyqP9jY7OU)1PufGm{iUVzWhJJ=P#+$9SGWN6Jzp{-J zZ<=D7LrlomkvXp&TmkRv23IdNnN2HOitH+Q7q;8P8@~qLMer`x6@rU(7Uq&^%;+ZF zM?LjA=`GX#Y@uPn}@sFtaY!Piltcxt^cT|Gp# zj=d)L6D{0Fd#~Jov!%~Duao;<$-OT3^X^{SJY9VNc7rm1M=5{qp1Fuxkn?yW^(f85 zWyPrvswJ8d)=(XtJQOcGy8t}iowq=`deGMqAKv%jg32kTpbee! zj*=9=i?7|31n;deBos-^@6^m}Iww>|IB1Y=F$EW}D3_ zMOIO4b+*%Hl}=loQ;V!rXR9v-ip^*4v;D^v)>Hz$44HAI;47n-Tt3%-DD}bT@RiOY zqd5*A)H(3c8D=EK5kTHriLay;)ETYdgWmcQ_$#2{n?#lGjMiF=sI5(uH=?TcLn0}tLw3^SzQ z)KeL{Z{R^4)73-&1AC%l=yZHYkBs zvxiuHZ$b_+_++lb=%v4ttsCGYe~v6bZtIr2`CX4BVuOk7KAukIqsgJ3`1WV`y*>SW zZ(ncUeZ4#T_`Q4f(Z9VsmB=P?{7Z*M`CU9WmhO-9t@|I^f49(6lZNch{%za%o;|&N zJA3=~@`p2{&t>_&d-v?-PmHDc*OKvU27WU7*mQpCuDxUR*zEuKlY=wPuV_4#$t8F? zlTI8;=JJVjo+s0}d@LPLNY)Tz!5>H*27XcEZ@cKnT=aRyHa=giR@?D6)P8~gJpue4 zV_k&z0MD<qf*fzq)fu*0H;=Hb3 z;FUkZJ`?e-VAX~h+XsB>H1Hvb5sx-5blyrarr$5{GXBQYzp)mt{^VM`I^;R=K%Z|| z;D3SULtI-3Bd+=v7g9b^2kq4LqN~uK!&j`w3_P@Q0li*aKcxkUYo_J1^)8;orFE?@EjsWba7~9irE1rGQ=jW5eMrL z*n0uL_UR6G^nY1m()qZ=Wb0c}C*o(rF8v2<|672c!!Gx5MgK@*^fdd2OZF2NzP-lp@rwLV{yhyYdbHoP)_GK6S4Hy2k z#6hZwx;6ek$h)R_RS|R@weR^r@Y8S4-&}fR4i)6tQ_CUYTWdZjiVOQCMo7vXBCa6j zq0;5z*%logKFp%SnOr^{8%d-RX%=0Z)HOUhl6zX>WG0?ZNj#EF4`n2NHc3NX;H#GyQ$$RA?SbTXG2%EwuBG&wjN%MCM!V>FwIuXzPkalEy_ znPR551<^<;eDUFXlm#35DP&xs_!e~AjKft2d7(B~o53*=1mCD4yo=T<<&@zxo z)f^rj0~*YX#FFXNEQ|<`lS42%lFUJSJeGDC)6zTSZE#GaCO#S+8Au(-Me`Yeu^~7& z8cQd^HIy354a0gio=Xl2mmQ9w#GoVMw#%Z2Ga~~+dva*ZNh0kYeeChCKkNh`&SK9b z(%G@vO=U(`FU@ry6f}!cmPVq_#?sIh8Sa4zon+%qzkV*ddR;7g +#if (!defined(BSD)) || (BSD < 199306) +# include +#else +# include +#endif +#include +#else +#include +#define __LITTLE_ENDIAN 1 +#define __BYTE_ORDER __LITTLE_ENDIAN +#endif + +/* + * revision information. this is the release date in YYYYMMDD format. + * it can change every day so the right thing to do with it is use it + * in preprocessor commands such as "#if (__BIND > 19931104)". do not + * compare for equality; rather, use it to determine whether your resolver + * is new enough to contain a certain feature. + */ + +#define __BIND 19940417 /* interface version stamp */ + +/* + * Define constants based on rfc883 + */ +#define PACKETSZ 512 /* maximum packet size */ +#define MAXDNAME 256 /* maximum domain name */ +#define MAXCDNAME 255 /* maximum compressed domain name */ +#define MAXLABEL 63 /* maximum length of domain label */ +#define HFIXEDSZ 12 /* #/bytes of fixed data in header */ +#define QFIXEDSZ 4 /* #/bytes of fixed data in query */ +#define RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ +#define INT32SZ 4 /* for systems without 32-bit ints */ +#define INT16SZ 2 /* for systems without 16-bit ints */ +#define INADDRSZ 4 /* for sizeof(struct inaddr) != 4 */ + +/* + * Internet nameserver port number + */ +#define NAMESERVER_PORT 53 + +/* + * Currently defined opcodes + */ +#define QUERY 0x0 /* standard query */ +#define IQUERY 0x1 /* inverse query */ +#define STATUS 0x2 /* nameserver status query */ +/*#define xxx 0x3 *//* 0x3 reserved */ +#define NS_NOTIFY_OP 0x4 /* notify secondary of SOA change */ +#ifdef ALLOW_UPDATES + /* non standard - supports ALLOW_UPDATES stuff from Mike Schwartz */ +# define UPDATEA 0x9 /* add resource record */ +# define UPDATED 0xa /* delete a specific resource record */ +# define UPDATEDA 0xb /* delete all named resource record */ +# define UPDATEM 0xc /* modify a specific resource record */ +# define UPDATEMA 0xd /* modify all named resource record */ +# define ZONEINIT 0xe /* initial zone transfer */ +# define ZONEREF 0xf /* incremental zone referesh */ +#endif + +/* + * Currently defined response codes + */ +#ifdef HAVE_ADDRINFO +#define NOERROR 0 /* no error */ +#endif /* HAVE_ADDRINFO */ +#define FORMERR 1 /* format error */ +#define SERVFAIL 2 /* server failure */ +#define NXDOMAIN 3 /* non existent domain */ +#define NOTIMP 4 /* not implemented */ +#define REFUSED 5 /* query refused */ +#ifdef ALLOW_UPDATES + /* non standard */ +# define NOCHANGE 0xf /* update failed to change db */ +#endif + +/* + * Type values for resources and queries + */ +#define T_A 1 /* host address */ +#define T_NS 2 /* authoritative server */ +#define T_MD 3 /* mail destination */ +#define T_MF 4 /* mail forwarder */ +#define T_CNAME 5 /* canonical name */ +#define T_SOA 6 /* start of authority zone */ +#define T_MB 7 /* mailbox domain name */ +#define T_MG 8 /* mail group member */ +#define T_MR 9 /* mail rename name */ +#define T_NULL 10 /* null resource record */ +#define T_WKS 11 /* well known service */ +#define T_PTR 12 /* domain name pointer */ +#define T_HINFO 13 /* host information */ +#define T_MINFO 14 /* mailbox information */ +#define T_MX 15 /* mail routing information */ +#define T_TXT 16 /* text strings */ +#define T_RP 17 /* responsible person */ +#define T_AFSDB 18 /* AFS cell database */ +#define T_X25 19 /* X_25 calling address */ +#define T_ISDN 20 /* ISDN calling address */ +#define T_RT 21 /* router */ +#define T_NSAP 22 /* NSAP address */ +#define T_NSAP_PTR 23 /* reverse NSAP lookup (deprecated) */ +#define T_SIG 24 /* security signature */ +#define T_KEY 25 /* security key */ +#define T_PX 26 /* X.400 mail mapping */ +#define T_GPOS 27 /* geographical position (withdrawn) */ +#define T_AAAA 28 /* IP6 Address */ +#define T_LOC 29 /* Location Information */ + /* non standard */ +#define T_UINFO 100 /* user (finger) information */ +#define T_UID 101 /* user ID */ +#define T_GID 102 /* group ID */ +#define T_UNSPEC 103 /* Unspecified format (binary data) */ + /* Query type values which do not appear in resource records */ +#define T_AXFR 252 /* transfer zone of authority */ +#define T_MAILB 253 /* transfer mailbox records */ +#define T_MAILA 254 /* transfer mail agent records */ +#define T_ANY 255 /* wildcard match */ + +/* + * Values for class field + */ + +#define C_IN 1 /* the arpa internet */ +#define C_CHAOS 3 /* for chaos net (MIT) */ +#define C_HS 4 /* for Hesiod name server (MIT) (XXX) */ + /* Query class values which do not appear in resource records */ +#define C_ANY 255 /* wildcard match */ + +/* + * Status return codes for T_UNSPEC conversion routines + */ +#define CONV_SUCCESS 0 +#define CONV_OVERFLOW (-1) +#define CONV_BADFMT (-2) +#define CONV_BADCKSUM (-3) +#define CONV_BADBUFLEN (-4) + +#ifndef __BYTE_ORDER +#if (BSD >= 199103) +# include +#else +#ifdef linux +# include +#else +#define __LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */ +#define __BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ +#define __PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/ + +#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \ + defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \ + defined(__alpha__) || defined(__alpha) +#define __BYTE_ORDER __LITTLE_ENDIAN +#endif + +#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \ + defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \ + defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\ + defined(apollo) || defined(__convex__) || defined(_CRAY) || \ + defined(__hppa) || defined(__hp9000) || \ + defined(__hp9000s300) || defined(__hp9000s700) || \ + defined (BIT_ZERO_ON_LEFT) || defined(m68k) +#define __BYTE_ORDER __BIG_ENDIAN +#endif +#endif /* linux */ +#endif /* BSD */ +#endif /* __BYTE_ORDER */ + +#if !defined(__BYTE_ORDER) || \ + (__BYTE_ORDER != __BIG_ENDIAN && __BYTE_ORDER != __LITTLE_ENDIAN && \ + __BYTE_ORDER != __PDP_ENDIAN) + /* you must determine what the correct bit order is for + * your compiler - the next line is an intentional error + * which will force your compiles to bomb until you fix + * the above macros. + */ + error "Undefined or invalid __BYTE_ORDER"; +#endif + +/* + * Structure for query header. The order of the fields is machine- and + * compiler-dependent, depending on the byte/bit order and the layout + * of bit fields. We use bit fields only in int variables, as this + * is all ANSI requires. This requires a somewhat confusing rearrangement. + */ + +typedef struct { + unsigned id :16; /* query identification number */ +#if __BYTE_ORDER == __BIG_ENDIAN + /* fields in third byte */ + unsigned qr: 1; /* response flag */ + unsigned opcode: 4; /* purpose of message */ + unsigned aa: 1; /* authoritive answer */ + unsigned tc: 1; /* truncated message */ + unsigned rd: 1; /* recursion desired */ + /* fields in fourth byte */ + unsigned ra: 1; /* recursion available */ + unsigned pr: 1; /* primary server req'd (!standard) */ + unsigned unused :2; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned rcode :4; /* response code */ +#endif +#if __BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __PDP_ENDIAN + /* fields in third byte */ + unsigned rd :1; /* recursion desired */ + unsigned tc :1; /* truncated message */ + unsigned aa :1; /* authoritive answer */ + unsigned opcode :4; /* purpose of message */ + unsigned qr :1; /* response flag */ + /* fields in fourth byte */ + unsigned rcode :4; /* response code */ + unsigned unused :2; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned pr :1; /* primary server req'd (!standard) */ + unsigned ra :1; /* recursion available */ +#endif + /* remaining bytes */ + unsigned qdcount :16; /* number of question entries */ + unsigned ancount :16; /* number of answer entries */ + unsigned nscount :16; /* number of authority entries */ + unsigned arcount :16; /* number of resource entries */ +} HEADER; + +/* + * Defines for handling compressed domain names + */ +#define INDIR_MASK 0xc0 + +/* + * Structure for passing resource records around. + */ +struct rrec { + int16_t r_zone; /* zone number */ + int16_t r_class; /* class number */ + int16_t r_type; /* type number */ + u_int32_t r_ttl; /* time to live */ + int r_size; /* size of data area */ + char *r_data; /* pointer to data */ +}; + +//extern u_int16_t _getshort __P((const u_char *)); +//extern u_int32_t _getlong __P((const u_char *)); + +/* + * Inline versions of get/put short/long. Pointer is advanced. + * + * These macros demonstrate the property of C whereby it can be + * portable or it can be elegant but rarely both. + */ +#define GETSHORT(s, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (s) = ((u_int16_t)t_cp[0] << 8) \ + | ((u_int16_t)t_cp[1]) \ + ; \ + (cp) += INT16SZ; \ +} + +#define GETLONG(l, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (l) = ((u_int32_t)t_cp[0] << 24) \ + | ((u_int32_t)t_cp[1] << 16) \ + | ((u_int32_t)t_cp[2] << 8) \ + | ((u_int32_t)t_cp[3]) \ + ; \ + (cp) += INT32SZ; \ +} + +#define PUTSHORT(s, cp) { \ + register u_int16_t t_s = (u_int16_t)(s); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp = t_s; \ + (cp) += INT16SZ; \ +} + +#define PUTLONG(l, cp) { \ + register u_int32_t t_l = (u_int32_t)(l); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ + *t_cp = t_l; \ + (cp) += INT32SZ; \ +} + +#endif /* !_NAMESER_H_ */ diff --git a/winpcap/wpcap/libpcap/Win32/Include/bittypes.h b/winpcap/wpcap/libpcap/Win32/Include/bittypes.h new file mode 100644 index 0000000..c84077a --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Include/bittypes.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef _BITTYPES_H +#define _BITTYPES_H + +#ifndef HAVE_U_INT8_T + +#if SIZEOF_CHAR == 1 +typedef unsigned char u_int8_t; +typedef signed char int8_t; +#elif SIZEOF_INT == 1 +typedef unsigned int u_int8_t; +typedef signed int int8_t; +#else /* XXX */ +#error "there's no appropriate type for u_int8_t" +#endif +#define HAVE_U_INT8_T 1 +#define HAVE_INT8_T 1 + +#endif /* HAVE_U_INT8_T */ + +#ifndef HAVE_U_INT16_T + +#if SIZEOF_SHORT == 2 +typedef unsigned short u_int16_t; +typedef signed short int16_t; +#elif SIZEOF_INT == 2 +typedef unsigned int u_int16_t; +typedef signed int int16_t; +#elif SIZEOF_CHAR == 2 +typedef unsigned char u_int16_t; +typedef signed char int16_t; +#else /* XXX */ +#error "there's no appropriate type for u_int16_t" +#endif +#define HAVE_U_INT16_T 1 +#define HAVE_INT16_T 1 + +#endif /* HAVE_U_INT16_T */ + +#ifndef HAVE_U_INT32_T + +#if SIZEOF_INT == 4 +typedef unsigned int u_int32_t; +typedef signed int int32_t; +#elif SIZEOF_LONG == 4 +typedef unsigned long u_int32_t; +typedef signed long int32_t; +#elif SIZEOF_SHORT == 4 +typedef unsigned short u_int32_t; +typedef signed short int32_t; +#else /* XXX */ +#error "there's no appropriate type for u_int32_t" +#endif +#define HAVE_U_INT32_T 1 +#define HAVE_INT32_T 1 + +#endif /* HAVE_U_INT32_T */ + +#ifndef HAVE_U_INT64_T +#if SIZEOF_LONG_LONG == 8 +typedef unsigned long long u_int64_t; +#elif defined(_MSC_EXTENSIONS) +typedef unsigned _int64 u_int64_t; +#elif SIZEOF_INT == 8 +typedef unsigned int u_int64_t; +#elif SIZEOF_LONG == 8 +typedef unsigned long u_int64_t; +#elif SIZEOF_SHORT == 8 +typedef unsigned short u_int64_t; +#else /* XXX */ +#error "there's no appropriate type for u_int64_t" +#endif + +#endif /* HAVE_U_INT64_T */ + +#ifndef PRId64 +#ifdef _MSC_EXTENSIONS +#define PRId64 "I64d" +#else /* _MSC_EXTENSIONS */ +#define PRId64 "lld" +#endif /* _MSC_EXTENSIONS */ +#endif /* PRId64 */ + +#ifndef PRIo64 +#ifdef _MSC_EXTENSIONS +#define PRIo64 "I64o" +#else /* _MSC_EXTENSIONS */ +#define PRIo64 "llo" +#endif /* _MSC_EXTENSIONS */ +#endif /* PRIo64 */ + +#ifndef PRIx64 +#ifdef _MSC_EXTENSIONS +#define PRIx64 "I64x" +#else /* _MSC_EXTENSIONS */ +#define PRIx64 "llx" +#endif /* _MSC_EXTENSIONS */ +#endif /* PRIx64 */ + +#ifndef PRIu64 +#ifdef _MSC_EXTENSIONS +#define PRIu64 "I64u" +#else /* _MSC_EXTENSIONS */ +#define PRIu64 "llu" +#endif /* _MSC_EXTENSIONS */ +#endif /* PRIu64 */ + +#endif /* _BITTYPES_H */ diff --git a/winpcap/wpcap/libpcap/Win32/Include/cdecl_ext.h b/winpcap/wpcap/libpcap/Win32/Include/cdecl_ext.h new file mode 100644 index 0000000..9591db2 --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Include/cdecl_ext.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef HAVE_PORTABLE_PROTOTYPE + +#if defined(__STDC__) || defined(__cplusplus) +#define __P(protos) protos /* full-blown ANSI C */ +#else +#define __P(protos) () /* traditional C preprocessor */ +#endif + +#endif /* !HAVE_PORTABLE_PROTOTYPE */ diff --git a/winpcap/wpcap/libpcap/Win32/Include/inetprivate.h b/winpcap/wpcap/libpcap/Win32/Include/inetprivate.h new file mode 100644 index 0000000..e25ed3d --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Include/inetprivate.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 1999 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern void _sethtent(int f); +extern void _endhtent(void); +extern struct hostent *_gethtent(void); +extern struct hostent *_gethtbyname(const char *name); +extern struct hostent *_gethtbyaddr(const char *addr, int len, + int type); +extern int _validuser(FILE *hostf, const char *rhost, + const char *luser, const char *ruser, int baselen); +extern int _checkhost(const char *rhost, const char *lhost, int len); +#if 0 +extern void putlong(u_long l, u_char *msgp); +extern void putshort(u_short l, u_char *msgp); +extern u_int32_t _getlong(register const u_char *msgp); +extern u_int16_t _getshort(register const u_char *msgp); +extern void p_query(char *msg); +extern void fp_query(char *msg, FILE *file); +extern char *p_cdname(char *cp, char *msg, FILE *file); +extern char *p_rr(char *cp, char *msg, FILE *file); +extern char *p_type(int type); +extern char * p_class(int class); +extern char *p_time(u_long value); +#endif +extern char * hostalias(const char *name); +extern void sethostfile(char *name); +extern void _res_close (void); +extern void ruserpass(const char *host, char **aname, char **apass); diff --git a/winpcap/wpcap/libpcap/Win32/Include/ip6_misc.h b/winpcap/wpcap/libpcap/Win32/Include/ip6_misc.h new file mode 100644 index 0000000..6ff3dd5 --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Include/ip6_misc.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 1993, 1994, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/Win32/Include/ip6_misc.h,v 1.4.2.1 2006/01/22 18:13:47 gianluca Exp $ (LBL) + */ + +/* + * This file contains a collage of declarations for IPv6 from FreeBSD not present in Windows + */ + +#include + +#ifndef __MINGW32__ +#include +#endif /* __MINGW32__ */ + +#ifndef __MINGW32__ +#define IN_MULTICAST(a) IN_CLASSD(a) +#endif + +#define IN_EXPERIMENTAL(a) ((((u_int32_t) (a)) & 0xf0000000) == 0xf0000000) + +#define IN_LOOPBACKNET 127 + +#ifdef __MINGW32__ +/* IPv6 address */ +struct in6_addr + { + union + { + u_int8_t u6_addr8[16]; + u_int16_t u6_addr16[8]; + u_int32_t u6_addr32[4]; + } in6_u; +#define s6_addr in6_u.u6_addr8 +#define s6_addr16 in6_u.u6_addr16 +#define s6_addr32 in6_u.u6_addr32 +#define s6_addr64 in6_u.u6_addr64 + }; + +#define IN6ADDR_ANY_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } +#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } +#endif /* __MINGW32__ */ + + +#if (defined WIN32) || (defined __MINGW32__) +typedef unsigned short sa_family_t; +#endif + + +#ifdef __MINGW32__ + +#define __SOCKADDR_COMMON(sa_prefix) \ + sa_family_t sa_prefix##family + +/* Ditto, for IPv6. */ +struct sockaddr_in6 + { + __SOCKADDR_COMMON (sin6_); + u_int16_t sin6_port; /* Transport layer port # */ + u_int32_t sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ + }; + +#define IN6_IS_ADDR_V4MAPPED(a) \ + ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \ + (((u_int32_t *) (a))[2] == htonl (0xffff))) + +#define IN6_IS_ADDR_MULTICAST(a) (((u_int8_t *) (a))[0] == 0xff) + +#define IN6_IS_ADDR_LINKLOCAL(a) \ + ((((u_int32_t *) (a))[0] & htonl (0xffc00000)) == htonl (0xfe800000)) + +#define IN6_IS_ADDR_LOOPBACK(a) \ + (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ + ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) +#endif /* __MINGW32__ */ + +#define ip6_vfc ip6_ctlun.ip6_un2_vfc +#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow +#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen +#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt +#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim +#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim + +#define nd_rd_type nd_rd_hdr.icmp6_type +#define nd_rd_code nd_rd_hdr.icmp6_code +#define nd_rd_cksum nd_rd_hdr.icmp6_cksum +#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] + +/* + * IPV6 extension headers + */ +#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */ +#define IPPROTO_IPV6 41 /* IPv6 header. */ +#define IPPROTO_ROUTING 43 /* IPv6 routing header */ +#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ +#define IPPROTO_ESP 50 /* encapsulating security payload */ +#define IPPROTO_AH 51 /* authentication header */ +#define IPPROTO_ICMPV6 58 /* ICMPv6 */ +#define IPPROTO_NONE 59 /* IPv6 no next header */ +#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ +#define IPPROTO_PIM 103 /* Protocol Independent Multicast. */ + +#define IPV6_RTHDR_TYPE_0 0 + +/* Option types and related macros */ +#define IP6OPT_PAD1 0x00 /* 00 0 00000 */ +#define IP6OPT_PADN 0x01 /* 00 0 00001 */ +#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */ +#define IP6OPT_JUMBO_LEN 6 +#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */ + +#define IP6OPT_RTALERT_LEN 4 +#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */ +#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */ +#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */ +#define IP6OPT_MINLEN 2 + +#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */ +#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */ +#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */ +#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */ +#define IP6OPT_EID 0x8a /* 10 0 01010 */ + +#define IP6OPT_TYPE(o) ((o) & 0xC0) +#define IP6OPT_TYPE_SKIP 0x00 +#define IP6OPT_TYPE_DISCARD 0x40 +#define IP6OPT_TYPE_FORCEICMP 0x80 +#define IP6OPT_TYPE_ICMP 0xC0 + +#define IP6OPT_MUTABLE 0x20 + + +#ifdef __MINGW32__ +#ifndef EAI_ADDRFAMILY +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif +#endif /* __MINGW32__ */ diff --git a/winpcap/wpcap/libpcap/Win32/Include/net/if.h b/winpcap/wpcap/libpcap/Win32/Include/net/if.h new file mode 100644 index 0000000..bf926b6 --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Include/net/if.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 1982, 1986, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)if.h 8.1 (Berkeley) 6/10/93 + * $FreeBSD: src/sys/net/if.h,v 1.49.2.1 1999/08/29 16:28:15 peter Exp $ + */ + +#ifndef _NET_IF_H_ +#define _NET_IF_H_ + +/* + * does not depend on on most other systems. This + * helps userland compatability. (struct timeval ifi_lastchange) + */ +#ifndef KERNEL +#include +#endif + +/* + * Structure describing information about an interface + * which may be of interest to management entities. + */ +struct if_data { + /* generic interface information */ + u_char ifi_type; /* ethernet, tokenring, etc */ + u_char ifi_physical; /* e.g., AUI, Thinnet, 10base-T, etc */ + u_char ifi_addrlen; /* media address length */ + u_char ifi_hdrlen; /* media header length */ + u_char ifi_recvquota; /* polling quota for receive intrs */ + u_char ifi_xmitquota; /* polling quota for xmit intrs */ + u_long ifi_mtu; /* maximum transmission unit */ + u_long ifi_metric; /* routing metric (external only) */ + u_long ifi_baudrate; /* linespeed */ + /* volatile statistics */ + u_long ifi_ipackets; /* packets received on interface */ + u_long ifi_ierrors; /* input errors on interface */ + u_long ifi_opackets; /* packets sent on interface */ + u_long ifi_oerrors; /* output errors on interface */ + u_long ifi_collisions; /* collisions on csma interfaces */ + u_long ifi_ibytes; /* total number of octets received */ + u_long ifi_obytes; /* total number of octets sent */ + u_long ifi_imcasts; /* packets received via multicast */ + u_long ifi_omcasts; /* packets sent via multicast */ + u_long ifi_iqdrops; /* dropped on input, this interface */ + u_long ifi_noproto; /* destined for unsupported protocol */ + u_long ifi_recvtiming; /* usec spent receiving when timing */ + u_long ifi_xmittiming; /* usec spent xmitting when timing */ + struct timeval ifi_lastchange; /* time of last administrative change */ +}; + +/* ws2tcpip.h has interface flags: IFF_* */ +#if 0 +#define IFF_UP 0x1 /* interface is up */ +#define IFF_BROADCAST 0x2 /* broadcast address valid */ +#define IFF_DEBUG 0x4 /* turn on debugging */ +#define IFF_LOOPBACK 0x8 /* is a loopback net */ +#define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */ +/*#define IFF_NOTRAILERS 0x20 * obsolete: avoid use of trailers */ +#define IFF_RUNNING 0x40 /* resources allocated */ +#define IFF_NOARP 0x80 /* no address resolution protocol */ +#define IFF_PROMISC 0x100 /* receive all packets */ +#define IFF_ALLMULTI 0x200 /* receive all multicast packets */ +#define IFF_OACTIVE 0x400 /* transmission in progress */ +#define IFF_SIMPLEX 0x800 /* can't hear own transmissions */ +#define IFF_LINK0 0x1000 /* per link layer defined bit */ +#define IFF_LINK1 0x2000 /* per link layer defined bit */ +#define IFF_LINK2 0x4000 /* per link layer defined bit */ +#define IFF_ALTPHYS IFF_LINK2 /* use alternate physical connection */ +#define IFF_MULTICAST 0x8000 /* supports multicast */ +#endif /* 0 */ + +/* flags set internally only: */ +#define IFF_CANTCHANGE \ + (IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\ + IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI) + +#define IFQ_MAXLEN 50 +#define IFNET_SLOWHZ 1 /* granularity is 1 second */ + +/* + * Message format for use in obtaining information about interfaces + * from getkerninfo and the routing socket + */ +struct if_msghdr { + u_short ifm_msglen; /* to skip over non-understood messages */ + u_char ifm_version; /* future binary compatability */ + u_char ifm_type; /* message type */ + int ifm_addrs; /* like rtm_addrs */ + int ifm_flags; /* value of if_flags */ + u_short ifm_index; /* index for associated ifp */ + struct if_data ifm_data;/* statistics and other data about if */ +}; + +/* + * Message format for use in obtaining information about interface addresses + * from getkerninfo and the routing socket + */ +struct ifa_msghdr { + u_short ifam_msglen; /* to skip over non-understood messages */ + u_char ifam_version; /* future binary compatability */ + u_char ifam_type; /* message type */ + int ifam_addrs; /* like rtm_addrs */ + int ifam_flags; /* value of ifa_flags */ + u_short ifam_index; /* index for associated ifp */ + int ifam_metric; /* value of ifa_metric */ +}; + +/* + * Message format for use in obtaining information about multicast addresses + * from the routing socket + */ +struct ifma_msghdr { + u_short ifmam_msglen; /* to skip over non-understood messages */ + u_char ifmam_version; /* future binary compatability */ + u_char ifmam_type; /* message type */ + int ifmam_addrs; /* like rtm_addrs */ + int ifmam_flags; /* value of ifa_flags */ + u_short ifmam_index; /* index for associated ifp */ +}; + +/* + * Interface request structure used for socket + * ioctl's. All interface ioctl's must have parameter + * definitions which begin with ifr_name. The + * remainder may be interface specific. + */ +struct ifreq { +#define IFNAMSIZ 16 + char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + union { + struct sockaddr ifru_addr; + struct sockaddr ifru_dstaddr; + struct sockaddr ifru_broadaddr; + short ifru_flags; + int ifru_metric; + int ifru_mtu; + int ifru_phys; + int ifru_media; + caddr_t ifru_data; + } ifr_ifru; +#define ifr_addr ifr_ifru.ifru_addr /* address */ +#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ +#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ +#define ifr_flags ifr_ifru.ifru_flags /* flags */ +#define ifr_metric ifr_ifru.ifru_metric /* metric */ +#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ +#define ifr_phys ifr_ifru.ifru_phys /* physical wire */ +#define ifr_media ifr_ifru.ifru_media /* physical media */ +#define ifr_data ifr_ifru.ifru_data /* for use by interface */ +}; + +#define _SIZEOF_ADDR_IFREQ(ifr) \ + ((ifr).ifr_addr.sa_len > sizeof(struct sockaddr) ? \ + (sizeof(struct ifreq) - sizeof(struct sockaddr) + \ + (ifr).ifr_addr.sa_len) : sizeof(struct ifreq)) + +struct ifaliasreq { + char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + struct sockaddr ifra_addr; + struct sockaddr ifra_broadaddr; + struct sockaddr ifra_mask; +}; + +struct ifmediareq { + char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + int ifm_current; /* current media options */ + int ifm_mask; /* don't care mask */ + int ifm_status; /* media status */ + int ifm_active; /* active options */ + int ifm_count; /* # entries in ifm_ulist array */ + int *ifm_ulist; /* media words */ +}; +/* + * Structure used in SIOCGIFCONF request. + * Used to retrieve interface configuration + * for machine (useful for programs which + * must know all networks accessible). + */ +struct ifconf { + int ifc_len; /* size of associated buffer */ + union { + caddr_t ifcu_buf; + struct ifreq *ifcu_req; + } ifc_ifcu; +#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ +#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */ +}; + +#ifdef KERNEL +#ifdef MALLOC_DECLARE +MALLOC_DECLARE(M_IFADDR); +MALLOC_DECLARE(M_IFMADDR); +#endif +#endif + +/* XXX - this should go away soon */ +#ifdef KERNEL +#include +#endif + +#endif /* !_NET_IF_H_ */ diff --git a/winpcap/wpcap/libpcap/Win32/Include/net/netdb.h b/winpcap/wpcap/libpcap/Win32/Include/net/netdb.h new file mode 100644 index 0000000..b9d45ac --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Include/net/netdb.h @@ -0,0 +1,164 @@ +/*- + * Copyright (c) 1980, 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)netdb.h 8.1 (Berkeley) 6/2/93 + * netdb.h,v 1.4 1995/08/14 04:05:04 hjl Exp + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +#ifndef _NETDB_H_ +#define _NETDB_H_ + +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT) +#include +#include +#endif + +#include +#include + +#define _PATH_HEQUIV __PATH_ETC_INET"/hosts.equiv" +#define _PATH_HOSTS __PATH_ETC_INET"/hosts" +#define _PATH_NETWORKS __PATH_ETC_INET"/networks" +#define _PATH_PROTOCOLS __PATH_ETC_INET"/protocols" +#define _PATH_SERVICES __PATH_ETC_INET"/services" +#define _PATH_RESCONF __PATH_ETC_INET"/resolv.conf" +#define _PATH_RPC __PATH_ETC_INET"/rpc" + +struct rpcent { + char *r_name; /* name of server for this rpc program */ + char **r_aliases; /* alias list */ + int r_number; /* rpc program number */ +}; + +#ifndef WIN32 +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT) + +#define __NETDB_MAXALIASES 35 +#define __NETDB_MAXADDRS 35 + +/* + * Error return codes from gethostbyname() and gethostbyaddr() + * (left in extern int h_errno). + */ +#define h_errno (*__h_errno_location ()) +#else +extern int h_errno; +#endif +#endif + +#define NETDB_INTERNAL -1 /* see errno */ +#define NETDB_SUCCESS 0 /* no problem */ + +//#include + +void endhostent (void); +void endnetent (void); +void endprotoent (void); +void endservent (void); +void endrpcent (void); +struct hostent *gethostent (void); +struct netent *getnetbyaddr (long, int); /* u_long? */ +struct netent *getnetbyname (const char *); +struct netent *getnetent (void); +struct protoent *getprotoent (void); +struct servent *getservent (void); +struct rpcent *getrpcent (void); +struct rpcent *getrpcbyname (const char *); +struct rpcent *getrpcbynumber (int); +void herror (const char *); +void sethostent (int); +/* void sethostfile (const char *); */ +void setnetent (int); +void setprotoent (int); +void setservent (int); +void setrpcent (int); + +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT) +struct hostent *gethostbyaddr_r (const char *__addr, + int __length, int __type, + struct hostent *__result, + char *__buffer, int __buflen, int *__h_errnop); +struct hostent *gethostbyname_r (const char * __name, + struct hostent *__result, char *__buffer, + int __buflen, int *__h_errnop); +struct hostent *gethostent_r (struct hostent *__result, + char *__buffer, int __buflen, int *__h_errnop); +struct netent *getnetbyaddr_r (long __net, int __type, + struct netent *__result, char *__buffer, + int __buflen); +struct netent *getnetbyname_r (const char * __name, + struct netent *__result, char *__buffer, + int __buflen); +struct netent *getnetent_r (struct netent *__result, + char *__buffer, int __buflen); +struct protoent *getprotobyname_r (const char * __name, + struct protoent *__result, char *__buffer, + int __buflen); +struct protoent *getprotobynumber_r (int __proto, + struct protoent *__result, char *__buffer, + int __buflen); +struct protoent *getprotoent_r (struct protoent *__result, + char *__buffer, int __buflen); +struct servent *getservbyname_r (const char * __name, + const char *__proto, struct servent *__result, + char *__buffer, int __buflen); +struct servent *getservbyport_r (int __port, + const char *__proto, struct servent *__result, + char *__buffer, int __buflen); +struct servent *getservent_r (struct servent *__result, + char *__buffer, int __buflen); + +int *__h_errno_location (void); + +#endif + +#endif /* !_NETDB_H_ */ diff --git a/winpcap/wpcap/libpcap/Win32/Include/net/paths.h b/winpcap/wpcap/libpcap/Win32/Include/net/paths.h new file mode 100644 index 0000000..987de4f --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Include/net/paths.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)paths.h 5.15 (Berkeley) 5/29/91 + */ + +#ifndef _PATHS_H_ +#define _PATHS_H_ + +#if 0 +#define __PATH_ETC_INET "/usr/etc/inet" +#else +#define __PATH_ETC_INET "/etc" +#endif + +/* Default search path. */ +#define _PATH_DEFPATH "/usr/local/bin:/usr/bin:/bin:." +#define _PATH_DEFPATH_ROOT "/sbin:/bin:/usr/sbin:/usr/bin" + +#define _PATH_BSHELL "/bin/sh" +#define _PATH_CONSOLE "/dev/console" +#define _PATH_CSHELL "/bin/csh" +#define _PATH_DEVDB "/var/run/dev.db" +#define _PATH_DEVNULL "/dev/null" +#define _PATH_DRUM "/dev/drum" +#define _PATH_HEQUIV __PATH_ETC_INET"/hosts.equiv" +#define _PATH_KMEM "/dev/kmem" +#define _PATH_MAILDIR "/var/spool/mail" +#define _PATH_MAN "/usr/man" +#define _PATH_MEM "/dev/mem" +#define _PATH_LOGIN "/bin/login" +#define _PATH_NOLOGIN "/etc/nologin" +#define _PATH_SENDMAIL "/usr/sbin/sendmail" +#define _PATH_SHELLS "/etc/shells" +#define _PATH_TTY "/dev/tty" +#define _PATH_UNIX "/vmlinux" +#define _PATH_VI "/usr/bin/vi" + +/* Provide trailing slash, since mostly used for building pathnames. */ +#define _PATH_DEV "/dev/" +#define _PATH_TMP "/tmp/" +#define _PATH_VARRUN "/var/run/" +#define _PATH_VARTMP "/var/tmp/" + +#define _PATH_KLOG "/proc/kmsg" +#define _PATH_LOGCONF __PATH_ETC_INET"/syslog.conf" +#if 0 +#define _PATH_LOGPID __PATH_ETC_INET"/syslog.pid" +#else +#define _PATH_LOGPID "/var/run/syslog.pid" +#endif +#define _PATH_LOG "/dev/log" +#define _PATH_CONSOLE "/dev/console" + +#if 0 +#define _PATH_UTMP "/var/adm/utmp" +#define _PATH_WTMP "/var/adm/wtmp" +#define _PATH_LASTLOG "/var/adm/lastlog" +#else +#define _PATH_UTMP "/var/run/utmp" +#define _PATH_WTMP "/var/log/wtmp" +#define _PATH_LASTLOG "/var/log/lastlog" +#endif + +#define _PATH_LOCALE "/usr/lib/locale" + +#define _PATH_RWHODIR "/var/spool/rwho" + +#if _MIT_POSIX_THREADS +/* For the MIT pthreads */ +#define _PATH_PTY "/dev/" +#define _PATH_TZDIR "/usr/lib/zoneinfo" +#define _PATH_TZFILE "/usr/lib/zoneinfo/localtime" +#endif + +#endif /* !_PATHS_H_ */ diff --git a/winpcap/wpcap/libpcap/Win32/Include/sockstorage.h b/winpcap/wpcap/libpcap/Win32/Include/sockstorage.h new file mode 100644 index 0000000..557eb4d --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Include/sockstorage.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +struct sockaddr_storage { +#ifdef HAVE_SOCKADDR_SA_LEN + u_int8_t __ss_len; + u_int8_t __ss_family; + u_int8_t fill[126]; +#else + u_int8_t __ss_family; + u_int8_t fill[127]; +#endif /* HAVE_SOCKADDR_SA_LEN */ +}; diff --git a/winpcap/wpcap/libpcap/Win32/Prj/libpcap.dsp b/winpcap/wpcap/libpcap/Win32/Prj/libpcap.dsp new file mode 100644 index 0000000..d60b843 --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Prj/libpcap.dsp @@ -0,0 +1,218 @@ +# Microsoft Developer Studio Project File - Name="libpcap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=libpcap - Win32 Debug REMOTE +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libpcap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libpcap.mak" CFG="libpcap - Win32 Debug REMOTE" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libpcap - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libpcap - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "libpcap - Win32 Debug REMOTE" (based on "Win32 (x86) Static Library") +!MESSAGE "libpcap - Win32 Release REMOTE" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libpcap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "NDEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "libpcap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "_DEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "libpcap - Win32 Debug REMOTE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "libpcap___Win32_Debug_REMOTE" +# PROP BASE Intermediate_Dir "libpcap___Win32_Debug_REMOTE" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_REMOTE" +# PROP Intermediate_Dir "Debug_REMOTE" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "_DEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "_DEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "HAVE_REMOTE" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "libpcap - Win32 Release REMOTE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "libpcap___Win32_Release_REMOTE" +# PROP BASE Intermediate_Dir "libpcap___Win32_Release_REMOTE" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_REMOTE" +# PROP Intermediate_Dir "Release_REMOTE" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "NDEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "NDEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "libpcap - Win32 Release" +# Name "libpcap - Win32 Debug" +# Name "libpcap - Win32 Debug REMOTE" +# Name "libpcap - Win32 Release REMOTE" +# Begin Source File + +SOURCE=..\..\bpf_dump.c +# End Source File +# Begin Source File + +SOURCE=..\..\bpf\net\bpf_filter.c +# End Source File +# Begin Source File + +SOURCE=..\..\bpf_image.c +# End Source File +# Begin Source File + +SOURCE=..\..\etherent.c +# End Source File +# Begin Source File + +SOURCE="..\..\fad-win32.c" +# End Source File +# Begin Source File + +SOURCE=..\Src\ffs.c +# End Source File +# Begin Source File + +SOURCE=..\..\gencode.c +# End Source File +# Begin Source File + +SOURCE=..\Src\getnetbynm.c +# End Source File +# Begin Source File + +SOURCE=..\Src\getnetent.c +# End Source File +# Begin Source File + +SOURCE=..\Src\getservent.c +# End Source File +# Begin Source File + +SOURCE=..\..\grammar.c +# End Source File +# Begin Source File + +SOURCE=..\..\inet.c +# End Source File +# Begin Source File + +SOURCE=..\Src\inet_aton.c +# End Source File +# Begin Source File + +SOURCE=..\Src\inet_net.c +# End Source File +# Begin Source File + +SOURCE=..\Src\inet_pton.c +# End Source File +# Begin Source File + +SOURCE=..\..\nametoaddr.c +# End Source File +# Begin Source File + +SOURCE=..\..\optimize.c +# End Source File +# Begin Source File + +SOURCE="..\..\Pcap-win32.c" +# End Source File +# Begin Source File + +SOURCE=..\..\pcap.c +# End Source File +# Begin Source File + +SOURCE=..\..\savefile.c +# End Source File +# Begin Source File + +SOURCE=..\..\scanner.c +# End Source File +# End Target +# End Project diff --git a/winpcap/wpcap/libpcap/Win32/Prj/libpcap.dsw b/winpcap/wpcap/libpcap/Win32/Prj/libpcap.dsw new file mode 100644 index 0000000..8cdff2d --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Prj/libpcap.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "libpcap"=".\libpcap.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/wpcap/libpcap/Win32/Src/ffs.c b/winpcap/wpcap/libpcap/Win32/Src/ffs.c new file mode 100644 index 0000000..099ff8e --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Src/ffs.c @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)ffs.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include + +/* + * ffs -- vax ffs instruction + */ +int +ffs(mask) + register int mask; +{ + register int bit; + + if (mask == 0) + return(0); + for (bit = 1; !(mask & 1); bit++) + mask >>= 1; + return(bit); +} diff --git a/winpcap/wpcap/libpcap/Win32/Src/gai_strerror.c b/winpcap/wpcap/libpcap/Win32/Src/gai_strerror.c new file mode 100644 index 0000000..d3d7d68 --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Src/gai_strerror.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* +#include + +__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/net/gai_strerror.c,v 1.1 2005/04/06 12:45:51 ume Exp $"); + +*/ + +#ifdef WIN32 + +#include + +#else + +#include + +#endif + +/* Entries EAI_ADDRFAMILY (1) and EAI_NODATA (7) are obsoleted, but left */ +/* for backward compatibility with userland code prior to 2553bis-02 */ +static char *ai_errlist[] = { + "Success", /* 0 */ + "Address family for hostname not supported", /* 1 */ + "Temporary failure in name resolution", /* EAI_AGAIN */ + "Invalid value for ai_flags", /* EAI_BADFLAGS */ + "Non-recoverable failure in name resolution", /* EAI_FAIL */ + "ai_family not supported", /* EAI_FAMILY */ + "Memory allocation failure", /* EAI_MEMORY */ + "No address associated with hostname", /* 7 */ + "hostname nor servname provided, or not known", /* EAI_NONAME */ + "servname not supported for ai_socktype", /* EAI_SERVICE */ + "ai_socktype not supported", /* EAI_SOCKTYPE */ + "System error returned in errno", /* EAI_SYSTEM */ + "Invalid value for hints", /* EAI_BADHINTS */ + "Resolved protocol is unknown" /* EAI_PROTOCOL */ +}; + +#ifndef EAI_MAX +#define EAI_MAX (sizeof(ai_errlist)/sizeof(ai_errlist[0])) +#endif + +char * +WSAAPI gai_strerrorA(int ecode) +{ + if (ecode >= 0 && ecode < EAI_MAX) + return ai_errlist[ecode]; + return "Unknown error"; +} + diff --git a/winpcap/wpcap/libpcap/Win32/Src/getaddrinfo.c b/winpcap/wpcap/libpcap/Win32/Src/getaddrinfo.c new file mode 100644 index 0000000..5f33f15 --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Src/getaddrinfo.c @@ -0,0 +1,1119 @@ +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator. + * + * Issues to be discussed: + * - Thread safe-ness must be checked. + * - Return values. There are nonstandard return values defined and used + * in the source code. This is because RFC2553 is silent about which error + * code must be returned for which situation. + * Note: + * - We use getipnodebyname() just for thread-safeness. There's no intent + * to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to + * getipnodebyname(). + * - The code filters out AFs that are not supported by the kernel, + * when globbing NULL hostname (to loopback, or wildcard). Is it the right + * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG + * in ai_flags? + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/Win32/Src/getaddrinfo.c,v 1.2 2003/11/15 23:24:06 guy Exp $"; +#endif + +#include +#if 0 +#include +#endif +#ifndef __MINGW32__ +#include +#endif +#include +#include +#include +#include +#include +#include + +#ifndef HAVE_PORTABLE_PROTOTYPE +#include "cdecl_ext.h" +#endif + +#ifndef HAVE_U_INT32_T +#include "bittypes.h" +#endif + +#ifndef HAVE_SOCKADDR_STORAGE +#ifndef __MINGW32__ +#include "sockstorage.h" +#endif +#endif + +#ifdef NEED_ADDRINFO_H +#include "addrinfo.h" +#ifdef WIN32 +#include "IP6_misc.h" +#endif +#endif + + +#if defined(__KAME__) && defined(INET6) +# define FAITH +#endif + +#define SUCCESS 0 +#define ANY 0 +#define YES 1 +#define NO 0 + +#ifdef FAITH +static int translate = NO; +static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT; +#endif + +static const char in_addrany[] = { 0, 0, 0, 0 }; +static const char in6_addrany[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +static const char in_loopback[] = { 127, 0, 0, 1 }; +static const char in6_loopback[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 +}; + +struct sockinet { + u_char si_len; + u_char si_family; + u_short si_port; + u_int32_t si_scope_id; +}; + +static const struct afd { + int a_af; + int a_addrlen; + int a_socklen; + int a_off; + const char *a_addrany; + const char *a_loopback; + int a_scoped; +} afdl [] = { +#ifdef INET6 + {PF_INET6, sizeof(struct in6_addr), + sizeof(struct sockaddr_in6), + offsetof(struct sockaddr_in6, sin6_addr), + in6_addrany, in6_loopback, 1}, +#endif + {PF_INET, sizeof(struct in_addr), + sizeof(struct sockaddr_in), + offsetof(struct sockaddr_in, sin_addr), + in_addrany, in_loopback, 0}, + {0, 0, 0, 0, NULL, NULL, 0}, +}; + +struct explore { + int e_af; + int e_socktype; + int e_protocol; + const char *e_protostr; + int e_wild; +#define WILD_AF(ex) ((ex)->e_wild & 0x01) +#define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02) +#define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04) +}; + +static const struct explore explore[] = { +#if 0 + { PF_LOCAL, 0, ANY, ANY, NULL, 0x01 }, +#endif +#ifdef INET6 + { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, + { PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, + { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 }, +#endif + { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, + { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, + { PF_INET, SOCK_RAW, ANY, NULL, 0x05 }, + { -1, 0, 0, NULL, 0 }, +}; + +#ifdef INET6 +#define PTON_MAX 16 +#else +#define PTON_MAX 4 +#endif + + +static int str_isnumber __P((const char *)); +static int explore_fqdn __P((const struct addrinfo *, const char *, + const char *, struct addrinfo **)); +static int explore_null __P((const struct addrinfo *, const char *, + const char *, struct addrinfo **)); +static int explore_numeric __P((const struct addrinfo *, const char *, + const char *, struct addrinfo **)); +static int explore_numeric_scope __P((const struct addrinfo *, const char *, + const char *, struct addrinfo **)); +static int get_name __P((const char *, const struct afd *, struct addrinfo **, + char *, const struct addrinfo *, const char *)); +static int get_canonname __P((const struct addrinfo *, + struct addrinfo *, const char *)); +static struct addrinfo *get_ai __P((const struct addrinfo *, + const struct afd *, const char *)); +static int get_portmatch __P((const struct addrinfo *, const char *)); +static int get_port __P((struct addrinfo *, const char *, int)); +static const struct afd *find_afd __P((int)); + +static char *ai_errlist[] = { + "Success", + "Address family for hostname not supported", /* EAI_ADDRFAMILY */ + "Temporary failure in name resolution", /* EAI_AGAIN */ + "Invalid value for ai_flags", /* EAI_BADFLAGS */ + "Non-recoverable failure in name resolution", /* EAI_FAIL */ + "ai_family not supported", /* EAI_FAMILY */ + "Memory allocation failure", /* EAI_MEMORY */ + "No address associated with hostname", /* EAI_NODATA */ + "hostname nor servname provided, or not known", /* EAI_NONAME */ + "servname not supported for ai_socktype", /* EAI_SERVICE */ + "ai_socktype not supported", /* EAI_SOCKTYPE */ + "System error returned in errno", /* EAI_SYSTEM */ + "Invalid value for hints", /* EAI_BADHINTS */ + "Resolved protocol is unknown", /* EAI_PROTOCOL */ + "Unknown error", /* EAI_MAX */ +}; + +/* XXX macros that make external reference is BAD. */ + +#define GET_AI(ai, afd, addr) \ +do { \ + /* external reference: pai, error, and label free */ \ + (ai) = get_ai(pai, (afd), (addr)); \ + if ((ai) == NULL) { \ + error = EAI_MEMORY; \ + goto free; \ + } \ +} while (0) + +#define GET_PORT(ai, serv) \ +do { \ + /* external reference: error and label free */ \ + error = get_port((ai), (serv), 0); \ + if (error != 0) \ + goto free; \ +} while (0) + +#define GET_CANONNAME(ai, str) \ +do { \ + /* external reference: pai, error and label free */ \ + error = get_canonname(pai, (ai), (str)); \ + if (error != 0) \ + goto free; \ +} while (0) + +#define ERR(err) \ +do { \ + /* external reference: error, and label bad */ \ + error = (err); \ + goto bad; \ +} while (0) + +#define MATCH_FAMILY(x, y, w) \ + ((x) == (y) || ((w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC))) +#define MATCH(x, y, w) \ + ((x) == (y) || ((w) && ((x) == ANY || (y) == ANY))) + +char * +gai_strerror(ecode) + int ecode; +{ + if (ecode < 0 || ecode > EAI_MAX) + ecode = EAI_MAX; + return ai_errlist[ecode]; +} + +void +freeaddrinfo(ai) + struct addrinfo *ai; +{ + struct addrinfo *next; + + do { + next = ai->ai_next; + if (ai->ai_canonname) + free(ai->ai_canonname); + /* no need to free(ai->ai_addr) */ + free(ai); + } while ((ai = next) != NULL); +} + +static int +str_isnumber(p) + const char *p; +{ + char *q = (char *)p; + while (*q) { + if (! isdigit(*q)) + return NO; + q++; + } + return YES; +} + +int +getaddrinfo(hostname, servname, hints, res) + const char *hostname, *servname; + const struct addrinfo *hints; + struct addrinfo **res; +{ + struct addrinfo sentinel; + struct addrinfo *cur; + int error = 0; + struct addrinfo ai; + struct addrinfo ai0; + struct addrinfo *pai; + const struct afd *afd; + const struct explore *ex; + +#ifdef FAITH + static int firsttime = 1; + + if (firsttime) { + /* translator hack */ + char *q = getenv("GAI"); + if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) + translate = YES; + firsttime = 0; + } +#endif + + sentinel.ai_next = NULL; + cur = &sentinel; + pai = &ai; + pai->ai_flags = 0; + pai->ai_family = PF_UNSPEC; + pai->ai_socktype = ANY; + pai->ai_protocol = ANY; + pai->ai_addrlen = 0; + pai->ai_canonname = NULL; + pai->ai_addr = NULL; + pai->ai_next = NULL; + + if (hostname == NULL && servname == NULL) + return EAI_NONAME; + if (hints) { + /* error check for hints */ + if (hints->ai_addrlen || hints->ai_canonname || + hints->ai_addr || hints->ai_next) + ERR(EAI_BADHINTS); /* xxx */ + if (hints->ai_flags & ~AI_MASK) + ERR(EAI_BADFLAGS); + switch (hints->ai_family) { + case PF_UNSPEC: + case PF_INET: +#ifdef INET6 + case PF_INET6: +#endif + break; + default: + ERR(EAI_FAMILY); + } + memcpy(pai, hints, sizeof(*pai)); + + /* + * if both socktype/protocol are specified, check if they + * are meaningful combination. + */ + if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) { + for (ex = explore; ex->e_af >= 0; ex++) { + if (pai->ai_family != ex->e_af) + continue; + if (ex->e_socktype == ANY) + continue; + if (ex->e_protocol == ANY) + continue; + if (pai->ai_socktype == ex->e_socktype + && pai->ai_protocol != ex->e_protocol) { + ERR(EAI_BADHINTS); + } + } + } + } + + /* + * check for special cases. (1) numeric servname is disallowed if + * socktype/protocol are left unspecified. (2) servname is disallowed + * for raw and other inet{,6} sockets. + */ + if (MATCH_FAMILY(pai->ai_family, PF_INET, 1) +#ifdef PF_INET6 + || MATCH_FAMILY(pai->ai_family, PF_INET6, 1) +#endif + ) { + ai0 = *pai; + + if (pai->ai_family == PF_UNSPEC) { +#ifdef PF_INET6 + pai->ai_family = PF_INET6; +#else + pai->ai_family = PF_INET; +#endif + } + error = get_portmatch(pai, servname); + if (error) + ERR(error); + + *pai = ai0; + } + + ai0 = *pai; + + /* NULL hostname, or numeric hostname */ + for (ex = explore; ex->e_af >= 0; ex++) { + *pai = ai0; + + if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) + continue; + if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) + continue; + if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) + continue; + + if (pai->ai_family == PF_UNSPEC) + pai->ai_family = ex->e_af; + if (pai->ai_socktype == ANY && ex->e_socktype != ANY) + pai->ai_socktype = ex->e_socktype; + if (pai->ai_protocol == ANY && ex->e_protocol != ANY) + pai->ai_protocol = ex->e_protocol; + + if (hostname == NULL) + error = explore_null(pai, hostname, servname, &cur->ai_next); + else + error = explore_numeric_scope(pai, hostname, servname, &cur->ai_next); + + if (error) + goto free; + + while (cur && cur->ai_next) + cur = cur->ai_next; + } + + /* + * XXX + * If numreic representation of AF1 can be interpreted as FQDN + * representation of AF2, we need to think again about the code below. + */ + if (sentinel.ai_next) + goto good; + + if (pai->ai_flags & AI_NUMERICHOST) + ERR(EAI_NONAME); + if (hostname == NULL) + ERR(EAI_NONAME); + + /* + * hostname as alphabetical name. + * we would like to prefer AF_INET6 than AF_INET, so we'll make a + * outer loop by AFs. + */ + for (afd = afdl; afd->a_af; afd++) { + *pai = ai0; + + if (!MATCH_FAMILY(pai->ai_family, afd->a_af, 1)) + continue; + + for (ex = explore; ex->e_af >= 0; ex++) { + *pai = ai0; + + if (pai->ai_family == PF_UNSPEC) + pai->ai_family = afd->a_af; + + if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) + continue; + if (!MATCH(pai->ai_socktype, ex->e_socktype, + WILD_SOCKTYPE(ex))) { + continue; + } + if (!MATCH(pai->ai_protocol, ex->e_protocol, + WILD_PROTOCOL(ex))) { + continue; + } + + if (pai->ai_family == PF_UNSPEC) + pai->ai_family = ex->e_af; + if (pai->ai_socktype == ANY && ex->e_socktype != ANY) + pai->ai_socktype = ex->e_socktype; + if (pai->ai_protocol == ANY && ex->e_protocol != ANY) + pai->ai_protocol = ex->e_protocol; + + error = explore_fqdn(pai, hostname, servname, + &cur->ai_next); + + while (cur && cur->ai_next) + cur = cur->ai_next; + } + } + + /* XXX */ + if (sentinel.ai_next) + error = 0; + + if (error) + goto free; + if (error == 0) { + if (sentinel.ai_next) { + good: + *res = sentinel.ai_next; + return SUCCESS; + } else + error = EAI_FAIL; + } + free: + bad: + if (sentinel.ai_next) + freeaddrinfo(sentinel.ai_next); + *res = NULL; + return error; +} + +/* + * FQDN hostname, DNS lookup + */ +static int +explore_fqdn(pai, hostname, servname, res) + const struct addrinfo *pai; + const char *hostname; + const char *servname; + struct addrinfo **res; +{ + struct hostent *hp; + int h_error; + int af; + char **aplist = NULL, *apbuf = NULL; + char *ap; + struct addrinfo sentinel, *cur; + int i; +#ifndef USE_GETIPNODEBY + int naddrs; +#endif + const struct afd *afd; + int error; + + *res = NULL; + sentinel.ai_next = NULL; + cur = &sentinel; + + /* + * Do not filter unsupported AFs here. We need to honor content of + * databases (/etc/hosts, DNS and others). Otherwise we cannot + * replace gethostbyname() by getaddrinfo(). + */ + + /* + * if the servname does not match socktype/protocol, ignore it. + */ + if (get_portmatch(pai, servname) != 0) + return 0; + + afd = find_afd(pai->ai_family); + + /* + * post-RFC2553: should look at (pai->ai_flags & AI_ADDRCONFIG) + * rather than hardcoding it. we may need to add AI_ADDRCONFIG + * handling code by ourselves in case we don't have getipnodebyname(). + */ +#ifdef USE_GETIPNODEBY + hp = getipnodebyname(hostname, pai->ai_family, AI_ADDRCONFIG, &h_error); +#else +#ifdef HAVE_GETHOSTBYNAME2 + hp = gethostbyname2(hostname, pai->ai_family); +#else + if (pai->ai_family != AF_INET) + return 0; + hp = gethostbyname(hostname); +#ifdef HAVE_H_ERRNO + h_error = h_errno; +#else + h_error = EINVAL; +#endif +#endif /*HAVE_GETHOSTBYNAME2*/ +#endif /*USE_GETIPNODEBY*/ + + if (hp == NULL) { + switch (h_error) { + case HOST_NOT_FOUND: + case NO_DATA: + error = EAI_NODATA; + break; + case TRY_AGAIN: + error = EAI_AGAIN; + break; + case NO_RECOVERY: + case NETDB_INTERNAL: + default: + error = EAI_FAIL; + break; + } + } else if ((hp->h_name == NULL) || (hp->h_name[0] == 0) + || (hp->h_addr_list[0] == NULL)) { +#ifdef USE_GETIPNODEBY + freehostent(hp); +#endif + hp = NULL; + error = EAI_FAIL; + } + + if (hp == NULL) + goto free; + +#ifdef USE_GETIPNODEBY + aplist = hp->h_addr_list; +#else + /* + * hp will be overwritten if we use gethostbyname2(). + * always deep copy for simplification. + */ + for (naddrs = 0; hp->h_addr_list[naddrs] != NULL; naddrs++) + ; + naddrs++; + aplist = (char **)malloc(sizeof(aplist[0]) * naddrs); + apbuf = (char *)malloc(hp->h_length * naddrs); + if (aplist == NULL || apbuf == NULL) { + error = EAI_MEMORY; + goto free; + } + memset(aplist, 0, sizeof(aplist[0]) * naddrs); + for (i = 0; i < naddrs; i++) { + if (hp->h_addr_list[i] == NULL) { + aplist[i] = NULL; + continue; + } + memcpy(&apbuf[i * hp->h_length], hp->h_addr_list[i], + hp->h_length); + aplist[i] = &apbuf[i * hp->h_length]; + } +#endif + + for (i = 0; aplist[i] != NULL; i++) { + af = hp->h_addrtype; + ap = aplist[i]; +#ifdef AF_INET6 + if (af == AF_INET6 + && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { + af = AF_INET; + ap = ap + sizeof(struct in6_addr) + - sizeof(struct in_addr); + } +#endif + + if (af != pai->ai_family) + continue; + + if ((pai->ai_flags & AI_CANONNAME) == 0) { + GET_AI(cur->ai_next, afd, ap); + GET_PORT(cur->ai_next, servname); + } else { + /* + * if AI_CANONNAME and if reverse lookup + * fail, return ai anyway to pacify + * calling application. + * + * XXX getaddrinfo() is a name->address + * translation function, and it looks + * strange that we do addr->name + * translation here. + */ + get_name(ap, afd, &cur->ai_next, + ap, pai, servname); + } + + while (cur && cur->ai_next) + cur = cur->ai_next; + } + + *res = sentinel.ai_next; + return 0; + +free: +#ifdef USE_GETIPNODEBY + if (hp) + freehostent(hp); +#endif + if (aplist) + free(aplist); + if (apbuf) + free(apbuf); + if (sentinel.ai_next) + freeaddrinfo(sentinel.ai_next); + return error; +} + +/* + * hostname == NULL. + * passive socket -> anyaddr (0.0.0.0 or ::) + * non-passive socket -> localhost (127.0.0.1 or ::1) + */ +static int +explore_null(pai, hostname, servname, res) + const struct addrinfo *pai; + const char *hostname; + const char *servname; + struct addrinfo **res; +{ + int s; + const struct afd *afd; + struct addrinfo *cur; + struct addrinfo sentinel; + int error; + + *res = NULL; + sentinel.ai_next = NULL; + cur = &sentinel; + + /* + * filter out AFs that are not supported by the kernel + * XXX errno? + */ + s = socket(pai->ai_family, SOCK_DGRAM, 0); + if (s < 0) { + if (errno != EMFILE) + return 0; + } else + close(s); + + /* + * if the servname does not match socktype/protocol, ignore it. + */ + if (get_portmatch(pai, servname) != 0) + return 0; + + afd = find_afd(pai->ai_family); + + if (pai->ai_flags & AI_PASSIVE) { + GET_AI(cur->ai_next, afd, afd->a_addrany); + /* xxx meaningless? + * GET_CANONNAME(cur->ai_next, "anyaddr"); + */ + GET_PORT(cur->ai_next, servname); + } else { + GET_AI(cur->ai_next, afd, afd->a_loopback); + /* xxx meaningless? + * GET_CANONNAME(cur->ai_next, "localhost"); + */ + GET_PORT(cur->ai_next, servname); + } + cur = cur->ai_next; + + *res = sentinel.ai_next; + return 0; + +free: + if (sentinel.ai_next) + freeaddrinfo(sentinel.ai_next); + return error; +} + +/* + * numeric hostname + */ +static int +explore_numeric(pai, hostname, servname, res) + const struct addrinfo *pai; + const char *hostname; + const char *servname; + struct addrinfo **res; +{ + const struct afd *afd; + struct addrinfo *cur; + struct addrinfo sentinel; + int error; + char pton[PTON_MAX]; + int flags; + + *res = NULL; + sentinel.ai_next = NULL; + cur = &sentinel; + + /* + * if the servname does not match socktype/protocol, ignore it. + */ + if (get_portmatch(pai, servname) != 0) + return 0; + + afd = find_afd(pai->ai_family); + flags = pai->ai_flags; + + if (inet_pton(afd->a_af, hostname, pton) == 1) { + u_int32_t v4a; +#ifdef INET6 + u_char pfx; +#endif + + switch (afd->a_af) { + case AF_INET: + v4a = (u_int32_t)ntohl(((struct in_addr *)pton)->s_addr); + if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) + flags &= ~AI_CANONNAME; + v4a >>= IN_CLASSA_NSHIFT; + if (v4a == 0 || v4a == IN_LOOPBACKNET) + flags &= ~AI_CANONNAME; + break; +#ifdef INET6 + case AF_INET6: + pfx = ((struct in6_addr *)pton)->s6_addr[0]; + if (pfx == 0 || pfx == 0xfe || pfx == 0xff) + flags &= ~AI_CANONNAME; + break; +#endif + } + + if (pai->ai_family == afd->a_af || + pai->ai_family == PF_UNSPEC /*?*/) { + if ((flags & AI_CANONNAME) == 0) { + GET_AI(cur->ai_next, afd, pton); + GET_PORT(cur->ai_next, servname); + } else { + /* + * if AI_CANONNAME and if reverse lookup + * fail, return ai anyway to pacify + * calling application. + * + * XXX getaddrinfo() is a name->address + * translation function, and it looks + * strange that we do addr->name + * translation here. + */ + get_name(pton, afd, &cur->ai_next, + pton, pai, servname); + } + while (cur && cur->ai_next) + cur = cur->ai_next; + } else + ERR(EAI_FAMILY); /*xxx*/ + } + + *res = sentinel.ai_next; + return 0; + +free: +bad: + if (sentinel.ai_next) + freeaddrinfo(sentinel.ai_next); + return error; +} + +/* + * numeric hostname with scope + */ +static int +explore_numeric_scope(pai, hostname, servname, res) + const struct addrinfo *pai; + const char *hostname; + const char *servname; + struct addrinfo **res; +{ +#ifndef SCOPE_DELIMITER + return explore_numeric(pai, hostname, servname, res); +#else + const struct afd *afd; + struct addrinfo *cur; + int error; + char *cp, *hostname2 = NULL; + int scope; + struct sockaddr_in6 *sin6; + + /* + * if the servname does not match socktype/protocol, ignore it. + */ + if (get_portmatch(pai, servname) != 0) + return 0; + + afd = find_afd(pai->ai_family); + if (!afd->a_scoped) + return explore_numeric(pai, hostname, servname, res); + + cp = strchr(hostname, SCOPE_DELIMITER); + if (cp == NULL) + return explore_numeric(pai, hostname, servname, res); + + /* + * Handle special case of + */ + hostname2 = strdup(hostname); + if (hostname2 == NULL) + return EAI_MEMORY; + /* terminate at the delimiter */ + hostname2[cp - hostname] = '\0'; + + cp++; + switch (pai->ai_family) { +#ifdef INET6 + case AF_INET6: + scope = if_nametoindex(cp); + if (scope == 0) { + free(hostname2); + return (EAI_NONAME); + } + break; +#endif + } + + error = explore_numeric(pai, hostname2, servname, res); + if (error == 0) { + for (cur = *res; cur; cur = cur->ai_next) { + if (cur->ai_family != AF_INET6) + continue; + sin6 = (struct sockaddr_in6 *)cur->ai_addr; + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || + IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr)) + sin6->sin6_scope_id = scope; + } + } + + free(hostname2); + + return error; +#endif +} + +static int +get_name(addr, afd, res, numaddr, pai, servname) + const char *addr; + const struct afd *afd; + struct addrinfo **res; + char *numaddr; + const struct addrinfo *pai; + const char *servname; +{ + struct hostent *hp = NULL; + struct addrinfo *cur = NULL; + int error = 0; + char *ap = NULL, *cn = NULL; +#ifdef USE_GETIPNODEBY + int h_error; + + hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); +#else + hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); +#endif + if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { +#ifdef USE_GETIPNODEBY + GET_AI(cur, afd, hp->h_addr_list[0]); + GET_PORT(cur, servname); + GET_CANONNAME(cur, hp->h_name); +#else + /* hp will be damaged if we use gethostbyaddr() */ + if ((ap = (char *)malloc(hp->h_length)) == NULL) { + error = EAI_MEMORY; + goto free; + } + memcpy(ap, hp->h_addr_list[0], hp->h_length); + if ((cn = strdup(hp->h_name)) == NULL) { + error = EAI_MEMORY; + goto free; + } + + GET_AI(cur, afd, ap); + GET_PORT(cur, servname); + GET_CANONNAME(cur, cn); + free(ap); ap = NULL; + free(cn); cn = NULL; +#endif + } else { + GET_AI(cur, afd, numaddr); + GET_PORT(cur, servname); + } + +#ifdef USE_GETIPNODEBY + if (hp) + freehostent(hp); +#endif + *res = cur; + return SUCCESS; + free: + if (cur) + freeaddrinfo(cur); + if (ap) + free(ap); + if (cn) + free(cn); +#ifdef USE_GETIPNODEBY + if (hp) + freehostent(hp); +#endif + *res = NULL; + return error; +} + +static int +get_canonname(pai, ai, str) + const struct addrinfo *pai; + struct addrinfo *ai; + const char *str; +{ + if ((pai->ai_flags & AI_CANONNAME) != 0) { + ai->ai_canonname = (char *)malloc(strlen(str) + 1); + if (ai->ai_canonname == NULL) + return EAI_MEMORY; + strcpy(ai->ai_canonname, str); + } + return 0; +} + +static struct addrinfo * +get_ai(pai, afd, addr) + const struct addrinfo *pai; + const struct afd *afd; + const char *addr; +{ + char *p; + struct addrinfo *ai; + + ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + + (afd->a_socklen)); + if (ai == NULL) + return NULL; + + memcpy(ai, pai, sizeof(struct addrinfo)); + ai->ai_addr = (struct sockaddr *)(ai + 1); + memset(ai->ai_addr, 0, afd->a_socklen); +#ifdef HAVE_SOCKADDR_SA_LEN + ai->ai_addr->sa_len = afd->a_socklen; +#endif + ai->ai_addrlen = afd->a_socklen; + ai->ai_addr->sa_family = ai->ai_family = afd->a_af; + p = (char *)(ai->ai_addr); + memcpy(p + afd->a_off, addr, afd->a_addrlen); + return ai; +} + +static int +get_portmatch(ai, servname) + const struct addrinfo *ai; + const char *servname; +{ + + /* get_port does not touch first argument. when matchonly == 1. */ + return get_port((struct addrinfo *)ai, servname, 1); +} + +static int +get_port(ai, servname, matchonly) + struct addrinfo *ai; + const char *servname; + int matchonly; +{ + const char *proto; + struct servent *sp; + int port; + int allownumeric; + + if (servname == NULL) + return 0; + switch (ai->ai_family) { + case AF_INET: +#ifdef AF_INET6 + case AF_INET6: +#endif + break; + default: + return 0; + } + + switch (ai->ai_socktype) { + case SOCK_RAW: + return EAI_SERVICE; + case SOCK_DGRAM: + case SOCK_STREAM: + allownumeric = 1; + break; + case ANY: + allownumeric = 0; + break; + default: + return EAI_SOCKTYPE; + } + + if (str_isnumber(servname)) { + if (!allownumeric) + return EAI_SERVICE; + port = htons(atoi(servname)); + if (port < 0 || port > 65535) + return EAI_SERVICE; + } else { + switch (ai->ai_socktype) { + case SOCK_DGRAM: + proto = "udp"; + break; + case SOCK_STREAM: + proto = "tcp"; + break; + default: + proto = NULL; + break; + } + + if ((sp = getservbyname(servname, proto)) == NULL) + return EAI_SERVICE; + port = sp->s_port; + } + + if (!matchonly) { + switch (ai->ai_family) { + case AF_INET: + ((struct sockaddr_in *)ai->ai_addr)->sin_port = port; + break; +#ifdef INET6 + case AF_INET6: + ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = port; + break; +#endif + } + } + + return 0; +} + +static const struct afd * +find_afd(af) + int af; +{ + const struct afd *afd; + + if (af == PF_UNSPEC) + return NULL; + for (afd = afdl; afd->a_af; afd++) { + if (afd->a_af == af) + return afd; + } + return NULL; +} diff --git a/winpcap/wpcap/libpcap/Win32/Src/getnetbynm.c b/winpcap/wpcap/libpcap/Win32/Src/getnetbynm.c new file mode 100644 index 0000000..fa4d398 --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Src/getnetbynm.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getnetbyname.c 5.5 (Berkeley) 6/27/88"; +#endif /* LIBC_SCCS and not lint */ + +#include "inetprivate.h" + +extern int _net_stayopen; + +struct netent * +getnetbyname(const char *name) +{ + register struct netent *p; + register char **cp; + + setnetent(_net_stayopen); + while (p = getnetent()) { + if (strcmp(p->n_name, name) == 0) + break; + for (cp = p->n_aliases; *cp != 0; cp++) + if (strcmp(*cp, name) == 0) + goto found; + } +found: + if (!_net_stayopen) + endnetent(); + return (p); +} diff --git a/winpcap/wpcap/libpcap/Win32/Src/getnetent.c b/winpcap/wpcap/libpcap/Win32/Src/getnetent.c new file mode 100644 index 0000000..d4cceb3 --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Src/getnetent.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getnetent.c 5.5 (Berkeley) 6/27/88"; +#endif /* LIBC_SCCS and not lint */ + +#include "inetprivate.h" + +#define MAXALIASES 35 + +static char NETDB[] = _PATH_NETWORKS; +static FILE *netf = NULL; +static char line[BUFSIZ+1]; +static struct netent net; +static char *net_aliases[MAXALIASES]; +static char *any(char *, char *); + +int _net_stayopen; +extern u_int32_t inet_network(const char *cp); + +void +setnetent(f) + int f; +{ + if (netf == NULL) + netf = fopen(NETDB, "r" ); + else + rewind(netf); + _net_stayopen |= f; +} + +void +endnetent() +{ + if (netf) { + fclose(netf); + netf = NULL; + } + _net_stayopen = 0; +} + +struct netent * +getnetent() +{ + char *p; + register char *cp, **q; + + if (netf == NULL && (netf = fopen(NETDB, "r" )) == NULL) + return (NULL); +again: + p = fgets(line, BUFSIZ, netf); + if (p == NULL) + return (NULL); + if (*p == '#') + goto again; + cp = any(p, "#\n"); + if (cp == NULL) + goto again; + *cp = '\0'; + net.n_name = p; + cp = any(p, " \t"); + if (cp == NULL) + goto again; + *cp++ = '\0'; + while (*cp == ' ' || *cp == '\t') + cp++; + p = any(cp, " \t"); + if (p != NULL) + *p++ = '\0'; + net.n_net = inet_network(cp); + net.n_addrtype = AF_INET; + q = net.n_aliases = net_aliases; + if (p != NULL) + cp = p; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &net_aliases[MAXALIASES - 1]) + *q++ = cp; + cp = any(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + } + *q = NULL; + return (&net); +} + +static char * +any(cp, match) + register char *cp; + char *match; +{ + register char *mp, c; + + while (c = *cp) { + for (mp = match; *mp; mp++) + if (*mp == c) + return (cp); + cp++; + } + return ((char *)0); +} diff --git a/winpcap/wpcap/libpcap/Win32/Src/getopt.c b/winpcap/wpcap/libpcap/Win32/Src/getopt.c new file mode 100644 index 0000000..03c2086 --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Src/getopt.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt(nargc, nargv, ostr) + int nargc; + char * const *nargv; + const char *ostr; +{ +#ifdef WIN32 + char *__progname="windump"; +#else + extern char *__progname; +#endif + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return (-1); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++optind; + place = EMSG; + return (-1); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means -1. + */ + if (optopt == (int)'-') + return (-1); + if (!*place) + ++optind; + if (opterr && *ostr != ':') + (void)fprintf(stderr, + "%s: illegal option -- %c\n", __progname, optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } + else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (opterr) + (void)fprintf(stderr, + "%s: option requires an argument -- %c\n", + __progname, optopt); + return (BADCH); + } + else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return (optopt); /* dump back option letter */ +} diff --git a/winpcap/wpcap/libpcap/Win32/Src/getservent.c b/winpcap/wpcap/libpcap/Win32/Src/getservent.c new file mode 100644 index 0000000..61b8cb0 --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Src/getservent.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define MAXALIASES 35 + +static char SERVDB[] = _PATH_SERVICES; +static FILE *servf = NULL; +static char line[BUFSIZ+1]; +static struct servent serv; +static char *serv_aliases[MAXALIASES]; +int _serv_stayopen; + +void +setservent(f) + int f; +{ + if (servf == NULL) + servf = fopen(SERVDB, "r" ); + else + rewind(servf); + _serv_stayopen |= f; +} + +void +endservent() +{ + if (servf) { + fclose(servf); + servf = NULL; + } + _serv_stayopen = 0; +} + +struct servent * +getservent() +{ + char *p; + register char *cp, **q; + + if (servf == NULL && (servf = fopen(SERVDB, "r" )) == NULL) + return (NULL); +again: + if ((p = fgets(line, BUFSIZ, servf)) == NULL) + return (NULL); + if (*p == '#') + goto again; + cp = strpbrk(p, "#\n"); + if (cp == NULL) + goto again; + *cp = '\0'; + serv.s_name = p; + p = strpbrk(p, " \t"); + if (p == NULL) + goto again; + *p++ = '\0'; + while (*p == ' ' || *p == '\t') + p++; + cp = strpbrk(p, ",/"); + if (cp == NULL) + goto again; + *cp++ = '\0'; + serv.s_port = htons((u_short)atoi(p)); + serv.s_proto = cp; + q = serv.s_aliases = serv_aliases; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &serv_aliases[MAXALIASES - 1]) + *q++ = cp; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + } + *q = NULL; + return (&serv); +} diff --git a/winpcap/wpcap/libpcap/Win32/Src/inet_aton.c b/winpcap/wpcap/libpcap/Win32/Src/inet_aton.c new file mode 100644 index 0000000..98d1012 --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Src/inet_aton.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: inet_aton.c,v 1.2 2003/11/15 23:24:06 guy Exp $ */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/Win32/Src/inet_aton.c,v 1.2 2003/11/15 23:24:06 guy Exp $"; +#endif + +#include +#include + +/* Minimal implementation of inet_aton. + * Cannot distinguish between failure and a local broadcast address. */ + +#ifndef INADDR_NONE +#define INADDR_NONE 0xffffffff +#endif + +int +inet_aton(const char *cp, struct in_addr *addr) +{ + addr->s_addr = inet_addr(cp); + return (addr->s_addr == INADDR_NONE) ? 0 : 1; +} diff --git a/winpcap/wpcap/libpcap/Win32/Src/inet_net.c b/winpcap/wpcap/libpcap/Win32/Src/inet_net.c new file mode 100644 index 0000000..5bbe391 --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Src/inet_net.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include "inetprivate.h" + +/* + * Internet network address interpretation routine. + * The library routines call this routine to interpret + * network numbers. + */ +u_int32_t +inet_network(const char *cp) +{ + register u_long val, base, n; + register char c; + u_long parts[4], *pp = parts; + register int i; + +again: + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, other=decimal. + */ + val = 0; base = 10; + /* + * The 4.4BSD version of this file also accepts 'x__' as a hexa + * number. I don't think this is correct. -- Uli + */ + if (*cp == '0') { + if (*++cp == 'x' || *cp == 'X') + base = 16, cp++; + else + base = 8; + } + while ((c = *cp)) { + if (isdigit(c)) { + val = (val * base) + (c - '0'); + cp++; + continue; + } + if (base == 16 && isxdigit(c)) { + val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A')); + cp++; + continue; + } + break; + } + if (*cp == '.') { + if (pp >= parts + 4) + return (INADDR_NONE); + *pp++ = val, cp++; + goto again; + } + if (*cp && !isspace(*cp)) + return (INADDR_NONE); + *pp++ = val; + n = pp - parts; + if (n > 4) + return (INADDR_NONE); + for (val = 0, i = 0; i < (int)n; i++) { + val <<= 8; + val |= parts[i] & 0xff; + } + return (val); +} diff --git a/winpcap/wpcap/libpcap/Win32/Src/inet_pton.c b/winpcap/wpcap/libpcap/Win32/Src/inet_pton.c new file mode 100644 index 0000000..46a8541 --- /dev/null +++ b/winpcap/wpcap/libpcap/Win32/Src/inet_pton.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: inet_pton.c,v 1.2 2003/11/15 23:24:06 guy Exp $ */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/Win32/Src/inet_pton.c,v 1.2 2003/11/15 23:24:06 guy Exp $"; +#endif + +#include + +#ifdef WIN32 +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT 97 /* not present in errno.h provided with VC */ +#endif +#endif + +#ifdef __MINGW32__ +int* _errno(); +#define errno (*_errno()) +#endif /* __MINGW32__ */ + +#include + +int +inet_pton(int af, const char *src, void *dst) +{ + if (af != AF_INET) { + errno = EAFNOSUPPORT; + return -1; + } + return inet_aton (src, dst); +} diff --git a/winpcap/wpcap/libpcap/acconfig.h b/winpcap/wpcap/libpcap/acconfig.h new file mode 100644 index 0000000..a23f320 --- /dev/null +++ b/winpcap/wpcap/libpcap/acconfig.h @@ -0,0 +1,7 @@ +/* Long story short: aclocal.m4 depends on autoconf 2.13 + * implementation details wrt "const"; newer versions + * have different implementation details so for now we + * put "const" here. This may cause duplicate definitions + * in config.h but that should be OK since they're the same. + */ +#undef const diff --git a/winpcap/wpcap/libpcap/aclocal.m4 b/winpcap/wpcap/libpcap/aclocal.m4 new file mode 100644 index 0000000..1efb474 --- /dev/null +++ b/winpcap/wpcap/libpcap/aclocal.m4 @@ -0,0 +1,900 @@ +dnl @(#) $Header: /tcpdump/master/libpcap/aclocal.m4,v 1.85.2.1 2005/04/21 03:42:09 guy Exp $ (LBL) +dnl +dnl Copyright (c) 1995, 1996, 1997, 1998 +dnl The Regents of the University of California. All rights reserved. +dnl +dnl Redistribution and use in source and binary forms, with or without +dnl modification, are permitted provided that: (1) source code distributions +dnl retain the above copyright notice and this paragraph in its entirety, (2) +dnl distributions including binary code include the above copyright notice and +dnl this paragraph in its entirety in the documentation or other materials +dnl provided with the distribution, and (3) all advertising materials mentioning +dnl features or use of this software display the following acknowledgement: +dnl ``This product includes software developed by the University of California, +dnl Lawrence Berkeley Laboratory and its contributors.'' Neither the name of +dnl the University nor the names of its contributors may be used to endorse +dnl or promote products derived from this software without specific prior +dnl written permission. +dnl THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +dnl WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +dnl MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +dnl +dnl LBL autoconf macros +dnl + +dnl +dnl Determine which compiler we're using (cc or gcc) +dnl If using gcc, determine the version number +dnl If using cc, require that it support ansi prototypes +dnl If using gcc, use -O2 (otherwise use -O) +dnl If using cc, explicitly specify /usr/local/include +dnl +dnl usage: +dnl +dnl AC_LBL_C_INIT(copt, incls) +dnl +dnl results: +dnl +dnl $1 (copt set) +dnl $2 (incls set) +dnl CC +dnl LDFLAGS +dnl ac_cv_lbl_gcc_vers +dnl LBL_CFLAGS +dnl +AC_DEFUN(AC_LBL_C_INIT, + [AC_PREREQ(2.12) + AC_BEFORE([$0], [AC_PROG_CC]) + AC_BEFORE([$0], [AC_LBL_FIXINCLUDES]) + AC_BEFORE([$0], [AC_LBL_DEVEL]) + AC_ARG_WITH(gcc, [ --without-gcc don't use gcc]) + $1="-O" + $2="" + if test "${srcdir}" != "." ; then + $2="-I\$(srcdir)" + fi + if test "${CFLAGS+set}" = set; then + LBL_CFLAGS="$CFLAGS" + fi + if test -z "$CC" ; then + case "$target_os" in + + bsdi*) + AC_CHECK_PROG(SHLICC2, shlicc2, yes, no) + if test $SHLICC2 = yes ; then + CC=shlicc2 + export CC + fi + ;; + esac + fi + if test -z "$CC" -a "$with_gcc" = no ; then + CC=cc + export CC + fi + AC_PROG_CC + if test "$GCC" = yes ; then + if test "$SHLICC2" = yes ; then + ac_cv_lbl_gcc_vers=2 + $1="-O2" + else + AC_MSG_CHECKING(gcc version) + AC_CACHE_VAL(ac_cv_lbl_gcc_vers, + ac_cv_lbl_gcc_vers=`$CC -v 2>&1 | \ + sed -e '/^gcc version /!d' \ + -e 's/^gcc version //' \ + -e 's/ .*//' -e 's/^[[[^0-9]]]*//' \ + -e 's/\..*//'`) + AC_MSG_RESULT($ac_cv_lbl_gcc_vers) + if test $ac_cv_lbl_gcc_vers -gt 1 ; then + $1="-O2" + fi + fi + else + AC_MSG_CHECKING(that $CC handles ansi prototypes) + AC_CACHE_VAL(ac_cv_lbl_cc_ansi_prototypes, + AC_TRY_COMPILE( + [#include ], + [int frob(int, char *)], + ac_cv_lbl_cc_ansi_prototypes=yes, + ac_cv_lbl_cc_ansi_prototypes=no)) + AC_MSG_RESULT($ac_cv_lbl_cc_ansi_prototypes) + if test $ac_cv_lbl_cc_ansi_prototypes = no ; then + case "$target_os" in + + hpux*) + AC_MSG_CHECKING(for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE)) + savedcflags="$CFLAGS" + CFLAGS="-Aa -D_HPUX_SOURCE $CFLAGS" + AC_CACHE_VAL(ac_cv_lbl_cc_hpux_cc_aa, + AC_TRY_COMPILE( + [#include ], + [int frob(int, char *)], + ac_cv_lbl_cc_hpux_cc_aa=yes, + ac_cv_lbl_cc_hpux_cc_aa=no)) + AC_MSG_RESULT($ac_cv_lbl_cc_hpux_cc_aa) + if test $ac_cv_lbl_cc_hpux_cc_aa = no ; then + AC_MSG_ERROR(see the INSTALL doc for more info) + fi + CFLAGS="$savedcflags" + V_CCOPT="-Aa $V_CCOPT" + AC_DEFINE(_HPUX_SOURCE,1,[needed on HP-UX]) + ;; + + *) + AC_MSG_ERROR(see the INSTALL doc for more info) + ;; + esac + fi + $2="$$2 -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + + case "$target_os" in + + irix*) + V_CCOPT="$V_CCOPT -xansi -signed -g3" + ;; + + osf*) + V_CCOPT="$V_CCOPT -std1 -g3" + ;; + + ultrix*) + AC_MSG_CHECKING(that Ultrix $CC hacks const in prototypes) + AC_CACHE_VAL(ac_cv_lbl_cc_const_proto, + AC_TRY_COMPILE( + [#include ], + [struct a { int b; }; + void c(const struct a *)], + ac_cv_lbl_cc_const_proto=yes, + ac_cv_lbl_cc_const_proto=no)) + AC_MSG_RESULT($ac_cv_lbl_cc_const_proto) + if test $ac_cv_lbl_cc_const_proto = no ; then + AC_DEFINE(const,) + fi + ;; + esac + fi +]) + +# +# Try compiling a sample of the type of code that appears in +# gencode.c with "inline", "__inline__", and "__inline". +# +# Autoconf's AC_C_INLINE, at least in autoconf 2.13, isn't good enough, +# as it just tests whether a function returning "int" can be inlined; +# at least some versions of HP's C compiler can inline that, but can't +# inline a function that returns a struct pointer. +# +# Make sure we use the V_CCOPT flags, because some of those might +# disable inlining. +# +AC_DEFUN(AC_LBL_C_INLINE, + [AC_MSG_CHECKING(for inline) + save_CFLAGS="$CFLAGS" + CFLAGS="$V_CCOPT" + AC_CACHE_VAL(ac_cv_lbl_inline, [ + ac_cv_lbl_inline="" + ac_lbl_cc_inline=no + for ac_lbl_inline in inline __inline__ __inline + do + AC_TRY_COMPILE( + [#define inline $ac_lbl_inline + static inline struct iltest *foo(void); + struct iltest { + int iltest1; + int iltest2; + }; + + static inline struct iltest * + foo() + { + static struct iltest xxx; + + return &xxx; + }],,ac_lbl_cc_inline=yes,) + if test "$ac_lbl_cc_inline" = yes ; then + break; + fi + done + if test "$ac_lbl_cc_inline" = yes ; then + ac_cv_lbl_inline=$ac_lbl_inline + fi]) + CFLAGS="$save_CFLAGS" + if test ! -z "$ac_cv_lbl_inline" ; then + AC_MSG_RESULT($ac_cv_lbl_inline) + else + AC_MSG_RESULT(no) + fi + AC_DEFINE_UNQUOTED(inline, $ac_cv_lbl_inline, [Define as token for inline if inlining supported])]) + +dnl +dnl Use pfopen.c if available and pfopen() not in standard libraries +dnl Require libpcap +dnl Look for libpcap in .. +dnl Use the installed libpcap if there is no local version +dnl +dnl usage: +dnl +dnl AC_LBL_LIBPCAP(pcapdep, incls) +dnl +dnl results: +dnl +dnl $1 (pcapdep set) +dnl $2 (incls appended) +dnl LIBS +dnl LBL_LIBS +dnl +AC_DEFUN(AC_LBL_LIBPCAP, + [AC_REQUIRE([AC_LBL_LIBRARY_NET]) + dnl + dnl save a copy before locating libpcap.a + dnl + LBL_LIBS="$LIBS" + pfopen=/usr/examples/packetfilter/pfopen.c + if test -f $pfopen ; then + AC_CHECK_FUNCS(pfopen) + if test $ac_cv_func_pfopen = "no" ; then + AC_MSG_RESULT(Using $pfopen) + LIBS="$LIBS $pfopen" + fi + fi + AC_MSG_CHECKING(for local pcap library) + libpcap=FAIL + lastdir=FAIL + places=`ls .. | sed -e 's,/$,,' -e 's,^,../,' | \ + egrep '/libpcap-[[0-9]]*\.[[0-9]]*(\.[[0-9]]*)?([[ab]][[0-9]]*)?$'` + for dir in $places ../libpcap libpcap ; do + basedir=`echo $dir | sed -e 's/[[ab]][[0-9]]*$//'` + if test $lastdir = $basedir ; then + dnl skip alphas when an actual release is present + continue; + fi + lastdir=$dir + if test -r $dir/pcap.c ; then + libpcap=$dir/libpcap.a + d=$dir + dnl continue and select the last one that exists + fi + done + if test $libpcap = FAIL ; then + AC_MSG_RESULT(not found) + AC_CHECK_LIB(pcap, main, libpcap="-lpcap") + if test $libpcap = FAIL ; then + AC_MSG_ERROR(see the INSTALL doc for more info) + fi + else + $1=$libpcap + $2="-I$d $$2" + AC_MSG_RESULT($libpcap) + fi + LIBS="$libpcap $LIBS" + case "$target_os" in + + aix*) + pseexe="/lib/pse.exp" + AC_MSG_CHECKING(for $pseexe) + if test -f $pseexe ; then + AC_MSG_RESULT(yes) + LIBS="$LIBS -I:$pseexe" + fi + ;; + esac]) + +dnl +dnl Define RETSIGTYPE and RETSIGVAL +dnl +dnl usage: +dnl +dnl AC_LBL_TYPE_SIGNAL +dnl +dnl results: +dnl +dnl RETSIGTYPE (defined) +dnl RETSIGVAL (defined) +dnl +AC_DEFUN(AC_LBL_TYPE_SIGNAL, + [AC_BEFORE([$0], [AC_LBL_LIBPCAP]) + AC_TYPE_SIGNAL + if test "$ac_cv_type_signal" = void ; then + AC_DEFINE(RETSIGVAL,[],[return value of signal handlers]) + else + AC_DEFINE(RETSIGVAL,(0),[return value of signal handlers]) + fi + case "$target_os" in + + irix*) + AC_DEFINE(_BSD_SIGNALS,1,[get BSD semantics on Irix]) + ;; + + *) + dnl prefer sigset() to sigaction() + AC_CHECK_FUNCS(sigset) + if test $ac_cv_func_sigset = no ; then + AC_CHECK_FUNCS(sigaction) + fi + ;; + esac]) + +dnl +dnl If using gcc, make sure we have ANSI ioctl definitions +dnl +dnl usage: +dnl +dnl AC_LBL_FIXINCLUDES +dnl +AC_DEFUN(AC_LBL_FIXINCLUDES, + [if test "$GCC" = yes ; then + AC_MSG_CHECKING(for ANSI ioctl definitions) + AC_CACHE_VAL(ac_cv_lbl_gcc_fixincludes, + AC_TRY_COMPILE( + [/* + * This generates a "duplicate case value" when fixincludes + * has not be run. + */ +# include +# include +# include +# ifdef HAVE_SYS_IOCCOM_H +# include +# endif], + [switch (0) { + case _IO('A', 1):; + case _IO('B', 1):; + }], + ac_cv_lbl_gcc_fixincludes=yes, + ac_cv_lbl_gcc_fixincludes=no)) + AC_MSG_RESULT($ac_cv_lbl_gcc_fixincludes) + if test $ac_cv_lbl_gcc_fixincludes = no ; then + # Don't cache failure + unset ac_cv_lbl_gcc_fixincludes + AC_MSG_ERROR(see the INSTALL for more info) + fi + fi]) + +dnl +dnl Check for flex, default to lex +dnl Require flex 2.4 or higher +dnl Check for bison, default to yacc +dnl Default to lex/yacc if both flex and bison are not available +dnl Define the yy prefix string if using flex and bison +dnl +dnl usage: +dnl +dnl AC_LBL_LEX_AND_YACC(lex, yacc, yyprefix) +dnl +dnl results: +dnl +dnl $1 (lex set) +dnl $2 (yacc appended) +dnl $3 (optional flex and bison -P prefix) +dnl +AC_DEFUN(AC_LBL_LEX_AND_YACC, + [AC_ARG_WITH(flex, [ --without-flex don't use flex]) + AC_ARG_WITH(bison, [ --without-bison don't use bison]) + if test "$with_flex" = no ; then + $1=lex + else + AC_CHECK_PROGS($1, flex, lex) + fi + if test "$$1" = flex ; then + # The -V flag was added in 2.4 + AC_MSG_CHECKING(for flex 2.4 or higher) + AC_CACHE_VAL(ac_cv_lbl_flex_v24, + if flex -V >/dev/null 2>&1; then + ac_cv_lbl_flex_v24=yes + else + ac_cv_lbl_flex_v24=no + fi) + AC_MSG_RESULT($ac_cv_lbl_flex_v24) + if test $ac_cv_lbl_flex_v24 = no ; then + s="2.4 or higher required" + AC_MSG_WARN(ignoring obsolete flex executable ($s)) + $1=lex + fi + fi + if test "$with_bison" = no ; then + $2=yacc + else + AC_CHECK_PROGS($2, bison, yacc) + fi + if test "$$2" = bison ; then + $2="$$2 -y" + fi + if test "$$1" != lex -a "$$2" = yacc -o "$$1" = lex -a "$$2" != yacc ; then + AC_MSG_WARN(don't have both flex and bison; reverting to lex/yacc) + $1=lex + $2=yacc + fi + if test "$$1" = flex -a -n "$3" ; then + $1="$$1 -P$3" + $2="$$2 -p $3" + fi]) + +dnl +dnl Checks to see if union wait is used with WEXITSTATUS() +dnl +dnl usage: +dnl +dnl AC_LBL_UNION_WAIT +dnl +dnl results: +dnl +dnl DECLWAITSTATUS (defined) +dnl +AC_DEFUN(AC_LBL_UNION_WAIT, + [AC_MSG_CHECKING(if union wait is used) + AC_CACHE_VAL(ac_cv_lbl_union_wait, + AC_TRY_COMPILE([ +# include +# include ], + [int status; + u_int i = WEXITSTATUS(status); + u_int j = waitpid(0, &status, 0);], + ac_cv_lbl_union_wait=no, + ac_cv_lbl_union_wait=yes)) + AC_MSG_RESULT($ac_cv_lbl_union_wait) + if test $ac_cv_lbl_union_wait = yes ; then + AC_DEFINE(DECLWAITSTATUS,union wait,[type for wait]) + else + AC_DEFINE(DECLWAITSTATUS,int,[type for wait]) + fi]) + +dnl +dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member +dnl +dnl usage: +dnl +dnl AC_LBL_SOCKADDR_SA_LEN +dnl +dnl results: +dnl +dnl HAVE_SOCKADDR_SA_LEN (defined) +dnl +AC_DEFUN(AC_LBL_SOCKADDR_SA_LEN, + [AC_MSG_CHECKING(if sockaddr struct has sa_len member) + AC_CACHE_VAL(ac_cv_lbl_sockaddr_has_sa_len, + AC_TRY_COMPILE([ +# include +# include ], + [u_int i = sizeof(((struct sockaddr *)0)->sa_len)], + ac_cv_lbl_sockaddr_has_sa_len=yes, + ac_cv_lbl_sockaddr_has_sa_len=no)) + AC_MSG_RESULT($ac_cv_lbl_sockaddr_has_sa_len) + if test $ac_cv_lbl_sockaddr_has_sa_len = yes ; then + AC_DEFINE(HAVE_SOCKADDR_SA_LEN,1,[if struct sockaddr has sa_len]) + fi]) + +dnl +dnl Checks to see if there's a sockaddr_storage structure +dnl +dnl usage: +dnl +dnl AC_LBL_SOCKADDR_STORAGE +dnl +dnl results: +dnl +dnl HAVE_SOCKADDR_STORAGE (defined) +dnl +AC_DEFUN(AC_LBL_SOCKADDR_STORAGE, + [AC_MSG_CHECKING(if sockaddr_storage struct exists) + AC_CACHE_VAL(ac_cv_lbl_has_sockaddr_storage, + AC_TRY_COMPILE([ +# include +# include ], + [u_int i = sizeof (struct sockaddr_storage)], + ac_cv_lbl_has_sockaddr_storage=yes, + ac_cv_lbl_has_sockaddr_storage=no)) + AC_MSG_RESULT($ac_cv_lbl_has_sockaddr_storage) + if test $ac_cv_lbl_has_sockaddr_storage = yes ; then + AC_DEFINE(HAVE_SOCKADDR_STORAGE,1,[if struct sockaddr_storage exists]) + fi]) + +dnl +dnl Checks to see if the dl_hp_ppa_info_t struct has the HP-UX 11.00 +dnl dl_module_id_1 member +dnl +dnl usage: +dnl +dnl AC_LBL_HP_PPA_INFO_T_DL_MODULE_ID_1 +dnl +dnl results: +dnl +dnl HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 (defined) +dnl +dnl NOTE: any compile failure means we conclude that it doesn't have +dnl that member, so if we don't have DLPI, don't have a +dnl header, or have one that doesn't declare a dl_hp_ppa_info_t type, +dnl we conclude it doesn't have that member (which is OK, as either we +dnl won't be using code that would use that member, or we wouldn't +dnl compile in any case). +dnl +AC_DEFUN(AC_LBL_HP_PPA_INFO_T_DL_MODULE_ID_1, + [AC_MSG_CHECKING(if dl_hp_ppa_info_t struct has dl_module_id_1 member) + AC_CACHE_VAL(ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1, + AC_TRY_COMPILE([ +# include +# include +# include ], + [u_int i = sizeof(((dl_hp_ppa_info_t *)0)->dl_module_id_1)], + ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=yes, + ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=no)) + AC_MSG_RESULT($ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1) + if test $ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1 = yes ; then + AC_DEFINE(HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1,1,[if ppa_info_t_dl_module_id exists]) + fi]) + +dnl +dnl Checks to see if -R is used +dnl +dnl usage: +dnl +dnl AC_LBL_HAVE_RUN_PATH +dnl +dnl results: +dnl +dnl ac_cv_lbl_have_run_path (yes or no) +dnl +AC_DEFUN(AC_LBL_HAVE_RUN_PATH, + [AC_MSG_CHECKING(for ${CC-cc} -R) + AC_CACHE_VAL(ac_cv_lbl_have_run_path, + [echo 'main(){}' > conftest.c + ${CC-cc} -o conftest conftest.c -R/a1/b2/c3 >conftest.out 2>&1 + if test ! -s conftest.out ; then + ac_cv_lbl_have_run_path=yes + else + ac_cv_lbl_have_run_path=no + fi + rm -f conftest*]) + AC_MSG_RESULT($ac_cv_lbl_have_run_path) + ]) + +dnl +dnl Due to the stupid way it's implemented, AC_CHECK_TYPE is nearly useless. +dnl +dnl usage: +dnl +dnl AC_LBL_CHECK_TYPE +dnl +dnl results: +dnl +dnl int32_t (defined) +dnl u_int32_t (defined) +dnl +AC_DEFUN(AC_LBL_CHECK_TYPE, + [AC_MSG_CHECKING(for $1 using $CC) + AC_CACHE_VAL(ac_cv_lbl_have_$1, + AC_TRY_COMPILE([ +# include "confdefs.h" +# include +# if STDC_HEADERS +# include +# include +# endif], + [$1 i], + ac_cv_lbl_have_$1=yes, + ac_cv_lbl_have_$1=no)) + AC_MSG_RESULT($ac_cv_lbl_have_$1) + if test $ac_cv_lbl_have_$1 = no ; then + AC_DEFINE($1, $2, [if we have $1]) + fi]) + +dnl +dnl Checks to see if unaligned memory accesses fail +dnl +dnl usage: +dnl +dnl AC_LBL_UNALIGNED_ACCESS +dnl +dnl results: +dnl +dnl LBL_ALIGN (DEFINED) +dnl +AC_DEFUN(AC_LBL_UNALIGNED_ACCESS, + [AC_MSG_CHECKING(if unaligned accesses fail) + AC_CACHE_VAL(ac_cv_lbl_unaligned_fail, + [case "$host_cpu" in + + # + # These are CPU types where: + # + # the CPU faults on an unaligned access, but at least some + # OSes that support that CPU catch the fault and simulate + # the unaligned access (e.g., Alpha/{Digital,Tru64} UNIX) - + # the simulation is slow, so we don't want to use it; + # + # the CPU, I infer (from the old + # + # XXX: should also check that they don't do weird things (like on arm) + # + # comment) doesn't fault on unaligned accesses, but doesn't + # do a normal unaligned fetch, either (e.g., presumably, ARM); + # + # for whatever reason, the test program doesn't work + # (this has been claimed to be the case for several of those + # CPUs - I don't know what the problem is; the problem + # was reported as "the test program dumps core" for SuperH, + # but that's what the test program is *supposed* to do - + # it dumps core before it writes anything, so the test + # for an empty output file should find an empty output + # file and conclude that unaligned accesses don't work). + # + # This run-time test won't work if you're cross-compiling, so + # in order to support cross-compiling for a particular CPU, + # we have to wire in the list of CPU types anyway, as far as + # I know, so perhaps we should just have a set of CPUs on + # which we know it doesn't work, a set of CPUs on which we + # know it does work, and have the script just fail on other + # cpu types and update it when such a failure occurs. + # + alpha*|arm*|hp*|mips*|sh*|sparc*|ia64|nv1) + ac_cv_lbl_unaligned_fail=yes + ;; + + *) + cat >conftest.c < +# include +# include + unsigned char a[[5]] = { 1, 2, 3, 4, 5 }; + main() { + unsigned int i; + pid_t pid; + int status; + /* avoid "core dumped" message */ + pid = fork(); + if (pid < 0) + exit(2); + if (pid > 0) { + /* parent */ + pid = waitpid(pid, &status, 0); + if (pid < 0) + exit(3); + exit(!WIFEXITED(status)); + } + /* child */ + i = *(unsigned int *)&a[[1]]; + printf("%d\n", i); + exit(0); + } +EOF + ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \ + conftest.c $LIBS >/dev/null 2>&1 + if test ! -x conftest ; then + dnl failed to compile for some reason + ac_cv_lbl_unaligned_fail=yes + else + ./conftest >conftest.out + if test ! -s conftest.out ; then + ac_cv_lbl_unaligned_fail=yes + else + ac_cv_lbl_unaligned_fail=no + fi + fi + rm -f conftest* core core.conftest + ;; + esac]) + AC_MSG_RESULT($ac_cv_lbl_unaligned_fail) + if test $ac_cv_lbl_unaligned_fail = yes ; then + AC_DEFINE(LBL_ALIGN,1,[if unaligned access fails]) + fi]) + +dnl +dnl If using gcc and the file .devel exists: +dnl Compile with -g (if supported) and -Wall +dnl If using gcc 2, do extra prototype checking +dnl If an os prototype include exists, symlink os-proto.h to it +dnl +dnl usage: +dnl +dnl AC_LBL_DEVEL(copt) +dnl +dnl results: +dnl +dnl $1 (copt appended) +dnl HAVE_OS_PROTO_H (defined) +dnl os-proto.h (symlinked) +dnl +AC_DEFUN(AC_LBL_DEVEL, + [rm -f os-proto.h + if test "${LBL_CFLAGS+set}" = set; then + $1="$$1 ${LBL_CFLAGS}" + fi + if test -f .devel ; then + if test "$GCC" = yes ; then + if test "${LBL_CFLAGS+set}" != set; then + if test "$ac_cv_prog_cc_g" = yes ; then + $1="-g $$1" + fi + $1="$$1 -Wall" + if test $ac_cv_lbl_gcc_vers -gt 1 ; then + $1="$$1 -Wmissing-prototypes -Wstrict-prototypes" + fi + fi + else + case "$target_os" in + + irix6*) + V_CCOPT="$V_CCOPT -n32" + ;; + + *) + ;; + esac + fi + os=`echo $target_os | sed -e 's/\([[0-9]][[0-9]]*\)[[^0-9]].*$/\1/'` + name="lbl/os-$os.h" + if test -f $name ; then + ln -s $name os-proto.h + AC_DEFINE(HAVE_OS_PROTO_H,1,[if there's an os_proto.h]) + else + AC_MSG_WARN(can't find $name) + fi + fi]) + +dnl +dnl Improved version of AC_CHECK_LIB +dnl +dnl Thanks to John Hawkinson (jhawk@mit.edu) +dnl +dnl usage: +dnl +dnl AC_LBL_CHECK_LIB(LIBRARY, FUNCTION [, ACTION-IF-FOUND [, +dnl ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]]) +dnl +dnl results: +dnl +dnl LIBS +dnl + +define(AC_LBL_CHECK_LIB, +[AC_MSG_CHECKING([for $2 in -l$1]) +dnl Use a cache variable name containing both the library and function name, +dnl because the test really is for library $1 defining function $2, not +dnl just for library $1. Separate tests with the same $1 and different $2's +dnl may have different results. +ac_lib_var=`echo $1['_']$2['_']$5 | sed 'y%./+- %__p__%'` +AC_CACHE_VAL(ac_cv_lbl_lib_$ac_lib_var, +[ac_save_LIBS="$LIBS" +LIBS="-l$1 $5 $LIBS" +AC_TRY_LINK(dnl +ifelse([$2], [main], , dnl Avoid conflicting decl of main. +[/* Override any gcc2 internal prototype to avoid an error. */ +]ifelse(AC_LANG, CPLUSPLUS, [#ifdef __cplusplus +extern "C" +#endif +])dnl +[/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $2(); +]), + [$2()], + eval "ac_cv_lbl_lib_$ac_lib_var=yes", + eval "ac_cv_lbl_lib_$ac_lib_var=no") +LIBS="$ac_save_LIBS" +])dnl +if eval "test \"`echo '$ac_cv_lbl_lib_'$ac_lib_var`\" = yes"; then + AC_MSG_RESULT(yes) + ifelse([$3], , +[changequote(, )dnl + ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` +changequote([, ])dnl + AC_DEFINE_UNQUOTED($ac_tr_lib) + LIBS="-l$1 $LIBS" +], [$3]) +else + AC_MSG_RESULT(no) +ifelse([$4], , , [$4 +])dnl +fi +]) + +dnl +dnl AC_LBL_LIBRARY_NET +dnl +dnl This test is for network applications that need socket() and +dnl gethostbyname() -ish functions. Under Solaris, those applications +dnl need to link with "-lsocket -lnsl". Under IRIX, they need to link +dnl with "-lnsl" but should *not* link with "-lsocket" because +dnl libsocket.a breaks a number of things (for instance: +dnl gethostbyname() under IRIX 5.2, and snoop sockets under most +dnl versions of IRIX). +dnl +dnl Unfortunately, many application developers are not aware of this, +dnl and mistakenly write tests that cause -lsocket to be used under +dnl IRIX. It is also easy to write tests that cause -lnsl to be used +dnl under operating systems where neither are necessary (or useful), +dnl such as SunOS 4.1.4, which uses -lnsl for TLI. +dnl +dnl This test exists so that every application developer does not test +dnl this in a different, and subtly broken fashion. + +dnl It has been argued that this test should be broken up into two +dnl seperate tests, one for the resolver libraries, and one for the +dnl libraries necessary for using Sockets API. Unfortunately, the two +dnl are carefully intertwined and allowing the autoconf user to use +dnl them independantly potentially results in unfortunate ordering +dnl dependancies -- as such, such component macros would have to +dnl carefully use indirection and be aware if the other components were +dnl executed. Since other autoconf macros do not go to this trouble, +dnl and almost no applications use sockets without the resolver, this +dnl complexity has not been implemented. +dnl +dnl The check for libresolv is in case you are attempting to link +dnl statically and happen to have a libresolv.a lying around (and no +dnl libnsl.a). +dnl +AC_DEFUN(AC_LBL_LIBRARY_NET, [ + # Most operating systems have gethostbyname() in the default searched + # libraries (i.e. libc): + # Some OSes (eg. Solaris) place it in libnsl + # Some strange OSes (SINIX) have it in libsocket: + AC_SEARCH_LIBS(gethostbyname, nsl socket resolv) + # Unfortunately libsocket sometimes depends on libnsl and + # AC_SEARCH_LIBS isn't up to the task of handling dependencies like this. + if test "$ac_cv_search_gethostbyname" = "no" + then + AC_CHECK_LIB(socket, gethostbyname, + LIBS="-lsocket -lnsl $LIBS", , -lnsl) + fi + AC_SEARCH_LIBS(socket, socket, , + AC_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", , -lnsl)) + # DLPI needs putmsg under HPUX so test for -lstr while we're at it + AC_SEARCH_LIBS(putmsg, str) + ]) + +dnl +dnl Test for __attribute__ +dnl + +AC_DEFUN(AC_C___ATTRIBUTE__, [ +AC_MSG_CHECKING(for __attribute__) +AC_CACHE_VAL(ac_cv___attribute__, [ +AC_COMPILE_IFELSE( + AC_LANG_SOURCE([[ +#include + +static void foo(void) __attribute__ ((noreturn)); + +static void +foo(void) +{ + exit(1); +} + +int +main(int argc, char **argv) +{ + foo(); +} + ]]), +ac_cv___attribute__=yes, +ac_cv___attribute__=no)]) +if test "$ac_cv___attribute__" = "yes"; then + AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__]) + V_DEFS="$V_DEFS -D_U_=\"__attribute__((unused))\"" +else + V_DEFS="$V_DEFS -D_U_=\"\"" +fi +AC_MSG_RESULT($ac_cv___attribute__) +]) + +dnl +dnl Checks to see if tpacket_stats is defined in linux/if_packet.h +dnl If so then pcap-linux.c can use this to report proper statistics. +dnl +dnl -Scott Barron +dnl +AC_DEFUN(AC_LBL_TPACKET_STATS, + [AC_MSG_CHECKING(if if_packet.h has tpacket_stats defined) + AC_CACHE_VAL(ac_cv_lbl_tpacket_stats, + AC_TRY_COMPILE([ +# include ], + [struct tpacket_stats stats], + ac_cv_lbl_tpacket_stats=yes, + ac_cv_lbl_tpacket_stats=no)) + AC_MSG_RESULT($ac_cv_lbl_tpacket_stats) + if test $ac_cv_lbl_tpacket_stats = yes; then + AC_DEFINE(HAVE_TPACKET_STATS,1,[if if_packet.h has tpacket_stats defined]) + fi]) diff --git a/winpcap/wpcap/libpcap/arcnet.h b/winpcap/wpcap/libpcap/arcnet.h new file mode 100644 index 0000000..dce7335 --- /dev/null +++ b/winpcap/wpcap/libpcap/arcnet.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#) $Id: arcnet.h,v 1.2 2001/04/24 02:17:52 guy Exp $ (LBL) + * + * from: NetBSD: if_arc.h,v 1.13 1999/11/19 20:41:19 thorpej Exp + */ + +/* RFC 1051 */ +#define ARCTYPE_IP_OLD 240 /* IP protocol */ +#define ARCTYPE_ARP_OLD 241 /* address resolution protocol */ + +/* RFC 1201 */ +#define ARCTYPE_IP 212 /* IP protocol */ +#define ARCTYPE_ARP 213 /* address resolution protocol */ +#define ARCTYPE_REVARP 214 /* reverse addr resolution protocol */ + +#define ARCTYPE_ATALK 221 /* Appletalk */ +#define ARCTYPE_BANIAN 247 /* Banyan Vines */ +#define ARCTYPE_IPX 250 /* Novell IPX */ + +#define ARCTYPE_INET6 0xc4 /* IPng */ +#define ARCTYPE_DIAGNOSE 0x80 /* as per ANSI/ATA 878.1 */ diff --git a/winpcap/wpcap/libpcap/atmuni31.h b/winpcap/wpcap/libpcap/atmuni31.h new file mode 100644 index 0000000..877ed68 --- /dev/null +++ b/winpcap/wpcap/libpcap/atmuni31.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1997 Yen Yen Lim and North Dakota State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Yen Yen Lim and + North Dakota State University + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @(#) $Header: /tcpdump/master/libpcap/atmuni31.h,v 1.1 2002/07/11 09:06:32 guy Exp $ (LBL) + */ + +/* Based on UNI3.1 standard by ATM Forum */ + +/* ATM traffic types based on VPI=0 and (the following VCI */ +#define PPC 0x05 /* Point-to-point signal msg */ +#define BCC 0x02 /* Broadcast signal msg */ +#define OAMF4SC 0x03 /* Segment OAM F4 flow cell */ +#define OAMF4EC 0x04 /* End-to-end OAM F4 flow cell */ +#define METAC 0x01 /* Meta signal msg */ +#define ILMIC 0x10 /* ILMI msg */ + +/* Q.2931 signalling messages */ +#define CALL_PROCEED 0x02 /* call proceeding */ +#define CONNECT 0x07 /* connect */ +#define CONNECT_ACK 0x0f /* connect_ack */ +#define SETUP 0x05 /* setup */ +#define RELEASE 0x4d /* release */ +#define RELEASE_DONE 0x5a /* release_done */ +#define RESTART 0x46 /* restart */ +#define RESTART_ACK 0x4e /* restart ack */ +#define STATUS 0x7d /* status */ +#define STATUS_ENQ 0x75 /* status ack */ +#define ADD_PARTY 0x80 /* add party */ +#define ADD_PARTY_ACK 0x81 /* add party ack */ +#define ADD_PARTY_REJ 0x82 /* add party rej */ +#define DROP_PARTY 0x83 /* drop party */ +#define DROP_PARTY_ACK 0x84 /* drop party ack */ + +/* Information Element Parameters in the signalling messages */ +#define CAUSE 0x08 /* cause */ +#define ENDPT_REF 0x54 /* endpoint reference */ +#define AAL_PARA 0x58 /* ATM adaptation layer parameters */ +#define TRAFF_DESCRIP 0x59 /* atm traffic descriptors */ +#define CONNECT_ID 0x5a /* connection identifier */ +#define QOS_PARA 0x5c /* quality of service parameters */ +#define B_HIGHER 0x5d /* broadband higher layer information */ +#define B_BEARER 0x5e /* broadband bearer capability */ +#define B_LOWER 0x5f /* broadband lower information */ +#define CALLING_PARTY 0x6c /* calling party number */ +#define CALLED_PARTY 0x70 /* called party nmber */ + +#define Q2931 0x09 + +/* Q.2931 signalling general messages format */ +#define PROTO_POS 0 /* offset of protocol discriminator */ +#define CALL_REF_POS 2 /* offset of call reference value */ +#define MSG_TYPE_POS 5 /* offset of message type */ +#define MSG_LEN_POS 7 /* offset of mesage length */ +#define IE_BEGIN_POS 9 /* offset of first information element */ + +/* format of signalling messages */ +#define TYPE_POS 0 +#define LEN_POS 2 +#define FIELD_BEGIN_POS 4 diff --git a/winpcap/wpcap/libpcap/bpf/net/bpf_filter.c b/winpcap/wpcap/libpcap/bpf/net/bpf_filter.c new file mode 100644 index 0000000..40df32a --- /dev/null +++ b/winpcap/wpcap/libpcap/bpf/net/bpf_filter.c @@ -0,0 +1,565 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)bpf.c 7.5 (Berkeley) 7/15/91 + */ + +#if !(defined(lint) || defined(KERNEL) || defined(_KERNEL)) +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.44 2003/11/15 23:24:07 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 + +#include + +#else /* WIN32 */ + +#include +#include +#include + +#define SOLARIS (defined(sun) && (defined(__SVR4) || defined(__svr4__))) +#if defined(__hpux) || SOLARIS +# include +# include +# define mbuf msgb +# define m_next b_cont +# define MLEN(m) ((m)->b_wptr - (m)->b_rptr) +# define mtod(m,t) ((t)(m)->b_rptr) +#else +# define MLEN(m) ((m)->m_len) +#endif + +#endif /* WIN32 */ + +#include + +#if !defined(KERNEL) && !defined(_KERNEL) +#include +#endif + +#define int32 bpf_int32 +#define u_int32 bpf_u_int32 + +#ifndef LBL_ALIGN +/* + * XXX - IA-64? If not, this probably won't work on Win64 IA-64 + * systems, unless LBL_ALIGN is defined elsewhere for them. + * XXX - SuperH? If not, this probably won't work on WinCE SuperH + * systems, unless LBL_ALIGN is defined elsewhere for them. + */ +#if defined(sparc) || defined(__sparc__) || defined(mips) || \ + defined(ibm032) || defined(__alpha) || defined(__hpux) || \ + defined(__arm__) +#define LBL_ALIGN +#endif +#endif + +#ifndef LBL_ALIGN +#ifndef WIN32 +#include +#endif + +#define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p)) +#define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p)) +#else +#define EXTRACT_SHORT(p)\ + ((u_short)\ + ((u_short)*((u_char *)p+0)<<8|\ + (u_short)*((u_char *)p+1)<<0)) +#define EXTRACT_LONG(p)\ + ((u_int32)*((u_char *)p+0)<<24|\ + (u_int32)*((u_char *)p+1)<<16|\ + (u_int32)*((u_char *)p+2)<<8|\ + (u_int32)*((u_char *)p+3)<<0) +#endif + +#if defined(KERNEL) || defined(_KERNEL) +# if !defined(__hpux) && !SOLARIS +#include +# endif +#define MINDEX(len, _m, _k) \ +{ \ + len = MLEN(m); \ + while ((_k) >= len) { \ + (_k) -= len; \ + (_m) = (_m)->m_next; \ + if ((_m) == 0) \ + return 0; \ + len = MLEN(m); \ + } \ +} + +static int +m_xword(m, k, err) + register struct mbuf *m; + register int k, *err; +{ + register int len; + register u_char *cp, *np; + register struct mbuf *m0; + + MINDEX(len, m, k); + cp = mtod(m, u_char *) + k; + if (len - k >= 4) { + *err = 0; + return EXTRACT_LONG(cp); + } + m0 = m->m_next; + if (m0 == 0 || MLEN(m0) + len - k < 4) + goto bad; + *err = 0; + np = mtod(m0, u_char *); + switch (len - k) { + + case 1: + return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2]; + + case 2: + return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1]; + + default: + return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0]; + } + bad: + *err = 1; + return 0; +} + +static int +m_xhalf(m, k, err) + register struct mbuf *m; + register int k, *err; +{ + register int len; + register u_char *cp; + register struct mbuf *m0; + + MINDEX(len, m, k); + cp = mtod(m, u_char *) + k; + if (len - k >= 2) { + *err = 0; + return EXTRACT_SHORT(cp); + } + m0 = m->m_next; + if (m0 == 0) + goto bad; + *err = 0; + return (cp[0] << 8) | mtod(m0, u_char *)[0]; + bad: + *err = 1; + return 0; +} +#endif + +/* + * Execute the filter program starting at pc on the packet p + * wirelen is the length of the original packet + * buflen is the amount of data present + * For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0, + * in all other cases, p is a pointer to a buffer and buflen is its size. + */ +u_int +bpf_filter(pc, p, wirelen, buflen) + register struct bpf_insn *pc; + register u_char *p; + u_int wirelen; + register u_int buflen; +{ + register u_int32 A, X; + register int k; + int32 mem[BPF_MEMWORDS]; +#if defined(KERNEL) || defined(_KERNEL) + struct mbuf *m, *n; + int merr, len; + + if (buflen == 0) { + m = (struct mbuf *)p; + p = mtod(m, u_char *); + buflen = MLEN(m); + } else + m = NULL; +#endif + + if (pc == 0) + /* + * No filter means accept all. + */ + return (u_int)-1; + A = 0; + X = 0; + --pc; + while (1) { + ++pc; + switch (pc->code) { + + default: +#if defined(KERNEL) || defined(_KERNEL) + return 0; +#else + abort(); +#endif + case BPF_RET|BPF_K: + return (u_int)pc->k; + + case BPF_RET|BPF_A: + return (u_int)A; + + case BPF_LD|BPF_W|BPF_ABS: + k = pc->k; + if (k + sizeof(int32) > buflen) { +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) + return 0; + A = m_xword(m, k, &merr); + if (merr != 0) + return 0; + continue; +#else + return 0; +#endif + } + A = EXTRACT_LONG(&p[k]); + continue; + + case BPF_LD|BPF_H|BPF_ABS: + k = pc->k; + if (k + sizeof(short) > buflen) { +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) + return 0; + A = m_xhalf(m, k, &merr); + if (merr != 0) + return 0; + continue; +#else + return 0; +#endif + } + A = EXTRACT_SHORT(&p[k]); + continue; + + case BPF_LD|BPF_B|BPF_ABS: + k = pc->k; + if (k >= buflen) { +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) + return 0; + n = m; + MINDEX(len, n, k); + A = mtod(n, u_char *)[k]; + continue; +#else + return 0; +#endif + } + A = p[k]; + continue; + + case BPF_LD|BPF_W|BPF_LEN: + A = wirelen; + continue; + + case BPF_LDX|BPF_W|BPF_LEN: + X = wirelen; + continue; + + case BPF_LD|BPF_W|BPF_IND: + k = X + pc->k; + if (k + sizeof(int32) > buflen) { +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) + return 0; + A = m_xword(m, k, &merr); + if (merr != 0) + return 0; + continue; +#else + return 0; +#endif + } + A = EXTRACT_LONG(&p[k]); + continue; + + case BPF_LD|BPF_H|BPF_IND: + k = X + pc->k; + if (k + sizeof(short) > buflen) { +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) + return 0; + A = m_xhalf(m, k, &merr); + if (merr != 0) + return 0; + continue; +#else + return 0; +#endif + } + A = EXTRACT_SHORT(&p[k]); + continue; + + case BPF_LD|BPF_B|BPF_IND: + k = X + pc->k; + if (k >= buflen) { +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) + return 0; + n = m; + MINDEX(len, n, k); + A = mtod(n, u_char *)[k]; + continue; +#else + return 0; +#endif + } + A = p[k]; + continue; + + case BPF_LDX|BPF_MSH|BPF_B: + k = pc->k; + if (k >= buflen) { +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) + return 0; + n = m; + MINDEX(len, n, k); + X = (mtod(n, char *)[k] & 0xf) << 2; + continue; +#else + return 0; +#endif + } + X = (p[pc->k] & 0xf) << 2; + continue; + + case BPF_LD|BPF_IMM: + A = pc->k; + continue; + + case BPF_LDX|BPF_IMM: + X = pc->k; + continue; + + case BPF_LD|BPF_MEM: + A = mem[pc->k]; + continue; + + case BPF_LDX|BPF_MEM: + X = mem[pc->k]; + continue; + + case BPF_ST: + mem[pc->k] = A; + continue; + + case BPF_STX: + mem[pc->k] = X; + continue; + + case BPF_JMP|BPF_JA: + pc += pc->k; + continue; + + case BPF_JMP|BPF_JGT|BPF_K: + pc += (A > pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_K: + pc += (A >= pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_K: + pc += (A == pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_K: + pc += (A & pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGT|BPF_X: + pc += (A > X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_X: + pc += (A >= X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_X: + pc += (A == X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_X: + pc += (A & X) ? pc->jt : pc->jf; + continue; + + case BPF_ALU|BPF_ADD|BPF_X: + A += X; + continue; + + case BPF_ALU|BPF_SUB|BPF_X: + A -= X; + continue; + + case BPF_ALU|BPF_MUL|BPF_X: + A *= X; + continue; + + case BPF_ALU|BPF_DIV|BPF_X: + if (X == 0) + return 0; + A /= X; + continue; + + case BPF_ALU|BPF_AND|BPF_X: + A &= X; + continue; + + case BPF_ALU|BPF_OR|BPF_X: + A |= X; + continue; + + case BPF_ALU|BPF_LSH|BPF_X: + A <<= X; + continue; + + case BPF_ALU|BPF_RSH|BPF_X: + A >>= X; + continue; + + case BPF_ALU|BPF_ADD|BPF_K: + A += pc->k; + continue; + + case BPF_ALU|BPF_SUB|BPF_K: + A -= pc->k; + continue; + + case BPF_ALU|BPF_MUL|BPF_K: + A *= pc->k; + continue; + + case BPF_ALU|BPF_DIV|BPF_K: + A /= pc->k; + continue; + + case BPF_ALU|BPF_AND|BPF_K: + A &= pc->k; + continue; + + case BPF_ALU|BPF_OR|BPF_K: + A |= pc->k; + continue; + + case BPF_ALU|BPF_LSH|BPF_K: + A <<= pc->k; + continue; + + case BPF_ALU|BPF_RSH|BPF_K: + A >>= pc->k; + continue; + + case BPF_ALU|BPF_NEG: + A = -A; + continue; + + case BPF_MISC|BPF_TAX: + X = A; + continue; + + case BPF_MISC|BPF_TXA: + A = X; + continue; + } + } +} + + +/* + * Return true if the 'fcode' is a valid filter program. + * The constraints are that each jump be forward and to a valid + * code. The code must terminate with either an accept or reject. + * 'valid' is an array for use by the routine (it must be at least + * 'len' bytes long). + * + * The kernel needs to be able to verify an application's filter code. + * Otherwise, a bogus program could easily crash the system. + */ +int +bpf_validate(f, len) + struct bpf_insn *f; + int len; +{ + register int i; + register struct bpf_insn *p; + + for (i = 0; i < len; ++i) { + /* + * Check that that jumps are forward, and within + * the code block. + */ + p = &f[i]; + if (BPF_CLASS(p->code) == BPF_JMP) { + register int from = i + 1; + + if (BPF_OP(p->code) == BPF_JA) { + if (from + p->k >= (unsigned)len) + return 0; + } + else if (from + p->jt >= len || from + p->jf >= len) + return 0; + } + /* + * Check that memory operations use valid addresses. + */ + if ((BPF_CLASS(p->code) == BPF_ST || + (BPF_CLASS(p->code) == BPF_LD && + (p->code & 0xe0) == BPF_MEM)) && + (p->k >= BPF_MEMWORDS || p->k < 0)) + return 0; + /* + * Check for constant division by 0. + */ + if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0) + return 0; + } + return BPF_CLASS(f[len - 1].code) == BPF_RET; +} diff --git a/winpcap/wpcap/libpcap/bpf_dump.c b/winpcap/wpcap/libpcap/bpf_dump.c new file mode 100644 index 0000000..303602e --- /dev/null +++ b/winpcap/wpcap/libpcap/bpf_dump.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1992, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.14 2003/11/15 23:23:57 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +void +bpf_dump(struct bpf_program *p, int option) +{ + struct bpf_insn *insn; + int i; + int n = p->bf_len; + + insn = p->bf_insns; + if (option > 2) { + printf("%d\n", n); + for (i = 0; i < n; ++insn, ++i) { + printf("%u %u %u %u\n", insn->code, + insn->jt, insn->jf, insn->k); + } + return ; + } + if (option > 1) { + for (i = 0; i < n; ++insn, ++i) + printf("{ 0x%x, %d, %d, 0x%08x },\n", + insn->code, insn->jt, insn->jf, insn->k); + return; + } + for (i = 0; i < n; ++insn, ++i) { +#ifdef BDEBUG + extern int bids[]; + printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1); +#endif + puts(bpf_image(insn, i)); + } +} diff --git a/winpcap/wpcap/libpcap/bpf_image.c b/winpcap/wpcap/libpcap/bpf_image.c new file mode 100644 index 0000000..7f31d9c --- /dev/null +++ b/winpcap/wpcap/libpcap/bpf_image.c @@ -0,0 +1,288 @@ +/* + * Copyright (c) 1990, 1991, 1992, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.26 2003/11/15 23:23:57 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "pcap-int.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +char * +bpf_image(p, n) + struct bpf_insn *p; + int n; +{ + int v; + char *fmt, *op; + static char image[256]; + char operand[64]; + + v = p->k; + switch (p->code) { + + default: + op = "unimp"; + fmt = "0x%x"; + v = p->code; + break; + + case BPF_RET|BPF_K: + op = "ret"; + fmt = "#%d"; + break; + + case BPF_RET|BPF_A: + op = "ret"; + fmt = ""; + break; + + case BPF_LD|BPF_W|BPF_ABS: + op = "ld"; + fmt = "[%d]"; + break; + + case BPF_LD|BPF_H|BPF_ABS: + op = "ldh"; + fmt = "[%d]"; + break; + + case BPF_LD|BPF_B|BPF_ABS: + op = "ldb"; + fmt = "[%d]"; + break; + + case BPF_LD|BPF_W|BPF_LEN: + op = "ld"; + fmt = "#pktlen"; + break; + + case BPF_LD|BPF_W|BPF_IND: + op = "ld"; + fmt = "[x + %d]"; + break; + + case BPF_LD|BPF_H|BPF_IND: + op = "ldh"; + fmt = "[x + %d]"; + break; + + case BPF_LD|BPF_B|BPF_IND: + op = "ldb"; + fmt = "[x + %d]"; + break; + + case BPF_LD|BPF_IMM: + op = "ld"; + fmt = "#0x%x"; + break; + + case BPF_LDX|BPF_IMM: + op = "ldx"; + fmt = "#0x%x"; + break; + + case BPF_LDX|BPF_MSH|BPF_B: + op = "ldxb"; + fmt = "4*([%d]&0xf)"; + break; + + case BPF_LD|BPF_MEM: + op = "ld"; + fmt = "M[%d]"; + break; + + case BPF_LDX|BPF_MEM: + op = "ldx"; + fmt = "M[%d]"; + break; + + case BPF_ST: + op = "st"; + fmt = "M[%d]"; + break; + + case BPF_STX: + op = "stx"; + fmt = "M[%d]"; + break; + + case BPF_JMP|BPF_JA: + op = "ja"; + fmt = "%d"; + v = n + 1 + p->k; + break; + + case BPF_JMP|BPF_JGT|BPF_K: + op = "jgt"; + fmt = "#0x%x"; + break; + + case BPF_JMP|BPF_JGE|BPF_K: + op = "jge"; + fmt = "#0x%x"; + break; + + case BPF_JMP|BPF_JEQ|BPF_K: + op = "jeq"; + fmt = "#0x%x"; + break; + + case BPF_JMP|BPF_JSET|BPF_K: + op = "jset"; + fmt = "#0x%x"; + break; + + case BPF_JMP|BPF_JGT|BPF_X: + op = "jgt"; + fmt = "x"; + break; + + case BPF_JMP|BPF_JGE|BPF_X: + op = "jge"; + fmt = "x"; + break; + + case BPF_JMP|BPF_JEQ|BPF_X: + op = "jeq"; + fmt = "x"; + break; + + case BPF_JMP|BPF_JSET|BPF_X: + op = "jset"; + fmt = "x"; + break; + + case BPF_ALU|BPF_ADD|BPF_X: + op = "add"; + fmt = "x"; + break; + + case BPF_ALU|BPF_SUB|BPF_X: + op = "sub"; + fmt = "x"; + break; + + case BPF_ALU|BPF_MUL|BPF_X: + op = "mul"; + fmt = "x"; + break; + + case BPF_ALU|BPF_DIV|BPF_X: + op = "div"; + fmt = "x"; + break; + + case BPF_ALU|BPF_AND|BPF_X: + op = "and"; + fmt = "x"; + break; + + case BPF_ALU|BPF_OR|BPF_X: + op = "or"; + fmt = "x"; + break; + + case BPF_ALU|BPF_LSH|BPF_X: + op = "lsh"; + fmt = "x"; + break; + + case BPF_ALU|BPF_RSH|BPF_X: + op = "rsh"; + fmt = "x"; + break; + + case BPF_ALU|BPF_ADD|BPF_K: + op = "add"; + fmt = "#%d"; + break; + + case BPF_ALU|BPF_SUB|BPF_K: + op = "sub"; + fmt = "#%d"; + break; + + case BPF_ALU|BPF_MUL|BPF_K: + op = "mul"; + fmt = "#%d"; + break; + + case BPF_ALU|BPF_DIV|BPF_K: + op = "div"; + fmt = "#%d"; + break; + + case BPF_ALU|BPF_AND|BPF_K: + op = "and"; + fmt = "#0x%x"; + break; + + case BPF_ALU|BPF_OR|BPF_K: + op = "or"; + fmt = "#0x%x"; + break; + + case BPF_ALU|BPF_LSH|BPF_K: + op = "lsh"; + fmt = "#%d"; + break; + + case BPF_ALU|BPF_RSH|BPF_K: + op = "rsh"; + fmt = "#%d"; + break; + + case BPF_ALU|BPF_NEG: + op = "neg"; + fmt = ""; + break; + + case BPF_MISC|BPF_TAX: + op = "tax"; + fmt = ""; + break; + + case BPF_MISC|BPF_TXA: + op = "txa"; + fmt = ""; + break; + } + (void)snprintf(operand, sizeof operand, fmt, v); + (void)snprintf(image, sizeof image, + (BPF_CLASS(p->code) == BPF_JMP && + BPF_OP(p->code) != BPF_JA) ? + "(%03d) %-8s %-16s jt %d\tjf %d" + : "(%03d) %-8s %s", + n, op, operand, n + 1 + p->jt, n + 1 + p->jf); + return image; +} diff --git a/winpcap/wpcap/libpcap/config.guess b/winpcap/wpcap/libpcap/config.guess new file mode 100644 index 0000000..4c5bde8 --- /dev/null +++ b/winpcap/wpcap/libpcap/config.guess @@ -0,0 +1,1429 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-10-16' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pegasos:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha*:OpenVMS:*:*) + echo alpha-hp-vms + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + # GNU/KFreeBSD systems have a "k" prefix to indicate we are using + # FreeBSD's kernel, but not the complete OS. + case ${LIBC} in gnu) kernel_only='k' ;; esac + echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + case `uname -p` in + *86) UNAME_PROCESSOR=i686 ;; + powerpc) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVWY]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit 0 ;; + *:DRAGONFLY:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/winpcap/wpcap/libpcap/config.h.in b/winpcap/wpcap/libpcap/config.h.in new file mode 100644 index 0000000..c7b7763 --- /dev/null +++ b/winpcap/wpcap/libpcap/config.h.in @@ -0,0 +1,189 @@ +/* config.h.in. Generated from configure.in by autoheader. */ +/* Long story short: aclocal.m4 depends on autoconf 2.13 + * implementation details wrt "const"; newer versions + * have different implementation details so for now we + * put "const" here. This may cause duplicate definitions + * in config.h but that should be OK since they're the same. + */ +#undef const + +/* Enable optimizer debugging */ +#undef BDEBUG + +/* define if you have the DAG API */ +#undef HAVE_DAG_API + +/* define if you have dag_get_erf_types() */ +#undef HAVE_DAG_GET_ERF_TYPES + +/* define if you have streams capable DAG API */ +#undef HAVE_DAG_STREAMS_API + +/* Define to 1 if you have the declaration of `ether_hostton', and to 0 if you + don't. */ +#undef HAVE_DECL_ETHER_HOSTTON + +/* define if you have a /dev/dlpi */ +#undef HAVE_DEV_DLPI + +/* Define to 1 if you have the `ether_hostton' function. */ +#undef HAVE_ETHER_HOSTTON + +/* on HP-UX 10.20 or later */ +#undef HAVE_HPUX10_20_OR_LATER + +/* on HP-UX 9.x */ +#undef HAVE_HPUX9 + +/* if ppa_info_t_dl_module_id exists */ +#undef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_ETHER_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IF_ETHER_H + +/* if there's an os_proto.h */ +#undef HAVE_OS_PROTO_H + +/* define if you have a /proc/net/dev */ +#undef HAVE_PROC_NET_DEV + +/* define if you have a Septel API */ +#undef HAVE_SEPTEL_API + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* if struct sockaddr has sa_len */ +#undef HAVE_SOCKADDR_SA_LEN + +/* if struct sockaddr_storage exists */ +#undef HAVE_SOCKADDR_STORAGE + +/* On solaris */ +#undef HAVE_SOLARIS + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define to 1 if the system has the type `struct ether_addr'. */ +#undef HAVE_STRUCT_ETHER_ADDR + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_BUFMOD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_DLPI_EXT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCCOM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* if if_packet.h has tpacket_stats defined */ +#undef HAVE_TPACKET_STATS + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* define if version.h is generated in the build procedure */ +#undef HAVE_VERSION_H + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* define if your compiler has __attribute__ */ +#undef HAVE___ATTRIBUTE__ + +/* IPv6 */ +#undef INET6 + +/* if unaligned access fails */ +#undef LBL_ALIGN + +/* Define to 1 if netinet/ether.h declares `ether_hostton' */ +#undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON + +/* Define to 1 if netinet/if_ether.h declares `ether_hostton' */ +#undef NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON + +/* do not use protochain */ +#undef NO_PROTOCHAIN + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* /dev/dlpi directory */ +#undef PCAP_DEV_PREFIX + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Enable parser debugging */ +#undef YYDEBUG + +/* needed on HP-UX */ +#undef _HPUX_SOURCE + +/* define on AIX to get certain functions */ +#undef _SUN + +/* Define as token for inline if inlining supported */ +#undef inline + +/* on sinix */ +#undef sinix + +/* if we have u_int16_t */ +#undef u_int16_t + +/* if we have u_int32_t */ +#undef u_int32_t + +/* if we have u_int8_t */ +#undef u_int8_t diff --git a/winpcap/wpcap/libpcap/config.sub b/winpcap/wpcap/libpcap/config.sub new file mode 100644 index 0000000..5698174 --- /dev/null +++ b/winpcap/wpcap/libpcap/config.sub @@ -0,0 +1,1531 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-11-03' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | msp430-* \ + | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nv1) + basic_machine=nv1-cray + os=-unicosmp + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/winpcap/wpcap/libpcap/configure b/winpcap/wpcap/libpcap/configure new file mode 100644 index 0000000..cb0d7c0 --- /dev/null +++ b/winpcap/wpcap/libpcap/configure @@ -0,0 +1,8409 @@ +#! /bin/sh +# From configure.in Revision: 1.120.2.8 . +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59. +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="pcap.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os SHLICC2 CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP LIBOBJS V_LEX V_YACC RANLIB ac_ct_RANLIB V_CCOPT V_DEFS V_INCLS V_LIBS V_PCAP V_FINDALLDEVS V_RANLIB SSRC DYEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-protochain disable \"protochain\" insn + --enable-ipv6 build IPv6-capable version + --enable-optimizer-dbg build optimizer debugging code + --enable-yydebug build parser debugging code + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --without-gcc don't use gcc + --with-pcap=TYPE use packet capture TYPE + --with-dag[=DIR] include Endace DAG support ("yes", "no" or DIR; default="yes" on BSD and Linux if present) + --with-dag-includes=DIR Endace DAG include directory + --with-dag-libraries=DIR Endace DAG library directory + --with-septel[=DIR] include Septel support (located in directory DIR, if supplied). default=yes, on Linux, if present + --without-flex don't use flex + --without-bison don't use bison + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking target system type" >&5 +echo $ECHO_N "checking target system type... $ECHO_C" >&6 +if test "${ac_cv_target+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_target_alias=$target_alias +test "x$ac_cv_target_alias" = "x" && + ac_cv_target_alias=$ac_cv_host_alias +ac_cv_target=`$ac_config_sub $ac_cv_target_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_target" >&5 +echo "${ECHO_T}$ac_cv_target" >&6 +target=$ac_cv_target +target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + + + + + +# Check whether --with-gcc or --without-gcc was given. +if test "${with_gcc+set}" = set; then + withval="$with_gcc" + +fi; + V_CCOPT="-O" + V_INCLS="" + if test "${srcdir}" != "." ; then + V_INCLS="-I\$(srcdir)" + fi + if test "${CFLAGS+set}" = set; then + LBL_CFLAGS="$CFLAGS" + fi + if test -z "$CC" ; then + case "$target_os" in + + bsdi*) + # Extract the first word of "shlicc2", so it can be a program name with args. +set dummy shlicc2; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_SHLICC2+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$SHLICC2"; then + ac_cv_prog_SHLICC2="$SHLICC2" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_SHLICC2="yes" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_SHLICC2" && ac_cv_prog_SHLICC2="no" +fi +fi +SHLICC2=$ac_cv_prog_SHLICC2 +if test -n "$SHLICC2"; then + echo "$as_me:$LINENO: result: $SHLICC2" >&5 +echo "${ECHO_T}$SHLICC2" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + if test $SHLICC2 = yes ; then + CC=shlicc2 + export CC + fi + ;; + esac + fi + if test -z "$CC" -a "$with_gcc" = no ; then + CC=cc + export CC + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test "$GCC" = yes ; then + if test "$SHLICC2" = yes ; then + ac_cv_lbl_gcc_vers=2 + V_CCOPT="-O2" + else + echo "$as_me:$LINENO: checking gcc version" >&5 +echo $ECHO_N "checking gcc version... $ECHO_C" >&6 + if test "${ac_cv_lbl_gcc_vers+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_lbl_gcc_vers=`$CC -v 2>&1 | \ + sed -e '/^gcc version /!d' \ + -e 's/^gcc version //' \ + -e 's/ .*//' -e 's/^[^0-9]*//' \ + -e 's/\..*//'` +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_gcc_vers" >&5 +echo "${ECHO_T}$ac_cv_lbl_gcc_vers" >&6 + if test $ac_cv_lbl_gcc_vers -gt 1 ; then + V_CCOPT="-O2" + fi + fi + else + echo "$as_me:$LINENO: checking that $CC handles ansi prototypes" >&5 +echo $ECHO_N "checking that $CC handles ansi prototypes... $ECHO_C" >&6 + if test "${ac_cv_lbl_cc_ansi_prototypes+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +int frob(int, char *) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lbl_cc_ansi_prototypes=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lbl_cc_ansi_prototypes=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_cc_ansi_prototypes" >&5 +echo "${ECHO_T}$ac_cv_lbl_cc_ansi_prototypes" >&6 + if test $ac_cv_lbl_cc_ansi_prototypes = no ; then + case "$target_os" in + + hpux*) + echo "$as_me:$LINENO: checking for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE)" >&5 +echo $ECHO_N "checking for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE)... $ECHO_C" >&6 + savedcflags="$CFLAGS" + CFLAGS="-Aa -D_HPUX_SOURCE $CFLAGS" + if test "${ac_cv_lbl_cc_hpux_cc_aa+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +int frob(int, char *) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lbl_cc_hpux_cc_aa=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lbl_cc_hpux_cc_aa=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_cc_hpux_cc_aa" >&5 +echo "${ECHO_T}$ac_cv_lbl_cc_hpux_cc_aa" >&6 + if test $ac_cv_lbl_cc_hpux_cc_aa = no ; then + { { echo "$as_me:$LINENO: error: see the INSTALL doc for more info" >&5 +echo "$as_me: error: see the INSTALL doc for more info" >&2;} + { (exit 1); exit 1; }; } + fi + CFLAGS="$savedcflags" + V_CCOPT="-Aa $V_CCOPT" + +cat >>confdefs.h <<\_ACEOF +#define _HPUX_SOURCE 1 +_ACEOF + + ;; + + *) + { { echo "$as_me:$LINENO: error: see the INSTALL doc for more info" >&5 +echo "$as_me: error: see the INSTALL doc for more info" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + fi + V_INCLS="$V_INCLS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + + case "$target_os" in + + irix*) + V_CCOPT="$V_CCOPT -xansi -signed -g3" + ;; + + osf*) + V_CCOPT="$V_CCOPT -std1 -g3" + ;; + + ultrix*) + echo "$as_me:$LINENO: checking that Ultrix $CC hacks const in prototypes" >&5 +echo $ECHO_N "checking that Ultrix $CC hacks const in prototypes... $ECHO_C" >&6 + if test "${ac_cv_lbl_cc_const_proto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +struct a { int b; }; + void c(const struct a *) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lbl_cc_const_proto=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lbl_cc_const_proto=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_cc_const_proto" >&5 +echo "${ECHO_T}$ac_cv_lbl_cc_const_proto" >&6 + if test $ac_cv_lbl_cc_const_proto = no ; then + cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + + fi + ;; + esac + fi + +echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6 + save_CFLAGS="$CFLAGS" + CFLAGS="$V_CCOPT" + if test "${ac_cv_lbl_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + ac_cv_lbl_inline="" + ac_lbl_cc_inline=no + for ac_lbl_inline in inline __inline__ __inline + do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define inline $ac_lbl_inline + static inline struct iltest *foo(void); + struct iltest { + int iltest1; + int iltest2; + }; + + static inline struct iltest * + foo() + { + static struct iltest xxx; + + return &xxx; + } +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lbl_cc_inline=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + if test "$ac_lbl_cc_inline" = yes ; then + break; + fi + done + if test "$ac_lbl_cc_inline" = yes ; then + ac_cv_lbl_inline=$ac_lbl_inline + fi +fi + + CFLAGS="$save_CFLAGS" + if test ! -z "$ac_cv_lbl_inline" ; then + echo "$as_me:$LINENO: result: $ac_cv_lbl_inline" >&5 +echo "${ECHO_T}$ac_cv_lbl_inline" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + +cat >>confdefs.h <<_ACEOF +#define inline $ac_cv_lbl_inline +_ACEOF + + +echo "$as_me:$LINENO: checking for __attribute__" >&5 +echo $ECHO_N "checking for __attribute__... $ECHO_C" >&6 +if test "${ac_cv___attribute__+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include + +static void foo(void) __attribute__ ((noreturn)); + +static void +foo(void) +{ + exit(1); +} + +int +main(int argc, char **argv) +{ + foo(); +} + +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv___attribute__=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv___attribute__=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +if test "$ac_cv___attribute__" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE___ATTRIBUTE__ 1 +_ACEOF + + V_DEFS="$V_DEFS -D_U_=\"__attribute__((unused))\"" +else + V_DEFS="$V_DEFS -D_U_=\"\"" +fi +echo "$as_me:$LINENO: result: $ac_cv___attribute__" >&5 +echo "${ECHO_T}$ac_cv___attribute__" >&6 + + +echo "$as_me:$LINENO: checking for u_int8_t using $CC" >&5 +echo $ECHO_N "checking for u_int8_t using $CC... $ECHO_C" >&6 + if test "${ac_cv_lbl_have_u_int8_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include "confdefs.h" +# include +# if STDC_HEADERS +# include +# include +# endif +int +main () +{ +u_int8_t i + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lbl_have_u_int8_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lbl_have_u_int8_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_have_u_int8_t" >&5 +echo "${ECHO_T}$ac_cv_lbl_have_u_int8_t" >&6 + if test $ac_cv_lbl_have_u_int8_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define u_int8_t u_char +_ACEOF + + fi +echo "$as_me:$LINENO: checking for u_int16_t using $CC" >&5 +echo $ECHO_N "checking for u_int16_t using $CC... $ECHO_C" >&6 + if test "${ac_cv_lbl_have_u_int16_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include "confdefs.h" +# include +# if STDC_HEADERS +# include +# include +# endif +int +main () +{ +u_int16_t i + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lbl_have_u_int16_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lbl_have_u_int16_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_have_u_int16_t" >&5 +echo "${ECHO_T}$ac_cv_lbl_have_u_int16_t" >&6 + if test $ac_cv_lbl_have_u_int16_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define u_int16_t u_short +_ACEOF + + fi +echo "$as_me:$LINENO: checking for u_int32_t using $CC" >&5 +echo $ECHO_N "checking for u_int32_t using $CC... $ECHO_C" >&6 + if test "${ac_cv_lbl_have_u_int32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include "confdefs.h" +# include +# if STDC_HEADERS +# include +# include +# endif +int +main () +{ +u_int32_t i + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lbl_have_u_int32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lbl_have_u_int32_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_have_u_int32_t" >&5 +echo "${ECHO_T}$ac_cv_lbl_have_u_int32_t" >&6 + if test $ac_cv_lbl_have_u_int32_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define u_int32_t u_int +_ACEOF + + fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + +for ac_header in sys/ioccom.h sys/sockio.h limits.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in netinet/if_ether.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +if test "$ac_cv_header_netinet_if_ether_h" != yes; then + # + # The simple test didn't work. + # Do we need to include first? + # Unset ac_cv_header_netinet_if_ether_h so we don't + # treat the previous failure as a cached value and + # suppress the next test. + # + { echo "$as_me:$LINENO: Rechecking with some additional includes" >&5 +echo "$as_me: Rechecking with some additional includes" >&6;} + unset ac_cv_header_netinet_if_ether_h + +for ac_header in netinet/if_ether.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +struct mbuf; +struct rtentry; +#include + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +fi + +if test "$GCC" = yes ; then + echo "$as_me:$LINENO: checking for ANSI ioctl definitions" >&5 +echo $ECHO_N "checking for ANSI ioctl definitions... $ECHO_C" >&6 + if test "${ac_cv_lbl_gcc_fixincludes+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* + * This generates a "duplicate case value" when fixincludes + * has not be run. + */ +# include +# include +# include +# ifdef HAVE_SYS_IOCCOM_H +# include +# endif +int +main () +{ +switch (0) { + case _IO('A', 1):; + case _IO('B', 1):; + } + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lbl_gcc_fixincludes=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lbl_gcc_fixincludes=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_gcc_fixincludes" >&5 +echo "${ECHO_T}$ac_cv_lbl_gcc_fixincludes" >&6 + if test $ac_cv_lbl_gcc_fixincludes = no ; then + # Don't cache failure + unset ac_cv_lbl_gcc_fixincludes + { { echo "$as_me:$LINENO: error: see the INSTALL for more info" >&5 +echo "$as_me: error: see the INSTALL for more info" >&2;} + { (exit 1); exit 1; }; } + fi + fi + + + +for ac_func in strerror strlcpy +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +needsnprintf=no + + +for ac_func in vsnprintf snprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + needsnprintf=yes +fi +done + +if test $needsnprintf = yes; then + case $LIBOBJS in + "snprintf.$ac_objext" | \ + *" snprintf.$ac_objext" | \ + "snprintf.$ac_objext "* | \ + *" snprintf.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS snprintf.$ac_objext" ;; +esac + +fi + +# +# Do this before checking for ether_hostton(), as it's a +# "gethostbyname() -ish function". +# + + # Most operating systems have gethostbyname() in the default searched + # libraries (i.e. libc): + # Some OSes (eg. Solaris) place it in libnsl + # Some strange OSes (SINIX) have it in libsocket: + echo "$as_me:$LINENO: checking for library containing gethostbyname" >&5 +echo $ECHO_N "checking for library containing gethostbyname... $ECHO_C" >&6 +if test "${ac_cv_search_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_gethostbyname=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +int +main () +{ +gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_gethostbyname="none required" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_gethostbyname" = no; then + for ac_lib in nsl socket resolv; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +int +main () +{ +gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_gethostbyname="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_search_gethostbyname" >&6 +if test "$ac_cv_search_gethostbyname" != no; then + test "$ac_cv_search_gethostbyname" = "none required" || LIBS="$ac_cv_search_gethostbyname $LIBS" + +fi + + # Unfortunately libsocket sometimes depends on libnsl and + # AC_SEARCH_LIBS isn't up to the task of handling dependencies like this. + if test "$ac_cv_search_gethostbyname" = "no" + then + echo "$as_me:$LINENO: checking for gethostbyname in -lsocket" >&5 +echo $ECHO_N "checking for gethostbyname in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket -lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +int +main () +{ +gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_socket_gethostbyname=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_gethostbyname" >&6 +if test $ac_cv_lib_socket_gethostbyname = yes; then + LIBS="-lsocket -lnsl $LIBS" +fi + + fi + echo "$as_me:$LINENO: checking for library containing socket" >&5 +echo $ECHO_N "checking for library containing socket... $ECHO_C" >&6 +if test "${ac_cv_search_socket+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_socket=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_socket="none required" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_socket" = no; then + for ac_lib in socket; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_socket="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_socket" >&5 +echo "${ECHO_T}$ac_cv_search_socket" >&6 +if test "$ac_cv_search_socket" != no; then + test "$ac_cv_search_socket" = "none required" || LIBS="$ac_cv_search_socket $LIBS" + +else + echo "$as_me:$LINENO: checking for socket in -lsocket" >&5 +echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_socket+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket -lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_socket=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_socket_socket=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6 +if test $ac_cv_lib_socket_socket = yes; then + LIBS="-lsocket -lnsl $LIBS" +fi + +fi + + # DLPI needs putmsg under HPUX so test for -lstr while we're at it + echo "$as_me:$LINENO: checking for library containing putmsg" >&5 +echo $ECHO_N "checking for library containing putmsg... $ECHO_C" >&6 +if test "${ac_cv_search_putmsg+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_putmsg=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char putmsg (); +int +main () +{ +putmsg (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_putmsg="none required" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_putmsg" = no; then + for ac_lib in str; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char putmsg (); +int +main () +{ +putmsg (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_putmsg="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_putmsg" >&5 +echo "${ECHO_T}$ac_cv_search_putmsg" >&6 +if test "$ac_cv_search_putmsg" != no; then + test "$ac_cv_search_putmsg" = "none required" || LIBS="$ac_cv_search_putmsg $LIBS" + +fi + + + +# +# You are in a twisty little maze of UN*Xes, all different. +# Some might not have ether_hostton(). +# Some might have it, but not declare it in any header file. +# Some might have it, but declare it in . +# Some might have it, but declare it in +# (And some might have it but document it as something declared in +# , although appears to work.) +# +# Before you is a C compiler. +# + +for ac_func in ether_hostton +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "$ac_cv_func_ether_hostton" = yes; then + # + # OK, we have ether_hostton(). Do we have ? + # + if test "$ac_cv_header_netinet_if_ether_h" = yes; then + # + # Yes. Does it declare ether_hostton()? + # + echo "$as_me:$LINENO: checking whether ether_hostton is declared" >&5 +echo $ECHO_N "checking whether ether_hostton is declared... $ECHO_C" >&6 +if test "${ac_cv_have_decl_ether_hostton+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include +struct mbuf; +struct rtentry; +#include +#include + + +int +main () +{ +#ifndef ether_hostton + char *p = (char *) ether_hostton; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_have_decl_ether_hostton=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_have_decl_ether_hostton=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_have_decl_ether_hostton" >&5 +echo "${ECHO_T}$ac_cv_have_decl_ether_hostton" >&6 +if test $ac_cv_have_decl_ether_hostton = yes; then + + +cat >>confdefs.h <<\_ACEOF +#define NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON +_ACEOF + + +fi + + fi + # + # Did that succeed? + # + if test "$ac_cv_have_decl_ether_hostton" != yes; then + # + # No, how about , as on Linux? + # + +for ac_header in netinet/ether.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + if test "$ac_cv_header_netinet_ether_h" = yes; then + # + # We have it - does it declare ether_hostton()? + # Unset ac_cv_have_decl_ether_hostton so we don't + # treat the previous failure as a cached value and + # suppress the next test. + # + unset ac_cv_have_decl_ether_hostton + echo "$as_me:$LINENO: checking whether ether_hostton is declared" >&5 +echo $ECHO_N "checking whether ether_hostton is declared... $ECHO_C" >&6 +if test "${ac_cv_have_decl_ether_hostton+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include + + +int +main () +{ +#ifndef ether_hostton + char *p = (char *) ether_hostton; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_have_decl_ether_hostton=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_have_decl_ether_hostton=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_have_decl_ether_hostton" >&5 +echo "${ECHO_T}$ac_cv_have_decl_ether_hostton" >&6 +if test $ac_cv_have_decl_ether_hostton = yes; then + + +cat >>confdefs.h <<\_ACEOF +#define NETINET_ETHER_H_DECLARES_ETHER_HOSTTON +_ACEOF + + +fi + + fi + fi + # + # Is ether_hostton() declared? + # + if test "$ac_cv_have_decl_ether_hostton" != yes; then + # + # No, we'll have to declare it ourselves. + # Do we have "struct ether_addr"? + # + echo "$as_me:$LINENO: checking for struct ether_addr" >&5 +echo $ECHO_N "checking for struct ether_addr... $ECHO_C" >&6 +if test "${ac_cv_type_struct_ether_addr+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include +struct mbuf; +struct rtentry; +#include +#include + + +int +main () +{ +if ((struct ether_addr *) 0) + return 0; +if (sizeof (struct ether_addr)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_struct_ether_addr=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_struct_ether_addr=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_struct_ether_addr" >&5 +echo "${ECHO_T}$ac_cv_type_struct_ether_addr" >&6 +if test $ac_cv_type_struct_ether_addr = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_ETHER_ADDR 1 +_ACEOF + + +fi + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DECL_ETHER_HOSTTON 0 +_ACEOF + + else + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DECL_ETHER_HOSTTON 1 +_ACEOF + + fi +fi + +echo "$as_me:$LINENO: checking if --disable-protochain option is specified" >&5 +echo $ECHO_N "checking if --disable-protochain option is specified... $ECHO_C" >&6 +# Check whether --enable-protochain or --disable-protochain was given. +if test "${enable_protochain+set}" = set; then + enableval="$enable_protochain" + +fi; +case "x$enable_protochain" in +xyes) enable_protochain=enabled ;; +xno) enable_protochain=disabled ;; +x) enable_protochain=enabled ;; +esac + +if test "$enable_protochain" = "disabled"; then + +cat >>confdefs.h <<\_ACEOF +#define NO_PROTOCHAIN 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: ${enable_protochain}" >&5 +echo "${ECHO_T}${enable_protochain}" >&6 + +if test -z "$with_pcap" && test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: pcap type not determined when cross-compiling; use --with-pcap=..." >&5 +echo "$as_me: error: pcap type not determined when cross-compiling; use --with-pcap=..." >&2;} + { (exit 1); exit 1; }; } +fi + +# Check whether --with-pcap or --without-pcap was given. +if test "${with_pcap+set}" = set; then + withval="$with_pcap" + +fi; +echo "$as_me:$LINENO: checking packet capture type" >&5 +echo $ECHO_N "checking packet capture type... $ECHO_C" >&6 +if test ! -z "$with_pcap" ; then + V_PCAP="$withval" +elif test -r /dev/bpf0 ; then + V_PCAP=bpf +elif test -r /usr/include/net/pfilt.h ; then + V_PCAP=pf +elif test -r /dev/enet ; then + V_PCAP=enet +elif test -r /dev/nit ; then + V_PCAP=snit +elif test -r /usr/include/sys/net/nit.h ; then + V_PCAP=nit +elif test -r /usr/include/linux/socket.h ; then + V_PCAP=linux +elif test -r /usr/include/net/raw.h ; then + V_PCAP=snoop +elif test -r /usr/include/odmi.h ; then + # + # On AIX, the BPF devices might not yet be present - they're + # created the first time libpcap runs after booting. + # We check for odmi.h instead. + # + V_PCAP=bpf +elif test -r /usr/include/sys/dlpi.h ; then + V_PCAP=dlpi +elif test -c /dev/bpf0 ; then # check again in case not readable + V_PCAP=bpf +elif test -c /dev/enet ; then # check again in case not readable + V_PCAP=enet +elif test -c /dev/nit ; then # check again in case not readable + V_PCAP=snit +else + V_PCAP=null +fi +echo "$as_me:$LINENO: result: $V_PCAP" >&5 +echo "${ECHO_T}$V_PCAP" >&6 + +if test "$V_PCAP" = null +then + # + # We can't capture, so we can't open any capture + # devices, so we won't return any interfaces. + # + V_FINDALLDEVS=null +else + echo "$as_me:$LINENO: checking for getifaddrs" >&5 +echo $ECHO_N "checking for getifaddrs... $ECHO_C" >&6 +if test "${ac_cv_func_getifaddrs+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define getifaddrs to an innocuous variant, in case declares getifaddrs. + For example, HP-UX 11i declares gettimeofday. */ +#define getifaddrs innocuous_getifaddrs + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getifaddrs (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef getifaddrs + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getifaddrs (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getifaddrs) || defined (__stub___getifaddrs) +choke me +#else +char (*f) () = getifaddrs; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != getifaddrs; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_getifaddrs=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_getifaddrs=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_getifaddrs" >&5 +echo "${ECHO_T}$ac_cv_func_getifaddrs" >&6 +if test $ac_cv_func_getifaddrs = yes; then + + # + # We have "getifaddrs()"; make sure we have + # as well, just in case some platform is really weird. + # + if test "${ac_cv_header_ifaddrs_h+set}" = set; then + echo "$as_me:$LINENO: checking for ifaddrs.h" >&5 +echo $ECHO_N "checking for ifaddrs.h... $ECHO_C" >&6 +if test "${ac_cv_header_ifaddrs_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_ifaddrs_h" >&5 +echo "${ECHO_T}$ac_cv_header_ifaddrs_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking ifaddrs.h usability" >&5 +echo $ECHO_N "checking ifaddrs.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking ifaddrs.h presence" >&5 +echo $ECHO_N "checking ifaddrs.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: ifaddrs.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: ifaddrs.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: ifaddrs.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: ifaddrs.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: ifaddrs.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: ifaddrs.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: ifaddrs.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: ifaddrs.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: ifaddrs.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: ifaddrs.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: ifaddrs.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: ifaddrs.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: ifaddrs.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: ifaddrs.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: ifaddrs.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: ifaddrs.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for ifaddrs.h" >&5 +echo $ECHO_N "checking for ifaddrs.h... $ECHO_C" >&6 +if test "${ac_cv_header_ifaddrs_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_ifaddrs_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_ifaddrs_h" >&5 +echo "${ECHO_T}$ac_cv_header_ifaddrs_h" >&6 + +fi +if test $ac_cv_header_ifaddrs_h = yes; then + + # + # We have the header, so we use "getifaddrs()" to + # get the list of interfaces. + # + V_FINDALLDEVS=getad + +else + + # + # We don't have the header - give up. + # XXX - we could also fall back on some other + # mechanism, but, for now, this'll catch this + # problem so that we can at least try to figure + # out something to do on systems with "getifaddrs()" + # but without "ifaddrs.h", if there is something + # we can do on those systems. + # + { { echo "$as_me:$LINENO: error: Your system has getifaddrs() but doesn't have a usable ." >&5 +echo "$as_me: error: Your system has getifaddrs() but doesn't have a usable ." >&2;} + { (exit 1); exit 1; }; } + +fi + + + +else + + # + # Well, we don't have "getifaddrs()", so we have to use + # some other mechanism; determine what that mechanism is. + # + # The first thing we use is the type of capture mechanism, + # which is somewhat of a proxy for the OS we're using. + # + case "$V_PCAP" in + + dlpi) + # + # This might be Solaris 8 or later, with + # SIOCGLIFCONF, or it might be some other OS + # or some older version of Solaris, with + # just SIOCGIFCONF. + # + echo "$as_me:$LINENO: checking whether we have SIOCGLIFCONF" >&5 +echo $ECHO_N "checking whether we have SIOCGLIFCONF... $ECHO_C" >&6 + if test "${ac_cv_lbl_have_siocglifconf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + #include + #include + #include + #include +int +main () +{ +ioctl(0, SIOCGLIFCONF, (char *)0); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lbl_have_siocglifconf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lbl_have_siocglifconf=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_have_siocglifconf" >&5 +echo "${ECHO_T}$ac_cv_lbl_have_siocglifconf" >&6 + if test $ac_cv_lbl_have_siocglifconf = yes ; then + V_FINDALLDEVS=glifc + else + V_FINDALLDEVS=gifc + fi + ;; + + *) + # + # Assume we just have SIOCGIFCONF. + # (XXX - on at least later Linux kernels, there's + # another mechanism, and we should be using that + # instead.) + # + V_FINDALLDEVS=gifc + ;; + esac +fi + +fi + +echo "$as_me:$LINENO: checking if --enable-ipv6 option is specified" >&5 +echo $ECHO_N "checking if --enable-ipv6 option is specified... $ECHO_C" >&6 +# Check whether --enable-ipv6 or --disable-ipv6 was given. +if test "${enable_ipv6+set}" = set; then + enableval="$enable_ipv6" + +fi; +if test "$enable_ipv6" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define INET6 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: ${enable_ipv6-no}" >&5 +echo "${ECHO_T}${enable_ipv6-no}" >&6 + +echo "$as_me:$LINENO: checking whether to build optimizer debugging code" >&5 +echo $ECHO_N "checking whether to build optimizer debugging code... $ECHO_C" >&6 +# Check whether --enable-optimizer-dbg or --disable-optimizer-dbg was given. +if test "${enable_optimizer_dbg+set}" = set; then + enableval="$enable_optimizer_dbg" + +fi; +if test "$enable_optimizer_dbg" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define BDEBUG 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: ${enable_optimizer_dbg-no}" >&5 +echo "${ECHO_T}${enable_optimizer_dbg-no}" >&6 + +echo "$as_me:$LINENO: checking whether to build parser debugging code" >&5 +echo $ECHO_N "checking whether to build parser debugging code... $ECHO_C" >&6 +# Check whether --enable-yydebug or --disable-yydebug was given. +if test "${enable_yydebug+set}" = set; then + enableval="$enable_yydebug" + +fi; +if test "$enable_yydebug" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define YYDEBUG 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: ${enable_yydebug-no}" >&5 +echo "${ECHO_T}${enable_yydebug-no}" >&6 + +case "$V_PCAP" in + +dlpi) + + +for ac_header in sys/bufmod.h sys/dlpi_ext.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + echo "$as_me:$LINENO: checking for /dev/dlpi device" >&5 +echo $ECHO_N "checking for /dev/dlpi device... $ECHO_C" >&6 + if test -c /dev/dlpi ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DEV_DLPI 1 +_ACEOF + + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + dir="/dev/dlpi" + echo "$as_me:$LINENO: checking for $dir directory" >&5 +echo $ECHO_N "checking for $dir directory... $ECHO_C" >&6 + if test -d $dir ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<_ACEOF +#define PCAP_DEV_PREFIX "$dir" +_ACEOF + + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + fi + ;; + +linux) + echo "$as_me:$LINENO: checking Linux kernel version" >&5 +echo $ECHO_N "checking Linux kernel version... $ECHO_C" >&6 + if test "$cross_compiling" = yes; then + if test "${ac_cv_linux_vers+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_linux_vers=unknown +fi + + else + if test "${ac_cv_linux_vers+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_linux_vers=`uname -r 2>&1 | \ + sed -n -e '$s/.* //' -e '$s/\..*//p'` +fi + + fi + echo "$as_me:$LINENO: result: $ac_cv_linux_vers" >&5 +echo "${ECHO_T}$ac_cv_linux_vers" >&6 + if test $ac_cv_linux_vers = unknown ; then + { { echo "$as_me:$LINENO: error: cannot determine linux version when cross-compiling" >&5 +echo "$as_me: error: cannot determine linux version when cross-compiling" >&2;} + { (exit 1); exit 1; }; } + fi + if test $ac_cv_linux_vers -lt 2 ; then + { { echo "$as_me:$LINENO: error: version 2 or higher required; see the INSTALL doc for more info" >&5 +echo "$as_me: error: version 2 or higher required; see the INSTALL doc for more info" >&2;} + { (exit 1); exit 1; }; } + fi + echo "$as_me:$LINENO: checking if if_packet.h has tpacket_stats defined" >&5 +echo $ECHO_N "checking if if_packet.h has tpacket_stats defined... $ECHO_C" >&6 + if test "${ac_cv_lbl_tpacket_stats+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include +int +main () +{ +struct tpacket_stats stats + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lbl_tpacket_stats=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lbl_tpacket_stats=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_tpacket_stats" >&5 +echo "${ECHO_T}$ac_cv_lbl_tpacket_stats" >&6 + if test $ac_cv_lbl_tpacket_stats = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_TPACKET_STATS 1 +_ACEOF + + fi + ;; + +dag) + V_DEFS="$V_DEFS -DDAG_ONLY" + ;; + +septel) + V_DEFS="$V_DEFS -DSEPTEL_ONLY" + ;; + +null) + { echo "$as_me:$LINENO: WARNING: cannot determine packet capture interface" >&5 +echo "$as_me: WARNING: cannot determine packet capture interface" >&2;} + { echo "$as_me:$LINENO: WARNING: (see the INSTALL doc for more info)" >&5 +echo "$as_me: WARNING: (see the INSTALL doc for more info)" >&2;} + ;; + +esac + +echo "$as_me:$LINENO: checking whether we have /proc/net/dev" >&5 +echo $ECHO_N "checking whether we have /proc/net/dev... $ECHO_C" >&6 +if test -r /proc/net/dev ; then + ac_cv_lbl_proc_net_dev=yes +else + ac_cv_lbl_proc_net_dev=no +fi +if test $ac_cv_lbl_proc_net_dev = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_PROC_NET_DEV 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: $ac_cv_lbl_proc_net_dev" >&5 +echo "${ECHO_T}$ac_cv_lbl_proc_net_dev" >&6 + +# Check for Endace DAG card support. + +# Check whether --with-dag or --without-dag was given. +if test "${with_dag+set}" = set; then + withval="$with_dag" + + if test "$withval" = no + then + # User doesn't want DAG support. + want_dag=no + elif test "$withval" = yes + then + # User wants DAG support but hasn't specified a directory. + want_dag=yes + else + # User wants DAG support and has specified a directory, so use the provided value. + want_dag=yes + dag_root=$withval + fi + +else + + # + # Use DAG API if present, otherwise don't + # + want_dag=ifpresent + +fi; + + +# Check whether --with-dag-includes or --without-dag-includes was given. +if test "${with_dag_includes+set}" = set; then + withval="$with_dag_includes" + + # User wants DAG support and has specified a header directory, so use the provided value. + want_dag=yes + dag_include_dir=$withval + +fi; + + +# Check whether --with-dag-libraries or --without-dag-libraries was given. +if test "${with_dag_libraries+set}" = set; then + withval="$with_dag_libraries" + + # User wants DAG support and has specified a library directory, so use the provided value. + want_dag=yes + dag_lib_dir=$withval + +fi; + +case "$V_PCAP" in +linux|bpf|dag) + # + # We support the DAG API if we're on Linux or BSD, or if we're + # building a DAG-only libpcap. + # + ;; +*) + # + # If the user explicitly requested DAG, tell them it's not + # supported. + # + # If they expressed no preference, don't include it. + # + if test $want_dag = yes; then + { { echo "$as_me:$LINENO: error: DAG support is only available with 'linux' 'bpf' and 'dag' packet capture types" >&5 +echo "$as_me: error: DAG support is only available with 'linux' 'bpf' and 'dag' packet capture types" >&2;} + { (exit 1); exit 1; }; } + elif test $want_dag = yes; then + want_dag=no + fi + ;; +esac + +ac_cv_lbl_dag_api=no +if test "$want_dag" != no; then + + echo "$as_me:$LINENO: checking whether we have DAG API headers" >&5 +echo $ECHO_N "checking whether we have DAG API headers... $ECHO_C" >&6 + + # If necessary, set default paths for DAG API headers and libraries. + if test -z "$dag_root"; then + dag_root=/usr/local + fi + + if test -z "$dag_include_dir"; then + dag_include_dir="$dag_root/include" + fi + + if test -z "$dag_lib_dir"; then + dag_lib_dir="$dag_root/lib" + fi + + if test -z "$dag_tools_dir"; then + dag_tools_dir="$dag_root/tools" + fi + + if test -r $dag_include_dir/dagapi.h; then + ac_cv_lbl_dag_api=yes + fi + echo "$as_me:$LINENO: result: $ac_cv_lbl_dag_api ($dag_include_dir)" >&5 +echo "${ECHO_T}$ac_cv_lbl_dag_api ($dag_include_dir)" >&6 +fi + +if test $ac_cv_lbl_dag_api = yes; then + + echo "$as_me:$LINENO: checking dagapi.o" >&5 +echo $ECHO_N "checking dagapi.o... $ECHO_C" >&6 + dagapi_obj=no + if test -r $dag_tools_dir/dagapi.o; then + # 2.4.x. + dagapi_obj=$dag_tools_dir/dagapi.o + elif test -r $dag_lib_dir/dagapi.o; then + # 2.5.x. + dagapi_obj=$dag_lib_dir/dagapi.o + elif test -r $dag_lib_dir/libdag.a; then + # 2.5.x. + ar x $dag_lib_dir/libdag.a dagapi.o + if test -r ./dagapi.o; then + dagapi_obj=./dagapi.o + fi + fi + + if test $dagapi_obj = no; then + echo "$as_me:$LINENO: result: no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)" >&5 +echo "${ECHO_T}no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)" >&6 + ac_cv_lbl_dag_api=no + else + echo "$as_me:$LINENO: result: yes ($dagapi_obj)" >&5 +echo "${ECHO_T}yes ($dagapi_obj)" >&6 + fi +fi + +if test $ac_cv_lbl_dag_api = yes; then + + echo "$as_me:$LINENO: checking dagopts.o" >&5 +echo $ECHO_N "checking dagopts.o... $ECHO_C" >&6 + dagopts_obj=no + if test -r $dag_tools_dir/dagopts.o; then + # 2.4.x. + dagopts_obj=$dag_tools_dir/dagopts.o + elif test -r $dag_lib_dir/dagopts.o; then + # 2.5.x. + dagopts_obj=$dag_lib_dir/dagopts.o + elif test -r $dag_lib_dir/libdag.a; then + # 2.5.x. + ar x $dag_lib_dir/libdag.a dagopts.o + if test -r ./dagopts.o; then + dagopts_obj=./dagopts.o + fi + fi + + if test $dagopts_obj = no; then + echo "$as_me:$LINENO: result: no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)" >&5 +echo "${ECHO_T}no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)" >&6 + ac_cv_lbl_dag_api=no + else + echo "$as_me:$LINENO: result: yes ($dagopts_obj)" >&5 +echo "${ECHO_T}yes ($dagopts_obj)" >&6 + fi +fi + +if test $ac_cv_lbl_dag_api = yes; then + # Under 2.5.x only we need to add dagreg.o. + if test -r $dag_include_dir/dagreg.h; then + echo "$as_me:$LINENO: checking dagreg.o" >&5 +echo $ECHO_N "checking dagreg.o... $ECHO_C" >&6 + dagreg_obj=no + if test -r $dag_lib_dir/dagreg.o; then + # Object file is ready and waiting. + dagreg_obj=$dag_lib_dir/dagreg.o + elif test -r $dag_lib_dir/libdag.a; then + # Extract from libdag.a. + ar x $dag_lib_dir/libdag.a dagreg.o + if test -r ./dagreg.o; then + dagreg_obj=./dagreg.o + fi + fi + + if test $dagreg_obj = no; then + echo "$as_me:$LINENO: result: no (checked $dag_lib_dir $dag_lib_dir/libdag.a)" >&5 +echo "${ECHO_T}no (checked $dag_lib_dir $dag_lib_dir/libdag.a)" >&6 + ac_cv_lbl_dag_api=no + else + echo "$as_me:$LINENO: result: yes ($dagreg_obj)" >&5 +echo "${ECHO_T}yes ($dagreg_obj)" >&6 + fi + fi +fi + +if test $ac_cv_lbl_dag_api = yes; then + V_INCLS="$V_INCLS -I$dag_include_dir" + V_LIBS="$V_LIBS $dagapi_obj $dagopts_obj $dagreg_obj" + if test $V_PCAP != dag ; then + SSRC="pcap-dag.c" + fi + + # See if we can find a general version string. + # Don't need to save and restore LIBS to prevent -ldag being + # included if there's a found-action (arg 3). + saved_ldflags=$LDFLAGS + LDFLAGS="-L$dag_lib_dir" + echo "$as_me:$LINENO: checking for dag_attach_stream in -ldag" >&5 +echo $ECHO_N "checking for dag_attach_stream in -ldag... $ECHO_C" >&6 +if test "${ac_cv_lib_dag_dag_attach_stream+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldag $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dag_attach_stream (); +int +main () +{ +dag_attach_stream (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dag_dag_attach_stream=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dag_dag_attach_stream=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dag_dag_attach_stream" >&5 +echo "${ECHO_T}$ac_cv_lib_dag_dag_attach_stream" >&6 +if test $ac_cv_lib_dag_dag_attach_stream = yes; then + dag_version="2.5.x" +else + dag_version="2.4.x" +fi + + echo "$as_me:$LINENO: checking for dag_get_erf_types in -ldag" >&5 +echo $ECHO_N "checking for dag_get_erf_types in -ldag... $ECHO_C" >&6 +if test "${ac_cv_lib_dag_dag_get_erf_types+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldag $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dag_get_erf_types (); +int +main () +{ +dag_get_erf_types (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dag_dag_get_erf_types=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dag_dag_get_erf_types=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dag_dag_get_erf_types" >&5 +echo "${ECHO_T}$ac_cv_lib_dag_dag_get_erf_types" >&6 +if test $ac_cv_lib_dag_dag_get_erf_types = yes; then + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DAG_GET_ERF_TYPES 1 +_ACEOF + + +fi + + LDFLAGS=$saved_ldflags + + if test "$dag_version" = 2.5.x; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DAG_STREAMS_API 1 +_ACEOF + + fi + + # See if we can find a specific version string. + echo "$as_me:$LINENO: checking the DAG API version" >&5 +echo $ECHO_N "checking the DAG API version... $ECHO_C" >&6 + if test -r "$dag_root/VERSION"; then + dag_version="`cat $dag_root/VERSION`" + fi + echo "$as_me:$LINENO: result: $dag_version" >&5 +echo "${ECHO_T}$dag_version" >&6 + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DAG_API 1 +_ACEOF + +fi + +if test $ac_cv_lbl_dag_api = no; then + if test "$want_dag" = yes; then + # User wanted DAG support but we couldn't find it. + { { echo "$as_me:$LINENO: error: DAG API requested, but not found at $dag_root: use --without-dag" >&5 +echo "$as_me: error: DAG API requested, but not found at $dag_root: use --without-dag" >&2;} + { (exit 1); exit 1; }; } + fi + + if test "$V_PCAP" = dag; then + # User requested "dag" capture type but the DAG API wasn't + # found. + { { echo "$as_me:$LINENO: error: Specifying the capture type as \"dag\" requires the DAG API to be present; use the --with-dag options to specify the location. (Try \"./configure --help\" for more information.)" >&5 +echo "$as_me: error: Specifying the capture type as \"dag\" requires the DAG API to be present; use the --with-dag options to specify the location. (Try \"./configure --help\" for more information.)" >&2;} + { (exit 1); exit 1; }; } + fi +fi + + +# Check whether --with-septel or --without-septel was given. +if test "${with_septel+set}" = set; then + withval="$with_septel" + + if test "$withval" = no + then + want_septel=no + elif test "$withval" = yes + then + want_septel=yes + septel_root= + else + want_septel=yes + septel_root=$withval + fi + +else + + # + # Use Septel API if present, otherwise don't + # + want_septel=ifpresent + septel_root=./../septel + +fi; +ac_cv_lbl_septel_api=no +case "$V_PCAP" in +linux|septel) + # + # We support the Septel API if we're on Linux, or if we're building + # a Septel-only libpcap. + # + ;; +*) + # + # If the user explicitly requested Septel, tell them it's not + # supported. + # + # If they expressed no preference, don't include it. + # + if test $want_septel = yes; then + { { echo "$as_me:$LINENO: error: Septel support only available with 'linux' and 'septel' packet capture types" >&5 +echo "$as_me: error: Septel support only available with 'linux' and 'septel' packet capture types" >&2;} + { (exit 1); exit 1; }; } + elif test $want_septel = yes; then + want_septel=no + fi + ;; +esac + +if test "$with_septel" != no; then + echo "$as_me:$LINENO: checking whether we have Septel API" >&5 +echo $ECHO_N "checking whether we have Septel API... $ECHO_C" >&6 + + if test -z "$septel_root"; then + septel_root=$srcdir/../septel + + fi + + septel_tools_dir="$septel_root" + septel_include_dir="$septel_root/INC" + DEF="-DHAVE_SEPTEL_API" + + ac_cv_lbl_septel_api=no + if test -r "$septel_include_dir/msg.h"; then + V_INCLS="$V_INCLS -I$septel_include_dir" + V_DEFS="$V_DEFS $DEF" + V_LIBS="$V_LIBS $septel_tools_dir/asciibin.o $septel_tools_dir/bit2byte.o $septel_tools_dir/confirm.o $septel_tools_dir/fmtmsg.o $septel_tools_dir/gct_unix.o $septel_tools_dir/hqueue.o $septel_tools_dir/ident.o $septel_tools_dir/mem.o $septel_tools_dir/pack.o $septel_tools_dir/parse.o $septel_tools_dir/pool.o $septel_tools_dir/sdlsig.o $septel_tools_dir/strtonum.o $septel_tools_dir/timer.o $septel_tools_dir/trace.o " + + if test "$V_PCAP" != septel ; then + SSRC="pcap-septel.c" + + fi + ac_cv_lbl_septel_api=yes + fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_septel_api" >&5 +echo "${ECHO_T}$ac_cv_lbl_septel_api" >&6 + if test $ac_cv_lbl_septel_api = no; then + if test "$want_septel" = yes; then + { { echo "$as_me:$LINENO: error: Septel API not found under directory $septel_root; use --without-septel" >&5 +echo "$as_me: error: Septel API not found under directory $septel_root; use --without-septel" >&2;} + { (exit 1); exit 1; }; } + fi + else + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SEPTEL_API 1 +_ACEOF + + fi +fi + +if test "$V_PCAP" = septel -a "$ac_cv_lbl_septel_api" = no; then + { { echo "$as_me:$LINENO: error: Specifying the capture type as 'septel' requires the Septel API to be present; use --with-septel=DIR" >&5 +echo "$as_me: error: Specifying the capture type as 'septel' requires the Septel API to be present; use --with-septel=DIR" >&2;} + { (exit 1); exit 1; }; } +fi + + + +# Check whether --with-flex or --without-flex was given. +if test "${with_flex+set}" = set; then + withval="$with_flex" + +fi; + +# Check whether --with-bison or --without-bison was given. +if test "${with_bison+set}" = set; then + withval="$with_bison" + +fi; + if test "$with_flex" = no ; then + V_LEX=lex + else + for ac_prog in flex +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_V_LEX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$V_LEX"; then + ac_cv_prog_V_LEX="$V_LEX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_V_LEX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +V_LEX=$ac_cv_prog_V_LEX +if test -n "$V_LEX"; then + echo "$as_me:$LINENO: result: $V_LEX" >&5 +echo "${ECHO_T}$V_LEX" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$V_LEX" && break +done +test -n "$V_LEX" || V_LEX="lex" + + fi + if test "$V_LEX" = flex ; then + # The -V flag was added in 2.4 + echo "$as_me:$LINENO: checking for flex 2.4 or higher" >&5 +echo $ECHO_N "checking for flex 2.4 or higher... $ECHO_C" >&6 + if test "${ac_cv_lbl_flex_v24+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if flex -V >/dev/null 2>&1; then + ac_cv_lbl_flex_v24=yes + else + ac_cv_lbl_flex_v24=no + fi +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_flex_v24" >&5 +echo "${ECHO_T}$ac_cv_lbl_flex_v24" >&6 + if test $ac_cv_lbl_flex_v24 = no ; then + s="2.4 or higher required" + { echo "$as_me:$LINENO: WARNING: ignoring obsolete flex executable ($s)" >&5 +echo "$as_me: WARNING: ignoring obsolete flex executable ($s)" >&2;} + V_LEX=lex + fi + fi + if test "$with_bison" = no ; then + V_YACC=yacc + else + for ac_prog in bison +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_V_YACC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$V_YACC"; then + ac_cv_prog_V_YACC="$V_YACC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_V_YACC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +V_YACC=$ac_cv_prog_V_YACC +if test -n "$V_YACC"; then + echo "$as_me:$LINENO: result: $V_YACC" >&5 +echo "${ECHO_T}$V_YACC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$V_YACC" && break +done +test -n "$V_YACC" || V_YACC="yacc" + + fi + if test "$V_YACC" = bison ; then + V_YACC="$V_YACC -y" + fi + if test "$V_LEX" != lex -a "$V_YACC" = yacc -o "$V_LEX" = lex -a "$V_YACC" != yacc ; then + { echo "$as_me:$LINENO: WARNING: don't have both flex and bison; reverting to lex/yacc" >&5 +echo "$as_me: WARNING: don't have both flex and bison; reverting to lex/yacc" >&2;} + V_LEX=lex + V_YACC=yacc + fi + if test "$V_LEX" = flex -a -n "pcap_" ; then + V_LEX="$V_LEX -Ppcap_" + V_YACC="$V_YACC -p pcap_" + fi +if test "$V_LEX" = lex ; then +# Some versions of lex can't handle the definitions section of scanner.l . +# Try lexing it and complain if it can't deal. + echo "$as_me:$LINENO: checking for capable lex" >&5 +echo $ECHO_N "checking for capable lex... $ECHO_C" >&6 +if test "${tcpdump_cv_capable_lex+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if lex -t scanner.l > /dev/null 2>&1; then + tcpdump_cv_capable_lex=yes + else + tcpdump_cv_capable_lex=insufficient + fi +fi +echo "$as_me:$LINENO: result: $tcpdump_cv_capable_lex" >&5 +echo "${ECHO_T}$tcpdump_cv_capable_lex" >&6 + if test $tcpdump_cv_capable_lex = insufficient ; then + { { echo "$as_me:$LINENO: error: Your operating system's lex is insufficient to compile + libpcap. flex is a lex replacement that has many advantages, including + being able to compile libpcap. For more information, see + http://www.gnu.org/software/flex/flex.html ." >&5 +echo "$as_me: error: Your operating system's lex is insufficient to compile + libpcap. flex is a lex replacement that has many advantages, including + being able to compile libpcap. For more information, see + http://www.gnu.org/software/flex/flex.html ." >&2;} + { (exit 1); exit 1; }; } + fi +fi + +DYEXT="so" +case "$host_os" in + +aix*) + +cat >>confdefs.h <<\_ACEOF +#define _SUN 1 +_ACEOF + + ;; + +hpux9*) + +cat >>confdefs.h <<\_ACEOF +#define HAVE_HPUX9 1 +_ACEOF + + ;; + +hpux10.0*) + ;; + +hpux10.1*) + ;; + +hpux*) + +cat >>confdefs.h <<\_ACEOF +#define HAVE_HPUX10_20_OR_LATER 1 +_ACEOF + + ;; + +sinix*) + echo "$as_me:$LINENO: checking if SINIX compiler defines sinix" >&5 +echo $ECHO_N "checking if SINIX compiler defines sinix... $ECHO_C" >&6 + if test "${ac_cv_cc_sinix_defined+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +int i = sinix; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_cc_sinix_defined=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_cc_sinix_defined=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_cc_sinix_defined" >&5 +echo "${ECHO_T}$ac_cv_cc_sinix_defined" >&6 + if test $ac_cv_cc_sinix_defined = no ; then + +cat >>confdefs.h <<\_ACEOF +#define sinix 1 +_ACEOF + + fi + ;; + +solaris*) + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SOLARIS 1 +_ACEOF + + ;; + +darwin*) + DYEXT="dylib" + V_CCOPT="$V_CCOPT -fno-common" + ;; +esac + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + +rm -f os-proto.h + if test "${LBL_CFLAGS+set}" = set; then + V_CCOPT="$V_CCOPT ${LBL_CFLAGS}" + fi + if test -f .devel ; then + if test "$GCC" = yes ; then + if test "${LBL_CFLAGS+set}" != set; then + if test "$ac_cv_prog_cc_g" = yes ; then + V_CCOPT="-g $V_CCOPT" + fi + V_CCOPT="$V_CCOPT -Wall" + if test $ac_cv_lbl_gcc_vers -gt 1 ; then + V_CCOPT="$V_CCOPT -Wmissing-prototypes -Wstrict-prototypes" + fi + fi + else + case "$target_os" in + + irix6*) + V_CCOPT="$V_CCOPT -n32" + ;; + + *) + ;; + esac + fi + os=`echo $target_os | sed -e 's/\([0-9][0-9]*\)[^0-9].*$/\1/'` + name="lbl/os-$os.h" + if test -f $name ; then + ln -s $name os-proto.h + +cat >>confdefs.h <<\_ACEOF +#define HAVE_OS_PROTO_H 1 +_ACEOF + + else + { echo "$as_me:$LINENO: WARNING: can't find $name" >&5 +echo "$as_me: WARNING: can't find $name" >&2;} + fi + fi + +echo "$as_me:$LINENO: checking if sockaddr struct has sa_len member" >&5 +echo $ECHO_N "checking if sockaddr struct has sa_len member... $ECHO_C" >&6 + if test "${ac_cv_lbl_sockaddr_has_sa_len+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include +# include +int +main () +{ +u_int i = sizeof(((struct sockaddr *)0)->sa_len) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lbl_sockaddr_has_sa_len=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lbl_sockaddr_has_sa_len=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_sockaddr_has_sa_len" >&5 +echo "${ECHO_T}$ac_cv_lbl_sockaddr_has_sa_len" >&6 + if test $ac_cv_lbl_sockaddr_has_sa_len = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SOCKADDR_SA_LEN 1 +_ACEOF + + fi + +echo "$as_me:$LINENO: checking if sockaddr_storage struct exists" >&5 +echo $ECHO_N "checking if sockaddr_storage struct exists... $ECHO_C" >&6 + if test "${ac_cv_lbl_has_sockaddr_storage+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include +# include +int +main () +{ +u_int i = sizeof (struct sockaddr_storage) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lbl_has_sockaddr_storage=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lbl_has_sockaddr_storage=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_has_sockaddr_storage" >&5 +echo "${ECHO_T}$ac_cv_lbl_has_sockaddr_storage" >&6 + if test $ac_cv_lbl_has_sockaddr_storage = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SOCKADDR_STORAGE 1 +_ACEOF + + fi + +echo "$as_me:$LINENO: checking if dl_hp_ppa_info_t struct has dl_module_id_1 member" >&5 +echo $ECHO_N "checking if dl_hp_ppa_info_t struct has dl_module_id_1 member... $ECHO_C" >&6 + if test "${ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include +# include +# include +int +main () +{ +u_int i = sizeof(((dl_hp_ppa_info_t *)0)->dl_module_id_1) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1" >&5 +echo "${ECHO_T}$ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1" >&6 + if test $ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1 = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 1 +_ACEOF + + fi + +echo "$as_me:$LINENO: checking if unaligned accesses fail" >&5 +echo $ECHO_N "checking if unaligned accesses fail... $ECHO_C" >&6 + if test "${ac_cv_lbl_unaligned_fail+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case "$host_cpu" in + + # + # These are CPU types where: + # + # the CPU faults on an unaligned access, but at least some + # OSes that support that CPU catch the fault and simulate + # the unaligned access (e.g., Alpha/{Digital,Tru64} UNIX) - + # the simulation is slow, so we don't want to use it; + # + # the CPU, I infer (from the old + # + # XXX: should also check that they don't do weird things (like on arm) + # + # comment) doesn't fault on unaligned accesses, but doesn't + # do a normal unaligned fetch, either (e.g., presumably, ARM); + # + # for whatever reason, the test program doesn't work + # (this has been claimed to be the case for several of those + # CPUs - I don't know what the problem is; the problem + # was reported as "the test program dumps core" for SuperH, + # but that's what the test program is *supposed* to do - + # it dumps core before it writes anything, so the test + # for an empty output file should find an empty output + # file and conclude that unaligned accesses don't work). + # + # This run-time test won't work if you're cross-compiling, so + # in order to support cross-compiling for a particular CPU, + # we have to wire in the list of CPU types anyway, as far as + # I know, so perhaps we should just have a set of CPUs on + # which we know it doesn't work, a set of CPUs on which we + # know it does work, and have the script just fail on other + # cpu types and update it when such a failure occurs. + # + alpha*|arm*|hp*|mips*|sh*|sparc*|ia64|nv1) + ac_cv_lbl_unaligned_fail=yes + ;; + + *) + cat >conftest.c < +# include +# include + unsigned char a[5] = { 1, 2, 3, 4, 5 }; + main() { + unsigned int i; + pid_t pid; + int status; + /* avoid "core dumped" message */ + pid = fork(); + if (pid < 0) + exit(2); + if (pid > 0) { + /* parent */ + pid = waitpid(pid, &status, 0); + if (pid < 0) + exit(3); + exit(!WIFEXITED(status)); + } + /* child */ + i = *(unsigned int *)&a[1]; + printf("%d\n", i); + exit(0); + } +EOF + ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \ + conftest.c $LIBS >/dev/null 2>&1 + if test ! -x conftest ; then + ac_cv_lbl_unaligned_fail=yes + else + ./conftest >conftest.out + if test ! -s conftest.out ; then + ac_cv_lbl_unaligned_fail=yes + else + ac_cv_lbl_unaligned_fail=no + fi + fi + rm -f conftest* core core.conftest + ;; + esac +fi + + echo "$as_me:$LINENO: result: $ac_cv_lbl_unaligned_fail" >&5 +echo "${ECHO_T}$ac_cv_lbl_unaligned_fail" >&6 + if test $ac_cv_lbl_unaligned_fail = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define LBL_ALIGN 1 +_ACEOF + + fi + +# +# Makefile.in includes rules to generate version.h, so we assume +# that it will be generated if autoconf is used. +# + +cat >>confdefs.h <<\_ACEOF +#define HAVE_VERSION_H 1 +_ACEOF + + +rm -f net +ln -s ${srcdir}/bpf/net net + + + + + + + + + + + + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + + ac_config_headers="$ac_config_headers config.h" + + + ac_config_files="$ac_config_files Makefile" +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@target@,$target,;t t +s,@target_cpu@,$target_cpu,;t t +s,@target_vendor@,$target_vendor,;t t +s,@target_os@,$target_os,;t t +s,@SHLICC2@,$SHLICC2,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@V_LEX@,$V_LEX,;t t +s,@V_YACC@,$V_YACC,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@V_CCOPT@,$V_CCOPT,;t t +s,@V_DEFS@,$V_DEFS,;t t +s,@V_INCLS@,$V_INCLS,;t t +s,@V_LIBS@,$V_LIBS,;t t +s,@V_PCAP@,$V_PCAP,;t t +s,@V_FINDALLDEVS@,$V_FINDALLDEVS,;t t +s,@V_RANLIB@,$V_RANLIB,;t t +s,@SSRC@,$SSRC,;t t +s,@DYEXT@,$DYEXT,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + + +if test -f .devel ; then + make depend +fi +exit 0 diff --git a/winpcap/wpcap/libpcap/configure.in b/winpcap/wpcap/libpcap/configure.in new file mode 100644 index 0000000..04d34d2 --- /dev/null +++ b/winpcap/wpcap/libpcap/configure.in @@ -0,0 +1,852 @@ +dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.120.2.8 2006/04/07 07:08:50 guy Exp $ (LBL) +dnl +dnl Copyright (c) 1994, 1995, 1996, 1997 +dnl The Regents of the University of California. All rights reserved. +dnl +dnl Process this file with autoconf to produce a configure script. +dnl + +AC_REVISION($Revision: 1.120.2.8 $) +AC_PREREQ(2.50) +AC_INIT(pcap.c) + +AC_CANONICAL_SYSTEM + +AC_LBL_C_INIT(V_CCOPT, V_INCLS, V_LIBS) +AC_LBL_C_INLINE +AC_C___ATTRIBUTE__ + +AC_LBL_CHECK_TYPE(u_int8_t, u_char) +AC_LBL_CHECK_TYPE(u_int16_t, u_short) +AC_LBL_CHECK_TYPE(u_int32_t, u_int) + +dnl +dnl libpcap doesn't itself use ; however, the test program +dnl in "AC_LBL_FIXINCLUDES" in "aclocal.m4" uses it, so we have to +dnl test for it and set "HAVE_SYS_IOCCOM_H" if we have it, otherwise +dnl "AC_LBL_FIXINCLUDES" won't work on some platforms such as Solaris. +dnl +AC_CHECK_HEADERS(sys/ioccom.h sys/sockio.h limits.h) +AC_CHECK_HEADERS(netinet/if_ether.h, , , [#include +#include ]) +if test "$ac_cv_header_netinet_if_ether_h" != yes; then + # + # The simple test didn't work. + # Do we need to include first? + # Unset ac_cv_header_netinet_if_ether_h so we don't + # treat the previous failure as a cached value and + # suppress the next test. + # + AC_MSG_NOTICE([Rechecking with some additional includes]) + unset ac_cv_header_netinet_if_ether_h + AC_CHECK_HEADERS(netinet/if_ether.h, , , [#include +#include +#include +struct mbuf; +struct rtentry; +#include ]) +fi + +AC_LBL_FIXINCLUDES + +AC_CHECK_FUNCS(strerror strlcpy) + +needsnprintf=no +AC_CHECK_FUNCS(vsnprintf snprintf,, + [needsnprintf=yes]) +if test $needsnprintf = yes; then + AC_LIBOBJ(snprintf) +fi + +# +# Do this before checking for ether_hostton(), as it's a +# "gethostbyname() -ish function". +# +AC_LBL_LIBRARY_NET + +# +# You are in a twisty little maze of UN*Xes, all different. +# Some might not have ether_hostton(). +# Some might have it, but not declare it in any header file. +# Some might have it, but declare it in . +# Some might have it, but declare it in +# (And some might have it but document it as something declared in +# , although appears to work.) +# +# Before you is a C compiler. +# +AC_CHECK_FUNCS(ether_hostton) +if test "$ac_cv_func_ether_hostton" = yes; then + # + # OK, we have ether_hostton(). Do we have ? + # + if test "$ac_cv_header_netinet_if_ether_h" = yes; then + # + # Yes. Does it declare ether_hostton()? + # + AC_CHECK_DECL(ether_hostton, + [ + AC_DEFINE(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON,, + [Define to 1 if netinet/if_ether.h declares `ether_hostton']) + ],, + [ +#include +#include +#include +#include +struct mbuf; +struct rtentry; +#include +#include + ]) + fi + # + # Did that succeed? + # + if test "$ac_cv_have_decl_ether_hostton" != yes; then + # + # No, how about , as on Linux? + # + AC_CHECK_HEADERS(netinet/ether.h) + if test "$ac_cv_header_netinet_ether_h" = yes; then + # + # We have it - does it declare ether_hostton()? + # Unset ac_cv_have_decl_ether_hostton so we don't + # treat the previous failure as a cached value and + # suppress the next test. + # + unset ac_cv_have_decl_ether_hostton + AC_CHECK_DECL(ether_hostton, + [ + AC_DEFINE(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON,, + [Define to 1 if netinet/ether.h declares `ether_hostton']) + ],, + [ +#include + ]) + fi + fi + # + # Is ether_hostton() declared? + # + if test "$ac_cv_have_decl_ether_hostton" != yes; then + # + # No, we'll have to declare it ourselves. + # Do we have "struct ether_addr"? + # + AC_CHECK_TYPES(struct ether_addr,,, + [ +#include +#include +#include +#include +struct mbuf; +struct rtentry; +#include +#include + ]) + AC_DEFINE(HAVE_DECL_ETHER_HOSTTON, 0, + [Define to 1 if you have the declaration of `ether_hostton', and to 0 if you +don't.]) + else + AC_DEFINE(HAVE_DECL_ETHER_HOSTTON, 1, + [Define to 1 if you have the declaration of `ether_hostton', and to 0 if you +don't.]) + fi +fi + +dnl to pacify those who hate protochain insn +AC_MSG_CHECKING(if --disable-protochain option is specified) +AC_ARG_ENABLE(protochain, [ --disable-protochain disable \"protochain\" insn]) +case "x$enable_protochain" in +xyes) enable_protochain=enabled ;; +xno) enable_protochain=disabled ;; +x) enable_protochain=enabled ;; +esac + +if test "$enable_protochain" = "disabled"; then + AC_DEFINE(NO_PROTOCHAIN,1,[do not use protochain]) +fi +AC_MSG_RESULT(${enable_protochain}) + +dnl +dnl Not all versions of test support -c (character special) but it's a +dnl better way of testing since the device might be protected. So we +dnl check in our normal order using -r and then check the for the /dev +dnl guys again using -c. +dnl +dnl XXX This could be done for cross-compiling, but for now it's not. +dnl +if test -z "$with_pcap" && test "$cross_compiling" = yes; then + AC_MSG_ERROR(pcap type not determined when cross-compiling; use --with-pcap=...) +fi +AC_ARG_WITH(pcap, [ --with-pcap=TYPE use packet capture TYPE]) +AC_MSG_CHECKING(packet capture type) +if test ! -z "$with_pcap" ; then + V_PCAP="$withval" +elif test -r /dev/bpf0 ; then + V_PCAP=bpf +elif test -r /usr/include/net/pfilt.h ; then + V_PCAP=pf +elif test -r /dev/enet ; then + V_PCAP=enet +elif test -r /dev/nit ; then + V_PCAP=snit +elif test -r /usr/include/sys/net/nit.h ; then + V_PCAP=nit +elif test -r /usr/include/linux/socket.h ; then + V_PCAP=linux +elif test -r /usr/include/net/raw.h ; then + V_PCAP=snoop +elif test -r /usr/include/odmi.h ; then + # + # On AIX, the BPF devices might not yet be present - they're + # created the first time libpcap runs after booting. + # We check for odmi.h instead. + # + V_PCAP=bpf +elif test -r /usr/include/sys/dlpi.h ; then + V_PCAP=dlpi +elif test -c /dev/bpf0 ; then # check again in case not readable + V_PCAP=bpf +elif test -c /dev/enet ; then # check again in case not readable + V_PCAP=enet +elif test -c /dev/nit ; then # check again in case not readable + V_PCAP=snit +else + V_PCAP=null +fi +AC_MSG_RESULT($V_PCAP) + +dnl +dnl Now figure out how we get a list of interfaces and addresses, +dnl if we support capturing. Don't bother if we don't support +dnl capturing. +dnl +if test "$V_PCAP" = null +then + # + # We can't capture, so we can't open any capture + # devices, so we won't return any interfaces. + # + V_FINDALLDEVS=null +else + AC_CHECK_FUNC(getifaddrs,[ + # + # We have "getifaddrs()"; make sure we have + # as well, just in case some platform is really weird. + # + AC_CHECK_HEADER(ifaddrs.h,[ + # + # We have the header, so we use "getifaddrs()" to + # get the list of interfaces. + # + V_FINDALLDEVS=getad + ],[ + # + # We don't have the header - give up. + # XXX - we could also fall back on some other + # mechanism, but, for now, this'll catch this + # problem so that we can at least try to figure + # out something to do on systems with "getifaddrs()" + # but without "ifaddrs.h", if there is something + # we can do on those systems. + # + AC_MSG_ERROR([Your system has getifaddrs() but doesn't have a usable .]) + ]) + ],[ + # + # Well, we don't have "getifaddrs()", so we have to use + # some other mechanism; determine what that mechanism is. + # + # The first thing we use is the type of capture mechanism, + # which is somewhat of a proxy for the OS we're using. + # + case "$V_PCAP" in + + dlpi) + # + # This might be Solaris 8 or later, with + # SIOCGLIFCONF, or it might be some other OS + # or some older version of Solaris, with + # just SIOCGIFCONF. + # + AC_MSG_CHECKING(whether we have SIOCGLIFCONF) + AC_CACHE_VAL(ac_cv_lbl_have_siocglifconf, + AC_TRY_COMPILE( + [#include + #include + #include + #include + #include ], + [ioctl(0, SIOCGLIFCONF, (char *)0);], + ac_cv_lbl_have_siocglifconf=yes, + ac_cv_lbl_have_siocglifconf=no)) + AC_MSG_RESULT($ac_cv_lbl_have_siocglifconf) + if test $ac_cv_lbl_have_siocglifconf = yes ; then + V_FINDALLDEVS=glifc + else + V_FINDALLDEVS=gifc + fi + ;; + + *) + # + # Assume we just have SIOCGIFCONF. + # (XXX - on at least later Linux kernels, there's + # another mechanism, and we should be using that + # instead.) + # + V_FINDALLDEVS=gifc + ;; + esac]) +fi + +dnl HAVE_REMOTE +AC_MSG_CHECKING(if --disable-remote option is specified) +AC_ARG_ENABLE(remote, [ --disable-remote disable remote capture capabilities]) + +case "x$enable_remote" in +xyes) enable_remote=enabled ;; +xno) enable_remote=disabled ;; +x) enable_remote=enabled ;; +esac + +AC_MSG_RESULT(${enable_remote}) + + +if test "$enable_remote" = "enabled"; then + + dnl + dnl Checking if the remote features of libpcap are supported by + dnl the OS and must be compiled + dnl + + AC_MSG_CHECKING(if remote capture is supported) + + if test -e ./remote-ext.h ; then # Check that the remote extensions are there + + case "$V_PCAP" in + + linux) + V_REMOTE_FILES="pcap-new.c pcap-remote.c sockutils.c" + V_HAVE_REMOTE="-DHAVE_REMOTE" + AC_DEFINE(HAVE_REMOTE,1,[Enable remote capture support]) + have_remote=yes + ;; + + bpf) + V_REMOTE_FILES="pcap-new.c pcap-remote.c sockutils.c" + V_HAVE_REMOTE="-DHAVE_REMOTE" + AC_DEFINE(HAVE_REMOTE,1,[Enable remote capture support]) + have_remote=yes + ;; + + *) + have_remote=no + ;; + + esac + + AC_MSG_RESULT(${have_remote}) + fi + +fi +dnl END HAVE_REMOTE + +AC_MSG_CHECKING(if --enable-ipv6 option is specified) +AC_ARG_ENABLE(ipv6, [ --enable-ipv6 build IPv6-capable version]) +if test "$enable_ipv6" = "yes"; then + AC_DEFINE(INET6,1,[IPv6]) +fi +AC_MSG_RESULT(${enable_ipv6-no}) + +AC_MSG_CHECKING(whether to build optimizer debugging code) +AC_ARG_ENABLE(optimizer-dbg, [ --enable-optimizer-dbg build optimizer debugging code]) +if test "$enable_optimizer_dbg" = "yes"; then + AC_DEFINE(BDEBUG,1,[Enable optimizer debugging]) +fi +AC_MSG_RESULT(${enable_optimizer_dbg-no}) + +AC_MSG_CHECKING(whether to build parser debugging code) +AC_ARG_ENABLE(yydebug, [ --enable-yydebug build parser debugging code]) +if test "$enable_yydebug" = "yes"; then + AC_DEFINE(YYDEBUG,1,[Enable parser debugging]) +fi +AC_MSG_RESULT(${enable_yydebug-no}) + +case "$V_PCAP" in + +dlpi) + AC_CHECK_HEADERS(sys/bufmod.h sys/dlpi_ext.h) + AC_MSG_CHECKING(for /dev/dlpi device) + if test -c /dev/dlpi ; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_DEV_DLPI, 1, [define if you have a /dev/dlpi]) + else + AC_MSG_RESULT(no) + dir="/dev/dlpi" + AC_MSG_CHECKING(for $dir directory) + if test -d $dir ; then + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(PCAP_DEV_PREFIX, "$dir", [/dev/dlpi directory]) + else + AC_MSG_RESULT(no) + fi + fi + ;; + +linux) + AC_MSG_CHECKING(Linux kernel version) + if test "$cross_compiling" = yes; then + AC_CACHE_VAL(ac_cv_linux_vers, + ac_cv_linux_vers=unknown) + else + AC_CACHE_VAL(ac_cv_linux_vers, + ac_cv_linux_vers=`uname -r 2>&1 | \ + sed -n -e '$s/.* //' -e '$s/\..*//p'`) + fi + AC_MSG_RESULT($ac_cv_linux_vers) + if test $ac_cv_linux_vers = unknown ; then + AC_MSG_ERROR(cannot determine linux version when cross-compiling) + fi + if test $ac_cv_linux_vers -lt 2 ; then + AC_MSG_ERROR(version 2 or higher required; see the INSTALL doc for more info) + fi + AC_LBL_TPACKET_STATS + ;; + +dag) + V_DEFS="$V_DEFS -DDAG_ONLY" + ;; + +septel) + V_DEFS="$V_DEFS -DSEPTEL_ONLY" + ;; + +null) + AC_MSG_WARN(cannot determine packet capture interface) + AC_MSG_WARN((see the INSTALL doc for more info)) + ;; + +esac + +AC_MSG_CHECKING(whether we have /proc/net/dev) +if test -r /proc/net/dev ; then + ac_cv_lbl_proc_net_dev=yes +else + ac_cv_lbl_proc_net_dev=no +fi +if test $ac_cv_lbl_proc_net_dev = yes; then + AC_DEFINE(HAVE_PROC_NET_DEV, 1, [define if you have a /proc/net/dev]) +fi +AC_MSG_RESULT($ac_cv_lbl_proc_net_dev) + +# Check for Endace DAG card support. +AC_ARG_WITH([dag], [ --with-dag[[=DIR]] include Endace DAG support ("yes", "no" or DIR; default="yes" on BSD and Linux if present)], +[ + if test "$withval" = no + then + # User doesn't want DAG support. + want_dag=no + elif test "$withval" = yes + then + # User wants DAG support but hasn't specified a directory. + want_dag=yes + else + # User wants DAG support and has specified a directory, so use the provided value. + want_dag=yes + dag_root=$withval + fi +],[ + # + # Use DAG API if present, otherwise don't + # + want_dag=ifpresent +]) + +AC_ARG_WITH([dag-includes], [ --with-dag-includes=DIR Endace DAG include directory], +[ + # User wants DAG support and has specified a header directory, so use the provided value. + want_dag=yes + dag_include_dir=$withval +],[]) + +AC_ARG_WITH([dag-libraries], [ --with-dag-libraries=DIR Endace DAG library directory], +[ + # User wants DAG support and has specified a library directory, so use the provided value. + want_dag=yes + dag_lib_dir=$withval +],[]) + +case "$V_PCAP" in +linux|bpf|dag) + # + # We support the DAG API if we're on Linux or BSD, or if we're + # building a DAG-only libpcap. + # + ;; +*) + # + # If the user explicitly requested DAG, tell them it's not + # supported. + # + # If they expressed no preference, don't include it. + # + if test $want_dag = yes; then + AC_MSG_ERROR([DAG support is only available with 'linux' 'bpf' and 'dag' packet capture types]) + elif test $want_dag = yes; then + want_dag=no + fi + ;; +esac + +ac_cv_lbl_dag_api=no +if test "$want_dag" != no; then + + AC_MSG_CHECKING([whether we have DAG API headers]) + + # If necessary, set default paths for DAG API headers and libraries. + if test -z "$dag_root"; then + dag_root=/usr/local + fi + + if test -z "$dag_include_dir"; then + dag_include_dir="$dag_root/include" + fi + + if test -z "$dag_lib_dir"; then + dag_lib_dir="$dag_root/lib" + fi + + if test -z "$dag_tools_dir"; then + dag_tools_dir="$dag_root/tools" + fi + + if test -r $dag_include_dir/dagapi.h; then + ac_cv_lbl_dag_api=yes + fi + AC_MSG_RESULT([$ac_cv_lbl_dag_api ($dag_include_dir)]) +fi + +if test $ac_cv_lbl_dag_api = yes; then + + AC_MSG_CHECKING([dagapi.o]) + dagapi_obj=no + if test -r $dag_tools_dir/dagapi.o; then + # 2.4.x. + dagapi_obj=$dag_tools_dir/dagapi.o + elif test -r $dag_lib_dir/dagapi.o; then + # 2.5.x. + dagapi_obj=$dag_lib_dir/dagapi.o + elif test -r $dag_lib_dir/libdag.a; then + # 2.5.x. + ar x $dag_lib_dir/libdag.a dagapi.o + if test -r ./dagapi.o; then + dagapi_obj=./dagapi.o + fi + fi + + if test $dagapi_obj = no; then + AC_MSG_RESULT([no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)]) + ac_cv_lbl_dag_api=no + else + AC_MSG_RESULT([yes ($dagapi_obj)]) + fi +fi + +if test $ac_cv_lbl_dag_api = yes; then + + AC_MSG_CHECKING([dagopts.o]) + dagopts_obj=no + if test -r $dag_tools_dir/dagopts.o; then + # 2.4.x. + dagopts_obj=$dag_tools_dir/dagopts.o + elif test -r $dag_lib_dir/dagopts.o; then + # 2.5.x. + dagopts_obj=$dag_lib_dir/dagopts.o + elif test -r $dag_lib_dir/libdag.a; then + # 2.5.x. + ar x $dag_lib_dir/libdag.a dagopts.o + if test -r ./dagopts.o; then + dagopts_obj=./dagopts.o + fi + fi + + if test $dagopts_obj = no; then + AC_MSG_RESULT([no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)]) + ac_cv_lbl_dag_api=no + else + AC_MSG_RESULT([yes ($dagopts_obj)]) + fi +fi + +if test $ac_cv_lbl_dag_api = yes; then + # Under 2.5.x only we need to add dagreg.o. + if test -r $dag_include_dir/dagreg.h; then + AC_MSG_CHECKING([dagreg.o]) + dagreg_obj=no + if test -r $dag_lib_dir/dagreg.o; then + # Object file is ready and waiting. + dagreg_obj=$dag_lib_dir/dagreg.o + elif test -r $dag_lib_dir/libdag.a; then + # Extract from libdag.a. + ar x $dag_lib_dir/libdag.a dagreg.o + if test -r ./dagreg.o; then + dagreg_obj=./dagreg.o + fi + fi + + if test $dagreg_obj = no; then + AC_MSG_RESULT([no (checked $dag_lib_dir $dag_lib_dir/libdag.a)]) + ac_cv_lbl_dag_api=no + else + AC_MSG_RESULT([yes ($dagreg_obj)]) + fi + fi +fi + +if test $ac_cv_lbl_dag_api = yes; then + V_INCLS="$V_INCLS -I$dag_include_dir" + V_LIBS="$V_LIBS $dagapi_obj $dagopts_obj $dagreg_obj" + if test $V_PCAP != dag ; then + SSRC="pcap-dag.c" + fi + + # See if we can find a general version string. + # Don't need to save and restore LIBS to prevent -ldag being + # included if there's a found-action (arg 3). + saved_ldflags=$LDFLAGS + LDFLAGS="-L$dag_lib_dir" + AC_CHECK_LIB([dag], [dag_attach_stream], [dag_version="2.5.x"], [dag_version="2.4.x"]) + AC_CHECK_LIB([dag],[dag_get_erf_types], [ + AC_DEFINE(HAVE_DAG_GET_ERF_TYPES, 1, [define if you have dag_get_erf_types()])] + ) + LDFLAGS=$saved_ldflags + + if test "$dag_version" = 2.5.x; then + AC_DEFINE(HAVE_DAG_STREAMS_API, 1, [define if you have streams capable DAG API]) + fi + + # See if we can find a specific version string. + AC_MSG_CHECKING([the DAG API version]) + if test -r "$dag_root/VERSION"; then + dag_version="`cat $dag_root/VERSION`" + fi + AC_MSG_RESULT([$dag_version]) + AC_DEFINE(HAVE_DAG_API, 1, [define if you have the DAG API]) +fi + +if test $ac_cv_lbl_dag_api = no; then + if test "$want_dag" = yes; then + # User wanted DAG support but we couldn't find it. + AC_MSG_ERROR([DAG API requested, but not found at $dag_root: use --without-dag]) + fi + + if test "$V_PCAP" = dag; then + # User requested "dag" capture type but the DAG API wasn't + # found. + AC_MSG_ERROR([Specifying the capture type as "dag" requires the DAG API to be present; use the --with-dag options to specify the location. (Try "./configure --help" for more information.)]) + fi +fi + +AC_ARG_WITH(septel, [ --with-septel[[=DIR]] include Septel support (located in directory DIR, if supplied). [default=yes, on Linux, if present]], +[ + if test "$withval" = no + then + want_septel=no + elif test "$withval" = yes + then + want_septel=yes + septel_root= + else + want_septel=yes + septel_root=$withval + fi +],[ + # + # Use Septel API if present, otherwise don't + # + want_septel=ifpresent + septel_root=./../septel +]) +ac_cv_lbl_septel_api=no +case "$V_PCAP" in +linux|septel) + # + # We support the Septel API if we're on Linux, or if we're building + # a Septel-only libpcap. + # + ;; +*) + # + # If the user explicitly requested Septel, tell them it's not + # supported. + # + # If they expressed no preference, don't include it. + # + if test $want_septel = yes; then + AC_MSG_ERROR(Septel support only available with 'linux' and 'septel' packet capture types) + elif test $want_septel = yes; then + want_septel=no + fi + ;; +esac + +if test "$with_septel" != no; then + AC_MSG_CHECKING(whether we have Septel API) + + if test -z "$septel_root"; then + septel_root=$srcdir/../septel + + fi + + septel_tools_dir="$septel_root" + septel_include_dir="$septel_root/INC" + DEF="-DHAVE_SEPTEL_API" + + ac_cv_lbl_septel_api=no + if test -r "$septel_include_dir/msg.h"; then + V_INCLS="$V_INCLS -I$septel_include_dir" + V_DEFS="$V_DEFS $DEF" + V_LIBS="$V_LIBS $septel_tools_dir/asciibin.o $septel_tools_dir/bit2byte.o $septel_tools_dir/confirm.o $septel_tools_dir/fmtmsg.o $septel_tools_dir/gct_unix.o $septel_tools_dir/hqueue.o $septel_tools_dir/ident.o $septel_tools_dir/mem.o $septel_tools_dir/pack.o $septel_tools_dir/parse.o $septel_tools_dir/pool.o $septel_tools_dir/sdlsig.o $septel_tools_dir/strtonum.o $septel_tools_dir/timer.o $septel_tools_dir/trace.o " + + if test "$V_PCAP" != septel ; then + SSRC="pcap-septel.c" + + fi + ac_cv_lbl_septel_api=yes + fi + + AC_MSG_RESULT($ac_cv_lbl_septel_api) + if test $ac_cv_lbl_septel_api = no; then + if test "$want_septel" = yes; then + AC_MSG_ERROR(Septel API not found under directory $septel_root; use --without-septel) + fi + else + AC_DEFINE(HAVE_SEPTEL_API, 1, [define if you have a Septel API]) + fi +fi + +if test "$V_PCAP" = septel -a "$ac_cv_lbl_septel_api" = no; then + AC_MSG_ERROR(Specifying the capture type as 'septel' requires the Septel API to be present; use --with-septel=DIR) +fi + + +AC_LBL_LEX_AND_YACC(V_LEX, V_YACC, pcap_) +if test "$V_LEX" = lex ; then +# Some versions of lex can't handle the definitions section of scanner.l . +# Try lexing it and complain if it can't deal. + AC_CACHE_CHECK([for capable lex], tcpdump_cv_capable_lex, + if lex -t scanner.l > /dev/null 2>&1; then + tcpdump_cv_capable_lex=yes + else + tcpdump_cv_capable_lex=insufficient + fi) + if test $tcpdump_cv_capable_lex = insufficient ; then + AC_MSG_ERROR([Your operating system's lex is insufficient to compile + libpcap. flex is a lex replacement that has many advantages, including + being able to compile libpcap. For more information, see + http://www.gnu.org/software/flex/flex.html .]) + fi +fi + +DYEXT="so" +case "$host_os" in + +aix*) + dnl Workaround to enable certain features + AC_DEFINE(_SUN,1,[define on AIX to get certain functions]) + ;; + +hpux9*) + AC_DEFINE(HAVE_HPUX9,1,[on HP-UX 9.x]) + ;; + +hpux10.0*) + ;; + +hpux10.1*) + ;; + +hpux*) + dnl HPUX 10.20 and above is similar to HPUX 9, but + dnl not the same.... + dnl + dnl XXX - DYEXT should be set to "sl" if this is building + dnl for 32-bit PA-RISC, but should be left as "so" for + dnl 64-bit PA-RISC or, I suspect, IA-64. + AC_DEFINE(HAVE_HPUX10_20_OR_LATER,1,[on HP-UX 10.20 or later]) + ;; + +sinix*) + AC_MSG_CHECKING(if SINIX compiler defines sinix) + AC_CACHE_VAL(ac_cv_cc_sinix_defined, + AC_TRY_COMPILE( + [], + [int i = sinix;], + ac_cv_cc_sinix_defined=yes, + ac_cv_cc_sinix_defined=no)) + AC_MSG_RESULT($ac_cv_cc_sinix_defined) + if test $ac_cv_cc_sinix_defined = no ; then + AC_DEFINE(sinix,1,[on sinix]) + fi + ;; + +solaris*) + AC_DEFINE(HAVE_SOLARIS,1,[On solaris]) + ;; + +darwin*) + DYEXT="dylib" + V_CCOPT="$V_CCOPT -fno-common" + ;; +esac + +AC_PROG_RANLIB + +AC_LBL_DEVEL(V_CCOPT) + +AC_LBL_SOCKADDR_SA_LEN + +AC_LBL_SOCKADDR_STORAGE + +AC_LBL_HP_PPA_INFO_T_DL_MODULE_ID_1 + +AC_LBL_UNALIGNED_ACCESS + +# +# Makefile.in includes rules to generate version.h, so we assume +# that it will be generated if autoconf is used. +# +AC_DEFINE(HAVE_VERSION_H, 1, [define if version.h is generated in the build procedure]) + +rm -f net +ln -s ${srcdir}/bpf/net net + +AC_SUBST(V_CCOPT) +AC_SUBST(V_DEFS) +AC_SUBST(V_INCLS) +AC_SUBST(V_LIBS) +AC_SUBST(V_LEX) +AC_SUBST(V_PCAP) +AC_SUBST(V_FINDALLDEVS) +# HAVE_REMOTE +AC_SUBST(V_HAVE_REMOTE) +AC_SUBST(V_REMOTE_FILES) +# END HAVE_REMOTE +AC_SUBST(V_RANLIB) +AC_SUBST(V_YACC) +AC_SUBST(SSRC) +AC_SUBST(DYEXT) + +AC_PROG_INSTALL + +AC_CONFIG_HEADER(config.h) + +AC_OUTPUT(Makefile) + +if test -f .devel ; then + make depend +fi +exit 0 diff --git a/winpcap/wpcap/libpcap/doc/pcap.html b/winpcap/wpcap/libpcap/doc/pcap.html new file mode 100644 index 0000000..94e3514 --- /dev/null +++ b/winpcap/wpcap/libpcap/doc/pcap.html @@ -0,0 +1,997 @@ + +PCAP New Generation Dump File Format + + + + + + +
 TOC 
+
+ + + + +
Network Working GroupL. Degioanni
Internet-DraftF. Risso
Expires: August 30, 2004Politecnico di Torino
 March 2004
+


PCAP New Generation Dump File Format
+

pcap
+ +

Status of this Memo

+

+This document is an Internet-Draft and is +in full conformance with all provisions of Section 10 of RFC2026.

+

+Internet-Drafts are working documents of the Internet Engineering +Task Force (IETF), its areas, and its working groups. +Note that other groups may also distribute working documents as +Internet-Drafts.

+

+Internet-Drafts are draft documents valid for a maximum of six months +and may be updated, replaced, or obsoleted by other documents at any time. +It is inappropriate to use Internet-Drafts as reference material or to cite +them other than as "work in progress."

+

+The list of current Internet-Drafts can be accessed at +http://www.ietf.org/ietf/1id-abstracts.txt.

+

+The list of Internet-Draft Shadow Directories can be accessed at +http://www.ietf.org/shadow.html.

+

+This Internet-Draft will expire on August 30, 2004.

+ +

Copyright Notice

+

+Copyright (C) The Internet Society (2004). All Rights Reserved.

+ +

Abstract

+ +

This document describes a format to dump captured packets on a file. This format is extensible and it is currently proposed for implementation in the libpcap/WinPcap packet capture library. +



+

Table of Contents

+

+1.  +Objectives
+2.  +General File Structure
+2.1  +General Block Structure
+2.2  +Block Types
+2.3  +Block Hierarchy and Precedence
+2.4  +Data format
+3.  +Block Definition
+3.1  +Section Header Block (mandatory)
+3.2  +Interface Description Block (mandatory)
+3.3  +Packet Block (optional)
+3.4  +Simple Packet Block (optional)
+3.5  +Name Resolution Block (optional)
+3.6  +Interface Statistics Block (optional)
+4.  +Options
+5.  +Experimental Blocks (deserved to a further investigation)
+5.1  +Other Packet Blocks (experimental)
+5.2  +Compression Block (experimental)
+5.3  +Encryption Block (experimental)
+5.4  +Fixed Length Block (experimental)
+5.5  +Directory Block (experimental)
+5.6  +Traffic Statistics and Monitoring Blocks (experimental)
+5.7  +Event/Security Block (experimental)
+6.  +Conclusions
+7.  +Most important open issues
+§  +Intellectual Property and Copyright Statements
+

+
+ +

+
 TOC 
+

1. Objectives

+ +

The problem of exchanging packet traces becomes more and more critical every day; unfortunately, no standard solutions exist for this task right now. One of the most accepted packet interchange formats is the one defined by libpcap, which is rather old and does not fit for some of the nowadays applications especially in terms of extensibility. +

+

This document proposes a new format for dumping packet traces. The following goals are being pursued: +

+
    +
  • Extensibility: aside of some common functionalities, third parties should be able to enrich the information embedded in the file with proprietary extensions, which will be ignored by tools that are not able to understand them. +
  • +
  • Portability: a capture trace must contain all the information needed to read data independently from network, hardware and operating system of the machine that made the capture. +
  • +
  • Merge/Append data: it should be possible to add data at the end of a given file, and the resulting file must still be readable. +
  • +
+

+
 TOC 
+

2. General File Structure

+ +

2.1 General Block Structure

+ +

A capture file is organized in blocks, that are appended one to another to form the file. All the blocks share a common format, which is shown in Figure 1. +



+ +
+    0                   1                   2                   3   
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                          Block Type                           |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                      Block Total Length                       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   /                          Block Body                           /
+   /          /* variable length, aligned to 32 bits */            /
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                      Block Total Length                       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
 Basic block structure. 

+ +

The fields have the following meaning: +

+
    +
  • Block Type (32 bits): unique value that identifies the block. Values whose Most Significant Bit (MSB) is equal to 1 are reserved for local use. They allow to save private data to the file and to extend the file format. +
  • +
  • Block Total Length: total size of this block, in bytes. For instance, a block that does not have a body has a length of 12 bytes. +
  • +
  • Block Body: content of the block. +
  • +
  • Block Total Length: total size of this block, in bytes. This field is duplicated for permitting backward file navigation. +
  • +
+

This structure, shared among all blocks, makes easy to process a file and to skip unneeded or unknown blocks. Blocks can be nested one inside the others (NOTE: needed?). Some of the blocks are mandatory, i.e. a dump file is not valid if they are not present, other are optional. +

+

The structure of the blocks allows to define other blocks if needed. A parser that does non understand them can simply ignore their content. +

+

2.2 Block Types

+ +

The currently defined blocks are the following: +

+
    +
  1. Section Header Block: it defines the most important characteristics of the capture file. +
  2. +
  3. Interface Description Block: it defines the most important characteristics of the interface(s) used for capturing traffic. +
  4. +
  5. Packet Block: it contains a single captured packet, or a portion of it. +
  6. +
  7. Simple Packet Block: it contains a single captured packet, or a portion of it, with only a minimal set of information about it. +
  8. +
  9. Name Resolution Block: it defines the mapping from numeric addresses present in the packet dump and the canonical name counterpart. +
  10. +
  11. Capture Statistics Block: it defines how to store some statistical data (e.g. packet dropped, etc) which can be useful to undestand the conditions in which the capture has been made. +
  12. +
  13. Compression Marker Block: TODO +
  14. +
  15. Encryption Marker Block: TODO +
  16. +
  17. Fixed Length Marker Block: TODO +
  18. +
+

The following blocks instead are considered interesting but the authors believe that they deserve more in-depth discussion before being defined: +

+
    +
  1. Further Packet Blocks +
  2. +
  3. Directory Block +
  4. +
  5. Traffic Statistics and Monitoring Blocks +
  6. +
  7. Alert and Security Blocks +
  8. +
+

TODO Currently standardized Block Type codes are specified in Appendix 1. +

+

2.3 Block Hierarchy and Precedence

+ +

The file must begin with a Section Header Block. However, more than one Section Header Block can be present on the dump, each one covering the data following it till the next one (or the end of file). A Section includes the data delimited by two Section Header Blocks (or by a Section Header Block and the end of the file), including the first Section Header Block. +

+

In case an application cannot read a Section because of different version number, it must skip everything until the next Section Header Block. Note that, in order to properly skip the blocks until the next section, all blocks must have the fields Type and Length at the beginning. This is a mandatory requirement that must be maintained in future versions of the block format. +

+

Figure 2 shows two valid files: the first has a typical configuration, with a single Section Header that covers the whole file. The second one contains three headers, and is normally the result of file concatenation. An application that understands only version 1.0 of the file format skips the intermediate section and restart processing the packets after the third Section Header. +



+ +
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | SHB v1.0  |                      Data                         |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   Typical configuration with a single Section Header Block 
+
+
+   |--   1st Section   --|--   2nd Section   --|--  3rd Section  --|
+   |                                                               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | SHB v1.0  |  Data   | SHB V1.1  |  Data   | SHB V1.0  |  Data |  
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   Configuration with three different Section Header Blocks
+
+
 File structure example: the Section Header Block. 

+ +

NOTE: TO BE COMPLETED with some examples of other blocks +

+

2.4 Data format

+ +

Data contained in each section will always be saved according to the characteristics (little endian / big endian) of the dumping machine. This refers to all fields that are saved as numbers and that span over two or more bytes. +

+

The approach of having each section saved in the native format of the generating host is more efficient because it avoids translation of data when reading / writing on the host itself, which is the most common case when generating/processing capture dumps. +

+

TODO Probably we have to specify something more here. Is what we're saying enough to avoid any kind of ambiguity?. +

+

+
 TOC 
+

3. Block Definition

+ +

This section details the format of the body of the blocks currently defined. +

+

3.1 Section Header Block (mandatory)

+ +

The Section Header Block is mandatory. It identifies the beginning of a section of the capture dump file. Its format is shown in Figure 3. +



+ +
+    0                   1                   2                   3   
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                            Magic                              |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |              Major            |             Minor             |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   /                                                               / 
+   /                      Options (variable)                       / 
+   /                                                               / 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
 Section Header Block format. 

+ +

The meaning of the fields is: +

+
    +
  • Magic: magic number, whose value is the hexadecimal number 0x1A2B3C4D. This number can be used to distinguish section that have been saved on little-endian machines from the one saved on big-endian machines. +
  • +
  • Major: number of the current mayor version of the format. Current value is 1. +
  • +
  • Minor: number of the current minor version of the format. Current value is 0. +
  • +
  • Options: optionally, a list of options (formatted according to the rules defined in Section 4) can be present. +
  • +
+

Aside form the options defined in Section 4, the following options are valid within this block: +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameCodeLengthDescription
Hardware2variableAn ascii string containing the description of the hardware used to create this section.
Operating System3variableAn ascii string containing the name of the operating system used to create this section.
User Application3variableAn ascii string containing the name of the application used to create this section.
+ +

The Section Header Block does not contain data but it rather identifies a list of blocks (interfaces, packets) that are logically correlated. This block does not contain any reference to the size of the section it is currently delimiting, therefore the reader cannot skip a whole section at once. In case a section must be skipped, the user has to repeatedly skip all the blocks contained within it; this makes the parsing of the file slower but it permits to append several capture dumps at the same file. +

+

3.2 Interface Description Block (mandatory)

+ +

The Interface Description Block is mandatory. This block is needed to specify the characteristics of the network interface on which the capture has been made. In order to properly associate the captured data to the corresponding interface, the Interface Description Block must be defined before any other block that uses it; therefore, this block is usually placed immediately after the Section Header Block. +

+

An Interface Description Block is valid only inside the section which it belongs to. The structure of a Interface Description Block is shown in Figure 4. +



+ +
+    0                   1                   2                   3   
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |          Interface ID         |           LinkType            |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                            SnapLen                            |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   /                                                               / 
+   /                      Options (variable)                       / 
+   /                                                               / 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ 
+
 Interface Description Block format. 

+ +

The meaning of the fields is: +

+
    +
  • Interface ID: a progressive number that identifies uniquely any interface inside current section. Two Interface Description Blocks can have the same Interface ID only if they are in different sections of the file. The Interface ID is referenced by the packet blocks. +
  • +
  • LinkType: a value that defines the link layer type of this interface. +
  • +
  • SnapLen: maximum number of bytes dumped from each packet. The portion of each packet that exceeds this value will not be stored in the file. +
  • +
  • Options: optionally, a list of options (formatted according to the rules defined in Section 4) can be present. +
  • +
+

In addition to the options defined in Section 4, the following options are valid within this block: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameCodeLengthDescription
if_name2VariableName of the device used to capture data.
if_IPv4addr38Interface network address and netmask.
if_IPv6addr417Interface network address and prefix length (stored in the last byte).
if_MACaddr56Interface Hardware MAC address (48 bits).
if_EUIaddr68Interface Hardware EUI address (64 bits), if available.
if_speed78Interface speed (in bps).
if_tsaccur81Precision of timestamps. If the Most Significant Bit is equal to zero, the remaining bits indicates the accuracy as as a negative power of 10 (e.g. 6 means microsecond accuracy). If the Most Significant Bit is equal to zero, the remaining bits indicates the accuracy as as negative power of 2 (e.g. 10 means 1/1024 of second). If this option is not present, a precision of 10^-6 is assumed.
if_tzone94Time zone for GMT support (TODO: specify better).
if_flags104Interface flags. (TODO: specify better. Possible flags: promiscuous, inbound/outbound, traffic filtered during capture).
if_filter11variableThe filter (e.g. "capture only TCP traffic") used to capture traffic. The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string, or BPF bytecode, and more). More details about this format will be presented in Appendix XXX (TODO).
if_opersystem12variableAn ascii string containing the name of the operating system of the machine that hosts this interface. This can be different from the same information that can be contained by the Section Header Block (Section 3.1) because the capture can have been done on a remote machine.
+ +

3.3 Packet Block (optional)

+ +

A Packet Block is the standard container for storing the packets coming from the network. The Packet Block is optional because packets can be stored either by means of this block or the Simple Packet Block, which can be used to speed up dump generation. The format of a packet block is shown in Figure 5. +



+ +
+    0                   1                   2                   3   
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |         Interface ID          |          Drops Count          |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                        Timestamp (High)                       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                        Timestamp (Low)                        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                         Captured Len                          |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                          Packet Len                           |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                                               |
+   |                          Packet Data                          |
+   |                                                               |
+   |              /* variable length, byte-aligned */              |
+   |                                                               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   /                                                               / 
+   /                      Options (variable)                       / 
+   /                                                               / 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
 Packet Block format. 

+ +

The Packet Block has the following fields: +

+
    +
  • Interface ID: Specifies the interface this packet comes from, and corresponds to the ID of one of the Interface Description Blocks present in this section of the file (see Figure 4). +
  • +
  • Drops Count: a local drop counter. It specified the number of packets lost (by the interface and the operating system) between this packet and the preceding one. The value xFFFF (in hexadecimal) is reserved for those systems in which this information is not available. +
  • +
  • Timestamp (High): the most significative part of the timestamp. in standard Unix format, i.e. from 1/1/1970. +
  • +
  • Timestamp (Low): the less significative part of the timestamp. The way to interpret this field is specified by the 'ts_accur' option (see Figure 4) of the Interface Description block referenced by this packet. If the Interface Description block does not contain a 'ts_accur' option, then this field is expressed in microseconds. +
  • +
  • Captured Len: number of bytes captured from the packet (i.e. the length of the Packet Data field). It will be the minimum value among the actual Packet Length and the snapshot length (defined in Figure 4). +
  • +
  • Packet Len: actual length of the packet when it was transmitted on the network. Can be different from Captured Len if the user wants only a snapshot of the packet. +
  • +
  • Packet Data: the data coming from the network, including link-layer headers. The length of this field is Captured Len. The format of the link-layer headers depends on the LinkType field specified in the Interface Description Block (see Section 3.2) and it is specified in Appendix XXX (TODO). +
  • +
  • Options: optionally, a list of options (formatted according to the rules defined in Section 4) can be present. +
  • +
+

+

+

3.4 Simple Packet Block (optional)

+ +

The Simple Packet Block is a lightweight container for storing the packets coming from the network. Its presence is optional. +

+

A Simple Packet Block is similar to a Packet Block (see Section 3.3), but it is smaller, simpler to process and contains only a minimal set of information. This block is preferred to the standard Packet Block when performance or space occupation are critical factors, such as in sustained traffic dump applications. A capture file can contain both Packet Blocks and Simple Packet Blocks: for example, a capture tool could switch from Packet Blocks to Simple Packet Blocks when the hardware resources become critical. +

+

The Simple Packet Block does not contain the Interface ID field. Therefore, it must be assumed that all the Simple Packet Blocks have been captured on the interface previously specified in the Interface Description Block. +

+

Figure 6 shows the format of the Simple Packet Block. +



+ +
+    0                   1                   2                   3   
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                          Packet Len                           |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                                               |
+   |                          Packet Data                          |
+   |                                                               |
+   |              /* variable length, byte-aligned */              |
+   |                                                               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ 
+
 Simple Packet Block format. 

+ +

The Packet Block has the following fields: +

+
    +
  • Packet Len: actual length of the packet when it was transmitted on the network. Can be different from captured len if the packet has been truncated. +
  • +
  • Packet data: the data coming from the network, including link-layers headers. The length of this field can be derived from the field Block Total Length, present in the Block Header. +
  • +
+

The Simple Packet Block does not contain the timestamp because this is one of the most costly operations on PCs. Additionally, there are applications that do not require it; e.g. an Intrusion Detection System is interested in packets, not in their timestamp. +

+

The Simple Packet Block is very efficient in term of disk space: a snapshot of length 100 bytes requires only 16 bytes of overhead, which corresponds to an efficiency of more than 86%. +

+

3.5 Name Resolution Block (optional)

+ +

The Name Resolution Block is used to support the correlation of numeric addresses (present in the captured packets) and their corresponding canonical names and it is optional. Having the literal names saved in the file, this prevents the need of a name resolution in a delayed time, when the association between names and addresses can be different from the one in use at capture time. Moreover, The Name Resolution Block avoids the need of issuing a lot of DNS requests every time the trace capture is opened, and allows to have name resolution also when reading the capture with a machine not connected to the network. +

+

The format of the Name Resolution Block is shown in Figure 7. +



+ +
+    0                   1                   2                   3   
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |      Record Type              |         Record Length         | 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                       Record Value                            |
+   |              /* variable length, byte-aligned */              |
+   |               + + + + + + + + + + + + + + + + + + + + + + + + +
+   |               |               |               |               |
+   +-+-+-+-+-+-+-+-+ + + + + + + + + + + + + + + + + + + + + + + + +
+             . . . other records . . .
+   |  Record Type == end_of_recs   |  Record Length == 00          |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   /                                                               / 
+   /                      Options (variable)                       / 
+   /                                                               / 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ 
+
 Name Resolution Block format. 

+ +

A Name Resolution Block is a zero-terminated list of records (in the TLV format), each of which contains an association between a network address and a name. There are three possible types of records: +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameCodeLengthDescription
end_of_recs00End of records
ip4_rec1VariableSpecifies an IPv4 address (contained in the first 4 bytes), followed by one or more zero-terminated strings containing the DNS entries for that address.
ip6_rec1VariableSpecifies an IPv6 address (contained in the first 16 bytes), followed by one or more zero-terminated strings containing the DNS entries for that address.
+ +

After the list or Name Resolution Records, optionally, a list of options (formatted according to the rules defined in Section 4) can be present. +

+

A Name Resolution Block is normally placed at the beginning of the file, but no assumptions can be taken about its position. Name Resolution Blocks can be added in a second time by tools that process the file, like network analyzers. +

+

In addiction to the options defined in Section 4, the following options are valid within this block: +

+ + + + + + + + + + + + +
NameCodeLengthDescription
ns_dnsname2VariableAn ascii string containing the name of the machine (DNS server) used to perform the name resolution.
+ +

3.6 Interface Statistics Block (optional)

+ +

The Interface Statistics Block contains the capture statistics for a given interface and it is optional. The statistics are referred to the interface defined in the current Section identified by the Interface ID field. +

+

The format of the Interface Statistics Block is shown in Figure 8. +



+ +
+    0                   1                   2                   3   
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                         IfRecv                                |
+   |                          (high + low)                         |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                         IfDrop                                |
+   |                          (high + low)                         |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                         FilterAccept                          |
+   |                          (high + low)                         |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                         OSDrop                                |
+   |                          (high + low)                         |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                         UsrDelivered                          |
+   |                          (high + low)                         |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |          Interface ID         |           Reserved            |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   /                                                               / 
+   /                      Options (variable)                       / 
+   /                                                               / 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ 
+
 Interface Statistics Block format. 

+ +

The fields have the following meaning: +

+
    +
  • IfRecv: number of packets received from the interface during the capture. This number is reported as a 64 bits value, in which the most significat bits are located in the first four bytes of the field. +
  • +
  • IfDrop: number of packets dropped by the interface during the capture due to lack of resources. +
  • +
  • FilterAccept: number of packets accepeted by filter during current capture. +
  • +
  • OSDrop: number of packets dropped by the operating system during the capture. +
  • +
  • UsrDelivered: number of packets delivered to the user. UsrDelivered can be different from the value 'FilterAccept - OSDropped' because some packets could still lay in the OS buffers when the capture ended. +
  • +
  • Interface ID: reference to an Interface Description Block. +
  • +
  • Reserved: Reserved to future use. +
  • +
  • Options: optionally, a list of options (formatted according to the rules defined in Section 4) can be present. +
  • +
+

In addiction to the options defined in Section 4, the following options are valid within this block: +

+ + + + + + + + + + + + + + + + + + +
NameCodeLengthDescription
isb_starttime28Time in which the capture started; time will be stored in two blocks of four bytes each, containing the timestamp in seconds and nanoseconds.
isb_endtime38Time in which the capture started; time will be stored in two blocks of four bytes each, containing the timestamp in seconds and nanoseconds.
+ +

+
 TOC 
+

4. Options

+ +

Almost all blocks have the possibility to embed optional fields. Optional fields can be used to insert some information that may be useful when reading data, but that it is not really needed for packet processing. Therefore, each tool can be either read the content of the optional fields (if any), or skip them at once. +

+

Skipping all the optional fields at once is straightforward because most of the blocks have a fixed length, therefore the field Block Length (present in the General Block Structure, see Section 2.1) can be used to skip everything till the next block. +

+

Options are a list of Type - Length - Value fields, each one containing a single value: +

+
    +
  • Option Type (2 bytes): it contains the code that specifies the type of the current TLV record. Option types whose Most Significant Bit is equal to one are reserved for local use; therefore, there is no guarantee that the code used is unique among all capture files (generated by other applications). In case of vendor-specific extensions that have to be identified uniquely, vendors must request an Option Code whose MSB is equal to zero. +
  • +
  • Option Length (2 bytes): it contains the length of the following 'Option Value' field. +
  • +
  • Option Value (variable length): it contains the value of the given option. The length of this field as been specified by the Option Length field. +
  • +
+

Options may be repeated several times (e.g. an interface that has several IP addresses associated to it). The option list is terminated by a special code which is the 'End of Option'. +

+

The format of the optional fields is shown in Figure 9. +



+ +
+    0                   1                   2                   3   
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |      Option Code              |         Option Length         | 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                       Option Value                            |
+   |              /* variable length, byte-aligned */              |
+   |               + + + + + + + + + + + + + + + + + + + + + + + + +
+   |               /               /               /               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   /                                                               /
+   /                 . . . other options . . .                     /
+   /                                                               /
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |   Option Code == opt_endofopt  |  Option Length == 0          |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ 
+
 Options format. 

+ +

The following codes can always be present in any optional field: +

+ + + + + + + + + + + + + + + + + + +
NameCodeLengthDescription
opt_endofopt00End of options: it is used to delimit the end of the optional fields. This block cannot be repeated within a given list of options.
opt_comment1variableComment: it is an ascii string containing a comment that is associated to the current block.
+ +

+
 TOC 
+

5. Experimental Blocks (deserved to a further investigation)

+ +

5.1 Other Packet Blocks (experimental)

+ +

Can some other packet blocks (besides the two described in the previous paragraphs) be useful? +

+

5.2 Compression Block (experimental)

+ +

The Compression Block is optional. A file can contain an arbitrary number of these blocks. A Compression Block, as the name says, is used to store compressed data. Its format is shown in Figure 10. +



+ +
+    0                   1                   2                   3   
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |  Compr. Type  |                                               |
+   +-+-+-+-+-+-+-+-+                                               |
+   |                                                               |
+   |                       Compressed Data                         |
+   |                                                               |
+   |              /* variable length, byte-aligned */              |
+   |                                                               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ 
+
 Compression Block format. 

+ +

The fields have the following meaning: +

+
    +
  • Compression Type: specifies the compression algorithm. Possible values for this field are 0 (uncompressed), 1 (Lempel Ziv), 2 (Gzip), other?? Probably some kind of dumb and fast compression algorithm could be effective with some types of traffic (for example web), but which? +
  • +
  • Compressed Data: data of this block. Once decompressed, it is made of other blocks. +
  • +
+

5.3 Encryption Block (experimental)

+ +

The Encryption Block is optional. A file can contain an arbitrary number of these blocks. An Encryption Block is used to sotre encrypted data. Its format is shown in Figure 11. +



+ +
+    0                   1                   2                   3   
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |   Encr. Type  |                                               |
+   +-+-+-+-+-+-+-+-+                                               |
+   |                                                               |
+   |                       Compressed Data                         |
+   |                                                               |
+   |              /* variable length, byte-aligned */              |
+   |                                                               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ 
+
 Encryption Block format. 

+ +

The fields have the following meaning: +

+
    +
  • Compression Type: specifies the encryption algorithm. Possible values for this field are ??? NOTE: this block should probably contain other fields, depending on the encryption algorithm. To be define precisely. +
  • +
  • Encrypted Data: data of this block. Once decripted, it consists of other blocks. +
  • +
+

5.4 Fixed Length Block (experimental)

+ +

The Fixed Length Block is optional. A file can contain an arbitrary number of these blocks. A Fixed Length Block can be used to optimize the access to the file. Its format is shown in Figure 12. +A Fixed Length Block stores records with constant size. It contains a set of Blocks (normally Packet Blocks or Simple Packet Blocks), of wihich it specifies the size. Knowing this size a priori helps to scan the file and to load some portions of it without truncating a block, and is particularly useful with cell-based networks like ATM. +



+ +
+    0                   1                   2                   3   
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |          Cell Size            |                               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
+   |                                                               |
+   |                        Fixed Size Data                        |
+   |                                                               |
+   |              /* variable length, byte-aligned */              |
+   |                                                               |
+   |                                                               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ 
+
 Fixed Length Block format. 

+ +

The fields have the following meaning: +

+
    +
  • Cell size: the size of the blocks contained in the data field. +
  • +
  • Fixed Size Data: data of this block. +
  • +
+

5.5 Directory Block (experimental)

+ +

If present, this block contains the following information: +

+
    +
  • number of indexed packets (N) +
  • +
  • table with position and length of any indexed packet (N entries) +
  • +
+

A directory block must be followed by at least N packets, otherwise it must be considered invalid. It can be used to efficiently load portions of the file to memory and to support operations on memory mapped files. This block can be added by tools like network analyzers as a consequence of file processing. +

+

5.6 Traffic Statistics and Monitoring Blocks (experimental)

+ +

One or more blocks could be defined to contain network statistics or traffic monitoring information. They could be use to store data collected from RMON or Netflow probes, or from other network monitoring tools. +

+

5.7 Event/Security Block (experimental)

+ +

This block could be used to store events. Events could contain generic information (for example network load over 50%, server down...) or security alerts. An event could be: +

+
    +
  • skipped, if the application doesn't know how to do with it +
  • +
  • processed independently by the packets. In other words, the applications skips the packets and processes only the alerts +
  • +
  • processed in relation to packets: for example, a security tool could load only the packets of the file that are near a security alert; a monitorg tool could skip the packets captured while the server was down. +
  • +
+

+
 TOC 
+

6. Conclusions

+ +

The file format proposed in this document should be very versatile and satisfy a wide range of applications. +In the simplest case, it can contain a raw dump of the network data, made of a series of Simple Packet Blocks. +In the most complex case, it can be used as a repository for heterogeneous information. +In every case, the file remains easy to parse and an application can always skip the data it is not interested in; at the same time, different applications can share the file, and each of them can benfit of the information produced by the others. +Two or more files can be concatenated obtaining another valid file. +

+

+
 TOC 
+

7. Most important open issues

+ +
    +
  • Data, in the file, must be byte or word aligned? Currently, the structure of this document is not consistent with respect to this point. +
  • +


+
 TOC 
+

Intellectual Property Statement

+ + +

Full Copyright Statement

+ + + + +

Acknowledgment

+ + diff --git a/winpcap/wpcap/libpcap/doc/pcap.txt b/winpcap/wpcap/libpcap/doc/pcap.txt new file mode 100644 index 0000000..cfa6645 --- /dev/null +++ b/winpcap/wpcap/libpcap/doc/pcap.txt @@ -0,0 +1,1680 @@ + + +Network Working Group L. Degioanni +Internet-Draft F. Risso +Expires: August 30, 2004 Politecnico di Torino + March 2004 + + + PCAP New Generation Dump File Format + pcap + +Status of this Memo + + This document is an Internet-Draft and is in full conformance with + all provisions of Section 10 of RFC2026. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF), its areas, and its working groups. Note that other + groups may also distribute working documents as Internet-Drafts. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + The list of current Internet-Drafts can be accessed at http:// + www.ietf.org/ietf/1id-abstracts.txt. + + The list of Internet-Draft Shadow Directories can be accessed at + http://www.ietf.org/shadow.html. + + This Internet-Draft will expire on August 30, 2004. + +Copyright Notice + + Copyright (C) The Internet Society (2004). All Rights Reserved. + +Abstract + + This document describes a format to dump captured packets on a file. + This format is extensible and it is currently proposed for + implementation in the libpcap/WinPcap packet capture library. + + + + + + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 1] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + +Table of Contents + + 1. Objectives . . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 2. General File Structure . . . . . . . . . . . . . . . . . . . . 4 + 2.1 General Block Structure . . . . . . . . . . . . . . . . . . . 4 + 2.2 Block Types . . . . . . . . . . . . . . . . . . . . . . . . . 5 + 2.3 Block Hierarchy and Precedence . . . . . . . . . . . . . . . . 5 + 2.4 Data format . . . . . . . . . . . . . . . . . . . . . . . . . 6 + 3. Block Definition . . . . . . . . . . . . . . . . . . . . . . . 8 + 3.1 Section Header Block (mandatory) . . . . . . . . . . . . . . . 8 + 3.2 Interface Description Block (mandatory) . . . . . . . . . . . 9 + 3.3 Packet Block (optional) . . . . . . . . . . . . . . . . . . . 13 + 3.4 Simple Packet Block (optional) . . . . . . . . . . . . . . . . 15 + 3.5 Name Resolution Block (optional) . . . . . . . . . . . . . . . 16 + 3.6 Interface Statistics Block (optional) . . . . . . . . . . . . 18 + 4. Options . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 + 5. Experimental Blocks (deserved to a further investigation) . . 23 + 5.1 Other Packet Blocks (experimental) . . . . . . . . . . . . . . 23 + 5.2 Compression Block (experimental) . . . . . . . . . . . . . . . 23 + 5.3 Encryption Block (experimental) . . . . . . . . . . . . . . . 23 + 5.4 Fixed Length Block (experimental) . . . . . . . . . . . . . . 24 + 5.5 Directory Block (experimental) . . . . . . . . . . . . . . . . 25 + 5.6 Traffic Statistics and Monitoring Blocks (experimental) . . . 25 + 5.7 Event/Security Block (experimental) . . . . . . . . . . . . . 25 + 6. Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . 27 + 7. Most important open issues . . . . . . . . . . . . . . . . . . 28 + Intellectual Property and Copyright Statements . . . . . . . . 29 + + + + + + + + + + + + + + + + + + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 2] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + +1. Objectives + + The problem of exchanging packet traces becomes more and more + critical every day; unfortunately, no standard solutions exist for + this task right now. One of the most accepted packet interchange + formats is the one defined by libpcap, which is rather old and does + not fit for some of the nowadays applications especially in terms of + extensibility. + + This document proposes a new format for dumping packet traces. The + following goals are being pursued: + + o Extensibility: aside of some common functionalities, third parties + should be able to enrich the information embedded in the file with + proprietary extensions, which will be ignored by tools that are + not able to understand them. + + o Portability: a capture trace must contain all the information + needed to read data independently from network, hardware and + operating system of the machine that made the capture. + + o Merge/Append data: it should be possible to add data at the end of + a given file, and the resulting file must still be readable. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 3] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + +2. General File Structure + +2.1 General Block Structure + + A capture file is organized in blocks, that are appended one to + another to form the file. All the blocks share a common format, which + is shown in Figure 1. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Block Type | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Block Total Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / Block Body / + / /* variable length, aligned to 32 bits */ / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Block Total Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 1: Basic block structure. + + The fields have the following meaning: + + o Block Type (32 bits): unique value that identifies the block. + Values whose Most Significant Bit (MSB) is equal to 1 are reserved + for local use. They allow to save private data to the file and to + extend the file format. + + o Block Total Length: total size of this block, in bytes. For + instance, a block that does not have a body has a length of 12 + bytes. + + o Block Body: content of the block. + + o Block Total Length: total size of this block, in bytes. This field + is duplicated for permitting backward file navigation. + + This structure, shared among all blocks, makes easy to process a file + and to skip unneeded or unknown blocks. Blocks can be nested one + inside the others (NOTE: needed?). Some of the blocks are mandatory, + i.e. a dump file is not valid if they are not present, other are + optional. + + The structure of the blocks allows to define other blocks if needed. + A parser that does non understand them can simply ignore their + content. + + + +Degioanni & Risso Expires August 30, 2004 [Page 4] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + +2.2 Block Types + + The currently defined blocks are the following: + + 1. Section Header Block: it defines the most important + characteristics of the capture file. + + 2. Interface Description Block: it defines the most important + characteristics of the interface(s) used for capturing traffic. + + 3. Packet Block: it contains a single captured packet, or a portion + of it. + + 4. Simple Packet Block: it contains a single captured packet, or a + portion of it, with only a minimal set of information about it. + + 5. Name Resolution Block: it defines the mapping from numeric + addresses present in the packet dump and the canonical name + counterpart. + + 6. Capture Statistics Block: it defines how to store some + statistical data (e.g. packet dropped, etc) which can be useful + to undestand the conditions in which the capture has been made. + + 7. Compression Marker Block: TODO + + 8. Encryption Marker Block: TODO + + 9. Fixed Length Marker Block: TODO + + The following blocks instead are considered interesting but the + authors believe that they deserve more in-depth discussion before + being defined: + + 1. Further Packet Blocks + + 2. Directory Block + + 3. Traffic Statistics and Monitoring Blocks + + 4. Alert and Security Blocks + + TODO Currently standardized Block Type codes are specified in + Appendix 1. + +2.3 Block Hierarchy and Precedence + + The file must begin with a Section Header Block. However, more than + + + +Degioanni & Risso Expires August 30, 2004 [Page 5] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + one Section Header Block can be present on the dump, each one + covering the data following it till the next one (or the end of + file). A Section includes the data delimited by two Section Header + Blocks (or by a Section Header Block and the end of the file), + including the first Section Header Block. + + In case an application cannot read a Section because of different + version number, it must skip everything until the next Section Header + Block. Note that, in order to properly skip the blocks until the next + section, all blocks must have the fields Type and Length at the + beginning. This is a mandatory requirement that must be maintained in + future versions of the block format. + + Figure 2 shows two valid files: the first has a typical + configuration, with a single Section Header that covers the whole + file. The second one contains three headers, and is normally the + result of file concatenation. An application that understands only + version 1.0 of the file format skips the intermediate section and + restart processing the packets after the third Section Header. + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SHB v1.0 | Data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Typical configuration with a single Section Header Block + + + |-- 1st Section --|-- 2nd Section --|-- 3rd Section --| + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SHB v1.0 | Data | SHB V1.1 | Data | SHB V1.0 | Data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Configuration with three different Section Header Blocks + + Figure 2: File structure example: the Section Header Block. + + NOTE: TO BE COMPLETED with some examples of other blocks + +2.4 Data format + + Data contained in each section will always be saved according to the + characteristics (little endian / big endian) of the dumping machine. + This refers to all fields that are saved as numbers and that span + over two or more bytes. + + The approach of having each section saved in the native format of the + generating host is more efficient because it avoids translation of + data when reading / writing on the host itself, which is the most + common case when generating/processing capture dumps. + + + +Degioanni & Risso Expires August 30, 2004 [Page 6] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + TODO Probably we have to specify something more here. Is what we're + saying enough to avoid any kind of ambiguity?. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 7] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + +3. Block Definition + + This section details the format of the body of the blocks currently + defined. + +3.1 Section Header Block (mandatory) + + The Section Header Block is mandatory. It identifies the beginning of + a section of the capture dump file. Its format is shown in Figure 3. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Magic | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Major | Minor | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + / Options (variable) / + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 3: Section Header Block format. + + The meaning of the fields is: + + o Magic: magic number, whose value is the hexadecimal number + 0x1A2B3C4D. This number can be used to distinguish section that + have been saved on little-endian machines from the one saved on + big-endian machines. + + o Major: number of the current mayor version of the format. Current + value is 1. + + o Minor: number of the current minor version of the format. Current + value is 0. + + o Options: optionally, a list of options (formatted according to the + rules defined in Section 4) can be present. + + Aside form the options defined in Section 4, the following options + are valid within this block: + + +----------------+----------------+----------------+----------------+ + | Name | Code | Length | Description | + +----------------+----------------+----------------+----------------+ + | Hardware | 2 | variable | An ascii | + | | | | string | + + + +Degioanni & Risso Expires August 30, 2004 [Page 8] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + | | | | containing the | + | | | | description of | + | | | | the hardware | + | | | | used to create | + | | | | this section. | + | | | | | + | Operating | 3 | variable | An ascii | + | System | | | string | + | | | | containing the | + | | | | name of the | + | | | | operating | + | | | | system used to | + | | | | create this | + | | | | section. | + | | | | | + | User | 3 | variable | An ascii | + | Application | | | string | + | | | | containing the | + | | | | name of the | + | | | | application | + | | | | used to create | + | | | | this section. | + +----------------+----------------+----------------+----------------+ + + Table 1 + + The Section Header Block does not contain data but it rather + identifies a list of blocks (interfaces, packets) that are logically + correlated. This block does not contain any reference to the size of + the section it is currently delimiting, therefore the reader cannot + skip a whole section at once. In case a section must be skipped, the + user has to repeatedly skip all the blocks contained within it; this + makes the parsing of the file slower but it permits to append several + capture dumps at the same file. + +3.2 Interface Description Block (mandatory) + + The Interface Description Block is mandatory. This block is needed to + specify the characteristics of the network interface on which the + capture has been made. In order to properly associate the captured + data to the corresponding interface, the Interface Description Block + must be defined before any other block that uses it; therefore, this + block is usually placed immediately after the Section Header Block. + + An Interface Description Block is valid only inside the section which + it belongs to. The structure of a Interface Description Block is + shown in Figure 4. + + + + +Degioanni & Risso Expires August 30, 2004 [Page 9] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Interface ID | LinkType | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SnapLen | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + / Options (variable) / + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 4: Interface Description Block format. + + The meaning of the fields is: + + o Interface ID: a progressive number that identifies uniquely any + interface inside current section. Two Interface Description Blocks + can have the same Interface ID only if they are in different + sections of the file. The Interface ID is referenced by the packet + blocks. + + o LinkType: a value that defines the link layer type of this + interface. + + o SnapLen: maximum number of bytes dumped from each packet. The + portion of each packet that exceeds this value will not be stored + in the file. + + o Options: optionally, a list of options (formatted according to the + rules defined in Section 4) can be present. + + In addition to the options defined in Section 4, the following + options are valid within this block: + + +----------------+----------------+----------------+----------------+ + | Name | Code | Length | Description | + +----------------+----------------+----------------+----------------+ + | if_name | 2 | Variable | Name of the | + | | | | device used to | + | | | | capture data. | + | | | | | + | if_IPv4addr | 3 | 8 | Interface | + | | | | network | + | | | | address and | + | | | | netmask. | + | | | | | + | if_IPv6addr | 4 | 17 | Interface | + + + +Degioanni & Risso Expires August 30, 2004 [Page 10] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + | | | | network | + | | | | address and | + | | | | prefix length | + | | | | (stored in the | + | | | | last byte). | + | | | | | + | if_MACaddr | 5 | 6 | Interface | + | | | | Hardware MAC | + | | | | address (48 | + | | | | bits). | + | | | | | + | if_EUIaddr | 6 | 8 | Interface | + | | | | Hardware EUI | + | | | | address (64 | + | | | | bits), if | + | | | | available. | + | | | | | + | if_speed | 7 | 8 | Interface | + | | | | speed (in | + | | | | bps). | + | | | | | + | if_tsaccur | 8 | 1 | Precision of | + | | | | timestamps. If | + | | | | the Most | + | | | | Significant | + | | | | Bit is equal | + | | | | to zero, the | + | | | | remaining bits | + | | | | indicates the | + | | | | accuracy as as | + | | | | a negative | + | | | | power of 10 | + | | | | (e.g. 6 means | + | | | | microsecond | + | | | | accuracy). If | + | | | | the Most | + | | | | Significant | + | | | | Bit is equal | + | | | | to zero, the | + | | | | remaining bits | + | | | | indicates the | + | | | | accuracy as as | + | | | | negative power | + | | | | of 2 (e.g. 10 | + | | | | means 1/1024 | + | | | | of second). If | + | | | | this option is | + | | | | not present, a | + + + +Degioanni & Risso Expires August 30, 2004 [Page 11] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + | | | | precision of | + | | | | 10^-6 is | + | | | | assumed. | + | | | | | + | if_tzone | 9 | 4 | Time zone for | + | | | | GMT support | + | | | | (TODO: specify | + | | | | better). | + | | | | | + | if_flags | 10 | 4 | Interface | + | | | | flags. (TODO: | + | | | | specify | + | | | | better. | + | | | | Possible | + | | | | flags: | + | | | | promiscuous, | + | | | | inbound/outbou | + | | | | nd, traffic | + | | | | filtered | + | | | | during | + | | | | capture). | + | | | | | + | if_filter | 11 | variable | The filter | + | | | | (e.g. "capture | + | | | | only TCP | + | | | | traffic") used | + | | | | to capture | + | | | | traffic. The | + | | | | first byte of | + | | | | the Option | + | | | | Data keeps a | + | | | | code of the | + | | | | filter used | + | | | | (e.g. if this | + | | | | is a libpcap | + | | | | string, or BPF | + | | | | bytecode, and | + | | | | more). More | + | | | | details about | + | | | | this format | + | | | | will be | + | | | | presented in | + | | | | Appendix XXX | + | | | | (TODO). | + | | | | | + | if_opersystem | 12 | variable | An ascii | + | | | | string | + | | | | containing the | + + + +Degioanni & Risso Expires August 30, 2004 [Page 12] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + | | | | name of the | + | | | | operating | + | | | | system of the | + | | | | machine that | + | | | | hosts this | + | | | | interface. | + | | | | This can be | + | | | | different from | + | | | | the same | + | | | | information | + | | | | that can be | + | | | | contained by | + | | | | the Section | + | | | | Header Block | + | | | | (Section 3.1) | + | | | | because the | + | | | | capture can | + | | | | have been done | + | | | | on a remote | + | | | | machine. | + +----------------+----------------+----------------+----------------+ + + Table 2 + + +3.3 Packet Block (optional) + + A Packet Block is the standard container for storing the packets + coming from the network. The Packet Block is optional because packets + can be stored either by means of this block or the Simple Packet + Block, which can be used to speed up dump generation. The format of a + packet block is shown in Figure 5. + + + + + + + + + + + + + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 13] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Interface ID | Drops Count | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Timestamp (High) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Timestamp (Low) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Captured Len | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Packet Len | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + | Packet Data | + | | + | /* variable length, byte-aligned */ | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + / Options (variable) / + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 5: Packet Block format. + + The Packet Block has the following fields: + + o Interface ID: Specifies the interface this packet comes from, and + corresponds to the ID of one of the Interface Description Blocks + present in this section of the file (see Figure 4). + + o Drops Count: a local drop counter. It specified the number of + packets lost (by the interface and the operating system) between + this packet and the preceding one. The value xFFFF (in + hexadecimal) is reserved for those systems in which this + information is not available. + + o Timestamp (High): the most significative part of the timestamp. in + standard Unix format, i.e. from 1/1/1970. + + o Timestamp (Low): the less significative part of the timestamp. The + way to interpret this field is specified by the 'ts_accur' option + (see Figure 4) of the Interface Description block referenced by + this packet. If the Interface Description block does not contain a + 'ts_accur' option, then this field is expressed in microseconds. + + o Captured Len: number of bytes captured from the packet (i.e. the + + + +Degioanni & Risso Expires August 30, 2004 [Page 14] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + length of the Packet Data field). It will be the minimum value + among the actual Packet Length and the snapshot length (defined in + Figure 4). + + o Packet Len: actual length of the packet when it was transmitted on + the network. Can be different from Captured Len if the user wants + only a snapshot of the packet. + + o Packet Data: the data coming from the network, including + link-layer headers. The length of this field is Captured Len. The + format of the link-layer headers depends on the LinkType field + specified in the Interface Description Block (see Section 3.2) and + it is specified in Appendix XXX (TODO). + + o Options: optionally, a list of options (formatted according to the + rules defined in Section 4) can be present. + + +3.4 Simple Packet Block (optional) + + The Simple Packet Block is a lightweight container for storing the + packets coming from the network. Its presence is optional. + + A Simple Packet Block is similar to a Packet Block (see Section 3.3), + but it is smaller, simpler to process and contains only a minimal set + of information. This block is preferred to the standard Packet Block + when performance or space occupation are critical factors, such as in + sustained traffic dump applications. A capture file can contain both + Packet Blocks and Simple Packet Blocks: for example, a capture tool + could switch from Packet Blocks to Simple Packet Blocks when the + hardware resources become critical. + + The Simple Packet Block does not contain the Interface ID field. + Therefore, it must be assumed that all the Simple Packet Blocks have + been captured on the interface previously specified in the Interface + Description Block. + + Figure 6 shows the format of the Simple Packet Block. + + + + + + + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 15] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Packet Len | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + | Packet Data | + | | + | /* variable length, byte-aligned */ | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 6: Simple Packet Block format. + + The Packet Block has the following fields: + + o Packet Len: actual length of the packet when it was transmitted on + the network. Can be different from captured len if the packet has + been truncated. + + o Packet data: the data coming from the network, including + link-layers headers. The length of this field can be derived from + the field Block Total Length, present in the Block Header. + + The Simple Packet Block does not contain the timestamp because this + is one of the most costly operations on PCs. Additionally, there are + applications that do not require it; e.g. an Intrusion Detection + System is interested in packets, not in their timestamp. + + The Simple Packet Block is very efficient in term of disk space: a + snapshot of length 100 bytes requires only 16 bytes of overhead, + which corresponds to an efficiency of more than 86%. + +3.5 Name Resolution Block (optional) + + The Name Resolution Block is used to support the correlation of + numeric addresses (present in the captured packets) and their + corresponding canonical names and it is optional. Having the literal + names saved in the file, this prevents the need of a name resolution + in a delayed time, when the association between names and addresses + can be different from the one in use at capture time. Moreover, The + Name Resolution Block avoids the need of issuing a lot of DNS + requests every time the trace capture is opened, and allows to have + name resolution also when reading the capture with a machine not + connected to the network. + + The format of the Name Resolution Block is shown in Figure 7. + + + + +Degioanni & Risso Expires August 30, 2004 [Page 16] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Record Type | Record Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Record Value | + | /* variable length, byte-aligned */ | + | + + + + + + + + + + + + + + + + + + + + + + + + + + | | | | | + +-+-+-+-+-+-+-+-+ + + + + + + + + + + + + + + + + + + + + + + + + + . . . other records . . . + | Record Type == end_of_recs | Record Length == 00 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + / Options (variable) / + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 7: Name Resolution Block format. + + A Name Resolution Block is a zero-terminated list of records (in the + TLV format), each of which contains an association between a network + address and a name. There are three possible types of records: + + +----------------+----------------+----------------+----------------+ + | Name | Code | Length | Description | + +----------------+----------------+----------------+----------------+ + | end_of_recs | 0 | 0 | End of records | + | | | | | + | ip4_rec | 1 | Variable | Specifies an | + | | | | IPv4 address | + | | | | (contained in | + | | | | the first 4 | + | | | | bytes), | + | | | | followed by | + | | | | one or more | + | | | | zero-terminate | + | | | | d strings | + | | | | containing the | + | | | | DNS entries | + | | | | for that | + | | | | address. | + | | | | | + | ip6_rec | 1 | Variable | Specifies an | + | | | | IPv6 address | + | | | | (contained in | + | | | | the first 16 | + | | | | bytes), | + + + +Degioanni & Risso Expires August 30, 2004 [Page 17] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + | | | | followed by | + | | | | one or more | + | | | | zero-terminate | + | | | | d strings | + | | | | containing the | + | | | | DNS entries | + | | | | for that | + | | | | address. | + +----------------+----------------+----------------+----------------+ + + Table 3 + + After the list or Name Resolution Records, optionally, a list of + options (formatted according to the rules defined in Section 4) can + be present. + + A Name Resolution Block is normally placed at the beginning of the + file, but no assumptions can be taken about its position. Name + Resolution Blocks can be added in a second time by tools that process + the file, like network analyzers. + + In addiction to the options defined in Section 4, the following + options are valid within this block: + + +----------------+----------------+----------------+----------------+ + | Name | Code | Length | Description | + +----------------+----------------+----------------+----------------+ + | ns_dnsname | 2 | Variable | An ascii | + | | | | string | + | | | | containing the | + | | | | name of the | + | | | | machine (DNS | + | | | | server) used | + | | | | to perform the | + | | | | name | + | | | | resolution. | + +----------------+----------------+----------------+----------------+ + + +3.6 Interface Statistics Block (optional) + + The Interface Statistics Block contains the capture statistics for a + given interface and it is optional. The statistics are referred to + the interface defined in the current Section identified by the + Interface ID field. + + The format of the Interface Statistics Block is shown in Figure 8. + + + + +Degioanni & Risso Expires August 30, 2004 [Page 18] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IfRecv | + | (high + low) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IfDrop | + | (high + low) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | FilterAccept | + | (high + low) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | OSDrop | + | (high + low) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | UsrDelivered | + | (high + low) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Interface ID | Reserved | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + / Options (variable) / + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 8: Interface Statistics Block format. + + The fields have the following meaning: + + o IfRecv: number of packets received from the interface during the + capture. This number is reported as a 64 bits value, in which the + most significat bits are located in the first four bytes of the + field. + + o IfDrop: number of packets dropped by the interface during the + capture due to lack of resources. + + o FilterAccept: number of packets accepeted by filter during current + capture. + + o OSDrop: number of packets dropped by the operating system during + the capture. + + o UsrDelivered: number of packets delivered to the user. + UsrDelivered can be different from the value 'FilterAccept - + OSDropped' because some packets could still lay in the OS buffers + when the capture ended. + + + + +Degioanni & Risso Expires August 30, 2004 [Page 19] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + o Interface ID: reference to an Interface Description Block. + + o Reserved: Reserved to future use. + + o Options: optionally, a list of options (formatted according to the + rules defined in Section 4) can be present. + + In addiction to the options defined in Section 4, the following + options are valid within this block: + + +----------------+----------------+----------------+----------------+ + | Name | Code | Length | Description | + +----------------+----------------+----------------+----------------+ + | isb_starttime | 2 | 8 | Time in which | + | | | | the capture | + | | | | started; time | + | | | | will be stored | + | | | | in two blocks | + | | | | of four bytes | + | | | | each, | + | | | | containing the | + | | | | timestamp in | + | | | | seconds and | + | | | | nanoseconds. | + | | | | | + | isb_endtime | 3 | 8 | Time in which | + | | | | the capture | + | | | | started; time | + | | | | will be stored | + | | | | in two blocks | + | | | | of four bytes | + | | | | each, | + | | | | containing the | + | | | | timestamp in | + | | | | seconds and | + | | | | nanoseconds. | + +----------------+----------------+----------------+----------------+ + + + + + + + + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 20] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + +4. Options + + Almost all blocks have the possibility to embed optional fields. + Optional fields can be used to insert some information that may be + useful when reading data, but that it is not really needed for packet + processing. Therefore, each tool can be either read the content of + the optional fields (if any), or skip them at once. + + Skipping all the optional fields at once is straightforward because + most of the blocks have a fixed length, therefore the field Block + Length (present in the General Block Structure, see Section 2.1) can + be used to skip everything till the next block. + + Options are a list of Type - Length - Value fields, each one + containing a single value: + + o Option Type (2 bytes): it contains the code that specifies the + type of the current TLV record. Option types whose Most + Significant Bit is equal to one are reserved for local use; + therefore, there is no guarantee that the code used is unique + among all capture files (generated by other applications). In case + of vendor-specific extensions that have to be identified uniquely, + vendors must request an Option Code whose MSB is equal to zero. + + o Option Length (2 bytes): it contains the length of the following + 'Option Value' field. + + o Option Value (variable length): it contains the value of the given + option. The length of this field as been specified by the Option + Length field. + + Options may be repeated several times (e.g. an interface that has + several IP addresses associated to it). The option list is terminated + by a special code which is the 'End of Option'. + + The format of the optional fields is shown in Figure 9. + + + + + + + + + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 21] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Option Code | Option Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Option Value | + | /* variable length, byte-aligned */ | + | + + + + + + + + + + + + + + + + + + + + + + + + + + | / / / | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + / . . . other options . . . / + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Option Code == opt_endofopt | Option Length == 0 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 9: Options format. + + The following codes can always be present in any optional field: + + +----------------+----------------+----------------+----------------+ + | Name | Code | Length | Description | + +----------------+----------------+----------------+----------------+ + | opt_endofopt | 0 | 0 | End of | + | | | | options: it is | + | | | | used to | + | | | | delimit the | + | | | | end of the | + | | | | optional | + | | | | fields. This | + | | | | block cannot | + | | | | be repeated | + | | | | within a given | + | | | | list of | + | | | | options. | + | | | | | + | opt_comment | 1 | variable | Comment: it is | + | | | | an ascii | + | | | | string | + | | | | containing a | + | | | | comment that | + | | | | is associated | + | | | | to the current | + | | | | block. | + +----------------+----------------+----------------+----------------+ + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 22] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + +5. Experimental Blocks (deserved to a further investigation) + +5.1 Other Packet Blocks (experimental) + + Can some other packet blocks (besides the two described in the + previous paragraphs) be useful? + +5.2 Compression Block (experimental) + + The Compression Block is optional. A file can contain an arbitrary + number of these blocks. A Compression Block, as the name says, is + used to store compressed data. Its format is shown in Figure 10. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Compr. Type | | + +-+-+-+-+-+-+-+-+ | + | | + | Compressed Data | + | | + | /* variable length, byte-aligned */ | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 10: Compression Block format. + + The fields have the following meaning: + + o Compression Type: specifies the compression algorithm. Possible + values for this field are 0 (uncompressed), 1 (Lempel Ziv), 2 + (Gzip), other?? Probably some kind of dumb and fast compression + algorithm could be effective with some types of traffic (for + example web), but which? + + o Compressed Data: data of this block. Once decompressed, it is made + of other blocks. + + +5.3 Encryption Block (experimental) + + The Encryption Block is optional. A file can contain an arbitrary + number of these blocks. An Encryption Block is used to sotre + encrypted data. Its format is shown in Figure 11. + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 23] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Encr. Type | | + +-+-+-+-+-+-+-+-+ | + | | + | Compressed Data | + | | + | /* variable length, byte-aligned */ | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 11: Encryption Block format. + + The fields have the following meaning: + + o Compression Type: specifies the encryption algorithm. Possible + values for this field are ??? NOTE: this block should probably + contain other fields, depending on the encryption algorithm. To be + define precisely. + + o Encrypted Data: data of this block. Once decripted, it consists of + other blocks. + + +5.4 Fixed Length Block (experimental) + + The Fixed Length Block is optional. A file can contain an arbitrary + number of these blocks. A Fixed Length Block can be used to optimize + the access to the file. Its format is shown in Figure 12. A Fixed + Length Block stores records with constant size. It contains a set of + Blocks (normally Packet Blocks or Simple Packet Blocks), of wihich it + specifies the size. Knowing this size a priori helps to scan the file + and to load some portions of it without truncating a block, and is + particularly useful with cell-based networks like ATM. + + + + + + + + + + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 24] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cell Size | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | | + | Fixed Size Data | + | | + | /* variable length, byte-aligned */ | + | | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 12: Fixed Length Block format. + + The fields have the following meaning: + + o Cell size: the size of the blocks contained in the data field. + + o Fixed Size Data: data of this block. + + +5.5 Directory Block (experimental) + + If present, this block contains the following information: + + o number of indexed packets (N) + + o table with position and length of any indexed packet (N entries) + + A directory block must be followed by at least N packets, otherwise + it must be considered invalid. It can be used to efficiently load + portions of the file to memory and to support operations on memory + mapped files. This block can be added by tools like network analyzers + as a consequence of file processing. + +5.6 Traffic Statistics and Monitoring Blocks (experimental) + + One or more blocks could be defined to contain network statistics or + traffic monitoring information. They could be use to store data + collected from RMON or Netflow probes, or from other network + monitoring tools. + +5.7 Event/Security Block (experimental) + + This block could be used to store events. Events could contain + generic information (for example network load over 50%, server + down...) or security alerts. An event could be: + + + +Degioanni & Risso Expires August 30, 2004 [Page 25] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + o skipped, if the application doesn't know how to do with it + + o processed independently by the packets. In other words, the + applications skips the packets and processes only the alerts + + o processed in relation to packets: for example, a security tool + could load only the packets of the file that are near a security + alert; a monitorg tool could skip the packets captured while the + server was down. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 26] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + +6. Conclusions + + The file format proposed in this document should be very versatile + and satisfy a wide range of applications. In the simplest case, it + can contain a raw dump of the network data, made of a series of + Simple Packet Blocks. In the most complex case, it can be used as a + repository for heterogeneous information. In every case, the file + remains easy to parse and an application can always skip the data it + is not interested in; at the same time, different applications can + share the file, and each of them can benfit of the information + produced by the others. Two or more files can be concatenated + obtaining another valid file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 27] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + +7. Most important open issues + + o Data, in the file, must be byte or word aligned? Currently, the + structure of this document is not consistent with respect to this + point. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 28] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + +Intellectual Property Statement + + The IETF takes no position regarding the validity or scope of any + intellectual property or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; neither does it represent that it + has made any effort to identify any such rights. Information on the + IETF's procedures with respect to rights in standards-track and + standards-related documentation can be found in BCP-11. Copies of + claims of rights made available for publication and any assurances of + licenses to be made available, or the result of an attempt made to + obtain a general license or permission for the use of such + proprietary rights by implementors or users of this specification can + be obtained from the IETF Secretariat. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights which may cover technology that may be required to practice + this standard. Please address the information to the IETF Executive + Director. + + +Full Copyright Statement + + Copyright (C) The Internet Society (2004). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assignees. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + + + +Degioanni & Risso Expires August 30, 2004 [Page 29] + +Internet-Draft PCAP New Generation Dump File Format March 2004 + + + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + +Acknowledgment + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Degioanni & Risso Expires August 30, 2004 [Page 30] + diff --git a/winpcap/wpcap/libpcap/doc/pcap.xml b/winpcap/wpcap/libpcap/doc/pcap.xml new file mode 100644 index 0000000..ebbf321 --- /dev/null +++ b/winpcap/wpcap/libpcap/doc/pcap.xml @@ -0,0 +1,746 @@ + + + + + + + + PCAP New Generation Dump File Format + + Politecnico di Torino +
+ + Corso Duca degli Abruzzi, 24 + Torino + 10129 + Italy + + +39 011 564 7008 + loris.degioanni@polito.it + http://netgroup.polito.it/loris/ +
+
+ + Politecnico di Torino +
+ + Corso Duca degli Abruzzi, 24 + Torino + 10129 + Italy + + +39 011 564 7008 + fulvio.risso@polito.it + http://netgroup.polito.it/fulvio.risso/ +
+
+ + + + + General + + Internet-Draft + Libpcap, dump file format + +This document describes a format to dump captured packets on a file. This format is extensible and it is currently proposed for implementation in the libpcap/WinPcap packet capture library. + + +
+ + +
+The problem of exchanging packet traces becomes more and more critical every day; unfortunately, no standard solutions exist for this task right now. One of the most accepted packet interchange formats is the one defined by libpcap, which is rather old and does not fit for some of the nowadays applications especially in terms of extensibility. +This document proposes a new format for dumping packet traces. The following goals are being pursued: + +Extensibility: aside of some common functionalities, third parties should be able to enrich the information embedded in the file with proprietary extensions, which will be ignored by tools that are not able to understand them. +Portability: a capture trace must contain all the information needed to read data independently from network, hardware and operating system of the machine that made the capture. +Merge/Append data: it should be possible to add data at the end of a given file, and the resulting file must still be readable. + + +
+ + +
+ +
+A capture file is organized in blocks, that are appended one to another to form the file. All the blocks share a common format, which is shown in . + +
+ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Block Type | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Block Total Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / Block Body / + / /* variable length, aligned to 32 bits */ / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Block Total Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +
+ +The fields have the following meaning: + + +Block Type (32 bits): unique value that identifies the block. Values whose Most Significant Bit (MSB) is equal to 1 are reserved for local use. They allow to save private data to the file and to extend the file format. +Block Total Length: total size of this block, in bytes. For instance, a block that does not have a body has a length of 12 bytes. +Block Body: content of the block. +Block Total Length: total size of this block, in bytes. This field is duplicated for permitting backward file navigation. + + +This structure, shared among all blocks, makes easy to process a file and to skip unneeded or unknown blocks. Blocks can be nested one inside the others (NOTE: needed?). Some of the blocks are mandatory, i.e. a dump file is not valid if they are not present, other are optional. +The structure of the blocks allows to define other blocks if needed. A parser that does non understand them can simply ignore their content. +
+ +
+The currently defined blocks are the following: + +Section Header Block: it defines the most important characteristics of the capture file. +Interface Description Block: it defines the most important characteristics of the interface(s) used for capturing traffic. +Packet Block: it contains a single captured packet, or a portion of it. +Simple Packet Block: it contains a single captured packet, or a portion of it, with only a minimal set of information about it. +Name Resolution Block: it defines the mapping from numeric addresses present in the packet dump and the canonical name counterpart. +Capture Statistics Block: it defines how to store some statistical data (e.g. packet dropped, etc) which can be useful to undestand the conditions in which the capture has been made. +Compression Marker Block: TODO +Encryption Marker Block: TODO +Fixed Length Marker Block: TODO + + +The following blocks instead are considered interesting but the authors believe that they deserve more in-depth discussion before being defined: + +Further Packet Blocks +Directory Block +Traffic Statistics and Monitoring Blocks +Alert and Security Blocks + + +TODO Currently standardized Block Type codes are specified in Appendix 1. + +
+ +
+The file must begin with a Section Header Block. However, more than one Section Header Block can be present on the dump, each one covering the data following it till the next one (or the end of file). A Section includes the data delimited by two Section Header Blocks (or by a Section Header Block and the end of the file), including the first Section Header Block. +In case an application cannot read a Section because of different version number, it must skip everything until the next Section Header Block. Note that, in order to properly skip the blocks until the next section, all blocks must have the fields Type and Length at the beginning. This is a mandatory requirement that must be maintained in future versions of the block format. + shows two valid files: the first has a typical configuration, with a single Section Header that covers the whole file. The second one contains three headers, and is normally the result of file concatenation. An application that understands only version 1.0 of the file format skips the intermediate section and restart processing the packets after the third Section Header. + +
+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SHB v1.0 | Data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Typical configuration with a single Section Header Block + + + |-- 1st Section --|-- 2nd Section --|-- 3rd Section --| + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SHB v1.0 | Data | SHB V1.1 | Data | SHB V1.0 | Data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Configuration with three different Section Header Blocks + +
+ +NOTE: TO BE COMPLETED with some examples of other blocks + +
+ +
+Data contained in each section will always be saved according to the characteristics (little endian / big endian) of the dumping machine. This refers to all fields that are saved as numbers and that span over two or more bytes. +The approach of having each section saved in the native format of the generating host is more efficient because it avoids translation of data when reading / writing on the host itself, which is the most common case when generating/processing capture dumps. +TODO Probably we have to specify something more here. Is what we're saying enough to avoid any kind of ambiguity?. +
+ +
+ + + + +
+This section details the format of the body of the blocks currently defined. + +
+The Section Header Block is mandatory. It identifies the beginning of a section of the capture dump file. Its format is shown in . +
+ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Magic | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Major | Minor | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + / Options (variable) / + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +
+ +The meaning of the fields is: + +Magic: magic number, whose value is the hexadecimal number 0x1A2B3C4D. This number can be used to distinguish section that have been saved on little-endian machines from the one saved on big-endian machines. +Major: number of the current mayor version of the format. Current value is 1. +Minor: number of the current minor version of the format. Current value is 0. +Options: optionally, a list of options (formatted according to the rules defined in ) can be present. + + +Aside form the options defined in , the following options are valid within this block: + + + Name + Code + Length + Description + + Hardware + 2 + variable + An ascii string containing the description of the hardware used to create this section. + + Operating System + 3 + variable + An ascii string containing the name of the operating system used to create this section. + + User Application + 3 + variable + An ascii string containing the name of the application used to create this section. + + + +The Section Header Block does not contain data but it rather identifies a list of blocks (interfaces, packets) that are logically correlated. This block does not contain any reference to the size of the section it is currently delimiting, therefore the reader cannot skip a whole section at once. In case a section must be skipped, the user has to repeatedly skip all the blocks contained within it; this makes the parsing of the file slower but it permits to append several capture dumps at the same file. +
+ +
+The Interface Description Block is mandatory. This block is needed to specify the characteristics of the network interface on which the capture has been made. In order to properly associate the captured data to the corresponding interface, the Interface Description Block must be defined before any other block that uses it; therefore, this block is usually placed immediately after the Section Header Block. + +An Interface Description Block is valid only inside the section which it belongs to. The structure of a Interface Description Block is shown in . + +
+ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Interface ID | LinkType | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SnapLen | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + / Options (variable) / + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +
+ +The meaning of the fields is: + +Interface ID: a progressive number that identifies uniquely any interface inside current section. Two Interface Description Blocks can have the same Interface ID only if they are in different sections of the file. The Interface ID is referenced by the packet blocks. +LinkType: a value that defines the link layer type of this interface. +SnapLen: maximum number of bytes dumped from each packet. The portion of each packet that exceeds this value will not be stored in the file. +Options: optionally, a list of options (formatted according to the rules defined in ) can be present. + + +In addition to the options defined in , the following options are valid within this block: + + + Name + Code + Length + Description + + if_name + 2 + Variable + Name of the device used to capture data. + + if_IPv4addr + 3 + 8 + Interface network address and netmask. + + if_IPv6addr + 4 + 17 + Interface network address and prefix length (stored in the last byte). + + if_MACaddr + 5 + 6 + Interface Hardware MAC address (48 bits). + + if_EUIaddr + 6 + 8 + Interface Hardware EUI address (64 bits), if available. + + if_speed + 7 + 8 + Interface speed (in bps). + + if_tsaccur + 8 + 1 + Precision of timestamps. If the Most Significant Bit is equal to zero, the remaining bits indicates the accuracy as as a negative power of 10 (e.g. 6 means microsecond accuracy). If the Most Significant Bit is equal to zero, the remaining bits indicates the accuracy as as negative power of 2 (e.g. 10 means 1/1024 of second). If this option is not present, a precision of 10^-6 is assumed. + + if_tzone + 9 + 4 + Time zone for GMT support (TODO: specify better). + + if_flags + 10 + 4 + Interface flags. (TODO: specify better. Possible flags: promiscuous, inbound/outbound, traffic filtered during capture). + + if_filter + 11 + variable + The filter (e.g. "capture only TCP traffic") used to capture traffic. The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string, or BPF bytecode, and more). More details about this format will be presented in Appendix XXX (TODO). + + if_opersystem + 12 + variable + An ascii string containing the name of the operating system of the machine that hosts this interface. This can be different from the same information that can be contained by the Section Header Block () because the capture can have been done on a remote machine. + + + +
+ + + +
+A Packet Block is the standard container for storing the packets coming from the network. The Packet Block is optional because packets can be stored either by means of this block or the Simple Packet Block, which can be used to speed up dump generation. The format of a packet block is shown in . + +
+ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Interface ID | Drops Count | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Timestamp (High) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Timestamp (Low) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Captured Len | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Packet Len | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + | Packet Data | + | | + | /* variable length, byte-aligned */ | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + / Options (variable) / + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +
+ +The Packet Block has the following fields: + + +Interface ID: Specifies the interface this packet comes from, and corresponds to the ID of one of the Interface Description Blocks present in this section of the file (see ). +Drops Count: a local drop counter. It specified the number of packets lost (by the interface and the operating system) between this packet and the preceding one. The value xFFFF (in hexadecimal) is reserved for those systems in which this information is not available. +Timestamp (High): the most significative part of the timestamp. in standard Unix format, i.e. from 1/1/1970. +Timestamp (Low): the less significative part of the timestamp. The way to interpret this field is specified by the 'ts_accur' option (see ) of the Interface Description block referenced by this packet. If the Interface Description block does not contain a 'ts_accur' option, then this field is expressed in microseconds. +Captured Len: number of bytes captured from the packet (i.e. the length of the Packet Data field). It will be the minimum value among the actual Packet Length and the snapshot length (defined in ). +Packet Len: actual length of the packet when it was transmitted on the network. Can be different from Captured Len if the user wants only a snapshot of the packet. +Packet Data: the data coming from the network, including link-layer headers. The length of this field is Captured Len. The format of the link-layer headers depends on the LinkType field specified in the Interface Description Block (see ) and it is specified in Appendix XXX (TODO). +Options: optionally, a list of options (formatted according to the rules defined in ) can be present. + + + +
+ + +
+The Simple Packet Block is a lightweight container for storing the packets coming from the network. Its presence is optional. +A Simple Packet Block is similar to a Packet Block (see ), but it is smaller, simpler to process and contains only a minimal set of information. This block is preferred to the standard Packet Block when performance or space occupation are critical factors, such as in sustained traffic dump applications. A capture file can contain both Packet Blocks and Simple Packet Blocks: for example, a capture tool could switch from Packet Blocks to Simple Packet Blocks when the hardware resources become critical. +The Simple Packet Block does not contain the Interface ID field. Therefore, it must be assumed that all the Simple Packet Blocks have been captured on the interface previously specified in the Interface Description Block. + shows the format of the Simple Packet Block. + +
+ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Packet Len | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + | Packet Data | + | | + | /* variable length, byte-aligned */ | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +
+ +The Packet Block has the following fields: + +Packet Len: actual length of the packet when it was transmitted on the network. Can be different from captured len if the packet has been truncated. +Packet data: the data coming from the network, including link-layers headers. The length of this field can be derived from the field Block Total Length, present in the Block Header. + + +The Simple Packet Block does not contain the timestamp because this is one of the most costly operations on PCs. Additionally, there are applications that do not require it; e.g. an Intrusion Detection System is interested in packets, not in their timestamp. + +The Simple Packet Block is very efficient in term of disk space: a snapshot of length 100 bytes requires only 16 bytes of overhead, which corresponds to an efficiency of more than 86%. + +
+ + + +
+The Name Resolution Block is used to support the correlation of numeric addresses (present in the captured packets) and their corresponding canonical names and it is optional. Having the literal names saved in the file, this prevents the need of a name resolution in a delayed time, when the association between names and addresses can be different from the one in use at capture time. Moreover, The Name Resolution Block avoids the need of issuing a lot of DNS requests every time the trace capture is opened, and allows to have name resolution also when reading the capture with a machine not connected to the network. +The format of the Name Resolution Block is shown in . + +
+ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Record Type | Record Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Record Value | + | /* variable length, byte-aligned */ | + | + + + + + + + + + + + + + + + + + + + + + + + + + + | | | | | + +-+-+-+-+-+-+-+-+ + + + + + + + + + + + + + + + + + + + + + + + + + . . . other records . . . + | Record Type == end_of_recs | Record Length == 00 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + / Options (variable) / + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +
+ +A Name Resolution Block is a zero-terminated list of records (in the TLV format), each of which contains an association between a network address and a name. There are three possible types of records: + + + Name + Code + Length + Description + + end_of_recs + 0 + 0 + End of records + + ip4_rec + 1 + Variable + Specifies an IPv4 address (contained in the first 4 bytes), followed by one or more zero-terminated strings containing the DNS entries for that address. + + ip6_rec + 1 + Variable + Specifies an IPv6 address (contained in the first 16 bytes), followed by one or more zero-terminated strings containing the DNS entries for that address. + + +After the list or Name Resolution Records, optionally, a list of options (formatted according to the rules defined in ) can be present. + +A Name Resolution Block is normally placed at the beginning of the file, but no assumptions can be taken about its position. Name Resolution Blocks can be added in a second time by tools that process the file, like network analyzers. + +In addiction to the options defined in , the following options are valid within this block: + + + Name + Code + Length + Description + + ns_dnsname + 2 + Variable + An ascii string containing the name of the machine (DNS server) used to perform the name resolution. + + +
+ + +
+The Interface Statistics Block contains the capture statistics for a given interface and it is optional. The statistics are referred to the interface defined in the current Section identified by the Interface ID field. +The format of the Interface Statistics Block is shown in . + +
+ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IfRecv | + | (high + low) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IfDrop | + | (high + low) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | FilterAccept | + | (high + low) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | OSDrop | + | (high + low) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | UsrDelivered | + | (high + low) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Interface ID | Reserved | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + / Options (variable) / + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +
+ +The fields have the following meaning: + + +IfRecv: number of packets received from the interface during the capture. This number is reported as a 64 bits value, in which the most significat bits are located in the first four bytes of the field. +IfDrop: number of packets dropped by the interface during the capture due to lack of resources. +FilterAccept: number of packets accepeted by filter during current capture. +OSDrop: number of packets dropped by the operating system during the capture. +UsrDelivered: number of packets delivered to the user. UsrDelivered can be different from the value 'FilterAccept - OSDropped' because some packets could still lay in the OS buffers when the capture ended. +Interface ID: reference to an Interface Description Block. +Reserved: Reserved to future use. +Options: optionally, a list of options (formatted according to the rules defined in ) can be present. + + +In addiction to the options defined in , the following options are valid within this block: + + + Name + Code + Length + Description + + isb_starttime + 2 + 8 + Time in which the capture started; time will be stored in two blocks of four bytes each, containing the timestamp in seconds and nanoseconds. + + isb_endtime + 3 + 8 + Time in which the capture started; time will be stored in two blocks of four bytes each, containing the timestamp in seconds and nanoseconds. + + +
+
+ + + +
+Almost all blocks have the possibility to embed optional fields. Optional fields can be used to insert some information that may be useful when reading data, but that it is not really needed for packet processing. Therefore, each tool can be either read the content of the optional fields (if any), or skip them at once. +Skipping all the optional fields at once is straightforward because most of the blocks have a fixed length, therefore the field Block Length (present in the General Block Structure, see ) can be used to skip everything till the next block. + +Options are a list of Type - Length - Value fields, each one containing a single value: + + +Option Type (2 bytes): it contains the code that specifies the type of the current TLV record. Option types whose Most Significant Bit is equal to one are reserved for local use; therefore, there is no guarantee that the code used is unique among all capture files (generated by other applications). In case of vendor-specific extensions that have to be identified uniquely, vendors must request an Option Code whose MSB is equal to zero. +Option Length (2 bytes): it contains the length of the following 'Option Value' field. +Option Value (variable length): it contains the value of the given option. The length of this field as been specified by the Option Length field. + + +Options may be repeated several times (e.g. an interface that has several IP addresses associated to it). The option list is terminated by a special code which is the 'End of Option'. + +The format of the optional fields is shown in . + +
+ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Option Code | Option Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Option Value | + | /* variable length, byte-aligned */ | + | + + + + + + + + + + + + + + + + + + + + + + + + + + | / / / | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / / + / . . . other options . . . / + / / + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Option Code == opt_endofopt | Option Length == 0 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +
+ +The following codes can always be present in any optional field: + + + Name + Code + Length + Description + + opt_endofopt + 0 + 0 + End of options: it is used to delimit the end of the optional fields. This block cannot be repeated within a given list of options. + + opt_comment + 1 + variable + Comment: it is an ascii string containing a comment that is associated to the current block. + + +
+ + + + +
+ +
+Can some other packet blocks (besides the two described in the previous paragraphs) be useful? +
+ +
+The Compression Block is optional. A file can contain an arbitrary number of these blocks. A Compression Block, as the name says, is used to store compressed data. Its format is shown in . + +
+ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Compr. Type | | + +-+-+-+-+-+-+-+-+ | + | | + | Compressed Data | + | | + | /* variable length, byte-aligned */ | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +
+ +The fields have the following meaning: + + +Compression Type: specifies the compression algorithm. Possible values for this field are 0 (uncompressed), 1 (Lempel Ziv), 2 (Gzip), other?? Probably some kind of dumb and fast compression algorithm could be effective with some types of traffic (for example web), but which? +Compressed Data: data of this block. Once decompressed, it is made of other blocks. + + +
+ + +
+The Encryption Block is optional. A file can contain an arbitrary number of these blocks. An Encryption Block is used to sotre encrypted data. Its format is shown in . + +
+ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Encr. Type | | + +-+-+-+-+-+-+-+-+ | + | | + | Compressed Data | + | | + | /* variable length, byte-aligned */ | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +
+ +The fields have the following meaning: + +Compression Type: specifies the encryption algorithm. Possible values for this field are ??? NOTE: this block should probably contain other fields, depending on the encryption algorithm. To be define precisely. +Encrypted Data: data of this block. Once decripted, it consists of other blocks. + + +
+ + +
+The Fixed Length Block is optional. A file can contain an arbitrary number of these blocks. A Fixed Length Block can be used to optimize the access to the file. Its format is shown in . +A Fixed Length Block stores records with constant size. It contains a set of Blocks (normally Packet Blocks or Simple Packet Blocks), of wihich it specifies the size. Knowing this size a priori helps to scan the file and to load some portions of it without truncating a block, and is particularly useful with cell-based networks like ATM. + +
+ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cell Size | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | | + | Fixed Size Data | + | | + | /* variable length, byte-aligned */ | + | | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +
+ +The fields have the following meaning: + +Cell size: the size of the blocks contained in the data field. +Fixed Size Data: data of this block. + + +
+ +
+If present, this block contains the following information: + +number of indexed packets (N) +table with position and length of any indexed packet (N entries) + + +A directory block must be followed by at least N packets, otherwise it must be considered invalid. It can be used to efficiently load portions of the file to memory and to support operations on memory mapped files. This block can be added by tools like network analyzers as a consequence of file processing. +
+ +
+One or more blocks could be defined to contain network statistics or traffic monitoring information. They could be use to store data collected from RMON or Netflow probes, or from other network monitoring tools. +
+ +
+This block could be used to store events. Events could contain generic information (for example network load over 50%, server down...) or security alerts. An event could be: + + +skipped, if the application doesn't know how to do with it +processed independently by the packets. In other words, the applications skips the packets and processes only the alerts +processed in relation to packets: for example, a security tool could load only the packets of the file that are near a security alert; a monitorg tool could skip the packets captured while the server was down. + + +
+ +
+ + + + +
+The file format proposed in this document should be very versatile and satisfy a wide range of applications. +In the simplest case, it can contain a raw dump of the network data, made of a series of Simple Packet Blocks. +In the most complex case, it can be used as a repository for heterogeneous information. +In every case, the file remains easy to parse and an application can always skip the data it is not interested in; at the same time, different applications can share the file, and each of them can benfit of the information produced by the others. +Two or more files can be concatenated obtaining another valid file. +
+ + +
+ +Data, in the file, must be byte or word aligned? Currently, the structure of this document is not consistent with respect to this point. + +
+ +
+ +
diff --git a/winpcap/wpcap/libpcap/etherent.c b/winpcap/wpcap/libpcap/etherent.c new file mode 100644 index 0000000..9d29955 --- /dev/null +++ b/winpcap/wpcap/libpcap/etherent.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.22 2003/11/15 23:23:57 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include +#include + +#include "pcap-int.h" + +#include + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +static inline int xdtoi(int); +static inline int skip_space(FILE *); +static inline int skip_line(FILE *); + +/* Hex digit to integer. */ +static inline int +xdtoi(c) + register int c; +{ + if (isdigit(c)) + return c - '0'; + else if (islower(c)) + return c - 'a' + 10; + else + return c - 'A' + 10; +} + +static inline int +skip_space(f) + FILE *f; +{ + int c; + + do { + c = getc(f); + } while (isspace(c) && c != '\n'); + + return c; +} + +static inline int +skip_line(f) + FILE *f; +{ + int c; + + do + c = getc(f); + while (c != '\n' && c != EOF); + + return c; +} + +struct pcap_etherent * +pcap_next_etherent(FILE *fp) +{ + register int c, d, i; + char *bp; + static struct pcap_etherent e; + + memset((char *)&e, 0, sizeof(e)); + do { + /* Find addr */ + c = skip_space(fp); + if (c == '\n') + continue; + + /* If this is a comment, or first thing on line + cannot be etehrnet address, skip the line. */ + if (!isxdigit(c)) { + c = skip_line(fp); + continue; + } + + /* must be the start of an address */ + for (i = 0; i < 6; i += 1) { + d = xdtoi(c); + c = getc(fp); + if (isxdigit(c)) { + d <<= 4; + d |= xdtoi(c); + c = getc(fp); + } + e.addr[i] = d; + if (c != ':') + break; + c = getc(fp); + } + if (c == EOF) + break; + + /* Must be whitespace */ + if (!isspace(c)) { + c = skip_line(fp); + continue; + } + c = skip_space(fp); + + /* hit end of line... */ + if (c == '\n') + continue; + + if (c == '#') { + c = skip_line(fp); + continue; + } + + /* pick up name */ + bp = e.name; + /* Use 'd' to prevent buffer overflow. */ + d = sizeof(e.name) - 1; + do { + *bp++ = c; + c = getc(fp); + } while (!isspace(c) && c != EOF && --d > 0); + *bp = '\0'; + + /* Eat trailing junk */ + if (c != '\n') + (void)skip_line(fp); + + return &e; + + } while (c != EOF); + + return (NULL); +} diff --git a/winpcap/wpcap/libpcap/ethertype.h b/winpcap/wpcap/libpcap/ethertype.h new file mode 100644 index 0000000..2d21c6d --- /dev/null +++ b/winpcap/wpcap/libpcap/ethertype.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 1993, 1994, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.13.2.1 2005/09/05 09:08:03 guy Exp $ (LBL) + */ + +/* + * Ethernet types. + * + * We wrap the declarations with #ifdef, so that if a file includes + * , which may declare some of these, we don't + * get a bunch of complaints from the C compiler about redefinitions + * of these values. + * + * We declare all of them here so that no file has to include + * if all it needs are ETHERTYPE_ values. + */ + +#ifndef ETHERTYPE_PUP +#define ETHERTYPE_PUP 0x0200 /* PUP protocol */ +#endif +#ifndef ETHERTYPE_IP +#define ETHERTYPE_IP 0x0800 /* IP protocol */ +#endif +#ifndef ETHERTYPE_ARP +#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */ +#endif +#ifndef ETHERTYPE_REVARP +#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */ +#endif +#ifndef ETHERTYPE_NS +#define ETHERTYPE_NS 0x0600 +#endif +#ifndef ETHERTYPE_SPRITE +#define ETHERTYPE_SPRITE 0x0500 +#endif +#ifndef ETHERTYPE_TRAIL +#define ETHERTYPE_TRAIL 0x1000 +#endif +#ifndef ETHERTYPE_MOPDL +#define ETHERTYPE_MOPDL 0x6001 +#endif +#ifndef ETHERTYPE_MOPRC +#define ETHERTYPE_MOPRC 0x6002 +#endif +#ifndef ETHERTYPE_DN +#define ETHERTYPE_DN 0x6003 +#endif +#ifndef ETHERTYPE_LAT +#define ETHERTYPE_LAT 0x6004 +#endif +#ifndef ETHERTYPE_SCA +#define ETHERTYPE_SCA 0x6007 +#endif +#ifndef ETHERTYPE_REVARP +#define ETHERTYPE_REVARP 0x8035 +#endif +#ifndef ETHERTYPE_LANBRIDGE +#define ETHERTYPE_LANBRIDGE 0x8038 +#endif +#ifndef ETHERTYPE_DECDNS +#define ETHERTYPE_DECDNS 0x803c +#endif +#ifndef ETHERTYPE_DECDTS +#define ETHERTYPE_DECDTS 0x803e +#endif +#ifndef ETHERTYPE_VEXP +#define ETHERTYPE_VEXP 0x805b +#endif +#ifndef ETHERTYPE_VPROD +#define ETHERTYPE_VPROD 0x805c +#endif +#ifndef ETHERTYPE_ATALK +#define ETHERTYPE_ATALK 0x809b +#endif +#ifndef ETHERTYPE_AARP +#define ETHERTYPE_AARP 0x80f3 +#endif +#ifndef ETHERTYPE_8021Q +#define ETHERTYPE_8021Q 0x8100 +#endif +#ifndef ETHERTYPE_IPX +#define ETHERTYPE_IPX 0x8137 +#endif +#ifndef ETHERTYPE_IPV6 +#define ETHERTYPE_IPV6 0x86dd +#endif +#ifndef ETHERTYPE_MPLS +#define ETHERTYPE_MPLS 0x8847 +#endif +#ifndef ETHERTYPE_MPLS_MULTI +#define ETHERTYPE_MPLS_MULTI 0x8848 +#endif +#ifndef ETHERTYPE_PPPOED +#define ETHERTYPE_PPPOED 0x8863 +#endif +#ifndef ETHERTYPE_PPPOES +#define ETHERTYPE_PPPOES 0x8864 +#endif +#ifndef ETHERTYPE_LOOPBACK +#define ETHERTYPE_LOOPBACK 0x9000 +#endif diff --git a/winpcap/wpcap/libpcap/fad-getad.c b/winpcap/wpcap/libpcap/fad-getad.c new file mode 100644 index 0000000..58305d5 --- /dev/null +++ b/winpcap/wpcap/libpcap/fad-getad.c @@ -0,0 +1,284 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1994, 1995, 1996, 1997, 1998 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.10.2.1 2005/04/10 18:04:49 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "pcap-int.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#ifdef AF_PACKET +# include +#endif + +/* + * This is fun. + * + * In older BSD systems, socket addresses were fixed-length, and + * "sizeof (struct sockaddr)" gave the size of the structure. + * All addresses fit within a "struct sockaddr". + * + * In newer BSD systems, the socket address is variable-length, and + * there's an "sa_len" field giving the length of the structure; + * this allows socket addresses to be longer than 2 bytes of family + * and 14 bytes of data. + * + * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553 + * variant of the old BSD scheme (with "struct sockaddr_storage" rather + * than "struct sockaddr"), and some use the new BSD scheme. + * + * Some versions of GNU libc use neither scheme, but has an "SA_LEN()" + * macro that determines the size based on the address family. Other + * versions don't have "SA_LEN()" (as it was in drafts of RFC 2553 + * but not in the final version). On the latter systems, we explicitly + * check the AF_ type to determine the length; we assume that on + * all those systems we have "struct sockaddr_storage". + */ +#ifndef SA_LEN +#ifdef HAVE_SOCKADDR_SA_LEN +#define SA_LEN(addr) ((addr)->sa_len) +#else /* HAVE_SOCKADDR_SA_LEN */ +#ifdef HAVE_SOCKADDR_STORAGE +static size_t +get_sa_len(struct sockaddr *addr) +{ + switch (addr->sa_family) { + +#ifdef AF_INET + case AF_INET: + return (sizeof (struct sockaddr_in)); +#endif + +#ifdef AF_INET6 + case AF_INET6: + return (sizeof (struct sockaddr_in6)); +#endif + +#ifdef AF_PACKET + case AF_PACKET: + return (sizeof (struct sockaddr_ll)); +#endif + + default: + return (sizeof (struct sockaddr)); + } +} +#define SA_LEN(addr) (get_sa_len(addr)) +#else /* HAVE_SOCKADDR_STORAGE */ +#define SA_LEN(addr) (sizeof (struct sockaddr)) +#endif /* HAVE_SOCKADDR_STORAGE */ +#endif /* HAVE_SOCKADDR_SA_LEN */ +#endif /* SA_LEN */ + +/* + * Get a list of all interfaces that are up and that we can open. + * Returns -1 on error, 0 otherwise. + * The list, as returned through "alldevsp", may be null if no interfaces + * were up and could be opened. + * + * This is the implementation used on platforms that have "getifaddrs()". + */ +int +pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) +{ + pcap_if_t *devlist = NULL; + struct ifaddrs *ifap, *ifa; + struct sockaddr *addr, *netmask, *broadaddr, *dstaddr; + size_t addr_size, broadaddr_size, dstaddr_size; + int ret = 0; + char *p, *q; + + /* + * Get the list of interface addresses. + * + * Note: this won't return information about interfaces + * with no addresses; are there any such interfaces + * that would be capable of receiving packets? + * (Interfaces incapable of receiving packets aren't + * very interesting from libpcap's point of view.) + * + * LAN interfaces will probably have link-layer + * addresses; I don't know whether all implementations + * of "getifaddrs()" now, or in the future, will return + * those. + */ + if (getifaddrs(&ifap) != 0) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "getifaddrs: %s", pcap_strerror(errno)); + return (-1); + } + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { + /* + * Is this interface up? + */ + if (!(ifa->ifa_flags & IFF_UP)) { + /* + * No, so don't add it to the list. + */ + continue; + } + + /* + * "ifa_addr" was apparently null on at least one + * interface on some system. + * + * "ifa_broadaddr" may be non-null even on + * non-broadcast interfaces, and was null on + * at least one OpenBSD 3.4 system on at least + * one interface with IFF_BROADCAST set. + * + * "ifa_dstaddr" was, on at least one FreeBSD 4.1 + * system, non-null on a non-point-to-point + * interface. + * + * Therefore, we supply the address and netmask only + * if "ifa_addr" is non-null (if there's no address, + * there's obviously no netmask), and supply the + * broadcast and destination addresses if the appropriate + * flag is set *and* the appropriate "ifa_" entry doesn't + * evaluate to a null pointer. + */ + if (ifa->ifa_addr != NULL) { + addr = ifa->ifa_addr; + addr_size = SA_LEN(addr); + netmask = ifa->ifa_netmask; + } else { + addr = NULL; + addr_size = 0; + netmask = NULL; + } + if (ifa->ifa_flags & IFF_BROADCAST && + ifa->ifa_broadaddr != NULL) { + broadaddr = ifa->ifa_broadaddr; + broadaddr_size = SA_LEN(broadaddr); + } else { + broadaddr = NULL; + broadaddr_size = 0; + } + if (ifa->ifa_flags & IFF_POINTOPOINT && + ifa->ifa_dstaddr != NULL) { + dstaddr = ifa->ifa_dstaddr; + dstaddr_size = SA_LEN(ifa->ifa_dstaddr); + } else { + dstaddr = NULL; + dstaddr_size = 0; + } + + /* + * If this entry has a colon followed by a number at + * the end, we assume it's a logical interface. Those + * are just the way you assign multiple IP addresses to + * a real interface on Linux, so an entry for a logical + * interface should be treated like the entry for the + * real interface; we do that by stripping off the ":" + * and the number. + * + * XXX - should we do this only on Linux? + */ + p = strchr(ifa->ifa_name, ':'); + if (p != NULL) { + /* + * We have a ":"; is it followed by a number? + */ + q = p + 1; + while (isdigit((unsigned char)*q)) + q++; + if (*q == '\0') { + /* + * All digits after the ":" until the end. + * Strip off the ":" and everything after + * it. + */ + *p = '\0'; + } + } + + /* + * Add information for this address to the list. + */ + if (add_addr_to_iflist(&devlist, ifa->ifa_name, + ifa->ifa_flags, addr, addr_size, netmask, addr_size, + broadaddr, broadaddr_size, dstaddr, dstaddr_size, + errbuf) < 0) { + ret = -1; + break; + } + } + + freeifaddrs(ifap); + + if (ret != -1) { + /* + * We haven't had any errors yet; do any platform-specific + * operations to add devices. + */ + if (pcap_platform_finddevs(&devlist, errbuf) < 0) + ret = -1; + } + + if (ret == -1) { + /* + * We had an error; free the list we've been constructing. + */ + if (devlist != NULL) { + pcap_freealldevs(devlist); + devlist = NULL; + } + } + + *alldevsp = devlist; + return (ret); +} diff --git a/winpcap/wpcap/libpcap/fad-gifc.c b/winpcap/wpcap/libpcap/fad-gifc.c new file mode 100644 index 0000000..985d2c0 --- /dev/null +++ b/winpcap/wpcap/libpcap/fad-gifc.c @@ -0,0 +1,578 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1994, 1995, 1996, 1997, 1998 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/fad-gifc.c,v 1.8.2.2 2005/06/29 06:43:31 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif +#include /* concession to AIX */ + +struct mbuf; /* Squelch compiler warnings on some platforms for */ +struct rtentry; /* declarations in */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "pcap-int.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +/* + * This is fun. + * + * In older BSD systems, socket addresses were fixed-length, and + * "sizeof (struct sockaddr)" gave the size of the structure. + * All addresses fit within a "struct sockaddr". + * + * In newer BSD systems, the socket address is variable-length, and + * there's an "sa_len" field giving the length of the structure; + * this allows socket addresses to be longer than 2 bytes of family + * and 14 bytes of data. + * + * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553 + * variant of the old BSD scheme (with "struct sockaddr_storage" rather + * than "struct sockaddr"), and some use the new BSD scheme. + * + * Some versions of GNU libc use neither scheme, but has an "SA_LEN()" + * macro that determines the size based on the address family. Other + * versions don't have "SA_LEN()" (as it was in drafts of RFC 2553 + * but not in the final version). + * + * We assume that a UNIX that doesn't have "getifaddrs()" and doesn't have + * SIOCGLIFCONF, but has SIOCGIFCONF, uses "struct sockaddr" for the + * address in an entry returned by SIOCGIFCONF. + */ +#ifndef SA_LEN +#ifdef HAVE_SOCKADDR_SA_LEN +#define SA_LEN(addr) ((addr)->sa_len) +#else /* HAVE_SOCKADDR_SA_LEN */ +#define SA_LEN(addr) (sizeof (struct sockaddr)) +#endif /* HAVE_SOCKADDR_SA_LEN */ +#endif /* SA_LEN */ + +/* + * This is also fun. + * + * There is no ioctl that returns the amount of space required for all + * the data that SIOCGIFCONF could return, and if a buffer is supplied + * that's not large enough for all the data SIOCGIFCONF could return, + * on at least some platforms it just returns the data that'd fit with + * no indication that there wasn't enough room for all the data, much + * less an indication of how much more room is required. + * + * The only way to ensure that we got all the data is to pass a buffer + * large enough that the amount of space in the buffer *not* filled in + * is greater than the largest possible entry. + * + * We assume that's "sizeof(ifreq.ifr_name)" plus 255, under the assumption + * that no address is more than 255 bytes (on systems where the "sa_len" + * field in a "struct sockaddr" is 1 byte, e.g. newer BSDs, that's the + * case, and addresses are unlikely to be bigger than that in any case). + */ +#define MAX_SA_LEN 255 + +#ifdef HAVE_PROC_NET_DEV +/* + * Get from "/proc/net/dev" all interfaces listed there; if they're + * already in the list of interfaces we have, that won't add another + * instance, but if they're not, that'll add them. + * + * We don't bother getting any addresses for them; it appears you can't + * use SIOCGIFADDR on Linux to get IPv6 addresses for interfaces, and, + * although some other types of addresses can be fetched with SIOCGIFADDR, + * we don't bother with them for now. + * + * We also don't fail if we couldn't open "/proc/net/dev"; we just leave + * the list of interfaces as is. + */ +static int +scan_proc_net_dev(pcap_if_t **devlistp, int fd, char *errbuf) +{ + FILE *proc_net_f; + char linebuf[512]; + int linenum; + unsigned char *p; + char name[512]; /* XXX - pick a size */ + char *q, *saveq; + struct ifreq ifrflags; + int ret = 0; + + proc_net_f = fopen("/proc/net/dev", "r"); + if (proc_net_f == NULL) + return (0); + + for (linenum = 1; + fgets(linebuf, sizeof linebuf, proc_net_f) != NULL; linenum++) { + /* + * Skip the first two lines - they're headers. + */ + if (linenum <= 2) + continue; + + p = &linebuf[0]; + + /* + * Skip leading white space. + */ + while (*p != '\0' && isspace(*p)) + p++; + if (*p == '\0' || *p == '\n') + continue; /* blank line */ + + /* + * Get the interface name. + */ + q = &name[0]; + while (*p != '\0' && !isspace(*p)) { + if (*p == ':') { + /* + * This could be the separator between a + * name and an alias number, or it could be + * the separator between a name with no + * alias number and the next field. + * + * If there's a colon after digits, it + * separates the name and the alias number, + * otherwise it separates the name and the + * next field. + */ + saveq = q; + while (isdigit(*p)) + *q++ = *p++; + if (*p != ':') { + /* + * That was the next field, + * not the alias number. + */ + q = saveq; + } + break; + } else + *q++ = *p++; + } + *q = '\0'; + + /* + * Get the flags for this interface, and skip it if + * it's not up. + */ + strncpy(ifrflags.ifr_name, name, sizeof(ifrflags.ifr_name)); + if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) { + if (errno == ENXIO) + continue; + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGIFFLAGS: %.*s: %s", + (int)sizeof(ifrflags.ifr_name), + ifrflags.ifr_name, + pcap_strerror(errno)); + ret = -1; + break; + } + if (!(ifrflags.ifr_flags & IFF_UP)) + continue; + + /* + * Add an entry for this interface, with no addresses. + */ + if (pcap_add_if(devlistp, name, ifrflags.ifr_flags, NULL, + errbuf) == -1) { + /* + * Failure. + */ + ret = -1; + break; + } + } + if (ret != -1) { + /* + * Well, we didn't fail for any other reason; did we + * fail due to an error reading the file? + */ + if (ferror(proc_net_f)) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "Error reading /proc/net/dev: %s", + pcap_strerror(errno)); + ret = -1; + } + } + + (void)fclose(proc_net_f); + return (ret); +} +#endif /* HAVE_PROC_NET_DEV */ + +/* + * Get a list of all interfaces that are up and that we can open. + * Returns -1 on error, 0 otherwise. + * The list, as returned through "alldevsp", may be null if no interfaces + * were up and could be opened. + * + * This is the implementation used on platforms that have SIOCGIFCONF but + * don't have any other mechanism for getting a list of interfaces. + * + * XXX - or platforms that have other, better mechanisms but for which + * we don't yet have code to use that mechanism; I think there's a better + * way on Linux, for example. + */ +int +pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) +{ + pcap_if_t *devlist = NULL; + register int fd; + register struct ifreq *ifrp, *ifend, *ifnext; + int n; + struct ifconf ifc; + char *buf = NULL; + unsigned buf_size; +#if defined (HAVE_SOLARIS) || defined (HAVE_HPUX10_20_OR_LATER) + char *p, *q; +#endif + struct ifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr; + struct sockaddr *netmask, *broadaddr, *dstaddr; + size_t netmask_size, broadaddr_size, dstaddr_size; + int ret = 0; + + /* + * Create a socket from which to fetch the list of interfaces. + */ + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "socket: %s", pcap_strerror(errno)); + return (-1); + } + + /* + * Start with an 8K buffer, and keep growing the buffer until + * we have more than "sizeof(ifrp->ifr_name) + MAX_SA_LEN" + * bytes left over in the buffer or we fail to get the + * interface list for some reason other than EINVAL (which is + * presumed here to mean "buffer is too small"). + */ + buf_size = 8192; + for (;;) { + buf = malloc(buf_size); + if (buf == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + (void)close(fd); + return (-1); + } + + ifc.ifc_len = buf_size; + ifc.ifc_buf = buf; + memset(buf, 0, buf_size); + if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 + && errno != EINVAL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGIFCONF: %s", pcap_strerror(errno)); + (void)close(fd); + free(buf); + return (-1); + } + if (ifc.ifc_len < buf_size && + (buf_size - ifc.ifc_len) > sizeof(ifrp->ifr_name) + MAX_SA_LEN) + break; + free(buf); + buf_size *= 2; + } + + ifrp = (struct ifreq *)buf; + ifend = (struct ifreq *)(buf + ifc.ifc_len); + + for (; ifrp < ifend; ifrp = ifnext) { + /* + * XXX - what if this isn't an IPv4 address? Can + * we still get the netmask, etc. with ioctls on + * an IPv4 socket? + * + * The answer is probably platform-dependent, and + * if the answer is "no" on more than one platform, + * the way you work around it is probably platform- + * dependent as well. + */ + n = SA_LEN(&ifrp->ifr_addr) + sizeof(ifrp->ifr_name); + if (n < sizeof(*ifrp)) + ifnext = ifrp + 1; + else + ifnext = (struct ifreq *)((char *)ifrp + n); + + /* + * XXX - The 32-bit compatibility layer for Linux on IA-64 + * is slightly broken. It correctly converts the structures + * to and from kernel land from 64 bit to 32 bit but + * doesn't update ifc.ifc_len, leaving it larger than the + * amount really used. This means we read off the end + * of the buffer and encounter an interface with an + * "empty" name. Since this is highly unlikely to ever + * occur in a valid case we can just finish looking for + * interfaces if we see an empty name. + */ + if (!(*ifrp->ifr_name)) + break; + + /* + * Skip entries that begin with "dummy". + * XXX - what are these? Is this Linux-specific? + * Are there platforms on which we shouldn't do this? + */ + if (strncmp(ifrp->ifr_name, "dummy", 5) == 0) + continue; + + /* + * Get the flags for this interface, and skip it if it's + * not up. + */ + strncpy(ifrflags.ifr_name, ifrp->ifr_name, + sizeof(ifrflags.ifr_name)); + if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) { + if (errno == ENXIO) + continue; + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGIFFLAGS: %.*s: %s", + (int)sizeof(ifrflags.ifr_name), + ifrflags.ifr_name, + pcap_strerror(errno)); + ret = -1; + break; + } + if (!(ifrflags.ifr_flags & IFF_UP)) + continue; + + /* + * Get the netmask for this address on this interface. + */ + strncpy(ifrnetmask.ifr_name, ifrp->ifr_name, + sizeof(ifrnetmask.ifr_name)); + memcpy(&ifrnetmask.ifr_addr, &ifrp->ifr_addr, + sizeof(ifrnetmask.ifr_addr)); + if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifrnetmask) < 0) { + if (errno == EADDRNOTAVAIL) { + /* + * Not available. + */ + netmask = NULL; + netmask_size = 0; + } else { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGIFNETMASK: %.*s: %s", + (int)sizeof(ifrnetmask.ifr_name), + ifrnetmask.ifr_name, + pcap_strerror(errno)); + ret = -1; + break; + } + } else { + netmask = &ifrnetmask.ifr_addr; + netmask_size = SA_LEN(netmask); + } + + /* + * Get the broadcast address for this address on this + * interface (if any). + */ + if (ifrflags.ifr_flags & IFF_BROADCAST) { + strncpy(ifrbroadaddr.ifr_name, ifrp->ifr_name, + sizeof(ifrbroadaddr.ifr_name)); + memcpy(&ifrbroadaddr.ifr_addr, &ifrp->ifr_addr, + sizeof(ifrbroadaddr.ifr_addr)); + if (ioctl(fd, SIOCGIFBRDADDR, + (char *)&ifrbroadaddr) < 0) { + if (errno == EADDRNOTAVAIL) { + /* + * Not available. + */ + broadaddr = NULL; + broadaddr_size = 0; + } else { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGIFBRDADDR: %.*s: %s", + (int)sizeof(ifrbroadaddr.ifr_name), + ifrbroadaddr.ifr_name, + pcap_strerror(errno)); + ret = -1; + break; + } + } else { + broadaddr = &ifrbroadaddr.ifr_broadaddr; + broadaddr_size = SA_LEN(broadaddr); + } + } else { + /* + * Not a broadcast interface, so no broadcast + * address. + */ + broadaddr = NULL; + broadaddr_size = 0; + } + + /* + * Get the destination address for this address on this + * interface (if any). + */ + if (ifrflags.ifr_flags & IFF_POINTOPOINT) { + strncpy(ifrdstaddr.ifr_name, ifrp->ifr_name, + sizeof(ifrdstaddr.ifr_name)); + memcpy(&ifrdstaddr.ifr_addr, &ifrp->ifr_addr, + sizeof(ifrdstaddr.ifr_addr)); + if (ioctl(fd, SIOCGIFDSTADDR, + (char *)&ifrdstaddr) < 0) { + if (errno == EADDRNOTAVAIL) { + /* + * Not available. + */ + dstaddr = NULL; + dstaddr_size = 0; + } else { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGIFDSTADDR: %.*s: %s", + (int)sizeof(ifrdstaddr.ifr_name), + ifrdstaddr.ifr_name, + pcap_strerror(errno)); + ret = -1; + break; + } + } else { + dstaddr = &ifrdstaddr.ifr_dstaddr; + dstaddr_size = SA_LEN(dstaddr); + } + } else { + /* + * Not a point-to-point interface, so no destination + * address. + */ + dstaddr = NULL; + dstaddr_size = 0; + } + +#if defined (HAVE_SOLARIS) || defined (HAVE_HPUX10_20_OR_LATER) + /* + * If this entry has a colon followed by a number at + * the end, it's a logical interface. Those are just + * the way you assign multiple IP addresses to a real + * interface, so an entry for a logical interface should + * be treated like the entry for the real interface; + * we do that by stripping off the ":" and the number. + */ + p = strchr(ifrp->ifr_name, ':'); + if (p != NULL) { + /* + * We have a ":"; is it followed by a number? + */ + q = p + 1; + while (isdigit((unsigned char)*q)) + q++; + if (*q == '\0') { + /* + * All digits after the ":" until the end. + * Strip off the ":" and everything after + * it. + */ + *p = '\0'; + } + } +#endif + + /* + * Add information for this address to the list. + */ + if (add_addr_to_iflist(&devlist, ifrp->ifr_name, + ifrflags.ifr_flags, &ifrp->ifr_addr, + SA_LEN(&ifrp->ifr_addr), netmask, netmask_size, + broadaddr, broadaddr_size, dstaddr, dstaddr_size, + errbuf) < 0) { + ret = -1; + break; + } + } + free(buf); + +#ifdef HAVE_PROC_NET_DEV + if (ret != -1) { + /* + * We haven't had any errors yet; now read "/proc/net/dev", + * and add to the list of interfaces all interfaces listed + * there that we don't already have, because, on Linux, + * SIOCGIFCONF reports only interfaces with IPv4 addresses, + * so you need to read "/proc/net/dev" to get the names of + * the rest of the interfaces. + */ + ret = scan_proc_net_dev(&devlist, fd, errbuf); + } +#endif + (void)close(fd); + + if (ret != -1) { + /* + * We haven't had any errors yet; do any platform-specific + * operations to add devices. + */ + if (pcap_platform_finddevs(&devlist, errbuf) < 0) + ret = -1; + } + + if (ret == -1) { + /* + * We had an error; free the list we've been constructing. + */ + if (devlist != NULL) { + pcap_freealldevs(devlist); + devlist = NULL; + } + } + + *alldevsp = devlist; + return (ret); +} diff --git a/winpcap/wpcap/libpcap/fad-glifc.c b/winpcap/wpcap/libpcap/fad-glifc.c new file mode 100644 index 0000000..8a86a3d --- /dev/null +++ b/winpcap/wpcap/libpcap/fad-glifc.c @@ -0,0 +1,386 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1994, 1995, 1996, 1997, 1998 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/fad-glifc.c,v 1.5.2.1 2005/04/19 00:54:16 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif +#include /* concession to AIX */ + +struct mbuf; /* Squelch compiler warnings on some platforms for */ +struct rtentry; /* declarations in */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "pcap-int.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +/* + * Get a list of all interfaces that are up and that we can open. + * Returns -1 on error, 0 otherwise. + * The list, as returned through "alldevsp", may be null if no interfaces + * were up and could be opened. + * + * This is the implementation used on platforms that have SIOCLGIFCONF + * but don't have "getifaddrs()". (Solaris 8 and later; we use + * SIOCLGIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.) + */ +int +pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) +{ + pcap_if_t *devlist = NULL; + register int fd4, fd6, fd; + register struct lifreq *ifrp, *ifend; + struct lifnum ifn; + struct lifconf ifc; + char *buf = NULL; + unsigned buf_size; +#ifdef HAVE_SOLARIS + char *p, *q; +#endif + struct lifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr; + struct sockaddr *netmask, *broadaddr, *dstaddr; + int ret = 0; + + /* + * Create a socket from which to fetch the list of interfaces, + * and from which to fetch IPv4 information. + */ + fd4 = socket(AF_INET, SOCK_DGRAM, 0); + if (fd4 < 0) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "socket: %s", pcap_strerror(errno)); + return (-1); + } + + /* + * Create a socket from which to fetch IPv6 information. + */ + fd6 = socket(AF_INET6, SOCK_DGRAM, 0); + if (fd6 < 0) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "socket: %s", pcap_strerror(errno)); + (void)close(fd4); + return (-1); + } + + /* + * How many entries will SIOCGLIFCONF return? + */ + ifn.lifn_family = AF_UNSPEC; + ifn.lifn_flags = 0; + ifn.lifn_count = 0; + if (ioctl(fd4, SIOCGLIFNUM, (char *)&ifn) < 0) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGLIFNUM: %s", pcap_strerror(errno)); + (void)close(fd6); + (void)close(fd4); + return (-1); + } + + /* + * Allocate a buffer for those entries. + */ + buf_size = ifn.lifn_count * sizeof (struct lifreq); + buf = malloc(buf_size); + if (buf == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + (void)close(fd6); + (void)close(fd4); + return (-1); + } + + /* + * Get the entries. + */ + ifc.lifc_len = buf_size; + ifc.lifc_buf = buf; + ifc.lifc_family = AF_UNSPEC; + ifc.lifc_flags = 0; + memset(buf, 0, buf_size); + if (ioctl(fd4, SIOCGLIFCONF, (char *)&ifc) < 0) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGLIFCONF: %s", pcap_strerror(errno)); + (void)close(fd6); + (void)close(fd4); + free(buf); + return (-1); + } + + /* + * Loop over the entries. + */ + ifrp = (struct lifreq *)buf; + ifend = (struct lifreq *)(buf + ifc.lifc_len); + + for (; ifrp < ifend; ifrp++) { + /* + * IPv6 or not? + */ + if (((struct sockaddr *)&ifrp->lifr_addr)->sa_family == AF_INET6) + fd = fd6; + else + fd = fd4; + + /* + * Skip entries that begin with "dummy". + * XXX - what are these? Is this Linux-specific? + * Are there platforms on which we shouldn't do this? + */ + if (strncmp(ifrp->lifr_name, "dummy", 5) == 0) + continue; + +#ifdef HAVE_SOLARIS + /* + * Skip entries that have a ":" followed by a number + * at the end - those are Solaris virtual interfaces + * on which you can't capture. + */ + p = strchr(ifrp->lifr_name, ':'); + if (p != NULL) { + /* + * We have a ":"; is it followed by a number? + */ + while (isdigit((unsigned char)*p)) + p++; + if (*p == '\0') { + /* + * All digits after the ":" until the end. + */ + continue; + } + } +#endif + + /* + * Get the flags for this interface, and skip it if it's + * not up. + */ + strncpy(ifrflags.lifr_name, ifrp->lifr_name, + sizeof(ifrflags.lifr_name)); + if (ioctl(fd, SIOCGLIFFLAGS, (char *)&ifrflags) < 0) { + if (errno == ENXIO) + continue; + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGLIFFLAGS: %.*s: %s", + (int)sizeof(ifrflags.lifr_name), + ifrflags.lifr_name, + pcap_strerror(errno)); + ret = -1; + break; + } + if (!(ifrflags.lifr_flags & IFF_UP)) + continue; + + /* + * Get the netmask for this address on this interface. + */ + strncpy(ifrnetmask.lifr_name, ifrp->lifr_name, + sizeof(ifrnetmask.lifr_name)); + memcpy(&ifrnetmask.lifr_addr, &ifrp->lifr_addr, + sizeof(ifrnetmask.lifr_addr)); + if (ioctl(fd, SIOCGLIFNETMASK, (char *)&ifrnetmask) < 0) { + if (errno == EADDRNOTAVAIL) { + /* + * Not available. + */ + netmask = NULL; + } else { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGLIFNETMASK: %.*s: %s", + (int)sizeof(ifrnetmask.lifr_name), + ifrnetmask.lifr_name, + pcap_strerror(errno)); + ret = -1; + break; + } + } else + netmask = (struct sockaddr *)&ifrnetmask.lifr_addr; + + /* + * Get the broadcast address for this address on this + * interface (if any). + */ + if (ifrflags.lifr_flags & IFF_BROADCAST) { + strncpy(ifrbroadaddr.lifr_name, ifrp->lifr_name, + sizeof(ifrbroadaddr.lifr_name)); + memcpy(&ifrbroadaddr.lifr_addr, &ifrp->lifr_addr, + sizeof(ifrbroadaddr.lifr_addr)); + if (ioctl(fd, SIOCGLIFBRDADDR, + (char *)&ifrbroadaddr) < 0) { + if (errno == EADDRNOTAVAIL) { + /* + * Not available. + */ + broadaddr = NULL; + } else { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGLIFBRDADDR: %.*s: %s", + (int)sizeof(ifrbroadaddr.lifr_name), + ifrbroadaddr.lifr_name, + pcap_strerror(errno)); + ret = -1; + break; + } + } else + broadaddr = (struct sockaddr *)&ifrbroadaddr.lifr_broadaddr; + } else { + /* + * Not a broadcast interface, so no broadcast + * address. + */ + broadaddr = NULL; + } + + /* + * Get the destination address for this address on this + * interface (if any). + */ + if (ifrflags.lifr_flags & IFF_POINTOPOINT) { + strncpy(ifrdstaddr.lifr_name, ifrp->lifr_name, + sizeof(ifrdstaddr.lifr_name)); + memcpy(&ifrdstaddr.lifr_addr, &ifrp->lifr_addr, + sizeof(ifrdstaddr.lifr_addr)); + if (ioctl(fd, SIOCGLIFDSTADDR, + (char *)&ifrdstaddr) < 0) { + if (errno == EADDRNOTAVAIL) { + /* + * Not available. + */ + dstaddr = NULL; + } else { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGLIFDSTADDR: %.*s: %s", + (int)sizeof(ifrdstaddr.lifr_name), + ifrdstaddr.lifr_name, + pcap_strerror(errno)); + ret = -1; + break; + } + } else + dstaddr = (struct sockaddr *)&ifrdstaddr.lifr_dstaddr; + } else + dstaddr = NULL; + +#ifdef HAVE_SOLARIS + /* + * If this entry has a colon followed by a number at + * the end, it's a logical interface. Those are just + * the way you assign multiple IP addresses to a real + * interface, so an entry for a logical interface should + * be treated like the entry for the real interface; + * we do that by stripping off the ":" and the number. + */ + p = strchr(ifrp->lifr_name, ':'); + if (p != NULL) { + /* + * We have a ":"; is it followed by a number? + */ + q = p + 1; + while (isdigit((unsigned char)*q)) + q++; + if (*q == '\0') { + /* + * All digits after the ":" until the end. + * Strip off the ":" and everything after + * it. + */ + *p = '\0'; + } + } +#endif + + /* + * Add information for this address to the list. + */ + if (add_addr_to_iflist(&devlist, ifrp->lifr_name, + ifrflags.lifr_flags, (struct sockaddr *)&ifrp->lifr_addr, + sizeof (struct sockaddr_storage), + netmask, sizeof (struct sockaddr_storage), + broadaddr, sizeof (struct sockaddr_storage), + dstaddr, sizeof (struct sockaddr_storage), errbuf) < 0) { + ret = -1; + break; + } + } + free(buf); + (void)close(fd6); + (void)close(fd4); + + if (ret != -1) { + /* + * We haven't had any errors yet; do any platform-specific + * operations to add devices. + */ + if (pcap_platform_finddevs(&devlist, errbuf) < 0) + ret = -1; + } + + if (ret == -1) { + /* + * We had an error; free the list we've been constructing. + */ + if (devlist != NULL) { + pcap_freealldevs(devlist); + devlist = NULL; + } + } + + *alldevsp = devlist; + return (ret); +} diff --git a/winpcap/wpcap/libpcap/fad-null.c b/winpcap/wpcap/libpcap/fad-null.c new file mode 100644 index 0000000..676ff71 --- /dev/null +++ b/winpcap/wpcap/libpcap/fad-null.c @@ -0,0 +1,65 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1994, 1995, 1996, 1997, 1998 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/fad-null.c,v 1.2 2003/11/15 23:23:58 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +/* + * Get a list of all interfaces that are up and that we can open. + * Returns -1 on error, 0 otherwise. + * The list, as returned through "alldevsp", may be null if no interfaces + * were up and could be opened. + * + * This is the implementation used on platforms that have no support for + * packet capture. + */ +int +pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) +{ + /* + * Succeed, but don't return any interfaces; we return only those + * we can open, and we can't open any if there's no support + * for packet capture. + */ + *alldevsp = NULL; + return (0); +} diff --git a/winpcap/wpcap/libpcap/fad-win32.c b/winpcap/wpcap/libpcap/fad-win32.c new file mode 100644 index 0000000..4d2c01e --- /dev/null +++ b/winpcap/wpcap/libpcap/fad-win32.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/fad-win32.c,v 1.11.2.3 2006/02/22 17:09:32 gianluca Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +/* + * Add an entry to the list of addresses for an interface. + * "curdev" is the entry for that interface. + */ +static int +add_addr_to_list(pcap_if_t *curdev, struct sockaddr *addr, + struct sockaddr *netmask, struct sockaddr *broadaddr, + struct sockaddr *dstaddr, char *errbuf) +{ + pcap_addr_t *curaddr, *prevaddr, *nextaddr; + + /* + * Allocate the new entry and fill it in. + */ + curaddr = (pcap_addr_t*)malloc(sizeof(pcap_addr_t)); + if (curaddr == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + return (-1); + } + + curaddr->next = NULL; + if (addr != NULL) { + curaddr->addr = (struct sockaddr*)dup_sockaddr(addr, sizeof(struct sockaddr_storage)); + if (curaddr->addr == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + free(curaddr); + return (-1); + } + } else + curaddr->addr = NULL; + + if (netmask != NULL) { + curaddr->netmask = (struct sockaddr*)dup_sockaddr(netmask, sizeof(struct sockaddr_storage)); + if (curaddr->netmask == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + free(curaddr); + return (-1); + } + } else + curaddr->netmask = NULL; + + if (broadaddr != NULL) { + curaddr->broadaddr = (struct sockaddr*)dup_sockaddr(broadaddr, sizeof(struct sockaddr_storage)); + if (curaddr->broadaddr == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + free(curaddr); + return (-1); + } + } else + curaddr->broadaddr = NULL; + + if (dstaddr != NULL) { + curaddr->dstaddr = (struct sockaddr*)dup_sockaddr(dstaddr, sizeof(struct sockaddr_storage)); + if (curaddr->dstaddr == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + free(curaddr); + return (-1); + } + } else + curaddr->dstaddr = NULL; + + /* + * Find the end of the list of addresses. + */ + for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) { + nextaddr = prevaddr->next; + if (nextaddr == NULL) { + /* + * This is the end of the list. + */ + break; + } + } + + if (prevaddr == NULL) { + /* + * The list was empty; this is the first member. + */ + curdev->addresses = curaddr; + } else { + /* + * "prevaddr" is the last member of the list; append + * this member to it. + */ + prevaddr->next = curaddr; + } + + return (0); +} + + +static int +pcap_add_if_win32(pcap_if_t **devlist, char *name, const char *desc, + char *errbuf) +{ + pcap_if_t *curdev; + npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES]; + LONG if_addr_size; + int res = 0; + + if_addr_size = MAX_NETWORK_ADDRESSES; + + /* + * Add an entry for this interface, with no addresses. + */ + if (add_or_find_if(&curdev, devlist, name, 0, desc, errbuf) == -1) { + /* + * Failure. + */ + return (-1); + } + + /* + * Get the list of addresses for the interface. + */ + if (!PacketGetNetInfoEx((void *)name, if_addrs, &if_addr_size)) { + /* + * Failure. + * + * We don't return an error, because this can happen with + * NdisWan interfaces, and we want to supply them even + * if we can't supply their addresses. + * + * We return an entry with an empty address list. + */ + return (0); + } + + /* + * Now add the addresses. + */ + while (if_addr_size-- > 0) { + /* + * "curdev" is an entry for this interface; add an entry for + * this address to its list of addresses. + */ + if(curdev == NULL) + break; + res = add_addr_to_list(curdev, + (struct sockaddr *)&if_addrs[if_addr_size].IPAddress, + (struct sockaddr *)&if_addrs[if_addr_size].SubnetMask, + (struct sockaddr *)&if_addrs[if_addr_size].Broadcast, + NULL, + errbuf); + if (res == -1) { + /* + * Failure. + */ + break; + } + } + + return (res); +} + + +/* + * Get a list of all interfaces that are up and that we can open. + * Returns -1 on error, 0 otherwise. + * The list, as returned through "alldevsp", may be null if no interfaces + * were up and could be opened. + * + * Win32 implementation, based on WinPcap + */ +int +pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) +{ + pcap_if_t *devlist = NULL; + int ret = 0; + const char *desc; + char *AdaptersName; + ULONG NameLength; + char *name; + + if (!PacketGetAdapterNames(NULL, &NameLength)) + { + DWORD last_error = GetLastError(); + + if (last_error != ERROR_INSUFFICIENT_BUFFER) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "PacketGetAdapterNames: %s", + pcap_win32strerror()); + return (-1); + } + } + + if (NameLength > 0) + AdaptersName = (char*) malloc(NameLength); + else + { + *alldevsp = NULL; + return 0; + } + if (AdaptersName == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters."); + return (-1); + } + + if (!PacketGetAdapterNames(AdaptersName, &NameLength)) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "PacketGetAdapterNames: %s", + pcap_win32strerror()); + free(AdaptersName); + return (-1); + } + + /* + * "PacketGetAdapterNames()" returned a list of + * null-terminated ASCII interface name strings, + * terminated by a null string, followed by a list + * of null-terminated ASCII interface description + * strings, terminated by a null string. + * This means there are two ASCII nulls at the end + * of the first list. + * + * Find the end of the first list; that's the + * beginning of the second list. + */ + desc = &AdaptersName[0]; + while (*desc != '\0' || *(desc + 1) != '\0') + desc++; + + /* + * Found it - "desc" points to the first of the two + * nulls at the end of the list of names, so the + * first byte of the list of descriptions is two bytes + * after it. + */ + desc += 2; + + /* + * Loop over the elements in the first list. + */ + name = &AdaptersName[0]; + while (*name != '\0') { + /* + * Add an entry for this interface. + */ + if (pcap_add_if_win32(&devlist, name, desc, errbuf) == -1) { + /* + * Failure. + */ + ret = -1; + break; + } + name += strlen(name) + 1; + desc += strlen(desc) + 1; + } + + if (ret == -1) { + /* + * We had an error; free the list we've been constructing. + */ + if (devlist != NULL) { + pcap_freealldevs(devlist); + devlist = NULL; + } + } + + *alldevsp = devlist; + free(AdaptersName); + return (ret); +} diff --git a/winpcap/wpcap/libpcap/gencode.c b/winpcap/wpcap/libpcap/gencode.c new file mode 100644 index 0000000..0d57152 --- /dev/null +++ b/winpcap/wpcap/libpcap/gencode.c @@ -0,0 +1,6944 @@ +/*#define CHASE_CHAIN*/ +/* + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.221.2.43 2006/09/13 07:36:19 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include +#else /* WIN32 */ +#include +#include +#endif /* WIN32 */ + +/* + * XXX - why was this included even on UNIX? + */ +#ifdef __MINGW32__ +#include "IP6_misc.h" +#endif + +#ifndef WIN32 + +#ifdef __NetBSD__ +#include +#endif + +#include + +#endif /* WIN32 */ + +#include +#include +#include +#include +#include + +#ifdef MSDOS +#include "pcap-dos.h" +#endif + +#include "pcap-int.h" + +#include "ethertype.h" +#include "nlpid.h" +#include "llc.h" +#include "gencode.h" +#include "atmuni31.h" +#include "sunatmpos.h" +#include "ppp.h" +#include "sll.h" +#include "arcnet.h" +#include "pf.h" +#ifndef offsetof +#define offsetof(s, e) ((size_t)&((s *)0)->e) +#endif +#ifdef INET6 +#ifndef WIN32 +#include /* for "struct addrinfo" */ +#endif /* WIN32 */ +#endif /*INET6*/ +#include + +#define ETHERMTU 1500 + +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#define JMP(c) ((c)|BPF_JMP|BPF_K) + +/* Locals */ +static jmp_buf top_ctx; +static pcap_t *bpf_pcap; + +/* Hack for updating VLAN, MPLS, and PPPoE offsets. */ +static u_int orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U; + +/* XXX */ +#ifdef PCAP_FDDIPAD +static int pcap_fddipad; +#endif + +/* VARARGS */ +void +bpf_error(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (bpf_pcap != NULL) + (void)vsnprintf(pcap_geterr(bpf_pcap), PCAP_ERRBUF_SIZE, + fmt, ap); + va_end(ap); + longjmp(top_ctx, 1); + /* NOTREACHED */ +} + +static void init_linktype(pcap_t *); + +static int alloc_reg(void); +static void free_reg(int); + +static struct block *root; + +/* + * Value passed to gen_load_a() to indicate what the offset argument + * is relative to. + */ +enum e_offrel { + OR_PACKET, /* relative to the beginning of the packet */ + OR_LINK, /* relative to the link-layer header */ + OR_NET, /* relative to the network-layer header */ + OR_NET_NOSNAP, /* relative to the network-layer header, with no SNAP header at the link layer */ + OR_TRAN_IPV4, /* relative to the transport-layer header, with IPv4 network layer */ + OR_TRAN_IPV6 /* relative to the transport-layer header, with IPv6 network layer */ +}; + +/* + * We divy out chunks of memory rather than call malloc each time so + * we don't have to worry about leaking memory. It's probably + * not a big deal if all this memory was wasted but if this ever + * goes into a library that would probably not be a good idea. + * + * XXX - this *is* in a library.... + */ +#define NCHUNKS 16 +#define CHUNK0SIZE 1024 +struct chunk { + u_int n_left; + void *m; +}; + +static struct chunk chunks[NCHUNKS]; +static int cur_chunk; + +static void *newchunk(u_int); +static void freechunks(void); +static inline struct block *new_block(int); +static inline struct slist *new_stmt(int); +static struct block *gen_retblk(int); +static inline void syntax(void); + +static void backpatch(struct block *, struct block *); +static void merge(struct block *, struct block *); +static struct block *gen_cmp(enum e_offrel, u_int, u_int, bpf_int32); +static struct block *gen_cmp_gt(enum e_offrel, u_int, u_int, bpf_int32); +static struct block *gen_cmp_ge(enum e_offrel, u_int, u_int, bpf_int32); +static struct block *gen_cmp_lt(enum e_offrel, u_int, u_int, bpf_int32); +static struct block *gen_cmp_le(enum e_offrel, u_int, u_int, bpf_int32); +static struct block *gen_mcmp(enum e_offrel, u_int, u_int, bpf_int32, + bpf_u_int32); +static struct block *gen_bcmp(enum e_offrel, u_int, u_int, const u_char *); +static struct block *gen_ncmp(enum e_offrel, bpf_u_int32, bpf_u_int32, + bpf_u_int32, bpf_u_int32, int, bpf_int32); +static struct slist *gen_load_llrel(u_int, u_int); +static struct slist *gen_load_a(enum e_offrel, u_int, u_int); +static struct slist *gen_loadx_iphdrlen(void); +static struct block *gen_uncond(int); +static inline struct block *gen_true(void); +static inline struct block *gen_false(void); +static struct block *gen_ether_linktype(int); +static struct block *gen_linux_sll_linktype(int); +static void insert_radiotap_load_llprefixlen(struct block *); +static void insert_load_llprefixlen(struct block *); +static struct slist *gen_llprefixlen(void); +static struct block *gen_linktype(int); +static struct block *gen_snap(bpf_u_int32, bpf_u_int32, u_int); +static struct block *gen_llc_linktype(int); +static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int); +#ifdef INET6 +static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int); +#endif +static struct block *gen_ahostop(const u_char *, int); +static struct block *gen_ehostop(const u_char *, int); +static struct block *gen_fhostop(const u_char *, int); +static struct block *gen_thostop(const u_char *, int); +static struct block *gen_wlanhostop(const u_char *, int); +static struct block *gen_ipfchostop(const u_char *, int); +static struct block *gen_dnhostop(bpf_u_int32, int); +static struct block *gen_mpls_linktype(int); +static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int, int); +#ifdef INET6 +static struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int, int); +#endif +#ifndef INET6 +static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int); +#endif +static struct block *gen_ipfrag(void); +static struct block *gen_portatom(int, bpf_int32); +static struct block *gen_portrangeatom(int, bpf_int32, bpf_int32); +#ifdef INET6 +static struct block *gen_portatom6(int, bpf_int32); +static struct block *gen_portrangeatom6(int, bpf_int32, bpf_int32); +#endif +struct block *gen_portop(int, int, int); +static struct block *gen_port(int, int, int); +struct block *gen_portrangeop(int, int, int, int); +static struct block *gen_portrange(int, int, int, int); +#ifdef INET6 +struct block *gen_portop6(int, int, int); +static struct block *gen_port6(int, int, int); +struct block *gen_portrangeop6(int, int, int, int); +static struct block *gen_portrange6(int, int, int, int); +#endif +static int lookup_proto(const char *, int); +static struct block *gen_protochain(int, int, int); +static struct block *gen_proto(int, int, int); +static struct slist *xfer_to_x(struct arth *); +static struct slist *xfer_to_a(struct arth *); +static struct block *gen_mac_multicast(int); +static struct block *gen_len(int, int); + +static struct block *gen_msg_abbrev(int type); + +static void * +newchunk(n) + u_int n; +{ + struct chunk *cp; + int k; + size_t size; + +#ifndef __NetBSD__ + /* XXX Round up to nearest long. */ + n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1); +#else + /* XXX Round up to structure boundary. */ + n = ALIGN(n); +#endif + + cp = &chunks[cur_chunk]; + if (n > cp->n_left) { + ++cp, k = ++cur_chunk; + if (k >= NCHUNKS) + bpf_error("out of memory"); + size = CHUNK0SIZE << k; + cp->m = (void *)malloc(size); + if (cp->m == NULL) + bpf_error("out of memory"); + memset((char *)cp->m, 0, size); + cp->n_left = size; + if (n > size) + bpf_error("out of memory"); + } + cp->n_left -= n; + return (void *)((char *)cp->m + cp->n_left); +} + +static void +freechunks() +{ + int i; + + cur_chunk = 0; + for (i = 0; i < NCHUNKS; ++i) + if (chunks[i].m != NULL) { + free(chunks[i].m); + chunks[i].m = NULL; + } +} + +/* + * A strdup whose allocations are freed after code generation is over. + */ +char * +sdup(s) + register const char *s; +{ + int n = strlen(s) + 1; + char *cp = newchunk(n); + + strlcpy(cp, s, n); + return (cp); +} + +static inline struct block * +new_block(code) + int code; +{ + struct block *p; + + p = (struct block *)newchunk(sizeof(*p)); + p->s.code = code; + p->head = p; + + return p; +} + +static inline struct slist * +new_stmt(code) + int code; +{ + struct slist *p; + + p = (struct slist *)newchunk(sizeof(*p)); + p->s.code = code; + + return p; +} + +static struct block * +gen_retblk(v) + int v; +{ + struct block *b = new_block(BPF_RET|BPF_K); + + b->s.k = v; + return b; +} + +static inline void +syntax() +{ + bpf_error("syntax error in filter expression"); +} + +static bpf_u_int32 netmask; +static int snaplen; +int no_optimize; + +int +pcap_compile(pcap_t *p, struct bpf_program *program, + char *buf, int optimize, bpf_u_int32 mask) +{ + extern int n_errors; + int len; + +#ifdef HAVE_REMOTE + /* + Check if: + - We are on an remote capture + - we do not want to capture RPCAP traffic + + If so, we have to save the current filter, because we have to add some + piece of stuff later + */ + if ( (p->rmt_clientside) && (p->rmt_flags & PCAP_OPENFLAG_NOCAPTURE_RPCAP) ) + { + int bufferlen; + + if (p->currentfilter) + free (p->currentfilter); + + if (buf) + bufferlen= strlen(buf) + 1; + else + bufferlen= 1; + + p->currentfilter= (char *) malloc( sizeof(char) * bufferlen); + + strncpy(p->currentfilter, buf, bufferlen); + + p->currentfilter[bufferlen - 1]= 0; + } +#endif /* HAVE_REMOTE */ + + no_optimize = 0; + n_errors = 0; + root = NULL; + bpf_pcap = p; + if (setjmp(top_ctx)) { + lex_cleanup(); + freechunks(); + return (-1); + } + + netmask = mask; + + snaplen = pcap_snapshot(p); + if (snaplen == 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "snaplen of 0 rejects all packets"); + return -1; + } + + lex_init(buf ? buf : ""); + init_linktype(p); + (void)pcap_parse(); + + if (n_errors) + syntax(); + + if (root == NULL) + root = gen_retblk(snaplen); + + if (optimize && !no_optimize) { + bpf_optimize(&root); + if (root == NULL || + (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0)) + bpf_error("expression rejects all packets"); + } + program->bf_insns = icode_to_fcode(root, &len); + program->bf_len = len; + + lex_cleanup(); + freechunks(); + return (0); +} + +/* + * entry point for using the compiler with no pcap open + * pass in all the stuff that is needed explicitly instead. + */ +int +pcap_compile_nopcap(int snaplen_arg, int linktype_arg, + struct bpf_program *program, + char *buf, int optimize, bpf_u_int32 mask) +{ + pcap_t *p; + int ret; + + p = pcap_open_dead(linktype_arg, snaplen_arg); + if (p == NULL) + return (-1); + ret = pcap_compile(p, program, buf, optimize, mask); + pcap_close(p); + return (ret); +} + +/* + * Clean up a "struct bpf_program" by freeing all the memory allocated + * in it. + */ +void +pcap_freecode(struct bpf_program *program) +{ + program->bf_len = 0; + if (program->bf_insns != NULL) { + free((char *)program->bf_insns); + program->bf_insns = NULL; + } +} + +/* + * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates + * which of the jt and jf fields has been resolved and which is a pointer + * back to another unresolved block (or nil). At least one of the fields + * in each block is already resolved. + */ +static void +backpatch(list, target) + struct block *list, *target; +{ + struct block *next; + + while (list) { + if (!list->sense) { + next = JT(list); + JT(list) = target; + } else { + next = JF(list); + JF(list) = target; + } + list = next; + } +} + +/* + * Merge the lists in b0 and b1, using the 'sense' field to indicate + * which of jt and jf is the link. + */ +static void +merge(b0, b1) + struct block *b0, *b1; +{ + register struct block **p = &b0; + + /* Find end of list. */ + while (*p) + p = !((*p)->sense) ? &JT(*p) : &JF(*p); + + /* Concatenate the lists. */ + *p = b1; +} + +void +finish_parse(p) + struct block *p; +{ + backpatch(p, gen_retblk(snaplen)); + p->sense = !p->sense; + backpatch(p, gen_retblk(0)); + root = p->head; + + /* + * Insert before the statements of the first (root) block any + * statements needed to load the lengths of any variable-length + * headers into registers. + * + * XXX - a fancier strategy would be to insert those before the + * statements of all blocks that use those lengths and that + * have no predecessors that use them, so that we only compute + * the lengths if we need them. There might be even better + * approaches than that. However, as we're currently only + * handling variable-length radiotap headers, and as all + * filtering expressions other than raw link[M:N] tests + * require the length of that header, doing more for that + * header length isn't really worth the effort. + */ + insert_load_llprefixlen(root); +} + +void +gen_and(b0, b1) + struct block *b0, *b1; +{ + backpatch(b0, b1->head); + b0->sense = !b0->sense; + b1->sense = !b1->sense; + merge(b1, b0); + b1->sense = !b1->sense; + b1->head = b0->head; +} + +void +gen_or(b0, b1) + struct block *b0, *b1; +{ + b0->sense = !b0->sense; + backpatch(b0, b1->head); + b0->sense = !b0->sense; + merge(b1, b0); + b1->head = b0->head; +} + +void +gen_not(b) + struct block *b; +{ + b->sense = !b->sense; +} + +static struct block * +gen_cmp(offrel, offset, size, v) + enum e_offrel offrel; + u_int offset, size; + bpf_int32 v; +{ + return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JEQ, 0, v); +} + +static struct block * +gen_cmp_gt(offrel, offset, size, v) + enum e_offrel offrel; + u_int offset, size; + bpf_int32 v; +{ + return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGT, 0, v); +} + +static struct block * +gen_cmp_ge(offrel, offset, size, v) + enum e_offrel offrel; + u_int offset, size; + bpf_int32 v; +{ + return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGE, 0, v); +} + +static struct block * +gen_cmp_lt(offrel, offset, size, v) + enum e_offrel offrel; + u_int offset, size; + bpf_int32 v; +{ + return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGE, 1, v); +} + +static struct block * +gen_cmp_le(offrel, offset, size, v) + enum e_offrel offrel; + u_int offset, size; + bpf_int32 v; +{ + return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGT, 1, v); +} + +static struct block * +gen_mcmp(offrel, offset, size, v, mask) + enum e_offrel offrel; + u_int offset, size; + bpf_int32 v; + bpf_u_int32 mask; +{ + return gen_ncmp(offrel, offset, size, mask, BPF_JEQ, 0, v); +} + +static struct block * +gen_bcmp(offrel, offset, size, v) + enum e_offrel offrel; + register u_int offset, size; + register const u_char *v; +{ + register struct block *b, *tmp; + + b = NULL; + while (size >= 4) { + register const u_char *p = &v[size - 4]; + bpf_int32 w = ((bpf_int32)p[0] << 24) | + ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3]; + + tmp = gen_cmp(offrel, offset + size - 4, BPF_W, w); + if (b != NULL) + gen_and(b, tmp); + b = tmp; + size -= 4; + } + while (size >= 2) { + register const u_char *p = &v[size - 2]; + bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1]; + + tmp = gen_cmp(offrel, offset + size - 2, BPF_H, w); + if (b != NULL) + gen_and(b, tmp); + b = tmp; + size -= 2; + } + if (size > 0) { + tmp = gen_cmp(offrel, offset, BPF_B, (bpf_int32)v[0]); + if (b != NULL) + gen_and(b, tmp); + b = tmp; + } + return b; +} + +/* + * AND the field of size "size" at offset "offset" relative to the header + * specified by "offrel" with "mask", and compare it with the value "v" + * with the test specified by "jtype"; if "reverse" is true, the test + * should test the opposite of "jtype". + */ +static struct block * +gen_ncmp(offrel, offset, size, mask, jtype, reverse, v) + enum e_offrel offrel; + bpf_int32 v; + bpf_u_int32 offset, size, mask, jtype; + int reverse; +{ + struct slist *s, *s2; + struct block *b; + + s = gen_load_a(offrel, offset, size); + + if (mask != 0xffffffff) { + s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K); + s2->s.k = mask; + sappend(s, s2); + } + + b = new_block(JMP(jtype)); + b->stmts = s; + b->s.k = v; + if (reverse && (jtype == BPF_JGT || jtype == BPF_JGE)) + gen_not(b); + return b; +} + +/* + * Various code constructs need to know the layout of the data link + * layer. These variables give the necessary offsets from the beginning + * of the packet data. + * + * If the link layer has variable_length headers, the offsets are offsets + * from the end of the link-link-layer header, and "reg_ll_size" is + * the register number for a register containing the length of the + * link-layer header. Otherwise, "reg_ll_size" is -1. + */ +static int reg_ll_size; + +/* + * This is the offset of the beginning of the link-layer header from + * the beginning of the raw packet data. + * + * It's usually 0, except for 802.11 with a fixed-length radio header. + * (For 802.11 with a variable-length radio header, we have to generate + * code to compute that offset; off_ll is 0 in that case.) + */ +static u_int off_ll; + +/* + * This is the offset of the beginning of the MAC-layer header. + * It's usually 0, except for ATM LANE, where it's the offset, relative + * to the beginning of the raw packet data, of the Ethernet header. + */ +static u_int off_mac; + +/* + * "off_linktype" is the offset to information in the link-layer header + * giving the packet type. This offset is relative to the beginning + * of the link-layer header (i.e., it doesn't include off_ll). + * + * For Ethernet, it's the offset of the Ethernet type field. + * + * For link-layer types that always use 802.2 headers, it's the + * offset of the LLC header. + * + * For PPP, it's the offset of the PPP type field. + * + * For Cisco HDLC, it's the offset of the CHDLC type field. + * + * For BSD loopback, it's the offset of the AF_ value. + * + * For Linux cooked sockets, it's the offset of the type field. + * + * It's set to -1 for no encapsulation, in which case, IP is assumed. + */ +static u_int off_linktype; + +/* + * TRUE if the link layer includes an ATM pseudo-header. + */ +static int is_atm = 0; + +/* + * TRUE if "lane" appeared in the filter; it causes us to generate + * code that assumes LANE rather than LLC-encapsulated traffic in SunATM. + */ +static int is_lane = 0; + +/* + * These are offsets for the ATM pseudo-header. + */ +static u_int off_vpi; +static u_int off_vci; +static u_int off_proto; + +/* + * These are offsets for the MTP3 fields. + */ +static u_int off_sio; +static u_int off_opc; +static u_int off_dpc; +static u_int off_sls; + +/* + * This is the offset of the first byte after the ATM pseudo_header, + * or -1 if there is no ATM pseudo-header. + */ +static u_int off_payload; + +/* + * These are offsets to the beginning of the network-layer header. + * They are relative to the beginning of the link-layer header (i.e., + * they don't include off_ll). + * + * If the link layer never uses 802.2 LLC: + * + * "off_nl" and "off_nl_nosnap" are the same. + * + * If the link layer always uses 802.2 LLC: + * + * "off_nl" is the offset if there's a SNAP header following + * the 802.2 header; + * + * "off_nl_nosnap" is the offset if there's no SNAP header. + * + * If the link layer is Ethernet: + * + * "off_nl" is the offset if the packet is an Ethernet II packet + * (we assume no 802.3+802.2+SNAP); + * + * "off_nl_nosnap" is the offset if the packet is an 802.3 packet + * with an 802.2 header following it. + */ +static u_int off_nl; +static u_int off_nl_nosnap; + +static int linktype; + +static void +init_linktype(p) + pcap_t *p; +{ + linktype = pcap_datalink(p); +#ifdef PCAP_FDDIPAD + pcap_fddipad = p->fddipad; +#endif + + /* + * Assume it's not raw ATM with a pseudo-header, for now. + */ + off_mac = 0; + is_atm = 0; + is_lane = 0; + off_vpi = -1; + off_vci = -1; + off_proto = -1; + off_payload = -1; + + /* + * And assume we're not doing SS7. + */ + off_sio = -1; + off_opc = -1; + off_dpc = -1; + off_sls = -1; + + /* + * Also assume it's not 802.11 with a fixed-length radio header. + */ + off_ll = 0; + + orig_linktype = -1; + orig_nl = -1; + label_stack_depth = 0; + + reg_ll_size = -1; + + switch (linktype) { + + case DLT_ARCNET: + off_linktype = 2; + off_nl = 6; /* XXX in reality, variable! */ + off_nl_nosnap = 6; /* no 802.2 LLC */ + return; + + case DLT_ARCNET_LINUX: + off_linktype = 4; + off_nl = 8; /* XXX in reality, variable! */ + off_nl_nosnap = 8; /* no 802.2 LLC */ + return; + + case DLT_EN10MB: + off_linktype = 12; + off_nl = 14; /* Ethernet II */ + off_nl_nosnap = 17; /* 802.3+802.2 */ + return; + + case DLT_SLIP: + /* + * SLIP doesn't have a link level type. The 16 byte + * header is hacked into our SLIP driver. + */ + off_linktype = -1; + off_nl = 16; + off_nl_nosnap = 16; /* no 802.2 LLC */ + return; + + case DLT_SLIP_BSDOS: + /* XXX this may be the same as the DLT_PPP_BSDOS case */ + off_linktype = -1; + /* XXX end */ + off_nl = 24; + off_nl_nosnap = 24; /* no 802.2 LLC */ + return; + + case DLT_NULL: + case DLT_LOOP: + off_linktype = 0; + off_nl = 4; + off_nl_nosnap = 4; /* no 802.2 LLC */ + return; + + case DLT_ENC: + off_linktype = 0; + off_nl = 12; + off_nl_nosnap = 12; /* no 802.2 LLC */ + return; + + case DLT_PPP: + case DLT_PPP_PPPD: + case DLT_C_HDLC: /* BSD/OS Cisco HDLC */ + case DLT_PPP_SERIAL: /* NetBSD sync/async serial PPP */ + off_linktype = 2; + off_nl = 4; + off_nl_nosnap = 4; /* no 802.2 LLC */ + return; + + case DLT_PPP_ETHER: + /* + * This does no include the Ethernet header, and + * only covers session state. + */ + off_linktype = 6; + off_nl = 8; + off_nl_nosnap = 8; /* no 802.2 LLC */ + return; + + case DLT_PPP_BSDOS: + off_linktype = 5; + off_nl = 24; + off_nl_nosnap = 24; /* no 802.2 LLC */ + return; + + case DLT_FDDI: + /* + * FDDI doesn't really have a link-level type field. + * We set "off_linktype" to the offset of the LLC header. + * + * To check for Ethernet types, we assume that SSAP = SNAP + * is being used and pick out the encapsulated Ethernet type. + * XXX - should we generate code to check for SNAP? + */ + off_linktype = 13; +#ifdef PCAP_FDDIPAD + off_linktype += pcap_fddipad; +#endif + off_nl = 21; /* FDDI+802.2+SNAP */ + off_nl_nosnap = 16; /* FDDI+802.2 */ +#ifdef PCAP_FDDIPAD + off_nl += pcap_fddipad; + off_nl_nosnap += pcap_fddipad; +#endif + return; + + case DLT_IEEE802: + /* + * Token Ring doesn't really have a link-level type field. + * We set "off_linktype" to the offset of the LLC header. + * + * To check for Ethernet types, we assume that SSAP = SNAP + * is being used and pick out the encapsulated Ethernet type. + * XXX - should we generate code to check for SNAP? + * + * XXX - the header is actually variable-length. + * Some various Linux patched versions gave 38 + * as "off_linktype" and 40 as "off_nl"; however, + * if a token ring packet has *no* routing + * information, i.e. is not source-routed, the correct + * values are 20 and 22, as they are in the vanilla code. + * + * A packet is source-routed iff the uppermost bit + * of the first byte of the source address, at an + * offset of 8, has the uppermost bit set. If the + * packet is source-routed, the total number of bytes + * of routing information is 2 plus bits 0x1F00 of + * the 16-bit value at an offset of 14 (shifted right + * 8 - figure out which byte that is). + */ + off_linktype = 14; + off_nl = 22; /* Token Ring+802.2+SNAP */ + off_nl_nosnap = 17; /* Token Ring+802.2 */ + return; + + case DLT_IEEE802_11: + /* + * 802.11 doesn't really have a link-level type field. + * We set "off_linktype" to the offset of the LLC header. + * + * To check for Ethernet types, we assume that SSAP = SNAP + * is being used and pick out the encapsulated Ethernet type. + * XXX - should we generate code to check for SNAP? + * + * XXX - the header is actually variable-length. We + * assume a 24-byte link-layer header, as appears in + * data frames in networks with no bridges. If the + * fromds and tods 802.11 header bits are both set, + * it's actually supposed to be 30 bytes. + */ + off_linktype = 24; + off_nl = 32; /* 802.11+802.2+SNAP */ + off_nl_nosnap = 27; /* 802.11+802.2 */ + return; + + case DLT_PRISM_HEADER: + /* + * Same as 802.11, but with an additional header before + * the 802.11 header, containing a bunch of additional + * information including radio-level information. + * + * The header is 144 bytes long. + * + * XXX - same variable-length header problem; at least + * the Prism header is fixed-length. + */ + off_ll = 144; + off_linktype = 24; + off_nl = 32; /* Prism+802.11+802.2+SNAP */ + off_nl_nosnap = 27; /* Prism+802.11+802.2 */ + return; + + case DLT_IEEE802_11_RADIO_AVS: + /* + * Same as 802.11, but with an additional header before + * the 802.11 header, containing a bunch of additional + * information including radio-level information. + * + * The header is 64 bytes long, at least in its + * current incarnation. + * + * XXX - same variable-length header problem, only + * more so; this header is also variable-length, + * with the length being the 32-bit big-endian + * number at an offset of 4 from the beginning + * of the radio header. We should handle that the + * same way we handle the length at the beginning + * of the radiotap header. + * + * XXX - in Linux, do any drivers that supply an AVS + * header supply a link-layer type other than + * ARPHRD_IEEE80211_PRISM? If so, we should map that + * to DLT_IEEE802_11_RADIO_AVS; if not, or if there are + * any drivers that supply an AVS header but supply + * an ARPHRD value of ARPHRD_IEEE80211_PRISM, we'll + * have to check the header in the generated code to + * determine whether it's Prism or AVS. + */ + off_ll = 64; + off_linktype = 24; + off_nl = 32; /* Radio+802.11+802.2+SNAP */ + off_nl_nosnap = 27; /* Radio+802.11+802.2 */ + return; + + case DLT_IEEE802_11_RADIO: + /* + * Same as 802.11, but with an additional header before + * the 802.11 header, containing a bunch of additional + * information including radio-level information. + * + * The radiotap header is variable length, and we + * generate code to compute its length and store it + * in a register. These offsets are relative to the + * beginning of the 802.11 header. + */ + off_linktype = 24; + off_nl = 32; /* 802.11+802.2+SNAP */ + off_nl_nosnap = 27; /* 802.11+802.2 */ + return; + + case DLT_ATM_RFC1483: + case DLT_ATM_CLIP: /* Linux ATM defines this */ + /* + * assume routed, non-ISO PDUs + * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00) + * + * XXX - what about ISO PDUs, e.g. CLNP, ISIS, ESIS, + * or PPP with the PPP NLPID (e.g., PPPoA)? The + * latter would presumably be treated the way PPPoE + * should be, so you can do "pppoe and udp port 2049" + * or "pppoa and tcp port 80" and have it check for + * PPPo{A,E} and a PPP protocol of IP and.... + */ + off_linktype = 0; + off_nl = 8; /* 802.2+SNAP */ + off_nl_nosnap = 3; /* 802.2 */ + return; + + case DLT_SUNATM: + /* + * Full Frontal ATM; you get AALn PDUs with an ATM + * pseudo-header. + */ + is_atm = 1; + off_vpi = SUNATM_VPI_POS; + off_vci = SUNATM_VCI_POS; + off_proto = PROTO_POS; + off_mac = -1; /* LLC-encapsulated, so no MAC-layer header */ + off_payload = SUNATM_PKT_BEGIN_POS; + off_linktype = off_payload; + off_nl = off_payload+8; /* 802.2+SNAP */ + off_nl_nosnap = off_payload+3; /* 802.2 */ + return; + + case DLT_RAW: + off_linktype = -1; + off_nl = 0; + off_nl_nosnap = 0; /* no 802.2 LLC */ + return; + + case DLT_LINUX_SLL: /* fake header for Linux cooked socket */ + off_linktype = 14; + off_nl = 16; + off_nl_nosnap = 16; /* no 802.2 LLC */ + return; + + case DLT_LTALK: + /* + * LocalTalk does have a 1-byte type field in the LLAP header, + * but really it just indicates whether there is a "short" or + * "long" DDP packet following. + */ + off_linktype = -1; + off_nl = 0; + off_nl_nosnap = 0; /* no 802.2 LLC */ + return; + + case DLT_IP_OVER_FC: + /* + * RFC 2625 IP-over-Fibre-Channel doesn't really have a + * link-level type field. We set "off_linktype" to the + * offset of the LLC header. + * + * To check for Ethernet types, we assume that SSAP = SNAP + * is being used and pick out the encapsulated Ethernet type. + * XXX - should we generate code to check for SNAP? RFC + * 2625 says SNAP should be used. + */ + off_linktype = 16; + off_nl = 24; /* IPFC+802.2+SNAP */ + off_nl_nosnap = 19; /* IPFC+802.2 */ + return; + + case DLT_FRELAY: + /* + * XXX - we should set this to handle SNAP-encapsulated + * frames (NLPID of 0x80). + */ + off_linktype = -1; + off_nl = 0; + off_nl_nosnap = 0; /* no 802.2 LLC */ + return; + + /* + * the only BPF-interesting FRF.16 frames are non-control frames; + * Frame Relay has a variable length link-layer + * so lets start with offset 4 for now and increments later on (FIXME); + */ + case DLT_MFR: + off_linktype = -1; + off_nl = 4; + off_nl_nosnap = 0; /* XXX - for now -> no 802.2 LLC */ + return; + + case DLT_APPLE_IP_OVER_IEEE1394: + off_linktype = 16; + off_nl = 18; + off_nl_nosnap = 18; /* no 802.2 LLC */ + return; + + case DLT_LINUX_IRDA: + /* + * Currently, only raw "link[N:M]" filtering is supported. + */ + off_linktype = -1; + off_nl = -1; + off_nl_nosnap = -1; + return; + + case DLT_DOCSIS: + /* + * Currently, only raw "link[N:M]" filtering is supported. + */ + off_linktype = -1; + off_nl = -1; + off_nl_nosnap = -1; + return; + + case DLT_SYMANTEC_FIREWALL: + off_linktype = 6; + off_nl = 44; /* Ethernet II */ + off_nl_nosnap = 44; /* XXX - what does it do with 802.3 packets? */ + return; + + case DLT_PFLOG: + off_linktype = 0; + /* XXX read this from pf.h? */ + off_nl = PFLOG_HDRLEN; + off_nl_nosnap = PFLOG_HDRLEN; /* no 802.2 LLC */ + return; + + case DLT_JUNIPER_MFR: + case DLT_JUNIPER_MLFR: + case DLT_JUNIPER_MLPPP: + case DLT_JUNIPER_PPP: + case DLT_JUNIPER_CHDLC: + case DLT_JUNIPER_FRELAY: + off_linktype = 4; + off_nl = 4; + off_nl_nosnap = -1; /* no 802.2 LLC */ + return; + + case DLT_JUNIPER_ATM1: + off_linktype = 4; /* in reality variable between 4-8 */ + off_nl = 4; + off_nl_nosnap = 14; + return; + + case DLT_JUNIPER_ATM2: + off_linktype = 8; /* in reality variable between 8-12 */ + off_nl = 8; + off_nl_nosnap = 18; + return; + + /* frames captured on a Juniper PPPoE service PIC + * contain raw ethernet frames */ + case DLT_JUNIPER_PPPOE: + case DLT_JUNIPER_ETHER: + off_linktype = 16; + off_nl = 18; /* Ethernet II */ + off_nl_nosnap = 21; /* 802.3+802.2 */ + return; + + case DLT_JUNIPER_PPPOE_ATM: + off_linktype = 4; + off_nl = 6; + off_nl_nosnap = -1; /* no 802.2 LLC */ + return; + + case DLT_JUNIPER_GGSN: + off_linktype = 6; + off_nl = 12; + off_nl_nosnap = -1; /* no 802.2 LLC */ + return; + + case DLT_JUNIPER_ES: + off_linktype = 6; + off_nl = -1; /* not really a network layer but raw IP adresses */ + off_nl_nosnap = -1; /* no 802.2 LLC */ + return; + + case DLT_JUNIPER_MONITOR: + off_linktype = 12; + off_nl = 12; /* raw IP/IP6 header */ + off_nl_nosnap = -1; /* no 802.2 LLC */ + return; + + case DLT_JUNIPER_SERVICES: + off_linktype = 12; + off_nl = -1; /* L3 proto location dep. on cookie type */ + off_nl_nosnap = -1; /* no 802.2 LLC */ + return; + + case DLT_MTP2: + off_sio = 3; + off_opc = 4; + off_dpc = 4; + off_sls = 7; + off_linktype = -1; + off_nl = -1; + off_nl_nosnap = -1; + return; + +#ifdef DLT_PFSYNC + case DLT_PFSYNC: + off_linktype = -1; + off_nl = 4; + off_nl_nosnap = 4; + return; +#endif + + case DLT_LINUX_LAPD: + /* + * Currently, only raw "link[N:M]" filtering is supported. + */ + off_linktype = -1; + off_nl = -1; + off_nl_nosnap = -1; + return; + } + bpf_error("unknown data link type %d", linktype); + /* NOTREACHED */ +} + +/* + * Load a value relative to the beginning of the link-layer header. + * The link-layer header doesn't necessarily begin at the beginning + * of the packet data; there might be a variable-length prefix containing + * radio information. + */ +static struct slist * +gen_load_llrel(offset, size) + u_int offset, size; +{ + struct slist *s, *s2; + + s = gen_llprefixlen(); + + /* + * If "s" is non-null, it has code to arrange that the X register + * contains the length of the prefix preceding the link-layer + * header. + * + * Otherwise, the length of the prefix preceding the link-layer + * header is "off_ll". + */ + if (s != NULL) { + /* + * There's a variable-length prefix preceding the + * link-layer header. "s" points to a list of statements + * that put the length of that prefix into the X register. + * do an indirect load, to use the X register as an offset. + */ + s2 = new_stmt(BPF_LD|BPF_IND|size); + s2->s.k = offset; + sappend(s, s2); + } else { + /* + * There is no variable-length header preceding the + * link-layer header; add in off_ll, which, if there's + * a fixed-length header preceding the link-layer header, + * is the length of that header. + */ + s = new_stmt(BPF_LD|BPF_ABS|size); + s->s.k = offset + off_ll; + } + return s; +} + +/* + * Load a value relative to the beginning of the specified header. + */ +static struct slist * +gen_load_a(offrel, offset, size) + enum e_offrel offrel; + u_int offset, size; +{ + struct slist *s, *s2; + + switch (offrel) { + + case OR_PACKET: + s = new_stmt(BPF_LD|BPF_ABS|size); + s->s.k = offset; + break; + + case OR_LINK: + s = gen_load_llrel(offset, size); + break; + + case OR_NET: + s = gen_load_llrel(off_nl + offset, size); + break; + + case OR_NET_NOSNAP: + s = gen_load_llrel(off_nl_nosnap + offset, size); + break; + + case OR_TRAN_IPV4: + /* + * Load the X register with the length of the IPv4 header + * (plus the offset of the link-layer header, if it's + * preceded by a variable-length header such as a radio + * header), in bytes. + */ + s = gen_loadx_iphdrlen(); + + /* + * Load the item at {offset of the link-layer header} + + * {offset, relative to the start of the link-layer + * header, of the IPv4 header} + {length of the IPv4 header} + + * {specified offset}. + * + * (If the link-layer is variable-length, it's included + * in the value in the X register, and off_ll is 0.) + */ + s2 = new_stmt(BPF_LD|BPF_IND|size); + s2->s.k = off_ll + off_nl + offset; + sappend(s, s2); + break; + + case OR_TRAN_IPV6: + s = gen_load_llrel(off_nl + 40 + offset, size); + break; + + default: + abort(); + return NULL; + } + return s; +} + +/* + * Generate code to load into the X register the sum of the length of + * the IPv4 header and any variable-length header preceding the link-layer + * header. + */ +static struct slist * +gen_loadx_iphdrlen() +{ + struct slist *s, *s2; + + s = gen_llprefixlen(); + if (s != NULL) { + /* + * There's a variable-length prefix preceding the + * link-layer header. "s" points to a list of statements + * that put the length of that prefix into the X register. + * The 4*([k]&0xf) addressing mode can't be used, as we + * don't have a constant offset, so we have to load the + * value in question into the A register and add to it + * the value from the X register. + */ + s2 = new_stmt(BPF_LD|BPF_IND|BPF_B); + s2->s.k = off_nl; + sappend(s, s2); + s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K); + s2->s.k = 0xf; + sappend(s, s2); + s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K); + s2->s.k = 2; + sappend(s, s2); + + /* + * The A register now contains the length of the + * IP header. We need to add to it the length + * of the prefix preceding the link-layer + * header, which is still in the X register, and + * move the result into the X register. + */ + sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); + sappend(s, new_stmt(BPF_MISC|BPF_TAX)); + } else { + /* + * There is no variable-length header preceding the + * link-layer header; add in off_ll, which, if there's + * a fixed-length header preceding the link-layer header, + * is the length of that header. + */ + s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); + s->s.k = off_ll + off_nl; + } + return s; +} + +static struct block * +gen_uncond(rsense) + int rsense; +{ + struct block *b; + struct slist *s; + + s = new_stmt(BPF_LD|BPF_IMM); + s->s.k = !rsense; + b = new_block(JMP(BPF_JEQ)); + b->stmts = s; + + return b; +} + +static inline struct block * +gen_true() +{ + return gen_uncond(1); +} + +static inline struct block * +gen_false() +{ + return gen_uncond(0); +} + +/* + * Byte-swap a 32-bit number. + * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on + * big-endian platforms.) + */ +#define SWAPLONG(y) \ +((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) + +/* + * Generate code to match a particular packet type. + * + * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP + * value, if <= ETHERMTU. We use that to determine whether to + * match the type/length field or to check the type/length field for + * a value <= ETHERMTU to see whether it's a type field and then do + * the appropriate test. + */ +static struct block * +gen_ether_linktype(proto) + register int proto; +{ + struct block *b0, *b1; + + switch (proto) { + + case LLCSAP_ISONS: + case LLCSAP_IP: + case LLCSAP_NETBEUI: + /* + * OSI protocols and NetBEUI always use 802.2 encapsulation, + * so we check the DSAP and SSAP. + * + * LLCSAP_IP checks for IP-over-802.2, rather + * than IP-over-Ethernet or IP-over-SNAP. + * + * XXX - should we check both the DSAP and the + * SSAP, like this, or should we check just the + * DSAP, as we do for other types <= ETHERMTU + * (i.e., other SAP values)? + */ + b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU); + gen_not(b0); + b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_H, (bpf_int32) + ((proto << 8) | proto)); + gen_and(b0, b1); + return b1; + + case LLCSAP_IPX: + /* + * Check for; + * + * Ethernet_II frames, which are Ethernet + * frames with a frame type of ETHERTYPE_IPX; + * + * Ethernet_802.3 frames, which are 802.3 + * frames (i.e., the type/length field is + * a length field, <= ETHERMTU, rather than + * a type field) with the first two bytes + * after the Ethernet/802.3 header being + * 0xFFFF; + * + * Ethernet_802.2 frames, which are 802.3 + * frames with an 802.2 LLC header and + * with the IPX LSAP as the DSAP in the LLC + * header; + * + * Ethernet_SNAP frames, which are 802.3 + * frames with an LLC header and a SNAP + * header and with an OUI of 0x000000 + * (encapsulated Ethernet) and a protocol + * ID of ETHERTYPE_IPX in the SNAP header. + * + * XXX - should we generate the same code both + * for tests for LLCSAP_IPX and for ETHERTYPE_IPX? + */ + + /* + * This generates code to check both for the + * IPX LSAP (Ethernet_802.2) and for Ethernet_802.3. + */ + b0 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B, + (bpf_int32)LLCSAP_IPX); + b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_H, + (bpf_int32)0xFFFF); + gen_or(b0, b1); + + /* + * Now we add code to check for SNAP frames with + * ETHERTYPE_IPX, i.e. Ethernet_SNAP. + */ + b0 = gen_snap(0x000000, ETHERTYPE_IPX, 14); + gen_or(b0, b1); + + /* + * Now we generate code to check for 802.3 + * frames in general. + */ + b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU); + gen_not(b0); + + /* + * Now add the check for 802.3 frames before the + * check for Ethernet_802.2 and Ethernet_802.3, + * as those checks should only be done on 802.3 + * frames, not on Ethernet frames. + */ + gen_and(b0, b1); + + /* + * Now add the check for Ethernet_II frames, and + * do that before checking for the other frame + * types. + */ + b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, + (bpf_int32)ETHERTYPE_IPX); + gen_or(b0, b1); + return b1; + + case ETHERTYPE_ATALK: + case ETHERTYPE_AARP: + /* + * EtherTalk (AppleTalk protocols on Ethernet link + * layer) may use 802.2 encapsulation. + */ + + /* + * Check for 802.2 encapsulation (EtherTalk phase 2?); + * we check for an Ethernet type field less than + * 1500, which means it's an 802.3 length field. + */ + b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU); + gen_not(b0); + + /* + * 802.2-encapsulated ETHERTYPE_ATALK packets are + * SNAP packets with an organization code of + * 0x080007 (Apple, for Appletalk) and a protocol + * type of ETHERTYPE_ATALK (Appletalk). + * + * 802.2-encapsulated ETHERTYPE_AARP packets are + * SNAP packets with an organization code of + * 0x000000 (encapsulated Ethernet) and a protocol + * type of ETHERTYPE_AARP (Appletalk ARP). + */ + if (proto == ETHERTYPE_ATALK) + b1 = gen_snap(0x080007, ETHERTYPE_ATALK, 14); + else /* proto == ETHERTYPE_AARP */ + b1 = gen_snap(0x000000, ETHERTYPE_AARP, 14); + gen_and(b0, b1); + + /* + * Check for Ethernet encapsulation (Ethertalk + * phase 1?); we just check for the Ethernet + * protocol type. + */ + b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto); + + gen_or(b0, b1); + return b1; + + default: + if (proto <= ETHERMTU) { + /* + * This is an LLC SAP value, so the frames + * that match would be 802.2 frames. + * Check that the frame is an 802.2 frame + * (i.e., that the length/type field is + * a length field, <= ETHERMTU) and + * then check the DSAP. + */ + b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU); + gen_not(b0); + b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B, + (bpf_int32)proto); + gen_and(b0, b1); + return b1; + } else { + /* + * This is an Ethernet type, so compare + * the length/type field with it (if + * the frame is an 802.2 frame, the length + * field will be <= ETHERMTU, and, as + * "proto" is > ETHERMTU, this test + * will fail and the frame won't match, + * which is what we want). + */ + return gen_cmp(OR_LINK, off_linktype, BPF_H, + (bpf_int32)proto); + } + } +} + +/* + * Generate code to match a particular packet type. + * + * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP + * value, if <= ETHERMTU. We use that to determine whether to + * match the type field or to check the type field for the special + * LINUX_SLL_P_802_2 value and then do the appropriate test. + */ +static struct block * +gen_linux_sll_linktype(proto) + register int proto; +{ + struct block *b0, *b1; + + switch (proto) { + + case LLCSAP_ISONS: + case LLCSAP_IP: + case LLCSAP_NETBEUI: + /* + * OSI protocols and NetBEUI always use 802.2 encapsulation, + * so we check the DSAP and SSAP. + * + * LLCSAP_IP checks for IP-over-802.2, rather + * than IP-over-Ethernet or IP-over-SNAP. + * + * XXX - should we check both the DSAP and the + * SSAP, like this, or should we check just the + * DSAP, as we do for other types <= ETHERMTU + * (i.e., other SAP values)? + */ + b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2); + b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_H, (bpf_int32) + ((proto << 8) | proto)); + gen_and(b0, b1); + return b1; + + case LLCSAP_IPX: + /* + * Ethernet_II frames, which are Ethernet + * frames with a frame type of ETHERTYPE_IPX; + * + * Ethernet_802.3 frames, which have a frame + * type of LINUX_SLL_P_802_3; + * + * Ethernet_802.2 frames, which are 802.3 + * frames with an 802.2 LLC header (i.e, have + * a frame type of LINUX_SLL_P_802_2) and + * with the IPX LSAP as the DSAP in the LLC + * header; + * + * Ethernet_SNAP frames, which are 802.3 + * frames with an LLC header and a SNAP + * header and with an OUI of 0x000000 + * (encapsulated Ethernet) and a protocol + * ID of ETHERTYPE_IPX in the SNAP header. + * + * First, do the checks on LINUX_SLL_P_802_2 + * frames; generate the check for either + * Ethernet_802.2 or Ethernet_SNAP frames, and + * then put a check for LINUX_SLL_P_802_2 frames + * before it. + */ + b0 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B, + (bpf_int32)LLCSAP_IPX); + b1 = gen_snap(0x000000, ETHERTYPE_IPX, + off_linktype + 2); + gen_or(b0, b1); + b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2); + gen_and(b0, b1); + + /* + * Now check for 802.3 frames and OR that with + * the previous test. + */ + b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_3); + gen_or(b0, b1); + + /* + * Now add the check for Ethernet_II frames, and + * do that before checking for the other frame + * types. + */ + b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, + (bpf_int32)ETHERTYPE_IPX); + gen_or(b0, b1); + return b1; + + case ETHERTYPE_ATALK: + case ETHERTYPE_AARP: + /* + * EtherTalk (AppleTalk protocols on Ethernet link + * layer) may use 802.2 encapsulation. + */ + + /* + * Check for 802.2 encapsulation (EtherTalk phase 2?); + * we check for the 802.2 protocol type in the + * "Ethernet type" field. + */ + b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2); + + /* + * 802.2-encapsulated ETHERTYPE_ATALK packets are + * SNAP packets with an organization code of + * 0x080007 (Apple, for Appletalk) and a protocol + * type of ETHERTYPE_ATALK (Appletalk). + * + * 802.2-encapsulated ETHERTYPE_AARP packets are + * SNAP packets with an organization code of + * 0x000000 (encapsulated Ethernet) and a protocol + * type of ETHERTYPE_AARP (Appletalk ARP). + */ + if (proto == ETHERTYPE_ATALK) + b1 = gen_snap(0x080007, ETHERTYPE_ATALK, + off_linktype + 2); + else /* proto == ETHERTYPE_AARP */ + b1 = gen_snap(0x000000, ETHERTYPE_AARP, + off_linktype + 2); + gen_and(b0, b1); + + /* + * Check for Ethernet encapsulation (Ethertalk + * phase 1?); we just check for the Ethernet + * protocol type. + */ + b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto); + + gen_or(b0, b1); + return b1; + + default: + if (proto <= ETHERMTU) { + /* + * This is an LLC SAP value, so the frames + * that match would be 802.2 frames. + * Check for the 802.2 protocol type + * in the "Ethernet type" field, and + * then check the DSAP. + */ + b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, + LINUX_SLL_P_802_2); + b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B, + (bpf_int32)proto); + gen_and(b0, b1); + return b1; + } else { + /* + * This is an Ethernet type, so compare + * the length/type field with it (if + * the frame is an 802.2 frame, the length + * field will be <= ETHERMTU, and, as + * "proto" is > ETHERMTU, this test + * will fail and the frame won't match, + * which is what we want). + */ + return gen_cmp(OR_LINK, off_linktype, BPF_H, + (bpf_int32)proto); + } + } +} + +static void +insert_radiotap_load_llprefixlen(b) + struct block *b; +{ + struct slist *s1, *s2; + + /* + * Prepend to the statements in this block code to load the + * length of the radiotap header into the register assigned + * to hold that length, if one has been assigned. + */ + if (reg_ll_size != -1) { + /* + * The 2 bytes at offsets of 2 and 3 from the beginning + * of the radiotap header are the length of the radiotap + * header; unfortunately, it's little-endian, so we have + * to load it a byte at a time and construct the value. + */ + + /* + * Load the high-order byte, at an offset of 3, shift it + * left a byte, and put the result in the X register. + */ + s1 = new_stmt(BPF_LD|BPF_B|BPF_ABS); + s1->s.k = 3; + s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K); + sappend(s1, s2); + s2->s.k = 8; + s2 = new_stmt(BPF_MISC|BPF_TAX); + sappend(s1, s2); + + /* + * Load the next byte, at an offset of 2, and OR the + * value from the X register into it. + */ + s2 = new_stmt(BPF_LD|BPF_B|BPF_ABS); + sappend(s1, s2); + s2->s.k = 2; + s2 = new_stmt(BPF_ALU|BPF_OR|BPF_X); + sappend(s1, s2); + + /* + * Now allocate a register to hold that value and store + * it. + */ + s2 = new_stmt(BPF_ST); + s2->s.k = reg_ll_size; + sappend(s1, s2); + + /* + * Now move it into the X register. + */ + s2 = new_stmt(BPF_MISC|BPF_TAX); + sappend(s1, s2); + + /* + * Now append all the existing statements in this + * block to these statements. + */ + sappend(s1, b->stmts); + b->stmts = s1; + } +} + + +static void +insert_load_llprefixlen(b) + struct block *b; +{ + switch (linktype) { + + case DLT_IEEE802_11_RADIO: + insert_radiotap_load_llprefixlen(b); + } +} + + +static struct slist * +gen_radiotap_llprefixlen(void) +{ + struct slist *s; + + if (reg_ll_size == -1) { + /* + * We haven't yet assigned a register for the length + * of the radiotap header; allocate one. + */ + reg_ll_size = alloc_reg(); + } + + /* + * Load the register containing the radiotap length + * into the X register. + */ + s = new_stmt(BPF_LDX|BPF_MEM); + s->s.k = reg_ll_size; + return s; +} + +/* + * Generate code to compute the link-layer header length, if necessary, + * putting it into the X register, and to return either a pointer to a + * "struct slist" for the list of statements in that code, or NULL if + * no code is necessary. + */ +static struct slist * +gen_llprefixlen(void) +{ + switch (linktype) { + + case DLT_IEEE802_11_RADIO: + return gen_radiotap_llprefixlen(); + + default: + return NULL; + } +} + +/* + * Generate code to match a particular packet type by matching the + * link-layer type field or fields in the 802.2 LLC header. + * + * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP + * value, if <= ETHERMTU. + */ +static struct block * +gen_linktype(proto) + register int proto; +{ + struct block *b0, *b1, *b2; + + /* are we checking MPLS-encapsulated packets? */ + if (label_stack_depth > 0) { + switch (proto) { + case ETHERTYPE_IP: + case PPP_IP: + /* FIXME add other L3 proto IDs */ + return gen_mpls_linktype(Q_IP); + + case ETHERTYPE_IPV6: + case PPP_IPV6: + /* FIXME add other L3 proto IDs */ + return gen_mpls_linktype(Q_IPV6); + + default: + bpf_error("unsupported protocol over mpls"); + /* NOTREACHED */ + } + } + + switch (linktype) { + + case DLT_EN10MB: + return gen_ether_linktype(proto); + /*NOTREACHED*/ + break; + + case DLT_C_HDLC: + switch (proto) { + + case LLCSAP_ISONS: + proto = (proto << 8 | LLCSAP_ISONS); + /* fall through */ + + default: + return gen_cmp(OR_LINK, off_linktype, BPF_H, + (bpf_int32)proto); + /*NOTREACHED*/ + break; + } + break; + + case DLT_FDDI: + case DLT_IEEE802: + case DLT_IEEE802_11: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PRISM_HEADER: + case DLT_ATM_RFC1483: + case DLT_ATM_CLIP: + case DLT_IP_OVER_FC: + return gen_llc_linktype(proto); + /*NOTREACHED*/ + break; + + case DLT_SUNATM: + /* + * If "is_lane" is set, check for a LANE-encapsulated + * version of this protocol, otherwise check for an + * LLC-encapsulated version of this protocol. + * + * We assume LANE means Ethernet, not Token Ring. + */ + if (is_lane) { + /* + * Check that the packet doesn't begin with an + * LE Control marker. (We've already generated + * a test for LANE.) + */ + b0 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H, + 0xFF00); + gen_not(b0); + + /* + * Now generate an Ethernet test. + */ + b1 = gen_ether_linktype(proto); + gen_and(b0, b1); + return b1; + } else { + /* + * Check for LLC encapsulation and then check the + * protocol. + */ + b0 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0); + b1 = gen_llc_linktype(proto); + gen_and(b0, b1); + return b1; + } + /*NOTREACHED*/ + break; + + case DLT_LINUX_SLL: + return gen_linux_sll_linktype(proto); + /*NOTREACHED*/ + break; + + case DLT_SLIP: + case DLT_SLIP_BSDOS: + case DLT_RAW: + /* + * These types don't provide any type field; packets + * are always IP. + * + * XXX - for IPv4, check for a version number of 4, and, + * for IPv6, check for a version number of 6? + */ + switch (proto) { + + case ETHERTYPE_IP: +#ifdef INET6 + case ETHERTYPE_IPV6: +#endif + return gen_true(); /* always true */ + + default: + return gen_false(); /* always false */ + } + /*NOTREACHED*/ + break; + + case DLT_PPP: + case DLT_PPP_PPPD: + case DLT_PPP_SERIAL: + case DLT_PPP_ETHER: + /* + * We use Ethernet protocol types inside libpcap; + * map them to the corresponding PPP protocol types. + */ + switch (proto) { + + case ETHERTYPE_IP: + proto = PPP_IP; + break; + +#ifdef INET6 + case ETHERTYPE_IPV6: + proto = PPP_IPV6; + break; +#endif + + case ETHERTYPE_DN: + proto = PPP_DECNET; + break; + + case ETHERTYPE_ATALK: + proto = PPP_APPLE; + break; + + case ETHERTYPE_NS: + proto = PPP_NS; + break; + + case LLCSAP_ISONS: + proto = PPP_OSI; + break; + + case LLCSAP_8021D: + /* + * I'm assuming the "Bridging PDU"s that go + * over PPP are Spanning Tree Protocol + * Bridging PDUs. + */ + proto = PPP_BRPDU; + break; + + case LLCSAP_IPX: + proto = PPP_IPX; + break; + } + break; + + case DLT_PPP_BSDOS: + /* + * We use Ethernet protocol types inside libpcap; + * map them to the corresponding PPP protocol types. + */ + switch (proto) { + + case ETHERTYPE_IP: + b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_IP); + b1 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_VJC); + gen_or(b0, b1); + b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_VJNC); + gen_or(b1, b0); + return b0; + +#ifdef INET6 + case ETHERTYPE_IPV6: + proto = PPP_IPV6; + /* more to go? */ + break; +#endif + + case ETHERTYPE_DN: + proto = PPP_DECNET; + break; + + case ETHERTYPE_ATALK: + proto = PPP_APPLE; + break; + + case ETHERTYPE_NS: + proto = PPP_NS; + break; + + case LLCSAP_ISONS: + proto = PPP_OSI; + break; + + case LLCSAP_8021D: + /* + * I'm assuming the "Bridging PDU"s that go + * over PPP are Spanning Tree Protocol + * Bridging PDUs. + */ + proto = PPP_BRPDU; + break; + + case LLCSAP_IPX: + proto = PPP_IPX; + break; + } + break; + + case DLT_NULL: + case DLT_LOOP: + case DLT_ENC: + /* + * For DLT_NULL, the link-layer header is a 32-bit + * word containing an AF_ value in *host* byte order, + * and for DLT_ENC, the link-layer header begins + * with a 32-bit work containing an AF_ value in + * host byte order. + * + * In addition, if we're reading a saved capture file, + * the host byte order in the capture may not be the + * same as the host byte order on this machine. + * + * For DLT_LOOP, the link-layer header is a 32-bit + * word containing an AF_ value in *network* byte order. + * + * XXX - AF_ values may, unfortunately, be platform- + * dependent; for example, FreeBSD's AF_INET6 is 24 + * whilst NetBSD's and OpenBSD's is 26. + * + * This means that, when reading a capture file, just + * checking for our AF_INET6 value won't work if the + * capture file came from another OS. + */ + switch (proto) { + + case ETHERTYPE_IP: + proto = AF_INET; + break; + +#ifdef INET6 + case ETHERTYPE_IPV6: + proto = AF_INET6; + break; +#endif + + default: + /* + * Not a type on which we support filtering. + * XXX - support those that have AF_ values + * #defined on this platform, at least? + */ + return gen_false(); + } + + if (linktype == DLT_NULL || linktype == DLT_ENC) { + /* + * The AF_ value is in host byte order, but + * the BPF interpreter will convert it to + * network byte order. + * + * If this is a save file, and it's from a + * machine with the opposite byte order to + * ours, we byte-swap the AF_ value. + * + * Then we run it through "htonl()", and + * generate code to compare against the result. + */ + if (bpf_pcap->sf.rfile != NULL && + bpf_pcap->sf.swapped) + proto = SWAPLONG(proto); + proto = htonl(proto); + } + return (gen_cmp(OR_LINK, 0, BPF_W, (bpf_int32)proto)); + + case DLT_PFLOG: + /* + * af field is host byte order in contrast to the rest of + * the packet. + */ + if (proto == ETHERTYPE_IP) + return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af), + BPF_B, (bpf_int32)AF_INET)); +#ifdef INET6 + else if (proto == ETHERTYPE_IPV6) + return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af), + BPF_B, (bpf_int32)AF_INET6)); +#endif /* INET6 */ + else + return gen_false(); + /*NOTREACHED*/ + break; + + case DLT_ARCNET: + case DLT_ARCNET_LINUX: + /* + * XXX should we check for first fragment if the protocol + * uses PHDS? + */ + switch (proto) { + + default: + return gen_false(); + +#ifdef INET6 + case ETHERTYPE_IPV6: + return (gen_cmp(OR_LINK, off_linktype, BPF_B, + (bpf_int32)ARCTYPE_INET6)); +#endif /* INET6 */ + + case ETHERTYPE_IP: + b0 = gen_cmp(OR_LINK, off_linktype, BPF_B, + (bpf_int32)ARCTYPE_IP); + b1 = gen_cmp(OR_LINK, off_linktype, BPF_B, + (bpf_int32)ARCTYPE_IP_OLD); + gen_or(b0, b1); + return (b1); + + case ETHERTYPE_ARP: + b0 = gen_cmp(OR_LINK, off_linktype, BPF_B, + (bpf_int32)ARCTYPE_ARP); + b1 = gen_cmp(OR_LINK, off_linktype, BPF_B, + (bpf_int32)ARCTYPE_ARP_OLD); + gen_or(b0, b1); + return (b1); + + case ETHERTYPE_REVARP: + return (gen_cmp(OR_LINK, off_linktype, BPF_B, + (bpf_int32)ARCTYPE_REVARP)); + + case ETHERTYPE_ATALK: + return (gen_cmp(OR_LINK, off_linktype, BPF_B, + (bpf_int32)ARCTYPE_ATALK)); + } + /*NOTREACHED*/ + break; + + case DLT_LTALK: + switch (proto) { + case ETHERTYPE_ATALK: + return gen_true(); + default: + return gen_false(); + } + /*NOTREACHED*/ + break; + + case DLT_FRELAY: + /* + * XXX - assumes a 2-byte Frame Relay header with + * DLCI and flags. What if the address is longer? + */ + switch (proto) { + + case ETHERTYPE_IP: + /* + * Check for the special NLPID for IP. + */ + return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0xcc); + +#ifdef INET6 + case ETHERTYPE_IPV6: + /* + * Check for the special NLPID for IPv6. + */ + return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0x8e); +#endif + + case LLCSAP_ISONS: + /* + * Check for several OSI protocols. + * + * Frame Relay packets typically have an OSI + * NLPID at the beginning; we check for each + * of them. + * + * What we check for is the NLPID and a frame + * control field of UI, i.e. 0x03 followed + * by the NLPID. + */ + b0 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO8473_CLNP); + b1 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO9542_ESIS); + b2 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO10589_ISIS); + gen_or(b1, b2); + gen_or(b0, b2); + return b2; + + default: + return gen_false(); + } + /*NOTREACHED*/ + break; + + case DLT_JUNIPER_MFR: + case DLT_JUNIPER_MLFR: + case DLT_JUNIPER_MLPPP: + case DLT_JUNIPER_ATM1: + case DLT_JUNIPER_ATM2: + case DLT_JUNIPER_PPPOE: + case DLT_JUNIPER_PPPOE_ATM: + case DLT_JUNIPER_GGSN: + case DLT_JUNIPER_ES: + case DLT_JUNIPER_MONITOR: + case DLT_JUNIPER_SERVICES: + case DLT_JUNIPER_ETHER: + case DLT_JUNIPER_PPP: + case DLT_JUNIPER_FRELAY: + case DLT_JUNIPER_CHDLC: + /* just lets verify the magic number for now - + * on ATM we may have up to 6 different encapsulations on the wire + * and need a lot of heuristics to figure out that the payload + * might be; + * + * FIXME encapsulation specific BPF_ filters + */ + return gen_mcmp(OR_LINK, 0, BPF_W, 0x4d474300, 0xffffff00); /* compare the magic number */ + + case DLT_LINUX_IRDA: + bpf_error("IrDA link-layer type filtering not implemented"); + + case DLT_DOCSIS: + bpf_error("DOCSIS link-layer type filtering not implemented"); + + case DLT_LINUX_LAPD: + bpf_error("LAPD link-layer type filtering not implemented"); + } + + /* + * All the types that have no encapsulation should either be + * handled as DLT_SLIP, DLT_SLIP_BSDOS, and DLT_RAW are, if + * all packets are IP packets, or should be handled in some + * special case, if none of them are (if some are and some + * aren't, the lack of encapsulation is a problem, as we'd + * have to find some other way of determining the packet type). + * + * Therefore, if "off_linktype" is -1, there's an error. + */ + if (off_linktype == (u_int)-1) + abort(); + + /* + * Any type not handled above should always have an Ethernet + * type at an offset of "off_linktype". (PPP is partially + * handled above - the protocol type is mapped from the + * Ethernet and LLC types we use internally to the corresponding + * PPP type - but the PPP type is always specified by a value + * at "off_linktype", so we don't have to do the code generation + * above.) + */ + return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto); +} + +/* + * Check for an LLC SNAP packet with a given organization code and + * protocol type; we check the entire contents of the 802.2 LLC and + * snap headers, checking for DSAP and SSAP of SNAP and a control + * field of 0x03 in the LLC header, and for the specified organization + * code and protocol type in the SNAP header. + */ +static struct block * +gen_snap(orgcode, ptype, offset) + bpf_u_int32 orgcode; + bpf_u_int32 ptype; + u_int offset; +{ + u_char snapblock[8]; + + snapblock[0] = LLCSAP_SNAP; /* DSAP = SNAP */ + snapblock[1] = LLCSAP_SNAP; /* SSAP = SNAP */ + snapblock[2] = 0x03; /* control = UI */ + snapblock[3] = (orgcode >> 16); /* upper 8 bits of organization code */ + snapblock[4] = (orgcode >> 8); /* middle 8 bits of organization code */ + snapblock[5] = (orgcode >> 0); /* lower 8 bits of organization code */ + snapblock[6] = (ptype >> 8); /* upper 8 bits of protocol type */ + snapblock[7] = (ptype >> 0); /* lower 8 bits of protocol type */ + return gen_bcmp(OR_LINK, offset, 8, snapblock); +} + +/* + * Generate code to match a particular packet type, for link-layer types + * using 802.2 LLC headers. + * + * This is *NOT* used for Ethernet; "gen_ether_linktype()" is used + * for that - it handles the D/I/X Ethernet vs. 802.3+802.2 issues. + * + * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP + * value, if <= ETHERMTU. We use that to determine whether to + * match the DSAP or both DSAP and LSAP or to check the OUI and + * protocol ID in a SNAP header. + */ +static struct block * +gen_llc_linktype(proto) + int proto; +{ + /* + * XXX - handle token-ring variable-length header. + */ + switch (proto) { + + case LLCSAP_IP: + case LLCSAP_ISONS: + case LLCSAP_NETBEUI: + /* + * XXX - should we check both the DSAP and the + * SSAP, like this, or should we check just the + * DSAP, as we do for other types <= ETHERMTU + * (i.e., other SAP values)? + */ + return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_u_int32) + ((proto << 8) | proto)); + + case LLCSAP_IPX: + /* + * XXX - are there ever SNAP frames for IPX on + * non-Ethernet 802.x networks? + */ + return gen_cmp(OR_LINK, off_linktype, BPF_B, + (bpf_int32)LLCSAP_IPX); + + case ETHERTYPE_ATALK: + /* + * 802.2-encapsulated ETHERTYPE_ATALK packets are + * SNAP packets with an organization code of + * 0x080007 (Apple, for Appletalk) and a protocol + * type of ETHERTYPE_ATALK (Appletalk). + * + * XXX - check for an organization code of + * encapsulated Ethernet as well? + */ + return gen_snap(0x080007, ETHERTYPE_ATALK, off_linktype); + + default: + /* + * XXX - we don't have to check for IPX 802.3 + * here, but should we check for the IPX Ethertype? + */ + if (proto <= ETHERMTU) { + /* + * This is an LLC SAP value, so check + * the DSAP. + */ + return gen_cmp(OR_LINK, off_linktype, BPF_B, + (bpf_int32)proto); + } else { + /* + * This is an Ethernet type; we assume that it's + * unlikely that it'll appear in the right place + * at random, and therefore check only the + * location that would hold the Ethernet type + * in a SNAP frame with an organization code of + * 0x000000 (encapsulated Ethernet). + * + * XXX - if we were to check for the SNAP DSAP and + * LSAP, as per XXX, and were also to check for an + * organization code of 0x000000 (encapsulated + * Ethernet), we'd do + * + * return gen_snap(0x000000, proto, + * off_linktype); + * + * here; for now, we don't, as per the above. + * I don't know whether it's worth the extra CPU + * time to do the right check or not. + */ + return gen_cmp(OR_LINK, off_linktype+6, BPF_H, + (bpf_int32)proto); + } + } +} + +static struct block * +gen_hostop(addr, mask, dir, proto, src_off, dst_off) + bpf_u_int32 addr; + bpf_u_int32 mask; + int dir, proto; + u_int src_off, dst_off; +{ + struct block *b0, *b1; + u_int offset; + + switch (dir) { + + case Q_SRC: + offset = src_off; + break; + + case Q_DST: + offset = dst_off; + break; + + case Q_AND: + b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); + b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); + gen_and(b0, b1); + return b1; + + case Q_OR: + case Q_DEFAULT: + b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); + b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); + gen_or(b0, b1); + return b1; + + default: + abort(); + } + b0 = gen_linktype(proto); + b1 = gen_mcmp(OR_NET, offset, BPF_W, (bpf_int32)addr, mask); + gen_and(b0, b1); + return b1; +} + +#ifdef INET6 +static struct block * +gen_hostop6(addr, mask, dir, proto, src_off, dst_off) + struct in6_addr *addr; + struct in6_addr *mask; + int dir, proto; + u_int src_off, dst_off; +{ + struct block *b0, *b1; + u_int offset; + u_int32_t *a, *m; + + switch (dir) { + + case Q_SRC: + offset = src_off; + break; + + case Q_DST: + offset = dst_off; + break; + + case Q_AND: + b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off); + b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off); + gen_and(b0, b1); + return b1; + + case Q_OR: + case Q_DEFAULT: + b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off); + b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off); + gen_or(b0, b1); + return b1; + + default: + abort(); + } + /* this order is important */ + a = (u_int32_t *)addr; + m = (u_int32_t *)mask; + b1 = gen_mcmp(OR_NET, offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3])); + b0 = gen_mcmp(OR_NET, offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2])); + gen_and(b0, b1); + b0 = gen_mcmp(OR_NET, offset + 4, BPF_W, ntohl(a[1]), ntohl(m[1])); + gen_and(b0, b1); + b0 = gen_mcmp(OR_NET, offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0])); + gen_and(b0, b1); + b0 = gen_linktype(proto); + gen_and(b0, b1); + return b1; +} +#endif /*INET6*/ + +static struct block * +gen_ehostop(eaddr, dir) + register const u_char *eaddr; + register int dir; +{ + register struct block *b0, *b1; + + switch (dir) { + case Q_SRC: + return gen_bcmp(OR_LINK, off_mac + 6, 6, eaddr); + + case Q_DST: + return gen_bcmp(OR_LINK, off_mac + 0, 6, eaddr); + + case Q_AND: + b0 = gen_ehostop(eaddr, Q_SRC); + b1 = gen_ehostop(eaddr, Q_DST); + gen_and(b0, b1); + return b1; + + case Q_DEFAULT: + case Q_OR: + b0 = gen_ehostop(eaddr, Q_SRC); + b1 = gen_ehostop(eaddr, Q_DST); + gen_or(b0, b1); + return b1; + } + abort(); + /* NOTREACHED */ +} + +/* + * Like gen_ehostop, but for DLT_FDDI + */ +static struct block * +gen_fhostop(eaddr, dir) + register const u_char *eaddr; + register int dir; +{ + struct block *b0, *b1; + + switch (dir) { + case Q_SRC: +#ifdef PCAP_FDDIPAD + return gen_bcmp(OR_LINK, 6 + 1 + pcap_fddipad, 6, eaddr); +#else + return gen_bcmp(OR_LINK, 6 + 1, 6, eaddr); +#endif + + case Q_DST: +#ifdef PCAP_FDDIPAD + return gen_bcmp(OR_LINK, 0 + 1 + pcap_fddipad, 6, eaddr); +#else + return gen_bcmp(OR_LINK, 0 + 1, 6, eaddr); +#endif + + case Q_AND: + b0 = gen_fhostop(eaddr, Q_SRC); + b1 = gen_fhostop(eaddr, Q_DST); + gen_and(b0, b1); + return b1; + + case Q_DEFAULT: + case Q_OR: + b0 = gen_fhostop(eaddr, Q_SRC); + b1 = gen_fhostop(eaddr, Q_DST); + gen_or(b0, b1); + return b1; + } + abort(); + /* NOTREACHED */ +} + +/* + * Like gen_ehostop, but for DLT_IEEE802 (Token Ring) + */ +static struct block * +gen_thostop(eaddr, dir) + register const u_char *eaddr; + register int dir; +{ + register struct block *b0, *b1; + + switch (dir) { + case Q_SRC: + return gen_bcmp(OR_LINK, 8, 6, eaddr); + + case Q_DST: + return gen_bcmp(OR_LINK, 2, 6, eaddr); + + case Q_AND: + b0 = gen_thostop(eaddr, Q_SRC); + b1 = gen_thostop(eaddr, Q_DST); + gen_and(b0, b1); + return b1; + + case Q_DEFAULT: + case Q_OR: + b0 = gen_thostop(eaddr, Q_SRC); + b1 = gen_thostop(eaddr, Q_DST); + gen_or(b0, b1); + return b1; + } + abort(); + /* NOTREACHED */ +} + +/* + * Like gen_ehostop, but for DLT_IEEE802_11 (802.11 wireless LAN) + */ +static struct block * +gen_wlanhostop(eaddr, dir) + register const u_char *eaddr; + register int dir; +{ + register struct block *b0, *b1, *b2; + register struct slist *s; + + switch (dir) { + case Q_SRC: + /* + * Oh, yuk. + * + * For control frames, there is no SA. + * + * For management frames, SA is at an + * offset of 10 from the beginning of + * the packet. + * + * For data frames, SA is at an offset + * of 10 from the beginning of the packet + * if From DS is clear, at an offset of + * 16 from the beginning of the packet + * if From DS is set and To DS is clear, + * and an offset of 24 from the beginning + * of the packet if From DS is set and To DS + * is set. + */ + + /* + * Generate the tests to be done for data frames + * with From DS set. + * + * First, check for To DS set, i.e. check "link[1] & 0x01". + */ + s = gen_load_a(OR_LINK, 1, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x01; /* To DS */ + b1->stmts = s; + + /* + * If To DS is set, the SA is at 24. + */ + b0 = gen_bcmp(OR_LINK, 24, 6, eaddr); + gen_and(b1, b0); + + /* + * Now, check for To DS not set, i.e. check + * "!(link[1] & 0x01)". + */ + s = gen_load_a(OR_LINK, 1, BPF_B); + b2 = new_block(JMP(BPF_JSET)); + b2->s.k = 0x01; /* To DS */ + b2->stmts = s; + gen_not(b2); + + /* + * If To DS is not set, the SA is at 16. + */ + b1 = gen_bcmp(OR_LINK, 16, 6, eaddr); + gen_and(b2, b1); + + /* + * Now OR together the last two checks. That gives + * the complete set of checks for data frames with + * From DS set. + */ + gen_or(b1, b0); + + /* + * Now check for From DS being set, and AND that with + * the ORed-together checks. + */ + s = gen_load_a(OR_LINK, 1, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x02; /* From DS */ + b1->stmts = s; + gen_and(b1, b0); + + /* + * Now check for data frames with From DS not set. + */ + s = gen_load_a(OR_LINK, 1, BPF_B); + b2 = new_block(JMP(BPF_JSET)); + b2->s.k = 0x02; /* From DS */ + b2->stmts = s; + gen_not(b2); + + /* + * If From DS isn't set, the SA is at 10. + */ + b1 = gen_bcmp(OR_LINK, 10, 6, eaddr); + gen_and(b2, b1); + + /* + * Now OR together the checks for data frames with + * From DS not set and for data frames with From DS + * set; that gives the checks done for data frames. + */ + gen_or(b1, b0); + + /* + * Now check for a data frame. + * I.e, check "link[0] & 0x08". + */ + gen_load_a(OR_LINK, 0, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x08; + b1->stmts = s; + + /* + * AND that with the checks done for data frames. + */ + gen_and(b1, b0); + + /* + * If the high-order bit of the type value is 0, this + * is a management frame. + * I.e, check "!(link[0] & 0x08)". + */ + s = gen_load_a(OR_LINK, 0, BPF_B); + b2 = new_block(JMP(BPF_JSET)); + b2->s.k = 0x08; + b2->stmts = s; + gen_not(b2); + + /* + * For management frames, the SA is at 10. + */ + b1 = gen_bcmp(OR_LINK, 10, 6, eaddr); + gen_and(b2, b1); + + /* + * OR that with the checks done for data frames. + * That gives the checks done for management and + * data frames. + */ + gen_or(b1, b0); + + /* + * If the low-order bit of the type value is 1, + * this is either a control frame or a frame + * with a reserved type, and thus not a + * frame with an SA. + * + * I.e., check "!(link[0] & 0x04)". + */ + s = gen_load_a(OR_LINK, 0, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x04; + b1->stmts = s; + gen_not(b1); + + /* + * AND that with the checks for data and management + * frames. + */ + gen_and(b1, b0); + return b0; + + case Q_DST: + /* + * Oh, yuk. + * + * For control frames, there is no DA. + * + * For management frames, DA is at an + * offset of 4 from the beginning of + * the packet. + * + * For data frames, DA is at an offset + * of 4 from the beginning of the packet + * if To DS is clear and at an offset of + * 16 from the beginning of the packet + * if To DS is set. + */ + + /* + * Generate the tests to be done for data frames. + * + * First, check for To DS set, i.e. "link[1] & 0x01". + */ + s = gen_load_a(OR_LINK, 1, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x01; /* To DS */ + b1->stmts = s; + + /* + * If To DS is set, the DA is at 16. + */ + b0 = gen_bcmp(OR_LINK, 16, 6, eaddr); + gen_and(b1, b0); + + /* + * Now, check for To DS not set, i.e. check + * "!(link[1] & 0x01)". + */ + s = gen_load_a(OR_LINK, 1, BPF_B); + b2 = new_block(JMP(BPF_JSET)); + b2->s.k = 0x01; /* To DS */ + b2->stmts = s; + gen_not(b2); + + /* + * If To DS is not set, the DA is at 4. + */ + b1 = gen_bcmp(OR_LINK, 4, 6, eaddr); + gen_and(b2, b1); + + /* + * Now OR together the last two checks. That gives + * the complete set of checks for data frames. + */ + gen_or(b1, b0); + + /* + * Now check for a data frame. + * I.e, check "link[0] & 0x08". + */ + s = gen_load_a(OR_LINK, 0, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x08; + b1->stmts = s; + + /* + * AND that with the checks done for data frames. + */ + gen_and(b1, b0); + + /* + * If the high-order bit of the type value is 0, this + * is a management frame. + * I.e, check "!(link[0] & 0x08)". + */ + s = gen_load_a(OR_LINK, 0, BPF_B); + b2 = new_block(JMP(BPF_JSET)); + b2->s.k = 0x08; + b2->stmts = s; + gen_not(b2); + + /* + * For management frames, the DA is at 4. + */ + b1 = gen_bcmp(OR_LINK, 4, 6, eaddr); + gen_and(b2, b1); + + /* + * OR that with the checks done for data frames. + * That gives the checks done for management and + * data frames. + */ + gen_or(b1, b0); + + /* + * If the low-order bit of the type value is 1, + * this is either a control frame or a frame + * with a reserved type, and thus not a + * frame with an SA. + * + * I.e., check "!(link[0] & 0x04)". + */ + s = gen_load_a(OR_LINK, 0, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x04; + b1->stmts = s; + gen_not(b1); + + /* + * AND that with the checks for data and management + * frames. + */ + gen_and(b1, b0); + return b0; + + case Q_AND: + b0 = gen_wlanhostop(eaddr, Q_SRC); + b1 = gen_wlanhostop(eaddr, Q_DST); + gen_and(b0, b1); + return b1; + + case Q_DEFAULT: + case Q_OR: + b0 = gen_wlanhostop(eaddr, Q_SRC); + b1 = gen_wlanhostop(eaddr, Q_DST); + gen_or(b0, b1); + return b1; + } + abort(); + /* NOTREACHED */ +} + +/* + * Like gen_ehostop, but for RFC 2625 IP-over-Fibre-Channel. + * (We assume that the addresses are IEEE 48-bit MAC addresses, + * as the RFC states.) + */ +static struct block * +gen_ipfchostop(eaddr, dir) + register const u_char *eaddr; + register int dir; +{ + register struct block *b0, *b1; + + switch (dir) { + case Q_SRC: + return gen_bcmp(OR_LINK, 10, 6, eaddr); + + case Q_DST: + return gen_bcmp(OR_LINK, 2, 6, eaddr); + + case Q_AND: + b0 = gen_ipfchostop(eaddr, Q_SRC); + b1 = gen_ipfchostop(eaddr, Q_DST); + gen_and(b0, b1); + return b1; + + case Q_DEFAULT: + case Q_OR: + b0 = gen_ipfchostop(eaddr, Q_SRC); + b1 = gen_ipfchostop(eaddr, Q_DST); + gen_or(b0, b1); + return b1; + } + abort(); + /* NOTREACHED */ +} + +/* + * This is quite tricky because there may be pad bytes in front of the + * DECNET header, and then there are two possible data packet formats that + * carry both src and dst addresses, plus 5 packet types in a format that + * carries only the src node, plus 2 types that use a different format and + * also carry just the src node. + * + * Yuck. + * + * Instead of doing those all right, we just look for data packets with + * 0 or 1 bytes of padding. If you want to look at other packets, that + * will require a lot more hacking. + * + * To add support for filtering on DECNET "areas" (network numbers) + * one would want to add a "mask" argument to this routine. That would + * make the filter even more inefficient, although one could be clever + * and not generate masking instructions if the mask is 0xFFFF. + */ +static struct block * +gen_dnhostop(addr, dir) + bpf_u_int32 addr; + int dir; +{ + struct block *b0, *b1, *b2, *tmp; + u_int offset_lh; /* offset if long header is received */ + u_int offset_sh; /* offset if short header is received */ + + switch (dir) { + + case Q_DST: + offset_sh = 1; /* follows flags */ + offset_lh = 7; /* flgs,darea,dsubarea,HIORD */ + break; + + case Q_SRC: + offset_sh = 3; /* follows flags, dstnode */ + offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */ + break; + + case Q_AND: + /* Inefficient because we do our Calvinball dance twice */ + b0 = gen_dnhostop(addr, Q_SRC); + b1 = gen_dnhostop(addr, Q_DST); + gen_and(b0, b1); + return b1; + + case Q_OR: + case Q_DEFAULT: + /* Inefficient because we do our Calvinball dance twice */ + b0 = gen_dnhostop(addr, Q_SRC); + b1 = gen_dnhostop(addr, Q_DST); + gen_or(b0, b1); + return b1; + + case Q_ISO: + bpf_error("ISO host filtering not implemented"); + + default: + abort(); + } + b0 = gen_linktype(ETHERTYPE_DN); + /* Check for pad = 1, long header case */ + tmp = gen_mcmp(OR_NET, 2, BPF_H, + (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF)); + b1 = gen_cmp(OR_NET, 2 + 1 + offset_lh, + BPF_H, (bpf_int32)ntohs(addr)); + gen_and(tmp, b1); + /* Check for pad = 0, long header case */ + tmp = gen_mcmp(OR_NET, 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7); + b2 = gen_cmp(OR_NET, 2 + offset_lh, BPF_H, (bpf_int32)ntohs(addr)); + gen_and(tmp, b2); + gen_or(b2, b1); + /* Check for pad = 1, short header case */ + tmp = gen_mcmp(OR_NET, 2, BPF_H, + (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF)); + b2 = gen_cmp(OR_NET, 2 + 1 + offset_sh, BPF_H, (bpf_int32)ntohs(addr)); + gen_and(tmp, b2); + gen_or(b2, b1); + /* Check for pad = 0, short header case */ + tmp = gen_mcmp(OR_NET, 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7); + b2 = gen_cmp(OR_NET, 2 + offset_sh, BPF_H, (bpf_int32)ntohs(addr)); + gen_and(tmp, b2); + gen_or(b2, b1); + + /* Combine with test for linktype */ + gen_and(b0, b1); + return b1; +} + +/* + * Generate a check for IPv4 or IPv6 for MPLS-encapsulated packets; + * test the bottom-of-stack bit, and then check the version number + * field in the IP header. + */ +static struct block * +gen_mpls_linktype(proto) + int proto; +{ + struct block *b0, *b1; + + switch (proto) { + + case Q_IP: + /* match the bottom-of-stack bit */ + b0 = gen_mcmp(OR_NET, -2, BPF_B, 0x01, 0x01); + /* match the IPv4 version number */ + b1 = gen_mcmp(OR_NET, 0, BPF_B, 0x40, 0xf0); + gen_and(b0, b1); + return b1; + + case Q_IPV6: + /* match the bottom-of-stack bit */ + b0 = gen_mcmp(OR_NET, -2, BPF_B, 0x01, 0x01); + /* match the IPv4 version number */ + b1 = gen_mcmp(OR_NET, 0, BPF_B, 0x60, 0xf0); + gen_and(b0, b1); + return b1; + + default: + abort(); + } +} + +static struct block * +gen_host(addr, mask, proto, dir, type) + bpf_u_int32 addr; + bpf_u_int32 mask; + int proto; + int dir; + int type; +{ + struct block *b0, *b1; + const char *typestr; + + if (type == Q_NET) + typestr = "net"; + else + typestr = "host"; + + switch (proto) { + + case Q_DEFAULT: + b0 = gen_host(addr, mask, Q_IP, dir, type); + /* + * Only check for non-IPv4 addresses if we're not + * checking MPLS-encapsulated packets. + */ + if (label_stack_depth == 0) { + b1 = gen_host(addr, mask, Q_ARP, dir, type); + gen_or(b0, b1); + b0 = gen_host(addr, mask, Q_RARP, dir, type); + gen_or(b1, b0); + } + return b0; + + case Q_IP: + return gen_hostop(addr, mask, dir, ETHERTYPE_IP, 12, 16); + + case Q_RARP: + return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP, 14, 24); + + case Q_ARP: + return gen_hostop(addr, mask, dir, ETHERTYPE_ARP, 14, 24); + + case Q_TCP: + bpf_error("'tcp' modifier applied to %s", typestr); + + case Q_SCTP: + bpf_error("'sctp' modifier applied to %s", typestr); + + case Q_UDP: + bpf_error("'udp' modifier applied to %s", typestr); + + case Q_ICMP: + bpf_error("'icmp' modifier applied to %s", typestr); + + case Q_IGMP: + bpf_error("'igmp' modifier applied to %s", typestr); + + case Q_IGRP: + bpf_error("'igrp' modifier applied to %s", typestr); + + case Q_PIM: + bpf_error("'pim' modifier applied to %s", typestr); + + case Q_VRRP: + bpf_error("'vrrp' modifier applied to %s", typestr); + + case Q_ATALK: + bpf_error("ATALK host filtering not implemented"); + + case Q_AARP: + bpf_error("AARP host filtering not implemented"); + + case Q_DECNET: + return gen_dnhostop(addr, dir); + + case Q_SCA: + bpf_error("SCA host filtering not implemented"); + + case Q_LAT: + bpf_error("LAT host filtering not implemented"); + + case Q_MOPDL: + bpf_error("MOPDL host filtering not implemented"); + + case Q_MOPRC: + bpf_error("MOPRC host filtering not implemented"); + +#ifdef INET6 + case Q_IPV6: + bpf_error("'ip6' modifier applied to ip host"); + + case Q_ICMPV6: + bpf_error("'icmp6' modifier applied to %s", typestr); +#endif /* INET6 */ + + case Q_AH: + bpf_error("'ah' modifier applied to %s", typestr); + + case Q_ESP: + bpf_error("'esp' modifier applied to %s", typestr); + + case Q_ISO: + bpf_error("ISO host filtering not implemented"); + + case Q_ESIS: + bpf_error("'esis' modifier applied to %s", typestr); + + case Q_ISIS: + bpf_error("'isis' modifier applied to %s", typestr); + + case Q_CLNP: + bpf_error("'clnp' modifier applied to %s", typestr); + + case Q_STP: + bpf_error("'stp' modifier applied to %s", typestr); + + case Q_IPX: + bpf_error("IPX host filtering not implemented"); + + case Q_NETBEUI: + bpf_error("'netbeui' modifier applied to %s", typestr); + + case Q_RADIO: + bpf_error("'radio' modifier applied to %s", typestr); + + default: + abort(); + } + /* NOTREACHED */ +} + +#ifdef INET6 +static struct block * +gen_host6(addr, mask, proto, dir, type) + struct in6_addr *addr; + struct in6_addr *mask; + int proto; + int dir; + int type; +{ + const char *typestr; + + if (type == Q_NET) + typestr = "net"; + else + typestr = "host"; + + switch (proto) { + + case Q_DEFAULT: + return gen_host6(addr, mask, Q_IPV6, dir, type); + + case Q_IP: + bpf_error("'ip' modifier applied to ip6 %s", typestr); + + case Q_RARP: + bpf_error("'rarp' modifier applied to ip6 %s", typestr); + + case Q_ARP: + bpf_error("'arp' modifier applied to ip6 %s", typestr); + + case Q_SCTP: + bpf_error("'sctp' modifier applied to %s", typestr); + + case Q_TCP: + bpf_error("'tcp' modifier applied to %s", typestr); + + case Q_UDP: + bpf_error("'udp' modifier applied to %s", typestr); + + case Q_ICMP: + bpf_error("'icmp' modifier applied to %s", typestr); + + case Q_IGMP: + bpf_error("'igmp' modifier applied to %s", typestr); + + case Q_IGRP: + bpf_error("'igrp' modifier applied to %s", typestr); + + case Q_PIM: + bpf_error("'pim' modifier applied to %s", typestr); + + case Q_VRRP: + bpf_error("'vrrp' modifier applied to %s", typestr); + + case Q_ATALK: + bpf_error("ATALK host filtering not implemented"); + + case Q_AARP: + bpf_error("AARP host filtering not implemented"); + + case Q_DECNET: + bpf_error("'decnet' modifier applied to ip6 %s", typestr); + + case Q_SCA: + bpf_error("SCA host filtering not implemented"); + + case Q_LAT: + bpf_error("LAT host filtering not implemented"); + + case Q_MOPDL: + bpf_error("MOPDL host filtering not implemented"); + + case Q_MOPRC: + bpf_error("MOPRC host filtering not implemented"); + + case Q_IPV6: + return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6, 8, 24); + + case Q_ICMPV6: + bpf_error("'icmp6' modifier applied to %s", typestr); + + case Q_AH: + bpf_error("'ah' modifier applied to %s", typestr); + + case Q_ESP: + bpf_error("'esp' modifier applied to %s", typestr); + + case Q_ISO: + bpf_error("ISO host filtering not implemented"); + + case Q_ESIS: + bpf_error("'esis' modifier applied to %s", typestr); + + case Q_ISIS: + bpf_error("'isis' modifier applied to %s", typestr); + + case Q_CLNP: + bpf_error("'clnp' modifier applied to %s", typestr); + + case Q_STP: + bpf_error("'stp' modifier applied to %s", typestr); + + case Q_IPX: + bpf_error("IPX host filtering not implemented"); + + case Q_NETBEUI: + bpf_error("'netbeui' modifier applied to %s", typestr); + + case Q_RADIO: + bpf_error("'radio' modifier applied to %s", typestr); + + default: + abort(); + } + /* NOTREACHED */ +} +#endif /*INET6*/ + +#ifndef INET6 +static struct block * +gen_gateway(eaddr, alist, proto, dir) + const u_char *eaddr; + bpf_u_int32 **alist; + int proto; + int dir; +{ + struct block *b0, *b1, *tmp; + + if (dir != 0) + bpf_error("direction applied to 'gateway'"); + + switch (proto) { + case Q_DEFAULT: + case Q_IP: + case Q_ARP: + case Q_RARP: + switch (linktype) { + case DLT_EN10MB: + b0 = gen_ehostop(eaddr, Q_OR); + break; + case DLT_FDDI: + b0 = gen_fhostop(eaddr, Q_OR); + break; + case DLT_IEEE802: + b0 = gen_thostop(eaddr, Q_OR); + break; + case DLT_IEEE802_11: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PRISM_HEADER: + b0 = gen_wlanhostop(eaddr, Q_OR); + break; + case DLT_SUNATM: + if (is_lane) { + /* + * Check that the packet doesn't begin with an + * LE Control marker. (We've already generated + * a test for LANE.) + */ + b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H, + 0xFF00); + gen_not(b1); + + /* + * Now check the MAC address. + */ + b0 = gen_ehostop(eaddr, Q_OR); + gen_and(b1, b0); + } + break; + case DLT_IP_OVER_FC: + b0 = gen_ipfchostop(eaddr, Q_OR); + break; + default: + bpf_error( + "'gateway' supported only on ethernet/FDDI/token ring/802.11/Fibre Channel"); + } + b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR, Q_HOST); + while (*alist) { + tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR, + Q_HOST); + gen_or(b1, tmp); + b1 = tmp; + } + gen_not(b1); + gen_and(b0, b1); + return b1; + } + bpf_error("illegal modifier of 'gateway'"); + /* NOTREACHED */ +} +#endif + +struct block * +gen_proto_abbrev(proto) + int proto; +{ + struct block *b0; + struct block *b1; + + switch (proto) { + + case Q_SCTP: + b1 = gen_proto(IPPROTO_SCTP, Q_IP, Q_DEFAULT); +#ifdef INET6 + b0 = gen_proto(IPPROTO_SCTP, Q_IPV6, Q_DEFAULT); + gen_or(b0, b1); +#endif + break; + + case Q_TCP: + b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT); +#ifdef INET6 + b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT); + gen_or(b0, b1); +#endif + break; + + case Q_UDP: + b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT); +#ifdef INET6 + b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT); + gen_or(b0, b1); +#endif + break; + + case Q_ICMP: + b1 = gen_proto(IPPROTO_ICMP, Q_IP, Q_DEFAULT); + break; + +#ifndef IPPROTO_IGMP +#define IPPROTO_IGMP 2 +#endif + + case Q_IGMP: + b1 = gen_proto(IPPROTO_IGMP, Q_IP, Q_DEFAULT); + break; + +#ifndef IPPROTO_IGRP +#define IPPROTO_IGRP 9 +#endif + case Q_IGRP: + b1 = gen_proto(IPPROTO_IGRP, Q_IP, Q_DEFAULT); + break; + +#ifndef IPPROTO_PIM +#define IPPROTO_PIM 103 +#endif + + case Q_PIM: + b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT); +#ifdef INET6 + b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT); + gen_or(b0, b1); +#endif + break; + +#ifndef IPPROTO_VRRP +#define IPPROTO_VRRP 112 +#endif + + case Q_VRRP: + b1 = gen_proto(IPPROTO_VRRP, Q_IP, Q_DEFAULT); + break; + + case Q_IP: + b1 = gen_linktype(ETHERTYPE_IP); + break; + + case Q_ARP: + b1 = gen_linktype(ETHERTYPE_ARP); + break; + + case Q_RARP: + b1 = gen_linktype(ETHERTYPE_REVARP); + break; + + case Q_LINK: + bpf_error("link layer applied in wrong context"); + + case Q_ATALK: + b1 = gen_linktype(ETHERTYPE_ATALK); + break; + + case Q_AARP: + b1 = gen_linktype(ETHERTYPE_AARP); + break; + + case Q_DECNET: + b1 = gen_linktype(ETHERTYPE_DN); + break; + + case Q_SCA: + b1 = gen_linktype(ETHERTYPE_SCA); + break; + + case Q_LAT: + b1 = gen_linktype(ETHERTYPE_LAT); + break; + + case Q_MOPDL: + b1 = gen_linktype(ETHERTYPE_MOPDL); + break; + + case Q_MOPRC: + b1 = gen_linktype(ETHERTYPE_MOPRC); + break; + +#ifdef INET6 + case Q_IPV6: + b1 = gen_linktype(ETHERTYPE_IPV6); + break; + +#ifndef IPPROTO_ICMPV6 +#define IPPROTO_ICMPV6 58 +#endif + case Q_ICMPV6: + b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT); + break; +#endif /* INET6 */ + +#ifndef IPPROTO_AH +#define IPPROTO_AH 51 +#endif + case Q_AH: + b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT); +#ifdef INET6 + b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT); + gen_or(b0, b1); +#endif + break; + +#ifndef IPPROTO_ESP +#define IPPROTO_ESP 50 +#endif + case Q_ESP: + b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT); +#ifdef INET6 + b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT); + gen_or(b0, b1); +#endif + break; + + case Q_ISO: + b1 = gen_linktype(LLCSAP_ISONS); + break; + + case Q_ESIS: + b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT); + break; + + case Q_ISIS: + b1 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT); + break; + + case Q_ISIS_L1: /* all IS-IS Level1 PDU-Types */ + b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT); + b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */ + gen_or(b0, b1); + b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + break; + + case Q_ISIS_L2: /* all IS-IS Level2 PDU-Types */ + b0 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT); + b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */ + gen_or(b0, b1); + b0 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + b0 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + break; + + case Q_ISIS_IIH: /* all IS-IS Hello PDU-Types */ + b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT); + b1 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + b0 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + break; + + case Q_ISIS_LSP: + b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT); + b1 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + break; + + case Q_ISIS_SNP: + b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT); + b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + break; + + case Q_ISIS_CSNP: + b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT); + b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + break; + + case Q_ISIS_PSNP: + b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT); + b1 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT); + gen_or(b0, b1); + break; + + case Q_CLNP: + b1 = gen_proto(ISO8473_CLNP, Q_ISO, Q_DEFAULT); + break; + + case Q_STP: + b1 = gen_linktype(LLCSAP_8021D); + break; + + case Q_IPX: + b1 = gen_linktype(LLCSAP_IPX); + break; + + case Q_NETBEUI: + b1 = gen_linktype(LLCSAP_NETBEUI); + break; + + case Q_RADIO: + bpf_error("'radio' is not a valid protocol type"); + + default: + abort(); + } + return b1; +} + +static struct block * +gen_ipfrag() +{ + struct slist *s; + struct block *b; + + /* not ip frag */ + s = gen_load_a(OR_NET, 6, BPF_H); + b = new_block(JMP(BPF_JSET)); + b->s.k = 0x1fff; + b->stmts = s; + gen_not(b); + + return b; +} + +/* + * Generate a comparison to a port value in the transport-layer header + * at the specified offset from the beginning of that header. + * + * XXX - this handles a variable-length prefix preceding the link-layer + * header, such as the radiotap or AVS radio prefix, but doesn't handle + * variable-length link-layer headers (such as Token Ring or 802.11 + * headers). + */ +static struct block * +gen_portatom(off, v) + int off; + bpf_int32 v; +{ + return gen_cmp(OR_TRAN_IPV4, off, BPF_H, v); +} + +#ifdef INET6 +static struct block * +gen_portatom6(off, v) + int off; + bpf_int32 v; +{ + return gen_cmp(OR_TRAN_IPV6, off, BPF_H, v); +} +#endif/*INET6*/ + +struct block * +gen_portop(port, proto, dir) + int port, proto, dir; +{ + struct block *b0, *b1, *tmp; + + /* ip proto 'proto' */ + tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto); + b0 = gen_ipfrag(); + gen_and(tmp, b0); + + switch (dir) { + case Q_SRC: + b1 = gen_portatom(0, (bpf_int32)port); + break; + + case Q_DST: + b1 = gen_portatom(2, (bpf_int32)port); + break; + + case Q_OR: + case Q_DEFAULT: + tmp = gen_portatom(0, (bpf_int32)port); + b1 = gen_portatom(2, (bpf_int32)port); + gen_or(tmp, b1); + break; + + case Q_AND: + tmp = gen_portatom(0, (bpf_int32)port); + b1 = gen_portatom(2, (bpf_int32)port); + gen_and(tmp, b1); + break; + + default: + abort(); + } + gen_and(b0, b1); + + return b1; +} + +static struct block * +gen_port(port, ip_proto, dir) + int port; + int ip_proto; + int dir; +{ + struct block *b0, *b1, *tmp; + + /* + * ether proto ip + * + * For FDDI, RFC 1188 says that SNAP encapsulation is used, + * not LLC encapsulation with LLCSAP_IP. + * + * For IEEE 802 networks - which includes 802.5 token ring + * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042 + * says that SNAP encapsulation is used, not LLC encapsulation + * with LLCSAP_IP. + * + * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and + * RFC 2225 say that SNAP encapsulation is used, not LLC + * encapsulation with LLCSAP_IP. + * + * So we always check for ETHERTYPE_IP. + */ + b0 = gen_linktype(ETHERTYPE_IP); + + switch (ip_proto) { + case IPPROTO_UDP: + case IPPROTO_TCP: + case IPPROTO_SCTP: + b1 = gen_portop(port, ip_proto, dir); + break; + + case PROTO_UNDEF: + tmp = gen_portop(port, IPPROTO_TCP, dir); + b1 = gen_portop(port, IPPROTO_UDP, dir); + gen_or(tmp, b1); + tmp = gen_portop(port, IPPROTO_SCTP, dir); + gen_or(tmp, b1); + break; + + default: + abort(); + } + gen_and(b0, b1); + return b1; +} + +#ifdef INET6 +struct block * +gen_portop6(port, proto, dir) + int port, proto, dir; +{ + struct block *b0, *b1, *tmp; + + /* ip6 proto 'proto' */ + b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto); + + switch (dir) { + case Q_SRC: + b1 = gen_portatom6(0, (bpf_int32)port); + break; + + case Q_DST: + b1 = gen_portatom6(2, (bpf_int32)port); + break; + + case Q_OR: + case Q_DEFAULT: + tmp = gen_portatom6(0, (bpf_int32)port); + b1 = gen_portatom6(2, (bpf_int32)port); + gen_or(tmp, b1); + break; + + case Q_AND: + tmp = gen_portatom6(0, (bpf_int32)port); + b1 = gen_portatom6(2, (bpf_int32)port); + gen_and(tmp, b1); + break; + + default: + abort(); + } + gen_and(b0, b1); + + return b1; +} + +static struct block * +gen_port6(port, ip_proto, dir) + int port; + int ip_proto; + int dir; +{ + struct block *b0, *b1, *tmp; + + /* link proto ip6 */ + b0 = gen_linktype(ETHERTYPE_IPV6); + + switch (ip_proto) { + case IPPROTO_UDP: + case IPPROTO_TCP: + case IPPROTO_SCTP: + b1 = gen_portop6(port, ip_proto, dir); + break; + + case PROTO_UNDEF: + tmp = gen_portop6(port, IPPROTO_TCP, dir); + b1 = gen_portop6(port, IPPROTO_UDP, dir); + gen_or(tmp, b1); + tmp = gen_portop6(port, IPPROTO_SCTP, dir); + gen_or(tmp, b1); + break; + + default: + abort(); + } + gen_and(b0, b1); + return b1; +} +#endif /* INET6 */ + +/* gen_portrange code */ +static struct block * +gen_portrangeatom(off, v1, v2) + int off; + bpf_int32 v1, v2; +{ + struct block *b1, *b2; + + if (v1 > v2) { + /* + * Reverse the order of the ports, so v1 is the lower one. + */ + bpf_int32 vtemp; + + vtemp = v1; + v1 = v2; + v2 = vtemp; + } + + b1 = gen_cmp_ge(OR_TRAN_IPV4, off, BPF_H, v1); + b2 = gen_cmp_le(OR_TRAN_IPV4, off, BPF_H, v2); + + gen_and(b1, b2); + + return b2; +} + +struct block * +gen_portrangeop(port1, port2, proto, dir) + int port1, port2; + int proto; + int dir; +{ + struct block *b0, *b1, *tmp; + + /* ip proto 'proto' */ + tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto); + b0 = gen_ipfrag(); + gen_and(tmp, b0); + + switch (dir) { + case Q_SRC: + b1 = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2); + break; + + case Q_DST: + b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2); + break; + + case Q_OR: + case Q_DEFAULT: + tmp = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2); + b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2); + gen_or(tmp, b1); + break; + + case Q_AND: + tmp = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2); + b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2); + gen_and(tmp, b1); + break; + + default: + abort(); + } + gen_and(b0, b1); + + return b1; +} + +static struct block * +gen_portrange(port1, port2, ip_proto, dir) + int port1, port2; + int ip_proto; + int dir; +{ + struct block *b0, *b1, *tmp; + + /* link proto ip */ + b0 = gen_linktype(ETHERTYPE_IP); + + switch (ip_proto) { + case IPPROTO_UDP: + case IPPROTO_TCP: + case IPPROTO_SCTP: + b1 = gen_portrangeop(port1, port2, ip_proto, dir); + break; + + case PROTO_UNDEF: + tmp = gen_portrangeop(port1, port2, IPPROTO_TCP, dir); + b1 = gen_portrangeop(port1, port2, IPPROTO_UDP, dir); + gen_or(tmp, b1); + tmp = gen_portrangeop(port1, port2, IPPROTO_SCTP, dir); + gen_or(tmp, b1); + break; + + default: + abort(); + } + gen_and(b0, b1); + return b1; +} + +#ifdef INET6 +static struct block * +gen_portrangeatom6(off, v1, v2) + int off; + bpf_int32 v1, v2; +{ + struct block *b1, *b2; + + if (v1 > v2) { + /* + * Reverse the order of the ports, so v1 is the lower one. + */ + bpf_int32 vtemp; + + vtemp = v1; + v1 = v2; + v2 = vtemp; + } + + b1 = gen_cmp_ge(OR_TRAN_IPV6, off, BPF_H, v1); + b2 = gen_cmp_le(OR_TRAN_IPV6, off, BPF_H, v2); + + gen_and(b1, b2); + + return b2; +} + +struct block * +gen_portrangeop6(port1, port2, proto, dir) + int port1, port2; + int proto; + int dir; +{ + struct block *b0, *b1, *tmp; + + /* ip6 proto 'proto' */ + b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto); + + switch (dir) { + case Q_SRC: + b1 = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2); + break; + + case Q_DST: + b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2); + break; + + case Q_OR: + case Q_DEFAULT: + tmp = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2); + b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2); + gen_or(tmp, b1); + break; + + case Q_AND: + tmp = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2); + b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2); + gen_and(tmp, b1); + break; + + default: + abort(); + } + gen_and(b0, b1); + + return b1; +} + +static struct block * +gen_portrange6(port1, port2, ip_proto, dir) + int port1, port2; + int ip_proto; + int dir; +{ + struct block *b0, *b1, *tmp; + + /* link proto ip6 */ + b0 = gen_linktype(ETHERTYPE_IPV6); + + switch (ip_proto) { + case IPPROTO_UDP: + case IPPROTO_TCP: + case IPPROTO_SCTP: + b1 = gen_portrangeop6(port1, port2, ip_proto, dir); + break; + + case PROTO_UNDEF: + tmp = gen_portrangeop6(port1, port2, IPPROTO_TCP, dir); + b1 = gen_portrangeop6(port1, port2, IPPROTO_UDP, dir); + gen_or(tmp, b1); + tmp = gen_portrangeop6(port1, port2, IPPROTO_SCTP, dir); + gen_or(tmp, b1); + break; + + default: + abort(); + } + gen_and(b0, b1); + return b1; +} +#endif /* INET6 */ + +static int +lookup_proto(name, proto) + register const char *name; + register int proto; +{ + register int v; + + switch (proto) { + + case Q_DEFAULT: + case Q_IP: + case Q_IPV6: + v = pcap_nametoproto(name); + if (v == PROTO_UNDEF) + bpf_error("unknown ip proto '%s'", name); + break; + + case Q_LINK: + /* XXX should look up h/w protocol type based on linktype */ + v = pcap_nametoeproto(name); + if (v == PROTO_UNDEF) { + v = pcap_nametollc(name); + if (v == PROTO_UNDEF) + bpf_error("unknown ether proto '%s'", name); + } + break; + + case Q_ISO: + if (strcmp(name, "esis") == 0) + v = ISO9542_ESIS; + else if (strcmp(name, "isis") == 0) + v = ISO10589_ISIS; + else if (strcmp(name, "clnp") == 0) + v = ISO8473_CLNP; + else + bpf_error("unknown osi proto '%s'", name); + break; + + default: + v = PROTO_UNDEF; + break; + } + return v; +} + +#if 0 +struct stmt * +gen_joinsp(s, n) + struct stmt **s; + int n; +{ + return NULL; +} +#endif + +static struct block * +gen_protochain(v, proto, dir) + int v; + int proto; + int dir; +{ +#ifdef NO_PROTOCHAIN + return gen_proto(v, proto, dir); +#else + struct block *b0, *b; + struct slist *s[100]; + int fix2, fix3, fix4, fix5; + int ahcheck, again, end; + int i, max; + int reg2 = alloc_reg(); + + memset(s, 0, sizeof(s)); + fix2 = fix3 = fix4 = fix5 = 0; + + switch (proto) { + case Q_IP: + case Q_IPV6: + break; + case Q_DEFAULT: + b0 = gen_protochain(v, Q_IP, dir); + b = gen_protochain(v, Q_IPV6, dir); + gen_or(b0, b); + return b; + default: + bpf_error("bad protocol applied for 'protochain'"); + /*NOTREACHED*/ + } + + /* + * We don't handle variable-length radiotap here headers yet. + * We might want to add BPF instructions to do the protochain + * work, to simplify that and, on platforms that have a BPF + * interpreter with the new instructions, let the filtering + * be done in the kernel. (We already require a modified BPF + * engine to do the protochain stuff, to support backward + * branches, and backward branch support is unlikely to appear + * in kernel BPF engines.) + */ + if (linktype == DLT_IEEE802_11_RADIO) + bpf_error("'protochain' not supported with radiotap headers"); + + no_optimize = 1; /*this code is not compatible with optimzer yet */ + + /* + * s[0] is a dummy entry to protect other BPF insn from damage + * by s[fix] = foo with uninitialized variable "fix". It is somewhat + * hard to find interdependency made by jump table fixup. + */ + i = 0; + s[i] = new_stmt(0); /*dummy*/ + i++; + + switch (proto) { + case Q_IP: + b0 = gen_linktype(ETHERTYPE_IP); + + /* A = ip->ip_p */ + s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); + s[i]->s.k = off_ll + off_nl + 9; + i++; + /* X = ip->ip_hl << 2 */ + s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B); + s[i]->s.k = off_ll + off_nl; + i++; + break; +#ifdef INET6 + case Q_IPV6: + b0 = gen_linktype(ETHERTYPE_IPV6); + + /* A = ip6->ip_nxt */ + s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); + s[i]->s.k = off_ll + off_nl + 6; + i++; + /* X = sizeof(struct ip6_hdr) */ + s[i] = new_stmt(BPF_LDX|BPF_IMM); + s[i]->s.k = 40; + i++; + break; +#endif + default: + bpf_error("unsupported proto to gen_protochain"); + /*NOTREACHED*/ + } + + /* again: if (A == v) goto end; else fall through; */ + again = i; + s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); + s[i]->s.k = v; + s[i]->s.jt = NULL; /*later*/ + s[i]->s.jf = NULL; /*update in next stmt*/ + fix5 = i; + i++; + +#ifndef IPPROTO_NONE +#define IPPROTO_NONE 59 +#endif + /* if (A == IPPROTO_NONE) goto end */ + s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); + s[i]->s.jt = NULL; /*later*/ + s[i]->s.jf = NULL; /*update in next stmt*/ + s[i]->s.k = IPPROTO_NONE; + s[fix5]->s.jf = s[i]; + fix2 = i; + i++; + +#ifdef INET6 + if (proto == Q_IPV6) { + int v6start, v6end, v6advance, j; + + v6start = i; + /* if (A == IPPROTO_HOPOPTS) goto v6advance */ + s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); + s[i]->s.jt = NULL; /*later*/ + s[i]->s.jf = NULL; /*update in next stmt*/ + s[i]->s.k = IPPROTO_HOPOPTS; + s[fix2]->s.jf = s[i]; + i++; + /* if (A == IPPROTO_DSTOPTS) goto v6advance */ + s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); + s[i]->s.jt = NULL; /*later*/ + s[i]->s.jf = NULL; /*update in next stmt*/ + s[i]->s.k = IPPROTO_DSTOPTS; + i++; + /* if (A == IPPROTO_ROUTING) goto v6advance */ + s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); + s[i]->s.jt = NULL; /*later*/ + s[i]->s.jf = NULL; /*update in next stmt*/ + s[i]->s.k = IPPROTO_ROUTING; + i++; + /* if (A == IPPROTO_FRAGMENT) goto v6advance; else goto ahcheck; */ + s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); + s[i]->s.jt = NULL; /*later*/ + s[i]->s.jf = NULL; /*later*/ + s[i]->s.k = IPPROTO_FRAGMENT; + fix3 = i; + v6end = i; + i++; + + /* v6advance: */ + v6advance = i; + + /* + * in short, + * A = P[X]; + * X = X + (P[X + 1] + 1) * 8; + */ + /* A = X */ + s[i] = new_stmt(BPF_MISC|BPF_TXA); + i++; + /* A = P[X + packet head] */ + s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); + s[i]->s.k = off_ll + off_nl; + i++; + /* MEM[reg2] = A */ + s[i] = new_stmt(BPF_ST); + s[i]->s.k = reg2; + i++; + /* A = X */ + s[i] = new_stmt(BPF_MISC|BPF_TXA); + i++; + /* A += 1 */ + s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); + s[i]->s.k = 1; + i++; + /* X = A */ + s[i] = new_stmt(BPF_MISC|BPF_TAX); + i++; + /* A = P[X + packet head]; */ + s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); + s[i]->s.k = off_ll + off_nl; + i++; + /* A += 1 */ + s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); + s[i]->s.k = 1; + i++; + /* A *= 8 */ + s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K); + s[i]->s.k = 8; + i++; + /* X = A; */ + s[i] = new_stmt(BPF_MISC|BPF_TAX); + i++; + /* A = MEM[reg2] */ + s[i] = new_stmt(BPF_LD|BPF_MEM); + s[i]->s.k = reg2; + i++; + + /* goto again; (must use BPF_JA for backward jump) */ + s[i] = new_stmt(BPF_JMP|BPF_JA); + s[i]->s.k = again - i - 1; + s[i - 1]->s.jf = s[i]; + i++; + + /* fixup */ + for (j = v6start; j <= v6end; j++) + s[j]->s.jt = s[v6advance]; + } else +#endif + { + /* nop */ + s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); + s[i]->s.k = 0; + s[fix2]->s.jf = s[i]; + i++; + } + + /* ahcheck: */ + ahcheck = i; + /* if (A == IPPROTO_AH) then fall through; else goto end; */ + s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); + s[i]->s.jt = NULL; /*later*/ + s[i]->s.jf = NULL; /*later*/ + s[i]->s.k = IPPROTO_AH; + if (fix3) + s[fix3]->s.jf = s[ahcheck]; + fix4 = i; + i++; + + /* + * in short, + * A = P[X]; + * X = X + (P[X + 1] + 2) * 4; + */ + /* A = X */ + s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA); + i++; + /* A = P[X + packet head]; */ + s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); + s[i]->s.k = off_ll + off_nl; + i++; + /* MEM[reg2] = A */ + s[i] = new_stmt(BPF_ST); + s[i]->s.k = reg2; + i++; + /* A = X */ + s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA); + i++; + /* A += 1 */ + s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); + s[i]->s.k = 1; + i++; + /* X = A */ + s[i] = new_stmt(BPF_MISC|BPF_TAX); + i++; + /* A = P[X + packet head] */ + s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); + s[i]->s.k = off_ll + off_nl; + i++; + /* A += 2 */ + s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); + s[i]->s.k = 2; + i++; + /* A *= 4 */ + s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K); + s[i]->s.k = 4; + i++; + /* X = A; */ + s[i] = new_stmt(BPF_MISC|BPF_TAX); + i++; + /* A = MEM[reg2] */ + s[i] = new_stmt(BPF_LD|BPF_MEM); + s[i]->s.k = reg2; + i++; + + /* goto again; (must use BPF_JA for backward jump) */ + s[i] = new_stmt(BPF_JMP|BPF_JA); + s[i]->s.k = again - i - 1; + i++; + + /* end: nop */ + end = i; + s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); + s[i]->s.k = 0; + s[fix2]->s.jt = s[end]; + s[fix4]->s.jf = s[end]; + s[fix5]->s.jt = s[end]; + i++; + + /* + * make slist chain + */ + max = i; + for (i = 0; i < max - 1; i++) + s[i]->next = s[i + 1]; + s[max - 1]->next = NULL; + + /* + * emit final check + */ + b = new_block(JMP(BPF_JEQ)); + b->stmts = s[1]; /*remember, s[0] is dummy*/ + b->s.k = v; + + free_reg(reg2); + + gen_and(b0, b); + return b; +#endif +} + +/* + * Generate code that checks whether the packet is a packet for protocol + * and whether the type field in that protocol's header has + * the value , e.g. if is Q_IP, it checks whether it's an + * IP packet and checks the protocol number in the IP header against . + * + * If is Q_DEFAULT, i.e. just "proto" was specified, it checks + * against Q_IP and Q_IPV6. + */ +static struct block * +gen_proto(v, proto, dir) + int v; + int proto; + int dir; +{ + struct block *b0, *b1; + + if (dir != Q_DEFAULT) + bpf_error("direction applied to 'proto'"); + + switch (proto) { + case Q_DEFAULT: +#ifdef INET6 + b0 = gen_proto(v, Q_IP, dir); + b1 = gen_proto(v, Q_IPV6, dir); + gen_or(b0, b1); + return b1; +#else + /*FALLTHROUGH*/ +#endif + case Q_IP: + /* + * For FDDI, RFC 1188 says that SNAP encapsulation is used, + * not LLC encapsulation with LLCSAP_IP. + * + * For IEEE 802 networks - which includes 802.5 token ring + * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042 + * says that SNAP encapsulation is used, not LLC encapsulation + * with LLCSAP_IP. + * + * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and + * RFC 2225 say that SNAP encapsulation is used, not LLC + * encapsulation with LLCSAP_IP. + * + * So we always check for ETHERTYPE_IP. + */ + + b0 = gen_linktype(ETHERTYPE_IP); +#ifndef CHASE_CHAIN + b1 = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)v); +#else + b1 = gen_protochain(v, Q_IP); +#endif + gen_and(b0, b1); + return b1; + + case Q_ISO: + switch (linktype) { + + case DLT_FRELAY: + /* + * Frame Relay packets typically have an OSI + * NLPID at the beginning; "gen_linktype(LLCSAP_ISONS)" + * generates code to check for all the OSI + * NLPIDs, so calling it and then adding a check + * for the particular NLPID for which we're + * looking is bogus, as we can just check for + * the NLPID. + * + * What we check for is the NLPID and a frame + * control field value of UI, i.e. 0x03 followed + * by the NLPID. + * + * XXX - assumes a 2-byte Frame Relay header with + * DLCI and flags. What if the address is longer? + * + * XXX - what about SNAP-encapsulated frames? + */ + return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | v); + /*NOTREACHED*/ + break; + + case DLT_C_HDLC: + /* + * Cisco uses an Ethertype lookalike - for OSI, + * it's 0xfefe. + */ + b0 = gen_linktype(LLCSAP_ISONS<<8 | LLCSAP_ISONS); + /* OSI in C-HDLC is stuffed with a fudge byte */ + b1 = gen_cmp(OR_NET_NOSNAP, 1, BPF_B, (long)v); + gen_and(b0, b1); + return b1; + + default: + b0 = gen_linktype(LLCSAP_ISONS); + b1 = gen_cmp(OR_NET_NOSNAP, 0, BPF_B, (long)v); + gen_and(b0, b1); + return b1; + } + + case Q_ISIS: + b0 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT); + /* + * 4 is the offset of the PDU type relative to the IS-IS + * header. + */ + b1 = gen_cmp(OR_NET_NOSNAP, 4, BPF_B, (long)v); + gen_and(b0, b1); + return b1; + + case Q_ARP: + bpf_error("arp does not encapsulate another protocol"); + /* NOTREACHED */ + + case Q_RARP: + bpf_error("rarp does not encapsulate another protocol"); + /* NOTREACHED */ + + case Q_ATALK: + bpf_error("atalk encapsulation is not specifiable"); + /* NOTREACHED */ + + case Q_DECNET: + bpf_error("decnet encapsulation is not specifiable"); + /* NOTREACHED */ + + case Q_SCA: + bpf_error("sca does not encapsulate another protocol"); + /* NOTREACHED */ + + case Q_LAT: + bpf_error("lat does not encapsulate another protocol"); + /* NOTREACHED */ + + case Q_MOPRC: + bpf_error("moprc does not encapsulate another protocol"); + /* NOTREACHED */ + + case Q_MOPDL: + bpf_error("mopdl does not encapsulate another protocol"); + /* NOTREACHED */ + + case Q_LINK: + return gen_linktype(v); + + case Q_UDP: + bpf_error("'udp proto' is bogus"); + /* NOTREACHED */ + + case Q_TCP: + bpf_error("'tcp proto' is bogus"); + /* NOTREACHED */ + + case Q_SCTP: + bpf_error("'sctp proto' is bogus"); + /* NOTREACHED */ + + case Q_ICMP: + bpf_error("'icmp proto' is bogus"); + /* NOTREACHED */ + + case Q_IGMP: + bpf_error("'igmp proto' is bogus"); + /* NOTREACHED */ + + case Q_IGRP: + bpf_error("'igrp proto' is bogus"); + /* NOTREACHED */ + + case Q_PIM: + bpf_error("'pim proto' is bogus"); + /* NOTREACHED */ + + case Q_VRRP: + bpf_error("'vrrp proto' is bogus"); + /* NOTREACHED */ + +#ifdef INET6 + case Q_IPV6: + b0 = gen_linktype(ETHERTYPE_IPV6); +#ifndef CHASE_CHAIN + b1 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)v); +#else + b1 = gen_protochain(v, Q_IPV6); +#endif + gen_and(b0, b1); + return b1; + + case Q_ICMPV6: + bpf_error("'icmp6 proto' is bogus"); +#endif /* INET6 */ + + case Q_AH: + bpf_error("'ah proto' is bogus"); + + case Q_ESP: + bpf_error("'ah proto' is bogus"); + + case Q_STP: + bpf_error("'stp proto' is bogus"); + + case Q_IPX: + bpf_error("'ipx proto' is bogus"); + + case Q_NETBEUI: + bpf_error("'netbeui proto' is bogus"); + + case Q_RADIO: + bpf_error("'radio proto' is bogus"); + + default: + abort(); + /* NOTREACHED */ + } + /* NOTREACHED */ +} + +struct block * +gen_scode(name, q) + register const char *name; + struct qual q; +{ + int proto = q.proto; + int dir = q.dir; + int tproto; + u_char *eaddr; + bpf_u_int32 mask, addr; +#ifndef INET6 + bpf_u_int32 **alist; +#else + int tproto6; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + struct addrinfo *res, *res0; + struct in6_addr mask128; +#endif /*INET6*/ + struct block *b, *tmp; + int port, real_proto; + int port1, port2; + + switch (q.addr) { + + case Q_NET: + addr = pcap_nametonetaddr(name); + if (addr == 0) + bpf_error("unknown network '%s'", name); + /* Left justify network addr and calculate its network mask */ + mask = 0xffffffff; + while (addr && (addr & 0xff000000) == 0) { + addr <<= 8; + mask <<= 8; + } + return gen_host(addr, mask, proto, dir, q.addr); + + case Q_DEFAULT: + case Q_HOST: + if (proto == Q_LINK) { + switch (linktype) { + + case DLT_EN10MB: + eaddr = pcap_ether_hostton(name); + if (eaddr == NULL) + bpf_error( + "unknown ether host '%s'", name); + b = gen_ehostop(eaddr, dir); + free(eaddr); + return b; + + case DLT_FDDI: + eaddr = pcap_ether_hostton(name); + if (eaddr == NULL) + bpf_error( + "unknown FDDI host '%s'", name); + b = gen_fhostop(eaddr, dir); + free(eaddr); + return b; + + case DLT_IEEE802: + eaddr = pcap_ether_hostton(name); + if (eaddr == NULL) + bpf_error( + "unknown token ring host '%s'", name); + b = gen_thostop(eaddr, dir); + free(eaddr); + return b; + + case DLT_IEEE802_11: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PRISM_HEADER: + eaddr = pcap_ether_hostton(name); + if (eaddr == NULL) + bpf_error( + "unknown 802.11 host '%s'", name); + b = gen_wlanhostop(eaddr, dir); + free(eaddr); + return b; + + case DLT_IP_OVER_FC: + eaddr = pcap_ether_hostton(name); + if (eaddr == NULL) + bpf_error( + "unknown Fibre Channel host '%s'", name); + b = gen_ipfchostop(eaddr, dir); + free(eaddr); + return b; + + case DLT_SUNATM: + if (!is_lane) + break; + + /* + * Check that the packet doesn't begin + * with an LE Control marker. (We've + * already generated a test for LANE.) + */ + tmp = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, + BPF_H, 0xFF00); + gen_not(tmp); + + eaddr = pcap_ether_hostton(name); + if (eaddr == NULL) + bpf_error( + "unknown ether host '%s'", name); + b = gen_ehostop(eaddr, dir); + gen_and(tmp, b); + free(eaddr); + return b; + } + + bpf_error("only ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel supports link-level host name"); + } else if (proto == Q_DECNET) { + unsigned short dn_addr = __pcap_nametodnaddr(name); + /* + * I don't think DECNET hosts can be multihomed, so + * there is no need to build up a list of addresses + */ + return (gen_host(dn_addr, 0, proto, dir, q.addr)); + } else { +#ifndef INET6 + alist = pcap_nametoaddr(name); + if (alist == NULL || *alist == NULL) + bpf_error("unknown host '%s'", name); + tproto = proto; + if (off_linktype == (u_int)-1 && tproto == Q_DEFAULT) + tproto = Q_IP; + b = gen_host(**alist++, 0xffffffff, tproto, dir, q.addr); + while (*alist) { + tmp = gen_host(**alist++, 0xffffffff, + tproto, dir, q.addr); + gen_or(b, tmp); + b = tmp; + } + return b; +#else + memset(&mask128, 0xff, sizeof(mask128)); + res0 = res = pcap_nametoaddrinfo(name); + if (res == NULL) + bpf_error("unknown host '%s'", name); + b = tmp = NULL; + tproto = tproto6 = proto; + if (off_linktype == -1 && tproto == Q_DEFAULT) { + tproto = Q_IP; + tproto6 = Q_IPV6; + } + for (res = res0; res; res = res->ai_next) { + switch (res->ai_family) { + case AF_INET: + if (tproto == Q_IPV6) + continue; + + sin = (struct sockaddr_in *) + res->ai_addr; + tmp = gen_host(ntohl(sin->sin_addr.s_addr), + 0xffffffff, tproto, dir, q.addr); + break; + case AF_INET6: + if (tproto6 == Q_IP) + continue; + + sin6 = (struct sockaddr_in6 *) + res->ai_addr; + tmp = gen_host6(&sin6->sin6_addr, + &mask128, tproto6, dir, q.addr); + break; + default: + continue; + } + if (b) + gen_or(b, tmp); + b = tmp; + } + freeaddrinfo(res0); + if (b == NULL) { + bpf_error("unknown host '%s'%s", name, + (proto == Q_DEFAULT) + ? "" + : " for specified address family"); + } + return b; +#endif /*INET6*/ + } + + case Q_PORT: + if (proto != Q_DEFAULT && + proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP) + bpf_error("illegal qualifier of 'port'"); + if (pcap_nametoport(name, &port, &real_proto) == 0) + bpf_error("unknown port '%s'", name); + if (proto == Q_UDP) { + if (real_proto == IPPROTO_TCP) + bpf_error("port '%s' is tcp", name); + else if (real_proto == IPPROTO_SCTP) + bpf_error("port '%s' is sctp", name); + else + /* override PROTO_UNDEF */ + real_proto = IPPROTO_UDP; + } + if (proto == Q_TCP) { + if (real_proto == IPPROTO_UDP) + bpf_error("port '%s' is udp", name); + + else if (real_proto == IPPROTO_SCTP) + bpf_error("port '%s' is sctp", name); + else + /* override PROTO_UNDEF */ + real_proto = IPPROTO_TCP; + } + if (proto == Q_SCTP) { + if (real_proto == IPPROTO_UDP) + bpf_error("port '%s' is udp", name); + + else if (real_proto == IPPROTO_TCP) + bpf_error("port '%s' is tcp", name); + else + /* override PROTO_UNDEF */ + real_proto = IPPROTO_SCTP; + } +#ifndef INET6 + return gen_port(port, real_proto, dir); +#else + { + struct block *b; + b = gen_port(port, real_proto, dir); + gen_or(gen_port6(port, real_proto, dir), b); + return b; + } +#endif /* INET6 */ + + case Q_PORTRANGE: + if (proto != Q_DEFAULT && + proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP) + bpf_error("illegal qualifier of 'portrange'"); + if (pcap_nametoportrange(name, &port1, &port2, &real_proto) == 0) + bpf_error("unknown port in range '%s'", name); + if (proto == Q_UDP) { + if (real_proto == IPPROTO_TCP) + bpf_error("port in range '%s' is tcp", name); + else if (real_proto == IPPROTO_SCTP) + bpf_error("port in range '%s' is sctp", name); + else + /* override PROTO_UNDEF */ + real_proto = IPPROTO_UDP; + } + if (proto == Q_TCP) { + if (real_proto == IPPROTO_UDP) + bpf_error("port in range '%s' is udp", name); + else if (real_proto == IPPROTO_SCTP) + bpf_error("port in range '%s' is sctp", name); + else + /* override PROTO_UNDEF */ + real_proto = IPPROTO_TCP; + } + if (proto == Q_SCTP) { + if (real_proto == IPPROTO_UDP) + bpf_error("port in range '%s' is udp", name); + else if (real_proto == IPPROTO_TCP) + bpf_error("port in range '%s' is tcp", name); + else + /* override PROTO_UNDEF */ + real_proto = IPPROTO_SCTP; + } +#ifndef INET6 + return gen_portrange(port1, port2, real_proto, dir); +#else + { + struct block *b; + b = gen_portrange(port1, port2, real_proto, dir); + gen_or(gen_portrange6(port1, port2, real_proto, dir), b); + return b; + } +#endif /* INET6 */ + + case Q_GATEWAY: +#ifndef INET6 + eaddr = pcap_ether_hostton(name); + if (eaddr == NULL) + bpf_error("unknown ether host: %s", name); + + alist = pcap_nametoaddr(name); + if (alist == NULL || *alist == NULL) + bpf_error("unknown host '%s'", name); + b = gen_gateway(eaddr, alist, proto, dir); + free(eaddr); + return b; +#else + bpf_error("'gateway' not supported in this configuration"); +#endif /*INET6*/ + + case Q_PROTO: + real_proto = lookup_proto(name, proto); + if (real_proto >= 0) + return gen_proto(real_proto, proto, dir); + else + bpf_error("unknown protocol: %s", name); + + case Q_PROTOCHAIN: + real_proto = lookup_proto(name, proto); + if (real_proto >= 0) + return gen_protochain(real_proto, proto, dir); + else + bpf_error("unknown protocol: %s", name); + + + case Q_UNDEF: + syntax(); + /* NOTREACHED */ + } + abort(); + /* NOTREACHED */ +} + +struct block * +gen_mcode(s1, s2, masklen, q) + register const char *s1, *s2; + register int masklen; + struct qual q; +{ + register int nlen, mlen; + bpf_u_int32 n, m; + + nlen = __pcap_atoin(s1, &n); + /* Promote short ipaddr */ + n <<= 32 - nlen; + + if (s2 != NULL) { + mlen = __pcap_atoin(s2, &m); + /* Promote short ipaddr */ + m <<= 32 - mlen; + if ((n & ~m) != 0) + bpf_error("non-network bits set in \"%s mask %s\"", + s1, s2); + } else { + /* Convert mask len to mask */ + if (masklen > 32) + bpf_error("mask length must be <= 32"); + if (masklen == 0) { + /* + * X << 32 is not guaranteed by C to be 0; it's + * undefined. + */ + m = 0; + } else + m = 0xffffffff << (32 - masklen); + if ((n & ~m) != 0) + bpf_error("non-network bits set in \"%s/%d\"", + s1, masklen); + } + + switch (q.addr) { + + case Q_NET: + return gen_host(n, m, q.proto, q.dir, q.addr); + + default: + bpf_error("Mask syntax for networks only"); + /* NOTREACHED */ + } + /* NOTREACHED */ +} + +struct block * +gen_ncode(s, v, q) + register const char *s; + bpf_u_int32 v; + struct qual q; +{ + bpf_u_int32 mask; + int proto = q.proto; + int dir = q.dir; + register int vlen; + + if (s == NULL) + vlen = 32; + else if (q.proto == Q_DECNET) + vlen = __pcap_atodn(s, &v); + else + vlen = __pcap_atoin(s, &v); + + switch (q.addr) { + + case Q_DEFAULT: + case Q_HOST: + case Q_NET: + if (proto == Q_DECNET) + return gen_host(v, 0, proto, dir, q.addr); + else if (proto == Q_LINK) { + bpf_error("illegal link layer address"); + } else { + mask = 0xffffffff; + if (s == NULL && q.addr == Q_NET) { + /* Promote short net number */ + while (v && (v & 0xff000000) == 0) { + v <<= 8; + mask <<= 8; + } + } else { + /* Promote short ipaddr */ + v <<= 32 - vlen; + mask <<= 32 - vlen; + } + return gen_host(v, mask, proto, dir, q.addr); + } + + case Q_PORT: + if (proto == Q_UDP) + proto = IPPROTO_UDP; + else if (proto == Q_TCP) + proto = IPPROTO_TCP; + else if (proto == Q_SCTP) + proto = IPPROTO_SCTP; + else if (proto == Q_DEFAULT) + proto = PROTO_UNDEF; + else + bpf_error("illegal qualifier of 'port'"); + +#ifndef INET6 + return gen_port((int)v, proto, dir); +#else + { + struct block *b; + b = gen_port((int)v, proto, dir); + gen_or(gen_port6((int)v, proto, dir), b); + return b; + } +#endif /* INET6 */ + + case Q_PORTRANGE: + if (proto == Q_UDP) + proto = IPPROTO_UDP; + else if (proto == Q_TCP) + proto = IPPROTO_TCP; + else if (proto == Q_SCTP) + proto = IPPROTO_SCTP; + else if (proto == Q_DEFAULT) + proto = PROTO_UNDEF; + else + bpf_error("illegal qualifier of 'portrange'"); + +#ifndef INET6 + return gen_portrange((int)v, (int)v, proto, dir); +#else + { + struct block *b; + b = gen_portrange((int)v, (int)v, proto, dir); + gen_or(gen_portrange6((int)v, (int)v, proto, dir), b); + return b; + } +#endif /* INET6 */ + + case Q_GATEWAY: + bpf_error("'gateway' requires a name"); + /* NOTREACHED */ + + case Q_PROTO: + return gen_proto((int)v, proto, dir); + + case Q_PROTOCHAIN: + return gen_protochain((int)v, proto, dir); + + case Q_UNDEF: + syntax(); + /* NOTREACHED */ + + default: + abort(); + /* NOTREACHED */ + } + /* NOTREACHED */ +} + +#ifdef INET6 +struct block * +gen_mcode6(s1, s2, masklen, q) + register const char *s1, *s2; + register int masklen; + struct qual q; +{ + struct addrinfo *res; + struct in6_addr *addr; + struct in6_addr mask; + struct block *b; + u_int32_t *a, *m; + + if (s2) + bpf_error("no mask %s supported", s2); + + res = pcap_nametoaddrinfo(s1); + if (!res) + bpf_error("invalid ip6 address %s", s1); + if (res->ai_next) + bpf_error("%s resolved to multiple address", s1); + addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; + + if (sizeof(mask) * 8 < masklen) + bpf_error("mask length must be <= %u", (unsigned int)(sizeof(mask) * 8)); + memset(&mask, 0, sizeof(mask)); + memset(&mask, 0xff, masklen / 8); + if (masklen % 8) { + mask.s6_addr[masklen / 8] = + (0xff << (8 - masklen % 8)) & 0xff; + } + + a = (u_int32_t *)addr; + m = (u_int32_t *)&mask; + if ((a[0] & ~m[0]) || (a[1] & ~m[1]) + || (a[2] & ~m[2]) || (a[3] & ~m[3])) { + bpf_error("non-network bits set in \"%s/%d\"", s1, masklen); + } + + switch (q.addr) { + + case Q_DEFAULT: + case Q_HOST: + if (masklen != 128) + bpf_error("Mask syntax for networks only"); + /* FALLTHROUGH */ + + case Q_NET: + b = gen_host6(addr, &mask, q.proto, q.dir, q.addr); + freeaddrinfo(res); + return b; + + default: + bpf_error("invalid qualifier against IPv6 address"); + /* NOTREACHED */ + } +} +#endif /*INET6*/ + +struct block * +gen_ecode(eaddr, q) + register const u_char *eaddr; + struct qual q; +{ + struct block *b, *tmp; + + if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) { + switch (linktype) { + case DLT_EN10MB: + return gen_ehostop(eaddr, (int)q.dir); + case DLT_FDDI: + return gen_fhostop(eaddr, (int)q.dir); + case DLT_IEEE802: + return gen_thostop(eaddr, (int)q.dir); + case DLT_IEEE802_11: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PRISM_HEADER: + return gen_wlanhostop(eaddr, (int)q.dir); + case DLT_SUNATM: + if (is_lane) { + /* + * Check that the packet doesn't begin with an + * LE Control marker. (We've already generated + * a test for LANE.) + */ + tmp = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H, + 0xFF00); + gen_not(tmp); + + /* + * Now check the MAC address. + */ + b = gen_ehostop(eaddr, (int)q.dir); + gen_and(tmp, b); + return b; + } + break; + case DLT_IP_OVER_FC: + return gen_ipfchostop(eaddr, (int)q.dir); + default: + bpf_error("ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel"); + break; + } + } + bpf_error("ethernet address used in non-ether expression"); + /* NOTREACHED */ +} + +void +sappend(s0, s1) + struct slist *s0, *s1; +{ + /* + * This is definitely not the best way to do this, but the + * lists will rarely get long. + */ + while (s0->next) + s0 = s0->next; + s0->next = s1; +} + +static struct slist * +xfer_to_x(a) + struct arth *a; +{ + struct slist *s; + + s = new_stmt(BPF_LDX|BPF_MEM); + s->s.k = a->regno; + return s; +} + +static struct slist * +xfer_to_a(a) + struct arth *a; +{ + struct slist *s; + + s = new_stmt(BPF_LD|BPF_MEM); + s->s.k = a->regno; + return s; +} + +/* + * Modify "index" to use the value stored into its register as an + * offset relative to the beginning of the header for the protocol + * "proto", and allocate a register and put an item "size" bytes long + * (1, 2, or 4) at that offset into that register, making it the register + * for "index". + */ +struct arth * +gen_load(proto, index, size) + int proto; + struct arth *index; + int size; +{ + struct slist *s, *tmp; + struct block *b; + int regno = alloc_reg(); + + free_reg(index->regno); + switch (size) { + + default: + bpf_error("data size must be 1, 2, or 4"); + + case 1: + size = BPF_B; + break; + + case 2: + size = BPF_H; + break; + + case 4: + size = BPF_W; + break; + } + switch (proto) { + default: + bpf_error("unsupported index operation"); + + case Q_RADIO: + /* + * The offset is relative to the beginning of the packet + * data, if we have a radio header. (If we don't, this + * is an error.) + */ + if (linktype != DLT_IEEE802_11_RADIO_AVS && + linktype != DLT_IEEE802_11_RADIO && + linktype != DLT_PRISM_HEADER) + bpf_error("radio information not present in capture"); + + /* + * Load into the X register the offset computed into the + * register specifed by "index". + */ + s = xfer_to_x(index); + + /* + * Load the item at that offset. + */ + tmp = new_stmt(BPF_LD|BPF_IND|size); + sappend(s, tmp); + sappend(index->s, s); + break; + + case Q_LINK: + /* + * The offset is relative to the beginning of + * the link-layer header. + * + * XXX - what about ATM LANE? Should the index be + * relative to the beginning of the AAL5 frame, so + * that 0 refers to the beginning of the LE Control + * field, or relative to the beginning of the LAN + * frame, so that 0 refers, for Ethernet LANE, to + * the beginning of the destination address? + */ + s = gen_llprefixlen(); + + /* + * If "s" is non-null, it has code to arrange that the + * X register contains the length of the prefix preceding + * the link-layer header. Add to it the offset computed + * into the register specified by "index", and move that + * into the X register. Otherwise, just load into the X + * register the offset computed into the register specifed + * by "index". + */ + if (s != NULL) { + sappend(s, xfer_to_a(index)); + sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); + sappend(s, new_stmt(BPF_MISC|BPF_TAX)); + } else + s = xfer_to_x(index); + + /* + * Load the item at the sum of the offset we've put in the + * X register and the offset of the start of the link + * layer header (which is 0 if the radio header is + * variable-length; that header length is what we put + * into the X register and then added to the index). + */ + tmp = new_stmt(BPF_LD|BPF_IND|size); + tmp->s.k = off_ll; + sappend(s, tmp); + sappend(index->s, s); + break; + + case Q_IP: + case Q_ARP: + case Q_RARP: + case Q_ATALK: + case Q_DECNET: + case Q_SCA: + case Q_LAT: + case Q_MOPRC: + case Q_MOPDL: +#ifdef INET6 + case Q_IPV6: +#endif + /* + * The offset is relative to the beginning of + * the network-layer header. + * XXX - are there any cases where we want + * off_nl_nosnap? + */ + s = gen_llprefixlen(); + + /* + * If "s" is non-null, it has code to arrange that the + * X register contains the length of the prefix preceding + * the link-layer header. Add to it the offset computed + * into the register specified by "index", and move that + * into the X register. Otherwise, just load into the X + * register the offset computed into the register specifed + * by "index". + */ + if (s != NULL) { + sappend(s, xfer_to_a(index)); + sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); + sappend(s, new_stmt(BPF_MISC|BPF_TAX)); + } else + s = xfer_to_x(index); + + /* + * Load the item at the sum of the offset we've put in the + * X register, the offset of the start of the network + * layer header, and the offset of the start of the link + * layer header (which is 0 if the radio header is + * variable-length; that header length is what we put + * into the X register and then added to the index). + */ + tmp = new_stmt(BPF_LD|BPF_IND|size); + tmp->s.k = off_ll + off_nl; + sappend(s, tmp); + sappend(index->s, s); + + /* + * Do the computation only if the packet contains + * the protocol in question. + */ + b = gen_proto_abbrev(proto); + if (index->b) + gen_and(index->b, b); + index->b = b; + break; + + case Q_SCTP: + case Q_TCP: + case Q_UDP: + case Q_ICMP: + case Q_IGMP: + case Q_IGRP: + case Q_PIM: + case Q_VRRP: + /* + * The offset is relative to the beginning of + * the transport-layer header. + * + * Load the X register with the length of the IPv4 header + * (plus the offset of the link-layer header, if it's + * a variable-length header), in bytes. + * + * XXX - are there any cases where we want + * off_nl_nosnap? + * XXX - we should, if we're built with + * IPv6 support, generate code to load either + * IPv4, IPv6, or both, as appropriate. + */ + s = gen_loadx_iphdrlen(); + + /* + * The X register now contains the sum of the length + * of any variable-length header preceding the link-layer + * header and the length of the network-layer header. + * Load into the A register the offset relative to + * the beginning of the transport layer header, + * add the X register to that, move that to the + * X register, and load with an offset from the + * X register equal to the offset of the network + * layer header relative to the beginning of + * the link-layer header plus the length of any + * fixed-length header preceding the link-layer + * header. + */ + sappend(s, xfer_to_a(index)); + sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); + sappend(s, new_stmt(BPF_MISC|BPF_TAX)); + sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size)); + tmp->s.k = off_ll + off_nl; + sappend(index->s, s); + + /* + * Do the computation only if the packet contains + * the protocol in question - which is true only + * if this is an IP datagram and is the first or + * only fragment of that datagram. + */ + gen_and(gen_proto_abbrev(proto), b = gen_ipfrag()); + if (index->b) + gen_and(index->b, b); +#ifdef INET6 + gen_and(gen_proto_abbrev(Q_IP), b); +#endif + index->b = b; + break; +#ifdef INET6 + case Q_ICMPV6: + bpf_error("IPv6 upper-layer protocol is not supported by proto[x]"); + /*NOTREACHED*/ +#endif + } + index->regno = regno; + s = new_stmt(BPF_ST); + s->s.k = regno; + sappend(index->s, s); + + return index; +} + +struct block * +gen_relation(code, a0, a1, reversed) + int code; + struct arth *a0, *a1; + int reversed; +{ + struct slist *s0, *s1, *s2; + struct block *b, *tmp; + + s0 = xfer_to_x(a1); + s1 = xfer_to_a(a0); + if (code == BPF_JEQ) { + s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X); + b = new_block(JMP(code)); + sappend(s1, s2); + } + else + b = new_block(BPF_JMP|code|BPF_X); + if (reversed) + gen_not(b); + + sappend(s0, s1); + sappend(a1->s, s0); + sappend(a0->s, a1->s); + + b->stmts = a0->s; + + free_reg(a0->regno); + free_reg(a1->regno); + + /* 'and' together protocol checks */ + if (a0->b) { + if (a1->b) { + gen_and(a0->b, tmp = a1->b); + } + else + tmp = a0->b; + } else + tmp = a1->b; + + if (tmp) + gen_and(tmp, b); + + return b; +} + +struct arth * +gen_loadlen() +{ + int regno = alloc_reg(); + struct arth *a = (struct arth *)newchunk(sizeof(*a)); + struct slist *s; + + s = new_stmt(BPF_LD|BPF_LEN); + s->next = new_stmt(BPF_ST); + s->next->s.k = regno; + a->s = s; + a->regno = regno; + + return a; +} + +struct arth * +gen_loadi(val) + int val; +{ + struct arth *a; + struct slist *s; + int reg; + + a = (struct arth *)newchunk(sizeof(*a)); + + reg = alloc_reg(); + + s = new_stmt(BPF_LD|BPF_IMM); + s->s.k = val; + s->next = new_stmt(BPF_ST); + s->next->s.k = reg; + a->s = s; + a->regno = reg; + + return a; +} + +struct arth * +gen_neg(a) + struct arth *a; +{ + struct slist *s; + + s = xfer_to_a(a); + sappend(a->s, s); + s = new_stmt(BPF_ALU|BPF_NEG); + s->s.k = 0; + sappend(a->s, s); + s = new_stmt(BPF_ST); + s->s.k = a->regno; + sappend(a->s, s); + + return a; +} + +struct arth * +gen_arth(code, a0, a1) + int code; + struct arth *a0, *a1; +{ + struct slist *s0, *s1, *s2; + + s0 = xfer_to_x(a1); + s1 = xfer_to_a(a0); + s2 = new_stmt(BPF_ALU|BPF_X|code); + + sappend(s1, s2); + sappend(s0, s1); + sappend(a1->s, s0); + sappend(a0->s, a1->s); + + free_reg(a0->regno); + free_reg(a1->regno); + + s0 = new_stmt(BPF_ST); + a0->regno = s0->s.k = alloc_reg(); + sappend(a0->s, s0); + + return a0; +} + +/* + * Here we handle simple allocation of the scratch registers. + * If too many registers are alloc'd, the allocator punts. + */ +static int regused[BPF_MEMWORDS]; +static int curreg; + +/* + * Return the next free register. + */ +static int +alloc_reg() +{ + int n = BPF_MEMWORDS; + + while (--n >= 0) { + if (regused[curreg]) + curreg = (curreg + 1) % BPF_MEMWORDS; + else { + regused[curreg] = 1; + return curreg; + } + } + bpf_error("too many registers needed to evaluate expression"); + /* NOTREACHED */ +} + +/* + * Return a register to the table so it can + * be used later. + */ +static void +free_reg(n) + int n; +{ + regused[n] = 0; +} + +static struct block * +gen_len(jmp, n) + int jmp, n; +{ + struct slist *s; + struct block *b; + + s = new_stmt(BPF_LD|BPF_LEN); + b = new_block(JMP(jmp)); + b->stmts = s; + b->s.k = n; + + return b; +} + +struct block * +gen_greater(n) + int n; +{ + return gen_len(BPF_JGE, n); +} + +/* + * Actually, this is less than or equal. + */ +struct block * +gen_less(n) + int n; +{ + struct block *b; + + b = gen_len(BPF_JGT, n); + gen_not(b); + + return b; +} + +/* + * This is for "byte {idx} {op} {val}"; "idx" is treated as relative to + * the beginning of the link-layer header. + * XXX - that means you can't test values in the radiotap header, but + * as that header is difficult if not impossible to parse generally + * without a loop, that might not be a severe problem. A new keyword + * "radio" could be added for that, although what you'd really want + * would be a way of testing particular radio header values, which + * would generate code appropriate to the radio header in question. + */ +struct block * +gen_byteop(op, idx, val) + int op, idx, val; +{ + struct block *b; + struct slist *s; + + switch (op) { + default: + abort(); + + case '=': + return gen_cmp(OR_LINK, (u_int)idx, BPF_B, (bpf_int32)val); + + case '<': + b = gen_cmp_lt(OR_LINK, (u_int)idx, BPF_B, (bpf_int32)val); + return b; + + case '>': + b = gen_cmp_gt(OR_LINK, (u_int)idx, BPF_B, (bpf_int32)val); + return b; + + case '|': + s = new_stmt(BPF_ALU|BPF_OR|BPF_K); + break; + + case '&': + s = new_stmt(BPF_ALU|BPF_AND|BPF_K); + break; + } + s->s.k = val; + b = new_block(JMP(BPF_JEQ)); + b->stmts = s; + gen_not(b); + + return b; +} + +static u_char abroadcast[] = { 0x0 }; + +struct block * +gen_broadcast(proto) + int proto; +{ + bpf_u_int32 hostmask; + struct block *b0, *b1, *b2; + static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + switch (proto) { + + case Q_DEFAULT: + case Q_LINK: + switch (linktype) { + case DLT_ARCNET: + case DLT_ARCNET_LINUX: + return gen_ahostop(abroadcast, Q_DST); + case DLT_EN10MB: + return gen_ehostop(ebroadcast, Q_DST); + case DLT_FDDI: + return gen_fhostop(ebroadcast, Q_DST); + case DLT_IEEE802: + return gen_thostop(ebroadcast, Q_DST); + case DLT_IEEE802_11: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PRISM_HEADER: + return gen_wlanhostop(ebroadcast, Q_DST); + case DLT_IP_OVER_FC: + return gen_ipfchostop(ebroadcast, Q_DST); + case DLT_SUNATM: + if (is_lane) { + /* + * Check that the packet doesn't begin with an + * LE Control marker. (We've already generated + * a test for LANE.) + */ + b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H, + 0xFF00); + gen_not(b1); + + /* + * Now check the MAC address. + */ + b0 = gen_ehostop(ebroadcast, Q_DST); + gen_and(b1, b0); + return b0; + } + break; + default: + bpf_error("not a broadcast link"); + } + break; + + case Q_IP: + b0 = gen_linktype(ETHERTYPE_IP); + hostmask = ~netmask; + b1 = gen_mcmp(OR_NET, 16, BPF_W, (bpf_int32)0, hostmask); + b2 = gen_mcmp(OR_NET, 16, BPF_W, + (bpf_int32)(~0 & hostmask), hostmask); + gen_or(b1, b2); + gen_and(b0, b2); + return b2; + } + bpf_error("only link-layer/IP broadcast filters supported"); + /* NOTREACHED */ +} + +/* + * Generate code to test the low-order bit of a MAC address (that's + * the bottom bit of the *first* byte). + */ +static struct block * +gen_mac_multicast(offset) + int offset; +{ + register struct block *b0; + register struct slist *s; + + /* link[offset] & 1 != 0 */ + s = gen_load_a(OR_LINK, offset, BPF_B); + b0 = new_block(JMP(BPF_JSET)); + b0->s.k = 1; + b0->stmts = s; + return b0; +} + +struct block * +gen_multicast(proto) + int proto; +{ + register struct block *b0, *b1, *b2; + register struct slist *s; + + switch (proto) { + + case Q_DEFAULT: + case Q_LINK: + switch (linktype) { + case DLT_ARCNET: + case DLT_ARCNET_LINUX: + /* all ARCnet multicasts use the same address */ + return gen_ahostop(abroadcast, Q_DST); + case DLT_EN10MB: + /* ether[0] & 1 != 0 */ + return gen_mac_multicast(0); + case DLT_FDDI: + /* + * XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX + * + * XXX - was that referring to bit-order issues? + */ + /* fddi[1] & 1 != 0 */ + return gen_mac_multicast(1); + case DLT_IEEE802: + /* tr[2] & 1 != 0 */ + return gen_mac_multicast(2); + case DLT_IEEE802_11: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PRISM_HEADER: + /* + * Oh, yuk. + * + * For control frames, there is no DA. + * + * For management frames, DA is at an + * offset of 4 from the beginning of + * the packet. + * + * For data frames, DA is at an offset + * of 4 from the beginning of the packet + * if To DS is clear and at an offset of + * 16 from the beginning of the packet + * if To DS is set. + */ + + /* + * Generate the tests to be done for data frames. + * + * First, check for To DS set, i.e. "link[1] & 0x01". + */ + s = gen_load_a(OR_LINK, 1, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x01; /* To DS */ + b1->stmts = s; + + /* + * If To DS is set, the DA is at 16. + */ + b0 = gen_mac_multicast(16); + gen_and(b1, b0); + + /* + * Now, check for To DS not set, i.e. check + * "!(link[1] & 0x01)". + */ + s = gen_load_a(OR_LINK, 1, BPF_B); + b2 = new_block(JMP(BPF_JSET)); + b2->s.k = 0x01; /* To DS */ + b2->stmts = s; + gen_not(b2); + + /* + * If To DS is not set, the DA is at 4. + */ + b1 = gen_mac_multicast(4); + gen_and(b2, b1); + + /* + * Now OR together the last two checks. That gives + * the complete set of checks for data frames. + */ + gen_or(b1, b0); + + /* + * Now check for a data frame. + * I.e, check "link[0] & 0x08". + */ + s = gen_load_a(OR_LINK, 0, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x08; + b1->stmts = s; + + /* + * AND that with the checks done for data frames. + */ + gen_and(b1, b0); + + /* + * If the high-order bit of the type value is 0, this + * is a management frame. + * I.e, check "!(link[0] & 0x08)". + */ + s = gen_load_a(OR_LINK, 0, BPF_B); + b2 = new_block(JMP(BPF_JSET)); + b2->s.k = 0x08; + b2->stmts = s; + gen_not(b2); + + /* + * For management frames, the DA is at 4. + */ + b1 = gen_mac_multicast(4); + gen_and(b2, b1); + + /* + * OR that with the checks done for data frames. + * That gives the checks done for management and + * data frames. + */ + gen_or(b1, b0); + + /* + * If the low-order bit of the type value is 1, + * this is either a control frame or a frame + * with a reserved type, and thus not a + * frame with an SA. + * + * I.e., check "!(link[0] & 0x04)". + */ + s = gen_load_a(OR_LINK, 0, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x04; + b1->stmts = s; + gen_not(b1); + + /* + * AND that with the checks for data and management + * frames. + */ + gen_and(b1, b0); + return b0; + case DLT_IP_OVER_FC: + b0 = gen_mac_multicast(2); + return b0; + case DLT_SUNATM: + if (is_lane) { + /* + * Check that the packet doesn't begin with an + * LE Control marker. (We've already generated + * a test for LANE.) + */ + b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H, + 0xFF00); + gen_not(b1); + + /* ether[off_mac] & 1 != 0 */ + b0 = gen_mac_multicast(off_mac); + gen_and(b1, b0); + return b0; + } + break; + default: + break; + } + /* Link not known to support multicasts */ + break; + + case Q_IP: + b0 = gen_linktype(ETHERTYPE_IP); + b1 = gen_cmp_ge(OR_NET, 16, BPF_B, (bpf_int32)224); + gen_and(b0, b1); + return b1; + +#ifdef INET6 + case Q_IPV6: + b0 = gen_linktype(ETHERTYPE_IPV6); + b1 = gen_cmp(OR_NET, 24, BPF_B, (bpf_int32)255); + gen_and(b0, b1); + return b1; +#endif /* INET6 */ + } + bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel"); + /* NOTREACHED */ +} + +/* + * generate command for inbound/outbound. It's here so we can + * make it link-type specific. 'dir' = 0 implies "inbound", + * = 1 implies "outbound". + */ +struct block * +gen_inbound(dir) + int dir; +{ + register struct block *b0; + + /* + * Only some data link types support inbound/outbound qualifiers. + */ + switch (linktype) { + case DLT_SLIP: + b0 = gen_relation(BPF_JEQ, + gen_load(Q_LINK, gen_loadi(0), 1), + gen_loadi(0), + dir); + break; + + case DLT_LINUX_SLL: + if (dir) { + /* + * Match packets sent by this machine. + */ + b0 = gen_cmp(OR_LINK, 0, BPF_H, LINUX_SLL_OUTGOING); + } else { + /* + * Match packets sent to this machine. + * (No broadcast or multicast packets, or + * packets sent to some other machine and + * received promiscuously.) + * + * XXX - packets sent to other machines probably + * shouldn't be matched, but what about broadcast + * or multicast packets we received? + */ + b0 = gen_cmp(OR_LINK, 0, BPF_H, LINUX_SLL_HOST); + } + break; + + case DLT_PFLOG: + b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, dir), BPF_B, + (bpf_int32)((dir == 0) ? PF_IN : PF_OUT)); + break; + + case DLT_PPP_PPPD: + if (dir) { + /* match outgoing packets */ + b0 = gen_cmp(OR_LINK, 0, BPF_B, PPP_PPPD_OUT); + } else { + /* match incoming packets */ + b0 = gen_cmp(OR_LINK, 0, BPF_B, PPP_PPPD_IN); + } + break; + + case DLT_JUNIPER_MFR: + case DLT_JUNIPER_MLFR: + case DLT_JUNIPER_MLPPP: + case DLT_JUNIPER_ATM1: + case DLT_JUNIPER_ATM2: + case DLT_JUNIPER_PPPOE: + case DLT_JUNIPER_PPPOE_ATM: + case DLT_JUNIPER_GGSN: + case DLT_JUNIPER_ES: + case DLT_JUNIPER_MONITOR: + case DLT_JUNIPER_SERVICES: + case DLT_JUNIPER_ETHER: + case DLT_JUNIPER_PPP: + case DLT_JUNIPER_FRELAY: + case DLT_JUNIPER_CHDLC: + /* juniper flags (including direction) are stored + * the byte after the 3-byte magic number */ + if (dir) { + /* match outgoing packets */ + b0 = gen_mcmp(OR_LINK, 3, BPF_B, 0, 0x01); + } else { + /* match incoming packets */ + b0 = gen_mcmp(OR_LINK, 3, BPF_B, 1, 0x01); + } + break; + + default: + bpf_error("inbound/outbound not supported on linktype %d", + linktype); + b0 = NULL; + /* NOTREACHED */ + } + return (b0); +} + +/* PF firewall log matched interface */ +struct block * +gen_pf_ifname(const char *ifname) +{ + struct block *b0; + u_int len, off; + + if (linktype == DLT_PFLOG) { + len = sizeof(((struct pfloghdr *)0)->ifname); + off = offsetof(struct pfloghdr, ifname); + } else { + bpf_error("ifname not supported on linktype 0x%x", linktype); + /* NOTREACHED */ + } + if (strlen(ifname) >= len) { + bpf_error("ifname interface names can only be %d characters", + len-1); + /* NOTREACHED */ + } + b0 = gen_bcmp(OR_LINK, off, strlen(ifname), (const u_char *)ifname); + return (b0); +} + +/* PF firewall log ruleset name */ +struct block * +gen_pf_ruleset(char *ruleset) +{ + struct block *b0; + + if (linktype != DLT_PFLOG) { + bpf_error("ruleset not supported on linktype 0x%x", linktype); + /* NOTREACHED */ + } + if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) { + bpf_error("ruleset names can only be %ld characters", + (long)(sizeof(((struct pfloghdr *)0)->ruleset) - 1)); + /* NOTREACHED */ + } + b0 = gen_bcmp(OR_LINK, offsetof(struct pfloghdr, ruleset), + strlen(ruleset), (const u_char *)ruleset); + return (b0); +} + +/* PF firewall log rule number */ +struct block * +gen_pf_rnr(int rnr) +{ + struct block *b0; + + if (linktype == DLT_PFLOG) { + b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, rulenr), BPF_W, + (bpf_int32)rnr); + } else { + bpf_error("rnr not supported on linktype 0x%x", linktype); + /* NOTREACHED */ + } + + return (b0); +} + +/* PF firewall log sub-rule number */ +struct block * +gen_pf_srnr(int srnr) +{ + struct block *b0; + + if (linktype != DLT_PFLOG) { + bpf_error("srnr not supported on linktype 0x%x", linktype); + /* NOTREACHED */ + } + + b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, subrulenr), BPF_W, + (bpf_int32)srnr); + return (b0); +} + +/* PF firewall log reason code */ +struct block * +gen_pf_reason(int reason) +{ + struct block *b0; + + if (linktype == DLT_PFLOG) { + b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, reason), BPF_B, + (bpf_int32)reason); + } else { + bpf_error("reason not supported on linktype 0x%x", linktype); + /* NOTREACHED */ + } + + return (b0); +} + +/* PF firewall log action */ +struct block * +gen_pf_action(int action) +{ + struct block *b0; + + if (linktype == DLT_PFLOG) { + b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, action), BPF_B, + (bpf_int32)action); + } else { + bpf_error("action not supported on linktype 0x%x", linktype); + /* NOTREACHED */ + } + + return (b0); +} + +struct block * +gen_acode(eaddr, q) + register const u_char *eaddr; + struct qual q; +{ + if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) { + if (linktype == DLT_ARCNET || linktype == DLT_ARCNET_LINUX) + return gen_ahostop(eaddr, (int)q.dir); + } + bpf_error("ARCnet address used in non-arc expression"); + /* NOTREACHED */ +} + +static struct block * +gen_ahostop(eaddr, dir) + register const u_char *eaddr; + register int dir; +{ + register struct block *b0, *b1; + + switch (dir) { + /* src comes first, different from Ethernet */ + case Q_SRC: + return gen_bcmp(OR_LINK, 0, 1, eaddr); + + case Q_DST: + return gen_bcmp(OR_LINK, 1, 1, eaddr); + + case Q_AND: + b0 = gen_ahostop(eaddr, Q_SRC); + b1 = gen_ahostop(eaddr, Q_DST); + gen_and(b0, b1); + return b1; + + case Q_DEFAULT: + case Q_OR: + b0 = gen_ahostop(eaddr, Q_SRC); + b1 = gen_ahostop(eaddr, Q_DST); + gen_or(b0, b1); + return b1; + } + abort(); + /* NOTREACHED */ +} + +/* + * support IEEE 802.1Q VLAN trunk over ethernet + */ +struct block * +gen_vlan(vlan_num) + int vlan_num; +{ + struct block *b0, *b1; + + /* can't check for VLAN-encapsulated packets inside MPLS */ + if (label_stack_depth > 0) + bpf_error("no VLAN match after MPLS"); + + /* + * Change the offsets to point to the type and data fields within + * the VLAN packet. Just increment the offsets, so that we + * can support a hierarchy, e.g. "vlan 300 && vlan 200" to + * capture VLAN 200 encapsulated within VLAN 100. + * + * XXX - this is a bit of a kludge. If we were to split the + * compiler into a parser that parses an expression and + * generates an expression tree, and a code generator that + * takes an expression tree (which could come from our + * parser or from some other parser) and generates BPF code, + * we could perhaps make the offsets parameters of routines + * and, in the handler for an "AND" node, pass to subnodes + * other than the VLAN node the adjusted offsets. + * + * This would mean that "vlan" would, instead of changing the + * behavior of *all* tests after it, change only the behavior + * of tests ANDed with it. That would change the documented + * semantics of "vlan", which might break some expressions. + * However, it would mean that "(vlan and ip) or ip" would check + * both for VLAN-encapsulated IP and IP-over-Ethernet, rather than + * checking only for VLAN-encapsulated IP, so that could still + * be considered worth doing; it wouldn't break expressions + * that are of the form "vlan and ..." or "vlan N and ...", + * which I suspect are the most common expressions involving + * "vlan". "vlan or ..." doesn't necessarily do what the user + * would really want, now, as all the "or ..." tests would + * be done assuming a VLAN, even though the "or" could be viewed + * as meaning "or, if this isn't a VLAN packet...". + */ + orig_linktype = off_linktype; /* save original values */ + orig_nl = off_nl; + + switch (linktype) { + + case DLT_EN10MB: + off_linktype += 4; + off_nl_nosnap += 4; + off_nl += 4; + break; + + default: + bpf_error("no VLAN support for data link type %d", + linktype); + /*NOTREACHED*/ + } + + /* check for VLAN */ + b0 = gen_cmp(OR_LINK, orig_linktype, BPF_H, (bpf_int32)ETHERTYPE_8021Q); + + /* If a specific VLAN is requested, check VLAN id */ + if (vlan_num >= 0) { + b1 = gen_mcmp(OR_LINK, orig_nl, BPF_H, (bpf_int32)vlan_num, + 0x0fff); + gen_and(b0, b1); + b0 = b1; + } + + return (b0); +} + +/* + * support for MPLS + */ +struct block * +gen_mpls(label_num) + int label_num; +{ + struct block *b0,*b1; + + /* + * Change the offsets to point to the type and data fields within + * the MPLS packet. Just increment the offsets, so that we + * can support a hierarchy, e.g. "mpls 100000 && mpls 1024" to + * capture packets with an outer label of 100000 and an inner + * label of 1024. + * + * XXX - this is a bit of a kludge. See comments in gen_vlan(). + */ + orig_nl = off_nl; + + if (label_stack_depth > 0) { + /* just match the bottom-of-stack bit clear */ + b0 = gen_mcmp(OR_LINK, orig_nl-2, BPF_B, 0, 0x01); + } else { + /* + * Indicate that we're checking MPLS-encapsulated headers, + * to make sure higher level code generators don't try to + * match against IP-related protocols such as Q_ARP, Q_RARP + * etc. + */ + switch (linktype) { + + case DLT_C_HDLC: /* fall through */ + case DLT_EN10MB: + b0 = gen_linktype(ETHERTYPE_MPLS); + break; + + case DLT_PPP: + b0 = gen_linktype(PPP_MPLS_UCAST); + break; + + /* FIXME add other DLT_s ... + * for Frame-Relay/and ATM this may get messy due to SNAP headers + * leave it for now */ + + default: + bpf_error("no MPLS support for data link type %d", + linktype); + b0 = NULL; + /*NOTREACHED*/ + break; + } + } + + /* If a specific MPLS label is requested, check it */ + if (label_num >= 0) { + label_num = label_num << 12; /* label is shifted 12 bits on the wire */ + b1 = gen_mcmp(OR_LINK, orig_nl, BPF_W, (bpf_int32)label_num, + 0xfffff000); /* only compare the first 20 bits */ + gen_and(b0, b1); + b0 = b1; + } + + off_nl_nosnap += 4; + off_nl += 4; + label_stack_depth++; + return (b0); +} + +/* + * Support PPPOE discovery and session. + */ +struct block * +gen_pppoed() +{ + /* check for PPPoE discovery */ + return gen_linktype((bpf_int32)ETHERTYPE_PPPOED); +} + +struct block * +gen_pppoes() +{ + struct block *b0; + + /* + * Test against the PPPoE session link-layer type. + */ + b0 = gen_linktype((bpf_int32)ETHERTYPE_PPPOES); + + /* + * Change the offsets to point to the type and data fields within + * the PPP packet. + * + * XXX - this is a bit of a kludge. If we were to split the + * compiler into a parser that parses an expression and + * generates an expression tree, and a code generator that + * takes an expression tree (which could come from our + * parser or from some other parser) and generates BPF code, + * we could perhaps make the offsets parameters of routines + * and, in the handler for an "AND" node, pass to subnodes + * other than the PPPoE node the adjusted offsets. + * + * This would mean that "pppoes" would, instead of changing the + * behavior of *all* tests after it, change only the behavior + * of tests ANDed with it. That would change the documented + * semantics of "pppoes", which might break some expressions. + * However, it would mean that "(pppoes and ip) or ip" would check + * both for VLAN-encapsulated IP and IP-over-Ethernet, rather than + * checking only for VLAN-encapsulated IP, so that could still + * be considered worth doing; it wouldn't break expressions + * that are of the form "pppoes and ..." which I suspect are the + * most common expressions involving "pppoes". "pppoes or ..." + * doesn't necessarily do what the user would really want, now, + * as all the "or ..." tests would be done assuming PPPoE, even + * though the "or" could be viewed as meaning "or, if this isn't + * a PPPoE packet...". + */ + orig_linktype = off_linktype; /* save original values */ + orig_nl = off_nl; + + /* + * The "network-layer" protocol is PPPoE, which has a 6-byte + * PPPoE header, followed by PPP payload, so we set the + * offsets to the network layer offset plus 6 bytes for + * the PPPoE header plus the values appropriate for PPP when + * encapsulated in Ethernet (which means there's no HDLC + * encapsulation). + */ + off_linktype = orig_nl + 6; + off_nl = orig_nl + 6 + 2; + off_nl_nosnap = orig_nl + 6 + 2; + + /* + * Set the link-layer type to PPP, as all subsequent tests will + * be on the encapsulated PPP header. + */ + linktype = DLT_PPP; + + return b0; +} + +struct block * +gen_atmfield_code(atmfield, jvalue, jtype, reverse) + int atmfield; + bpf_int32 jvalue; + bpf_u_int32 jtype; + int reverse; +{ + struct block *b0; + + switch (atmfield) { + + case A_VPI: + if (!is_atm) + bpf_error("'vpi' supported only on raw ATM"); + if (off_vpi == (u_int)-1) + abort(); + b0 = gen_ncmp(OR_LINK, off_vpi, BPF_B, 0xffffffff, jtype, + reverse, jvalue); + break; + + case A_VCI: + if (!is_atm) + bpf_error("'vci' supported only on raw ATM"); + if (off_vci == (u_int)-1) + abort(); + b0 = gen_ncmp(OR_LINK, off_vci, BPF_H, 0xffffffff, jtype, + reverse, jvalue); + break; + + case A_PROTOTYPE: + if (off_proto == (u_int)-1) + abort(); /* XXX - this isn't on FreeBSD */ + b0 = gen_ncmp(OR_LINK, off_proto, BPF_B, 0x0f, jtype, + reverse, jvalue); + break; + + case A_MSGTYPE: + if (off_payload == (u_int)-1) + abort(); + b0 = gen_ncmp(OR_LINK, off_payload + MSG_TYPE_POS, BPF_B, + 0xffffffff, jtype, reverse, jvalue); + break; + + case A_CALLREFTYPE: + if (!is_atm) + bpf_error("'callref' supported only on raw ATM"); + if (off_proto == (u_int)-1) + abort(); + b0 = gen_ncmp(OR_LINK, off_proto, BPF_B, 0xffffffff, + jtype, reverse, jvalue); + break; + + default: + abort(); + } + return b0; +} + +struct block * +gen_atmtype_abbrev(type) + int type; +{ + struct block *b0, *b1; + + switch (type) { + + case A_METAC: + /* Get all packets in Meta signalling Circuit */ + if (!is_atm) + bpf_error("'metac' supported only on raw ATM"); + b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); + b1 = gen_atmfield_code(A_VCI, 1, BPF_JEQ, 0); + gen_and(b0, b1); + break; + + case A_BCC: + /* Get all packets in Broadcast Circuit*/ + if (!is_atm) + bpf_error("'bcc' supported only on raw ATM"); + b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); + b1 = gen_atmfield_code(A_VCI, 2, BPF_JEQ, 0); + gen_and(b0, b1); + break; + + case A_OAMF4SC: + /* Get all cells in Segment OAM F4 circuit*/ + if (!is_atm) + bpf_error("'oam4sc' supported only on raw ATM"); + b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); + b1 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0); + gen_and(b0, b1); + break; + + case A_OAMF4EC: + /* Get all cells in End-to-End OAM F4 Circuit*/ + if (!is_atm) + bpf_error("'oam4ec' supported only on raw ATM"); + b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); + b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0); + gen_and(b0, b1); + break; + + case A_SC: + /* Get all packets in connection Signalling Circuit */ + if (!is_atm) + bpf_error("'sc' supported only on raw ATM"); + b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); + b1 = gen_atmfield_code(A_VCI, 5, BPF_JEQ, 0); + gen_and(b0, b1); + break; + + case A_ILMIC: + /* Get all packets in ILMI Circuit */ + if (!is_atm) + bpf_error("'ilmic' supported only on raw ATM"); + b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); + b1 = gen_atmfield_code(A_VCI, 16, BPF_JEQ, 0); + gen_and(b0, b1); + break; + + case A_LANE: + /* Get all LANE packets */ + if (!is_atm) + bpf_error("'lane' supported only on raw ATM"); + b1 = gen_atmfield_code(A_PROTOTYPE, PT_LANE, BPF_JEQ, 0); + + /* + * Arrange that all subsequent tests assume LANE + * rather than LLC-encapsulated packets, and set + * the offsets appropriately for LANE-encapsulated + * Ethernet. + * + * "off_mac" is the offset of the Ethernet header, + * which is 2 bytes past the ATM pseudo-header + * (skipping the pseudo-header and 2-byte LE Client + * field). The other offsets are Ethernet offsets + * relative to "off_mac". + */ + is_lane = 1; + off_mac = off_payload + 2; /* MAC header */ + off_linktype = off_mac + 12; + off_nl = off_mac + 14; /* Ethernet II */ + off_nl_nosnap = off_mac + 17; /* 802.3+802.2 */ + break; + + case A_LLC: + /* Get all LLC-encapsulated packets */ + if (!is_atm) + bpf_error("'llc' supported only on raw ATM"); + b1 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0); + is_lane = 0; + break; + + default: + abort(); + } + return b1; +} + +struct block * +gen_mtp3field_code(mtp3field, jvalue, jtype, reverse) + int mtp3field; + bpf_u_int32 jvalue; + bpf_u_int32 jtype; + int reverse; +{ + struct block *b0; + bpf_u_int32 val1 , val2 , val3; + + switch (mtp3field) { + + case M_SIO: + if (off_sio == (u_int)-1) + bpf_error("'sio' supported only on SS7"); + /* sio coded on 1 byte so max value 255 */ + if(jvalue > 255) + bpf_error("sio value %u too big; max value = 255", + jvalue); + b0 = gen_ncmp(OR_PACKET, off_sio, BPF_B, 0xffffffff, + (u_int)jtype, reverse, (u_int)jvalue); + break; + + case M_OPC: + if (off_opc == (u_int)-1) + bpf_error("'opc' supported only on SS7"); + /* opc coded on 14 bits so max value 16383 */ + if (jvalue > 16383) + bpf_error("opc value %u too big; max value = 16383", + jvalue); + /* the following instructions are made to convert jvalue + * to the form used to write opc in an ss7 message*/ + val1 = jvalue & 0x00003c00; + val1 = val1 >>10; + val2 = jvalue & 0x000003fc; + val2 = val2 <<6; + val3 = jvalue & 0x00000003; + val3 = val3 <<22; + jvalue = val1 + val2 + val3; + b0 = gen_ncmp(OR_PACKET, off_opc, BPF_W, 0x00c0ff0f, + (u_int)jtype, reverse, (u_int)jvalue); + break; + + case M_DPC: + if (off_dpc == (u_int)-1) + bpf_error("'dpc' supported only on SS7"); + /* dpc coded on 14 bits so max value 16383 */ + if (jvalue > 16383) + bpf_error("dpc value %u too big; max value = 16383", + jvalue); + /* the following instructions are made to convert jvalue + * to the forme used to write dpc in an ss7 message*/ + val1 = jvalue & 0x000000ff; + val1 = val1 << 24; + val2 = jvalue & 0x00003f00; + val2 = val2 << 8; + jvalue = val1 + val2; + b0 = gen_ncmp(OR_PACKET, off_dpc, BPF_W, 0xff3f0000, + (u_int)jtype, reverse, (u_int)jvalue); + break; + + case M_SLS: + if (off_sls == (u_int)-1) + bpf_error("'sls' supported only on SS7"); + /* sls coded on 4 bits so max value 15 */ + if (jvalue > 15) + bpf_error("sls value %u too big; max value = 15", + jvalue); + /* the following instruction is made to convert jvalue + * to the forme used to write sls in an ss7 message*/ + jvalue = jvalue << 4; + b0 = gen_ncmp(OR_PACKET, off_sls, BPF_B, 0xf0, + (u_int)jtype,reverse, (u_int)jvalue); + break; + + default: + abort(); + } + return b0; +} + +static struct block * +gen_msg_abbrev(type) + int type; +{ + struct block *b1; + + /* + * Q.2931 signalling protocol messages for handling virtual circuits + * establishment and teardown + */ + switch (type) { + + case A_SETUP: + b1 = gen_atmfield_code(A_MSGTYPE, SETUP, BPF_JEQ, 0); + break; + + case A_CALLPROCEED: + b1 = gen_atmfield_code(A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0); + break; + + case A_CONNECT: + b1 = gen_atmfield_code(A_MSGTYPE, CONNECT, BPF_JEQ, 0); + break; + + case A_CONNECTACK: + b1 = gen_atmfield_code(A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0); + break; + + case A_RELEASE: + b1 = gen_atmfield_code(A_MSGTYPE, RELEASE, BPF_JEQ, 0); + break; + + case A_RELEASE_DONE: + b1 = gen_atmfield_code(A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0); + break; + + default: + abort(); + } + return b1; +} + +struct block * +gen_atmmulti_abbrev(type) + int type; +{ + struct block *b0, *b1; + + switch (type) { + + case A_OAM: + if (!is_atm) + bpf_error("'oam' supported only on raw ATM"); + b1 = gen_atmmulti_abbrev(A_OAMF4); + break; + + case A_OAMF4: + if (!is_atm) + bpf_error("'oamf4' supported only on raw ATM"); + /* OAM F4 type */ + b0 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0); + b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0); + gen_or(b0, b1); + b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); + gen_and(b0, b1); + break; + + case A_CONNECTMSG: + /* + * Get Q.2931 signalling messages for switched + * virtual connection + */ + if (!is_atm) + bpf_error("'connectmsg' supported only on raw ATM"); + b0 = gen_msg_abbrev(A_SETUP); + b1 = gen_msg_abbrev(A_CALLPROCEED); + gen_or(b0, b1); + b0 = gen_msg_abbrev(A_CONNECT); + gen_or(b0, b1); + b0 = gen_msg_abbrev(A_CONNECTACK); + gen_or(b0, b1); + b0 = gen_msg_abbrev(A_RELEASE); + gen_or(b0, b1); + b0 = gen_msg_abbrev(A_RELEASE_DONE); + gen_or(b0, b1); + b0 = gen_atmtype_abbrev(A_SC); + gen_and(b0, b1); + break; + + case A_METACONNECT: + if (!is_atm) + bpf_error("'metaconnect' supported only on raw ATM"); + b0 = gen_msg_abbrev(A_SETUP); + b1 = gen_msg_abbrev(A_CALLPROCEED); + gen_or(b0, b1); + b0 = gen_msg_abbrev(A_CONNECT); + gen_or(b0, b1); + b0 = gen_msg_abbrev(A_RELEASE); + gen_or(b0, b1); + b0 = gen_msg_abbrev(A_RELEASE_DONE); + gen_or(b0, b1); + b0 = gen_atmtype_abbrev(A_METAC); + gen_and(b0, b1); + break; + + default: + abort(); + } + return b1; +} diff --git a/winpcap/wpcap/libpcap/gencode.h b/winpcap/wpcap/libpcap/gencode.h new file mode 100644 index 0000000..5abc251 --- /dev/null +++ b/winpcap/wpcap/libpcap/gencode.h @@ -0,0 +1,326 @@ +/* + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.60.2.6 2005/09/05 09:08:06 guy Exp $ (LBL) + */ + +/* + * ATM support: + * + * Copyright (c) 1997 Yen Yen Lim and North Dakota State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Yen Yen Lim and + * North Dakota State University + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HAVE___ATTRIBUTE__ +#define __attribute__(x) +#endif /* HAVE___ATTRIBUTE__ */ + +/* Address qualifiers. */ + +#define Q_HOST 1 +#define Q_NET 2 +#define Q_PORT 3 +#define Q_GATEWAY 4 +#define Q_PROTO 5 +#define Q_PROTOCHAIN 6 +#define Q_PORTRANGE 7 + +/* Protocol qualifiers. */ + +#define Q_LINK 1 +#define Q_IP 2 +#define Q_ARP 3 +#define Q_RARP 4 +#define Q_SCTP 5 +#define Q_TCP 6 +#define Q_UDP 7 +#define Q_ICMP 8 +#define Q_IGMP 9 +#define Q_IGRP 10 + + +#define Q_ATALK 11 +#define Q_DECNET 12 +#define Q_LAT 13 +#define Q_SCA 14 +#define Q_MOPRC 15 +#define Q_MOPDL 16 + + +#define Q_IPV6 17 +#define Q_ICMPV6 18 +#define Q_AH 19 +#define Q_ESP 20 + +#define Q_PIM 21 +#define Q_VRRP 22 + +#define Q_AARP 23 + +#define Q_ISO 24 +#define Q_ESIS 25 +#define Q_ISIS 26 +#define Q_CLNP 27 + +#define Q_STP 28 + +#define Q_IPX 29 + +#define Q_NETBEUI 30 + +/* IS-IS Levels */ +#define Q_ISIS_L1 31 +#define Q_ISIS_L2 32 +/* PDU types */ +#define Q_ISIS_IIH 33 +#define Q_ISIS_LAN_IIH 34 +#define Q_ISIS_PTP_IIH 35 +#define Q_ISIS_SNP 36 +#define Q_ISIS_CSNP 37 +#define Q_ISIS_PSNP 38 +#define Q_ISIS_LSP 39 + +#define Q_RADIO 40 + +/* Directional qualifiers. */ + +#define Q_SRC 1 +#define Q_DST 2 +#define Q_OR 3 +#define Q_AND 4 + +#define Q_DEFAULT 0 +#define Q_UNDEF 255 + +/* ATM types */ +#define A_METAC 22 /* Meta signalling Circuit */ +#define A_BCC 23 /* Broadcast Circuit */ +#define A_OAMF4SC 24 /* Segment OAM F4 Circuit */ +#define A_OAMF4EC 25 /* End-to-End OAM F4 Circuit */ +#define A_SC 26 /* Signalling Circuit*/ +#define A_ILMIC 27 /* ILMI Circuit */ +#define A_OAM 28 /* OAM cells : F4 only */ +#define A_OAMF4 29 /* OAM F4 cells: Segment + End-to-end */ +#define A_LANE 30 /* LANE traffic */ +#define A_LLC 31 /* LLC-encapsulated traffic */ + +/* Based on Q.2931 signalling protocol */ +#define A_SETUP 41 /* Setup message */ +#define A_CALLPROCEED 42 /* Call proceeding message */ +#define A_CONNECT 43 /* Connect message */ +#define A_CONNECTACK 44 /* Connect Ack message */ +#define A_RELEASE 45 /* Release message */ +#define A_RELEASE_DONE 46 /* Release message */ + +/* ATM field types */ +#define A_VPI 51 +#define A_VCI 52 +#define A_PROTOTYPE 53 +#define A_MSGTYPE 54 +#define A_CALLREFTYPE 55 + +#define A_CONNECTMSG 70 /* returns Q.2931 signalling messages for + establishing and destroying switched + virtual connection */ +#define A_METACONNECT 71 /* returns Q.2931 signalling messages for + establishing and destroying predefined + virtual circuits, such as broadcast + circuit, oamf4 segment circuit, oamf4 + end-to-end circuits, ILMI circuits or + connection signalling circuit. */ + +/*MTP3 field types */ +#define M_SIO 1 +#define M_OPC 2 +#define M_DPC 3 +#define M_SLS 4 + + +struct slist; + +struct stmt { + int code; + struct slist *jt; /*only for relative jump in block*/ + struct slist *jf; /*only for relative jump in block*/ + bpf_int32 k; +}; + +struct slist { + struct stmt s; + struct slist *next; +}; + +/* + * A bit vector to represent definition sets. We assume TOT_REGISTERS + * is smaller than 8*sizeof(atomset). + */ +typedef bpf_u_int32 atomset; +#define ATOMMASK(n) (1 << (n)) +#define ATOMELEM(d, n) (d & ATOMMASK(n)) + +/* + * An unbounded set. + */ +typedef bpf_u_int32 *uset; + +/* + * Total number of atomic entities, including accumulator (A) and index (X). + * We treat all these guys similarly during flow analysis. + */ +#define N_ATOMS (BPF_MEMWORDS+2) + +struct edge { + int id; + int code; + uset edom; + struct block *succ; + struct block *pred; + struct edge *next; /* link list of incoming edges for a node */ +}; + +struct block { + int id; + struct slist *stmts; /* side effect stmts */ + struct stmt s; /* branch stmt */ + int mark; + int longjt; /* jt branch requires long jump */ + int longjf; /* jf branch requires long jump */ + int level; + int offset; + int sense; + struct edge et; + struct edge ef; + struct block *head; + struct block *link; /* link field used by optimizer */ + uset dom; + uset closure; + struct edge *in_edges; + atomset def, kill; + atomset in_use; + atomset out_use; + int oval; + int val[N_ATOMS]; +}; + +struct arth { + struct block *b; /* protocol checks */ + struct slist *s; /* stmt list */ + int regno; /* virtual register number of result */ +}; + +struct qual { + unsigned char addr; + unsigned char proto; + unsigned char dir; + unsigned char pad; +}; + +struct arth *gen_loadi(int); +struct arth *gen_load(int, struct arth *, int); +struct arth *gen_loadlen(void); +struct arth *gen_neg(struct arth *); +struct arth *gen_arth(int, struct arth *, struct arth *); + +void gen_and(struct block *, struct block *); +void gen_or(struct block *, struct block *); +void gen_not(struct block *); + +struct block *gen_scode(const char *, struct qual); +struct block *gen_ecode(const u_char *, struct qual); +struct block *gen_acode(const u_char *, struct qual); +struct block *gen_mcode(const char *, const char *, int, struct qual); +#ifdef INET6 +struct block *gen_mcode6(const char *, const char *, int, struct qual); +#endif +struct block *gen_ncode(const char *, bpf_u_int32, struct qual); +struct block *gen_proto_abbrev(int); +struct block *gen_relation(int, struct arth *, struct arth *, int); +struct block *gen_less(int); +struct block *gen_greater(int); +struct block *gen_byteop(int, int, int); +struct block *gen_broadcast(int); +struct block *gen_multicast(int); +struct block *gen_inbound(int); + +struct block *gen_vlan(int); +struct block *gen_mpls(int); + +struct block *gen_pppoed(void); +struct block *gen_pppoes(void); + +struct block *gen_atmfield_code(int atmfield, bpf_int32 jvalue, bpf_u_int32 jtype, int reverse); +struct block *gen_atmtype_abbrev(int type); +struct block *gen_atmmulti_abbrev(int type); + +struct block *gen_mtp3field_code(int mtp3field, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse); + +struct block *gen_pf_ifname(const char *); +struct block *gen_pf_rnr(int); +struct block *gen_pf_srnr(int); +struct block *gen_pf_ruleset(char *); +struct block *gen_pf_reason(int); +struct block *gen_pf_action(int); +struct block *gen_pf_dir(int); + +void bpf_optimize(struct block **); +void bpf_error(const char *, ...) + __attribute__((noreturn, format (printf, 1, 2))); + +void finish_parse(struct block *); +char *sdup(const char *); + +struct bpf_insn *icode_to_fcode(struct block *, int *); +int pcap_parse(void); +void lex_init(char *); +void lex_cleanup(void); +void sappend(struct slist *, struct slist *); + +/* XXX */ +#define JT(b) ((b)->et.succ) +#define JF(b) ((b)->ef.succ) + +extern int no_optimize; diff --git a/winpcap/wpcap/libpcap/grammar.c b/winpcap/wpcap/libpcap/grammar.c new file mode 100644 index 0000000..2b7b61a --- /dev/null +++ b/winpcap/wpcap/libpcap/grammar.c @@ -0,0 +1,2919 @@ +/* A Bison parser, made by GNU Bison 2.1. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* Substitute the variable and function names. */ +#define yyparse pcap_parse +#define yylex pcap_lex +#define yyerror pcap_error +#define yylval pcap_lval +#define yychar pcap_char +#define yydebug pcap_debug +#define yynerrs pcap_nerrs + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + DST = 258, + SRC = 259, + HOST = 260, + GATEWAY = 261, + NET = 262, + NETMASK = 263, + PORT = 264, + PORTRANGE = 265, + LESS = 266, + GREATER = 267, + PROTO = 268, + PROTOCHAIN = 269, + CBYTE = 270, + ARP = 271, + RARP = 272, + IP = 273, + SCTP = 274, + TCP = 275, + UDP = 276, + ICMP = 277, + IGMP = 278, + IGRP = 279, + PIM = 280, + VRRP = 281, + ATALK = 282, + AARP = 283, + DECNET = 284, + LAT = 285, + SCA = 286, + MOPRC = 287, + MOPDL = 288, + TK_BROADCAST = 289, + TK_MULTICAST = 290, + NUM = 291, + INBOUND = 292, + OUTBOUND = 293, + PF_IFNAME = 294, + PF_RSET = 295, + PF_RNR = 296, + PF_SRNR = 297, + PF_REASON = 298, + PF_ACTION = 299, + LINK = 300, + GEQ = 301, + LEQ = 302, + NEQ = 303, + ID = 304, + EID = 305, + HID = 306, + HID6 = 307, + AID = 308, + LSH = 309, + RSH = 310, + LEN = 311, + IPV6 = 312, + ICMPV6 = 313, + AH = 314, + ESP = 315, + VLAN = 316, + MPLS = 317, + PPPOED = 318, + PPPOES = 319, + ISO = 320, + ESIS = 321, + CLNP = 322, + ISIS = 323, + L1 = 324, + L2 = 325, + IIH = 326, + LSP = 327, + SNP = 328, + CSNP = 329, + PSNP = 330, + STP = 331, + IPX = 332, + NETBEUI = 333, + LANE = 334, + LLC = 335, + METAC = 336, + BCC = 337, + SC = 338, + ILMIC = 339, + OAMF4EC = 340, + OAMF4SC = 341, + OAM = 342, + OAMF4 = 343, + CONNECTMSG = 344, + METACONNECT = 345, + VPI = 346, + VCI = 347, + RADIO = 348, + SIO = 349, + OPC = 350, + DPC = 351, + SLS = 352, + AND = 353, + OR = 354, + UMINUS = 355 + }; +#endif +/* Tokens. */ +#define DST 258 +#define SRC 259 +#define HOST 260 +#define GATEWAY 261 +#define NET 262 +#define NETMASK 263 +#define PORT 264 +#define PORTRANGE 265 +#define LESS 266 +#define GREATER 267 +#define PROTO 268 +#define PROTOCHAIN 269 +#define CBYTE 270 +#define ARP 271 +#define RARP 272 +#define IP 273 +#define SCTP 274 +#define TCP 275 +#define UDP 276 +#define ICMP 277 +#define IGMP 278 +#define IGRP 279 +#define PIM 280 +#define VRRP 281 +#define ATALK 282 +#define AARP 283 +#define DECNET 284 +#define LAT 285 +#define SCA 286 +#define MOPRC 287 +#define MOPDL 288 +#define TK_BROADCAST 289 +#define TK_MULTICAST 290 +#define NUM 291 +#define INBOUND 292 +#define OUTBOUND 293 +#define PF_IFNAME 294 +#define PF_RSET 295 +#define PF_RNR 296 +#define PF_SRNR 297 +#define PF_REASON 298 +#define PF_ACTION 299 +#define LINK 300 +#define GEQ 301 +#define LEQ 302 +#define NEQ 303 +#define ID 304 +#define EID 305 +#define HID 306 +#define HID6 307 +#define AID 308 +#define LSH 309 +#define RSH 310 +#define LEN 311 +#define IPV6 312 +#define ICMPV6 313 +#define AH 314 +#define ESP 315 +#define VLAN 316 +#define MPLS 317 +#define PPPOED 318 +#define PPPOES 319 +#define ISO 320 +#define ESIS 321 +#define CLNP 322 +#define ISIS 323 +#define L1 324 +#define L2 325 +#define IIH 326 +#define LSP 327 +#define SNP 328 +#define CSNP 329 +#define PSNP 330 +#define STP 331 +#define IPX 332 +#define NETBEUI 333 +#define LANE 334 +#define LLC 335 +#define METAC 336 +#define BCC 337 +#define SC 338 +#define ILMIC 339 +#define OAMF4EC 340 +#define OAMF4SC 341 +#define OAM 342 +#define OAMF4 343 +#define CONNECTMSG 344 +#define METACONNECT 345 +#define VPI 346 +#define VCI 347 +#define RADIO 348 +#define SIO 349 +#define OPC 350 +#define DPC 351 +#define SLS 352 +#define AND 353 +#define OR 354 +#define UMINUS 355 + + + + +/* Copy the first part of user declarations. */ +#line 1 "../libpcap/GRAMMAR.Y" + +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.86.2.5 2005/09/05 09:08:06 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include +#else /* WIN32 */ +#include +#include +#endif /* WIN32 */ + +#include + +#ifndef WIN32 +#if __STDC__ +struct mbuf; +struct rtentry; +#endif + +#include +#endif /* WIN32 */ + +#include + +#include "pcap-int.h" + +#include "gencode.h" +#include "pf.h" +#include + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#define QSET(q, p, d, a) (q).proto = (p),\ + (q).dir = (d),\ + (q).addr = (a) + +int n_errors = 0; + +static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF }; + +static void +yyerror(char *msg) +{ + ++n_errors; + bpf_error("%s", msg); + /* NOTREACHED */ +} + +#ifndef YYBISON +int yyparse(void); + +int +pcap_parse() +{ + return (yyparse()); +} +#endif + + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 90 "../libpcap/GRAMMAR.Y" +typedef union YYSTYPE { + int i; + bpf_u_int32 h; + u_char *e; + char *s; + struct stmt *stmt; + struct arth *a; + struct { + struct qual q; + int atmfieldtype; + int mtp3fieldtype; + struct block *b; + } blk; + struct block *rblk; +} YYSTYPE; +/* Line 196 of yacc.c. */ +#line 398 "y.tab.c" +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 219 of yacc.c. */ +#line 410 "y.tab.c" + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus)) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# else +# define YYSTACK_ALLOC alloca +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYINCLUDED_STDLIB_H +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1) +# endif +# ifdef __cplusplus +extern "C" { +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \ + && (defined (__STDC__) || defined (__cplusplus))) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \ + && (defined (__STDC__) || defined (__cplusplus))) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifdef __cplusplus +} +# endif +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short int yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined (__GNUC__) && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short int yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 3 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 591 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 116 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 40 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 182 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 250 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 355 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 100, 2, 2, 2, 2, 102, 2, + 109, 108, 105, 103, 2, 104, 2, 106, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 115, 2, + 112, 111, 110, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 113, 2, 114, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 101, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 107 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned short int yyprhs[] = +{ + 0, 0, 3, 6, 8, 9, 11, 15, 19, 23, + 27, 29, 31, 33, 35, 39, 41, 45, 49, 51, + 55, 57, 59, 61, 64, 66, 68, 70, 74, 78, + 80, 82, 84, 87, 91, 94, 97, 100, 103, 106, + 109, 113, 115, 119, 123, 125, 127, 129, 132, 135, + 137, 138, 140, 142, 146, 150, 154, 158, 160, 162, + 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, + 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, + 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, + 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, + 244, 247, 250, 253, 256, 261, 263, 265, 268, 270, + 273, 275, 277, 279, 281, 284, 287, 290, 293, 296, + 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, + 319, 321, 326, 333, 337, 341, 345, 349, 353, 357, + 361, 365, 368, 372, 374, 376, 378, 380, 382, 384, + 386, 390, 392, 394, 396, 398, 400, 402, 404, 406, + 408, 410, 412, 414, 416, 418, 420, 423, 426, 430, + 432, 434, 438, 440, 442, 444, 446, 448, 451, 454, + 458, 460, 462 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const short int yyrhs[] = +{ + 117, 0, -1, 118, 119, -1, 118, -1, -1, 128, + -1, 119, 120, 128, -1, 119, 120, 122, -1, 119, + 121, 128, -1, 119, 121, 122, -1, 98, -1, 99, + -1, 123, -1, 145, -1, 125, 126, 108, -1, 49, + -1, 51, 106, 36, -1, 51, 8, 51, -1, 51, + -1, 52, 106, 36, -1, 52, -1, 50, -1, 53, + -1, 124, 122, -1, 100, -1, 109, -1, 123, -1, + 127, 120, 122, -1, 127, 121, 122, -1, 145, -1, + 126, -1, 130, -1, 124, 128, -1, 131, 132, 133, + -1, 131, 132, -1, 131, 133, -1, 131, 13, -1, + 131, 14, -1, 131, 134, -1, 129, 122, -1, 125, + 119, 108, -1, 135, -1, 142, 140, 142, -1, 142, + 141, 142, -1, 136, -1, 146, -1, 147, -1, 148, + 149, -1, 152, 153, -1, 135, -1, -1, 4, -1, + 3, -1, 4, 99, 3, -1, 3, 99, 4, -1, + 4, 98, 3, -1, 3, 98, 4, -1, 5, -1, + 7, -1, 9, -1, 10, -1, 6, -1, 45, -1, + 18, -1, 16, -1, 17, -1, 19, -1, 20, -1, + 21, -1, 22, -1, 23, -1, 24, -1, 25, -1, + 26, -1, 27, -1, 28, -1, 29, -1, 30, -1, + 31, -1, 33, -1, 32, -1, 57, -1, 58, -1, + 59, -1, 60, -1, 65, -1, 66, -1, 68, -1, + 69, -1, 70, -1, 71, -1, 72, -1, 73, -1, + 75, -1, 74, -1, 67, -1, 76, -1, 77, -1, + 78, -1, 93, -1, 131, 34, -1, 131, 35, -1, + 11, 36, -1, 12, 36, -1, 15, 36, 144, 36, + -1, 37, -1, 38, -1, 61, 145, -1, 61, -1, + 62, 145, -1, 62, -1, 63, -1, 64, -1, 137, + -1, 39, 49, -1, 40, 49, -1, 41, 36, -1, + 42, 36, -1, 43, 138, -1, 44, 139, -1, 36, + -1, 49, -1, 49, -1, 110, -1, 46, -1, 111, + -1, 47, -1, 112, -1, 48, -1, 145, -1, 143, + -1, 135, 113, 142, 114, -1, 135, 113, 142, 115, + 36, 114, -1, 142, 103, 142, -1, 142, 104, 142, + -1, 142, 105, 142, -1, 142, 106, 142, -1, 142, + 102, 142, -1, 142, 101, 142, -1, 142, 54, 142, + -1, 142, 55, 142, -1, 104, 142, -1, 125, 143, + 108, -1, 56, -1, 102, -1, 101, -1, 112, -1, + 110, -1, 111, -1, 36, -1, 125, 145, 108, -1, + 79, -1, 80, -1, 81, -1, 82, -1, 85, -1, + 86, -1, 83, -1, 84, -1, 87, -1, 88, -1, + 89, -1, 90, -1, 91, -1, 92, -1, 150, -1, + 140, 36, -1, 141, 36, -1, 125, 151, 108, -1, + 36, -1, 150, -1, 151, 121, 150, -1, 94, -1, + 95, -1, 96, -1, 97, -1, 154, -1, 140, 36, + -1, 141, 36, -1, 125, 155, 108, -1, 36, -1, + 154, -1, 155, 121, 154, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short int yyrline[] = +{ + 0, 160, 160, 164, 166, 168, 169, 170, 171, 172, + 174, 176, 178, 179, 181, 183, 184, 186, 188, 193, + 202, 211, 220, 229, 231, 233, 235, 236, 237, 239, + 241, 243, 244, 246, 247, 248, 249, 250, 251, 253, + 254, 255, 256, 258, 260, 261, 262, 263, 264, 267, + 268, 271, 272, 273, 274, 275, 276, 279, 280, 281, + 282, 285, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, + 336, 337, 338, 339, 342, 343, 344, 345, 346, 347, + 350, 351, 364, 375, 376, 377, 379, 380, 381, 383, + 384, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 400, 401, 402, 403, 404, 406, + 407, 409, 410, 411, 412, 413, 414, 415, 416, 418, + 419, 420, 421, 424, 425, 427, 428, 429, 430, 432, + 439, 440, 443, 444, 445, 446, 448, 449, 450, 451, + 453, 462, 463 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "DST", "SRC", "HOST", "GATEWAY", "NET", + "NETMASK", "PORT", "PORTRANGE", "LESS", "GREATER", "PROTO", "PROTOCHAIN", + "CBYTE", "ARP", "RARP", "IP", "SCTP", "TCP", "UDP", "ICMP", "IGMP", + "IGRP", "PIM", "VRRP", "ATALK", "AARP", "DECNET", "LAT", "SCA", "MOPRC", + "MOPDL", "TK_BROADCAST", "TK_MULTICAST", "NUM", "INBOUND", "OUTBOUND", + "PF_IFNAME", "PF_RSET", "PF_RNR", "PF_SRNR", "PF_REASON", "PF_ACTION", + "LINK", "GEQ", "LEQ", "NEQ", "ID", "EID", "HID", "HID6", "AID", "LSH", + "RSH", "LEN", "IPV6", "ICMPV6", "AH", "ESP", "VLAN", "MPLS", "PPPOED", + "PPPOES", "ISO", "ESIS", "CLNP", "ISIS", "L1", "L2", "IIH", "LSP", "SNP", + "CSNP", "PSNP", "STP", "IPX", "NETBEUI", "LANE", "LLC", "METAC", "BCC", + "SC", "ILMIC", "OAMF4EC", "OAMF4SC", "OAM", "OAMF4", "CONNECTMSG", + "METACONNECT", "VPI", "VCI", "RADIO", "SIO", "OPC", "DPC", "SLS", "AND", + "OR", "'!'", "'|'", "'&'", "'+'", "'-'", "'*'", "'/'", "UMINUS", "')'", + "'('", "'>'", "'='", "'<'", "'['", "']'", "':'", "$accept", "prog", + "null", "expr", "and", "or", "id", "nid", "not", "paren", "pid", "qid", + "term", "head", "rterm", "pqual", "dqual", "aqual", "ndaqual", "pname", + "other", "pfvar", "reason", "action", "relop", "irelop", "arth", "narth", + "byteop", "pnum", "atmtype", "atmmultitype", "atmfield", "atmvalue", + "atmfieldvalue", "atmlistvalue", "mtp3field", "mtp3value", + "mtp3fieldvalue", "mtp3listvalue", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short int yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 33, 124, 38, 43, 45, 42, 47, 355, 41, 40, + 62, 61, 60, 91, 93, 58 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 116, 117, 117, 118, 119, 119, 119, 119, 119, + 120, 121, 122, 122, 122, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 124, 125, 126, 126, 126, 127, + 127, 128, 128, 129, 129, 129, 129, 129, 129, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 130, 131, + 131, 132, 132, 132, 132, 132, 132, 133, 133, 133, + 133, 134, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 137, 137, 137, 137, 137, 137, + 138, 138, 139, 140, 140, 140, 141, 141, 141, 142, + 142, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 144, 144, 144, 144, 144, 145, + 145, 146, 146, 146, 146, 146, 146, 146, 146, 147, + 147, 147, 147, 148, 148, 149, 149, 149, 149, 150, + 151, 151, 152, 152, 152, 152, 153, 153, 153, 153, + 154, 155, 155 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 2, 1, 0, 1, 3, 3, 3, 3, + 1, 1, 1, 1, 3, 1, 3, 3, 1, 3, + 1, 1, 1, 2, 1, 1, 1, 3, 3, 1, + 1, 1, 2, 3, 2, 2, 2, 2, 2, 2, + 3, 1, 3, 3, 1, 1, 1, 2, 2, 1, + 0, 1, 1, 3, 3, 3, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 4, 1, 1, 2, 1, 2, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 4, 6, 3, 3, 3, 3, 3, 3, 3, + 3, 2, 3, 1, 1, 1, 1, 1, 1, 1, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 3, 1, + 1, 3, 1, 1, 1, 1, 1, 2, 2, 3, + 1, 1, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 4, 0, 50, 1, 0, 0, 0, 64, 65, 63, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 80, 79, 149, 105, 106, 0, 0, + 0, 0, 0, 0, 62, 143, 81, 82, 83, 84, + 108, 110, 111, 112, 85, 86, 95, 87, 88, 89, + 90, 91, 92, 94, 93, 96, 97, 98, 151, 152, + 153, 154, 157, 158, 155, 156, 159, 160, 161, 162, + 163, 164, 99, 172, 173, 174, 175, 24, 0, 25, + 2, 50, 50, 5, 0, 31, 0, 49, 44, 113, + 0, 130, 129, 45, 46, 0, 0, 102, 103, 0, + 114, 115, 116, 117, 120, 121, 118, 122, 119, 0, + 107, 109, 0, 0, 141, 10, 11, 50, 50, 32, + 0, 130, 129, 15, 21, 18, 20, 22, 39, 12, + 0, 0, 13, 52, 51, 57, 61, 58, 59, 60, + 36, 37, 100, 101, 34, 35, 38, 0, 124, 126, + 128, 0, 0, 0, 0, 0, 0, 0, 0, 123, + 125, 127, 0, 0, 169, 0, 0, 0, 47, 165, + 180, 0, 0, 0, 48, 176, 145, 144, 147, 148, + 146, 0, 0, 0, 7, 50, 50, 6, 129, 9, + 8, 40, 142, 150, 0, 0, 0, 23, 26, 30, + 0, 29, 0, 0, 0, 0, 33, 0, 139, 140, + 138, 137, 133, 134, 135, 136, 42, 43, 170, 0, + 166, 167, 181, 0, 177, 178, 104, 129, 17, 16, + 19, 14, 0, 0, 56, 54, 55, 53, 131, 0, + 168, 0, 179, 0, 27, 28, 0, 171, 182, 132 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const short int yydefgoto[] = +{ + -1, 1, 2, 120, 117, 118, 197, 129, 130, 112, + 199, 200, 83, 84, 85, 86, 144, 145, 146, 113, + 88, 89, 106, 108, 162, 163, 90, 91, 181, 92, + 93, 94, 95, 168, 169, 219, 96, 174, 175, 223 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -177 +static const short int yypact[] = +{ + -177, 15, 196, -177, -13, -7, -3, -177, -177, -177, + -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, + -177, -177, -177, -177, -177, -177, -177, -177, 10, 14, + 0, 17, -24, 25, -177, -177, -177, -177, -177, -177, + -14, -14, -177, -177, -177, -177, -177, -177, -177, -177, + -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, + -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, + -177, -177, -177, -177, -177, -177, -177, -177, 480, -177, + -67, 386, 386, -177, -33, -177, 556, 4, -177, -177, + 475, -177, -177, -177, -177, 133, 139, -177, -177, -56, + -177, -177, -177, -177, -177, -177, -177, -177, -177, -14, + -177, -177, 480, -36, -177, -177, -177, 291, 291, -177, + -71, -51, -27, -177, -177, 5, -15, -177, -177, -177, + -33, -33, -177, -30, -26, -177, -177, -177, -177, -177, + -177, -177, -177, -177, 55, -177, -177, 480, -177, -177, + -177, 480, 480, 480, 480, 480, 480, 480, 480, -177, + -177, -177, 480, 480, -177, 50, 63, 70, -177, -177, + -177, 72, 94, 105, -177, -177, -177, -177, -177, -177, + -177, 112, -27, 99, -177, 291, 291, -177, 2, -177, + -177, -177, -177, -177, 106, 122, 123, -177, -177, 58, + -67, -27, 163, 164, 167, 168, -177, 59, 41, 41, + 335, 16, -1, -1, -177, -177, 99, 99, -177, -78, + -177, -177, -177, -59, -177, -177, -177, -47, -177, -177, + -177, -177, -33, -33, -177, -177, -177, -177, -177, 136, + -177, 50, -177, 72, -177, -177, 62, -177, -177, -177 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const short int yypgoto[] = +{ + -177, -177, -177, 175, -22, -176, -83, -120, 6, -2, + -177, -177, -76, -177, -177, -177, -177, 38, -177, 8, + -177, -177, -177, -177, 44, 60, -20, -68, -177, -34, + -177, -177, -177, -177, -156, -177, -177, -177, -145, -177 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -42 +static const short int yytable[] = +{ + 82, 128, -13, 25, -41, 119, 110, 111, 81, 218, + 87, 198, 104, 194, 121, 3, 123, 124, 125, 126, + 127, 116, 25, 97, 233, 105, 222, 115, 116, 98, + 240, 115, 116, 99, 184, 189, 102, 191, 109, 109, + 116, 187, 190, 241, 121, 176, 177, 243, 122, 242, + 132, -29, -29, 103, 178, 179, 180, 192, 114, 100, + 135, 193, 137, 101, 138, 139, 198, 77, 202, 203, + 151, 152, 204, 205, 107, 182, 79, 147, 122, 82, + 82, 193, 131, 188, 188, 247, 164, 81, 81, 87, + 87, 196, 183, 165, 171, 79, 132, 201, 248, 220, + -13, -13, -41, -41, 157, 158, 221, 109, 170, 119, + -13, 195, -41, 151, 152, 186, 186, 147, 121, 155, + 156, 157, 158, 185, 185, 87, 87, 207, 131, 109, + 224, 208, 209, 210, 211, 212, 213, 214, 215, 166, + 172, 225, 216, 217, 155, 156, 157, 158, 226, 244, + 245, 188, 227, 151, 152, 167, 173, 228, 229, 230, + 153, 154, 155, 156, 157, 158, 231, 234, 235, 164, + 236, 237, 246, 238, 239, 170, 249, 80, 232, 148, + 149, 150, 206, 186, 82, 148, 149, 150, 0, 0, + 0, 185, 185, 87, 87, 0, -3, 0, 132, 132, + 153, 154, 155, 156, 157, 158, 0, 4, 5, 0, + 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 131, 131, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 79, 159, 160, 161, 0, 0, 79, 159, + 160, 161, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 0, 0, 77, 0, 0, 0, + 78, 0, 4, 5, 0, 79, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 0, 0, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 0, 0, 0, + 123, 124, 125, 126, 127, 0, 0, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 151, + 152, 77, 0, 0, 0, 78, 0, 4, 5, 0, + 79, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 0, 0, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 0, 0, 0, 0, 0, 154, 155, 156, + 157, 158, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 0, 0, 77, 0, 0, 0, + 78, 0, 0, 0, 0, 79, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 0, 0, 25, 0, 0, 0, + 0, 148, 149, 150, 0, 34, 0, 0, 0, 151, + 152, 0, 0, 0, 0, 0, 35, 36, 37, 38, + 39, 0, 0, 0, 0, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 133, + 134, 135, 136, 137, 0, 138, 139, 0, 0, 140, + 141, 0, 0, 72, 0, 0, 153, 154, 155, 156, + 157, 158, 0, 0, 78, 159, 160, 161, 0, 79, + 142, 143 +}; + +static const short int yycheck[] = +{ + 2, 84, 0, 36, 0, 81, 40, 41, 2, 165, + 2, 131, 36, 8, 82, 0, 49, 50, 51, 52, + 53, 99, 36, 36, 200, 49, 171, 98, 99, 36, + 108, 98, 99, 36, 117, 118, 36, 108, 40, 41, + 99, 117, 118, 219, 112, 101, 102, 223, 82, 108, + 84, 98, 99, 36, 110, 111, 112, 108, 78, 49, + 5, 108, 7, 49, 9, 10, 186, 100, 98, 99, + 54, 55, 98, 99, 49, 109, 109, 113, 112, 81, + 82, 108, 84, 117, 118, 241, 36, 81, 82, 81, + 82, 106, 112, 95, 96, 109, 130, 131, 243, 36, + 98, 99, 98, 99, 105, 106, 36, 109, 36, 185, + 108, 106, 108, 54, 55, 117, 118, 113, 186, 103, + 104, 105, 106, 117, 118, 117, 118, 147, 130, 131, + 36, 151, 152, 153, 154, 155, 156, 157, 158, 95, + 96, 36, 162, 163, 103, 104, 105, 106, 36, 232, + 233, 185, 186, 54, 55, 95, 96, 51, 36, 36, + 101, 102, 103, 104, 105, 106, 108, 4, 4, 36, + 3, 3, 36, 114, 115, 36, 114, 2, 200, 46, + 47, 48, 144, 185, 186, 46, 47, 48, -1, -1, + -1, 185, 186, 185, 186, -1, 0, -1, 232, 233, + 101, 102, 103, 104, 105, 106, -1, 11, 12, -1, + -1, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 232, 233, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 109, 110, 111, 112, -1, -1, 109, 110, + 111, 112, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, -1, -1, 100, -1, -1, -1, + 104, -1, 11, 12, -1, 109, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, -1, -1, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, -1, -1, -1, + 49, 50, 51, 52, 53, -1, -1, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 54, + 55, 100, -1, -1, -1, 104, -1, 11, 12, -1, + 109, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + -1, -1, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, -1, -1, -1, -1, -1, 102, 103, 104, + 105, 106, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, -1, -1, 100, -1, -1, -1, + 104, -1, -1, -1, -1, 109, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, -1, -1, 36, -1, -1, -1, + -1, 46, 47, 48, -1, 45, -1, -1, -1, 54, + 55, -1, -1, -1, -1, -1, 56, 57, 58, 59, + 60, -1, -1, -1, -1, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 3, + 4, 5, 6, 7, -1, 9, 10, -1, -1, 13, + 14, -1, -1, 93, -1, -1, 101, 102, 103, 104, + 105, 106, -1, -1, 104, 110, 111, 112, -1, 109, + 34, 35 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 117, 118, 0, 11, 12, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 100, 104, 109, + 119, 124, 125, 128, 129, 130, 131, 135, 136, 137, + 142, 143, 145, 146, 147, 148, 152, 36, 36, 36, + 49, 49, 36, 36, 36, 49, 138, 49, 139, 125, + 145, 145, 125, 135, 142, 98, 99, 120, 121, 128, + 119, 143, 145, 49, 50, 51, 52, 53, 122, 123, + 124, 125, 145, 3, 4, 5, 6, 7, 9, 10, + 13, 14, 34, 35, 132, 133, 134, 113, 46, 47, + 48, 54, 55, 101, 102, 103, 104, 105, 106, 110, + 111, 112, 140, 141, 36, 125, 140, 141, 149, 150, + 36, 125, 140, 141, 153, 154, 101, 102, 110, 111, + 112, 144, 145, 142, 122, 124, 125, 128, 145, 122, + 128, 108, 108, 108, 8, 106, 106, 122, 123, 126, + 127, 145, 98, 99, 98, 99, 133, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 150, 151, + 36, 36, 154, 155, 36, 36, 36, 145, 51, 36, + 36, 108, 120, 121, 4, 4, 3, 3, 114, 115, + 108, 121, 108, 121, 122, 122, 36, 150, 154, 114 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (0) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (0) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short int *bottom, short int *top) +#else +static void +yy_stack_print (bottom, top) + short int *bottom; + short int *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ", + yyrule - 1, yylno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + size_t yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +#endif /* YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The look-ahead symbol. */ +int yychar; + +/* The semantic value of the look-ahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + ; +#endif +#endif +{ + + int yystate; + int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Look-ahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + short int yyssa[YYINITDEPTH]; + short int *yyss = yyssa; + short int *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short int *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short int *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a look-ahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to look-ahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a look-ahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 161 "../libpcap/GRAMMAR.Y" + { + finish_parse((yyvsp[0].blk).b); +} + break; + + case 4: +#line 166 "../libpcap/GRAMMAR.Y" + { (yyval.blk).q = qerr; } + break; + + case 6: +#line 169 "../libpcap/GRAMMAR.Y" + { gen_and((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); } + break; + + case 7: +#line 170 "../libpcap/GRAMMAR.Y" + { gen_and((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); } + break; + + case 8: +#line 171 "../libpcap/GRAMMAR.Y" + { gen_or((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); } + break; + + case 9: +#line 172 "../libpcap/GRAMMAR.Y" + { gen_or((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); } + break; + + case 10: +#line 174 "../libpcap/GRAMMAR.Y" + { (yyval.blk) = (yyvsp[-1].blk); } + break; + + case 11: +#line 176 "../libpcap/GRAMMAR.Y" + { (yyval.blk) = (yyvsp[-1].blk); } + break; + + case 13: +#line 179 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_ncode(NULL, (bpf_u_int32)(yyvsp[0].i), + (yyval.blk).q = (yyvsp[-1].blk).q); } + break; + + case 14: +#line 181 "../libpcap/GRAMMAR.Y" + { (yyval.blk) = (yyvsp[-1].blk); } + break; + + case 15: +#line 183 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_scode((yyvsp[0].s), (yyval.blk).q = (yyvsp[-1].blk).q); } + break; + + case 16: +#line 184 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_mcode((yyvsp[-2].s), NULL, (yyvsp[0].i), + (yyval.blk).q = (yyvsp[-3].blk).q); } + break; + + case 17: +#line 186 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_mcode((yyvsp[-2].s), (yyvsp[0].s), 0, + (yyval.blk).q = (yyvsp[-3].blk).q); } + break; + + case 18: +#line 188 "../libpcap/GRAMMAR.Y" + { + /* Decide how to parse HID based on proto */ + (yyval.blk).q = (yyvsp[-1].blk).q; + (yyval.blk).b = gen_ncode((yyvsp[0].s), 0, (yyval.blk).q); + } + break; + + case 19: +#line 193 "../libpcap/GRAMMAR.Y" + { +#ifdef INET6 + (yyval.blk).b = gen_mcode6((yyvsp[-2].s), NULL, (yyvsp[0].i), + (yyval.blk).q = (yyvsp[-3].blk).q); +#else + bpf_error("'ip6addr/prefixlen' not supported " + "in this configuration"); +#endif /*INET6*/ + } + break; + + case 20: +#line 202 "../libpcap/GRAMMAR.Y" + { +#ifdef INET6 + (yyval.blk).b = gen_mcode6((yyvsp[0].s), 0, 128, + (yyval.blk).q = (yyvsp[-1].blk).q); +#else + bpf_error("'ip6addr' not supported " + "in this configuration"); +#endif /*INET6*/ + } + break; + + case 21: +#line 211 "../libpcap/GRAMMAR.Y" + { + (yyval.blk).b = gen_ecode((yyvsp[0].e), (yyval.blk).q = (yyvsp[-1].blk).q); + /* + * $1 was allocated by "pcap_ether_aton()", + * so we must free it now that we're done + * with it. + */ + free((yyvsp[0].e)); + } + break; + + case 22: +#line 220 "../libpcap/GRAMMAR.Y" + { + (yyval.blk).b = gen_acode((yyvsp[0].e), (yyval.blk).q = (yyvsp[-1].blk).q); + /* + * $1 was allocated by "pcap_ether_aton()", + * so we must free it now that we're done + * with it. + */ + free((yyvsp[0].e)); + } + break; + + case 23: +#line 229 "../libpcap/GRAMMAR.Y" + { gen_not((yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); } + break; + + case 24: +#line 231 "../libpcap/GRAMMAR.Y" + { (yyval.blk) = (yyvsp[-1].blk); } + break; + + case 25: +#line 233 "../libpcap/GRAMMAR.Y" + { (yyval.blk) = (yyvsp[-1].blk); } + break; + + case 27: +#line 236 "../libpcap/GRAMMAR.Y" + { gen_and((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); } + break; + + case 28: +#line 237 "../libpcap/GRAMMAR.Y" + { gen_or((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); } + break; + + case 29: +#line 239 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_ncode(NULL, (bpf_u_int32)(yyvsp[0].i), + (yyval.blk).q = (yyvsp[-1].blk).q); } + break; + + case 32: +#line 244 "../libpcap/GRAMMAR.Y" + { gen_not((yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); } + break; + + case 33: +#line 246 "../libpcap/GRAMMAR.Y" + { QSET((yyval.blk).q, (yyvsp[-2].i), (yyvsp[-1].i), (yyvsp[0].i)); } + break; + + case 34: +#line 247 "../libpcap/GRAMMAR.Y" + { QSET((yyval.blk).q, (yyvsp[-1].i), (yyvsp[0].i), Q_DEFAULT); } + break; + + case 35: +#line 248 "../libpcap/GRAMMAR.Y" + { QSET((yyval.blk).q, (yyvsp[-1].i), Q_DEFAULT, (yyvsp[0].i)); } + break; + + case 36: +#line 249 "../libpcap/GRAMMAR.Y" + { QSET((yyval.blk).q, (yyvsp[-1].i), Q_DEFAULT, Q_PROTO); } + break; + + case 37: +#line 250 "../libpcap/GRAMMAR.Y" + { QSET((yyval.blk).q, (yyvsp[-1].i), Q_DEFAULT, Q_PROTOCHAIN); } + break; + + case 38: +#line 251 "../libpcap/GRAMMAR.Y" + { QSET((yyval.blk).q, (yyvsp[-1].i), Q_DEFAULT, (yyvsp[0].i)); } + break; + + case 39: +#line 253 "../libpcap/GRAMMAR.Y" + { (yyval.blk) = (yyvsp[0].blk); } + break; + + case 40: +#line 254 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = (yyvsp[-1].blk).b; (yyval.blk).q = (yyvsp[-2].blk).q; } + break; + + case 41: +#line 255 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_proto_abbrev((yyvsp[0].i)); (yyval.blk).q = qerr; } + break; + + case 42: +#line 256 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_relation((yyvsp[-1].i), (yyvsp[-2].a), (yyvsp[0].a), 0); + (yyval.blk).q = qerr; } + break; + + case 43: +#line 258 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_relation((yyvsp[-1].i), (yyvsp[-2].a), (yyvsp[0].a), 1); + (yyval.blk).q = qerr; } + break; + + case 44: +#line 260 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = (yyvsp[0].rblk); (yyval.blk).q = qerr; } + break; + + case 45: +#line 261 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_atmtype_abbrev((yyvsp[0].i)); (yyval.blk).q = qerr; } + break; + + case 46: +#line 262 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_atmmulti_abbrev((yyvsp[0].i)); (yyval.blk).q = qerr; } + break; + + case 47: +#line 263 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = (yyvsp[0].blk).b; (yyval.blk).q = qerr; } + break; + + case 48: +#line 264 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = (yyvsp[0].blk).b; (yyval.blk).q = qerr; } + break; + + case 50: +#line 268 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_DEFAULT; } + break; + + case 51: +#line 271 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_SRC; } + break; + + case 52: +#line 272 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_DST; } + break; + + case 53: +#line 273 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_OR; } + break; + + case 54: +#line 274 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_OR; } + break; + + case 55: +#line 275 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_AND; } + break; + + case 56: +#line 276 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_AND; } + break; + + case 57: +#line 279 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_HOST; } + break; + + case 58: +#line 280 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_NET; } + break; + + case 59: +#line 281 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_PORT; } + break; + + case 60: +#line 282 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_PORTRANGE; } + break; + + case 61: +#line 285 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_GATEWAY; } + break; + + case 62: +#line 287 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_LINK; } + break; + + case 63: +#line 288 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_IP; } + break; + + case 64: +#line 289 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ARP; } + break; + + case 65: +#line 290 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_RARP; } + break; + + case 66: +#line 291 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_SCTP; } + break; + + case 67: +#line 292 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_TCP; } + break; + + case 68: +#line 293 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_UDP; } + break; + + case 69: +#line 294 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ICMP; } + break; + + case 70: +#line 295 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_IGMP; } + break; + + case 71: +#line 296 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_IGRP; } + break; + + case 72: +#line 297 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_PIM; } + break; + + case 73: +#line 298 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_VRRP; } + break; + + case 74: +#line 299 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ATALK; } + break; + + case 75: +#line 300 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_AARP; } + break; + + case 76: +#line 301 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_DECNET; } + break; + + case 77: +#line 302 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_LAT; } + break; + + case 78: +#line 303 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_SCA; } + break; + + case 79: +#line 304 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_MOPDL; } + break; + + case 80: +#line 305 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_MOPRC; } + break; + + case 81: +#line 306 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_IPV6; } + break; + + case 82: +#line 307 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ICMPV6; } + break; + + case 83: +#line 308 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_AH; } + break; + + case 84: +#line 309 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ESP; } + break; + + case 85: +#line 310 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ISO; } + break; + + case 86: +#line 311 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ESIS; } + break; + + case 87: +#line 312 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ISIS; } + break; + + case 88: +#line 313 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ISIS_L1; } + break; + + case 89: +#line 314 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ISIS_L2; } + break; + + case 90: +#line 315 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ISIS_IIH; } + break; + + case 91: +#line 316 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ISIS_LSP; } + break; + + case 92: +#line 317 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ISIS_SNP; } + break; + + case 93: +#line 318 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ISIS_PSNP; } + break; + + case 94: +#line 319 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_ISIS_CSNP; } + break; + + case 95: +#line 320 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_CLNP; } + break; + + case 96: +#line 321 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_STP; } + break; + + case 97: +#line 322 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_IPX; } + break; + + case 98: +#line 323 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_NETBEUI; } + break; + + case 99: +#line 324 "../libpcap/GRAMMAR.Y" + { (yyval.i) = Q_RADIO; } + break; + + case 100: +#line 326 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_broadcast((yyvsp[-1].i)); } + break; + + case 101: +#line 327 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_multicast((yyvsp[-1].i)); } + break; + + case 102: +#line 328 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_less((yyvsp[0].i)); } + break; + + case 103: +#line 329 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_greater((yyvsp[0].i)); } + break; + + case 104: +#line 330 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_byteop((yyvsp[-1].i), (yyvsp[-2].i), (yyvsp[0].i)); } + break; + + case 105: +#line 331 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_inbound(0); } + break; + + case 106: +#line 332 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_inbound(1); } + break; + + case 107: +#line 333 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_vlan((yyvsp[0].i)); } + break; + + case 108: +#line 334 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_vlan(-1); } + break; + + case 109: +#line 335 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_mpls((yyvsp[0].i)); } + break; + + case 110: +#line 336 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_mpls(-1); } + break; + + case 111: +#line 337 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_pppoed(); } + break; + + case 112: +#line 338 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_pppoes(); } + break; + + case 113: +#line 339 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = (yyvsp[0].rblk); } + break; + + case 114: +#line 342 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_pf_ifname((yyvsp[0].s)); } + break; + + case 115: +#line 343 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_pf_ruleset((yyvsp[0].s)); } + break; + + case 116: +#line 344 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_pf_rnr((yyvsp[0].i)); } + break; + + case 117: +#line 345 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_pf_srnr((yyvsp[0].i)); } + break; + + case 118: +#line 346 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_pf_reason((yyvsp[0].i)); } + break; + + case 119: +#line 347 "../libpcap/GRAMMAR.Y" + { (yyval.rblk) = gen_pf_action((yyvsp[0].i)); } + break; + + case 120: +#line 350 "../libpcap/GRAMMAR.Y" + { (yyval.i) = (yyvsp[0].i); } + break; + + case 121: +#line 351 "../libpcap/GRAMMAR.Y" + { const char *reasons[] = PFRES_NAMES; + int i; + for (i = 0; reasons[i]; i++) { + if (pcap_strcasecmp((yyvsp[0].s), reasons[i]) == 0) { + (yyval.i) = i; + break; + } + } + if (reasons[i] == NULL) + bpf_error("unknown PF reason"); + } + break; + + case 122: +#line 364 "../libpcap/GRAMMAR.Y" + { if (pcap_strcasecmp((yyvsp[0].s), "pass") == 0 || + pcap_strcasecmp((yyvsp[0].s), "accept") == 0) + (yyval.i) = PF_PASS; + else if (pcap_strcasecmp((yyvsp[0].s), "drop") == 0 || + pcap_strcasecmp((yyvsp[0].s), "block") == 0) + (yyval.i) = PF_DROP; + else + bpf_error("unknown PF action"); + } + break; + + case 123: +#line 375 "../libpcap/GRAMMAR.Y" + { (yyval.i) = BPF_JGT; } + break; + + case 124: +#line 376 "../libpcap/GRAMMAR.Y" + { (yyval.i) = BPF_JGE; } + break; + + case 125: +#line 377 "../libpcap/GRAMMAR.Y" + { (yyval.i) = BPF_JEQ; } + break; + + case 126: +#line 379 "../libpcap/GRAMMAR.Y" + { (yyval.i) = BPF_JGT; } + break; + + case 127: +#line 380 "../libpcap/GRAMMAR.Y" + { (yyval.i) = BPF_JGE; } + break; + + case 128: +#line 381 "../libpcap/GRAMMAR.Y" + { (yyval.i) = BPF_JEQ; } + break; + + case 129: +#line 383 "../libpcap/GRAMMAR.Y" + { (yyval.a) = gen_loadi((yyvsp[0].i)); } + break; + + case 131: +#line 386 "../libpcap/GRAMMAR.Y" + { (yyval.a) = gen_load((yyvsp[-3].i), (yyvsp[-1].a), 1); } + break; + + case 132: +#line 387 "../libpcap/GRAMMAR.Y" + { (yyval.a) = gen_load((yyvsp[-5].i), (yyvsp[-3].a), (yyvsp[-1].i)); } + break; + + case 133: +#line 388 "../libpcap/GRAMMAR.Y" + { (yyval.a) = gen_arth(BPF_ADD, (yyvsp[-2].a), (yyvsp[0].a)); } + break; + + case 134: +#line 389 "../libpcap/GRAMMAR.Y" + { (yyval.a) = gen_arth(BPF_SUB, (yyvsp[-2].a), (yyvsp[0].a)); } + break; + + case 135: +#line 390 "../libpcap/GRAMMAR.Y" + { (yyval.a) = gen_arth(BPF_MUL, (yyvsp[-2].a), (yyvsp[0].a)); } + break; + + case 136: +#line 391 "../libpcap/GRAMMAR.Y" + { (yyval.a) = gen_arth(BPF_DIV, (yyvsp[-2].a), (yyvsp[0].a)); } + break; + + case 137: +#line 392 "../libpcap/GRAMMAR.Y" + { (yyval.a) = gen_arth(BPF_AND, (yyvsp[-2].a), (yyvsp[0].a)); } + break; + + case 138: +#line 393 "../libpcap/GRAMMAR.Y" + { (yyval.a) = gen_arth(BPF_OR, (yyvsp[-2].a), (yyvsp[0].a)); } + break; + + case 139: +#line 394 "../libpcap/GRAMMAR.Y" + { (yyval.a) = gen_arth(BPF_LSH, (yyvsp[-2].a), (yyvsp[0].a)); } + break; + + case 140: +#line 395 "../libpcap/GRAMMAR.Y" + { (yyval.a) = gen_arth(BPF_RSH, (yyvsp[-2].a), (yyvsp[0].a)); } + break; + + case 141: +#line 396 "../libpcap/GRAMMAR.Y" + { (yyval.a) = gen_neg((yyvsp[0].a)); } + break; + + case 142: +#line 397 "../libpcap/GRAMMAR.Y" + { (yyval.a) = (yyvsp[-1].a); } + break; + + case 143: +#line 398 "../libpcap/GRAMMAR.Y" + { (yyval.a) = gen_loadlen(); } + break; + + case 144: +#line 400 "../libpcap/GRAMMAR.Y" + { (yyval.i) = '&'; } + break; + + case 145: +#line 401 "../libpcap/GRAMMAR.Y" + { (yyval.i) = '|'; } + break; + + case 146: +#line 402 "../libpcap/GRAMMAR.Y" + { (yyval.i) = '<'; } + break; + + case 147: +#line 403 "../libpcap/GRAMMAR.Y" + { (yyval.i) = '>'; } + break; + + case 148: +#line 404 "../libpcap/GRAMMAR.Y" + { (yyval.i) = '='; } + break; + + case 150: +#line 407 "../libpcap/GRAMMAR.Y" + { (yyval.i) = (yyvsp[-1].i); } + break; + + case 151: +#line 409 "../libpcap/GRAMMAR.Y" + { (yyval.i) = A_LANE; } + break; + + case 152: +#line 410 "../libpcap/GRAMMAR.Y" + { (yyval.i) = A_LLC; } + break; + + case 153: +#line 411 "../libpcap/GRAMMAR.Y" + { (yyval.i) = A_METAC; } + break; + + case 154: +#line 412 "../libpcap/GRAMMAR.Y" + { (yyval.i) = A_BCC; } + break; + + case 155: +#line 413 "../libpcap/GRAMMAR.Y" + { (yyval.i) = A_OAMF4EC; } + break; + + case 156: +#line 414 "../libpcap/GRAMMAR.Y" + { (yyval.i) = A_OAMF4SC; } + break; + + case 157: +#line 415 "../libpcap/GRAMMAR.Y" + { (yyval.i) = A_SC; } + break; + + case 158: +#line 416 "../libpcap/GRAMMAR.Y" + { (yyval.i) = A_ILMIC; } + break; + + case 159: +#line 418 "../libpcap/GRAMMAR.Y" + { (yyval.i) = A_OAM; } + break; + + case 160: +#line 419 "../libpcap/GRAMMAR.Y" + { (yyval.i) = A_OAMF4; } + break; + + case 161: +#line 420 "../libpcap/GRAMMAR.Y" + { (yyval.i) = A_CONNECTMSG; } + break; + + case 162: +#line 421 "../libpcap/GRAMMAR.Y" + { (yyval.i) = A_METACONNECT; } + break; + + case 163: +#line 424 "../libpcap/GRAMMAR.Y" + { (yyval.blk).atmfieldtype = A_VPI; } + break; + + case 164: +#line 425 "../libpcap/GRAMMAR.Y" + { (yyval.blk).atmfieldtype = A_VCI; } + break; + + case 166: +#line 428 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_atmfield_code((yyvsp[-2].blk).atmfieldtype, (bpf_int32)(yyvsp[0].i), (bpf_u_int32)(yyvsp[-1].i), 0); } + break; + + case 167: +#line 429 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_atmfield_code((yyvsp[-2].blk).atmfieldtype, (bpf_int32)(yyvsp[0].i), (bpf_u_int32)(yyvsp[-1].i), 1); } + break; + + case 168: +#line 430 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = (yyvsp[-1].blk).b; (yyval.blk).q = qerr; } + break; + + case 169: +#line 432 "../libpcap/GRAMMAR.Y" + { + (yyval.blk).atmfieldtype = (yyvsp[-1].blk).atmfieldtype; + if ((yyval.blk).atmfieldtype == A_VPI || + (yyval.blk).atmfieldtype == A_VCI) + (yyval.blk).b = gen_atmfield_code((yyval.blk).atmfieldtype, (bpf_int32) (yyvsp[0].i), BPF_JEQ, 0); + } + break; + + case 171: +#line 440 "../libpcap/GRAMMAR.Y" + { gen_or((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); } + break; + + case 172: +#line 443 "../libpcap/GRAMMAR.Y" + { (yyval.blk).mtp3fieldtype = M_SIO; } + break; + + case 173: +#line 444 "../libpcap/GRAMMAR.Y" + { (yyval.blk).mtp3fieldtype = M_OPC; } + break; + + case 174: +#line 445 "../libpcap/GRAMMAR.Y" + { (yyval.blk).mtp3fieldtype = M_DPC; } + break; + + case 175: +#line 446 "../libpcap/GRAMMAR.Y" + { (yyval.blk).mtp3fieldtype = M_SLS; } + break; + + case 177: +#line 449 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_mtp3field_code((yyvsp[-2].blk).mtp3fieldtype, (u_int)(yyvsp[0].i), (u_int)(yyvsp[-1].i), 0); } + break; + + case 178: +#line 450 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = gen_mtp3field_code((yyvsp[-2].blk).mtp3fieldtype, (u_int)(yyvsp[0].i), (u_int)(yyvsp[-1].i), 1); } + break; + + case 179: +#line 451 "../libpcap/GRAMMAR.Y" + { (yyval.blk).b = (yyvsp[-1].blk).b; (yyval.blk).q = qerr; } + break; + + case 180: +#line 453 "../libpcap/GRAMMAR.Y" + { + (yyval.blk).mtp3fieldtype = (yyvsp[-1].blk).mtp3fieldtype; + if ((yyval.blk).mtp3fieldtype == M_SIO || + (yyval.blk).mtp3fieldtype == M_OPC || + (yyval.blk).mtp3fieldtype == M_DPC || + (yyval.blk).mtp3fieldtype == M_SLS ) + (yyval.blk).b = gen_mtp3field_code((yyval.blk).mtp3fieldtype, (u_int) (yyvsp[0].i), BPF_JEQ, 0); + } + break; + + case 182: +#line 463 "../libpcap/GRAMMAR.Y" + { gen_or((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); } + break; + + + default: break; + } + +/* Line 1126 of yacc.c. */ +#line 2650 "y.tab.c" + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + char *yymsg = 0; +# define YYERROR_VERBOSE_ARGS_MAXIMUM 5 + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +#if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +#endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= yysize1 < yysize; + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= yysize1 < yysize; + yysize = yysize1; + + if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM) + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yymsg; + int yyi = 0; + while ((*yyp = *yyf)) + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + { + yyerror (YY_("syntax error")); + goto yyexhaustedlab; + } + } + else +#endif /* YYERROR_VERBOSE */ + yyerror (YY_("syntax error")); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse look-ahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (0) + goto yyerrorlab; + +yyvsp -= yylen; + yyssp -= yylen; + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", yystos[yystate], yyvsp); + YYPOPSTACK; + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEOF && yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK; + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 465 "../libpcap/GRAMMAR.Y" + + diff --git a/winpcap/wpcap/libpcap/grammar.y b/winpcap/wpcap/libpcap/grammar.y new file mode 100644 index 0000000..c2f96f1 --- /dev/null +++ b/winpcap/wpcap/libpcap/grammar.y @@ -0,0 +1,465 @@ +%{ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.86.2.5 2005/09/05 09:08:06 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include +#else /* WIN32 */ +#include +#include +#endif /* WIN32 */ + +#include + +#ifndef WIN32 +#if __STDC__ +struct mbuf; +struct rtentry; +#endif + +#include +#endif /* WIN32 */ + +#include + +#include "pcap-int.h" + +#include "gencode.h" +#include "pf.h" +#include + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#define QSET(q, p, d, a) (q).proto = (p),\ + (q).dir = (d),\ + (q).addr = (a) + +int n_errors = 0; + +static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF }; + +static void +yyerror(char *msg) +{ + ++n_errors; + bpf_error("%s", msg); + /* NOTREACHED */ +} + +#ifndef YYBISON +int yyparse(void); + +int +pcap_parse() +{ + return (yyparse()); +} +#endif + +%} + +%union { + int i; + bpf_u_int32 h; + u_char *e; + char *s; + struct stmt *stmt; + struct arth *a; + struct { + struct qual q; + int atmfieldtype; + int mtp3fieldtype; + struct block *b; + } blk; + struct block *rblk; +} + +%type expr id nid pid term rterm qid +%type head +%type pqual dqual aqual ndaqual +%type arth narth +%type byteop pname pnum relop irelop +%type and or paren not null prog +%type other pfvar +%type atmtype atmmultitype +%type atmfield +%type atmfieldvalue atmvalue atmlistvalue +%type mtp3field +%type mtp3fieldvalue mtp3value mtp3listvalue + + +%token DST SRC HOST GATEWAY +%token NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE +%token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP +%token ATALK AARP DECNET LAT SCA MOPRC MOPDL +%token TK_BROADCAST TK_MULTICAST +%token NUM INBOUND OUTBOUND +%token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION +%token LINK +%token GEQ LEQ NEQ +%token ID EID HID HID6 AID +%token LSH RSH +%token LEN +%token IPV6 ICMPV6 AH ESP +%token VLAN MPLS +%token PPPOED PPPOES +%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP +%token STP +%token IPX +%token NETBEUI +%token LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC +%token OAM OAMF4 CONNECTMSG METACONNECT +%token VPI VCI +%token RADIO +%token SIO OPC DPC SLS + +%type ID +%type EID +%type AID +%type HID HID6 +%type NUM action reason + +%left OR AND +%nonassoc '!' +%left '|' +%left '&' +%left LSH RSH +%left '+' '-' +%left '*' '/' +%nonassoc UMINUS +%% +prog: null expr +{ + finish_parse($2.b); +} + | null + ; +null: /* null */ { $$.q = qerr; } + ; +expr: term + | expr and term { gen_and($1.b, $3.b); $$ = $3; } + | expr and id { gen_and($1.b, $3.b); $$ = $3; } + | expr or term { gen_or($1.b, $3.b); $$ = $3; } + | expr or id { gen_or($1.b, $3.b); $$ = $3; } + ; +and: AND { $$ = $0; } + ; +or: OR { $$ = $0; } + ; +id: nid + | pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1, + $$.q = $0.q); } + | paren pid ')' { $$ = $2; } + ; +nid: ID { $$.b = gen_scode($1, $$.q = $0.q); } + | HID '/' NUM { $$.b = gen_mcode($1, NULL, $3, + $$.q = $0.q); } + | HID NETMASK HID { $$.b = gen_mcode($1, $3, 0, + $$.q = $0.q); } + | HID { + /* Decide how to parse HID based on proto */ + $$.q = $0.q; + $$.b = gen_ncode($1, 0, $$.q); + } + | HID6 '/' NUM { +#ifdef INET6 + $$.b = gen_mcode6($1, NULL, $3, + $$.q = $0.q); +#else + bpf_error("'ip6addr/prefixlen' not supported " + "in this configuration"); +#endif /*INET6*/ + } + | HID6 { +#ifdef INET6 + $$.b = gen_mcode6($1, 0, 128, + $$.q = $0.q); +#else + bpf_error("'ip6addr' not supported " + "in this configuration"); +#endif /*INET6*/ + } + | EID { + $$.b = gen_ecode($1, $$.q = $0.q); + /* + * $1 was allocated by "pcap_ether_aton()", + * so we must free it now that we're done + * with it. + */ + free($1); + } + | AID { + $$.b = gen_acode($1, $$.q = $0.q); + /* + * $1 was allocated by "pcap_ether_aton()", + * so we must free it now that we're done + * with it. + */ + free($1); + } + | not id { gen_not($2.b); $$ = $2; } + ; +not: '!' { $$ = $0; } + ; +paren: '(' { $$ = $0; } + ; +pid: nid + | qid and id { gen_and($1.b, $3.b); $$ = $3; } + | qid or id { gen_or($1.b, $3.b); $$ = $3; } + ; +qid: pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1, + $$.q = $0.q); } + | pid + ; +term: rterm + | not term { gen_not($2.b); $$ = $2; } + ; +head: pqual dqual aqual { QSET($$.q, $1, $2, $3); } + | pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); } + | pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); } + | pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); } + | pqual PROTOCHAIN { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); } + | pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); } + ; +rterm: head id { $$ = $2; } + | paren expr ')' { $$.b = $2.b; $$.q = $1.q; } + | pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; } + | arth relop arth { $$.b = gen_relation($2, $1, $3, 0); + $$.q = qerr; } + | arth irelop arth { $$.b = gen_relation($2, $1, $3, 1); + $$.q = qerr; } + | other { $$.b = $1; $$.q = qerr; } + | atmtype { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; } + | atmmultitype { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; } + | atmfield atmvalue { $$.b = $2.b; $$.q = qerr; } + | mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; } + ; +/* protocol level qualifiers */ +pqual: pname + | { $$ = Q_DEFAULT; } + ; +/* 'direction' qualifiers */ +dqual: SRC { $$ = Q_SRC; } + | DST { $$ = Q_DST; } + | SRC OR DST { $$ = Q_OR; } + | DST OR SRC { $$ = Q_OR; } + | SRC AND DST { $$ = Q_AND; } + | DST AND SRC { $$ = Q_AND; } + ; +/* address type qualifiers */ +aqual: HOST { $$ = Q_HOST; } + | NET { $$ = Q_NET; } + | PORT { $$ = Q_PORT; } + | PORTRANGE { $$ = Q_PORTRANGE; } + ; +/* non-directional address type qualifiers */ +ndaqual: GATEWAY { $$ = Q_GATEWAY; } + ; +pname: LINK { $$ = Q_LINK; } + | IP { $$ = Q_IP; } + | ARP { $$ = Q_ARP; } + | RARP { $$ = Q_RARP; } + | SCTP { $$ = Q_SCTP; } + | TCP { $$ = Q_TCP; } + | UDP { $$ = Q_UDP; } + | ICMP { $$ = Q_ICMP; } + | IGMP { $$ = Q_IGMP; } + | IGRP { $$ = Q_IGRP; } + | PIM { $$ = Q_PIM; } + | VRRP { $$ = Q_VRRP; } + | ATALK { $$ = Q_ATALK; } + | AARP { $$ = Q_AARP; } + | DECNET { $$ = Q_DECNET; } + | LAT { $$ = Q_LAT; } + | SCA { $$ = Q_SCA; } + | MOPDL { $$ = Q_MOPDL; } + | MOPRC { $$ = Q_MOPRC; } + | IPV6 { $$ = Q_IPV6; } + | ICMPV6 { $$ = Q_ICMPV6; } + | AH { $$ = Q_AH; } + | ESP { $$ = Q_ESP; } + | ISO { $$ = Q_ISO; } + | ESIS { $$ = Q_ESIS; } + | ISIS { $$ = Q_ISIS; } + | L1 { $$ = Q_ISIS_L1; } + | L2 { $$ = Q_ISIS_L2; } + | IIH { $$ = Q_ISIS_IIH; } + | LSP { $$ = Q_ISIS_LSP; } + | SNP { $$ = Q_ISIS_SNP; } + | PSNP { $$ = Q_ISIS_PSNP; } + | CSNP { $$ = Q_ISIS_CSNP; } + | CLNP { $$ = Q_CLNP; } + | STP { $$ = Q_STP; } + | IPX { $$ = Q_IPX; } + | NETBEUI { $$ = Q_NETBEUI; } + | RADIO { $$ = Q_RADIO; } + ; +other: pqual TK_BROADCAST { $$ = gen_broadcast($1); } + | pqual TK_MULTICAST { $$ = gen_multicast($1); } + | LESS NUM { $$ = gen_less($2); } + | GREATER NUM { $$ = gen_greater($2); } + | CBYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); } + | INBOUND { $$ = gen_inbound(0); } + | OUTBOUND { $$ = gen_inbound(1); } + | VLAN pnum { $$ = gen_vlan($2); } + | VLAN { $$ = gen_vlan(-1); } + | MPLS pnum { $$ = gen_mpls($2); } + | MPLS { $$ = gen_mpls(-1); } + | PPPOED { $$ = gen_pppoed(); } + | PPPOES { $$ = gen_pppoes(); } + | pfvar { $$ = $1; } + ; + +pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); } + | PF_RSET ID { $$ = gen_pf_ruleset($2); } + | PF_RNR NUM { $$ = gen_pf_rnr($2); } + | PF_SRNR NUM { $$ = gen_pf_srnr($2); } + | PF_REASON reason { $$ = gen_pf_reason($2); } + | PF_ACTION action { $$ = gen_pf_action($2); } + ; + +reason: NUM { $$ = $1; } + | ID { const char *reasons[] = PFRES_NAMES; + int i; + for (i = 0; reasons[i]; i++) { + if (pcap_strcasecmp($1, reasons[i]) == 0) { + $$ = i; + break; + } + } + if (reasons[i] == NULL) + bpf_error("unknown PF reason"); + } + ; + +action: ID { if (pcap_strcasecmp($1, "pass") == 0 || + pcap_strcasecmp($1, "accept") == 0) + $$ = PF_PASS; + else if (pcap_strcasecmp($1, "drop") == 0 || + pcap_strcasecmp($1, "block") == 0) + $$ = PF_DROP; + else + bpf_error("unknown PF action"); + } + ; + +relop: '>' { $$ = BPF_JGT; } + | GEQ { $$ = BPF_JGE; } + | '=' { $$ = BPF_JEQ; } + ; +irelop: LEQ { $$ = BPF_JGT; } + | '<' { $$ = BPF_JGE; } + | NEQ { $$ = BPF_JEQ; } + ; +arth: pnum { $$ = gen_loadi($1); } + | narth + ; +narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); } + | pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); } + | arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); } + | arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); } + | arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); } + | arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); } + | arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); } + | arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); } + | arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); } + | arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); } + | '-' arth %prec UMINUS { $$ = gen_neg($2); } + | paren narth ')' { $$ = $2; } + | LEN { $$ = gen_loadlen(); } + ; +byteop: '&' { $$ = '&'; } + | '|' { $$ = '|'; } + | '<' { $$ = '<'; } + | '>' { $$ = '>'; } + | '=' { $$ = '='; } + ; +pnum: NUM + | paren pnum ')' { $$ = $2; } + ; +atmtype: LANE { $$ = A_LANE; } + | LLC { $$ = A_LLC; } + | METAC { $$ = A_METAC; } + | BCC { $$ = A_BCC; } + | OAMF4EC { $$ = A_OAMF4EC; } + | OAMF4SC { $$ = A_OAMF4SC; } + | SC { $$ = A_SC; } + | ILMIC { $$ = A_ILMIC; } + ; +atmmultitype: OAM { $$ = A_OAM; } + | OAMF4 { $$ = A_OAMF4; } + | CONNECTMSG { $$ = A_CONNECTMSG; } + | METACONNECT { $$ = A_METACONNECT; } + ; + /* ATM field types quantifier */ +atmfield: VPI { $$.atmfieldtype = A_VPI; } + | VCI { $$.atmfieldtype = A_VCI; } + ; +atmvalue: atmfieldvalue + | relop NUM { $$.b = gen_atmfield_code($0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); } + | irelop NUM { $$.b = gen_atmfield_code($0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); } + | paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; } + ; +atmfieldvalue: NUM { + $$.atmfieldtype = $0.atmfieldtype; + if ($$.atmfieldtype == A_VPI || + $$.atmfieldtype == A_VCI) + $$.b = gen_atmfield_code($$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0); + } + ; +atmlistvalue: atmfieldvalue + | atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; } + ; + /* MTP3 field types quantifier */ +mtp3field: SIO { $$.mtp3fieldtype = M_SIO; } + | OPC { $$.mtp3fieldtype = M_OPC; } + | DPC { $$.mtp3fieldtype = M_DPC; } + | SLS { $$.mtp3fieldtype = M_SLS; } + ; +mtp3value: mtp3fieldvalue + | relop NUM { $$.b = gen_mtp3field_code($0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); } + | irelop NUM { $$.b = gen_mtp3field_code($0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); } + | paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; } + ; +mtp3fieldvalue: NUM { + $$.mtp3fieldtype = $0.mtp3fieldtype; + if ($$.mtp3fieldtype == M_SIO || + $$.mtp3fieldtype == M_OPC || + $$.mtp3fieldtype == M_DPC || + $$.mtp3fieldtype == M_SLS ) + $$.b = gen_mtp3field_code($$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0); + } + ; +mtp3listvalue: mtp3fieldvalue + | mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; } + ; +%% diff --git a/winpcap/wpcap/libpcap/inet.c b/winpcap/wpcap/libpcap/inet.c new file mode 100644 index 0000000..792df35 --- /dev/null +++ b/winpcap/wpcap/libpcap/inet.c @@ -0,0 +1,750 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1994, 1995, 1996, 1997, 1998 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.66.2.2 2006/01/21 10:46:13 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include +#else /* WIN32 */ + +#include +#ifndef MSDOS +#include +#endif +#include +#include +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif + +struct mbuf; /* Squelch compiler warnings on some platforms for */ +struct rtentry; /* declarations in */ +#include +#include +#endif /* WIN32 */ + +#include +#include +#include +#include +#include +#include +#if !defined(WIN32) && !defined(__BORLANDC__) +#include +#endif /* !WIN32 && !__BORLANDC__ */ +#ifdef HAVE_LIMITS_H +#include +#else +#define INT_MAX 2147483647 +#endif + +#include "pcap-int.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +/* Not all systems have IFF_LOOPBACK */ +#ifdef IFF_LOOPBACK +#define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK) +#else +#define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \ + (isdigit((unsigned char)((name)[2])) || (name)[2] == '\0')) +#endif + +struct sockaddr * +dup_sockaddr(struct sockaddr *sa, size_t sa_length) +{ + struct sockaddr *newsa; + + if ((newsa = malloc(sa_length)) == NULL) + return (NULL); + return (memcpy(newsa, sa, sa_length)); +} + +static int +get_instance(const char *name) +{ + const char *cp, *endcp; + int n; + + if (strcmp(name, "any") == 0) { + /* + * Give the "any" device an artificially high instance + * number, so it shows up after all other non-loopback + * interfaces. + */ + return INT_MAX; + } + + endcp = name + strlen(name); + for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp) + continue; + + if (isdigit((unsigned char)*cp)) + n = atoi(cp); + else + n = 0; + return (n); +} + +int +add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name, + u_int flags, const char *description, char *errbuf) +{ + pcap_t *p; + pcap_if_t *curdev, *prevdev, *nextdev; + int this_instance; + + /* + * Can we open this interface for live capture? + * + * We do this check so that interfaces that ae supplied + * by the interface enumeration mechanism we're using + * but that don't support packet capture aren't included + * in the list. An example of this is loopback interfaces + * on Solaris; we don't just omit loopback interfaces + * becaue you *can* capture on loopback interfaces on some + * OSes. + */ + p = pcap_open_live(name, 68, 0, 0, errbuf); + if (p == NULL) { + /* + * No. Don't bother including it. + * Don't treat this as an error, though. + */ + *curdev_ret = NULL; + return (0); + } + pcap_close(p); + + /* + * Is there already an entry in the list for this interface? + */ + for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) { + if (strcmp(name, curdev->name) == 0) + break; /* yes, we found it */ + } + if (curdev == NULL) { + /* + * No, we didn't find it. + * Allocate a new entry. + */ + curdev = malloc(sizeof(pcap_if_t)); + if (curdev == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + return (-1); + } + + /* + * Fill in the entry. + */ + curdev->next = NULL; + curdev->name = strdup(name); + if (curdev->name == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + free(curdev); + return (-1); + } + if (description != NULL) { + /* + * We have a description for this interface. + */ + curdev->description = strdup(description); + if (curdev->description == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + free(curdev->name); + free(curdev); + return (-1); + } + } else { + /* + * We don't. + */ + curdev->description = NULL; + } + curdev->addresses = NULL; /* list starts out as empty */ + curdev->flags = 0; + if (ISLOOPBACK(name, flags)) + curdev->flags |= PCAP_IF_LOOPBACK; + + /* + * Add it to the list, in the appropriate location. + * First, get the instance number of this interface. + */ + this_instance = get_instance(name); + + /* + * Now look for the last interface with an instance number + * less than or equal to the new interface's instance + * number - except that non-loopback interfaces are + * arbitrarily treated as having interface numbers less + * than those of loopback interfaces, so the loopback + * interfaces are put at the end of the list. + * + * We start with "prevdev" being NULL, meaning we're before + * the first element in the list. + */ + prevdev = NULL; + for (;;) { + /* + * Get the interface after this one. + */ + if (prevdev == NULL) { + /* + * The next element is the first element. + */ + nextdev = *alldevs; + } else + nextdev = prevdev->next; + + /* + * Are we at the end of the list? + */ + if (nextdev == NULL) { + /* + * Yes - we have to put the new entry + * after "prevdev". + */ + break; + } + + /* + * Is the new interface a non-loopback interface + * and the next interface a loopback interface? + */ + if (!(curdev->flags & PCAP_IF_LOOPBACK) && + (nextdev->flags & PCAP_IF_LOOPBACK)) { + /* + * Yes, we should put the new entry + * before "nextdev", i.e. after "prevdev". + */ + break; + } + + /* + * Is the new interface's instance number less + * than the next interface's instance number, + * and is it the case that the new interface is a + * non-loopback interface or the next interface is + * a loopback interface? + * + * (The goal of both loopback tests is to make + * sure that we never put a loopback interface + * before any non-loopback interface and that we + * always put a non-loopback interface before all + * loopback interfaces.) + */ + if (this_instance < get_instance(nextdev->name) && + (!(curdev->flags & PCAP_IF_LOOPBACK) || + (nextdev->flags & PCAP_IF_LOOPBACK))) { + /* + * Yes - we should put the new entry + * before "nextdev", i.e. after "prevdev". + */ + break; + } + + prevdev = nextdev; + } + + /* + * Insert before "nextdev". + */ + curdev->next = nextdev; + + /* + * Insert after "prevdev" - unless "prevdev" is null, + * in which case this is the first interface. + */ + if (prevdev == NULL) { + /* + * This is the first interface. Pass back a + * pointer to it, and put "curdev" before + * "nextdev". + */ + *alldevs = curdev; + } else + prevdev->next = curdev; + } + + *curdev_ret = curdev; + return (0); +} + +int +add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags, + struct sockaddr *addr, size_t addr_size, + struct sockaddr *netmask, size_t netmask_size, + struct sockaddr *broadaddr, size_t broadaddr_size, + struct sockaddr *dstaddr, size_t dstaddr_size, + char *errbuf) +{ + pcap_if_t *curdev; + pcap_addr_t *curaddr, *prevaddr, *nextaddr; + + if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) { + /* + * Error - give up. + */ + return (-1); + } + if (curdev == NULL) { + /* + * Device wasn't added because it can't be opened. + * Not a fatal error. + */ + return (0); + } + + /* + * "curdev" is an entry for this interface; add an entry for this + * address to its list of addresses. + * + * Allocate the new entry and fill it in. + */ + curaddr = malloc(sizeof(pcap_addr_t)); + if (curaddr == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + return (-1); + } + + curaddr->next = NULL; + if (addr != NULL) { + curaddr->addr = dup_sockaddr(addr, addr_size); + if (curaddr->addr == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + free(curaddr); + return (-1); + } + } else + curaddr->addr = NULL; + + if (netmask != NULL) { + curaddr->netmask = dup_sockaddr(netmask, netmask_size); + if (curaddr->netmask == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + if (curaddr->addr != NULL) + free(curaddr->addr); + free(curaddr); + return (-1); + } + } else + curaddr->netmask = NULL; + + if (broadaddr != NULL) { + curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size); + if (curaddr->broadaddr == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + if (curaddr->netmask != NULL) + free(curaddr->netmask); + if (curaddr->addr != NULL) + free(curaddr->addr); + free(curaddr); + return (-1); + } + } else + curaddr->broadaddr = NULL; + + if (dstaddr != NULL) { + curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size); + if (curaddr->dstaddr == NULL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + if (curaddr->broadaddr != NULL) + free(curaddr->broadaddr); + if (curaddr->netmask != NULL) + free(curaddr->netmask); + if (curaddr->addr != NULL) + free(curaddr->addr); + free(curaddr); + return (-1); + } + } else + curaddr->dstaddr = NULL; + + /* + * Find the end of the list of addresses. + */ + for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) { + nextaddr = prevaddr->next; + if (nextaddr == NULL) { + /* + * This is the end of the list. + */ + break; + } + } + + if (prevaddr == NULL) { + /* + * The list was empty; this is the first member. + */ + curdev->addresses = curaddr; + } else { + /* + * "prevaddr" is the last member of the list; append + * this member to it. + */ + prevaddr->next = curaddr; + } + + return (0); +} + +int +pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags, + const char *description, char *errbuf) +{ + pcap_if_t *curdev; + + return (add_or_find_if(&curdev, devlist, name, flags, description, + errbuf)); +} + + +/* + * Free a list of interfaces. + */ +void +pcap_freealldevs(pcap_if_t *alldevs) +{ + pcap_if_t *curdev, *nextdev; + pcap_addr_t *curaddr, *nextaddr; + + for (curdev = alldevs; curdev != NULL; curdev = nextdev) { + nextdev = curdev->next; + + /* + * Free all addresses. + */ + for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) { + nextaddr = curaddr->next; + if (curaddr->addr) + free(curaddr->addr); + if (curaddr->netmask) + free(curaddr->netmask); + if (curaddr->broadaddr) + free(curaddr->broadaddr); + if (curaddr->dstaddr) + free(curaddr->dstaddr); + free(curaddr); + } + + /* + * Free the name string. + */ + free(curdev->name); + + /* + * Free the description string, if any. + */ + if (curdev->description != NULL) + free(curdev->description); + + /* + * Free the interface. + */ + free(curdev); + } +} + +#if !defined(WIN32) && !defined(MSDOS) + +/* + * Return the name of a network interface attached to the system, or NULL + * if none can be found. The interface must be configured up; the + * lowest unit number is preferred; loopback is ignored. + */ +char * +pcap_lookupdev(errbuf) + register char *errbuf; +{ + pcap_if_t *alldevs; +/* for old BSD systems, including bsdi3 */ +#ifndef IF_NAMESIZE +#define IF_NAMESIZE IFNAMSIZ +#endif + static char device[IF_NAMESIZE + 1]; + char *ret; + + if (pcap_findalldevs(&alldevs, errbuf) == -1) + return (NULL); + + if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) { + /* + * There are no devices on the list, or the first device + * on the list is a loopback device, which means there + * are no non-loopback devices on the list. This means + * we can't return any device. + * + * XXX - why not return a loopback device? If we can't + * capture on it, it won't be on the list, and if it's + * on the list, there aren't any non-loopback devices, + * so why not just supply it as the default device? + */ + (void)strlcpy(errbuf, "no suitable device found", + PCAP_ERRBUF_SIZE); + ret = NULL; + } else { + /* + * Return the name of the first device on the list. + */ + (void)strlcpy(device, alldevs->name, sizeof(device)); + ret = device; + } + + pcap_freealldevs(alldevs); + return (ret); +} + +int +pcap_lookupnet(device, netp, maskp, errbuf) + register const char *device; + register bpf_u_int32 *netp, *maskp; + register char *errbuf; +{ + register int fd; + register struct sockaddr_in *sin; + struct ifreq ifr; + + /* + * The pseudo-device "any" listens on all interfaces and therefore + * has the network address and -mask "0.0.0.0" therefore catching + * all traffic. Using NULL for the interface is the same as "any". + */ + if (!device || strcmp(device, "any") == 0 +#ifdef HAVE_DAG_API + || strstr(device, "dag") != NULL +#endif +#ifdef HAVE_SEPTEL_API + || strstr(device, "septel") != NULL +#endif + ) { + *netp = *maskp = 0; + return 0; + } + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s", + pcap_strerror(errno)); + return (-1); + } + memset(&ifr, 0, sizeof(ifr)); +#ifdef linux + /* XXX Work around Linux kernel bug */ + ifr.ifr_addr.sa_family = AF_INET; +#endif + (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { + if (errno == EADDRNOTAVAIL) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "%s: no IPv4 address assigned", device); + } else { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGIFADDR: %s: %s", + device, pcap_strerror(errno)); + } + (void)close(fd); + return (-1); + } + sin = (struct sockaddr_in *)&ifr.ifr_addr; + *netp = sin->sin_addr.s_addr; + if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno)); + (void)close(fd); + return (-1); + } + (void)close(fd); + *maskp = sin->sin_addr.s_addr; + if (*maskp == 0) { + if (IN_CLASSA(*netp)) + *maskp = IN_CLASSA_NET; + else if (IN_CLASSB(*netp)) + *maskp = IN_CLASSB_NET; + else if (IN_CLASSC(*netp)) + *maskp = IN_CLASSC_NET; + else { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "inet class for 0x%x unknown", *netp); + return (-1); + } + } + *netp &= *maskp; + return (0); +} + +#elif defined(WIN32) + +/* + * Return the name of a network interface attached to the system, or NULL + * if none can be found. The interface must be configured up; the + * lowest unit number is preferred; loopback is ignored. + */ +char * +pcap_lookupdev(errbuf) + register char *errbuf; +{ + DWORD dwVersion; + DWORD dwWindowsMajorVersion; + dwVersion = GetVersion(); /* get the OS version */ + dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); + + if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) { + /* + * Windows 95, 98, ME. + */ + ULONG NameLength = 8192; + static char AdaptersName[8192]; + + if (PacketGetAdapterNames(AdaptersName,&NameLength) ) + return (AdaptersName); + else + return NULL; + } else { + /* + * Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility + */ + ULONG NameLength = 8192; + static WCHAR AdaptersName[8192]; + char *tAstr; + WCHAR *tUstr; + WCHAR *TAdaptersName = (WCHAR*)malloc(8192 * sizeof(WCHAR)); + int NAdapts = 0; + + if(TAdaptersName == NULL) + { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure"); + return NULL; + } + + if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) ) + { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "PacketGetAdapterNames: %s", + pcap_win32strerror()); + free(TAdaptersName); + return NULL; + } + + + tAstr = (char*)TAdaptersName; + tUstr = (WCHAR*)AdaptersName; + + /* + * Convert and copy the device names + */ + while(sscanf(tAstr, "%S", tUstr) > 0) + { + tAstr += strlen(tAstr) + 1; + tUstr += wcslen(tUstr) + 1; + NAdapts ++; + } + + tAstr++; + *tUstr = 0; + tUstr++; + + /* + * Copy the descriptions + */ + while(NAdapts--) + { + strcpy((char*)tUstr, tAstr); + (char*)tUstr += strlen(tAstr) + 1;; + tAstr += strlen(tAstr) + 1; + } + + free(TAdaptersName); + return (char *)(AdaptersName); + } +} + + +int +pcap_lookupnet(device, netp, maskp, errbuf) + register const char *device; + register bpf_u_int32 *netp, *maskp; + register char *errbuf; +{ + /* + * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo() + * in order to skip non IPv4 (i.e. IPv6 addresses) + */ + npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES]; + LONG if_addr_size = 1; + struct sockaddr_in *t_addr; + unsigned int i; + + if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) { + *netp = *maskp = 0; + return (0); + } + + for(i=0; isin_addr.S_un.S_addr; + t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask); + *maskp = t_addr->sin_addr.S_un.S_addr; + + *netp &= *maskp; + return (0); + } + + } + + *netp = *maskp = 0; + return (0); +} + +#endif /* !WIN32 && !MSDOS */ diff --git a/winpcap/wpcap/libpcap/install-sh b/winpcap/wpcap/libpcap/install-sh new file mode 100644 index 0000000..ebc6691 --- /dev/null +++ b/winpcap/wpcap/libpcap/install-sh @@ -0,0 +1,250 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/winpcap/wpcap/libpcap/lbl/os-aix4.h b/winpcap/wpcap/libpcap/lbl/os-aix4.h new file mode 100644 index 0000000..f7edb62 --- /dev/null +++ b/winpcap/wpcap/libpcap/lbl/os-aix4.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/lbl/os-aix4.h,v 1.1 2002/06/01 09:37:40 guy Exp $ + */ + +/* Prototypes missing in AIX 4.x */ +int ffs(int i); diff --git a/winpcap/wpcap/libpcap/lbl/os-hpux11.h b/winpcap/wpcap/libpcap/lbl/os-hpux11.h new file mode 100644 index 0000000..55a79e5 --- /dev/null +++ b/winpcap/wpcap/libpcap/lbl/os-hpux11.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/lbl/os-hpux11.h,v 1.1 2002/06/01 09:37:41 guy Exp $ + */ + +/* Prototypes missing in HP-UX 11.x */ +int ffs(int i); diff --git a/winpcap/wpcap/libpcap/lbl/os-osf4.h b/winpcap/wpcap/libpcap/lbl/os-osf4.h new file mode 100644 index 0000000..abb207e --- /dev/null +++ b/winpcap/wpcap/libpcap/lbl/os-osf4.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/lbl/os-osf4.h,v 1.2 2000/12/22 11:51:33 guy Exp $ (LBL) + */ + +/* Prototypes missing in Digital UNIX 4.x */ +int snprintf(char *, size_t, const char *, ...); +int vsnprintf(char *, size_t, const char *, va_list); +int pfopen(char *, int); + diff --git a/winpcap/wpcap/libpcap/lbl/os-osf5.h b/winpcap/wpcap/libpcap/lbl/os-osf5.h new file mode 100644 index 0000000..338caa8 --- /dev/null +++ b/winpcap/wpcap/libpcap/lbl/os-osf5.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/lbl/os-osf5.h,v 1.2 2002/08/02 03:24:15 guy Exp $ (LBL) + */ + +/* + * Prototypes missing in Tru64 UNIX 5.x + * XXX - "snprintf()" and "vsnprintf()" aren't missing, but you have to + * #define the right value to get them defined by . + */ +int snprintf(char *, size_t, const char *, ...); +int vsnprintf(char *, size_t, const char *, va_list); +int pfopen(char *, int); + diff --git a/winpcap/wpcap/libpcap/lbl/os-solaris2.h b/winpcap/wpcap/libpcap/lbl/os-solaris2.h new file mode 100644 index 0000000..5de2c6e --- /dev/null +++ b/winpcap/wpcap/libpcap/lbl/os-solaris2.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/lbl/os-solaris2.h,v 1.19 2000/10/11 04:02:52 guy Exp $ (LBL) + */ + +/* Prototypes missing in SunOS 5 */ +char *strerror(int); +int snprintf(char *, size_t, const char *, ...); diff --git a/winpcap/wpcap/libpcap/lbl/os-sunos4.h b/winpcap/wpcap/libpcap/lbl/os-sunos4.h new file mode 100644 index 0000000..fd8f508 --- /dev/null +++ b/winpcap/wpcap/libpcap/lbl/os-sunos4.h @@ -0,0 +1,215 @@ +/* + * Copyright (c) 1989, 1990, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/lbl/os-sunos4.h,v 1.32.1.1 1999/10/07 23:46:41 mcr Exp $ (LBL) + */ + +/* Prototypes missing in SunOS 4 */ +#ifdef FILE +int _filbuf(FILE *); +int _flsbuf(u_char, FILE *); +int fclose(FILE *); +int fflush(FILE *); +int fgetc(FILE *); +int fprintf(FILE *, const char *, ...); +int fputc(int, FILE *); +int fputs(const char *, FILE *); +u_int fread(void *, u_int, u_int, FILE *); +int fseek(FILE *, long, int); +u_int fwrite(const void *, u_int, u_int, FILE *); +int pclose(FILE *); +void rewind(FILE *); +void setbuf(FILE *, char *); +int setlinebuf(FILE *); +int ungetc(int, FILE *); +int vfprintf(FILE *, const char *, ...); +int vprintf(const char *, ...); +#endif + +#if __GNUC__ <= 1 +int read(int, char *, u_int); +int write(int, char *, u_int); +#endif + +long a64l(const char *); +#ifdef __STDC__ +struct sockaddr; +#endif +int accept(int, struct sockaddr *, int *); +int bind(int, struct sockaddr *, int); +int bcmp(const void *, const void *, u_int); +void bcopy(const void *, void *, u_int); +void bzero(void *, int); +int chroot(const char *); +int close(int); +void closelog(void); +int connect(int, struct sockaddr *, int); +char *crypt(const char *, const char *); +int daemon(int, int); +int fchmod(int, int); +int fchown(int, int, int); +void endgrent(void); +void endpwent(void); +void endservent(void); +#ifdef __STDC__ +struct ether_addr; +#endif +struct ether_addr *ether_aton(const char *); +int flock(int, int); +#ifdef __STDC__ +struct stat; +#endif +int fstat(int, struct stat *); +#ifdef __STDC__ +struct statfs; +#endif +int fstatfs(int, struct statfs *); +int fsync(int); +#ifdef __STDC__ +struct timeb; +#endif +int ftime(struct timeb *); +int ftruncate(int, off_t); +int getdtablesize(void); +long gethostid(void); +int gethostname(char *, int); +int getopt(int, char * const *, const char *); +int getpagesize(void); +char *getpass(char *); +int getpeername(int, struct sockaddr *, int *); +int getpriority(int, int); +#ifdef __STDC__ +struct rlimit; +#endif +int getrlimit(int, struct rlimit *); +int getsockname(int, struct sockaddr *, int *); +int getsockopt(int, int, int, char *, int *); +#ifdef __STDC__ +struct timeval; +struct timezone; +#endif +int gettimeofday(struct timeval *, struct timezone *); +char *getusershell(void); +char *getwd(char *); +int initgroups(const char *, int); +int ioctl(int, int, caddr_t); +int iruserok(u_long, int, char *, char *); +int isatty(int); +int killpg(int, int); +int listen(int, int); +#ifdef __STDC__ +struct utmp; +#endif +void login(struct utmp *); +int logout(const char *); +off_t lseek(int, off_t, int); +int lstat(const char *, struct stat *); +int mkstemp(char *); +char *mktemp(char *); +int munmap(caddr_t, int); +void openlog(const char *, int, int); +void perror(const char *); +int printf(const char *, ...); +int puts(const char *); +long random(void); +int readlink(const char *, char *, int); +#ifdef __STDC__ +struct iovec; +#endif +int readv(int, struct iovec *, int); +int recv(int, char *, u_int, int); +int recvfrom(int, char *, u_int, int, struct sockaddr *, int *); +int rename(const char *, const char *); +int rcmd(char **, u_short, char *, char *, char *, int *); +int rresvport(int *); +int send(int, char *, u_int, int); +int sendto(int, char *, u_int, int, struct sockaddr *, int); +int setenv(const char *, const char *, int); +int seteuid(int); +int setpriority(int, int, int); +int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); +int setpgrp(int, int); +void setpwent(void); +int setrlimit(int, struct rlimit *); +void setservent(int); +int setsockopt(int, int, int, char *, int); +int shutdown(int, int); +int sigblock(int); +void (*signal (int, void (*) (int))) (int); +int sigpause(int); +int sigsetmask(int); +#ifdef __STDC__ +struct sigvec; +#endif +int sigvec(int, struct sigvec *, struct sigvec*); +int snprintf(char *, size_t, const char *, ...); +int socket(int, int, int); +int socketpair(int, int, int, int *); +int symlink(const char *, const char *); +void srandom(int); +int sscanf(char *, const char *, ...); +int stat(const char *, struct stat *); +int statfs(char *, struct statfs *); +char *strerror(int); +int strcasecmp(const char *, const char *); +#ifdef __STDC__ +struct tm; +#endif +int strftime(char *, int, char *, struct tm *); +int strncasecmp(const char *, const char *, int); +long strtol(const char *, char **, int); +void sync(void); +void syslog(int, const char *, ...); +int system(const char *); +long tell(int); +time_t time(time_t *); +char *timezone(int, int); +int tolower(int); +int toupper(int); +int truncate(char *, off_t); +void unsetenv(const char *); +int vfork(void); +int vsprintf(char *, const char *, ...); +int writev(int, struct iovec *, int); +#ifdef __STDC__ +struct rusage; +#endif +int utimes(const char *, struct timeval *); +#if __GNUC__ <= 1 +int wait(int *); +pid_t wait3(int *, int, struct rusage *); +#endif + +/* Ugly signal hacking */ +#ifdef SIG_ERR +#undef SIG_ERR +#define SIG_ERR (void (*)(int))-1 +#undef SIG_DFL +#define SIG_DFL (void (*)(int))0 +#undef SIG_IGN +#define SIG_IGN (void (*)(int))1 + +#ifdef KERNEL +#undef SIG_CATCH +#define SIG_CATCH (void (*)(int))2 +#endif +#undef SIG_HOLD +#define SIG_HOLD (void (*)(int))3 +#endif diff --git a/winpcap/wpcap/libpcap/lbl/os-ultrix4.h b/winpcap/wpcap/libpcap/lbl/os-ultrix4.h new file mode 100644 index 0000000..bd931b3 --- /dev/null +++ b/winpcap/wpcap/libpcap/lbl/os-ultrix4.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/lbl/os-ultrix4.h,v 1.19.1.1 1999/10/07 23:46:41 mcr Exp $ (LBL) + */ + +/* Prototypes missing in Ultrix 4 */ +int bcmp(const char *, const char *, u_int); +void bcopy(const void *, void *, u_int); +void bzero(void *, u_int); +void endservent(void); +int getopt(int, char * const *, const char *); +#ifdef __STDC__ +struct timeval; +struct timezone; +#endif +int gettimeofday(struct timeval *, struct timezone *); +int ioctl(int, int, caddr_t); +int pfopen(char *, int); +int setlinebuf(FILE *); +int socket(int, int, int); +int strcasecmp(const char *, const char *); diff --git a/winpcap/wpcap/libpcap/llc.h b/winpcap/wpcap/libpcap/llc.h new file mode 100644 index 0000000..ffd3a60 --- /dev/null +++ b/winpcap/wpcap/libpcap/llc.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1993, 1994, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/llc.h,v 1.2 2001/01/28 09:44:50 guy Exp $ (LBL) + */ + +/* + * 802.2 LLC SAP values. + */ + +#ifndef LLCSAP_NULL +#define LLCSAP_NULL 0x00 +#endif +#ifndef LLCSAP_GLOBAL +#define LLCSAP_GLOBAL 0xff +#endif +#ifndef LLCSAP_8021B +#define LLCSAP_8021B_I 0x02 +#endif +#ifndef LLCSAP_8021B +#define LLCSAP_8021B_G 0x03 +#endif +#ifndef LLCSAP_IP +#define LLCSAP_IP 0x06 +#endif +#ifndef LLCSAP_PROWAYNM +#define LLCSAP_PROWAYNM 0x0e +#endif +#ifndef LLCSAP_8021D +#define LLCSAP_8021D 0x42 +#endif +#ifndef LLCSAP_RS511 +#define LLCSAP_RS511 0x4e +#endif +#ifndef LLCSAP_ISO8208 +#define LLCSAP_ISO8208 0x7e +#endif +#ifndef LLCSAP_PROWAY +#define LLCSAP_PROWAY 0x8e +#endif +#ifndef LLCSAP_SNAP +#define LLCSAP_SNAP 0xaa +#endif +#ifndef LLCSAP_IPX +#define LLCSAP_IPX 0xe0 +#endif +#ifndef LLCSAP_NETBEUI +#define LLCSAP_NETBEUI 0xf0 +#endif +#ifndef LLCSAP_ISONS +#define LLCSAP_ISONS 0xfe +#endif diff --git a/winpcap/wpcap/libpcap/missing/snprintf.c b/winpcap/wpcap/libpcap/missing/snprintf.c new file mode 100644 index 0000000..9c0a6ee --- /dev/null +++ b/winpcap/wpcap/libpcap/missing/snprintf.c @@ -0,0 +1,632 @@ +/* + * Copyright (c) 1995-1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: snprintf.c,v 1.1 2004/04/05 22:43:51 guy Exp $ */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/missing/snprintf.c,v 1.1 2004/04/05 22:43:51 guy Exp $"; +#endif + +#include +#include +#include +#include +#include +#include + +#include + +enum format_flags { + minus_flag = 1, + plus_flag = 2, + space_flag = 4, + alternate_flag = 8, + zero_flag = 16 +}; + +/* + * Common state + */ + +struct state { + unsigned char *str; + unsigned char *s; + unsigned char *theend; + size_t sz; + size_t max_sz; + int (*append_char)(struct state *, unsigned char); + int (*reserve)(struct state *, size_t); + /* XXX - methods */ +}; + +#ifndef HAVE_VSNPRINTF +static int +sn_reserve (struct state *state, size_t n) +{ + return state->s + n > state->theend; +} + +static int +sn_append_char (struct state *state, unsigned char c) +{ + if (sn_reserve (state, 1)) { + return 1; + } else { + *state->s++ = c; + return 0; + } +} +#endif + +#if 0 +static int +as_reserve (struct state *state, size_t n) +{ + if (state->s + n > state->theend) { + int off = state->s - state->str; + unsigned char *tmp; + + if (state->max_sz && state->sz >= state->max_sz) + return 1; + + state->sz = max(state->sz * 2, state->sz + n); + if (state->max_sz) + state->sz = min(state->sz, state->max_sz); + tmp = realloc (state->str, state->sz); + if (tmp == NULL) + return 1; + state->str = tmp; + state->s = state->str + off; + state->theend = state->str + state->sz - 1; + } + return 0; +} + +static int +as_append_char (struct state *state, unsigned char c) +{ + if(as_reserve (state, 1)) + return 1; + else { + *state->s++ = c; + return 0; + } +} +#endif + +static int +append_number(struct state *state, + unsigned long num, unsigned base, char *rep, + int width, int prec, int flags, int minusp) +{ + int len = 0; + int i; + + /* given precision, ignore zero flag */ + if(prec != -1) + flags &= ~zero_flag; + else + prec = 1; + /* zero value with zero precision -> "" */ + if(prec == 0 && num == 0) + return 0; + do{ + if((*state->append_char)(state, rep[num % base])) + return 1; + len++; + num /= base; + }while(num); + prec -= len; + /* pad with prec zeros */ + while(prec-- > 0){ + if((*state->append_char)(state, '0')) + return 1; + len++; + } + /* add length of alternate prefix (added later) to len */ + if(flags & alternate_flag && (base == 16 || base == 8)) + len += base / 8; + /* pad with zeros */ + if(flags & zero_flag){ + width -= len; + if(minusp || (flags & space_flag) || (flags & plus_flag)) + width--; + while(width-- > 0){ + if((*state->append_char)(state, '0')) + return 1; + len++; + } + } + /* add alternate prefix */ + if(flags & alternate_flag && (base == 16 || base == 8)){ + if(base == 16) + if((*state->append_char)(state, rep[10] + 23)) /* XXX */ + return 1; + if((*state->append_char)(state, '0')) + return 1; + } + /* add sign */ + if(minusp){ + if((*state->append_char)(state, '-')) + return 1; + len++; + } else if(flags & plus_flag) { + if((*state->append_char)(state, '+')) + return 1; + len++; + } else if(flags & space_flag) { + if((*state->append_char)(state, ' ')) + return 1; + len++; + } + if(flags & minus_flag) + /* swap before padding with spaces */ + for(i = 0; i < len / 2; i++){ + char c = state->s[-i-1]; + state->s[-i-1] = state->s[-len+i]; + state->s[-len+i] = c; + } + width -= len; + while(width-- > 0){ + if((*state->append_char)(state, ' ')) + return 1; + len++; + } + if(!(flags & minus_flag)) + /* swap after padding with spaces */ + for(i = 0; i < len / 2; i++){ + char c = state->s[-i-1]; + state->s[-i-1] = state->s[-len+i]; + state->s[-len+i] = c; + } + + return 0; +} + +static int +append_string (struct state *state, + unsigned char *arg, + int width, + int prec, + int flags) +{ + if(prec != -1) + width -= prec; + else + width -= strlen((char *)arg); + if(!(flags & minus_flag)) + while(width-- > 0) + if((*state->append_char) (state, ' ')) + return 1; + if (prec != -1) { + while (*arg && prec--) + if ((*state->append_char) (state, *arg++)) + return 1; + } else { + while (*arg) + if ((*state->append_char) (state, *arg++)) + return 1; + } + if(flags & minus_flag) + while(width-- > 0) + if((*state->append_char) (state, ' ')) + return 1; + return 0; +} + +static int +append_char(struct state *state, + unsigned char arg, + int width, + int flags) +{ + while(!(flags & minus_flag) && --width > 0) + if((*state->append_char) (state, ' ')) + return 1; + + if((*state->append_char) (state, arg)) + return 1; + while((flags & minus_flag) && --width > 0) + if((*state->append_char) (state, ' ')) + return 1; + + return 0; +} + +/* + * This can't be made into a function... + */ + +#define PARSE_INT_FORMAT(res, arg, unsig) \ +if (long_flag) \ + res = (unsig long)va_arg(arg, unsig long); \ +else if (short_flag) \ + res = (unsig short)va_arg(arg, unsig int); \ +else \ + res = (unsig int)va_arg(arg, unsig int) + +/* + * zyxprintf - return 0 or -1 + */ + +static int +xyzprintf (struct state *state, const char *char_format, va_list ap) +{ + const unsigned char *format = (const unsigned char *)char_format; + unsigned char c; + + while((c = *format++)) { + if (c == '%') { + int flags = 0; + int width = 0; + int prec = -1; + int long_flag = 0; + int short_flag = 0; + + /* flags */ + while((c = *format++)){ + if(c == '-') + flags |= minus_flag; + else if(c == '+') + flags |= plus_flag; + else if(c == ' ') + flags |= space_flag; + else if(c == '#') + flags |= alternate_flag; + else if(c == '0') + flags |= zero_flag; + else + break; + } + + if((flags & space_flag) && (flags & plus_flag)) + flags ^= space_flag; + + if((flags & minus_flag) && (flags & zero_flag)) + flags ^= zero_flag; + + /* width */ + if (isdigit(c)) + do { + width = width * 10 + c - '0'; + c = *format++; + } while(isdigit(c)); + else if(c == '*') { + width = va_arg(ap, int); + c = *format++; + } + + /* precision */ + if (c == '.') { + prec = 0; + c = *format++; + if (isdigit(c)) + do { + prec = prec * 10 + c - '0'; + c = *format++; + } while(isdigit(c)); + else if (c == '*') { + prec = va_arg(ap, int); + c = *format++; + } + } + + /* size */ + + if (c == 'h') { + short_flag = 1; + c = *format++; + } else if (c == 'l') { + long_flag = 1; + c = *format++; + } + + switch (c) { + case 'c' : + if(append_char(state, va_arg(ap, int), width, flags)) + return -1; + break; + case 's' : + if (append_string(state, + va_arg(ap, unsigned char*), + width, + prec, + flags)) + return -1; + break; + case 'd' : + case 'i' : { + long arg; + unsigned long num; + int minusp = 0; + + PARSE_INT_FORMAT(arg, ap, signed); + + if (arg < 0) { + minusp = 1; + num = -arg; + } else + num = arg; + + if (append_number (state, num, 10, "0123456789", + width, prec, flags, minusp)) + return -1; + break; + } + case 'u' : { + unsigned long arg; + + PARSE_INT_FORMAT(arg, ap, unsigned); + + if (append_number (state, arg, 10, "0123456789", + width, prec, flags, 0)) + return -1; + break; + } + case 'o' : { + unsigned long arg; + + PARSE_INT_FORMAT(arg, ap, unsigned); + + if (append_number (state, arg, 010, "01234567", + width, prec, flags, 0)) + return -1; + break; + } + case 'x' : { + unsigned long arg; + + PARSE_INT_FORMAT(arg, ap, unsigned); + + if (append_number (state, arg, 0x10, "0123456789abcdef", + width, prec, flags, 0)) + return -1; + break; + } + case 'X' :{ + unsigned long arg; + + PARSE_INT_FORMAT(arg, ap, unsigned); + + if (append_number (state, arg, 0x10, "0123456789ABCDEF", + width, prec, flags, 0)) + return -1; + break; + } + case 'p' : { + unsigned long arg = (unsigned long)va_arg(ap, void*); + + if (append_number (state, arg, 0x10, "0123456789ABCDEF", + width, prec, flags, 0)) + return -1; + break; + } + case 'n' : { + int *arg = va_arg(ap, int*); + *arg = state->s - state->str; + break; + } + case '\0' : + --format; + /* FALLTHROUGH */ + case '%' : + if ((*state->append_char)(state, c)) + return -1; + break; + default : + if ( (*state->append_char)(state, '%') + || (*state->append_char)(state, c)) + return -1; + break; + } + } else + if ((*state->append_char) (state, c)) + return -1; + } + return 0; +} + +#ifndef HAVE_SNPRINTF +int +snprintf (char *str, size_t sz, const char *format, ...) +{ + va_list args; + int ret; + + va_start(args, format); + ret = vsnprintf (str, sz, format, args); + +#ifdef PARANOIA + { + int ret2; + char *tmp; + + tmp = malloc (sz); + if (tmp == NULL) + abort (); + + ret2 = vsprintf (tmp, format, args); + if (ret != ret2 || strcmp(str, tmp)) + abort (); + free (tmp); + } +#endif + + va_end(args); + return ret; +} +#endif + +#if 0 +#ifndef HAVE_ASPRINTF +int +asprintf (char **ret, const char *format, ...) +{ + va_list args; + int val; + + va_start(args, format); + val = vasprintf (ret, format, args); + +#ifdef PARANOIA + { + int ret2; + char *tmp; + tmp = malloc (val + 1); + if (tmp == NULL) + abort (); + + ret2 = vsprintf (tmp, format, args); + if (val != ret2 || strcmp(*ret, tmp)) + abort (); + free (tmp); + } +#endif + + va_end(args); + return val; +} +#endif + +#ifndef HAVE_ASNPRINTF +int +asnprintf (char **ret, size_t max_sz, const char *format, ...) +{ + va_list args; + int val; + + va_start(args, format); + val = vasnprintf (ret, max_sz, format, args); + +#ifdef PARANOIA + { + int ret2; + char *tmp; + tmp = malloc (val + 1); + if (tmp == NULL) + abort (); + + ret2 = vsprintf (tmp, format, args); + if (val != ret2 || strcmp(*ret, tmp)) + abort (); + free (tmp); + } +#endif + + va_end(args); + return val; +} +#endif + +#ifndef HAVE_VASPRINTF +int +vasprintf (char **ret, const char *format, va_list args) +{ + return vasnprintf (ret, 0, format, args); +} +#endif + + +#ifndef HAVE_VASNPRINTF +int +vasnprintf (char **ret, size_t max_sz, const char *format, va_list args) +{ + int st; + size_t len; + struct state state; + + state.max_sz = max_sz; + state.sz = 1; + state.str = malloc(state.sz); + if (state.str == NULL) { + *ret = NULL; + return -1; + } + state.s = state.str; + state.theend = state.s + state.sz - 1; + state.append_char = as_append_char; + state.reserve = as_reserve; + + st = xyzprintf (&state, format, args); + if (st) { + free (state.str); + *ret = NULL; + return -1; + } else { + char *tmp; + + *state.s = '\0'; + len = state.s - state.str; + tmp = realloc (state.str, len+1); + if (tmp == NULL) { + free (state.str); + *ret = NULL; + return -1; + } + *ret = tmp; + return len; + } +} +#endif +#endif + +#ifndef HAVE_VSNPRINTF +int +vsnprintf (char *str, size_t sz, const char *format, va_list args) +{ + struct state state; + int ret; + unsigned char *ustr = (unsigned char *)str; + + state.max_sz = 0; + state.sz = sz; + state.str = ustr; + state.s = ustr; + state.theend = ustr + sz - 1; + state.append_char = sn_append_char; + state.reserve = sn_reserve; + + ret = xyzprintf (&state, format, args); + *state.s = '\0'; + if (ret) + return sz; + else + return state.s - state.str; +} +#endif + diff --git a/winpcap/wpcap/libpcap/mkdep b/winpcap/wpcap/libpcap/mkdep new file mode 100644 index 0000000..2a9c221 --- /dev/null +++ b/winpcap/wpcap/libpcap/mkdep @@ -0,0 +1,109 @@ +#!/bin/sh - +# +# Copyright (c) 1994, 1996 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of California at Berkeley. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# @(#)mkdep.sh 5.11 (Berkeley) 5/5/88 +# + +PATH=/bin:/usr/bin:/usr/ucb:/usr/local:/usr/local/bin +export PATH + +MAKE=Makefile # default makefile name is "Makefile" +CC=cc # default C compiler is "cc" + +while : + do case "$1" in + # -c allows you to specify the C compiler + -c) + CC=$2 + shift; shift ;; + + # -f allows you to select a makefile name + -f) + MAKE=$2 + shift; shift ;; + + # the -p flag produces "program: program.c" style dependencies + # so .o's don't get produced + -p) + SED='s;\.o;;' + shift ;; + *) + break ;; + esac +done + +if [ $# = 0 ] ; then + echo 'usage: mkdep [-p] [-c cc] [-f makefile] [flags] file ...' + exit 1 +fi + +if [ ! -w $MAKE ]; then + echo "mkdep: no writeable file \"$MAKE\"" + exit 1 +fi + +TMP=/tmp/mkdep$$ + +trap 'rm -f $TMP ; exit 1' 1 2 3 13 15 + +cp $MAKE ${MAKE}.bak + +sed -e '/DO NOT DELETE THIS LINE/,$d' < $MAKE > $TMP + +cat << _EOF_ >> $TMP +# DO NOT DELETE THIS LINE -- mkdep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +_EOF_ + +# If your compiler doesn't have -M, add it. If you can't, the next two +# lines will try and replace the "cc -M". The real problem is that this +# hack can't deal with anything that requires a search path, and doesn't +# even try for anything using bracket (<>) syntax. +# +# egrep '^#include[ ]*".*"' /dev/null $* | +# sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' -e 's/\.c/.o/' | + +# XXX this doesn't work with things like "-DDECLWAITSTATUS=union\ wait" +$CC -M $* | +sed " + s; \./; ;g + $SED" | +awk '{ + if ($1 != prev) { + if (rec != "") + print rec; + rec = $0; + prev = $1; + } + else { + if (length(rec $2) > 78) { + print rec; + rec = $0; + } + else + rec = rec " " $2 + } +} +END { + print rec +}' >> $TMP + +cat << _EOF_ >> $TMP + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +_EOF_ + +# copy to preserve permissions +cp $TMP $MAKE +rm -f ${MAKE}.bak $TMP +exit 0 diff --git a/winpcap/wpcap/libpcap/msdos/bin2c.c b/winpcap/wpcap/libpcap/msdos/bin2c.c new file mode 100644 index 0000000..d82056e --- /dev/null +++ b/winpcap/wpcap/libpcap/msdos/bin2c.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +static void Abort (char *fmt,...) +{ + va_list args; + va_start (args, fmt); + vfprintf (stderr, fmt, args); + va_end (args); + exit (1); +} + +int main (int argc, char **argv) +{ + FILE *inFile; + FILE *outFile = stdout; + time_t now = time (NULL); + int ch, i; + + if (argc != 2) + Abort ("Usage: %s bin-file [> result]", argv[0]); + + if ((inFile = fopen(argv[1],"rb")) == NULL) + Abort ("Cannot open %s\n", argv[1]); + + fprintf (outFile, + "/* data statements for file %s at %.24s */\n" + "/* Generated by BIN2C, G.Vanem 1995 */\n", + argv[1], ctime(&now)); + + i = 0; + while ((ch = fgetc(inFile)) != EOF) + { + if (i++ % 12 == 0) + fputs ("\n ", outFile); + fprintf (outFile, "0x%02X,", ch); + } + fputc ('\n', outFile); + fclose (inFile); + return (0); +} diff --git a/winpcap/wpcap/libpcap/msdos/common.dj b/winpcap/wpcap/libpcap/msdos/common.dj new file mode 100644 index 0000000..88e39d8 --- /dev/null +++ b/winpcap/wpcap/libpcap/msdos/common.dj @@ -0,0 +1,80 @@ +# +# Common defines for libpcap and 16/32-bit network drivers (djgpp) +# +# @(#) $Header: /tcpdump/master/libpcap/msdos/common.dj,v 1.2 2004/12/19 19:36:33 guy Exp $ (LBL) + +.SUFFIXES: .exe .wlm .dxe .l .y +.PHONY: check_gcclib + +default: check_gcclib all + +GCCLIB = /djgpp/lib/gcc-lib/djgpp/3.31 +MAKEFILE = Makefile.dj + +# +# DLX 2.91+ lib. Change path to suite. +# Not used anymore. Uses DXE3 now. +# +# DLX_LIB = $(DJDIR)/contrib/dlx.291/libdlx.a +# DLX_LINK = $(DJDIR)/bin/dlxgen.exe + +WATT32_ROOT = $(subst \,/,$(WATT_ROOT)) + + +ifeq ($(wildcard $(GCCLIB)/libgcc.a),) +check_gcclib: + @echo libgcc.a not found. Set \"$(GCCLIB)\" to \"/djgpp/lib/gcc-lib/djgpp/3.X\" +endif + + +# +# Include 32-bit driver support +# +USE_32BIT_DRIVERS = 0 + +# +# Use loadable driver modules instead of statically linking +# all drivers. +# +USE_32BIT_MODULES = 0 + +# +# Put interrupt sensitive code/data in locked sections +# Do `make clean' in all affected directories after changing this. +# +USE_SECTION_LOCKING = 0 + +# +# Set to 1 to use exception handler lib (only for me) +# +USE_EXCEPT = 0 + +CC = gcc.exe +LD = ld.exe +ASM = nasm.exe -fbin -dDEBUG +YACC = bison.exe +LEX = flex.exe + +CFLAGS = -g -gcoff -O2 -Wall -I. -I$(WATT32_ROOT)/inc + +ifeq ($(USE_EXCEPT),1) + CFLAGS += -DUSE_EXCEPT + EXC_LIB = d:/prog/mw/except/lib/libexc.a +endif + +ifeq ($(USE_SECTION_LOCKING),1) + CFLAGS += -DUSE_SECTION_LOCKING +endif + +ifeq ($(USE_32BIT_DRIVERS),1) + CFLAGS += -DUSE_32BIT_DRIVERS +endif + +%.o: %.c + $(CC) -c $(CFLAGS) $< + @echo + +%.o: %.s + $(CC) -c $(CFLAGS) -x assembler-with-cpp -o $@ $< + @echo + diff --git a/winpcap/wpcap/libpcap/msdos/makefile b/winpcap/wpcap/libpcap/msdos/makefile new file mode 100644 index 0000000..cdb4e7c --- /dev/null +++ b/winpcap/wpcap/libpcap/msdos/makefile @@ -0,0 +1,184 @@ +# +# Makefile for dos-libpcap. NB. This makefile requires a Borland +# compatible make tool. +# +# Targets: +# Borland C 4.0+ (DOS large model) +# Metaware HighC 3.3+ (PharLap 386|DosX) +# + +.AUTODEPEND +.SWAP + +!if "$(WATT_ROOT)" == "" +!error Environment variable "WATT_ROOT" not set. +!endif + +WATT_INC = $(WATT_ROOT)\inc + +DEFS = -DMSDOS -DDEBUG -DNDIS_DEBUG -D_U_= -Dinline= \ + -DHAVE_STRERROR -DHAVE_LIMITS_H + +ASM = tasm.exe -t -l -mx -m2 -DDEBUG + +SOURCE = grammar.c scanner.c bpf_filt.c bpf_imag.c bpf_dump.c \ + etherent.c gencode.c nametoad.c pcap-dos.c optimize.c \ + savefile.c pcap.c inet.c msdos\ndis2.c msdos\pktdrvr.c \ + missing\snprintf.c + +BORLAND_OBJ = $(SOURCE:.c=.obj) msdos\pkt_rx0.obj msdos\ndis_0.obj + +HIGHC_OBJ = $(SOURCE:.c=.o32) msdos\pkt_rx0.o32 + +all: + @echo Usage: make pcap_bc.lib or pcap_hc.lib + + +pcap_bc.lib: bcc.arg $(BORLAND_OBJ) pcap_bc + + +pcap_hc.lib: hc386.arg $(HIGHC_OBJ) + 386lib $< @&&| + -nowarn -nobackup -twocase -replace $(HIGHC_OBJ) +| + +pcap_bc: $(BORLAND_OBJ) + @tlib pcap_bc.lib /C @&&| + -+$(**:.obj=-+) +| + +.c.obj: + bcc.exe @bcc.arg -o$*.obj $*.c + +.c.o32: + hc386.exe @hc386.arg -o $*.o32 $*.c + +.asm.obj: + $(ASM) $*.asm, $*.obj + +.asm.o32: + $(ASM) -DDOSX=1 $*.asm, $*.o32 + +scanner.c: scanner.l + flex -Ppcap_ -7 -oscanner.c scanner.l + +grammar.c tokdefs.h: grammar.y + bison --name-prefix=pcap_ --yacc --defines grammar.y + - @del grammar.c + - @del tokdefs.h + ren y_tab.c grammar.c + ren y_tab.h tokdefs.h + +bcc.arg: msdos\Makefile + @copy &&| + $(DEFS) -ml -c -v -3 -O2 -po -RT- -w- + -I$(WATT_INC) -I. -I.\msdos\pm_drvr -H=$(TEMP)\bcc.sym +| $< + +hc386.arg: msdos\Makefile + @copy &&| + # -DUSE_32BIT_DRIVERS + $(DEFS) -DDOSX=1 -w3 -c -g -O5 + -I$(WATT_INC) -I. -I.\msdos\pm_drvr + -Hsuffix=.o32 + -Hnocopyr + -Hpragma=Offwarn(491,553,572) + -Hon=Recognize_library # make memcpy/strlen etc. inline + -Hoff=Behaved # turn off some optimiser warnings +| $< + +clean: + @del *.obj + @del *.o32 + @del *.lst + @del *.map + @del bcc.arg + @del hc386.arg + @del grammar.c + @del tokdefs.h + @del scanner.c + @echo Cleaned + +# +# dependencies +# +pkt_rx0.obj: msdos\pkt_rx0.asm + +bpf_filt.obj: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h + +bpf_imag.obj: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h + +bpf_dump.obj: bpf_dump.c pcap.h pcap-bpf.h + +etherent.obj: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h + +optimize.obj: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h + +savefile.obj: savefile.c pcap-int.h pcap.h pcap-bpf.h + +pcap.obj: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h + +inet.obj: inet.c pcap-int.h pcap.h pcap-bpf.h + +grammar.obj: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h \ + pf.h pcap-namedb.h + +scanner.obj: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h \ + pcap-namedb.h tokdefs.h + +gencode.obj: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \ + ethertype.h nlpid.h llc.h gencode.h atmuni31.h sunatmpos.h ppp.h sll.h \ + arcnet.h pf.h pcap-namedb.h + +nametoad.obj: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \ + pcap-namedb.h ethertype.h + +pcap-dos.obj: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h \ + msdos\pktdrvr.h + +pktdrvr.obj: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h \ + pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc + +ndis2.obj: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \ + msdos\ndis2.h + +pkt_rx0.o32: msdos\pkt_rx0.asm + +bpf_filt.o32: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h + +bpf_imag.o32: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h + +bpf_dump.o32: bpf_dump.c pcap.h pcap-bpf.h + +etherent.o32: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h + +optimize.o32: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h + +savefile.o32: savefile.c pcap-int.h pcap.h pcap-bpf.h + +pcap.o32: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h + +inet.o32: inet.c pcap-int.h pcap.h pcap-bpf.h + +grammar.o32: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h \ + pf.h pcap-namedb.h + +scanner.o32: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h \ + pcap-namedb.h tokdefs.h + +gencode.o32: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \ + ethertype.h nlpid.h llc.h gencode.h atmuni31.h sunatmpos.h ppp.h sll.h \ + arcnet.h pf.h pcap-namedb.h + +nametoad.o32: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \ + pcap-namedb.h ethertype.h + +pcap-dos.o32: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h \ + msdos\pktdrvr.h + +pktdrvr.o32: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h \ + pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc + +ndis2.o32: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \ + msdos\ndis2.h + diff --git a/winpcap/wpcap/libpcap/msdos/makefile.dj b/winpcap/wpcap/libpcap/msdos/makefile.dj new file mode 100644 index 0000000..3575771 --- /dev/null +++ b/winpcap/wpcap/libpcap/msdos/makefile.dj @@ -0,0 +1,152 @@ +# +# GNU Makefile for DOS-libpcap. djgpp version. +# +# Use this makefile from the libpcap root directory. +# E.g. like this: +# +# c:\net\pcap> make -f msdos/makefile.dj +# +# @(#) $Header: /tcpdump/master/libpcap/msdos/makefile.dj,v 1.2 2004/12/19 19:41:06 guy Exp $ (LBL) + +VPATH = missing msdos + +PREREQUISITES = scanner.c grammar.c tokdefs.h version.h msdos/pkt_stub.inc + +include msdos/common.dj + +DRIVER_DIR = ./msdos/pm_drvr + +CFLAGS += -DDEBUG -DNDIS_DEBUG -DHAVE_LIMITS_H -DHAVE_STRERROR \ + -D_U_='__attribute__((unused))' -DHAVE_VERSION_H + +# CFLAGS += -Dyylval=pcap_lval -DBDEBUG -DNDEBUG + +SOURCES = grammar.c scanner.c bpf_filt.c bpf_imag.c bpf_dump.c \ + etherent.c gencode.c nametoad.c pcap-dos.c optimize.c \ + savefile.c pcap.c inet.c msdos\pktdrvr.c msdos/ndis2.c \ + missing/snprintf.c + +OBJECTS = $(notdir $(SOURCES:.c=.o)) +TEMPBIN = tmp.bin + +ifeq ($(USE_32BIT_DRIVERS),1) + PM_OBJECTS = $(addprefix $(DRIVER_DIR)/, \ + printk.o pci.o pci-scan.o bios32.o dma.o irq.o intwrap.o \ + lock.o kmalloc.o quirks.o timer.o net_init.o) + # + # Static link of drivers + # + ifeq ($(USE_32BIT_MODULES),0) + PM_OBJECTS += $(addprefix $(DRIVER_DIR)/, \ + accton.o 8390.o 3c503.o 3c509.o 3c59x.o 3c515.o \ + 3c575_cb.o 3c90x.o ne.o wd.o cs89x0.o rtl8139.o) + endif +endif + +all: libpcap.a + +ifeq ($(USE_32BIT_DRIVERS),1) +$(PM_OBJECTS): + $(MAKE) -f Makefile.dj -C $(DRIVER_DIR) $(notdir $@) +endif + +libpcap.a: version.h $(OBJECTS) $(PM_OBJECTS) + rm -f $@ + ar rs $@ $^ + +msdos/pkt_stub.inc: msdos/bin2c.exe msdos/pkt_rx1.S + $(ASM) -o $(TEMPBIN) -lmsdos/pkt_rx1.lst msdos/pkt_rx1.S + ./msdos/bin2c $(TEMPBIN) > $@ + rm -f $(TEMPBIN) + +grammar.c tokdefs.h: grammar.y + rm -f grammar.c tokdefs.h + $(YACC) --name-prefix=pcap_ --yacc --defines grammar.y + mv -f y_tab.c grammar.c + mv -f y_tab.h tokdefs.h + +version.h: ./VERSION + @echo '/* Generated from VERSION. Do not edit */' > $@ + sed -e 's/.*/static char pcap_version_string[] = "libpcap (&)";/' ./VERSION >> $@ + +scanner.c: scanner.l + $(LEX) -Ppcap_ -7 -t $^ > $@ + @echo + +msdos/bin2c.exe: msdos/bin2c.c + $(CC) $*.c -o $*.exe + +clean: + $(MAKE) -f Makefile.dj -C $(DRIVER_DIR) clean + $(MAKE) -f Makefile.dj -C libcpcap clean + rm -f $(OBJECTS) msdos/pkt_rx1.lst Makefile.bak $(PREREQUISITES) + +vclean: clean + rm -f libpcap.a msdos/bin2c.exe + +# +# Generated dependencies; Due to some hacks in gcc 2.95 and djgpp 2.03 +# we must prevent "$(DJDIR)/bin/../include/sys/version.h" from beeing +# included in dependency output (or else this makefile cannot be used on +# another machine). We therefore use a special 'specs' file during +# pre-processing. +# +MM_SPECS = specs.tmp +MAKEFILE = msdos/Makefile.dj + +depend: $(PREREQUISITES) + @echo Generating dependencies.. + @cp $(MAKEFILE) Makefile.bak + @echo "*cpp: %(cpp_cpu) %{posix:-D_POSIX_SOURCE} -remap" > $(MM_SPECS) + sed -e "/^# DO NOT DELETE THIS LINE/,$$d" < Makefile.bak > $(MAKEFILE) + echo "# DO NOT DELETE THIS LINE" >> $(MAKEFILE) + $(CC) -MM -specs=$(MM_SPECS) $(CFLAGS) $(SOURCES) >> $(MAKEFILE) + rm -f $(MM_SPECS) + +# +# Manually generated dependencies +# +msdos/pktdrvr.c: msdos/pkt_stub.inc +scanner.c: scanner.l +grammar.c tokdefs.h: grammar.y +grammar.h: grammar.y +scanner.l: pcap-int.h pcap-namedb.h gencode.h grammar.h gnuc.h +grammar.y: pcap-int.h gencode.h pcap-namedb.h gnuc.h + +# +# Automatically generated dependencies +# +# DO NOT DELETE THIS LINE +grammar.o: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h pf.h \ + pcap-namedb.h +scanner.o: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h pcap-namedb.h \ + tokdefs.h +bpf_filt.o: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h +bpf_imag.o: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h +bpf_dump.o: bpf_dump.c pcap.h pcap-bpf.h +etherent.o: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h +gencode.o: gencode.c pcap-dos.h msdos/pm_drvr/lock.h pcap-int.h pcap.h \ + pcap-bpf.h ethertype.h nlpid.h llc.h gencode.h atmuni31.h sunatmpos.h \ + ppp.h sll.h arcnet.h pf.h pcap-namedb.h +nametoad.o: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \ + pcap-namedb.h ethertype.h +pcap-dos.o: pcap-dos.c msdos/pm_drvr/pmdrvr.h msdos/pm_drvr/iface.h \ + msdos/pm_drvr/lock.h msdos/pm_drvr/ioport.h pcap-dos.h pcap-int.h \ + pcap.h pcap-bpf.h msdos/pm_drvr/kmalloc.h msdos/pm_drvr/bitops.h \ + msdos/pm_drvr/timer.h msdos/pm_drvr/dma.h msdos/pm_drvr/irq.h \ + msdos/pm_drvr/printk.h msdos/pm_drvr/pci.h msdos/pm_drvr/bios32.h \ + msdos/pm_drvr/module.h msdos/pm_drvr/3c501.h msdos/pm_drvr/3c503.h \ + msdos/pm_drvr/3c509.h msdos/pm_drvr/3c59x.h msdos/pm_drvr/3c515.h \ + msdos/pm_drvr/3c90x.h msdos/pm_drvr/3c575_cb.h msdos/pm_drvr/ne.h \ + msdos/pm_drvr/wd.h msdos/pm_drvr/accton.h msdos/pm_drvr/cs89x0.h \ + msdos/pm_drvr/rtl8139.h msdos/pm_drvr/ne2k-pci.h msdos/pktdrvr.h +optimize.o: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h +savefile.o: savefile.c pcap-int.h pcap.h pcap-bpf.h +pcap.o: pcap.c pcap-dos.h msdos/pm_drvr/lock.h pcap-int.h pcap.h \ + pcap-bpf.h +inet.o: inet.c pcap-int.h pcap.h pcap-bpf.h +pktdrvr.o: msdos/pktdrvr.c gnuc.h pcap-dos.h msdos/pm_drvr/lock.h \ + pcap-int.h pcap.h pcap-bpf.h msdos/pktdrvr.h msdos/pkt_stub.inc +ndis2.o: msdos/ndis2.c pcap-dos.h msdos/pm_drvr/lock.h pcap-int.h pcap.h \ + pcap-bpf.h msdos/ndis2.h +snprintf.o: missing/snprintf.c pcap-int.h pcap.h pcap-bpf.h diff --git a/winpcap/wpcap/libpcap/msdos/makefile.wc b/winpcap/wpcap/libpcap/msdos/makefile.wc new file mode 100644 index 0000000..e0d5672 --- /dev/null +++ b/winpcap/wpcap/libpcap/msdos/makefile.wc @@ -0,0 +1,131 @@ +# +# Watcom Makefile for dos-libpcap. +# +# Specify MODEL = `3r' or `3s' +# Specify TARGET = `pharlap' or `dos4g' +# +# Use this makefile from the libpcap root directory. +# E.g. like this: +# +# c:\net\pcap> wmake -f msdos\makefile.wc +# + +MODEL = 3s +TARGET = dos4g + +OBJDIR = msdos\$(TARGET).w$(MODEL) +LIB = $(OBJDIR)\pcap.lib + +.EXTENSIONS: .l .y + +DEFS = -dDEBUG -dNDIS_DEBUG -d_U_= -dHAVE_LIMITS_H -dHAVE_STRERROR & + -dHAVE_SNPRINTF -dHAVE_VSNPRINTF + +CC = wcc386.exe +ASM = wasm.exe -$(MODEL) $(DEFS) -dDOSX -dDOS4GW -zq -bt=dos -fr=nul -d3 -s + +OBJS = $(OBJDIR)\grammar.obj $(OBJDIR)\scanner.obj $(OBJDIR)\pcap.obj & + $(OBJDIR)\bpf_filt.obj $(OBJDIR)\bpf_imag.obj $(OBJDIR)\bpf_dump.obj & + $(OBJDIR)\etherent.obj $(OBJDIR)\gencode.obj $(OBJDIR)\nametoad.obj & + $(OBJDIR)\pcap-dos.obj $(OBJDIR)\pktdrvr.obj $(OBJDIR)\optimize.obj & + $(OBJDIR)\savefile.obj $(OBJDIR)\inet.obj $(OBJDIR)\ndis2.obj + +CFLAGS = $(DEFS) $(YYDEFS) -I. -I$(%watt_root)\inc -I.\msdos\pm_drvr & + -$(MODEL) -mf -zff -zgf -zq -bt=dos -fr=nul -w6 -fpi & + -oilrtf -zm + +TEMPBIN = tmp.bin + +all: $(OBJDIR) $(OBJDIR)\pcap.lib + +$(OBJDIR): + - mkdir $(OBJDIR) + +$(OBJDIR)\pcap.lib: $(OBJS) wlib.arg + wlib -q -b -c $(OBJDIR)\pcap.lib @wlib.arg + +wlib.arg: msdos\makefile.wc + %create $^@ + for %f in ($(OBJS)) do %append $^@ +- %f + +$(OBJDIR)\pktdrvr.obj: msdos\pkt_stub.inc msdos\pktdrvr.c gnuc.h & + pcap-dos.h pcap-int.h pcap.h msdos\pktdrvr.h + *$(CC) $(CFLAGS) msdos\pktdrvr.c -fo=$@ + +$(OBJDIR)\ndis2.obj: msdos\ndis2.c + *$(CC) $(CFLAGS) msdos\ndis2.c -fo=$@ + +.ERASE +.c{$(OBJDIR)}.obj: + *$(CC) $(CFLAGS) $[@ -fo=$@ + +grammar.c tokdefs.h: grammar.y + bison --name-prefix=pcap_ --yacc --defines $[@ + - @del grammar.c + - @del tokdefs.h + ren y_tab.c grammar.c + ren y_tab.h tokdefs.h + +scanner.c: scanner.l + flex -Ppcap_ -7 -o$@ $[@ + +msdos\pkt_stub.inc: bin2c.exe msdos\pkt_rx1.S + nasm -fbin -dDEBUG -o $(TEMPBIN) -lmsdos\pkt_rx1.lst msdos\pkt_rx1.S + bin2c.exe $(TEMPBIN) > $@ + @del $(TEMPBIN) + +bin2c.exe: msdos\bin2c.c + wcl $[@ + +clean realclean vclean: .SYMBOLIC + for %f in (dos4g.w3r dos4g.w3s pharlap.w3r pharlap.w3s) do & + @del %f\*.obj + @del grammar.c + @del tokdefs.h + @del scanner.c + @del bin2c.exe + @del bin2c.obj + @del msdos\pkt_stub.inc + @echo Cleaned + +# +# dependencies +# +$(OBJDIR)\bpf_filt.obj: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h + +$(OBJDIR)\bpf_imag.obj: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h + +$(OBJDIR)\bpf_dump.obj: bpf_dump.c pcap.h pcap-bpf.h + +$(OBJDIR)\etherent.obj: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-nam.h + +$(OBJDIR)\optimize.obj: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h + +$(OBJDIR)\savefile.obj: savefile.c pcap-int.h pcap.h pcap-bpf.h + +$(OBJDIR)\pcap.obj: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h + +$(OBJDIR)\inet.obj: inet.c pcap-int.h pcap.h pcap-bpf.h + +$(OBJDIR)\grammar.obj: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h & + pf.h pcap-nam.h + +$(OBJDIR)\scanner.obj: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h & + pcap-nam.h tokdefs.h + +$(OBJDIR)\gencode.obj: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h & + ethertyp.h nlpid.h llc.h gencode.h atmuni31.h sunatmpo.h ppp.h sll.h & + arcnet.h pf.h pcap-nam.h + +$(OBJDIR)\nametoad.obj: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h & + pcap-nam.h ethertyp.h + +$(OBJDIR)\pcap-dos.obj: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h & + msdos\pktdrvr.h + +$(OBJDIR)\pktdrvr.obj: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h & + pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc + +$(OBJDIR)\ndis2.obj: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h & + msdos\ndis2.h + diff --git a/winpcap/wpcap/libpcap/msdos/ndis2.c b/winpcap/wpcap/libpcap/msdos/ndis2.c new file mode 100644 index 0000000..0a5ea2a --- /dev/null +++ b/winpcap/wpcap/libpcap/msdos/ndis2.c @@ -0,0 +1,860 @@ +/* + * Copyright (c) 1993,1994 + * Texas A&M University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Texas A&M University + * and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Developers: + * David K. Hess, Douglas Lee Schales, David R. Safford + * + * Heavily modified for Metaware HighC + GNU C 2.8+ + * Gisle Vanem 1998 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "pcap-dos.h" +#include "pcap-int.h" +#include "msdos/ndis2.h" + +#if defined(USE_NDIS2) + +/* + * Packet buffer handling + */ +extern int FreePktBuf (PktBuf *buf); +extern int EnquePktBuf (PktBuf *buf); +extern PktBuf* AllocPktBuf (void); + +/* + * Various defines + */ +#define MAX_NUM_DEBUG_STRINGS 90 +#define DEBUG_STRING_LENGTH 80 +#define STACK_POOL_SIZE 6 +#define STACK_SIZE 256 + +#define MEDIA_FDDI 1 +#define MEDIA_ETHERNET 2 +#define MEDIA_TOKEN 3 + +static int startDebug = 0; +static int stopDebug = 0; + +static DWORD droppedPackets = 0L; +static WORD frameSize = 0; +static WORD headerSize = 0; +static int mediaType = 0; +static char *lastErr = NULL; + +static BYTE debugStrings [MAX_NUM_DEBUG_STRINGS][DEBUG_STRING_LENGTH]; +static BYTE *freeStacks [STACK_POOL_SIZE]; +static int freeStackPtr = STACK_POOL_SIZE - 1; + +static ProtMan protManEntry = NULL; +static WORD protManDS = 0; +static volatile int xmitPending; + +static struct _PktBuf *txBufPending; +static struct _CardHandle *handle; +static struct _CommonChars common; +static struct _ProtocolChars protChars; +static struct _ProtDispatch lowerTable; + +static struct _FailingModules failingModules; +static struct _BindingsList bindings; + +static struct { + WORD err_num; + char *err_text; + } ndis_errlist[] = { + + { ERR_SUCCESS, + "The function completed successfully.\n" }, + + { ERR_WAIT_FOR_RELEASE, + "The ReceiveChain completed successfully but the protocol has\n" + "retained control of the buffer.\n" }, + + { ERR_REQUEST_QUEUED, + "The current request has been queued.\n" }, + + { ERR_FRAME_NOT_RECOGNIZED, + "Frame not recognized.\n" }, + + { ERR_FRAME_REJECTED, + "Frame was discarded.\n" }, + + { ERR_FORWARD_FRAME, + "Protocol wishes to forward frame to another protocol.\n" }, + + { ERR_OUT_OF_RESOURCE, + "Out of resource.\n" }, + + { ERR_INVALID_PARAMETER, + "Invalid parameter.\n" }, + + { ERR_INVALID_FUNCTION, + "Invalid function.\n" }, + + { ERR_NOT_SUPPORTED, + "Not supported.\n" }, + + { ERR_HARDWARE_ERROR, + "Hardware error.\n" }, + + { ERR_TRANSMIT_ERROR, + "The packet was not transmitted due to an error.\n" }, + + { ERR_NO_SUCH_DESTINATION, + "Token ring packet was not recognized when transmitted.\n" }, + + { ERR_BUFFER_TOO_SMALL, + "Provided buffer was too small.\n" }, + + { ERR_ALREADY_STARTED, + "Network drivers already started.\n" }, + + { ERR_INCOMPLETE_BINDING, + "Protocol driver could not complete its bindings.\n" }, + + { ERR_DRIVER_NOT_INITIALIZED, + "MAC did not initialize properly.\n" }, + + { ERR_HARDWARE_NOT_FOUND, + "Hardware not found.\n" }, + + { ERR_HARDWARE_FAILURE, + "Hardware failure.\n" }, + + { ERR_CONFIGURATION_FAILURE, + "Configuration failure.\n" }, + + { ERR_INTERRUPT_CONFLICT, + "Interrupt conflict.\n" }, + + { ERR_INCOMPATIBLE_MAC, + "The MAC is not compatible with the protocol.\n" }, + + { ERR_INITIALIZATION_FAILED, + "Initialization failed.\n" }, + + { ERR_NO_BINDING, + "Binding did not occur.\n" }, + + { ERR_NETWORK_MAY_NOT_BE_CONNECTED, + "The network may not be connected to the adapter.\n" }, + + { ERR_INCOMPATIBLE_OS_VERSION, + "The version of the operating system is incompatible with the protocol.\n" }, + + { ERR_ALREADY_REGISTERED, + "The protocol is already registered.\n" }, + + { ERR_PATH_NOT_FOUND, + "PROTMAN.EXE could not be found.\n" }, + + { ERR_INSUFFICIENT_MEMORY, + "Insufficient memory.\n" }, + + { ERR_INFO_NOT_FOUND, + "Protocol Mananger info structure is lost or corrupted.\n" }, + + { ERR_GENERAL_FAILURE, + "General failure.\n" } +}; + +/* + * Some handy macros + */ +#define PERROR(str) printf("%s (%d): %s\n", __FILE__,__LINE__,str) +#define DEBUG_RING() (debugStrings[stopDebug+1 == MAX_NUM_DEBUG_STRINGS ? \ + stopDebug = 0 : ++stopDebug]) + +/* + * needs rewrite for DOSX + */ +#define MAC_DISPATCH(hnd) ((struct _MacUpperDispatch*)(hnd)->common->upperDispatchTable) +#define MAC_STATUS(hnd) ((struct _MacStatusTable*) (hnd)->common->serviceStatus) +#define MAC_CHAR(hnd) ((struct _MacChars*) (hnd)->common->serviceChars) + +#ifdef NDIS_DEBUG + #define DEBUG0(str) printf (str) + #define DEBUG1(fmt,a) printf (fmt,a) + #define DEBUG2(fmt,a,b) printf (fmt,a,b) + #define TRACE0(str) sprintf (DEBUG_RING(),str) + #define TRACE1(fmt,a) sprintf (DEBUG_RING(),fmt,a) +#else + #define DEBUG0(str) ((void)0) + #define DEBUG1(fmt,a) ((void)0) + #define DEBUG2(fmt,a,b) ((void)0) + #define TRACE0(str) ((void)0) + #define TRACE1(fmt,a) ((void)0) +#endif + +/* + * This routine is called from both threads + */ +void NdisFreeStack (BYTE *aStack) +{ + GUARD(); + + if (freeStackPtr == STACK_POOL_SIZE - 1) + PERROR ("tried to free too many stacks"); + + freeStacks[++freeStackPtr] = aStack; + + if (freeStackPtr == 0) + TRACE0 ("freeStackPtr went positive\n"); + + UNGUARD(); +} + +/* + * This routine is called from callbacks to allocate local data + */ +BYTE *NdisAllocStack (void) +{ + BYTE *stack; + + GUARD(); + + if (freeStackPtr < 0) + { + /* Ran out of stack buffers. Return NULL which will start + * dropping packets + */ + TRACE0 ("freeStackPtr went negative\n"); + stack = 0; + } + else + stack = freeStacks[freeStackPtr--]; + + UNGUARD(); + return (stack); +} + +CALLBACK (NdisSystemRequest (DWORD param1, DWORD param2, WORD param3, + WORD opcode, WORD targetDS)) +{ + static int bindEntry = 0; + struct _CommonChars *macCommon; + volatile WORD result; + + switch (opcode) + { + case REQ_INITIATE_BIND: + macCommon = (struct _CommonChars*) param2; + if (macCommon == NULL) + { + printf ("There is an NDIS misconfiguration.\n"); + result = ERR_GENERAL_FAILURE; + break; + } + DEBUG2 ("module name %s\n" + "module type %s\n", + macCommon->moduleName, + ((MacChars*) macCommon->serviceChars)->macName); + + /* Binding to the MAC */ + result = macCommon->systemRequest ((DWORD)&common, (DWORD)&macCommon, + 0, REQ_BIND, + macCommon->moduleDS); + + if (!strcmp(bindings.moduleName[bindEntry], handle->moduleName)) + handle->common = macCommon; + else PERROR ("unknown module"); + ++bindEntry; + break; + + case REQ_INITIATE_UNBIND: + macCommon = (struct _CommonChars*) param2; + result = macCommon->systemRequest ((DWORD)&common, 0, + 0, REQ_UNBIND, + macCommon->moduleDS); + break; + + default: + result = ERR_GENERAL_FAILURE; + break; + } + ARGSUSED (param1); + ARGSUSED (param3); + ARGSUSED (targetDS); + return (result); +} + +CALLBACK (NdisRequestConfirm (WORD protId, WORD macId, WORD reqHandle, + WORD status, WORD request, WORD protDS)) +{ + ARGSUSED (protId); ARGSUSED (macId); + ARGSUSED (reqHandle); ARGSUSED (status); + ARGSUSED (request); ARGSUSED (protDS); + return (ERR_SUCCESS); +} + +CALLBACK (NdisTransmitConfirm (WORD protId, WORD macId, WORD reqHandle, + WORD status, WORD protDS)) +{ + xmitPending--; + FreePktBuf (txBufPending); /* Add passed ECB back to the free list */ + + ARGSUSED (reqHandle); + ARGSUSED (status); + ARGSUSED (protDS); + return (ERR_SUCCESS); +} + + +/* + * The primary function for receiving packets + */ +CALLBACK (NdisReceiveLookahead (WORD macId, WORD frameSize, + WORD bytesAvail, BYTE *buffer, + BYTE *indicate, WORD protDS)) +{ + int result; + PktBuf *pktBuf; + WORD bytesCopied; + struct _TDBufDescr tDBufDescr; + +#if 0 + TRACE1 ("lookahead length = %d, ", bytesAvail); + TRACE1 ("ecb = %08lX, ", *ecb); + TRACE1 ("count = %08lX\n", count); + TRACE1 ("offset = %08lX, ", offset); + TRACE1 ("timesAllowed = %d, ", timesAllowed); + TRACE1 ("packet size = %d\n", look->dataLookAheadLen); +#endif + + /* Allocate a buffer for the packet + */ + if ((pktBuf = AllocPktBuf()) == NULL) + { + droppedPackets++; + return (ERR_FRAME_REJECTED); + } + + /* + * Now kludge things. Note we will have to undo this later. This will + * make the packet contiguous after the MLID has done the requested copy. + */ + + tDBufDescr.tDDataCount = 1; + tDBufDescr.tDBufDescrRec[0].tDPtrType = NDIS_PTR_PHYSICAL; + tDBufDescr.tDBufDescrRec[0].tDDataPtr = pktBuf->buffer; + tDBufDescr.tDBufDescrRec[0].tDDataLen = pktBuf->length; + tDBufDescr.tDBufDescrRec[0].dummy = 0; + + result = MAC_DISPATCH(handle)->transferData (&bytesCopied, 0, &tDBufDescr, + handle->common->moduleDS); + pktBuf->packetLength = bytesCopied; + + if (result == ERR_SUCCESS) + EnquePktBuf(pktBuf); + else FreePktBuf (pktBuf); + + ARGSUSED (frameSize); + ARGSUSED (bytesAvail); + ARGSUSED (indicate); + ARGSUSED (protDS); + + return (ERR_SUCCESS); +} + +CALLBACK (NdisIndicationComplete (WORD macId, WORD protDS)) +{ + ARGSUSED (macId); + ARGSUSED (protDS); + + /* We don't give a hoot about these. Just return + */ + return (ERR_SUCCESS); +} + +/* + * This is the OTHER way we may receive packets + */ +CALLBACK (NdisReceiveChain (WORD macId, WORD frameSize, WORD reqHandle, + struct _RxBufDescr *rxBufDescr, + BYTE *indicate, WORD protDS)) +{ + struct _PktBuf *pktBuf; + int i; + + /* + * For now we copy the entire packet over to a PktBuf structure. This may be + * a performance hit but this routine probably isn't called very much, and + * it is a lot of work to do it otherwise. Also if it is a filter protocol + * packet we could end up sucking up MAC buffes. + */ + + if ((pktBuf = AllocPktBuf()) == NULL) + { + droppedPackets++; + return (ERR_FRAME_REJECTED); + } + pktBuf->packetLength = 0; + + /* Copy the packet to the buffer + */ + for (i = 0; i < rxBufDescr->rxDataCount; ++i) + { + struct _RxBufDescrRec *rxDescr = &rxBufDescr->rxBufDescrRec[i]; + + memcpy (pktBuf->buffer + pktBuf->packetLength, + rxDescr->rxDataPtr, rxDescr->rxDataLen); + pktBuf->packetLength += rxDescr->rxDataLen; + } + + EnquePktBuf (pktBuf); + + ARGSUSED (frameSize); + ARGSUSED (reqHandle); + ARGSUSED (indicate); + ARGSUSED (protDS); + + /* This frees up the buffer for the MAC to use + */ + return (ERR_SUCCESS); +} + +CALLBACK (NdisStatusProc (WORD macId, WORD param1, BYTE *indicate, + WORD opcode, WORD protDS)) +{ + switch (opcode) + { + case STATUS_RING_STATUS: + break; + case STATUS_ADAPTER_CHECK: + break; + case STATUS_START_RESET: + break; + case STATUS_INTERRUPT: + break; + case STATUS_END_RESET: + break; + default: + break; + } + ARGSUSED (macId); + ARGSUSED (param1); + ARGSUSED (indicate); + ARGSUSED (opcode); + ARGSUSED (protDS); + + /* We don't need to do anything about this stuff yet + */ + return (ERR_SUCCESS); +} + +/* + * Tell the NDIS driver to start the delivery of the packet + */ +int NdisSendPacket (struct _PktBuf *pktBuf, int macId) +{ + struct _TxBufDescr txBufDescr; + int result; + + xmitPending++; + txBufPending = pktBuf; /* we only have 1 pending Tx at a time */ + + txBufDescr.txImmedLen = 0; + txBufDescr.txImmedPtr = NULL; + txBufDescr.txDataCount = 1; + txBufDescr.txBufDescrRec[0].txPtrType = NDIS_PTR_PHYSICAL; + txBufDescr.txBufDescrRec[0].dummy = 0; + txBufDescr.txBufDescrRec[0].txDataLen = pktBuf->packetLength; + txBufDescr.txBufDescrRec[0].txDataPtr = pktBuf->buffer; + + result = MAC_DISPATCH(handle)->transmitChain (common.moduleId, + pktBuf->handle, + &txBufDescr, + handle->common->moduleDS); + switch (result) + { + case ERR_OUT_OF_RESOURCE: + /* Note that this should not happen but if it does there is not + * much we can do about it + */ + printf ("ERROR: transmit queue overflowed\n"); + return (0); + + case ERR_SUCCESS: + /* Everything was hunky dory and synchronous. Free up the + * packet buffer + */ + xmitPending--; + FreePktBuf (pktBuf); + return (1); + + case ERR_REQUEST_QUEUED: + /* Everything was hunky dory and asynchronous. Do nothing + */ + return (1); + + default: + printf ("Tx fail, code = %04X\n", result); + return (0); + } +} + + + +static int ndis_nerr = sizeof(ndis_errlist) / sizeof(ndis_errlist[0]); + +static char *Ndis_strerror (WORD errorCode) +{ + static char buf[30]; + int i; + + for (i = 0; i < ndis_nerr; i++) + if (errorCode == ndis_errlist[i].err_num) + return (ndis_errlist[i].err_text); + + sprintf (buf,"unknown error %d",errorCode); + return (buf); +} + + +char *NdisLastError (void) +{ + char *errStr = lastErr; + lastErr = NULL; + return (errStr); +} + +int NdisOpen (void) +{ + struct _ReqBlock reqBlock; + int result; + int ndisFd = open (NDIS_PATH, O_RDONLY); + + if (ndisFd < 0) + { + printf ("Could not open NDIS Protocol Manager device.\n"); + return (0); + } + + memset (&reqBlock, 0, sizeof(ReqBlock)); + + reqBlock.opcode = PM_GET_PROTOCOL_MANAGER_LINKAGE; + + result = NdisGetLinkage (ndisFd, (char*)&reqBlock, sizeof(ReqBlock)); + if (result != 0) + { + printf ("Could not get Protocol Manager linkage.\n"); + close (ndisFd); + return (0); + } + + close (ndisFd); + protManEntry = (ProtMan) reqBlock.pointer1; + protManDS = reqBlock.word1; + + DEBUG2 ("Entry Point = %04X:%04X\n", FP_SEG(protManEntry),FP_OFF(protManEntry)); + DEBUG1 ("ProtMan DS = %04X\n", protManDS); + return (1); +} + + +int NdisRegisterAndBind (int promis) +{ + struct _ReqBlock reqBlock; + WORD result; + + memset (&common,0,sizeof(common)); + + common.tableSize = sizeof (common); + + common.majorNdisVersion = 2; + common.minorNdisVersion = 0; + common.majorModuleVersion = 2; + common.minorModuleVersion = 0; + + /* Indicates binding from below and dynamically loaded + */ + common.moduleFlags = 0x00000006L; + + strcpy (common.moduleName, "PCAP"); + + common.protocolLevelUpper = 0xFF; + common.protocolLevelLower = 1; + common.interfaceLower = 1; +#ifdef __DJGPP__ + common.moduleDS = _dos_ds; /* the callback data segment */ +#else + common.moduleDS = _DS; +#endif + + common.systemRequest = (SystemRequest) systemRequestGlue; + common.serviceChars = (BYTE*) &protChars; + common.serviceStatus = NULL; + common.upperDispatchTable = NULL; + common.lowerDispatchTable = (BYTE*) &lowerTable; + + protChars.length = sizeof (protChars); + protChars.name[0] = 0; + protChars.type = 0; + + lowerTable.backPointer = &common; + lowerTable.requestConfirm = requestConfirmGlue; + lowerTable.transmitConfirm = transmitConfirmGlue; + lowerTable.receiveLookahead = receiveLookaheadGlue; + lowerTable.indicationComplete = indicationCompleteGlue; + lowerTable.receiveChain = receiveChainGlue; + lowerTable.status = statusGlue; + lowerTable.flags = 3; + if (promis) + lowerTable.flags |= 4; /* promiscous mode (receive everything) */ + + bindings.numBindings = 1; + strcpy (bindings.moduleName[0], handle->moduleName); + + /* Register ourselves with NDIS + */ + reqBlock.opcode = PM_REGISTER_MODULE; + reqBlock.pointer1 = (BYTE FAR*) &common; + reqBlock.pointer2 = (BYTE FAR*) &bindings; + + result = (*protManEntry) (&reqBlock, protManDS); + if (result) + { + printf ("Protman registering failed: %s\n", Ndis_strerror(result)); + return (0); + } + + /* Start the binding process + */ + reqBlock.opcode = PM_BIND_AND_START; + reqBlock.pointer1 = (BYTE FAR*) &failingModules; + + result = (*protManEntry) (&reqBlock, protManDS); + if (result) + { + printf ("Start binding failed: %s\n", Ndis_strerror(result)); + return (0); + } + return (1); +} + +static int CheckMacFeatures (CardHandle *card) +{ + DWORD serviceFlags; + BYTE _far *mediaString; + BYTE _far *mac_addr; + + DEBUG2 ("checking card features\n" + "common table address = %08lX, macId = %d\n", + card->common, card->common->moduleId); + + serviceFlags = MAC_CHAR (handle)->serviceFlags; + + if ((serviceFlags & SF_PROMISCUOUS) == 0) + { + printf ("The MAC %s does not support promiscuous mode.\n", + card->moduleName); + return (0); + } + + mediaString = MAC_CHAR (handle)->macName; + + DEBUG1 ("media type = %s\n",mediaString); + + /* Get the media type. And set the header size + */ + if (!strncmp(mediaString,"802.3",5) || + !strncmp(mediaString,"DIX",3) || + !strncmp(mediaString,"DIX+802.3",9)) + headerSize = sizeof (EthernetIIHeader); + + else if (!strncmp(mediaString,"FDDI",4)) + headerSize = sizeof (FddiHeader) + + sizeof (Ieee802Dot2SnapHeader); + else + { + printf ("Unsupported MAC type: `%s'\n", mediaString); + return (0); + } + + frameSize = MAC_CHAR (handle)->maxFrameSize; + mac_addr = MAC_CHAR (handle)->currentAddress; + + printf ("Hardware address: %02X:%02X:%02X:%02X:%02X:%02X\n", + mac_addr[0], mac_addr[1], mac_addr[2], + mac_addr[3], mac_addr[4], mac_addr[5]); + return (1); +} + +static int NdisStartMac (CardHandle *card) +{ + WORD result; + + /* Set the lookahead length + */ + result = MAC_DISPATCH(handle)->request (common.moduleId, 0, + headerSize, 0, + REQ_SET_LOOKAHEAD, + card->common->moduleDS); + + /* We assume that if we got INVALID PARAMETER then either this + * is not supported or will work anyway. NE2000 does this. + */ + if (result != ERR_SUCCESS && result != ERR_INVALID_PARAMETER) + { + DEBUG1 ("Set lookahead failed: %s\n", Ndis_strerror(result)); + return (0); + } + + /* Set the packet filter. Note that for some medias and drivers we + * must specify all three flags or the card(s) will not operate correctly. + */ + result = MAC_DISPATCH(handle)->request (common.moduleId, 0, + /* all packets */ FILTER_PROMISCUOUS | + /* packets to us */ FILTER_DIRECTED | + /* broadcasts */ FILTER_BROADCAST, + 0, REQ_SET_PACKET_FILTER, + card->common->moduleDS); + if (result != ERR_SUCCESS) + { + DEBUG1 ("Set packet filter failed: %s\n", Ndis_strerror(result)); + return (0); + } + + /* If OPEN/CLOSE supported then open the adapter + */ + if (MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE) + { + result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, NULL, + REQ_OPEN_ADAPTER, + card->common->moduleDS); + if (result != ERR_SUCCESS) + { + DEBUG1 ("Opening the MAC failed: %s\n", Ndis_strerror(result)); + return (0); + } + } + return (1); +} + +void NdisShutdown (void) +{ + struct _ReqBlock reqBlock; + int result, i; + + if (!handle) + return; + + /* If the adapters support open and are open then close them + */ + if ((MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE) && + (MAC_STATUS(handle)->macStatus & MAC_OPEN)) + { + result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, 0, + REQ_CLOSE_ADAPTER, + handle->common->moduleDS); + if (result != ERR_SUCCESS) + { + printf ("Closing the MAC failed: %s\n", Ndis_strerror(result)); + return; + } + } + + /* Tell the Protocol Manager to unbind and stop + */ + reqBlock.opcode = PM_UNBIND_AND_STOP; + reqBlock.pointer1 = (BYTE FAR*) &failingModules; + reqBlock.pointer2 = NULL; + + result = (*protManEntry) (&reqBlock, protManDS); + if (result) + printf ("Unbind failed: %s\n", Ndis_strerror(result)); + + for (i = 0; i < STACK_POOL_SIZE; ++i) + free (freeStacks[i] - STACK_SIZE); + + handle = NULL; +} + +int NdisInit (int promis) +{ + int i, result; + + /* Allocate the real mode stacks used for NDIS callbacks + */ + for (i = 0; i < STACK_POOL_SIZE; ++i) + { + freeStacks[i] = malloc (STACK_SIZE); + if (!freeStacks[i]) + return (0); + freeStacks[i] += STACK_SIZE; + } + + if (!NdisOpen()) + return (0); + + if (!NdisRegisterAndBind(promis)) + return (0); + + DEBUG1 ("My module id: %d\n", common.moduleId); + DEBUG1 ("Handle id; %d\n", handle->common->moduleId); + DEBUG1 ("MAC card: %-16s - ", handle->moduleName); + + atexit (NdisShutdown); + + if (!CheckMacFeatures(&handle)) + return (0); + + switch (mediaType) + { + case MEDIA_FDDI: + DEBUG0 ("Media type: FDDI"); + break; + case MEDIA_ETHERNET: + DEBUG0 ("Media type: ETHERNET"); + break; + default: + DEBUG0 ("Unsupported media.\n"); + return (0); + } + + DEBUG1 (" - Frame size: %d\n", frameSize); + + if (!NdisStartMac(&handle)) + return (0); + return (1); +} +#endif /* USE_NDIS2 */ + diff --git a/winpcap/wpcap/libpcap/msdos/ndis2.h b/winpcap/wpcap/libpcap/msdos/ndis2.h new file mode 100644 index 0000000..dc72f4c --- /dev/null +++ b/winpcap/wpcap/libpcap/msdos/ndis2.h @@ -0,0 +1,559 @@ +/* + * Copyright (c) 1993,1994 + * Texas A&M University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Texas A&M University + * and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Developers: + * David K. Hess, Douglas Lee Schales, David R. Safford + * + * Heavily modified for Metaware HighC + GNU C 2.8+ + * Gisle Vanem 1998 + */ + +#ifndef __PCAP_NDIS_H +#define __PCAP_NDIS_H + +#if defined (__HIGHC__) + #define pascal _CC(_CALLEE_POPS_STACK & ~_REVERSE_PARMS) /* calling convention */ + #define CALLBACK(foo) pascal WORD foo + #define PAS_PTR(x,arg) typedef FAR WORD pascal (*x) arg + #define GUARD() _inline (0x9C,0xFA) /* pushfd, cli */ + #define UNGUARD() _inline (0x9D) /* popfd */ + #define FAR _far + +#elif defined(__GNUC__) + #define CALLBACK(foo) WORD foo __attribute__((stdcall)) + #define PAS_PTR(x,arg) typedef WORD (*x) arg __attribute__((stdcall)) + #define GUARD() __asm__ __volatile__ ("pushfd; cli") + #define UNGUARD() __asm__ __volatile__ ("popfd") + #define FAR + +#elif defined (__TURBOC__) + #define CALLBACK(foo) WORD pascal foo + #define PAS_PTR(x,arg) typedef WORD pascal (_far *x) arg + #define GUARD() _asm { pushf; cli } + #define UNGUARD() _asm { popf } + #define FAR _far + +#elif defined (__WATCOMC__) + #define CALLBACK(foo) WORD pascal foo + #define PAS_PTR(x,arg) typedef WORD pascal (_far *x) arg + #define GUARD() _disable() + #define UNGUARD() _enable() + #define FAR _far + +#else + #error Unsupported compiler +#endif + + +/* + * Forwards + */ +struct _ReqBlock; +struct _TxBufDescr; +struct _TDBufDescr; + +/* + * Protocol Manager API + */ +PAS_PTR (ProtMan, (struct _ReqBlock FAR*, WORD)); + +/* + * System request + */ +PAS_PTR (SystemRequest, (DWORD, DWORD, WORD, WORD, WORD)); + +/* + * MAC API + */ +PAS_PTR (TransmitChain, (WORD, WORD, struct _TxBufDescr FAR*, WORD)); +PAS_PTR (TransferData, (WORD*,WORD, struct _TDBufDescr FAR*, WORD)); +PAS_PTR (Request, (WORD, WORD, WORD, DWORD, WORD, WORD)); +PAS_PTR (ReceiveRelease,(WORD, WORD)); +PAS_PTR (IndicationOn, (WORD)); +PAS_PTR (IndicationOff, (WORD)); + + +typedef enum { + HARDWARE_NOT_INSTALLED = 0, + HARDWARE_FAILED_DIAG = 1, + HARDWARE_FAILED_CONFIG = 2, + HARDWARE_HARD_FAULT = 3, + HARDWARE_SOFT_FAULT = 4, + HARDWARE_OK = 7, + HARDWARE_MASK = 0x0007, + MAC_BOUND = 0x0008, + MAC_OPEN = 0x0010, + DIAG_IN_PROGRESS = 0x0020 + } NdisMacStatus; + +typedef enum { + STATUS_RING_STATUS = 1, + STATUS_ADAPTER_CHECK = 2, + STATUS_START_RESET = 3, + STATUS_INTERRUPT = 4, + STATUS_END_RESET = 5 + } NdisStatus; + +typedef enum { + FILTER_DIRECTED = 1, + FILTER_BROADCAST = 2, + FILTER_PROMISCUOUS = 4, + FILTER_SOURCE_ROUTE = 8 + } NdisPacketFilter; + +typedef enum { + REQ_INITIATE_DIAGNOSTICS = 1, + REQ_READ_ERROR_LOG = 2, + REQ_SET_STATION_ADDRESS = 3, + REQ_OPEN_ADAPTER = 4, + REQ_CLOSE_ADAPTER = 5, + REQ_RESET_MAC = 6, + REQ_SET_PACKET_FILTER = 7, + REQ_ADD_MULTICAST_ADDRESS = 8, + REQ_DELETE_MULTICAST_ADDRESS = 9, + REQ_UPDATE_STATISTICS = 10, + REQ_CLEAR_STATISTICS = 11, + REQ_INTERRUPT_REQUEST = 12, + REQ_SET_FUNCTIONAL_ADDRESS = 13, + REQ_SET_LOOKAHEAD = 14 + } NdisGeneralRequest; + +typedef enum { + SF_BROADCAST = 0x00000001L, + SF_MULTICAST = 0x00000002L, + SF_FUNCTIONAL = 0x00000004L, + SF_PROMISCUOUS = 0x00000008L, + SF_SOFT_ADDRESS = 0x00000010L, + SF_STATS_CURRENT = 0x00000020L, + SF_INITIATE_DIAGS = 0x00000040L, + SF_LOOPBACK = 0x00000080L, + SF_RECEIVE_CHAIN = 0x00000100L, + SF_SOURCE_ROUTING = 0x00000200L, + SF_RESET_MAC = 0x00000400L, + SF_OPEN_CLOSE = 0x00000800L, + SF_INTERRUPT_REQUEST = 0x00001000L, + SF_SOURCE_ROUTING_BRIDGE = 0x00002000L, + SF_VIRTUAL_ADDRESSES = 0x00004000L + } NdisMacServiceFlags; + +typedef enum { + REQ_INITIATE_BIND = 1, + REQ_BIND = 2, + REQ_INITIATE_PREBIND = 3, + REQ_INITIATE_UNBIND = 4, + REQ_UNBIND = 5 + } NdisSysRequest; + +typedef enum { + PM_GET_PROTOCOL_MANAGER_INFO = 1, + PM_REGISTER_MODULE = 2, + PM_BIND_AND_START = 3, + PM_GET_PROTOCOL_MANAGER_LINKAGE = 4, + PM_GET_PROTOCOL_INI_PATH = 5, + PM_REGISTER_PROTOCOL_MANAGER_INFO = 6, + PM_INIT_AND_REGISTER = 7, + PM_UNBIND_AND_STOP = 8, + PM_BIND_STATUS = 9, + PM_REGISTER_STATUS = 10 + } NdisProtManager; + + +typedef enum { + ERR_SUCCESS = 0x00, + ERR_WAIT_FOR_RELEASE = 0x01, + ERR_REQUEST_QUEUED = 0x02, + ERR_FRAME_NOT_RECOGNIZED = 0x03, + ERR_FRAME_REJECTED = 0x04, + ERR_FORWARD_FRAME = 0x05, + ERR_OUT_OF_RESOURCE = 0x06, + ERR_INVALID_PARAMETER = 0x07, + ERR_INVALID_FUNCTION = 0x08, + ERR_NOT_SUPPORTED = 0x09, + ERR_HARDWARE_ERROR = 0x0A, + ERR_TRANSMIT_ERROR = 0x0B, + ERR_NO_SUCH_DESTINATION = 0x0C, + ERR_BUFFER_TOO_SMALL = 0x0D, + ERR_ALREADY_STARTED = 0x20, + ERR_INCOMPLETE_BINDING = 0x21, + ERR_DRIVER_NOT_INITIALIZED = 0x22, + ERR_HARDWARE_NOT_FOUND = 0x23, + ERR_HARDWARE_FAILURE = 0x24, + ERR_CONFIGURATION_FAILURE = 0x25, + ERR_INTERRUPT_CONFLICT = 0x26, + ERR_INCOMPATIBLE_MAC = 0x27, + ERR_INITIALIZATION_FAILED = 0x28, + ERR_NO_BINDING = 0x29, + ERR_NETWORK_MAY_NOT_BE_CONNECTED = 0x2A, + ERR_INCOMPATIBLE_OS_VERSION = 0x2B, + ERR_ALREADY_REGISTERED = 0x2C, + ERR_PATH_NOT_FOUND = 0x2D, + ERR_INSUFFICIENT_MEMORY = 0x2E, + ERR_INFO_NOT_FOUND = 0x2F, + ERR_GENERAL_FAILURE = 0xFF + } NdisError; + +#define NDIS_PARAM_INTEGER 0 +#define NDIS_PARAM_STRING 1 + +#define NDIS_TX_BUF_LENGTH 8 +#define NDIS_TD_BUF_LENGTH 1 +#define NDIS_RX_BUF_LENGTH 8 + +#define NDIS_PTR_PHYSICAL 0 +#define NDIS_PTR_VIRTUAL 2 + +#define NDIS_PATH "PROTMAN$" + + +typedef struct _CommonChars { + WORD tableSize; + BYTE majorNdisVersion; /* 2 - Latest version */ + BYTE minorNdisVersion; /* 0 */ + WORD reserved1; + BYTE majorModuleVersion; + BYTE minorModuleVersion; + DWORD moduleFlags; + /* 0 - Binding at upper boundary supported + * 1 - Binding at lower boundary supported + * 2 - Dynamically bound. + * 3-31 - Reserved, must be zero. + */ + BYTE moduleName[16]; + BYTE protocolLevelUpper; + /* 1 - MAC + * 2 - Data Link + * 3 - Network + * 4 - Transport + * 5 - Session + * -1 - Not specified + */ + BYTE interfaceUpper; + BYTE protocolLevelLower; + /* 0 - Physical + * 1 - MAC + * 2 - Data Link + * 3 - Network + * 4 - Transport + * 5 - Session + * -1 - Not specified + */ + BYTE interfaceLower; + WORD moduleId; + WORD moduleDS; + SystemRequest systemRequest; + BYTE *serviceChars; + BYTE *serviceStatus; + BYTE *upperDispatchTable; + BYTE *lowerDispatchTable; + BYTE *reserved2; /* Must be NULL */ + BYTE *reserved3; /* Must be NULL */ + } CommonChars; + + +typedef struct _MulticastList { + WORD maxMulticastAddresses; + WORD numberMulticastAddresses; + BYTE multicastAddress[16][16]; + } MulticastList; + + +typedef struct _MacChars { + WORD tableSize; + BYTE macName[16]; + WORD addressLength; + BYTE permanentAddress[16]; + BYTE currentAddress[16]; + DWORD currentFunctionalAddress; + MulticastList *multicastList; + DWORD linkSpeed; + DWORD serviceFlags; + WORD maxFrameSize; + DWORD txBufferSize; + WORD txBufferAllocSize; + DWORD rxBufferSize; + WORD rxBufferAllocSize; + BYTE ieeeVendor[3]; + BYTE vendorAdapter; + BYTE *vendorAdapterDescription; + WORD interruptLevel; + WORD txQueueDepth; + WORD maxDataBlocks; + } MacChars; + + +typedef struct _ProtocolChars { + WORD length; + BYTE name[16]; + WORD type; + } ProtocolChars; + + +typedef struct _MacUpperDispatch { + CommonChars *backPointer; + Request request; + TransmitChain transmitChain; + TransferData transferData; + ReceiveRelease receiveRelease; + IndicationOn indicationOn; + IndicationOff indicationOff; + } MacUpperDispatch; + + +typedef struct _MacStatusTable { + WORD tableSize; + DWORD lastDiag; + DWORD macStatus; + WORD packetFilter; + BYTE *mediaSpecificStats; + DWORD lastClear; + DWORD totalFramesRx; + DWORD totalFramesCrc; + DWORD totalBytesRx; + DWORD totalDiscardBufSpaceRx; + DWORD totalMulticastRx; + DWORD totalBroadcastRx; + DWORD obsolete1[5]; + DWORD totalDiscardHwErrorRx; + DWORD totalFramesTx; + DWORD totalBytesTx; + DWORD totalMulticastTx; + DWORD totalBroadcastTx; + DWORD obsolete2[2]; + DWORD totalDiscardTimeoutTx; + DWORD totalDiscardHwErrorTx; + } MacStatusTable; + + +typedef struct _ProtDispatch { + CommonChars *backPointer; + DWORD flags; + /* 0 - handles non-LLC frames + * 1 - handles specific-LSAP LLC frames + * 2 - handles specific-LSAP LLC frames + * 3-31 - reserved must be 0 + */ + void (*requestConfirm) (void); + void (*transmitConfirm) (void); + void (*receiveLookahead) (void); + void (*indicationComplete) (void); + void (*receiveChain) (void); + void (*status) (void); + } ProtDispatch; + + +typedef struct _ReqBlock { + WORD opcode; + WORD status; + BYTE FAR *pointer1; + BYTE FAR *pointer2; + WORD word1; + } ReqBlock; + + +typedef struct _TxBufDescrRec { + BYTE txPtrType; + BYTE dummy; + WORD txDataLen; + BYTE *txDataPtr; + } TxBufDescrRec; + + +typedef struct _TxBufDescr { + WORD txImmedLen; + BYTE *txImmedPtr; + WORD txDataCount; + TxBufDescrRec txBufDescrRec[NDIS_TX_BUF_LENGTH]; + } TxBufDescr; + + +typedef struct _TDBufDescrRec { + BYTE tDPtrType; + BYTE dummy; + WORD tDDataLen; + BYTE *tDDataPtr; + } TDBufDescrRec; + + +typedef struct _TDBufDescr { + WORD tDDataCount; + TDBufDescrRec tDBufDescrRec[NDIS_TD_BUF_LENGTH]; + } TDBufDescr; + + +typedef struct _RxBufDescrRec { + WORD rxDataLen; + BYTE *rxDataPtr; + } RxBufDescrRec; + + +typedef struct _RxBufDescr { + WORD rxDataCount; + RxBufDescrRec rxBufDescrRec[NDIS_RX_BUF_LENGTH]; + } RxBufDescr; + + +typedef struct _PktBuf { + struct _PktBuf *nextLink; + struct _PktBuf *prevLink; + int handle; + int length; + int packetLength; + DWORD sequence; + BYTE *buffer; + } PktBuf; + + +typedef struct _CardHandle { + BYTE moduleName[16]; + CommonChars *common; + } CardHandle; + + +typedef struct _BindingsList { + WORD numBindings; + BYTE moduleName[2][16]; + } BindingsList; + + +typedef struct _FailingModules { + BYTE upperModuleName[16]; + BYTE lowerModuleName[16]; + } FailingModules; + + +typedef union _HardwareAddress { + BYTE bytes[6]; + WORD words[3]; + struct { + BYTE bytes[6]; + } addr; + } HardwareAddress; + + +typedef struct _FddiHeader { + BYTE frameControl; + HardwareAddress etherDestHost; + HardwareAddress etherSrcHost; + } FddiHeader; + + +typedef struct _EthernetIIHeader { + HardwareAddress etherDestHost; + HardwareAddress etherSrcHost; + WORD etherType; + } EthernetIIHeader; + + +typedef struct _Ieee802Dot5Header { + HardwareAddress etherDestHost; + HardwareAddress etherSrcHost; + BYTE routeInfo[30]; + } Ieee802Dot5Header; + + +typedef struct _Ieee802Dot2SnapHeader { + BYTE dsap; /* 0xAA */ + BYTE ssap; /* 0xAA */ + BYTE control; /* 3 */ + BYTE protocolId[5]; + } Ieee802Dot2SnapHeader; + + +/* + * Prototypes + */ +extern char *NdisLastError (void); +extern int NdisOpen (void); +extern int NdisInit (int promis); +extern int NdisRegisterAndBind (int promis); +extern void NdisShutdown (void); +extern void NdisCheckMacFeatures (struct _CardHandle *card); +extern int NdisSendPacket (struct _PktBuf *pktBuf, int macId); + +/* + * Assembly "glue" functions + */ +extern int systemRequestGlue(); +extern int requestConfirmGlue(); +extern int transmitConfirmGlue(); +extern int receiveLookaheadGlue(); +extern int indicationCompleteGlue(); +extern int receiveChainGlue(); +extern int statusGlue(); + +/* + * IOCTL function + */ +#ifdef __SMALL__ +extern int _far NdisGetLinkage (int handle, char *data, int size); +#else +extern int NdisGetLinkage (int handle, char *data, int size); +#endif + +/* + * NDIS callback handlers + */ +CALLBACK (NdisSystemRequest (DWORD,DWORD, WORD, WORD, WORD)); +CALLBACK (NdisRequestConfirm ( WORD, WORD, WORD, WORD, WORD,WORD)); +CALLBACK (NdisTransmitConfirm ( WORD, WORD, WORD, WORD, WORD)); +CALLBACK (NdisReceiveLookahead ( WORD, WORD, WORD, BYTE*, BYTE*, WORD)); +CALLBACK (NdisReceiveChain ( WORD, WORD, WORD, struct _RxBufDescr*, BYTE*, WORD)); +CALLBACK (NdisStatusProc ( WORD, WORD, BYTE*, WORD,WORD)); +CALLBACK (NdisIndicationComplete( WORD, WORD)); + +BYTE *NdisAllocStack (void); +void NdisFreeStack (BYTE*); + +#ifdef __HIGHC__ + #define RENAME_ASM_SYM(x) pragma Alias(x,"@" #x "") /* prepend `@' */ + #define RENAME_C_SYM(x) pragma Alias(x,"_" #x "") /* prepend `_' */ + + RENAME_ASM_SYM (systemRequestGlue); + RENAME_ASM_SYM (requestConfirmGlue); + RENAME_ASM_SYM (transmitConfirmGlue); + RENAME_ASM_SYM (receiveLookaheadGlue); + RENAME_ASM_SYM (indicationCompleteGlue); + RENAME_ASM_SYM (receiveChainGlue); + RENAME_ASM_SYM (statusGlue); + RENAME_ASM_SYM (NdisGetLinkage); + RENAME_C_SYM (NdisSystemRequest); + RENAME_C_SYM (NdisRequestConfirm); + RENAME_C_SYM (NdisTransmitConfirm); + RENAME_C_SYM (NdisReceiveLookahead); + RENAME_C_SYM (NdisIndicationComplete); + RENAME_C_SYM (NdisReceiveChain); + RENAME_C_SYM (NdisStatusProc); + RENAME_C_SYM (NdisAllocStack); + RENAME_C_SYM (NdisFreeStack); +#endif + +#endif diff --git a/winpcap/wpcap/libpcap/msdos/ndis_0.asm b/winpcap/wpcap/libpcap/msdos/ndis_0.asm new file mode 100644 index 0000000..2990985 --- /dev/null +++ b/winpcap/wpcap/libpcap/msdos/ndis_0.asm @@ -0,0 +1,188 @@ +PAGE 60,132 +NAME NDIS_0 + +ifdef DOSX + .386 + _TEXT SEGMENT PUBLIC DWORD USE16 'CODE' + _TEXT ENDS + _DATA SEGMENT PUBLIC DWORD USE16 'CODE' + _DATA ENDS + _TEXT32 SEGMENT PUBLIC BYTE USE32 'CODE' + _TEXT32 ENDS + CB_DSEG EQU ; DOSX is tiny-model + D_SEG EQU <_TEXT SEGMENT> + D_END EQU <_TEXT ENDS> + ASSUME CS:_TEXT,DS:_TEXT + + PUSHREGS equ + POPREGS equ + + PUBPROC macro name + align 4 + public @&name + @&name label near + endm +else + .286 + _TEXT SEGMENT PUBLIC DWORD 'CODE' + _TEXT ENDS + _DATA SEGMENT PUBLIC DWORD 'DATA' + _DATA ENDS + CB_DSEG EQU ; 16bit is small/large model + D_SEG EQU <_DATA SEGMENT> + D_END EQU <_DATA ENDS> + ASSUME CS:_TEXT,DS:_DATA + + PUSHREGS equ + POPREGS equ + + PUBPROC macro name + public _&name + _&name label far + endm +endif + +;------------------------------------------- + +D_SEG + +D_END + + +_TEXT SEGMENT + +EXTRN _NdisSystemRequest : near +EXTRN _NdisRequestConfirm : near +EXTRN _NdisTransmitConfirm : near +EXTRN _NdisReceiveLookahead : near +EXTRN _NdisIndicationComplete : near +EXTRN _NdisReceiveChain : near +EXTRN _NdisStatusProc : near +EXTRN _NdisAllocStack : near +EXTRN _NdisFreeStack : near + +; +; *ALL* interrupt threads come through this macro. +; +CALLBACK macro callbackProc, argsSize + + pushf + PUSHREGS ;; Save the registers + + push es + push ds + mov ax,CB_DSEG ;; Load DS + mov ds,ax + call _NdisAllocStack ;; Get and install a stack. + + mov bx,ss ;; Save off the old stack in other regs + mov cx,sp + mov ss,dx ;; Install the new one + mov sp,ax + push bx ;; Save the old one on to the new stack + push cx + sub sp,&argsSize ;; Allocate space for arguments on the stack + + mov ax,ss ;; Set up the destination for the move + mov es,ax + mov di,sp + mov ds,bx ;; Set up the source for the move. + mov si,cx + add si,4+6+32 + + mov cx,&argsSize ;; Move the arguments to the stack. + shr cx,1 + cld + rep movsw + + mov ax,CB_DSEG ;; Set my data segment again. + mov ds,ax + + call &callbackProc ;; Call the real callback. + pop di ;; Pop off the old stack + pop si + mov bx,ss ;; Save off the current allocated stack. + mov cx,sp + mov ss,si ;; Restore the old stack + mov sp,di + push ax ;; Save the return code + push bx ;; Free the stack. Push the pointer to it + push cx + call _NdisFreeStack + add sp,4 + pop ax ;; Get the return code back + add di,32 ;; Get a pointer to ax on the stack + mov word ptr ss:[di],ax + pop ds + pop es + + POPREGS + popf +endm + +; +; Define all of the callbacks for the NDIS procs. +; + +PUBPROC systemRequestGlue +CALLBACK _NdisSystemRequest,14 +RETF + +PUBPROC requestConfirmGlue +CALLBACK _NdisRequestConfirm,12 +RETF + +PUBPROC transmitConfirmGlue +CALLBACK _NdisTransmitConfirm,10 +RETF + +PUBPROC receiveLookaheadGlue +CALLBACK _NdisReceiveLookahead,16 +RETF + +PUBPROC indicationCompleteGlue +CALLBACK _NdisIndicationComplete,4 +RETF + +PUBPROC receiveChainGlue +CALLBACK _NdisReceiveChain,16 +RETF + +PUBPROC statusGlue +CALLBACK _NdisStatusProc,12 +RETF + +; +; int FAR NdisGetLinkage (int handle, char *data, int size); +; + +ifdef DOSX + PUBPROC NdisGetLinkage + push ebx + mov ebx, [esp+8] ; device handle + mov eax, 4402h ; IOCTRL read function + mov edx, [esp+12] ; DS:EDX -> result data + mov ecx, [esp+16] ; ECX = length + int 21h + pop ebx + jc @fail + xor eax, eax + @fail: ret + +else + PUBPROC NdisGetLinkage + enter 0, 0 + mov bx, [bp+6] + mov ax, 4402h + mov dx, [bp+8] + mov cx, [bp+12] + int 21h + jc @fail + xor ax, ax + @fail: leave + retf +endif + +ENDS + +END diff --git a/winpcap/wpcap/libpcap/msdos/pkt_rx0.asm b/winpcap/wpcap/libpcap/msdos/pkt_rx0.asm new file mode 100644 index 0000000..94f3d09 --- /dev/null +++ b/winpcap/wpcap/libpcap/msdos/pkt_rx0.asm @@ -0,0 +1,197 @@ +PAGE 60,132 +NAME PKT_RX + +ifdef ??version ; using TASM + masm + jumps +endif + +PUBLIC _pktDrop, _pktRxBuf, _pktTxBuf, _pktTemp +PUBLIC _rxOutOfs, _rxInOfs, _PktReceiver, _pktRxEnd + +; +; these sizes MUST be equal to the sizes in PKTDRVR.H +; + +RX_BUF_SIZE = 1500 ; max message size on Ethernet +TX_BUF_SIZE = 1500 + +ifdef DOSX + .386 + NUM_RX_BUF = 32 ; # of RX element buffers + _TEXT SEGMENT PUBLIC DWORD USE16 'CODE' + _TEXT ENDS + _DATA SEGMENT PUBLIC DWORD USE16 'CODE' + _DATA ENDS + D_SEG EQU <_TEXT SEGMENT> + D_END EQU <_TEXT ENDS> + ASSUME CS:_TEXT,DS:_TEXT +else + .286 + NUM_RX_BUF = 10 + _TEXT SEGMENT PUBLIC DWORD 'CODE' + _TEXT ENDS + _DATA SEGMENT PUBLIC DWORD 'DATA' + _DATA ENDS + D_SEG EQU <_DATA SEGMENT> + D_END EQU <_DATA ENDS> + ASSUME CS:_TEXT,DS:_DATA +endif + +;------------------------------------------- + +D_SEG + +RX_ELEMENT STRUC + firstCount dw 0 ; # of bytes on 1st call + secondCount dw 0 ; # of bytes on 2nd call + handle dw 0 ; handle for upcall + destinAdr db 6 dup (0) ; packet destination address + sourceAdr db 6 dup (0) ; packet source address + protocol dw 0 ; packet protocol number + rxBuffer db RX_BUF_SIZE dup (0) ; RX buffer +ENDS + align 4 +_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets +_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf +_pktDrop dw 0,0 ; packet drop counter +_pktTemp db 20 dup (0) ; temp work area +_pktTxBuf db (TX_BUF_SIZE+14) dup (0) ; TX buffer +_pktRxBuf RX_ELEMENT NUM_RX_BUF dup (<>) ; RX structures + LAST_OFS = offset $ + + screenSeg dw 0B800h + newInOffset dw 0 + + fanChars db '-\|/' + fanIndex dw 0 + +D_END + +_TEXT SEGMENT + + +SHOW_RX MACRO + push es + push bx + mov bx, screenSeg + mov es, bx ;; r-mode segment of colour screen + mov di, 158 ;; upper right corner - 1 + mov bx, fanIndex + mov al, fanChars[bx] ;; get write char + mov ah, 15 ;; and white colour + stosw ;; write to screen at ES:EDI + inc fanIndex ;; update next index + and fanIndex, 3 + pop bx + pop es +ENDM + +;------------------------------------------------------------------------ +; +; This macro return ES:DI to tail of Rx queue + +ENQUEUE MACRO + LOCAL @noWrap + mov ax, _rxInOfs ;; DI = current in-offset + add ax, SIZE RX_ELEMENT ;; point to next _pktRxBuf buffer + cmp ax, LAST_OFS ;; pointing past last ? + jb @noWrap ;; no - jump + lea ax, _pktRxBuf ;; yes, point to 1st buffer + align 4 +@noWrap: cmp ax, _rxOutOfs ;; in-ofs = out-ofs ? + je @dump ;; yes, queue is full + mov di, _rxInOfs ;; ES:DI -> buffer at queue input + mov newInOffset, ax ;; remember new input offset + + ;; NOTE. rxInOfs is updated after the packet has been copied + ;; to ES:DI (= DS:SI on 2nd call) by the packet driver + +ENDM + +;------------------------------------------------------------------------ +; +; This routine gets called by the packet driver twice: +; 1st time (AX=0) it requests an address where to put the packet +; +; 2nd time (AX=1) the packet has been copied to this location (DS:SI) +; BX has client handle (stored in RX_ELEMENT.handle). +; CX has # of bytes in packet on both call. They should be equal. +; +; A test for equality is done by putting CX in _pktRxBuf [n].firstCount +; and _pktRxBuf[n].secondCount, and CL on first call in +; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive" +; (PKTDRVR.C) +; +;--------------------------------------------------------------------- + +_PktReceiver: + pushf + cli ; no distraction wanted ! + push ds + push bx +ifdef DOSX + mov bx, cs +else + mov bx, SEG _DATA +endif + mov ds, bx + mov es, bx ; ES = DS = CS or seg _DATA + pop bx ; restore handle + + cmp ax, 0 ; first call? (AX=0) + jne @post ; AX=1: second call, do post process + +ifdef DEBUG + SHOW_RX ; show that a packet is received +endif + cmp cx, RX_BUF_SIZE+14 ; size OK ? + ja @skip ; no, packet to large for us + + ENQUEUE ; ES:DI -> _pktRxBuf[n] + + mov [di].firstCount, cx ; remember the first count. + mov [di].handle, bx ; remember the handle. + add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr + pop ds + popf + retf ; far return to driver with ES:DI + + align 4 +@dump: inc _pktDrop[0] ; discard the packet on 1st call + adc _pktDrop[2], 0 ; increment packets lost + +@skip: xor di, di ; return ES:DI = NIL pointer + xor ax, ax + mov es, ax + pop ds + popf + retf + + align 4 +@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr + jz @discard ; make sure we don't use NULL-pointer + + sub si, 6 ; DS:SI -> _pktRxBuf[n].destinAdr + ; + ; push si + ; push [si].firstCount + ; call bpf_filter_match ; run the filter here some day? + ; add sp, 4 + ; cmp ax, 0 + ; je @discard + + mov [si].secondCount, cx + mov ax, newInOffset + mov _rxInOfs, ax ; update _pktRxBuf input offset + + align 4 +@discard:pop ds + popf + retf + +_pktRxEnd db 0 ; marker for end of r-mode code/data + +_TEXT ENDS + +END diff --git a/winpcap/wpcap/libpcap/msdos/pkt_rx1.s b/winpcap/wpcap/libpcap/msdos/pkt_rx1.s new file mode 100644 index 0000000..b294a36 --- /dev/null +++ b/winpcap/wpcap/libpcap/msdos/pkt_rx1.s @@ -0,0 +1,155 @@ +; +; This file requires NASM 0.97+ to assemble +; +; Currently used only for djgpp + DOS4GW targets +; +; these sizes MUST be equal to the sizes in PKTDRVR.H +; +%define ETH_MTU 1500 ; max data size on Ethernet +%define ETH_MIN 60 ; min/max total frame size +%define ETH_MAX (ETH_MTU+2*6+2) +%define NUM_RX_BUF 32 ; # of RX element buffers +%define RX_SIZE (ETH_MAX+6) ; sizeof(RX_ELEMENT) = 1514+6 +%idefine offset + +struc RX_ELEMENT + .firstCount resw 1 ; # of bytes on 1st call + .secondCount resw 1 ; # of bytes on 2nd call + .handle resw 1 ; handle for upcall + ; .timeStamp resw 4 ; 64-bit RDTSC value + .destinAdr resb 6 ; packet destination address + .sourceAdr resb 6 ; packet source address + .protocol resw 1 ; packet protocol number + .rxBuffer resb ETH_MTU ; RX buffer +endstruc + +;------------------------------------------- + +[org 0] ; assemble to .bin file + +_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets +_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf +_pktDrop dw 0,0 ; packet drop counter +_pktTemp resb 20 ; temp work area +_pktTxBuf resb (ETH_MAX) ; TX buffer +_pktRxBuf resb (RX_SIZE*NUM_RX_BUF) ; RX structures + LAST_OFS equ $ + +screenSeg dw 0B800h +newInOffset dw 0 + +fanChars db '-\|/' +fanIndex dw 0 + +%macro SHOW_RX 0 + push es + push bx + mov bx, [screenSeg] + mov es, bx ;; r-mode segment of colour screen + mov di, 158 ;; upper right corner - 1 + mov bx, [fanIndex] + mov al, [fanChars+bx] ;; get write char + mov ah, 15 ;; and white colour + cld ;; Needed? + stosw ;; write to screen at ES:EDI + inc word [fanIndex] ;; update next index + and word [fanIndex], 3 + pop bx + pop es +%endmacro + +;PutTimeStamp +; rdtsc +; mov [si].timeStamp, eax +; mov [si+4].timeStamp, edx +; ret + + +;------------------------------------------------------------------------ +; +; This routine gets called by the packet driver twice: +; 1st time (AX=0) it requests an address where to put the packet +; +; 2nd time (AX=1) the packet has been copied to this location (DS:SI) +; BX has client handle (stored in RX_ELEMENT.handle). +; CX has # of bytes in packet on both call. They should be equal. +; A test for equality is done by putting CX in _pktRxBuf [n].firstCount +; and _pktRxBuf[n].secondCount, and CL on first call in +; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive" +; (PKTDRVR.C) +; +;--------------------------------------------------------------------- + +_PktReceiver: + pushf + cli ; no distraction wanted ! + push ds + push bx + mov bx, cs + mov ds, bx + mov es, bx ; ES = DS = CS or seg _DATA + pop bx ; restore handle + + cmp ax, 0 ; first call? (AX=0) + jne @post ; AX=1: second call, do post process + +%ifdef DEBUG + SHOW_RX ; show that a packet is received +%endif + + cmp cx, ETH_MAX ; size OK ? + ja @skip ; no, too big + + mov ax, [_rxInOfs] + add ax, RX_SIZE + cmp ax, LAST_OFS + jb @noWrap + mov ax, offset _pktRxBuf +@noWrap: + cmp ax, [_rxOutOfs] + je @dump + mov di, [_rxInOfs] ; ES:DI -> _pktRxBuf[n] + mov [newInOffset], ax + + mov [di], cx ; remember firstCount. + mov [di+4], bx ; remember handle. + add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr + pop ds + popf + retf ; far return to driver with ES:DI + +@dump: add word [_pktDrop+0], 1 ; discard the packet on 1st call + adc word [_pktDrop+2], 0 ; increment packets lost + +@skip: xor di, di ; return ES:DI = NIL pointer + xor ax, ax + mov es, ax + pop ds + popf + retf + +@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr + jz @discard ; make sure we don't use NULL-pointer + + ; + ; push si + ; call bpf_filter_match ; run the filter here some day + ; pop si + ; cmp ax, 0 + ; je @discard + + mov [si-6+2], cx ; store _pktRxBuf[n].secondCount + mov ax, [newInOffset] + mov [_rxInOfs], ax ; update _pktRxBuf input offset + + ; call PutTimeStamp + +@discard: + pop ds + popf + retf + +_pktRxEnd db 0 ; marker for end of r-mode code/data + +END + diff --git a/winpcap/wpcap/libpcap/msdos/pktdrvr.c b/winpcap/wpcap/libpcap/msdos/pktdrvr.c new file mode 100644 index 0000000..204ab90 --- /dev/null +++ b/winpcap/wpcap/libpcap/msdos/pktdrvr.c @@ -0,0 +1,1437 @@ +/* + * File.........: pktdrvr.c + * + * Responsible..: Gisle Vanem, giva@bgnett.no + * + * Created......: 26.Sept 1995 + * + * Description..: Packet-driver interface for 16/32-bit C : + * Borland C/C++ 3.0+ small/large model + * Watcom C/C++ 11+, DOS4GW flat model + * Metaware HighC 3.1+ and PharLap 386|DosX + * GNU C/C++ 2.7+ and djgpp 2.x extender + * + * References...: PC/TCP Packet driver Specification. rev 1.09 + * FTP Software Inc. + * + */ + +#include +#include +#include +#include + +#include "gnuc.h" +#include "pcap-dos.h" +#include "pcap-int.h" +#include "msdos/pktdrvr.h" + +#if (DOSX) +#define NUM_RX_BUF 32 /* # of buffers in Rx FIFO queue */ +#else +#define NUM_RX_BUF 10 +#endif + +#define DIM(x) (sizeof((x)) / sizeof(x[0])) +#define PUTS(s) do { \ + if (!pktInfo.quiet) \ + pktInfo.error ? \ + printf ("%s: %s\n", s, pktInfo.error) : \ + printf ("%s\n", pktInfo.error = s); \ + } while (0) + +#if defined(__HIGHC__) + extern UINT _mwenv; + +#elif defined(__DJGPP__) + #include + #include + #include + #include + #include + +#elif defined(__WATCOMC__) + #include + #include + extern char _Extender; + +#else + extern void far PktReceiver (void); +#endif + + +#if (DOSX & (DJGPP|DOS4GW)) + #include + + struct DPMI_regs { + DWORD r_di; + DWORD r_si; + DWORD r_bp; + DWORD reserved; + DWORD r_bx; + DWORD r_dx; + DWORD r_cx; + DWORD r_ax; + WORD r_flags; + WORD r_es, r_ds, r_fs, r_gs; + WORD r_ip, r_cs, r_sp, r_ss; + }; + + /* Data located in a real-mode segment. This becomes far at runtime + */ + typedef struct { /* must match data/code in pkt_rx1.s */ + WORD _rxOutOfs; + WORD _rxInOfs; + DWORD _pktDrop; + BYTE _pktTemp [20]; + TX_ELEMENT _pktTxBuf[1]; + RX_ELEMENT _pktRxBuf[NUM_RX_BUF]; + WORD _dummy[2]; /* screenSeg,newInOffset */ + BYTE _fanChars[4]; + WORD _fanIndex; + BYTE _PktReceiver[15]; /* starts on a paragraph (16byte) */ + } PktRealStub; + #include + + static BYTE real_stub_array [] = { + #include "pkt_stub.inc" /* generated opcode array */ + }; + + #define rxOutOfs offsetof (PktRealStub,_rxOutOfs) + #define rxInOfs offsetof (PktRealStub,_rxInOfs) + #define PktReceiver offsetof (PktRealStub,_PktReceiver [para_skip]) + #define pktDrop offsetof (PktRealStub,_pktDrop) + #define pktTemp offsetof (PktRealStub,_pktTemp) + #define pktTxBuf offsetof (PktRealStub,_pktTxBuf) + #define FIRST_RX_BUF offsetof (PktRealStub,_pktRxBuf [0]) + #define LAST_RX_BUF offsetof (PktRealStub,_pktRxBuf [NUM_RX_BUF-1]) + +#else + extern WORD rxOutOfs; /* offsets into pktRxBuf FIFO queue */ + extern WORD rxInOfs; + extern DWORD pktDrop; /* # packets dropped in PktReceiver() */ + extern BYTE pktRxEnd; /* marks the end of r-mode code/data */ + + extern RX_ELEMENT pktRxBuf [NUM_RX_BUF]; /* PktDrvr Rx buffers */ + extern TX_ELEMENT pktTxBuf; /* PktDrvr Tx buffer */ + extern char pktTemp[20]; /* PktDrvr temp area */ + + #define FIRST_RX_BUF (WORD) &pktRxBuf [0] + #define LAST_RX_BUF (WORD) &pktRxBuf [NUM_RX_BUF-1] +#endif + + +#ifdef __BORLANDC__ /* Use Borland's inline functions */ + #define memcpy __memcpy__ + #define memcmp __memcmp__ + #define memset __memset__ +#endif + + +#if (DOSX & PHARLAP) + extern void PktReceiver (void); /* in pkt_rx0.asm */ + static int RealCopy (ULONG, ULONG, REALPTR*, FARPTR*, USHORT*); + + #undef FP_SEG + #undef FP_OFF + #define FP_OFF(x) ((WORD)(x)) + #define FP_SEG(x) ((WORD)(realBase >> 16)) + #define DOS_ADDR(s,o) (((DWORD)(s) << 16) + (WORD)(o)) + #define r_ax eax + #define r_bx ebx + #define r_dx edx + #define r_cx ecx + #define r_si esi + #define r_di edi + #define r_ds ds + #define r_es es + LOCAL FARPTR protBase; + LOCAL REALPTR realBase; + LOCAL WORD realSeg; /* DOS para-address of allocated area */ + LOCAL SWI_REGS reg; + + static WORD _far *rxOutOfsFp, *rxInOfsFp; + +#elif (DOSX & DJGPP) + static _go32_dpmi_seginfo rm_mem; + static __dpmi_regs reg; + static DWORD realBase; + static int para_skip = 0; + + #define DOS_ADDR(s,o) (((WORD)(s) << 4) + (o)) + #define r_ax x.ax + #define r_bx x.bx + #define r_dx x.dx + #define r_cx x.cx + #define r_si x.si + #define r_di x.di + #define r_ds x.ds + #define r_es x.es + +#elif (DOSX & DOS4GW) + LOCAL struct DPMI_regs reg; + LOCAL WORD rm_base_seg, rm_base_sel; + LOCAL DWORD realBase; + LOCAL int para_skip = 0; + + LOCAL DWORD dpmi_get_real_vector (int intr); + LOCAL WORD dpmi_real_malloc (int size, WORD *selector); + LOCAL void dpmi_real_free (WORD selector); + #define DOS_ADDR(s,o) (((DWORD)(s) << 4) + (WORD)(o)) + +#else /* real-mode Borland etc. */ + static struct { + WORD r_ax, r_bx, r_cx, r_dx, r_bp; + WORD r_si, r_di, r_ds, r_es, r_flags; + } reg; +#endif + +#ifdef __HIGHC__ + #pragma Alias (pktDrop, "_pktDrop") + #pragma Alias (pktRxBuf, "_pktRxBuf") + #pragma Alias (pktTxBuf, "_pktTxBuf") + #pragma Alias (pktTemp, "_pktTemp") + #pragma Alias (rxOutOfs, "_rxOutOfs") + #pragma Alias (rxInOfs, "_rxInOfs") + #pragma Alias (pktRxEnd, "_pktRxEnd") + #pragma Alias (PktReceiver,"_PktReceiver") +#endif + + +PUBLIC PKT_STAT pktStat; /* statistics for packets */ +PUBLIC PKT_INFO pktInfo; /* packet-driver information */ + +PUBLIC PKT_RX_MODE receiveMode = PDRX_DIRECT; +PUBLIC ETHER myAddress = { 0, 0, 0, 0, 0, 0 }; +PUBLIC ETHER ethBroadcast = { 255,255,255,255,255,255 }; + +LOCAL struct { /* internal statistics */ + DWORD tooSmall; /* size < ETH_MIN */ + DWORD tooLarge; /* size > ETH_MAX */ + DWORD badSync; /* count_1 != count_2 */ + DWORD wrongHandle; /* upcall to wrong handle */ + } intStat; + +/***************************************************************************/ + +PUBLIC const char *PktGetErrorStr (int errNum) +{ + static const char *errStr[] = { + "", + "Invalid handle number", + "No interfaces of specified class found", + "No interfaces of specified type found", + "No interfaces of specified number found", + "Bad packet type specified", + "Interface does not support multicast", + "Packet driver cannot terminate", + "Invalid receiver mode specified", + "Insufficient memory space", + "Type previously accessed, and not released", + "Command out of range, or not implemented", + "Cannot send packet (usually hardware error)", + "Cannot change hardware address ( > 1 handle open)", + "Hardware address has bad length or format", + "Cannot reset interface (more than 1 handle open)", + "Bad Check-sum", + "Bad size", + "Bad sync" , + "Source hit" + }; + + if (errNum < 0 || errNum >= DIM(errStr)) + return ("Unknown driver error."); + return (errStr [errNum]); +} + +/**************************************************************************/ + +PUBLIC const char *PktGetClassName (WORD class) +{ + switch (class) + { + case PD_ETHER: + return ("DIX-Ether"); + case PD_PRONET10: + return ("ProNET-10"); + case PD_IEEE8025: + return ("IEEE 802.5"); + case PD_OMNINET: + return ("OmniNet"); + case PD_APPLETALK: + return ("AppleTalk"); + case PD_SLIP: + return ("SLIP"); + case PD_STARTLAN: + return ("StartLAN"); + case PD_ARCNET: + return ("ArcNet"); + case PD_AX25: + return ("AX.25"); + case PD_KISS: + return ("KISS"); + case PD_IEEE8023_2: + return ("IEEE 802.3 w/802.2 hdr"); + case PD_FDDI8022: + return ("FDDI w/802.2 hdr"); + case PD_X25: + return ("X.25"); + case PD_LANstar: + return ("LANstar"); + case PD_PPP: + return ("PPP"); + default: + return ("unknown"); + } +} + +/**************************************************************************/ + +PUBLIC char const *PktRXmodeStr (PKT_RX_MODE mode) +{ + static const char *modeStr [] = { + "Receiver turned off", + "Receive only directly addressed packets", + "Receive direct & broadcast packets", + "Receive direct,broadcast and limited multicast packets", + "Receive direct,broadcast and all multicast packets", + "Receive all packets (promiscuouos mode)" + }; + + if (mode > DIM(modeStr)) + return ("??"); + return (modeStr [mode-1]); +} + +/**************************************************************************/ + +LOCAL __inline BOOL PktInterrupt (void) +{ + BOOL okay; + +#if (DOSX & PHARLAP) + _dx_real_int ((UINT)pktInfo.intr, ®); + okay = ((reg.flags & 1) == 0); /* OK if carry clear */ + +#elif (DOSX & DJGPP) + __dpmi_int ((int)pktInfo.intr, ®); + okay = ((reg.x.flags & 1) == 0); + +#elif (DOSX & DOS4GW) + union REGS r; + struct SREGS s; + + memset (&r, 0, sizeof(r)); + segread (&s); + r.w.ax = 0x300; + r.x.ebx = pktInfo.intr; + r.w.cx = 0; + s.es = FP_SEG (®); + r.x.edi = FP_OFF (®); + reg.r_flags = 0; + reg.r_ss = reg.r_sp = 0; /* DPMI host provides stack */ + + int386x (0x31, &r, &r, &s); + okay = (!r.w.cflag); + +#else + reg.r_flags = 0; + intr (pktInfo.intr, (struct REGPACK*)®); + okay = ((reg.r_flags & 1) == 0); +#endif + + if (okay) + pktInfo.error = NULL; + else pktInfo.error = PktGetErrorStr (reg.r_dx >> 8); + return (okay); +} + +/**************************************************************************/ + +/* + * Search for packet driver at interrupt 60h through 80h. If ASCIIZ + * string "PKT DRVR" found at offset 3 in the interrupt handler, return + * interrupt number, else return zero in pktInfo.intr + */ +PUBLIC BOOL PktSearchDriver (void) +{ + BYTE intr = 0x20; + BOOL found = FALSE; + + while (!found && intr < 0xFF) + { + static char str[12]; /* 3 + strlen("PKT DRVR") */ + static char pktStr[9] = "PKT DRVR"; /* ASCIIZ string at ofs 3 */ + DWORD rp; /* in interrupt routine */ + +#if (DOSX & PHARLAP) + _dx_rmiv_get (intr, &rp); + ReadRealMem (&str, (REALPTR)rp, sizeof(str)); + +#elif (DOSX & DJGPP) + __dpmi_raddr realAdr; + __dpmi_get_real_mode_interrupt_vector (intr, &realAdr); + rp = (realAdr.segment << 4) + realAdr.offset16; + dosmemget (rp, sizeof(str), &str); + +#elif (DOSX & DOS4GW) + rp = dpmi_get_real_vector (intr); + memcpy (&str, (void*)rp, sizeof(str)); + +#else + _fmemcpy (&str, getvect(intr), sizeof(str)); +#endif + + found = memcmp (&str[3],&pktStr,sizeof(pktStr)) == 0; + intr++; + } + pktInfo.intr = (found ? intr-1 : 0); + return (found); +} + + +/**************************************************************************/ + +static BOOL PktSetAccess (void) +{ + reg.r_ax = 0x0200 + pktInfo.class; + reg.r_bx = 0xFFFF; + reg.r_dx = 0; + reg.r_cx = 0; + +#if (DOSX & PHARLAP) + reg.ds = 0; + reg.esi = 0; + reg.es = RP_SEG (realBase); + reg.edi = (WORD) &PktReceiver; + +#elif (DOSX & DJGPP) + reg.x.ds = 0; + reg.x.si = 0; + reg.x.es = rm_mem.rm_segment; + reg.x.di = PktReceiver; + +#elif (DOSX & DOS4GW) + reg.r_ds = 0; + reg.r_si = 0; + reg.r_es = rm_base_seg; + reg.r_di = PktReceiver; + +#else + reg.r_ds = 0; + reg.r_si = 0; + reg.r_es = FP_SEG (&PktReceiver); + reg.r_di = FP_OFF (&PktReceiver); +#endif + + if (!PktInterrupt()) + return (FALSE); + + pktInfo.handle = reg.r_ax; + return (TRUE); +} + +/**************************************************************************/ + +PUBLIC BOOL PktReleaseHandle (WORD handle) +{ + reg.r_ax = 0x0300; + reg.r_bx = handle; + return PktInterrupt(); +} + +/**************************************************************************/ + +PUBLIC BOOL PktTransmit (const void *eth, int len) +{ + if (len > ETH_MTU) + return (FALSE); + + reg.r_ax = 0x0400; /* Function 4, send pkt */ + reg.r_cx = len; /* total size of frame */ + +#if (DOSX & DJGPP) + dosmemput (eth, len, realBase+pktTxBuf); + reg.x.ds = rm_mem.rm_segment; /* DOS data segment and */ + reg.x.si = pktTxBuf; /* DOS offset to buffer */ + +#elif (DOSX & DOS4GW) + memcpy ((void*)(realBase+pktTxBuf), eth, len); + reg.r_ds = rm_base_seg; + reg.r_si = pktTxBuf; + +#elif (DOSX & PHARLAP) + memcpy (&pktTxBuf, eth, len); + reg.r_ds = FP_SEG (&pktTxBuf); + reg.r_si = FP_OFF (&pktTxBuf); + +#else + reg.r_ds = FP_SEG (eth); + reg.r_si = FP_OFF (eth); +#endif + + return PktInterrupt(); +} + +/**************************************************************************/ + +#if (DOSX & (DJGPP|DOS4GW)) +LOCAL __inline BOOL CheckElement (RX_ELEMENT *rx) +#else +LOCAL __inline BOOL CheckElement (RX_ELEMENT _far *rx) +#endif +{ + WORD count_1, count_2; + + /* + * We got an upcall to the same RMCB with wrong handle. + * This can happen if we failed to release handle at program exit + */ + if (rx->handle != pktInfo.handle) + { + pktInfo.error = "Wrong handle"; + intStat.wrongHandle++; + PktReleaseHandle (rx->handle); + return (FALSE); + } + count_1 = rx->firstCount; + count_2 = rx->secondCount; + + if (count_1 != count_2) + { + pktInfo.error = "Bad sync"; + intStat.badSync++; + return (FALSE); + } + if (count_1 > ETH_MAX) + { + pktInfo.error = "Large esize"; + intStat.tooLarge++; + return (FALSE); + } +#if 0 + if (count_1 < ETH_MIN) + { + pktInfo.error = "Small esize"; + intStat.tooSmall++; + return (FALSE); + } +#endif + return (TRUE); +} + +/**************************************************************************/ + +PUBLIC BOOL PktTerminHandle (WORD handle) +{ + reg.r_ax = 0x0500; + reg.r_bx = handle; + return PktInterrupt(); +} + +/**************************************************************************/ + +PUBLIC BOOL PktResetInterface (WORD handle) +{ + reg.r_ax = 0x0700; + reg.r_bx = handle; + return PktInterrupt(); +} + +/**************************************************************************/ + +PUBLIC BOOL PktSetReceiverMode (PKT_RX_MODE mode) +{ + if (pktInfo.class == PD_SLIP || pktInfo.class == PD_PPP) + return (TRUE); + + reg.r_ax = 0x1400; + reg.r_bx = pktInfo.handle; + reg.r_cx = (WORD)mode; + + if (!PktInterrupt()) + return (FALSE); + + receiveMode = mode; + return (TRUE); +} + +/**************************************************************************/ + +PUBLIC BOOL PktGetReceiverMode (PKT_RX_MODE *mode) +{ + reg.r_ax = 0x1500; + reg.r_bx = pktInfo.handle; + + if (!PktInterrupt()) + return (FALSE); + + *mode = reg.r_ax; + return (TRUE); +} + +/**************************************************************************/ + +static PKT_STAT initialStat; /* statistics at startup */ +static BOOL resetStat = FALSE; /* statistics reset ? */ + +PUBLIC BOOL PktGetStatistics (WORD handle) +{ + reg.r_ax = 0x1800; + reg.r_bx = handle; + + if (!PktInterrupt()) + return (FALSE); + +#if (DOSX & PHARLAP) + ReadRealMem (&pktStat, DOS_ADDR(reg.ds,reg.esi), sizeof(pktStat)); + +#elif (DOSX & DJGPP) + dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktStat), &pktStat); + +#elif (DOSX & DOS4GW) + memcpy (&pktStat, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktStat)); + +#else + _fmemcpy (&pktStat, MK_FP(reg.r_ds,reg.r_si), sizeof(pktStat)); +#endif + + return (TRUE); +} + +/**************************************************************************/ + +PUBLIC BOOL PktSessStatistics (WORD handle) +{ + if (!PktGetStatistics(pktInfo.handle)) + return (FALSE); + + if (resetStat) + { + pktStat.inPackets -= initialStat.inPackets; + pktStat.outPackets -= initialStat.outPackets; + pktStat.inBytes -= initialStat.inBytes; + pktStat.outBytes -= initialStat.outBytes; + pktStat.inErrors -= initialStat.inErrors; + pktStat.outErrors -= initialStat.outErrors; + pktStat.outErrors -= initialStat.outErrors; + pktStat.lost -= initialStat.lost; + } + return (TRUE); +} + +/**************************************************************************/ + +PUBLIC BOOL PktResetStatistics (WORD handle) +{ + if (!PktGetStatistics(pktInfo.handle)) + return (FALSE); + + memcpy (&initialStat, &pktStat, sizeof(initialStat)); + resetStat = TRUE; + return (TRUE); +} + +/**************************************************************************/ + +PUBLIC BOOL PktGetAddress (ETHER *addr) +{ + reg.r_ax = 0x0600; + reg.r_bx = pktInfo.handle; + reg.r_cx = sizeof (*addr); + +#if (DOSX & DJGPP) + reg.x.es = rm_mem.rm_segment; + reg.x.di = pktTemp; +#elif (DOSX & DOS4GW) + reg.r_es = rm_base_seg; + reg.r_di = pktTemp; +#else + reg.r_es = FP_SEG (&pktTemp); + reg.r_di = FP_OFF (&pktTemp); /* ES:DI = address for result */ +#endif + + if (!PktInterrupt()) + return (FALSE); + +#if (DOSX & PHARLAP) + ReadRealMem (addr, realBase + (WORD)&pktTemp, sizeof(*addr)); + +#elif (DOSX & DJGPP) + dosmemget (realBase+pktTemp, sizeof(*addr), addr); + +#elif (DOSX & DOS4GW) + memcpy (addr, (void*)(realBase+pktTemp), sizeof(*addr)); + +#else + memcpy ((void*)addr, &pktTemp, sizeof(*addr)); +#endif + + return (TRUE); +} + +/**************************************************************************/ + +PUBLIC BOOL PktSetAddress (const ETHER *addr) +{ + /* copy addr to real-mode scrath area */ + +#if (DOSX & PHARLAP) + WriteRealMem (realBase + (WORD)&pktTemp, (void*)addr, sizeof(*addr)); + +#elif (DOSX & DJGPP) + dosmemput (addr, sizeof(*addr), realBase+pktTemp); + +#elif (DOSX & DOS4GW) + memcpy ((void*)(realBase+pktTemp), addr, sizeof(*addr)); + +#else + memcpy (&pktTemp, (void*)addr, sizeof(*addr)); +#endif + + reg.r_ax = 0x1900; + reg.r_cx = sizeof (*addr); /* address length */ + +#if (DOSX & DJGPP) + reg.x.es = rm_mem.rm_segment; /* DOS offset to param */ + reg.x.di = pktTemp; /* DOS segment to param */ +#elif (DOSX & DOS4GW) + reg.r_es = rm_base_seg; + reg.r_di = pktTemp; +#else + reg.r_es = FP_SEG (&pktTemp); + reg.r_di = FP_OFF (&pktTemp); +#endif + + return PktInterrupt(); +} + +/**************************************************************************/ + +PUBLIC BOOL PktGetDriverInfo (void) +{ + pktInfo.majVer = 0; + pktInfo.minVer = 0; + memset (&pktInfo.name, 0, sizeof(pktInfo.name)); + reg.r_ax = 0x01FF; + reg.r_bx = 0; + + if (!PktInterrupt()) + return (FALSE); + + pktInfo.number = reg.r_cx & 0xFF; + pktInfo.class = reg.r_cx >> 8; +#if 0 + pktInfo.minVer = reg.r_bx % 10; + pktInfo.majVer = reg.r_bx / 10; +#else + pktInfo.majVer = reg.r_bx; // !! +#endif + pktInfo.funcs = reg.r_ax & 0xFF; + pktInfo.type = reg.r_dx & 0xFF; + +#if (DOSX & PHARLAP) + ReadRealMem (&pktInfo.name, DOS_ADDR(reg.ds,reg.esi), sizeof(pktInfo.name)); + +#elif (DOSX & DJGPP) + dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktInfo.name), &pktInfo.name); + +#elif (DOSX & DOS4GW) + memcpy (&pktInfo.name, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktInfo.name)); + +#else + _fmemcpy (&pktInfo.name, MK_FP(reg.r_ds,reg.r_si), sizeof(pktInfo.name)); +#endif + return (TRUE); +} + +/**************************************************************************/ + +PUBLIC BOOL PktGetDriverParam (void) +{ + reg.r_ax = 0x0A00; + + if (!PktInterrupt()) + return (FALSE); + +#if (DOSX & PHARLAP) + ReadRealMem (&pktInfo.majVer, DOS_ADDR(reg.es,reg.edi), PKT_PARAM_SIZE); + +#elif (DOSX & DJGPP) + dosmemget (DOS_ADDR(reg.x.es,reg.x.di), PKT_PARAM_SIZE, &pktInfo.majVer); + +#elif (DOSX & DOS4GW) + memcpy (&pktInfo.majVer, (void*)DOS_ADDR(reg.r_es,reg.r_di), PKT_PARAM_SIZE); + +#else + _fmemcpy (&pktInfo.majVer, MK_FP(reg.r_es,reg.r_di), PKT_PARAM_SIZE); +#endif + return (TRUE); +} + +/**************************************************************************/ + +#if (DOSX & PHARLAP) + PUBLIC int PktReceive (BYTE *buf, int max) + { + WORD inOfs = *rxInOfsFp; + WORD outOfs = *rxOutOfsFp; + + if (outOfs != inOfs) + { + RX_ELEMENT _far *head = (RX_ELEMENT _far*)(protBase+outOfs); + int size, len = max; + + if (CheckElement(head)) + { + size = min (head->firstCount, sizeof(RX_ELEMENT)); + len = min (size, max); + _fmemcpy (buf, &head->destin, len); + } + else + size = -1; + + outOfs += sizeof (RX_ELEMENT); + if (outOfs > LAST_RX_BUF) + outOfs = FIRST_RX_BUF; + *rxOutOfsFp = outOfs; + return (size); + } + return (0); + } + + PUBLIC void PktQueueBusy (BOOL busy) + { + *rxOutOfsFp = busy ? (*rxInOfsFp + sizeof(RX_ELEMENT)) : *rxInOfsFp; + if (*rxOutOfsFp > LAST_RX_BUF) + *rxOutOfsFp = FIRST_RX_BUF; + *(DWORD _far*)(protBase + (WORD)&pktDrop) = 0; + } + + PUBLIC WORD PktBuffersUsed (void) + { + WORD inOfs = *rxInOfsFp; + WORD outOfs = *rxOutOfsFp; + + if (inOfs >= outOfs) + return (inOfs - outOfs) / sizeof(RX_ELEMENT); + return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT)); + } + + PUBLIC DWORD PktRxDropped (void) + { + return (*(DWORD _far*)(protBase + (WORD)&pktDrop)); + } + +#elif (DOSX & DJGPP) + PUBLIC int PktReceive (BYTE *buf, int max) + { + WORD ofs = _farpeekw (_dos_ds, realBase+rxOutOfs); + + if (ofs != _farpeekw (_dos_ds, realBase+rxInOfs)) + { + RX_ELEMENT head; + int size, len = max; + + head.firstCount = _farpeekw (_dos_ds, realBase+ofs); + head.secondCount = _farpeekw (_dos_ds, realBase+ofs+2); + head.handle = _farpeekw (_dos_ds, realBase+ofs+4); + + if (CheckElement(&head)) + { + size = min (head.firstCount, sizeof(RX_ELEMENT)); + len = min (size, max); + dosmemget (realBase+ofs+6, len, buf); + } + else + size = -1; + + ofs += sizeof (RX_ELEMENT); + if (ofs > LAST_RX_BUF) + _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF); + else _farpokew (_dos_ds, realBase+rxOutOfs, ofs); + return (size); + } + return (0); + } + + PUBLIC void PktQueueBusy (BOOL busy) + { + WORD ofs; + + disable(); + ofs = _farpeekw (_dos_ds, realBase+rxInOfs); + if (busy) + ofs += sizeof (RX_ELEMENT); + + if (ofs > LAST_RX_BUF) + _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF); + else _farpokew (_dos_ds, realBase+rxOutOfs, ofs); + _farpokel (_dos_ds, realBase+pktDrop, 0UL); + enable(); + } + + PUBLIC WORD PktBuffersUsed (void) + { + WORD inOfs, outOfs; + + disable(); + inOfs = _farpeekw (_dos_ds, realBase+rxInOfs); + outOfs = _farpeekw (_dos_ds, realBase+rxOutOfs); + enable(); + if (inOfs >= outOfs) + return (inOfs - outOfs) / sizeof(RX_ELEMENT); + return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT)); + } + + PUBLIC DWORD PktRxDropped (void) + { + return _farpeekl (_dos_ds, realBase+pktDrop); + } + +#elif (DOSX & DOS4GW) + PUBLIC int PktReceive (BYTE *buf, int max) + { + WORD ofs = *(WORD*) (realBase+rxOutOfs); + + if (ofs != *(WORD*) (realBase+rxInOfs)) + { + RX_ELEMENT head; + int size, len = max; + + head.firstCount = *(WORD*) (realBase+ofs); + head.secondCount = *(WORD*) (realBase+ofs+2); + head.handle = *(WORD*) (realBase+ofs+4); + + if (CheckElement(&head)) + { + size = min (head.firstCount, sizeof(RX_ELEMENT)); + len = min (size, max); + memcpy (buf, (const void*)(realBase+ofs+6), len); + } + else + size = -1; + + ofs += sizeof (RX_ELEMENT); + if (ofs > LAST_RX_BUF) + *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF; + else *(WORD*) (realBase+rxOutOfs) = ofs; + return (size); + } + return (0); + } + + PUBLIC void PktQueueBusy (BOOL busy) + { + WORD ofs; + + _disable(); + ofs = *(WORD*) (realBase+rxInOfs); + if (busy) + ofs += sizeof (RX_ELEMENT); + + if (ofs > LAST_RX_BUF) + *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF; + else *(WORD*) (realBase+rxOutOfs) = ofs; + *(DWORD*) (realBase+pktDrop) = 0UL; + _enable(); + } + + PUBLIC WORD PktBuffersUsed (void) + { + WORD inOfs, outOfs; + + _disable(); + inOfs = *(WORD*) (realBase+rxInOfs); + outOfs = *(WORD*) (realBase+rxOutOfs); + _enable(); + if (inOfs >= outOfs) + return (inOfs - outOfs) / sizeof(RX_ELEMENT); + return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT)); + } + + PUBLIC DWORD PktRxDropped (void) + { + return *(DWORD*) (realBase+pktDrop); + } + +#else /* real-mode small/large model */ + + PUBLIC int PktReceive (BYTE *buf, int max) + { + if (rxOutOfs != rxInOfs) + { + RX_ELEMENT far *head = (RX_ELEMENT far*) MK_FP (_DS,rxOutOfs); + int size, len = max; + + if (CheckElement(head)) + { + size = min (head->firstCount, sizeof(RX_ELEMENT)); + len = min (size, max); + _fmemcpy (buf, &head->destin, len); + } + else + size = -1; + + rxOutOfs += sizeof (RX_ELEMENT); + if (rxOutOfs > LAST_RX_BUF) + rxOutOfs = FIRST_RX_BUF; + return (size); + } + return (0); + } + + PUBLIC void PktQueueBusy (BOOL busy) + { + rxOutOfs = busy ? (rxInOfs + sizeof(RX_ELEMENT)) : rxInOfs; + if (rxOutOfs > LAST_RX_BUF) + rxOutOfs = FIRST_RX_BUF; + pktDrop = 0L; + } + + PUBLIC WORD PktBuffersUsed (void) + { + WORD inOfs = rxInOfs; + WORD outOfs = rxOutOfs; + + if (inOfs >= outOfs) + return ((inOfs - outOfs) / sizeof(RX_ELEMENT)); + return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT)); + } + + PUBLIC DWORD PktRxDropped (void) + { + return (pktDrop); + } +#endif + +/**************************************************************************/ + +LOCAL __inline void PktFreeMem (void) +{ +#if (DOSX & PHARLAP) + if (realSeg) + { + _dx_real_free (realSeg); + realSeg = 0; + } +#elif (DOSX & DJGPP) + if (rm_mem.rm_segment) + { + unsigned ofs; /* clear the DOS-mem to prevent further upcalls */ + + for (ofs = 0; ofs < 16 * rm_mem.size / 4; ofs += 4) + _farpokel (_dos_ds, realBase + ofs, 0); + _go32_dpmi_free_dos_memory (&rm_mem); + rm_mem.rm_segment = 0; + } +#elif (DOSX & DOS4GW) + if (rm_base_sel) + { + dpmi_real_free (rm_base_sel); + rm_base_sel = 0; + } +#endif +} + +/**************************************************************************/ + +PUBLIC BOOL PktExitDriver (void) +{ + if (pktInfo.handle) + { + if (!PktSetReceiverMode(PDRX_BROADCAST)) + PUTS ("Error restoring receiver mode."); + + if (!PktReleaseHandle(pktInfo.handle)) + PUTS ("Error releasing PKT-DRVR handle."); + + PktFreeMem(); + pktInfo.handle = 0; + } + + if (pcap_pkt_debug >= 1) + printf ("Internal stats: too-small %lu, too-large %lu, bad-sync %lu, " + "wrong-handle %lu\n", + intStat.tooSmall, intStat.tooLarge, + intStat.badSync, intStat.wrongHandle); + return (TRUE); +} + +#if (DOSX & (DJGPP|DOS4GW)) +static void dump_pkt_stub (void) +{ + int i; + + fprintf (stderr, "PktReceiver %lu, pkt_stub[PktReceiver] =\n", + PktReceiver); + for (i = 0; i < 15; i++) + fprintf (stderr, "%02X, ", real_stub_array[i+PktReceiver]); + fputs ("\n", stderr); +} +#endif + +/* + * Front end initialization routine + */ +PUBLIC BOOL PktInitDriver (PKT_RX_MODE mode) +{ + PKT_RX_MODE rxMode; + BOOL writeInfo = (pcap_pkt_debug >= 3); + + pktInfo.quiet = (pcap_pkt_debug < 3); + +#if (DOSX & PHARLAP) && defined(__HIGHC__) + if (_mwenv != 2) + { + fprintf (stderr, "Only Pharlap DOS extender supported.\n"); + return (FALSE); + } +#endif + +#if (DOSX & PHARLAP) && defined(__WATCOMC__) + if (_Extender != 1) + { + fprintf (stderr, "Only DOS4GW style extenders supported.\n"); + return (FALSE); + } +#endif + + if (!PktSearchDriver()) + { + PUTS ("Packet driver not found."); + PktFreeMem(); + return (FALSE); + } + + if (!PktGetDriverInfo()) + { + PUTS ("Error getting pkt-drvr information."); + PktFreeMem(); + return (FALSE); + } + +#if (DOSX & PHARLAP) + if (RealCopy((ULONG)&rxOutOfs, (ULONG)&pktRxEnd, + &realBase, &protBase, (USHORT*)&realSeg)) + { + rxOutOfsFp = (WORD _far *) (protBase + (WORD) &rxOutOfs); + rxInOfsFp = (WORD _far *) (protBase + (WORD) &rxInOfs); + *rxOutOfsFp = FIRST_RX_BUF; + *rxInOfsFp = FIRST_RX_BUF; + } + else + { + PUTS ("Cannot allocate real-mode stub."); + return (FALSE); + } + +#elif (DOSX & (DJGPP|DOS4GW)) + if (sizeof(real_stub_array) > 0xFFFF) + { + fprintf (stderr, "`real_stub_array[]' too big.\n"); + return (FALSE); + } +#if (DOSX & DJGPP) + rm_mem.size = (sizeof(real_stub_array) + 15) / 16; + + if (_go32_dpmi_allocate_dos_memory(&rm_mem) || rm_mem.rm_offset != 0) + { + PUTS ("real-mode init failed."); + return (FALSE); + } + realBase = (rm_mem.rm_segment << 4); + dosmemput (&real_stub_array, sizeof(real_stub_array), realBase); + _farpokel (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF); + _farpokel (_dos_ds, realBase+rxInOfs, FIRST_RX_BUF); + +#elif (DOSX & DOS4GW) + rm_base_seg = dpmi_real_malloc (sizeof(real_stub_array), &rm_base_sel); + if (!rm_base_seg) + { + PUTS ("real-mode init failed."); + return (FALSE); + } + realBase = (rm_base_seg << 4); + memcpy ((void*)realBase, &real_stub_array, sizeof(real_stub_array)); + *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF; + *(WORD*) (realBase+rxInOfs) = FIRST_RX_BUF; + +#endif + { + int pushf = PktReceiver; + + while (real_stub_array[pushf++] != 0x9C && /* pushf */ + real_stub_array[pushf] != 0xFA) /* cli */ + { + if (++para_skip > 16) + { + fprintf (stderr, "Something wrong with `pkt_stub.inc'.\n"); + para_skip = 0; + dump_pkt_stub(); + return (FALSE); + } + } + if (*(WORD*)(real_stub_array + offsetof(PktRealStub,_dummy)) != 0xB800) + { + fprintf (stderr, "`real_stub_array[]' is misaligned.\n"); + return (FALSE); + } + } + + if (pcap_pkt_debug > 2) + dump_pkt_stub(); + +#else + rxOutOfs = FIRST_RX_BUF; + rxInOfs = FIRST_RX_BUF; +#endif + + if (!PktSetAccess()) + { + PUTS ("Error setting pkt-drvr access."); + PktFreeMem(); + return (FALSE); + } + + if (!PktGetAddress(&myAddress)) + { + PUTS ("Error fetching adapter address."); + PktFreeMem(); + return (FALSE); + } + + if (!PktSetReceiverMode(mode)) + { + PUTS ("Error setting receiver mode."); + PktFreeMem(); + return (FALSE); + } + + if (!PktGetReceiverMode(&rxMode)) + { + PUTS ("Error getting receiver mode."); + PktFreeMem(); + return (FALSE); + } + + if (writeInfo) + printf ("Pkt-driver information:\n" + " Version : %d.%d\n" + " Name : %.15s\n" + " Class : %u (%s)\n" + " Type : %u\n" + " Number : %u\n" + " Funcs : %u\n" + " Intr : %Xh\n" + " Handle : %u\n" + " Extended : %s\n" + " Hi-perf : %s\n" + " RX mode : %s\n" + " Eth-addr : %02X:%02X:%02X:%02X:%02X:%02X\n", + + pktInfo.majVer, pktInfo.minVer, pktInfo.name, + pktInfo.class, PktGetClassName(pktInfo.class), + pktInfo.type, pktInfo.number, + pktInfo.funcs, pktInfo.intr, pktInfo.handle, + pktInfo.funcs == 2 || pktInfo.funcs == 6 ? "Yes" : "No", + pktInfo.funcs == 5 || pktInfo.funcs == 6 ? "Yes" : "No", + PktRXmodeStr(rxMode), + myAddress[0], myAddress[1], myAddress[2], + myAddress[3], myAddress[4], myAddress[5]); + +#if defined(DEBUG) && (DOSX & PHARLAP) + if (writeInfo) + { + DWORD rAdr = realBase + (WORD)&PktReceiver; + unsigned sel, ofs; + + printf ("\nReceiver at %04X:%04X\n", RP_SEG(rAdr), RP_OFF(rAdr)); + printf ("Realbase = %04X:%04X\n", RP_SEG(realBase),RP_OFF(realBase)); + + sel = _FP_SEG (protBase); + ofs = _FP_OFF (protBase); + printf ("Protbase = %04X:%08X\n", sel,ofs); + printf ("RealSeg = %04X\n", realSeg); + + sel = _FP_SEG (rxOutOfsFp); + ofs = _FP_OFF (rxOutOfsFp); + printf ("rxOutOfsFp = %04X:%08X\n", sel,ofs); + + sel = _FP_SEG (rxInOfsFp); + ofs = _FP_OFF (rxInOfsFp); + printf ("rxInOfsFp = %04X:%08X\n", sel,ofs); + + printf ("Ready: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n", + *rxOutOfsFp, *rxInOfsFp); + + PktQueueBusy (TRUE); + printf ("Busy: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n", + *rxOutOfsFp, *rxInOfsFp); + } +#endif + + memset (&pktStat, 0, sizeof(pktStat)); /* clear statistics */ + PktQueueBusy (TRUE); + return (TRUE); +} + + +/* + * DPMI functions only for Watcom + DOS4GW extenders + */ +#if (DOSX & DOS4GW) +LOCAL DWORD dpmi_get_real_vector (int intr) +{ + union REGS r; + + r.x.eax = 0x200; + r.x.ebx = (DWORD) intr; + int386 (0x31, &r, &r); + return ((r.w.cx << 4) + r.w.dx); +} + +LOCAL WORD dpmi_real_malloc (int size, WORD *selector) +{ + union REGS r; + + r.x.eax = 0x0100; /* DPMI allocate DOS memory */ + r.x.ebx = (size + 15) / 16; /* Number of paragraphs requested */ + int386 (0x31, &r, &r); + if (r.w.cflag & 1) + return (0); + + *selector = r.w.dx; + return (r.w.ax); /* Return segment address */ +} + +LOCAL void dpmi_real_free (WORD selector) +{ + union REGS r; + + r.x.eax = 0x101; /* DPMI free DOS memory */ + r.x.ebx = selector; /* Selector to free */ + int386 (0x31, &r, &r); +} +#endif + + +#if defined(DOSX) && (DOSX & PHARLAP) +/* + * Description: + * This routine allocates conventional memory for the specified block + * of code (which must be within the first 64K of the protected mode + * program segment) and copies the code to it. + * + * The caller should free up the conventional memory block when it + * is done with the conventional memory. + * + * NOTE THIS ROUTINE REQUIRES 386|DOS-EXTENDER 3.0 OR LATER. + * + * Calling arguments: + * start_offs start of real mode code in program segment + * end_offs 1 byte past end of real mode code in program segment + * real_basep returned; real mode ptr to use as a base for the + * real mode code (eg, to get the real mode FAR + * addr of a function foo(), take + * real_basep + (ULONG) foo). + * This pointer is constructed such that + * offsets within the real mode segment are + * the same as the link-time offsets in the + * protected mode program segment + * prot_basep returned; prot mode ptr to use as a base for getting + * to the conventional memory, also constructed + * so that adding the prot mode offset of a + * function or variable to the base gets you a + * ptr to the function or variable in the + * conventional memory block. + * rmem_adrp returned; real mode para addr of allocated + * conventional memory block, to be used to free + * up the conventional memory when done. DO NOT + * USE THIS TO CONSTRUCT A REAL MODE PTR, USE + * REAL_BASEP INSTEAD SO THAT OFFSETS WORK OUT + * CORRECTLY. + * + * Returned values: + * 0 if error + * 1 if success + */ +int RealCopy (ULONG start_offs, + ULONG end_offs, + REALPTR *real_basep, + FARPTR *prot_basep, + USHORT *rmem_adrp) +{ + ULONG rm_base; /* base real mode para addr for accessing */ + /* allocated conventional memory */ + UCHAR *source; /* source pointer for copy */ + FARPTR destin; /* destination pointer for copy */ + ULONG len; /* number of bytes to copy */ + ULONG temp; + USHORT stemp; + + /* First check for valid inputs + */ + if (start_offs >= end_offs || end_offs > 0x10000) + return (FALSE); + + /* Round start_offs down to a paragraph (16-byte) boundary so we can set up + * the real mode pointer easily. Round up end_offs to make sure we allocate + * enough paragraphs + */ + start_offs &= ~15; + end_offs = (15 + (end_offs << 4)) >> 4; + + /* Allocate the conventional memory for our real mode code. Remember to + * round byte count UP to 16-byte paragraph size. We alloc it + * above the DOS data buffer so both the DOS data buffer and the appl + * conventional mem block can still be resized. + * + * First just try to alloc it; if we can't get it, shrink the appl mem + * block down to the minimum, try to alloc the memory again, then grow the + * appl mem block back to the maximum. (Don't try to shrink the DOS data + * buffer to free conventional memory; it wouldn't be good for this routine + * to have the possible side effect of making file I/O run slower.) + */ + len = ((end_offs - start_offs) + 15) >> 4; + if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE) + { + if (_dx_cmem_usage(0, 0, &temp, &temp) != _DOSE_NONE) + return (FALSE); + + if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE) + *rmem_adrp = 0; + + if (_dx_cmem_usage(0, 1, &temp, &temp) != _DOSE_NONE) + { + if (*rmem_adrp != 0) + _dx_real_free (*rmem_adrp); + return (FALSE); + } + + if (*rmem_adrp == 0) + return (FALSE); + } + + /* Construct real mode & protected mode pointers to access the allocated + * memory. Note we know start_offs is aligned on a paragraph (16-byte) + * boundary, because we rounded it down. + * + * We make the offsets come out rights by backing off the real mode selector + * by start_offs. + */ + rm_base = ((ULONG) *rmem_adrp) - (start_offs >> 4); + RP_SET (*real_basep, 0, rm_base); + FP_SET (*prot_basep, rm_base << 4, SS_DOSMEM); + + /* Copy the real mode code/data to the allocated memory + */ + source = (UCHAR *) start_offs; + destin = *prot_basep; + FP_SET (destin, FP_OFF(*prot_basep) + start_offs, FP_SEL(*prot_basep)); + len = end_offs - start_offs; + WriteFarMem (destin, source, len); + + return (TRUE); +} +#endif /* DOSX && (DOSX & PHARLAP) */ diff --git a/winpcap/wpcap/libpcap/msdos/pktdrvr.h b/winpcap/wpcap/libpcap/msdos/pktdrvr.h new file mode 100644 index 0000000..08898ae --- /dev/null +++ b/winpcap/wpcap/libpcap/msdos/pktdrvr.h @@ -0,0 +1,153 @@ +#ifndef __PKTDRVR_H +#define __PKTDRVR_H + +#define PUBLIC +#define LOCAL static + +#define RX_BUF_SIZE ETH_MTU /* buffer size variables. NB !! */ +#define TX_BUF_SIZE ETH_MTU /* must be same as in pkt_rx*.* */ + +#ifdef __HIGHC__ +#pragma Off(Align_members) +#else +#pragma pack(1) +#endif + +typedef enum { /* Packet-driver classes */ + PD_ETHER = 1, + PD_PRONET10 = 2, + PD_IEEE8025 = 3, + PD_OMNINET = 4, + PD_APPLETALK = 5, + PD_SLIP = 6, + PD_STARTLAN = 7, + PD_ARCNET = 8, + PD_AX25 = 9, + PD_KISS = 10, + PD_IEEE8023_2 = 11, + PD_FDDI8022 = 12, + PD_X25 = 13, + PD_LANstar = 14, + PD_PPP = 18 + } PKT_CLASS; + +typedef enum { /* Packet-driver receive modes */ + PDRX_OFF = 1, /* turn off receiver */ + PDRX_DIRECT, /* receive only to this interface */ + PDRX_BROADCAST, /* DIRECT + broadcast packets */ + PDRX_MULTICAST1, /* BROADCAST + limited multicast */ + PDRX_MULTICAST2, /* BROADCAST + all multicast */ + PDRX_ALL_PACKETS, /* receive all packets on network */ + } PKT_RX_MODE; + +typedef struct { + char type[8]; + char len; + } PKT_FRAME; + + +typedef struct { + BYTE class; /* = 1 for DEC/Interl/Xerox Ethernet */ + BYTE number; /* = 0 for single LAN adapter */ + WORD type; /* = 13 for 3C523 */ + BYTE funcs; /* Basic/Extended/HiPerf functions */ + WORD intr; /* user interrupt vector number */ + WORD handle; /* Handle associated with session */ + BYTE name [15]; /* Name of adapter interface,ie.3C523*/ + BOOL quiet; /* (don't) print errors to stdout */ + const char *error; /* address of error string */ + BYTE majVer; /* Major driver implementation ver. */ + BYTE minVer; /* Minor driver implementation ver. */ + BYTE dummyLen; /* length of following data */ + WORD MAClength; /* HiPerformance data, N/A */ + WORD MTU; /* HiPerformance data, N/A */ + WORD multicast; /* HiPerformance data, N/A */ + WORD rcvrBuffers; /* valid for */ + WORD UMTbufs; /* High Performance drivers only */ + WORD postEOIintr; /* Usage ?? */ + } PKT_INFO; + +#define PKT_PARAM_SIZE 14 /* members majVer - postEOIintr */ + + +typedef struct { + DWORD inPackets; /* # of packets received */ + DWORD outPackets; /* # of packets transmitted */ + DWORD inBytes; /* # of bytes received */ + DWORD outBytes; /* # of bytes transmitted */ + DWORD inErrors; /* # of reception errors */ + DWORD outErrors; /* # of transmission errors */ + DWORD lost; /* # of packets lost (RX) */ + } PKT_STAT; + + +typedef struct { + ETHER destin; + ETHER source; + WORD proto; + BYTE data [TX_BUF_SIZE]; + } TX_ELEMENT; + +typedef struct { + WORD firstCount; /* # of bytes on 1st */ + WORD secondCount; /* and 2nd upcall */ + WORD handle; /* instance that upcalled */ + ETHER destin; /* E-net destination address */ + ETHER source; /* E-net source address */ + WORD proto; /* protocol number */ + BYTE data [RX_BUF_SIZE]; + } RX_ELEMENT; + + +#ifdef __HIGHC__ +#pragma pop(Align_members) +#else +#pragma pack() +#endif + + +/* + * Prototypes for publics + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern PKT_STAT pktStat; /* statistics for packets */ +extern PKT_INFO pktInfo; /* packet-driver information */ + +extern PKT_RX_MODE receiveMode; +extern ETHER myAddress, ethBroadcast; + +extern BOOL PktInitDriver (PKT_RX_MODE mode); +extern BOOL PktExitDriver (void); + +extern const char *PktGetErrorStr (int errNum); +extern const char *PktGetClassName (WORD class); +extern const char *PktRXmodeStr (PKT_RX_MODE mode); +extern BOOL PktSearchDriver (void); +extern int PktReceive (BYTE *buf, int max); +extern BOOL PktTransmit (const void *eth, int len); +extern DWORD PktRxDropped (void); +extern BOOL PktReleaseHandle (WORD handle); +extern BOOL PktTerminHandle (WORD handle); +extern BOOL PktResetInterface (WORD handle); +extern BOOL PktSetReceiverMode(PKT_RX_MODE mode); +extern BOOL PktGetReceiverMode(PKT_RX_MODE *mode); +extern BOOL PktGetStatistics (WORD handle); +extern BOOL PktSessStatistics (WORD handle); +extern BOOL PktResetStatistics(WORD handle); +extern BOOL PktGetAddress (ETHER *addr); +extern BOOL PktSetAddress (const ETHER *addr); +extern BOOL PktGetDriverInfo (void); +extern BOOL PktGetDriverParam (void); +extern void PktQueueBusy (BOOL busy); +extern WORD PktBuffersUsed (void); + +#ifdef __cplusplus +} +#endif + +#endif /* __PKTDRVR_H */ + diff --git a/winpcap/wpcap/libpcap/msdos/readme.dos b/winpcap/wpcap/libpcap/msdos/readme.dos new file mode 100644 index 0000000..d38fdbd --- /dev/null +++ b/winpcap/wpcap/libpcap/msdos/readme.dos @@ -0,0 +1,162 @@ +@(#) $Header: /tcpdump/master/libpcap/msdos/readme.dos,v 1.3 2004/12/19 19:47:01 guy Exp $ (LBL) + +libpcap for DOS +--------------- + +This file contains some notes on building and using libpcap for MS-DOS. +Look in `README' and `pcap.man' for usage and details. These targets are +supported: + + - Borland C 4.0+ small or large model. + - Metaware HighC 3.1+ with PharLap DOS-extender + - GNU C 2.7+ with djgpp 2.01+ DOS extender + - Watcom C 11.x with DOS4GW extender + +Note: the files in the libpcap.zip contains short trucated filenames. + So for djgpp to work with these, disable the use of long file names by + setting "LFN=n" in the environment. + +Files specific to DOS are pcap-dos.[ch] and the assembly and C files in +the MSDOS sub-directory. Remember to built lipcap libraries from the top +install directory. And not from the MSDOS sub-directory. + +Note for djgpp users: + If you got the libpcap from the official site www.tcpdump, then that + distribution does NOT contain any sources for building 32-bit drivers. + Instead get the full version at + http://www.bgnett.no/~giva/pcap/libpcap.zip + + and set "USE_32BIT_DRIVERS = 1" in msdos\common.dj. + + + +Requirements +------------ + +DOS-libpcap currently only works reliably with a real-mode Ethernet packet- +driver. This driver must be installed prior to using any program (e.g. +tcpdump) compiled with libpcap. Work is underway to implement protected- +mode drivers for 32-bit targets (djgpp only). The 3Com 3c509 driver is +working almost perfectly. Due to lack of LAN-cards, I've not had the +opportunity to test other drivers. These 32-bit drivers are modified +Linux drivers. + + +Required packages +----------------- + +The following packages and tools must be present for all targets. + +1. Watt-32 tcp/ip library. This library is *not* used to send or + receive network data. It's mostly used to access the 'hosts' + file and other features. Get 'watt32s*.zip' at: + + http://www.bgnett.no/~giva/ + +2. Exception handler and disassember library (libexc.a) is needed if + "USE_EXCEPT = 1" in common.dj. Available at: + + http://www.bgnett.no/~giva/misc/exc_dx07.zip + +3. Flex & Bison is used to generate parser for the filter handler + pcap_compile: + + ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/flx254b.zip + ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsn128b.zip + +4. NASM assembler v 0.98 or later is required when building djgpp and + Watcom targets: + + ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2tk/nasm098p.zip + +5. sed (Stream Editor) is required for doing `make depend'. + It's available at + ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/sed*.zip + + A touch tool to update the time-stamp of a file. E.g. + ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/grep*.zip + +6. For djgpp rm.exe and cp.exe are required. These should already be + part of your djgpp installation. Also required (experimental at the + time) for djgpp is DLX 2.91 or later. This tool is for the generation + of dynamically loadable modules. + + +Compiling libpcap +----------------- + +Follow these steps in building libpcap: + +1. Make sure you've installed Watt-32 properly (see it's `INSTALL' file). + During that installation a environment variable `WATT_ROOT' is set. + This variable is used for building libpcap also (`WATT_INC' is + deducted from `WATT_ROOT'). djgpp users should also define environment + variables `C_INCLUDE_PATH' and `LIBRARY_PATH' to point to the include + directory and library directory respectively. E.g. put this in your + AUTOEXEC.BAT: + set C_INCLUDE_PATH=c:/net/watt/inc + set LIBRARY_PATH=c:/net/watt/lib + +2. Revise the msdos/common.dj file for your djgpp/gcc installation; + - change the value of `GCCLIB' to match location of libgcc.a. + - set `USE_32BIT_DRIVERS = 1' to build 32-bit driver objects. + + +3. Build pcap by using appropriate makefile. For djgpp, use: + `make -f msdos/makefile.dj' (i.e. GNU `make') + + For a Watcom target say: + `wmake -f msdos\makefile.wc' + + For a Borland target say: + `maker -f msdos\Makefile pcap_bc.lib' (Borland's `maker.exe') + + And for a HighC/Pharlap target say: + `maker -f msdos\Makefile pcap_hc.lib' (Borland's `maker.exe') + + You might like to change some `CFLAGS' -- only `DEBUG' define currently + have any effect. It shows a rotating "fan" in upper right corner of + screen. Remove `DEBUG' if you don't like it. You could add + `-fomit-frame-pointer' to `CFLAGS' to speed up the generated code. + But note, this makes debugging and crash-traceback difficult. Only + add it if you're fully confident your application is 100% stable. + + Note: Code in `USE_NDIS2' does not work at the moment. + +4. The resulting libraries are put in current directory. There's no + test-program for `libpcap'. Linking the library with `tcpdump' is + the ultimate test anyway. + + + +Extensions to libpcap +--------------------- + +I've included some extra functions to DOS-libpcap: + + `pcap_config_hook (const char *name, const char *value)' + + Allows an application to set values of internal libpcap variables. + `name' is typically a left-side keyword with an associated `value' + that is called from application's configure process (see tcpdump's + config.c file). libpcap keeps a set of tables that are searched for + a name/value match. Currently only used to set debug-levels and + parameters for the 32-bit network drivers. + + `pcap_set_wait (pcap_t *, void (*)(void), int)' : + + Only effective when reading offline traffic from dump-files. + Function `pcap_offline_read()' will wait (and optionally yield) + before printing next packet. This will simulate the pace the packets + where actually recorded. + + + +Happy sniffing ! + + +Gisle Vanem + + +October 1999, 2004 + diff --git a/winpcap/wpcap/libpcap/nametoaddr.c b/winpcap/wpcap/libpcap/nametoaddr.c new file mode 100644 index 0000000..a795e49 --- /dev/null +++ b/winpcap/wpcap/libpcap/nametoaddr.c @@ -0,0 +1,505 @@ +/* + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Name to id translation routines used by the scanner. + * These functions are not time critical. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.77.2.3 2005/04/20 11:13:51 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include + +#else /* WIN32 */ + +#include +#include /* concession to AIX */ +#include +#include + +#include +#endif /* WIN32 */ + +/* + * XXX - why was this included even on UNIX? + */ +#ifdef __MINGW32__ +#include "IP6_misc.h" +#endif + +#ifndef WIN32 +#ifdef HAVE_ETHER_HOSTTON +/* + * XXX - do we need any of this if doesn't declare + * ether_hostton()? + */ +#ifdef HAVE_NETINET_IF_ETHER_H +struct mbuf; /* Squelch compiler warnings on some platforms for */ +struct rtentry; /* declarations in */ +#include /* for "struct ifnet" in "struct arpcom" on Solaris */ +#include +#endif /* HAVE_NETINET_IF_ETHER_H */ +#ifdef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON +#include +#endif /* NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */ +#endif /* HAVE_ETHER_HOSTTON */ +#include +#include +#endif /* WIN32 */ + +#include +#include +#include +#include +#include + +#include "pcap-int.h" + +#include "gencode.h" +#include + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#ifndef NTOHL +#define NTOHL(x) (x) = ntohl(x) +#define NTOHS(x) (x) = ntohs(x) +#endif + +static inline int xdtoi(int); + +/* + * Convert host name to internet address. + * Return 0 upon failure. + */ +bpf_u_int32 ** +pcap_nametoaddr(const char *name) +{ +#ifndef h_addr + static bpf_u_int32 *hlist[2]; +#endif + bpf_u_int32 **p; + struct hostent *hp; + + if ((hp = gethostbyname(name)) != NULL) { +#ifndef h_addr + hlist[0] = (bpf_u_int32 *)hp->h_addr; + NTOHL(hp->h_addr); + return hlist; +#else + for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p) + NTOHL(**p); + return (bpf_u_int32 **)hp->h_addr_list; +#endif + } + else + return 0; +} + +#ifdef INET6 +struct addrinfo * +pcap_nametoaddrinfo(const char *name) +{ + struct addrinfo hints, *res; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; /*not really*/ + hints.ai_protocol = IPPROTO_TCP; /*not really*/ + error = getaddrinfo(name, NULL, &hints, &res); + if (error) + return NULL; + else + return res; +} +#endif /*INET6*/ + +/* + * Convert net name to internet address. + * Return 0 upon failure. + */ +bpf_u_int32 +pcap_nametonetaddr(const char *name) +{ +#ifndef WIN32 + struct netent *np; + + if ((np = getnetbyname(name)) != NULL) + return np->n_net; + else + return 0; +#else + /* + * There's no "getnetbyname()" on Windows. + */ + return 0; +#endif +} + +/* + * Convert a port name to its port and protocol numbers. + * We assume only TCP or UDP. + * Return 0 upon failure. + */ +int +pcap_nametoport(const char *name, int *port, int *proto) +{ + struct servent *sp; + int tcp_port = -1; + int udp_port = -1; + + /* + * We need to check /etc/services for ambiguous entries. + * If we find the ambiguous entry, and it has the + * same port number, change the proto to PROTO_UNDEF + * so both TCP and UDP will be checked. + */ + sp = getservbyname(name, "tcp"); + if (sp != NULL) tcp_port = ntohs(sp->s_port); + sp = getservbyname(name, "udp"); + if (sp != NULL) udp_port = ntohs(sp->s_port); + if (tcp_port >= 0) { + *port = tcp_port; + *proto = IPPROTO_TCP; + if (udp_port >= 0) { + if (udp_port == tcp_port) + *proto = PROTO_UNDEF; +#ifdef notdef + else + /* Can't handle ambiguous names that refer + to different port numbers. */ + warning("ambiguous port %s in /etc/services", + name); +#endif + } + return 1; + } + if (udp_port >= 0) { + *port = udp_port; + *proto = IPPROTO_UDP; + return 1; + } +#if defined(ultrix) || defined(__osf__) + /* Special hack in case NFS isn't in /etc/services */ + if (strcmp(name, "nfs") == 0) { + *port = 2049; + *proto = PROTO_UNDEF; + return 1; + } +#endif + return 0; +} + +/* + * Convert a string in the form PPP-PPP, where correspond to ports, to + * a starting and ending port in a port range. + * Return 0 on failure. + */ +int +pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto) +{ + u_int p1, p2; + char *off, *cpy; + int save_proto; + + if (sscanf(name, "%d-%d", &p1, &p2) != 2) { + if ((cpy = strdup(name)) == NULL) + return 0; + + if ((off = strchr(cpy, '-')) == NULL) { + free(cpy); + return 0; + } + + *off = '\0'; + + if (pcap_nametoport(cpy, port1, proto) == 0) { + free(cpy); + return 0; + } + save_proto = *proto; + + if (pcap_nametoport(off + 1, port2, proto) == 0) { + free(cpy); + return 0; + } + + if (*proto != save_proto) + *proto = PROTO_UNDEF; + } else { + *port1 = p1; + *port2 = p2; + *proto = PROTO_UNDEF; + } + + return 1; +} + +int +pcap_nametoproto(const char *str) +{ + struct protoent *p; + + p = getprotobyname(str); + if (p != 0) + return p->p_proto; + else + return PROTO_UNDEF; +} + +#include "ethertype.h" + +struct eproto { + char *s; + u_short p; +}; + +/* Static data base of ether protocol types. */ +struct eproto eproto_db[] = { + { "pup", ETHERTYPE_PUP }, + { "xns", ETHERTYPE_NS }, + { "ip", ETHERTYPE_IP }, +#ifdef INET6 + { "ip6", ETHERTYPE_IPV6 }, +#endif + { "arp", ETHERTYPE_ARP }, + { "rarp", ETHERTYPE_REVARP }, + { "sprite", ETHERTYPE_SPRITE }, + { "mopdl", ETHERTYPE_MOPDL }, + { "moprc", ETHERTYPE_MOPRC }, + { "decnet", ETHERTYPE_DN }, + { "lat", ETHERTYPE_LAT }, + { "sca", ETHERTYPE_SCA }, + { "lanbridge", ETHERTYPE_LANBRIDGE }, + { "vexp", ETHERTYPE_VEXP }, + { "vprod", ETHERTYPE_VPROD }, + { "atalk", ETHERTYPE_ATALK }, + { "atalkarp", ETHERTYPE_AARP }, + { "loopback", ETHERTYPE_LOOPBACK }, + { "decdts", ETHERTYPE_DECDTS }, + { "decdns", ETHERTYPE_DECDNS }, + { (char *)0, 0 } +}; + +int +pcap_nametoeproto(const char *s) +{ + struct eproto *p = eproto_db; + + while (p->s != 0) { + if (strcmp(p->s, s) == 0) + return p->p; + p += 1; + } + return PROTO_UNDEF; +} + +#include "llc.h" + +/* Static data base of LLC values. */ +static struct eproto llc_db[] = { + { "iso", LLCSAP_ISONS }, + { "stp", LLCSAP_8021D }, + { "ipx", LLCSAP_IPX }, + { "netbeui", LLCSAP_NETBEUI }, + { (char *)0, 0 } +}; + +int +pcap_nametollc(const char *s) +{ + struct eproto *p = llc_db; + + while (p->s != 0) { + if (strcmp(p->s, s) == 0) + return p->p; + p += 1; + } + return PROTO_UNDEF; +} + +/* Hex digit to integer. */ +static inline int +xdtoi(c) + register int c; +{ + if (isdigit(c)) + return c - '0'; + else if (islower(c)) + return c - 'a' + 10; + else + return c - 'A' + 10; +} + +int +__pcap_atoin(const char *s, bpf_u_int32 *addr) +{ + u_int n; + int len; + + *addr = 0; + len = 0; + while (1) { + n = 0; + while (*s && *s != '.') + n = n * 10 + *s++ - '0'; + *addr <<= 8; + *addr |= n & 0xff; + len += 8; + if (*s == '\0') + return len; + ++s; + } + /* NOTREACHED */ +} + +int +__pcap_atodn(const char *s, bpf_u_int32 *addr) +{ +#define AREASHIFT 10 +#define AREAMASK 0176000 +#define NODEMASK 01777 + + u_int node, area; + + if (sscanf((char *)s, "%d.%d", &area, &node) != 2) + bpf_error("malformed decnet address '%s'", s); + + *addr = (area << AREASHIFT) & AREAMASK; + *addr |= (node & NODEMASK); + + return(32); +} + +/* + * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new + * ethernet address. Assumes 's' is well formed. + */ +u_char * +pcap_ether_aton(const char *s) +{ + register u_char *ep, *e; + register u_int d; + + e = ep = (u_char *)malloc(6); + + while (*s) { + if (*s == ':') + s += 1; + d = xdtoi(*s++); + if (isxdigit((unsigned char)*s)) { + d <<= 4; + d |= xdtoi(*s++); + } + *ep++ = d; + } + + return (e); +} + +#ifndef HAVE_ETHER_HOSTTON +/* Roll our own */ +u_char * +pcap_ether_hostton(const char *name) +{ + register struct pcap_etherent *ep; + register u_char *ap; + static FILE *fp = NULL; + static int init = 0; + + if (!init) { + fp = fopen(PCAP_ETHERS_FILE, "r"); + ++init; + if (fp == NULL) + return (NULL); + } else if (fp == NULL) + return (NULL); + else + rewind(fp); + + while ((ep = pcap_next_etherent(fp)) != NULL) { + if (strcmp(ep->name, name) == 0) { + ap = (u_char *)malloc(6); + if (ap != NULL) { + memcpy(ap, ep->addr, 6); + return (ap); + } + break; + } + } + return (NULL); +} +#else + +#if !defined(HAVE_DECL_ETHER_HOSTTON) || !HAVE_DECL_ETHER_HOSTTON +#ifndef HAVE_STRUCT_ETHER_ADDR +struct ether_addr { + unsigned char ether_addr_octet[6]; +}; +#endif +extern int ether_hostton(const char *, struct ether_addr *); +#endif + +/* Use the os supplied routines */ +u_char * +pcap_ether_hostton(const char *name) +{ + register u_char *ap; + u_char a[6]; + + ap = NULL; + if (ether_hostton((char *)name, (struct ether_addr *)a) == 0) { + ap = (u_char *)malloc(6); + if (ap != NULL) + memcpy((char *)ap, (char *)a, 6); + } + return (ap); +} +#endif + +u_short +__pcap_nametodnaddr(const char *name) +{ +#ifdef DECNETLIB + struct nodeent *getnodebyname(); + struct nodeent *nep; + unsigned short res; + + nep = getnodebyname(name); + if (nep == ((struct nodeent *)0)) + bpf_error("unknown decnet host name '%s'\n", name); + + memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short)); + return(res); +#else + bpf_error("decnet name support not included, '%s' cannot be translated\n", + name); + return(0); +#endif +} diff --git a/winpcap/wpcap/libpcap/nlpid.h b/winpcap/wpcap/libpcap/nlpid.h new file mode 100644 index 0000000..c3ab8c2 --- /dev/null +++ b/winpcap/wpcap/libpcap/nlpid.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1996 + * Juniper Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution. The name of Juniper Networks may not + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/nlpid.h,v 1.2 2002/12/06 00:01:34 hannes Exp $ (Juniper) + */ + +/* Types missing from some systems */ + +/* + * Network layer prototocol identifiers + */ +#ifndef ISO8473_CLNP +#define ISO8473_CLNP 0x81 +#endif +#ifndef ISO9542_ESIS +#define ISO9542_ESIS 0x82 +#endif +#ifndef ISO9542X25_ESIS +#define ISO9542X25_ESIS 0x8a +#endif +#ifndef ISO10589_ISIS +#define ISO10589_ISIS 0x83 +#endif +/* + * this does not really belong in the nlpid.h file + * however we need it for generating nice + * IS-IS related BPF filters + */ +#define ISIS_L1_LAN_IIH 15 +#define ISIS_L2_LAN_IIH 16 +#define ISIS_PTP_IIH 17 +#define ISIS_L1_LSP 18 +#define ISIS_L2_LSP 20 +#define ISIS_L1_CSNP 24 +#define ISIS_L2_CSNP 25 +#define ISIS_L1_PSNP 26 +#define ISIS_L2_PSNP 27 + +#ifndef ISO8878A_CONS +#define ISO8878A_CONS 0x84 +#endif +#ifndef ISO10747_IDRP +#define ISO10747_IDRP 0x85 +#endif diff --git a/winpcap/wpcap/libpcap/optimize.c b/winpcap/wpcap/libpcap/optimize.c new file mode 100644 index 0000000..173bc55 --- /dev/null +++ b/winpcap/wpcap/libpcap/optimize.c @@ -0,0 +1,2295 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Optimization module for tcpdump intermediate representation. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.85 2005/04/04 08:42:18 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include + +#include "pcap-int.h" + +#include "gencode.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#ifdef BDEBUG +extern int dflag; +#endif + +#if defined(MSDOS) && !defined(__DJGPP__) +extern int _w32_ffs (int mask); +#define ffs _w32_ffs +#endif + +/* + * Represents a deleted instruction. + */ +#define NOP -1 + +/* + * Register numbers for use-def values. + * 0 through BPF_MEMWORDS-1 represent the corresponding scratch memory + * location. A_ATOM is the accumulator and X_ATOM is the index + * register. + */ +#define A_ATOM BPF_MEMWORDS +#define X_ATOM (BPF_MEMWORDS+1) + +/* + * This define is used to represent *both* the accumulator and + * x register in use-def computations. + * Currently, the use-def code assumes only one definition per instruction. + */ +#define AX_ATOM N_ATOMS + +/* + * A flag to indicate that further optimization is needed. + * Iterative passes are continued until a given pass yields no + * branch movement. + */ +static int done; + +/* + * A block is marked if only if its mark equals the current mark. + * Rather than traverse the code array, marking each item, 'cur_mark' is + * incremented. This automatically makes each element unmarked. + */ +static int cur_mark; +#define isMarked(p) ((p)->mark == cur_mark) +#define unMarkAll() cur_mark += 1 +#define Mark(p) ((p)->mark = cur_mark) + +static void opt_init(struct block *); +static void opt_cleanup(void); + +static void make_marks(struct block *); +static void mark_code(struct block *); + +static void intern_blocks(struct block *); + +static int eq_slist(struct slist *, struct slist *); + +static void find_levels_r(struct block *); + +static void find_levels(struct block *); +static void find_dom(struct block *); +static void propedom(struct edge *); +static void find_edom(struct block *); +static void find_closure(struct block *); +static int atomuse(struct stmt *); +static int atomdef(struct stmt *); +static void compute_local_ud(struct block *); +static void find_ud(struct block *); +static void init_val(void); +static int F(int, int, int); +static inline void vstore(struct stmt *, int *, int, int); +static void opt_blk(struct block *, int); +static int use_conflict(struct block *, struct block *); +static void opt_j(struct edge *); +static void or_pullup(struct block *); +static void and_pullup(struct block *); +static void opt_blks(struct block *, int); +static inline void link_inedge(struct edge *, struct block *); +static void find_inedges(struct block *); +static void opt_root(struct block **); +static void opt_loop(struct block *, int); +static void fold_op(struct stmt *, int, int); +static inline struct slist *this_op(struct slist *); +static void opt_not(struct block *); +static void opt_peep(struct block *); +static void opt_stmt(struct stmt *, int[], int); +static void deadstmt(struct stmt *, struct stmt *[]); +static void opt_deadstores(struct block *); +static struct block *fold_edge(struct block *, struct edge *); +static inline int eq_blk(struct block *, struct block *); +static int slength(struct slist *); +static int count_blocks(struct block *); +static void number_blks_r(struct block *); +static int count_stmts(struct block *); +static int convert_code_r(struct block *); +#ifdef BDEBUG +static void opt_dump(struct block *); +#endif + +static int n_blocks; +struct block **blocks; +static int n_edges; +struct edge **edges; + +/* + * A bit vector set representation of the dominators. + * We round up the set size to the next power of two. + */ +static int nodewords; +static int edgewords; +struct block **levels; +bpf_u_int32 *space; +#define BITS_PER_WORD (8*sizeof(bpf_u_int32)) +/* + * True if a is in uset {p} + */ +#define SET_MEMBER(p, a) \ +((p)[(unsigned)(a) / BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD))) + +/* + * Add 'a' to uset p. + */ +#define SET_INSERT(p, a) \ +(p)[(unsigned)(a) / BITS_PER_WORD] |= (1 << ((unsigned)(a) % BITS_PER_WORD)) + +/* + * Delete 'a' from uset p. + */ +#define SET_DELETE(p, a) \ +(p)[(unsigned)(a) / BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD)) + +/* + * a := a intersect b + */ +#define SET_INTERSECT(a, b, n)\ +{\ + register bpf_u_int32 *_x = a, *_y = b;\ + register int _n = n;\ + while (--_n >= 0) *_x++ &= *_y++;\ +} + +/* + * a := a - b + */ +#define SET_SUBTRACT(a, b, n)\ +{\ + register bpf_u_int32 *_x = a, *_y = b;\ + register int _n = n;\ + while (--_n >= 0) *_x++ &=~ *_y++;\ +} + +/* + * a := a union b + */ +#define SET_UNION(a, b, n)\ +{\ + register bpf_u_int32 *_x = a, *_y = b;\ + register int _n = n;\ + while (--_n >= 0) *_x++ |= *_y++;\ +} + +static uset all_dom_sets; +static uset all_closure_sets; +static uset all_edge_sets; + +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + +static void +find_levels_r(b) + struct block *b; +{ + int level; + + if (isMarked(b)) + return; + + Mark(b); + b->link = 0; + + if (JT(b)) { + find_levels_r(JT(b)); + find_levels_r(JF(b)); + level = MAX(JT(b)->level, JF(b)->level) + 1; + } else + level = 0; + b->level = level; + b->link = levels[level]; + levels[level] = b; +} + +/* + * Level graph. The levels go from 0 at the leaves to + * N_LEVELS at the root. The levels[] array points to the + * first node of the level list, whose elements are linked + * with the 'link' field of the struct block. + */ +static void +find_levels(root) + struct block *root; +{ + memset((char *)levels, 0, n_blocks * sizeof(*levels)); + unMarkAll(); + find_levels_r(root); +} + +/* + * Find dominator relationships. + * Assumes graph has been leveled. + */ +static void +find_dom(root) + struct block *root; +{ + int i; + struct block *b; + bpf_u_int32 *x; + + /* + * Initialize sets to contain all nodes. + */ + x = all_dom_sets; + i = n_blocks * nodewords; + while (--i >= 0) + *x++ = ~0; + /* Root starts off empty. */ + for (i = nodewords; --i >= 0;) + root->dom[i] = 0; + + /* root->level is the highest level no found. */ + for (i = root->level; i >= 0; --i) { + for (b = levels[i]; b; b = b->link) { + SET_INSERT(b->dom, b->id); + if (JT(b) == 0) + continue; + SET_INTERSECT(JT(b)->dom, b->dom, nodewords); + SET_INTERSECT(JF(b)->dom, b->dom, nodewords); + } + } +} + +static void +propedom(ep) + struct edge *ep; +{ + SET_INSERT(ep->edom, ep->id); + if (ep->succ) { + SET_INTERSECT(ep->succ->et.edom, ep->edom, edgewords); + SET_INTERSECT(ep->succ->ef.edom, ep->edom, edgewords); + } +} + +/* + * Compute edge dominators. + * Assumes graph has been leveled and predecessors established. + */ +static void +find_edom(root) + struct block *root; +{ + int i; + uset x; + struct block *b; + + x = all_edge_sets; + for (i = n_edges * edgewords; --i >= 0; ) + x[i] = ~0; + + /* root->level is the highest level no found. */ + memset(root->et.edom, 0, edgewords * sizeof(*(uset)0)); + memset(root->ef.edom, 0, edgewords * sizeof(*(uset)0)); + for (i = root->level; i >= 0; --i) { + for (b = levels[i]; b != 0; b = b->link) { + propedom(&b->et); + propedom(&b->ef); + } + } +} + +/* + * Find the backwards transitive closure of the flow graph. These sets + * are backwards in the sense that we find the set of nodes that reach + * a given node, not the set of nodes that can be reached by a node. + * + * Assumes graph has been leveled. + */ +static void +find_closure(root) + struct block *root; +{ + int i; + struct block *b; + + /* + * Initialize sets to contain no nodes. + */ + memset((char *)all_closure_sets, 0, + n_blocks * nodewords * sizeof(*all_closure_sets)); + + /* root->level is the highest level no found. */ + for (i = root->level; i >= 0; --i) { + for (b = levels[i]; b; b = b->link) { + SET_INSERT(b->closure, b->id); + if (JT(b) == 0) + continue; + SET_UNION(JT(b)->closure, b->closure, nodewords); + SET_UNION(JF(b)->closure, b->closure, nodewords); + } + } +} + +/* + * Return the register number that is used by s. If A and X are both + * used, return AX_ATOM. If no register is used, return -1. + * + * The implementation should probably change to an array access. + */ +static int +atomuse(s) + struct stmt *s; +{ + register int c = s->code; + + if (c == NOP) + return -1; + + switch (BPF_CLASS(c)) { + + case BPF_RET: + return (BPF_RVAL(c) == BPF_A) ? A_ATOM : + (BPF_RVAL(c) == BPF_X) ? X_ATOM : -1; + + case BPF_LD: + case BPF_LDX: + return (BPF_MODE(c) == BPF_IND) ? X_ATOM : + (BPF_MODE(c) == BPF_MEM) ? s->k : -1; + + case BPF_ST: + return A_ATOM; + + case BPF_STX: + return X_ATOM; + + case BPF_JMP: + case BPF_ALU: + if (BPF_SRC(c) == BPF_X) + return AX_ATOM; + return A_ATOM; + + case BPF_MISC: + return BPF_MISCOP(c) == BPF_TXA ? X_ATOM : A_ATOM; + } + abort(); + /* NOTREACHED */ +} + +/* + * Return the register number that is defined by 's'. We assume that + * a single stmt cannot define more than one register. If no register + * is defined, return -1. + * + * The implementation should probably change to an array access. + */ +static int +atomdef(s) + struct stmt *s; +{ + if (s->code == NOP) + return -1; + + switch (BPF_CLASS(s->code)) { + + case BPF_LD: + case BPF_ALU: + return A_ATOM; + + case BPF_LDX: + return X_ATOM; + + case BPF_ST: + case BPF_STX: + return s->k; + + case BPF_MISC: + return BPF_MISCOP(s->code) == BPF_TAX ? X_ATOM : A_ATOM; + } + return -1; +} + +/* + * Compute the sets of registers used, defined, and killed by 'b'. + * + * "Used" means that a statement in 'b' uses the register before any + * statement in 'b' defines it, i.e. it uses the value left in + * that register by a predecessor block of this block. + * "Defined" means that a statement in 'b' defines it. + * "Killed" means that a statement in 'b' defines it before any + * statement in 'b' uses it, i.e. it kills the value left in that + * register by a predecessor block of this block. + */ +static void +compute_local_ud(b) + struct block *b; +{ + struct slist *s; + atomset def = 0, use = 0, kill = 0; + int atom; + + for (s = b->stmts; s; s = s->next) { + if (s->s.code == NOP) + continue; + atom = atomuse(&s->s); + if (atom >= 0) { + if (atom == AX_ATOM) { + if (!ATOMELEM(def, X_ATOM)) + use |= ATOMMASK(X_ATOM); + if (!ATOMELEM(def, A_ATOM)) + use |= ATOMMASK(A_ATOM); + } + else if (atom < N_ATOMS) { + if (!ATOMELEM(def, atom)) + use |= ATOMMASK(atom); + } + else + abort(); + } + atom = atomdef(&s->s); + if (atom >= 0) { + if (!ATOMELEM(use, atom)) + kill |= ATOMMASK(atom); + def |= ATOMMASK(atom); + } + } + if (BPF_CLASS(b->s.code) == BPF_JMP) { + /* + * XXX - what about RET? + */ + atom = atomuse(&b->s); + if (atom >= 0) { + if (atom == AX_ATOM) { + if (!ATOMELEM(def, X_ATOM)) + use |= ATOMMASK(X_ATOM); + if (!ATOMELEM(def, A_ATOM)) + use |= ATOMMASK(A_ATOM); + } + else if (atom < N_ATOMS) { + if (!ATOMELEM(def, atom)) + use |= ATOMMASK(atom); + } + else + abort(); + } + } + + b->def = def; + b->kill = kill; + b->in_use = use; +} + +/* + * Assume graph is already leveled. + */ +static void +find_ud(root) + struct block *root; +{ + int i, maxlevel; + struct block *p; + + /* + * root->level is the highest level no found; + * count down from there. + */ + maxlevel = root->level; + for (i = maxlevel; i >= 0; --i) + for (p = levels[i]; p; p = p->link) { + compute_local_ud(p); + p->out_use = 0; + } + + for (i = 1; i <= maxlevel; ++i) { + for (p = levels[i]; p; p = p->link) { + p->out_use |= JT(p)->in_use | JF(p)->in_use; + p->in_use |= p->out_use &~ p->kill; + } + } +} + +/* + * These data structures are used in a Cocke and Shwarz style + * value numbering scheme. Since the flowgraph is acyclic, + * exit values can be propagated from a node's predecessors + * provided it is uniquely defined. + */ +struct valnode { + int code; + int v0, v1; + int val; + struct valnode *next; +}; + +#define MODULUS 213 +static struct valnode *hashtbl[MODULUS]; +static int curval; +static int maxval; + +/* Integer constants mapped with the load immediate opcode. */ +#define K(i) F(BPF_LD|BPF_IMM|BPF_W, i, 0L) + +struct vmapinfo { + int is_const; + bpf_int32 const_val; +}; + +struct vmapinfo *vmap; +struct valnode *vnode_base; +struct valnode *next_vnode; + +static void +init_val() +{ + curval = 0; + next_vnode = vnode_base; + memset((char *)vmap, 0, maxval * sizeof(*vmap)); + memset((char *)hashtbl, 0, sizeof hashtbl); +} + +/* Because we really don't have an IR, this stuff is a little messy. */ +static int +F(code, v0, v1) + int code; + int v0, v1; +{ + u_int hash; + int val; + struct valnode *p; + + hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8); + hash %= MODULUS; + + for (p = hashtbl[hash]; p; p = p->next) + if (p->code == code && p->v0 == v0 && p->v1 == v1) + return p->val; + + val = ++curval; + if (BPF_MODE(code) == BPF_IMM && + (BPF_CLASS(code) == BPF_LD || BPF_CLASS(code) == BPF_LDX)) { + vmap[val].const_val = v0; + vmap[val].is_const = 1; + } + p = next_vnode++; + p->val = val; + p->code = code; + p->v0 = v0; + p->v1 = v1; + p->next = hashtbl[hash]; + hashtbl[hash] = p; + + return val; +} + +static inline void +vstore(s, valp, newval, alter) + struct stmt *s; + int *valp; + int newval; + int alter; +{ + if (alter && *valp == newval) + s->code = NOP; + else + *valp = newval; +} + +static void +fold_op(s, v0, v1) + struct stmt *s; + int v0, v1; +{ + bpf_int32 a, b; + + a = vmap[v0].const_val; + b = vmap[v1].const_val; + + switch (BPF_OP(s->code)) { + case BPF_ADD: + a += b; + break; + + case BPF_SUB: + a -= b; + break; + + case BPF_MUL: + a *= b; + break; + + case BPF_DIV: + if (b == 0) + bpf_error("division by zero"); + a /= b; + break; + + case BPF_AND: + a &= b; + break; + + case BPF_OR: + a |= b; + break; + + case BPF_LSH: + a <<= b; + break; + + case BPF_RSH: + a >>= b; + break; + + case BPF_NEG: + a = -a; + break; + + default: + abort(); + } + s->k = a; + s->code = BPF_LD|BPF_IMM; + done = 0; +} + +static inline struct slist * +this_op(s) + struct slist *s; +{ + while (s != 0 && s->s.code == NOP) + s = s->next; + return s; +} + +static void +opt_not(b) + struct block *b; +{ + struct block *tmp = JT(b); + + JT(b) = JF(b); + JF(b) = tmp; +} + +static void +opt_peep(b) + struct block *b; +{ + struct slist *s; + struct slist *next, *last; + int val; + + s = b->stmts; + if (s == 0) + return; + + last = s; + for (/*empty*/; /*empty*/; s = next) { + /* + * Skip over nops. + */ + s = this_op(s); + if (s == 0) + break; /* nothing left in the block */ + + /* + * Find the next real instruction after that one + * (skipping nops). + */ + next = this_op(s->next); + if (next == 0) + break; /* no next instruction */ + last = next; + + /* + * st M[k] --> st M[k] + * ldx M[k] tax + */ + if (s->s.code == BPF_ST && + next->s.code == (BPF_LDX|BPF_MEM) && + s->s.k == next->s.k) { + done = 0; + next->s.code = BPF_MISC|BPF_TAX; + } + /* + * ld #k --> ldx #k + * tax txa + */ + if (s->s.code == (BPF_LD|BPF_IMM) && + next->s.code == (BPF_MISC|BPF_TAX)) { + s->s.code = BPF_LDX|BPF_IMM; + next->s.code = BPF_MISC|BPF_TXA; + done = 0; + } + /* + * This is an ugly special case, but it happens + * when you say tcp[k] or udp[k] where k is a constant. + */ + if (s->s.code == (BPF_LD|BPF_IMM)) { + struct slist *add, *tax, *ild; + + /* + * Check that X isn't used on exit from this + * block (which the optimizer might cause). + * We know the code generator won't generate + * any local dependencies. + */ + if (ATOMELEM(b->out_use, X_ATOM)) + continue; + + /* + * Check that the instruction following the ldi + * is an addx, or it's an ldxms with an addx + * following it (with 0 or more nops between the + * ldxms and addx). + */ + if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B)) + add = next; + else + add = this_op(next->next); + if (add == 0 || add->s.code != (BPF_ALU|BPF_ADD|BPF_X)) + continue; + + /* + * Check that a tax follows that (with 0 or more + * nops between them). + */ + tax = this_op(add->next); + if (tax == 0 || tax->s.code != (BPF_MISC|BPF_TAX)) + continue; + + /* + * Check that an ild follows that (with 0 or more + * nops between them). + */ + ild = this_op(tax->next); + if (ild == 0 || BPF_CLASS(ild->s.code) != BPF_LD || + BPF_MODE(ild->s.code) != BPF_IND) + continue; + /* + * We want to turn this sequence: + * + * (004) ldi #0x2 {s} + * (005) ldxms [14] {next} -- optional + * (006) addx {add} + * (007) tax {tax} + * (008) ild [x+0] {ild} + * + * into this sequence: + * + * (004) nop + * (005) ldxms [14] + * (006) nop + * (007) nop + * (008) ild [x+2] + * + * XXX We need to check that X is not + * subsequently used, because we want to change + * what'll be in it after this sequence. + * + * We know we can eliminate the accumulator + * modifications earlier in the sequence since + * it is defined by the last stmt of this sequence + * (i.e., the last statement of the sequence loads + * a value into the accumulator, so we can eliminate + * earlier operations on the accumulator). + */ + ild->s.k += s->s.k; + s->s.code = NOP; + add->s.code = NOP; + tax->s.code = NOP; + done = 0; + } + } + /* + * If the comparison at the end of a block is an equality + * comparison against a constant, and nobody uses the value + * we leave in the A register at the end of a block, and + * the operation preceding the comparison is an arithmetic + * operation, we can sometime optimize it away. + */ + if (b->s.code == (BPF_JMP|BPF_JEQ|BPF_K) && + !ATOMELEM(b->out_use, A_ATOM)) { + /* + * We can optimize away certain subtractions of the + * X register. + */ + if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X)) { + val = b->val[X_ATOM]; + if (vmap[val].is_const) { + /* + * If we have a subtract to do a comparison, + * and the X register is a known constant, + * we can merge this value into the + * comparison: + * + * sub x -> nop + * jeq #y jeq #(x+y) + */ + b->s.k += vmap[val].const_val; + last->s.code = NOP; + done = 0; + } else if (b->s.k == 0) { + /* + * If the X register isn't a constant, + * and the comparison in the test is + * against 0, we can compare with the + * X register, instead: + * + * sub x -> nop + * jeq #0 jeq x + */ + last->s.code = NOP; + b->s.code = BPF_JMP|BPF_JEQ|BPF_X; + done = 0; + } + } + /* + * Likewise, a constant subtract can be simplified: + * + * sub #x -> nop + * jeq #y -> jeq #(x+y) + */ + else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K)) { + last->s.code = NOP; + b->s.k += last->s.k; + done = 0; + } + /* + * And, similarly, a constant AND can be simplified + * if we're testing against 0, i.e.: + * + * and #k nop + * jeq #0 -> jset #k + */ + else if (last->s.code == (BPF_ALU|BPF_AND|BPF_K) && + b->s.k == 0) { + b->s.k = last->s.k; + b->s.code = BPF_JMP|BPF_K|BPF_JSET; + last->s.code = NOP; + done = 0; + opt_not(b); + } + } + /* + * jset #0 -> never + * jset #ffffffff -> always + */ + if (b->s.code == (BPF_JMP|BPF_K|BPF_JSET)) { + if (b->s.k == 0) + JT(b) = JF(b); + if (b->s.k == 0xffffffff) + JF(b) = JT(b); + } + /* + * If the accumulator is a known constant, we can compute the + * comparison result. + */ + val = b->val[A_ATOM]; + if (vmap[val].is_const && BPF_SRC(b->s.code) == BPF_K) { + bpf_int32 v = vmap[val].const_val; + switch (BPF_OP(b->s.code)) { + + case BPF_JEQ: + v = v == b->s.k; + break; + + case BPF_JGT: + v = (unsigned)v > b->s.k; + break; + + case BPF_JGE: + v = (unsigned)v >= b->s.k; + break; + + case BPF_JSET: + v &= b->s.k; + break; + + default: + abort(); + } + if (JF(b) != JT(b)) + done = 0; + if (v) + JF(b) = JT(b); + else + JT(b) = JF(b); + } +} + +/* + * Compute the symbolic value of expression of 's', and update + * anything it defines in the value table 'val'. If 'alter' is true, + * do various optimizations. This code would be cleaner if symbolic + * evaluation and code transformations weren't folded together. + */ +static void +opt_stmt(s, val, alter) + struct stmt *s; + int val[]; + int alter; +{ + int op; + int v; + + switch (s->code) { + + case BPF_LD|BPF_ABS|BPF_W: + case BPF_LD|BPF_ABS|BPF_H: + case BPF_LD|BPF_ABS|BPF_B: + v = F(s->code, s->k, 0L); + vstore(s, &val[A_ATOM], v, alter); + break; + + case BPF_LD|BPF_IND|BPF_W: + case BPF_LD|BPF_IND|BPF_H: + case BPF_LD|BPF_IND|BPF_B: + v = val[X_ATOM]; + if (alter && vmap[v].is_const) { + s->code = BPF_LD|BPF_ABS|BPF_SIZE(s->code); + s->k += vmap[v].const_val; + v = F(s->code, s->k, 0L); + done = 0; + } + else + v = F(s->code, s->k, v); + vstore(s, &val[A_ATOM], v, alter); + break; + + case BPF_LD|BPF_LEN: + v = F(s->code, 0L, 0L); + vstore(s, &val[A_ATOM], v, alter); + break; + + case BPF_LD|BPF_IMM: + v = K(s->k); + vstore(s, &val[A_ATOM], v, alter); + break; + + case BPF_LDX|BPF_IMM: + v = K(s->k); + vstore(s, &val[X_ATOM], v, alter); + break; + + case BPF_LDX|BPF_MSH|BPF_B: + v = F(s->code, s->k, 0L); + vstore(s, &val[X_ATOM], v, alter); + break; + + case BPF_ALU|BPF_NEG: + if (alter && vmap[val[A_ATOM]].is_const) { + s->code = BPF_LD|BPF_IMM; + s->k = -vmap[val[A_ATOM]].const_val; + val[A_ATOM] = K(s->k); + } + else + val[A_ATOM] = F(s->code, val[A_ATOM], 0L); + break; + + case BPF_ALU|BPF_ADD|BPF_K: + case BPF_ALU|BPF_SUB|BPF_K: + case BPF_ALU|BPF_MUL|BPF_K: + case BPF_ALU|BPF_DIV|BPF_K: + case BPF_ALU|BPF_AND|BPF_K: + case BPF_ALU|BPF_OR|BPF_K: + case BPF_ALU|BPF_LSH|BPF_K: + case BPF_ALU|BPF_RSH|BPF_K: + op = BPF_OP(s->code); + if (alter) { + if (s->k == 0) { + /* don't optimize away "sub #0" + * as it may be needed later to + * fixup the generated math code */ + if (op == BPF_ADD || + op == BPF_LSH || op == BPF_RSH || + op == BPF_OR) { + s->code = NOP; + break; + } + if (op == BPF_MUL || op == BPF_AND) { + s->code = BPF_LD|BPF_IMM; + val[A_ATOM] = K(s->k); + break; + } + } + if (vmap[val[A_ATOM]].is_const) { + fold_op(s, val[A_ATOM], K(s->k)); + val[A_ATOM] = K(s->k); + break; + } + } + val[A_ATOM] = F(s->code, val[A_ATOM], K(s->k)); + break; + + case BPF_ALU|BPF_ADD|BPF_X: + case BPF_ALU|BPF_SUB|BPF_X: + case BPF_ALU|BPF_MUL|BPF_X: + case BPF_ALU|BPF_DIV|BPF_X: + case BPF_ALU|BPF_AND|BPF_X: + case BPF_ALU|BPF_OR|BPF_X: + case BPF_ALU|BPF_LSH|BPF_X: + case BPF_ALU|BPF_RSH|BPF_X: + op = BPF_OP(s->code); + if (alter && vmap[val[X_ATOM]].is_const) { + if (vmap[val[A_ATOM]].is_const) { + fold_op(s, val[A_ATOM], val[X_ATOM]); + val[A_ATOM] = K(s->k); + } + else { + s->code = BPF_ALU|BPF_K|op; + s->k = vmap[val[X_ATOM]].const_val; + done = 0; + val[A_ATOM] = + F(s->code, val[A_ATOM], K(s->k)); + } + break; + } + /* + * Check if we're doing something to an accumulator + * that is 0, and simplify. This may not seem like + * much of a simplification but it could open up further + * optimizations. + * XXX We could also check for mul by 1, etc. + */ + if (alter && vmap[val[A_ATOM]].is_const + && vmap[val[A_ATOM]].const_val == 0) { + if (op == BPF_ADD || op == BPF_OR) { + s->code = BPF_MISC|BPF_TXA; + vstore(s, &val[A_ATOM], val[X_ATOM], alter); + break; + } + else if (op == BPF_MUL || op == BPF_DIV || + op == BPF_AND || op == BPF_LSH || op == BPF_RSH) { + s->code = BPF_LD|BPF_IMM; + s->k = 0; + vstore(s, &val[A_ATOM], K(s->k), alter); + break; + } + else if (op == BPF_NEG) { + s->code = NOP; + break; + } + } + val[A_ATOM] = F(s->code, val[A_ATOM], val[X_ATOM]); + break; + + case BPF_MISC|BPF_TXA: + vstore(s, &val[A_ATOM], val[X_ATOM], alter); + break; + + case BPF_LD|BPF_MEM: + v = val[s->k]; + if (alter && vmap[v].is_const) { + s->code = BPF_LD|BPF_IMM; + s->k = vmap[v].const_val; + done = 0; + } + vstore(s, &val[A_ATOM], v, alter); + break; + + case BPF_MISC|BPF_TAX: + vstore(s, &val[X_ATOM], val[A_ATOM], alter); + break; + + case BPF_LDX|BPF_MEM: + v = val[s->k]; + if (alter && vmap[v].is_const) { + s->code = BPF_LDX|BPF_IMM; + s->k = vmap[v].const_val; + done = 0; + } + vstore(s, &val[X_ATOM], v, alter); + break; + + case BPF_ST: + vstore(s, &val[s->k], val[A_ATOM], alter); + break; + + case BPF_STX: + vstore(s, &val[s->k], val[X_ATOM], alter); + break; + } +} + +static void +deadstmt(s, last) + register struct stmt *s; + register struct stmt *last[]; +{ + register int atom; + + atom = atomuse(s); + if (atom >= 0) { + if (atom == AX_ATOM) { + last[X_ATOM] = 0; + last[A_ATOM] = 0; + } + else + last[atom] = 0; + } + atom = atomdef(s); + if (atom >= 0) { + if (last[atom]) { + done = 0; + last[atom]->code = NOP; + } + last[atom] = s; + } +} + +static void +opt_deadstores(b) + register struct block *b; +{ + register struct slist *s; + register int atom; + struct stmt *last[N_ATOMS]; + + memset((char *)last, 0, sizeof last); + + for (s = b->stmts; s != 0; s = s->next) + deadstmt(&s->s, last); + deadstmt(&b->s, last); + + for (atom = 0; atom < N_ATOMS; ++atom) + if (last[atom] && !ATOMELEM(b->out_use, atom)) { + last[atom]->code = NOP; + done = 0; + } +} + +static void +opt_blk(b, do_stmts) + struct block *b; + int do_stmts; +{ + struct slist *s; + struct edge *p; + int i; + bpf_int32 aval, xval; + +#if 0 + for (s = b->stmts; s && s->next; s = s->next) + if (BPF_CLASS(s->s.code) == BPF_JMP) { + do_stmts = 0; + break; + } +#endif + + /* + * Initialize the atom values. + */ + p = b->in_edges; + if (p == 0) { + /* + * We have no predecessors, so everything is undefined + * upon entry to this block. + */ + memset((char *)b->val, 0, sizeof(b->val)); + } else { + /* + * Inherit values from our predecessors. + * + * First, get the values from the predecessor along the + * first edge leading to this node. + */ + memcpy((char *)b->val, (char *)p->pred->val, sizeof(b->val)); + /* + * Now look at all the other nodes leading to this node. + * If, for the predecessor along that edge, a register + * has a different value from the one we have (i.e., + * control paths are merging, and the merging paths + * assign different values to that register), give the + * register the undefined value of 0. + */ + while ((p = p->next) != NULL) { + for (i = 0; i < N_ATOMS; ++i) + if (b->val[i] != p->pred->val[i]) + b->val[i] = 0; + } + } + aval = b->val[A_ATOM]; + xval = b->val[X_ATOM]; + for (s = b->stmts; s; s = s->next) + opt_stmt(&s->s, b->val, do_stmts); + + /* + * This is a special case: if we don't use anything from this + * block, and we load the accumulator or index register with a + * value that is already there, or if this block is a return, + * eliminate all the statements. + * + * XXX - what if it does a store? + * + * XXX - why does it matter whether we use anything from this + * block? If the accumulator or index register doesn't change + * its value, isn't that OK even if we use that value? + * + * XXX - if we load the accumulator with a different value, + * and the block ends with a conditional branch, we obviously + * can't eliminate it, as the branch depends on that value. + * For the index register, the conditional branch only depends + * on the index register value if the test is against the index + * register value rather than a constant; if nothing uses the + * value we put into the index register, and we're not testing + * against the index register's value, and there aren't any + * other problems that would keep us from eliminating this + * block, can we eliminate it? + */ + if (do_stmts && + ((b->out_use == 0 && aval != 0 && b->val[A_ATOM] == aval && + xval != 0 && b->val[X_ATOM] == xval) || + BPF_CLASS(b->s.code) == BPF_RET)) { + if (b->stmts != 0) { + b->stmts = 0; + done = 0; + } + } else { + opt_peep(b); + opt_deadstores(b); + } + /* + * Set up values for branch optimizer. + */ + if (BPF_SRC(b->s.code) == BPF_K) + b->oval = K(b->s.k); + else + b->oval = b->val[X_ATOM]; + b->et.code = b->s.code; + b->ef.code = -b->s.code; +} + +/* + * Return true if any register that is used on exit from 'succ', has + * an exit value that is different from the corresponding exit value + * from 'b'. + */ +static int +use_conflict(b, succ) + struct block *b, *succ; +{ + int atom; + atomset use = succ->out_use; + + if (use == 0) + return 0; + + for (atom = 0; atom < N_ATOMS; ++atom) + if (ATOMELEM(use, atom)) + if (b->val[atom] != succ->val[atom]) + return 1; + return 0; +} + +static struct block * +fold_edge(child, ep) + struct block *child; + struct edge *ep; +{ + int sense; + int aval0, aval1, oval0, oval1; + int code = ep->code; + + if (code < 0) { + code = -code; + sense = 0; + } else + sense = 1; + + if (child->s.code != code) + return 0; + + aval0 = child->val[A_ATOM]; + oval0 = child->oval; + aval1 = ep->pred->val[A_ATOM]; + oval1 = ep->pred->oval; + + if (aval0 != aval1) + return 0; + + if (oval0 == oval1) + /* + * The operands of the branch instructions are + * identical, so the result is true if a true + * branch was taken to get here, otherwise false. + */ + return sense ? JT(child) : JF(child); + + if (sense && code == (BPF_JMP|BPF_JEQ|BPF_K)) + /* + * At this point, we only know the comparison if we + * came down the true branch, and it was an equality + * comparison with a constant. + * + * I.e., if we came down the true branch, and the branch + * was an equality comparison with a constant, we know the + * accumulator contains that constant. If we came down + * the false branch, or the comparison wasn't with a + * constant, we don't know what was in the accumulator. + * + * We rely on the fact that distinct constants have distinct + * value numbers. + */ + return JF(child); + + return 0; +} + +static void +opt_j(ep) + struct edge *ep; +{ + register int i, k; + register struct block *target; + + if (JT(ep->succ) == 0) + return; + + if (JT(ep->succ) == JF(ep->succ)) { + /* + * Common branch targets can be eliminated, provided + * there is no data dependency. + */ + if (!use_conflict(ep->pred, ep->succ->et.succ)) { + done = 0; + ep->succ = JT(ep->succ); + } + } + /* + * For each edge dominator that matches the successor of this + * edge, promote the edge successor to the its grandchild. + * + * XXX We violate the set abstraction here in favor a reasonably + * efficient loop. + */ + top: + for (i = 0; i < edgewords; ++i) { + register bpf_u_int32 x = ep->edom[i]; + + while (x != 0) { + k = ffs(x) - 1; + x &=~ (1 << k); + k += i * BITS_PER_WORD; + + target = fold_edge(ep->succ, edges[k]); + /* + * Check that there is no data dependency between + * nodes that will be violated if we move the edge. + */ + if (target != 0 && !use_conflict(ep->pred, target)) { + done = 0; + ep->succ = target; + if (JT(target) != 0) + /* + * Start over unless we hit a leaf. + */ + goto top; + return; + } + } + } +} + + +static void +or_pullup(b) + struct block *b; +{ + int val, at_top; + struct block *pull; + struct block **diffp, **samep; + struct edge *ep; + + ep = b->in_edges; + if (ep == 0) + return; + + /* + * Make sure each predecessor loads the same value. + * XXX why? + */ + val = ep->pred->val[A_ATOM]; + for (ep = ep->next; ep != 0; ep = ep->next) + if (val != ep->pred->val[A_ATOM]) + return; + + if (JT(b->in_edges->pred) == b) + diffp = &JT(b->in_edges->pred); + else + diffp = &JF(b->in_edges->pred); + + at_top = 1; + while (1) { + if (*diffp == 0) + return; + + if (JT(*diffp) != JT(b)) + return; + + if (!SET_MEMBER((*diffp)->dom, b->id)) + return; + + if ((*diffp)->val[A_ATOM] != val) + break; + + diffp = &JF(*diffp); + at_top = 0; + } + samep = &JF(*diffp); + while (1) { + if (*samep == 0) + return; + + if (JT(*samep) != JT(b)) + return; + + if (!SET_MEMBER((*samep)->dom, b->id)) + return; + + if ((*samep)->val[A_ATOM] == val) + break; + + /* XXX Need to check that there are no data dependencies + between dp0 and dp1. Currently, the code generator + will not produce such dependencies. */ + samep = &JF(*samep); + } +#ifdef notdef + /* XXX This doesn't cover everything. */ + for (i = 0; i < N_ATOMS; ++i) + if ((*samep)->val[i] != pred->val[i]) + return; +#endif + /* Pull up the node. */ + pull = *samep; + *samep = JF(pull); + JF(pull) = *diffp; + + /* + * At the top of the chain, each predecessor needs to point at the + * pulled up node. Inside the chain, there is only one predecessor + * to worry about. + */ + if (at_top) { + for (ep = b->in_edges; ep != 0; ep = ep->next) { + if (JT(ep->pred) == b) + JT(ep->pred) = pull; + else + JF(ep->pred) = pull; + } + } + else + *diffp = pull; + + done = 0; +} + +static void +and_pullup(b) + struct block *b; +{ + int val, at_top; + struct block *pull; + struct block **diffp, **samep; + struct edge *ep; + + ep = b->in_edges; + if (ep == 0) + return; + + /* + * Make sure each predecessor loads the same value. + */ + val = ep->pred->val[A_ATOM]; + for (ep = ep->next; ep != 0; ep = ep->next) + if (val != ep->pred->val[A_ATOM]) + return; + + if (JT(b->in_edges->pred) == b) + diffp = &JT(b->in_edges->pred); + else + diffp = &JF(b->in_edges->pred); + + at_top = 1; + while (1) { + if (*diffp == 0) + return; + + if (JF(*diffp) != JF(b)) + return; + + if (!SET_MEMBER((*diffp)->dom, b->id)) + return; + + if ((*diffp)->val[A_ATOM] != val) + break; + + diffp = &JT(*diffp); + at_top = 0; + } + samep = &JT(*diffp); + while (1) { + if (*samep == 0) + return; + + if (JF(*samep) != JF(b)) + return; + + if (!SET_MEMBER((*samep)->dom, b->id)) + return; + + if ((*samep)->val[A_ATOM] == val) + break; + + /* XXX Need to check that there are no data dependencies + between diffp and samep. Currently, the code generator + will not produce such dependencies. */ + samep = &JT(*samep); + } +#ifdef notdef + /* XXX This doesn't cover everything. */ + for (i = 0; i < N_ATOMS; ++i) + if ((*samep)->val[i] != pred->val[i]) + return; +#endif + /* Pull up the node. */ + pull = *samep; + *samep = JT(pull); + JT(pull) = *diffp; + + /* + * At the top of the chain, each predecessor needs to point at the + * pulled up node. Inside the chain, there is only one predecessor + * to worry about. + */ + if (at_top) { + for (ep = b->in_edges; ep != 0; ep = ep->next) { + if (JT(ep->pred) == b) + JT(ep->pred) = pull; + else + JF(ep->pred) = pull; + } + } + else + *diffp = pull; + + done = 0; +} + +static void +opt_blks(root, do_stmts) + struct block *root; + int do_stmts; +{ + int i, maxlevel; + struct block *p; + + init_val(); + maxlevel = root->level; + + find_inedges(root); + for (i = maxlevel; i >= 0; --i) + for (p = levels[i]; p; p = p->link) + opt_blk(p, do_stmts); + + if (do_stmts) + /* + * No point trying to move branches; it can't possibly + * make a difference at this point. + */ + return; + + for (i = 1; i <= maxlevel; ++i) { + for (p = levels[i]; p; p = p->link) { + opt_j(&p->et); + opt_j(&p->ef); + } + } + + find_inedges(root); + for (i = 1; i <= maxlevel; ++i) { + for (p = levels[i]; p; p = p->link) { + or_pullup(p); + and_pullup(p); + } + } +} + +static inline void +link_inedge(parent, child) + struct edge *parent; + struct block *child; +{ + parent->next = child->in_edges; + child->in_edges = parent; +} + +static void +find_inedges(root) + struct block *root; +{ + int i; + struct block *b; + + for (i = 0; i < n_blocks; ++i) + blocks[i]->in_edges = 0; + + /* + * Traverse the graph, adding each edge to the predecessor + * list of its successors. Skip the leaves (i.e. level 0). + */ + for (i = root->level; i > 0; --i) { + for (b = levels[i]; b != 0; b = b->link) { + link_inedge(&b->et, JT(b)); + link_inedge(&b->ef, JF(b)); + } + } +} + +static void +opt_root(b) + struct block **b; +{ + struct slist *tmp, *s; + + s = (*b)->stmts; + (*b)->stmts = 0; + while (BPF_CLASS((*b)->s.code) == BPF_JMP && JT(*b) == JF(*b)) + *b = JT(*b); + + tmp = (*b)->stmts; + if (tmp != 0) + sappend(s, tmp); + (*b)->stmts = s; + + /* + * If the root node is a return, then there is no + * point executing any statements (since the bpf machine + * has no side effects). + */ + if (BPF_CLASS((*b)->s.code) == BPF_RET) + (*b)->stmts = 0; +} + +static void +opt_loop(root, do_stmts) + struct block *root; + int do_stmts; +{ + +#ifdef BDEBUG + if (dflag > 1) { + printf("opt_loop(root, %d) begin\n", do_stmts); + opt_dump(root); + } +#endif + do { + done = 1; + find_levels(root); + find_dom(root); + find_closure(root); + find_ud(root); + find_edom(root); + opt_blks(root, do_stmts); +#ifdef BDEBUG + if (dflag > 1) { + printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, done); + opt_dump(root); + } +#endif + } while (!done); +} + +/* + * Optimize the filter code in its dag representation. + */ +void +bpf_optimize(rootp) + struct block **rootp; +{ + struct block *root; + + root = *rootp; + + opt_init(root); + opt_loop(root, 0); + opt_loop(root, 1); + intern_blocks(root); +#ifdef BDEBUG + if (dflag > 1) { + printf("after intern_blocks()\n"); + opt_dump(root); + } +#endif + opt_root(rootp); +#ifdef BDEBUG + if (dflag > 1) { + printf("after opt_root()\n"); + opt_dump(root); + } +#endif + opt_cleanup(); +} + +static void +make_marks(p) + struct block *p; +{ + if (!isMarked(p)) { + Mark(p); + if (BPF_CLASS(p->s.code) != BPF_RET) { + make_marks(JT(p)); + make_marks(JF(p)); + } + } +} + +/* + * Mark code array such that isMarked(i) is true + * only for nodes that are alive. + */ +static void +mark_code(p) + struct block *p; +{ + cur_mark += 1; + make_marks(p); +} + +/* + * True iff the two stmt lists load the same value from the packet into + * the accumulator. + */ +static int +eq_slist(x, y) + struct slist *x, *y; +{ + while (1) { + while (x && x->s.code == NOP) + x = x->next; + while (y && y->s.code == NOP) + y = y->next; + if (x == 0) + return y == 0; + if (y == 0) + return x == 0; + if (x->s.code != y->s.code || x->s.k != y->s.k) + return 0; + x = x->next; + y = y->next; + } +} + +static inline int +eq_blk(b0, b1) + struct block *b0, *b1; +{ + if (b0->s.code == b1->s.code && + b0->s.k == b1->s.k && + b0->et.succ == b1->et.succ && + b0->ef.succ == b1->ef.succ) + return eq_slist(b0->stmts, b1->stmts); + return 0; +} + +static void +intern_blocks(root) + struct block *root; +{ + struct block *p; + int i, j; + int done; + top: + done = 1; + for (i = 0; i < n_blocks; ++i) + blocks[i]->link = 0; + + mark_code(root); + + for (i = n_blocks - 1; --i >= 0; ) { + if (!isMarked(blocks[i])) + continue; + for (j = i + 1; j < n_blocks; ++j) { + if (!isMarked(blocks[j])) + continue; + if (eq_blk(blocks[i], blocks[j])) { + blocks[i]->link = blocks[j]->link ? + blocks[j]->link : blocks[j]; + break; + } + } + } + for (i = 0; i < n_blocks; ++i) { + p = blocks[i]; + if (JT(p) == 0) + continue; + if (JT(p)->link) { + done = 0; + JT(p) = JT(p)->link; + } + if (JF(p)->link) { + done = 0; + JF(p) = JF(p)->link; + } + } + if (!done) + goto top; +} + +static void +opt_cleanup() +{ + free((void *)vnode_base); + free((void *)vmap); + free((void *)edges); + free((void *)space); + free((void *)levels); + free((void *)blocks); +} + +/* + * Return the number of stmts in 's'. + */ +static int +slength(s) + struct slist *s; +{ + int n = 0; + + for (; s; s = s->next) + if (s->s.code != NOP) + ++n; + return n; +} + +/* + * Return the number of nodes reachable by 'p'. + * All nodes should be initially unmarked. + */ +static int +count_blocks(p) + struct block *p; +{ + if (p == 0 || isMarked(p)) + return 0; + Mark(p); + return count_blocks(JT(p)) + count_blocks(JF(p)) + 1; +} + +/* + * Do a depth first search on the flow graph, numbering the + * the basic blocks, and entering them into the 'blocks' array.` + */ +static void +number_blks_r(p) + struct block *p; +{ + int n; + + if (p == 0 || isMarked(p)) + return; + + Mark(p); + n = n_blocks++; + p->id = n; + blocks[n] = p; + + number_blks_r(JT(p)); + number_blks_r(JF(p)); +} + +/* + * Return the number of stmts in the flowgraph reachable by 'p'. + * The nodes should be unmarked before calling. + * + * Note that "stmts" means "instructions", and that this includes + * + * side-effect statements in 'p' (slength(p->stmts)); + * + * statements in the true branch from 'p' (count_stmts(JT(p))); + * + * statements in the false branch from 'p' (count_stmts(JF(p))); + * + * the conditional jump itself (1); + * + * an extra long jump if the true branch requires it (p->longjt); + * + * an extra long jump if the false branch requires it (p->longjf). + */ +static int +count_stmts(p) + struct block *p; +{ + int n; + + if (p == 0 || isMarked(p)) + return 0; + Mark(p); + n = count_stmts(JT(p)) + count_stmts(JF(p)); + return slength(p->stmts) + n + 1 + p->longjt + p->longjf; +} + +/* + * Allocate memory. All allocation is done before optimization + * is begun. A linear bound on the size of all data structures is computed + * from the total number of blocks and/or statements. + */ +static void +opt_init(root) + struct block *root; +{ + bpf_u_int32 *p; + int i, n, max_stmts; + + /* + * First, count the blocks, so we can malloc an array to map + * block number to block. Then, put the blocks into the array. + */ + unMarkAll(); + n = count_blocks(root); + blocks = (struct block **)malloc(n * sizeof(*blocks)); + if (blocks == NULL) + bpf_error("malloc"); + unMarkAll(); + n_blocks = 0; + number_blks_r(root); + + n_edges = 2 * n_blocks; + edges = (struct edge **)malloc(n_edges * sizeof(*edges)); + if (edges == NULL) + bpf_error("malloc"); + + /* + * The number of levels is bounded by the number of nodes. + */ + levels = (struct block **)malloc(n_blocks * sizeof(*levels)); + if (levels == NULL) + bpf_error("malloc"); + + edgewords = n_edges / (8 * sizeof(bpf_u_int32)) + 1; + nodewords = n_blocks / (8 * sizeof(bpf_u_int32)) + 1; + + /* XXX */ + space = (bpf_u_int32 *)malloc(2 * n_blocks * nodewords * sizeof(*space) + + n_edges * edgewords * sizeof(*space)); + if (space == NULL) + bpf_error("malloc"); + p = space; + all_dom_sets = p; + for (i = 0; i < n; ++i) { + blocks[i]->dom = p; + p += nodewords; + } + all_closure_sets = p; + for (i = 0; i < n; ++i) { + blocks[i]->closure = p; + p += nodewords; + } + all_edge_sets = p; + for (i = 0; i < n; ++i) { + register struct block *b = blocks[i]; + + b->et.edom = p; + p += edgewords; + b->ef.edom = p; + p += edgewords; + b->et.id = i; + edges[i] = &b->et; + b->ef.id = n_blocks + i; + edges[n_blocks + i] = &b->ef; + b->et.pred = b; + b->ef.pred = b; + } + max_stmts = 0; + for (i = 0; i < n; ++i) + max_stmts += slength(blocks[i]->stmts) + 1; + /* + * We allocate at most 3 value numbers per statement, + * so this is an upper bound on the number of valnodes + * we'll need. + */ + maxval = 3 * max_stmts; + vmap = (struct vmapinfo *)malloc(maxval * sizeof(*vmap)); + vnode_base = (struct valnode *)malloc(maxval * sizeof(*vnode_base)); + if (vmap == NULL || vnode_base == NULL) + bpf_error("malloc"); +} + +/* + * Some pointers used to convert the basic block form of the code, + * into the array form that BPF requires. 'fstart' will point to + * the malloc'd array while 'ftail' is used during the recursive traversal. + */ +static struct bpf_insn *fstart; +static struct bpf_insn *ftail; + +#ifdef BDEBUG +int bids[1000]; +#endif + +/* + * Returns true if successful. Returns false if a branch has + * an offset that is too large. If so, we have marked that + * branch so that on a subsequent iteration, it will be treated + * properly. + */ +static int +convert_code_r(p) + struct block *p; +{ + struct bpf_insn *dst; + struct slist *src; + int slen; + u_int off; + int extrajmps; /* number of extra jumps inserted */ + struct slist **offset = NULL; + + if (p == 0 || isMarked(p)) + return (1); + Mark(p); + + if (convert_code_r(JF(p)) == 0) + return (0); + if (convert_code_r(JT(p)) == 0) + return (0); + + slen = slength(p->stmts); + dst = ftail -= (slen + 1 + p->longjt + p->longjf); + /* inflate length by any extra jumps */ + + p->offset = dst - fstart; + + /* generate offset[] for convenience */ + if (slen) { + offset = (struct slist **)calloc(slen, sizeof(struct slist *)); + if (!offset) { + bpf_error("not enough core"); + /*NOTREACHED*/ + } + } + src = p->stmts; + for (off = 0; off < slen && src; off++) { +#if 0 + printf("off=%d src=%x\n", off, src); +#endif + offset[off] = src; + src = src->next; + } + + off = 0; + for (src = p->stmts; src; src = src->next) { + if (src->s.code == NOP) + continue; + dst->code = (u_short)src->s.code; + dst->k = src->s.k; + + /* fill block-local relative jump */ + if (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == (BPF_JMP|BPF_JA)) { +#if 0 + if (src->s.jt || src->s.jf) { + bpf_error("illegal jmp destination"); + /*NOTREACHED*/ + } +#endif + goto filled; + } + if (off == slen - 2) /*???*/ + goto filled; + + { + int i; + int jt, jf; + char *ljerr = "%s for block-local relative jump: off=%d"; + +#if 0 + printf("code=%x off=%d %x %x\n", src->s.code, + off, src->s.jt, src->s.jf); +#endif + + if (!src->s.jt || !src->s.jf) { + bpf_error(ljerr, "no jmp destination", off); + /*NOTREACHED*/ + } + + jt = jf = 0; + for (i = 0; i < slen; i++) { + if (offset[i] == src->s.jt) { + if (jt) { + bpf_error(ljerr, "multiple matches", off); + /*NOTREACHED*/ + } + + dst->jt = i - off - 1; + jt++; + } + if (offset[i] == src->s.jf) { + if (jf) { + bpf_error(ljerr, "multiple matches", off); + /*NOTREACHED*/ + } + dst->jf = i - off - 1; + jf++; + } + } + if (!jt || !jf) { + bpf_error(ljerr, "no destination found", off); + /*NOTREACHED*/ + } + } +filled: + ++dst; + ++off; + } + if (offset) + free(offset); + +#ifdef BDEBUG + bids[dst - fstart] = p->id + 1; +#endif + dst->code = (u_short)p->s.code; + dst->k = p->s.k; + if (JT(p)) { + extrajmps = 0; + off = JT(p)->offset - (p->offset + slen) - 1; + if (off >= 256) { + /* offset too large for branch, must add a jump */ + if (p->longjt == 0) { + /* mark this instruction and retry */ + p->longjt++; + return(0); + } + /* branch if T to following jump */ + dst->jt = extrajmps; + extrajmps++; + dst[extrajmps].code = BPF_JMP|BPF_JA; + dst[extrajmps].k = off - extrajmps; + } + else + dst->jt = off; + off = JF(p)->offset - (p->offset + slen) - 1; + if (off >= 256) { + /* offset too large for branch, must add a jump */ + if (p->longjf == 0) { + /* mark this instruction and retry */ + p->longjf++; + return(0); + } + /* branch if F to following jump */ + /* if two jumps are inserted, F goes to second one */ + dst->jf = extrajmps; + extrajmps++; + dst[extrajmps].code = BPF_JMP|BPF_JA; + dst[extrajmps].k = off - extrajmps; + } + else + dst->jf = off; + } + return (1); +} + + +/* + * Convert flowgraph intermediate representation to the + * BPF array representation. Set *lenp to the number of instructions. + */ +struct bpf_insn * +icode_to_fcode(root, lenp) + struct block *root; + int *lenp; +{ + int n; + struct bpf_insn *fp; + + /* + * Loop doing convert_code_r() until no branches remain + * with too-large offsets. + */ + while (1) { + unMarkAll(); + n = *lenp = count_stmts(root); + + fp = (struct bpf_insn *)malloc(sizeof(*fp) * n); + if (fp == NULL) + bpf_error("malloc"); + memset((char *)fp, 0, sizeof(*fp) * n); + fstart = fp; + ftail = fp + n; + + unMarkAll(); + if (convert_code_r(root)) + break; + free(fp); + } + + return fp; +} + +/* + * Make a copy of a BPF program and put it in the "fcode" member of + * a "pcap_t". + * + * If we fail to allocate memory for the copy, fill in the "errbuf" + * member of the "pcap_t" with an error message, and return -1; + * otherwise, return 0. + */ +int +install_bpf_program(pcap_t *p, struct bpf_program *fp) +{ + size_t prog_size; + + /* + * Free up any already installed program. + */ + pcap_freecode(&p->fcode); + + prog_size = sizeof(*fp->bf_insns) * fp->bf_len; + p->fcode.bf_len = fp->bf_len; + p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size); + if (p->fcode.bf_insns == NULL) { + snprintf(p->errbuf, sizeof(p->errbuf), + "malloc: %s", pcap_strerror(errno)); + return (-1); + } + memcpy(p->fcode.bf_insns, fp->bf_insns, prog_size); + return (0); +} + +#ifdef BDEBUG +static void +opt_dump(root) + struct block *root; +{ + struct bpf_program f; + + memset(bids, 0, sizeof bids); + f.bf_insns = icode_to_fcode(root, &f.bf_len); + bpf_dump(&f, 1); + putchar('\n'); + free((char *)f.bf_insns); +} +#endif diff --git a/winpcap/wpcap/libpcap/packaging/pcap.spec b/winpcap/wpcap/libpcap/packaging/pcap.spec new file mode 100644 index 0000000..7df7abc --- /dev/null +++ b/winpcap/wpcap/libpcap/packaging/pcap.spec @@ -0,0 +1,65 @@ +%define prefix /usr +%define version 0.9.4 + +Summary: packet capture library +Name: libpcap +Version: %version +Release: 1 +Group: Development/Libraries +Copyright: BSD +Source: libpcap-0.9.4.tar.gz +BuildRoot: /tmp/%{name}-buildroot +URL: http://www.tcpdump.org + +%description +Packet-capture library LIBPCAP 0.9.4 +Now maintained by "The Tcpdump Group" +See http://www.tcpdump.org +Please send inquiries/comments/reports to tcpdump-workers@tcpdump.org + +%prep +%setup + +%post +ldconfig + +%build +CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%prefix +make + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/usr/{lib,include} +mkdir -p $RPM_BUILD_ROOT/usr/share/man +mkdir -p $RPM_BUILD_ROOT/usr/include/net +mkdir -p $RPM_BUILD_ROOT/usr/man/man3 +make install DESTDIR=$RPM_BUILD_ROOT mandir=/usr/share/man +cd $RPM_BUILD_ROOT/usr/lib +V1=`echo 0.9.4 | sed 's/\\.[^\.]*$//g'` +V2=`echo 0.9.4 | sed 's/\\.[^\.]*\.[^\.]*$//g'` +ln -sf libpcap.so.0.9.4 libpcap.so.$V1 +if test "$V2" -ne "$V1"; then + ln -sf libpcap.so.$V1 libpcap.so.$V2 + ln -sf libpcap.so.$V2 libpcap.so +else + ln -sf libpcap.so.$V1 libpcap.so +fi + +#install -m 755 -o root libpcap.a $RPM_BUILD_ROOT/usr/lib +#install -m 644 -o root pcap.3 $RPM_BUILD_ROOT/usr/man/man3 +#install -m 644 -o root pcap.h $RPM_BUILD_ROOT/usr/include +#install -m 644 -o root pcap-bpf.h $RPM_BUILD_ROOT/usr/include/net +#install -m 644 -o root pcap-namedb.h $RPM_BUILD_ROOT/usr/include + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%doc LICENSE CHANGES INSTALL.txt README.linux TODO VERSION CREDITS packaging/pcap.spec +/usr/lib/libpcap.a +/usr/share/man/man3/* +/usr/include/pcap.h +/usr/include/pcap-bpf.h +/usr/include/pcap-namedb.h +/usr/lib/libpcap.so* diff --git a/winpcap/wpcap/libpcap/packaging/pcap.spec.in b/winpcap/wpcap/libpcap/packaging/pcap.spec.in new file mode 100644 index 0000000..388427e --- /dev/null +++ b/winpcap/wpcap/libpcap/packaging/pcap.spec.in @@ -0,0 +1,65 @@ +%define prefix /usr +%define version @VERSION@ + +Summary: packet capture library +Name: libpcap +Version: %version +Release: 1 +Group: Development/Libraries +Copyright: BSD +Source: @NAME@.tar.gz +BuildRoot: /tmp/%{name}-buildroot +URL: http://www.tcpdump.org + +%description +Packet-capture library LIBPCAP @VERSION@ +Now maintained by "The Tcpdump Group" +See http://www.tcpdump.org +Please send inquiries/comments/reports to tcpdump-workers@tcpdump.org + +%prep +%setup + +%post +ldconfig + +%build +CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%prefix +make + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/usr/{lib,include} +mkdir -p $RPM_BUILD_ROOT/usr/share/man +mkdir -p $RPM_BUILD_ROOT/usr/include/net +mkdir -p $RPM_BUILD_ROOT/usr/man/man3 +make install DESTDIR=$RPM_BUILD_ROOT mandir=/usr/share/man +cd $RPM_BUILD_ROOT/usr/lib +V1=`echo @VERSION@ | sed 's/\\.[^\.]*$//g'` +V2=`echo @VERSION@ | sed 's/\\.[^\.]*\.[^\.]*$//g'` +ln -sf libpcap.so.@VERSION@ libpcap.so.$V1 +if test "$V2" -ne "$V1"; then + ln -sf libpcap.so.$V1 libpcap.so.$V2 + ln -sf libpcap.so.$V2 libpcap.so +else + ln -sf libpcap.so.$V1 libpcap.so +fi + +#install -m 755 -o root libpcap.a $RPM_BUILD_ROOT/usr/lib +#install -m 644 -o root pcap.3 $RPM_BUILD_ROOT/usr/man/man3 +#install -m 644 -o root pcap.h $RPM_BUILD_ROOT/usr/include +#install -m 644 -o root pcap-bpf.h $RPM_BUILD_ROOT/usr/include/net +#install -m 644 -o root pcap-namedb.h $RPM_BUILD_ROOT/usr/include + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%doc LICENSE CHANGES INSTALL.txt README.linux TODO VERSION CREDITS packaging/pcap.spec +/usr/lib/libpcap.a +/usr/share/man/man3/* +/usr/include/pcap.h +/usr/include/pcap-bpf.h +/usr/include/pcap-namedb.h +/usr/lib/libpcap.so* diff --git a/winpcap/wpcap/libpcap/pcap-bpf.c b/winpcap/wpcap/libpcap/pcap-bpf.c new file mode 100644 index 0000000..56c3db7 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-bpf.c @@ -0,0 +1,1169 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1998 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.86.2.9 2006/01/22 05:28:34 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* optionally get BSD define */ +#include +#include +#include +#include +#include +#include + +#include + +#ifdef _AIX + +/* + * Make "pcap.h" not include "pcap-bpf.h"; we are going to include the + * native OS version, as we need "struct bpf_config" from it. + */ +#define PCAP_DONT_INCLUDE_PCAP_BPF_H + +#include + +/* + * Prevent bpf.h from redefining the DLT_ values to their + * IFT_ values, as we're going to return the standard libpcap + * values, not IBM's non-standard IFT_ values. + */ +#undef _AIX +#include +#define _AIX + +#include /* for IFT_ values */ +#include +#include +#include +#include + +#ifdef __64BIT__ +#define domakedev makedev64 +#define getmajor major64 +#define bpf_hdr bpf_hdr32 +#else /* __64BIT__ */ +#define domakedev makedev +#define getmajor major +#endif /* __64BIT__ */ + +#define BPF_NAME "bpf" +#define BPF_MINORS 4 +#define DRIVER_PATH "/usr/lib/drivers" +#define BPF_NODE "/dev/bpf" +static int bpfloadedflag = 0; +static int odmlockid = 0; + +#else /* _AIX */ + +#include + +#endif /* _AIX */ + +#include +#include +#include +#include +#include +#include +#include + +#include "pcap-int.h" + +#ifdef HAVE_DAG_API +#include "pcap-dag.h" +#endif /* HAVE_DAG_API */ + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#ifdef HAVE_REMOTE +#include +#endif /* HAVE_REMOTE */ + +#include "gencode.h" /* for "no_optimize" */ + +static int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp); +static int pcap_setdirection_bpf(pcap_t *, pcap_direction_t); +static int pcap_set_datalink_bpf(pcap_t *p, int dlt); + +static int +pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps) +{ + struct bpf_stat s; + + /* + * "ps_recv" counts packets handed to the filter, not packets + * that passed the filter. This includes packets later dropped + * because we ran out of buffer space. + * + * "ps_drop" counts packets dropped inside the BPF device + * because we ran out of buffer space. It doesn't count + * packets dropped by the interface driver. It counts + * only packets that passed the filter. + * + * Both statistics include packets not yet read from the kernel + * by libpcap, and thus not yet seen by the application. + */ + if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s", + pcap_strerror(errno)); + return (-1); + } + + ps->ps_recv = s.bs_recv; + ps->ps_drop = s.bs_drop; + return (0); +} + +static int +pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ + int cc; + int n = 0; + register u_char *bp, *ep; + u_char *datap; + struct bpf_insn *fcode; +#ifdef PCAP_FDDIPAD + register int pad; +#endif + + fcode = p->md.use_bpf ? NULL : p->fcode.bf_insns; + again: + /* + * Has "pcap_breakloop()" been called? + */ + if (p->break_loop) { + /* + * Yes - clear the flag that indicates that it + * has, and return -2 to indicate that we were + * told to break out of the loop. + */ + p->break_loop = 0; + return (-2); + } + cc = p->cc; + if (p->cc == 0) { + cc = read(p->fd, (char *)p->buffer, p->bufsize); + if (cc < 0) { + /* Don't choke when we get ptraced */ + switch (errno) { + + case EINTR: + goto again; + +#ifdef _AIX + case EFAULT: + /* + * Sigh. More AIX wonderfulness. + * + * For some unknown reason the uiomove() + * operation in the bpf kernel extension + * used to copy the buffer into user + * space sometimes returns EFAULT. I have + * no idea why this is the case given that + * a kernel debugger shows the user buffer + * is correct. This problem appears to + * be mostly mitigated by the memset of + * the buffer before it is first used. + * Very strange.... Shaun Clowes + * + * In any case this means that we shouldn't + * treat EFAULT as a fatal error; as we + * don't have an API for returning + * a "some packets were dropped since + * the last packet you saw" indication, + * we just ignore EFAULT and keep reading. + */ + goto again; +#endif + + case EWOULDBLOCK: + return (0); +#if defined(sun) && !defined(BSD) + /* + * Due to a SunOS bug, after 2^31 bytes, the kernel + * file offset overflows and read fails with EINVAL. + * The lseek() to 0 will fix things. + */ + case EINVAL: + if (lseek(p->fd, 0L, SEEK_CUR) + + p->bufsize < 0) { + (void)lseek(p->fd, 0L, SEEK_SET); + goto again; + } + /* fall through */ +#endif + } + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read: %s", + pcap_strerror(errno)); + return (-1); + } + bp = p->buffer; + } else + bp = p->bp; + + /* + * Loop through each packet. + */ +#define bhp ((struct bpf_hdr *)bp) + ep = bp + cc; +#ifdef PCAP_FDDIPAD + pad = p->fddipad; +#endif + while (bp < ep) { + register int caplen, hdrlen; + + /* + * Has "pcap_breakloop()" been called? + * If so, return immediately - if we haven't read any + * packets, clear the flag and return -2 to indicate + * that we were told to break out of the loop, otherwise + * leave the flag set, so that the *next* call will break + * out of the loop without having read any packets, and + * return the number of packets we've processed so far. + */ + if (p->break_loop) { + if (n == 0) { + p->break_loop = 0; + return (-2); + } else { + p->bp = bp; + p->cc = ep - bp; + return (n); + } + } + + caplen = bhp->bh_caplen; + hdrlen = bhp->bh_hdrlen; + datap = bp + hdrlen; + /* + * Short-circuit evaluation: if using BPF filter + * in kernel, no need to do it now. + * +#ifdef PCAP_FDDIPAD + * Note: the filter code was generated assuming + * that p->fddipad was the amount of padding + * before the header, as that's what's required + * in the kernel, so we run the filter before + * skipping that padding. +#endif + */ + if (fcode == NULL || + bpf_filter(fcode, datap, bhp->bh_datalen, caplen)) { + struct pcap_pkthdr pkthdr; + + pkthdr.ts.tv_sec = bhp->bh_tstamp.tv_sec; +#ifdef _AIX + /* + * AIX's BPF returns seconds/nanoseconds time + * stamps, not seconds/microseconds time stamps. + */ + pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec/1000; +#else + pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec; +#endif +#ifdef PCAP_FDDIPAD + if (caplen > pad) + pkthdr.caplen = caplen - pad; + else + pkthdr.caplen = 0; + if (bhp->bh_datalen > pad) + pkthdr.len = bhp->bh_datalen - pad; + else + pkthdr.len = 0; + datap += pad; +#else + pkthdr.caplen = caplen; + pkthdr.len = bhp->bh_datalen; +#endif + (*callback)(user, &pkthdr, datap); + bp += BPF_WORDALIGN(caplen + hdrlen); + if (++n >= cnt && cnt > 0) { + p->bp = bp; + p->cc = ep - bp; + return (n); + } + } else { + /* + * Skip this packet. + */ + bp += BPF_WORDALIGN(caplen + hdrlen); + } + } +#undef bhp + p->cc = 0; + return (n); +} + +static int +pcap_inject_bpf(pcap_t *p, const void *buf, size_t size) +{ + int ret; + + ret = write(p->fd, buf, size); +#ifdef __APPLE__ + if (ret == -1 && errno == EAFNOSUPPORT) { + /* + * In Mac OS X, there's a bug wherein setting the + * BIOCSHDRCMPLT flag causes writes to fail; see, + * for example: + * + * http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/BIOCSHDRCMPLT-10.3.3.patch + * + * So, if, on OS X, we get EAFNOSUPPORT from the write, we + * assume it's due to that bug, and turn off that flag + * and try again. If we succeed, it either means that + * somebody applied the fix from that URL, or other patches + * for that bug from + * + * http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/ + * + * and are running a Darwin kernel with those fixes, or + * that Apple fixed the problem in some OS X release. + */ + u_int spoof_eth_src = 0; + + if (ioctl(p->fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) { + (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "send: can't turn off BIOCSHDRCMPLT: %s", + pcap_strerror(errno)); + return (-1); + } + + /* + * Now try the write again. + */ + ret = write(p->fd, buf, size); + } +#endif /* __APPLE__ */ + if (ret == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", + pcap_strerror(errno)); + return (-1); + } + return (ret); +} + +#ifdef _AIX +static int +bpf_odminit(char *errbuf) +{ + char *errstr; + + if (odm_initialize() == -1) { + if (odm_err_msg(odmerrno, &errstr) == -1) + errstr = "Unknown error"; + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "bpf_load: odm_initialize failed: %s", + errstr); + return (-1); + } + + if ((odmlockid = odm_lock("/etc/objrepos/config_lock", ODM_WAIT)) == -1) { + if (odm_err_msg(odmerrno, &errstr) == -1) + errstr = "Unknown error"; + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "bpf_load: odm_lock of /etc/objrepos/config_lock failed: %s", + errstr); + return (-1); + } + + return (0); +} + +static int +bpf_odmcleanup(char *errbuf) +{ + char *errstr; + + if (odm_unlock(odmlockid) == -1) { + if (odm_err_msg(odmerrno, &errstr) == -1) + errstr = "Unknown error"; + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "bpf_load: odm_unlock failed: %s", + errstr); + return (-1); + } + + if (odm_terminate() == -1) { + if (odm_err_msg(odmerrno, &errstr) == -1) + errstr = "Unknown error"; + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "bpf_load: odm_terminate failed: %s", + errstr); + return (-1); + } + + return (0); +} + +static int +bpf_load(char *errbuf) +{ + long major; + int *minors; + int numminors, i, rc; + char buf[1024]; + struct stat sbuf; + struct bpf_config cfg_bpf; + struct cfg_load cfg_ld; + struct cfg_kmod cfg_km; + + /* + * This is very very close to what happens in the real implementation + * but I've fixed some (unlikely) bug situations. + */ + if (bpfloadedflag) + return (0); + + if (bpf_odminit(errbuf) != 0) + return (-1); + + major = genmajor(BPF_NAME); + if (major == -1) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "bpf_load: genmajor failed: %s", pcap_strerror(errno)); + return (-1); + } + + minors = getminor(major, &numminors, BPF_NAME); + if (!minors) { + minors = genminor("bpf", major, 0, BPF_MINORS, 1, 1); + if (!minors) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "bpf_load: genminor failed: %s", + pcap_strerror(errno)); + return (-1); + } + } + + if (bpf_odmcleanup(errbuf)) + return (-1); + + rc = stat(BPF_NODE "0", &sbuf); + if (rc == -1 && errno != ENOENT) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "bpf_load: can't stat %s: %s", + BPF_NODE "0", pcap_strerror(errno)); + return (-1); + } + + if (rc == -1 || getmajor(sbuf.st_rdev) != major) { + for (i = 0; i < BPF_MINORS; i++) { + sprintf(buf, "%s%d", BPF_NODE, i); + unlink(buf); + if (mknod(buf, S_IRUSR | S_IFCHR, domakedev(major, i)) == -1) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "bpf_load: can't mknod %s: %s", + buf, pcap_strerror(errno)); + return (-1); + } + } + } + + /* Check if the driver is loaded */ + memset(&cfg_ld, 0x0, sizeof(cfg_ld)); + cfg_ld.path = buf; + sprintf(cfg_ld.path, "%s/%s", DRIVER_PATH, BPF_NAME); + if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) || + (cfg_ld.kmid == 0)) { + /* Driver isn't loaded, load it now */ + if (sysconfig(SYS_SINGLELOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "bpf_load: could not load driver: %s", + strerror(errno)); + return (-1); + } + } + + /* Configure the driver */ + cfg_km.cmd = CFG_INIT; + cfg_km.kmid = cfg_ld.kmid; + cfg_km.mdilen = sizeof(cfg_bpf); + cfg_km.mdiptr = (void *)&cfg_bpf; + for (i = 0; i < BPF_MINORS; i++) { + cfg_bpf.devno = domakedev(major, i); + if (sysconfig(SYS_CFGKMOD, (void *)&cfg_km, sizeof(cfg_km)) == -1) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "bpf_load: could not configure driver: %s", + strerror(errno)); + return (-1); + } + } + + bpfloadedflag = 1; + + return (0); +} +#endif + +static inline int +bpf_open(pcap_t *p, char *errbuf) +{ + int fd; + int n = 0; + char device[sizeof "/dev/bpf0000000000"]; + +#ifdef _AIX + /* + * Load the bpf driver, if it isn't already loaded, + * and create the BPF device entries, if they don't + * already exist. + */ + if (bpf_load(errbuf) == -1) + return (-1); +#endif + + /* + * Go through all the minors and find one that isn't in use. + */ + do { + (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++); + /* + * Initially try a read/write open (to allow the inject + * method to work). If that fails due to permission + * issues, fall back to read-only. This allows a + * non-root user to be granted specific access to pcap + * capabilities via file permissions. + * + * XXX - we should have an API that has a flag that + * controls whether to open read-only or read-write, + * so that denial of permission to send (or inability + * to send, if sending packets isn't supported on + * the device in question) can be indicated at open + * time. + */ + fd = open(device, O_RDWR); + if (fd == -1 && errno == EACCES) + fd = open(device, O_RDONLY); + } while (fd < 0 && errno == EBUSY); + + /* + * XXX better message for all minors used + */ + if (fd < 0) + snprintf(errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s", + device, pcap_strerror(errno)); + + return (fd); +} + +/* + * We include the OS's , not our "pcap-bpf.h", so we probably + * don't get DLT_DOCSIS defined. + */ +#ifndef DLT_DOCSIS +#define DLT_DOCSIS 143 +#endif + +pcap_t * +pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, + char *ebuf) +{ + int fd; + struct ifreq ifr; + struct bpf_version bv; +#ifdef BIOCGDLTLIST + struct bpf_dltlist bdl; +#endif +#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) + u_int spoof_eth_src = 1; +#endif + u_int v; + pcap_t *p; + struct bpf_insn total_insn; + struct bpf_program total_prog; + struct utsname osinfo; + +#ifdef HAVE_REMOTE + /* + Retrofit; we have to make older applications compatible with the remote capture + So, we're calling the pcap_open_remote() from here, that is a very dirty thing. + Obviously, we cannot exploit all the new features; for instance, we cannot + send authentication, we cannot use a UDP data connection, and so on. + */ + + char host[PCAP_BUF_SIZE + 1]; + char port[PCAP_BUF_SIZE + 1]; + char name[PCAP_BUF_SIZE + 1]; + int srctype; + + if (pcap_parsesrcstr(device, &srctype, host, port, name, ebuf) ) + return NULL; + + if (srctype == PCAP_SRC_IFREMOTE) + { + p= pcap_opensource_remote(device, NULL, ebuf); + + if (p == NULL) + return NULL; + + p->snapshot= snaplen; + p->timeout= to_ms; + p->rmt_flags= (promisc) ? PCAP_OPENFLAG_PROMISCUOUS : 0; + + return p; + } +#endif /* HAVE_REMOTE */ + +#ifdef HAVE_DAG_API + if (strstr(device, "dag")) { + return dag_open_live(device, snaplen, promisc, to_ms, ebuf); + } +#endif /* HAVE_DAG_API */ + +#ifdef BIOCGDLTLIST + memset(&bdl, 0, sizeof(bdl)); +#endif + + p = (pcap_t *)malloc(sizeof(*p)); + if (p == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + return (NULL); + } + memset(p, 0, sizeof(*p)); + fd = bpf_open(p, ebuf); + if (fd < 0) + goto bad; + + p->fd = fd; + p->snapshot = snaplen; + + if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s", + pcap_strerror(errno)); + goto bad; + } + if (bv.bv_major != BPF_MAJOR_VERSION || + bv.bv_minor < BPF_MINOR_VERSION) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "kernel bpf filter out of date"); + goto bad; + } + + /* + * Try finding a good size for the buffer; 32768 may be too + * big, so keep cutting it in half until we find a size + * that works, or run out of sizes to try. If the default + * is larger, don't make it smaller. + * + * XXX - there should be a user-accessible hook to set the + * initial buffer size. + */ + if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) || v < 32768) + v = 32768; + for ( ; v != 0; v >>= 1) { + /* Ignore the return value - this is because the call fails + * on BPF systems that don't have kernel malloc. And if + * the call fails, it's no big deal, we just continue to + * use the standard buffer size. + */ + (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v); + + (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0) + break; /* that size worked; we're done */ + + if (errno != ENOBUFS) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s", + device, pcap_strerror(errno)); + goto bad; + } + } + + if (v == 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "BIOCSBLEN: %s: No buffer size worked", device); + goto bad; + } + + /* Get the data link layer type. */ + if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s", + pcap_strerror(errno)); + goto bad; + } +#ifdef _AIX + /* + * AIX's BPF returns IFF_ types, not DLT_ types, in BIOCGDLT. + */ + switch (v) { + + case IFT_ETHER: + case IFT_ISO88023: + v = DLT_EN10MB; + break; + + case IFT_FDDI: + v = DLT_FDDI; + break; + + case IFT_ISO88025: + v = DLT_IEEE802; + break; + + case IFT_LOOP: + v = DLT_NULL; + break; + + default: + /* + * We don't know what to map this to yet. + */ + snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown interface type %u", + v); + goto bad; + } +#endif +#if _BSDI_VERSION - 0 >= 199510 + /* The SLIP and PPP link layer header changed in BSD/OS 2.1 */ + switch (v) { + + case DLT_SLIP: + v = DLT_SLIP_BSDOS; + break; + + case DLT_PPP: + v = DLT_PPP_BSDOS; + break; + + case 11: /*DLT_FR*/ + v = DLT_FRELAY; + break; + + case 12: /*DLT_C_HDLC*/ + v = DLT_CHDLC; + break; + } +#endif +#ifdef PCAP_FDDIPAD + if (v == DLT_FDDI) + p->fddipad = PCAP_FDDIPAD; + else + p->fddipad = 0; +#endif + p->linktype = v; + +#ifdef BIOCGDLTLIST + /* + * We know the default link type -- now determine all the DLTs + * this interface supports. If this fails with EINVAL, it's + * not fatal; we just don't get to use the feature later. + */ + if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) == 0) { + u_int i; + int is_ethernet; + + bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * (bdl.bfl_len + 1)); + if (bdl.bfl_list == NULL) { + (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + goto bad; + } + + if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) < 0) { + (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, + "BIOCGDLTLIST: %s", pcap_strerror(errno)); + free(bdl.bfl_list); + goto bad; + } + + /* + * OK, for real Ethernet devices, add DLT_DOCSIS to the + * list, so that an application can let you choose it, + * in case you're capturing DOCSIS traffic that a Cisco + * Cable Modem Termination System is putting out onto + * an Ethernet (it doesn't put an Ethernet header onto + * the wire, it puts raw DOCSIS frames out on the wire + * inside the low-level Ethernet framing). + * + * A "real Ethernet device" is defined here as a device + * that has a link-layer type of DLT_EN10MB and that has + * no alternate link-layer types; that's done to exclude + * 802.11 interfaces (which might or might not be the + * right thing to do, but I suspect it is - Ethernet <-> + * 802.11 bridges would probably badly mishandle frames + * that don't have Ethernet headers). + */ + if (p->linktype == DLT_EN10MB) { + is_ethernet = 1; + for (i = 0; i < bdl.bfl_len; i++) { + if (bdl.bfl_list[i] != DLT_EN10MB) { + is_ethernet = 0; + break; + } + } + if (is_ethernet) { + /* + * We reserved one more slot at the end of + * the list. + */ + bdl.bfl_list[bdl.bfl_len] = DLT_DOCSIS; + bdl.bfl_len++; + } + } + p->dlt_count = bdl.bfl_len; + p->dlt_list = bdl.bfl_list; + } else { + if (errno != EINVAL) { + (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, + "BIOCGDLTLIST: %s", pcap_strerror(errno)); + goto bad; + } + } +#endif + + /* + * If this is an Ethernet device, and we don't have a DLT_ list, + * give it a list with DLT_EN10MB and DLT_DOCSIS. (That'd give + * 802.11 interfaces DLT_DOCSIS, which isn't the right thing to + * do, but there's not much we can do about that without finding + * some other way of determining whether it's an Ethernet or 802.11 + * device.) + */ + if (p->linktype == DLT_EN10MB && p->dlt_count == 0) { + p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); + /* + * If that fails, just leave the list empty. + */ + if (p->dlt_list != NULL) { + p->dlt_list[0] = DLT_EN10MB; + p->dlt_list[1] = DLT_DOCSIS; + p->dlt_count = 2; + } + } + +#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) + /* + * Do a BIOCSHDRCMPLT, if defined, to turn that flag on, so + * the link-layer source address isn't forcibly overwritten. + * (Should we ignore errors? Should we do this only if + * we're open for writing?) + * + * XXX - I seem to remember some packet-sending bug in some + * BSDs - check CVS log for "bpf.c"? + */ + if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) { + (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, + "BIOCSHDRCMPLT: %s", pcap_strerror(errno)); + goto bad; + } +#endif + /* set timeout */ + if (to_ms != 0) { + /* + * XXX - is this seconds/nanoseconds in AIX? + * (Treating it as such doesn't fix the timeout + * problem described below.) + */ + struct timeval to; + to.tv_sec = to_ms / 1000; + to.tv_usec = (to_ms * 1000) % 1000000; + if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s", + pcap_strerror(errno)); + goto bad; + } + } + +#ifdef _AIX +#ifdef BIOCIMMEDIATE + /* + * Darren Reed notes that + * + * On AIX (4.2 at least), if BIOCIMMEDIATE is not set, the + * timeout appears to be ignored and it waits until the buffer + * is filled before returning. The result of not having it + * set is almost worse than useless if your BPF filter + * is reducing things to only a few packets (i.e. one every + * second or so). + * + * so we turn BIOCIMMEDIATE mode on if this is AIX. + * + * We don't turn it on for other platforms, as that means we + * get woken up for every packet, which may not be what we want; + * in the Winter 1993 USENIX paper on BPF, they say: + * + * Since a process might want to look at every packet on a + * network and the time between packets can be only a few + * microseconds, it is not possible to do a read system call + * per packet and BPF must collect the data from several + * packets and return it as a unit when the monitoring + * application does a read. + * + * which I infer is the reason for the timeout - it means we + * wait that amount of time, in the hopes that more packets + * will arrive and we'll get them all with one read. + * + * Setting BIOCIMMEDIATE mode on FreeBSD (and probably other + * BSDs) causes the timeout to be ignored. + * + * On the other hand, some platforms (e.g., Linux) don't support + * timeouts, they just hand stuff to you as soon as it arrives; + * if that doesn't cause a problem on those platforms, it may + * be OK to have BIOCIMMEDIATE mode on BSD as well. + * + * (Note, though, that applications may depend on the read + * completing, even if no packets have arrived, when the timeout + * expires, e.g. GUI applications that have to check for input + * while waiting for packets to arrive; a non-zero timeout + * prevents "select()" from working right on FreeBSD and + * possibly other BSDs, as the timer doesn't start until a + * "read()" is done, so the timer isn't in effect if the + * application is blocked on a "select()", and the "select()" + * doesn't get woken up for a BPF device until the buffer + * fills up.) + */ + v = 1; + if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s", + pcap_strerror(errno)); + goto bad; + } +#endif /* BIOCIMMEDIATE */ +#endif /* _AIX */ + + if (promisc) { + /* set promiscuous mode, okay if it fails */ + if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s", + pcap_strerror(errno)); + } + } + + if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s", + pcap_strerror(errno)); + goto bad; + } + p->bufsize = v; + p->buffer = (u_char *)malloc(p->bufsize); + if (p->buffer == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + goto bad; + } +#ifdef _AIX + /* For some strange reason this seems to prevent the EFAULT + * problems we have experienced from AIX BPF. */ + memset(p->buffer, 0x0, p->bufsize); +#endif + + /* + * If there's no filter program installed, there's + * no indication to the kernel of what the snapshot + * length should be, so no snapshotting is done. + * + * Therefore, when we open the device, we install + * an "accept everything" filter with the specified + * snapshot length. + */ + total_insn.code = (u_short)(BPF_RET | BPF_K); + total_insn.jt = 0; + total_insn.jf = 0; + total_insn.k = snaplen; + + total_prog.bf_len = 1; + total_prog.bf_insns = &total_insn; + if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s", + pcap_strerror(errno)); + goto bad; + } + + /* + * On most BPF platforms, either you can do a "select()" or + * "poll()" on a BPF file descriptor and it works correctly, + * or you can do it and it will return "readable" if the + * hold buffer is full but not if the timeout expires *and* + * a non-blocking read will, if the hold buffer is empty + * but the store buffer isn't empty, rotate the buffers + * and return what packets are available. + * + * In the latter case, the fact that a non-blocking read + * will give you the available packets means you can work + * around the failure of "select()" and "poll()" to wake up + * and return "readable" when the timeout expires by using + * the timeout as the "select()" or "poll()" timeout, putting + * the BPF descriptor into non-blocking mode, and read from + * it regardless of whether "select()" reports it as readable + * or not. + * + * However, in FreeBSD 4.3 and 4.4, "select()" and "poll()" + * won't wake up and return "readable" if the timer expires + * and non-blocking reads return EWOULDBLOCK if the hold + * buffer is empty, even if the store buffer is non-empty. + * + * This means the workaround in question won't work. + * + * Therefore, on FreeBSD 4.3 and 4.4, we set "p->selectable_fd" + * to -1, which means "sorry, you can't use 'select()' or 'poll()' + * here". On all other BPF platforms, we set it to the FD for + * the BPF device; in NetBSD, OpenBSD, and Darwin, a non-blocking + * read will, if the hold buffer is empty and the store buffer + * isn't empty, rotate the buffers and return what packets are + * there (and in sufficiently recent versions of OpenBSD + * "select()" and "poll()" should work correctly). + * + * XXX - what about AIX? + */ + p->selectable_fd = p->fd; /* assume select() works until we know otherwise */ + if (uname(&osinfo) == 0) { + /* + * We can check what OS this is. + */ + if (strcmp(osinfo.sysname, "FreeBSD") == 0) { + if (strncmp(osinfo.release, "4.3-", 4) == 0 || + strncmp(osinfo.release, "4.4-", 4) == 0) + p->selectable_fd = -1; + } + } + + p->read_op = pcap_read_bpf; + p->inject_op = pcap_inject_bpf; + p->setfilter_op = pcap_setfilter_bpf; + p->setdirection_op = pcap_setdirection_bpf; + p->set_datalink_op = pcap_set_datalink_bpf; + p->getnonblock_op = pcap_getnonblock_fd; + p->setnonblock_op = pcap_setnonblock_fd; + p->stats_op = pcap_stats_bpf; + p->close_op = pcap_close_common; + + return (p); + bad: + (void)close(fd); + if (p->dlt_list != NULL) + free(p->dlt_list); + free(p); + return (NULL); +} + +int +pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) +{ +#ifdef HAVE_DAG_API + if (dag_platform_finddevs(alldevsp, errbuf) < 0) + return (-1); +#endif /* HAVE_DAG_API */ + + return (0); +} + +static int +pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp) +{ + /* + * It looks that BPF code generated by gen_protochain() is not + * compatible with some of kernel BPF code (for example BSD/OS 3.1). + * Take a safer side for now. + */ + if (no_optimize) { + /* + * XXX - what if we already have a filter in the kernel? + */ + if (install_bpf_program(p, fp) < 0) + return (-1); + p->md.use_bpf = 0; /* filtering in userland */ + return (0); + } + + /* + * Free any user-mode filter we might happen to have installed. + */ + pcap_freecode(&p->fcode); + + /* + * Try to install the kernel filter. + */ + if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s", + pcap_strerror(errno)); + return (-1); + } + p->md.use_bpf = 1; /* filtering in the kernel */ + + /* + * Discard any previously-received packets, as they might have + * passed whatever filter was formerly in effect, but might + * not pass this filter (BIOCSETF discards packets buffered + * in the kernel, so you can lose packets in any case). + */ + p->cc = 0; + return (0); +} + +/* + * Set direction flag: Which packets do we accept on a forwarding + * single device? IN, OUT or both? + */ +static int +pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d) +{ +#ifdef BIOCSSEESENT + u_int seesent; +#endif + + /* + * We don't support PCAP_D_OUT. + */ + if (d == PCAP_D_OUT) { + snprintf(p->errbuf, sizeof(p->errbuf), + "Setting direction to PCAP_D_OUT is not supported on BPF"); + return -1; + } +#ifdef BIOCSSEESENT + seesent = (d == PCAP_D_INOUT); + if (ioctl(p->fd, BIOCSSEESENT, &seesent) == -1) { + (void) snprintf(p->errbuf, sizeof(p->errbuf), + "Cannot set direction to %s: %s", + (d == PCAP_D_INOUT) ? "PCAP_D_INOUT" : "PCAP_D_IN", + strerror(errno)); + return (-1); + } + return (0); +#else + (void) snprintf(p->errbuf, sizeof(p->errbuf), + "This system doesn't support BIOCSSEESENT, so the direction can't be set"); + return (-1); +#endif +} + +static int +pcap_set_datalink_bpf(pcap_t *p, int dlt) +{ +#ifdef BIOCSDLT + if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) { + (void) snprintf(p->errbuf, sizeof(p->errbuf), + "Cannot set DLT %d: %s", dlt, strerror(errno)); + return (-1); + } +#endif + return (0); +} diff --git a/winpcap/wpcap/libpcap/pcap-bpf.h b/winpcap/wpcap/libpcap/pcap-bpf.h new file mode 100644 index 0000000..5429767 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-bpf.h @@ -0,0 +1,736 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)bpf.h 7.1 (Berkeley) 5/7/91 + * + * @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.34.2.11 2006/07/27 21:06:17 gianluca Exp $ (LBL) + */ + +/* + * This is libpcap's cut-down version of bpf.h; it includes only + * the stuff needed for the code generator and the userland BPF + * interpreter, and the libpcap APIs for setting filters, etc.. + * + * "pcap-bpf.c" will include the native OS version, as it deals with + * the OS's BPF implementation. + * + * XXX - should this all just be moved to "pcap.h"? + */ + +#ifndef BPF_MAJOR_VERSION + +#ifdef __cplusplus +extern "C" { +#endif + +/* BSD style release date */ +#define BPF_RELEASE 199606 + +#ifdef MSDOS /* must be 32-bit */ +typedef long bpf_int32; +typedef unsigned long bpf_u_int32; +#else +typedef int bpf_int32; +typedef u_int bpf_u_int32; +#endif + +/* + * Alignment macros. BPF_WORDALIGN rounds up to the next + * even multiple of BPF_ALIGNMENT. + */ +#ifndef __NetBSD__ +#define BPF_ALIGNMENT sizeof(bpf_int32) +#else +#define BPF_ALIGNMENT sizeof(long) +#endif +#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) + +#define BPF_MAXINSNS 512 +#define BPF_MAXBUFSIZE 0x8000 +#define BPF_MINBUFSIZE 32 + +/* + * Structure for "pcap_compile()", "pcap_setfilter()", etc.. + */ +struct bpf_program { + u_int bf_len; + struct bpf_insn *bf_insns; +}; + +/* + * Struct return by BIOCVERSION. This represents the version number of + * the filter language described by the instruction encodings below. + * bpf understands a program iff kernel_major == filter_major && + * kernel_minor >= filter_minor, that is, if the value returned by the + * running kernel has the same major number and a minor number equal + * equal to or less than the filter being downloaded. Otherwise, the + * results are undefined, meaning an error may be returned or packets + * may be accepted haphazardly. + * It has nothing to do with the source code version. + */ +struct bpf_version { + u_short bv_major; + u_short bv_minor; +}; +/* Current version number of filter architecture. */ +#define BPF_MAJOR_VERSION 1 +#define BPF_MINOR_VERSION 1 + +/* + * Data-link level type codes. + * + * Do *NOT* add new values to this list without asking + * "tcpdump-workers@tcpdump.org" for a value. Otherwise, you run the + * risk of using a value that's already being used for some other purpose, + * and of having tools that read libpcap-format captures not being able + * to handle captures with your new DLT_ value, with no hope that they + * will ever be changed to do so (as that would destroy their ability + * to read captures using that value for that other purpose). + */ + +/* + * These are the types that are the same on all platforms, and that + * have been defined by for ages. + */ +#define DLT_NULL 0 /* BSD loopback encapsulation */ +#define DLT_EN10MB 1 /* Ethernet (10Mb) */ +#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ +#define DLT_AX25 3 /* Amateur Radio AX.25 */ +#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ +#define DLT_CHAOS 5 /* Chaos */ +#define DLT_IEEE802 6 /* IEEE 802 Networks */ +#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ +#define DLT_SLIP 8 /* Serial Line IP */ +#define DLT_PPP 9 /* Point-to-point Protocol */ +#define DLT_FDDI 10 /* FDDI */ + +/* + * These are types that are different on some platforms, and that + * have been defined by for ages. We use #ifdefs to + * detect the BSDs that define them differently from the traditional + * libpcap + * + * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, + * but I don't know what the right #define is for BSD/OS. + */ +#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ + +#ifdef __OpenBSD__ +#define DLT_RAW 14 /* raw IP */ +#else +#define DLT_RAW 12 /* raw IP */ +#endif + +/* + * Given that the only OS that currently generates BSD/OS SLIP or PPP + * is, well, BSD/OS, arguably everybody should have chosen its values + * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they + * didn't. So it goes. + */ +#if defined(__NetBSD__) || defined(__FreeBSD__) +#ifndef DLT_SLIP_BSDOS +#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ +#endif +#else +#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ +#endif + +/* + * 17 is used for DLT_OLD_PFLOG in OpenBSD; + * OBSOLETE: DLT_PFLOG is 117 in OpenBSD now as well. See below. + * 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else. + */ + +#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + +/* + * Apparently Redback uses this for its SmartEdge 400/800. I hope + * nobody else decided to use it, too. + */ +#define DLT_REDBACK_SMARTEDGE 32 + +/* + * These values are defined by NetBSD; other platforms should refrain from + * using them for other purposes, so that NetBSD savefiles with link + * types of 50 or 51 can be read as this type on all platforms. + */ +#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ +#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ + +/* + * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses + * a link-layer type of 99 for the tcpdump it supplies. The link-layer + * header has 6 bytes of unknown data, something that appears to be an + * Ethernet type, and 36 bytes that appear to be 0 in at least one capture + * I've seen. + */ +#define DLT_SYMANTEC_FIREWALL 99 + +/* + * Values between 100 and 103 are used in capture file headers as + * link-layer types corresponding to DLT_ types that differ + * between platforms; don't use those values for new DLT_ new types. + */ + +/* + * This value was defined by libpcap 0.5; platforms that have defined + * it with a different value should define it here with that value - + * a link type of 104 in a save file will be mapped to DLT_C_HDLC, + * whatever value that happens to be, so programs will correctly + * handle files with that link type regardless of the value of + * DLT_C_HDLC. + * + * The name DLT_C_HDLC was used by BSD/OS; we use that name for source + * compatibility with programs written for BSD/OS. + * + * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, + * for source compatibility with programs written for libpcap 0.5. + */ +#define DLT_C_HDLC 104 /* Cisco HDLC */ +#define DLT_CHDLC DLT_C_HDLC + +#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + +/* + * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, + * except when it isn't. (I.e., sometimes it's just raw IP, and + * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL, + * so that we don't have to worry about the link-layer header.) + */ + +/* + * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides + * with other values. + * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header + * (DLCI, etc.). + */ +#define DLT_FRELAY 107 + +/* + * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except + * that the AF_ type in the link-layer header is in network byte order. + * + * OpenBSD defines it as 12, but that collides with DLT_RAW, so we + * define it as 108 here. If OpenBSD picks up this file, it should + * define DLT_LOOP as 12 in its version, as per the comment above - + * and should not use 108 as a DLT_ value. + */ +#define DLT_LOOP 108 + +/* + * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's + * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other + * than OpenBSD. + */ +#ifdef __OpenBSD__ +#define DLT_ENC 13 +#else +#define DLT_ENC 109 +#endif + +/* + * Values between 110 and 112 are reserved for use in capture file headers + * as link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ types + * other than the corresponding DLT_ types. + */ + +/* + * This is for Linux cooked sockets. + */ +#define DLT_LINUX_SLL 113 + +/* + * Apple LocalTalk hardware. + */ +#define DLT_LTALK 114 + +/* + * Acorn Econet. + */ +#define DLT_ECONET 115 + +/* + * Reserved for use with OpenBSD ipfilter. + */ +#define DLT_IPFILTER 116 + +/* + * OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023 + * in SuSE 6.3, so we can't use 17 for it in capture-file headers. + * + * XXX: is there a conflict with DLT_PFSYNC 18 as well? + */ +#ifdef __OpenBSD__ +#define DLT_OLD_PFLOG 17 +#define DLT_PFSYNC 18 +#endif +#define DLT_PFLOG 117 + +/* + * Registered for Cisco-internal use. + */ +#define DLT_CISCO_IOS 118 + +/* + * For 802.11 cards using the Prism II chips, with a link-layer + * header including Prism monitor mode information plus an 802.11 + * header. + */ +#define DLT_PRISM_HEADER 119 + +/* + * Reserved for Aironet 802.11 cards, with an Aironet link-layer header + * (see Doug Ambrisko's FreeBSD patches). + */ +#define DLT_AIRONET_HEADER 120 + +/* + * Reserved for Siemens HiPath HDLC. + */ +#define DLT_HHDLC 121 + +/* + * This is for RFC 2625 IP-over-Fibre Channel. + * + * This is not for use with raw Fibre Channel, where the link-layer + * header starts with a Fibre Channel frame header; it's for IP-over-FC, + * where the link-layer header starts with an RFC 2625 Network_Header + * field. + */ +#define DLT_IP_OVER_FC 122 + +/* + * This is for Full Frontal ATM on Solaris with SunATM, with a + * pseudo-header followed by an AALn PDU. + * + * There may be other forms of Full Frontal ATM on other OSes, + * with different pseudo-headers. + * + * If ATM software returns a pseudo-header with VPI/VCI information + * (and, ideally, packet type information, e.g. signalling, ILMI, + * LANE, LLC-multiplexed traffic, etc.), it should not use + * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump + * and the like don't have to infer the presence or absence of a + * pseudo-header and the form of the pseudo-header. + */ +#define DLT_SUNATM 123 /* Solaris+SunATM */ + +/* + * Reserved as per request from Kent Dahlgren + * for private use. + */ +#define DLT_RIO 124 /* RapidIO */ +#define DLT_PCI_EXP 125 /* PCI Express */ +#define DLT_AURORA 126 /* Xilinx Aurora link layer */ + +/* + * Header for 802.11 plus a number of bits of link-layer information + * including radio information, used by some recent BSD drivers as + * well as the madwifi Atheros driver for Linux. + */ +#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ + +/* + * Reserved for the TZSP encapsulation, as per request from + * Chris Waters + * TZSP is a generic encapsulation for any other link type, + * which includes a means to include meta-information + * with the packet, e.g. signal strength and channel + * for 802.11 packets. + */ +#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ + +/* + * BSD's ARCNET headers have the source host, destination host, + * and type at the beginning of the packet; that's what's handed + * up to userland via BPF. + * + * Linux's ARCNET headers, however, have a 2-byte offset field + * between the host IDs and the type; that's what's handed up + * to userland via PF_PACKET sockets. + * + * We therefore have to have separate DLT_ values for them. + */ +#define DLT_ARCNET_LINUX 129 /* ARCNET */ + +/* + * Juniper-private data link types, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, etc.. + */ +#define DLT_JUNIPER_MLPPP 130 +#define DLT_JUNIPER_MLFR 131 +#define DLT_JUNIPER_ES 132 +#define DLT_JUNIPER_GGSN 133 +#define DLT_JUNIPER_MFR 134 +#define DLT_JUNIPER_ATM2 135 +#define DLT_JUNIPER_SERVICES 136 +#define DLT_JUNIPER_ATM1 137 + +/* + * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund + * . The header that's presented is an Ethernet-like + * header: + * + * #define FIREWIRE_EUI64_LEN 8 + * struct firewire_header { + * u_char firewire_dhost[FIREWIRE_EUI64_LEN]; + * u_char firewire_shost[FIREWIRE_EUI64_LEN]; + * u_short firewire_type; + * }; + * + * with "firewire_type" being an Ethernet type value, rather than, + * for example, raw GASP frames being handed up. + */ +#define DLT_APPLE_IP_OVER_IEEE1394 138 + +/* + * Various SS7 encapsulations, as per a request from Jeff Morriss + * and subsequent discussions. + */ +#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ +#define DLT_MTP2 140 /* MTP2, without pseudo-header */ +#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ +#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ + +/* + * DOCSIS MAC frames. + */ +#define DLT_DOCSIS 143 + +/* + * Linux-IrDA packets. Protocol defined at http://www.irda.org. + * Those packets include IrLAP headers and above (IrLMP...), but + * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy + * framing can be handled by the hardware and depend on the bitrate. + * This is exactly the format you would get capturing on a Linux-IrDA + * interface (irdaX), but not on a raw serial port. + * Note the capture is done in "Linux-cooked" mode, so each packet include + * a fake packet header (struct sll_header). This is because IrDA packet + * decoding is dependant on the direction of the packet (incomming or + * outgoing). + * When/if other platform implement IrDA capture, we may revisit the + * issue and define a real DLT_IRDA... + * Jean II + */ +#define DLT_LINUX_IRDA 144 + +/* + * Reserved for IBM SP switch and IBM Next Federation switch. + */ +#define DLT_IBM_SP 145 +#define DLT_IBM_SN 146 + +/* + * Reserved for private use. If you have some link-layer header type + * that you want to use within your organization, with the capture files + * using that link-layer header type not ever be sent outside your + * organization, you can use these values. + * + * No libpcap release will use these for any purpose, nor will any + * tcpdump release use them, either. + * + * Do *NOT* use these in capture files that you expect anybody not using + * your private versions of capture-file-reading tools to read; in + * particular, do *NOT* use them in products, otherwise you may find that + * people won't be able to use tcpdump, or snort, or Ethereal, or... to + * read capture files from your firewall/intrusion detection/traffic + * monitoring/etc. appliance, or whatever product uses that DLT_ value, + * and you may also find that the developers of those applications will + * not accept patches to let them read those files. + * + * Also, do not use them if somebody might send you a capture using them + * for *their* private type and tools using them for *your* private type + * would have to read them. + * + * Instead, ask "tcpdump-workers@tcpdump.org" for a new DLT_ value, + * as per the comment above, and use the type you're given. + */ +#define DLT_USER0 147 +#define DLT_USER1 148 +#define DLT_USER2 149 +#define DLT_USER3 150 +#define DLT_USER4 151 +#define DLT_USER5 152 +#define DLT_USER6 153 +#define DLT_USER7 154 +#define DLT_USER8 155 +#define DLT_USER9 156 +#define DLT_USER10 157 +#define DLT_USER11 158 +#define DLT_USER12 159 +#define DLT_USER13 160 +#define DLT_USER14 161 +#define DLT_USER15 162 + +/* + * For future use with 802.11 captures - defined by AbsoluteValue + * Systems to store a number of bits of link-layer information + * including radio information: + * + * http://www.shaftnet.org/~pizza/software/capturefrm.txt + * + * but it might be used by some non-AVS drivers now or in the + * future. + */ +#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, etc.. + */ +#define DLT_JUNIPER_MONITOR 164 + +/* + * Reserved for BACnet MS/TP. + */ +#define DLT_BACNET_MS_TP 165 + +/* + * Another PPP variant as per request from Karsten Keil . + * + * This is used in some OSes to allow a kernel socket filter to distinguish + * between incoming and outgoing packets, on a socket intended to + * supply pppd with outgoing packets so it can do dial-on-demand and + * hangup-on-lack-of-demand; incoming packets are filtered out so they + * don't cause pppd to hold the connection up (you don't want random + * input packets such as port scans, packets from old lost connections, + * etc. to force the connection to stay up). + * + * The first byte of the PPP header (0xff03) is modified to accomodate + * the direction - 0x00 = IN, 0x01 = OUT. + */ +#define DLT_PPP_PPPD 166 + +/* + * Names for backwards compatibility with older versions of some PPP + * software; new software should use DLT_PPP_PPPD. + */ +#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD +#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, cookies, etc.. + */ +#define DLT_JUNIPER_PPPOE 167 +#define DLT_JUNIPER_PPPOE_ATM 168 + +#define DLT_GPRS_LLC 169 /* GPRS LLC */ +#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ +#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ + +/* + * Requested by Oolan Zimmer for use in Gcom's T1/E1 line + * monitoring equipment. + */ +#define DLT_GCOM_T1E1 172 +#define DLT_GCOM_SERIAL 173 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_ is used + * for internal communication to Physical Interface Cards (PIC) + */ +#define DLT_JUNIPER_PIC_PEER 174 + +/* + * Link types requested by Gregor Maier of Endace + * Measurement Systems. They add an ERF header (see + * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of + * the link-layer header. + */ +#define DLT_ERF_ETH 175 /* Ethernet */ +#define DLT_ERF_POS 176 /* Packet-over-SONET */ + +/* + * Requested by Daniele Orlandi for raw LAPD + * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header + * includes additional information before the LAPD header, so it's + * not necessarily a generic LAPD header. + */ +#define DLT_LINUX_LAPD 177 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ are used for prepending meta-information + * like interface index, interface name + * before standard Ethernet, PPP, Frelay & C-HDLC Frames + */ +#define DLT_JUNIPER_ETHER 178 +#define DLT_JUNIPER_PPP 179 +#define DLT_JUNIPER_FRELAY 180 +#define DLT_JUNIPER_CHDLC 181 + +/* + * Multi Link Frame Relay (FRF.16) + */ +#define DLT_MFR 182 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for internal communication with a + * voice Adapter Card (PIC) + */ +#define DLT_JUNIPER_VP 183 + +/* + * Arinc 429 frames. + * DLT_ requested by Gianluca Varenni . + * Every frame contains a 32bit A429 label. + * More documentation on Arinc 429 can be found at + * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf + */ +#define DLT_A429 184 + +/* + * Arinc 653 Interpartition Communication messages. + * DLT_ requested by Gianluca Varenni . + * Please refer to the A653-1 standard for more information. + */ +#define DLT_A653_ICM 185 + +/* + * Controller Area Network (CAN) v. 2.0B packets. + * DLT_ requested by Gianluca Varenni . + * Used to dump CAN packets coming from a CAN Vector board. + * More documentation on the CAN v2.0B frames can be found at + * http://www.can-cia.org/downloads/?269 + */ +#define DLT_CAN20B 190 + + +/* + * The instruction encodings. + */ +/* instruction classes */ +#define BPF_CLASS(code) ((code) & 0x07) +#define BPF_LD 0x00 +#define BPF_LDX 0x01 +#define BPF_ST 0x02 +#define BPF_STX 0x03 +#define BPF_ALU 0x04 +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 + +/* ld/ldx fields */ +#define BPF_SIZE(code) ((code) & 0x18) +#define BPF_W 0x00 +#define BPF_H 0x08 +#define BPF_B 0x10 +#define BPF_MODE(code) ((code) & 0xe0) +#define BPF_IMM 0x00 +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 + +/* alu/jmp fields */ +#define BPF_OP(code) ((code) & 0xf0) +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 +#define BPF_SRC(code) ((code) & 0x08) +#define BPF_K 0x00 +#define BPF_X 0x08 + +/* ret - BPF_K and BPF_X also apply */ +#define BPF_RVAL(code) ((code) & 0x18) +#define BPF_A 0x10 + +/* misc */ +#define BPF_MISCOP(code) ((code) & 0xf8) +#define BPF_TAX 0x00 +#define BPF_TXA 0x80 + +/* + * The instruction data structure. + */ +struct bpf_insn { + u_short code; + u_char jt; + u_char jf; + bpf_int32 k; +}; + +/* + * Macros for insn array initializers. + */ +#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } +#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } + +#if __STDC__ || defined(__cplusplus) +extern int bpf_validate(struct bpf_insn *, int); +extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); +#else +extern int bpf_validate(); +extern u_int bpf_filter(); +#endif + +/* + * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). + */ +#define BPF_MEMWORDS 16 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/winpcap/wpcap/libpcap/pcap-dag.c b/winpcap/wpcap/libpcap/pcap-dag.c new file mode 100644 index 0000000..f5a34fd --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-dag.c @@ -0,0 +1,927 @@ +/* + * pcap-dag.c: Packet capture interface for Endace DAG card. + * + * The functionality of this code attempts to mimic that of pcap-linux as much + * as possible. This code is compiled in several different ways depending on + * whether DAG_ONLY and HAVE_DAG_API are defined. If HAVE_DAG_API is not + * defined it should not get compiled in, otherwise if DAG_ONLY is defined then + * the 'dag_' function calls are renamed to 'pcap_' equivalents. If DAG_ONLY + * is not defined then nothing is altered - the dag_ functions will be + * called as required from their pcap-linux/bpf equivalents. + * + * Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com) + * Modifications: Jesper Peterson + * Koryn Grant + * Stephen Donnelly + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.21.2.4 2006/04/07 07:08:50 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* optionally get BSD define */ + +#include +#include +#include + +#include "pcap-int.h" + +#include +#include +#include +#include +#include +#include + +struct mbuf; /* Squelch compiler warnings on some platforms for */ +struct rtentry; /* declarations in */ +#include + +#include "dagnew.h" +#include "dagapi.h" + +#define ATM_CELL_SIZE 52 +#define ATM_HDR_SIZE 4 + +/* SunATM pseudo header */ +struct sunatm_hdr { + unsigned char flags; /* destination and traffic type */ + unsigned char vpi; /* VPI */ + unsigned short vci; /* VCI */ +}; + +typedef struct pcap_dag_node { + struct pcap_dag_node *next; + pcap_t *p; + pid_t pid; +} pcap_dag_node_t; + +static pcap_dag_node_t *pcap_dags = NULL; +static int atexit_handler_installed = 0; +static const unsigned short endian_test_word = 0x0100; + +#define IS_BIGENDIAN() (*((unsigned char *)&endian_test_word)) + +/* + * Swap byte ordering of unsigned long long timestamp on a big endian + * machine. + */ +#define SWAP_TS(ull) ((ull & 0xff00000000000000LL) >> 56) | \ + ((ull & 0x00ff000000000000LL) >> 40) | \ + ((ull & 0x0000ff0000000000LL) >> 24) | \ + ((ull & 0x000000ff00000000LL) >> 8) | \ + ((ull & 0x00000000ff000000LL) << 8) | \ + ((ull & 0x0000000000ff0000LL) << 24) | \ + ((ull & 0x000000000000ff00LL) << 40) | \ + ((ull & 0x00000000000000ffLL) << 56) + + +#ifdef DAG_ONLY +/* This code is required when compiling for a DAG device only. */ +#include "pcap-dag.h" + +/* Replace dag function names with pcap equivalent. */ +#define dag_open_live pcap_open_live +#define dag_platform_finddevs pcap_platform_finddevs +#endif /* DAG_ONLY */ + +static int dag_setfilter(pcap_t *p, struct bpf_program *fp); +static int dag_stats(pcap_t *p, struct pcap_stat *ps); +static int dag_set_datalink(pcap_t *p, int dlt); +static int dag_get_datalink(pcap_t *p); +static int dag_setnonblock(pcap_t *p, int nonblock, char *errbuf); + +static void +delete_pcap_dag(pcap_t *p) +{ + pcap_dag_node_t *curr = NULL, *prev = NULL; + + for (prev = NULL, curr = pcap_dags; curr != NULL && curr->p != p; prev = curr, curr = curr->next) { + /* empty */ + } + + if (curr != NULL && curr->p == p) { + if (prev != NULL) { + prev->next = curr->next; + } else { + pcap_dags = curr->next; + } + } +} + +/* + * Performs a graceful shutdown of the DAG card, frees dynamic memory held + * in the pcap_t structure, and closes the file descriptor for the DAG card. + */ + +static void +dag_platform_close(pcap_t *p) +{ + + if (p != NULL) { +#ifdef HAVE_DAG_STREAMS_API + if(dag_stop_stream(p->fd, p->md.dag_stream) < 0) + fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno)); + + if(dag_detach_stream(p->fd, p->md.dag_stream) < 0) + fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno)); +#else + if(dag_stop(p->fd) < 0) + fprintf(stderr,"dag_stop: %s\n", strerror(errno)); +#endif /* HAVE_DAG_STREAMS_API */ + if(dag_close(p->fd) < 0) + fprintf(stderr,"dag_close: %s\n", strerror(errno)); +#ifdef linux + free(p->md.device); +#endif + } + delete_pcap_dag(p); + /* Note: don't need to call close(p->fd) here as dag_close(p->fd) does this. */ +} + +static void +atexit_handler(void) +{ + while (pcap_dags != NULL) { + if (pcap_dags->pid == getpid()) { + dag_platform_close(pcap_dags->p); + } else { + delete_pcap_dag(pcap_dags->p); + } + } +} + +static int +new_pcap_dag(pcap_t *p) +{ + pcap_dag_node_t *node = NULL; + + if ((node = malloc(sizeof(pcap_dag_node_t))) == NULL) { + return -1; + } + + if (!atexit_handler_installed) { + atexit(atexit_handler); + atexit_handler_installed = 1; + } + + node->next = pcap_dags; + node->p = p; + node->pid = getpid(); + + pcap_dags = node; + + return 0; +} + +/* + * Read at most max_packets from the capture stream and call the callback + * for each of them. Returns the number of packets handled, -1 if an + * error occured, or -2 if we were told to break out of the loop. + */ +static int +dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ + unsigned int processed = 0; + int flags = p->md.dag_offset_flags; + unsigned int nonblocking = flags & DAGF_NONBLOCK; + + /* Get the next bufferful of packets (if necessary). */ + while (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size) { + + /* + * Has "pcap_breakloop()" been called? + */ + if (p->break_loop) { + /* + * Yes - clear the flag that indicates that + * it has, and return -2 to indicate that + * we were told to break out of the loop. + */ + p->break_loop = 0; + return -2; + } + +#ifdef HAVE_DAG_STREAMS_API + /* dag_advance_stream() will block (unless nonblock is called) + * until 64kB of data has accumulated. + * If to_ms is set, it will timeout before 64kB has accumulated. + * We wait for 64kB because processing a few packets at a time + * can cause problems at high packet rates (>200kpps) due + * to inefficiencies. + * This does mean if to_ms is not specified the capture may 'hang' + * for long periods if the data rate is extremely slow (<64kB/sec) + * If non-block is specified it will return immediately. The user + * is then responsible for efficiency. + */ + p->md.dag_mem_top = dag_advance_stream(p->fd, p->md.dag_stream, &(p->md.dag_mem_bottom)); +#else + /* dag_offset does not support timeouts */ + p->md.dag_mem_top = dag_offset(p->fd, &(p->md.dag_mem_bottom), flags); +#endif /* HAVE_DAG_STREAMS_API */ + + if (nonblocking && (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size)) + { + /* Pcap is configured to process only available packets, and there aren't any, return immediately. */ + return 0; + } + + if(!nonblocking && + p->md.dag_timeout && + (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size)) + { + /* Blocking mode, but timeout set and no data has arrived, return anyway.*/ + return 0; + } + + } + + /* Process the packets. */ + while (p->md.dag_mem_top - p->md.dag_mem_bottom >= dag_record_size) { + + unsigned short packet_len = 0; + int caplen = 0; + struct pcap_pkthdr pcap_header; + +#ifdef HAVE_DAG_STREAMS_API + dag_record_t *header = (dag_record_t *)(p->md.dag_mem_bottom); +#else + dag_record_t *header = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom); +#endif /* HAVE_DAG_STREAMS_API */ + + u_char *dp = ((u_char *)header) + dag_record_size; + unsigned short rlen; + + /* + * Has "pcap_breakloop()" been called? + */ + if (p->break_loop) { + /* + * Yes - clear the flag that indicates that + * it has, and return -2 to indicate that + * we were told to break out of the loop. + */ + p->break_loop = 0; + return -2; + } + + rlen = ntohs(header->rlen); + if (rlen < dag_record_size) + { + strncpy(p->errbuf, "dag_read: record too small", PCAP_ERRBUF_SIZE); + return -1; + } + p->md.dag_mem_bottom += rlen; + + switch(header->type) { + case TYPE_ATM: +#ifdef TYPE_AAL5 + case TYPE_AAL5: + if (header->type == TYPE_AAL5) { + packet_len = ntohs(header->wlen); + caplen = rlen - dag_record_size; + } +#endif +#ifdef TYPE_MC_ATM + case TYPE_MC_ATM: + if (header->type == TYPE_MC_ATM) { + caplen = packet_len = ATM_CELL_SIZE; + dp+=4; + } +#endif +#ifdef TYPE_MC_AAL5 + case TYPE_MC_AAL5: + if (header->type == TYPE_MC_AAL5) { + packet_len = ntohs(header->wlen); + caplen = rlen - dag_record_size - 4; + dp+=4; + } +#endif + if (header->type == TYPE_ATM) { + caplen = packet_len = ATM_CELL_SIZE; + } + if (p->linktype == DLT_SUNATM) { + struct sunatm_hdr *sunatm = (struct sunatm_hdr *)dp; + unsigned long rawatm; + + rawatm = ntohl(*((unsigned long *)dp)); + sunatm->vci = htons((rawatm >> 4) & 0xffff); + sunatm->vpi = (rawatm >> 20) & 0x00ff; + sunatm->flags = ((header->flags.iface & 1) ? 0x80 : 0x00) | + ((sunatm->vpi == 0 && sunatm->vci == htons(5)) ? 6 : + ((sunatm->vpi == 0 && sunatm->vci == htons(16)) ? 5 : + ((dp[ATM_HDR_SIZE] == 0xaa && + dp[ATM_HDR_SIZE+1] == 0xaa && + dp[ATM_HDR_SIZE+2] == 0x03) ? 2 : 1))); + + } else { + packet_len -= ATM_HDR_SIZE; + caplen -= ATM_HDR_SIZE; + dp += ATM_HDR_SIZE; + } + break; + +#ifdef TYPE_COLOR_ETH + case TYPE_COLOR_ETH: +#endif + case TYPE_ETH: + packet_len = ntohs(header->wlen); + packet_len -= (p->md.dag_fcs_bits >> 3); + caplen = rlen - dag_record_size - 2; + if (caplen > packet_len) { + caplen = packet_len; + } + dp += 2; + break; +#ifdef TYPE_COLOR_HDLC_POS + case TYPE_COLOR_HDLC_POS: +#endif + case TYPE_HDLC_POS: + packet_len = ntohs(header->wlen); + packet_len -= (p->md.dag_fcs_bits >> 3); + caplen = rlen - dag_record_size; + if (caplen > packet_len) { + caplen = packet_len; + } + break; +#ifdef TYPE_MC_HDLC + case TYPE_MC_HDLC: + packet_len = ntohs(header->wlen); + packet_len -= (p->md.dag_fcs_bits >> 3); + caplen = rlen - dag_record_size - 4; + if (caplen > packet_len) { + caplen = packet_len; + } + dp += 4; + break; +#endif + } + + if (caplen > p->snapshot) + caplen = p->snapshot; + + /* Count lost packets. */ + switch(header->type) { +#ifdef TYPE_COLOR_HDLC_POS + /* in this type the color value overwrites the lctr */ + case TYPE_COLOR_HDLC_POS: + break; +#endif +#ifdef TYPE_COLOR_ETH + /* in this type the color value overwrites the lctr */ + case TYPE_COLOR_ETH: + break; +#endif + default: + if (header->lctr) { + if (p->md.stat.ps_drop > (UINT_MAX - ntohs(header->lctr))) { + p->md.stat.ps_drop = UINT_MAX; + } else { + p->md.stat.ps_drop += ntohs(header->lctr); + } + } + } + + /* Run the packet filter if there is one. */ + if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) { + + /* convert between timestamp formats */ + register unsigned long long ts; + + if (IS_BIGENDIAN()) { + ts = SWAP_TS(header->ts); + } else { + ts = header->ts; + } + + pcap_header.ts.tv_sec = ts >> 32; + ts = (ts & 0xffffffffULL) * 1000000; + ts += 0x80000000; /* rounding */ + pcap_header.ts.tv_usec = ts >> 32; + if (pcap_header.ts.tv_usec >= 1000000) { + pcap_header.ts.tv_usec -= 1000000; + pcap_header.ts.tv_sec++; + } + + /* Fill in our own header data */ + pcap_header.caplen = caplen; + pcap_header.len = packet_len; + + /* Count the packet. */ + p->md.stat.ps_recv++; + + /* Call the user supplied callback function */ + callback(user, &pcap_header, dp); + + /* Only count packets that pass the filter, for consistency with standard Linux behaviour. */ + processed++; + if (processed == cnt) + { + /* Reached the user-specified limit. */ + return cnt; + } + } + } + + return processed; +} + +static int +dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_) +{ + strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards", + PCAP_ERRBUF_SIZE); + return (-1); +} + +/* + * Get a handle for a live capture from the given DAG device. Passing a NULL + * device will result in a failure. The promisc flag is ignored because DAG + * cards are always promiscuous. The to_ms parameter is also ignored as it is + * not supported in hardware. + * + * See also pcap(3). + */ +pcap_t * +dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) +{ + char conf[30]; /* dag configure string */ + pcap_t *handle; + char *s; + int n; + daginf_t* daginf; + char * newDev; +#ifdef HAVE_DAG_STREAMS_API + uint32_t mindata; + struct timeval maxwait; + struct timeval poll; +#endif + + if (device == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno)); + return NULL; + } + /* Allocate a handle for this session. */ + + handle = malloc(sizeof(*handle)); + if (handle == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno)); + return NULL; + } + + /* Initialize some components of the pcap structure. */ + + memset(handle, 0, sizeof(*handle)); + + newDev = (char *)malloc(strlen(device) + 16); + +#ifdef HAVE_DAG_STREAMS_API + + /* Parse input name to get dag device and stream number if provided */ + if (dag_parse_name(device, newDev, strlen(device) + 16, &handle->md.dag_stream) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s\n", pcap_strerror(errno)); + goto fail; + } + device = newDev; + + if (handle->md.dag_stream%2) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture\n"); + goto fail; + } +#else + if (strstr(device, "/dev") == NULL) { + newDev[0] = '\0'; + strcat(newDev, "/dev/"); + strcat(newDev,device); + device = newDev; + } else { + device = strdup(device); + } + + if (device == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "str_dup: %s\n", pcap_strerror(errno)); + goto fail; + } +#endif /* HAVE_DAG_STREAMS_API */ + + /* setup device parameters */ + if((handle->fd = dag_open((char *)device)) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno)); + goto fail; + } + +#ifdef HAVE_DAG_STREAMS_API + /* Open requested stream. Can fail if already locked or on error */ + if (dag_attach_stream(handle->fd, handle->md.dag_stream, 0, 0) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s\n", pcap_strerror(errno)); + goto fail; + } + + /* Set up default poll parameters for stream + * Can be overridden by pcap_set_nonblock() + */ + if (dag_get_stream_poll(handle->fd, handle->md.dag_stream, + &mindata, &maxwait, &poll) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno)); + goto fail; + } + + /* Amount of data to collect in Bytes before calling callbacks. + * Important for efficiency, but can introduce latency + * at low packet rates if to_ms not set! + */ + mindata = 65536; + + /* Obey to_ms if supplied. This is a good idea! + * Recommend 10-100ms. Calls will time out even if no data arrived. + */ + maxwait.tv_sec = to_ms/1000; + maxwait.tv_usec = (to_ms%1000) * 1000; + + if (dag_set_stream_poll(handle->fd, handle->md.dag_stream, + mindata, &maxwait, &poll) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno)); + goto fail; + } + +#else + if((handle->md.dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) { + snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno)); + goto fail; + } + +#endif /* HAVE_DAG_STREAMS_API */ + + /* XXX Not calling dag_configure() to set slen; this is unsafe in + * multi-stream environments as the gpp config is global. + * Once the firmware provides 'per-stream slen' this can be supported + * again via the Config API without side-effects */ +#if 0 + /* set the card snap length to the specified snaplen parameter */ + /* This is a really bad idea, as different cards have different + * valid slen ranges. Should fix in Config API. */ + if (snaplen == 0 || snaplen > MAX_DAG_SNAPLEN) { + snaplen = MAX_DAG_SNAPLEN; + } else if (snaplen < MIN_DAG_SNAPLEN) { + snaplen = MIN_DAG_SNAPLEN; + } + /* snap len has to be a multiple of 4 */ + snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3); + + if(dag_configure(handle->fd, conf) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno)); + goto fail; + } +#endif + +#ifdef HAVE_DAG_STREAMS_API + if(dag_start_stream(handle->fd, handle->md.dag_stream) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s\n", device, pcap_strerror(errno)); + goto fail; + } +#else + if(dag_start(handle->fd) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno)); + goto fail; + } +#endif /* HAVE_DAG_STREAMS_API */ + + /* + * Important! You have to ensure bottom is properly + * initialized to zero on startup, it won't give you + * a compiler warning if you make this mistake! + */ + handle->md.dag_mem_bottom = 0; + handle->md.dag_mem_top = 0; + handle->md.dag_fcs_bits = 32; + + /* Query the card first for special cases. */ + daginf = dag_info(handle->fd); + if ((0x4200 == daginf->device_code) || (0x4230 == daginf->device_code)) + { + /* DAG 4.2S and 4.23S already strip the FCS. Stripping the final word again truncates the packet. */ + handle->md.dag_fcs_bits = 0; + } + + /* Then allow an environment variable to override. */ + if ((s = getenv("ERF_FCS_BITS")) != NULL) { + if ((n = atoi(s)) == 0 || n == 16|| n == 32) { + handle->md.dag_fcs_bits = n; + } else { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "pcap_open_live %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n); + goto fail; + } + } + + handle->snapshot = snaplen; + handle->md.dag_timeout = to_ms; + + handle->linktype = -1; + if (dag_get_datalink(handle) < 0) { + strcpy(ebuf, handle->errbuf); + goto fail; + } + + handle->bufsize = 0; + + if (new_pcap_dag(handle) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno)); + goto fail; + } + + /* + * "select()" and "poll()" don't work on DAG device descriptors. + */ + handle->selectable_fd = -1; + +#ifdef linux + handle->md.device = (char *)device; + handle->md.timeout = to_ms; +#else + free((char *)device); + device = NULL; +#endif + + handle->read_op = dag_read; + handle->inject_op = dag_inject; + handle->setfilter_op = dag_setfilter; + handle->setdirection_op = NULL; /* Not implemented.*/ + handle->set_datalink_op = dag_set_datalink; + handle->getnonblock_op = pcap_getnonblock_fd; + handle->setnonblock_op = dag_setnonblock; + handle->stats_op = dag_stats; + handle->close_op = dag_platform_close; + + return handle; + +fail: + if (newDev != NULL) { + free((char *)newDev); + } + if (handle != NULL) { + /* + * Get rid of any link-layer type list we allocated. + */ + if (handle->dlt_list != NULL) { + free(handle->dlt_list); + } + free(handle); + } + + return NULL; +} + +static int +dag_stats(pcap_t *p, struct pcap_stat *ps) { + /* This needs to be filled out correctly. Hopefully a dagapi call will + provide all necessary information. + */ + /*p->md.stat.ps_recv = 0;*/ + /*p->md.stat.ps_drop = 0;*/ + + *ps = p->md.stat; + + return 0; +} + +/* + * Simply submit all possible dag names as candidates. + * pcap_add_if() internally tests each candidate with pcap_open_live(), + * so any non-existent devices are dropped. + * For 2.5 try all rx stream names as well. + */ +int +dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf) +{ + char name[12]; /* XXX - pick a size */ + int ret = 0; + int c; + + /* Try all the DAGs 0-9 */ + for (c = 0; c < 9; c++) { + snprintf(name, 12, "dag%d", c); + if (pcap_add_if(devlistp, name, 0, NULL, errbuf) == -1) { + /* + * Failure. + */ + ret = -1; + } +#ifdef HAVE_DAG_STREAMS_API + { + int stream; + for(stream=0;stream<16;stream+=2) { + snprintf(name, 10, "dag%d:%d", c, stream); + if (pcap_add_if(devlistp, name, 0, NULL, errbuf) == -1) { + /* + * Failure. + */ + ret = -1; + } + } + } +#endif /* HAVE_DAG_STREAMS_API */ + } + return (ret); +} + +/* + * Installs the given bpf filter program in the given pcap structure. There is + * no attempt to store the filter in kernel memory as that is not supported + * with DAG cards. + */ +static int +dag_setfilter(pcap_t *p, struct bpf_program *fp) +{ + if (!p) + return -1; + if (!fp) { + strncpy(p->errbuf, "setfilter: No filter specified", + sizeof(p->errbuf)); + return -1; + } + + /* Make our private copy of the filter */ + + if (install_bpf_program(p, fp) < 0) + return -1; + + p->md.use_bpf = 0; + + return (0); +} + +static int +dag_set_datalink(pcap_t *p, int dlt) +{ + p->linktype = dlt; + + return (0); +} + +static int +dag_setnonblock(pcap_t *p, int nonblock, char *errbuf) +{ + /* + * Set non-blocking mode on the FD. + * XXX - is that necessary? If not, don't bother calling it, + * and have a "dag_getnonblock()" function that looks at + * "p->md.dag_offset_flags". + */ + if (pcap_setnonblock_fd(p, nonblock, errbuf) < 0) + return (-1); +#ifdef HAVE_DAG_STREAMS_API + { + uint32_t mindata; + struct timeval maxwait; + struct timeval poll; + + if (dag_get_stream_poll(p->fd, p->md.dag_stream, + &mindata, &maxwait, &poll) < 0) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno)); + return -1; + } + + /* Amount of data to collect in Bytes before calling callbacks. + * Important for efficiency, but can introduce latency + * at low packet rates if to_ms not set! + */ + if(nonblock) + mindata = 0; + else + mindata = 65536; + + if (dag_set_stream_poll(p->fd, p->md.dag_stream, + mindata, &maxwait, &poll) < 0) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno)); + return -1; + } + } +#endif /* HAVE_DAG_STREAMS_API */ + if (nonblock) { + p->md.dag_offset_flags |= DAGF_NONBLOCK; + } else { + p->md.dag_offset_flags &= ~DAGF_NONBLOCK; + } + return (0); +} + +static int +dag_get_datalink(pcap_t *p) +{ + int index=0; + uint8_t types[255]; + + memset(types, 0, 255); + + if (p->dlt_list == NULL && (p->dlt_list = malloc(255*sizeof(*(p->dlt_list)))) == NULL) { + (void)snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s", pcap_strerror(errno)); + return (-1); + } + + p->linktype = 0; + +#ifdef HAVE_DAG_GET_ERF_TYPES + /* Get list of possible ERF types for this card */ + if (dag_get_erf_types(p->fd, types, 255) < 0) { + snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_erf_types: %s", pcap_strerror(errno)); + return (-1); + } + + while (types[index]) { +#else + /* Check the type through a dagapi call. */ + types[index] = dag_linktype(p->fd); + + { +#endif + switch(types[index]) { + + case TYPE_HDLC_POS: +#ifdef TYPE_COLOR_HDLC_POS + case TYPE_COLOR_HDLC_POS: +#endif + if (p->dlt_list != NULL) { + p->dlt_list[index++] = DLT_CHDLC; + p->dlt_list[index++] = DLT_PPP_SERIAL; + p->dlt_list[index++] = DLT_FRELAY; + } + if(!p->linktype) + p->linktype = DLT_CHDLC; + break; + + case TYPE_ETH: +#ifdef TYPE_COLOR_ETH + case TYPE_COLOR_ETH: +#endif + /* + * This is (presumably) a real Ethernet capture; give it a + * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so + * that an application can let you choose it, in case you're + * capturing DOCSIS traffic that a Cisco Cable Modem + * Termination System is putting out onto an Ethernet (it + * doesn't put an Ethernet header onto the wire, it puts raw + * DOCSIS frames out on the wire inside the low-level + * Ethernet framing). + */ + if (p->dlt_list != NULL) { + p->dlt_list[index++] = DLT_EN10MB; + p->dlt_list[index++] = DLT_DOCSIS; + } + if(!p->linktype) + p->linktype = DLT_EN10MB; + break; + + case TYPE_ATM: +#ifdef TYPE_AAL5 + case TYPE_AAL5: +#endif +#ifdef TYPE_MC_ATM + case TYPE_MC_ATM: +#endif +#ifdef TYPE_MC_AAL5 + case TYPE_MC_AAL5: +#endif + if (p->dlt_list != NULL) { + p->dlt_list[index++] = DLT_ATM_RFC1483; + p->dlt_list[index++] = DLT_SUNATM; + } + if(!p->linktype) + p->linktype = DLT_ATM_RFC1483; + break; + +#ifdef TYPE_MC_HDLC + case TYPE_MC_HDLC: + if (p->dlt_list != NULL) { + p->dlt_list[index++] = DLT_CHDLC; + p->dlt_list[index++] = DLT_PPP_SERIAL; + p->dlt_list[index++] = DLT_FRELAY; + p->dlt_list[index++] = DLT_MTP2; + } + if(!p->linktype) + p->linktype = DLT_CHDLC; + break; +#endif + + case TYPE_LEGACY: + if(!p->linktype) + p->linktype = DLT_NULL; + break; + + default: + snprintf(p->errbuf, sizeof(p->errbuf), "unknown DAG linktype %d", types[index]); + return (-1); + + } /* switch */ + } + + p->dlt_count = index; + + return p->linktype; +} diff --git a/winpcap/wpcap/libpcap/pcap-dag.h b/winpcap/wpcap/libpcap/pcap-dag.h new file mode 100644 index 0000000..eff01d6 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-dag.h @@ -0,0 +1,14 @@ +/* + * pcap-dag.c: Packet capture interface for Endace DAG card. + * + * The functionality of this code attempts to mimic that of pcap-linux as much + * as possible. This code is only needed when compiling in the DAG card code + * at the same time as another type of device. + * + * Author: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com) + * + * @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.3.4.1 2005/07/07 06:56:04 guy Exp $ (LBL) + */ + +pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf); +int dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf); diff --git a/winpcap/wpcap/libpcap/pcap-dlpi.c b/winpcap/wpcap/libpcap/pcap-dlpi.c new file mode 100644 index 0000000..8ea7850 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-dlpi.c @@ -0,0 +1,1873 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * This code contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk), + * University College London, and subsequently modified by + * Guy Harris (guy@alum.mit.edu), Mark Pizzolato + * , + * and Mark C. Brown (mbrown@hp.com). + */ + +/* + * Packet capture routine for DLPI under SunOS 5, HP-UX 9/10/11, and AIX. + * + * Notes: + * + * - The DLIOCRAW ioctl() is specific to SunOS. + * + * - There is a bug in bufmod(7) such that setting the snapshot + * length results in data being left of the front of the packet. + * + * - It might be desirable to use pfmod(7) to filter packets in the + * kernel when possible. + * + * - An older version of the HP-UX DLPI Programmer's Guide, which + * I think was advertised as the 10.20 version, used to be available + * at + * + * http://docs.hp.com/hpux/onlinedocs/B2355-90093/B2355-90093.html + * + * but is no longer available; it can still be found at + * + * http://h21007.www2.hp.com/dspp/files/unprotected/Drivers/Docs/Refs/B2355-90093.pdf + * + * in PDF form. + * + * - The HP-UX 10.x, 11.0, and 11i v1.6 version of the HP-UX DLPI + * Programmer's Guide, which I think was once advertised as the + * 11.00 version is available at + * + * http://docs.hp.com/en/B2355-90139/index.html + * + * - The HP-UX 11i v2 version of the HP-UX DLPI Programmer's Guide + * is available at + * + * http://docs.hp.com/en/B2355-90871/index.html + * + * - All of the HP documents describe raw-mode services, which are + * what we use if DL_HP_RAWDLS is defined. XXX - we use __hpux + * in some places to test for HP-UX, but use DL_HP_RAWDLS in + * other places; do we support any versions of HP-UX without + * DL_HP_RAWDLS? + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.108.2.7 2006/04/04 05:33:02 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#ifdef HAVE_SYS_BUFMOD_H +#include +#endif +#include +#ifdef HAVE_SYS_DLPI_EXT_H +#include +#endif +#ifdef HAVE_HPUX9 +#include +#endif +#ifdef DL_HP_PPA_REQ +#include +#endif +#include +#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) +#include +#endif + +#ifdef HAVE_HPUX9 +#include +#endif + +#include +#ifdef HAVE_HPUX9 +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_LIMITS_H +#include +#else +#define INT_MAX 2147483647 +#endif + +#include "pcap-int.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#ifndef PCAP_DEV_PREFIX +#ifdef _AIX +#define PCAP_DEV_PREFIX "/dev/dlpi" +#else +#define PCAP_DEV_PREFIX "/dev" +#endif +#endif + +#define MAXDLBUF 8192 + +#ifdef HAVE_SYS_BUFMOD_H + +/* + * Size of a bufmod chunk to pass upstream; that appears to be the biggest + * value to which you can set it, and setting it to that value (which + * is bigger than what appears to be the Solaris default of 8192) + * reduces the number of packet drops. + */ +#define CHUNKSIZE 65536 + +/* + * Size of the buffer to allocate for packet data we read; it must be + * large enough to hold a chunk. + */ +#define PKTBUFSIZE CHUNKSIZE + +#else /* HAVE_SYS_BUFMOD_H */ + +/* + * Size of the buffer to allocate for packet data we read; this is + * what the value used to be - there's no particular reason why it + * should be tied to MAXDLBUF, but we'll leave it as this for now. + */ +#define PKTBUFSIZE (MAXDLBUF * sizeof(bpf_u_int32)) + +#endif + +/* Forwards */ +static char *split_dname(char *, int *, char *); +static int dl_doattach(int, int, char *); +#ifdef DL_HP_RAWDLS +static int dl_dohpuxbind(int, char *); +#endif +static int dlattachreq(int, bpf_u_int32, char *); +static int dlbindreq(int, bpf_u_int32, char *); +static int dlbindack(int, char *, char *, int *); +static int dlpromisconreq(int, bpf_u_int32, char *); +static int dlokack(int, const char *, char *, char *); +static int dlinforeq(int, char *); +static int dlinfoack(int, char *, char *); +#ifdef DL_HP_RAWDLS +static int dlrawdatareq(int, const u_char *, int); +#endif +static int recv_ack(int, int, const char *, char *, char *, int *); +static char *dlstrerror(bpf_u_int32); +static char *dlprim(bpf_u_int32); +#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) +static char *get_release(bpf_u_int32 *, bpf_u_int32 *, bpf_u_int32 *); +#endif +static int send_request(int, char *, int, char *, char *); +#ifdef HAVE_SYS_BUFMOD_H +static int strioctl(int, int, int, char *); +#endif +#ifdef HAVE_HPUX9 +static int dlpi_kread(int, off_t, void *, u_int, char *); +#endif +#ifdef HAVE_DEV_DLPI +static int get_dlpi_ppa(int, const char *, int, char *); +#endif + +static int +pcap_stats_dlpi(pcap_t *p, struct pcap_stat *ps) +{ + + /* + * "ps_recv" counts packets handed to the filter, not packets + * that passed the filter. As filtering is done in userland, + * this would not include packets dropped because we ran out + * of buffer space; in order to make this more like other + * platforms (Linux 2.4 and later, BSDs with BPF), where the + * "packets received" count includes packets received but dropped + * due to running out of buffer space, and to keep from confusing + * applications that, for example, compute packet drop percentages, + * we also make it count packets dropped by "bufmod" (otherwise we + * might run the risk of the packet drop count being bigger than + * the received-packet count). + * + * "ps_drop" counts packets dropped by "bufmod" because of + * flow control requirements or resource exhaustion; it doesn't + * count packets dropped by the interface driver, or packets + * dropped upstream. As filtering is done in userland, it counts + * packets regardless of whether they would've passed the filter. + * + * These statistics don't include packets not yet read from + * the kernel by libpcap, but they may include packets not + * yet read from libpcap by the application. + */ + *ps = p->md.stat; + + /* + * Add in the drop count, as per the above comment. + */ + ps->ps_recv += ps->ps_drop; + return (0); +} + +/* XXX Needed by HP-UX (at least) */ +static bpf_u_int32 ctlbuf[MAXDLBUF]; +static struct strbuf ctl = { + MAXDLBUF, + 0, + (char *)ctlbuf +}; + +static int +pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ + register int cc, n, caplen, origlen; + register u_char *bp, *ep, *pk; + register struct bpf_insn *fcode; +#ifdef HAVE_SYS_BUFMOD_H + register struct sb_hdr *sbp; +#ifdef LBL_ALIGN + struct sb_hdr sbhdr; +#endif +#endif + int flags; + struct strbuf data; + struct pcap_pkthdr pkthdr; + + flags = 0; + cc = p->cc; + if (cc == 0) { + data.buf = (char *)p->buffer + p->offset; + data.maxlen = p->bufsize; + data.len = 0; + do { + /* + * Has "pcap_breakloop()" been called? + */ + if (p->break_loop) { + /* + * Yes - clear the flag that indicates + * that it has, and return -2 to + * indicate that we were told to + * break out of the loop. + */ + p->break_loop = 0; + return (-2); + } + /* + * XXX - check for the DLPI primitive, which + * would be DL_HP_RAWDATA_IND on HP-UX + * if we're in raw mode? + */ + if (getmsg(p->fd, &ctl, &data, &flags) < 0) { + /* Don't choke when we get ptraced */ + switch (errno) { + + case EINTR: + cc = 0; + continue; + + case EAGAIN: + return (0); + } + strlcpy(p->errbuf, pcap_strerror(errno), + sizeof(p->errbuf)); + return (-1); + } + cc = data.len; + } while (cc == 0); + bp = p->buffer + p->offset; + } else + bp = p->bp; + + /* Loop through packets */ + fcode = p->fcode.bf_insns; + ep = bp + cc; + n = 0; +#ifdef HAVE_SYS_BUFMOD_H + while (bp < ep) { + /* + * Has "pcap_breakloop()" been called? + * If so, return immediately - if we haven't read any + * packets, clear the flag and return -2 to indicate + * that we were told to break out of the loop, otherwise + * leave the flag set, so that the *next* call will break + * out of the loop without having read any packets, and + * return the number of packets we've processed so far. + */ + if (p->break_loop) { + if (n == 0) { + p->break_loop = 0; + return (-2); + } else { + p->bp = bp; + p->cc = ep - bp; + return (n); + } + } +#ifdef LBL_ALIGN + if ((long)bp & 3) { + sbp = &sbhdr; + memcpy(sbp, bp, sizeof(*sbp)); + } else +#endif + sbp = (struct sb_hdr *)bp; + p->md.stat.ps_drop = sbp->sbh_drops; + pk = bp + sizeof(*sbp); + bp += sbp->sbh_totlen; + origlen = sbp->sbh_origlen; + caplen = sbp->sbh_msglen; +#else + origlen = cc; + caplen = min(p->snapshot, cc); + pk = bp; + bp += caplen; +#endif + ++p->md.stat.ps_recv; + if (bpf_filter(fcode, pk, origlen, caplen)) { +#ifdef HAVE_SYS_BUFMOD_H + pkthdr.ts.tv_sec = sbp->sbh_timestamp.tv_sec; + pkthdr.ts.tv_usec = sbp->sbh_timestamp.tv_usec; +#else + (void)gettimeofday(&pkthdr.ts, NULL); +#endif + pkthdr.len = origlen; + pkthdr.caplen = caplen; + /* Insure caplen does not exceed snapshot */ + if (pkthdr.caplen > p->snapshot) + pkthdr.caplen = p->snapshot; + (*callback)(user, &pkthdr, pk); + if (++n >= cnt && cnt >= 0) { + p->cc = ep - bp; + p->bp = bp; + return (n); + } + } +#ifdef HAVE_SYS_BUFMOD_H + } +#endif + p->cc = 0; + return (n); +} + +static int +pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size) +{ + int ret; + +#if defined(DLIOCRAW) + ret = write(p->fd, buf, size); + if (ret == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", + pcap_strerror(errno)); + return (-1); + } +#elif defined(DL_HP_RAWDLS) + if (p->send_fd < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "send: Output FD couldn't be opened"); + return (-1); + } + ret = dlrawdatareq(p->send_fd, buf, size); + if (ret == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", + pcap_strerror(errno)); + return (-1); + } + /* + * putmsg() returns either 0 or -1; it doesn't indicate how + * many bytes were written (presumably they were all written + * or none of them were written). OpenBSD's pcap_inject() + * returns the number of bytes written, so, for API compatibility, + * we return the number of bytes we were told to write. + */ + ret = size; +#else /* no raw mode */ + /* + * XXX - this is a pain, because you might have to extract + * the address from the packet and use it in a DL_UNITDATA_REQ + * request. That would be dependent on the link-layer type. + * + * I also don't know what SAP you'd have to bind the descriptor + * to, or whether you'd need separate "receive" and "send" FDs, + * nor do I know whether you'd need different bindings for + * D/I/X Ethernet and 802.3, or for {FDDI,Token Ring} plus + * 802.2 and {FDDI,Token Ring} plus 802.2 plus SNAP. + * + * So, for now, we just return a "you can't send" indication, + * and leave it up to somebody with a DLPI-based system lacking + * both DLIOCRAW and DL_HP_RAWDLS to supply code to implement + * packet transmission on that system. If they do, they should + * send it to us - but should not send us code that assumes + * Ethernet; if the code doesn't work on non-Ethernet interfaces, + * it should check "p->linktype" and reject the send request if + * it's anything other than DLT_EN10MB. + */ + strlcpy(p->errbuf, "send: Not supported on this version of this OS", + PCAP_ERRBUF_SIZE); + ret = -1; +#endif /* raw mode */ + return (ret); +} + +#ifndef DL_IPATM +#define DL_IPATM 0x12 /* ATM Classical IP interface */ +#endif + +#ifdef HAVE_SOLARIS +/* + * For SunATM. + */ +#ifndef A_GET_UNITS +#define A_GET_UNITS (('A'<<8)|118) +#endif /* A_GET_UNITS */ +#ifndef A_PROMISCON_REQ +#define A_PROMISCON_REQ (('A'<<8)|121) +#endif /* A_PROMISCON_REQ */ +#endif /* HAVE_SOLARIS */ + +static void +pcap_close_dlpi(pcap_t *p) +{ + pcap_close_common(p); + if (p->send_fd >= 0) + close(p->send_fd); +} + +pcap_t * +pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, + char *ebuf) +{ + register char *cp; + register pcap_t *p; + int ppa; +#ifdef HAVE_SOLARIS + int isatm = 0; +#endif + register dl_info_ack_t *infop; +#ifdef HAVE_SYS_BUFMOD_H + bpf_u_int32 ss, chunksize; +#ifdef HAVE_SOLARIS + register char *release; + bpf_u_int32 osmajor, osminor, osmicro; +#endif +#endif + bpf_u_int32 buf[MAXDLBUF]; + char dname[100]; +#ifndef HAVE_DEV_DLPI + char dname2[100]; +#endif + + p = (pcap_t *)malloc(sizeof(*p)); + if (p == NULL) { + strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); + return (NULL); + } + memset(p, 0, sizeof(*p)); + p->fd = -1; /* indicate that it hasn't been opened yet */ + p->send_fd = -1; + +#ifdef HAVE_DEV_DLPI + /* + ** Remove any "/dev/" on the front of the device. + */ + cp = strrchr(device, '/'); + if (cp == NULL) + strlcpy(dname, device, sizeof(dname)); + else + strlcpy(dname, cp + 1, sizeof(dname)); + + /* + * Split the device name into a device type name and a unit number; + * chop off the unit number, so "dname" is just a device type name. + */ + cp = split_dname(dname, &ppa, ebuf); + if (cp == NULL) + goto bad; + *cp = '\0'; + + /* + * Use "/dev/dlpi" as the device. + * + * XXX - HP's DLPI Programmer's Guide for HP-UX 11.00 says that + * the "dl_mjr_num" field is for the "major number of interface + * driver"; that's the major of "/dev/dlpi" on the system on + * which I tried this, but there may be DLPI devices that + * use a different driver, in which case we may need to + * search "/dev" for the appropriate device with that major + * device number, rather than hardwiring "/dev/dlpi". + */ + cp = "/dev/dlpi"; + if ((p->fd = open(cp, O_RDWR)) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "%s: %s", cp, pcap_strerror(errno)); + goto bad; + } + +#ifdef DL_HP_RAWDLS + /* + * XXX - HP-UX 10.20 and 11.xx don't appear to support sending and + * receiving packets on the same descriptor - you need separate + * descriptors for sending and receiving, bound to different SAPs. + * + * If the open fails, we just leave -1 in "p->send_fd" and reject + * attempts to send packets, just as if, in pcap-bpf.c, we fail + * to open the BPF device for reading and writing, we just try + * to open it for reading only and, if that succeeds, just let + * the send attempts fail. + */ + p->send_fd = open(cp, O_RDWR); +#endif + + /* + * Get a table of all PPAs for that device, and search that + * table for the specified device type name and unit number. + */ + ppa = get_dlpi_ppa(p->fd, dname, ppa, ebuf); + if (ppa < 0) + goto bad; +#else + /* + * If the device name begins with "/", assume it begins with + * the pathname of the directory containing the device to open; + * otherwise, concatenate the device directory name and the + * device name. + */ + if (*device == '/') + strlcpy(dname, device, sizeof(dname)); + else + snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX, + device); + + /* + * Get the unit number, and a pointer to the end of the device + * type name. + */ + cp = split_dname(dname, &ppa, ebuf); + if (cp == NULL) + goto bad; + + /* + * Make a copy of the device pathname, and then remove the unit + * number from the device pathname. + */ + strlcpy(dname2, dname, sizeof(dname)); + *cp = '\0'; + + /* Try device without unit number */ + if ((p->fd = open(dname, O_RDWR)) < 0) { + if (errno != ENOENT) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dname, + pcap_strerror(errno)); + goto bad; + } + + /* Try again with unit number */ + if ((p->fd = open(dname2, O_RDWR)) < 0) { + if (errno == ENOENT) { + /* + * We just report "No DLPI device found" + * with the device name, so people don't + * get confused and think, for example, + * that if they can't capture on "lo0" + * on Solaris the fix is to change libpcap + * (or the application that uses it) to + * look for something other than "/dev/lo0", + * as the fix is to look for an operating + * system other than Solaris - you just + * *can't* capture on a loopback interface + * on Solaris, the lack of a DLPI device + * for the loopback interface is just a + * symptom of that inability. + */ + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "%s: No DLPI device found", device); + } else { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", + dname2, pcap_strerror(errno)); + } + goto bad; + } + /* XXX Assume unit zero */ + ppa = 0; + } +#endif + + p->snapshot = snaplen; + + /* + ** Attach if "style 2" provider + */ + if (dlinforeq(p->fd, ebuf) < 0 || + dlinfoack(p->fd, (char *)buf, ebuf) < 0) + goto bad; + infop = &((union DL_primitives *)buf)->info_ack; +#ifdef HAVE_SOLARIS + if (infop->dl_mac_type == DL_IPATM) + isatm = 1; +#endif + if (infop->dl_provider_style == DL_STYLE2) { + if (dl_doattach(p->fd, ppa, ebuf) < 0) + goto bad; +#ifdef DL_HP_RAWDLS + if (p->send_fd >= 0) { + if (dl_doattach(p->send_fd, ppa, ebuf) < 0) + goto bad; + } +#endif + } + + /* + ** Bind (defer if using HP-UX 9 or HP-UX 10.20 or later, totally + ** skip if using SINIX) + */ +#if !defined(HAVE_HPUX9) && !defined(HAVE_HPUX10_20_OR_LATER) && !defined(sinix) +#ifdef _AIX + /* + ** AIX. + ** According to IBM's AIX Support Line, the dl_sap value + ** should not be less than 0x600 (1536) for standard Ethernet. + ** However, we seem to get DL_BADADDR - "DLSAP addr in improper + ** format or invalid" - errors if we use 1537 on the "tr0" + ** device, which, given that its name starts with "tr" and that + ** it's IBM, probably means a Token Ring device. (Perhaps we + ** need to use 1537 on "/dev/dlpi/en" because that device is for + ** D/I/X Ethernet, the "SAP" is actually an Ethernet type, and + ** it rejects invalid Ethernet types.) + ** + ** So if 1537 fails, we try 2, as Hyung Sik Yoon of IBM Korea + ** says that works on Token Ring (he says that 0 does *not* + ** work; perhaps that's considered an invalid LLC SAP value - I + ** assume the SAP value in a DLPI bind is an LLC SAP for network + ** types that use 802.2 LLC). + */ + if ((dlbindreq(p->fd, 1537, ebuf) < 0 && + dlbindreq(p->fd, 2, ebuf) < 0) || + dlbindack(p->fd, (char *)buf, ebuf, NULL) < 0) + goto bad; +#elif defined(DL_HP_RAWDLS) + /* + ** HP-UX 10.0x and 10.1x. + */ + if (dl_dohpuxbind(p->fd, ebuf) < 0) + goto bad; + if (p->send_fd >= 0) { + /* + ** XXX - if this fails, just close send_fd and + ** set it to -1, so that you can't send but can + ** still receive? + */ + if (dl_dohpuxbind(p->send_fd, ebuf) < 0) + goto bad; + } +#else /* neither AIX nor HP-UX */ + /* + ** Not Sinix, and neither AIX nor HP-UX - Solaris, and any other + ** OS using DLPI. + **/ + if (dlbindreq(p->fd, 0, ebuf) < 0 || + dlbindack(p->fd, (char *)buf, ebuf, NULL) < 0) + goto bad; +#endif /* AIX vs. HP-UX vs. other */ +#endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */ + +#ifdef HAVE_SOLARIS + if (isatm) { + /* + ** Have to turn on some special ATM promiscuous mode + ** for SunATM. + ** Do *NOT* turn regular promiscuous mode on; it doesn't + ** help, and may break things. + */ + if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "A_PROMISCON_REQ: %s", + pcap_strerror(errno)); + goto bad; + } + } else +#endif + if (promisc) { + /* + ** Enable promiscuous (not necessary on send FD) + */ + if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, ebuf) < 0 || + dlokack(p->fd, "promisc_phys", (char *)buf, ebuf) < 0) + goto bad; + + /* + ** Try to enable multicast (you would have thought + ** promiscuous would be sufficient). (Skip if using + ** HP-UX or SINIX) (Not necessary on send FD) + */ +#if !defined(__hpux) && !defined(sinix) + if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, ebuf) < 0 || + dlokack(p->fd, "promisc_multi", (char *)buf, ebuf) < 0) + fprintf(stderr, + "WARNING: DL_PROMISC_MULTI failed (%s)\n", ebuf); +#endif + } + /* + ** Try to enable SAP promiscuity (when not in promiscuous mode + ** when using HP-UX, when not doing SunATM on Solaris, and never + ** under SINIX) (Not necessary on send FD) + */ +#ifndef sinix + if ( +#ifdef __hpux + !promisc && +#endif +#ifdef HAVE_SOLARIS + !isatm && +#endif + (dlpromisconreq(p->fd, DL_PROMISC_SAP, ebuf) < 0 || + dlokack(p->fd, "promisc_sap", (char *)buf, ebuf) < 0)) { + /* Not fatal if promisc since the DL_PROMISC_PHYS worked */ + if (promisc) + fprintf(stderr, + "WARNING: DL_PROMISC_SAP failed (%s)\n", ebuf); + else + goto bad; + } +#endif /* sinix */ + + /* + ** HP-UX 9, and HP-UX 10.20 or later, must bind after setting + ** promiscuous options. + */ +#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER) + if (dl_dohpuxbind(p->fd, ebuf) < 0) + goto bad; + /* + ** We don't set promiscuous mode on the send FD, but we'll defer + ** binding it anyway, just to keep the HP-UX 9/10.20 or later + ** code together. + */ + if (p->send_fd >= 0) { + /* + ** XXX - if this fails, just close send_fd and + ** set it to -1, so that you can't send but can + ** still receive? + */ + if (dl_dohpuxbind(p->send_fd, ebuf) < 0) + goto bad; + } +#endif + + /* + ** Determine link type + ** XXX - get SAP length and address length as well, for use + ** when sending packets. + */ + if (dlinforeq(p->fd, ebuf) < 0 || + dlinfoack(p->fd, (char *)buf, ebuf) < 0) + goto bad; + + infop = &((union DL_primitives *)buf)->info_ack; + switch (infop->dl_mac_type) { + + case DL_CSMACD: + case DL_ETHER: + p->linktype = DLT_EN10MB; + p->offset = 2; + /* + * This is (presumably) a real Ethernet capture; give it a + * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so + * that an application can let you choose it, in case you're + * capturing DOCSIS traffic that a Cisco Cable Modem + * Termination System is putting out onto an Ethernet (it + * doesn't put an Ethernet header onto the wire, it puts raw + * DOCSIS frames out on the wire inside the low-level + * Ethernet framing). + */ + p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); + /* + * If that fails, just leave the list empty. + */ + if (p->dlt_list != NULL) { + p->dlt_list[0] = DLT_EN10MB; + p->dlt_list[1] = DLT_DOCSIS; + p->dlt_count = 2; + } + break; + + case DL_FDDI: + p->linktype = DLT_FDDI; + p->offset = 3; + break; + + case DL_TPR: + /* + * XXX - what about DL_TPB? Is that Token Bus? + */ + p->linktype = DLT_IEEE802; + p->offset = 2; + break; + +#ifdef HAVE_SOLARIS + case DL_IPATM: + p->linktype = DLT_SUNATM; + p->offset = 0; /* works for LANE and LLC encapsulation */ + break; +#endif + + default: + snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown mac type %lu", + (unsigned long)infop->dl_mac_type); + goto bad; + } + +#ifdef DLIOCRAW + /* + ** This is a non standard SunOS hack to get the full raw link-layer + ** header. + */ + if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s", + pcap_strerror(errno)); + goto bad; + } +#endif + +#ifdef HAVE_SYS_BUFMOD_H + /* + ** Another non standard call to get the data nicely buffered + */ + if (ioctl(p->fd, I_PUSH, "bufmod") != 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_PUSH bufmod: %s", + pcap_strerror(errno)); + goto bad; + } + + /* + ** Now that the bufmod is pushed lets configure it. + ** + ** There is a bug in bufmod(7). When dealing with messages of + ** less than snaplen size it strips data from the beginning not + ** the end. + ** + ** This bug is supposed to be fixed in 5.3.2. Also, there is a + ** patch available. Ask for bugid 1149065. + */ + ss = snaplen; +#ifdef HAVE_SOLARIS + release = get_release(&osmajor, &osminor, &osmicro); + if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) && + getenv("BUFMOD_FIXED") == NULL) { + fprintf(stderr, + "WARNING: bufmod is broken in SunOS %s; ignoring snaplen.\n", + release); + ss = 0; + } +#endif + if (ss > 0 && + strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSSNAP: %s", + pcap_strerror(errno)); + goto bad; + } + + /* + ** Set up the bufmod timeout + */ + if (to_ms != 0) { + struct timeval to; + + to.tv_sec = to_ms / 1000; + to.tv_usec = (to_ms * 1000) % 1000000; + if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSTIME: %s", + pcap_strerror(errno)); + goto bad; + } + } + + /* + ** Set the chunk length. + */ + chunksize = CHUNKSIZE; + if (strioctl(p->fd, SBIOCSCHUNK, sizeof(chunksize), (char *)&chunksize) + != 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSCHUNKP: %s", + pcap_strerror(errno)); + goto bad; + } +#endif + + /* + ** As the last operation flush the read side. + */ + if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s", + pcap_strerror(errno)); + goto bad; + } + + /* Allocate data buffer */ + p->bufsize = PKTBUFSIZE; + p->buffer = (u_char *)malloc(p->bufsize + p->offset); + if (p->buffer == NULL) { + strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); + goto bad; + } + + /* + * "p->fd" is an FD for a STREAMS device, so "select()" and + * "poll()" should work on it. + */ + p->selectable_fd = p->fd; + + p->read_op = pcap_read_dlpi; + p->inject_op = pcap_inject_dlpi; + p->setfilter_op = install_bpf_program; /* no kernel filtering */ + p->setdirection_op = NULL; /* Not implemented.*/ + p->set_datalink_op = NULL; /* can't change data link type */ + p->getnonblock_op = pcap_getnonblock_fd; + p->setnonblock_op = pcap_setnonblock_fd; + p->stats_op = pcap_stats_dlpi; + p->close_op = pcap_close_dlpi; + + return (p); +bad: + if (p->fd >= 0) + close(p->fd); + if (p->send_fd >= 0) + close(p->send_fd); + /* + * Get rid of any link-layer type list we allocated. + */ + if (p->dlt_list != NULL) + free(p->dlt_list); + free(p); + return (NULL); +} + +/* + * Split a device name into a device type name and a unit number; + * return the a pointer to the beginning of the unit number, which + * is the end of the device type name, and set "*unitp" to the unit + * number. + * + * Returns NULL on error, and fills "ebuf" with an error message. + */ +static char * +split_dname(char *device, int *unitp, char *ebuf) +{ + char *cp; + char *eos; + long unit; + + /* + * Look for a number at the end of the device name string. + */ + cp = device + strlen(device) - 1; + if (*cp < '0' || *cp > '9') { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number", + device); + return (NULL); + } + + /* Digits at end of string are unit number */ + while (cp-1 >= device && *(cp-1) >= '0' && *(cp-1) <= '9') + cp--; + + errno = 0; + unit = strtol(cp, &eos, 10); + if (*eos != '\0') { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device); + return (NULL); + } + if (errno == ERANGE || unit > INT_MAX) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number too large", + device); + return (NULL); + } + if (unit < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number is negative", + device); + return (NULL); + } + *unitp = (int)unit; + return (cp); +} + +static int +dl_doattach(int fd, int ppa, char *ebuf) +{ + bpf_u_int32 buf[MAXDLBUF]; + + if (dlattachreq(fd, ppa, ebuf) < 0 || + dlokack(fd, "attach", (char *)buf, ebuf) < 0) + return (-1); + return (0); +} + +#ifdef DL_HP_RAWDLS +static int +dl_dohpuxbind(int fd, char *ebuf) +{ + int hpsap; + int uerror; + bpf_u_int32 buf[MAXDLBUF]; + + /* + * XXX - we start at 22 because we used to use only 22, but + * that was just because that was the value used in some + * sample code from HP. With what value *should* we start? + * Does it matter, given that we're enabling SAP promiscuity + * on the input FD? + */ + hpsap = 22; + for (;;) { + if (dlbindreq(fd, hpsap, ebuf) < 0) + return (-1); + if (dlbindack(fd, (char *)buf, ebuf, &uerror) >= 0) + break; + /* + * For any error other than a UNIX EBUSY, give up. + */ + if (uerror != EBUSY) { + /* + * dlbindack() has already filled in ebuf for + * this error. + */ + return (-1); + } + + /* + * For EBUSY, try the next SAP value; that means that + * somebody else is using that SAP. Clear ebuf so + * that application doesn't report the "Device busy" + * error as a warning. + */ + *ebuf = '\0'; + hpsap++; + if (hpsap > 100) { + strlcpy(ebuf, + "All SAPs from 22 through 100 are in use", + PCAP_ERRBUF_SIZE); + return (-1); + } + } + return (0); +} +#endif + +int +pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) +{ +#ifdef HAVE_SOLARIS + int fd; + union { + u_int nunits; + char pad[516]; /* XXX - must be at least 513; is 516 + in "atmgetunits" */ + } buf; + char baname[2+1+1]; + u_int i; + + /* + * We may have to do special magic to get ATM devices. + */ + if ((fd = open("/dev/ba", O_RDWR)) < 0) { + /* + * We couldn't open the "ba" device. + * For now, just give up; perhaps we should + * return an error if the problem is neither + * a "that device doesn't exist" error (ENOENT, + * ENXIO, etc.) or a "you're not allowed to do + * that" error (EPERM, EACCES). + */ + return (0); + } + + if (strioctl(fd, A_GET_UNITS, sizeof(buf), (char *)&buf) < 0) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s", + pcap_strerror(errno)); + return (-1); + } + for (i = 0; i < buf.nunits; i++) { + snprintf(baname, sizeof baname, "ba%u", i); + if (pcap_add_if(alldevsp, baname, 0, NULL, errbuf) < 0) + return (-1); + } +#endif + + return (0); +} + +static int +send_request(int fd, char *ptr, int len, char *what, char *ebuf) +{ + struct strbuf ctl; + int flags; + + ctl.maxlen = 0; + ctl.len = len; + ctl.buf = ptr; + + flags = 0; + if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "send_request: putmsg \"%s\": %s", + what, pcap_strerror(errno)); + return (-1); + } + return (0); +} + +static int +recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror) +{ + union DL_primitives *dlp; + struct strbuf ctl; + int flags; + + /* + * Clear out "*uerror", so it's only set for DL_ERROR_ACK/DL_SYSERR, + * making that the only place where EBUSY is treated specially. + */ + if (uerror != NULL) + *uerror = 0; + + ctl.maxlen = MAXDLBUF; + ctl.len = 0; + ctl.buf = bufp; + + flags = 0; + if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s", + what, pcap_strerror(errno)); + return (-1); + } + + dlp = (union DL_primitives *) ctl.buf; + switch (dlp->dl_primitive) { + + case DL_INFO_ACK: + case DL_BIND_ACK: + case DL_OK_ACK: +#ifdef DL_HP_PPA_ACK + case DL_HP_PPA_ACK: +#endif + /* These are OK */ + break; + + case DL_ERROR_ACK: + switch (dlp->error_ack.dl_errno) { + + case DL_SYSERR: + if (uerror != NULL) + *uerror = dlp->error_ack.dl_unix_errno; + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "recv_ack: %s: UNIX error - %s", + what, pcap_strerror(dlp->error_ack.dl_unix_errno)); + break; + + default: + snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s", + what, dlstrerror(dlp->error_ack.dl_errno)); + break; + } + return (-1); + + default: + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "recv_ack: %s: Unexpected primitive ack %s", + what, dlprim(dlp->dl_primitive)); + return (-1); + } + + if (ctl.len < size) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "recv_ack: %s: Ack too small (%d < %d)", + what, ctl.len, size); + return (-1); + } + return (ctl.len); +} + +static char * +dlstrerror(bpf_u_int32 dl_errno) +{ + static char errstring[6+2+8+1]; + + switch (dl_errno) { + + case DL_ACCESS: + return ("Improper permissions for request"); + + case DL_BADADDR: + return ("DLSAP addr in improper format or invalid"); + + case DL_BADCORR: + return ("Seq number not from outstand DL_CONN_IND"); + + case DL_BADDATA: + return ("User data exceeded provider limit"); + + case DL_BADPPA: +#ifdef HAVE_DEV_DLPI + /* + * With a single "/dev/dlpi" device used for all + * DLPI providers, PPAs have nothing to do with + * unit numbers. + */ + return ("Specified PPA was invalid"); +#else + /* + * We have separate devices for separate devices; + * the PPA is just the unit number. + */ + return ("Specified PPA (device unit) was invalid"); +#endif + + case DL_BADPRIM: + return ("Primitive received not known by provider"); + + case DL_BADQOSPARAM: + return ("QOS parameters contained invalid values"); + + case DL_BADQOSTYPE: + return ("QOS structure type is unknown/unsupported"); + + case DL_BADSAP: + return ("Bad LSAP selector"); + + case DL_BADTOKEN: + return ("Token used not an active stream"); + + case DL_BOUND: + return ("Attempted second bind with dl_max_conind"); + + case DL_INITFAILED: + return ("Physical link initialization failed"); + + case DL_NOADDR: + return ("Provider couldn't allocate alternate address"); + + case DL_NOTINIT: + return ("Physical link not initialized"); + + case DL_OUTSTATE: + return ("Primitive issued in improper state"); + + case DL_SYSERR: + return ("UNIX system error occurred"); + + case DL_UNSUPPORTED: + return ("Requested service not supplied by provider"); + + case DL_UNDELIVERABLE: + return ("Previous data unit could not be delivered"); + + case DL_NOTSUPPORTED: + return ("Primitive is known but not supported"); + + case DL_TOOMANY: + return ("Limit exceeded"); + + case DL_NOTENAB: + return ("Promiscuous mode not enabled"); + + case DL_BUSY: + return ("Other streams for PPA in post-attached"); + + case DL_NOAUTO: + return ("Automatic handling XID&TEST not supported"); + + case DL_NOXIDAUTO: + return ("Automatic handling of XID not supported"); + + case DL_NOTESTAUTO: + return ("Automatic handling of TEST not supported"); + + case DL_XIDAUTO: + return ("Automatic handling of XID response"); + + case DL_TESTAUTO: + return ("Automatic handling of TEST response"); + + case DL_PENDING: + return ("Pending outstanding connect indications"); + + default: + sprintf(errstring, "Error %02x", dl_errno); + return (errstring); + } +} + +static char * +dlprim(bpf_u_int32 prim) +{ + static char primbuf[80]; + + switch (prim) { + + case DL_INFO_REQ: + return ("DL_INFO_REQ"); + + case DL_INFO_ACK: + return ("DL_INFO_ACK"); + + case DL_ATTACH_REQ: + return ("DL_ATTACH_REQ"); + + case DL_DETACH_REQ: + return ("DL_DETACH_REQ"); + + case DL_BIND_REQ: + return ("DL_BIND_REQ"); + + case DL_BIND_ACK: + return ("DL_BIND_ACK"); + + case DL_UNBIND_REQ: + return ("DL_UNBIND_REQ"); + + case DL_OK_ACK: + return ("DL_OK_ACK"); + + case DL_ERROR_ACK: + return ("DL_ERROR_ACK"); + + case DL_SUBS_BIND_REQ: + return ("DL_SUBS_BIND_REQ"); + + case DL_SUBS_BIND_ACK: + return ("DL_SUBS_BIND_ACK"); + + case DL_UNITDATA_REQ: + return ("DL_UNITDATA_REQ"); + + case DL_UNITDATA_IND: + return ("DL_UNITDATA_IND"); + + case DL_UDERROR_IND: + return ("DL_UDERROR_IND"); + + case DL_UDQOS_REQ: + return ("DL_UDQOS_REQ"); + + case DL_CONNECT_REQ: + return ("DL_CONNECT_REQ"); + + case DL_CONNECT_IND: + return ("DL_CONNECT_IND"); + + case DL_CONNECT_RES: + return ("DL_CONNECT_RES"); + + case DL_CONNECT_CON: + return ("DL_CONNECT_CON"); + + case DL_TOKEN_REQ: + return ("DL_TOKEN_REQ"); + + case DL_TOKEN_ACK: + return ("DL_TOKEN_ACK"); + + case DL_DISCONNECT_REQ: + return ("DL_DISCONNECT_REQ"); + + case DL_DISCONNECT_IND: + return ("DL_DISCONNECT_IND"); + + case DL_RESET_REQ: + return ("DL_RESET_REQ"); + + case DL_RESET_IND: + return ("DL_RESET_IND"); + + case DL_RESET_RES: + return ("DL_RESET_RES"); + + case DL_RESET_CON: + return ("DL_RESET_CON"); + + default: + (void) sprintf(primbuf, "unknown primitive 0x%x", prim); + return (primbuf); + } +} + +static int +dlattachreq(int fd, bpf_u_int32 ppa, char *ebuf) +{ + dl_attach_req_t req; + + req.dl_primitive = DL_ATTACH_REQ; + req.dl_ppa = ppa; + + return (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf)); +} + +static int +dlbindreq(int fd, bpf_u_int32 sap, char *ebuf) +{ + + dl_bind_req_t req; + + memset((char *)&req, 0, sizeof(req)); + req.dl_primitive = DL_BIND_REQ; + /* XXX - what if neither of these are defined? */ +#if defined(DL_HP_RAWDLS) + req.dl_max_conind = 1; /* XXX magic number */ + req.dl_service_mode = DL_HP_RAWDLS; +#elif defined(DL_CLDLS) + req.dl_service_mode = DL_CLDLS; +#endif + req.dl_sap = sap; + + return (send_request(fd, (char *)&req, sizeof(req), "bind", ebuf)); +} + +static int +dlbindack(int fd, char *bufp, char *ebuf, int *uerror) +{ + + return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf, uerror)); +} + +static int +dlpromisconreq(int fd, bpf_u_int32 level, char *ebuf) +{ + dl_promiscon_req_t req; + + req.dl_primitive = DL_PROMISCON_REQ; + req.dl_level = level; + + return (send_request(fd, (char *)&req, sizeof(req), "promiscon", ebuf)); +} + +static int +dlokack(int fd, const char *what, char *bufp, char *ebuf) +{ + + return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf, NULL)); +} + + +static int +dlinforeq(int fd, char *ebuf) +{ + dl_info_req_t req; + + req.dl_primitive = DL_INFO_REQ; + + return (send_request(fd, (char *)&req, sizeof(req), "info", ebuf)); +} + +static int +dlinfoack(int fd, char *bufp, char *ebuf) +{ + + return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf, NULL)); +} + +#ifdef DL_HP_RAWDLS +/* + * There's an ack *if* there's an error. + */ +static int +dlrawdatareq(int fd, const u_char *datap, int datalen) +{ + struct strbuf ctl, data; + long buf[MAXDLBUF]; /* XXX - char? */ + union DL_primitives *dlp; + int dlen; + + dlp = (union DL_primitives*) buf; + + dlp->dl_primitive = DL_HP_RAWDATA_REQ; + dlen = DL_HP_RAWDATA_REQ_SIZE; + + /* + * HP's documentation doesn't appear to show us supplying any + * address pointed to by the control part of the message. + * I think that's what raw mode means - you just send the raw + * packet, you don't specify where to send it to, as that's + * implied by the destination address. + */ + ctl.maxlen = 0; + ctl.len = dlen; + ctl.buf = (void *)buf; + + data.maxlen = 0; + data.len = datalen; + data.buf = (void *)datap; + + return (putmsg(fd, &ctl, &data, 0)); +} +#endif /* DL_HP_RAWDLS */ + +#ifdef HAVE_SYS_BUFMOD_H +static int +strioctl(int fd, int cmd, int len, char *dp) +{ + struct strioctl str; + int rc; + + str.ic_cmd = cmd; + str.ic_timout = -1; + str.ic_len = len; + str.ic_dp = dp; + rc = ioctl(fd, I_STR, &str); + + if (rc < 0) + return (rc); + else + return (str.ic_len); +} +#endif + +#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) +static char * +get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp) +{ + char *cp; + static char buf[32]; + + *majorp = 0; + *minorp = 0; + *microp = 0; + if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0) + return ("?"); + cp = buf; + if (!isdigit((unsigned char)*cp)) + return (buf); + *majorp = strtol(cp, &cp, 10); + if (*cp++ != '.') + return (buf); + *minorp = strtol(cp, &cp, 10); + if (*cp++ != '.') + return (buf); + *microp = strtol(cp, &cp, 10); + return (buf); +} +#endif + +#ifdef DL_HP_PPA_REQ +/* + * Under HP-UX 10 and HP-UX 11, we can ask for the ppa + */ + + +/* + * Determine ppa number that specifies ifname. + * + * If the "dl_hp_ppa_info_t" doesn't have a "dl_module_id_1" member, + * the code that's used here is the old code for HP-UX 10.x. + * + * However, HP-UX 10.20, at least, appears to have such a member + * in its "dl_hp_ppa_info_t" structure, so the new code is used. + * The new code didn't work on an old 10.20 system on which Rick + * Jones of HP tried it, but with later patches installed, it + * worked - it appears that the older system had those members but + * didn't put anything in them, so, if the search by name fails, we + * do the old search. + * + * Rick suggests that making sure your system is "up on the latest + * lancommon/DLPI/driver patches" is probably a good idea; it'd fix + * that problem, as well as allowing libpcap to see packets sent + * from the system on which the libpcap application is being run. + * (On 10.20, in addition to getting the latest patches, you need + * to turn the kernel "lanc_outbound_promisc_flag" flag on with ADB; + * a posting to "comp.sys.hp.hpux" at + * + * http://www.deja.com/[ST_rn=ps]/getdoc.xp?AN=558092266 + * + * says that, to see the machine's outgoing traffic, you'd need to + * apply the right patches to your system, and also set that variable + * with: + +echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem + + * which could be put in, for example, "/sbin/init.d/lan". + * + * Setting the variable is not necessary on HP-UX 11.x. + */ +static int +get_dlpi_ppa(register int fd, register const char *device, register int unit, + register char *ebuf) +{ + register dl_hp_ppa_ack_t *ap; + register dl_hp_ppa_info_t *ipstart, *ip; + register int i; + char dname[100]; + register u_long majdev; + struct stat statbuf; + dl_hp_ppa_req_t req; + char buf[MAXDLBUF]; + char *ppa_data_buf; + dl_hp_ppa_ack_t *dlp; + struct strbuf ctl; + int flags; + int ppa; + + memset((char *)&req, 0, sizeof(req)); + req.dl_primitive = DL_HP_PPA_REQ; + + memset((char *)buf, 0, sizeof(buf)); + if (send_request(fd, (char *)&req, sizeof(req), "hpppa", ebuf) < 0) + return (-1); + + ctl.maxlen = DL_HP_PPA_ACK_SIZE; + ctl.len = 0; + ctl.buf = (char *)buf; + + flags = 0; + /* + * DLPI may return a big chunk of data for a DL_HP_PPA_REQ. The normal + * recv_ack will fail because it set the maxlen to MAXDLBUF (8192) + * which is NOT big enough for a DL_HP_PPA_REQ. + * + * This causes libpcap applications to fail on a system with HP-APA + * installed. + * + * To figure out how big the returned data is, we first call getmsg + * to get the small head and peek at the head to get the actual data + * length, and then issue another getmsg to get the actual PPA data. + */ + /* get the head first */ + if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno)); + return (-1); + } + + dlp = (dl_hp_ppa_ack_t *)ctl.buf; + if (dlp->dl_primitive != DL_HP_PPA_ACK) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "get_dlpi_ppa: hpppa unexpected primitive ack 0x%x", + (bpf_u_int32)dlp->dl_primitive); + return (-1); + } + + if (ctl.len < DL_HP_PPA_ACK_SIZE) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "get_dlpi_ppa: hpppa ack too small (%d < %lu)", + ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE); + return (-1); + } + + /* allocate buffer */ + if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno)); + return (-1); + } + ctl.maxlen = dlp->dl_length; + ctl.len = 0; + ctl.buf = (char *)ppa_data_buf; + /* get the data */ + if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno)); + free(ppa_data_buf); + return (-1); + } + if (ctl.len < dlp->dl_length) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "get_dlpi_ppa: hpppa ack too small (%d < %d)", + ctl.len, dlp->dl_length); + free(ppa_data_buf); + return (-1); + } + + ap = (dl_hp_ppa_ack_t *)buf; + ipstart = (dl_hp_ppa_info_t *)ppa_data_buf; + ip = ipstart; + +#ifdef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 + /* + * The "dl_hp_ppa_info_t" structure has a "dl_module_id_1" + * member that should, in theory, contain the part of the + * name for the device that comes before the unit number, + * and should also have a "dl_module_id_2" member that may + * contain an alternate name (e.g., I think Ethernet devices + * have both "lan", for "lanN", and "snap", for "snapN", with + * the former being for Ethernet packets and the latter being + * for 802.3/802.2 packets). + * + * Search for the device that has the specified name and + * instance number. + */ + for (i = 0; i < ap->dl_count; i++) { + if ((strcmp((const char *)ip->dl_module_id_1, device) == 0 || + strcmp((const char *)ip->dl_module_id_2, device) == 0) && + ip->dl_instance_num == unit) + break; + + ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset); + } +#else + /* + * We don't have that member, so the search is impossible; make it + * look as if the search failed. + */ + i = ap->dl_count; +#endif + + if (i == ap->dl_count) { + /* + * Well, we didn't, or can't, find the device by name. + * + * HP-UX 10.20, whilst it has "dl_module_id_1" and + * "dl_module_id_2" fields in the "dl_hp_ppa_info_t", + * doesn't seem to fill them in unless the system is + * at a reasonably up-to-date patch level. + * + * Older HP-UX 10.x systems might not have those fields + * at all. + * + * Therefore, we'll search for the entry with the major + * device number of a device with the name "/dev/", + * if such a device exists, as the old code did. + */ + snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit); + if (stat(dname, &statbuf) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s", + dname, pcap_strerror(errno)); + return (-1); + } + majdev = major(statbuf.st_rdev); + + ip = ipstart; + + for (i = 0; i < ap->dl_count; i++) { + if (ip->dl_mjr_num == majdev && + ip->dl_instance_num == unit) + break; + + ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset); + } + } + if (i == ap->dl_count) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "can't find /dev/dlpi PPA for %s%d", device, unit); + return (-1); + } + if (ip->dl_hdw_state == HDW_DEAD) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "%s%d: hardware state: DOWN\n", device, unit); + free(ppa_data_buf); + return (-1); + } + ppa = ip->dl_ppa; + free(ppa_data_buf); + return (ppa); +} +#endif + +#ifdef HAVE_HPUX9 +/* + * Under HP-UX 9, there is no good way to determine the ppa. + * So punt and read it from /dev/kmem. + */ +static struct nlist nl[] = { +#define NL_IFNET 0 + { "ifnet" }, + { "" } +}; + +static char path_vmunix[] = "/hp-ux"; + +/* Determine ppa number that specifies ifname */ +static int +get_dlpi_ppa(register int fd, register const char *ifname, register int unit, + register char *ebuf) +{ + register const char *cp; + register int kd; + void *addr; + struct ifnet ifnet; + char if_name[sizeof(ifnet.if_name) + 1]; + + cp = strrchr(ifname, '/'); + if (cp != NULL) + ifname = cp + 1; + if (nlist(path_vmunix, &nl) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed", + path_vmunix); + return (-1); + } + if (nl[NL_IFNET].n_value == 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "could't find %s kernel symbol", + nl[NL_IFNET].n_name); + return (-1); + } + kd = open("/dev/kmem", O_RDONLY); + if (kd < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s", + pcap_strerror(errno)); + return (-1); + } + if (dlpi_kread(kd, nl[NL_IFNET].n_value, + &addr, sizeof(addr), ebuf) < 0) { + close(kd); + return (-1); + } + for (; addr != NULL; addr = ifnet.if_next) { + if (dlpi_kread(kd, (off_t)addr, + &ifnet, sizeof(ifnet), ebuf) < 0 || + dlpi_kread(kd, (off_t)ifnet.if_name, + if_name, sizeof(ifnet.if_name), ebuf) < 0) { + (void)close(kd); + return (-1); + } + if_name[sizeof(ifnet.if_name)] = '\0'; + if (strcmp(if_name, ifname) == 0 && ifnet.if_unit == unit) + return (ifnet.if_index); + } + + snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname); + return (-1); +} + +static int +dlpi_kread(register int fd, register off_t addr, + register void *buf, register u_int len, register char *ebuf) +{ + register int cc; + + if (lseek(fd, addr, SEEK_SET) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "lseek: %s", + pcap_strerror(errno)); + return (-1); + } + cc = read(fd, buf, len); + if (cc < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s", + pcap_strerror(errno)); + return (-1); + } else if (cc != len) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc, + len); + return (-1); + } + return (cc); +} +#endif diff --git a/winpcap/wpcap/libpcap/pcap-dos.c b/winpcap/wpcap/libpcap/pcap-dos.c new file mode 100644 index 0000000..0700d6b --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-dos.c @@ -0,0 +1,1474 @@ +/* + * This file is part of DOS-libpcap + * Ported to DOS/DOSX by G. Vanem + * + * pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode + * network drivers. + * + * @(#) $Header: /tcpdump/master/libpcap/pcap-dos.c,v 1.1.2.1 2005/05/03 18:54:35 guy Exp $ (LBL) + */ + +#include +#include +#include +#include +#include +#include +#include + +#if defined(USE_32BIT_DRIVERS) + #include "msdos/pm_drvr/pmdrvr.h" + #include "msdos/pm_drvr/pci.h" + #include "msdos/pm_drvr/bios32.h" + #include "msdos/pm_drvr/module.h" + #include "msdos/pm_drvr/3c501.h" + #include "msdos/pm_drvr/3c503.h" + #include "msdos/pm_drvr/3c509.h" + #include "msdos/pm_drvr/3c59x.h" + #include "msdos/pm_drvr/3c515.h" + #include "msdos/pm_drvr/3c90x.h" + #include "msdos/pm_drvr/3c575_cb.h" + #include "msdos/pm_drvr/ne.h" + #include "msdos/pm_drvr/wd.h" + #include "msdos/pm_drvr/accton.h" + #include "msdos/pm_drvr/cs89x0.h" + #include "msdos/pm_drvr/rtl8139.h" + #include "msdos/pm_drvr/ne2k-pci.h" +#endif + +#include "pcap.h" +#include "pcap-dos.h" +#include "pcap-int.h" +#include "msdos/pktdrvr.h" + +#ifdef USE_NDIS2 +#include "msdos/ndis2.h" +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(USE_32BIT_DRIVERS) + #define FLUSHK() do { _printk_safe = 1; _printk_flush(); } while (0) + #define NDIS_NEXT_DEV &rtl8139_dev + + static char *rx_pool = NULL; + static void init_32bit (void); + + static int pktq_init (struct rx_ringbuf *q, int size, int num, char *pool); + static int pktq_check (struct rx_ringbuf *q); + static int pktq_inc_out (struct rx_ringbuf *q); + static int pktq_in_index (struct rx_ringbuf *q) LOCKED_FUNC; + static void pktq_clear (struct rx_ringbuf *q) LOCKED_FUNC; + + static struct rx_elem *pktq_in_elem (struct rx_ringbuf *q) LOCKED_FUNC; + static struct rx_elem *pktq_out_elem (struct rx_ringbuf *q); + +#else + #define FLUSHK() ((void)0) + #define NDIS_NEXT_DEV NULL +#endif + +/* + * Internal variables/functions in Watt-32 + */ +extern WORD _pktdevclass; +extern BOOL _eth_is_init; +extern int _w32_dynamic_host; +extern int _watt_do_exit; +extern int _watt_is_init; +extern int _w32__bootp_on, _w32__dhcp_on, _w32__rarp_on, _w32__do_mask_req; +extern void (*_w32_usr_post_init) (void); +extern void (*_w32_print_hook)(); + +extern void dbug_write (const char *); /* Watt-32 lib, pcdbug.c */ +extern int pkt_get_mtu (void); + +static int ref_count = 0; + +static u_long mac_count = 0; +static u_long filter_count = 0; + +static volatile BOOL exc_occured = 0; + +static struct device *handle_to_device [20]; + +static int pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, + u_char *data); +static void pcap_close_dos (pcap_t *p); +static int pcap_stats_dos (pcap_t *p, struct pcap_stat *ps); +static int pcap_sendpacket_dos (pcap_t *p, const void *buf, size_t len); +static int pcap_setfilter_dos (pcap_t *p, struct bpf_program *fp); + +static int ndis_probe (struct device *dev); +static int pkt_probe (struct device *dev); + +static void close_driver (void); +static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf); +static int first_init (const char *name, char *ebuf, int promisc); + +static void watt32_recv_hook (u_char *dummy, const struct pcap_pkthdr *pcap, + const u_char *buf); + +/* + * These are the device we always support + */ +static struct device ndis_dev = { + "ndis", + "NDIS2 LanManager", + 0, + 0,0,0,0,0,0, + NDIS_NEXT_DEV, /* NULL or a 32-bit device */ + ndis_probe + }; + +static struct device pkt_dev = { + "pkt", + "Packet-Driver", + 0, + 0,0,0,0,0,0, + &ndis_dev, + pkt_probe + }; + +static struct device *get_device (int fd) +{ + if (fd <= 0 || fd >= sizeof(handle_to_device)/sizeof(handle_to_device[0])) + return (NULL); + return handle_to_device [fd-1]; +} + +/* + * Open MAC-driver with name 'device_name' for live capture of + * network packets. + */ +pcap_t *pcap_open_live (const char *device_name, int snaplen, int promisc, + int timeout_ms, char *errbuf) +{ + struct pcap *pcap; + + if (snaplen < ETH_MIN) + snaplen = ETH_MIN; + + if (snaplen > ETH_MAX) /* silently accept and truncate large MTUs */ + snaplen = ETH_MAX; + + pcap = calloc (sizeof(*pcap), 1); + if (!pcap) + { + strcpy (errbuf, "Not enough memory (pcap)"); + return (NULL); + } + + pcap->snapshot = max (ETH_MIN+8, snaplen); + pcap->linktype = DLT_EN10MB; /* !! */ + pcap->inter_packet_wait = timeout_ms; + pcap->close_op = pcap_close_dos; + pcap->read_op = pcap_read_dos; + pcap->stats_op = pcap_stats_dos; + pcap->inject_op = pcap_sendpacket_dos; + pcap->setfilter_op = pcap_setfilter_dos; + pcap->setdirection_op = NULL; /* Not implemented.*/ + pcap->fd = ++ref_count; + + if (pcap->fd == 1) /* first time we're called */ + { + if (!init_watt32(pcap, device_name, errbuf) || + !first_init(device_name, errbuf, promisc)) + { + free (pcap); + return (NULL); + } + atexit (close_driver); + } + else if (stricmp(active_dev->name,device_name)) + { + snprintf (errbuf, PCAP_ERRBUF_SIZE, + "Cannot use different devices simultaneously " + "(`%s' vs. `%s')", active_dev->name, device_name); + free (pcap); + pcap = NULL; + } + handle_to_device [pcap->fd-1] = active_dev; + return (pcap); +} + +/* + * Poll the receiver queue and call the pcap callback-handler + * with the packet. + */ +static int +pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data) +{ + struct pcap_pkthdr pcap; + struct bpf_insn *fcode = p->fcode.bf_insns; + struct timeval now, expiry; + BYTE *rx_buf; + int rx_len = 0; + + if (p->inter_packet_wait > 0) + { + gettimeofday2 (&now, NULL); + expiry.tv_usec = now.tv_usec + 1000UL * p->inter_packet_wait; + expiry.tv_sec = now.tv_sec; + while (expiry.tv_usec >= 1000000L) + { + expiry.tv_usec -= 1000000L; + expiry.tv_sec++; + } + } + + while (!exc_occured) + { + volatile struct device *dev; /* might be reset by sig_handler */ + + dev = get_device (p->fd); + if (!dev) + break; + + PCAP_ASSERT (dev->copy_rx_buf || dev->peek_rx_buf); + FLUSHK(); + + /* If driver has a zero-copy receive facility, peek at the queue, + * filter it, do the callback and release the buffer. + */ + if (dev->peek_rx_buf) + { + PCAP_ASSERT (dev->release_rx_buf); + rx_len = (*dev->peek_rx_buf) (&rx_buf); + } + else + { + BYTE buf [ETH_MAX+100]; /* add some margin */ + rx_len = (*dev->copy_rx_buf) (buf, p->snapshot); + rx_buf = buf; + } + + if (rx_len > 0) /* got a packet */ + { + mac_count++; + + FLUSHK(); + + pcap.caplen = min (rx_len, p->snapshot); + pcap.len = rx_len; + + if (callback && + (!fcode || bpf_filter(fcode, rx_buf, pcap.len, pcap.caplen))) + { + filter_count++; + + /* Fix-me!! Should be time of arrival. Not time of + * capture. + */ + gettimeofday2 (&pcap.ts, NULL); + (*callback) (data, &pcap, rx_buf); + } + + if (dev->release_rx_buf) + (*dev->release_rx_buf) (rx_buf); + + if (pcap_pkt_debug > 0) + { + if (callback == watt32_recv_hook) + dbug_write ("pcap_recv_hook\n"); + else dbug_write ("pcap_read_op\n"); + } + FLUSHK(); + return (1); + } + + /* If not to wait for a packet or pcap_close() called from + * e.g. SIGINT handler, exit loop now. + */ + if (p->inter_packet_wait <= 0 || (volatile int)p->fd <= 0) + break; + + gettimeofday2 (&now, NULL); + + if (timercmp(&now, &expiry, >)) + break; + +#ifndef DJGPP + kbhit(); /* a real CPU hog */ +#endif + + if (p->wait_proc) + (*p->wait_proc)(); /* call yield func */ + } + + if (rx_len < 0) /* receive error */ + { + p->md.stat.ps_drop++; +#ifdef USE_32BIT_DRIVERS + if (pcap_pkt_debug > 1) + printk ("pkt-err %s\n", pktInfo.error); +#endif + return (-1); + } + return (0); +} + +static int +pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, u_char *data) +{ + int rc, num = 0; + + while (num <= cnt || (cnt < 0)) + { + if (p->fd <= 0) + return (-1); + rc = pcap_read_one (p, callback, data); + if (rc > 0) + num++; + if (rc < 0) + break; + _w32_os_yield(); /* allow SIGINT generation, yield to Win95/NT */ + } + return (num); +} + +/* + * Return network statistics + */ +static int pcap_stats_dos (pcap_t *p, struct pcap_stat *ps) +{ + struct net_device_stats *stats; + struct device *dev = p ? get_device(p->fd) : NULL; + + if (!dev) + { + strcpy (p->errbuf, "illegal pcap handle"); + return (-1); + } + + if (!dev->get_stats || (stats = (*dev->get_stats)(dev)) == NULL) + { + strcpy (p->errbuf, "device statistics not available"); + return (-1); + } + + FLUSHK(); + + p->md.stat.ps_recv = stats->rx_packets; + p->md.stat.ps_drop += stats->rx_missed_errors; + p->md.stat.ps_ifdrop = stats->rx_dropped + /* queue full */ + stats->rx_errors; /* HW errors */ + if (ps) + *ps = p->md.stat; + + return (0); +} + +/* + * Return detailed network/device statistics. + * May be called after 'dev->close' is called. + */ +int pcap_stats_ex (pcap_t *p, struct pcap_stat_ex *se) +{ + struct device *dev = p ? get_device (p->fd) : NULL; + + if (!dev || !dev->get_stats) + { + strlcpy (p->errbuf, "detailed device statistics not available", + PCAP_ERRBUF_SIZE); + return (-1); + } + + if (!strnicmp(dev->name,"pkt",3)) + { + strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics", + PCAP_ERRBUF_SIZE); + return (-1); + } + memcpy (se, (*dev->get_stats)(dev), sizeof(*se)); + return (0); +} + +/* + * Simply store the filter-code for the pcap_read_dos() callback + * Some day the filter-code could be handed down to the active + * device (pkt_rx1.s or 32-bit device interrupt handler). + */ +static int pcap_setfilter_dos (pcap_t *p, struct bpf_program *fp) +{ + if (!p) + return (-1); + p->fcode = *fp; + return (0); +} + +/* + * Return # of packets received in pcap_read_dos() + */ +u_long pcap_mac_packets (void) +{ + return (mac_count); +} + +/* + * Return # of packets passed through filter in pcap_read_dos() + */ +u_long pcap_filter_packets (void) +{ + return (filter_count); +} + +/* + * Close pcap device. Not called for offline captures. + */ +static void pcap_close_dos (pcap_t *p) +{ + if (p && !exc_occured) + { + if (pcap_stats(p,NULL) < 0) + p->md.stat.ps_drop = 0; + if (!get_device(p->fd)) + return; + + handle_to_device [p->fd-1] = NULL; + p->fd = 0; + if (ref_count > 0) + ref_count--; + if (ref_count > 0) + return; + } + close_driver(); +} + +/* + * Return the name of the 1st network interface, + * or NULL if none can be found. + */ +char *pcap_lookupdev (char *ebuf) +{ + struct device *dev; + +#ifdef USE_32BIT_DRIVERS + init_32bit(); +#endif + + for (dev = (struct device*)dev_base; dev; dev = dev->next) + { + PCAP_ASSERT (dev->probe); + + if ((*dev->probe)(dev)) + { + FLUSHK(); + probed_dev = (struct device*) dev; /* remember last probed device */ + return (char*) dev->name; + } + } + + if (ebuf) + strcpy (ebuf, "No driver found"); + return (NULL); +} + +/* + * Gets localnet & netmask from Watt-32. + */ +int pcap_lookupnet (const char *device, bpf_u_int32 *localnet, + bpf_u_int32 *netmask, char *errbuf) +{ + if (!_watt_is_init) + { + strcpy (errbuf, "pcap_open_offline() or pcap_open_live() must be " + "called first"); + return (-1); + } + + *netmask = _w32_sin_mask; + *localnet = my_ip_addr & *netmask; + if (*localnet == 0) + { + if (IN_CLASSA(*netmask)) + *localnet = IN_CLASSA_NET; + else if (IN_CLASSB(*netmask)) + *localnet = IN_CLASSB_NET; + else if (IN_CLASSC(*netmask)) + *localnet = IN_CLASSC_NET; + else + { + sprintf (errbuf, "inet class for 0x%lx unknown", *netmask); + return (-1); + } + } + ARGSUSED (device); + return (0); +} + +/* + * Get a list of all interfaces that are present and that we probe okay. + * Returns -1 on error, 0 otherwise. + * The list, as returned through "alldevsp", may be null if no interfaces + * were up and could be opened. + */ +int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf) +{ + struct device *dev; + struct sockaddr_ll sa_ll_1, sa_ll_2; + struct sockaddr *addr, *netmask, *broadaddr, *dstaddr; + pcap_if_t *devlist = NULL; + int ret = 0; + size_t addr_size = sizeof(struct sockaddr_ll); + + for (dev = (struct device*)dev_base; dev; dev = dev->next) + { + PCAP_ASSERT (dev->probe); + + if (!(*dev->probe)(dev)) + continue; + + PCAP_ASSERT (dev->close); /* set by probe routine */ + FLUSHK(); + (*dev->close) (dev); + + memset (&sa_ll_1, 0, sizeof(sa_ll_1)); + memset (&sa_ll_2, 0, sizeof(sa_ll_2)); + sa_ll_1.sll_family = AF_PACKET; + sa_ll_2.sll_family = AF_PACKET; + + addr = (struct sockaddr*) &sa_ll_1; + netmask = (struct sockaddr*) &sa_ll_1; + dstaddr = (struct sockaddr*) &sa_ll_1; + broadaddr = (struct sockaddr*) &sa_ll_2; + memset (&sa_ll_2.sll_addr, 0xFF, sizeof(sa_ll_2.sll_addr)); + + if (pcap_add_if(&devlist, dev->name, dev->flags, + dev->long_name, errbuf) < 0) + { + ret = -1; + break; + } + if (add_addr_to_iflist(&devlist,dev->name, dev->flags, addr, addr_size, + netmask, addr_size, broadaddr, addr_size, + dstaddr, addr_size, errbuf) < 0) + { + ret = -1; + break; + } + } + + if (devlist && ret < 0) + { + pcap_freealldevs (devlist); + devlist = NULL; + } + else + if (!devlist) + strcpy (errbuf, "No drivers found"); + + *alldevsp = devlist; + return (ret); +} + +/* + * pcap_assert() is mainly used for debugging + */ +void pcap_assert (const char *what, const char *file, unsigned line) +{ + FLUSHK(); + fprintf (stderr, "%s (%u): Assertion \"%s\" failed\n", + file, line, what); + close_driver(); + _exit (-1); +} + +/* + * For pcap_offline_read(): wait and yield between printing packets + * to simulate the pace packets where actually recorded. + */ +void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait) +{ + if (p) + { + p->wait_proc = yield; + p->inter_packet_wait = wait; + } +} + +/* + * Initialise a named network device. + */ +static struct device * +open_driver (const char *dev_name, char *ebuf, int promisc) +{ + struct device *dev; + + for (dev = (struct device*)dev_base; dev; dev = dev->next) + { + PCAP_ASSERT (dev->name); + + if (strcmp (dev_name,dev->name)) + continue; + + if (!probed_dev) /* user didn't call pcap_lookupdev() first */ + { + PCAP_ASSERT (dev->probe); + + if (!(*dev->probe)(dev)) /* call the xx_probe() function */ + { + sprintf (ebuf, "failed to detect device `%s'", dev_name); + return (NULL); + } + probed_dev = dev; /* device is probed okay and may be used */ + } + else if (dev != probed_dev) + { + goto not_probed; + } + + FLUSHK(); + + /* Select what traffic to receive + */ + if (promisc) + dev->flags |= (IFF_ALLMULTI | IFF_PROMISC); + else dev->flags &= ~(IFF_ALLMULTI | IFF_PROMISC); + + PCAP_ASSERT (dev->open); + + if (!(*dev->open)(dev)) + { + sprintf (ebuf, "failed to activate device `%s'", dev_name); + if (pktInfo.error && !strncmp(dev->name,"pkt",3)) + { + strcat (ebuf, ": "); + strcat (ebuf, pktInfo.error); + } + return (NULL); + } + + /* Some devices need this to operate in promiscous mode + */ + if (promisc && dev->set_multicast_list) + (*dev->set_multicast_list) (dev); + + active_dev = dev; /* remember our active device */ + break; + } + + /* 'dev_name' not matched in 'dev_base' list. + */ + if (!dev) + { + sprintf (ebuf, "device `%s' not supported", dev_name); + return (NULL); + } + +not_probed: + if (!probed_dev) + { + sprintf (ebuf, "device `%s' not probed", dev_name); + return (NULL); + } + return (dev); +} + +/* + * Deinitialise MAC driver. + * Set receive mode back to default mode. + */ +static void close_driver (void) +{ + /* !!todo: loop over all 'handle_to_device[]' ? */ + struct device *dev = active_dev; + + if (dev && dev->close) + { + (*dev->close) (dev); + FLUSHK(); + } + + active_dev = NULL; + +#ifdef USE_32BIT_DRIVERS + if (rx_pool) + { + k_free (rx_pool); + rx_pool = NULL; + } + if (dev) + pcibios_exit(); +#endif +} + + +#ifdef __DJGPP__ +static void setup_signals (void (*handler)(int)) +{ + signal (SIGSEGV,handler); + signal (SIGILL, handler); + signal (SIGFPE, handler); +} + +static void exc_handler (int sig) +{ +#ifdef USE_32BIT_DRIVERS + if (active_dev->irq > 0) /* excludes IRQ 0 */ + { + disable_irq (active_dev->irq); + irq_eoi_cmd (active_dev->irq); + _printk_safe = 1; + } +#endif + + switch (sig) + { + case SIGSEGV: + fputs ("Catching SIGSEGV.\n", stderr); + break; + case SIGILL: + fputs ("Catching SIGILL.\n", stderr); + break; + case SIGFPE: + _fpreset(); + fputs ("Catching SIGFPE.\n", stderr); + break; + default: + fprintf (stderr, "Catching signal %d.\n", sig); + } + exc_occured = 1; + pcap_close_dos (NULL); +} +#endif /* __DJGPP__ */ + + +/* + * Open the pcap device for the first client calling pcap_open_live() + */ +static int first_init (const char *name, char *ebuf, int promisc) +{ + struct device *dev; + +#ifdef USE_32BIT_DRIVERS + rx_pool = k_calloc (RECEIVE_BUF_SIZE, RECEIVE_QUEUE_SIZE); + if (!rx_pool) + { + strcpy (ebuf, "Not enough memory (Rx pool)"); + return (0); + } +#endif + +#ifdef __DJGPP__ + setup_signals (exc_handler); +#endif + +#ifdef USE_32BIT_DRIVERS + init_32bit(); +#endif + + dev = open_driver (name, ebuf, promisc); + if (!dev) + { +#ifdef USE_32BIT_DRIVERS + k_free (rx_pool); + rx_pool = NULL; +#endif + +#ifdef __DJGPP__ + setup_signals (SIG_DFL); +#endif + return (0); + } + +#ifdef USE_32BIT_DRIVERS + /* + * If driver is NOT a 16-bit "pkt/ndis" driver (having a 'copy_rx_buf' + * set in it's probe handler), initialise near-memory ring-buffer for + * the 32-bit device. + */ + if (dev->copy_rx_buf == NULL) + { + dev->get_rx_buf = get_rxbuf; + dev->peek_rx_buf = peek_rxbuf; + dev->release_rx_buf = release_rxbuf; + pktq_init (&dev->queue, RECEIVE_BUF_SIZE, RECEIVE_QUEUE_SIZE, rx_pool); + } +#endif + return (1); +} + +#ifdef USE_32BIT_DRIVERS +static void init_32bit (void) +{ + static int init_pci = 0; + + if (!_printk_file) + _printk_init (64*1024, NULL); /* calls atexit(printk_exit) */ + + if (!init_pci) + (void)pci_init(); /* init BIOS32+PCI interface */ + init_pci = 1; +} +#endif + + +/* + * Hook functions for using Watt-32 together with pcap + */ +static char rxbuf [ETH_MAX+100]; /* rx-buffer with some margin */ +static WORD etype; +static pcap_t pcap_save; + +static void watt32_recv_hook (u_char *dummy, const struct pcap_pkthdr *pcap, + const u_char *buf) +{ + /* Fix me: assumes Ethernet II only */ + struct ether_header *ep = (struct ether_header*) buf; + + memcpy (rxbuf, buf, pcap->caplen); + etype = ep->ether_type; + ARGSUSED (dummy); +} + +#if (WATTCP_VER >= 0x0224) +/* + * This function is used by Watt-32 to poll for a packet. + * i.e. it's set to bypass _eth_arrived() + */ +static void *pcap_recv_hook (WORD *type) +{ + int len = pcap_read_dos (&pcap_save, 1, watt32_recv_hook, NULL); + + if (len < 0) + return (NULL); + + *type = etype; + return (void*) &rxbuf; +} + +/* + * This function is called by Watt-32 (via _eth_xmit_hook). + * If dbug_init() was called, we should trace packets sent. + */ +static int pcap_xmit_hook (const void *buf, unsigned len) +{ + int rc = 0; + + if (pcap_pkt_debug > 0) + dbug_write ("pcap_xmit_hook: "); + + if (active_dev && active_dev->xmit) + if ((*active_dev->xmit) (active_dev, buf, len) > 0) + rc = len; + + if (pcap_pkt_debug > 0) + dbug_write (rc ? "ok\n" : "fail\n"); + return (rc); +} +#endif + +static int pcap_sendpacket_dos (pcap_t *p, const void *buf, size_t len) +{ + struct device *dev = p ? get_device(p->fd) : NULL; + + if (!dev || !dev->xmit) + return (-1); + return (*dev->xmit) (dev, buf, len); +} + +/* + * This function is called by Watt-32 in tcp_post_init(). + * We should prevent Watt-32 from using BOOTP/DHCP/RARP etc. + */ +static void (*prev_post_hook) (void); + +static void pcap_init_hook (void) +{ + _w32__bootp_on = _w32__dhcp_on = _w32__rarp_on = 0; + _w32__do_mask_req = 0; + _w32_dynamic_host = 0; + if (prev_post_hook) + (*prev_post_hook)(); +} + +/* + * Supress PRINT message from Watt-32's sock_init() + */ +static void null_print (void) {} + +/* + * To use features of Watt-32 (netdb functions and socket etc.) + * we must call sock_init(). But we set various hooks to prevent + * using normal PKTDRVR functions in pcpkt.c. This should hopefully + * make Watt-32 and pcap co-operate. + */ +static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf) +{ + char *env; + int rc, MTU, has_ip_addr; + int using_pktdrv = 1; + + /* If user called sock_init() first, we need to reinit in + * order to open debug/trace-file properly + */ + if (_watt_is_init) + sock_exit(); + + env = getenv ("PCAP_DEBUG"); + if (env && atoi(env) > 0 && + pcap_pkt_debug < 0) /* if not already set */ + { + dbug_init(); + pcap_pkt_debug = atoi (env); + } + + _watt_do_exit = 0; /* prevent sock_init() calling exit() */ + prev_post_hook = _w32_usr_post_init; + _w32_usr_post_init = pcap_init_hook; + _w32_print_hook = null_print; + + if (dev_name && strncmp(dev_name,"pkt",3)) + using_pktdrv = FALSE; + + rc = sock_init(); + has_ip_addr = (rc != 8); /* IP-address assignment failed */ + + /* if pcap is using a 32-bit driver w/o a pktdrvr loaded, we + * just pretend Watt-32 is initialised okay. + * + * !! fix-me: The Watt-32 config isn't done if no pktdrvr + * was found. In that case my_ip_addr + sin_mask + * have default values. Should be taken from another + * ini-file/environment in any case (ref. tcpdump.ini) + */ + _watt_is_init = 1; + + if (!using_pktdrv || !has_ip_addr) /* for now .... */ + { + static const char myip[] = "192.168.0.1"; + static const char mask[] = "255.255.255.0"; + + printf ("Just guessing, using IP %s and netmask %s\n", myip, mask); + my_ip_addr = aton (myip); + _w32_sin_mask = aton (mask); + } + else if (rc && using_pktdrv) + { + sprintf (err_buf, "sock_init() failed, code %d", rc); + return (0); + } + + /* Set recv-hook for peeking in _eth_arrived(). + */ +#if (WATTCP_VER >= 0x0224) + _eth_recv_hook = pcap_recv_hook; + _eth_xmit_hook = pcap_xmit_hook; +#endif + + /* Free the pkt-drvr handle allocated in pkt_init(). + * The above hooks should thus use the handle reopened in open_driver() + */ + if (using_pktdrv) + { + _eth_release(); +/* _eth_is_init = 1; */ /* hack to get Rx/Tx-hooks in Watt-32 working */ + } + + memcpy (&pcap_save, pcap, sizeof(pcap_save)); + MTU = pkt_get_mtu(); + pcap_save.fcode.bf_insns = NULL; + pcap_save.linktype = _eth_get_hwtype (NULL, NULL); + pcap_save.snapshot = MTU > 0 ? MTU : ETH_MAX; /* assume 1514 */ + +#if 1 + /* prevent use of resolve() and resolve_ip() + */ + last_nameserver = 0; +#endif + return (1); +} + +int EISA_bus = 0; /* Where is natural place for this? */ + +/* + * Application config hooks to set various driver parameters. + */ + +static struct config_table debug_tab[] = { + { "PKT.DEBUG", ARG_ATOI, &pcap_pkt_debug }, + { "PKT.VECTOR", ARG_ATOX_W, NULL }, + { "NDIS.DEBUG", ARG_ATOI, NULL }, +#ifdef USE_32BIT_DRIVERS + { "3C503.DEBUG", ARG_ATOI, &ei_debug }, + { "3C503.IO_BASE", ARG_ATOX_W, &el2_dev.base_addr }, + { "3C503.MEMORY", ARG_ATOX_W, &el2_dev.mem_start }, + { "3C503.IRQ", ARG_ATOI, &el2_dev.irq }, + { "3C505.DEBUG", ARG_ATOI, NULL }, + { "3C505.BASE", ARG_ATOX_W, NULL }, + { "3C507.DEBUG", ARG_ATOI, NULL }, + { "3C509.DEBUG", ARG_ATOI, &el3_debug }, + { "3C509.ILOOP", ARG_ATOI, &el3_max_loop }, + { "3C529.DEBUG", ARG_ATOI, NULL }, + { "3C575.DEBUG", ARG_ATOI, &debug_3c575 }, + { "3C59X.DEBUG", ARG_ATOI, &vortex_debug }, + { "3C59X.IFACE0", ARG_ATOI, &vortex_options[0] }, + { "3C59X.IFACE1", ARG_ATOI, &vortex_options[1] }, + { "3C59X.IFACE2", ARG_ATOI, &vortex_options[2] }, + { "3C59X.IFACE3", ARG_ATOI, &vortex_options[3] }, + { "3C90X.DEBUG", ARG_ATOX_W, &tc90xbc_debug }, + { "ACCT.DEBUG", ARG_ATOI, ðpk_debug }, + { "CS89.DEBUG", ARG_ATOI, &cs89_debug }, + { "RTL8139.DEBUG", ARG_ATOI, &rtl8139_debug }, + /* { "RTL8139.FDUPLEX", ARG_ATOI, &rtl8139_options }, */ + { "SMC.DEBUG", ARG_ATOI, &ei_debug }, + /* { "E100.DEBUG", ARG_ATOI, &e100_debug }, */ + { "PCI.DEBUG", ARG_ATOI, &pci_debug }, + { "BIOS32.DEBUG", ARG_ATOI, &bios32_debug }, + { "IRQ.DEBUG", ARG_ATOI, &irq_debug }, + { "TIMER.IRQ", ARG_ATOI, &timer_irq }, +#endif + { NULL } + }; + +/* + * pcap_config_hook() is an extension to application's config + * handling. Uses Watt-32's config-table function. + */ +int pcap_config_hook (const char *name, const char *value) +{ + return parse_config_table (debug_tab, NULL, name, value); +} + +/* + * Linked list of supported devices + */ +struct device *active_dev = NULL; /* the device we have opened */ +struct device *probed_dev = NULL; /* the device we have probed */ +const struct device *dev_base = &pkt_dev; /* list of network devices */ + +/* + * PKTDRVR device functions + */ +int pcap_pkt_debug = -1; + +static void pkt_close (struct device *dev) +{ + BOOL okay = PktExitDriver(); + + if (pcap_pkt_debug > 1) + fprintf (stderr, "pkt_close(): %d\n", okay); + + if (dev->priv) + free (dev->priv); + dev->priv = NULL; +} + +static int pkt_open (struct device *dev) +{ + PKT_RX_MODE mode; + + if (dev->flags & IFF_PROMISC) + mode = PDRX_ALL_PACKETS; + else mode = PDRX_BROADCAST; + + if (!PktInitDriver(mode)) + return (0); + + PktResetStatistics (pktInfo.handle); + PktQueueBusy (FALSE); + return (1); +} + +static int pkt_xmit (struct device *dev, const void *buf, int len) +{ + struct net_device_stats *stats = (struct net_device_stats*) dev->priv; + + if (pcap_pkt_debug > 0) + dbug_write ("pcap_xmit\n"); + + if (!PktTransmit(buf,len)) + { + stats->tx_errors++; + return (0); + } + return (len); +} + +static void *pkt_stats (struct device *dev) +{ + struct net_device_stats *stats = (struct net_device_stats*) dev->priv; + + if (!stats || !PktSessStatistics(pktInfo.handle)) + return (NULL); + + stats->rx_packets = pktStat.inPackets; + stats->rx_errors = pktStat.lost; + stats->rx_missed_errors = PktRxDropped(); + return (stats); +} + +static int pkt_probe (struct device *dev) +{ + if (!PktSearchDriver()) + return (0); + + dev->open = pkt_open; + dev->xmit = pkt_xmit; + dev->close = pkt_close; + dev->get_stats = pkt_stats; + dev->copy_rx_buf = PktReceive; /* farmem peek and copy routine */ + dev->get_rx_buf = NULL; + dev->peek_rx_buf = NULL; + dev->release_rx_buf = NULL; + dev->priv = calloc (sizeof(struct net_device_stats), 1); + if (!dev->priv) + return (0); + return (1); +} + +/* + * NDIS device functions + */ +static void ndis_close (struct device *dev) +{ +#ifdef USE_NDIS2 + NdisShutdown(); +#endif + ARGSUSED (dev); +} + +static int ndis_open (struct device *dev) +{ + int promis = (dev->flags & IFF_PROMISC); + +#ifdef USE_NDIS2 + if (!NdisInit(promis)) + return (0); + return (1); +#else + ARGSUSED (promis); + return (0); +#endif +} + +static void *ndis_stats (struct device *dev) +{ + static struct net_device_stats stats; + + /* to-do */ + ARGSUSED (dev); + return (&stats); +} + +static int ndis_probe (struct device *dev) +{ +#ifdef USE_NDIS2 + if (!NdisOpen()) + return (0); +#endif + + dev->open = ndis_open; + dev->xmit = NULL; + dev->close = ndis_close; + dev->get_stats = ndis_stats; + dev->copy_rx_buf = NULL; /* to-do */ + dev->get_rx_buf = NULL; /* upcall is from rmode driver */ + dev->peek_rx_buf = NULL; + dev->release_rx_buf = NULL; + return (0); +} + +/* + * Search & probe for supported 32-bit (pmode) pcap devices + */ +#if defined(USE_32BIT_DRIVERS) + +struct device el2_dev LOCKED_VAR = { + "3c503", + "EtherLink II", + 0, + 0,0,0,0,0,0, + NULL, + el2_probe + }; + +struct device el3_dev LOCKED_VAR = { + "3c509", + "EtherLink III", + 0, + 0,0,0,0,0,0, + &el2_dev, + el3_probe + }; + +struct device tc515_dev LOCKED_VAR = { + "3c515", + "EtherLink PCI", + 0, + 0,0,0,0,0,0, + &el3_dev, + tc515_probe + }; + +struct device tc59_dev LOCKED_VAR = { + "3c59x", + "EtherLink PCI", + 0, + 0,0,0,0,0,0, + &tc515_dev, + tc59x_probe + }; + +struct device tc90xbc_dev LOCKED_VAR = { + "3c90x", + "EtherLink 90X", + 0, + 0,0,0,0,0,0, + &tc59_dev, + tc90xbc_probe + }; + +struct device wd_dev LOCKED_VAR = { + "wd", + "Westen Digital", + 0, + 0,0,0,0,0,0, + &tc90xbc_dev, + wd_probe + }; + +struct device ne_dev LOCKED_VAR = { + "ne", + "NEx000", + 0, + 0,0,0,0,0,0, + &wd_dev, + ne_probe + }; + +struct device acct_dev LOCKED_VAR = { + "acct", + "Accton EtherPocket", + 0, + 0,0,0,0,0,0, + &ne_dev, + ethpk_probe + }; + +struct device cs89_dev LOCKED_VAR = { + "cs89", + "Crystal Semiconductor", + 0, + 0,0,0,0,0,0, + &acct_dev, + cs89x0_probe + }; + +struct device rtl8139_dev LOCKED_VAR = { + "rtl8139", + "RealTek PCI", + 0, + 0,0,0,0,0,0, + &cs89_dev, + rtl8139_probe /* dev->probe routine */ + }; + +/* + * Dequeue routine is called by polling. + * NOTE: the queue-element is not copied, only a pointer is + * returned at '*buf' + */ +int peek_rxbuf (BYTE **buf) +{ + struct rx_elem *tail, *head; + + PCAP_ASSERT (pktq_check (&active_dev->queue)); + + DISABLE(); + tail = pktq_out_elem (&active_dev->queue); + head = pktq_in_elem (&active_dev->queue); + ENABLE(); + + if (head != tail) + { + PCAP_ASSERT (tail->size < active_dev->queue.elem_size-4-2); + + *buf = &tail->data[0]; + return (tail->size); + } + *buf = NULL; + return (0); +} + +/* + * Release buffer we peeked at above. + */ +int release_rxbuf (BYTE *buf) +{ +#ifndef NDEBUG + struct rx_elem *tail = pktq_out_elem (&active_dev->queue); + + PCAP_ASSERT (&tail->data[0] == buf); +#else + ARGSUSED (buf); +#endif + pktq_inc_out (&active_dev->queue); + return (1); +} + +/* + * get_rxbuf() routine (in locked code) is called from IRQ handler + * to request a buffer. Interrupts are disabled and we have a 32kB stack. + */ +BYTE *get_rxbuf (int len) +{ + int idx; + + if (len < ETH_MIN || len > ETH_MAX) + return (NULL); + + idx = pktq_in_index (&active_dev->queue); + +#ifdef DEBUG + { + static int fan_idx LOCKED_VAR = 0; + writew ("-\\|/"[fan_idx++] | (15 << 8), /* white on black colour */ + 0xB8000 + 2*79); /* upper-right corner, 80-col colour screen */ + fan_idx &= 3; + } +/* writew (idx + '0' + 0x0F00, 0xB8000 + 2*78); */ +#endif + + if (idx != active_dev->queue.out_index) + { + struct rx_elem *head = pktq_in_elem (&active_dev->queue); + + head->size = len; + active_dev->queue.in_index = idx; + return (&head->data[0]); + } + + /* !!to-do: drop 25% of the oldest element + */ + pktq_clear (&active_dev->queue); + return (NULL); +} + +/* + * Simple ring-buffer queue handler for reception of packets + * from network driver. + */ +#define PKTQ_MARKER 0xDEADBEEF + +static int pktq_check (struct rx_ringbuf *q) +{ +#ifndef NDEBUG + int i; + char *buf; +#endif + + if (!q || !q->num_elem || !q->buf_start) + return (0); + +#ifndef NDEBUG + buf = q->buf_start; + + for (i = 0; i < q->num_elem; i++) + { + buf += q->elem_size; + if (*(DWORD*)(buf - sizeof(DWORD)) != PKTQ_MARKER) + return (0); + } +#endif + return (1); +} + +static int pktq_init (struct rx_ringbuf *q, int size, int num, char *pool) +{ + int i; + + q->elem_size = size; + q->num_elem = num; + q->buf_start = pool; + q->in_index = 0; + q->out_index = 0; + + PCAP_ASSERT (size >= sizeof(struct rx_elem) + sizeof(DWORD)); + PCAP_ASSERT (num); + PCAP_ASSERT (pool); + + for (i = 0; i < num; i++) + { +#if 0 + struct rx_elem *elem = (struct rx_elem*) pool; + + /* assert dword aligned elements + */ + PCAP_ASSERT (((unsigned)(&elem->data[0]) & 3) == 0); +#endif + pool += size; + *(DWORD*) (pool - sizeof(DWORD)) = PKTQ_MARKER; + } + return (1); +} + +/* + * Increment the queue 'out_index' (tail). + * Check for wraps. + */ +static int pktq_inc_out (struct rx_ringbuf *q) +{ + q->out_index++; + if (q->out_index >= q->num_elem) + q->out_index = 0; + return (q->out_index); +} + +/* + * Return the queue's next 'in_index' (head). + * Check for wraps. + */ +static int pktq_in_index (struct rx_ringbuf *q) +{ + volatile int index = q->in_index + 1; + + if (index >= q->num_elem) + index = 0; + return (index); +} + +/* + * Return the queue's head-buffer. + */ +static struct rx_elem *pktq_in_elem (struct rx_ringbuf *q) +{ + return (struct rx_elem*) (q->buf_start + (q->elem_size * q->in_index)); +} + +/* + * Return the queue's tail-buffer. + */ +static struct rx_elem *pktq_out_elem (struct rx_ringbuf *q) +{ + return (struct rx_elem*) (q->buf_start + (q->elem_size * q->out_index)); +} + +/* + * Clear the queue ring-buffer by setting head=tail. + */ +static void pktq_clear (struct rx_ringbuf *q) +{ + q->in_index = q->out_index; +} + +/* + * Symbols that must be linkable for "gcc -O0" + */ +#undef __IOPORT_H +#undef __DMA_H + +#define extern +#define __inline__ + +#include "msdos/pm_drvr/ioport.h" +#include "msdos/pm_drvr/dma.h" + +#endif /* USE_32BIT_DRIVERS */ + diff --git a/winpcap/wpcap/libpcap/pcap-dos.h b/winpcap/wpcap/libpcap/pcap-dos.h new file mode 100644 index 0000000..c9737ba --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-dos.h @@ -0,0 +1,227 @@ +/* + * Internal details for libpcap on DOS. + * 32-bit targets: djgpp, Pharlap or DOS4GW. + * + * @(#) $Header: /tcpdump/master/libpcap/pcap-dos.h,v 1.1 2004/12/18 08:52:10 guy Exp $ (LBL) + */ + +#ifndef __PCAP_DOS_H +#define __PCAP_DOS_H + +#ifdef __DJGPP__ +#include /* simple non-conio kbhit */ +#else +#include +#endif + +typedef int BOOL; +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef BYTE ETHER[6]; + +#define ETH_ALEN sizeof(ETHER) /* Ether address length */ +#define ETH_HLEN (2*ETH_ALEN+2) /* Ether header length */ +#define ETH_MTU 1500 +#define ETH_MIN 60 +#define ETH_MAX (ETH_MTU+ETH_HLEN) + +#ifndef TRUE + #define TRUE 1 + #define FALSE 0 +#endif + +#define PHARLAP 1 +#define DJGPP 2 +#define DOS4GW 4 + +#ifdef __DJGPP__ + #undef DOSX + #define DOSX DJGPP +#endif + +#ifdef __WATCOMC__ + #undef DOSX + #define DOSX DOS4GW +#endif + +#ifdef __HIGHC__ + #include + #undef DOSX + #define DOSX PHARLAP + #define inline +#else + typedef unsigned int UINT; +#endif + + +#if defined(__GNUC__) || defined(__HIGHC__) + typedef unsigned long long uint64; + typedef unsigned long long QWORD; +#endif + +#if defined(__WATCOMC__) + typedef unsigned __int64 uint64; + typedef unsigned __int64 QWORD; +#endif + +#define ARGSUSED(x) (void) x + +#if defined (__SMALL__) || defined(__LARGE__) + #define DOSX 0 + +#elif !defined(DOSX) + #error DOSX not defined; 1 = PharLap, 2 = djgpp, 4 = DOS4GW +#endif + +#ifdef __HIGHC__ +#define min(a,b) _min(a,b) +#define max(a,b) _max(a,b) +#endif + +#ifndef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef max +#define max(a,b) ((a) < (b) ? (b) : (a)) +#endif + +#if !defined(_U_) && defined(__GNUC__) +#define _U_ __attribute__((unused)) +#endif + +#ifndef _U_ +#define _U_ +#endif + +#if defined(USE_32BIT_DRIVERS) + #include "msdos/pm_drvr/lock.h" + + #ifndef RECEIVE_QUEUE_SIZE + #define RECEIVE_QUEUE_SIZE 60 + #endif + + #ifndef RECEIVE_BUF_SIZE + #define RECEIVE_BUF_SIZE (ETH_MAX+20) + #endif + + extern struct device el2_dev LOCKED_VAR; /* 3Com EtherLink II */ + extern struct device el3_dev LOCKED_VAR; /* EtherLink III */ + extern struct device tc59_dev LOCKED_VAR; /* 3Com Vortex Card (?) */ + extern struct device tc515_dev LOCKED_VAR; + extern struct device tc90x_dev LOCKED_VAR; + extern struct device tc90bcx_dev LOCKED_VAR; + extern struct device wd_dev LOCKED_VAR; + extern struct device ne_dev LOCKED_VAR; + extern struct device acct_dev LOCKED_VAR; + extern struct device cs89_dev LOCKED_VAR; + extern struct device rtl8139_dev LOCKED_VAR; + + struct rx_ringbuf { + volatile int in_index; /* queue index head */ + int out_index; /* queue index tail */ + int elem_size; /* size of each element */ + int num_elem; /* number of elements */ + char *buf_start; /* start of buffer pool */ + }; + + struct rx_elem { + DWORD size; /* size copied to this element */ + BYTE data[ETH_MAX+10]; /* add some margin. data[0] should be */ + }; /* dword aligned */ + + extern BYTE *get_rxbuf (int len) LOCKED_FUNC; + extern int peek_rxbuf (BYTE **buf); + extern int release_rxbuf (BYTE *buf); + +#else + #define LOCKED_VAR + #define LOCKED_FUNC + + struct device { + const char *name; + const char *long_name; + DWORD base_addr; /* device I/O address */ + int irq; /* device IRQ number */ + int dma; /* DMA channel */ + DWORD mem_start; /* shared mem start */ + DWORD mem_end; /* shared mem end */ + DWORD rmem_start; /* shmem "recv" start */ + DWORD rmem_end; /* shared "recv" end */ + + struct device *next; /* next device in list */ + + /* interface service routines */ + int (*probe)(struct device *dev); + int (*open) (struct device *dev); + void (*close)(struct device *dev); + int (*xmit) (struct device *dev, const void *buf, int len); + void *(*get_stats)(struct device *dev); + void (*set_multicast_list)(struct device *dev); + + /* driver-to-pcap receive buffer routines */ + int (*copy_rx_buf) (BYTE *buf, int max); /* rx-copy (pktdrvr only) */ + BYTE *(*get_rx_buf) (int len); /* rx-buf fetch/enqueue */ + int (*peek_rx_buf) (BYTE **buf); /* rx-non-copy at queue */ + int (*release_rx_buf) (BYTE *buf); /* release after peek */ + + WORD flags; /* Low-level status flags. */ + void *priv; /* private data */ + }; + + /* + * Network device statistics + */ + typedef struct net_device_stats { + DWORD rx_packets; /* total packets received */ + DWORD tx_packets; /* total packets transmitted */ + DWORD rx_bytes; /* total bytes received */ + DWORD tx_bytes; /* total bytes transmitted */ + DWORD rx_errors; /* bad packets received */ + DWORD tx_errors; /* packet transmit problems */ + DWORD rx_dropped; /* no space in Rx buffers */ + DWORD tx_dropped; /* no space available for Tx */ + DWORD multicast; /* multicast packets received */ + + /* detailed rx_errors: */ + DWORD rx_length_errors; + DWORD rx_over_errors; /* recv'r overrun error */ + DWORD rx_osize_errors; /* recv'r over-size error */ + DWORD rx_crc_errors; /* recv'd pkt with crc error */ + DWORD rx_frame_errors; /* recv'd frame alignment error */ + DWORD rx_fifo_errors; /* recv'r fifo overrun */ + DWORD rx_missed_errors; /* recv'r missed packet */ + + /* detailed tx_errors */ + DWORD tx_aborted_errors; + DWORD tx_carrier_errors; + DWORD tx_fifo_errors; + DWORD tx_heartbeat_errors; + DWORD tx_window_errors; + DWORD tx_collisions; + DWORD tx_jabbers; + } NET_STATS; +#endif + +extern struct device *active_dev LOCKED_VAR; +extern const struct device *dev_base LOCKED_VAR; +extern struct device *probed_dev; + +extern int pcap_pkt_debug; + +extern void _w32_os_yield (void); /* Watt-32's misc.c */ + +#ifdef NDEBUG + #define PCAP_ASSERT(x) ((void)0) + +#else + void pcap_assert (const char *what, const char *file, unsigned line); + + #define PCAP_ASSERT(x) do { \ + if (!(x)) \ + pcap_assert (#x, __FILE__, __LINE__); \ + } while (0) +#endif + +#endif /* __PCAP_DOS_H */ diff --git a/winpcap/wpcap/libpcap/pcap-enet.c b/winpcap/wpcap/libpcap/pcap-enet.c new file mode 100644 index 0000000..a484207 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-enet.c @@ -0,0 +1,235 @@ +/* + * Stanford Enetfilter subroutines for tcpdump + * + * Based on the MERIT NNstat etherifrt.c and the Ultrix pcap-pf.c + * subroutines. + * + * Rayan Zachariassen, CA*Net + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/pcap-enet.c,v 1.8 2003/11/15 23:24:02 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include "interface.h" + +struct packet_header { +#ifdef IBMRTPC + struct LengthWords length; + struct tap_header tap; +#endif /* IBMRTPC */ + u_char packet[8] +}; + +extern int errno; + +#define BUFSPACE (4*1024) + +/* Forwards */ +static void efReadError(int, char *); + +void +readloop(int cnt, int if_fd, struct bpf_program *fp, printfunc printit) +{ +#ifdef IBMRTPC + register struct packet_header *ph; + register u_char *bp; + register int inc; +#else /* !IBMRTPC */ + static struct timeval tv = { 0 }; +#endif /* IBMRTPC */ + register int cc, caplen; + register struct bpf_insn *fcode = fp->bf_insns; + union { + struct packet_header hdr; + u_char p[BUFSPACE]; + u_short s; + } buf; + + while (1) { + if ((cc = read(if_fd, (char *)buf.p, sizeof(buf))) < 0) + efReadError(if_fd, "reader"); + +#ifdef IBMRTPC + /* + * Loop through each packet. + */ + bp = buf.p; + while (cc > 0) { + ph = (struct packet_header *)bp; + caplen = ph->tap.th_wirelen > snaplen ? snaplen : ph->tap +.th_wirelen ; + if (bpf_filter(fcode, (char *)ph->packet, + ph->tap.th_wirelen, caplen)) { + if (cnt >= 0 && --cnt < 0) + goto out; + (*printit)((char *)ph->packet, + (struct timeval *)ph->tap.th_timestamp, + ph->tap.th_wirelen, caplen); + } + inc = ph->length.PacketOffset; + cc -= inc; + bp += inc; + } +#else /* !IBMRTPC */ + caplen = cc > snaplen ? snaplen : cc ; + if (bpf_filter(fcode, buf.hdr.packet, cc, caplen)) { + if (cnt >= 0 && --cnt < 0) + goto out; + (*printit)(buf.hdr.packet, &tv, cc, caplen); + } +#endif /* IBMRTPC */ + } + out: + wrapup(if_fd); +} + +/* Call ONLY if read() has returned an error on packet filter */ +static void +efReadError(int fid, char *msg) +{ + if (errno == EINVAL) { /* read MAXINT bytes already! */ + if (lseek(fid, 0, 0) < 0) { + perror("tcpdump: efReadError/lseek"); + exit(-1); + } + else + return; + } + else { + (void) fprintf(stderr, "tcpdump: "); + perror(msg); + exit(-1); + } +} + +void +wrapup(int fd) +{ +#ifdef IBMRTPC + struct enstats es; + + if (ioctl(fd, EIOSTATS, &es) == -1) { + perror("tcpdump: enet ioctl EIOSTATS error"); + exit(-1); + } + + fprintf(stderr, "%d packets queued", es.enStat_Rcnt); + if (es.enStat_Rdrops > 0) + fprintf(stderr, ", %d dropped", es.enStat_Rdrops); + if (es.enStat_Reads > 0) + fprintf(stderr, ", %d tcpdump %s", es.enStat_Reads, + es.enStat_Reads > 1 ? "reads" : "read"); + if (es.enStat_MaxRead > 1) + fprintf(stderr, ", %d packets in largest read", + es.enStat_MaxRead); + putc('\n', stderr); +#endif /* IBMRTPC */ + close(fd); +} + +int +initdevice(char *device, int pflag, int *linktype) +{ + struct eniocb ctl; + struct enfilter filter; + u_int maxwaiting; + int if_fd; + +#ifdef IBMRTPC + GETENETDEVICE(0, O_RDONLY, &if_fd); +#else /* !IBMRTPC */ + if_fd = open("/dev/enet", O_RDONLY, 0); +#endif /* IBMRTPC */ + + if (if_fd == -1) { + perror("tcpdump: enet open error"); + error( +"your system may not be properly configured; see \"man enet(4)\""); + exit(-1); + } + + /* Get operating parameters. */ + + if (ioctl(if_fd, EIOCGETP, (char *)&ctl) == -1) { + perror("tcpdump: enet ioctl EIOCGETP error"); + exit(-1); + } + + /* Set operating parameters. */ + +#ifdef IBMRTPC + ctl.en_rtout = 1 * ctl.en_hz; + ctl.en_tr_etherhead = 1; + ctl.en_tap_network = 1; + ctl.en_multi_packet = 1; + ctl.en_maxlen = BUFSPACE; +#else /* !IBMRTPC */ + ctl.en_rtout = 64; /* randomly picked value for HZ */ +#endif /* IBMRTPC */ + if (ioctl(if_fd, EIOCSETP, &ctl) == -1) { + perror("tcpdump: enet ioctl EIOCSETP error"); + exit(-1); + } + + /* Flush the receive queue, since we've changed + the operating parameters and we otherwise might + receive data without headers. */ + + if (ioctl(if_fd, EIOCFLUSH) == -1) { + perror("tcpdump: enet ioctl EIOCFLUSH error"); + exit(-1); + } + + /* Set the receive queue depth to its maximum. */ + + maxwaiting = ctl.en_maxwaiting; + if (ioctl(if_fd, EIOCSETW, &maxwaiting) == -1) { + perror("tcpdump: enet ioctl EIOCSETW error"); + exit(-1); + } + +#ifdef IBMRTPC + /* Clear statistics. */ + + if (ioctl(if_fd, EIOCLRSTAT, 0) == -1) { + perror("tcpdump: enet ioctl EIOCLRSTAT error"); + exit(-1); + } +#endif /* IBMRTPC */ + + /* Set the filter (accept all packets). */ + + filter.enf_Priority = 3; + filter.enf_FilterLen = 0; + if (ioctl(if_fd, EIOCSETF, &filter) == -1) { + perror("tcpdump: enet ioctl EIOCSETF error"); + exit(-1); + } + /* + * "enetfilter" supports only ethernets. + */ + *linktype = DLT_EN10MB; + + return(if_fd); +} diff --git a/winpcap/wpcap/libpcap/pcap-int.h b/winpcap/wpcap/libpcap/pcap-int.h new file mode 100644 index 0000000..7aefa19 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-int.h @@ -0,0 +1,373 @@ +/* + * Copyright (c) 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.68.2.9 2006/02/22 17:09:54 gianluca Exp $ (LBL) + */ + +#ifndef pcap_int_h +#define pcap_int_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#ifdef WIN32 +#include +#endif /* WIN32 */ + +#ifdef MSDOS +#include +#include +#endif + +/* + * Savefile + */ +typedef enum { + NOT_SWAPPED, + SWAPPED, + MAYBE_SWAPPED +} swapped_type_t; + +struct pcap_sf { + FILE *rfile; + int swapped; + int hdrsize; + swapped_type_t lengths_swapped; + int version_major; + int version_minor; + u_char *base; +}; + +struct pcap_md { + struct pcap_stat stat; + /*XXX*/ + int use_bpf; /* using kernel filter */ + u_long TotPkts; /* can't oflow for 79 hrs on ether */ + u_long TotAccepted; /* count accepted by filter */ + u_long TotDrops; /* count of dropped packets */ + long TotMissed; /* missed by i/f during this run */ + long OrigMissed; /* missed by i/f before this run */ + char *device; /* device name */ +#ifdef linux + int sock_packet; /* using Linux 2.0 compatible interface */ + int timeout; /* timeout specified to pcap_open_live */ + int clear_promisc; /* must clear promiscuous mode when we close */ + int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */ + int ifindex; /* interface index of device we're bound to */ + int lo_ifindex; /* interface index of the loopback device */ + struct pcap *next; /* list of open promiscuous sock_packet pcaps */ + u_int packets_read; /* count of packets read with recvfrom() */ +#endif + +#ifdef HAVE_DAG_API +#ifdef HAVE_DAG_STREAMS_API + u_char *dag_mem_bottom; /* DAG card current memory bottom pointer */ + u_char *dag_mem_top; /* DAG card current memory top pointer */ +#else + void *dag_mem_base; /* DAG card memory base address */ + u_int dag_mem_bottom; /* DAG card current memory bottom offset */ + u_int dag_mem_top; /* DAG card current memory top offset */ +#endif /* HAVE_DAG_STREAMS_API */ + int dag_fcs_bits; /* Number of checksum bits from link layer */ + int dag_offset_flags; /* Flags to pass to dag_offset(). */ + int dag_stream; /* DAG stream number */ + int dag_timeout; /* timeout specified to pcap_open_live. + * Same as in linux above, introduce + * generally? */ +#endif /* HAVE_DAG_API */ + +#ifdef HAVE_REMOTE +/*! + There is really a mess with previous variables, and it seems to me that they are not used + (they are used in pcap_pf.c only). I think we have to start using them. + The meaning is the following: + + - TotPkts: the amount of packets received by the bpf filter, *before* applying the filter + - TotAccepted: the amount of packets that satisfies the filter + - TotDrops: the amount of packet that were dropped into the kernel buffer because of lack of space + - TotMissed: the amount of packets that were dropped by the physical interface; it is basically + the value of the hardware counter into the card. This number is never put to zero, so this number + takes into account the *total* number of interface drops starting from the interface power-on. + - OrigMissed: the amount of packets that were dropped by the interface *when the capture begins*. + This value is used to detect the number of packets dropped by the interface *during the present + capture*, so that (ps_ifdrops= TotMissed - OrigMissed). +*/ + unsigned int TotNetDrops; //!< keeps the number of packets that have been dropped by the network +/*! + \brief It keeps the number of packets that have been received by the application. + + Packets dropped by the kernel buffer are not counted in this variable. The variable is always + equal to (TotAccepted - TotDrops), exept for the case of remote capture, in which we have also + packets in fligh, i.e. that have been transmitted by the remote host, but that have not been + received (yet) from the client. In this case, (TotAccepted - TotDrops - TotNetDrops) gives a + wrong result, since this number does not corresponds always to the number of packet received by + the application. For this reason, in the remote capture we need another variable that takes + into account of the number of packets actually received by the application. +*/ + unsigned int TotCapt; +#endif /* HAVE_REMOTE */ +}; + +/* + * Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H + * Tru64 UNIX, and NetBSD pad to make everything line up on a nice boundary. + */ +#if defined(ultrix) || defined(__osf__) || (defined(__NetBSD__) && __NetBSD_Version__ > 106000000) +#define PCAP_FDDIPAD 3 +#endif + +struct pcap { +#ifdef WIN32 + ADAPTER *adapter; + LPPACKET Packet; + int timeout; + int nonblock; +#else + int fd; + int selectable_fd; + int send_fd; +#endif /* WIN32 */ + int snapshot; + int linktype; + int tzoff; /* timezone offset */ + int offset; /* offset for proper alignment */ + + int break_loop; /* flag set to force break from packet-reading loop */ + +#ifdef PCAP_FDDIPAD + int fddipad; +#endif + +#ifdef MSDOS + int inter_packet_wait; /* offline: wait between packets */ + void (*wait_proc)(void); /* call proc while waiting */ +#endif + + struct pcap_sf sf; + struct pcap_md md; + + /* + * Read buffer. + */ + int bufsize; + u_char *buffer; + u_char *bp; + int cc; + + /* + * Place holder for pcap_next(). + */ + u_char *pkt; + + /* We're accepting only packets in this direction/these directions. */ + pcap_direction_t direction; + + /* + * Methods. + */ + int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *); + int (*inject_op)(pcap_t *, const void *, size_t); + int (*setfilter_op)(pcap_t *, struct bpf_program *); + int (*setdirection_op)(pcap_t *, pcap_direction_t); + int (*set_datalink_op)(pcap_t *, int); + int (*getnonblock_op)(pcap_t *, char *); + int (*setnonblock_op)(pcap_t *, int, char *); + int (*stats_op)(pcap_t *, struct pcap_stat *); + void (*close_op)(pcap_t *); + + /* + * Placeholder for filter code if bpf not in kernel. + */ + struct bpf_program fcode; + + char errbuf[PCAP_ERRBUF_SIZE + 1]; + int dlt_count; + u_int *dlt_list; + + struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */ + +#ifdef HAVE_REMOTE +#ifndef WIN32 // Win32 already defines 'timeout' + int timeout; //!< timeout to be used in the pcap_open() +#endif + /*! \brief '1' if we're the network client; needed by several functions (like pcap_setfilter() ) to know if + they have to use the socket or they have to open the local adapter. */ + int rmt_clientside; + + SOCKET rmt_sockctrl; //!< socket ID of the socket used for the control connection + SOCKET rmt_sockdata; //!< socket ID of the socket used for the data connection + int rmt_flags; //!< we have to save flags, since they are passed by the pcap_open_live(), but they are used by the pcap_startcapture() + int rmt_capstarted; //!< 'true' if the capture is already started (needed to knoe if we have to call the pcap_startcapture() + struct pcap_samp rmt_samp; //!< Keeps the parameters related to the sampling process. + char *currentfilter; //!< Pointer to a buffer (allocated at run-time) that stores the current filter. Needed when flag PCAP_OPENFLAG_NOCAPTURE_RPCAP is turned on. +#endif /* HAVE_REMOTE */ +}; + +/* + * This is a timeval as stored in a savefile. + * It has to use the same types everywhere, independent of the actual + * `struct timeval'; `struct timeval' has 32-bit tv_sec values on some + * platforms and 64-bit tv_sec values on other platforms, and writing + * out native `struct timeval' values would mean files could only be + * read on systems with the same tv_sec size as the system on which + * the file was written. + */ + +struct pcap_timeval { + bpf_int32 tv_sec; /* seconds */ + bpf_int32 tv_usec; /* microseconds */ +}; + +/* + * This is a `pcap_pkthdr' as actually stored in a savefile. + * + * Do not change the format of this structure, in any way (this includes + * changes that only affect the length of fields in this structure), + * and do not make the time stamp anything other than seconds and + * microseconds (e.g., seconds and nanoseconds). Instead: + * + * introduce a new structure for the new format; + * + * send mail to "tcpdump-workers@tcpdump.org", requesting a new + * magic number for your new capture file format, and, when + * you get the new magic number, put it in "savefile.c"; + * + * use that magic number for save files with the changed record + * header; + * + * make the code in "savefile.c" capable of reading files with + * the old record header as well as files with the new record header + * (using the magic number to determine the header format). + * + * Then supply the changes to "patches@tcpdump.org", so that future + * versions of libpcap and programs that use it (such as tcpdump) will + * be able to read your new capture file format. + */ + +struct pcap_sf_pkthdr { + struct pcap_timeval ts; /* time stamp */ + bpf_u_int32 caplen; /* length of portion present */ + bpf_u_int32 len; /* length this packet (off wire) */ +}; + +/* + * How a `pcap_pkthdr' is actually stored in savefiles written + * by some patched versions of libpcap (e.g. the ones in Red + * Hat Linux 6.1 and 6.2). + * + * Do not change the format of this structure, in any way (this includes + * changes that only affect the length of fields in this structure). + * Instead, introduce a new structure, as per the above. + */ + +struct pcap_sf_patched_pkthdr { + struct pcap_timeval ts; /* time stamp */ + bpf_u_int32 caplen; /* length of portion present */ + bpf_u_int32 len; /* length this packet (off wire) */ + int index; + unsigned short protocol; + unsigned char pkt_type; +}; + +int yylex(void); + +#ifndef min +#define min(a, b) ((a) > (b) ? (b) : (a)) +#endif + +/* XXX should these be in pcap.h? */ +int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *); +int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *); + +#ifndef HAVE_STRLCPY +#define strlcpy(x, y, z) \ + (strncpy((x), (y), (z)), \ + ((z) <= 0 ? 0 : ((x)[(z) - 1] = '\0')), \ + strlen((y))) +#endif + +#include + +#if !defined(HAVE_SNPRINTF) +#define snprintf pcap_snprintf +extern int snprintf (char *, size_t, const char *, ...); +#endif + +#if !defined(HAVE_VSNPRINTF) +#define vsnprintf pcap_vsnprintf +extern int vsnprintf (char *, size_t, const char *, va_list ap); +#endif + +/* + * Routines that most pcap implementations can use for non-blocking mode. + */ +#if !defined(WIN32) && !defined(MSDOS) +int pcap_getnonblock_fd(pcap_t *, char *); +int pcap_setnonblock_fd(pcap_t *p, int, char *); +#endif + +void pcap_close_common(pcap_t *); + +/* + * Internal interfaces for "pcap_findalldevs()". + * + * "pcap_platform_finddevs()" is a platform-dependent routine to + * add devices not found by the "standard" mechanisms (SIOCGIFCONF, + * "getifaddrs()", etc.. + * + * "pcap_add_if()" adds an interface to the list of interfaces. + */ +int pcap_platform_finddevs(pcap_if_t **, char *); +int add_addr_to_iflist(pcap_if_t **, const char *, u_int, struct sockaddr *, + size_t, struct sockaddr *, size_t, struct sockaddr *, size_t, + struct sockaddr *, size_t, char *); +int pcap_add_if(pcap_if_t **, const char *, u_int, const char *, char *); +struct sockaddr *dup_sockaddr(struct sockaddr *, size_t); +int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int, + const char *, char *); + +#ifdef WIN32 +char *pcap_win32strerror(void); +#endif + +int install_bpf_program(pcap_t *, struct bpf_program *); + +int pcap_strcasecmp(const char *, const char *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/winpcap/wpcap/libpcap/pcap-linux.c b/winpcap/wpcap/libpcap/pcap-linux.c new file mode 100644 index 0000000..29422d7 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-linux.c @@ -0,0 +1,2250 @@ +/* + * pcap-linux.c: Packet capture interface to the Linux kernel + * + * Copyright (c) 2000 Torsten Landschoff + * Sebastian Krahmer + * + * License: BSD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.110.2.12 2006/09/18 17:34:31 guy Exp $ (LBL)"; +#endif + +/* + * Known problems with 2.0[.x] kernels: + * + * - The loopback device gives every packet twice; on 2.2[.x] kernels, + * if we use PF_PACKET, we can filter out the transmitted version + * of the packet by using data in the "sockaddr_ll" returned by + * "recvfrom()", but, on 2.0[.x] kernels, we have to use + * PF_INET/SOCK_PACKET, which means "recvfrom()" supplies a + * "sockaddr_pkt" which doesn't give us enough information to let + * us do that. + * + * - We have to set the interface's IFF_PROMISC flag ourselves, if + * we're to run in promiscuous mode, which means we have to turn + * it off ourselves when we're done; the kernel doesn't keep track + * of how many sockets are listening promiscuously, which means + * it won't get turned off automatically when no sockets are + * listening promiscuously. We catch "pcap_close()" and, for + * interfaces we put into promiscuous mode, take them out of + * promiscuous mode - which isn't necessarily the right thing to + * do, if another socket also requested promiscuous mode between + * the time when we opened the socket and the time when we close + * the socket. + * + * - MSG_TRUNC isn't supported, so you can't specify that "recvfrom()" + * return the amount of data that you could have read, rather than + * the amount that was returned, so we can't just allocate a buffer + * whose size is the snapshot length and pass the snapshot length + * as the byte count, and also pass MSG_TRUNC, so that the return + * value tells us how long the packet was on the wire. + * + * This means that, if we want to get the actual size of the packet, + * so we can return it in the "len" field of the packet header, + * we have to read the entire packet, not just the part that fits + * within the snapshot length, and thus waste CPU time copying data + * from the kernel that our caller won't see. + * + * We have to get the actual size, and supply it in "len", because + * otherwise, the IP dissector in tcpdump, for example, will complain + * about "truncated-ip", as the packet will appear to have been + * shorter, on the wire, than the IP header said it should have been. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcap-int.h" +#include "sll.h" + +#ifdef HAVE_DAG_API +#include "pcap-dag.h" +#endif /* HAVE_DAG_API */ + +#ifdef HAVE_SEPTEL_API +#include "pcap-septel.h" +#endif /* HAVE_SEPTEL_API */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_REMOTE +#include +#endif + +/* + * If PF_PACKET is defined, we can use {SOCK_RAW,SOCK_DGRAM}/PF_PACKET + * sockets rather than SOCK_PACKET sockets. + * + * To use them, we include rather than + * ; we do so because + * + * some Linux distributions (e.g., Slackware 4.0) have 2.2 or + * later kernels and libc5, and don't provide a + * file; + * + * not all versions of glibc2 have a file + * that defines stuff needed for some of the 2.4-or-later-kernel + * features, so if the system has a 2.4 or later kernel, we + * still can't use those features. + * + * We're already including a number of other headers, and + * this code is Linux-specific (no other OS has PF_PACKET sockets as + * a raw packet capture mechanism), so it's not as if you gain any + * useful portability by using + * + * XXX - should we just include even if PF_PACKET + * isn't defined? It only defines one data structure in 2.0.x, so + * it shouldn't cause any problems. + */ +#ifdef PF_PACKET +# include + + /* + * On at least some Linux distributions (for example, Red Hat 5.2), + * there's no file, but PF_PACKET is defined if + * you include , but doesn't define + * any of the PF_PACKET stuff such as "struct sockaddr_ll" or any of + * the PACKET_xxx stuff. + * + * So we check whether PACKET_HOST is defined, and assume that we have + * PF_PACKET sockets only if it is defined. + */ +# ifdef PACKET_HOST +# define HAVE_PF_PACKET_SOCKETS +# endif /* PACKET_HOST */ +#endif /* PF_PACKET */ + +#ifdef SO_ATTACH_FILTER +#include +#include +#endif + +#ifndef __GLIBC__ +typedef int socklen_t; +#endif + +#ifndef MSG_TRUNC +/* + * This is being compiled on a system that lacks MSG_TRUNC; define it + * with the value it has in the 2.2 and later kernels, so that, on + * those kernels, when we pass it in the flags argument to "recvfrom()" + * we're passing the right value and thus get the MSG_TRUNC behavior + * we want. (We don't get that behavior on 2.0[.x] kernels, because + * they didn't support MSG_TRUNC.) + */ +#define MSG_TRUNC 0x20 +#endif + +#ifndef SOL_PACKET +/* + * This is being compiled on a system that lacks SOL_PACKET; define it + * with the value it has in the 2.2 and later kernels, so that we can + * set promiscuous mode in the good modern way rather than the old + * 2.0-kernel crappy way. + */ +#define SOL_PACKET 263 +#endif + +#define MAX_LINKHEADER_SIZE 256 + +/* + * When capturing on all interfaces we use this as the buffer size. + * Should be bigger then all MTUs that occur in real life. + * 64kB should be enough for now. + */ +#define BIGGER_THAN_ALL_MTUS (64*1024) + +/* + * Prototypes for internal functions + */ +static void map_arphrd_to_dlt(pcap_t *, int, int); +static int live_open_old(pcap_t *, const char *, int, int, char *); +static int live_open_new(pcap_t *, const char *, int, int, char *); +static int pcap_read_linux(pcap_t *, int, pcap_handler, u_char *); +static int pcap_read_packet(pcap_t *, pcap_handler, u_char *); +static int pcap_inject_linux(pcap_t *, const void *, size_t); +static int pcap_stats_linux(pcap_t *, struct pcap_stat *); +static int pcap_setfilter_linux(pcap_t *, struct bpf_program *); +static int pcap_setdirection_linux(pcap_t *, pcap_direction_t); +static void pcap_close_linux(pcap_t *); + +/* + * Wrap some ioctl calls + */ +#ifdef HAVE_PF_PACKET_SOCKETS +static int iface_get_id(int fd, const char *device, char *ebuf); +#endif +static int iface_get_mtu(int fd, const char *device, char *ebuf); +static int iface_get_arptype(int fd, const char *device, char *ebuf); +#ifdef HAVE_PF_PACKET_SOCKETS +static int iface_bind(int fd, int ifindex, char *ebuf); +#endif +static int iface_bind_old(int fd, const char *device, char *ebuf); + +#ifdef SO_ATTACH_FILTER +static int fix_program(pcap_t *handle, struct sock_fprog *fcode); +static int fix_offset(struct bpf_insn *p); +static int set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode); +static int reset_kernel_filter(pcap_t *handle); + +static struct sock_filter total_insn + = BPF_STMT(BPF_RET | BPF_K, 0); +static struct sock_fprog total_fcode + = { 1, &total_insn }; +#endif + +/* + * Get a handle for a live capture from the given device. You can + * pass NULL as device to get all packages (without link level + * information of course). If you pass 1 as promisc the interface + * will be set to promiscous mode (XXX: I think this usage should + * be deprecated and functions be added to select that later allow + * modification of that values -- Torsten). + * + * See also pcap(3). + */ +pcap_t * +pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, + char *ebuf) +{ + pcap_t *handle; + int mtu; + int err; + int live_open_ok = 0; + struct utsname utsname; + +#ifdef HAVE_REMOTE + /* + Retrofit; we have to make older applications compatible with the remote capture + So, we're calling the pcap_open_remote() from here, that is a very dirty thing. + Obviously, we cannot exploit all the new features; for instance, we cannot + send authentication, we cannot use a UDP data connection, and so on. + */ + + char host[PCAP_BUF_SIZE + 1]; + char port[PCAP_BUF_SIZE + 1]; + char name[PCAP_BUF_SIZE + 1]; + int srctype; + + if (pcap_parsesrcstr(device, &srctype, host, port, name, ebuf) ) + return NULL; + + if (srctype == PCAP_SRC_IFREMOTE) + { + handle= pcap_opensource_remote(device, NULL, ebuf); + + if (handle == NULL) + return NULL; + + handle->snapshot= snaplen; + handle->md.timeout= to_ms; + handle->rmt_flags= (promisc) ? PCAP_OPENFLAG_PROMISCUOUS : 0; + + return handle; + } +#endif /* HAVE_REMOTE */ + +#ifdef HAVE_DAG_API + if (strstr(device, "dag")) { + return dag_open_live(device, snaplen, promisc, to_ms, ebuf); + } +#endif /* HAVE_DAG_API */ + +#ifdef HAVE_SEPTEL_API + if (strstr(device, "septel")) { + return septel_open_live(device, snaplen, promisc, to_ms, ebuf); + } +#endif /* HAVE_SEPTEL_API */ + + /* Allocate a handle for this session. */ + + handle = malloc(sizeof(*handle)); + if (handle == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + return NULL; + } + + /* Initialize some components of the pcap structure. */ + + memset(handle, 0, sizeof(*handle)); + handle->snapshot = snaplen; + handle->md.timeout = to_ms; + + /* + * NULL and "any" are special devices which give us the hint to + * monitor all devices. + */ + if (!device || strcmp(device, "any") == 0) { + device = NULL; + handle->md.device = strdup("any"); + if (promisc) { + promisc = 0; + /* Just a warning. */ + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "Promiscuous mode not supported on the \"any\" device"); + } + + } else + handle->md.device = strdup(device); + + if (handle->md.device == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "strdup: %s", + pcap_strerror(errno) ); + free(handle); + return NULL; + } + + /* + * Current Linux kernels use the protocol family PF_PACKET to + * allow direct access to all packets on the network while + * older kernels had a special socket type SOCK_PACKET to + * implement this feature. + * While this old implementation is kind of obsolete we need + * to be compatible with older kernels for a while so we are + * trying both methods with the newer method preferred. + */ + + if ((err = live_open_new(handle, device, promisc, to_ms, ebuf)) == 1) + live_open_ok = 1; + else if (err == 0) { + /* Non-fatal error; try old way */ + if (live_open_old(handle, device, promisc, to_ms, ebuf)) + live_open_ok = 1; + } + if (!live_open_ok) { + /* + * Both methods to open the packet socket failed. Tidy + * up and report our failure (ebuf is expected to be + * set by the functions above). + */ + + if (handle->md.device != NULL) + free(handle->md.device); + free(handle); + return NULL; + } + + /* + * Compute the buffer size. + * + * If we're using SOCK_PACKET, this might be a 2.0[.x] kernel, + * and might require special handling - check. + */ + if (handle->md.sock_packet && (uname(&utsname) < 0 || + strncmp(utsname.release, "2.0", 3) == 0)) { + /* + * We're using a SOCK_PACKET structure, and either + * we couldn't find out what kernel release this is, + * or it's a 2.0[.x] kernel. + * + * In the 2.0[.x] kernel, a "recvfrom()" on + * a SOCK_PACKET socket, with MSG_TRUNC set, will + * return the number of bytes read, so if we pass + * a length based on the snapshot length, it'll + * return the number of bytes from the packet + * copied to userland, not the actual length + * of the packet. + * + * This means that, for example, the IP dissector + * in tcpdump will get handed a packet length less + * than the length in the IP header, and will + * complain about "truncated-ip". + * + * So we don't bother trying to copy from the + * kernel only the bytes in which we're interested, + * but instead copy them all, just as the older + * versions of libpcap for Linux did. + * + * The buffer therefore needs to be big enough to + * hold the largest packet we can get from this + * device. Unfortunately, we can't get the MRU + * of the network; we can only get the MTU. The + * MTU may be too small, in which case a packet larger + * than the buffer size will be truncated *and* we + * won't get the actual packet size. + * + * However, if the snapshot length is larger than + * the buffer size based on the MTU, we use the + * snapshot length as the buffer size, instead; + * this means that with a sufficiently large snapshot + * length we won't artificially truncate packets + * to the MTU-based size. + * + * This mess just one of many problems with packet + * capture on 2.0[.x] kernels; you really want a + * 2.2[.x] or later kernel if you want packet capture + * to work well. + */ + mtu = iface_get_mtu(handle->fd, device, ebuf); + if (mtu == -1) { + pcap_close_linux(handle); + free(handle); + return NULL; + } + handle->bufsize = MAX_LINKHEADER_SIZE + mtu; + if (handle->bufsize < handle->snapshot) + handle->bufsize = handle->snapshot; + } else { + /* + * This is a 2.2[.x] or later kernel (we know that + * either because we're not using a SOCK_PACKET + * socket - PF_PACKET is supported only in 2.2 + * and later kernels - or because we checked the + * kernel version). + * + * We can safely pass "recvfrom()" a byte count + * based on the snapshot length. + * + * If we're in cooked mode, make the snapshot length + * large enough to hold a "cooked mode" header plus + * 1 byte of packet data (so we don't pass a byte + * count of 0 to "recvfrom()"). + */ + if (handle->md.cooked) { + if (handle->snapshot < SLL_HDR_LEN + 1) + handle->snapshot = SLL_HDR_LEN + 1; + } + handle->bufsize = handle->snapshot; + } + + /* Allocate the buffer */ + + handle->buffer = malloc(handle->bufsize + handle->offset); + if (!handle->buffer) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + pcap_close_linux(handle); + free(handle); + return NULL; + } + + /* + * "handle->fd" is a socket, so "select()" and "poll()" + * should work on it. + */ + handle->selectable_fd = handle->fd; + + handle->read_op = pcap_read_linux; + handle->inject_op = pcap_inject_linux; + handle->setfilter_op = pcap_setfilter_linux; + handle->setdirection_op = pcap_setdirection_linux; + handle->set_datalink_op = NULL; /* can't change data link type */ + handle->getnonblock_op = pcap_getnonblock_fd; + handle->setnonblock_op = pcap_setnonblock_fd; + handle->stats_op = pcap_stats_linux; + handle->close_op = pcap_close_linux; + + return handle; +} + +/* + * Read at most max_packets from the capture stream and call the callback + * for each of them. Returns the number of packets handled or -1 if an + * error occured. + */ +static int +pcap_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) +{ + /* + * Currently, on Linux only one packet is delivered per read, + * so we don't loop. + */ + return pcap_read_packet(handle, callback, user); +} + +/* + * Read a packet from the socket calling the handler provided by + * the user. Returns the number of packets received or -1 if an + * error occured. + */ +static int +pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) +{ + u_char *bp; + int offset; +#ifdef HAVE_PF_PACKET_SOCKETS + struct sockaddr_ll from; + struct sll_header *hdrp; +#else + struct sockaddr from; +#endif + socklen_t fromlen; + int packet_len, caplen; + struct pcap_pkthdr pcap_header; + +#ifdef HAVE_PF_PACKET_SOCKETS + /* + * If this is a cooked device, leave extra room for a + * fake packet header. + */ + if (handle->md.cooked) + offset = SLL_HDR_LEN; + else + offset = 0; +#else + /* + * This system doesn't have PF_PACKET sockets, so it doesn't + * support cooked devices. + */ + offset = 0; +#endif + + /* Receive a single packet from the kernel */ + + bp = handle->buffer + handle->offset; + do { + /* + * Has "pcap_breakloop()" been called? + */ + if (handle->break_loop) { + /* + * Yes - clear the flag that indicates that it + * has, and return -2 as an indication that we + * were told to break out of the loop. + */ + handle->break_loop = 0; + return -2; + } + fromlen = sizeof(from); + packet_len = recvfrom( + handle->fd, bp + offset, + handle->bufsize - offset, MSG_TRUNC, + (struct sockaddr *) &from, &fromlen); + } while (packet_len == -1 && errno == EINTR); + + /* Check if an error occured */ + + if (packet_len == -1) { + if (errno == EAGAIN) + return 0; /* no packet there */ + else { + snprintf(handle->errbuf, sizeof(handle->errbuf), + "recvfrom: %s", pcap_strerror(errno)); + return -1; + } + } + +#ifdef HAVE_PF_PACKET_SOCKETS + if (!handle->md.sock_packet) { + /* + * Unfortunately, there is a window between socket() and + * bind() where the kernel may queue packets from any + * interface. If we're bound to a particular interface, + * discard packets not from that interface. + * + * (If socket filters are supported, we could do the + * same thing we do when changing the filter; however, + * that won't handle packet sockets without socket + * filter support, and it's a bit more complicated. + * It would save some instructions per packet, however.) + */ + if (handle->md.ifindex != -1 && + from.sll_ifindex != handle->md.ifindex) + return 0; + + /* + * Do checks based on packet direction. + * We can only do this if we're using PF_PACKET; the + * address returned for SOCK_PACKET is a "sockaddr_pkt" + * which lacks the relevant packet type information. + */ + if (from.sll_pkttype == PACKET_OUTGOING) { + /* + * Outgoing packet. + * If this is from the loopback device, reject it; + * we'll see the packet as an incoming packet as well, + * and we don't want to see it twice. + */ + if (from.sll_ifindex == handle->md.lo_ifindex) + return 0; + + /* + * If the user only wants incoming packets, reject it. + */ + if (handle->direction == PCAP_D_IN) + return 0; + } else { + /* + * Incoming packet. + * If the user only wants outgoing packets, reject it. + */ + if (handle->direction == PCAP_D_OUT) + return 0; + } + } +#endif + +#ifdef HAVE_PF_PACKET_SOCKETS + /* + * If this is a cooked device, fill in the fake packet header. + */ + if (handle->md.cooked) { + /* + * Add the length of the fake header to the length + * of packet data we read. + */ + packet_len += SLL_HDR_LEN; + + hdrp = (struct sll_header *)bp; + + /* + * Map the PACKET_ value to a LINUX_SLL_ value; we + * want the same numerical value to be used in + * the link-layer header even if the numerical values + * for the PACKET_ #defines change, so that programs + * that look at the packet type field will always be + * able to handle DLT_LINUX_SLL captures. + */ + switch (from.sll_pkttype) { + + case PACKET_HOST: + hdrp->sll_pkttype = htons(LINUX_SLL_HOST); + break; + + case PACKET_BROADCAST: + hdrp->sll_pkttype = htons(LINUX_SLL_BROADCAST); + break; + + case PACKET_MULTICAST: + hdrp->sll_pkttype = htons(LINUX_SLL_MULTICAST); + break; + + case PACKET_OTHERHOST: + hdrp->sll_pkttype = htons(LINUX_SLL_OTHERHOST); + break; + + case PACKET_OUTGOING: + hdrp->sll_pkttype = htons(LINUX_SLL_OUTGOING); + break; + + default: + hdrp->sll_pkttype = -1; + break; + } + + hdrp->sll_hatype = htons(from.sll_hatype); + hdrp->sll_halen = htons(from.sll_halen); + memcpy(hdrp->sll_addr, from.sll_addr, + (from.sll_halen > SLL_ADDRLEN) ? + SLL_ADDRLEN : + from.sll_halen); + hdrp->sll_protocol = from.sll_protocol; + } +#endif + + /* + * XXX: According to the kernel source we should get the real + * packet len if calling recvfrom with MSG_TRUNC set. It does + * not seem to work here :(, but it is supported by this code + * anyway. + * To be honest the code RELIES on that feature so this is really + * broken with 2.2.x kernels. + * I spend a day to figure out what's going on and I found out + * that the following is happening: + * + * The packet comes from a random interface and the packet_rcv + * hook is called with a clone of the packet. That code inserts + * the packet into the receive queue of the packet socket. + * If a filter is attached to that socket that filter is run + * first - and there lies the problem. The default filter always + * cuts the packet at the snaplen: + * + * # tcpdump -d + * (000) ret #68 + * + * So the packet filter cuts down the packet. The recvfrom call + * says "hey, it's only 68 bytes, it fits into the buffer" with + * the result that we don't get the real packet length. This + * is valid at least until kernel 2.2.17pre6. + * + * We currently handle this by making a copy of the filter + * program, fixing all "ret" instructions with non-zero + * operands to have an operand of 65535 so that the filter + * doesn't truncate the packet, and supplying that modified + * filter to the kernel. + */ + + caplen = packet_len; + if (caplen > handle->snapshot) + caplen = handle->snapshot; + + /* Run the packet filter if not using kernel filter */ + if (!handle->md.use_bpf && handle->fcode.bf_insns) { + if (bpf_filter(handle->fcode.bf_insns, bp, + packet_len, caplen) == 0) + { + /* rejected by filter */ + return 0; + } + } + + /* Fill in our own header data */ + + if (ioctl(handle->fd, SIOCGSTAMP, &pcap_header.ts) == -1) { + snprintf(handle->errbuf, sizeof(handle->errbuf), + "SIOCGSTAMP: %s", pcap_strerror(errno)); + return -1; + } + pcap_header.caplen = caplen; + pcap_header.len = packet_len; + + /* + * Count the packet. + * + * Arguably, we should count them before we check the filter, + * as on many other platforms "ps_recv" counts packets + * handed to the filter rather than packets that passed + * the filter, but if filtering is done in the kernel, we + * can't get a count of packets that passed the filter, + * and that would mean the meaning of "ps_recv" wouldn't + * be the same on all Linux systems. + * + * XXX - it's not the same on all systems in any case; + * ideally, we should have a "get the statistics" call + * that supplies more counts and indicates which of them + * it supplies, so that we supply a count of packets + * handed to the filter only on platforms where that + * information is available. + * + * We count them here even if we can get the packet count + * from the kernel, as we can only determine at run time + * whether we'll be able to get it from the kernel (if + * HAVE_TPACKET_STATS isn't defined, we can't get it from + * the kernel, but if it is defined, the library might + * have been built with a 2.4 or later kernel, but we + * might be running on a 2.2[.x] kernel without Alexey + * Kuznetzov's turbopacket patches, and thus the kernel + * might not be able to supply those statistics). We + * could, I guess, try, when opening the socket, to get + * the statistics, and if we can not increment the count + * here, but it's not clear that always incrementing + * the count is more expensive than always testing a flag + * in memory. + * + * We keep the count in "md.packets_read", and use that for + * "ps_recv" if we can't get the statistics from the kernel. + * We do that because, if we *can* get the statistics from + * the kernel, we use "md.stat.ps_recv" and "md.stat.ps_drop" + * as running counts, as reading the statistics from the + * kernel resets the kernel statistics, and if we directly + * increment "md.stat.ps_recv" here, that means it will + * count packets *twice* on systems where we can get kernel + * statistics - once here, and once in pcap_stats_linux(). + */ + handle->md.packets_read++; + + /* Call the user supplied callback function */ + callback(userdata, &pcap_header, bp); + + return 1; +} + +static int +pcap_inject_linux(pcap_t *handle, const void *buf, size_t size) +{ + int ret; + +#ifdef HAVE_PF_PACKET_SOCKETS + if (!handle->md.sock_packet) { + /* PF_PACKET socket */ + if (handle->md.ifindex == -1) { + /* + * We don't support sending on the "any" device. + */ + strlcpy(handle->errbuf, + "Sending packets isn't supported on the \"any\" device", + PCAP_ERRBUF_SIZE); + return (-1); + } + + if (handle->md.cooked) { + /* + * We don't support sending on the "any" device. + * + * XXX - how do you send on a bound cooked-mode + * socket? + * Is a "sendto()" required there? + */ + strlcpy(handle->errbuf, + "Sending packets isn't supported in cooked mode", + PCAP_ERRBUF_SIZE); + return (-1); + } + } +#endif + + ret = send(handle->fd, buf, size, 0); + if (ret == -1) { + snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "send: %s", + pcap_strerror(errno)); + return (-1); + } + return (ret); +} + +/* + * Get the statistics for the given packet capture handle. + * Reports the number of dropped packets iff the kernel supports + * the PACKET_STATISTICS "getsockopt()" argument (2.4 and later + * kernels, and 2.2[.x] kernels with Alexey Kuznetzov's turbopacket + * patches); otherwise, that information isn't available, and we lie + * and report 0 as the count of dropped packets. + */ +static int +pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats) +{ +#ifdef HAVE_TPACKET_STATS + struct tpacket_stats kstats; + socklen_t len = sizeof (struct tpacket_stats); +#endif + +#ifdef HAVE_TPACKET_STATS + /* + * Try to get the packet counts from the kernel. + */ + if (getsockopt(handle->fd, SOL_PACKET, PACKET_STATISTICS, + &kstats, &len) > -1) { + /* + * On systems where the PACKET_STATISTICS "getsockopt()" + * argument is supported on PF_PACKET sockets: + * + * "ps_recv" counts only packets that *passed* the + * filter, not packets that didn't pass the filter. + * This includes packets later dropped because we + * ran out of buffer space. + * + * "ps_drop" counts packets dropped because we ran + * out of buffer space. It doesn't count packets + * dropped by the interface driver. It counts only + * packets that passed the filter. + * + * Both statistics include packets not yet read from + * the kernel by libpcap, and thus not yet seen by + * the application. + * + * In "linux/net/packet/af_packet.c", at least in the + * 2.4.9 kernel, "tp_packets" is incremented for every + * packet that passes the packet filter *and* is + * successfully queued on the socket; "tp_drops" is + * incremented for every packet dropped because there's + * not enough free space in the socket buffer. + * + * When the statistics are returned for a PACKET_STATISTICS + * "getsockopt()" call, "tp_drops" is added to "tp_packets", + * so that "tp_packets" counts all packets handed to + * the PF_PACKET socket, including packets dropped because + * there wasn't room on the socket buffer - but not + * including packets that didn't pass the filter. + * + * In the BSD BPF, the count of received packets is + * incremented for every packet handed to BPF, regardless + * of whether it passed the filter. + * + * We can't make "pcap_stats()" work the same on both + * platforms, but the best approximation is to return + * "tp_packets" as the count of packets and "tp_drops" + * as the count of drops. + * + * Keep a running total because each call to + * getsockopt(handle->fd, SOL_PACKET, PACKET_STATISTICS, .... + * resets the counters to zero. + */ + handle->md.stat.ps_recv += kstats.tp_packets; + handle->md.stat.ps_drop += kstats.tp_drops; + *stats = handle->md.stat; + return 0; + } + else + { + /* + * If the error was EOPNOTSUPP, fall through, so that + * if you build the library on a system with + * "struct tpacket_stats" and run it on a system + * that doesn't, it works as it does if the library + * is built on a system without "struct tpacket_stats". + */ + if (errno != EOPNOTSUPP) { + snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, + "pcap_stats: %s", pcap_strerror(errno)); + return -1; + } + } +#endif + /* + * On systems where the PACKET_STATISTICS "getsockopt()" argument + * is not supported on PF_PACKET sockets: + * + * "ps_recv" counts only packets that *passed* the filter, + * not packets that didn't pass the filter. It does not + * count packets dropped because we ran out of buffer + * space. + * + * "ps_drop" is not supported. + * + * "ps_recv" doesn't include packets not yet read from + * the kernel by libpcap. + * + * We maintain the count of packets processed by libpcap in + * "md.packets_read", for reasons described in the comment + * at the end of pcap_read_packet(). We have no idea how many + * packets were dropped. + */ + stats->ps_recv = handle->md.packets_read; + stats->ps_drop = 0; + return 0; +} + +/* + * Description string for the "any" device. + */ +static const char any_descr[] = "Pseudo-device that captures on all interfaces"; + +int +pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) +{ + if (pcap_add_if(alldevsp, "any", 0, any_descr, errbuf) < 0) + return (-1); + +#ifdef HAVE_DAG_API + if (dag_platform_finddevs(alldevsp, errbuf) < 0) + return (-1); +#endif /* HAVE_DAG_API */ + +#ifdef HAVE_SEPTEL_API + if (septel_platform_finddevs(alldevsp, errbuf) < 0) + return (-1); +#endif /* HAVE_SEPTEL_API */ + + return (0); +} + +/* + * Attach the given BPF code to the packet capture device. + */ +static int +pcap_setfilter_linux(pcap_t *handle, struct bpf_program *filter) +{ +#ifdef SO_ATTACH_FILTER + struct sock_fprog fcode; + int can_filter_in_kernel; + int err = 0; +#endif + + if (!handle) + return -1; + if (!filter) { + strncpy(handle->errbuf, "setfilter: No filter specified", + sizeof(handle->errbuf)); + return -1; + } + + /* Make our private copy of the filter */ + + if (install_bpf_program(handle, filter) < 0) + /* install_bpf_program() filled in errbuf */ + return -1; + + /* + * Run user level packet filter by default. Will be overriden if + * installing a kernel filter succeeds. + */ + handle->md.use_bpf = 0; + + /* Install kernel level filter if possible */ + +#ifdef SO_ATTACH_FILTER +#ifdef USHRT_MAX + if (handle->fcode.bf_len > USHRT_MAX) { + /* + * fcode.len is an unsigned short for current kernel. + * I have yet to see BPF-Code with that much + * instructions but still it is possible. So for the + * sake of correctness I added this check. + */ + fprintf(stderr, "Warning: Filter too complex for kernel\n"); + fcode.filter = NULL; + can_filter_in_kernel = 0; + } else +#endif /* USHRT_MAX */ + { + /* + * Oh joy, the Linux kernel uses struct sock_fprog instead + * of struct bpf_program and of course the length field is + * of different size. Pointed out by Sebastian + * + * Oh, and we also need to fix it up so that all "ret" + * instructions with non-zero operands have 65535 as the + * operand, and so that, if we're in cooked mode, all + * memory-reference instructions use special magic offsets + * in references to the link-layer header and assume that + * the link-layer payload begins at 0; "fix_program()" + * will do that. + */ + switch (fix_program(handle, &fcode)) { + + case -1: + default: + /* + * Fatal error; just quit. + * (The "default" case shouldn't happen; we + * return -1 for that reason.) + */ + return -1; + + case 0: + /* + * The program performed checks that we can't make + * work in the kernel. + */ + can_filter_in_kernel = 0; + break; + + case 1: + /* + * We have a filter that'll work in the kernel. + */ + can_filter_in_kernel = 1; + break; + } + } + + if (can_filter_in_kernel) { + if ((err = set_kernel_filter(handle, &fcode)) == 0) + { + /* Installation succeded - using kernel filter. */ + handle->md.use_bpf = 1; + } + else if (err == -1) /* Non-fatal error */ + { + /* + * Print a warning if we weren't able to install + * the filter for a reason other than "this kernel + * isn't configured to support socket filters. + */ + if (errno != ENOPROTOOPT && errno != EOPNOTSUPP) { + fprintf(stderr, + "Warning: Kernel filter failed: %s\n", + pcap_strerror(errno)); + } + } + } + + /* + * If we're not using the kernel filter, get rid of any kernel + * filter that might've been there before, e.g. because the + * previous filter could work in the kernel, or because some other + * code attached a filter to the socket by some means other than + * calling "pcap_setfilter()". Otherwise, the kernel filter may + * filter out packets that would pass the new userland filter. + */ + if (!handle->md.use_bpf) + reset_kernel_filter(handle); + + /* + * Free up the copy of the filter that was made by "fix_program()". + */ + if (fcode.filter != NULL) + free(fcode.filter); + + if (err == -2) + /* Fatal error */ + return -1; +#endif /* SO_ATTACH_FILTER */ + + return 0; +} + +/* + * Set direction flag: Which packets do we accept on a forwarding + * single device? IN, OUT or both? + */ +static int +pcap_setdirection_linux(pcap_t *handle, pcap_direction_t d) +{ +#ifdef HAVE_PF_PACKET_SOCKETS + if (!handle->md.sock_packet) { + handle->direction = d; + return 0; + } +#endif + /* + * We're not using PF_PACKET sockets, so we can't determine + * the direction of the packet. + */ + snprintf(handle->errbuf, sizeof(handle->errbuf), + "Setting direction is not supported on SOCK_PACKET sockets"); + return -1; +} + +/* + * Linux uses the ARP hardware type to identify the type of an + * interface. pcap uses the DLT_xxx constants for this. This + * function takes a pointer to a "pcap_t", and an ARPHRD_xxx + * constant, as arguments, and sets "handle->linktype" to the + * appropriate DLT_XXX constant and sets "handle->offset" to + * the appropriate value (to make "handle->offset" plus link-layer + * header length be a multiple of 4, so that the link-layer payload + * will be aligned on a 4-byte boundary when capturing packets). + * (If the offset isn't set here, it'll be 0; add code as appropriate + * for cases where it shouldn't be 0.) + * + * If "cooked_ok" is non-zero, we can use DLT_LINUX_SLL and capture + * in cooked mode; otherwise, we can't use cooked mode, so we have + * to pick some type that works in raw mode, or fail. + * + * Sets the link type to -1 if unable to map the type. + */ +static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok) +{ + switch (arptype) { + + case ARPHRD_ETHER: + /* + * This is (presumably) a real Ethernet capture; give it a + * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so + * that an application can let you choose it, in case you're + * capturing DOCSIS traffic that a Cisco Cable Modem + * Termination System is putting out onto an Ethernet (it + * doesn't put an Ethernet header onto the wire, it puts raw + * DOCSIS frames out on the wire inside the low-level + * Ethernet framing). + * + * XXX - are there any sorts of "fake Ethernet" that have + * ARPHRD_ETHER but that *shouldn't offer DLT_DOCSIS as + * a Cisco CMTS won't put traffic onto it or get traffic + * bridged onto it? ISDN is handled in "live_open_new()", + * as we fall back on cooked mode there; are there any + * others? + */ + handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); + /* + * If that fails, just leave the list empty. + */ + if (handle->dlt_list != NULL) { + handle->dlt_list[0] = DLT_EN10MB; + handle->dlt_list[1] = DLT_DOCSIS; + handle->dlt_count = 2; + } + /* FALLTHROUGH */ + + case ARPHRD_METRICOM: + case ARPHRD_LOOPBACK: + handle->linktype = DLT_EN10MB; + handle->offset = 2; + break; + + case ARPHRD_EETHER: + handle->linktype = DLT_EN3MB; + break; + + case ARPHRD_AX25: + handle->linktype = DLT_AX25; + break; + + case ARPHRD_PRONET: + handle->linktype = DLT_PRONET; + break; + + case ARPHRD_CHAOS: + handle->linktype = DLT_CHAOS; + break; + +#ifndef ARPHRD_IEEE802_TR +#define ARPHRD_IEEE802_TR 800 /* From Linux 2.4 */ +#endif + case ARPHRD_IEEE802_TR: + case ARPHRD_IEEE802: + handle->linktype = DLT_IEEE802; + handle->offset = 2; + break; + + case ARPHRD_ARCNET: + handle->linktype = DLT_ARCNET_LINUX; + break; + +#ifndef ARPHRD_FDDI /* From Linux 2.2.13 */ +#define ARPHRD_FDDI 774 +#endif + case ARPHRD_FDDI: + handle->linktype = DLT_FDDI; + handle->offset = 3; + break; + +#ifndef ARPHRD_ATM /* FIXME: How to #include this? */ +#define ARPHRD_ATM 19 +#endif + case ARPHRD_ATM: + /* + * The Classical IP implementation in ATM for Linux + * supports both what RFC 1483 calls "LLC Encapsulation", + * in which each packet has an LLC header, possibly + * with a SNAP header as well, prepended to it, and + * what RFC 1483 calls "VC Based Multiplexing", in which + * different virtual circuits carry different network + * layer protocols, and no header is prepended to packets. + * + * They both have an ARPHRD_ type of ARPHRD_ATM, so + * you can't use the ARPHRD_ type to find out whether + * captured packets will have an LLC header, and, + * while there's a socket ioctl to *set* the encapsulation + * type, there's no ioctl to *get* the encapsulation type. + * + * This means that + * + * programs that dissect Linux Classical IP frames + * would have to check for an LLC header and, + * depending on whether they see one or not, dissect + * the frame as LLC-encapsulated or as raw IP (I + * don't know whether there's any traffic other than + * IP that would show up on the socket, or whether + * there's any support for IPv6 in the Linux + * Classical IP code); + * + * filter expressions would have to compile into + * code that checks for an LLC header and does + * the right thing. + * + * Both of those are a nuisance - and, at least on systems + * that support PF_PACKET sockets, we don't have to put + * up with those nuisances; instead, we can just capture + * in cooked mode. That's what we'll do, if we can. + * Otherwise, we'll just fail. + */ + if (cooked_ok) + handle->linktype = DLT_LINUX_SLL; + else + handle->linktype = -1; + break; + +#ifndef ARPHRD_IEEE80211 /* From Linux 2.4.6 */ +#define ARPHRD_IEEE80211 801 +#endif + case ARPHRD_IEEE80211: + handle->linktype = DLT_IEEE802_11; + break; + +#ifndef ARPHRD_IEEE80211_PRISM /* From Linux 2.4.18 */ +#define ARPHRD_IEEE80211_PRISM 802 +#endif + case ARPHRD_IEEE80211_PRISM: + handle->linktype = DLT_PRISM_HEADER; + break; + +#ifndef ARPHRD_IEEE80211_RADIOTAP /* new */ +#define ARPHRD_IEEE80211_RADIOTAP 803 +#endif + case ARPHRD_IEEE80211_RADIOTAP: + handle->linktype = DLT_IEEE802_11_RADIO; + break; + + case ARPHRD_PPP: + /* + * Some PPP code in the kernel supplies no link-layer + * header whatsoever to PF_PACKET sockets; other PPP + * code supplies PPP link-layer headers ("syncppp.c"); + * some PPP code might supply random link-layer + * headers (PPP over ISDN - there's code in Ethereal, + * for example, to cope with PPP-over-ISDN captures + * with which the Ethereal developers have had to cope, + * heuristically trying to determine which of the + * oddball link-layer headers particular packets have). + * + * As such, we just punt, and run all PPP interfaces + * in cooked mode, if we can; otherwise, we just treat + * it as DLT_RAW, for now - if somebody needs to capture, + * on a 2.0[.x] kernel, on PPP devices that supply a + * link-layer header, they'll have to add code here to + * map to the appropriate DLT_ type (possibly adding a + * new DLT_ type, if necessary). + */ + if (cooked_ok) + handle->linktype = DLT_LINUX_SLL; + else { + /* + * XXX - handle ISDN types here? We can't fall + * back on cooked sockets, so we'd have to + * figure out from the device name what type of + * link-layer encapsulation it's using, and map + * that to an appropriate DLT_ value, meaning + * we'd map "isdnN" devices to DLT_RAW (they + * supply raw IP packets with no link-layer + * header) and "isdY" devices to a new DLT_I4L_IP + * type that has only an Ethernet packet type as + * a link-layer header. + * + * But sometimes we seem to get random crap + * in the link-layer header when capturing on + * ISDN devices.... + */ + handle->linktype = DLT_RAW; + } + break; + +#ifndef ARPHRD_CISCO +#define ARPHRD_CISCO 513 /* previously ARPHRD_HDLC */ +#endif + case ARPHRD_CISCO: + handle->linktype = DLT_C_HDLC; + break; + + /* Not sure if this is correct for all tunnels, but it + * works for CIPE */ + case ARPHRD_TUNNEL: +#ifndef ARPHRD_SIT +#define ARPHRD_SIT 776 /* From Linux 2.2.13 */ +#endif + case ARPHRD_SIT: + case ARPHRD_CSLIP: + case ARPHRD_SLIP6: + case ARPHRD_CSLIP6: + case ARPHRD_ADAPT: + case ARPHRD_SLIP: +#ifndef ARPHRD_RAWHDLC +#define ARPHRD_RAWHDLC 518 +#endif + case ARPHRD_RAWHDLC: +#ifndef ARPHRD_DLCI +#define ARPHRD_DLCI 15 +#endif + case ARPHRD_DLCI: + /* + * XXX - should some of those be mapped to DLT_LINUX_SLL + * instead? Should we just map all of them to DLT_LINUX_SLL? + */ + handle->linktype = DLT_RAW; + break; + +#ifndef ARPHRD_FRAD +#define ARPHRD_FRAD 770 +#endif + case ARPHRD_FRAD: + handle->linktype = DLT_FRELAY; + break; + + case ARPHRD_LOCALTLK: + handle->linktype = DLT_LTALK; + break; + +#ifndef ARPHRD_FCPP +#define ARPHRD_FCPP 784 +#endif + case ARPHRD_FCPP: +#ifndef ARPHRD_FCAL +#define ARPHRD_FCAL 785 +#endif + case ARPHRD_FCAL: +#ifndef ARPHRD_FCPL +#define ARPHRD_FCPL 786 +#endif + case ARPHRD_FCPL: +#ifndef ARPHRD_FCFABRIC +#define ARPHRD_FCFABRIC 787 +#endif + case ARPHRD_FCFABRIC: + /* + * We assume that those all mean RFC 2625 IP-over- + * Fibre Channel, with the RFC 2625 header at + * the beginning of the packet. + */ + handle->linktype = DLT_IP_OVER_FC; + break; + +#ifndef ARPHRD_IRDA +#define ARPHRD_IRDA 783 +#endif + case ARPHRD_IRDA: + /* Don't expect IP packet out of this interfaces... */ + handle->linktype = DLT_LINUX_IRDA; + /* We need to save packet direction for IrDA decoding, + * so let's use "Linux-cooked" mode. Jean II */ + //handle->md.cooked = 1; + break; + + /* ARPHRD_LAPD is unofficial and randomly allocated, if reallocation + * is needed, please report it to */ +#ifndef ARPHRD_LAPD +#define ARPHRD_LAPD 8445 +#endif + case ARPHRD_LAPD: + /* Don't expect IP packet out of this interfaces... */ + handle->linktype = DLT_LINUX_LAPD; + break; + + default: + handle->linktype = -1; + break; + } +} + +/* ===== Functions to interface to the newer kernels ================== */ + +/* + * Try to open a packet socket using the new kernel interface. + * Returns 0 on failure. + * FIXME: 0 uses to mean success (Sebastian) + */ +static int +live_open_new(pcap_t *handle, const char *device, int promisc, + int to_ms, char *ebuf) +{ +#ifdef HAVE_PF_PACKET_SOCKETS + int sock_fd = -1, arptype; + int err; + int fatal_err = 0; + struct packet_mreq mr; + + /* One shot loop used for error handling - bail out with break */ + + do { + /* + * Open a socket with protocol family packet. If a device is + * given we try to open it in raw mode otherwise we use + * the cooked interface. + */ + sock_fd = device ? + socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) + : socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); + + if (sock_fd == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "socket: %s", + pcap_strerror(errno) ); + break; + } + + /* It seems the kernel supports the new interface. */ + handle->md.sock_packet = 0; + + /* + * Get the interface index of the loopback device. + * If the attempt fails, don't fail, just set the + * "md.lo_ifindex" to -1. + * + * XXX - can there be more than one device that loops + * packets back, i.e. devices other than "lo"? If so, + * we'd need to find them all, and have an array of + * indices for them, and check all of them in + * "pcap_read_packet()". + */ + handle->md.lo_ifindex = iface_get_id(sock_fd, "lo", ebuf); + + /* + * Default value for offset to align link-layer payload + * on a 4-byte boundary. + */ + handle->offset = 0; + + /* + * What kind of frames do we have to deal with? Fall back + * to cooked mode if we have an unknown interface type. + */ + + if (device) { + /* Assume for now we don't need cooked mode. */ + handle->md.cooked = 0; + + arptype = iface_get_arptype(sock_fd, device, ebuf); + if (arptype == -1) { + fatal_err = 1; + break; + } + map_arphrd_to_dlt(handle, arptype, 1); + if (handle->linktype == -1 || + handle->linktype == DLT_LINUX_SLL || + handle->linktype == DLT_LINUX_IRDA || + handle->linktype == DLT_LINUX_LAPD || + (handle->linktype == DLT_EN10MB && + (strncmp("isdn", device, 4) == 0 || + strncmp("isdY", device, 4) == 0))) { + /* + * Unknown interface type (-1), or a + * device we explicitly chose to run + * in cooked mode (e.g., PPP devices), + * or an ISDN device (whose link-layer + * type we can only determine by using + * APIs that may be different on different + * kernels) - reopen in cooked mode. + */ + if (close(sock_fd) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "close: %s", pcap_strerror(errno)); + break; + } + sock_fd = socket(PF_PACKET, SOCK_DGRAM, + htons(ETH_P_ALL)); + if (sock_fd == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "socket: %s", pcap_strerror(errno)); + break; + } + handle->md.cooked = 1; + + /* + * Get rid of any link-layer type list + * we allocated - this only supports cooked + * capture. + */ + if (handle->dlt_list != NULL) { + free(handle->dlt_list); + handle->dlt_list = NULL; + handle->dlt_count = 0; + } + + if (handle->linktype == -1) { + /* + * Warn that we're falling back on + * cooked mode; we may want to + * update "map_arphrd_to_dlt()" + * to handle the new type. + */ + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "arptype %d not " + "supported by libpcap - " + "falling back to cooked " + "socket", + arptype); + } + /* IrDA capture is not a real "cooked" capture, + * it's IrLAP frames, not IP packets. */ + if (handle->linktype != DLT_LINUX_IRDA && + handle->linktype != DLT_LINUX_LAPD) + handle->linktype = DLT_LINUX_SLL; + } + + handle->md.ifindex = iface_get_id(sock_fd, device, ebuf); + if (handle->md.ifindex == -1) + break; + + if ((err = iface_bind(sock_fd, handle->md.ifindex, + ebuf)) < 0) { + if (err == -2) + fatal_err = 1; + break; + } + } else { + /* + * This is cooked mode. + */ + handle->md.cooked = 1; + handle->linktype = DLT_LINUX_SLL; + + /* + * We're not bound to a device. + * XXX - true? Or true only if we're using + * the "any" device? + * For now, we're using this as an indication + * that we can't transmit; stop doing that only + * if we figure out how to transmit in cooked + * mode. + */ + handle->md.ifindex = -1; + } + + /* + * Select promiscuous mode on if "promisc" is set. + * + * Do not turn allmulti mode on if we don't select + * promiscuous mode - on some devices (e.g., Orinoco + * wireless interfaces), allmulti mode isn't supported + * and the driver implements it by turning promiscuous + * mode on, and that screws up the operation of the + * card as a normal networking interface, and on no + * other platform I know of does starting a non- + * promiscuous capture affect which multicast packets + * are received by the interface. + */ + + /* + * Hmm, how can we set promiscuous mode on all interfaces? + * I am not sure if that is possible at all. + */ + + if (device && promisc) { + memset(&mr, 0, sizeof(mr)); + mr.mr_ifindex = handle->md.ifindex; + mr.mr_type = PACKET_MR_PROMISC; + if (setsockopt(sock_fd, SOL_PACKET, + PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == -1) + { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "setsockopt: %s", pcap_strerror(errno)); + break; + } + } + + /* Save the socket FD in the pcap structure */ + + handle->fd = sock_fd; + + return 1; + + } while(0); + + if (sock_fd != -1) + close(sock_fd); + + if (fatal_err) { + /* + * Get rid of any link-layer type list we allocated. + */ + if (handle->dlt_list != NULL) + free(handle->dlt_list); + return -2; + } else + return 0; +#else + strncpy(ebuf, + "New packet capturing interface not supported by build " + "environment", PCAP_ERRBUF_SIZE); + return 0; +#endif +} + +#ifdef HAVE_PF_PACKET_SOCKETS +/* + * Return the index of the given device name. Fill ebuf and return + * -1 on failure. + */ +static int +iface_get_id(int fd, const char *device, char *ebuf) +{ + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + + if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "SIOCGIFINDEX: %s", pcap_strerror(errno)); + return -1; + } + + return ifr.ifr_ifindex; +} + +/* + * Bind the socket associated with FD to the given device. + */ +static int +iface_bind(int fd, int ifindex, char *ebuf) +{ + struct sockaddr_ll sll; + int err; + socklen_t errlen = sizeof(err); + + memset(&sll, 0, sizeof(sll)); + sll.sll_family = AF_PACKET; + sll.sll_ifindex = ifindex; + sll.sll_protocol = htons(ETH_P_ALL); + + if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "bind: %s", pcap_strerror(errno)); + return -1; + } + + /* Any pending errors, e.g., network is down? */ + + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "getsockopt: %s", pcap_strerror(errno)); + return -2; + } + + if (err > 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "bind: %s", pcap_strerror(err)); + return -2; + } + + return 0; +} + +#endif + + +/* ===== Functions to interface to the older kernels ================== */ + +/* + * With older kernels promiscuous mode is kind of interesting because we + * have to reset the interface before exiting. The problem can't really + * be solved without some daemon taking care of managing usage counts. + * If we put the interface into promiscuous mode, we set a flag indicating + * that we must take it out of that mode when the interface is closed, + * and, when closing the interface, if that flag is set we take it out + * of promiscuous mode. + */ + +/* + * List of pcaps for which we turned promiscuous mode on by hand. + * If there are any such pcaps, we arrange to call "pcap_close_all()" + * when we exit, and have it close all of them to turn promiscuous mode + * off. + */ +static struct pcap *pcaps_to_close; + +/* + * TRUE if we've already called "atexit()" to cause "pcap_close_all()" to + * be called on exit. + */ +static int did_atexit; + +static void pcap_close_all(void) +{ + struct pcap *handle; + + while ((handle = pcaps_to_close) != NULL) + pcap_close(handle); +} + +static void pcap_close_linux( pcap_t *handle ) +{ + struct pcap *p, *prevp; + struct ifreq ifr; + + if (handle->md.clear_promisc) { + /* + * We put the interface into promiscuous mode; take + * it out of promiscuous mode. + * + * XXX - if somebody else wants it in promiscuous mode, + * this code cannot know that, so it'll take it out + * of promiscuous mode. That's not fixable in 2.0[.x] + * kernels. + */ + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, handle->md.device, sizeof(ifr.ifr_name)); + if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) { + fprintf(stderr, + "Can't restore interface flags (SIOCGIFFLAGS failed: %s).\n" + "Please adjust manually.\n" + "Hint: This can't happen with Linux >= 2.2.0.\n", + strerror(errno)); + } else { + if (ifr.ifr_flags & IFF_PROMISC) { + /* + * Promiscuous mode is currently on; turn it + * off. + */ + ifr.ifr_flags &= ~IFF_PROMISC; + if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1) { + fprintf(stderr, + "Can't restore interface flags (SIOCSIFFLAGS failed: %s).\n" + "Please adjust manually.\n" + "Hint: This can't happen with Linux >= 2.2.0.\n", + strerror(errno)); + } + } + } + + /* + * Take this pcap out of the list of pcaps for which we + * have to take the interface out of promiscuous mode. + */ + for (p = pcaps_to_close, prevp = NULL; p != NULL; + prevp = p, p = p->md.next) { + if (p == handle) { + /* + * Found it. Remove it from the list. + */ + if (prevp == NULL) { + /* + * It was at the head of the list. + */ + pcaps_to_close = p->md.next; + } else { + /* + * It was in the middle of the list. + */ + prevp->md.next = p->md.next; + } + break; + } + } + } + + if (handle->md.device != NULL) + free(handle->md.device); + handle->md.device = NULL; + pcap_close_common(handle); +} + +/* + * Try to open a packet socket using the old kernel interface. + * Returns 0 on failure. + * FIXME: 0 uses to mean success (Sebastian) + */ +static int +live_open_old(pcap_t *handle, const char *device, int promisc, + int to_ms, char *ebuf) +{ + int arptype; + struct ifreq ifr; + + do { + /* Open the socket */ + + handle->fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL)); + if (handle->fd == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "socket: %s", pcap_strerror(errno)); + break; + } + + /* It worked - we are using the old interface */ + handle->md.sock_packet = 1; + + /* ...which means we get the link-layer header. */ + handle->md.cooked = 0; + + /* Bind to the given device */ + + if (!device) { + strncpy(ebuf, "pcap_open_live: The \"any\" device isn't supported on 2.0[.x]-kernel systems", + PCAP_ERRBUF_SIZE); + break; + } + if (iface_bind_old(handle->fd, device, ebuf) == -1) + break; + + /* + * Try to get the link-layer type. + */ + arptype = iface_get_arptype(handle->fd, device, ebuf); + if (arptype == -1) + break; + + /* + * Try to find the DLT_ type corresponding to that + * link-layer type. + */ + map_arphrd_to_dlt(handle, arptype, 0); + if (handle->linktype == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "unknown arptype %d", arptype); + break; + } + + /* Go to promisc mode if requested */ + + if (promisc) { + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "SIOCGIFFLAGS: %s", pcap_strerror(errno)); + break; + } + if ((ifr.ifr_flags & IFF_PROMISC) == 0) { + /* + * Promiscuous mode isn't currently on, + * so turn it on, and remember that + * we should turn it off when the + * pcap_t is closed. + */ + + /* + * If we haven't already done so, arrange + * to have "pcap_close_all()" called when + * we exit. + */ + if (!did_atexit) { + if (atexit(pcap_close_all) == -1) { + /* + * "atexit()" failed; don't + * put the interface in + * promiscuous mode, just + * give up. + */ + strncpy(ebuf, "atexit failed", + PCAP_ERRBUF_SIZE); + break; + } + did_atexit = 1; + } + + ifr.ifr_flags |= IFF_PROMISC; + if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "SIOCSIFFLAGS: %s", + pcap_strerror(errno)); + break; + } + handle->md.clear_promisc = 1; + + /* + * Add this to the list of pcaps + * to close when we exit. + */ + handle->md.next = pcaps_to_close; + pcaps_to_close = handle; + } + } + + /* + * Default value for offset to align link-layer payload + * on a 4-byte boundary. + */ + handle->offset = 0; + + return 1; + + } while (0); + + pcap_close_linux(handle); + return 0; +} + +/* + * Bind the socket associated with FD to the given device using the + * interface of the old kernels. + */ +static int +iface_bind_old(int fd, const char *device, char *ebuf) +{ + struct sockaddr saddr; + int err; + socklen_t errlen = sizeof(err); + + memset(&saddr, 0, sizeof(saddr)); + strncpy(saddr.sa_data, device, sizeof(saddr.sa_data)); + if (bind(fd, &saddr, sizeof(saddr)) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "bind: %s", pcap_strerror(errno)); + return -1; + } + + /* Any pending errors, e.g., network is down? */ + + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "getsockopt: %s", pcap_strerror(errno)); + return -1; + } + + if (err > 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "bind: %s", pcap_strerror(err)); + return -1; + } + + return 0; +} + + +/* ===== System calls available on all supported kernels ============== */ + +/* + * Query the kernel for the MTU of the given interface. + */ +static int +iface_get_mtu(int fd, const char *device, char *ebuf) +{ + struct ifreq ifr; + + if (!device) + return BIGGER_THAN_ALL_MTUS; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + + if (ioctl(fd, SIOCGIFMTU, &ifr) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "SIOCGIFMTU: %s", pcap_strerror(errno)); + return -1; + } + + return ifr.ifr_mtu; +} + +/* + * Get the hardware type of the given interface as ARPHRD_xxx constant. + */ +static int +iface_get_arptype(int fd, const char *device, char *ebuf) +{ + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + + if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "SIOCGIFHWADDR: %s", pcap_strerror(errno)); + return -1; + } + + return ifr.ifr_hwaddr.sa_family; +} + +#ifdef SO_ATTACH_FILTER +static int +fix_program(pcap_t *handle, struct sock_fprog *fcode) +{ + size_t prog_size; + register int i; + register struct bpf_insn *p; + struct bpf_insn *f; + int len; + + /* + * Make a copy of the filter, and modify that copy if + * necessary. + */ + prog_size = sizeof(*handle->fcode.bf_insns) * handle->fcode.bf_len; + len = handle->fcode.bf_len; + f = (struct bpf_insn *)malloc(prog_size); + if (f == NULL) { + snprintf(handle->errbuf, sizeof(handle->errbuf), + "malloc: %s", pcap_strerror(errno)); + return -1; + } + memcpy(f, handle->fcode.bf_insns, prog_size); + fcode->len = len; + fcode->filter = (struct sock_filter *) f; + + for (i = 0; i < len; ++i) { + p = &f[i]; + /* + * What type of instruction is this? + */ + switch (BPF_CLASS(p->code)) { + + case BPF_RET: + /* + * It's a return instruction; is the snapshot + * length a constant, rather than the contents + * of the accumulator? + */ + if (BPF_MODE(p->code) == BPF_K) { + /* + * Yes - if the value to be returned, + * i.e. the snapshot length, is anything + * other than 0, make it 65535, so that + * the packet is truncated by "recvfrom()", + * not by the filter. + * + * XXX - there's nothing we can easily do + * if it's getting the value from the + * accumulator; we'd have to insert + * code to force non-zero values to be + * 65535. + */ + if (p->k != 0) + p->k = 65535; + } + break; + + case BPF_LD: + case BPF_LDX: + /* + * It's a load instruction; is it loading + * from the packet? + */ + switch (BPF_MODE(p->code)) { + + case BPF_ABS: + case BPF_IND: + case BPF_MSH: + /* + * Yes; are we in cooked mode? + */ + if (handle->md.cooked) { + /* + * Yes, so we need to fix this + * instruction. + */ + if (fix_offset(p) < 0) { + /* + * We failed to do so. + * Return 0, so our caller + * knows to punt to userland. + */ + return 0; + } + } + break; + } + break; + } + } + return 1; /* we succeeded */ +} + +static int +fix_offset(struct bpf_insn *p) +{ + /* + * What's the offset? + */ + if (p->k >= SLL_HDR_LEN) { + /* + * It's within the link-layer payload; that starts at an + * offset of 0, as far as the kernel packet filter is + * concerned, so subtract the length of the link-layer + * header. + */ + p->k -= SLL_HDR_LEN; + } else if (p->k == 14) { + /* + * It's the protocol field; map it to the special magic + * kernel offset for that field. + */ + p->k = SKF_AD_OFF + SKF_AD_PROTOCOL; + } else { + /* + * It's within the header, but it's not one of those + * fields; we can't do that in the kernel, so punt + * to userland. + */ + return -1; + } + return 0; +} + +static int +set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode) +{ + int total_filter_on = 0; + int save_mode; + int ret; + int save_errno; + + /* + * The socket filter code doesn't discard all packets queued + * up on the socket when the filter is changed; this means + * that packets that don't match the new filter may show up + * after the new filter is put onto the socket, if those + * packets haven't yet been read. + * + * This means, for example, that if you do a tcpdump capture + * with a filter, the first few packets in the capture might + * be packets that wouldn't have passed the filter. + * + * We therefore discard all packets queued up on the socket + * when setting a kernel filter. (This isn't an issue for + * userland filters, as the userland filtering is done after + * packets are queued up.) + * + * To flush those packets, we put the socket in read-only mode, + * and read packets from the socket until there are no more to + * read. + * + * In order to keep that from being an infinite loop - i.e., + * to keep more packets from arriving while we're draining + * the queue - we put the "total filter", which is a filter + * that rejects all packets, onto the socket before draining + * the queue. + * + * This code deliberately ignores any errors, so that you may + * get bogus packets if an error occurs, rather than having + * the filtering done in userland even if it could have been + * done in the kernel. + */ + if (setsockopt(handle->fd, SOL_SOCKET, SO_ATTACH_FILTER, + &total_fcode, sizeof(total_fcode)) == 0) { + char drain[1]; + + /* + * Note that we've put the total filter onto the socket. + */ + total_filter_on = 1; + + /* + * Save the socket's current mode, and put it in + * non-blocking mode; we drain it by reading packets + * until we get an error (which is normally a + * "nothing more to be read" error). + */ + save_mode = fcntl(handle->fd, F_GETFL, 0); + if (save_mode != -1 && + fcntl(handle->fd, F_SETFL, save_mode | O_NONBLOCK) >= 0) { + while (recv(handle->fd, &drain, sizeof drain, + MSG_TRUNC) >= 0) + ; + save_errno = errno; + fcntl(handle->fd, F_SETFL, save_mode); + if (save_errno != EAGAIN) { + /* Fatal error */ + reset_kernel_filter(handle); + snprintf(handle->errbuf, sizeof(handle->errbuf), + "recv: %s", pcap_strerror(save_errno)); + return -2; + } + } + } + + /* + * Now attach the new filter. + */ + ret = setsockopt(handle->fd, SOL_SOCKET, SO_ATTACH_FILTER, + fcode, sizeof(*fcode)); + if (ret == -1 && total_filter_on) { + /* + * Well, we couldn't set that filter on the socket, + * but we could set the total filter on the socket. + * + * This could, for example, mean that the filter was + * too big to put into the kernel, so we'll have to + * filter in userland; in any case, we'll be doing + * filtering in userland, so we need to remove the + * total filter so we see packets. + */ + save_errno = errno; + + /* + * XXX - if this fails, we're really screwed; + * we have the total filter on the socket, + * and it won't come off. What do we do then? + */ + reset_kernel_filter(handle); + + errno = save_errno; + } + return ret; +} + +static int +reset_kernel_filter(pcap_t *handle) +{ + /* setsockopt() barfs unless it get a dummy parameter */ + int dummy; + + return setsockopt(handle->fd, SOL_SOCKET, SO_DETACH_FILTER, + &dummy, sizeof(dummy)); +} +#endif diff --git a/winpcap/wpcap/libpcap/pcap-namedb.h b/winpcap/wpcap/libpcap/pcap-namedb.h new file mode 100644 index 0000000..acaabd9 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-namedb.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1994, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.10.2.1 2005/04/19 04:26:08 guy Exp $ (LBL) + */ + +#ifndef lib_pcap_namedb_h +#define lib_pcap_namedb_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * As returned by the pcap_next_etherent() + * XXX this stuff doesn't belong in this interface, but this + * library already must do name to address translation, so + * on systems that don't have support for /etc/ethers, we + * export these hooks since they'll + */ +struct pcap_etherent { + u_char addr[6]; + char name[122]; +}; +#ifndef PCAP_ETHERS_FILE +#define PCAP_ETHERS_FILE "/etc/ethers" +#endif +struct pcap_etherent *pcap_next_etherent(FILE *); +u_char *pcap_ether_hostton(const char*); +u_char *pcap_ether_aton(const char *); + +bpf_u_int32 **pcap_nametoaddr(const char *); +#ifdef INET6 +struct addrinfo *pcap_nametoaddrinfo(const char *); +#endif +bpf_u_int32 pcap_nametonetaddr(const char *); + +int pcap_nametoport(const char *, int *, int *); +int pcap_nametoportrange(const char *, int *, int *, int *); +int pcap_nametoproto(const char *); +int pcap_nametoeproto(const char *); +int pcap_nametollc(const char *); +/* + * If a protocol is unknown, PROTO_UNDEF is returned. + * Also, pcap_nametoport() returns the protocol along with the port number. + * If there are ambiguous entried in /etc/services (i.e. domain + * can be either tcp or udp) PROTO_UNDEF is returned. + */ +#define PROTO_UNDEF -1 + +/* XXX move these to pcap-int.h? */ +int __pcap_atodn(const char *, bpf_u_int32 *); +int __pcap_atoin(const char *, bpf_u_int32 *); +u_short __pcap_nametodnaddr(const char *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/winpcap/wpcap/libpcap/pcap-new.c b/winpcap/wpcap/libpcap/pcap-new.c new file mode 100644 index 0000000..36b0c1f --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-new.c @@ -0,0 +1,1231 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include // for the details of the pcap_t structure +#include +#include +#include // for the errno variable +#include // for malloc(), free(), ... +#include // for strstr, etc + +#ifndef WIN32 +#include // for readdir +#endif + + + +//! Keeps a list of all the opened connections in the active mode. +extern struct activehosts *activeHosts; + + +/*! + \brief Keeps the main socket identifier when we want to accept a new remote connection (active mode only). + + See the documentation of pcap_remoteact_accept() and pcap_remoteact_cleanup() for more details. +*/ +SOCKET sockmain; + + +//! String identifier to be used in the pcap_findalldevs_ex() +#define PCAP_TEXT_SOURCE_FILE "File" +//! String identifier to be used in the pcap_findalldevs_ex() +#define PCAP_TEXT_SOURCE_ADAPTER "Network adapter" + +//! String identifier to be used in the pcap_findalldevs_ex() +#define PCAP_TEXT_SOURCE_ON_LOCAL_HOST "on local host" +//! String identifier to be used in the pcap_findalldevs_ex() +#define PCAP_TEXT_SOURCE_ON_REMOTE_HOST "on remote node" + + + +/**************************************************** + * * + * Function bodies * + * * + ****************************************************/ + +int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf) +{ +SOCKET sockctrl; // socket descriptor of the control connection +unsigned int nread= 0; // number of bytes of the payload read from the socket +struct addrinfo hints; // temp variable needed to resove hostnames into to socket representation +struct addrinfo *addrinfo; // temp variable needed to resove hostnames into to socket representation +struct rpcap_header header; // structure that keeps the general header of the rpcap protocol +int i,j; // temp variables +int naddr; // temp var needed to avoid problems with IPv6 addresses +int retval; // store the return value of the functions +int nif; // Number of interfaces listed +int active= 0; // 'true' if we the other end-party is in active mode +char host[PCAP_BUF_SIZE], port[PCAP_BUF_SIZE], name[PCAP_BUF_SIZE], path[PCAP_BUF_SIZE], filename[PCAP_BUF_SIZE]; +int type; +pcap_t *fp; +char tmpstring[PCAP_BUF_SIZE + 1]; // Needed to convert names and descriptions from 'old' syntax to the 'new' one +pcap_if_t *dev; // Previous device into the pcap_if_t chain + + + if (strlen(source) > PCAP_BUF_SIZE) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly."); + return -1; + } + + // Determine the type of the source (file, local, remote) + // There are some differences if pcap_findalldevs_ex() is called to list files and remote adapters. + // In the first case, the name of the directory we have to look into must be present (therefore + // the 'name' parameter of the pcap_parsesrcstr() is present). + // In the second case, the name of the adapter is not required (we need just the host). So, we have + // to use a first time this function to get the source type, and a second time to get the appropriate + // info, which depends on the source type. + if (pcap_parsesrcstr(source, &type, NULL, NULL, NULL, errbuf) == -1) + return -1; + + if (type == PCAP_SRC_IFLOCAL) + { + if (pcap_parsesrcstr(source, &type, host, NULL, NULL, errbuf) == -1) + return -1; + + // Initialize temporary string + tmpstring[PCAP_BUF_SIZE]= 0; + + // The user wants to retrieve adapters from a local host + if (pcap_findalldevs(alldevs, errbuf) == -1) + return -1; + + if ( (alldevs == NULL) || (*alldevs == NULL) ) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "No interfaces found! Make sure libpcap/WinPcap is properly installed" + " on the local machine."); + return -1; + } + + // Scan all the interfaces and modify name and description + // This is a trick in order to avoid the re-implementation of the pcap_findalldevs here + dev= *alldevs; + while (dev) + { + // Create the new device identifier + if (pcap_createsrcstr(tmpstring, PCAP_SRC_IFLOCAL, NULL, NULL, dev->name, errbuf) == -1) + return -1; + + // Delete the old pointer + free(dev->name); + + dev->name= (char *) malloc( strlen(tmpstring) + 1); + + if (dev->name == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + return -1; + } + + // Copy the new device identifier into the correct memory location + strncpy(dev->name, tmpstring, strlen(tmpstring) + 1); + + + // Create the new device description + if ( (dev->description == NULL) || (dev->description[0] == 0) ) + snprintf(tmpstring, sizeof(tmpstring) - 1, "%s '%s' %s", PCAP_TEXT_SOURCE_ADAPTER, + dev->name, PCAP_TEXT_SOURCE_ON_LOCAL_HOST); + else + snprintf(tmpstring, sizeof(tmpstring) - 1, "%s '%s' %s", PCAP_TEXT_SOURCE_ADAPTER, + dev->description, PCAP_TEXT_SOURCE_ON_LOCAL_HOST); + + // Delete the old pointer + free(dev->description); + + dev->description= (char *) malloc( strlen(tmpstring) + 1); + + if (dev->description == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + return -1; + } + + // Copy the new device description into the correct memory location + strncpy(dev->description, tmpstring, strlen(tmpstring) + 1); + + dev= dev->next; + } + + return 0; + } + + (*alldevs)= NULL; + + if (type == PCAP_SRC_FILE) + { + int stringlen; +#ifdef WIN32 + WIN32_FIND_DATA filedata; + HANDLE filehandle; +#else + struct dirent *filedata; + DIR *unixdir; +#endif + + if (pcap_parsesrcstr(source, &type, host, port, name, errbuf) == -1) + return -1; + + // Check that the filename is correct + stringlen= strlen(name); + + // The directory must end with '\' in Win32 and '/' in UNIX +#ifdef WIN32 + #define ENDING_CHAR '\\' +#else + #define ENDING_CHAR '/' +#endif + + if (name[stringlen - 1] != ENDING_CHAR ) + { + name[stringlen]= ENDING_CHAR; + name[stringlen + 1]= 0; + + stringlen++; + } + + // Save the path for future reference + snprintf(path, sizeof(path), "%s", name); + +#ifdef WIN32 + // To perform directory listing, Win32 must have an 'asterisk' as ending char + if (name[stringlen - 1] != '*' ) + { + name[stringlen]= '*'; + name[stringlen + 1]= 0; + } + + filehandle = FindFirstFile(name, &filedata); + + if (filehandle == INVALID_HANDLE_VALUE) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path); + return -1; + } + +#else + // opening the folder + unixdir= opendir(path); + + // get the first file into it + filedata= readdir(unixdir); + + if (filedata == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path); + return -1; + } +#endif + + do + { + +#ifdef WIN32 + snprintf(filename, sizeof(filename), "%s%s", path, filedata.cFileName); +#else + snprintf(filename, sizeof(filename), "%s%s", path, filedata->d_name); +#endif + + fp= pcap_open_offline(filename, errbuf); + + if (fp) + { + // allocate the main structure + if (*alldevs == NULL) // This is in case it is the first file + { + (*alldevs)= (pcap_if_t *) malloc(sizeof(pcap_if_t) ); + dev= (*alldevs); + } + else + { + dev->next= (pcap_if_t *) malloc(sizeof(pcap_if_t) ); + dev= dev->next; + } + + // check that the malloc() didn't fail + if (dev == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + return -1; + } + + // Initialize the structure to 'zero' + memset(dev, 0, sizeof(pcap_if_t) ); + + // Create the new source identifier + if (pcap_createsrcstr(tmpstring, PCAP_SRC_FILE, NULL, NULL, filename, errbuf) == -1) + return -1; + + stringlen= strlen(tmpstring); + + dev->name= (char *) malloc(stringlen + 1); + if (dev->name == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + return -1; + } + + strncpy(dev->name, tmpstring, stringlen); + + dev->name[stringlen]= 0; + + // Create the description + snprintf(tmpstring, sizeof(tmpstring) - 1, "%s '%s' %s", PCAP_TEXT_SOURCE_FILE, + filename, PCAP_TEXT_SOURCE_ON_LOCAL_HOST); + + stringlen= strlen(tmpstring); + + dev->description= (char *) malloc(stringlen + 1); + + if (dev->description == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + return -1; + } + + // Copy the new device description into the correct memory location + strncpy(dev->description, tmpstring, stringlen + 1); + + pcap_close(fp); + } + } +#ifdef WIN32 + while (FindNextFile(filehandle, &filedata) != 0); +#else + while ( (filedata= readdir(unixdir)) != NULL); +#endif + + +#ifdef WIN32 + // Close the search handle. + FindClose(filehandle); +#endif + + return 0; + } + + // If we come here, it is a remote host + + // Retrieve the needed data for getting adapter list + if (pcap_parsesrcstr(source, &type, host, port, NULL, errbuf) == -1) + return -1; + + // Warning: this call can be the first one called by the user. + // For this reason, we have to initialize the WinSock support. + if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + + // Check for active mode + if ( (retval= rpcap_remoteact_getsock(host, errbuf)) == -1) + return -1; + + if (retval) + { + sockctrl= retval; + active= 1; + } + else // we're not in active mode; let's opening a new control connection (if needed) + { + addrinfo= NULL; + + memset(&hints, 0, sizeof(struct addrinfo) ); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if ( (port == NULL) || (port[0] == 0) ) + { + // the user chose not to specify the port + if (sock_initaddress(host, RPCAP_DEFAULT_NETPORT, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + } + else + { + if (sock_initaddress(host, port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + } + + if ( (sockctrl= sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == -1) + goto error; + + // addrinfo is no longer used + freeaddrinfo(addrinfo); + addrinfo= NULL; + + if ( rpcap_sendauth(sockctrl, auth, errbuf) == -1) + { + // Control connection has to be closed only in case the remote machine is in passive mode + if (!active) + sock_close(sockctrl, NULL, 0); + return -1; + } + } + + // RPCAP findalldevs command + rpcap_createhdr(&header, RPCAP_MSG_FINDALLIF_REQ, 0, 0); + + if ( sock_send(sockctrl, (char *) &header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1 ) + goto error; + + if ( sock_recv(sockctrl, (char *) &header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + // Checks if the message is correct + retval= rpcap_checkmsg(errbuf, sockctrl, &header, RPCAP_MSG_FINDALLIF_REPLY, RPCAP_MSG_ERROR, 0); + + if (retval != RPCAP_MSG_FINDALLIF_REPLY) // the message is not the one expected + { + switch (retval) + { + case -3: // Unrecoverable network error + case -2: // The other endpoint send a message that is not allowed here + case -1: // The other endpoint has a version number that is not compatible with our + break; + + case RPCAP_MSG_ERROR: // The other endpoint reported an error + break; + + default: + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Internal error"); + break; + }; + } + + if (!active) + sock_close(sockctrl, NULL, 0); + + return -1; + } + + // read the number of interfaces + nif= ntohs(header.value); + + // loop until all interfaces have been received + for (i= 0; i < nif; i++) + { + struct rpcap_findalldevs_if findalldevs_if; + char tmpstring2[PCAP_BUF_SIZE + 1]; // Needed to convert names and descriptions from 'old' syntax to the 'new' one + int stringlen; + + tmpstring2[PCAP_BUF_SIZE]= 0; + + // receive the findalldevs structure from remote hsot + if ( (nread+= sock_recv(sockctrl, (char *) &findalldevs_if, + sizeof(struct rpcap_findalldevs_if), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) ) == -1) + goto error; + + findalldevs_if.namelen= ntohs(findalldevs_if.namelen); + findalldevs_if.desclen= ntohs(findalldevs_if.desclen); + findalldevs_if.naddr= ntohs(findalldevs_if.naddr); + + // allocate the main structure + if (i == 0) + { + (*alldevs)= (pcap_if_t *) malloc(sizeof(pcap_if_t) ); + dev= (*alldevs); + } + else + { + dev->next= (pcap_if_t *) malloc(sizeof(pcap_if_t) ); + dev= dev->next; + } + + // check that the malloc() didn't fail + if (dev == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + goto error; + } + + // Initialize the structure to 'zero' + memset(dev, 0, sizeof(pcap_if_t) ); + + // allocate mem for name and description + if (findalldevs_if.namelen) + { + + if (findalldevs_if.namelen >= sizeof(tmpstring) ) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface name too long"); + goto error; + } + + // Retrieve adapter name + if ( (nread+= sock_recv(sockctrl, tmpstring, findalldevs_if.namelen, SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) ) == -1) + goto error; + + tmpstring[findalldevs_if.namelen]= 0; + + // Create the new device identifier + if (pcap_createsrcstr(tmpstring2, PCAP_SRC_IFREMOTE, host, port, tmpstring, errbuf) == -1) + return -1; + + stringlen= strlen(tmpstring2); + + dev->name= (char *) malloc(stringlen + 1); + if (dev->name == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + goto error; + } + + // Copy the new device name into the correct memory location + strncpy(dev->name, tmpstring2, stringlen + 1); + } + + if (findalldevs_if.desclen) + { + if (findalldevs_if.desclen >= sizeof(tmpstring) ) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface description too long"); + goto error; + } + + // Retrieve adapter description + if ( (nread+= sock_recv(sockctrl, tmpstring, findalldevs_if.desclen, SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) ) == -1) + goto error; + + tmpstring[findalldevs_if.desclen]= 0; + + + snprintf(tmpstring2, sizeof(tmpstring2) - 1, "%s '%s' %s %s", PCAP_TEXT_SOURCE_ADAPTER, + tmpstring, PCAP_TEXT_SOURCE_ON_REMOTE_HOST, host); + + stringlen= strlen(tmpstring2); + + dev->description= (char *) malloc(stringlen + 1); + + if (dev->description == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + goto error; + } + + // Copy the new device description into the correct memory location + strncpy(dev->description, tmpstring2, stringlen + 1); + } + + dev->flags= ntohl(findalldevs_if.flags); + + naddr= 0; + // loop until all addresses have been received + for (j= 0; j < findalldevs_if.naddr; j++) + { + struct rpcap_findalldevs_ifaddr ifaddr; + + // Retrieve the interface addresses + if ( (nread+= sock_recv(sockctrl, (char *) &ifaddr, + sizeof(struct rpcap_findalldevs_ifaddr), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) ) == -1) + goto error; + + // WARNING libpcap bug: the address listing is available only for AF_INET + if ( ntohs(ifaddr.addr.ss_family) == AF_INET) + { + struct pcap_addr *addr; + + if (naddr == 0) + { + dev->addresses= (struct pcap_addr *) malloc ( sizeof(struct pcap_addr) ); + addr= dev->addresses; + } + else + { + addr->next= (struct pcap_addr *) malloc ( sizeof(struct pcap_addr) ); + addr= addr->next; + } + naddr++; + + if (addr == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + goto error; + } + addr->next= NULL; + + if (rpcap_deseraddr( (struct sockaddr_storage *) &ifaddr.addr, + (struct sockaddr_storage **) &addr->addr, errbuf) == -1) + goto error; + if (rpcap_deseraddr( (struct sockaddr_storage *) &ifaddr.netmask, + (struct sockaddr_storage **) &addr->netmask, errbuf) == -1) + goto error; + if (rpcap_deseraddr( (struct sockaddr_storage *) &ifaddr.broadaddr, + (struct sockaddr_storage **) &addr->broadaddr, errbuf) == -1) + goto error; + if (rpcap_deseraddr( (struct sockaddr_storage *) &ifaddr.dstaddr, + (struct sockaddr_storage **) &addr->dstaddr, errbuf) == -1) + goto error; + + if ( (addr->addr == NULL) && (addr->netmask == NULL) && + (addr->broadaddr == NULL) && (addr->dstaddr == NULL) ) + { + free(addr); + addr= NULL; + if (naddr == 1) + naddr= 0; // the first item of the list had NULL addresses + } + } + } + } + + // Checks if all the data has been read; if not, discard the data in excess + if (nread != ntohl(header.plen)) + { + if (sock_discard(sockctrl, ntohl(header.plen) - nread, errbuf, PCAP_ERRBUF_SIZE) == 1) + return -1; + } + + // Control connection has to be closed only in case the remote machine is in passive mode + if (!active) + { + // DO not send RPCAP_CLOSE, since we did not open a pcap_t; no need to free resources + if ( sock_close(sockctrl, errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + } + + // To avoid inconsistencies in the number of sock_init() + sock_cleanup(); + + return 0; + +error: + // In case there has been an error, I don't want to overwrite it with a new one + // if the following call fails. I want to return always the original error. + // + // Take care: this connection can already be closed when we try to close it. + // This happens because a previous error in the rpcapd, which requested to + // closed the connection. In that case, we already recognized that into the + // rpspck_isheaderok() and we already acknowledged the closing. + // In that sense, this call is useless here (however it is needed in case + // the client generates the error). + + // Checks if all the data has been read; if not, discard the data in excess + if (nread != ntohl(header.plen)) + { + if (sock_discard(sockctrl, ntohl(header.plen) - nread, NULL, 0) == 1) + return -1; + } + + // Control connection has to be closed only in case the remote machine is in passive mode + if (!active) + sock_close(sockctrl, NULL, 0); + + // To avoid inconsistencies in the number of sock_init() + sock_cleanup(); + + return -1; +} + + +int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf) +{ + switch (type) + { + case PCAP_SRC_FILE: + { + strncpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE); + if ((name) && (*name) ) + { + strncat(source, name, PCAP_BUF_SIZE); + return 0; + } + else + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The file name cannot be NULL."); + return -1; + } + } + + case PCAP_SRC_IFREMOTE: + { + strncpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE); + if ((host) && (*host) ) + { + if ( (strcspn(host, "aAbBcCdDeEfFgGhHjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ")) == strlen(host) ) + { + // the host name does not contains alphabetic chars. So, it is a numeric address + // In this case we have to include it between square brackets + strncat(source, "[", PCAP_BUF_SIZE); + strncat(source, host, PCAP_BUF_SIZE); + strncat(source, "]", PCAP_BUF_SIZE); + } + else + strncat(source, host, PCAP_BUF_SIZE); + + if ((port) && (*port) ) + { + strncat(source, ":", PCAP_BUF_SIZE); + strncat(source, port, PCAP_BUF_SIZE); + } + + strncat(source, "/", PCAP_BUF_SIZE); + } + else + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The host name cannot be NULL."); + return -1; + } + + if ((name) && (*name) ) + strncat(source, name, PCAP_BUF_SIZE); + + return 0; + } + + case PCAP_SRC_IFLOCAL: + { + strncpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE); + + if ((name) && (*name) ) + strncat(source, name, PCAP_BUF_SIZE); + + return 0; + } + + default: + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface type is not valid."); + return -1; + } + } +} + + +int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf) +{ +char *ptr; +int ntoken; +char tmpname[PCAP_BUF_SIZE]; +char tmphost[PCAP_BUF_SIZE]; +char tmpport[PCAP_BUF_SIZE]; +int tmptype; + + // Initialization stuff + tmpname[0]= 0; + tmphost[0]= 0; + tmpport[0]= 0; + + if (host) + *host= 0; + if (port) + *port= 0; + if (name) + *name= 0; + + // Look for a 'rpcap://' identifier + if ( (ptr= strstr(source, PCAP_SRC_IF_STRING)) != NULL) + { + if (strlen(PCAP_SRC_IF_STRING) == strlen(source) ) + { + // The source identifier contains only the 'rpcap://' string. + // So, this is a local capture. + *type= PCAP_SRC_IFLOCAL; + return 0; + } + + ptr+= strlen(PCAP_SRC_IF_STRING); + + if (strchr(ptr, '[')) // This is probably a numeric address + { + ntoken= sscanf(ptr, "[%[1234567890:.]]:%[^/]/%s", tmphost, tmpport, tmpname); + + if (ntoken == 1) // probably the port is missing + ntoken= sscanf(ptr, "[%[1234567890:.]]/%s", tmphost, tmpname); + + tmptype= PCAP_SRC_IFREMOTE; + } + else + { + ntoken= sscanf(ptr, "%[^/:]:%[^/]/%s", tmphost, tmpport, tmpname); + + if (ntoken == 1) + { + // This can be due to two reasons: + // - we want a remote capture, but the network port is missing + // - we want to do a local capture + // To distinguish between the two, we look for the '/' char + if (strchr(ptr, '/')) + { + // We're on a remote capture + sscanf(ptr, "%[^/]/%s", tmphost, tmpname); + tmptype= PCAP_SRC_IFREMOTE; + } + else + { + // We're on a local capture + if (*ptr) + strncpy(tmpname, ptr, PCAP_BUF_SIZE); + + // Clean the host name, since it is a remote capture + // NOTE: the host name has been assigned in the previous "ntoken= sscanf(...)" line + tmphost[0]= 0; + + tmptype= PCAP_SRC_IFLOCAL; + } + } + else + tmptype= PCAP_SRC_IFREMOTE; + } + + if (host) + strcpy(host, tmphost); + if (port) + strcpy(port, tmpport); + if (type) + *type= tmptype; + + if (name) + { + // If the user wants the host name, but it cannot be located into the source string, return error + // However, if the user is not interested in the interface name (e.g. if we're called by + // pcap_findalldevs_ex(), which does not have interface name, do not return error + if (tmpname[0]) + { + strcpy(name, tmpname); + } + else + { + if (errbuf) + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface name has not been specified in the source string."); + + return -1; + } + } + + return 0; + } + + // Look for a 'file://' identifier + if ( (ptr= strstr(source, PCAP_SRC_FILE_STRING)) != NULL) + { + ptr+= strlen(PCAP_SRC_FILE_STRING); + if (*ptr) + { + if (name) + strncpy(name, ptr, PCAP_BUF_SIZE); + + if (type) + *type= PCAP_SRC_FILE; + + return 0; + } + else + { + if (errbuf) + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The file name has not been specified in the source string."); + + return -1; + } + + } + + // Backward compatibility; the user didn't use the 'rpcap://, file://' specifiers + if ( (source) && (*source) ) + { + if (name) + strncpy(name, source, PCAP_BUF_SIZE); + + if (type) + *type= PCAP_SRC_IFLOCAL; + + return 0; + } + else + { + if (errbuf) + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface name has not been specified in the source string."); + + return -1; + } +}; + + +pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf) +{ +char host[PCAP_BUF_SIZE], port[PCAP_BUF_SIZE], name[PCAP_BUF_SIZE]; +int type; +pcap_t *fp; + + if (strlen(source) > PCAP_BUF_SIZE) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly."); + return NULL; + } + + // determine the type of the source (file, local, remote) + if (pcap_parsesrcstr(source, &type, host, port, name, errbuf) == -1) + return NULL; + + + switch (type) + { + case PCAP_SRC_FILE: + fp = pcap_open_offline(name, errbuf); + break; + + case PCAP_SRC_IFREMOTE: + // Although we already have host, port and iface, we prefer TO PASS only 'pars' to the + // pcap_open_remote() so that it has to call the pcap_parsesrcstr() again. + // This is less optimized, but much clearer. + fp= pcap_opensource_remote(source, auth, errbuf); + + if (fp == NULL) + return NULL; + + fp->snapshot= snaplen; +#ifdef linux + fp->md.timeout= read_timeout; +#else + fp->timeout= read_timeout; +#endif + fp->rmt_flags= flags; + break; + + case PCAP_SRC_IFLOCAL: + + fp = pcap_open_live(name, snaplen, (flags & PCAP_OPENFLAG_PROMISCUOUS), read_timeout, errbuf); + +#ifdef WIN32 +// +// these flags are supported on Windows only +// + if (fp != NULL) + { + /* disable loopback capture if requested */ + if(flags & PCAP_OPENFLAG_NOCAPTURE_LOCAL) + { + if(!PacketSetLoopbackBehavior(fp->adapter, NPF_DISABLE_LOOPBACK)) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Unable to disable the capture of loopback packets."); + pcap_close(fp); + return NULL; + } + } + + /* set mintocopy to zero if requested */ + if(flags & PCAP_OPENFLAG_MAX_RESPONSIVENESS) + { + if(!PacketSetMinToCopy(fp->adapter, 0)) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Unable to set max responsiveness."); + pcap_close(fp); + return NULL; + } + } + } +#endif //WIN32 + + break; + + default: + strcpy(errbuf, "Source type not supported"); + return NULL; + } + return fp; +} + + +struct pcap_samp *pcap_setsampling(pcap_t *p) +{ + return &(p->rmt_samp); +} + + +SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf) +{ +// socket-related variables +struct addrinfo hints; // temporary struct to keep settings needed to open the new socket +struct addrinfo *addrinfo; // keeps the addrinfo chain; required to open a new socket +struct sockaddr_storage from; // generic sockaddr_storage variable +socklen_t fromlen; // keeps the length of the sockaddr_storage variable +SOCKET sockctrl; // keeps the main socket identifier +struct activehosts *temp, *prev; // temp var needed to scan he host list chain + + *connectinghost= 0; // just in case + + // Prepare to open a new server socket + memset(&hints, 0, sizeof(struct addrinfo)); + // WARNING Currently it supports only ONE socket family among ipv4 and IPv6 + hints.ai_family = AF_INET; // PF_UNSPEC to have both IPv4 and IPv6 server + hints.ai_flags = AI_PASSIVE; // Ready to a bind() socket + hints.ai_socktype = SOCK_STREAM; + + // Warning: this call can be the first one called by the user. + // For this reason, we have to initialize the WinSock support. + if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + + // Do the work + if ((port == NULL) || (port[0] == 0) ) + { + if (sock_initaddress(address, RPCAP_DEFAULT_NETPORT_ACTIVE, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1) + { + SOCK_ASSERT(errbuf, 1); + return -2; + } + } + else + { + if (sock_initaddress(address, port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1) + { + SOCK_ASSERT(errbuf, 1); + return -2; + } + } + + + if ( (sockmain= sock_open(addrinfo, SOCKOPEN_SERVER, 1, errbuf, PCAP_ERRBUF_SIZE)) == -1) + { + SOCK_ASSERT(errbuf, 1); + return -2; + } + + // Connection creation + fromlen = sizeof(struct sockaddr_storage); + + sockctrl= accept(sockmain, (struct sockaddr *) &from, &fromlen); + + // We're not using sock_close, since we do not want to send a shutdown + // (which is not allowed on a non-connected socket) + closesocket(sockmain); + sockmain= 0; + + if (sockctrl == -1) + { + sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE); + return -2; + } + + // Get the numeric for of the name of the connecting host + if (getnameinfo( (struct sockaddr *) &from, fromlen, connectinghost, RPCAP_HOSTLIST_SIZE, NULL, 0, NI_NUMERICHOST) ) + { + sock_geterror("getnameinfo(): ", errbuf, PCAP_ERRBUF_SIZE); + rpcap_senderror(sockctrl, errbuf, PCAP_ERR_REMOTEACCEPT, NULL); + sock_close(sockctrl, NULL, 0); + return -1; + } + + // checks if the connecting host is among the ones allowed + if (sock_check_hostlist((char *) hostlist, RPCAP_HOSTLIST_SEP, &from, errbuf, PCAP_ERRBUF_SIZE) < 0) + { + rpcap_senderror(sockctrl, errbuf, PCAP_ERR_REMOTEACCEPT, NULL); + sock_close(sockctrl, NULL, 0); + return -1; + } + + // Send authentication to the remote machine + if ( rpcap_sendauth(sockctrl, auth, errbuf) == -1) + { + rpcap_senderror(sockctrl, errbuf, PCAP_ERR_REMOTEACCEPT, NULL); + sock_close(sockctrl, NULL, 0); + return -3; + } + + // Checks that this host does not already have a cntrl connection in place + + // Initialize pointers + temp= activeHosts; + prev= NULL; + + while (temp) + { + // This host already has an active connection in place, so I don't have to update the host list + if (sock_cmpaddr(&temp->host, &from) == 0) + return sockctrl; + + prev= temp; + temp= temp->next; + } + + // The host does not exist in the list; so I have to update the list + if (prev) + { + prev->next= (struct activehosts *) malloc (sizeof (struct activehosts) ); + temp= prev->next; + } + else + { + activeHosts= (struct activehosts *) malloc (sizeof (struct activehosts) ); + temp= activeHosts; + } + + if (temp == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + rpcap_senderror(sockctrl, errbuf, PCAP_ERR_REMOTEACCEPT, NULL); + sock_close(sockctrl, NULL, 0); + return -1; + } + + memcpy(&temp->host, &from, fromlen); + temp->sockctrl= sockctrl; + temp->next= NULL; + + return sockctrl; +} + + +int pcap_remoteact_close(const char *host, char *errbuf) +{ +struct activehosts *temp, *prev; // temp var needed to scan the host list chain +struct addrinfo hints, *addrinfo, *ai_next; // temp var needed to translate between hostname to its address +int retval; + + temp= activeHosts; + prev= NULL; + + // retrieve the network address corresponding to 'host' + addrinfo = NULL; + memset(&hints, 0, sizeof (struct addrinfo) ); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype= SOCK_STREAM; + + retval = getaddrinfo(host, "0", &hints, &addrinfo); + if (retval != 0) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "getaddrinfo() %s", gai_strerror(retval)); + return -1; + } + + while (temp) + { + ai_next= addrinfo; + while(ai_next) + { + if (sock_cmpaddr(&temp->host, (struct sockaddr_storage *) ai_next->ai_addr ) == 0) + { + struct rpcap_header header; + + // Close this connection + rpcap_createhdr( &header, RPCAP_MSG_CLOSE, 0, 0); + + // I don't check for errors, since I'm going to close everything + sock_send(temp->sockctrl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE); + + if (sock_close(temp->sockctrl, errbuf, PCAP_ERRBUF_SIZE) ) + { + // To avoid inconsistencies in the number of sock_init() + sock_cleanup(); + + return -1; + } + + if (prev) + prev->next= temp->next; + else + activeHosts= temp->next; + + freeaddrinfo(addrinfo); + + free(temp); + + // To avoid inconsistencies in the number of sock_init() + sock_cleanup(); + + return 0; + } + + ai_next= ai_next->ai_next; + } + prev= temp; + temp= temp->next; + } + + if (addrinfo) + freeaddrinfo(addrinfo); + + // To avoid inconsistencies in the number of sock_init() + sock_cleanup(); + + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The host you want to close the active connection is not known"); + return -1; +} + + +void pcap_remoteact_cleanup() +{ + // Very dirty, but it works + if (sockmain) + { + closesocket(sockmain); + + // To avoid inconsistencies in the number of sock_init() + sock_cleanup(); + } + +} + + +int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf) +{ +struct activehosts *temp; // temp var needed to scan the host list chain +int len; +char hoststr[RPCAP_HOSTLIST_SIZE + 1]; + + temp= activeHosts; + + len= 0; + *hostlist= 0; + + while (temp) + { +//int sock_getascii_addrport(const struct sockaddr_storage *sockaddr, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen) + + // Get the numeric form of the name of the connecting host + if (sock_getascii_addrport( (struct sockaddr_storage *) &temp->host,hoststr, + RPCAP_HOSTLIST_SIZE, NULL, 0, NI_NUMERICHOST, errbuf, PCAP_ERRBUF_SIZE) != -1) +// if (getnameinfo( (struct sockaddr *) &temp->host, sizeof (struct sockaddr_storage), hoststr, +// RPCAP_HOSTLIST_SIZE, NULL, 0, NI_NUMERICHOST) ) + { +// sock_geterror("getnameinfo(): ", errbuf, PCAP_ERRBUF_SIZE); + return -1; + } + + len= len + strlen(hoststr) + 1 /* the separator */; + + if (len >= size) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The string you provided is not able to keep " + "the hostnames for all the active connections"); + return -1; + } + + strcat(hostlist, hoststr); + hostlist[len - 1]= sep; + hostlist[len]= 0; + + temp= temp->next; + } + + return 0; +} + diff --git a/winpcap/wpcap/libpcap/pcap-nit.c b/winpcap/wpcap/libpcap/pcap-nit.c new file mode 100644 index 0000000..94c4528 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-nit.c @@ -0,0 +1,356 @@ +/* + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.57.2.1 2005/05/03 18:54:37 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "pcap-int.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +/* + * The chunk size for NIT. This is the amount of buffering + * done for read calls. + */ +#define CHUNKSIZE (2*1024) + +/* + * The total buffer space used by NIT. + */ +#define BUFSPACE (4*CHUNKSIZE) + +/* Forwards */ +static int nit_setflags(int, int, int, char *); + +static int +pcap_stats_nit(pcap_t *p, struct pcap_stat *ps) +{ + + /* + * "ps_recv" counts packets handed to the filter, not packets + * that passed the filter. As filtering is done in userland, + * this does not include packets dropped because we ran out + * of buffer space. + * + * "ps_drop" presumably counts packets dropped by the socket + * because of flow control requirements or resource exhaustion; + * it doesn't count packets dropped by the interface driver. + * As filtering is done in userland, it counts packets regardless + * of whether they would've passed the filter. + * + * These statistics don't include packets not yet read from the + * kernel by libpcap or packets not yet read from libpcap by the + * application. + */ + *ps = p->md.stat; + return (0); +} + +static int +pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ + register int cc, n; + register struct bpf_insn *fcode = p->fcode.bf_insns; + register u_char *bp, *cp, *ep; + register struct nit_hdr *nh; + register int caplen; + + cc = p->cc; + if (cc == 0) { + cc = read(p->fd, (char *)p->buffer, p->bufsize); + if (cc < 0) { + if (errno == EWOULDBLOCK) + return (0); + snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s", + pcap_strerror(errno)); + return (-1); + } + bp = p->buffer; + } else + bp = p->bp; + + /* + * Loop through each packet. The increment expression + * rounds up to the next int boundary past the end of + * the previous packet. + */ + n = 0; + ep = bp + cc; + while (bp < ep) { + /* + * Has "pcap_breakloop()" been called? + * If so, return immediately - if we haven't read any + * packets, clear the flag and return -2 to indicate + * that we were told to break out of the loop, otherwise + * leave the flag set, so that the *next* call will break + * out of the loop without having read any packets, and + * return the number of packets we've processed so far. + */ + if (p->break_loop) { + if (n == 0) { + p->break_loop = 0; + return (-2); + } else { + p->cc = ep - bp; + p->bp = bp; + return (n); + } + } + + nh = (struct nit_hdr *)bp; + cp = bp + sizeof(*nh); + + switch (nh->nh_state) { + + case NIT_CATCH: + break; + + case NIT_NOMBUF: + case NIT_NOCLUSTER: + case NIT_NOSPACE: + p->md.stat.ps_drop = nh->nh_dropped; + continue; + + case NIT_SEQNO: + continue; + + default: + snprintf(p->errbuf, sizeof(p->errbuf), + "bad nit state %d", nh->nh_state); + return (-1); + } + ++p->md.stat.ps_recv; + bp += ((sizeof(struct nit_hdr) + nh->nh_datalen + + sizeof(int) - 1) & ~(sizeof(int) - 1)); + + caplen = nh->nh_wirelen; + if (caplen > p->snapshot) + caplen = p->snapshot; + if (bpf_filter(fcode, cp, nh->nh_wirelen, caplen)) { + struct pcap_pkthdr h; + h.ts = nh->nh_timestamp; + h.len = nh->nh_wirelen; + h.caplen = caplen; + (*callback)(user, &h, cp); + if (++n >= cnt && cnt >= 0) { + p->cc = ep - bp; + p->bp = bp; + return (n); + } + } + } + p->cc = 0; + return (n); +} + +static int +pcap_inject_nit(pcap_t *p, const void *buf, size_t size) +{ + struct sockaddr sa; + int ret; + + memset(&sa, 0, sizeof(sa)); + strncpy(sa.sa_data, device, sizeof(sa.sa_data)); + ret = sendto(p->fd, buf, size, 0, &sa, sizeof(sa)); + if (ret == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", + pcap_strerror(errno)); + return (-1); + } + return (ret); +} + +static int +nit_setflags(int fd, int promisc, int to_ms, char *ebuf) +{ + struct nit_ioc nioc; + + memset(&nioc, 0, sizeof(nioc)); + nioc.nioc_bufspace = BUFSPACE; + nioc.nioc_chunksize = CHUNKSIZE; + nioc.nioc_typetomatch = NT_ALLTYPES; + nioc.nioc_snaplen = p->snapshot; + nioc.nioc_bufalign = sizeof(int); + nioc.nioc_bufoffset = 0; + + if (to_ms != 0) { + nioc.nioc_flags |= NF_TIMEOUT; + nioc.nioc_timeout.tv_sec = to_ms / 1000; + nioc.nioc_timeout.tv_usec = (to_ms * 1000) % 1000000; + } + if (promisc) + nioc.nioc_flags |= NF_PROMISC; + + if (ioctl(fd, SIOCSNIT, &nioc) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNIT: %s", + pcap_strerror(errno)); + return (-1); + } + return (0); +} + +static void +pcap_close_nit(pcap_t *p) +{ + pcap_close_common(p); + if (p->device != NULL) + free(p->device); +} + +pcap_t * +pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, + char *ebuf) +{ + int fd; + struct sockaddr_nit snit; + register pcap_t *p; + + p = (pcap_t *)malloc(sizeof(*p)); + if (p == NULL) { + strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); + return (NULL); + } + + if (snaplen < 96) + /* + * NIT requires a snapshot length of at least 96. + */ + snaplen = 96; + + memset(p, 0, sizeof(*p)); + p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW); + if (fd < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "socket: %s", pcap_strerror(errno)); + goto bad; + } + snit.snit_family = AF_NIT; + (void)strncpy(snit.snit_ifname, device, NITIFSIZ); + + if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "bind: %s: %s", snit.snit_ifname, pcap_strerror(errno)); + goto bad; + } + p->snapshot = snaplen; + nit_setflags(p->fd, promisc, to_ms, ebuf); + + /* + * NIT supports only ethernets. + */ + p->linktype = DLT_EN10MB; + + p->bufsize = BUFSPACE; + p->buffer = (u_char *)malloc(p->bufsize); + if (p->buffer == NULL) { + strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); + goto bad; + } + + /* + * We need the device name in order to send packets. + */ + p->device = strdup(device); + if (p->device == NULL) { + strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); + free(p->buffer); + goto bad; + } + + /* + * "p->fd" is a socket, so "select()" should work on it. + */ + p->selectable_fd = p->fd; + + /* + * This is (presumably) a real Ethernet capture; give it a + * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so + * that an application can let you choose it, in case you're + * capturing DOCSIS traffic that a Cisco Cable Modem + * Termination System is putting out onto an Ethernet (it + * doesn't put an Ethernet header onto the wire, it puts raw + * DOCSIS frames out on the wire inside the low-level + * Ethernet framing). + */ + p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); + /* + * If that fails, just leave the list empty. + */ + if (p->dlt_list != NULL) { + p->dlt_list[0] = DLT_EN10MB; + p->dlt_list[1] = DLT_DOCSIS; + p->dlt_count = 2; + } + + p->read_op = pcap_read_nit; + p->inject_op = pcap_inject_nit; + p->setfilter_op = install_bpf_program; /* no kernel filtering */ + p->setdirection_op = NULL; /* Not implemented. */ + p->set_datalink_op = NULL; /* can't change data link type */ + p->getnonblock_op = pcap_getnonblock_fd; + p->setnonblock_op = pcap_setnonblock_fd; + p->stats_op = pcap_stats_nit; + p->close_op = pcap_close_nit; + + return (p); + bad: + if (fd >= 0) + close(fd); + free(p); + return (NULL); +} + +int +pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) +{ + return (0); +} diff --git a/winpcap/wpcap/libpcap/pcap-nit.h b/winpcap/wpcap/libpcap/pcap-nit.h new file mode 100644 index 0000000..52f5fc4 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-nit.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 1990, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Lawrence Berkeley Laboratory, + * Berkeley, CA. The name of the University may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/pcap-nit.h,v 1.2.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL) + */ diff --git a/winpcap/wpcap/libpcap/pcap-null.c b/winpcap/wpcap/libpcap/pcap-null.c new file mode 100644 index 0000000..06e3ab3 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-null.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.21 2003/11/15 23:24:03 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* optionally get BSD define */ + +#include + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#include "pcap-int.h" + +static char nosup[] = "live packet capture not supported on this system"; + +pcap_t * +pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, + char *ebuf) +{ + (void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE); + return (NULL); +} + +int +pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) +{ + return (0); +} diff --git a/winpcap/wpcap/libpcap/pcap-pf.c b/winpcap/wpcap/libpcap/pcap-pf.c new file mode 100644 index 0000000..e733540 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-pf.c @@ -0,0 +1,610 @@ +/* + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * packet filter subroutines for tcpdump + * Extraction/creation by Jeffrey Mogul, DECWRL + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.91.2.2 2005/05/03 18:54:37 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +struct mbuf; +struct rtentry; +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * Make "pcap.h" not include "pcap-bpf.h"; we are going to include the + * native OS version, as we need various BPF ioctls from it. + */ +#define PCAP_DONT_INCLUDE_PCAP_BPF_H +#include + +#include "pcap-int.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +static int pcap_setfilter_pf(pcap_t *, struct bpf_program *); + +/* + * BUFSPACE is the size in bytes of the packet read buffer. Most tcpdump + * applications aren't going to need more than 200 bytes of packet header + * and the read shouldn't return more packets than packetfilter's internal + * queue limit (bounded at 256). + */ +#define BUFSPACE (200 * 256) + +static int +pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user) +{ + register u_char *p, *bp; + struct bpf_insn *fcode; + register int cc, n, buflen, inc; + register struct enstamp *sp; +#ifdef LBL_ALIGN + struct enstamp stamp; +#endif +#ifdef PCAP_FDDIPAD + register int pad; +#endif + + fcode = pc->md.use_bpf ? NULL : pc->fcode.bf_insns; + again: + cc = pc->cc; + if (cc == 0) { + cc = read(pc->fd, (char *)pc->buffer + pc->offset, pc->bufsize); + if (cc < 0) { + if (errno == EWOULDBLOCK) + return (0); + if (errno == EINVAL && + lseek(pc->fd, 0L, SEEK_CUR) + pc->bufsize < 0) { + /* + * Due to a kernel bug, after 2^31 bytes, + * the kernel file offset overflows and + * read fails with EINVAL. The lseek() + * to 0 will fix things. + */ + (void)lseek(pc->fd, 0L, SEEK_SET); + goto again; + } + snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s", + pcap_strerror(errno)); + return (-1); + } + bp = pc->buffer + pc->offset; + } else + bp = pc->bp; + /* + * Loop through each packet. + */ + n = 0; +#ifdef PCAP_FDDIPAD + pad = pc->fddipad; +#endif + while (cc > 0) { + /* + * Has "pcap_breakloop()" been called? + * If so, return immediately - if we haven't read any + * packets, clear the flag and return -2 to indicate + * that we were told to break out of the loop, otherwise + * leave the flag set, so that the *next* call will break + * out of the loop without having read any packets, and + * return the number of packets we've processed so far. + */ + if (pc->break_loop) { + if (n == 0) { + pc->break_loop = 0; + return (-2); + } else { + pc->cc = cc; + pc->bp = bp; + return (n); + } + } + if (cc < sizeof(*sp)) { + snprintf(pc->errbuf, sizeof(pc->errbuf), + "pf short read (%d)", cc); + return (-1); + } +#ifdef LBL_ALIGN + if ((long)bp & 3) { + sp = &stamp; + memcpy((char *)sp, (char *)bp, sizeof(*sp)); + } else +#endif + sp = (struct enstamp *)bp; + if (sp->ens_stamplen != sizeof(*sp)) { + snprintf(pc->errbuf, sizeof(pc->errbuf), + "pf short stamplen (%d)", + sp->ens_stamplen); + return (-1); + } + + p = bp + sp->ens_stamplen; + buflen = sp->ens_count; + if (buflen > pc->snapshot) + buflen = pc->snapshot; + + /* Calculate inc before possible pad update */ + inc = ENALIGN(buflen + sp->ens_stamplen); + cc -= inc; + bp += inc; + pc->md.TotPkts++; + pc->md.TotDrops += sp->ens_dropped; + pc->md.TotMissed = sp->ens_ifoverflows; + if (pc->md.OrigMissed < 0) + pc->md.OrigMissed = pc->md.TotMissed; + + /* + * Short-circuit evaluation: if using BPF filter + * in kernel, no need to do it now. + * +#ifdef PCAP_FDDIPAD + * Note: the filter code was generated assuming + * that pc->fddipad was the amount of padding + * before the header, as that's what's required + * in the kernel, so we run the filter before + * skipping that padding. +#endif + */ + if (fcode == NULL || + bpf_filter(fcode, p, sp->ens_count, buflen)) { + struct pcap_pkthdr h; + pc->md.TotAccepted++; + h.ts = sp->ens_tstamp; +#ifdef PCAP_FDDIPAD + h.len = sp->ens_count - pad; +#else + h.len = sp->ens_count; +#endif +#ifdef PCAP_FDDIPAD + p += pad; + buflen -= pad; +#endif + h.caplen = buflen; + (*callback)(user, &h, p); + if (++n >= cnt && cnt > 0) { + pc->cc = cc; + pc->bp = bp; + return (n); + } + } + } + pc->cc = 0; + return (n); +} + +static int +pcap_inject_pf(pcap_t *p, const void *buf, size_t size) +{ + int ret; + + ret = write(p->fd, buf, size); + if (ret == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", + pcap_strerror(errno)); + return (-1); + } + return (ret); +} + +static int +pcap_stats_pf(pcap_t *p, struct pcap_stat *ps) +{ + + /* + * If packet filtering is being done in the kernel: + * + * "ps_recv" counts only packets that passed the filter. + * This does not include packets dropped because we + * ran out of buffer space. (XXX - perhaps it should, + * by adding "ps_drop" to "ps_recv", for compatibility + * with some other platforms. On the other hand, on + * some platforms "ps_recv" counts only packets that + * passed the filter, and on others it counts packets + * that didn't pass the filter....) + * + * "ps_drop" counts packets that passed the kernel filter + * (if any) but were dropped because the input queue was + * full. + * + * "ps_ifdrop" counts packets dropped by the network + * inteface (regardless of whether they would have passed + * the input filter, of course). + * + * If packet filtering is not being done in the kernel: + * + * "ps_recv" counts only packets that passed the filter. + * + * "ps_drop" counts packets that were dropped because the + * input queue was full, regardless of whether they passed + * the userland filter. + * + * "ps_ifdrop" counts packets dropped by the network + * inteface (regardless of whether they would have passed + * the input filter, of course). + * + * These statistics don't include packets not yet read from + * the kernel by libpcap, but they may include packets not + * yet read from libpcap by the application. + */ + ps->ps_recv = p->md.TotAccepted; + ps->ps_drop = p->md.TotDrops; + ps->ps_ifdrop = p->md.TotMissed - p->md.OrigMissed; + return (0); +} + +/* + * We include the OS's , not our "pcap-bpf.h", so we probably + * don't get DLT_DOCSIS defined. + */ +#ifndef DLT_DOCSIS +#define DLT_DOCSIS 143 +#endif + +pcap_t * +pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, + char *ebuf) +{ + pcap_t *p; + short enmode; + int backlog = -1; /* request the most */ + struct enfilter Filter; + struct endevp devparams; + + p = (pcap_t *)malloc(sizeof(*p)); + if (p == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "pcap_open_live: %s", pcap_strerror(errno)); + return (0); + } + memset(p, 0, sizeof(*p)); + /* + * Initially try a read/write open (to allow the inject + * method to work). If that fails due to permission + * issues, fall back to read-only. This allows a + * non-root user to be granted specific access to pcap + * capabilities via file permissions. + * + * XXX - we should have an API that has a flag that + * controls whether to open read-only or read-write, + * so that denial of permission to send (or inability + * to send, if sending packets isn't supported on + * the device in question) can be indicated at open + * time. + * + * XXX - we assume here that "pfopen()" does not, in fact, modify + * its argument, even though it takes a "char *" rather than a + * "const char *" as its first argument. That appears to be + * the case, at least on Digital UNIX 4.0. + */ + p->fd = pfopen(device, O_RDWR); + if (p->fd == -1 && errno == EACCES) + p->fd = pfopen(device, O_RDONLY); + if (p->fd < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\ +your system may not be properly configured; see the packetfilter(4) man page\n", + device, pcap_strerror(errno)); + goto bad; + } + p->md.OrigMissed = -1; + enmode = ENTSTAMP|ENBATCH|ENNONEXCL; + if (promisc) + enmode |= ENPROMISC; + if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s", + pcap_strerror(errno)); + goto bad; + } +#ifdef ENCOPYALL + /* Try to set COPYALL mode so that we see packets to ourself */ + enmode = ENCOPYALL; + (void)ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode);/* OK if this fails */ +#endif + /* set the backlog */ + if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s", + pcap_strerror(errno)); + goto bad; + } + /* discover interface type */ + if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s", + pcap_strerror(errno)); + goto bad; + } + /* HACK: to compile prior to Ultrix 4.2 */ +#ifndef ENDT_FDDI +#define ENDT_FDDI 4 +#endif + switch (devparams.end_dev_type) { + + case ENDT_10MB: + p->linktype = DLT_EN10MB; + p->offset = 2; + /* + * This is (presumably) a real Ethernet capture; give it a + * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so + * that an application can let you choose it, in case you're + * capturing DOCSIS traffic that a Cisco Cable Modem + * Termination System is putting out onto an Ethernet (it + * doesn't put an Ethernet header onto the wire, it puts raw + * DOCSIS frames out on the wire inside the low-level + * Ethernet framing). + */ + p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); + /* + * If that fails, just leave the list empty. + */ + if (p->dlt_list != NULL) { + p->dlt_list[0] = DLT_EN10MB; + p->dlt_list[1] = DLT_DOCSIS; + p->dlt_count = 2; + } + break; + + case ENDT_FDDI: + p->linktype = DLT_FDDI; + break; + +#ifdef ENDT_SLIP + case ENDT_SLIP: + p->linktype = DLT_SLIP; + break; +#endif + +#ifdef ENDT_PPP + case ENDT_PPP: + p->linktype = DLT_PPP; + break; +#endif + +#ifdef ENDT_LOOPBACK + case ENDT_LOOPBACK: + /* + * It appears to use Ethernet framing, at least on + * Digital UNIX 4.0. + */ + p->linktype = DLT_EN10MB; + p->offset = 2; + break; +#endif + +#ifdef ENDT_TRN + case ENDT_TRN: + p->linktype = DLT_IEEE802; + break; +#endif + + default: + /* + * XXX - what about ENDT_IEEE802? The pfilt.h header + * file calls this "IEEE 802 networks (non-Ethernet)", + * but that doesn't specify a specific link layer type; + * it could be 802.4, or 802.5 (except that 802.5 is + * ENDT_TRN), or 802.6, or 802.11, or.... That's why + * DLT_IEEE802 was hijacked to mean Token Ring in various + * BSDs, and why we went along with that hijacking. + * + * XXX - what about ENDT_HDLC and ENDT_NULL? + * Presumably, as ENDT_OTHER is just "Miscellaneous + * framing", there's not much we can do, as that + * doesn't specify a particular type of header. + */ + snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown data-link type %u", + devparams.end_dev_type); + goto bad; + } + /* set truncation */ +#ifdef PCAP_FDDIPAD + if (p->linktype == DLT_FDDI) { + p->fddipad = PCAP_FDDIPAD; + + /* packetfilter includes the padding in the snapshot */ + snaplen += PCAP_FDDIPAD; + } else + p->fddipad = 0; +#endif + if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&snaplen) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s", + pcap_strerror(errno)); + goto bad; + } + p->snapshot = snaplen; + /* accept all packets */ + memset(&Filter, 0, sizeof(Filter)); + Filter.enf_Priority = 37; /* anything > 2 */ + Filter.enf_FilterLen = 0; /* means "always true" */ + if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s", + pcap_strerror(errno)); + goto bad; + } + + if (to_ms != 0) { + struct timeval timeout; + timeout.tv_sec = to_ms / 1000; + timeout.tv_usec = (to_ms * 1000) % 1000000; + if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s", + pcap_strerror(errno)); + goto bad; + } + } + + p->bufsize = BUFSPACE; + p->buffer = (u_char*)malloc(p->bufsize + p->offset); + if (p->buffer == NULL) { + strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); + goto bad; + } + + /* + * "select()" and "poll()" work on packetfilter devices. + */ + p->selectable_fd = p->fd; + + p->read_op = pcap_read_pf; + p->inject_op = pcap_inject_pf; + p->setfilter_op = pcap_setfilter_pf; + p->setdirection_op = NULL; /* Not implemented. */ + p->set_datalink_op = NULL; /* can't change data link type */ + p->getnonblock_op = pcap_getnonblock_fd; + p->setnonblock_op = pcap_setnonblock_fd; + p->stats_op = pcap_stats_pf; + p->close_op = pcap_close_common; + + return (p); + bad: + if (p->fd >= 0) + close(p->fd); + /* + * Get rid of any link-layer type list we allocated. + */ + if (p->dlt_list != NULL) + free(p->dlt_list); + free(p); + return (NULL); +} + +int +pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) +{ + return (0); +} + +static int +pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp) +{ + struct bpf_version bv; + + /* + * See if BIOCVERSION works. If not, we assume the kernel doesn't + * support BPF-style filters (it's not documented in the bpf(7) + * or packetfiler(7) man pages, but the code used to fail if + * BIOCSETF worked but BIOCVERSION didn't, and I've seen it do + * kernel filtering in DU 4.0, so presumably BIOCVERSION works + * there, at least). + */ + if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) >= 0) { + /* + * OK, we have the version of the BPF interpreter; + * is it the same major version as us, and the same + * or better minor version? + */ + if (bv.bv_major == BPF_MAJOR_VERSION && + bv.bv_minor >= BPF_MINOR_VERSION) { + /* + * Yes. Try to install the filter. + */ + if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) { + snprintf(p->errbuf, sizeof(p->errbuf), + "BIOCSETF: %s", pcap_strerror(errno)); + return (-1); + } + + /* + * OK, that succeeded. We're doing filtering in + * the kernel. (We assume we don't have a + * userland filter installed - that'd require + * a previous version check to have failed but + * this one to succeed.) + * + * XXX - this message should be supplied to the + * application as a warning of some sort, + * except that if it's a GUI application, it's + * not clear that it should be displayed in + * a window to annoy the user. + */ + fprintf(stderr, "tcpdump: Using kernel BPF filter\n"); + p->md.use_bpf = 1; + + /* + * Discard any previously-received packets, + * as they might have passed whatever filter + * was formerly in effect, but might not pass + * this filter (BIOCSETF discards packets buffered + * in the kernel, so you can lose packets in any + * case). + */ + p->cc = 0; + return (0); + } + + /* + * We can't use the kernel's BPF interpreter; don't give + * up, just log a message and be inefficient. + * + * XXX - this should really be supplied to the application + * as a warning of some sort. + */ + fprintf(stderr, + "tcpdump: Requires BPF language %d.%d or higher; kernel is %d.%d\n", + BPF_MAJOR_VERSION, BPF_MINOR_VERSION, + bv.bv_major, bv.bv_minor); + } + + /* + * We couldn't do filtering in the kernel; do it in userland. + */ + if (install_bpf_program(p, fp) < 0) + return (-1); + + /* + * XXX - this message should be supplied by the application as + * a warning of some sort. + */ + fprintf(stderr, "tcpdump: Filtering in user process\n"); + p->md.use_bpf = 0; + return (0); +} diff --git a/winpcap/wpcap/libpcap/pcap-pf.h b/winpcap/wpcap/libpcap/pcap-pf.h new file mode 100644 index 0000000..60bea83 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-pf.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 1990, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Lawrence Berkeley Laboratory, + * Berkeley, CA. The name of the University may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/libpcap/pcap-pf.h,v 1.2.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL) + */ diff --git a/winpcap/wpcap/libpcap/pcap-remote.c b/winpcap/wpcap/libpcap/pcap-remote.c new file mode 100644 index 0000000..4f1d357 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-remote.c @@ -0,0 +1,2109 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include // for strlen(), ... +#include // for malloc(), free(), ... +#include // for functions with variable number of arguments +#include // for the errno variable +#include +#include +#include +#include + + +/*! + \file pcap-remote.c + + This file keeps all the new funtions that are needed for the RPCAP protocol. + Almost all the pcap functions need to be modified in order to become compatible + with the RPCAP protocol. However, you can find here only the ones that are completely new. + + This file keeps also the functions that are 'private', i.e. are needed by the RPCAP + protocol but are not exported to the user. + + \warning All the RPCAP functions that are allowed to return a buffer containing + the error description can return max PCAP_ERRBUF_SIZE characters. + However there is no guarantees that the string will be zero-terminated. + Best practice is to define the errbuf variable as a char of size 'PCAP_ERRBUF_SIZE+1' + and to insert manually a NULL character at the end of the buffer. This will + guarantee that no buffer overflows occur even if we use the printf() to show + the error on the screen. +*/ + + + +#define PCAP_STATS_STANDARD 0 /*!< Used by pcap_stats_remote to see if we want standard or extended statistics */ +#define PCAP_STATS_EX 1 /*!< Used by pcap_stats_remote to see if we want standard or extended statistics */ + + + +//! Keeps a list of all the opened connections in the active mode. +struct activehosts *activeHosts; + + +/**************************************************** + * * + * Locally defined functions * + * * + ****************************************************/ +int rpcap_checkver(SOCKET sock, struct rpcap_header *header, char *errbuf); +struct pcap_stat *rpcap_stats_remote(pcap_t *p, struct pcap_stat *ps, int mode); +int pcap_pack_bpffilter(pcap_t *fp, char *sendbuf, int *sendbufidx, struct bpf_program *prog); +int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog); + + + + +/**************************************************** + * * + * Function bodies * + * * + ****************************************************/ + +/*! + \ingroup remote_pri_func + + \brief It traslates (i.e. de-serializes) a 'sockaddr_storage' structure from + the network byte order to the host byte order. + + It accepts a 'sockaddr_storage' structure as it is received from the network and it + converts it into the host byte order (by means of a set of ntoh() ). + The function will allocate the 'sockaddrout' variable according to the address family + in use. In case the address does not belong to the AF_INET nor AF_INET6 families, + 'sockaddrout' is not allocated and a NULL pointer is returned. + This usually happens because that address does not exist on the other host, so the + RPCAP daemon sent a 'sockaddr_storage' structure containing all 'zero' values. + + \param sockaddrin: a 'sockaddr_storage' pointer to the variable that has to be + de-serialized. + + \param sockaddrout: a 'sockaddr_storage' pointer to the variable that will contain + the de-serialized data. The structure returned can be either a 'sockaddr_in' or 'sockaddr_in6'. + This variable will be allocated automatically inside this function. + + \param errbuf: a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) + that will contain the error message (in case there is one). + + \return '0' if everything is fine, '-1' if some errors occurred. Basically, the error + can be only the fact that the malloc() failed to allocate memory. + The error message is returned in the 'errbuf' variable, while the deserialized address + is returned into the 'sockaddrout' variable. + + \warning This function supports only AF_INET and AF_INET6 address families. + + \warning The sockaddrout (if not NULL) must be deallocated by the user. +*/ +int rpcap_deseraddr(struct sockaddr_storage *sockaddrin, struct sockaddr_storage **sockaddrout, char *errbuf) +{ + // Warning: we support only AF_INET and AF_INET6 + if ( ntohs(sockaddrin->ss_family) == AF_INET) + { + struct sockaddr_in *sockaddr; + + sockaddr= (struct sockaddr_in *) sockaddrin; + sockaddr->sin_family= ntohs(sockaddr->sin_family); + sockaddr->sin_port= ntohs(sockaddr->sin_port); + + (*sockaddrout)= (struct sockaddr_storage *) malloc ( sizeof(struct sockaddr_in) ); + if ( (*sockaddrout) == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + return -1; + } + memcpy( *sockaddrout, sockaddr, sizeof(struct sockaddr_in) ); + return 0; + } + if ( ntohs(sockaddrin->ss_family) == AF_INET6) + { + struct sockaddr_in6 *sockaddr; + + sockaddr= (struct sockaddr_in6 *) sockaddrin; + sockaddr->sin6_family= ntohs(sockaddr->sin6_family); + sockaddr->sin6_port= ntohs(sockaddr->sin6_port); + sockaddr->sin6_flowinfo= ntohl(sockaddr->sin6_flowinfo); + sockaddr->sin6_scope_id= ntohl(sockaddr->sin6_scope_id); + + (*sockaddrout)= (struct sockaddr_storage *) malloc ( sizeof(struct sockaddr_in6) ); + if ( (*sockaddrout) == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + return -1; + } + memcpy( *sockaddrout, sockaddr, sizeof(struct sockaddr_in6) ); + return 0; + } + + // It is neither AF_INET nor AF_INET6 + *sockaddrout= NULL; + return 0; +} + + + +/*! \ingroup remote_pri_func + + \brief It reads a packet from the network socket. This does not make use of + callback (hence the "nocb" string into its name). + + This function is called by the several pcap_next_ex() when they detect that + we have a remote capture and they are the client side. In that case, they need + to read packets from the socket. + + Parameters and return values are exactly the same of the pcap_next_ex(). + + \warning By choice, this function does not make use of semaphores. A smarter + implementation should put a semaphore into the data thread, and a signal will + be raised as soon as there is data into the socket buffer. + However this is complicated and it does not bring any advantages when reading + from the network, in which network delays can be much more important than + these optimizations. Therefore, we chose the following approach: + - the 'timeout' chosen by the user is split in two (half on the server side, + with the usual meaning, and half on the client side) + - this function checks for packets; if there are no packets, it waits for + timeout/2 and then it checks again. If packets are still missing, it returns, + otherwise it reads packets. +*/ +int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data) +{ +struct rpcap_header *header; // general header according to the RPCAP format +struct rpcap_pkthdr *net_pkt_header; // header of the packet +char netbuf[RPCAP_NETBUF_SIZE]; // size of the network buffer in which the packet is copied, just for UDP +unsigned int nread; // number of bytes (of payload) currently read from the network (referred to the current pkt) +int retval; // generic return value + +// Structures needed for the select() call +fd_set rfds; // set of socket descriptors we have to check +struct timeval tv; // maximum time the select() can block waiting for data + + + // Define the read timeout, to be used in the select() + // 'timeout', in pcap_t, is in milliseconds; we have to convert it into sec and microsec +#ifdef linux + tv.tv_sec = p->md.timeout/1000; + tv.tv_usec = (p->md.timeout - tv.tv_sec * 1000 )* 1000; +#else + tv.tv_sec = p->timeout/1000; + tv.tv_usec = (p->timeout - tv.tv_sec * 1000 )* 1000; +#endif + + // Watch out sockdata to see if it has input + FD_ZERO(&rfds); + + // 'fp->rmt_sockdata' has always to be set before calling the select(), + // since it is cleared by the select() + FD_SET(p->rmt_sockdata, &rfds); + + retval = select(p->rmt_sockdata + 1, &rfds, NULL, NULL, &tv); + if (retval == -1) + { + sock_geterror("select(): ", p->errbuf, PCAP_ERRBUF_SIZE); + return -1; + } + + // There is no data waiting, so return '0' + if (retval == 0) + return 0; + + // data is here; so, let's copy it into the user buffer + // I'm going to read a new packet; so I reset the number of bytes (payload only) read + nread= 0; + + // We have to define 'header' as a pointer to a larger buffer, + // because in case of UDP we have to read all the message within a single call + header= (struct rpcap_header *) netbuf; + net_pkt_header= (struct rpcap_pkthdr *) (netbuf + sizeof(struct rpcap_header) ); + + if (p->rmt_flags & PCAP_OPENFLAG_DATATX_UDP) + { + // Read the entire message from the network + if (sock_recv(p->rmt_sockdata, netbuf, RPCAP_NETBUF_SIZE, SOCK_RECEIVEALL_NO, p->errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + } + else + { + if (sock_recv(p->rmt_sockdata, netbuf, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, p->errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + } + + // Checks if the message is correct + retval= rpcap_checkmsg(p->errbuf, p->rmt_sockdata, header, RPCAP_MSG_PACKET, 0); + + if (retval != RPCAP_MSG_PACKET) // the message is not the one expected + { + switch (retval) + { + case -3: // Unrecoverable network error + return -1; // Do nothing; just exit from here; the error code is already into the errbuf + + case -2: // The other endpoint sent a message that is not allowed here + case -1: // The other endpoint has a version number that is not compatible with our + return 0; // Return 'no packets received' + + default: + { + SOCK_ASSERT("Internal error", 1); + return 0; // Return 'no packets received + }; + } + } + + // In case of TCP, read the remaining of the packet from the socket + if ( !(p->rmt_flags & PCAP_OPENFLAG_DATATX_UDP)) + { + // Read the RPCAP packet header from the network + if ( (nread= sock_recv(p->rmt_sockdata, (char *) net_pkt_header, + sizeof(struct rpcap_pkthdr), SOCK_RECEIVEALL_YES, p->errbuf, PCAP_ERRBUF_SIZE)) == -1) + return -1; + } + + if ( (ntohl(net_pkt_header->caplen) + sizeof(struct pcap_pkthdr) ) <= ( (unsigned) p->bufsize) ) + { + // Initialize returned structures + *pkt_header= (struct pcap_pkthdr *) p->buffer; + *pkt_data= p->buffer + sizeof(struct pcap_pkthdr); + + (*pkt_header)->caplen= ntohl(net_pkt_header->caplen); + (*pkt_header)->len= ntohl(net_pkt_header->len); + (*pkt_header)->ts.tv_sec= ntohl(net_pkt_header->timestamp_sec); + (*pkt_header)->ts.tv_usec= ntohl(net_pkt_header->timestamp_usec); + + // I don't update the counter of the packets dropped by the network since we're using TCP; + // therefore no packets are dropped. Just update the number of packets received correctly + p->md.TotCapt++; + + // Copies the packet into the data buffer + if (p->rmt_flags & PCAP_OPENFLAG_DATATX_UDP) + { + unsigned int npkt; + + // In case of UDP the packet has already been read; we have to copy it into 'buffer' + // Another option should bne to declare 'netbuf' as 'static'; however this prevents + // using several pcap instances within the same process (because the static buffer is shared among + // all processes) + memcpy(*pkt_data, netbuf + sizeof(struct rpcap_header) + sizeof(struct rpcap_pkthdr), (*pkt_header)->caplen); + + // We're using UDP, so we need to update the counter of the packets dropped by the network + npkt= ntohl(net_pkt_header->npkt); + + if (p->md.TotCapt != npkt) + { + p->md.TotNetDrops+= (npkt - p->md.TotCapt); + p->md.TotCapt= npkt; + } + + } + else + { + // In case of TCP, read the remaining of the packet from the socket + if ( (nread+= sock_recv(p->rmt_sockdata, *pkt_data, (*pkt_header)->caplen, SOCK_RECEIVEALL_YES, p->errbuf, PCAP_ERRBUF_SIZE)) == -1) + return -1; + + // Checks if all the data has been read; if not, discard the data in excess + // This check has to be done only on TCP connections + if (nread != ntohl(header->plen)) + sock_discard(p->rmt_sockdata, ntohl(header->plen) - nread, NULL, 0); + } + + + // Packet read successfully + return 1; + } + else + { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Received a packet that is larger than the internal buffer size."); + return -1; + } + +} + + +/*! \ingroup remote_pri_func + + \brief It reads a packet from the network socket. + + This function is called by the several pcap_read() when they detect that + we have a remote capture and they are the client side. In that case, they need + to read packets from the socket. + + This function relies on the pcap_read_nocb_remote to deliver packets. The + difference, here, is that as soon as a packet is read, it is delivered + to the application by means of a callback function. + + Parameters and return values are exactly the same of the pcap_read(). +*/ +int pcap_read_remote(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ +struct pcap_pkthdr *pkt_header; +u_char *pkt_data; +int n = 0; + + while ( (n < cnt) || (cnt < 0) ) + { + if (pcap_read_nocb_remote(p, &pkt_header, &pkt_data) == 1) + { + (*callback)(user, pkt_header, pkt_data); + n++; + } + else + return n; + } + return n; +} + + +/*! \ingroup remote_pri_func + + \brief It sends a CLOSE command to the capture server. + + This function is called when the user wants to close a pcap_t adapter. + In case we're capturing from the network, it sends a command to the other + peer that says 'ok, let's stop capturing'. + This function is called automatically when the user calls the pcap_close(). + + Parameters and return values are exactly the same of the pcap_close(). + + \warning Since we're closing the connection, we do not check for errors. +*/ +void pcap_close_remote(pcap_t *fp) +{ +struct rpcap_header header; // header of the RPCAP packet +struct activehosts *temp; // temp var needed to scan the host list chain, to detect if we're in active mode +int active= 0; // active mode or not? + + // detect if we're in active mode + temp= activeHosts; + while (temp) + { + if (temp->sockctrl == fp->rmt_sockctrl) + { + active= 1; + break; + } + temp= temp->next; + } + + if (!active) + { + rpcap_createhdr( &header, RPCAP_MSG_CLOSE, 0, 0); + + // I don't check for errors, since I'm going to close everything + sock_send(fp->rmt_sockctrl, (char *) &header, sizeof (struct rpcap_header), NULL, 0); + } + else + { + rpcap_createhdr( &header, RPCAP_MSG_ENDCAP_REQ, 0, 0); + + // I don't check for errors, since I'm going to close everything + sock_send(fp->rmt_sockctrl, (char *) &header, sizeof (struct rpcap_header), NULL, 0); + + // wait for the answer + // Don't check what we got, since the present libpcap does not uses this pcap_t anymore + sock_recv(fp->rmt_sockctrl, (char *) &header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, NULL, 0); + + if ( ntohl(header.plen) != 0) + sock_discard(fp->rmt_sockctrl, ntohl(header.plen), NULL, 0); + } + + if (fp->rmt_sockdata) + { + sock_close(fp->rmt_sockdata, NULL, 0); + fp->rmt_sockdata= 0; + } + + if ( (!active) && (fp->rmt_sockctrl) ) + sock_close(fp->rmt_sockctrl, NULL, 0); + + fp->rmt_sockctrl= 0; + + if (fp->currentfilter) + { + free(fp->currentfilter); + fp->currentfilter= NULL; + } + + // To avoid inconsistencies in the number of sock_init() + sock_cleanup(); +} + + + +/*! \ingroup remote_pri_func + + \brief It retrieves network statistics from the other peer. + + This function is just a void cointainer, since the work is done by the rpcap_stats_remote(). + See that funcion for more details. + + Parameters and return values are exactly the same of the pcap_stats(). +*/ +int pcap_stats_remote(pcap_t *p, struct pcap_stat *ps) +{ +struct pcap_stat *retval; + + retval= rpcap_stats_remote(p, ps, PCAP_STATS_STANDARD); + + if (retval) + return 0; + else + return -1; +} + + + +/*! \ingroup remote_pri_func + + \brief It retrieves network statistics from the other peer. + + This function is just a void cointainer, since the work is done by the rpcap_stats_remote(). + See that funcion for more details. + + Parameters and return values are exactly the same of the pcap_stats_ex(). +*/ +struct pcap_stat *pcap_stats_ex_remote(pcap_t *p) +{ + // '0' (third param) means 'standard pcap_stats()' + return (rpcap_stats_remote(p, &(p->md.stat), PCAP_STATS_EX)); +} + + + +/*! \ingroup remote_pri_func + + \brief It retrieves network statistics from the other peer. + + This function can be called in two modes: + - PCAP_STATS_STANDARD: if we want just standard statistics (i.e. the pcap_stats() ) + - PCAP_STATS_EX: if we want extended statistics (i.e. the pcap_stats_ex() ) + + This 'mode' parameter is needed because in the standard pcap_stats() the variable that keeps the + statistics is allocated by the user. Unfortunately, this structure has been extended in order + to keep new stats. However, if the user has a smaller structure and it passes it to the pcap_stats, + thid function will try to fill in more data than the size of the structure, so that the application + goes in memory overflow. + So, we need to know it we have to copy just the standard fields, or the extended fields as well. + + In case we want to copy the extended fields as well, the problem of memory overflow does no + longer exist because the structure pcap_stat is no longer allocated by the program; + it is allocated by the library instead. + + \param p: the pcap_t structure related to the current instance. + + \param ps: a 'pcap_stat' structure, needed for compatibility with pcap_stat(), in which + the structure is allocated by the user. In case of pcap_stats_ex, this structure and the + function return value point to the same variable. + + \param mode: one of PCAP_STATS_STANDARD or PCAP_STATS_EX. + + \return The structure that keeps the statistics, or NULL in case of error. + The error string is placed in the pcap_t structure. +*/ +struct pcap_stat *rpcap_stats_remote(pcap_t *p, struct pcap_stat *ps, int mode) +{ +struct rpcap_header header; // header of the RPCAP packet +struct rpcap_stats netstats; // statistics sent on the network +unsigned int nread= 0; // number of bytes of the payload read from the socket +int retval; // temp variable which stores functions return value + + // If the capture has still to start, we cannot ask statistics to the other peer + // So, we return a fake number + if (!p->rmt_capstarted) + { + if (mode == PCAP_STATS_STANDARD) + { + ps->ps_drop= 0; + ps->ps_ifdrop= 0; + ps->ps_recv= 0; + } + else + { + ps->ps_capt= 0; + ps->ps_drop= 0; + ps->ps_ifdrop= 0; + ps->ps_netdrop= 0; + ps->ps_recv= 0; + ps->ps_sent= 0; + } + + return ps; + } + + rpcap_createhdr(&header, RPCAP_MSG_STATS_REQ, 0, 0); + + // Send the PCAP_STATS command + if (sock_send(p->rmt_sockctrl, (char *) &header, sizeof (struct rpcap_header), p->errbuf, PCAP_ERRBUF_SIZE) ) + goto error; + + // Receive the RPCAP stats reply message + if (sock_recv(p->rmt_sockctrl, (char *) &header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, p->errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + // Checks if the message is correct + retval= rpcap_checkmsg(p->errbuf, p->rmt_sockctrl, &header, RPCAP_MSG_STATS_REPLY, RPCAP_MSG_ERROR, 0); + + if (retval != RPCAP_MSG_STATS_REPLY) // the message is not the one expected + { + switch (retval) + { + case -3: // Unrecoverable network error + case -2: // The other endpoint send a message that is not allowed here + case -1: // The other endpoint has a version number that is not compatible with our + goto error; + + case RPCAP_MSG_ERROR: // The other endpoint reported an error + // Update nread, since the rpcap_checkmsg() already purged the buffer + nread = ntohl(header.plen); + + // Do nothing; just exit; the error code is already into the errbuf + goto error; + + default: + { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Internal error"); + goto error; + }; + } + } + + if ( (nread= sock_recv(p->rmt_sockctrl, (char *) &netstats, sizeof(struct rpcap_stats), SOCK_RECEIVEALL_YES, p->errbuf, PCAP_ERRBUF_SIZE)) == -1) + goto error; + + if (mode == PCAP_STATS_STANDARD) + { + ps->ps_drop= ntohl(netstats.krnldrop); + ps->ps_ifdrop= ntohl(netstats.ifdrop); + ps->ps_recv= ntohl(netstats.ifrecv); + } + else + { + ps->ps_capt= p->md.TotCapt; + ps->ps_drop= ntohl(netstats.krnldrop); + ps->ps_ifdrop= ntohl(netstats.ifdrop); + ps->ps_netdrop= p->md.TotNetDrops; + ps->ps_recv= ntohl(netstats.ifrecv); + ps->ps_sent= ntohl(netstats.svrcapt); + } + + // Checks if all the data has been read; if not, discard the data in excess + if (nread != ntohl(header.plen)) + { + if (sock_discard(p->rmt_sockctrl, ntohl(header.plen) - nread, NULL, 0) == 1) + goto error; + } + + return ps; + +error: + if (nread != ntohl(header.plen)) + sock_discard(p->rmt_sockctrl, ntohl(header.plen) - nread, NULL, 0); + + return NULL; +} + + + + +/*! \ingroup remote_pri_func + + \brief It opens a remote adapter by opening an RPCAP connection and so on. + + This function does basically the job of pcap_open_live() for a remote interface. + In other words, we have a pcap_read for win32, which reads packets from NPF, + another for LINUX, and so on. Now, we have a pcap_opensource_remote() as well. + The difference, here, is the capture thread does not start until the + pcap_startcapture_remote() is called. + + This is because, in remote capture, we cannot start capturing data as soon ad the + 'open adapter' command is sent. Suppose the remote adapter is already overloaded; + if we start a capture (which, by default, has a NULL filter) the new traffic can + saturate the network. + + Instead, we want to "open" the adapter, then send a "start capture" command only + when we're ready to start the capture. + This funtion does this job: it sends a "open adapter" command (according to the + RPCAP protocol), but it does not start the capture. + + Since the other libpcap functions do not share this way of life, we have to make + some dirty things in order to make everyting working. + + \param source: see pcap_open(). + \param auth: see pcap_open(). + + \param errbuf: a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) + that will contain the error message (in case there is one). It could be either a network problem, + an RPCAP problem (e.g. authentication failed), and more. + + \return A pointer to a 'pcap_t' which can be used as a parameter to the following + calls (pcap_compile() and so on) and that specifies an opened WinPcap session. In case of + problems, it returns NULL and the 'errbuf' variable keeps the error message. + + \warning In case we call the pcap_compile() and the capture is not started, the filter + will be saved into the pcap_t structure, and it will be sent to the other host later + (when the pcap_startcapture_remote() is called). +*/ +pcap_t *pcap_opensource_remote(const char *source, struct pcap_rmtauth *auth, char *errbuf) +{ +char host[PCAP_BUF_SIZE], ctrlport[PCAP_BUF_SIZE], iface[PCAP_BUF_SIZE]; + +char sendbuf[RPCAP_NETBUF_SIZE];// temporary buffer in which data to be sent is buffered +int sendbufidx= 0; // index which keeps the number of bytes currently buffered +struct pcap *fp= NULL; // pcap_t main variable +unsigned int nread= 0; // number of bytes of the payload read from the socket +int retval; // store the return value of the functions +int active= 0; // '1' if we're in active mode + +// socket-related variables +struct addrinfo hints; // temp, needed to open a socket connection +struct addrinfo *addrinfo; // temp, needed to open a socket connection +SOCKET sockctrl= 0; // socket descriptor of the control connection + +// RPCAP-related variables +struct rpcap_header header; // header of the RPCAP packet +struct rpcap_openreply openreply; // open reply message + + + // determine the type of the source (NULL, file, local, remote) + // You must have a valid source string even if we're in active mode, because otherwise + // the call to the following funciton will fail. + if (pcap_parsesrcstr(source, &retval, host, ctrlport, iface, errbuf) == -1) + return NULL; + + if ( retval != PCAP_SRC_IFREMOTE) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "This function is able to open only remote interfaces"); + return NULL; + } + + addrinfo= NULL; + + // Warning: this call can be the first one called by the user. + // For this reason, we have to initialize the WinSock support. + if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1) + return NULL; + + retval= rpcap_remoteact_getsock(host, errbuf); + + if (retval == -1) + return NULL; + + // The capturing machine is in active mode + if (retval) + { + sockctrl= retval; + active= 1; + } + else + { + memset(&hints, 0, sizeof(struct addrinfo) ); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if ( (ctrlport == NULL) || (ctrlport[0] == 0) ) + { + // the user chose not to specify the port + if (sock_initaddress(host, RPCAP_DEFAULT_NETPORT, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1) + return NULL; + } + else + { + // the user chose not to specify the port + if (sock_initaddress(host, ctrlport, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1) + return NULL; + } + + if ( (sockctrl= sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == -1) + goto error; + + freeaddrinfo(addrinfo); + addrinfo= NULL; + + if ( rpcap_sendauth(sockctrl, auth, errbuf) == -1) + goto error; + } + + + // Now it's time to start playing with the RPCAP protocol + // RPCAP open command: create the request message + if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) ) + goto error; + + rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_OPEN_REQ, 0, strlen(iface) ); + + if ( sock_bufferize(iface, strlen(iface), sendbuf, &sendbufidx, + RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE) ) + goto error; + + if ( sock_send(sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) ) + goto error; + + // Receive the RPCAP open reply message + if (sock_recv(sockctrl, (char *) &header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + // Checks if the message is correct + retval= rpcap_checkmsg(errbuf, sockctrl, &header, RPCAP_MSG_OPEN_REPLY, RPCAP_MSG_ERROR, 0); + + if (retval != RPCAP_MSG_OPEN_REPLY) // the message is not the one expected + { + switch (retval) + { + case -3: // Unrecoverable network error + case -2: // The other endpoint send a message that is not allowed here + case -1: // The other endpoint has a version number that is not compatible with our + goto error; + + case RPCAP_MSG_ERROR: // The other endpoint reported an error + // Update nread, since the rpcap_checkmsg() already purged the buffer + nread = ntohl(header.plen); + // Do nothing; just exit; the error code is already into the errbuf + goto error; + + default: + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Internal error"); + goto error; + }; + } + } + + + if ( (nread+= sock_recv(sockctrl, (char *) &openreply, sizeof(struct rpcap_openreply), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE)) == -1) + goto error; + + // Allocates a pcap_t struct for this end of the connection + fp = (pcap_t *) malloc( sizeof(pcap_t) ); + if (fp == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + goto error; + } + + memset(fp, 0, sizeof(pcap_t)); + + // Set proper fields into the pcap_t struct + fp->linktype= ntohl(openreply.linktype); + fp->tzoff= ntohl(openreply.tzoff); + fp->rmt_sockctrl= sockctrl; + fp->rmt_clientside= 1; + + + // This code is duplicated from the end of this function + fp->read_op= pcap_read_remote; + fp->setfilter_op= pcap_setfilter_remote; + fp->getnonblock_op= NULL; // This is not implemented in remote capture + fp->setnonblock_op= NULL; // This is not implemented in remote capture + fp->stats_op= pcap_stats_remote; + fp->close_op= pcap_close_remote; + + // Checks if all the data has been read; if not, discard the data in excess + if (nread != ntohl(header.plen)) + { + if (sock_discard(sockctrl, ntohl(header.plen) - nread, NULL, 0) == 1) + goto error; + } + return fp; + +error: +// When the connection has been established, we have to close it. So, at the +// beginning of this function, if an error occur we return immediately with +// a return NULL; when the connection is established, we have to come here +// ('goto error;') in order to close everything properly. + + // Checks if all the data has been read; if not, discard the data in excess + if (nread != ntohl(header.plen)) + sock_discard(sockctrl, ntohl(header.plen) - nread, NULL, 0); + + if (addrinfo) + freeaddrinfo(addrinfo); + + if (!active) + sock_close(sockctrl, NULL, 0); + + if (fp) + { + pcap_close(fp); + fp= NULL; + } + + return NULL; +} + + + + + + + +/*! \ingroup remote_pri_func + + \brief It starts a remote capture. + + This function is requires since the RPCAP protocol decouples the 'open' from the + 'start capture' functions. + This function takes all the parameters needed (which have been stored into the pcap_t structure) + and sends them to the server. + If everything is fine, it creates a new child thread that reads data from the network + and puts data it into the user buffer. + The pcap_read() will read data from the user buffer, as usual. + + The remote capture acts like a new "kernel", which puts packets directly into + the buffer pointed by pcap_t. + In fact, this function does not rely on a kernel that reads packets and put them + into the user buffer; it has to do that on its own. + + \param fp: the pcap_t descriptor of the device currently open. + + \return '0' if everything is fine, '-1' otherwise. The error message (if one) + is returned into the 'errbuf' field of the pcap_t structure. +*/ +int pcap_startcapture_remote(pcap_t *fp) +{ +char sendbuf[RPCAP_NETBUF_SIZE];// temporary buffer in which data to be sent is buffered +int sendbufidx= 0; // index which keeps the number of bytes currently buffered +char portdata[PCAP_BUF_SIZE]; // temp variable needed to keep the network port for the the data connection +unsigned int nread= 0; // number of bytes of the payload read from the socket +int retval; // store the return value of the functions +int active= 0; // '1' if we're in active mode +struct activehosts *temp; // temp var needed to scan the host list chain, to detect if we're in active mode +char host[INET6_ADDRSTRLEN + 1]; // numeric name of the other host + +// socket-related variables +struct addrinfo hints; // temp, needed to open a socket connection +struct addrinfo *addrinfo; // temp, needed to open a socket connection +SOCKET sockdata= 0; // socket descriptor of the data connection +struct sockaddr_storage saddr; // temp, needed to retrieve the network data port chosen on the local machine +socklen_t saddrlen; // temp, needed to retrieve the network data port chosen on the local machine +int ai_family; // temp, keeps the address family used by the control connection + +// RPCAP-related variables +struct rpcap_header header; // header of the RPCAP packet +struct rpcap_startcapreq *startcapreq; // start capture request message +struct rpcap_startcapreply startcapreply; // start capture reply message + +// Variables related to the buffer setting +int res, itemp; +int sockbufsize= 0; + + + // Let's check if sampling has been required. + // If so, let's set it first + if (pcap_setsampling_remote(fp) != 0) + return -1; + + + // detect if we're in active mode + temp= activeHosts; + while (temp) + { + if (temp->sockctrl == fp->rmt_sockctrl) + { + active= 1; + break; + } + temp= temp->next; + } + + addrinfo= NULL; + + // Gets the complete sockaddr structure used in the ctrl connection + // This is needed to get the address family of the control socket + // Tip: I cannot save the ai_family of the ctrl sock in the pcap_t struct, + // since the ctrl socket can already be open in case of active mode; + // so I would have to call getpeername() anyway + saddrlen = sizeof(struct sockaddr_storage); + if (getpeername(fp->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1) + { + sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE); + goto error; + } + ai_family= ((struct sockaddr_storage *) &saddr)->ss_family; + + // Get the numeric address of the remote host we are connected to + if (getnameinfo( (struct sockaddr *) &saddr, saddrlen, host, + sizeof(host), NULL, 0, NI_NUMERICHOST) ) + { + sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE); + goto error; + } + + /* + Data connection is opened by the server toward the client if: + - we're using TCP, and the user wants us to be in active mode + - we're using UDP + */ + if ( (active) || (fp->rmt_flags & PCAP_OPENFLAG_DATATX_UDP) ) + { + // We have to create a new socket to receive packets + // We have to do that immediately, since we have to tell the other + // end which network port we picked up + memset(&hints, 0, sizeof(struct addrinfo) ); + // TEMP addrinfo is NULL in case of active + hints.ai_family = ai_family; // Use the same address family of the control socket + hints.ai_socktype = (fp->rmt_flags & PCAP_OPENFLAG_DATATX_UDP) ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; // Data connection is opened by the server toward the client + + // Let's the server pick up a free network port for us + if (sock_initaddress(NULL, "0", &hints, &addrinfo, fp->errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + if ( (sockdata= sock_open(addrinfo, SOCKOPEN_SERVER, + 1 /* max 1 connection in queue */, fp->errbuf, PCAP_ERRBUF_SIZE)) == -1) + goto error; + + // addrinfo is no longer used + freeaddrinfo(addrinfo); + addrinfo= NULL; + + // get the complete sockaddr structure used in the data connection + saddrlen = sizeof(struct sockaddr_storage); + if (getsockname(sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1) + { + sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE); + goto error; + } + + // Get the local port the system picked up + if (getnameinfo( (struct sockaddr *) &saddr, saddrlen, NULL, + 0, portdata, sizeof(portdata), NI_NUMERICSERV) ) + { + sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE); + goto error; + } + } + + // Now it's time to start playing with the RPCAP protocol + // RPCAP start ca[ture command: create the request message + if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, fp->errbuf, PCAP_ERRBUF_SIZE) ) + goto error; + + rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_STARTCAP_REQ, 0, + sizeof(struct rpcap_startcapreq) + sizeof(struct rpcap_filter) + fp->fcode.bf_len * sizeof(struct rpcap_filterbpf_insn) ); + + // Fill the structure needed to open an adapter remotely + startcapreq= (struct rpcap_startcapreq *) &sendbuf[sendbufidx]; + + if ( sock_bufferize(NULL, sizeof(struct rpcap_startcapreq), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, fp->errbuf, PCAP_ERRBUF_SIZE) ) + goto error; + + memset(startcapreq, 0, sizeof(struct rpcap_startcapreq) ); + + // By default, apply half the timeout on one side, half of the other +#ifdef linux + fp->md.timeout= fp->md.timeout/2; + startcapreq->read_timeout= htonl(fp->md.timeout); +#else + fp->timeout= fp->timeout/2; + startcapreq->read_timeout= htonl(fp->timeout); +#endif + + // portdata on the openreq is meaningful only if we're in active mode + if ( (active) || (fp->rmt_flags & PCAP_OPENFLAG_DATATX_UDP) ) + { + sscanf(portdata, "%d", (int *) &(startcapreq->portdata)); // cast to avoid a compiler warning + startcapreq->portdata= htons(startcapreq->portdata); + } + + startcapreq->snaplen= htonl(fp->snapshot); + startcapreq->flags= 0; + + if (fp->rmt_flags & PCAP_OPENFLAG_PROMISCUOUS) + startcapreq->flags|= RPCAP_STARTCAPREQ_FLAG_PROMISC; + if (fp->rmt_flags & PCAP_OPENFLAG_DATATX_UDP) + startcapreq->flags|= RPCAP_STARTCAPREQ_FLAG_DGRAM; + if (active) + startcapreq->flags|= RPCAP_STARTCAPREQ_FLAG_SERVEROPEN; + + startcapreq->flags= htons(startcapreq->flags); + + // Pack the capture filter + if (pcap_pack_bpffilter(fp, &sendbuf[sendbufidx], &sendbufidx, &fp->fcode) ) + goto error; + + if ( sock_send(fp->rmt_sockctrl, sendbuf, sendbufidx, fp->errbuf, PCAP_ERRBUF_SIZE) ) + goto error; + + + // Receive the RPCAP start capture reply message + if (sock_recv(fp->rmt_sockctrl, (char *) &header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, fp->errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + // Checks if the message is correct + retval= rpcap_checkmsg(fp->errbuf, fp->rmt_sockctrl, &header, RPCAP_MSG_STARTCAP_REPLY, RPCAP_MSG_ERROR, 0); + + if (retval != RPCAP_MSG_STARTCAP_REPLY) // the message is not the one expected + { + switch (retval) + { + case -3: // Unrecoverable network error + case -2: // The other endpoint send a message that is not allowed here + case -1: // The other endpoint has a version number that is not compatible with our + goto error; + + case RPCAP_MSG_ERROR: // The other endpoint reported an error + // Update nread, since the rpcap_checkmsg() already purged the buffer + nread = ntohl(header.plen); + // Do nothing; just exit; the error code is already into the errbuf + goto error; + + default: + { + snprintf(fp->errbuf, PCAP_ERRBUF_SIZE, "Internal error"); + goto error; + }; + } + } + + + if ( (nread+= sock_recv(fp->rmt_sockctrl, (char *) &startcapreply, + sizeof(struct rpcap_startcapreply), SOCK_RECEIVEALL_YES, fp->errbuf, PCAP_ERRBUF_SIZE)) == -1) + goto error; + + // In case of UDP data stream, the connection is always opened by the daemon + // So, this case is already covered by the code above. + // Now, we have still to handle TCP connections, because: + // - if we're in active mode, we have to wait for a remote connection + // - if we're in passive more, we have to start a connection + // + // We have to do he job in two steps because in case we're opening a tcp connection, we have + // to tell the port we're using to the remote side; in case we're accepting a TCP + // connection, we have to wait this info from the remote side. + + if (!(fp->rmt_flags & PCAP_OPENFLAG_DATATX_UDP)) + { + if (!active) + { + memset(&hints, 0, sizeof(struct addrinfo) ); + hints.ai_family = ai_family; // Use the same address family of the control socket + hints.ai_socktype = (fp->rmt_flags & PCAP_OPENFLAG_DATATX_UDP) ? SOCK_DGRAM : SOCK_STREAM; + + sprintf(portdata, "%d", ntohs(startcapreply.portdata) ); + + // Let's the server pick up a free network port for us + if (sock_initaddress(host, portdata, &hints, &addrinfo, fp->errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + if ( (sockdata= sock_open(addrinfo, SOCKOPEN_CLIENT, 0, fp->errbuf, PCAP_ERRBUF_SIZE)) == -1) + goto error; + + // addrinfo is no longer used + freeaddrinfo(addrinfo); + addrinfo= NULL; + } + else + { + SOCKET socktemp; // We need another socket, since we're going to accept() a connection + + // Connection creation + saddrlen = sizeof(struct sockaddr_storage); + + socktemp= accept(sockdata, (struct sockaddr *) &saddr, &saddrlen); + + if (socktemp == -1) + { + sock_geterror("accept(): ", fp->errbuf, PCAP_ERRBUF_SIZE); + goto error; + } + + // Now that I accepted the connection, the server socket is no longer needed + sock_close(sockdata, fp->errbuf, PCAP_ERRBUF_SIZE); + sockdata= socktemp; + } + } + + // Let's save the socket of the data connection + fp->rmt_sockdata= sockdata; + + // Allocates WinPcap/libpcap user buffer, which is a socket buffer in case of a remote capture + // It has the same size of the one used on the other side of the connection + fp->bufsize= ntohl(startcapreply.bufsize); + + // Let's get the actual size of the socket buffer + itemp= sizeof(sockbufsize); + + res= getsockopt(sockdata, SOL_SOCKET, SO_RCVBUF, (char *) &sockbufsize, &itemp); + if (res == -1) + { + sock_geterror("pcap_startcapture_remote()", fp->errbuf, PCAP_ERRBUF_SIZE); + SOCK_ASSERT(fp->errbuf, 1); + } + + /* + Warning: on some kernels (e.g. linux), the size of the user buffer does not take + into account the pcap_header and such, and it is set equal to the snaplen. + In my view, this is wrong (the meaning of the bufsize becames a bit strange). + So, here bufsize is the whole size of the user buffer. + In case the bufsize returned is too small, let's adjust it accordingly. + */ + if (fp->bufsize <= fp->snapshot) + fp->bufsize+= sizeof (struct pcap_pkthdr); + + // if the current socket buffer is smaller than the desired one + if (sockbufsize < fp->bufsize) + { + // Loop until the buffer size is OK or the original socket buffer size is larger than this one + while (1) + { + res= setsockopt(sockdata, SOL_SOCKET, SO_RCVBUF, (char *) &(fp->bufsize), sizeof(fp->bufsize) ); + + if (res == 0) + break; + + // If something goes wrong, half the buffer size (checking that it does not become smaller than + // the current one) + fp->bufsize/= 2; + + if (sockbufsize >= fp->bufsize) + { + fp->bufsize= sockbufsize; + break; + } + } + } + + // Let's allocate the packet; this is required in order to put the packet somewhere when + // extracting data from the socket + // Since buffering has already been done in the socket buffer, here we need just a buffer, + // whose size is equal to the pcap header plus the snapshot length + fp->bufsize= fp->snapshot + sizeof (struct pcap_pkthdr); + + fp->buffer = (u_char *) malloc(fp->bufsize); + if (fp->buffer == NULL) + { + snprintf(fp->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); + goto error; + } + + + // Checks if all the data has been read; if not, discard the data in excess + if (nread != ntohl(header.plen)) + { + if (sock_discard(fp->rmt_sockctrl, ntohl(header.plen) - nread, NULL, 0) == 1) + goto error; + } + + // In case the user does not want to capture RPCAP packets, let's update the filter + // We have to update it here (instead of sending it into the 'StartCapture' message + // because when we generate the 'start capture' we do not know (yet) all the ports + // we're currently using. + if (fp->rmt_flags & PCAP_OPENFLAG_NOCAPTURE_RPCAP) + { + struct bpf_program fcode; + + if (pcap_createfilter_norpcappkt(fp, &fcode) == -1) + goto error; + + // We cannot use 'pcap_setfilter_remote' because formally the capture has not been started yet + // (the 'fp->rmt_capstarted' variable will be updated some lines below) + if (pcap_updatefilter_remote(fp, &fcode) == -1) + goto error; + + pcap_freecode(&fcode); + } + + fp->rmt_capstarted= 1; + return 0; + +error: +// When the connection has been established, we have to close it. So, at the +// beginning of this function, if an error occur we return immediately with +// a return NULL; when the connection is established, we have to come here +// ('goto error;') in order to close everything properly. + + // Checks if all the data has been read; if not, discard the data in excess + if (nread != ntohl(header.plen)) + sock_discard(fp->rmt_sockctrl, ntohl(header.plen) - nread, NULL, 0); + + if ((sockdata) && (sockdata != -1)) // we can be here because sockdata said 'error' + sock_close(sockdata, NULL, 0); + + if (!active) + sock_close(fp->rmt_sockctrl, NULL, 0); + + // We do not have to call pcap_close() here, because this function is always called + // by the user in case something bad happens +// if (fp) +// { +// pcap_close(fp); +// fp= NULL; +// } + + return -1; +} + + + + + +/*! + \brief Takes a bpf program and sends it to the other host. + + This function can be called in two cases: + - the pcap_startcapture() is called (we have to send the filter along with + the 'start capture' command) + - we want to udpate the filter during a capture (i.e. the pcap_setfilter() + is called when the capture is still on) + + This function serializes the filter into the sending buffer ('sendbuf', passed + as a parameter) and return back. It does not send anything on the network. + + \param fp: the pcap_t descriptor of the device currently opened. + + \param sendbuf: the buffer on which the serialized data has to copied. + + \param sendbufidx: it is used to return the abounf of bytes copied into the buffer. + + \param prog: the bpf program we have to copy. + + \return '0' if everything is fine, '-1' otherwise. The error message (if one) + is returned into the 'errbuf' field of the pcap_t structure. +*/ +int pcap_pack_bpffilter(pcap_t *fp, char *sendbuf, int *sendbufidx, struct bpf_program *prog) +{ +struct rpcap_filter *filter; +struct rpcap_filterbpf_insn *insn; +struct bpf_insn *bf_insn; +struct bpf_program fake_prog; // To be used just in case the user forgot to set a filter +unsigned int i; + + + if (prog->bf_len == 0) // No filters have been specified; so, let's apply a "fake" filter + { + if (pcap_compile(fp, &fake_prog, NULL /*buffer*/, 1, 0) == -1) + return -1; + + prog= &fake_prog; + } + + filter= (struct rpcap_filter *) sendbuf; + + if ( sock_bufferize(NULL, sizeof(struct rpcap_filter), NULL, sendbufidx, + RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, fp->errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + filter->filtertype= htons(RPCAP_UPDATEFILTER_BPF); + filter->nitems= htonl( (int32) prog->bf_len); + + if ( sock_bufferize(NULL, prog->bf_len * sizeof(struct rpcap_filterbpf_insn), + NULL, sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, fp->errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + insn= (struct rpcap_filterbpf_insn *) (filter + 1); + bf_insn= prog->bf_insns; + + for (i= 0; i < prog->bf_len; i++) + { + insn->code= htons(bf_insn->code); + insn->jf= bf_insn->jf; + insn->jt= bf_insn->jt; + insn->k= htonl(bf_insn->k); + + insn++; + bf_insn++; + } + + return 0; +} + + + + + +/*! \ingroup remote_pri_func + + \brief Update a filter on a remote host. + + This function is called when the user wants to update a filter. + In case we're capturing from the network, it sends the filter to the other peer. + This function is *not* called automatically when the user calls the pcap_setfilter(). + There will be two cases: + - the capture is already on: in this case, pcap_setfilter() calls pcap_updatefilter_remote() + - the capture has not started yet: in this case, pcap_setfilter() stores the filter into + the pcap_t structure, and then the filter is sent with the pcap_startcap(). + + Parameters and return values are exactly the same of the pcap_setfilter(). + + \warning This function *does not* clear the packet currently into the buffers. Therefore, + the user has to expect to receive some packets that are related to the previous filter. + If you want to discard all the packets before applying a new filter, you have to close + the current capture session and start a new one. +*/ +int pcap_updatefilter_remote(pcap_t *fp, struct bpf_program *prog) +{ +int retval; // general variable used to keep the return value of other functions +char sendbuf[RPCAP_NETBUF_SIZE];// temporary buffer in which data to be sent is buffered +int sendbufidx= 0; // index which keeps the number of bytes currently buffered +struct rpcap_header header; // To keep the reply message + + + if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx, + RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, fp->errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_UPDATEFILTER_REQ, 0, + sizeof(struct rpcap_filter) + prog->bf_len * sizeof(struct rpcap_filterbpf_insn)); + + if (pcap_pack_bpffilter(fp, &sendbuf[sendbufidx], &sendbufidx, prog) ) + return -1; + + if ( sock_send(fp->rmt_sockctrl, sendbuf, sendbufidx, fp->errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + // Waits for the answer + if (sock_recv(fp->rmt_sockctrl, (char *) &header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, fp->errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + + // Checks if the message is correct + retval= rpcap_checkmsg(fp->errbuf, fp->rmt_sockctrl, &header, RPCAP_MSG_UPDATEFILTER_REPLY, 0); + + if (retval != RPCAP_MSG_UPDATEFILTER_REPLY) // the message is not the one expected + { + switch (retval) + { + case -3: // Unrecoverable network error + case -2: // The other endpoint sent a message that is not allowed here + case -1: // The other endpoint has a version number that is not compatible with our + // Do nothing; just exit from here; the error code is already into the errbuf + return -1; + + default: + { + SOCK_ASSERT("Internal error", 0); + return -1; + }; + } + } + + if (ntohl(header.plen) != 0) // the message has an unexpected size + { + if (sock_discard(fp->rmt_sockctrl, ntohl(header.plen), fp->errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + } + + return 0; +} + + + + +/*! + \ingroup remote_pri_func + + \brief Send a filter to a remote host. + + This function is called when the user wants to set a filter. + In case we're capturing from the network, it sends the filter to the other peer. + This function is called automatically when the user calls the pcap_setfilter(). + + Parameters and return values are exactly the same of the pcap_setfilter(). +*/ +int pcap_setfilter_remote(pcap_t *fp, struct bpf_program *prog) +{ + if (!fp->rmt_capstarted) + { + // copy filter into the pcap_t structure + if (install_bpf_program(fp, prog) == -1) + return -1; + return 0; + } + + // we have to update a filter during run-time + if (pcap_updatefilter_remote(fp, prog) ) + return -1; + + return 0; +} + + + + + +/*! + \ingroup remote_pri_func + + \brief Update the current filter in order not to capture rpcap packets. + + This function is called *only* when the user wants exclude RPCAP packets + related to the current session from the captured packets. + + \return '0' if everything is fine, '-1' otherwise. The error message (if one) + is returned into the 'errbuf' field of the pcap_t structure. +*/ +int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog) +{ +int RetVal= 0; + + // We do not want to capture our RPCAP traffic. So, let's update the filter + if (fp->rmt_flags & PCAP_OPENFLAG_NOCAPTURE_RPCAP) + { + struct sockaddr_storage saddr; // temp, needed to retrieve the network data port chosen on the local machine + socklen_t saddrlen; // temp, needed to retrieve the network data port chosen on the local machine + char myaddress[128]; + char myctrlport[128]; + char mydataport[128]; + char peeraddress[128]; + char peerctrlport[128]; + char *newfilter; + const int newstringsize= 1024; + int currentfiltersize; + + // Get the name/port of the other peer + saddrlen = sizeof(struct sockaddr_storage); + if (getpeername(fp->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1) + { + sock_geterror("getpeername(): ", fp->errbuf, PCAP_ERRBUF_SIZE); + return -1; + } + + if (getnameinfo( (struct sockaddr *) &saddr, saddrlen, peeraddress, + sizeof(peeraddress), peerctrlport, sizeof(peerctrlport), NI_NUMERICHOST | NI_NUMERICSERV) ) + { + sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE); + return -1; + } + + // We cannot check the data port, because this is available only in case of TCP sockets + + // Get the name/port of the current host + if (getsockname(fp->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1) + { + sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE); + return -1; + } + + // Get the local port the system picked up + if (getnameinfo( (struct sockaddr *) &saddr, saddrlen, myaddress, + sizeof(myaddress), myctrlport, sizeof(myctrlport), NI_NUMERICHOST | NI_NUMERICSERV) ) + { + sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE); + return -1; + } + + // Let's now check the data port + if (getsockname(fp->rmt_sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1) + { + sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE); + return -1; + } + + // Get the local port the system picked up + if (getnameinfo( (struct sockaddr *) &saddr, saddrlen,NULL, 0, mydataport, sizeof(mydataport), NI_NUMERICSERV) ) + { + sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE); + return -1; + } + + currentfiltersize= strlen(fp->currentfilter); + + newfilter= (char *) malloc (currentfiltersize + newstringsize + 1); + + if (currentfiltersize) + { + snprintf(newfilter, currentfiltersize + newstringsize, + "(%s) and not (host %s and host %s and port %s and port %s) and not (host %s and host %s and port %s)", + fp->currentfilter, myaddress, peeraddress, myctrlport, peerctrlport, myaddress, peeraddress, mydataport); + } + else + { + snprintf(newfilter, currentfiltersize + newstringsize, + "not (host %s and host %s and port %s and port %s) and not (host %s and host %s and port %s)", + myaddress, peeraddress, myctrlport, peerctrlport, myaddress, peeraddress, mydataport); + } + + newfilter[currentfiltersize + newstringsize]= 0; + + // This is only an hack to make the pcap_compile() working properly + fp->rmt_clientside= 0; + + if (pcap_compile(fp, prog, newfilter, 1, 0) == -1) + RetVal= -1; + + // This is only an hack to make the pcap_compile() working properly + fp->rmt_clientside= 1; + + free(newfilter); + } + + return RetVal; +} + +/*! + \ingroup remote_pri_func + + \brief Set sampling parameters in the remote host. + + This function is called when the user wants to set activate sampling on the remote host. + + Sampling parameters are defined into the 'pcap_t' structure. + + \param p: the pcap_t descriptor of the device currently opened. + + \return '0' if everything is OK, '-1' is something goes wrong. The error message is returned + in the 'errbuf' member of the pcap_t structure. +*/ +int pcap_setsampling_remote(pcap_t *p) +{ +int retval; // general variable used to keep the return value of other functions +char sendbuf[RPCAP_NETBUF_SIZE];// temporary buffer in which data to be sent is buffered +int sendbufidx= 0; // index which keeps the number of bytes currently buffered +struct rpcap_header header; // To keep the reply message +struct rpcap_sampling *sampling_pars; // Structure that is needed to send sampling parameters to the remote host + + // If no samping is requested, return 'ok' + if (p->rmt_samp.method == PCAP_SAMP_NOSAMP) + return 0; + + if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, p->errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_SETSAMPLING_REQ, 0, sizeof(struct rpcap_sampling) ); + + // Fill the structure needed to open an adapter remotely + sampling_pars= (struct rpcap_sampling *) &sendbuf[sendbufidx]; + + if ( sock_bufferize(NULL, sizeof(struct rpcap_sampling), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, p->errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + memset(sampling_pars, 0, sizeof(struct rpcap_sampling) ); + + sampling_pars->method= p->rmt_samp.method; + sampling_pars->value= htonl(p->rmt_samp.value); + + if ( sock_send(p->rmt_sockctrl, sendbuf, sendbufidx, p->errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + // Waits for the answer + if (sock_recv(p->rmt_sockctrl, (char *) &header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, p->errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + + // Checks if the message is correct + retval= rpcap_checkmsg(p->errbuf, p->rmt_sockctrl, &header, RPCAP_MSG_SETSAMPLING_REPLY, 0); + + if (retval != RPCAP_MSG_SETSAMPLING_REPLY) // the message is not the one expected + { + switch (retval) + { + case -3: // Unrecoverable network error + case -2: // The other endpoint sent a message that is not allowed here + case -1: // The other endpoint has a version number that is not compatible with our + case RPCAP_MSG_ERROR: + // Do nothing; just exit from here; the error code is already into the errbuf + return -1; + + default: + { + SOCK_ASSERT("Internal error", 0); + return -1; + }; + } + } + + if (ntohl(header.plen) != 0) // the message has an unexpected size + { + if (sock_discard(p->rmt_sockctrl, ntohl(header.plen), p->errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + } + + return 0; + +} + + + + + +/********************************************************* + * * + * Miscellaneous functions * + * * + *********************************************************/ + + +/*! \ingroup remote_pri_func + \brief It sends a RPCAP error to the other peer. + + This function has to be called when the main program detects an error. This funcion + will send on the other peer the 'buffer' specified by the user. + This function *does not* request a RPCAP CLOSE connection. A CLOSE command must be sent + explicitely by the program, since we do not know it the error can be recovered in some + way or it is a non-recoverable one. + + \param sock: the socket we are currently using. + + \param error: an user-allocated (and '0' termined) buffer that contains the error + description thas has to be transmitted on the other peer. The error message cannot + be longer than PCAP_ERRBUF_SIZE. + + \param errcode: a integer which tells the other party the type of error we had; + currently is is not too much used. + + \param errbuf: a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) + that will contain the error message (in case there is one). It could be network problem. + + \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned + in the 'errbuf' variable. +*/ +int rpcap_senderror(SOCKET sock, char *error, unsigned short errcode, char *errbuf) +{ +char sendbuf[RPCAP_NETBUF_SIZE]; // temporary buffer in which data to be sent is buffered +int sendbufidx= 0; // index which keeps the number of bytes currently buffered +uint16 length; + + length= (uint16) strlen(error); + + if (length > PCAP_ERRBUF_SIZE) + length= PCAP_ERRBUF_SIZE; + + rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_ERROR, errcode, length); + + if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx, + RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + if ( sock_bufferize(error, length, sendbuf, &sendbufidx, + RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + if ( sock_send(sock, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + return 0; +} + + + +/*! \ingroup remote_pri_func + \brief Sends the authentication message. + + It sends the authentication parameters on the control socket. + Ths function is required in order to open the connection with the other end party. + + \param sock: the socket we are currently using. + + \param auth: authentication parameters that have to be sent. + + \param errbuf: a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) + that will contain the error message (in case there is one). It could be network problem + ot the fact that the authorization failed. + + \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned + in the 'errbuf' variable. + The error message could be also 'the authentication failed'. +*/ +int rpcap_sendauth(SOCKET sock, struct pcap_rmtauth *auth, char *errbuf) +{ +char sendbuf[RPCAP_NETBUF_SIZE]; // temporary buffer in which data that has to be sent is buffered +int sendbufidx= 0; // index which keeps the number of bytes currently buffered +uint16 length; // length of the payload of this message +struct rpcap_auth *rpauth; +uint16 auth_type; +struct rpcap_header header; +int retval; // temp variable which stores functions return value + + if (auth) + { + auth_type= auth->type; + + switch (auth->type) + { + case RPCAP_RMTAUTH_NULL: + length= sizeof (struct rpcap_auth); + break; + + case RPCAP_RMTAUTH_PWD: + length= sizeof (struct rpcap_auth); + if (auth->username) length+= strlen(auth->username); + if (auth->password) length+= strlen(auth->password); + break; + + default: + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication type not recognized."); + return -1; + } + } + else + { + auth_type= RPCAP_RMTAUTH_NULL; + length= sizeof (struct rpcap_auth); + } + + + if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_AUTH_REQ, 0, length); + + rpauth= (struct rpcap_auth *) &sendbuf[sendbufidx]; + + if ( sock_bufferize(NULL, sizeof(struct rpcap_auth), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + memset(rpauth, 0, sizeof (struct rpcap_auth) ); + + rpauth->type= htons(auth_type); + + if (auth_type == RPCAP_RMTAUTH_PWD) + { + + if (auth->username) + rpauth->slen1= strlen(auth->username); + else + rpauth->slen1= 0; + + if ( sock_bufferize(auth->username, rpauth->slen1, sendbuf, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + if (auth->password) + rpauth->slen2= strlen(auth->password); + else + rpauth->slen2= 0; + + if ( sock_bufferize(auth->password, rpauth->slen2, sendbuf, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + rpauth->slen1= htons (rpauth->slen1); + rpauth->slen2= htons (rpauth->slen2); + } + + if ( sock_send(sock, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + + if ( sock_recv(sock, (char *) &header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + + retval= rpcap_checkmsg(errbuf, sock, &header, RPCAP_MSG_AUTH_REPLY, RPCAP_MSG_ERROR, 0); + + if (retval != RPCAP_MSG_AUTH_REPLY) // the message is not the one expected + { + switch (retval) + { + case -3: // Unrecoverable network error + case -2: // The other endpoint sent a message that is not allowed here + case -1: // The other endpoint has a version number that is not compatible with our + // Do nothing; just exit from here; the error code is already into the errbuf + return -1; + + case RPCAP_MSG_ERROR: + { + return -1; + }; + + default: + { + SOCK_ASSERT("Internal error", 0); + return -1; + }; + } + } + + if (ntohl(header.plen) ) + { + if (sock_discard(sock, ntohl(header.plen), errbuf, PCAP_ERRBUF_SIZE) ) + return -1; + } + + return 0; +} + + + +/*! \ingroup remote_pri_func + \brief Creates a structure of type rpcap_header. + + This function is provided just because the creation of an rpcap header is quite a common + task. It accepts all the values that appears into an rpcap_header, and it puts them in + place using the proper hton() calls. + + \param header: a pointer to a user-allocated buffer which will contain the serialized + header, ready to be sent on the network. + + \param type: a value (in the host by order) which will be placed into the header.type + field and that represents the type of the current message. + + \param value: a value (in the host by order) which will be placed into the header.value + field and that has a message-dependent meaning. + + \param length: a value (in the host by order) which will be placed into the header.length + field and that represents the payload length of the message. + + \return Nothing. The serialized header is returned into the 'header' variable. +*/ +void rpcap_createhdr(struct rpcap_header *header, uint8 type, uint16 value, uint32 length) +{ + memset(header, 0, sizeof (struct rpcap_header) ); + + header->ver= RPCAP_VERSION; + header->type= type; + header->value= htons(value); + header->plen= htonl(length); +} + + + +/*! \ingroup remote_pri_func + \brief Checks if the header of the received message is correct. + + This function is a way to easily check if the message received, in a certain + state of the RPCAP protocol Finite State Machine, is valid. This function accepts, + as a parameter, the list of message types that are allowed in a certain situation, + and it returns the one which occurs. + + \param errbuf: a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) + that will contain the error message (in case there is one). It could be either problem + occurred inside this function (e.g. a network problem in case it tries to send an + error on the other peer and the send() call fails), an error message which has been + sent to us from the other party, or a version error (the message receive has a version + number that is incompabile with our). + + \param sock: the socket that has to be used to receive data. This function can + read data from socket in case the version contained into the message is not compatible + with our. In that case, all the message is purged from the socket, so that the following + recv() calls will return a new message. + + \param header: a pointer to and 'rpcap_header' structure that keeps the data received from + the network (still in network byte order) and that has to be checked. + + \param first: this function has a variable number of parameters. From this point on, + all the messages that are valid in this context must be passed as parameters. + The message type list must be terminated with a '0' value, the null message type, + which means 'no more types to check'. The RPCAP protocol does not define anything with + message type equal to zero, so there is no ambiguity in using this value as a list terminator. + + \return The message type of the message that has been detected. In case of errors (e.g. the + header contains a type that is not listed among the allowed types), this function will + return the following codes: + - (-1) if the version is incompatible. + - (-2) if the code is not among the one listed into the parameters list + - (-3) if a network error (connection reset, ...) + - RPCAP_MSG_ERROR if the message is an error message (it follow that the RPCAP_MSG_ERROR + could not be present in the allowed message-types list, becuase this function checks + for errors anyway) + + In case either the version is incompatible or nothing matches (i.e. it returns '-1' or '-2'), + it discards the message body (i.e. it reads the remaining part of the message from the + network and it discards it) so that the application is ready to receive a new message. +*/ +int rpcap_checkmsg(char *errbuf, SOCKET sock, struct rpcap_header *header, uint8 first, ...) +{ +va_list ap; +uint8 type; +int32 len; + + va_start(ap, first); + + // Check if the present version of the protocol can handle this message + if ( rpcap_checkver(sock, header, errbuf) ) + { + SOCK_ASSERT(errbuf, 1); + + va_end(ap); + return -1; + } + + type= first; + + while ( type != 0 ) + { + // The message matches with one of the types listed + // There is no need of conversions since both values are uint8 + + // Check if the other side reported an error. + // If yes, it retrieves it and it returns it back to the caller + if (header->type == RPCAP_MSG_ERROR) + { + len= ntohl(header->plen); + + if (len >= PCAP_ERRBUF_SIZE) + { + if (sock_recv(sock, errbuf, PCAP_ERRBUF_SIZE - 1, SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) ) + return -3; + + sock_discard(sock, len - (PCAP_ERRBUF_SIZE - 1), NULL, 0); + + // Put '\0' at the end of the string + errbuf[PCAP_ERRBUF_SIZE - 1]= 0; + } + else + { + if (sock_recv(sock, errbuf, len, SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -3; + + // Put '\0' at the end of the string + errbuf[len]= 0; + } + + + va_end(ap); + return header->type; + } + + if (header->type == type) + { + va_end(ap); + return header->type; + } + + // get next argument + type= va_arg(ap, int); + } + + // we already have an error, so please discard this one + sock_discard(sock, ntohl(header->plen), NULL, 0); + + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The other endpoint sent a message that is not allowed here."); + SOCK_ASSERT(errbuf, 1); + + va_end(ap); + return -2; +} + + + +/*! \ingroup remote_pri_func + \brief Checks if the version contained into the message is compatible with + the one handled by this implementation. + + Right now, this function does not have any sophisticated task: if the versions + are different, it returns -1 and it discards the message. + It is expected that in the future this message will become more complex. + + \param sock: the socket that has to be used to receive data. This function can + read data from socket in case the version contained into the message is not compatible + with our. In that case, all the message is purged from the socket, so that the following + recv() calls will return a new (clean) message. + + \param header: a pointer to and 'rpcap_header' structure that keeps the data received from + the network (still in network byte order) and that has to be checked. + + \param errbuf: a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) + that will contain the error message (in case there is one). The error message is + "incompatible version". + + \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned + in the 'errbuf' variable. +*/ +int rpcap_checkver(SOCKET sock, struct rpcap_header *header, char *errbuf) +{ + /* + This is a sample function. + + In the real world, you have to check at the type code, + and decide accordingly. + */ + + if (header->ver != RPCAP_VERSION) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Incompatible version number: message discarded."); + + // we already have an error, so please discard this one + sock_discard(sock, ntohl(header->plen), NULL, 0); + return -1; + } + + return 0; +} + + + +/*! \ingroup remote_pri_func + + \brief It returns the socket currently used for this active connection (active mode only). + + This function is just for internal use; it returns the socket ID of the active connection + currently opened. + + \param host: a string that keeps the host name of the host for which we want to + get the socket ID for that active connection. + + \param errbuf: a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) + that will contain the error message (in case there is one). + + \return the socket identifier if everything is fine, '0' if this host is not in the active + host list. It returns '-1' in case of error. The error message is returned into the errbuf variable. + + \warning Win32: be carefully not to assign the returning value of this call to a SOCKET + directly. It should lead to wrong results, since Win32 sockets are unsigned int; therefore + a negative value could not be handled correctly. +*/ +int rpcap_remoteact_getsock(const char *host, char *errbuf) +{ +struct activehosts *temp; // temp var needed to scan the host list chain +struct addrinfo hints, *addrinfo, *ai_next; // temp var needed to translate between hostname to its address +int retval; + + // retrieve the network address corresponding to 'host' + addrinfo = NULL; + memset(&hints, 0, sizeof (struct addrinfo) ); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype= SOCK_STREAM; + + retval = getaddrinfo(host, "0", &hints, &addrinfo); + if (retval != 0) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "getaddrinfo() %s", gai_strerror(retval)); + return -1; + } + + temp= activeHosts; + + while (temp) + { + ai_next= addrinfo; + while(ai_next) + { + if (sock_cmpaddr(&temp->host, (struct sockaddr_storage *) ai_next->ai_addr ) == 0) + return (temp->sockctrl ); + + ai_next= ai_next->ai_next; + } + temp= temp->next; + } + + if (addrinfo) + freeaddrinfo(addrinfo); + + // The host you want to get the socket ID does not have an active connection + return 0; +} + + + + + diff --git a/winpcap/wpcap/libpcap/pcap-remote.h b/winpcap/wpcap/libpcap/pcap-remote.h new file mode 100644 index 0000000..60dc763 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-remote.h @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __PCAP_REMOTE_H__ +#define __PCAP_REMOTE_H__ + + +#include "pcap.h" +#include "sockutils.h" // Needed for some structures (like SOCKET, sockaddr_in) which are used here + + +/*! + \file pcap-remote.h + + This file keeps all the new definitions and typedefs that are exported to the user and + that are needed for the RPCAP protocol. + + \warning All the RPCAP functions that are allowed to return a buffer containing + the error description can return max PCAP_ERRBUF_SIZE characters. + However there is no guarantees that the string will be zero-terminated. + Best practice is to define the errbuf variable as a char of size 'PCAP_ERRBUF_SIZE+1' + and to insert manually the termination char at the end of the buffer. This will + guarantee that no buffer overflows occur even if we use the printf() to show + the error on the screen. + + \warning This file declares some typedefs that MUST be of a specific size. + These definitions (i.e. typedefs) could need to be changed on other platforms than + Intel IA32. + + \warning This file defines some structures that are used to transfer data on the network. + Be careful that you compiler MUST not insert padding into these structures + for better alignment. + These structures have been created in order to be correctly aligned to a 32 bits + boundary, but be careful in any case. +*/ + + + + + + + + +/********************************************************* + * * + * General definitions / typedefs for the RPCAP protocol * + * * + *********************************************************/ + +// All the following structures and typedef belongs to the Private Documentation +/*! \addtogroup remote_pri_struct + \{ +*/ + +#define RPCAP_DEFAULT_NETPORT "2002" /*!< Default port on which the RPCAP daemon is waiting for connections. */ +/*! Default port on which the client workstation is waiting for connections in case of active mode. */ +#define RPCAP_DEFAULT_NETPORT_ACTIVE "2003" +#define RPCAP_DEFAULT_NETADDR "" /*!< Default network address on which the RPCAP daemon binds to. */ +#define RPCAP_VERSION 0 /*!< Present version of the RPCAP protocol (0 = Experimental). */ +#define RPCAP_TIMEOUT_INIT 90 /*!< Initial timeout for RPCAP connections (default: 90 sec) */ +#define RPCAP_TIMEOUT_RUNTIME 180 /*!< Run-time timeout for RPCAP connections (default: 3 min) */ +#define RPCAP_ACTIVE_WAIT 30 /*!< Waiting time betweek two attempts to open a connection, in active mode (default: 30 sec) */ +#define RPCAP_SUSPEND_WRONGAUTH 1 /*!< If the authentication is wrong, stops 1 sec before accepting a new auth message */ + +/*! + \brief Buffer used by socket functions to send-receive packets. + In case you plan to have messages larger than this value, you have to increase it. +*/ +#define RPCAP_NETBUF_SIZE 64000 + + +/*! + \brief Separators used for the host list. + + It is used: + - by the rpcapd daemon, when you types a list of allowed connecting hosts + - by the rpcap in active mode, when the client waits for incoming connections from other hosts +*/ +#define RPCAP_HOSTLIST_SEP " ,;\n\r" + + + + +// WARNING: These could need to be changed on other platforms +typedef unsigned char uint8; //!< Provides an 8-bits unsigned integer +typedef unsigned short uint16; //!< Provides a 16-bits unsigned integer +typedef unsigned int uint32; //!< Provides a 32-bits unsigned integer +typedef int int32; //!< Provides a 32-bits integer + + + + +/*! + \brief Keeps a list of all the opened connections in the active mode. + + This structure defines a linked list of items that are needed to keep the info required to + manage the active mode. + In other words, when a new connection in active mode starts, this structure is updated so that + it reflects the list of active mode connections currently opened. + This structure is required by findalldevs() and open_remote() to see if they have to open a new + control connection toward the host, or they already have a control connection in place. +*/ +struct activehosts +{ + struct sockaddr_storage host; + SOCKET sockctrl; + struct activehosts *next; +}; + + +/********************************************************* + * * + * Protocol messages formats * + * * + *********************************************************/ +// WARNING Take care you compiler does not insert padding for better alignments into these structs + + +//! Common header for all the RPCAP messages +struct rpcap_header +{ + uint8 ver; //!< RPCAP version number + uint8 type; //!< RPCAP message type (error, findalldevs, ...) + uint16 value; //!< Message-dependent value (not always used) + uint32 plen; //!< Length of the payload of this RPCAP message +}; + + +//! Format of the message for the interface description (findalldevs command) +struct rpcap_findalldevs_if +{ + uint16 namelen; //!< Length of the interface name + uint16 desclen; //!< Length of the interface description + uint32 flags; //!< Interface flags + uint16 naddr; //!< Number of addresses + uint16 dummy; //!< Must be zero +}; + + +//! Format of the message for the address listing (findalldevs command) +struct rpcap_findalldevs_ifaddr +{ + struct sockaddr_storage addr; //!< Network address + struct sockaddr_storage netmask; //!< Netmask for that address + struct sockaddr_storage broadaddr; //!< Broadcast address for that address + struct sockaddr_storage dstaddr; //!< P2P destination address for that address +}; + + + +/*! + \brief Format of the message of the connection opening reply (open command). + + This structure transfers over the network some of the values useful on the client side. +*/ +struct rpcap_openreply +{ + int32 linktype; //!< Link type + int32 tzoff; //!< Timezone offset +}; + + + +//! Format of the message that starts a remote capture (startcap command) +struct rpcap_startcapreq +{ + uint32 snaplen; //!< Length of the snapshot (number of bytes to capture for each packet) + uint32 read_timeout; //!< Read timeout in milliseconds + uint16 flags; //!< Flags (see RPCAP_STARTCAPREQ_FLAG_xxx) + uint16 portdata; //!< Network port on which the client is waiting at (if 'serveropen') +}; + + +//! Format of the reply message that devoted to start a remote capture (startcap reply command) +struct rpcap_startcapreply +{ + int32 bufsize; //!< Size of the user buffer allocated by WinPcap; it can be different from the one we chose + uint16 portdata; //!< Network port on which the server is waiting at (passive mode only) + uint16 dummy; //!< Must be zero +}; + + +/*! + \brief Format of the header which encapsulates captured packets when transmitted on the network. + + This message requries the general header as well, since we want to be albe to exchange + more information across the network in the future (for example statistics, and kind like that). +*/ +struct rpcap_pkthdr +{ + uint32 timestamp_sec; //!< 'struct timeval' compatible, it represents the 'tv_sec' field + uint32 timestamp_usec; //!< 'struct timeval' compatible, it represents the 'tv_usec' field + uint32 caplen; //!< Length of portion present in the capture + uint32 len; //!< Real length this packet (off wire) + uint32 npkt; //!< Ordinal number of the packet (i.e. the first one captured has '1', the second one '2', etc) +}; + + +//! General header used for the pcap_setfilter() command; keeps just the number of BPF instructions +struct rpcap_filter +{ + uint16 filtertype; //!< type of the filter transferred (BPF instructions, ...) + uint16 dummy; //!< Must be zero + uint32 nitems; //!< Number of items contained into the filter (e.g. BPF instructions for BPF filters) +}; + + +//! Structure that keeps a single BPF instuction; it is repeated 'ninsn' times according to the 'rpcap_filterbpf' header +struct rpcap_filterbpf_insn +{ + uint16 code; //!< opcode of the instuction + uint8 jt; //!< relative offset to jump to in case of 'true' + uint8 jf; //!< relative offset to jump to in case of 'false' + int32 k; //!< instruction-dependent value +}; + + +//! Structure that keeps the data required for the authentication on the remote host +struct rpcap_auth +{ + uint16 type; //!< Authentication type + uint16 dummy; //!< Must be zero + uint16 slen1; //!< Length of the first authentication item (e.g. username) + uint16 slen2; //!< Length of the second authentication item (e.g. password) +}; + + +//! Structure that keeps the statistics about the number of packets captured, dropped, etc. +struct rpcap_stats +{ + uint32 ifrecv; //!< Packets received by the kernel filter (i.e. pcap_stats.ps_recv) + uint32 ifdrop; //!< Packets dropped by the network interface (e.g. not enough buffers) (i.e. pcap_stats.ps_ifdrop) + uint32 krnldrop; //!< Packets dropped by the kernel filter (i.e. pcap_stats.ps_drop) + uint32 svrcapt; //!< Packets captured by the RPCAP daemon and sent on the network +}; + + +//! Structure that is needed to set sampling parameters +struct rpcap_sampling +{ + uint8 method; //!< Sampling method + uint8 dummy1; //!< Must be zero + uint16 dummy2; //!< Must be zero + uint32 value; //!< Parameter related to the sampling method +}; + + + +// Messages field coding +#define RPCAP_MSG_ERROR 1 /*!< Message that keeps an error notification */ +#define RPCAP_MSG_FINDALLIF_REQ 2 /*!< Request to list all the remote interfaces */ +#define RPCAP_MSG_OPEN_REQ 3 /*!< Request to open a remote device */ +#define RPCAP_MSG_STARTCAP_REQ 4 /*!< Request to start a capture on a remote device */ +#define RPCAP_MSG_UPDATEFILTER_REQ 5 /*!< Send a compiled filter into the remote device */ +#define RPCAP_MSG_CLOSE 6 /*!< Close the connection with the remote peer */ +#define RPCAP_MSG_PACKET 7 /*!< This is a 'data' message, which carries a network packet */ +#define RPCAP_MSG_AUTH_REQ 8 /*!< Message that keeps the authentication parameters */ +#define RPCAP_MSG_STATS_REQ 9 /*!< It requires to have network statistics */ +#define RPCAP_MSG_ENDCAP_REQ 10 /*!< Stops the current capture, keeping the device open */ +#define RPCAP_MSG_SETSAMPLING_REQ 11 /*!< Sset sampling parameters */ + +#define RPCAP_MSG_FINDALLIF_REPLY (128+RPCAP_MSG_FINDALLIF_REQ) /*!< Keeps the list of all the remote interfaces */ +#define RPCAP_MSG_OPEN_REPLY (128+RPCAP_MSG_OPEN_REQ) /*!< The remote device has been opened correctly */ +#define RPCAP_MSG_STARTCAP_REPLY (128+RPCAP_MSG_STARTCAP_REQ) /*!< The capture is staarting correctly */ +#define RPCAP_MSG_UPDATEFILTER_REPLY (128+RPCAP_MSG_UPDATEFILTER_REQ) /*!< The filter has been applied correctly on the remote device */ +#define RPCAP_MSG_AUTH_REPLY (128+RPCAP_MSG_AUTH_REQ) /*!< Sends a message that says 'ok, authorization successful' */ +#define RPCAP_MSG_STATS_REPLY (128+RPCAP_MSG_STATS_REQ) /*!< Message that keeps the network statistics */ +#define RPCAP_MSG_ENDCAP_REPLY (128+RPCAP_MSG_ENDCAP_REQ) /*!< Confirms that the capture stopped succesfully */ +#define RPCAP_MSG_SETSAMPLING_REPLY (128+RPCAP_MSG_SETSAMPLING_REQ) /*!< Confirms that the capture stopped succesfully */ + +#define RPCAP_STARTCAPREQ_FLAG_PROMISC 1 /*!< Enables promiscuous mode (default: disabled) */ +#define RPCAP_STARTCAPREQ_FLAG_DGRAM 2 /*!< Use a datagram (i.e. UDP) connection for the data stream (default: use TCP)*/ +#define RPCAP_STARTCAPREQ_FLAG_SERVEROPEN 4 /*!< The server has to open the data connection toward the client */ +#define RPCAP_STARTCAPREQ_FLAG_INBOUND 8 /*!< Capture only inbound packets (take care: the flag has no effects with promiscuous enabled) */ +#define RPCAP_STARTCAPREQ_FLAG_OUTBOUND 16 /*!< Capture only outbound packets (take care: the flag has no effects with promiscuous enabled) */ + +#define RPCAP_UPDATEFILTER_BPF 1 /*!< This code tells us that the filter is encoded with the BPF/NPF syntax */ + + +// Network error codes +#define PCAP_ERR_NETW 1 /*!< Network error */ +#define PCAP_ERR_INITTIMEOUT 2 /*!< The RPCAP initial timeout has expired */ +#define PCAP_ERR_AUTH 3 /*!< Generic authentication error */ +#define PCAP_ERR_FINDALLIF 4 /*!< Generic findalldevs error */ +#define PCAP_ERR_NOREMOTEIF 5 /*!< The findalldevs was ok, but the remote end had no interfaces to list */ +#define PCAP_ERR_OPEN 6 /*!< Generic pcap_open error */ +#define PCAP_ERR_UPDATEFILTER 7 /*!< Generic updatefilter error */ +#define PCAP_ERR_GETSTATS 8 /*!< Generic pcap_stats error */ +#define PCAP_ERR_READEX 9 /*!< Generic pcap_next_ex error */ +#define PCAP_ERR_HOSTNOAUTH 10 /*!< The host is not authorized to connect to this server */ +#define PCAP_ERR_REMOTEACCEPT 11 /*!< Generic pcap_remoteaccept error */ +#define PCAP_ERR_STARTCAPTURE 12 /*!< Generic pcap_startcapture error */ +#define PCAP_ERR_ENDCAPTURE 13 /*!< Generic pcap_endcapture error */ +#define PCAP_ERR_RUNTIMETIMEOUT 14 /*!< The RPCAP run-time timeout has expired */ +#define PCAP_ERR_SETSAMPLING 15 /*!< Error diring the settings of sampling parameters */ +#define PCAP_ERR_WRONGMSG 16 /*!< The other end endpoint sent a message which has not been recognized */ +#define PCAP_ERR_WRONGVER 17 /*!< The other end endpoint ahs a version number that is not compatible with our */ +/*! + \} +*/ // end of private documentation + + + + + + +/********************************************************* + * * + * Exported funtion prototypes * + * * + *********************************************************/ +pcap_t *pcap_opensource_remote(const char *source, struct pcap_rmtauth *auth, char *errbuf); +int pcap_startcapture_remote(pcap_t *fp); + +int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data); +int pcap_read_remote(pcap_t *p, int cnt, pcap_handler callback, u_char *user); +int pcap_updatefilter_remote(pcap_t *fp, struct bpf_program *prog); +int pcap_setfilter_remote(pcap_t *fp, struct bpf_program *prog); +int pcap_stats_remote(pcap_t *p, struct pcap_stat *ps); +int pcap_setsampling_remote(pcap_t *p); +struct pcap_stat *pcap_stats_ex_remote(pcap_t *p); +void pcap_close_remote(pcap_t *p); + +void rpcap_createhdr(struct rpcap_header *header, uint8 type, uint16 value, uint32 length); +int rpcap_deseraddr(struct sockaddr_storage *sockaddrin, struct sockaddr_storage **sockaddrout, char *errbuf); +int rpcap_checkmsg(char *errbuf, SOCKET sock, struct rpcap_header *header, uint8 first, ...); +int rpcap_senderror(SOCKET sock, char *error, unsigned short errcode, char *errbuf); +int rpcap_sendauth(SOCKET sock, struct pcap_rmtauth *auth, char *errbuf); + +int rpcap_remoteact_getsock(const char *host, char *errbuf); + +#endif + diff --git a/winpcap/wpcap/libpcap/pcap-septel.c b/winpcap/wpcap/libpcap/pcap-septel.c new file mode 100644 index 0000000..5169ec0 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-septel.c @@ -0,0 +1,307 @@ +/* + * pcap-septel.c: Packet capture interface for Intel/Septel card. + * + * The functionality of this code attempts to mimic that of pcap-linux as much + * as possible. This code is compiled in several different ways depending on + * whether SEPTEL_ONLY and HAVE_SEPTEL_API are defined. If HAVE_SEPTEL_API is + * not defined it should not get compiled in, otherwise if SEPTEL_ONLY is + * defined then the 'septel_' function calls are renamed to 'pcap_' + * equivalents. If SEPTEL_ONLY is not defined then nothing is altered - the + * septel_ functions will be called as required from their + * pcap-linux/equivalents. + * + * Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY + * (+961 3 485243) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/pcap-septel.c,v 1.1.2.2 2005/06/21 01:03:23 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "pcap-int.h" + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_SEPTEL_API +#include +#include +#include +#include +#include +#endif /* HAVE_SEPTEL_API */ + +#ifdef SEPTEL_ONLY +/* This code is required when compiling for a Septel device only. */ +#include "pcap-septel.h" + +/* Replace dag function names with pcap equivalent. */ +#define septel_open_live pcap_open_live +#define septel_platform_finddevs pcap_platform_finddevs +#endif /* SEPTEL_ONLY */ + +static int septel_setfilter(pcap_t *p, struct bpf_program *fp); +static int septel_stats(pcap_t *p, struct pcap_stat *ps); +static int septel_setnonblock(pcap_t *p, int nonblock, char *errbuf); + +static void septel_platform_close(pcap_t *p) { + +} + + + +/* + * Read at most max_packets from the capture queue and call the callback + * for each of them. Returns the number of packets handled, -1 if an + * error occured, or -2 if we were told to break out of the loop. + */ +static int septel_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { + + HDR *h; + MSG *m; + int processed = 0 ; + int t = 0 ; + + /* identifier for the message queue of the module(upe) from which we are capturing + * packets.These IDs are defined in system.txt . By default it is set to 0x2d + * so change it to 0xdd for technical reason and therefore the module id for upe becomes: + * LOCAL 0xdd * upe - Example user part task */ + unsigned int id = 0xdd; + + /* process the packets */ + do { + + unsigned short packet_len = 0; + int caplen = 0; + int counter = 0; + struct pcap_pkthdr pcap_header; + u_char *dp ; + + /* + * Has "pcap_breakloop()" been called? + */ +loop: + if (p->break_loop) { + /* + * Yes - clear the flag that indicates that + * it has, and return -2 to indicate that + * we were told to break out of the loop. + */ + p->break_loop = 0; + return -2; + } + + /*repeat until a packet is read + *a NULL message means : + * when no packet is in queue or all packets in queue already read */ + do { + /* receive packet in non-blocking mode + * GCT_grab is defined in the septel library software */ + h = GCT_grab(id); + + m = (MSG*)h; + /* a couter is added here to avoid an infinite loop + * that will cause our capture program GUI to freeze while waiting + * for a packet*/ + counter++ ; + + } + while ((m == NULL)&& (counter< 100)) ; + + if (m != NULL) { + + t = h->type ; + + /* catch only messages with type = 0xcf00 or 0x8f01 corrsponding to ss7 messages*/ + /* XXX = why not use API_MSG_TX_REQ for 0xcf00 and API_MSG_RX_IND + * for 0x8f01? */ + if ((t != 0xcf00) && (t != 0x8f01)) { + relm(h); + goto loop ; + } + + /* XXX - is API_MSG_RX_IND for an MTP2 or MTP3 message? */ + dp = get_param(m);/* get pointer to MSG parameter area (m->param) */ + packet_len = m->len; + caplen = p->snapshot ; + + + if (caplen > packet_len) { + + caplen = packet_len; + } + /* Run the packet filter if there is one. */ + if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) { + + + /* get a time stamp , consisting of : + * + * pcap_header.ts.tv_sec: + * ---------------------- + * a UNIX format time-in-seconds when he packet was captured, + * i.e. the number of seconds since Epoch time (January 1,1970, 00:00:00 GMT) + * + * pcap_header.ts.tv_usec : + * ------------------------ + * the number of microseconds since that second + * when the packet was captured + */ + + (void)gettimeofday(&pcap_header.ts, NULL); + + /* Fill in our own header data */ + pcap_header.caplen = caplen; + pcap_header.len = packet_len; + + /* Count the packet. */ + p->md.stat.ps_recv++; + + /* Call the user supplied callback function */ + callback(user, &pcap_header, dp); + + processed++ ; + + } + /* after being processed the packet must be + *released in order to receive another one */ + relm(h); + }else + processed++; + + } + while (processed < cnt) ; + + return processed ; +} + + +static int +septel_inject(pcap_t *handle, const void *buf _U_, size_t size _U_) +{ + strlcpy(handle->errbuf, "Sending packets isn't supported on Septel cards", + PCAP_ERRBUF_SIZE); + return (-1); +} + +/* + * Get a handle for a live capture from the given Septel device. Always pass a NULL device + * The promisc flag is ignored because Septel cards have built-in tracing. + * The to_ms parameter is also ignored as it is + * not supported in hardware. + * + * See also pcap(3). + */ +pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) { + pcap_t *handle; + + handle = malloc(sizeof(*handle)); + if (handle == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno)); + return NULL; + } + + /* Initialize some components of the pcap structure. */ + + memset(handle, 0, sizeof(*handle)); + + handle->snapshot = snaplen; + + handle->linktype = DLT_MTP2; + + handle->bufsize = 0; + + /* + * "select()" and "poll()" don't work on Septel queues + */ + handle->selectable_fd = -1; + + handle->read_op = septel_read; + handle->inject_op = septel_inject; + handle->setfilter_op = septel_setfilter; + handle->set_datalink_op = NULL; /* can't change data link type */ + handle->getnonblock_op = pcap_getnonblock_fd; + handle->setnonblock_op = septel_setnonblock; + handle->stats_op = septel_stats; + handle->close_op = septel_platform_close; + + return handle; + +fail: + if (handle != NULL) { + free(handle); + } + + return NULL; +} + +static int septel_stats(pcap_t *p, struct pcap_stat *ps) { + /*p->md.stat.ps_recv = 0;*/ + /*p->md.stat.ps_drop = 0;*/ + + *ps = p->md.stat; + + return 0; +} + + +int +septel_platform_finddevs(pcap_if_t **devlistp, char *errbuf) +{ +unsigned char *p; + const char description[512]= "Intel/Septel device"; + char name[512]="septel" ; + int ret = 0; + pcap_add_if(devlistp,name,0,description,errbuf); + + return (ret); +} + + +/* + * Installs the given bpf filter program in the given pcap structure. There is + * no attempt to store the filter in kernel memory as that is not supported + * with Septel cards. + */ +static int septel_setfilter(pcap_t *p, struct bpf_program *fp) { + if (!p) + return -1; + if (!fp) { + strncpy(p->errbuf, "setfilter: No filter specified", + sizeof(p->errbuf)); + return -1; + } + + /* Make our private copy of the filter */ + + if (install_bpf_program(p, fp) < 0) { + snprintf(p->errbuf, sizeof(p->errbuf), + "malloc: %s", pcap_strerror(errno)); + return -1; + } + + p->md.use_bpf = 0; + + return (0); +} + + +static int +septel_setnonblock(pcap_t *p, int nonblock, char *errbuf) +{ + return (0); +} diff --git a/winpcap/wpcap/libpcap/pcap-septel.h b/winpcap/wpcap/libpcap/pcap-septel.h new file mode 100644 index 0000000..1de6377 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-septel.h @@ -0,0 +1,15 @@ +/* + * pcap-septel.c: Packet capture interface for Intel Septel card + * + * The functionality of this code attempts to mimic that of pcap-linux as much + * as possible. This code is only needed when compiling in the Intel/Septel + * card code at the same time as another type of device. + * + * Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY + * (+961 3 485343); + * + * @(#) $Header: /tcpdump/master/libpcap/pcap-septel.h,v 1.1.2.1 2005/06/20 21:30:19 guy Exp $ + */ + +pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf); + diff --git a/winpcap/wpcap/libpcap/pcap-snit.c b/winpcap/wpcap/libpcap/pcap-snit.c new file mode 100644 index 0000000..60abe64 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-snit.c @@ -0,0 +1,419 @@ +/* + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Modifications made to accommodate the new SunOS4.0 NIT facility by + * Micky Liu, micky@cunixc.cc.columbia.edu, Columbia University in May, 1989. + * This module now handles the STREAMS based NIT. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.72.2.1 2005/05/03 18:54:38 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "pcap-int.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +/* + * The chunk size for NIT. This is the amount of buffering + * done for read calls. + */ +#define CHUNKSIZE (2*1024) + +/* + * The total buffer space used by NIT. + */ +#define BUFSPACE (4*CHUNKSIZE) + +/* Forwards */ +static int nit_setflags(int, int, int, char *); + +static int +pcap_stats_snit(pcap_t *p, struct pcap_stat *ps) +{ + + /* + * "ps_recv" counts packets handed to the filter, not packets + * that passed the filter. As filtering is done in userland, + * this does not include packets dropped because we ran out + * of buffer space. + * + * "ps_drop" counts packets dropped inside the "/dev/nit" + * device because of flow control requirements or resource + * exhaustion; it doesn't count packets dropped by the + * interface driver, or packets dropped upstream. As filtering + * is done in userland, it counts packets regardless of whether + * they would've passed the filter. + * + * These statistics don't include packets not yet read from the + * kernel by libpcap or packets not yet read from libpcap by the + * application. + */ + *ps = p->md.stat; + return (0); +} + +static int +pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ + register int cc, n; + register struct bpf_insn *fcode = p->fcode.bf_insns; + register u_char *bp, *cp, *ep; + register struct nit_bufhdr *hdrp; + register struct nit_iftime *ntp; + register struct nit_iflen *nlp; + register struct nit_ifdrops *ndp; + register int caplen; + + cc = p->cc; + if (cc == 0) { + cc = read(p->fd, (char *)p->buffer, p->bufsize); + if (cc < 0) { + if (errno == EWOULDBLOCK) + return (0); + snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s", + pcap_strerror(errno)); + return (-1); + } + bp = p->buffer; + } else + bp = p->bp; + + /* + * loop through each snapshot in the chunk + */ + n = 0; + ep = bp + cc; + while (bp < ep) { + /* + * Has "pcap_breakloop()" been called? + * If so, return immediately - if we haven't read any + * packets, clear the flag and return -2 to indicate + * that we were told to break out of the loop, otherwise + * leave the flag set, so that the *next* call will break + * out of the loop without having read any packets, and + * return the number of packets we've processed so far. + */ + if (p->break_loop) { + if (n == 0) { + p->break_loop = 0; + return (-2); + } else { + p->bp = bp; + p->cc = ep - bp; + return (n); + } + } + + ++p->md.stat.ps_recv; + cp = bp; + + /* get past NIT buffer */ + hdrp = (struct nit_bufhdr *)cp; + cp += sizeof(*hdrp); + + /* get past NIT timer */ + ntp = (struct nit_iftime *)cp; + cp += sizeof(*ntp); + + ndp = (struct nit_ifdrops *)cp; + p->md.stat.ps_drop = ndp->nh_drops; + cp += sizeof *ndp; + + /* get past packet len */ + nlp = (struct nit_iflen *)cp; + cp += sizeof(*nlp); + + /* next snapshot */ + bp += hdrp->nhb_totlen; + + caplen = nlp->nh_pktlen; + if (caplen > p->snapshot) + caplen = p->snapshot; + + if (bpf_filter(fcode, cp, nlp->nh_pktlen, caplen)) { + struct pcap_pkthdr h; + h.ts = ntp->nh_timestamp; + h.len = nlp->nh_pktlen; + h.caplen = caplen; + (*callback)(user, &h, cp); + if (++n >= cnt && cnt >= 0) { + p->cc = ep - bp; + p->bp = bp; + return (n); + } + } + } + p->cc = 0; + return (n); +} + +static int +pcap_inject_snit(pcap_t *p, const void *buf, size_t size) +{ + struct strbuf ctl, data; + + /* + * XXX - can we just do + * + ret = write(pd->f, buf, size); + */ + ctl.len = sizeof(*sa); /* XXX - what was this? */ + ctl.buf = (char *)sa; + data.buf = buf; + data.len = size; + ret = putmsg(p->fd, &ctl, &data); + if (ret == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", + pcap_strerror(errno)); + return (-1); + } + return (ret); +} + +static int +nit_setflags(int fd, int promisc, int to_ms, char *ebuf) +{ + bpf_u_int32 flags; + struct strioctl si; + struct timeval timeout; + + si.ic_timout = INFTIM; + if (to_ms != 0) { + timeout.tv_sec = to_ms / 1000; + timeout.tv_usec = (to_ms * 1000) % 1000000; + si.ic_cmd = NIOCSTIME; + si.ic_len = sizeof(timeout); + si.ic_dp = (char *)&timeout; + if (ioctl(fd, I_STR, (char *)&si) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSTIME: %s", + pcap_strerror(errno)); + return (-1); + } + } + flags = NI_TIMESTAMP | NI_LEN | NI_DROPS; + if (promisc) + flags |= NI_PROMISC; + si.ic_cmd = NIOCSFLAGS; + si.ic_len = sizeof(flags); + si.ic_dp = (char *)&flags; + if (ioctl(fd, I_STR, (char *)&si) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSFLAGS: %s", + pcap_strerror(errno)); + return (-1); + } + return (0); +} + +pcap_t * +pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, + char *ebuf) +{ + struct strioctl si; /* struct for ioctl() */ + struct ifreq ifr; /* interface request struct */ + int chunksize = CHUNKSIZE; + int fd; + static char dev[] = "/dev/nit"; + register pcap_t *p; + + p = (pcap_t *)malloc(sizeof(*p)); + if (p == NULL) { + strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); + return (NULL); + } + + if (snaplen < 96) + /* + * NIT requires a snapshot length of at least 96. + */ + snaplen = 96; + + memset(p, 0, sizeof(*p)); + /* + * Initially try a read/write open (to allow the inject + * method to work). If that fails due to permission + * issues, fall back to read-only. This allows a + * non-root user to be granted specific access to pcap + * capabilities via file permissions. + * + * XXX - we should have an API that has a flag that + * controls whether to open read-only or read-write, + * so that denial of permission to send (or inability + * to send, if sending packets isn't supported on + * the device in question) can be indicated at open + * time. + */ + p->fd = fd = open(dev, O_RDWR); + if (fd < 0 && errno == EACCES) + p->fd = fd = open(dev, O_RDONLY); + if (fd < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dev, + pcap_strerror(errno)); + goto bad; + } + + /* arrange to get discrete messages from the STREAM and use NIT_BUF */ + if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s", + pcap_strerror(errno)); + goto bad; + } + if (ioctl(fd, I_PUSH, "nbuf") < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "push nbuf: %s", + pcap_strerror(errno)); + goto bad; + } + /* set the chunksize */ + si.ic_cmd = NIOCSCHUNK; + si.ic_timout = INFTIM; + si.ic_len = sizeof(chunksize); + si.ic_dp = (char *)&chunksize; + if (ioctl(fd, I_STR, (char *)&si) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s", + pcap_strerror(errno)); + goto bad; + } + + /* request the interface */ + strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; + si.ic_cmd = NIOCBIND; + si.ic_len = sizeof(ifr); + si.ic_dp = (char *)𝔦 + if (ioctl(fd, I_STR, (char *)&si) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s", + ifr.ifr_name, pcap_strerror(errno)); + goto bad; + } + + /* set the snapshot length */ + si.ic_cmd = NIOCSSNAP; + si.ic_len = sizeof(snaplen); + si.ic_dp = (char *)&snaplen; + if (ioctl(fd, I_STR, (char *)&si) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s", + pcap_strerror(errno)); + goto bad; + } + p->snapshot = snaplen; + if (nit_setflags(p->fd, promisc, to_ms, ebuf) < 0) + goto bad; + + (void)ioctl(fd, I_FLUSH, (char *)FLUSHR); + /* + * NIT supports only ethernets. + */ + p->linktype = DLT_EN10MB; + + p->bufsize = BUFSPACE; + p->buffer = (u_char *)malloc(p->bufsize); + if (p->buffer == NULL) { + strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); + goto bad; + } + + /* + * "p->fd" is an FD for a STREAMS device, so "select()" and + * "poll()" should work on it. + */ + p->selectable_fd = p->fd; + + /* + * This is (presumably) a real Ethernet capture; give it a + * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so + * that an application can let you choose it, in case you're + * capturing DOCSIS traffic that a Cisco Cable Modem + * Termination System is putting out onto an Ethernet (it + * doesn't put an Ethernet header onto the wire, it puts raw + * DOCSIS frames out on the wire inside the low-level + * Ethernet framing). + */ + p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); + /* + * If that fails, just leave the list empty. + */ + if (p->dlt_list != NULL) { + p->dlt_list[0] = DLT_EN10MB; + p->dlt_list[1] = DLT_DOCSIS; + p->dlt_count = 2; + } + + p->read_op = pcap_read_snit; + p->inject_op = pcap_inject_snit; + p->setfilter_op = install_bpf_program; /* no kernel filtering */ + p->setdirection_op = NULL; /* Not implemented. */ + p->set_datalink_op = NULL; /* can't change data link type */ + p->getnonblock_op = pcap_getnonblock_fd; + p->setnonblock_op = pcap_setnonblock_fd; + p->stats_op = pcap_stats_snit; + p->close_op = pcap_close_common; + + return (p); + bad: + if (fd >= 0) + close(fd); + free(p); + return (NULL); +} + +int +pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) +{ + return (0); +} diff --git a/winpcap/wpcap/libpcap/pcap-snoop.c b/winpcap/wpcap/libpcap/pcap-snoop.c new file mode 100644 index 0000000..f6425f1 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-snoop.c @@ -0,0 +1,405 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.54.2.1 2005/05/03 18:54:38 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "pcap-int.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +static int +pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ + int cc; + register struct snoopheader *sh; + register u_int datalen; + register u_int caplen; + register u_char *cp; + +again: + /* + * Has "pcap_breakloop()" been called? + */ + if (p->break_loop) { + /* + * Yes - clear the flag that indicates that it + * has, and return -2 to indicate that we were + * told to break out of the loop. + */ + p->break_loop = 0; + return (-2); + } + cc = read(p->fd, (char *)p->buffer, p->bufsize); + if (cc < 0) { + /* Don't choke when we get ptraced */ + switch (errno) { + + case EINTR: + goto again; + + case EWOULDBLOCK: + return (0); /* XXX */ + } + snprintf(p->errbuf, sizeof(p->errbuf), + "read: %s", pcap_strerror(errno)); + return (-1); + } + sh = (struct snoopheader *)p->buffer; + datalen = sh->snoop_packetlen; + + /* + * XXX - Sigh, snoop_packetlen is a 16 bit quantity. If we + * got a short length, but read a full sized snoop pakcet, + * assume we overflowed and add back the 64K... + */ + if (cc == (p->snapshot + sizeof(struct snoopheader)) && + (datalen < p->snapshot)) + datalen += (64 * 1024); + + caplen = (datalen < p->snapshot) ? datalen : p->snapshot; + cp = (u_char *)(sh + 1) + p->offset; /* XXX */ + + /* + * XXX unfortunately snoop loopback isn't exactly like + * BSD's. The address family is encoded in the first 2 + * bytes rather than the first 4 bytes! Luckily the last + * two snoop loopback bytes are zeroed. + */ + if (p->linktype == DLT_NULL && *((short *)(cp + 2)) == 0) { + u_int *uip = (u_int *)cp; + *uip >>= 16; + } + + if (p->fcode.bf_insns == NULL || + bpf_filter(p->fcode.bf_insns, cp, datalen, caplen)) { + struct pcap_pkthdr h; + ++p->md.stat.ps_recv; + h.ts.tv_sec = sh->snoop_timestamp.tv_sec; + h.ts.tv_usec = sh->snoop_timestamp.tv_usec; + h.len = datalen; + h.caplen = caplen; + (*callback)(user, &h, cp); + return (1); + } + return (0); +} + +static int +pcap_inject_snoop(pcap_t *p, const void *buf, size_t size) +{ + int ret; + + /* + * XXX - libnet overwrites the source address with what I + * presume is the interface's address; is that required? + */ + ret = write(p->fd, buf, size); + if (ret == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", + pcap_strerror(errno)); + return (-1); + } + return (ret); +} + +static int +pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps) +{ + register struct rawstats *rs; + struct rawstats rawstats; + + rs = &rawstats; + memset(rs, 0, sizeof(*rs)); + if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) { + snprintf(p->errbuf, sizeof(p->errbuf), + "SIOCRAWSTATS: %s", pcap_strerror(errno)); + return (-1); + } + + /* + * "ifdrops" are those dropped by the network interface + * due to resource shortages or hardware errors. + * + * "sbdrops" are those dropped due to socket buffer limits. + * + * As filter is done in userland, "sbdrops" counts packets + * regardless of whether they would've passed the filter. + * + * XXX - does this count *all* Snoop or Drain sockets, + * rather than just this socket? If not, why does it have + * both Snoop and Drain statistics? + */ + p->md.stat.ps_drop = + rs->rs_snoop.ss_ifdrops + rs->rs_snoop.ss_sbdrops + + rs->rs_drain.ds_ifdrops + rs->rs_drain.ds_sbdrops; + + /* + * "ps_recv" counts only packets that passed the filter. + * As filtering is done in userland, this does not include + * packets dropped because we ran out of buffer space. + */ + *ps = p->md.stat; + return (0); +} + +/* XXX can't disable promiscuous */ +pcap_t * +pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, + char *ebuf) +{ + int fd; + struct sockaddr_raw sr; + struct snoopfilter sf; + u_int v; + int ll_hdrlen; + int snooplen; + pcap_t *p; + struct ifreq ifr; + + p = (pcap_t *)malloc(sizeof(*p)); + if (p == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + return (NULL); + } + memset(p, 0, sizeof(*p)); + fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP); + if (fd < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop socket: %s", + pcap_strerror(errno)); + goto bad; + } + p->fd = fd; + memset(&sr, 0, sizeof(sr)); + sr.sr_family = AF_RAW; + (void)strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname)); + if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop bind: %s", + pcap_strerror(errno)); + goto bad; + } + memset(&sf, 0, sizeof(sf)); + if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s", + pcap_strerror(errno)); + goto bad; + } + v = 64 * 1024; + (void)setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(v)); + /* + * XXX hack - map device name to link layer type + */ + if (strncmp("et", device, 2) == 0 || /* Challenge 10 Mbit */ + strncmp("ec", device, 2) == 0 || /* Indigo/Indy 10 Mbit, + O2 10/100 */ + strncmp("ef", device, 2) == 0 || /* O200/2000 10/100 Mbit */ + strncmp("eg", device, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */ + strncmp("gfe", device, 3) == 0 || /* GIO 100 Mbit */ + strncmp("fxp", device, 3) == 0 || /* Challenge VME Enet */ + strncmp("ep", device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */ + strncmp("vfe", device, 3) == 0 || /* Challenge VME 100Mbit */ + strncmp("fa", device, 2) == 0 || + strncmp("qaa", device, 3) == 0 || + strncmp("cip", device, 3) == 0 || + strncmp("el", device, 2) == 0) { + p->linktype = DLT_EN10MB; + p->offset = RAW_HDRPAD(sizeof(struct ether_header)); + ll_hdrlen = sizeof(struct ether_header); + /* + * This is (presumably) a real Ethernet capture; give it a + * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so + * that an application can let you choose it, in case you're + * capturing DOCSIS traffic that a Cisco Cable Modem + * Termination System is putting out onto an Ethernet (it + * doesn't put an Ethernet header onto the wire, it puts raw + * DOCSIS frames out on the wire inside the low-level + * Ethernet framing). + * + * XXX - are there any sorts of "fake Ethernet" that have + * Ethernet link-layer headers but that *shouldn't offer + * DLT_DOCSIS as a Cisco CMTS won't put traffic onto it + * or get traffic bridged onto it? "el" is for ATM LANE + * Ethernet devices, so that might be the case for them; + * the same applies for "qaa" classical IP devices. If + * "fa" devices are for FORE SPANS, that'd apply to them + * as well; what are "cip" devices - some other ATM + * Classical IP devices? + */ + p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); + /* + * If that fails, just leave the list empty. + */ + if (p->dlt_list != NULL) { + p->dlt_list[0] = DLT_EN10MB; + p->dlt_list[1] = DLT_DOCSIS; + p->dlt_count = 2; + } + } else if (strncmp("ipg", device, 3) == 0 || + strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */ + strncmp("xpi", device, 3) == 0) { + p->linktype = DLT_FDDI; + p->offset = 3; /* XXX yeah? */ + ll_hdrlen = 13; + } else if (strncmp("ppp", device, 3) == 0) { + p->linktype = DLT_RAW; + ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */ + } else if (strncmp("qfa", device, 3) == 0) { + p->linktype = DLT_IP_OVER_FC; + ll_hdrlen = 24; + } else if (strncmp("pl", device, 2) == 0) { + p->linktype = DLT_RAW; + ll_hdrlen = 0; /* Cray UNICOS/mp pseudo link */ + } else if (strncmp("lo", device, 2) == 0) { + p->linktype = DLT_NULL; + ll_hdrlen = 4; + } else { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "snoop: unknown physical layer type"); + goto bad; + } +#ifdef SIOCGIFMTU + /* + * XXX - IRIX appears to give you an error if you try to set the + * capture length to be greater than the MTU, so let's try to get + * the MTU first and, if that succeeds, trim the snap length + * to be no greater than the MTU. + */ + (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s", + pcap_strerror(errno)); + goto bad; + } + /* + * OK, we got it. + * + * XXX - some versions of IRIX 6.5 define "ifr_mtu" and have an + * "ifru_metric" member of the "ifr_ifru" union in an "ifreq" + * structure, others don't. + * + * I've no idea what's going on, so, if "ifr_mtu" isn't defined, + * we define it as "ifr_metric", as using that field appears to + * work on the versions that lack "ifr_mtu" (and, on those that + * don't lack it, "ifru_metric" and "ifru_mtu" are both "int" + * members of the "ifr_ifru" union, which suggests that they + * may be interchangeable in this case). + */ +#ifndef ifr_mtu +#define ifr_mtu ifr_metric +#endif + if (snaplen > ifr.ifr_mtu + ll_hdrlen) + snaplen = ifr.ifr_mtu + ll_hdrlen; +#endif + + /* + * The argument to SIOCSNOOPLEN is the number of link-layer + * payload bytes to capture - it doesn't count link-layer + * header bytes. + */ + snooplen = snaplen - ll_hdrlen; + if (snooplen < 0) + snooplen = 0; + if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s", + pcap_strerror(errno)); + goto bad; + } + p->snapshot = snaplen; + v = 1; + if (ioctl(fd, SIOCSNOOPING, &v) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s", + pcap_strerror(errno)); + goto bad; + } + + p->bufsize = 4096; /* XXX */ + p->buffer = (u_char *)malloc(p->bufsize); + if (p->buffer == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + goto bad; + } + + /* + * "p->fd" is a socket, so "select()" should work on it. + */ + p->selectable_fd = p->fd; + + p->read_op = pcap_read_snoop; + p->inject_op = pcap_inject_snoop; + p->setfilter_op = install_bpf_program; /* no kernel filtering */ + p->setdirection_op = NULL; /* Not implemented. */ + p->set_datalink_op = NULL; /* can't change data link type */ + p->getnonblock_op = pcap_getnonblock_fd; + p->setnonblock_op = pcap_setnonblock_fd; + p->stats_op = pcap_stats_snoop; + p->close_op = pcap_close_common; + + return (p); + bad: + (void)close(fd); + /* + * Get rid of any link-layer type list we allocated. + */ + if (p->dlt_list != NULL) + free(p->dlt_list); + free(p); + return (NULL); +} + +int +pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) +{ + return (0); +} diff --git a/winpcap/wpcap/libpcap/pcap-stdinc.h b/winpcap/wpcap/libpcap/pcap-stdinc.h new file mode 100644 index 0000000..1281024 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-stdinc.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define SIZEOF_CHAR 1 +#define SIZEOF_SHORT 2 +#define SIZEOF_INT 4 +#ifndef _MSC_EXTENSIONS +#define SIZEOF_LONG_LONG 8 +#endif + +/* + * Avoids a compiler warning in case this was already defined + * (someone defined _WINSOCKAPI_ when including 'windows.h', in order + * to prevent it from including 'winsock.h') + */ +#ifdef _WINSOCKAPI_ +#undef _WINSOCKAPI_ +#endif +#include + +#include + +#include "bittypes.h" +#include +#include + +#ifndef __MINGW32__ +#include "IP6_misc.h" +#endif + +#define caddr_t char* + +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#define inline __inline diff --git a/winpcap/wpcap/libpcap/pcap-win32.c b/winpcap/wpcap/libpcap/pcap-win32.c new file mode 100644 index 0000000..b0ce94e --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap-win32.c @@ -0,0 +1,867 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.25.2.5 2006/08/09 19:18:41 gianluca Exp $ (LBL)"; +#endif + +#include +#include +#include +#ifdef HAVE_DAG_API +#include +#include +#endif /* HAVE_DAG_API */ +#ifdef __MINGW32__ +int* _errno(); +#define errno (*_errno()) +#endif /* __MINGW32__ */ + +#ifdef HAVE_REMOTE +#include +#endif /* HAVE_REMOTE */ + +static int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *); +static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *); +static int pcap_getnonblock_win32(pcap_t *, char *); +static int pcap_setnonblock_win32(pcap_t *, int, char *); + +#define PcapBufSize 256000 /*dimension of the buffer in the pcap_t structure*/ +#define SIZE_BUF 1000000 + +/* Equivalent to ntohs(), but a lot faster under Windows */ +#define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8) + +/* + * Header that the WinPcap driver associates to the packets. + * Once was in bpf.h + */ +struct bpf_hdr { + struct timeval bh_tstamp; /* time stamp */ + bpf_u_int32 bh_caplen; /* length of captured portion */ + bpf_u_int32 bh_datalen; /* original length of packet */ + u_short bh_hdrlen; /* length of bpf header (this struct + plus alignment padding) */ +}; + +/* Start winsock */ +int +wsockinit() +{ + WORD wVersionRequested; + WSADATA wsaData; + int err; + wVersionRequested = MAKEWORD( 1, 1); + err = WSAStartup( wVersionRequested, &wsaData ); + if ( err != 0 ) + { + return -1; + } + return 0; +} + + +static int +pcap_stats_win32(pcap_t *p, struct pcap_stat *ps) +{ + + if(PacketGetStats(p->adapter, (struct bpf_stat*)ps) != TRUE){ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStats error: %s", pcap_win32strerror()); + return -1; + } + + return 0; +} + +static int +pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ + int cc; + int n = 0; + register u_char *bp, *ep; + +#ifdef HAVE_REMOTE + static int samp_npkt; // parameter needed for sampling, with '1 out of N' method has been requested + static struct timeval samp_time; // parameter needed for sampling, with '1 every N ms' method has been requested +#endif /* HAVE_REMOTE */ + + cc = p->cc; + if (p->cc == 0) { + /* + * Has "pcap_breakloop()" been called? + */ + if (p->break_loop) { + /* + * Yes - clear the flag that indicates that it + * has, and return -2 to indicate that we were + * told to break out of the loop. + */ + p->break_loop = 0; + return (-2); + } + + /* capture the packets */ + if(PacketReceivePacket(p->adapter,p->Packet,TRUE)==FALSE){ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed"); + return (-1); + } + + cc = p->Packet->ulBytesReceived; + + bp = p->Packet->Buffer; + } + else + bp = p->bp; + + /* + * Loop through each packet. + */ +#define bhp ((struct bpf_hdr *)bp) + ep = bp + cc; + while (1) { + register int caplen, hdrlen; + + /* + * Has "pcap_breakloop()" been called? + * If so, return immediately - if we haven't read any + * packets, clear the flag and return -2 to indicate + * that we were told to break out of the loop, otherwise + * leave the flag set, so that the *next* call will break + * out of the loop without having read any packets, and + * return the number of packets we've processed so far. + */ + if (p->break_loop) { + if (n == 0) { + p->break_loop = 0; + return (-2); + } else { + p->bp = bp; + p->cc = ep - bp; + return (n); + } + } + if (bp >= ep) + break; + + caplen = bhp->bh_caplen; + hdrlen = bhp->bh_hdrlen; + +#ifdef HAVE_REMOTE + if (p->rmt_samp.method == PCAP_SAMP_1_EVERY_N) + { + samp_npkt= (samp_npkt + 1) % p->rmt_samp.value; + + // Discard all packets that are not '1 out of N' + if (samp_npkt != 0) + { + bp += BPF_WORDALIGN(caplen + hdrlen); + continue; + } + } + + if (p->rmt_samp.method == PCAP_SAMP_FIRST_AFTER_N_MS) + { + struct pcap_pkthdr *pkt_header= (struct pcap_pkthdr*) bp; + + // Check if the timestamp of the arrived packet is smaller than our target time + if ( (pkt_header->ts.tv_sec < samp_time.tv_sec) || + ( (pkt_header->ts.tv_sec == samp_time.tv_sec) && (pkt_header->ts.tv_usec < samp_time.tv_usec) ) ) + { + bp += BPF_WORDALIGN(caplen + hdrlen); + continue; + } + + // The arrived packet is suitable for being sent to the remote host + // So, let's update the target time + samp_time.tv_usec= pkt_header->ts.tv_usec + p->rmt_samp.value * 1000; + if (samp_time.tv_usec > 1000000) + { + samp_time.tv_sec= pkt_header->ts.tv_sec + samp_time.tv_usec / 1000000; + samp_time.tv_usec= samp_time.tv_usec % 1000000; + } + } +#endif /* HAVE_REMOTE */ + + /* + * XXX A bpf_hdr matches a pcap_pkthdr. + */ + (*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen); + bp += BPF_WORDALIGN(caplen + hdrlen); + if (++n >= cnt && cnt > 0) { + p->bp = bp; + p->cc = ep - bp; + return (n); + } + } +#undef bhp + p->cc = 0; + return (n); +} + +#ifdef HAVE_DAG_API +static int +pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ + u_char *dp = NULL; + int packet_len = 0, caplen = 0; + struct pcap_pkthdr pcap_header; + u_char *endofbuf; + int n = 0; + dag_record_t *header; + unsigned erf_record_len; + ULONGLONG ts; + int cc; + unsigned swt; + unsigned dfp = p->adapter->DagFastProcess; + + cc = p->cc; + if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */ + { + /* Get new packets from the network */ + if(PacketReceivePacket(p->adapter, p->Packet, TRUE)==FALSE){ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed"); + return (-1); + } + + cc = p->Packet->ulBytesReceived; + if(cc == 0) + /* The timeout has expired but we no packets arrived */ + return 0; + header = (dag_record_t*)p->adapter->DagBuffer; + } + else + header = (dag_record_t*)p->bp; + + endofbuf = (char*)header + cc; + + /* + * Cycle through the packets + */ + do + { + erf_record_len = SWAPS(header->rlen); + if((char*)header + erf_record_len > endofbuf) + break; + + /* Increase the number of captured packets */ + p->md.stat.ps_recv++; + + /* Find the beginning of the packet */ + dp = ((u_char *)header) + dag_record_size; + + /* Determine actual packet len */ + switch(header->type) + { + case TYPE_ATM: + packet_len = ATM_SNAPLEN; + caplen = ATM_SNAPLEN; + dp += 4; + + break; + + case TYPE_ETH: + swt = SWAPS(header->wlen); + packet_len = swt - (p->md.dag_fcs_bits); + caplen = erf_record_len - dag_record_size - 2; + if (caplen > packet_len) + { + caplen = packet_len; + } + dp += 2; + + break; + + case TYPE_HDLC_POS: + swt = SWAPS(header->wlen); + packet_len = swt - (p->md.dag_fcs_bits); + caplen = erf_record_len - dag_record_size; + if (caplen > packet_len) + { + caplen = packet_len; + } + + break; + } + + if(caplen > p->snapshot) + caplen = p->snapshot; + + /* + * Has "pcap_breakloop()" been called? + * If so, return immediately - if we haven't read any + * packets, clear the flag and return -2 to indicate + * that we were told to break out of the loop, otherwise + * leave the flag set, so that the *next* call will break + * out of the loop without having read any packets, and + * return the number of packets we've processed so far. + */ + if (p->break_loop) + { + if (n == 0) + { + p->break_loop = 0; + return (-2); + } + else + { + p->bp = (char*)header; + p->cc = endofbuf - (char*)header; + return (n); + } + } + + if(!dfp) + { + /* convert between timestamp formats */ + ts = header->ts; + pcap_header.ts.tv_sec = (int)(ts >> 32); + ts = (ts & 0xffffffffi64) * 1000000; + ts += 0x80000000; /* rounding */ + pcap_header.ts.tv_usec = (int)(ts >> 32); + if (pcap_header.ts.tv_usec >= 1000000) { + pcap_header.ts.tv_usec -= 1000000; + pcap_header.ts.tv_sec++; + } + } + + /* No underlaying filtering system. We need to filter on our own */ + if (p->fcode.bf_insns) + { + if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0) + { + /* Move to next packet */ + header = (dag_record_t*)((char*)header + erf_record_len); + continue; + } + } + + /* Fill the header for the user suppplied callback function */ + pcap_header.caplen = caplen; + pcap_header.len = packet_len; + + /* Call the callback function */ + (*callback)(user, &pcap_header, dp); + + /* Move to next packet */ + header = (dag_record_t*)((char*)header + erf_record_len); + + /* Stop if the number of packets requested by user has been reached*/ + if (++n >= cnt && cnt > 0) + { + p->bp = (char*)header; + p->cc = endofbuf - (char*)header; + return (n); + } + } + while((u_char*)header < endofbuf); + + return 1; +} +#endif /* HAVE_DAG_API */ + +/* Send a packet to the network */ +static int +pcap_inject_win32(pcap_t *p, const void *buf, size_t size){ + LPPACKET PacketToSend; + + PacketToSend=PacketAllocatePacket(); + + if (PacketToSend == NULL) + { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketAllocatePacket failed"); + return -1; + } + + PacketInitPacket(PacketToSend,(PVOID)buf,size); + if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed"); + PacketFreePacket(PacketToSend); + return -1; + } + + PacketFreePacket(PacketToSend); + + /* + * We assume it all got sent if "PacketSendPacket()" succeeded. + * "pcap_inject()" is expected to return the number of bytes + * sent. + */ + return size; +} + +static void +pcap_close_win32(pcap_t *p) +{ + pcap_close_common(p); + if (p->adapter != NULL) { + PacketCloseAdapter(p->adapter); + p->adapter = NULL; + } + if (p->Packet) { + PacketFreePacket(p->Packet); + p->Packet = NULL; + } +} + +pcap_t * +pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, + char *ebuf) +{ + register pcap_t *p; + NetType type; + +#ifdef HAVE_REMOTE + char host[PCAP_BUF_SIZE + 1]; + char port[PCAP_BUF_SIZE + 1]; + char name[PCAP_BUF_SIZE + 1]; + int srctype; + + /* + Retrofit; we have to make older applications compatible with the remote capture + So, we're calling the pcap_open_remote() from here, that is a very dirty thing. + Obviously, we cannot exploit all the new features; for instance, we cannot + send authentication, we cannot use a UDP data connection, and so on. + */ + if (pcap_parsesrcstr(device, &srctype, host, port, name, ebuf) ) + return NULL; + + if (srctype == PCAP_SRC_IFREMOTE) + { + p= pcap_opensource_remote(device, NULL, ebuf); + + if (p == NULL) + return NULL; + + p->snapshot= snaplen; + p->timeout= to_ms; + p->rmt_flags= (promisc) ? PCAP_OPENFLAG_PROMISCUOUS : 0; + + return p; + } +#endif /* HAVE_REMOTE */ + + /* Init WinSock */ + wsockinit(); + + p = (pcap_t *)malloc(sizeof(*p)); + if (p == NULL) + { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); + return (NULL); + } + memset(p, 0, sizeof(*p)); + p->adapter=NULL; + + p->adapter = PacketOpenAdapter((char*)device); + + if (p->adapter == NULL) + { + free(p); + /* Adapter detected but we are not able to open it. Return failure. */ + snprintf(ebuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror()); + return NULL; + } + + /*get network type*/ + if(PacketGetNetType (p->adapter,&type) == FALSE) + { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror()); + goto bad; + } + + /*Set the linktype*/ + switch (type.LinkType) + { + case NdisMediumWan: + p->linktype = DLT_EN10MB; + break; + + case NdisMedium802_3: + p->linktype = DLT_EN10MB; + /* + * This is (presumably) a real Ethernet capture; give it a + * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so + * that an application can let you choose it, in case you're + * capturing DOCSIS traffic that a Cisco Cable Modem + * Termination System is putting out onto an Ethernet (it + * doesn't put an Ethernet header onto the wire, it puts raw + * DOCSIS frames out on the wire inside the low-level + * Ethernet framing). + */ + p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); + /* + * If that fails, just leave the list empty. + */ + if (p->dlt_list != NULL) { + p->dlt_list[0] = DLT_EN10MB; + p->dlt_list[1] = DLT_DOCSIS; + p->dlt_count = 2; + } + break; + + case NdisMediumFddi: + p->linktype = DLT_FDDI; + break; + + case NdisMedium802_5: + p->linktype = DLT_IEEE802; + break; + + case NdisMediumArcnetRaw: + p->linktype = DLT_ARCNET; + break; + + case NdisMediumArcnet878_2: + p->linktype = DLT_ARCNET; + break; + + case NdisMediumAtm: + p->linktype = DLT_ATM_RFC1483; + break; + + case NdisMediumCHDLC: + p->linktype = DLT_CHDLC; + break; + + case NdisMediumPPPSerial: + p->linktype = DLT_PPP_SERIAL; + break; + + case NdisMediumNull: + p->linktype = DLT_NULL; + break; + + case NdisMediumBare80211: + p->linktype = DLT_IEEE802_11; + break; + + case NdisMediumRadio80211: + p->linktype = DLT_IEEE802_11_RADIO; + break; + + default: + p->linktype = DLT_EN10MB; /*an unknown adapter is assumed to be ethernet*/ + break; + } + + /* Set promisquous mode */ + if (promisc) PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS); + else PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL); + + /* Set the buffer size */ + p->bufsize = PcapBufSize; + + /* Store the timeout. Used by pcap_setnonblock() */ + p->timeout= to_ms; + + /* allocate Packet structure used during the capture */ + if((p->Packet = PacketAllocatePacket())==NULL) + { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure"); + goto bad; + } + + if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD)) + { + /* + * Traditional Adapter + */ + + p->buffer = (u_char *)malloc(PcapBufSize); + if (p->buffer == NULL) + { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); + goto bad; + } + + PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize); + + p->snapshot = snaplen; + + /* allocate the standard buffer in the driver */ + if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE) + { + snprintf(ebuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n"); + goto bad; + } + + /* tell the driver to copy the buffer only if it contains at least 16K */ + if(PacketSetMinToCopy(p->adapter,16000)==FALSE) + { + snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror()); + goto bad; + } + } + else +#ifdef HAVE_DAG_API + { + /* + * Dag Card + */ + LONG status; + HKEY dagkey; + DWORD lptype; + DWORD lpcbdata; + int postype = 0; + char keyname[512]; + + snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s", + "SYSTEM\\CurrentControlSet\\Services\\DAG", + strstr(_strlwr((char*)device), "dag")); + do + { + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey); + if(status != ERROR_SUCCESS) + break; + + status = RegQueryValueEx(dagkey, + "PosType", + NULL, + &lptype, + (char*)&postype, + &lpcbdata); + + if(status != ERROR_SUCCESS) + { + postype = 0; + } + + RegCloseKey(dagkey); + } + while(FALSE); + + + p->snapshot = PacketSetSnapLen(p->adapter, snaplen); + + /* Set the length of the FCS associated to any packet. This value + * will be subtracted to the packet length */ + p->md.dag_fcs_bits = p->adapter->DagFcsLen; + } +#else + goto bad; +#endif /* HAVE_DAG_API */ + + PacketSetReadTimeout(p->adapter, to_ms); + +#ifdef HAVE_DAG_API + if(p->adapter->Flags & INFO_FLAG_DAG_CARD) + { + /* install dag specific handlers for read and setfilter */ + p->read_op = pcap_read_win32_dag; + p->setfilter_op = pcap_setfilter_win32_dag; + } + else + { +#endif /* HAVE_DAG_API */ + /* install traditional npf handlers for read and setfilter */ + p->read_op = pcap_read_win32_npf; + p->setfilter_op = pcap_setfilter_win32_npf; +#ifdef HAVE_DAG_API + } +#endif /* HAVE_DAG_API */ + p->setdirection_op = NULL; /* Not implemented. */ + /* XXX - can this be implemented on some versions of Windows? */ + p->inject_op = pcap_inject_win32; + p->set_datalink_op = NULL; /* can't change data link type */ + p->getnonblock_op = pcap_getnonblock_win32; + p->setnonblock_op = pcap_setnonblock_win32; + p->stats_op = pcap_stats_win32; + p->close_op = pcap_close_win32; + + return (p); +bad: + if (p->adapter) + PacketCloseAdapter(p->adapter); + if (p->buffer != NULL) + free(p->buffer); + if(p->Packet) + PacketFreePacket(p->Packet); + /* + * Get rid of any link-layer type list we allocated. + */ + if (p->dlt_list != NULL) + free(p->dlt_list); + free(p); + return (NULL); +} + + +static int +pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp) +{ + if(PacketSetBpf(p->adapter,fp)==FALSE){ + /* + * Kernel filter not installed. + * XXX - fall back on userland filtering, as is done + * on other platforms? + */ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror()); + return (-1); + } + + /* + * Discard any previously-received packets, as they might have + * passed whatever filter was formerly in effect, but might + * not pass this filter (BIOCSETF discards packets buffered + * in the kernel, so you can lose packets in any case). + */ + p->cc = 0; + return (0); +} + +/* + * We filter at user level, since the kernel driver does't process the packets + */ +static int +pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) { + + if(!fp) + { + strncpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf)); + return -1; + } + + /* Install a user level filter */ + if (install_bpf_program(p, fp) < 0) + { + snprintf(p->errbuf, sizeof(p->errbuf), + "setfilter, unable to install the filter: %s", pcap_strerror(errno)); + return -1; + } + + p->md.use_bpf = 0; + + return (0); +} + +static int +pcap_getnonblock_win32(pcap_t *p, char *errbuf) +{ + /* + * XXX - if there were a PacketGetReadTimeout() call, we + * would use it, and return 1 if the timeout is -1 + * and 0 otherwise. + */ + return (p->nonblock); +} + +static int +pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf) +{ + int newtimeout; + + if (nonblock) { + /* + * Set the read timeout to -1 for non-blocking mode. + */ + newtimeout = -1; + } else { + /* + * Restore the timeout set when the device was opened. + * (Note that this may be -1, in which case we're not + * really leaving non-blocking mode.) + */ + newtimeout = p->timeout; + } + if (!PacketSetReadTimeout(p->adapter, newtimeout)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "PacketSetReadTimeout: %s", pcap_win32strerror()); + return (-1); + } + p->nonblock = (newtimeout == -1); + return (0); +} + +/* Set the driver working mode */ +int +pcap_setmode(pcap_t *p, int mode){ + + if (p->adapter==NULL) + { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "impossible to set mode while reading from a file"); + return -1; + } + + if(PacketSetMode(p->adapter,mode)==FALSE) + { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized"); + return -1; + } + + return 0; +} + +/* Set the dimension of the kernel-level capture buffer */ +int +pcap_setbuff(pcap_t *p, int dim) +{ +#ifdef HAVE_REMOTE + if (p->rmt_clientside) + { + /* Currently, this is a bug: the capture buffer cannot be set with remote capture */ + return 0; + } +#endif /* HAVE_REMOTE */ + + if (p->adapter==NULL) + { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "The kernel buffer size cannot be set while reading from a file"); + return -1; + } + + if(PacketSetBuff(p->adapter,dim)==FALSE) + { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer"); + return -1; + } + return 0; +} + +/*set the minimum amount of data that will release a read call*/ +int +pcap_setmintocopy(pcap_t *p, int size) +{ + if (p->adapter==NULL) + { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Impossible to set the mintocopy parameter on an offline capture"); + return -1; + } + + if(PacketSetMinToCopy(p->adapter, size)==FALSE) + { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size"); + return -1; + } + return 0; +} diff --git a/winpcap/wpcap/libpcap/pcap.3 b/winpcap/wpcap/libpcap/pcap.3 new file mode 100644 index 0000000..3262b67 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap.3 @@ -0,0 +1,1311 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3,v 1.64.2.9 2006/01/22 20:12:10 guy Exp $ +.\" +.\" Copyright (c) 1994, 1996, 1997 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that: (1) source code distributions +.\" retain the above copyright notice and this paragraph in its entirety, (2) +.\" distributions including binary code include the above copyright notice and +.\" this paragraph in its entirety in the documentation or other materials +.\" provided with the distribution, and (3) all advertising materials mentioning +.\" features or use of this software display the following acknowledgement: +.\" ``This product includes software developed by the University of California, +.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of +.\" the University nor the names of its contributors may be used to endorse +.\" or promote products derived from this software without specific prior +.\" written permission. +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +.\" +.TH PCAP 3 "27 February 2004" +.SH NAME +pcap \- Packet Capture library +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.nf +.ft B +char errbuf[PCAP_ERRBUF_SIZE]; +.ft +.LP +.ft B +pcap_t *pcap_open_live(const char *device, int snaplen, +.ti +8 +int promisc, int to_ms, char *errbuf) +pcap_t *pcap_open_dead(int linktype, int snaplen) +pcap_t *pcap_open_offline(const char *fname, char *errbuf) +pcap_t *pcap_fopen_offline(FILE *fp, char *errbuf) +pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname) +pcap_dumper_t *pcap_dump_fopen(pcap_t *p, FILE *fp) +.ft +.LP +.ft B +int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf); +int pcap_getnonblock(pcap_t *p, char *errbuf); +.ft +.LP +.ft B +int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) +void pcap_freealldevs(pcap_if_t *alldevs) +char *pcap_lookupdev(char *errbuf) +int pcap_lookupnet(const char *device, bpf_u_int32 *netp, +.ti +8 +bpf_u_int32 *maskp, char *errbuf) +.ft +.LP +.ft B +typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h, +.ti +8 + const u_char *bytes); +.ft B +int pcap_dispatch(pcap_t *p, int cnt, +.ti +8 +pcap_handler callback, u_char *user) +int pcap_loop(pcap_t *p, int cnt, +.ti +8 +pcap_handler callback, u_char *user) +void pcap_dump(u_char *user, struct pcap_pkthdr *h, +.ti +8 +u_char *sp) +.ft +.LP +.ft B +int pcap_compile(pcap_t *p, struct bpf_program *fp, +.ti +8 +char *str, int optimize, bpf_u_int32 netmask) +int pcap_setfilter(pcap_t *p, struct bpf_program *fp) +void pcap_freecode(struct bpf_program *) +int pcap_setdirection(pcap_t *p, pcap_direction_t d) +.ft +.LP +.ft B +const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h) +int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, +.ti +8 +const u_char **pkt_data) +.ft +.LP +.ft B +void pcap_breakloop(pcap_t *) +.ft +.LP +.ft B +int pcap_inject(pcap_t *p, const void *buf, size_t size) +int pcap_sendpacket(pcap_t *p, const u_char *buf, int size) +.ft +.LP +.ft B +int pcap_datalink(pcap_t *p) +int pcap_list_datalinks(pcap_t *p, int **dlt_buf); +int pcap_set_datalink(pcap_t *p, int dlt); +int pcap_datalink_name_to_val(const char *name); +const char *pcap_datalink_val_to_name(int dlt); +const char *pcap_datalink_val_to_description(int dlt); +int pcap_snapshot(pcap_t *p) +int pcap_is_swapped(pcap_t *p) +int pcap_major_version(pcap_t *p) +int pcap_minor_version(pcap_t *p) +int pcap_stats(pcap_t *p, struct pcap_stat *ps) +FILE *pcap_file(pcap_t *p) +int pcap_fileno(pcap_t *p) +int pcap_get_selectable_fd(pcap_t *p); +void pcap_perror(pcap_t *p, char *prefix) +char *pcap_geterr(pcap_t *p) +char *pcap_strerror(int error) +const char *pcap_lib_version(void) +.ft +.LP +.ft B +void pcap_close(pcap_t *p) +int pcap_dump_flush(pcap_dumper_t *p) +long pcap_dump_ftell(pcap_dumper_t *p) +FILE *pcap_dump_file(pcap_dumper_t *p) +void pcap_dump_close(pcap_dumper_t *p) +.ft +.fi +.SH DESCRIPTION +The Packet Capture library +provides a high level interface to packet capture systems. All packets +on the network, even those destined for other hosts, are accessible +through this mechanism. +.PP +.SH ROUTINES +NOTE: +.I errbuf +in +.BR pcap_open_live() , +.BR pcap_open_dead() , +.BR pcap_open_offline() , +.BR pcap_fopen_offline() , +.BR pcap_setnonblock() , +.BR pcap_getnonblock() , +.BR pcap_findalldevs() , +.BR pcap_lookupdev() , +and +.B pcap_lookupnet() +is assumed to be able to hold at least +.B PCAP_ERRBUF_SIZE +chars. +.PP +.B pcap_open_live() +is used to obtain a packet capture descriptor to look +at packets on the network. +.I device +is a string that specifies the network device to open; on Linux systems +with 2.2 or later kernels, a +.I device +argument of "any" or +.B NULL +can be used to capture packets from all interfaces. +.I snaplen +specifies the maximum number of bytes to capture. If this value is less +than the size of a packet that is captured, only the first +.I snaplen +bytes of that packet will be captured and provided as packet data. A +value of 65535 should be sufficient, on most if not all networks, to +capture all the data available from the packet. +.I promisc +specifies if the interface is to be put into promiscuous mode. +(Note that even if this parameter is false, the interface +could well be in promiscuous mode for some other reason.) For now, this +doesn't work on the "any" device; if an argument of "any" or NULL is +supplied, the +.I promisc +flag is ignored. +.I to_ms +specifies the read timeout in milliseconds. The read timeout is used to +arrange that the read not necessarily return immediately when a packet +is seen, but that it wait for some amount of time to allow more packets +to arrive and to read multiple packets from the OS kernel in one +operation. Not all platforms support a read timeout; on platforms that +don't, the read timeout is ignored. A zero value for +.IR to_ms , +on platforms that support a read timeout, +will cause a read to wait forever to allow enough packets to +arrive, with no timeout. +.I errbuf +is used to return error or warning text. It will be set to error text when +.B pcap_open_live() +fails and returns +.BR NULL . +.I errbuf +may also be set to warning text when +.B pcap_open_live() +succeds; to detect this case the caller should store a zero-length string in +.I errbuf +before calling +.B pcap_open_live() +and display the warning to the user if +.I errbuf +is no longer a zero-length string. +.PP +.B pcap_open_dead() +is used for creating a +.B pcap_t +structure to use when calling the other functions in libpcap. It is +typically used when just using libpcap for compiling BPF code. +.PP +.B pcap_open_offline() +is called to open a ``savefile'' for reading. +.I fname +specifies the name of the file to open. The file has +the same format as those used by +.B tcpdump(1) +and +.BR tcpslice(1) . +The name "-" in a synonym for +.BR stdin . +Alternatively, you may call +.B pcap_fopen_offline() +to read dumped data from an existing open stream +.IR fp . +Note that on Windows, that stream should be opened in binary mode. +.I errbuf +is used to return error text and is only set when +.B pcap_open_offline() +or +.B pcap_fopen_offline() +fails and returns +.BR NULL . +.PP +.B pcap_dump_open() +is called to open a ``savefile'' for writing. The name "-" in a synonym +for +.BR stdout . +.B NULL +is returned on failure. +.I p +is a +.I pcap +struct as returned by +.B pcap_open_offline() +or +.BR pcap_open_live() . +.I fname +specifies the name of the file to open. Alternatively, you may call +.B pcap_dump_fopen() +to write data to an existing open stream +.IR fp . +Note that on Windows, that stream should be opened in binary mode. +If +.B NULL +is returned, +.B pcap_geterr() +can be used to get the error text. +.PP +.PP +.B pcap_setnonblock() +puts a capture descriptor, opened with +.BR pcap_open_live() , +into ``non-blocking'' mode, or takes it out of ``non-blocking'' mode, +depending on whether the +.I nonblock +argument is non-zero or zero. It has no effect on ``savefiles''. +If there is an error, \-1 is returned and +.I errbuf +is filled in with an appropriate error message; otherwise, 0 is +returned. +In +``non-blocking'' mode, an attempt to read from the capture descriptor +with +.B pcap_dispatch() +will, if no packets are currently available to be read, return 0 +immediately rather than blocking waiting for packets to arrive. +.B pcap_loop() +and +.B pcap_next() +will not work in ``non-blocking'' mode. +.PP +.B pcap_getnonblock() +returns the current ``non-blocking'' state of the capture descriptor; it +always returns 0 on ``savefiles''. +If there is an error, \-1 is returned and +.I errbuf +is filled in with an appropriate error message. +.PP +.B pcap_findalldevs() +constructs a list of network devices that can be opened with +.BR pcap_open_live() . +(Note that there may be network devices that cannot be opened with +.BR pcap_open_live() +by the +process calling +.BR pcap_findalldevs() , +because, for example, that process might not have sufficient privileges +to open them for capturing; if so, those devices will not appear on the +list.) +.I alldevsp +is set to point to the first element of the list; each element of the +list is of type +.BR pcap_if_t , +and has the following members: +.RS +.TP +.B next +if not +.BR NULL , +a pointer to the next element in the list; +.B NULL +for the last element of the list +.TP +.B name +a pointer to a string giving a name for the device to pass to +.B pcap_open_live() +.TP +.B description +if not +.BR NULL , +a pointer to a string giving a human-readable description of the device +.TP +.B addresses +a pointer to the first element of a list of addresses for the interface +.TP +.B flags +interface flags: +.RS +.TP +.B PCAP_IF_LOOPBACK +set if the interface is a loopback interface +.RE +.RE +.PP +Each element of the list of addresses is of type +.BR pcap_addr_t , +and has the following members: +.RS +.TP +.B next +if not +.BR NULL , +a pointer to the next element in the list; +.B NULL +for the last element of the list +.TP +.B addr +a pointer to a +.B "struct sockaddr" +containing an address +.TP +.B netmask +if not +.BR NULL , +a pointer to a +.B "struct sockaddr" +that contains the netmask corresponding to the address pointed to by +.B addr +.TP +.B broadaddr +if not +.BR NULL , +a pointer to a +.B "struct sockaddr" +that contains the broadcast address corresponding to the address pointed +to by +.BR addr ; +may be null if the interface doesn't support broadcasts +.TP +.B dstaddr +if not +.BR NULL , +a pointer to a +.B "struct sockaddr" +that contains the destination address corresponding to the address pointed +to by +.BR addr ; +may be null if the interface isn't a point-to-point interface +.RE +.PP +Note that not all the addresses in the list of addresses are +necessarily IPv4 or IPv6 addresses - you must check the +.B sa_family +member of the +.B "struct sockaddr" +before interpreting the contents of the address. +.PP +.B \-1 +is returned on failure, in which case +.B errbuf +is filled in with an appropriate error message; +.B 0 +is returned on success. +.PP +.B pcap_freealldevs() +is used to free a list allocated by +.BR pcap_findalldevs() . +.PP +.B pcap_lookupdev() +returns a pointer to a network device suitable for use with +.B pcap_open_live() +and +.BR pcap_lookupnet() . +If there is an error, +.B NULL +is returned and +.I errbuf +is filled in with an appropriate error message. +.PP +.B pcap_lookupnet() +is used to determine the network number and mask +associated with the network device +.BR device . +Both +.I netp +and +.I maskp +are +.I bpf_u_int32 +pointers. +A return of \-1 indicates an error in which case +.I errbuf +is filled in with an appropriate error message. +.PP +.B pcap_dispatch() +is used to collect and process packets. +.I cnt +specifies the maximum number of packets to process before returning. +This is not a minimum number; when reading a live capture, only one +bufferful of packets is read at a time, so fewer than +.I cnt +packets may be processed. A +.I cnt +of \-1 processes all the packets received in one buffer when reading a +live capture, or all the packets in the file when reading a +``savefile''. +.I callback +specifies a routine to be called with three arguments: +a +.I u_char +pointer which is passed in from +.BR pcap_dispatch() , +a +.I const struct pcap_pkthdr +pointer to a structure with the following members: +.RS +.TP +.B ts +a +.I struct timeval +containing the time when the packet was captured +.TP +.B caplen +a +.I bpf_u_int32 +giving the number of bytes of the packet that are available from the +capture +.TP +.B len +a +.I bpf_u_int32 +giving the length of the packet, in bytes (which might be more than the +number of bytes available from the capture, if the length of the packet +is larger than the maximum number of bytes to capture) +.RE +.PP +and a +.I const u_char +pointer to the first +.B caplen +(as given in the +.I struct pcap_pkthdr +a pointer to which is passed to the callback routine) +bytes of data from the packet (which won't necessarily be the entire +packet; to capture the entire packet, you will have to provide a value +for +.I snaplen +in your call to +.B pcap_open_live() +that is sufficiently large to get all of the packet's data - a value of +65535 should be sufficient on most if not all networks). +.PP +The number of packets read is returned. +0 is returned if no packets were read from a live capture (if, for +example, they were discarded because they didn't pass the packet filter, +or if, on platforms that support a read timeout that starts before any +packets arrive, the timeout expires before any packets arrive, or if the +file descriptor for the capture device is in non-blocking mode and no +packets were available to be read) or if no more packets are available +in a ``savefile.'' A return of \-1 indicates +an error in which case +.B pcap_perror() +or +.B pcap_geterr() +may be used to display the error text. +A return of \-2 indicates that the loop terminated due to a call to +.B pcap_breakloop() +before any packets were processed. +.ft B +If your application uses pcap_breakloop(), +make sure that you explicitly check for \-1 and \-2, rather than just +checking for a return value < 0. +.ft R +.PP +.BR NOTE : +when reading a live capture, +.B pcap_dispatch() +will not necessarily return when the read times out; on some platforms, +the read timeout isn't supported, and, on other platforms, the timer +doesn't start until at least one packet arrives. This means that the +read timeout should +.B NOT +be used in, for example, an interactive application, to allow the packet +capture loop to ``poll'' for user input periodically, as there's no +guarantee that +.B pcap_dispatch() +will return after the timeout expires. +.PP +.B pcap_loop() +is similar to +.B pcap_dispatch() +except it keeps reading packets until +.I cnt +packets are processed or an error occurs. +It does +.B not +return when live read timeouts occur. +Rather, specifying a non-zero read timeout to +.B pcap_open_live() +and then calling +.B pcap_dispatch() +allows the reception and processing of any packets that arrive when the +timeout occurs. +A negative +.I cnt +causes +.B pcap_loop() +to loop forever (or at least until an error occurs). \-1 is returned on +an error; 0 is returned if +.I cnt +is exhausted; \-2 is returned if the loop terminated due to a call to +.B pcap_breakloop() +before any packets were processed. +.ft B +If your application uses pcap_breakloop(), +make sure that you explicitly check for \-1 and \-2, rather than just +checking for a return value < 0. +.ft R +.PP +.B pcap_next() +reads the next packet (by calling +.B pcap_dispatch() +with a +.I cnt +of 1) and returns a +.I u_char +pointer to the data in that packet. (The +.I pcap_pkthdr +struct for that packet is not supplied.) +.B NULL +is returned if an error occured, or if no packets were read from a live +capture (if, for example, they were discarded because they didn't pass +the packet filter, or if, on platforms that support a read timeout that +starts before any packets arrive, the timeout expires before any packets +arrive, or if the file descriptor for the capture device is in +non-blocking mode and no packets were available to be read), or if no +more packets are available in a ``savefile.'' Unfortunately, there is +no way to determine whether an error occured or not. +.PP +.B pcap_next_ex() +reads the next packet and returns a success/failure indication: +.RS +.TP +1 +the packet was read without problems +.TP +0 +packets are being read from a live capture, and the timeout expired +.TP +\-1 +an error occurred while reading the packet +.TP +\-2 +packets are being read from a ``savefile'', and there are no more +packets to read from the savefile. +.RE +.PP +If the packet was read without problems, the pointer pointed to by the +.I pkt_header +argument is set to point to the +.I pcap_pkthdr +struct for the packet, and the +pointer pointed to by the +.I pkt_data +argument is set to point to the data in the packet. +.PP +.B pcap_breakloop() +sets a flag that will force +.B pcap_dispatch() +or +.B pcap_loop() +to return rather than looping; they will return the number of packets +that have been processed so far, or \-2 if no packets have been +processed so far. +.PP +This routine is safe to use inside a signal handler on UNIX or a console +control handler on Windows, as it merely sets a flag that is checked +within the loop. +.PP +The flag is checked in loops reading packets from the OS - a signal by +itself will not necessarily terminate those loops - as well as in loops +processing a set of packets returned by the OS. +.ft B +Note that if you are catching signals on UNIX systems that support +restarting system calls after a signal, and calling pcap_breakloop() +in the signal handler, you must specify, when catching those signals, +that system calls should NOT be restarted by that signal. Otherwise, +if the signal interrupted a call reading packets in a live capture, +when your signal handler returns after calling pcap_breakloop(), the +call will be restarted, and the loop will not terminate until more +packets arrive and the call completes. +.PP +Note also that, in a multi-threaded application, if one thread is +blocked in +.BR pcap_dispatch() , +.BR pcap_loop() , +.BR pcap_next() , +or +.BR pcap_next_ex() , +a call to +.B pcap_breakloop() +in a different thread will not unblock that thread; you will need to use +whatever mechanism the OS provides for breaking a thread out of blocking +calls in order to unblock the thread, such as thread cancellation in +systems that support POSIX threads. +.ft R +.PP +Note that +.B pcap_next() +will, on some platforms, loop reading packets from the OS; that loop +will not necessarily be terminated by a signal, so +.B pcap_breakloop() +should be used to terminate packet processing even if +.B pcap_next() +is being used. +.PP +.B pcap_breakloop() +does not guarantee that no further packets will be processed by +.B pcap_dispatch() +or +.B pcap_loop() +after it is called; at most one more packet might be processed. +.PP +If \-2 is returned from +.B pcap_dispatch() +or +.BR pcap_loop() , +the flag is cleared, so a subsequent call will resume reading packets. +If a positive number is returned, the flag is not cleared, so a +subsequent call will return \-2 and clear the flag. +.PP +.B pcap_inject() +sends a raw packet through the network interface; +.I buf +points to the data of the packet, including the link-layer header, and +.I size +is the number of bytes in the packet. +It returns the number of bytes written on success. A return of \-1 +indicates an error in which case +.B pcap_perror() +or +.B pcap_geterr() +may be used to display the error text. +Note that, even if you successfully open the network interface, you +might not have permission to send packets on it, or it might not support +sending packets; as +.I pcap_open_live() +doesn't have a flag to indicate whether to open for capturing, sending, +or capturing and sending, you cannot request an open that supports +sending and be notified at open time whether sending will be possible. +Note also that some devices might not support sending packets. +.PP +Note that, on some platforms, the link-layer header of the packet that's +sent might not be the same as the link-layer header of the packet +supplied to +.BR pcap_inject() , +as the source link-layer address, if the header contains such an +address, might be changed to be the address assigned to the interface on +which the packet it sent, if the platform doesn't support sending +completely raw and unchanged packets. Even worse, some drivers on some +platforms might change the link-layer type field to whatever value +libpcap used when attaching to the device, even on platforms that +.I do +nominally support sending completely raw and unchanged packets. +.PP +.B pcap_sendpacket() +is like +.BR pcap_inject() , +but it returns 0 on success and \-1 on failure. +.RB ( pcap_inject() +comes from OpenBSD; +.B pcap_sendpacket() +comes from WinPcap. Both are provided for compatibility.) +.PP +.B pcap_dump() +outputs a packet to the ``savefile'' opened with +.BR pcap_dump_open() . +Note that its calling arguments are suitable for use with +.B pcap_dispatch() +or +.BR pcap_loop() . +If called directly, the +.I user +parameter is of type +.I pcap_dumper_t +as returned by +.BR pcap_dump_open() . +.PP +.B pcap_compile() +is used to compile the string +.I str +into a filter program. +.I program +is a pointer to a +.I bpf_program +struct and is filled in by +.BR pcap_compile() . +.I optimize +controls whether optimization on the resulting code is performed. +.I netmask +specifies the IPv4 netmask of the network on which packets are being +captured; it is used only when checking for IPv4 broadcast addresses in +the filter program. If the netmask of the network on which packets are +being captured isn't known to the program, or if packets are being +captured on the Linux "any" pseudo-interface that can capture on more +than one network, a value of 0 can be supplied; tests for IPv4 broadcast +addreses won't be done correctly, but all other tests in the filter +program will be OK. A return of \-1 indicates an error in which case +.BR pcap_geterr() +may be used to display the error text. +.PP +.B pcap_compile_nopcap() +is similar to +.B pcap_compile() +except that instead of passing a pcap structure, one passes the +snaplen and linktype explicitly. It is intended to be used for +compiling filters for direct BPF usage, without necessarily having +called +.BR pcap_open() . +A return of \-1 indicates an error; the error text is unavailable. +.RB ( pcap_compile_nopcap() +is a wrapper around +.BR pcap_open_dead() , +.BR pcap_compile() , +and +.BR pcap_close() ; +the latter three routines can be used directly in order to get the error +text for a compilation error.) +.B +.PP +.B pcap_setfilter() +is used to specify a filter program. +.I fp +is a pointer to a +.I bpf_program +struct, usually the result of a call to +.BR pcap_compile() . +.B \-1 +is returned on failure, in which case +.BR pcap_geterr() +may be used to display the error text; +.B 0 +is returned on success. +.PP +.B pcap_freecode() +is used to free up allocated memory pointed to by a +.I bpf_program +struct generated by +.B pcap_compile() +when that BPF program is no longer needed, for example after it +has been made the filter program for a pcap structure by a call to +.BR pcap_setfilter() . +.PP +.B pcap_setdirection() +is used to specify a direction that packets will be captured. +.I pcap_direction_t +is one of the constants +.BR PCAP_D_IN , +.B PCAP_D_OUT +or +.BR PCAP_D_INOUT . +.B PCAP_D_IN +will only capture packets received by the device, +.B PCAP_D_OUT +will only capture packets sent by the device and +.B PCAP_D_INOUT +will capture packets received by or sent by the device. +.B PCAP_D_INOUT +is the default setting if this function is not called. This isn't +necessarily supported on all platforms; some platforms might return an +error, and some other platforms might not support +.BR PCAP_D_OUT . +This operation is not supported if a ``savefile'' is being read. +.B \-1 +is returned on failure, +.B 0 +is returned on success. +.PP +.B pcap_datalink() +returns the link layer type; link layer types it can return include: +.PP +.RS 5 +.TP 5 +.B DLT_NULL +BSD loopback encapsulation; the link layer header is a 4-byte field, in +.I host +byte order, containing a PF_ value from +.B socket.h +for the network-layer protocol of the packet. +.IP +Note that ``host byte order'' is the byte order of the machine on which +the packets are captured, and the PF_ values are for the OS of the +machine on which the packets are captured; if a live capture is being +done, ``host byte order'' is the byte order of the machine capturing the +packets, and the PF_ values are those of the OS of the machine capturing +the packets, but if a ``savefile'' is being read, the byte order and PF_ +values are +.I not +necessarily those of the machine reading the capture file. +.TP 5 +.B DLT_EN10MB +Ethernet (10Mb, 100Mb, 1000Mb, and up) +.TP 5 +.B DLT_IEEE802 +IEEE 802.5 Token Ring +.TP 5 +.B DLT_ARCNET +ARCNET +.TP 5 +.B DLT_SLIP +SLIP; the link layer header contains, in order: +.RS 10 +.LP +a 1-byte flag, which is 0 for packets received by the machine and 1 for +packets sent by the machine; +.LP +a 1-byte field, the upper 4 bits of which indicate the type of packet, +as per RFC 1144: +.RS 5 +.TP 5 +0x40 +an unmodified IP datagram (TYPE_IP); +.TP 5 +0x70 +an uncompressed-TCP IP datagram (UNCOMPRESSED_TCP), with that byte being +the first byte of the raw IP header on the wire, containing the +connection number in the protocol field; +.TP 5 +0x80 +a compressed-TCP IP datagram (COMPRESSED_TCP), with that byte being the +first byte of the compressed TCP/IP datagram header; +.RE +.LP +for UNCOMPRESSED_TCP, the rest of the modified IP header, and for +COMPRESSED_TCP, the compressed TCP/IP datagram header; +.RE +.RS 5 +.LP +for a total of 16 bytes; the uncompressed IP datagram follows the header. +.RE +.TP 5 +.B DLT_PPP +PPP; if the first 2 bytes are 0xff and 0x03, it's PPP in HDLC-like +framing, with the PPP header following those two bytes, otherwise it's +PPP without framing, and the packet begins with the PPP header. +.TP 5 +.B DLT_FDDI +FDDI +.TP 5 +.B DLT_ATM_RFC1483 +RFC 1483 LLC/SNAP-encapsulated ATM; the packet begins with an IEEE 802.2 +LLC header. +.TP 5 +.B DLT_RAW +raw IP; the packet begins with an IP header. +.TP 5 +.B DLT_PPP_SERIAL +PPP in HDLC-like framing, as per RFC 1662, or Cisco PPP with HDLC +framing, as per section 4.3.1 of RFC 1547; the first byte will be 0xFF +for PPP in HDLC-like framing, and will be 0x0F or 0x8F for Cisco PPP +with HDLC framing. +.TP 5 +.B DLT_PPP_ETHER +PPPoE; the packet begins with a PPPoE header, as per RFC 2516. +.TP 5 +.B DLT_C_HDLC +Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547. +.TP 5 +.B DLT_IEEE802_11 +IEEE 802.11 wireless LAN +.TP 5 +.B DLT_FRELAY +Frame Relay +.TP 5 +.B DLT_LOOP +OpenBSD loopback encapsulation; the link layer header is a 4-byte field, in +.I network +byte order, containing a PF_ value from OpenBSD's +.B socket.h +for the network-layer protocol of the packet. +.IP +Note that, if a ``savefile'' is being read, those PF_ values are +.I not +necessarily those of the machine reading the capture file. +.TP 5 +.B DLT_LINUX_SLL +Linux "cooked" capture encapsulation; the link layer header contains, in +order: +.RS 10 +.LP +a 2-byte "packet type", in network byte order, which is one of: +.RS 5 +.TP 5 +0 +packet was sent to us by somebody else +.TP 5 +1 +packet was broadcast by somebody else +.TP 5 +2 +packet was multicast, but not broadcast, by somebody else +.TP 5 +3 +packet was sent by somebody else to somebody else +.TP 5 +4 +packet was sent by us +.RE +.LP +a 2-byte field, in network byte order, containing a Linux ARPHRD_ value +for the link layer device type; +.LP +a 2-byte field, in network byte order, containing the length of the +link layer address of the sender of the packet (which could be 0); +.LP +an 8-byte field containing that number of bytes of the link layer header +(if there are more than 8 bytes, only the first 8 are present); +.LP +a 2-byte field containing an Ethernet protocol type, in network byte +order, or containing 1 for Novell 802.3 frames without an 802.2 LLC +header or 4 for frames beginning with an 802.2 LLC header. +.RE +.TP 5 +.B DLT_LTALK +Apple LocalTalk; the packet begins with an AppleTalk LLAP header. +.TP 5 +.B DLT_PFLOG +OpenBSD pflog; the link layer header contains, in order: +.RS 10 +.LP +a 1-byte header length, in host byte order; +.LP +a 4-byte PF_ value, in host byte order; +.LP +a 2-byte action code, in network byte order, which is one of: +.RS 5 +.TP 5 +0 +passed +.TP 5 +1 +dropped +.TP 5 +2 +scrubbed +.RE +.LP +a 2-byte reason code, in network byte order, which is one of: +.RS 5 +.TP 5 +0 +match +.TP 5 +1 +bad offset +.TP 5 +2 +fragment +.TP 5 +3 +short +.TP 5 +4 +normalize +.TP 5 +5 +memory +.RE +.LP +a 16-character interface name; +.LP +a 16-character ruleset name (only meaningful if subrule is set); +.LP +a 4-byte rule number, in network byte order; +.LP +a 4-byte subrule number, in network byte order; +.LP +a 1-byte direction, in network byte order, which is one of: +.RS 5 +.TP 5 +0 +incoming or outgoing +.TP 5 +1 +incoming +.TP 5 +2 +outgoing +.RE +.RE +.TP 5 +.B DLT_PRISM_HEADER +Prism monitor mode information followed by an 802.11 header. +.TP 5 +.B DLT_IP_OVER_FC +RFC 2625 IP-over-Fibre Channel, with the link-layer header being the +Network_Header as described in that RFC. +.TP 5 +.B DLT_SUNATM +SunATM devices; the link layer header contains, in order: +.RS 10 +.LP +a 1-byte flag field, containing a direction flag in the uppermost bit, +which is set for packets transmitted by the machine and clear for +packets received by the machine, and a 4-byte traffic type in the +low-order 4 bits, which is one of: +.RS 5 +.TP 5 +0 +raw traffic +.TP 5 +1 +LANE traffic +.TP 5 +2 +LLC-encapsulated traffic +.TP 5 +3 +MARS traffic +.TP 5 +4 +IFMP traffic +.TP 5 +5 +ILMI traffic +.TP 5 +6 +Q.2931 traffic +.RE +.LP +a 1-byte VPI value; +.LP +a 2-byte VCI field, in network byte order. +.RE +.TP 5 +.B DLT_IEEE802_11_RADIO +link-layer information followed by an 802.11 header - see +http://www.shaftnet.org/~pizza/software/capturefrm.txt for a description +of the link-layer information. +.TP 5 +.B DLT_ARCNET_LINUX +ARCNET, with no exception frames, reassembled packets rather than raw +frames, and an extra 16-bit offset field between the destination host +and type bytes. +.TP 5 +.B DLT_LINUX_IRDA +Linux-IrDA packets, with a +.B DLT_LINUX_SLL +header followed by the IrLAP header. +.TP 5 +.B DLT_LINUX_LAPD +LAPD (Q.921) frames, with a +.B DLT_LINUX_SLL +header captured via vISDN. +.RE +.PP +.B pcap_list_datalinks() +is used to get a list of the supported data link types of the interface +associated with the pcap descriptor. +.B pcap_list_datalinks() +allocates an array to hold the list and sets +.IR *dlt_buf . +The caller is responsible for freeing the array. +.B \-1 +is returned on failure; +otherwise, the number of data link types in the array is returned. +.PP +.B pcap_set_datalink() +is used to set the current data link type of the pcap descriptor +to the type specified by +.IR dlt . +.B \-1 +is returned on failure. +.PP +.B pcap_datalink_name_to_val() +translates a data link type name, which is a +.B DLT_ +name with the +.B DLT_ +removed, to the corresponding data link type value. The translation +is case-insensitive. +.B \-1 +is returned on failure. +.PP +.B pcap_datalink_val_to_name() +translates a data link type value to the corresponding data link type +name. NULL is returned on failure. +.PP +.B pcap_datalink_val_to_description() +translates a data link type value to a short description of that data +link type. NULL is returned on failure. +.PP +.B pcap_snapshot() +returns the snapshot length specified when +.B pcap_open_live() +was called. +.PP +.B pcap_is_swapped() +returns true if the current ``savefile'' uses a different byte order +than the current system. +.PP +.B pcap_major_version() +returns the major number of the file format of the savefile; +.B pcap_minor_version() +returns the minor number of the file format of the savefile. The +version number is stored in the header of the savefile. +.PP +.B pcap_file() +returns the standard I/O stream of the ``savefile,'' if a ``savefile'' +was opened with +.BR pcap_open_offline() , +or NULL, if a network device was opened with +.BR pcap_open_live() . +.PP +.B pcap_stats() +returns 0 and fills in a +.B pcap_stat +struct. The values represent packet statistics from the start of the +run to the time of the call. If there is an error or the underlying +packet capture doesn't support packet statistics, \-1 is returned and +the error text can be obtained with +.B pcap_perror() +or +.BR pcap_geterr() . +.B pcap_stats() +is supported only on live captures, not on ``savefiles''; no statistics +are stored in ``savefiles'', so no statistics are available when reading +from a ``savefile''. +.PP +.B pcap_fileno() +returns the file descriptor number from which captured packets are read, +if a network device was opened with +.BR pcap_open_live() , +or \-1, if a ``savefile'' was opened with +.BR pcap_open_offline() . +.PP +.B pcap_get_selectable_fd() +returns, on UNIX, a file descriptor number for a file descriptor on +which one can +do a +.B select() +or +.B poll() +to wait for it to be possible to read packets without blocking, if such +a descriptor exists, or \-1, if no such descriptor exists. Some network +devices opened with +.B pcap_open_live() +do not support +.B select() +or +.B poll() +(for example, regular network devices on FreeBSD 4.3 and 4.4, and Endace +DAG devices), so \-1 is returned for those devices. +.PP +Note that on most versions of most BSDs (including Mac OS X) +.B select() +and +.B poll() +do not work correctly on BPF devices; +.B pcap_get_selectable_fd() +will return a file descriptor on most of those versions (the exceptions +being FreeBSD 4.3 and 4.4), a simple +.B select() +or +.B poll() +will not return even after a timeout specified in +.B pcap_open_live() +expires. To work around this, an application that uses +.B select() +or +.B poll() +to wait for packets to arrive must put the +.B pcap_t +in non-blocking mode, and must arrange that the +.B select() +or +.B poll() +have a timeout less than or equal to the timeout specified in +.BR pcap_open_live() , +and must try to read packets after that timeout expires, regardless of +whether +.B select() +or +.B poll() +indicated that the file descriptor for the +.B pcap_t +is ready to be read or not. (That workaround will not work in FreeBSD +4.3 and later; however, in FreeBSD 4.6 and later, +.B select() +and +.B poll() +work correctly on BPF devices, so the workaround isn't necessary, +although it does no harm.) +.PP +.B pcap_get_selectable_fd() +is not available on Windows. +.PP +.B pcap_perror() +prints the text of the last pcap library error on +.BR stderr , +prefixed by +.IR prefix . +.PP +.B pcap_geterr() +returns the error text pertaining to the last pcap library error. +.BR NOTE : +the pointer it returns will no longer point to a valid error message +string after the +.B pcap_t +passed to it is closed; you must use or copy the string before closing +the +.BR pcap_t . +.PP +.B pcap_strerror() +is provided in case +.BR strerror (1) +isn't available. +.PP +.B pcap_lib_version() +returns a pointer to a string giving information about the version of +the libpcap library being used; note that it contains more information +than just a version number. +.PP +.B pcap_close() +closes the files associated with +.I p +and deallocates resources. +.PP +.B pcap_dump_file() +returns the standard I/O stream of the ``savefile'' opened by +.BR pcap_dump_open(). +.PP +.B pcap_dump_flush() +flushes the output buffer to the ``savefile,'' so that any packets +written with +.B pcap_dump() +but not yet written to the ``savefile'' will be written. +.B \-1 +is returned on error, 0 on success. +.PP +.B pcap_dump_ftell() +returns the current file position for the ``savefile'', representing the +number of bytes written by +.B pcap_dump_open() +and +.BR pcap_dump() . +.B \-1 +is returned on error. +.PP +.B pcap_dump_close() +closes the ``savefile.'' +.PP +.SH SEE ALSO +tcpdump(1), tcpslice(1) +.SH AUTHORS +The original authors are: +.LP +Van Jacobson, +Craig Leres and +Steven McCanne, all of the +Lawrence Berkeley National Laboratory, University of California, Berkeley, CA. +.LP +The current version is available from "The Tcpdump Group"'s Web site at +.LP +.RS +.I http://www.tcpdump.org/ +.RE +.SH BUGS +Please send problems, bugs, questions, desirable enhancements, etc. to: +.LP +.RS +tcpdump-workers@tcpdump.org +.RE +.LP +Please send source code contributions, etc. to: +.LP +.RS +patches@tcpdump.org +.RE diff --git a/winpcap/wpcap/libpcap/pcap.c b/winpcap/wpcap/libpcap/pcap.c new file mode 100644 index 0000000..565d37d --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap.c @@ -0,0 +1,967 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.88.2.13 2006/07/27 21:06:17 gianluca Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include +#else /* WIN32 */ +#include +#endif /* WIN32 */ + +#include +#include +#include +#if !defined(_MSC_VER) && !defined(__BORLANDC__) +#include +#endif +#include +#include + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#ifdef MSDOS +#include "pcap-dos.h" +#endif + +#include "pcap-int.h" + +#ifdef HAVE_DAG_API +#include +#include +#endif + +#ifdef HAVE_REMOTE +#include +#endif + +int +pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ + +#ifdef HAVE_REMOTE + /* Checks the capture type */ + if (p->rmt_clientside) + { + /* We are on an remote capture */ + if (!p->rmt_capstarted) + { + // if the capture has not started yet, please start it + if (pcap_startcapture_remote(p) ) + return -1; + } + } +#endif /* HAVE_REMOTE */ + + return p->read_op(p, cnt, callback, user); +} + +/* + * XXX - is this necessary? + */ +int +pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ + + return p->read_op(p, cnt, callback, user); +} + +int +pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ + register int n; + +#ifdef HAVE_REMOTE + /* Checks the capture type */ + if (p->rmt_clientside) + { + /* We are on an remote capture */ + if (!p->rmt_capstarted) + { + // if the capture has not started yet, please start it + if (pcap_startcapture_remote(p) ) + return -1; + } + } +#endif /* HAVE_REMOTE */ + + for (;;) { + if (p->sf.rfile != NULL) { + /* + * 0 means EOF, so don't loop if we get 0. + */ + n = pcap_offline_read(p, cnt, callback, user); + } else { + /* + * XXX keep reading until we get something + * (or an error occurs) + */ + do { + n = p->read_op(p, cnt, callback, user); + } while (n == 0); + } + if (n <= 0) + return (n); + if (cnt > 0) { + cnt -= n; + if (cnt <= 0) + return (0); + } + } +} + +struct singleton { + struct pcap_pkthdr *hdr; + const u_char *pkt; +}; + + +static void +pcap_oneshot(u_char *userData, const struct pcap_pkthdr *h, const u_char *pkt) +{ + struct singleton *sp = (struct singleton *)userData; + *sp->hdr = *h; + sp->pkt = pkt; +} + +const u_char * +pcap_next(pcap_t *p, struct pcap_pkthdr *h) +{ + struct singleton s; + + s.hdr = h; + if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <= 0) + return (0); + return (s.pkt); +} + +struct pkt_for_fakecallback { + struct pcap_pkthdr *hdr; + const u_char **pkt; +}; + +static void +pcap_fakecallback(u_char *userData, const struct pcap_pkthdr *h, + const u_char *pkt) +{ + struct pkt_for_fakecallback *sp = (struct pkt_for_fakecallback *)userData; + + *sp->hdr = *h; + *sp->pkt = pkt; +} + +int +pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, + const u_char **pkt_data) +{ + struct pkt_for_fakecallback s; + + s.hdr = &p->pcap_header; + s.pkt = pkt_data; + + /* Saves a pointer to the packet headers */ + *pkt_header= &p->pcap_header; + +#ifdef HAVE_REMOTE + /* Checks the capture type */ + if (p->rmt_clientside) + { + /* We are on an remote capture */ + if (!p->rmt_capstarted) + { + // if the capture has not started yet, please start it + if (pcap_startcapture_remote(p) ) + return -1; + } + + return pcap_read_nocb_remote(p, pkt_header, (u_char **) pkt_data); + } +#endif /* HAVE_REMOTE */ + + if (p->sf.rfile != NULL) { + int status; + + /* We are on an offline capture */ + status = pcap_offline_read(p, 1, pcap_fakecallback, + (u_char *)&s); + + /* + * Return codes for pcap_offline_read() are: + * - 0: EOF + * - -1: error + * - >1: OK + * The first one ('0') conflicts with the return code of + * 0 from pcap_read() meaning "no packets arrived before + * the timeout expired", so we map it to -2 so you can + * distinguish between an EOF from a savefile and a + * "no packets arrived before the timeout expired, try + * again" from a live capture. + */ + if (status == 0) + return (-2); + else + return (status); + } + + /* + * Return codes for pcap_read() are: + * - 0: timeout + * - -1: error + * - -2: loop was broken out of with pcap_breakloop() + * - >1: OK + * The first one ('0') conflicts with the return code of 0 from + * pcap_offline_read() meaning "end of file". + */ + return (p->read_op(p, 1, pcap_fakecallback, (u_char *)&s)); +} + +/* + * Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate. + */ +void +pcap_breakloop(pcap_t *p) +{ + p->break_loop = 1; +} + +int +pcap_datalink(pcap_t *p) +{ + return (p->linktype); +} + +int +pcap_list_datalinks(pcap_t *p, int **dlt_buffer) +{ + if (p->dlt_count == 0) { + /* + * We couldn't fetch the list of DLTs, which means + * this platform doesn't support changing the + * DLT for an interface. Return a list of DLTs + * containing only the DLT this device supports. + */ + *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer)); + if (*dlt_buffer == NULL) { + (void)snprintf(p->errbuf, sizeof(p->errbuf), + "malloc: %s", pcap_strerror(errno)); + return (-1); + } + **dlt_buffer = p->linktype; + return (1); + } else { + *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer) * p->dlt_count); + if (*dlt_buffer == NULL) { + (void)snprintf(p->errbuf, sizeof(p->errbuf), + "malloc: %s", pcap_strerror(errno)); + return (-1); + } + (void)memcpy(*dlt_buffer, p->dlt_list, + sizeof(**dlt_buffer) * p->dlt_count); + return (p->dlt_count); + } +} + +int +pcap_set_datalink(pcap_t *p, int dlt) +{ + int i; + const char *dlt_name; + + if (p->dlt_count == 0 || p->set_datalink_op == NULL) { + /* + * We couldn't fetch the list of DLTs, or we don't + * have a "set datalink" operation, which means + * this platform doesn't support changing the + * DLT for an interface. Check whether the new + * DLT is the one this interface supports. + */ + if (p->linktype != dlt) + goto unsupported; + + /* + * It is, so there's nothing we need to do here. + */ + return (0); + } + for (i = 0; i < p->dlt_count; i++) + if (p->dlt_list[i] == dlt) + break; + if (i >= p->dlt_count) + goto unsupported; + if (p->dlt_count == 2 && p->dlt_list[0] == DLT_EN10MB && + dlt == DLT_DOCSIS) { + /* + * This is presumably an Ethernet device, as the first + * link-layer type it offers is DLT_EN10MB, and the only + * other type it offers is DLT_DOCSIS. That means that + * we can't tell the driver to supply DOCSIS link-layer + * headers - we're just pretending that's what we're + * getting, as, presumably, we're capturing on a dedicated + * link to a Cisco Cable Modem Termination System, and + * it's putting raw DOCSIS frames on the wire inside low-level + * Ethernet framing. + */ + p->linktype = dlt; + return (0); + } + if (p->set_datalink_op(p, dlt) == -1) + return (-1); + p->linktype = dlt; + return (0); + +unsupported: + dlt_name = pcap_datalink_val_to_name(dlt); + if (dlt_name != NULL) { + (void) snprintf(p->errbuf, sizeof(p->errbuf), + "%s is not one of the DLTs supported by this device", + dlt_name); + } else { + (void) snprintf(p->errbuf, sizeof(p->errbuf), + "DLT %d is not one of the DLTs supported by this device", + dlt); + } + return (-1); +} + +struct dlt_choice { + const char *name; + const char *description; + int dlt; +}; + +#define DLT_CHOICE(code, description) { #code, description, code } +#define DLT_CHOICE_SENTINEL { NULL, NULL, 0 } + +static struct dlt_choice dlt_choices[] = { + DLT_CHOICE(DLT_NULL, "BSD loopback"), + DLT_CHOICE(DLT_EN10MB, "Ethernet"), + DLT_CHOICE(DLT_IEEE802, "Token ring"), + DLT_CHOICE(DLT_ARCNET, "ARCNET"), + DLT_CHOICE(DLT_SLIP, "SLIP"), + DLT_CHOICE(DLT_PPP, "PPP"), + DLT_CHOICE(DLT_FDDI, "FDDI"), + DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 LLC-encapsulated ATM"), + DLT_CHOICE(DLT_RAW, "Raw IP"), + DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"), + DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"), + DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"), + DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"), + DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"), + DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"), + DLT_CHOICE(DLT_IEEE802_11, "802.11"), + DLT_CHOICE(DLT_FRELAY, "Frame Relay"), + DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"), + DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"), + DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"), + DLT_CHOICE(DLT_LTALK, "Localtalk"), + DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"), + DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"), + DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"), + DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"), + DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus BSD radio information header"), + DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"), + DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"), + DLT_CHOICE(DLT_DOCSIS, "DOCSIS"), + DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"), + DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"), + DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"), + DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"), + DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"), + DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"), + DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"), + DLT_CHOICE(DLT_PPP_PPPD, "PPP for pppd, with direction flag"), + DLT_CHOICE(DLT_JUNIPER_PPPOE, "Juniper PPPoE"), + DLT_CHOICE(DLT_JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"), + DLT_CHOICE(DLT_GPRS_LLC, "GPRS LLC"), + DLT_CHOICE(DLT_GPF_T, "GPF-T"), + DLT_CHOICE(DLT_GPF_F, "GPF-F"), + DLT_CHOICE(DLT_JUNIPER_PIC_PEER, "Juniper PIC Peer"), + DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"), + DLT_CHOICE(DLT_ERF_ETH, "Ethernet with Endace ERF header"), + DLT_CHOICE(DLT_ERF_POS, "Packet-over-SONET with Endace ERF header"), + DLT_CHOICE(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"), + DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"), + DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"), + DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"), + DLT_CHOICE(DLT_JUNIPER_MFR, "Juniper FRF.16 Frame Relay"), + DLT_CHOICE(DLT_JUNIPER_ETHER, "Juniper Ethernet"), + DLT_CHOICE(DLT_JUNIPER_PPP, "Juniper PPP"), + DLT_CHOICE(DLT_JUNIPER_FRELAY, "Juniper Frame Relay"), + DLT_CHOICE(DLT_JUNIPER_CHDLC, "Juniper C-HDLC"), + DLT_CHOICE(DLT_MFR, "FRF.16 Frame Relay"), + DLT_CHOICE(DLT_JUNIPER_VP, "Juniper Voice PIC"), + DLT_CHOICE(DLT_A429, "Arinc 429"), + DLT_CHOICE(DLT_CAN20B, "Controller Area Network (CAN) v. 2.0B"), + DLT_CHOICE(DLT_A653_ICM, "Arinc 653 Interpartition Communication"), + DLT_CHOICE_SENTINEL +}; + +/* + * This array is designed for mapping upper and lower case letter + * together for a case independent comparison. The mappings are + * based upon ascii character sequences. + */ +static const u_char charmap[] = { + (u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003', + (u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007', + (u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013', + (u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017', + (u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023', + (u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027', + (u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033', + (u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037', + (u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043', + (u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047', + (u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053', + (u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057', + (u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063', + (u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067', + (u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073', + (u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077', + (u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143', + (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', + (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', + (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', + (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', + (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', + (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133', + (u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137', + (u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143', + (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', + (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', + (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', + (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', + (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', + (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173', + (u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177', + (u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203', + (u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207', + (u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213', + (u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217', + (u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223', + (u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227', + (u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233', + (u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237', + (u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243', + (u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247', + (u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253', + (u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257', + (u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263', + (u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267', + (u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273', + (u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277', + (u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343', + (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', + (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', + (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', + (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', + (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', + (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333', + (u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337', + (u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343', + (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', + (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', + (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', + (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', + (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', + (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373', + (u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377', +}; + +int +pcap_strcasecmp(const char *s1, const char *s2) +{ + register const u_char *cm = charmap, + *us1 = (u_char *)s1, + *us2 = (u_char *)s2; + + while (cm[*us1] == cm[*us2++]) + if (*us1++ == '\0') + return(0); + return (cm[*us1] - cm[*--us2]); +} + +int +pcap_datalink_name_to_val(const char *name) +{ + int i; + + for (i = 0; dlt_choices[i].name != NULL; i++) { + if (pcap_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1, + name) == 0) + return (dlt_choices[i].dlt); + } + return (-1); +} + +const char * +pcap_datalink_val_to_name(int dlt) +{ + int i; + + for (i = 0; dlt_choices[i].name != NULL; i++) { + if (dlt_choices[i].dlt == dlt) + return (dlt_choices[i].name + sizeof("DLT_") - 1); + } + return (NULL); +} + +const char * +pcap_datalink_val_to_description(int dlt) +{ + int i; + + for (i = 0; dlt_choices[i].name != NULL; i++) { + if (dlt_choices[i].dlt == dlt) + return (dlt_choices[i].description); + } + return (NULL); +} + +int +pcap_snapshot(pcap_t *p) +{ + return (p->snapshot); +} + +int +pcap_is_swapped(pcap_t *p) +{ + return (p->sf.swapped); +} + +int +pcap_major_version(pcap_t *p) +{ + return (p->sf.version_major); +} + +int +pcap_minor_version(pcap_t *p) +{ + return (p->sf.version_minor); +} + +FILE * +pcap_file(pcap_t *p) +{ + return (p->sf.rfile); +} + +int +pcap_fileno(pcap_t *p) +{ +#ifdef HAVE_REMOTE + if (p->rmt_clientside) + return(p->rmt_sockdata); +#endif /* HAVE_REMOTE */ + +#ifndef WIN32 + return (p->fd); +#else + if (p->adapter != NULL) + return ((int)(DWORD)p->adapter->hFile); + else + return (-1); +#endif +} + +#if !defined(WIN32) && !defined(MSDOS) +int +pcap_get_selectable_fd(pcap_t *p) +{ + return (p->selectable_fd); +} +#endif + +void +pcap_perror(pcap_t *p, char *prefix) +{ + fprintf(stderr, "%s: %s\n", prefix, p->errbuf); +} + +char * +pcap_geterr(pcap_t *p) +{ + return (p->errbuf); +} + +int +pcap_getnonblock(pcap_t *p, char *errbuf) +{ + return p->getnonblock_op(p, errbuf); +} + +/* + * Get the current non-blocking mode setting, under the assumption that + * it's just the standard POSIX non-blocking flag. + * + * We don't look at "p->nonblock", in case somebody tweaked the FD + * directly. + */ +#if !defined(WIN32) && !defined(MSDOS) +int +pcap_getnonblock_fd(pcap_t *p, char *errbuf) +{ + int fdflags; + + fdflags = fcntl(p->fd, F_GETFL, 0); + if (fdflags == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", + pcap_strerror(errno)); + return (-1); + } + if (fdflags & O_NONBLOCK) + return (1); + else + return (0); +} +#endif + +int +pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf) +{ + return p->setnonblock_op(p, nonblock, errbuf); +} + +#if !defined(WIN32) && !defined(MSDOS) +/* + * Set non-blocking mode, under the assumption that it's just the + * standard POSIX non-blocking flag. (This can be called by the + * per-platform non-blocking-mode routine if that routine also + * needs to do some additional work.) + */ +int +pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf) +{ + int fdflags; + + fdflags = fcntl(p->fd, F_GETFL, 0); + if (fdflags == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", + pcap_strerror(errno)); + return (-1); + } + if (nonblock) + fdflags |= O_NONBLOCK; + else + fdflags &= ~O_NONBLOCK; + if (fcntl(p->fd, F_SETFL, fdflags) == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s", + pcap_strerror(errno)); + return (-1); + } + return (0); +} +#endif + +#ifdef WIN32 +/* + * Generate a string for the last Win32-specific error (i.e. an error generated when + * calling a Win32 API). + * For errors occurred during standard C calls, we still use pcap_strerror() + */ +char * +pcap_win32strerror(void) +{ + DWORD error; + static char errbuf[PCAP_ERRBUF_SIZE+1]; + int errlen; + char *p; + + error = GetLastError(); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, + PCAP_ERRBUF_SIZE, NULL); + + /* + * "FormatMessage()" "helpfully" sticks CR/LF at the end of the + * message. Get rid of it. + */ + errlen = strlen(errbuf); + if (errlen >= 2) { + errbuf[errlen - 1] = '\0'; + errbuf[errlen - 2] = '\0'; + } + p = strchr(errbuf, '\0'); + snprintf (p, sizeof(errbuf)-(p-errbuf), " (%lu)", error); + return (errbuf); +} +#endif + +/* + * Not all systems have strerror(). + */ +char * +pcap_strerror(int errnum) +{ +#ifdef HAVE_STRERROR + return (strerror(errnum)); +#else + extern int sys_nerr; + extern const char *const sys_errlist[]; + static char ebuf[20]; + + if ((unsigned int)errnum < sys_nerr) + return ((char *)sys_errlist[errnum]); + (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); + return(ebuf); +#endif +} + +int +pcap_setfilter(pcap_t *p, struct bpf_program *fp) +{ + return p->setfilter_op(p, fp); +} + +/* + * Set direction flag, which controls whether we accept only incoming + * packets, only outgoing packets, or both. + * Note that, depending on the platform, some or all direction arguments + * might not be supported. + */ +int +pcap_setdirection(pcap_t *p, pcap_direction_t d) +{ + if (p->setdirection_op == NULL) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Setting direction is not implemented on this platform"); + return -1; + } else + return p->setdirection_op(p, d); +} + +int +pcap_stats(pcap_t *p, struct pcap_stat *ps) +{ + return p->stats_op(p, ps); +} + +static int +pcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Statistics aren't available from a pcap_open_dead pcap_t"); + return (-1); +} + +void +pcap_close_common(pcap_t *p) +{ + if (p->buffer != NULL) + free(p->buffer); +#if !defined(WIN32) && !defined(MSDOS) + if (p->fd >= 0) + close(p->fd); +#endif +} + +static void +pcap_close_dead(pcap_t *p _U_) +{ + /* Nothing to do. */ +} + +pcap_t * +pcap_open_dead(int linktype, int snaplen) +{ + pcap_t *p; + + p = malloc(sizeof(*p)); + if (p == NULL) + return NULL; + memset (p, 0, sizeof(*p)); + p->snapshot = snaplen; + p->linktype = linktype; + p->stats_op = pcap_stats_dead; + p->close_op = pcap_close_dead; + return p; +} + +/* + * API compatible with WinPcap's "send a packet" routine - returns -1 + * on error, 0 otherwise. + * + * XXX - what if we get a short write? + */ +int +pcap_sendpacket(pcap_t *p, const u_char *buf, int size) +{ + if (p->inject_op(p, buf, size) == -1) + return (-1); + return (0); +} + +/* + * API compatible with OpenBSD's "send a packet" routine - returns -1 on + * error, number of bytes written otherwise. + */ +int +pcap_inject(pcap_t *p, const void *buf, size_t size) +{ + return (p->inject_op(p, buf, size)); +} + +void +pcap_close(pcap_t *p) +{ + p->close_op(p); + if (p->dlt_list != NULL) + free(p->dlt_list); + pcap_freecode(&p->fcode); + free(p); +} + +/* + * We make the version string static, and return a pointer to it, rather + * than exporting the version string directly. On at least some UNIXes, + * if you import data from a shared library into an program, the data is + * bound into the program binary, so if the string in the version of the + * library with which the program was linked isn't the same as the + * string in the version of the library with which the program is being + * run, various undesirable things may happen (warnings, the string + * being the one from the version of the library with which the program + * was linked, or even weirder things, such as the string being the one + * from the library but being truncated). + */ +#ifdef HAVE_VERSION_H +#include "version.h" +#else +static const char pcap_version_string[] = "libpcap version 0.9.5"; +#endif + +#ifdef WIN32 +/* + * XXX - it'd be nice if we could somehow generate the WinPcap and libpcap + * version numbers when building WinPcap. (It'd be nice to do so for + * the packet.dll version number as well.) + */ +static const char wpcap_version_string[] = "4.0.2"; +static const char pcap_version_string_fmt[] = + "WinPcap version %s, based on %s"; +static const char pcap_version_string_packet_dll_fmt[] = + "WinPcap version %s (packet.dll version %s), based on %s"; +static char *full_pcap_version_string; + +const char * +pcap_lib_version(void) +{ + char *packet_version_string; + size_t full_pcap_version_string_len; + + if (full_pcap_version_string == NULL) { + /* + * Generate the version string. + */ + packet_version_string = PacketGetVersion(); + if (strcmp(wpcap_version_string, packet_version_string) == 0) { + /* + * WinPcap version string and packet.dll version + * string are the same; just report the WinPcap + * version. + */ + full_pcap_version_string_len = + (sizeof pcap_version_string_fmt - 4) + + strlen(wpcap_version_string) + + strlen(pcap_version_string); + full_pcap_version_string = + malloc(full_pcap_version_string_len); + sprintf(full_pcap_version_string, + pcap_version_string_fmt, wpcap_version_string, + pcap_version_string); + } else { + /* + * WinPcap version string and packet.dll version + * string are different; that shouldn't be the + * case (the two libraries should come from the + * same version of WinPcap), so we report both + * versions. + */ + full_pcap_version_string_len = + (sizeof pcap_version_string_packet_dll_fmt - 6) + + strlen(wpcap_version_string) + + strlen(packet_version_string) + + strlen(pcap_version_string); + full_pcap_version_string = malloc(full_pcap_version_string_len); + + sprintf(full_pcap_version_string, + pcap_version_string_packet_dll_fmt, + wpcap_version_string, packet_version_string, + pcap_version_string); + } + } + return (full_pcap_version_string); +} + +#elif defined(MSDOS) + +static char *full_pcap_version_string; + +const char * +pcap_lib_version (void) +{ + char *packet_version_string; + size_t full_pcap_version_string_len; + static char dospfx[] = "DOS-"; + + if (full_pcap_version_string == NULL) { + /* + * Generate the version string. + */ + full_pcap_version_string_len = + sizeof dospfx + strlen(pcap_version_string); + full_pcap_version_string = + malloc(full_pcap_version_string_len); + strcpy(full_pcap_version_string, dospfx); + strcat(full_pcap_version_string, pcap_version_string); + } + return (full_pcap_version_string); +} + +#else /* UN*X */ + +const char * +pcap_lib_version(void) +{ + return (pcap_version_string); +} +#endif diff --git a/winpcap/wpcap/libpcap/pcap.h b/winpcap/wpcap/libpcap/pcap.h new file mode 100644 index 0000000..c8a5711 --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap.h @@ -0,0 +1,344 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.52.2.6 2006/02/09 22:26:49 guy Exp $ (LBL) + */ + +#ifndef lib_pcap_h +#define lib_pcap_h + +#if defined(WIN32) + #include +#elif defined(MSDOS) + #include + #include /* u_int, u_char etc. */ +#else /* UN*X */ + #include + #include +#endif /* WIN32/MSDOS/UN*X */ + +#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H +#include +#endif + +#include + +#ifdef HAVE_REMOTE + // We have to define the SOCKET here, although it has been defined in sockutils.h + // This is to avoid the distribution of the 'sockutils.h' file around + // (for example in the WinPcap developer's pack) + #ifndef SOCKET + #ifdef WIN32 + #define SOCKET unsigned int + #else + #define SOCKET int + #endif + #endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define PCAP_VERSION_MAJOR 2 +#define PCAP_VERSION_MINOR 4 + +#define PCAP_ERRBUF_SIZE 256 + +/* + * Compatibility for systems that have a bpf.h that + * predates the bpf typedefs for 64-bit support. + */ +#if BPF_RELEASE - 0 < 199406 +typedef int bpf_int32; +typedef u_int bpf_u_int32; +#endif + +typedef struct pcap pcap_t; +typedef struct pcap_dumper pcap_dumper_t; +typedef struct pcap_if pcap_if_t; +typedef struct pcap_addr pcap_addr_t; + +/* + * The first record in the file contains saved values for some + * of the flags used in the printout phases of tcpdump. + * Many fields here are 32 bit ints so compilers won't insert unwanted + * padding; these files need to be interchangeable across architectures. + * + * Do not change the layout of this structure, in any way (this includes + * changes that only affect the length of fields in this structure). + * + * Also, do not change the interpretation of any of the members of this + * structure, in any way (this includes using values other than + * LINKTYPE_ values, as defined in "savefile.c", in the "linktype" + * field). + * + * Instead: + * + * introduce a new structure for the new format, if the layout + * of the structure changed; + * + * send mail to "tcpdump-workers@tcpdump.org", requesting a new + * magic number for your new capture file format, and, when + * you get the new magic number, put it in "savefile.c"; + * + * use that magic number for save files with the changed file + * header; + * + * make the code in "savefile.c" capable of reading files with + * the old file header as well as files with the new file header + * (using the magic number to determine the header format). + * + * Then supply the changes to "patches@tcpdump.org", so that future + * versions of libpcap and programs that use it (such as tcpdump) will + * be able to read your new capture file format. + */ +struct pcap_file_header { + bpf_u_int32 magic; + u_short version_major; + u_short version_minor; + bpf_int32 thiszone; /* gmt to local correction */ + bpf_u_int32 sigfigs; /* accuracy of timestamps */ + bpf_u_int32 snaplen; /* max length saved portion of each pkt */ + bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ +}; + +typedef enum { + PCAP_D_INOUT = 0, + PCAP_D_IN, + PCAP_D_OUT +} pcap_direction_t; + +/* + * Generic per-packet information, as supplied by libpcap. + * + * The time stamp can and should be a "struct timeval", regardless of + * whether your system supports 32-bit tv_sec in "struct timeval", + * 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit + * and 64-bit applications. The on-disk format of savefiles uses 32-bit + * tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit + * and 64-bit versions of libpcap, even if they're on the same platform, + * should supply the appropriate version of "struct timeval", even if + * that's not what the underlying packet capture mechanism supplies. + */ +struct pcap_pkthdr { + struct timeval ts; /* time stamp */ + bpf_u_int32 caplen; /* length of portion present */ + bpf_u_int32 len; /* length this packet (off wire) */ +}; + +/* + * As returned by the pcap_stats() + */ +struct pcap_stat { + u_int ps_recv; /* number of packets received */ + u_int ps_drop; /* number of packets dropped */ + u_int ps_ifdrop; /* drops by interface XXX not yet supported */ +#ifdef HAVE_REMOTE + u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ + u_int ps_sent; /* number of packets sent by the server on the network */ + u_int ps_netdrop; /* number of packets lost on the network */ +#endif /* HAVE_REMOTE */ +}; + +#ifdef MSDOS +/* + * As returned by the pcap_stats_ex() + */ +struct pcap_stat_ex { + u_long rx_packets; /* total packets received */ + u_long tx_packets; /* total packets transmitted */ + u_long rx_bytes; /* total bytes received */ + u_long tx_bytes; /* total bytes transmitted */ + u_long rx_errors; /* bad packets received */ + u_long tx_errors; /* packet transmit problems */ + u_long rx_dropped; /* no space in Rx buffers */ + u_long tx_dropped; /* no space available for Tx */ + u_long multicast; /* multicast packets received */ + u_long collisions; + + /* detailed rx_errors: */ + u_long rx_length_errors; + u_long rx_over_errors; /* receiver ring buff overflow */ + u_long rx_crc_errors; /* recv'd pkt with crc error */ + u_long rx_frame_errors; /* recv'd frame alignment error */ + u_long rx_fifo_errors; /* recv'r fifo overrun */ + u_long rx_missed_errors; /* recv'r missed packet */ + + /* detailed tx_errors */ + u_long tx_aborted_errors; + u_long tx_carrier_errors; + u_long tx_fifo_errors; + u_long tx_heartbeat_errors; + u_long tx_window_errors; + }; +#endif + +/* + * Item in a list of interfaces. + */ +struct pcap_if { + struct pcap_if *next; + char *name; /* name to hand to "pcap_open_live()" */ + char *description; /* textual description of interface, or NULL */ + struct pcap_addr *addresses; + bpf_u_int32 flags; /* PCAP_IF_ interface flags */ +}; + +#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ + +/* + * Representation of an interface address. + */ +struct pcap_addr { + struct pcap_addr *next; + struct sockaddr *addr; /* address */ + struct sockaddr *netmask; /* netmask for that address */ + struct sockaddr *broadaddr; /* broadcast address for that address */ + struct sockaddr *dstaddr; /* P2P destination address for that address */ +}; + +typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, + const u_char *); + +char *pcap_lookupdev(char *); +int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); +pcap_t *pcap_open_live(const char *, int, int, int, char *); +pcap_t *pcap_open_dead(int, int); +pcap_t *pcap_open_offline(const char *, char *); +pcap_t *pcap_fopen_offline(FILE *, char *); +void pcap_close(pcap_t *); +int pcap_loop(pcap_t *, int, pcap_handler, u_char *); +int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); +const u_char* + pcap_next(pcap_t *, struct pcap_pkthdr *); +int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **); +void pcap_breakloop(pcap_t *); +int pcap_stats(pcap_t *, struct pcap_stat *); +int pcap_setfilter(pcap_t *, struct bpf_program *); +int pcap_setdirection(pcap_t *, pcap_direction_t); +int pcap_getnonblock(pcap_t *, char *); +int pcap_setnonblock(pcap_t *, int, char *); +void pcap_perror(pcap_t *, char *); +int pcap_inject(pcap_t *, const void *, size_t); +int pcap_sendpacket(pcap_t *, const u_char *, int); +char *pcap_strerror(int); +char *pcap_geterr(pcap_t *); +int pcap_compile(pcap_t *, struct bpf_program *, char *, int, + bpf_u_int32); +int pcap_compile_nopcap(int, int, struct bpf_program *, + char *, int, bpf_u_int32); +void pcap_freecode(struct bpf_program *); +int pcap_datalink(pcap_t *); +int pcap_list_datalinks(pcap_t *, int **); +int pcap_set_datalink(pcap_t *, int); +int pcap_datalink_name_to_val(const char *); +const char *pcap_datalink_val_to_name(int); +const char *pcap_datalink_val_to_description(int); +int pcap_snapshot(pcap_t *); +int pcap_is_swapped(pcap_t *); +int pcap_major_version(pcap_t *); +int pcap_minor_version(pcap_t *); + +/* XXX */ +FILE *pcap_file(pcap_t *); +int pcap_fileno(pcap_t *); + +pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); +pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp); +FILE *pcap_dump_file(pcap_dumper_t *); +long pcap_dump_ftell(pcap_dumper_t *); +int pcap_dump_flush(pcap_dumper_t *); +void pcap_dump_close(pcap_dumper_t *); +void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); + +int pcap_findalldevs(pcap_if_t **, char *); +void pcap_freealldevs(pcap_if_t *); + +const char *pcap_lib_version(void); + +/* XXX this guy lives in the bpf tree */ +u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); +int bpf_validate(struct bpf_insn *f, int len); +char *bpf_image(struct bpf_insn *, int); +void bpf_dump(struct bpf_program *, int); + +#if defined(WIN32) + +/* + * Win32 definitions + */ + +int pcap_setbuff(pcap_t *p, int dim); +int pcap_setmode(pcap_t *p, int mode); +int pcap_setmintocopy(pcap_t *p, int size); + +#ifdef WPCAP +/* Include file with the wpcap-specific extensions */ +#include +#endif /* WPCAP */ + +#define MODE_CAPT 0 +#define MODE_STAT 1 +#define MODE_MON 2 + +#elif defined(MSDOS) + +/* + * MS-DOS definitions + */ + +int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *); +void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait); +u_long pcap_mac_packets (void); + +#else /* UN*X */ + +/* + * UN*X definitions + */ + +int pcap_get_selectable_fd(pcap_t *); + +#endif /* WIN32/MSDOS/UN*X */ + +#ifdef HAVE_REMOTE +/* Includes most of the public stuff that is needed for the remote capture */ +#include "remote-ext.h" +#endif /* HAVE_REMOTE */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/winpcap/wpcap/libpcap/pcap1.h b/winpcap/wpcap/libpcap/pcap1.h new file mode 100644 index 0000000..08d0c5a --- /dev/null +++ b/winpcap/wpcap/libpcap/pcap1.h @@ -0,0 +1,302 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#) $Header: /tcpdump/master/libpcap/pcap1.h,v 1.2 2004/03/30 14:42:50 mcr Exp $ (LBL) + */ + +#ifndef lib_pcap_h +#define lib_pcap_h + +#ifdef WIN32 +#include +#else /* WIN32 */ +#include +#include +#endif /* WIN32 */ + +#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H +#include +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PCAP_VERSION_MAJOR 3 +#define PCAP_VERSION_MINOR 0 + +#define PCAP_ERRBUF_SIZE 256 + +/* + * Compatibility for systems that have a bpf.h that + * predates the bpf typedefs for 64-bit support. + */ +#if BPF_RELEASE - 0 < 199406 +typedef int bpf_int32; +typedef u_int bpf_u_int32; +#endif + +typedef struct pcap pcap_t; +typedef struct pcap_dumper pcap_dumper_t; +typedef struct pcap_if pcap_if_t; +typedef struct pcap_addr pcap_addr_t; + +/* + * The first record in the file contains saved values for some + * of the flags used in the printout phases of tcpdump. + * Many fields here are 32 bit ints so compilers won't insert unwanted + * padding; these files need to be interchangeable across architectures. + * + * Do not change the layout of this structure, in any way (this includes + * changes that only affect the length of fields in this structure). + * + * Also, do not change the interpretation of any of the members of this + * structure, in any way (this includes using values other than + * LINKTYPE_ values, as defined in "savefile.c", in the "linktype" + * field). + * + * Instead: + * + * introduce a new structure for the new format, if the layout + * of the structure changed; + * + * send mail to "tcpdump-workers@tcpdump.org", requesting a new + * magic number for your new capture file format, and, when + * you get the new magic number, put it in "savefile.c"; + * + * use that magic number for save files with the changed file + * header; + * + * make the code in "savefile.c" capable of reading files with + * the old file header as well as files with the new file header + * (using the magic number to determine the header format). + * + * Then supply the changes to "patches@tcpdump.org", so that future + * versions of libpcap and programs that use it (such as tcpdump) will + * be able to read your new capture file format. + */ + +enum pcap1_info_types { + PCAP_DATACAPTURE, + PCAP_TIMESTAMP, + PCAP_WALLTIME, + PCAP_TIMESKEW, + PCAP_PROBEPLACE, /* aka direction */ + PCAP_COMMENT, /* comment */ +}; + +struct pcap1_info_container { + bpf_u_int32 info_len; /* in bytes */ + bpf_u_int32 info_type; /* enum pcap1_info_types */ + unsigned char info_data[0]; +}; + +struct pcap1_info_timestamp { + struct pcap1_info_container pic; + bpf_u_int32 nanoseconds; /* 10^-9 of seconds */ + bpf_u_int32 seconds; /* seconds since Unix epoch - GMT */ + bpf_u_int16 macroseconds; /* 16 bits more of MSB of time */ + bpf_u_int16 sigfigs; /* accuracy of timestamps - LSB bits */ +}; + +struct pcap1_info_packet { + struct pcap1_info_container pic; + bpf_u_int32 caplen; /* length of portion present */ + bpf_u_int32 len; /* length this packet (off wire) */ + bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ + bpf_u_int32 ifIndex; /* abstracted interface index */ + unsigned char packet_data[0]; +}; + +enum pcap1_probe { + INBOUND =1, + OUTBOUND =2, + FORWARD =3, + PREENCAP =4, + POSTDECAP=5, +}; + +struct pcap1_info_probe { + struct pcap1_info_container pic; + bpf_u_int32 probeloc; /* enum pcap1_probe */ + unsigned char probe_desc[0]; +}; + +struct pcap1_info_comment { + struct pcap1_info_container pic; + unsigned char comment[0]; +}; + +struct pcap1_packet_header { + bpf_u_int32 magic; + u_short version_major; + u_short version_minor; + bpf_u_int32 block_len; + struct pcap1_info_container pics[0]; +}; + +/* + * Each packet in the dump file is prepended with this generic header. + * This gets around the problem of different headers for different + * packet interfaces. + */ + +/* + * As returned by the pcap_stats() + */ +struct pcap_stat { + u_int ps_recv; /* number of packets received */ + u_int ps_drop; /* number of packets dropped */ + u_int ps_ifdrop; /* drops by interface XXX not yet supported */ +#ifdef WIN32 + u_int bs_capt; /* number of packets that reach the application */ +#endif /* WIN32 */ +}; + +/* + * Item in a list of interfaces. + */ +struct pcap_if { + struct pcap_if *next; + char *name; /* name to hand to "pcap_open_live()" */ + char *description; /* textual description of interface, or NULL */ + struct pcap_addr *addresses; + bpf_u_int32 flags; /* PCAP_IF_ interface flags */ +}; + +#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ + +/* + * Representation of an interface address. + */ +struct pcap_addr { + struct pcap_addr *next; + struct sockaddr *addr; /* address */ + struct sockaddr *netmask; /* netmask for that address */ + struct sockaddr *broadaddr; /* broadcast address for that address */ + struct sockaddr *dstaddr; /* P2P destination address for that address */ +}; + +typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, + const u_char *); + +char *pcap_lookupdev(char *); +int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); +pcap_t *pcap_open_live(const char *, int, int, int, char *); +pcap_t *pcap_open_dead(int, int); +pcap_t *pcap_open_offline(const char *, char *); +void pcap_close(pcap_t *); +int pcap_loop(pcap_t *, int, pcap_handler, u_char *); +int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); +const u_char* + pcap_next(pcap_t *, struct pcap_pkthdr *); +int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **); +void pcap_breakloop(pcap_t *); +int pcap_stats(pcap_t *, struct pcap_stat *); +int pcap_setfilter(pcap_t *, struct bpf_program *); +int pcap_getnonblock(pcap_t *, char *); +int pcap_setnonblock(pcap_t *, int, char *); +void pcap_perror(pcap_t *, char *); +char *pcap_strerror(int); +char *pcap_geterr(pcap_t *); +int pcap_compile(pcap_t *, struct bpf_program *, char *, int, + bpf_u_int32); +int pcap_compile_nopcap(int, int, struct bpf_program *, + char *, int, bpf_u_int32); +void pcap_freecode(struct bpf_program *); +int pcap_datalink(pcap_t *); +int pcap_list_datalinks(pcap_t *, int **); +int pcap_set_datalink(pcap_t *, int); +int pcap_datalink_name_to_val(const char *); +const char *pcap_datalink_val_to_name(int); +const char *pcap_datalink_val_to_description(int); +int pcap_snapshot(pcap_t *); +int pcap_is_swapped(pcap_t *); +int pcap_major_version(pcap_t *); +int pcap_minor_version(pcap_t *); + +/* XXX */ +FILE *pcap_file(pcap_t *); +int pcap_fileno(pcap_t *); + +pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); +int pcap_dump_flush(pcap_dumper_t *); +void pcap_dump_close(pcap_dumper_t *); +void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); +FILE *pcap_dump_file(pcap_dumper_t *); + +int pcap_findalldevs(pcap_if_t **, char *); +void pcap_freealldevs(pcap_if_t *); + +const char *pcap_lib_version(void); + +/* XXX this guy lives in the bpf tree */ +u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); +int bpf_validate(struct bpf_insn *f, int len); +char *bpf_image(struct bpf_insn *, int); +void bpf_dump(struct bpf_program *, int); + +#ifdef WIN32 +/* + * Win32 definitions + */ + +int pcap_setbuff(pcap_t *p, int dim); +int pcap_setmode(pcap_t *p, int mode); +int pcap_sendpacket(pcap_t *p, u_char *buf, int size); +int pcap_setmintocopy(pcap_t *p, int size); + +#ifdef WPCAP +/* Include file with the wpcap-specific extensions */ +#include +#endif + +#define MODE_CAPT 0 +#define MODE_STAT 1 + +#else +/* + * UN*X definitions + */ + +int pcap_get_selectable_fd(pcap_t *); + +#endif /* WIN32 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/winpcap/wpcap/libpcap/pf.h b/winpcap/wpcap/libpcap/pf.h new file mode 100644 index 0000000..a9b127a --- /dev/null +++ b/winpcap/wpcap/libpcap/pf.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2001 Daniel Hartmeier + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @(#) $Header: /tcpdump/master/libpcap/pf.h,v 1.3 2004/04/02 06:33:30 guy Exp $ (LBL) + */ + +/* from $OpenBSD: pfvar.h,v 1.170 2003/08/22 21:50:34 david Exp $ */ + +enum { PF_INOUT=0, PF_IN=1, PF_OUT=2 }; +enum { PF_PASS=0, PF_DROP=1, PF_SCRUB=2, PF_NAT=3, PF_NONAT=4, + PF_BINAT=5, PF_NOBINAT=6, PF_RDR=7, PF_NORDR=8, PF_SYNPROXY_DROP=9 }; + +/* Reasons code for passing/dropping a packet */ +#define PFRES_MATCH 0 /* Explicit match of a rule */ +#define PFRES_BADOFF 1 /* Bad offset for pull_hdr */ +#define PFRES_FRAG 2 /* Dropping following fragment */ +#define PFRES_SHORT 3 /* Dropping short packet */ +#define PFRES_NORM 4 /* Dropping by normalizer */ +#define PFRES_MEMORY 5 /* Dropped due to lacking mem */ +#define PFRES_MAX 6 /* total+1 */ + +#define PFRES_NAMES { \ + "match", \ + "bad-offset", \ + "fragment", \ + "short", \ + "normalize", \ + "memory", \ + NULL \ +} + +#define PF_RULESET_NAME_SIZE 16 + +/* from $OpenBSD: if_pflog.h,v 1.9 2003/07/15 20:27:27 dhartmei Exp $ */ + +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif + +struct pfloghdr { + u_int8_t length; + u_int8_t af; + u_int8_t action; + u_int8_t reason; + char ifname[IFNAMSIZ]; + char ruleset[PF_RULESET_NAME_SIZE]; + u_int32_t rulenr; + u_int32_t subrulenr; + u_int8_t dir; + u_int8_t pad[3]; +}; +#define PFLOG_HDRLEN sizeof(struct pfloghdr) diff --git a/winpcap/wpcap/libpcap/ppp.h b/winpcap/wpcap/libpcap/ppp.h new file mode 100644 index 0000000..80a6851 --- /dev/null +++ b/winpcap/wpcap/libpcap/ppp.h @@ -0,0 +1,58 @@ +/* @(#) $Header: /tcpdump/master/libpcap/ppp.h,v 1.12 2005/02/08 19:52:19 guy Exp $ (LBL) */ +/* + * Point to Point Protocol (PPP) RFC1331 + * + * Copyright 1989 by Carnegie Mellon. + * + * Permission to use, copy, modify, and distribute this program for any + * purpose and without fee is hereby granted, provided that this copyright + * and permission notice appear on all copies and supporting documentation, + * the name of Carnegie Mellon not be used in advertising or publicity + * pertaining to distribution of the program without specific prior + * permission, and notice be given in supporting documentation that copying + * and distribution is by permission of Carnegie Mellon and Stanford + * University. Carnegie Mellon makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ +#define PPP_ADDRESS 0xff /* The address byte value */ +#define PPP_CONTROL 0x03 /* The control byte value */ + +#define PPP_PPPD_IN 0x00 /* non-standard for DLT_PPP_PPPD */ +#define PPP_PPPD_OUT 0x01 /* non-standard for DLT_PPP_PPPD */ + +/* Protocol numbers */ +#define PPP_IP 0x0021 /* Raw IP */ +#define PPP_OSI 0x0023 /* OSI Network Layer */ +#define PPP_NS 0x0025 /* Xerox NS IDP */ +#define PPP_DECNET 0x0027 /* DECnet Phase IV */ +#define PPP_APPLE 0x0029 /* Appletalk */ +#define PPP_IPX 0x002b /* Novell IPX */ +#define PPP_VJC 0x002d /* Van Jacobson Compressed TCP/IP */ +#define PPP_VJNC 0x002f /* Van Jacobson Uncompressed TCP/IP */ +#define PPP_BRPDU 0x0031 /* Bridging PDU */ +#define PPP_STII 0x0033 /* Stream Protocol (ST-II) */ +#define PPP_VINES 0x0035 /* Banyan Vines */ +#define PPP_IPV6 0x0057 /* Internet Protocol version 6 */ + +#define PPP_HELLO 0x0201 /* 802.1d Hello Packets */ +#define PPP_LUXCOM 0x0231 /* Luxcom */ +#define PPP_SNS 0x0233 /* Sigma Network Systems */ +#define PPP_MPLS_UCAST 0x0281 /* rfc 3032 */ +#define PPP_MPLS_MCAST 0x0283 /* rfc 3022 */ + +#define PPP_IPCP 0x8021 /* IP Control Protocol */ +#define PPP_OSICP 0x8023 /* OSI Network Layer Control Protocol */ +#define PPP_NSCP 0x8025 /* Xerox NS IDP Control Protocol */ +#define PPP_DECNETCP 0x8027 /* DECnet Control Protocol */ +#define PPP_APPLECP 0x8029 /* Appletalk Control Protocol */ +#define PPP_IPXCP 0x802b /* Novell IPX Control Protocol */ +#define PPP_STIICP 0x8033 /* Strean Protocol Control Protocol */ +#define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */ +#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ +#define PPP_MPLSCP 0x8281 /* rfc 3022 */ + +#define PPP_LCP 0xc021 /* Link Control Protocol */ +#define PPP_PAP 0xc023 /* Password Authentication Protocol */ +#define PPP_LQM 0xc025 /* Link Quality Monitoring */ +#define PPP_CHAP 0xc223 /* Challenge Handshake Authentication Protocol */ diff --git a/winpcap/wpcap/libpcap/readme-rpcap.txt b/winpcap/wpcap/libpcap/readme-rpcap.txt new file mode 100644 index 0000000..f51cc84 --- /dev/null +++ b/winpcap/wpcap/libpcap/readme-rpcap.txt @@ -0,0 +1,31 @@ +******************** RPCAP AND CODE MODIFICATIONS ******************** + +These files are the ones which have to be modified when compiling a new release of WinPcap. + +All the modifications are included within: + + #ifdef REMOTE + .... + #endif + +therefore it should be quite easy to locate which point you have to modify. + + +******************** COMPILE LIBPCAP WITH RPCAP SUPPORT UNDER UNIX ******************** + +First, you must unpack all text files according to the UNIX standard. For this, you may use +"unzip -a" (it extracts the files using the platform-native format for text files) or the +dos2unix conversion utility. + +Second, you have to type '/.configure' in order to create the makefile. +In case this step fails, you should re-create the configure by launching 'autoconf' +(version 2.50 or higher) in the libpcap folder. + +Finally, you have to compile the project by typing 'make'. +In case some error occurs, let's try to delete all the config.* files from the 'libpcap' +folder and restart this process from scratch. + +These steps are able to compile the libpcap library; now you have to compile the rpcapd daemon. +For this, you have to type 'make' in the 'rpcapd' folder. + + diff --git a/winpcap/wpcap/libpcap/remote-ext.h b/winpcap/wpcap/libpcap/remote-ext.h new file mode 100644 index 0000000..9db8055 --- /dev/null +++ b/winpcap/wpcap/libpcap/remote-ext.h @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef __REMOTE_EXT_H__ +#define __REMOTE_EXT_H__ + + + +// Definition for Microsoft Visual Studio +#if _MSC_VER > 1000 +#pragma once +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + \file remote-ext.h + + The goal of this file it to include most of the new definitions that should be + placed into the pcap.h file. + + It includes all new definitions (structures and functions like pcap_open(). + Some of the functions are not really a remote feature, but, right now, + they are placed here. +*/ + + + +// All this stuff is public +/*! \addtogroup remote_struct + \{ +*/ + + + + +/*! + \brief Defines the maximum buffer size in which address, port, interface names are kept. + + In case the adapter name or such is larger than this value, it is truncated. + This is not used by the user; however it must be aware that an hostname / interface + name longer than this value will be truncated. +*/ +#define PCAP_BUF_SIZE 1024 + + +/*! \addtogroup remote_source_ID + \{ +*/ + + +/*! + \brief Internal representation of the type of source in use (file, + remote/local interface). + + This indicates a file, i.e. the user want to open a capture from a local file. +*/ +#define PCAP_SRC_FILE 2 +/*! + \brief Internal representation of the type of source in use (file, + remote/local interface). + + This indicates a local interface, i.e. the user want to open a capture from + a local interface. This does not involve the RPCAP protocol. +*/ +#define PCAP_SRC_IFLOCAL 3 +/*! + \brief Internal representation of the type of source in use (file, + remote/local interface). + + This indicates a remote interface, i.e. the user want to open a capture from + an interface on a remote host. This does involve the RPCAP protocol. +*/ +#define PCAP_SRC_IFREMOTE 4 + +/*! + \} +*/ + + + +/*! \addtogroup remote_source_string + + The formats allowed by the pcap_open() are the following: + - file://path_and_filename [opens a local file] + - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol] + - rpcap://host/devicename [opens the selected device available on a remote host] + - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP] + - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged] + - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged] + + The formats allowed by the pcap_findalldevs_ex() are the following: + - file://folder/ [lists all the files in the given folder] + - rpcap:// [lists all local adapters] + - rpcap://host:port/ [lists the devices available on a remote host] + + Referring to the 'host' and 'port' paramters, they can be either numeric or literal. Since + IPv6 is fully supported, these are the allowed formats: + + - host (literal): e.g. host.foo.bar + - host (numeric IPv4): e.g. 10.11.12.13 + - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13] + - host (numeric IPv6): e.g. [1:2:3::4] + - port: can be either numeric (e.g. '80') or literal (e.g. 'http') + + Here you find some allowed examples: + - rpcap://host.foo.bar/devicename [everything literal, no port number] + - rpcap://host.foo.bar:1234/devicename [everything literal, with port number] + - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number] + - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number] + - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number] + - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number] + - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number] + - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number] + + \{ +*/ + + +/*! + \brief String that will be used to determine the type of source in use (file, + remote/local interface). + + This string will be prepended to the interface name in order to create a string + that contains all the information required to open the source. + + This string indicates that the user wants to open a capture from a local file. +*/ +#define PCAP_SRC_FILE_STRING "file://" +/*! + \brief String that will be used to determine the type of source in use (file, + remote/local interface). + + This string will be prepended to the interface name in order to create a string + that contains all the information required to open the source. + + This string indicates that the user wants to open a capture from a network interface. + This string does not necessarily involve the use of the RPCAP protocol. If the + interface required resides on the local host, the RPCAP protocol is not involved + and the local functions are used. +*/ +#define PCAP_SRC_IF_STRING "rpcap://" + +/*! + \} +*/ + + + + + +/*! + \addtogroup remote_open_flags + \{ +*/ + +/*! + \brief Defines if the adapter has to go in promiscuous mode. + + It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise. + Note that even if this parameter is false, the interface could well be in promiscuous + mode for some other reason (for example because another capture process with + promiscuous mode enabled is currently using that interface). + On on Linux systems with 2.2 or later kernels (that have the "any" device), this + flag does not work on the "any" device; if an argument of "any" is supplied, + the 'promisc' flag is ignored. +*/ +#define PCAP_OPENFLAG_PROMISCUOUS 1 + +/*! + \brief Defines if the data trasfer (in case of a remote + capture) has to be done with UDP protocol. + + If it is '1' if you want a UDP data connection, '0' if you want + a TCP data connection; control connection is always TCP-based. + A UDP connection is much lighter, but it does not guarantee that all + the captured packets arrive to the client workstation. Moreover, + it could be harmful in case of network congestion. + This flag is meaningless if the source is not a remote interface. + In that case, it is simply ignored. +*/ +#define PCAP_OPENFLAG_DATATX_UDP 2 + + +/*! + \brief Defines if the remote probe will capture its own generated traffic. + + In case the remote probe uses the same interface to capture traffic and to send + data back to the caller, the captured traffic includes the RPCAP traffic as well. + If this flag is turned on, the RPCAP traffic is excluded from the capture, so that + the trace returned back to the collector is does not include this traffic. +*/ +#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4 + +/*! + \brief Defines if the local adapter will capture its own generated traffic. + + This flag tells the underlying capture driver to drop the packets that were sent by itself. + This is usefult when building applications like bridges, that should ignore the traffic + they just sent. +*/ +#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8 + +/*! + \brief This flag configures the adapter for maximum responsiveness. + + In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before + copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage, + i.e. better performance, which is good for applications like sniffers. If the user sets the + PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application + is ready to receive them. This is suggested for real time applications (like, for example, a bridge) + that need the best responsiveness.*/ +#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16 + +/*! + \} +*/ + + +/*! + \addtogroup remote_samp_methods + \{ +*/ + +/*! + \brief No sampling has to be done on the current capture. + + In this case, no sampling algorithms are applied to the current capture. +*/ +#define PCAP_SAMP_NOSAMP 0 + +/*! + \brief It defines that only 1 out of N packets must be returned to the user. + + In this case, the 'value' field of the 'pcap_samp' structure indicates the + number of packets (minus 1) that must be discarded before one packet got accepted. + In other words, if 'value = 10', the first packet is returned to the caller, while + the following 9 are discarded. +*/ +#define PCAP_SAMP_1_EVERY_N 1 + +/*! + \brief It defines that we have to return 1 packet every N milliseconds. + + In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting + time' in milliseconds before one packet got accepted. + In other words, if 'value = 10', the first packet is returned to the caller; the next + returned one will be the first packet that arrives when 10ms have elapsed. +*/ +#define PCAP_SAMP_FIRST_AFTER_N_MS 2 + +/*! + \} +*/ + + +/*! + \addtogroup remote_auth_methods + \{ +*/ + +/*! + \brief It defines the NULL authentication. + + This value has to be used within the 'type' member of the pcap_rmtauth structure. + The 'NULL' authentication has to be equal to 'zero', so that old applications + can just put every field of struct pcap_rmtauth to zero, and it does work. +*/ +#define RPCAP_RMTAUTH_NULL 0 +/*! + \brief It defines the username/password authentication. + + With this type of authentication, the RPCAP protocol will use the username/ + password provided to authenticate the user on the remote machine. If the + authentication is successful (and the user has the right to open network devices) + the RPCAP connection will continue; otherwise it will be dropped. + + This value has to be used within the 'type' member of the pcap_rmtauth structure. +*/ +#define RPCAP_RMTAUTH_PWD 1 + +/*! + \} +*/ + + + + +/*! + + \brief This structure keeps the information needed to autheticate + the user on a remote machine. + + The remote machine can either grant or refuse the access according + to the information provided. + In case the NULL authentication is required, both 'username' and + 'password' can be NULL pointers. + + This structure is meaningless if the source is not a remote interface; + in that case, the functions which requires such a structure can accept + a NULL pointer as well. +*/ +struct pcap_rmtauth +{ + /*! + \brief Type of the authentication required. + + In order to provide maximum flexibility, we can support different types + of authentication based on the value of this 'type' variable. The currently + supported authentication methods are defined into the + \link remote_auth_methods Remote Authentication Methods Section\endlink. + + */ + int type; + /*! + \brief Zero-terminated string containing the username that has to be + used on the remote machine for authentication. + + This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication + and it can be NULL. + */ + char *username; + /*! + \brief Zero-terminated string containing the password that has to be + used on the remote machine for authentication. + + This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication + and it can be NULL. + */ + char *password; +}; + + +/*! + \brief This structure defines the information related to sampling. + + In case the sampling is requested, the capturing device should read + only a subset of the packets coming from the source. The returned packets depend + on the sampling parameters. + + \warning The sampling process is applied after the filtering process. + In other words, packets are filtered first, then the sampling process selects a + subset of the 'filtered' packets and it returns them to the caller. +*/ +struct pcap_samp +{ + /*! + Method used for sampling. Currently, the supported methods are listed in the + \link remote_samp_methods Sampling Methods Section\endlink. + */ + int method; + + /*! + This value depends on the sampling method defined. For its meaning, please check + at the \link remote_samp_methods Sampling Methods Section\endlink. + */ + int value; +}; + + + + +//! Maximum lenght of an host name (needed for the RPCAP active mode) +#define RPCAP_HOSTLIST_SIZE 1024 + + +/*! + \} +*/ // end of public documentation + + +// Exported functions + + + +/** \name New WinPcap functions + + This section lists the new functions that are able to help considerably in writing + WinPcap programs because of their easiness of use. + */ +//\{ +pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf); +int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf); +int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf); +int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf); +struct pcap_samp *pcap_setsampling(pcap_t *p); + +//\} +// End of new winpcap functions + + + +/** \name Remote Capture functions + */ +//\{ +SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf); +int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf); +int pcap_remoteact_close(const char *host, char *errbuf); +void pcap_remoteact_cleanup(); +//\} +// End of remote capture functions + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/winpcap/wpcap/libpcap/remote_code.patch b/winpcap/wpcap/libpcap/remote_code.patch new file mode 100644 index 0000000..d3b8826 --- /dev/null +++ b/winpcap/wpcap/libpcap/remote_code.patch @@ -0,0 +1,713 @@ +diff -urb libpcap-2006.04.17/Makefile.in libpcap/Makefile.in +--- libpcap-2006.04.17/Makefile.in 2005-08-09 23:19:06.000000000 -0700 ++++ libpcap/Makefile.in 2006-04-20 20:35:58.328125000 -0700 +@@ -44,7 +44,8 @@ + CC = @CC@ + CCOPT = @V_CCOPT@ + INCLS = -I. @V_INCLS@ +-DEFS = @DEFS@ @V_DEFS@ ++# HAVE_REMOTE ++DEFS = @DEFS@ @V_DEFS@ @V_HAVE_REMOTE@ + LIBS = @V_LIBS@ + DYEXT = @DYEXT@ + +@@ -77,13 +78,17 @@ + CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c \ + etherent.c savefile.c bpf_filter.c bpf_image.c bpf_dump.c + GENSRC = scanner.c grammar.c version.c ++# HAVE_REMOTE ++REMOTESRC = @V_REMOTE_FILES@ + LIBOBJS = @LIBOBJS@ + +-SRC = $(PSRC) $(FSRC) $(CSRC) $(SSRC) $(GENSRC) ++# HAVE_REMOTE ++SRC = $(PSRC) $(FSRC) $(CSRC) $(SSRC) $(GENSRC) $(REMOTESRC) + + # We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot + # hack the extra indirection +-OBJ = $(PSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(GENSRC:.c=.o) $(LIBOBJS) ++# HAVE_REMOTE ++OBJ = $(PSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(GENSRC:.c=.o) $(REMOTESRC:.c=.o) $(LIBOBJS) + HDR = pcap.h pcap-int.h pcap-namedb.h pcap-nit.h pcap-pf.h \ + ethertype.h gencode.h gnuc.h + GENHDR = \ +diff -urb libpcap-2006.04.17/Win32/Prj/libpcap.dsp libpcap/Win32/Prj/libpcap.dsp +--- libpcap-2006.04.17/Win32/Prj/libpcap.dsp 2004-01-28 06:08:33.000000000 -0800 ++++ libpcap/Win32/Prj/libpcap.dsp 2006-04-20 20:35:58.328125000 -0700 +@@ -4,7 +4,7 @@ + + # TARGTYPE "Win32 (x86) Static Library" 0x0104 + +-CFG=libpcap - Win32 Debug ++CFG=libpcap - Win32 Debug REMOTE + !MESSAGE This is not a valid makefile. To build this project using NMAKE, + !MESSAGE use the Export Makefile command and run + !MESSAGE +@@ -13,12 +13,14 @@ + !MESSAGE You can specify a configuration when running NMAKE + !MESSAGE by defining the macro CFG on the command line. For example: + !MESSAGE +-!MESSAGE NMAKE /f "libpcap.mak" CFG="libpcap - Win32 Debug" ++!MESSAGE NMAKE /f "libpcap.mak" CFG="libpcap - Win32 Debug REMOTE" + !MESSAGE + !MESSAGE Possible choices for configuration are: + !MESSAGE + !MESSAGE "libpcap - Win32 Release" (based on "Win32 (x86) Static Library") + !MESSAGE "libpcap - Win32 Debug" (based on "Win32 (x86) Static Library") ++!MESSAGE "libpcap - Win32 Debug REMOTE" (based on "Win32 (x86) Static Library") ++!MESSAGE "libpcap - Win32 Release REMOTE" (based on "Win32 (x86) Static Library") + !MESSAGE + + # Begin Project +@@ -74,12 +76,60 @@ + # ADD BASE LIB32 /nologo + # ADD LIB32 /nologo + ++!ELSEIF "$(CFG)" == "libpcap - Win32 Debug REMOTE" ++ ++# PROP BASE Use_MFC 0 ++# PROP BASE Use_Debug_Libraries 1 ++# PROP BASE Output_Dir "libpcap___Win32_Debug_REMOTE" ++# PROP BASE Intermediate_Dir "libpcap___Win32_Debug_REMOTE" ++# PROP BASE Target_Dir "" ++# PROP Use_MFC 0 ++# PROP Use_Debug_Libraries 1 ++# PROP Output_Dir "Debug_REMOTE" ++# PROP Intermediate_Dir "Debug_REMOTE" ++# PROP Target_Dir "" ++# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "_DEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /GZ /c ++# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "_DEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "HAVE_REMOTE" /YX /FD /GZ /c ++# ADD BASE RSC /l 0x409 /d "_DEBUG" ++# ADD RSC /l 0x409 /d "_DEBUG" ++BSC32=bscmake.exe ++# ADD BASE BSC32 /nologo ++# ADD BSC32 /nologo ++LIB32=link.exe -lib ++# ADD BASE LIB32 /nologo ++# ADD LIB32 /nologo ++ ++!ELSEIF "$(CFG)" == "libpcap - Win32 Release REMOTE" ++ ++# PROP BASE Use_MFC 0 ++# PROP BASE Use_Debug_Libraries 0 ++# PROP BASE Output_Dir "libpcap___Win32_Release_REMOTE" ++# PROP BASE Intermediate_Dir "libpcap___Win32_Release_REMOTE" ++# PROP BASE Target_Dir "" ++# PROP Use_MFC 0 ++# PROP Use_Debug_Libraries 0 ++# PROP Output_Dir "Release_REMOTE" ++# PROP Intermediate_Dir "Release_REMOTE" ++# PROP Target_Dir "" ++# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "NDEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /c ++# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "NDEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "HAVE_REMOTE" /YX /FD /c ++# ADD BASE RSC /l 0x409 /d "NDEBUG" ++# ADD RSC /l 0x409 /d "NDEBUG" ++BSC32=bscmake.exe ++# ADD BASE BSC32 /nologo ++# ADD BSC32 /nologo ++LIB32=link.exe -lib ++# ADD BASE LIB32 /nologo ++# ADD LIB32 /nologo ++ + !ENDIF + + # Begin Target + + # Name "libpcap - Win32 Release" + # Name "libpcap - Win32 Debug" ++# Name "libpcap - Win32 Debug REMOTE" ++# Name "libpcap - Win32 Release REMOTE" + # Begin Source File + + SOURCE=..\..\bpf_dump.c +diff -urb libpcap-2006.04.17/configure.in libpcap/configure.in +--- libpcap-2006.04.17/configure.in 2006-04-07 00:07:25.000000000 -0700 ++++ libpcap/configure.in 2006-04-20 20:35:58.328125000 -0700 +@@ -302,6 +302,58 @@ + esac]) + fi + ++dnl HAVE_REMOTE ++AC_MSG_CHECKING(if --disable-remote option is specified) ++AC_ARG_ENABLE(remote, [ --disable-remote disable remote capture capabilities]) ++ ++case "x$enable_remote" in ++xyes) enable_remote=enabled ;; ++xno) enable_remote=disabled ;; ++x) enable_remote=enabled ;; ++esac ++ ++AC_MSG_RESULT(${enable_remote}) ++ ++ ++if test "$enable_remote" = "enabled"; then ++ ++ dnl ++ dnl Checking if the remote features of libpcap are supported by ++ dnl the OS and must be compiled ++ dnl ++ ++ AC_MSG_CHECKING(if remote capture is supported) ++ ++ if test -e ./remote-ext.h ; then # Check that the remote extensions are there ++ ++ case "$V_PCAP" in ++ ++ linux) ++ V_REMOTE_FILES="pcap-new.c pcap-remote.c sockutils.c" ++ V_HAVE_REMOTE="-DHAVE_REMOTE" ++ AC_DEFINE(HAVE_REMOTE,1,[Enable remote capture support]) ++ have_remote=yes ++ ;; ++ ++ bpf) ++ V_REMOTE_FILES="pcap-new.c pcap-remote.c sockutils.c" ++ V_HAVE_REMOTE="-DHAVE_REMOTE" ++ AC_DEFINE(HAVE_REMOTE,1,[Enable remote capture support]) ++ have_remote=yes ++ ;; ++ ++ *) ++ have_remote=no ++ ;; ++ ++ esac ++ ++ AC_MSG_RESULT(${have_remote}) ++ fi ++ ++fi ++dnl END HAVE_REMOTE ++ + AC_MSG_CHECKING(if --enable-ipv6 option is specified) + AC_ARG_ENABLE(ipv6, [ --enable-ipv6 build IPv6-capable version]) + if test "$enable_ipv6" = "yes"; then +@@ -779,6 +831,10 @@ + AC_SUBST(V_LEX) + AC_SUBST(V_PCAP) + AC_SUBST(V_FINDALLDEVS) ++# HAVE_REMOTE ++AC_SUBST(V_HAVE_REMOTE) ++AC_SUBST(V_REMOTE_FILES) ++# END HAVE_REMOTE + AC_SUBST(V_RANLIB) + AC_SUBST(V_YACC) + AC_SUBST(SSRC) +diff -urb libpcap-2006.04.17/gencode.c libpcap/gencode.c +--- libpcap-2006.04.17/gencode.c 2006-03-16 00:46:13.000000000 -0800 ++++ libpcap/gencode.c 2006-04-20 20:35:58.390625000 -0700 +@@ -353,6 +353,35 @@ + extern int n_errors; + int len; + ++#ifdef HAVE_REMOTE ++ /* ++ Check if: ++ - We are on an remote capture ++ - we do not want to capture RPCAP traffic ++ ++ If so, we have to save the current filter, because we have to add some ++ piece of stuff later ++ */ ++ if ( (p->rmt_clientside) && (p->rmt_flags & PCAP_OPENFLAG_NOCAPTURE_RPCAP) ) ++ { ++ int bufferlen; ++ ++ if (p->currentfilter) ++ free (p->currentfilter); ++ ++ if (buf) ++ bufferlen= strlen(buf) + 1; ++ else ++ bufferlen= 1; ++ ++ p->currentfilter= (char *) malloc( sizeof(char) * bufferlen); ++ ++ strncpy(p->currentfilter, buf, bufferlen); ++ ++ p->currentfilter[bufferlen - 1]= 0; ++ } ++#endif /* HAVE_REMOTE */ ++ + no_optimize = 0; + n_errors = 0; + root = NULL; +diff -urb libpcap-2006.04.17/pcap-bpf.c libpcap/pcap-bpf.c +--- libpcap-2006.04.17/pcap-bpf.c 2006-01-21 21:28:12.000000000 -0800 ++++ libpcap/pcap-bpf.c 2006-04-20 20:35:58.390625000 -0700 +@@ -102,6 +102,10 @@ + #include "os-proto.h" + #endif + ++#ifdef HAVE_REMOTE ++#include ++#endif /* HAVE_REMOTE */ ++ + #include "gencode.h" /* for "no_optimize" */ + + static int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp); +@@ -597,6 +601,37 @@ + struct bpf_program total_prog; + struct utsname osinfo; + ++#ifdef HAVE_REMOTE ++ /* ++ Retrofit; we have to make older applications compatible with the remote capture ++ So, we're calling the pcap_open_remote() from here, that is a very dirty thing. ++ Obviously, we cannot exploit all the new features; for instance, we cannot ++ send authentication, we cannot use a UDP data connection, and so on. ++ */ ++ ++ char host[PCAP_BUF_SIZE + 1]; ++ char port[PCAP_BUF_SIZE + 1]; ++ char name[PCAP_BUF_SIZE + 1]; ++ int srctype; ++ ++ if (pcap_parsesrcstr(device, &srctype, host, port, name, ebuf) ) ++ return NULL; ++ ++ if (srctype == PCAP_SRC_IFREMOTE) ++ { ++ p= pcap_opensource_remote(device, NULL, ebuf); ++ ++ if (p == NULL) ++ return NULL; ++ ++ p->snapshot= snaplen; ++ p->timeout= to_ms; ++ p->rmt_flags= (promisc) ? PCAP_OPENFLAG_PROMISCUOUS : 0; ++ ++ return p; ++ } ++#endif /* HAVE_REMOTE */ ++ + #ifdef HAVE_DAG_API + if (strstr(device, "dag")) { + return dag_open_live(device, snaplen, promisc, to_ms, ebuf); +diff -urb libpcap-2006.04.17/pcap-int.h libpcap/pcap-int.h +--- libpcap-2006.04.17/pcap-int.h 2006-02-22 09:09:02.000000000 -0800 ++++ libpcap/pcap-int.h 2006-04-20 20:35:58.406250000 -0700 +@@ -107,6 +107,37 @@ + * Same as in linux above, introduce + * generally? */ + #endif /* HAVE_DAG_API */ ++ ++#ifdef HAVE_REMOTE ++/*! ++ There is really a mess with previous variables, and it seems to me that they are not used ++ (they are used in pcap_pf.c only). I think we have to start using them. ++ The meaning is the following: ++ ++ - TotPkts: the amount of packets received by the bpf filter, *before* applying the filter ++ - TotAccepted: the amount of packets that satisfies the filter ++ - TotDrops: the amount of packet that were dropped into the kernel buffer because of lack of space ++ - TotMissed: the amount of packets that were dropped by the physical interface; it is basically ++ the value of the hardware counter into the card. This number is never put to zero, so this number ++ takes into account the *total* number of interface drops starting from the interface power-on. ++ - OrigMissed: the amount of packets that were dropped by the interface *when the capture begins*. ++ This value is used to detect the number of packets dropped by the interface *during the present ++ capture*, so that (ps_ifdrops= TotMissed - OrigMissed). ++*/ ++ unsigned int TotNetDrops; //!< keeps the number of packets that have been dropped by the network ++/*! ++ \brief It keeps the number of packets that have been received by the application. ++ ++ Packets dropped by the kernel buffer are not counted in this variable. The variable is always ++ equal to (TotAccepted - TotDrops), exept for the case of remote capture, in which we have also ++ packets in fligh, i.e. that have been transmitted by the remote host, but that have not been ++ received (yet) from the client. In this case, (TotAccepted - TotDrops - TotNetDrops) gives a ++ wrong result, since this number does not corresponds always to the number of packet received by ++ the application. For this reason, in the remote capture we need another variable that takes ++ into account of the number of packets actually received by the application. ++*/ ++ unsigned int TotCapt; ++#endif /* HAVE_REMOTE */ + }; + + /* +@@ -186,6 +217,22 @@ + u_int *dlt_list; + + struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */ ++ ++#ifdef HAVE_REMOTE ++#ifndef WIN32 // Win32 already defines 'timeout' ++ int timeout; //!< timeout to be used in the pcap_open() ++#endif ++ /*! \brief '1' if we're the network client; needed by several functions (like pcap_setfilter() ) to know if ++ they have to use the socket or they have to open the local adapter. */ ++ int rmt_clientside; ++ ++ SOCKET rmt_sockctrl; //!< socket ID of the socket used for the control connection ++ SOCKET rmt_sockdata; //!< socket ID of the socket used for the data connection ++ int rmt_flags; //!< we have to save flags, since they are passed by the pcap_open_live(), but they are used by the pcap_startcapture() ++ int rmt_capstarted; //!< 'true' if the capture is already started (needed to knoe if we have to call the pcap_startcapture() ++ struct pcap_samp rmt_samp; //!< Keeps the parameters related to the sampling process. ++ char *currentfilter; //!< Pointer to a buffer (allocated at run-time) that stores the current filter. Needed when flag PCAP_OPENFLAG_NOCAPTURE_RPCAP is turned on. ++#endif /* HAVE_REMOTE */ + }; + + /* +diff -urb libpcap-2006.04.17/pcap-linux.c libpcap/pcap-linux.c +--- libpcap-2006.04.17/pcap-linux.c 2006-04-07 01:02:28.000000000 -0700 ++++ libpcap/pcap-linux.c 2006-04-20 20:35:58.406250000 -0700 +@@ -101,6 +101,10 @@ + #include + #include + ++#ifdef HAVE_REMOTE ++#include ++#endif ++ + /* + * If PF_PACKET is defined, we can use {SOCK_RAW,SOCK_DGRAM}/PF_PACKET + * sockets rather than SOCK_PACKET sockets. +@@ -243,6 +247,37 @@ + int live_open_ok = 0; + struct utsname utsname; + ++#ifdef HAVE_REMOTE ++ /* ++ Retrofit; we have to make older applications compatible with the remote capture ++ So, we're calling the pcap_open_remote() from here, that is a very dirty thing. ++ Obviously, we cannot exploit all the new features; for instance, we cannot ++ send authentication, we cannot use a UDP data connection, and so on. ++ */ ++ ++ char host[PCAP_BUF_SIZE + 1]; ++ char port[PCAP_BUF_SIZE + 1]; ++ char name[PCAP_BUF_SIZE + 1]; ++ int srctype; ++ ++ if (pcap_parsesrcstr(device, &srctype, host, port, name, ebuf) ) ++ return NULL; ++ ++ if (srctype == PCAP_SRC_IFREMOTE) ++ { ++ handle= pcap_opensource_remote(device, NULL, ebuf); ++ ++ if (handle == NULL) ++ return NULL; ++ ++ handle->snapshot= snaplen; ++ handle->md.timeout= to_ms; ++ handle->rmt_flags= (promisc) ? PCAP_OPENFLAG_PROMISCUOUS : 0; ++ ++ return handle; ++ } ++#endif /* HAVE_REMOTE */ ++ + #ifdef HAVE_DAG_API + if (strstr(device, "dag")) { + return dag_open_live(device, snaplen, promisc, to_ms, ebuf); +diff -urb libpcap-2006.04.17/pcap-win32.c libpcap/pcap-win32.c +--- libpcap-2006.04.17/pcap-win32.c 2006-02-22 09:08:31.000000000 -0800 ++++ libpcap/pcap-win32.c 2006-04-20 20:35:58.421875000 -0700 +@@ -48,6 +48,10 @@ + #define errno (*_errno()) + #endif /* __MINGW32__ */ + ++#ifdef HAVE_REMOTE ++#include ++#endif /* HAVE_REMOTE */ ++ + static int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *); + static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *); + static int pcap_getnonblock_win32(pcap_t *, char *); +@@ -107,6 +111,11 @@ + int n = 0; + register u_char *bp, *ep; + ++#ifdef HAVE_REMOTE ++ static int samp_npkt; // parameter needed for sampling, with '1 out of N' method has been requested ++ static struct timeval samp_time; // parameter needed for sampling, with '1 every N ms' method has been requested ++#endif /* HAVE_REMOTE */ ++ + cc = p->cc; + if (p->cc == 0) { + /* +@@ -168,6 +177,42 @@ + caplen = bhp->bh_caplen; + hdrlen = bhp->bh_hdrlen; + ++#ifdef HAVE_REMOTE ++ if (p->rmt_samp.method == PCAP_SAMP_1_EVERY_N) ++ { ++ samp_npkt= (samp_npkt + 1) % p->rmt_samp.value; ++ ++ // Discard all packets that are not '1 out of N' ++ if (samp_npkt != 0) ++ { ++ bp += BPF_WORDALIGN(caplen + hdrlen); ++ continue; ++ } ++ } ++ ++ if (p->rmt_samp.method == PCAP_SAMP_FIRST_AFTER_N_MS) ++ { ++ struct pcap_pkthdr *pkt_header= (struct pcap_pkthdr*) bp; ++ ++ // Check if the timestamp of the arrived packet is smaller than our target time ++ if ( (pkt_header->ts.tv_sec < samp_time.tv_sec) || ++ ( (pkt_header->ts.tv_sec == samp_time.tv_sec) && (pkt_header->ts.tv_usec < samp_time.tv_usec) ) ) ++ { ++ bp += BPF_WORDALIGN(caplen + hdrlen); ++ continue; ++ } ++ ++ // The arrived packet is suitable for being sent to the remote host ++ // So, let's update the target time ++ samp_time.tv_usec= pkt_header->ts.tv_usec + p->rmt_samp.value * 1000; ++ if (samp_time.tv_usec > 1000000) ++ { ++ samp_time.tv_sec= pkt_header->ts.tv_sec + samp_time.tv_usec / 1000000; ++ samp_time.tv_usec= samp_time.tv_usec % 1000000; ++ } ++ } ++#endif /* HAVE_REMOTE */ ++ + /* + * XXX A bpf_hdr matches a pcap_pkthdr. + */ +@@ -396,6 +441,36 @@ + register pcap_t *p; + NetType type; + ++#ifdef HAVE_REMOTE ++ char host[PCAP_BUF_SIZE + 1]; ++ char port[PCAP_BUF_SIZE + 1]; ++ char name[PCAP_BUF_SIZE + 1]; ++ int srctype; ++ ++ /* ++ Retrofit; we have to make older applications compatible with the remote capture ++ So, we're calling the pcap_open_remote() from here, that is a very dirty thing. ++ Obviously, we cannot exploit all the new features; for instance, we cannot ++ send authentication, we cannot use a UDP data connection, and so on. ++ */ ++ if (pcap_parsesrcstr(device, &srctype, host, port, name, ebuf) ) ++ return NULL; ++ ++ if (srctype == PCAP_SRC_IFREMOTE) ++ { ++ p= pcap_opensource_remote(device, NULL, ebuf); ++ ++ if (p == NULL) ++ return NULL; ++ ++ p->snapshot= snaplen; ++ p->timeout= to_ms; ++ p->rmt_flags= (promisc) ? PCAP_OPENFLAG_PROMISCUOUS : 0; ++ ++ return p; ++ } ++#endif /* HAVE_REMOTE */ ++ + /* Init WinSock */ + wsockinit(); + +@@ -743,6 +818,14 @@ + int + pcap_setbuff(pcap_t *p, int dim) + { ++#ifdef HAVE_REMOTE ++ if (p->rmt_clientside) ++ { ++ /* Currently, this is a bug: the capture buffer cannot be set with remote capture */ ++ return 0; ++ } ++#endif /* HAVE_REMOTE */ ++ + if (p->adapter==NULL) + { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "The kernel buffer size cannot be set while reading from a file"); +diff -urb libpcap-2006.04.17/pcap.c libpcap/pcap.c +--- libpcap-2006.04.17/pcap.c 2006-01-22 12:11:26.000000000 -0800 ++++ libpcap/pcap.c 2006-04-20 20:37:59.187500000 -0700 +@@ -70,10 +70,28 @@ + #include + #endif + ++#ifdef HAVE_REMOTE ++#include ++#endif ++ + int + pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) + { + ++#ifdef HAVE_REMOTE ++ /* Checks the capture type */ ++ if (p->rmt_clientside) ++ { ++ /* We are on an remote capture */ ++ if (!p->rmt_capstarted) ++ { ++ // if the capture has not started yet, please start it ++ if (pcap_startcapture_remote(p) ) ++ return -1; ++ } ++ } ++#endif /* HAVE_REMOTE */ ++ + return p->read_op(p, cnt, callback, user); + } + +@@ -92,6 +110,20 @@ + { + register int n; + ++#ifdef HAVE_REMOTE ++ /* Checks the capture type */ ++ if (p->rmt_clientside) ++ { ++ /* We are on an remote capture */ ++ if (!p->rmt_capstarted) ++ { ++ // if the capture has not started yet, please start it ++ if (pcap_startcapture_remote(p) ) ++ return -1; ++ } ++ } ++#endif /* HAVE_REMOTE */ ++ + for (;;) { + if (p->sf.rfile != NULL) { + /* +@@ -169,6 +201,22 @@ + /* Saves a pointer to the packet headers */ + *pkt_header= &p->pcap_header; + ++#ifdef HAVE_REMOTE ++ /* Checks the capture type */ ++ if (p->rmt_clientside) ++ { ++ /* We are on an remote capture */ ++ if (!p->rmt_capstarted) ++ { ++ // if the capture has not started yet, please start it ++ if (pcap_startcapture_remote(p) ) ++ return -1; ++ } ++ ++ return pcap_read_nocb_remote(p, pkt_header, (u_char **) pkt_data); ++ } ++#endif /* HAVE_REMOTE */ ++ + if (p->sf.rfile != NULL) { + int status; + +@@ -538,6 +586,11 @@ + int + pcap_fileno(pcap_t *p) + { ++#ifdef HAVE_REMOTE ++ if (p->rmt_clientside) ++ return(p->rmt_sockdata); ++#endif /* HAVE_REMOTE */ ++ + #ifndef WIN32 + return (p->fd); + #else +diff -urb libpcap-2006.04.17/pcap.h libpcap/pcap.h +--- libpcap-2006.04.17/pcap.h 2006-02-09 14:26:12.000000000 -0800 ++++ libpcap/pcap.h 2006-04-20 20:35:58.453125000 -0700 +@@ -53,6 +53,19 @@ + + #include + ++#ifdef HAVE_REMOTE ++ // We have to define the SOCKET here, although it has been defined in sockutils.h ++ // This is to avoid the distribution of the 'sockutils.h' file around ++ // (for example in the WinPcap developer's pack) ++ #ifndef SOCKET ++ #ifdef WIN32 ++ #define SOCKET unsigned int ++ #else ++ #define SOCKET int ++ #endif ++ #endif ++#endif ++ + #ifdef __cplusplus + extern "C" { + #endif +@@ -151,9 +164,11 @@ + u_int ps_recv; /* number of packets received */ + u_int ps_drop; /* number of packets dropped */ + u_int ps_ifdrop; /* drops by interface XXX not yet supported */ +-#ifdef WIN32 +- u_int bs_capt; /* number of packets that reach the application */ +-#endif /* WIN32 */ ++#ifdef HAVE_REMOTE ++ u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ ++ u_int ps_sent; /* number of packets sent by the server on the network */ ++ u_int ps_netdrop; /* number of packets lost on the network */ ++#endif /* HAVE_REMOTE */ + }; + + #ifdef MSDOS +@@ -317,6 +332,11 @@ + + #endif /* WIN32/MSDOS/UN*X */ + ++#ifdef HAVE_REMOTE ++/* Includes most of the public stuff that is needed for the remote capture */ ++#include "remote-ext.h" ++#endif /* HAVE_REMOTE */ ++ + #ifdef __cplusplus + } + #endif +diff -urb libpcap-2006.04.17/savefile.c libpcap/savefile.c +--- libpcap-2006.04.17/savefile.c 2005-12-13 05:41:39.000000000 -0800 ++++ libpcap/savefile.c 2006-04-20 20:35:58.468750000 -0700 +@@ -1130,6 +1130,11 @@ + int status = 0; + int n = 0; + ++#ifdef HAVE_REMOTE ++ static int samp_npkt; // parameter needed for sampling, whtn '1 out of N' method has been requested ++ static struct timeval samp_time; // parameter needed for sampling, whtn '1 every N ms' method has been requested ++#endif /* HAVE_REMOTE */ ++ + while (status == 0) { + struct pcap_pkthdr h; + +@@ -1159,6 +1164,36 @@ + + if ((fcode = p->fcode.bf_insns) == NULL || + bpf_filter(fcode, p->buffer, h.len, h.caplen)) { ++ ++#ifdef HAVE_REMOTE ++ if (p->rmt_samp.method == PCAP_SAMP_1_EVERY_N) ++ { ++ samp_npkt= (samp_npkt + 1) % p->rmt_samp.value; ++ ++ // Discard all packets that are not '1 out of N' ++ if (samp_npkt != 0) ++ continue; ++ } ++ ++ if (p->rmt_samp.method == PCAP_SAMP_FIRST_AFTER_N_MS) ++ { ++ // Check if the timestamp of the arrived packet is smaller than our target time ++ if ( (h.ts.tv_sec < samp_time.tv_sec) || ++ ( (h.ts.tv_sec == samp_time.tv_sec) && (h.ts.tv_usec < samp_time.tv_usec) ) ) ++ continue; ++ ++ // The arrived packet is suitable for being sent to the remote host ++ // So, let's update the target time ++ samp_time.tv_usec= h.ts.tv_usec + p->rmt_samp.value * 1000; ++ if (samp_time.tv_usec > 1000000) ++ { ++ samp_time.tv_sec= h.ts.tv_sec + samp_time.tv_usec / 1000000; ++ samp_time.tv_usec= samp_time.tv_usec % 1000000; ++ } ++ ++ } ++#endif /* HAVE_REMOTE */ ++ + (*callback)(user, &h, p->buffer); + if (++n >= cnt && cnt > 0) + break; diff --git a/winpcap/wpcap/libpcap/rpcapd/Makefile b/winpcap/wpcap/libpcap/rpcapd/Makefile new file mode 100644 index 0000000..cb97426 --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/Makefile @@ -0,0 +1,50 @@ +################################ +# Makefile for the remote daemon +################################ + +CC = gcc +CFLAGS = -pthread -DHAVE_REMOTE -DHAVE_SNPRINTF +#flags for debugging: -D_DEBUG -g -Wall + +INCLUDE = -I../ + +LIB = -lpcap -lcrypt +#Solaris: add '-lsocket' + +LIBPATH = -L../ + +# Files that are needed to compile this project +FILES = rpcapd.o daemon.o utils.o fileconf.o pcap-remote.o sockutils.o pcap-new.o + +# Makefile syntax: +# Project name : dependencies +# command line + +rpcapd: $(FILES) + $(CC) $(CFLAGS) $(INCLUDE) -o rpcapd $(FILES) $(LIBPATH) $(LIB) + +rpcapd.o: rpcapd.c + $(CC) $(CFLAGS) $(INCLUDE) -c rpcapd.c + +daemon.o: daemon.c + $(CC) $(CFLAGS) $(INCLUDE) -c daemon.c + +utils.o: utils.c + $(CC) $(CFLAGS) $(INCLUDE) -c utils.c + +fileconf.o: fileconf.c + $(CC) $(CFLAGS) $(INCLUDE) -c fileconf.c + +sockutils.o: ../sockutils.c + $(CC) $(CFLAGS) $(INCLUDE) -c ../sockutils.c + +pcap-remote.o: ../pcap-remote.c + $(CC) $(CFLAGS) $(INCLUDE) -c ../pcap-remote.c + +pcap-new.o: ../pcap-new.c + $(CC) $(CFLAGS) $(INCLUDE) -c ../pcap-new.c + +clean: + rm -f *.o + rm rpcapd + diff --git a/winpcap/wpcap/libpcap/rpcapd/daemon.c b/winpcap/wpcap/libpcap/rpcapd/daemon.c new file mode 100644 index 0000000..6d31b7d --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/daemon.c @@ -0,0 +1,1604 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include // for libpcap/WinPcap calls +#include // for the pcap_t definition +#include // for the errno variable +#include // for malloc(), free(), ... +#include // for strlen(), ... +#include +#include "pcap-remote.h" +#include "daemon.h" +#include "sockutils.h" // for socket calls + +#ifndef WIN32 // for select() and such +#include +#include +#include +#include // for password management +#endif + +#ifdef linux +#include // for password management +#endif + + + +// Locally defined functions +int daemon_checkauth(SOCKET sockctrl, int nullAuthAllowed, char *errbuf); +int daemon_AuthUserPwd(char *username, char *password, char *errbuf); + +int daemon_findalldevs(SOCKET sockctrl, char *errbuf); + +int daemon_opensource(SOCKET sockctrl, char *source, int srclen, uint32 plen, char *errbuf); +pcap_t *daemon_startcapture(SOCKET sockctrl, pthread_t *threaddata, char *source, int active, + struct rpcap_sampling *samp_param, uint32 plen, char *errbuf); +int daemon_endcapture(pcap_t *fp, pthread_t *threaddata, char *errbuf); + +int daemon_updatefilter(pcap_t *fp, uint32 plen); +int daemon_unpackapplyfilter(pcap_t *fp, unsigned int *nread, int *plen, char *errbuf); + +int daemon_getstats(pcap_t *fp); +int daemon_getstatsnopcap(SOCKET sockctrl, unsigned int ifdrops, unsigned int ifrecv, + unsigned int krnldrop, unsigned int svrcapt, char *errbuf); + +int daemon_setsampling(SOCKET sockctrl, struct rpcap_sampling *samp_param, int plen, char *errbuf); + +void daemon_seraddr(struct sockaddr_storage *sockaddrin, struct sockaddr_storage *sockaddrout); +void *daemon_thrdatamain(void *ptr); + + + + + + + +/*! + \brief Main serving funtion + This function is the one which does the job. It is the main() of the child + thread, which is created as soon as a new connection is accepted. + + \param ptr: a void pointer that keeps the reference of the 'pthread_chain' + value corrisponding to this thread. This variable is casted into a 'pthread_chain' + value in order to retrieve the socket we're currently using, the therad ID, and + some pointers to the previous and next elements into this struct. + + \return None. +*/ +void daemon_serviceloop( void *ptr ) +{ +char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed +char source[PCAP_BUF_SIZE]; // keeps the string that contains the interface to open +struct rpcap_header header; // RPCAP message general header +pcap_t *fp= NULL; // pcap_t main variable +struct daemon_slpars *pars; // parameters related to the present daemon loop + +pthread_t threaddata= 0; // handle to the 'read from daemon and send to client' thread + +unsigned int ifdrops, ifrecv, krnldrop, svrcapt; // needed to save the values of the statistics + +struct rpcap_sampling samp_param; // in case sampling has been requested + +// Structures needed for the select() call +fd_set rfds; // set of socket descriptors we have to check +struct timeval tv; // maximum time the select() can block waiting for data +int retval; // select() return value + + + pars= (struct daemon_slpars *) ptr; + + *errbuf= 0; // Initialize errbuf + + // If we're in active mode, this is not a separate thread + if (! pars->isactive) + { + // Modify thread params so that it can be killed at any time + if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) ) + goto end; + if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) ) + goto end; + } + +auth_again: + // If we're in active mode, we have to check for the initial timeout + if (!pars->isactive) + { + FD_ZERO(&rfds); + // We do not have to block here + tv.tv_sec = RPCAP_TIMEOUT_INIT; + tv.tv_usec = 0; + + FD_SET(pars->sockctrl, &rfds); + + retval = select(pars->sockctrl + 1, &rfds, NULL, NULL, &tv); + if (retval == -1) + { + sock_geterror("select(): ", errbuf, PCAP_ERRBUF_SIZE); + rpcap_senderror(pars->sockctrl, errbuf, PCAP_ERR_NETW, NULL); + goto end; + } + + // The timeout has expired + // So, this was a fake connection. Drop it down + if (retval == 0) + { + rpcap_senderror(pars->sockctrl, "The RPCAP initial timeout has expired", PCAP_ERR_INITTIMEOUT, NULL); + goto end; + } + } + + + retval= daemon_checkauth(pars->sockctrl, pars->nullAuthAllowed, errbuf); + + if (retval) + { + // the other user requested to close the connection + // It can be also the case of 'active mode', in which this host is not + // allowed to connect to the other peer; in that case, it drops down the connection + if (retval == -3) + goto end; + + // It can be an authentication failure or an unrecoverable error + rpcap_senderror(pars->sockctrl, errbuf, PCAP_ERR_AUTH, NULL); + + // authentication error + if (retval == -2) + { + // suspend for 1 sec + // WARNING: this day is inserted only in this point; if the user drops down the connection + // and it connects again, this suspension time does not have any effects. + pthread_suspend(RPCAP_SUSPEND_WRONGAUTH*1000); + goto auth_again; + } + + // Unrecoverable error + if (retval == -1) + goto end; + } + + while (1) + { + int retval; + + errbuf[0]= 0; // clear errbuf + + // Avoid zombies connections; check if the connection is opens but no commands are performed + // from more than RPCAP_TIMEOUT_RUNTIME + // Conditions: + // - I have to be in normal mode (no active mode) + // - if the device is open, I don't have to be in the middle of a capture (fp->rmt_sockdata) + // - if the device is closed, I have always to check if a new command arrives + // + // Be carefully: the capture can have been started, but an error occurred (so fp != NULL, but + // rmt_sockdata is 0 + if ( (!pars->isactive) && ( (fp == NULL) || ( (fp != NULL) && (fp->rmt_sockdata == 0) ) )) + { + // Check for the initial timeout + FD_ZERO(&rfds); + // We do not have to block here + tv.tv_sec = RPCAP_TIMEOUT_RUNTIME; + tv.tv_usec = 0; + + FD_SET(pars->sockctrl, &rfds); + + retval = select(pars->sockctrl + 1, &rfds, NULL, NULL, &tv); + if (retval == -1) + { + sock_geterror("select(): ", errbuf, PCAP_ERRBUF_SIZE); + rpcap_senderror(pars->sockctrl, errbuf, PCAP_ERR_NETW, NULL); + goto end; + } + + // The timeout has expired + // So, this was a fake connection. Drop it down + if (retval == 0) + { + SOCK_ASSERT("The RPCAP runtime timeout has expired", 1); + rpcap_senderror(pars->sockctrl, "The RPCAP runtime timeout has expired", PCAP_ERR_RUNTIMETIMEOUT, NULL); + goto end; + } + } + + if (sock_recv(pars->sockctrl, (char *) &header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto end; + + // Checks if the message is correct + // In case it is wrong, it discard the data + retval= rpcap_checkmsg(errbuf, pars->sockctrl, &header, + RPCAP_MSG_FINDALLIF_REQ, + RPCAP_MSG_OPEN_REQ, + RPCAP_MSG_STARTCAP_REQ, + RPCAP_MSG_UPDATEFILTER_REQ, + RPCAP_MSG_STATS_REQ, + RPCAP_MSG_ENDCAP_REQ, + RPCAP_MSG_SETSAMPLING_REQ, + RPCAP_MSG_CLOSE, + RPCAP_MSG_ERROR, + 0); + + switch (retval) + { + case -3: // Unrecoverable network error + goto end; // Do nothing; just exit from findalldevs; the error code is already into the errbuf + + case -2: // The other endpoint send a message that is not allowed here + { + rpcap_senderror(pars->sockctrl, "The RPCAP daemon received a message that is not valid", PCAP_ERR_WRONGMSG, errbuf); + } + case -1: // The other endpoint has a version number that is not compatible with our + { + rpcap_senderror(pars->sockctrl, "RPCAP version number mismatch", PCAP_ERR_WRONGVER, errbuf); + } + break; + + case RPCAP_MSG_FINDALLIF_REQ: + { + // Checks that the header does not contain other data; if so, discard it + if (ntohl(header.plen)) + sock_discard(pars->sockctrl, ntohl(header.plen), errbuf, PCAP_ERRBUF_SIZE); + + if (daemon_findalldevs(pars->sockctrl, errbuf) ) + SOCK_ASSERT(errbuf, 1); + + break; + }; + + case RPCAP_MSG_OPEN_REQ: + { + retval= daemon_opensource(pars->sockctrl, source, sizeof(source), ntohl(header.plen), errbuf); + + if (retval == -1) + SOCK_ASSERT(errbuf, 1); + + break; + }; + + case RPCAP_MSG_SETSAMPLING_REQ: + { + retval= daemon_setsampling(pars->sockctrl, &samp_param, ntohl(header.plen), errbuf); + + if (retval == -1) + SOCK_ASSERT(errbuf, 1); + + break; + }; + + case RPCAP_MSG_STARTCAP_REQ: + { + fp= daemon_startcapture(pars->sockctrl, &threaddata, source, pars->isactive, &samp_param, ntohl(header.plen), errbuf); + + if (fp == NULL) + SOCK_ASSERT(errbuf, 1); + + break; + }; + + case RPCAP_MSG_UPDATEFILTER_REQ: + { + if (fp) + { + if (daemon_updatefilter(fp, ntohl(header.plen)) ) + SOCK_ASSERT(fp->errbuf, 1); + } + else + { + rpcap_senderror(pars->sockctrl, "Device not opened. Cannot update filter", PCAP_ERR_UPDATEFILTER, errbuf); + } + + break; + }; + + case RPCAP_MSG_STATS_REQ: + { + // Checks that the header does not contain other data; if so, discard it + if (ntohl(header.plen)) + sock_discard(pars->sockctrl, ntohl(header.plen), errbuf, PCAP_ERRBUF_SIZE); + + if (fp) + { + if (daemon_getstats(fp) ) + SOCK_ASSERT(fp->errbuf, 1); + } + else + { + SOCK_ASSERT("GetStats: this call should't be allowed here", 1); + + if (daemon_getstatsnopcap(pars->sockctrl, ifdrops, ifrecv, krnldrop, svrcapt, errbuf) ) + SOCK_ASSERT(errbuf, 1); + // we have to keep compatibility with old applications, which ask for statistics + // also when the capture has already stopped + +// rpcap_senderror(pars->sockctrl, "Device not opened. Cannot get statistics", PCAP_ERR_GETSTATS, errbuf); + } + + break; + }; + + case RPCAP_MSG_ENDCAP_REQ: // The other endpoint close the current capture session + { + if (fp) + { + struct pcap_stat stats; + + // Save statistics (we can need them in the future) + if (pcap_stats(fp, &stats) ) + { + ifdrops= stats.ps_ifdrop; + ifrecv= stats.ps_recv; + krnldrop= stats.ps_drop; + svrcapt= fp->md.TotCapt; + } + else + ifdrops= ifrecv= krnldrop= svrcapt= 0; + + if ( daemon_endcapture(fp, &threaddata, errbuf) ) + SOCK_ASSERT(errbuf, 1); + fp= NULL; + } + else + { + rpcap_senderror(pars->sockctrl, "Device not opened. Cannot close the capture", PCAP_ERR_ENDCAPTURE, errbuf); + } + break; + }; + + case RPCAP_MSG_CLOSE: // The other endpoint close the pcap session + { + // signal to the main that the user closed the control connection + // This is used only in case of active mode + pars->activeclose= 1; + SOCK_ASSERT("The other end system asked to close the connection.", 1); + goto end; + break; + }; + + case RPCAP_MSG_ERROR: // The other endpoint reported an error + { + // Do nothing; just exit; the error code is already into the errbuf + SOCK_ASSERT(errbuf, 1); + break; + }; + + default: + { + SOCK_ASSERT("Internal error.", 1); + break; + }; + } + } + +end: + // The child thread is about to end + + // perform pcap_t cleanup, in case it has not been done + if (fp) + { + if (threaddata) + { + pthread_cancel(threaddata); + threaddata= 0; + } + if (fp->rmt_sockdata) + { + sock_close(fp->rmt_sockdata, NULL, 0); + fp->rmt_sockdata= 0; + } + pcap_close(fp); + fp= NULL; + } + + // Print message and exit + SOCK_ASSERT("I'm exiting from the child loop", 1); + SOCK_ASSERT(errbuf, 1); + + if (!pars->isactive) + { + if (pars->sockctrl) + sock_close(pars->sockctrl, NULL, 0); + + free(pars); +#ifdef WIN32 + pthread_exit(0); +#endif + } +} + + +/*! + \brief It checks if the authentication credentials supplied by the user are valid. + + This function is called each time the rpcap daemon starts a new serving thread. + It reads the authentication message from the network and it checks that the + user information are valid. + + \param sockctrl: the socket if of the control connection. + + \param nullAuthAllowed: '1' if the NULL authentication is allowed. + + \param errbuf: a user-allocated buffer in which the error message (if one) has to be written. + + \return '0' if everything is fine, '-1' if an unrecoverable error occurred. + The error message is returned in the 'errbuf' variable. + '-2' is returned in case the authentication failed or in case of a recoverable error (like + wrong version). In that case, 'errbuf' keeps the reason of the failure. This provides + a way to know that the connection does not have to be closed. + + In case the message is a 'CLOSE' or an 'ERROR', it returns -3. The error can be due to a + connection refusal in active mode, since this host cannot be allowed to connect to the remote + peer. +*/ +int daemon_checkauth(SOCKET sockctrl, int nullAuthAllowed, char *errbuf) +{ +struct rpcap_header header; // RPCAP message general header +int retval; // generic return value +unsigned int nread; // number of bytes of the payload read from the socket +struct rpcap_auth auth; // RPCAP authentication header +char *string1, *string2; // two strings exchanged by the authentication message +unsigned int plen; // length of the payload +int retcode; // the value we have to return to the caller + + if (sock_recv(sockctrl, (char *) &header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + + plen= ntohl(header.plen); + + retval= rpcap_checkmsg(errbuf, sockctrl, &header, + RPCAP_MSG_AUTH_REQ, + RPCAP_MSG_CLOSE, + 0); + + if (retval != RPCAP_MSG_AUTH_REQ) + { + switch (retval) + { + case -3: // Unrecoverable network error + return -1; // Do nothing; just exit; the error code is already into the errbuf + + case -2: // The other endpoint send a message that is not allowed here + case -1: // The other endpoint has a version number that is not compatible with our + return -2; + + case RPCAP_MSG_CLOSE: + { + // Check if all the data has been read; if not, discard the data in excess + if (ntohl(header.plen) ) + { + if (sock_discard(sockctrl, ntohl(header.plen), NULL, 0) ) + { + retcode= -1; + goto error; + } + } + return -3; + }; + + case RPCAP_MSG_ERROR: + return -3; + + default: + { + SOCK_ASSERT("Internal error.", 1); + retcode= -2; + goto error; + }; + } + } + + // If it comes here, it means that we have an authentication request message + if ( (nread= sock_recv(sockctrl, (char *) &auth, sizeof(struct rpcap_auth), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE)) == -1) + { + retcode= -1; + goto error; + } + + switch (ntohs(auth.type) ) + { + case RPCAP_RMTAUTH_NULL: + { + if (!nullAuthAllowed) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed; NULL autentication not permitted."); + retcode= -2; + goto error; + } + break; + } + + case RPCAP_RMTAUTH_PWD: + { + int len1, len2; + + len1= ntohs(auth.slen1); + len2= ntohs(auth.slen2); + + string1= (char *) malloc (len1 + 1); + string2= (char *) malloc (len2 + 1); + + if ( (string1 == NULL) || (string2 == NULL) ) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + retcode= -1; + goto error; + } + + if ( (nread+= sock_recv(sockctrl, string1, len1, SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE)) == -1) + { + retcode= -1; + goto error; + } + if ( (nread+= sock_recv(sockctrl, string2, len2, SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE)) == -1) + { + retcode= -1; + goto error; + } + + string1[len1]= 0; + string2[len2]= 0; + + if (daemon_AuthUserPwd(string1, string2, errbuf) ) + { + retcode= -2; + goto error; + } + + break; + } + + default: + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication type not recognized."); + retcode= -2; + goto error; + } + + + // Check if all the data has been read; if not, discard the data in excess + if (nread != plen) + { + if (sock_discard(sockctrl, plen - nread, NULL, 0) ) + { + retcode= -1; + goto error; + } + } + + rpcap_createhdr(&header, RPCAP_MSG_AUTH_REPLY, 0, 0); + + // Send the ok message back + if ( sock_send(sockctrl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1) + { + retcode= -1; + goto error; + } + + return 0; + +error: + // Check if all the data has been read; if not, discard the data in excess + if (nread != plen) + sock_discard(sockctrl, plen - nread, NULL, 0); + + return retcode; +} + + + +int daemon_AuthUserPwd(char *username, char *password, char *errbuf) +{ +#ifdef WIN32 + /* + Warning: the user which launches the process must have the SE_TCB_NAME right. + This corresponds to have the "Act as part of the Operating System" turined on + (administrative tools, local security settings, local policies, user right assignment) + However, it seems to me that if you run it as a service, this right should be + provided by default. + */ + HANDLE Token; + if (LogonUser(username, ".", password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &Token) == 0) + { + int error; + + error = GetLastError(); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, + PCAP_ERRBUF_SIZE, NULL); + + return -1; + } + + // This call should change the current thread to the selected user. + // I didn't test it. + if (ImpersonateLoggedOnUser(Token) == 0) + { + int error; + + error = GetLastError(); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, + PCAP_ERRBUF_SIZE, NULL); + + CloseHandle(Token); + return -1; + } + + CloseHandle(Token); + return 0; + +#else +/* Standard user authentication: + http://www.unixpapa.com/incnote/passwd.html + Problem: it is not able to merge the standard pwd file with the shadow one + + Shadow user authentication: + http://www.tldp.org/HOWTO/Shadow-Password-HOWTO-8.html + Problem: the program must either (1) run as root, or (2) run as user, but it + must be owned by root and must be SUID root (chmod u+s rpcapd) +*/ + + struct passwd *user; +#ifdef linux + struct spwd *usersp; +#endif + + // This call is needed to get the uid + if ((user= getpwnam(username)) == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: no such user"); + return -1; + } + +#ifdef linux + // This call is needed to get the password; otherwise 'x' is returned + if ((usersp= getspnam(username)) == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: no such user"); + return -1; + } + + if (strcmp(usersp->sp_pwdp, (char *) crypt(password, usersp->sp_pwdp) ) != 0) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: password incorrect"); + return -1; + } +#endif + +#ifdef bsd + if (strcmp(user->pw_passwd, (char *) crypt(password, user->pw_passwd) ) != 0) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: password incorrect"); + return -1; + } +#endif + + if (setuid(user->pw_uid) ) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s", pcap_strerror(errno) ); + return -1; + } + +/* if (setgid(user->pw_gid) ) + { + SOCK_ASSERT("setgid failed", 1); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s", pcap_strerror(errno) ); + return -1; + } +*/ + return 0; + +#endif + +} + + + +// PORTING WARNING We assume u_int is a 32bit value +int daemon_findalldevs(SOCKET sockctrl, char *errbuf) +{ +char sendbuf[RPCAP_NETBUF_SIZE]; // temporary buffer in which data to be sent is buffered +int sendbufidx= 0; // index which keeps the number of bytes currently buffered +pcap_if_t *alldevs; // pointer to the heade of the interface chain +pcap_if_t *d; // temp pointer neede to scan the interface chain +uint16 plen= 0; // length of the payload of this message +struct pcap_addr *address; // pcap structure that keeps a network address of an interface +struct rpcap_findalldevs_if *findalldevs_if;// rpcap structure that packet all the data of an interface together +uint16 nif= 0; // counts the number of interface listed + + // Retrieve the device list + if (pcap_findalldevs(&alldevs, errbuf) == -1) + { + rpcap_senderror(sockctrl, errbuf, PCAP_ERR_FINDALLIF, NULL); + return -1; + } + + if (alldevs == NULL) + { + rpcap_senderror(sockctrl, + "No interfaces found! Make sure libpcap/WinPcap is properly installed" + " and you have the right to access to the remote device.", + PCAP_ERR_NOREMOTEIF, + errbuf); + return -1; + } + + // checks the number of interfaces and it computes the total length of the payload + for (d= alldevs; d != NULL; d= d->next) + { + nif++; + + if (d->description) + plen+= strlen(d->description); + if (d->name) + plen+= strlen(d->name); + + plen+= sizeof(struct rpcap_findalldevs_if); + + for (address= d->addresses; address != NULL; address= address->next) + plen+= ( sizeof(struct sockaddr_storage) * 4); + } + + // RPCAP findalldevs command + if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + + rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_FINDALLIF_REPLY, nif, plen); + + // send the interface list + for (d= alldevs; d != NULL; d= d->next) + { + uint16 lname, ldescr; + + findalldevs_if= (struct rpcap_findalldevs_if *) &sendbuf[sendbufidx]; + + if ( sock_bufferize(NULL, sizeof(struct rpcap_findalldevs_if), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + + memset(findalldevs_if, 0, sizeof(struct rpcap_findalldevs_if) ); + + if (d->description) ldescr= (short) strlen(d->description); + else ldescr= 0; + if (d->name) lname= (short) strlen(d->name); + else lname= 0; + + findalldevs_if->desclen= htons(ldescr); + findalldevs_if->namelen= htons(lname); + findalldevs_if->flags= htonl(d->flags); + + for (address= d->addresses; address != NULL; address= address->next) + findalldevs_if->naddr++; + + findalldevs_if->naddr= htons(findalldevs_if->naddr); + + if (sock_bufferize(d->name, lname, sendbuf, &sendbufidx, + RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + + if (sock_bufferize(d->description, ldescr, sendbuf, &sendbufidx, + RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + + // send all addresses + for (address= d->addresses; address != NULL; address= address->next) + { + struct sockaddr_storage *sockaddr; + + sockaddr= (struct sockaddr_storage *) &sendbuf[sendbufidx]; + if (sock_bufferize(NULL, sizeof(struct sockaddr_storage), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + daemon_seraddr( (struct sockaddr_storage *) address->addr, sockaddr); + + sockaddr= (struct sockaddr_storage *) &sendbuf[sendbufidx]; + if (sock_bufferize(NULL, sizeof(struct sockaddr_storage), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + daemon_seraddr( (struct sockaddr_storage *) address->netmask, sockaddr); + + sockaddr= (struct sockaddr_storage *) &sendbuf[sendbufidx]; + if (sock_bufferize(NULL, sizeof(struct sockaddr_storage), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + daemon_seraddr( (struct sockaddr_storage *) address->broadaddr, sockaddr); + + sockaddr= (struct sockaddr_storage *) &sendbuf[sendbufidx]; + if (sock_bufferize(NULL, sizeof(struct sockaddr_storage), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + daemon_seraddr( (struct sockaddr_storage *) address->dstaddr, sockaddr); + } + } + + // Send a final command that says "now send it!" + if (sock_send(sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + + // We do no longer need the device list. Free it + pcap_freealldevs(alldevs); + + // everything is fine + return 0; +} + + + + + +/* + \param plen: the length of the current message (needed in order to be able + to discard excess data in the message, if present) +*/ +int daemon_opensource(SOCKET sockctrl, char *source, int srclen, uint32 plen, char *errbuf) +{ +pcap_t *fp= NULL; // pcap_t main variable +unsigned int nread; // number of bytes of the payload read from the socket +char sendbuf[RPCAP_NETBUF_SIZE]; // temporary buffer in which data to be sent is buffered +int sendbufidx= 0; // index which keeps the number of bytes currently buffered +struct rpcap_openreply *openreply; // open reply message + + + strcpy(source, PCAP_SRC_IF_STRING); + + if (srclen <= (int) (strlen(PCAP_SRC_IF_STRING) + plen) ) + { + rpcap_senderror(sockctrl, "Source string too long", PCAP_ERR_OPEN, NULL); + return -1; + } + + if ( (nread= sock_recv(sockctrl, &source[strlen(PCAP_SRC_IF_STRING)], plen, SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE)) == -1) + return -1; + + // Check if all the data has been read; if not, discard the data in excess + if (nread != plen) + sock_discard(sockctrl, plen - nread, NULL, 0); + + // Puts a '0' to terminate the source string + source[strlen(PCAP_SRC_IF_STRING) + plen]= 0; + + // Open the selected device + // This is a fake open, since we do that only to get the needed parameters, then we close the device again + if ( (fp= pcap_open(source, + 1500 /* fake snaplen */, + 0 /* no promis */, + 1000 /* fake timeout */, + NULL /* local device, so no auth */, + errbuf)) == NULL) + { + rpcap_senderror(sockctrl, errbuf, PCAP_ERR_OPEN, NULL); + return -1; + } + + + // Now, I can send a RPCAP open reply message + if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx, + RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_OPEN_REPLY, 0, sizeof(struct rpcap_openreply) ); + + openreply= (struct rpcap_openreply *) &sendbuf[sendbufidx]; + + if ( sock_bufferize(NULL, sizeof(struct rpcap_openreply), NULL, &sendbufidx, + RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + memset(openreply, 0, sizeof(struct rpcap_openreply) ); + openreply->linktype= htonl(fp->linktype); + openreply->tzoff= htonl(fp->tzoff); + + if ( sock_send(sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + // I have to close the device again, since it has been opened with wrong parameters + pcap_close(fp); + fp= NULL; + + return 0; + +error: + if (fp) + { + pcap_close(fp); + fp= NULL; + } + + return -1; +} + + + + + +/* + \param plen: the length of the current message (needed in order to be able + to discard excess data in the message, if present) +*/ +pcap_t *daemon_startcapture(SOCKET sockctrl, pthread_t *threaddata, char *source, int active, struct rpcap_sampling *samp_param, uint32 plen, char *errbuf) +{ +char portdata[PCAP_BUF_SIZE]; // temp variable needed to derive the data port +char peerhost[PCAP_BUF_SIZE]; // temp variable needed to derive the host name of our peer +pcap_t *fp= NULL; // pcap_t main variable +unsigned int nread; // number of bytes of the payload read from the socket +char sendbuf[RPCAP_NETBUF_SIZE]; // temporary buffer in which data to be sent is buffered +int sendbufidx= 0; // index which keeps the number of bytes currently buffered + +// socket-related variables +SOCKET sockdata= 0; // socket descriptor of the data connection +struct addrinfo hints; // temp, needed to open a socket connection +struct addrinfo *addrinfo; // temp, needed to open a socket connection +struct sockaddr_storage saddr; // temp, needed to retrieve the network data port chosen on the local machine +socklen_t saddrlen; // temp, needed to retrieve the network data port chosen on the local machine + +pthread_attr_t detachedAttribute; // temp, needed to set the created thread as detached + +// RPCAP-related variables +struct rpcap_startcapreq startcapreq; // start capture request message +struct rpcap_startcapreply *startcapreply; // start capture reply message +int serveropen_dp; // keeps who is going to open the data connection + + addrinfo= NULL; + + if ( (nread= sock_recv(sockctrl, (char *) &startcapreq, sizeof(struct rpcap_startcapreq), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE)) == -1) + return NULL; + + startcapreq.flags= ntohs(startcapreq.flags); + + // Open the selected device + if ( (fp= pcap_open(source, + ntohl(startcapreq.snaplen), + (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_PROMISC) ? PCAP_OPENFLAG_PROMISCUOUS : 0 /* local device, other flags not needed */, + ntohl(startcapreq.read_timeout), + NULL /* local device, so no auth */, + errbuf)) == NULL) + { + rpcap_senderror(sockctrl, errbuf, PCAP_ERR_OPEN, NULL); + return NULL; + } + + // Apply sampling parameters + fp->rmt_samp.method= samp_param->method; + fp->rmt_samp.value= samp_param->value; + + /* + We're in active mode if: + - we're using TCP, and the user wants us to be in active mode + - we're using UDP + */ + serveropen_dp= (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_SERVEROPEN) || (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM) || active; + + /* + Gets the sockaddr structure referred to the other peer in the ctrl connection + + We need that because: + - if we're in passive mode, we need to know the address family we want to use + (the same used for the ctrl socket) + - if we're in active mode, we need to know the network address of the other host + we want to connect to + */ + saddrlen = sizeof(struct sockaddr_storage); + if (getpeername(sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1) + { + sock_geterror("getpeername(): ", errbuf, PCAP_ERRBUF_SIZE); + goto error; + } + + memset(&hints, 0, sizeof(struct addrinfo) ); + hints.ai_socktype = (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM) ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_family = saddr.ss_family; + + // Now we have to create a new socket to send packets + if (serveropen_dp) // Data connection is opened by the server toward the client + { + sprintf(portdata, "%d", ntohs(startcapreq.portdata) ); + + // Get the name of the other peer (needed to connect to that specific network address) + if (getnameinfo( (struct sockaddr *) &saddr, saddrlen, peerhost, + sizeof(peerhost), NULL, 0, NI_NUMERICHOST) ) + { + sock_geterror("getnameinfo(): ", errbuf, PCAP_ERRBUF_SIZE); + goto error; + } + + if (sock_initaddress(peerhost, portdata, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + if ( (sockdata= sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == -1) + goto error; + } + else // Data connection is opened by the client toward the server + { + hints.ai_flags = AI_PASSIVE; + + // Let's the server socket pick up a free network port for us + if (sock_initaddress(NULL, "0", &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + if ( (sockdata= sock_open(addrinfo, SOCKOPEN_SERVER, 1 /* max 1 connection in queue */, errbuf, PCAP_ERRBUF_SIZE)) == -1) + goto error; + + // get the complete sockaddr structure used in the data connection + saddrlen = sizeof(struct sockaddr_storage); + if (getsockname(sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1) + { + sock_geterror("getsockname(): ", errbuf, PCAP_ERRBUF_SIZE); + goto error; + } + + // Get the local port the system picked up + if (getnameinfo( (struct sockaddr *) &saddr, saddrlen, NULL, + 0, portdata, sizeof(portdata), NI_NUMERICSERV) ) + { + sock_geterror("getnameinfo(): ", errbuf, PCAP_ERRBUF_SIZE); + goto error; + } + } + + // addrinfo is no longer used + freeaddrinfo(addrinfo); + addrinfo= NULL; + + // save the socket ID for the next calls + fp->rmt_sockctrl= sockctrl; // Needed to send an error on the ctrl connection + + // Now I can set the filter + if ( daemon_unpackapplyfilter(fp, &nread, &plen, errbuf) ) + goto error; + + + // Now, I can send a RPCAP start capture reply message + if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx, + RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_STARTCAP_REPLY, 0, sizeof(struct rpcap_startcapreply) ); + + startcapreply= (struct rpcap_startcapreply *) &sendbuf[sendbufidx]; + + if ( sock_bufferize(NULL, sizeof(struct rpcap_startcapreply), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + memset(startcapreply, 0, sizeof(struct rpcap_startcapreply) ); + startcapreply->bufsize= htonl(fp->bufsize); + + if (!serveropen_dp) + { + unsigned short port = (unsigned short)strtoul(portdata,NULL,10); + startcapreply->portdata= htons(port); + } + + if ( sock_send(sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + if (!serveropen_dp) + { + SOCKET socktemp; // We need another socket, since we're going to accept() a connection + + // Connection creation + saddrlen = sizeof(struct sockaddr_storage); + + socktemp= accept(sockdata, (struct sockaddr *) &saddr, &saddrlen); + + if (socktemp == -1) + { + sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE); + goto error; + } + + // Now that I accepted the connection, the server socket is no longer needed + sock_close(sockdata, errbuf, PCAP_ERRBUF_SIZE); + sockdata= socktemp; + } + + fp->rmt_sockdata= sockdata; + + /* GV we need this to create the thread as detached. */ + /* GV otherwise, the thread handle is not destroyed */ + pthread_attr_init(&detachedAttribute); + pthread_attr_setdetachstate(&detachedAttribute, PTHREAD_CREATE_DETACHED); + + // Now we have to create a new thread to receive packets + if ( pthread_create(threaddata, &detachedAttribute, (void *) daemon_thrdatamain, (void *) fp) ) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the data thread"); + pthread_attr_destroy(&detachedAttribute); + goto error; + } + + pthread_attr_destroy(&detachedAttribute); + // Check if all the data has been read; if not, discard the data in excess + if (nread != plen) + sock_discard(sockctrl, plen - nread, NULL, 0); + + return fp; + +error: + rpcap_senderror(sockctrl, errbuf, PCAP_ERR_STARTCAPTURE, NULL); + + if (addrinfo) + freeaddrinfo(addrinfo); + + if (threaddata) + pthread_cancel(*threaddata); + + if (sockdata) + sock_close(sockdata, NULL, 0); + + // Check if all the data has been read; if not, discard the data in excess + if (nread != plen) + sock_discard(sockctrl, plen - nread, NULL, 0); + + if (fp) + { + pcap_close(fp); + fp= NULL; + } + + return NULL; +} + + + +int daemon_endcapture(pcap_t *fp, pthread_t *threaddata, char *errbuf) +{ +struct rpcap_header header; +SOCKET sockctrl; + + if (threaddata) + { + pthread_cancel(*threaddata); + threaddata= 0; + } + if (fp->rmt_sockdata) + { + sock_close(fp->rmt_sockdata, NULL, 0); + fp->rmt_sockdata= 0; + } + + sockctrl= fp->rmt_sockctrl; + + pcap_close(fp); + fp= NULL; + + rpcap_createhdr( &header, RPCAP_MSG_ENDCAP_REPLY, 0, 0); + + if ( sock_send(sockctrl, (char *) &header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1) + return -1; + + return 0; +} + + + +int daemon_unpackapplyfilter(pcap_t *fp, unsigned int *nread, int *plen, char *errbuf) +{ +struct rpcap_filter filter; +struct rpcap_filterbpf_insn insn; +struct bpf_insn *bf_insn; +struct bpf_program bf_prog; +unsigned int i; + + + if ( ( *nread+= sock_recv(fp->rmt_sockctrl, (char *) &filter, sizeof(struct rpcap_filter), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE)) == -1) + { + // to avoid blocking on the sock_discard() + *plen= *nread; + return -1; + } + + bf_prog.bf_len= ntohl(filter.nitems); + + if (ntohs(filter.filtertype) != RPCAP_UPDATEFILTER_BPF) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Only BPF/NPF filters are currently supported"); + return -1; + } + + bf_insn= (struct bpf_insn *) malloc ( sizeof(struct bpf_insn) * bf_prog.bf_len); + if (bf_insn == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + return -1; + } + + bf_prog.bf_insns= bf_insn; + + for (i= 0; i < bf_prog.bf_len; i++) + { + if ( ( *nread+= sock_recv(fp->rmt_sockctrl, (char *) &insn, + sizeof(struct rpcap_filterbpf_insn), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE)) == -1) + return -1; + + bf_insn->code= ntohs(insn.code); + bf_insn->jf= insn.jf; + bf_insn->jt= insn.jt; + bf_insn->k= ntohl(insn.k); + + bf_insn++; + } + + if (bpf_validate(bf_prog.bf_insns, bf_prog.bf_len) == 0) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The filter contains bogus instructions"); + return -1; + } + + if (pcap_setfilter(fp, &bf_prog) ) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "RPCAP error: %s", fp->errbuf); + return -1; + } + + return 0; +} + + + +int daemon_updatefilter(pcap_t *fp, uint32 plen) +{ +struct rpcap_header header; // keeps the answer to the updatefilter command +unsigned int nread; + + nread= 0; + + if ( daemon_unpackapplyfilter(fp, &nread, &plen, fp->errbuf) ) + goto error; + + // Check if all the data has been read; if not, discard the data in excess + if (nread != plen) + { + if (sock_discard(fp->rmt_sockctrl, plen - nread, NULL, 0) ) + { + nread= plen; // just to avoid to call discard again in the 'error' section + goto error; + } + } + + // A response is needed, otherwise the other host does not know that everything went well + rpcap_createhdr( &header, RPCAP_MSG_UPDATEFILTER_REPLY, 0, 0); + + if ( sock_send(fp->rmt_sockctrl, (char *) &header, sizeof (struct rpcap_header), fp->errbuf, PCAP_ERRBUF_SIZE) ) + goto error; + + return 0; + + +error: + if (nread != plen) + sock_discard(fp->rmt_sockctrl, plen - nread, NULL, 0); + + rpcap_senderror(fp->rmt_sockctrl, fp->errbuf, PCAP_ERR_UPDATEFILTER, NULL); + + return -1; +} + + + +/*! + \brief Received the sampling parameters from remote host and it stores in the pcap_t structure. +*/ +int daemon_setsampling(SOCKET sockctrl, struct rpcap_sampling *samp_param, int plen, char *errbuf) +{ +struct rpcap_header header; +struct rpcap_sampling rpcap_samp; +int nread; // number of bytes of the payload read from the socket + + + if ( ( nread= sock_recv(sockctrl, (char *) &rpcap_samp, sizeof(struct rpcap_sampling), + SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE)) == -1) + goto error; + + + // Save these settings in the pcap_t + samp_param->method= rpcap_samp.method; + samp_param->value= ntohl(rpcap_samp.value); + + + // A response is needed, otherwise the other host does not know that everything went well + rpcap_createhdr( &header, RPCAP_MSG_SETSAMPLING_REPLY, 0, 0); + + if ( sock_send(sockctrl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) ) + goto error; + + if (nread != plen) + sock_discard(sockctrl, plen - nread, NULL, 0); + + return 0; + +error: + if (nread != plen) + sock_discard(sockctrl, plen - nread, NULL, 0); + + rpcap_senderror(sockctrl, errbuf, PCAP_ERR_SETSAMPLING, NULL); + + return -1; +} + + + +int daemon_getstats(pcap_t *fp) +{ +char sendbuf[RPCAP_NETBUF_SIZE]; // temporary buffer in which data to be sent is buffered +int sendbufidx= 0; // index which keeps the number of bytes currently buffered +struct pcap_stat stats; // local statistics +struct rpcap_stats *netstats; // statistics sent on the network + + if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, fp->errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_STATS_REPLY, 0, (uint16) sizeof(struct rpcap_stats)); + + netstats= (struct rpcap_stats *) &sendbuf[sendbufidx]; + + if ( sock_bufferize(NULL, sizeof(struct rpcap_stats), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, fp->errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + if (pcap_stats(fp, &stats) ) + goto error; + + netstats->ifdrop= htonl(stats.ps_ifdrop); + netstats->ifrecv= htonl(stats.ps_recv); + netstats->krnldrop= htonl(stats.ps_drop); + netstats->svrcapt= htonl(fp->md.TotCapt); + + // Send the packet + if ( sock_send(fp->rmt_sockctrl, sendbuf, sendbufidx, fp->errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + return 0; + +error: + rpcap_senderror(fp->rmt_sockctrl, fp->errbuf, PCAP_ERR_GETSTATS, NULL); + return -1; +} + + + + +int daemon_getstatsnopcap(SOCKET sockctrl, unsigned int ifdrops, unsigned int ifrecv, + unsigned int krnldrop, unsigned int svrcapt, char *errbuf) +{ +char sendbuf[RPCAP_NETBUF_SIZE]; // temporary buffer in which data to be sent is buffered +int sendbufidx= 0; // index which keeps the number of bytes currently buffered +struct rpcap_stats *netstats; // statistics sent on the network + + if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_STATS_REPLY, 0, (uint16) sizeof(struct rpcap_stats)); + + netstats= (struct rpcap_stats *) &sendbuf[sendbufidx]; + + if ( sock_bufferize(NULL, sizeof(struct rpcap_stats), NULL, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + netstats->ifdrop= htonl(ifdrops); + netstats->ifrecv= htonl(ifrecv); + netstats->krnldrop= htonl(krnldrop); + netstats->svrcapt= htonl(svrcapt); + + // Send the packet + if ( sock_send(sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + return 0; + +error: + rpcap_senderror(sockctrl, errbuf, PCAP_ERR_GETSTATS, NULL); + return -1; +} + + + + +void *daemon_thrdatamain(void *ptr) +{ +char errbuf[PCAP_ERRBUF_SIZE + 1]; // error buffer +pcap_t *fp; // pointer to a 'pcap' structure +int retval; // general variable used to keep the return value of other functions +struct rpcap_pkthdr *net_pkt_header;// header of the packet +struct pcap_pkthdr *pkt_header; // pointer to the buffer that contains the header of the current packet +u_char *pkt_data; // pointer to the buffer that contains the current packet +char *sendbuf; // temporary buffer in which data to be sent is buffered +int sendbufidx; // index which keeps the number of bytes currently buffered + + fp= (pcap_t *) ptr; + + fp->md.TotCapt= 0; // counter which is incremented each time a packet is received + + // Initialize errbuf + memset(errbuf, 0, sizeof(errbuf) ); + + // Some platforms (e.g. Win32) allow creating a static variable with this size + // However, others (e.g. BSD) do not, so we're forced to allocate this buffer dynamically + sendbuf= (char *) malloc (sizeof(char) * RPCAP_NETBUF_SIZE); + if (sendbuf == NULL) + { + snprintf(errbuf, sizeof(errbuf) - 1, "Unable to create the buffer for this child thread"); + goto error; + } + + // Modify thread params so that it can be killed at any time + if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) ) + goto error; + if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) ) + goto error; + + // Retrieve the packets + while ((retval = pcap_next_ex(fp, &pkt_header, (const u_char **) &pkt_data)) >= 0) // cast to avoid a compiler warning + { + if (retval == 0) // Read timeout elapsed + continue; + + sendbufidx= 0; + + // Bufferize the general header + if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx, + RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_PACKET, 0, + (uint16) (sizeof(struct rpcap_pkthdr) + pkt_header->caplen) ); + + net_pkt_header= (struct rpcap_pkthdr *) &sendbuf[sendbufidx]; + + // Bufferize the pkt header + if ( sock_bufferize(NULL, sizeof(struct rpcap_pkthdr), NULL, &sendbufidx, + RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + net_pkt_header->caplen= htonl(pkt_header->caplen); + net_pkt_header->len= htonl(pkt_header->len); + net_pkt_header->npkt= htonl( ++(fp->md.TotCapt) ); + net_pkt_header->timestamp_sec= htonl(pkt_header->ts.tv_sec); + net_pkt_header->timestamp_usec= htonl(pkt_header->ts.tv_usec); + + // Bufferize the pkt data + if ( sock_bufferize((char *) pkt_data, pkt_header->caplen, sendbuf, &sendbufidx, + RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + // Send the packet + if ( sock_send(fp->rmt_sockdata, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + + } + + if (retval == -1) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error reading the packets: %s", pcap_geterr(fp) ); + rpcap_senderror(fp->rmt_sockctrl, errbuf, PCAP_ERR_READEX, NULL); + goto error; + } + +error: + + SOCK_ASSERT(errbuf, 1); + closesocket(fp->rmt_sockdata); + fp->rmt_sockdata= 0; + + free(sendbuf); + + return NULL; +} + + + +/*! + \brief It serializes a network address. + + It accepts a 'sockaddr_storage' structure as input, and it converts it appropriately into a format + that can be used to be sent on the network. Basically, it applies all the hton() + conversion required to the input variable. + + \param sockaddrin: a 'sockaddr_storage' pointer to the variable that has to be + serialized. This variable can be both a 'sockaddr_in' and 'sockaddr_in6'. + + \param sockaddrout: a 'sockaddr_storage' pointer to the variable that will contain + the serialized data. This variable has to be allocated by the user. + + \return None + + \warning This function supports only AF_INET and AF_INET6 address families. +*/ +void daemon_seraddr(struct sockaddr_storage *sockaddrin, struct sockaddr_storage *sockaddrout) +{ + memset(sockaddrout, 0, sizeof(struct sockaddr_storage) ); + + // There can be the case in which the sockaddrin is not available + if (sockaddrin == NULL) return; + + // Warning: we support only AF_INET and AF_INET6 + if (sockaddrin->ss_family == AF_INET) + { + struct sockaddr_in *sockaddr; + + sockaddr= (struct sockaddr_in *) sockaddrin; + sockaddr->sin_family= htons(sockaddr->sin_family); + sockaddr->sin_port= htons(sockaddr->sin_port); + memcpy(sockaddrout, sockaddr, sizeof(struct sockaddr_in) ); + } + else + { + struct sockaddr_in6 *sockaddr; + + sockaddr= (struct sockaddr_in6 *) sockaddrin; + sockaddr->sin6_family= htons(sockaddr->sin6_family); + sockaddr->sin6_port= htons(sockaddr->sin6_port); + sockaddr->sin6_flowinfo= htonl(sockaddr->sin6_flowinfo); + sockaddr->sin6_scope_id= htonl(sockaddr->sin6_scope_id); + memcpy(sockaddrout, sockaddr, sizeof(struct sockaddr_in6) ); + } +} + + + + + +/*! + \brief Suspends a pthread for msec milliseconds. + + This function is provided since pthreads do not have a suspend() call. +*/ +void pthread_suspend(int msec) +{ +#ifdef WIN32 + Sleep(msec); +#else +struct timespec abstime; +struct timeval now; + + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_mutexattr_t attr; + + pthread_mutexattr_init(&attr); + pthread_mutex_init(&mutex, &attr); + pthread_mutex_lock(&mutex); + + pthread_cond_init(&cond, NULL); + + gettimeofday(&now, NULL); + + abstime.tv_sec = now.tv_sec + msec/1000; + abstime.tv_nsec = now.tv_usec * 1000 + (msec%1000) * 1000 * 1000; + + pthread_cond_timedwait(&cond, &mutex, &abstime); + + pthread_mutex_destroy(&mutex); + pthread_cond_destroy(&cond); +#endif +} + + + diff --git a/winpcap/wpcap/libpcap/rpcapd/daemon.h b/winpcap/wpcap/libpcap/rpcapd/daemon.h new file mode 100644 index 0000000..888c54d --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/daemon.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __DAEMON_H__ +#define __DAEMON_H__ + +//! Structure that keeps the parameters needed by the daemon_serviceloop() function +struct daemon_slpars +{ + SOCKET sockctrl; //!< SOCKET ID of the control connection + int isactive; //!< Not null if the daemon has to run in active mode + int nullAuthAllowed; //!< '1' if we permit NULL authentication, '0' otherwise + int activeclose; //!< '1' if the client closed the control connection explicitely; used in active mode only +}; + + +void daemon_serviceloop( void *ptr ); + +void pthread_suspend(int msec); + +#endif + diff --git a/winpcap/wpcap/libpcap/rpcapd/fileconf.c b/winpcap/wpcap/libpcap/rpcapd/fileconf.c new file mode 100644 index 0000000..5c0422c --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/fileconf.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include +#include +#include +#include // for PCAP_ERRBUF_SIZE +#include "rpcapd.h" +#include "pcap-remote.h" +#include "sockutils.h" // for SOCK_ASSERT + + +extern char hostlist[MAX_HOST_LIST + 1]; //!< Keeps the list of the hosts that are allowed to connect to this server +extern struct active_pars activelist[MAX_ACTIVE_LIST]; //!< Keeps the list of the hosts (host, port) on which I want to connect to (active mode) +extern int nullAuthAllowed; //!< '1' if we permit NULL authentication, '0' otherwise +extern char loadfile[MAX_LINE + 1]; //!< Name of the file from which we have to load the configuration + + + +int strrem(char *string, char chr); + + + +void fileconf_read(int sign) +{ +FILE *fp; +char msg[PCAP_ERRBUF_SIZE + 1]; +int i; + +#ifndef WIN32 + signal(SIGHUP, fileconf_read); +#endif + + if ((fp= fopen(loadfile, "r") ) != NULL) + { + char line[MAX_LINE + 1]; + char *ptr; + + hostlist[0]= 0; + i= 0; + + while ( fgets(line, MAX_LINE, fp) != NULL ) + { + if (line[0] == '\n') continue; // Blank line + if (line[0] == '\r') continue; // Blank line + if (line[0] == '#') continue; // Comment + + if ( (ptr= strstr(line, "ActiveClient")) ) + { + char *address, *port; + + ptr= strchr(ptr, '=') + 1; + address= strtok(ptr, RPCAP_HOSTLIST_SEP); + + if ( (address != NULL) && (i < MAX_ACTIVE_LIST) ) + { + port = strtok(NULL, RPCAP_HOSTLIST_SEP); + snprintf(activelist[i].address, MAX_LINE, address); + + if (strcmp(port, "DEFAULT") == 0) // the user choose a custom port + snprintf(activelist[i].port, MAX_LINE, RPCAP_DEFAULT_NETPORT_ACTIVE); + else + snprintf(activelist[i].port, MAX_LINE, port); + + activelist[i].address[MAX_LINE] = 0; + activelist[i].port[MAX_LINE] = 0; + } + else + SOCK_ASSERT("Only MAX_ACTIVE_LIST active connections are currently supported.", 1); + + i++; + continue; + } + + if ( (ptr= strstr(line, "PassiveClient")) ) + { + ptr= strchr(ptr, '=') + 1; + strncat(hostlist, ptr, MAX_HOST_LIST); + strncat(hostlist, ",", MAX_HOST_LIST); + continue; + } + + if ( (ptr= strstr(line, "NullAuthPermit")) ) + { + ptr= strstr(ptr, "YES"); + if (ptr) + nullAuthAllowed= 1; + else + nullAuthAllowed= 0; + continue; + } + } + + // clear the remaining fields of the active list + while (i < MAX_ACTIVE_LIST) + { + activelist[i].address[0] = 0; + activelist[i].port[0] = 0; + i++; + } + + // Remove all '\n' and '\r' from the strings + strrem(hostlist, '\r'); + strrem(hostlist, '\n'); + + snprintf(msg, PCAP_ERRBUF_SIZE, "New passive host list: %s\n\n", hostlist); + SOCK_ASSERT(msg, 1); + fclose(fp); + } +} + + + +int fileconf_save(const char *savefile) +{ +FILE *fp; + + if ((fp= fopen(savefile, "w") ) != NULL) + { + char *token; /*, *port;*/ // temp, needed to separate items into the hostlist + char temphostlist[MAX_HOST_LIST + 1]; + int i= 0; + + fprintf(fp, "# Configuration file help.\n\n"); + + // Save list of clients which are allowed to connect to us in passive mode + fprintf(fp, "# Hosts which are allowed to connect to this server (passive mode)\n"); + fprintf(fp, "# Format: PassiveClient = \n\n"); + + strncpy(temphostlist, hostlist, MAX_HOST_LIST); + temphostlist[MAX_HOST_LIST]= 0; + + token= strtok(temphostlist, RPCAP_HOSTLIST_SEP); + while( token != NULL ) + { + fprintf(fp, "PassiveClient = %s\n", token); + token = strtok(NULL, RPCAP_HOSTLIST_SEP); + } + + + // Save list of clients which are allowed to connect to us in active mode + fprintf(fp, "\n\n"); + fprintf(fp, "# Hosts to which this server is trying to connect to (active mode)\n"); + fprintf(fp, "# Format: ActiveClient = , \n\n"); + + + while ( (activelist[i].address[0] != 0) && (i < MAX_ACTIVE_LIST) ) + { + fprintf(fp, "ActiveClient = %s, %s\n", activelist[i].address, activelist[i].port); + i++; + } + + // Save if we want to permit NULL authentication + fprintf(fp, "\n\n"); + fprintf(fp, "# Permit NULL authentication: YES or NOT\n\n"); + + if (nullAuthAllowed) + fprintf(fp, "NullAuthPermit = YES\n"); + else + fprintf(fp, "NullAuthPermit = NO\n"); + + fclose(fp); + return 0; + } + else + { + return -1; + } + +} + + + +int strrem(char *string, char chr) +{ +char *pos; +int num= 0; +int len, i; + + while ( (pos= strchr(string, chr) ) != NULL) + { + num++; + len= strlen(pos); + for (i=0; i // for the errno variable +#include // for strtok, etc +#include // for malloc(), free(), ... +#include // for PCAP_ERRBUF_SIZE +#include // for signal() +#include +#include "rpcapd.h" +#include "fileconf.h" // for the configuration file management +#include "pcap-remote.h" +#include "daemon.h" // the true main() method of this daemon +#include "utils.h" // Missing calls and such +#include "sockutils.h" // for socket calls + +#ifndef WIN32 +#include // for exit() +#include // waitpid() +#else +#include "win32-svc.h" // for Win32 service stuff +#endif + + +// Global variables +char hostlist[MAX_HOST_LIST + 1]; //!< Keeps the list of the hosts that are allowed to connect to this server +struct active_pars activelist[MAX_ACTIVE_LIST]; //!< Keeps the list of the hosts (host, port) on which I want to connect to (active mode) +int nullAuthAllowed; //!< '1' if we permit NULL authentication, '0' otherwise +SOCKET sockmain; //!< keeps the main socket identifier +char loadfile[MAX_LINE + 1]; //!< Name of the file from which we have to load the configuration +int passivemode= 1; //!< '1' if we want to run in passive mode as well +struct addrinfo mainhints; //!< temporary struct to keep settings needed to open the new socket +char address[MAX_LINE + 1]; //!< keeps the network address (either numeric or literal) to bind to +char port[MAX_LINE + 1]; //!< keeps the network port to bind to + +extern char *optarg; // for getopt() + + + +// Function definition +void main_passive(void *ptr); +void main_active(void *ptr); + + +#ifndef WIN32 +void main_cleanup_childs(int sign); +#endif + + +/*! + \brief Prints the usage screen if it is launched in console mode. +*/ +void printusage() +{ + char *usagetext = + "USAGE:\n" + " " PROGRAM_NAME " [-b
] [-p ] [-6] [-l ] [-a ]\n" + " [-n] [-v] [-d] [-s ] [-f ]\n" + " -b
: the address to bind to (either numeric or literal).\n" + " Default: it binds to all local IPv4 addresses\n" + " -p : the port to bind to. Default: it binds to port " RPCAP_DEFAULT_NETPORT "\n" + " -4: use only IPv4 (default both IPv4 and IPv6 waiting sockets are used)\n" + " -l : a file that keeps the list of the hosts which are allowed\n" + " to connect to this server (if more than one, list them one per line).\n" + " We suggest to use literal names (instead of numeric ones) in order to\n" + " avoid problems with different address families\n" + " -n: permit NULL authentication (usually used with '-l')\n" + " -a : run in active mode when connecting to 'host' on port 'port'\n" + " In case 'port' is omitted, the default port (" RPCAP_DEFAULT_NETPORT_ACTIVE ") is used\n" + " -v: run in active mode only (default: if '-a' is specified, it accepts\n" + " passive connections as well\n" + " -d: run in daemon mode (UNIX only) or as a service (Win32 only)\n" + " Warning (Win32): this switch is provided automatically when the service\n" + " is started from the control panel\n" + " -s : save the current configuration to file\n" + " -f : load the current configuration from file; all the switches\n" + " specified from the command line are ignored\n" + " -h: print this help screen\n\n"; + + printf(usagetext); +} + + + +//! Program main +int main(int argc, char *argv[], char *envp[]) +{ +char savefile[MAX_LINE + 1]; // name of the file on which we have to save the configuration +int isdaemon= 0; // Not null if the user wants to run this program as a daemon +int retval; // keeps the returning value from several functions +char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed + + + savefile[0]= 0; + loadfile[0]= 0; + hostlist[0]= 0; + + // Initialize errbuf + memset(errbuf, 0, sizeof(errbuf) ); + + if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1) + { + SOCK_ASSERT(errbuf, 1); + exit(-1); + } + + strncpy(address, RPCAP_DEFAULT_NETADDR, MAX_LINE); + strncpy(port, RPCAP_DEFAULT_NETPORT, MAX_LINE); + + // Prepare to open a new server socket + memset(&mainhints, 0, sizeof(struct addrinfo)); + + mainhints.ai_family = PF_UNSPEC; + mainhints.ai_flags = AI_PASSIVE; // Ready to a bind() socket + mainhints.ai_socktype = SOCK_STREAM; + + // Getting the proper command line options + while ((retval = getopt(argc, argv, "b:dhp:4l:na:s:f:v")) != -1) + { + switch (retval) + { + case 'b': + strncpy(address, optarg, MAX_LINE); + break; + case 'p': + strncpy(port, optarg, MAX_LINE); + break; + case '4': + mainhints.ai_family = PF_INET; // IPv4 server only + break; + case 'd': + isdaemon= 1; + break; + case 'n': + nullAuthAllowed= 1; + break; + case 'v': + passivemode= 0; + break; + case 'l': + { + strncpy(hostlist, optarg, sizeof(hostlist) ); + break; + } + case 'a': + { + char *tmpaddress, *tmpport; + int i= 0; + + tmpaddress= strtok(optarg, RPCAP_HOSTLIST_SEP); + + while ( (tmpaddress != NULL) && (i < MAX_ACTIVE_LIST) ) + { + tmpport= strtok(NULL, RPCAP_HOSTLIST_SEP); + + snprintf(activelist[i].address, MAX_LINE, tmpaddress); + + if ( (tmpport == NULL) || (strcmp(tmpport, "DEFAULT") == 0) ) // the user choose a custom port + snprintf(activelist[i].port, MAX_LINE, RPCAP_DEFAULT_NETPORT_ACTIVE); + else + snprintf(activelist[i].port, MAX_LINE, tmpport); + + tmpaddress = strtok(NULL, RPCAP_HOSTLIST_SEP); + + i++; + } + + if (i > MAX_ACTIVE_LIST) + SOCK_ASSERT("Only MAX_ACTIVE_LIST active connections are currently supported.", 1); + + // I don't initialize the remaining part of the structure, since + // it is already zeroed (it is a global var) + break; + } + case 'f': + strncpy(loadfile, optarg, MAX_LINE); + break; + case 's': + strncpy(savefile, optarg, MAX_LINE); + break; + case 'h': + printusage(); + exit(0); + default: + break; + } + } + + if (savefile[0]) + { + if (fileconf_save(savefile) ) + SOCK_ASSERT("Error when saving the configuration to file", 1); + } + + // If the file does not exist, it keeps the settings provided by the command line + if (loadfile[0]) + fileconf_read(0); + +#ifdef linux + // SIGTERM (i.e. kill -15) is not generated in WIN32, although it is included for ANSI compatibility + signal(SIGTERM, main_cleanup); + signal(SIGCHLD, main_cleanup_childs); +#endif + + // forking a daemon, if it is needed + if (isdaemon) + { + #ifndef WIN32 + int pid; + + // Unix Network Programming, pg 336 + if ( (pid = fork() ) != 0) + exit(0); // Parent terminates + + // First child continues + // Set daemon mode + setsid(); + + // generated under unix with 'kill -HUP', needed to reload the configuration + signal(SIGHUP, fileconf_read); + + if ( (pid = fork() ) != 0) + exit(0); // First child terminates + + // LINUX WARNING: the current linux implementation of pthreads requires a management thread + // to handle some hidden stuff. So, as soon as you create the first thread, two threads are + // created. Fom this point on, the number of threads active are always one more compared + // to the number you're expecting + + // Second child continues +// umask(0); +// chdir("/"); + #else + // We use the SIGABRT signal to kill the Win32 service + signal(SIGABRT, main_cleanup); + + // If this call succeeds, it is blocking on Win32 + if ( svc_start() != 1) + SOCK_ASSERT(1, "Unable to start the service"); + + // When the previous call returns, the entire application has to be stopped. + exit(0); + #endif + } + else // Console mode + { + // Enable the catching of Ctrl+C + signal(SIGINT, main_cleanup); + +#ifndef WIN32 + // generated under unix with 'kill -HUP', needed to reload the configuration + // We do not have this kind of signal in Win32 + signal(SIGHUP, fileconf_read); +#endif + + printf("Press CTRL + C to stop the server...\n"); + } + + // If we're a Win32 service, we have already called this function in the service_main + main_startup(); + + // The code should never arrive here (since the main_startup is blocking) + // however this avoids a compiler warning + exit(0); +} + + + +void main_startup(void) +{ +char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed +struct addrinfo *addrinfo; // keeps the addrinfo chain; required to open a new socket +int i; +#ifdef WIN32 + pthread_t threadId; // Pthread variable that keeps the thread structures + pthread_attr_t detachedAttribute; // PThread attribute needed to create the thread as detached +#else + pid_t pid; +#endif + + i= 0; + addrinfo= NULL; + memset(errbuf, 0, sizeof(errbuf) ); + + // Starts all the active threads + while ( (activelist[i].address[0] != 0) && (i < MAX_ACTIVE_LIST) ) + { + activelist[i].ai_family= mainhints.ai_family; + +#ifdef WIN32 + /* GV we need this to create the thread as detached. */ + /* GV otherwise, the thread handle is not destroyed */ + pthread_attr_init(&detachedAttribute); + pthread_attr_setdetachstate(&detachedAttribute, PTHREAD_CREATE_DETACHED); + + if ( pthread_create( &threadId, &detachedAttribute, (void *) &main_active, (void *) &activelist[i]) ) + { + SOCK_ASSERT("Error creating the active child thread", 1); + pthread_attr_destroy(&detachedAttribute); + continue; + } + pthread_attr_destroy(&detachedAttribute); +#else + if ( (pid= fork() ) == 0) // I am the child + { + main_active( (void *) &activelist[i]); + exit(0); + } +#endif + i++; + } + + /* + The code that manages the active connections is not blocking; + vice versa, the code that manages the passive connection is blocking. + So, if the user do not want to run in passive mode, we have to block + the main thread here, otherwise the program ends and all threads + are stopped. + + WARNING: this means that in case we have only active mode, the program does + not terminate even if all the child thread terminates. The user has always to + press Ctrl+C (or send a SIGTERM) to terminate the program. + */ + + if (passivemode) + { + struct addrinfo *tempaddrinfo; + + // Do the work + if (sock_initaddress((address[0]) ? address : NULL, port, &mainhints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1) + { + SOCK_ASSERT(errbuf, 1); + return; + } + + tempaddrinfo= addrinfo; + + while (tempaddrinfo) + { + SOCKET *socktemp; + + if ( (sockmain= sock_open(tempaddrinfo, SOCKOPEN_SERVER, SOCKET_MAXCONN, errbuf, PCAP_ERRBUF_SIZE)) == -1) + { + SOCK_ASSERT(errbuf, 1); + tempaddrinfo= tempaddrinfo->ai_next; + continue; + } + + // This trick is needed in order to allow the child thread to save the 'sockmain' variable + // withouth getting it overwritten by the sock_open, in case we want to open more than one waiting sockets + // For instance, the pthread_create() will accept the socktemp variable, and it will deallocate immediately that variable + socktemp= (SOCKET *) malloc (sizeof (SOCKET)); + if (socktemp == NULL) + exit(0); + + *socktemp= sockmain; + +#ifdef WIN32 + /* GV we need this to create the thread as detached. */ + /* GV otherwise, the thread handle is not destroyed */ + pthread_attr_init(&detachedAttribute); + pthread_attr_setdetachstate(&detachedAttribute, PTHREAD_CREATE_DETACHED); + + if ( pthread_create( &threadId, &detachedAttribute, (void *) &main_passive, (void *) socktemp ) ) + { + SOCK_ASSERT("Error creating the passive child thread", 1); + pthread_attr_destroy(&detachedAttribute); + continue; + } + + pthread_attr_destroy(&detachedAttribute); +#else + if ( (pid= fork() ) == 0) // I am the child + { + main_passive( (void *) socktemp); + return; + } +#endif + tempaddrinfo= tempaddrinfo->ai_next; + } + + freeaddrinfo(addrinfo); + } + + // All the previous calls are no blocking, so the main line of execution goes here + // and I have to avoid that the program terminates + while (1) + pthread_suspend(10*60*1000); // it wakes up every 10 minutes; it seems to me reasonable +} + + +/* + \brief Closes gracefully (more or less) the program. + + This function is called: + - when we're running in console + - when we're running as a Win32 service (in case we press STOP) + + It is not called when we are running as a daemon on UNIX, since + we do not define a signal in order to terminate gracefully the daemon. + + This function makes a fast cleanup (it does not clean everything, as + you can see from the fact that it uses kill() on UNIX), closes + the main socket, free winsock resources (on Win32) and exits the + program. +*/ +void main_cleanup(int sign) +{ +#ifndef WIN32 + // Sends a KILL signal to all the processes + // that share the same process group (i.e. kills all the childs) + kill(0, SIGKILL); +#endif + + SOCK_ASSERT(PROGRAM_NAME " is closing.\n", 1); + + // FULVIO (bug) + // Here we close only the latest 'sockmain' created; if we opened more than one waiting sockets, + // only the latest one is closed correctly. + if (sockmain) + closesocket(sockmain); + sock_cleanup(); + + /* + This code is executed under the following conditions: + - SIGTERM: we're under UNIX, and the user kills us with 'kill -15' + (no matter is we're a daemon or in a console mode) + - SIGINT: we're in console mode and the user sends us a Ctrl+C + (SIGINT signal), no matter if we're UNIX or Win32 + + In all these cases, we have to terminate the program. + The case that still remains is if we're a Win32 service: in this case, + we're a child thread, and we want just to terminate ourself. This is because + the exit(0) will be invoked by the main thread, which is blocked waiting that + all childs terminates. We are forced to call exit from the main thread otherwise + the Win32 service control manager (SCM) does not work well. + */ + if ( (sign == SIGTERM) || (sign == SIGINT) ) + exit(0); + else + return; +} + + + +#ifdef linux + +void main_cleanup_childs(int sign) +{ +pid_t pid; +int stat; + + // For reference, Stevens, pg 128 + + while ( (pid= waitpid(-1, &stat, WNOHANG) ) > 0) + SOCK_ASSERT("Child terminated", 1); + + return; +} + +#endif + + + + + +/*! + \brief 'true' main of the program. + + It must be in a separate function because: + - if we're in 'console' mode, we have to put the main thread waiting for a Ctrl+C + (in order to be able to stop everything) + - if we're in daemon mode, the main program must terminate and a new child must be + created in order to create the daemon + + \param ptr: it keeps the main socket handler (what's called 'sockmain' in the main() ), that + represents the socket used in the main connection. It is a 'void *' just because pthreads + want this format. +*/ +void main_passive(void *ptr) +{ +char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed +SOCKET sockctrl; // keeps the socket ID for this control connection +struct sockaddr_storage from; // generic sockaddr_storage variable +socklen_t fromlen; // keeps the length of the sockaddr_storage variable +SOCKET sockmain; + +#ifndef WIN32 + pid_t pid; +#endif + + sockmain= *((SOCKET *) ptr); + + // Delete the pointer (which has been allocated in the main) + free(ptr); + + // Initialize errbuf + memset(errbuf, 0, sizeof(errbuf) ); + + // main thread loop + while (1) + { +#ifdef WIN32 + pthread_t threadId; // Pthread variable that keeps the thread structures + pthread_attr_t detachedAttribute; +#endif + struct daemon_slpars *pars; // parameters needed by the daemon_serviceloop() + + // Connection creation + fromlen = sizeof(struct sockaddr_storage); + + sockctrl= accept(sockmain, (struct sockaddr *) &from, &fromlen); + + if (sockctrl == -1) + { + // The accept() call can return this error when a signal is catched + // In this case, we have simply to ignore this error code + // Stevens, pg 124 +#ifdef WIN32 + if (WSAGetLastError() == WSAEINTR) +#else + if (errno == EINTR) +#endif + continue; + + // Don't check for errors here, since the error can be due to the fact that the thread + // has been killed + sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE); + SOCK_ASSERT(errbuf, 1); + continue; + } + + // checks if the connecting host is among the ones allowed + if (sock_check_hostlist(hostlist, RPCAP_HOSTLIST_SEP, &from, errbuf, PCAP_ERRBUF_SIZE) < 0 ) + { + rpcap_senderror(sockctrl, errbuf, PCAP_ERR_HOSTNOAUTH, NULL); + sock_close(sockctrl, NULL, 0); + continue; + } + + +#ifdef WIN32 + // in case of passive mode, this variable is deallocated by the daemon_serviceloop() + pars= (struct daemon_slpars *) malloc ( sizeof(struct daemon_slpars) ); + if (pars == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + continue; + } + + pars->sockctrl= sockctrl; + pars->activeclose= 0; // useless in passive mode + pars->isactive= 0; + pars->nullAuthAllowed= nullAuthAllowed; + + /* GV we need this to create the thread as detached. */ + /* GV otherwise, the thread handle is not destroyed */ + pthread_attr_init(&detachedAttribute); + pthread_attr_setdetachstate(&detachedAttribute, PTHREAD_CREATE_DETACHED); + if ( pthread_create( &threadId, &detachedAttribute, (void *) &daemon_serviceloop, (void *) pars) ) + { + SOCK_ASSERT("Error creating the child thread", 1); + pthread_attr_destroy(&detachedAttribute); + continue; + } + pthread_attr_destroy(&detachedAttribute); + +#else + if ( (pid= fork() ) == 0) // I am the child + { + // in case of passive mode, this variable is deallocated by the daemon_serviceloop() + pars= (struct daemon_slpars *) malloc ( sizeof(struct daemon_slpars) ); + if (pars == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + exit(0); + } + + pars->sockctrl= sockctrl; + pars->activeclose= 0; // useless in passive mode + pars->isactive= 0; + pars->nullAuthAllowed= nullAuthAllowed; + + // Close the main socket (must be open only in the parent) + closesocket(sockmain); + + daemon_serviceloop( (void *) pars); + exit(0); + } + + // I am the parent + // Close the childsocket (must be open only in the child) + closesocket(sockctrl); +#endif + + // loop forever, until interrupted + } +} + + + + +/*! + \brief 'true' main of the program in case the active mode is turned on. + + It does not have any return value nor parameters. + This function loops forever trying to connect to the remote host, until the + daemon is turned down. + + \param ptr: it keeps the 'activepars' parameters. It is a 'void *' just because pthreads + want this format. +*/ +void main_active(void *ptr) +{ +char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed +SOCKET sockctrl; // keeps the socket ID for this control connection +struct addrinfo hints; // temporary struct to keep settings needed to open the new socket +struct addrinfo *addrinfo; // keeps the addrinfo chain; required to open a new socket +struct active_pars *activepars; +struct daemon_slpars *pars; // parameters needed by the daemon_serviceloop() + + + activepars= (struct active_pars *) ptr; + + // Prepare to open a new server socket + memset(&hints, 0, sizeof(struct addrinfo)); + // WARNING Currently it supports only ONE socket family among IPv4 and IPv6 + hints.ai_family = AF_INET; // PF_UNSPEC to have both IPv4 and IPv6 server + hints.ai_socktype = SOCK_STREAM; + hints.ai_family= activepars->ai_family; + + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Connecting to host %s, port %s, using protocol %s", + activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4": + (hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified"); + SOCK_ASSERT(errbuf, 1); + + // Initialize errbuf + memset(errbuf, 0, sizeof(errbuf) ); + + // Do the work + if (sock_initaddress(activepars->address, activepars->port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1) + { + SOCK_ASSERT(errbuf, 1); + return; + } + + while (1) + { + int activeclose; + + if ( (sockctrl= sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == -1) + { + SOCK_ASSERT(errbuf, 1); + + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error connecting to host %s, port %s, using protocol %s", + activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4": + (hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified" ); + + SOCK_ASSERT(errbuf, 1); + + pthread_suspend(RPCAP_ACTIVE_WAIT * 1000); + + continue; + } + + pars= (struct daemon_slpars *) malloc ( sizeof(struct daemon_slpars) ); + if (pars == NULL) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno)); + continue; + } + + pars->sockctrl= sockctrl; + pars->activeclose= 0; + pars->isactive= 1; + pars->nullAuthAllowed= nullAuthAllowed; + + daemon_serviceloop( (void *) pars); + + activeclose= pars->activeclose; + + free(pars); + + // If the connection is closed by the user explicitely, don't try to connect to it again + // just exit the program + if (activeclose == 1) + break; + } +} + diff --git a/winpcap/wpcap/libpcap/rpcapd/rpcapd.dsp b/winpcap/wpcap/libpcap/rpcapd/rpcapd.dsp new file mode 100644 index 0000000..5e1b5a6 --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/rpcapd.dsp @@ -0,0 +1,219 @@ +# Microsoft Developer Studio Project File - Name="rpcapd" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=rpcapd - Win32 Debug REMOTE DAG +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "rpcapd.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "rpcapd.mak" CFG="rpcapd - Win32 Debug REMOTE DAG" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "rpcapd - Win32 Debug REMOTE" (based on "Win32 (x86) Console Application") +!MESSAGE "rpcapd - Win32 Debug REMOTE DAG" (based on "Win32 (x86) Console Application") +!MESSAGE "rpcapd - Win32 Release REMOTE" (based on "Win32 (x86) Console Application") +!MESSAGE "rpcapd - Win32 Release REMOTE DAG" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "rpcapd - Win32 Debug REMOTE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_REMOTE" +# PROP BASE Intermediate_Dir "Debug_REMOTE" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_REMOTE" +# PROP Intermediate_Dir "Debug_REMOTE" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../Win32/Include" /I "../../../Common/" /I "win32-pthreads" /D "_DEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "HAVE_REMOTE" /FR /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../Win32/Include" /I "../../../Common/" /I "win32-pthreads" /D "_DEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "HAVE_REMOTE" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 ws2_32.lib wpcap.lib pthreadVC.lib packet.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../PRJ/Debug_REMOTE/rpcapd.exe" /pdbtype:sept /libpath:"../../lib" /libpath:"../../../Common/" /libpath:"win32-pthreads" +# ADD LINK32 ws2_32.lib wpcap.lib pthreadVC.lib packet.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../PRJ/Debug_REMOTE/rpcapd.exe" /pdbtype:sept /libpath:"../../../Common/" /libpath:"win32-pthreads" /libpath:"../../lib" + +!ELSEIF "$(CFG)" == "rpcapd - Win32 Debug REMOTE DAG" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_REMOTE_DAG" +# PROP BASE Intermediate_Dir "Debug_REMOTE_DAG" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_REMOTE_DAG" +# PROP Intermediate_Dir "Debug_REMOTE_DAG" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../Win32/Include" /I "../../../Common/" /I "win32-pthreads" /D "_DEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "HAVE_REMOTE" /FR /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../" /I "../bpf/" /I "../Win32/Include" /I "../../../Common/" /I "win32-pthreads" /D "_DEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "HAVE_REMOTE" /D "HAVE_DAG_API" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 ws2_32.lib wpcap.lib pthreadVC.lib packet.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../PRJ/Debug_REMOTE_DAG/rpcapd.exe" /pdbtype:sept /libpath:"../../lib" /libpath:"../../../Common/" /libpath:"win32-pthreads" +# ADD LINK32 ws2_32.lib wpcap.lib pthreadVC.lib packet.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../PRJ/Debug_REMOTE_DAG/rpcapd.exe" /pdbtype:sept /libpath:"../../PRJ\Debug_REMOTE_DAG" /libpath:"../../../Common/" /libpath:"win32-pthreads" + +!ELSEIF "$(CFG)" == "rpcapd - Win32 Release REMOTE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_REMOTE" +# PROP BASE Intermediate_Dir "Release_REMOTE" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_REMOTE" +# PROP Intermediate_Dir "Release_REMOTE" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../Win32/Include" /I "../../../Common/" /I "win32-pthreads" /D "NDEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "HAVE_REMOTE" /YX /FD /c +# ADD CPP /nologo /W3 /GX /Zi /O2 /I "../" /I "../bpf/" /I "../Win32/Include" /I "../../../Common/" /I "win32-pthreads" /D "NDEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "HAVE_REMOTE" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 ws2_32.lib wpcap.lib pthreadVC.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"../../lib" /libpath:"../../../Common/" /libpath:"win32-pthreads" +# ADD LINK32 ws2_32.lib wpcap.lib pthreadVC.lib packet.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:"../../PRJ/Release_REMOTE/rpcapd.pdb" /debug /machine:I386 /out:"../../PRJ/Release_REMOTE/rpcapd.exe" /libpath:"../../lib" /libpath:"../../../Common/" /libpath:"win32-pthreads" /opt:ref +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "rpcapd - Win32 Release REMOTE DAG" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_REMOTE_DAG" +# PROP BASE Intermediate_Dir "Release_REMOTE_DAG" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_REMOTE_DAG" +# PROP Intermediate_Dir "Release_REMOTE_DAG" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /I "../" /I "../bpf/" /I "../Win32/Include" /I "../../../Common/" /I "win32-pthreads" /D "NDEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "HAVE_REMOTE" /YX /FD /c +# ADD CPP /nologo /W3 /GX /Zi /O2 /I "../" /I "../bpf/" /I "../Win32/Include" /I "../../../Common/" /I "win32-pthreads" /D "NDEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /D "HAVE_REMOTE" /D "HAVE_DAG_API" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 ws2_32.lib wpcap.lib pthreadVC.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"../../lib" /libpath:"../../../Common/" /libpath:"win32-pthreads" +# ADD LINK32 ws2_32.lib wpcap.lib pthreadVC.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../../PRJ/Release_REMOTE_DAG/rpcapd.exe" /libpath:"../../PRJ\Release_REMOTE_DAG" /libpath:"../../../Common/" /libpath:"win32-pthreads" + +!ENDIF + +# Begin Target + +# Name "rpcapd - Win32 Debug REMOTE" +# Name "rpcapd - Win32 Debug REMOTE DAG" +# Name "rpcapd - Win32 Release REMOTE" +# Name "rpcapd - Win32 Release REMOTE DAG" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\daemon.c +# End Source File +# Begin Source File + +SOURCE=.\fileconf.c +# End Source File +# Begin Source File + +SOURCE="..\pcap-new.c" +# End Source File +# Begin Source File + +SOURCE="..\pcap-remote.c" +# End Source File +# Begin Source File + +SOURCE=.\rpcapd.c +# End Source File +# Begin Source File + +SOURCE=..\sockutils.c +# End Source File +# Begin Source File + +SOURCE=.\utils.c +# End Source File +# Begin Source File + +SOURCE=.\version.rc +# End Source File +# Begin Source File + +SOURCE=".\win32-svc.c" +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\daemon.h +# End Source File +# Begin Source File + +SOURCE=.\fileconf.h +# End Source File +# Begin Source File + +SOURCE="..\pcap-remote.h" +# End Source File +# Begin Source File + +SOURCE=.\rpcapd.h +# End Source File +# Begin Source File + +SOURCE=..\sockutils.h +# End Source File +# Begin Source File + +SOURCE=.\utils.h +# End Source File +# Begin Source File + +SOURCE=".\win32-svc.h" +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/winpcap/wpcap/libpcap/rpcapd/rpcapd.dsw b/winpcap/wpcap/libpcap/rpcapd/rpcapd.dsw new file mode 100644 index 0000000..1c305dd --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/rpcapd.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "rpcapd"=.\rpcapd.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/winpcap/wpcap/libpcap/rpcapd/rpcapd.h b/winpcap/wpcap/libpcap/rpcapd/rpcapd.h new file mode 100644 index 0000000..33c20ae --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/rpcapd.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __RPCAPD_H__ +#define __RPCAPD_H__ + + +#define PROGRAM_NAME "rpcapd" +#define MAX_LINE 2048 /* Maximum chars allowed for the host list (in passive mode) */ +#define SOCKET_MAXCONN 10 /* Maximum number of connections queued into the accept() */ +#define MAX_HOST_LIST 64000 +#define MAX_ACTIVE_LIST 10 + + +struct active_pars +{ + char address[MAX_LINE + 1]; // keeps the network address (either numeric or literal) to of the active client + char port[MAX_LINE + 1]; // keeps the network port to bind to + int ai_family; // address faimly to use +}; + + +void main_startup(void); +void main_cleanup(int sign); + +#endif + diff --git a/winpcap/wpcap/libpcap/rpcapd/utils.c b/winpcap/wpcap/libpcap/rpcapd/utils.c new file mode 100644 index 0000000..de66214 --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/utils.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +// getopt() is not present in Win32 + +#ifdef WIN32 +#include +#include // for getc() + +int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +#ifdef WIN32 +char *__progname = "rpcapd"; +#endif + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt(nargc, nargv, ostr) + int nargc; + char * const *nargv; + const char *ostr; +{ +// WIN32 extern char *__progname; + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + int ret; + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return (-1); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++optind; + place = EMSG; + return (-1); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means -1. + */ + if (optopt == (int)'-') + return (-1); + if (!*place) + ++optind; + if (opterr && *ostr != ':' && optopt != BADCH) + (void)fprintf(stderr, + "%s: illegal option -- %c\n", __progname, optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } + else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if (*ostr == ':') + ret = BADARG; + else + ret = BADCH; + if (opterr) + (void)fprintf(stderr, + "%s: option requires an argument -- %c\n", + __progname, optopt); + return (ret); + } + else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return (optopt); /* dump back option letter */ +} + +#endif + diff --git a/winpcap/wpcap/libpcap/rpcapd/utils.h b/winpcap/wpcap/libpcap/rpcapd/utils.h new file mode 100644 index 0000000..b72c0f6 --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/utils.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __UTILS_H__ +#define __UTILS_H__ + + +// Common functions declaration + +#ifdef WIN32 + int getopt(int nargc, char * const *nargv, const char *ostr); +#endif + + +#endif + diff --git a/winpcap/wpcap/libpcap/rpcapd/version.rc b/winpcap/wpcap/libpcap/rpcapd/version.rc new file mode 100644 index 0000000..2ef755d --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/version.rc @@ -0,0 +1,64 @@ +// Microsoft Visual C++ generated resource script. +// + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#include ""version.rc2""\r\n" + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "Version.rc2" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/winpcap/wpcap/libpcap/rpcapd/version.rc2 b/winpcap/wpcap/libpcap/rpcapd/version.rc2 new file mode 100644 index 0000000..8deb99c --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/version.rc2 @@ -0,0 +1,45 @@ +// +// version.rc2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +#include "..\..\..\version.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION WINPCAP_MAJOR,WINPCAP_MINOR,WINPCAP_REV,WINPCAP_BUILD + PRODUCTVERSION WINPCAP_MAJOR,WINPCAP_MINOR,WINPCAP_REV,WINPCAP_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", WINPCAP_COMPANY_NAME + VALUE "FileDescription", "Remote Packet Capture Daemon" + VALUE "FileVersion", WINPCAP_VER_STRING + VALUE "InternalName", "rpcapd" + VALUE "LegalCopyright", WINPCAP_RPCAPD_COPYRIGHT_STRING + VALUE "LegalTrademarks", "" + VALUE "OriginalFilename", "rpcapd.exe" + VALUE "ProductName", WINPCAP_PRODUCT_NAME + VALUE "ProductVersion", WINPCAP_VER_STRING + VALUE "Build Description", WINPCAP_BUILD_DESCRIPTION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/winpcap/wpcap/libpcap/rpcapd/win32-pthreads/pthread.h b/winpcap/wpcap/libpcap/rpcapd/win32-pthreads/pthread.h new file mode 100644 index 0000000..25c3cb5 --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/win32-pthreads/pthread.h @@ -0,0 +1,1300 @@ +/* This is an implementation of the threads API of POSIX 1003.1-2001. + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2003 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#if !defined( PTHREAD_H ) +#define PTHREAD_H + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + +#ifdef _UWIN +# define HAVE_STRUCT_TIMESPEC 1 +# define HAVE_SIGNAL_H 1 +# undef HAVE_CONFIG_H +# pragma comment(lib, "pthread") +#endif + +/* + * ------------------------------------------------------------- + * + * + * Module: pthread.h + * + * Purpose: + * Provides an implementation of PThreads based upon the + * standard: + * + * POSIX 1003.1-2001 + * and + * The Single Unix Specification version 3 + * + * (these two are equivalent) + * + * in order to enhance code portability between Windows, + * various commercial Unix implementations, and Linux. + * + * See the ANNOUNCE file for a full list of conforming + * routines and defined constants, and a list of missing + * routines and constants not defined in this implementation. + * + * Authors: + * There have been many contributors to this library. + * The initial implementation was contributed by + * John Bossom, and several others have provided major + * sections or revisions of parts of the implementation. + * Often significant effort has been contributed to + * find and fix important bugs and other problems to + * improve the reliability of the library, which sometimes + * is not reflected in the amount of code which changed as + * result. + * As much as possible, the contributors are acknowledged + * in the ChangeLog file in the source code distribution + * where their changes are noted in detail. + * + * Contributors are listed in the CONTRIBUTORS file. + * + * As usual, all bouquets go to the contributors, and all + * brickbats go to the project maintainer. + * + * Maintainer: + * The code base for this project is coordinated and + * eventually pre-tested, packaged, and made available by + * + * Ross Johnson + * + * QA Testers: + * Ultimately, the library is tested in the real world by + * a host of competent and demanding scientists and + * engineers who report bugs and/or provide solutions + * which are then fixed or incorporated into subsequent + * versions of the library. Each time a bug is fixed, a + * test case is written to prove the fix and ensure + * that later changes to the code don't reintroduce the + * same error. The number of test cases is slowly growing + * and therefore so is the code reliability. + * + * Compliance: + * See the file ANNOUNCE for the list of implemented + * and not-implemented routines and defined options. + * Of course, these are all defined is this file as well. + * + * Web site: + * The source code and other information about this library + * are available from + * + * http://sources.redhat.com/pthreads-win32/ + * + * ------------------------------------------------------------- + */ + +/* Try to avoid including windows.h */ +#if defined(__MINGW32__) && defined(__cplusplus) +/* + * FIXME: The pthreadGCE.dll build gets linker unresolved errors + * on pthread_key_create() unless windows.h is included here. + * It appears to have something to do with an argument type mismatch. + * Looking at tsd.o with 'nm' shows this line: + * 00000000 T _pthread_key_create__FPP14pthread_key_t_PFPv_v + * instead of + * 00000000 T _pthread_key_create + */ +#define PTW32_INCLUDE_WINDOWS_H +#endif + +#ifdef PTW32_INCLUDE_WINDOWS_H +#include +#endif + +/* + * ----------------- + * autoconf switches + * ----------------- + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* Try to avoid including windows.h */ +#if defined(__MINGW32__) && defined(__cplusplus) +/* + * FIXME: The pthreadGCE.dll build gets linker unresolved errors + * on pthread_key_create() unless windows.h is included here. + * It appears to have something to do with an argument type mismatch. + * Looking at tsd.o with 'nm' shows this line: + * 00000000 T _pthread_key_create__FPP14pthread_key_t_PFPv_v + * instead of + * 00000000 T _pthread_key_create + */ +#define PTW32_INCLUDE_WINDOWS_H +#endif + +#ifdef PTW32_INCLUDE_WINDOWS_H +#include +#endif + +#ifndef NEED_FTIME +#include +#else /* NEED_FTIME */ +/* use native WIN32 time API */ +#endif /* NEED_FTIME */ + +#if HAVE_SIGNAL_H +#include +#endif /* HAVE_SIGNAL_H */ + +#include +#include + +/* + * Boolean values to make us independent of system includes. + */ +enum { + PTW32_FALSE = 0, + PTW32_TRUE = (! PTW32_FALSE) +}; + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#ifndef PTW32_CONFIG_H +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#ifdef NEED_ERRNO +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Several systems don't define ENOTSUP. If not, we use + * the same value as Solaris. + */ +#ifndef ENOTSUP +# define ENOTSUP 48 +#endif + +#ifndef ETIMEDOUT +# define ETIMEDOUT 10060 /* This is the value in winsock.h. */ +#endif + +#include + +/* + * To avoid including windows.h we define only those things that we + * actually need from it. I don't like the potential incompatibility that + * this creates with future versions of windows. + */ +#ifndef PTW32_INCLUDE_WINDOWS_H +#ifndef HANDLE +# define PTW32__HANDLE_DEF +# define HANDLE void * +#endif +#ifndef DWORD +# define PTW32__DWORD_DEF +# define DWORD unsigned long +#endif +#endif + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#ifndef HAVE_STRUCT_TIMESPEC +struct timespec { + long tv_sec; + long tv_nsec; +}; +#endif /* HAVE_STRUCT_TIMESPEC */ + +#ifndef SIG_BLOCK +#define SIG_BLOCK 0 +#endif /* SIG_BLOCK */ + +#ifndef SIG_UNBLOCK +#define SIG_UNBLOCK 1 +#endif /* SIG_UNBLOCK */ + +#ifndef SIG_SETMASK +#define SIG_SETMASK 2 +#endif /* SIG_SETMASK */ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* + * ------------------------------------------------------------- + * + * POSIX 1003.1-2001 Options + * ========================= + * + * _POSIX_THREADS (set) + * If set, you can use threads + * + * _POSIX_THREAD_ATTR_STACKSIZE (set) + * If set, you can control the size of a thread's + * stack + * pthread_attr_getstacksize + * pthread_attr_setstacksize + * + * _POSIX_THREAD_ATTR_STACKADDR (not set) + * If set, you can allocate and control a thread's + * stack. If not supported, the following functions + * will return ENOSYS, indicating they are not + * supported: + * pthread_attr_getstackaddr + * pthread_attr_setstackaddr + * + * _POSIX_THREAD_PRIORITY_SCHEDULING (set) + * If set, you can use realtime scheduling. + * Indicates the availability of: + * pthread_attr_getinheritsched + * pthread_attr_getschedparam + * pthread_attr_getschedpolicy + * pthread_attr_getscope + * pthread_attr_setinheritsched + * pthread_attr_setschedparam + * pthread_attr_setschedpolicy + * pthread_attr_setscope + * pthread_getschedparam + * pthread_setschedparam + * sched_get_priority_max + * sched_get_priority_min + * sched_rr_set_interval + * + * _POSIX_THREAD_PRIO_INHERIT (not set) + * If set, you can create priority inheritance + * mutexes. + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PRIO_PROTECT (not set) + * If set, you can create priority ceiling mutexes + * Indicates the availability of: + * pthread_mutex_getprioceiling + * pthread_mutex_setprioceiling + * pthread_mutexattr_getprioceiling + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprioceiling + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PROCESS_SHARED (not set) + * If set, you can create mutexes and condition + * variables that can be shared with another + * process.If set, indicates the availability + * of: + * pthread_mutexattr_getpshared + * pthread_mutexattr_setpshared + * pthread_condattr_getpshared + * pthread_condattr_setpshared + * + * _POSIX_THREAD_SAFE_FUNCTIONS (set) + * If set you can use the special *_r library + * functions that provide thread-safe behaviour + * + * _POSIX_READER_WRITER_LOCKS (set) + * If set, you can use read/write locks + * + * _POSIX_SPIN_LOCKS (set) + * If set, you can use spin locks + * + * _POSIX_BARRIERS (set) + * If set, you can use barriers + * + * + These functions provide both 'inherit' and/or + * 'protect' protocol, based upon these macro + * settings. + * + * POSIX 1003.1-2001 Limits + * =========================== + * + * PTHREAD_DESTRUCTOR_ITERATIONS + * Maximum number of attempts to destroy + * a thread's thread-specific data on + * termination (must be at least 4) + * + * PTHREAD_KEYS_MAX + * Maximum number of thread-specific data keys + * available per process (must be at least 128) + * + * PTHREAD_STACK_MIN + * Minimum supported stack size for a thread + * + * PTHREAD_THREADS_MAX + * Maximum number of threads supported per + * process (must be at least 64). + * + * _POSIX_SEM_NSEMS_MAX + * The maximum number of semaphores a process can have. + * (only defined if not already defined) + * + * _POSIX_SEM_VALUE_MAX + * The maximum value a semaphore can have. + * (only defined if not already defined) + * + * ------------------------------------------------------------- + */ + +/* + * POSIX Options + */ +#ifndef _POSIX_THREADS +#define _POSIX_THREADS +#endif + +#ifndef _POSIX_READER_WRITER_LOCKS +#define _POSIX_READER_WRITER_LOCKS +#endif + +#ifndef _POSIX_SPIN_LOCKS +#define _POSIX_SPIN_LOCKS +#endif + +#ifndef _POSIX_BARRIERS +#define _POSIX_BARRIERS +#endif + +#define _POSIX_THREAD_SAFE_FUNCTIONS +#define _POSIX_THREAD_ATTR_STACKSIZE +#define _POSIX_THREAD_PRIORITY_SCHEDULING + +#if defined( KLUDGE ) +/* + * The following are not supported + */ +#define _POSIX_THREAD_ATTR_STACKADDR +#define _POSIX_THREAD_PRIO_INHERIT +#define _POSIX_THREAD_PRIO_PROTECT +#define _POSIX_THREAD_PROCESS_SHARED + +#endif /* KLUDGE */ + +/* + * POSIX Limits + * + * PTHREAD_DESTRUCTOR_ITERATIONS + * Standard states this must be at least + * 4. + * + * PTHREAD_KEYS_MAX + * WIN32 permits only 64 TLS keys per process. + * This limitation could be worked around by + * simply simulating keys. + * + * PTHREADS_STACK_MIN + * POSIX specifies 0 which is also the value WIN32 + * interprets as allowing the system to + * set the size to that of the main thread. The + * maximum stack size in Win32 is 1Meg. WIN32 + * allocates more stack as required up to the 1Meg + * limit. + * + * PTHREAD_THREADS_MAX + * Not documented by WIN32. Wrote a test program + * that kept creating threads until it failed + * revealed this approximate number (Windows NT). + * This number is somewhat less for Windows 9x + * and is effectively less than 64. Perhaps this + * constant should be set at DLL load time. + * + */ +#define PTHREAD_DESTRUCTOR_ITERATIONS 4 +#define PTHREAD_KEYS_MAX 64 +#define PTHREAD_STACK_MIN 0 +#define PTHREAD_THREADS_MAX 2019 +#ifndef _POSIX_SEM_NSEMS_MAX +/* Not used and only an arbitrary value. */ +# define _POSIX_SEM_NSEMS_MAX 1024 +#endif +#ifndef _POSIX_SEM_VALUE_MAX +# define _POSIX_SEM_VALUE_MAX (INT_MAX/2) +#endif + +#if __GNUC__ && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the DLL code, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the DLL, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#ifdef _DLL +# ifdef PTW32_BUILD +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#endif + +#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX +# include +#else +typedef struct pthread_t_ *pthread_t; +typedef struct pthread_attr_t_ *pthread_attr_t; +typedef struct pthread_once_t_ pthread_once_t; +typedef struct pthread_key_t_ *pthread_key_t; +typedef struct pthread_mutex_t_ *pthread_mutex_t; +typedef struct pthread_mutexattr_t_ *pthread_mutexattr_t; +typedef struct pthread_cond_t_ *pthread_cond_t; +typedef struct pthread_condattr_t_ *pthread_condattr_t; +#endif +typedef struct pthread_rwlock_t_ *pthread_rwlock_t; +typedef struct pthread_rwlockattr_t_ *pthread_rwlockattr_t; +typedef struct pthread_spinlock_t_ *pthread_spinlock_t; +typedef struct pthread_barrier_t_ *pthread_barrier_t; +typedef struct pthread_barrierattr_t_ *pthread_barrierattr_t; + +/* + * ==================== + * ==================== + * POSIX Threads + * ==================== + * ==================== + */ + +enum { +/* + * pthread_attr_{get,set}detachstate + */ + PTHREAD_CREATE_JOINABLE = 0, /* Default */ + PTHREAD_CREATE_DETACHED = 1, + +/* + * pthread_attr_{get,set}inheritsched + */ + PTHREAD_INHERIT_SCHED = 0, + PTHREAD_EXPLICIT_SCHED = 1, /* Default */ + +/* + * pthread_{get,set}scope + */ + PTHREAD_SCOPE_PROCESS = 0, + PTHREAD_SCOPE_SYSTEM = 1, /* Default */ + +/* + * pthread_setcancelstate paramters + */ + PTHREAD_CANCEL_ENABLE = 0, /* Default */ + PTHREAD_CANCEL_DISABLE = 1, + +/* + * pthread_setcanceltype parameters + */ + PTHREAD_CANCEL_ASYNCHRONOUS = 0, + PTHREAD_CANCEL_DEFERRED = 1, /* Default */ + +/* + * pthread_mutexattr_{get,set}pshared + * pthread_condattr_{get,set}pshared + */ + PTHREAD_PROCESS_PRIVATE = 0, + PTHREAD_PROCESS_SHARED = 1, + +/* + * pthread_barrier_wait + */ + PTHREAD_BARRIER_SERIAL_THREAD = -1 +}; + +/* + * ==================== + * ==================== + * Cancelation + * ==================== + * ==================== + */ +#define PTHREAD_CANCELED ((void *) -1) + + +/* + * ==================== + * ==================== + * Once Key + * ==================== + * ==================== + */ +#define PTHREAD_ONCE_INIT { PTW32_FALSE, -1 } + +struct pthread_once_t_ +{ + int done; /* indicates if user function executed */ + long started; /* First thread to increment this value */ + /* to zero executes the user function */ +}; + + +/* + * ==================== + * ==================== + * Object initialisers + * ==================== + * ==================== + */ +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1) + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1) + +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1) + +#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1) + + +/* + * Mutex types. + */ +enum +{ + /* Compatibility with LinuxThreads */ + PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, + /* For compatibility with POSIX */ + PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL +}; + + +/* There are three implementations of cancel cleanup. + * Note that pthread.h is included in both application + * compilation units and also internally for the library. + * The code here and within the library aims to work + * for all reasonable combinations of environments. + * + * The three implementations are: + * + * WIN32 SEH + * C + * C++ + * + * Please note that exiting a push/pop block via + * "return", "exit", "break", or "continue" will + * lead to different behaviour amongst applications + * depending upon whether the library was built + * using SEH, C++, or C. For example, a library built + * with SEH will call the cleanup routine, while both + * C++ and C built versions will not. + */ + +/* + * Define defaults for cleanup code. + * Note: Unless the build explicitly defines one of the following, then + * we default to standard C style cleanup. This style uses setjmp/longjmp + * in the cancelation and thread exit implementations and therefore won't + * do stack unwinding if linked to applications that have it (e.g. + * C++ apps). This is currently consistent with most/all commercial Unix + * POSIX threads implementations. + */ +#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C ) +# define __CLEANUP_C +#endif + +#if defined( __CLEANUP_SEH ) && defined(__GNUC__) +#error ERROR [__FILE__, line __LINE__]: GNUC does not support SEH. +#endif + +typedef struct ptw32_cleanup_t ptw32_cleanup_t; +typedef void (__cdecl *ptw32_cleanup_callback_t)(void *); + +struct ptw32_cleanup_t +{ + ptw32_cleanup_callback_t routine; + void *arg; + struct ptw32_cleanup_t *prev; +}; + +#ifdef __CLEANUP_SEH + /* + * WIN32 SEH version of cancel cleanup. + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ + _cleanup.arg = (_arg); \ + __try \ + { \ + +#define pthread_cleanup_pop( _execute ) \ + } \ + __finally \ + { \ + if( _execute || AbnormalTermination()) \ + { \ + (*(_cleanup.routine))( _cleanup.arg ); \ + } \ + } \ + } + +#else /* __CLEANUP_SEH */ + +#ifdef __CLEANUP_C + + /* + * C implementation of PThreads cancel cleanup + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ + +#define pthread_cleanup_pop( _execute ) \ + (void) ptw32_pop_cleanup( _execute ); \ + } + +#else /* __CLEANUP_C */ + +#ifdef __CLEANUP_CXX + + /* + * C++ version of cancel cleanup. + * - John E. Bossom. + */ + + class PThreadCleanup { + /* + * PThreadCleanup + * + * Purpose + * This class is a C++ helper class that is + * used to implement pthread_cleanup_push/ + * pthread_cleanup_pop. + * The destructor of this class automatically + * pops the pushed cleanup routine regardless + * of how the code exits the scope + * (i.e. such as by an exception) + */ + ptw32_cleanup_callback_t cleanUpRout; + void * obj; + int executeIt; + + public: + PThreadCleanup() : + cleanUpRout( 0 ), + obj( 0 ), + executeIt( 0 ) + /* + * No cleanup performed + */ + { + } + + PThreadCleanup( + ptw32_cleanup_callback_t routine, + void * arg ) : + cleanUpRout( routine ), + obj( arg ), + executeIt( 1 ) + /* + * Registers a cleanup routine for 'arg' + */ + { + } + + ~PThreadCleanup() + { + if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) + { + (void) (*cleanUpRout)( obj ); + } + } + + void execute( int exec ) + { + executeIt = exec; + } + }; + + /* + * C++ implementation of PThreads cancel cleanup; + * This implementation takes advantage of a helper + * class who's destructor automatically calls the + * cleanup routine if we exit our scope weirdly + */ +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ + (void *) (_arg) ); + +#define pthread_cleanup_pop( _execute ) \ + cleanup.execute( _execute ); \ + } + +#else + +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* __CLEANUP_CXX */ + +#endif /* __CLEANUP_C */ + +#endif /* __CLEANUP_SEH */ + +/* + * =============== + * =============== + * Methods + * =============== + * =============== + */ + +/* + * PThread Attribute Functions + */ +PTW32_DLLPORT int pthread_attr_init (pthread_attr_t * attr); + +PTW32_DLLPORT int pthread_attr_destroy (pthread_attr_t * attr); + +PTW32_DLLPORT int pthread_attr_getdetachstate (const pthread_attr_t * attr, + int *detachstate); + +PTW32_DLLPORT int pthread_attr_getstackaddr (const pthread_attr_t * attr, + void **stackaddr); + +PTW32_DLLPORT int pthread_attr_getstacksize (const pthread_attr_t * attr, + size_t * stacksize); + +PTW32_DLLPORT int pthread_attr_setdetachstate (pthread_attr_t * attr, + int detachstate); + +PTW32_DLLPORT int pthread_attr_setstackaddr (pthread_attr_t * attr, + void *stackaddr); + +PTW32_DLLPORT int pthread_attr_setstacksize (pthread_attr_t * attr, + size_t stacksize); + +PTW32_DLLPORT int pthread_attr_getschedparam (const pthread_attr_t *attr, + struct sched_param *param); + +PTW32_DLLPORT int pthread_attr_setschedparam (pthread_attr_t *attr, + const struct sched_param *param); + +PTW32_DLLPORT int pthread_attr_setschedpolicy (pthread_attr_t *, + int); + +PTW32_DLLPORT int pthread_attr_getschedpolicy (pthread_attr_t *, + int *); + +PTW32_DLLPORT int pthread_attr_setinheritsched(pthread_attr_t * attr, + int inheritsched); + +PTW32_DLLPORT int pthread_attr_getinheritsched(pthread_attr_t * attr, + int * inheritsched); + +PTW32_DLLPORT int pthread_attr_setscope (pthread_attr_t *, + int); + +PTW32_DLLPORT int pthread_attr_getscope (const pthread_attr_t *, + int *); + +/* + * PThread Functions + */ +PTW32_DLLPORT int pthread_create (pthread_t * tid, + const pthread_attr_t * attr, + void *(*start) (void *), + void *arg); + +PTW32_DLLPORT int pthread_detach (pthread_t tid); + +PTW32_DLLPORT int pthread_equal (pthread_t t1, + pthread_t t2); + +PTW32_DLLPORT void pthread_exit (void *value_ptr); + +PTW32_DLLPORT int pthread_join (pthread_t thread, + void **value_ptr); + +PTW32_DLLPORT pthread_t pthread_self (void); + +PTW32_DLLPORT int pthread_cancel (pthread_t thread); + +PTW32_DLLPORT int pthread_setcancelstate (int state, + int *oldstate); + +PTW32_DLLPORT int pthread_setcanceltype (int type, + int *oldtype); + +PTW32_DLLPORT void pthread_testcancel (void); + +PTW32_DLLPORT int pthread_once (pthread_once_t * once_control, + void (*init_routine) (void)); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +PTW32_DLLPORT ptw32_cleanup_t *ptw32_pop_cleanup (int execute); + +PTW32_DLLPORT void ptw32_push_cleanup (ptw32_cleanup_t * cleanup, + void (*routine) (void *), + void *arg); +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread Specific Data Functions + */ +PTW32_DLLPORT int pthread_key_create (pthread_key_t * key, + void (*destructor) (void *)); + +PTW32_DLLPORT int pthread_key_delete (pthread_key_t key); + +PTW32_DLLPORT int pthread_setspecific (pthread_key_t key, + const void *value); + +PTW32_DLLPORT void *pthread_getspecific (pthread_key_t key); + + +/* + * Mutex Attribute Functions + */ +PTW32_DLLPORT int pthread_mutexattr_init (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int pthread_mutexattr_destroy (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int pthread_mutexattr_getpshared (const pthread_mutexattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, + int pshared); + +PTW32_DLLPORT int pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); +PTW32_DLLPORT int pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind); + +/* + * Barrier Attribute Functions + */ +PTW32_DLLPORT int pthread_barrierattr_init (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int pthread_barrierattr_destroy (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int pthread_barrierattr_getpshared (const pthread_barrierattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, + int pshared); + +/* + * Mutex Functions + */ +PTW32_DLLPORT int pthread_mutex_init (pthread_mutex_t * mutex, + const pthread_mutexattr_t * attr); + +PTW32_DLLPORT int pthread_mutex_destroy (pthread_mutex_t * mutex); + +PTW32_DLLPORT int pthread_mutex_lock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int pthread_mutex_timedlock(pthread_mutex_t *mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int pthread_mutex_trylock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int pthread_mutex_unlock (pthread_mutex_t * mutex); + +/* + * Spinlock Functions + */ +PTW32_DLLPORT int pthread_spin_init (pthread_spinlock_t * lock, int pshared); + +PTW32_DLLPORT int pthread_spin_destroy (pthread_spinlock_t * lock); + +PTW32_DLLPORT int pthread_spin_lock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int pthread_spin_trylock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int pthread_spin_unlock (pthread_spinlock_t * lock); + +/* + * Barrier Functions + */ +PTW32_DLLPORT int pthread_barrier_init (pthread_barrier_t * barrier, + const pthread_barrierattr_t * attr, + unsigned int count); + +PTW32_DLLPORT int pthread_barrier_destroy (pthread_barrier_t * barrier); + +PTW32_DLLPORT int pthread_barrier_wait (pthread_barrier_t * barrier); + +/* + * Condition Variable Attribute Functions + */ +PTW32_DLLPORT int pthread_condattr_init (pthread_condattr_t * attr); + +PTW32_DLLPORT int pthread_condattr_destroy (pthread_condattr_t * attr); + +PTW32_DLLPORT int pthread_condattr_getpshared (const pthread_condattr_t * attr, + int *pshared); + +PTW32_DLLPORT int pthread_condattr_setpshared (pthread_condattr_t * attr, + int pshared); + +/* + * Condition Variable Functions + */ +PTW32_DLLPORT int pthread_cond_init (pthread_cond_t * cond, + const pthread_condattr_t * attr); + +PTW32_DLLPORT int pthread_cond_destroy (pthread_cond_t * cond); + +PTW32_DLLPORT int pthread_cond_wait (pthread_cond_t * cond, + pthread_mutex_t * mutex); + +PTW32_DLLPORT int pthread_cond_timedwait (pthread_cond_t * cond, + pthread_mutex_t * mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int pthread_cond_signal (pthread_cond_t * cond); + +PTW32_DLLPORT int pthread_cond_broadcast (pthread_cond_t * cond); + +/* + * Scheduling + */ +PTW32_DLLPORT int pthread_setschedparam (pthread_t thread, + int policy, + const struct sched_param *param); + +PTW32_DLLPORT int pthread_getschedparam (pthread_t thread, + int *policy, + struct sched_param *param); + +PTW32_DLLPORT int pthread_setconcurrency (int); + +PTW32_DLLPORT int pthread_getconcurrency (void); + +/* + * Read-Write Lock Functions + */ +PTW32_DLLPORT int pthread_rwlock_init(pthread_rwlock_t *lock, + const pthread_rwlockattr_t *attr); + +PTW32_DLLPORT int pthread_rwlock_destroy(pthread_rwlock_t *lock); + +PTW32_DLLPORT int pthread_rwlock_tryrdlock(pthread_rwlock_t *); + +PTW32_DLLPORT int pthread_rwlock_trywrlock(pthread_rwlock_t *); + +PTW32_DLLPORT int pthread_rwlock_rdlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int pthread_rwlock_wrlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int pthread_rwlock_unlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int pthread_rwlockattr_init (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, + int *pshared); + +PTW32_DLLPORT int pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, + int pshared); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 + +/* + * Signal Functions. Should be defined in but MSVC and MinGW32 + * already have signal.h that don't define these. + */ +PTW32_DLLPORT int pthread_kill(pthread_t thread, int sig); + +/* + * Non-portable functions + */ + +/* + * Compatibility with Linux. + */ +PTW32_DLLPORT int pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, + int kind); +PTW32_DLLPORT int pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, + int *kind); + +/* + * Possibly supported by other POSIX threads implementations + */ +PTW32_DLLPORT int pthread_delay_np (struct timespec * interval); +PTW32_DLLPORT int pthread_num_processors_np(void); + +/* + * Useful if an application wants to statically link + * the lib rather than load the DLL at run-time. + */ +PTW32_DLLPORT int pthread_win32_process_attach_np(void); +PTW32_DLLPORT int pthread_win32_process_detach_np(void); +PTW32_DLLPORT int pthread_win32_thread_attach_np(void); +PTW32_DLLPORT int pthread_win32_thread_detach_np(void); + +/* + * Register a system time change with the library. + * Causes the library to perform various functions + * in response to the change. Should be called whenever + * the application's top level window receives a + * WM_TIMECHANGE message. It can be passed directly to + * pthread_create() as a new thread if desired. + */ +PTW32_DLLPORT void * pthread_timechange_handler_np(void *); + +#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* + * Returns the Win32 HANDLE for the POSIX thread. + */ +PTW32_DLLPORT HANDLE pthread_getw32threadhandle_np(pthread_t thread); + + +/* + * Protected Methods + * + * This function blocks until the given WIN32 handle + * is signaled or pthread_cancel had been called. + * This function allows the caller to hook into the + * PThreads cancel mechanism. It is implemented using + * + * WaitForMultipleObjects + * + * on 'waitHandle' and a manually reset WIN32 Event + * used to implement pthread_cancel. The 'timeout' + * argument to TimedWait is simply passed to + * WaitForMultipleObjects. + */ +PTW32_DLLPORT int pthreadCancelableWait (HANDLE waitHandle); +PTW32_DLLPORT int pthreadCancelableTimedWait (HANDLE waitHandle, + DWORD timeout); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread-Safe C Runtime Library Mappings. + */ +#ifndef _UWIN +# if defined(NEED_ERRNO) + PTW32_DLLPORT int * _errno( void ); +# else +# ifndef errno +# if (defined(_MT) || defined(_DLL)) + __declspec(dllimport) extern int * __cdecl _errno(void); +# define errno (*_errno()) +# endif +# endif +# endif +#endif + +/* + * WIN32 C runtime library had been made thread-safe + * without affecting the user interface. Provide + * mappings from the UNIX thread-safe versions to + * the standard C runtime library calls. + * Only provide function mappings for functions that + * actually exist on WIN32. + */ + +#if !defined(__MINGW32__) +#define strtok_r( _s, _sep, _lasts ) \ + ( *(_lasts) = strtok( (_s), (_sep) ) ) +#endif /* !__MINGW32__ */ + +#define asctime_r( _tm, _buf ) \ + ( strcpy( (_buf), asctime( (_tm) ) ), \ + (_buf) ) + +#define ctime_r( _clock, _buf ) \ + ( strcpy( (_buf), ctime( (_clock) ) ), \ + (_buf) ) + +#define gmtime_r( _clock, _result ) \ + ( *(_result) = *gmtime( (_clock) ), \ + (_result) ) + +#define localtime_r( _clock, _result ) \ + ( *(_result) = *localtime( (_clock) ), \ + (_result) ) + +#define rand_r( _seed ) \ + ( _seed == _seed? rand() : rand() ) + + +#ifdef __cplusplus + +/* + * Internal exceptions + */ +class ptw32_exception {}; +class ptw32_exception_cancel : public ptw32_exception {}; +class ptw32_exception_exit : public ptw32_exception {}; + +#endif + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* FIXME: This is only required if the library was built using SEH */ +/* + * Get internal SEH tag + */ +PTW32_DLLPORT DWORD ptw32_get_exception_services_code(void); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#ifndef PTW32_BUILD + +#ifdef __CLEANUP_SEH + +/* + * Redefine the SEH __except keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#define __except( E ) \ + __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ + ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) + +#endif /* __CLEANUP_SEH */ + +#ifdef __CLEANUP_CXX + +/* + * Redefine the C++ catch keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#ifdef _MSC_VER + /* + * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' + * if you want Pthread-Win32 cancelation and pthread_exit to work. + */ + +#ifndef PtW32NoCatchWarn + +#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") +#pragma message("------------------------------------------------------------------") +#pragma message("When compiling applications with MSVC++ and C++ exception handling:") +#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads") +#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") +#pragma message(" cancelation and pthread_exit to work. For example:") +#pragma message("") +#pragma message(" #ifdef PtW32CatchAll") +#pragma message(" PtW32CatchAll") +#pragma message(" #else") +#pragma message(" catch(...)") +#pragma message(" #endif") +#pragma message(" {") +#pragma message(" /* Catchall block processing */") +#pragma message(" }") +#pragma message("------------------------------------------------------------------") + +#endif + +#define PtW32CatchAll \ + catch( ptw32_exception & ) { throw; } \ + catch( ... ) + +#else /* _MSC_VER */ + +#define catch( E ) \ + catch( ptw32_exception & ) { throw; } \ + catch( E ) + +#endif /* _MSC_VER */ + +#endif /* __CLEANUP_CXX */ + +#endif /* ! PTW32_BUILD */ + +#ifdef __cplusplus +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#ifdef PTW32__HANDLE_DEF +# undef HANDLE +#endif +#ifdef PTW32__DWORD_DEF +# undef DWORD +#endif + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* PTHREAD_H */ diff --git a/winpcap/wpcap/libpcap/rpcapd/win32-pthreads/pthreadVC.dll b/winpcap/wpcap/libpcap/rpcapd/win32-pthreads/pthreadVC.dll new file mode 100644 index 0000000000000000000000000000000000000000..2953ab11d97511342a2f437e4126117b8bb9bc2d GIT binary patch literal 53299 zcwX&&4SZC^wfJnZgatO)1rrDmB+{TLh?{J(N!WaVBumg3H!Rr|fh-|eNMcB0axWhW z0lG=`_PVWoRjX}n#jjecK2WT@r$WLa5v7W#n1WUGfgKFkSP>%ivG1I@_ilDK8x~9Z z@BjVYo*!rKz4LkI%$YOi%*=+HZoQYp5<=8~J|7`Fhy=4qWHDNA60R7f ziX)^MGe~hS)j*&J+{8Zh>|HPM0YQ1PPU@xC7&)u-t@p>{!?2l<$}#Y=)!#&T=p41*WzkuswU(HWNfFLuX9ko>q!)% z5QQj2Aqr85LKLD9g(yVfp91?4PMiU6?8NA6A^7DD5R97-K}Hb-tBeplSOS3&JoXd6 zx*CGt-ULCS4uX$!A$S9Pwi8)42o7MD-f<9omIy)DcnChc8G@gUgy0~yacU+6J(&=^ zFbsm7DOlg-5ENlUK1@9~0RkS}&J#y5%MmR5BvLg8T>BF#(;=8=fnW?~nS@#HF2wq< z`by05+er}YxdwubNZ(m6nhz;1wjt-uhj&> z7vF=R4ujKJOJNxVPv>EM*g*sK=xKY6!}aDlO8IjkUxeoAOg3$iV^l=?Ga^qY#DvJ>U@6r)fHT z{O}zxgNV~xpW;h8`aIFQ_ozEMAy&&`{{wgSx>29tLn}Sl?wwGQD3m03lP`RodxYV} zPN(!99IVnU@@t`+pgPH#8C{>Tkom|nTQ|N3SSeNZucYTf;+fw+W9VU89W7`nb4 z(;(+1q|5Z!2GbKKE=~Uy$o45q%b#xrjwcmr%us$uh!>4QC1n>39 z^(tS|RuB!b&%H;}afYjbx)Y&KBSiwCS|q(Oz>GGvP~d6P*AuHluxPt2Op56i#sL^Y zKFumxw4Sm=YdO8g9~mbYot2Bd4*Ju6#wojB2%VK|QY`ku%UJeuq5ek#TZPz=rnPsR za&SvTo4w9?psn9&1N!OW{%y4Wk0Y3oV3jd~f? zTCrQ;2}^(=47HKz#nG~Nbn4oFgWNZCoYA#E3~v>lMvcQRZXmv-L?8edHc7OoVJ--9 ztCy8nJw-e9R+)7gv9EW&jcz>ybeCkljAL$olON+LO-lqqUpd3_z;MMFk9ZdD)Gwfu zSd?1q>o~HQ(*XfEbo8fk#xwi`ri~oa-!8B4B`te`=#2->{kr>i-yr_gDehfb=?$FN zk@^=3_Ih=_%6LYSD@GWvgNdd24;=GKAx7--!aUJPx=B!pdqWgRXnl}bZ8x6j*vE|( zRnSYlRY>;_8kP>xLW9Z!|DjkClV}|_4OI;np=p?U(uBHj`%?KSB9=>Gvk?^*c1uus znYQU>$2M|hq2=ukdge5YTpvj0oiO{f9X@WD+o$3iZJx>*Hu^OVYf)OVq)dj1Wd;G3 z6QRw(7l@WjXeL{<=QtMll2RlwnI>9tx-D8fVX}5x4A`_UDH+miv;f+vkD*se18t)- zPcu0%b}n{SdYv+#Lg|YHHaj&9(7z;2>;9XHQ+FKU8y%ju84j8iN`I!H5iJIx5@|O> zKBV7v5%fD~+gFVK6<;&@9klT)nSN9ximr%6Zzur&SAT`{GivYpT2k9*xJ-AOLB-7k zYG88ssk_`E(ELOZro(?_6*&C@7peWtCl7!rY!|nu^}w^9*y#hTTN;50 zmaZca+M(}4wa|P#(~Omy_h1>Xt-@io)5DM*Bt`7E(S0}&mQ1E#Uqvc)9siD6#bUsU z9*5W5My<~C9K3*(U2PK@wMsvxNc|XjS{W^kbLnEGA+b&E@Ff|51@*)s@ghG4it(HW z)&r=;>X7T{E=o&L!Q$^rngN+m1$DQl?S}-zWTG#JveTF(ZvT>T3BJ>CbpZ_&&>GOV zApwK}WFl4Kx>{&RgHml$sgUgV216u%Un&5Tjsve24K==7te`OMR{D7#3Y8>FSEE{B z>Lm`s5n`FT+;;$bV%M}&uwZtF5GRzW#UxfItpy4Mi$)=c zXDw(W)o-uuM2!y$x@Q{<4d_ErnK*brF$~eLojCnM;xC5& zi(C)Q465_e&ROU3TRLI&uV`qUr`&3snQqz%mEY1G%N92G)=(53-fjcWR28;l$2 zOZpJY=JXbMD#5O)2ZQMIzYI>D1cnis2y^-*(+CzIZncg6@e4K|E9ikQLQFVVkA3{S z+SyN{G@u-HTau9nV*D*2AVOKn7JNb*u|jk5mW3FXCB=YUn1$bRStd!)BY$U%zTT%U zI3AY@<+cht`fSO@GsaWKBe2wh?$NdX1jbMtj&|Bz@CFk?*PaD00bLZc!LGE?&XbDa zpCI#(*@uf@7!oV!u2U=(bbB)7xXecHImr}m3R^QU8@LH&YI9ec!A6_?RcYm_G(u@w zas}m2Dz)feMkn#a{Ser?ha-#WTxdef|4?x;IgRfFQ7cUX`paA;U3(w)Iu51lGs2{c zpJ1mm{iBR)#|U@7Ue|$3sb~Uc%RwEVhY>XQo>Xv>9dm>PnlWVh`ZNQq%*o}Rg=uR?XuYH_JXSOOEFEzvbj^bvnvEyz5QEhm;ykCoj- z%4xTM&~djSS%?Xl9shX#O4~HNviATp!HQ8Z8OHoKTS+4CU*O!KiEQdpI@SjAa^_QTsR}n$0$P{hwvK99(!HJcfBj71=Qx??pqI}`k*Jdv<7h)_yqF*l zlAWR#+K{Kp z;&ArQr2^x>%1ZA$&l(@Z|8ijdu2Imw@d*95KTD3DuKg9{uw`1k7S|wYLsRaIuKf{A zD@{uQKBwZ`OX)Zz7=;_vf=$C+Cl;ffHBDTr5oc=!ODcSeC3;+j#FE60eY~F1_eNev-X|Q-~n0%i&pr-CW0k$5NHRLZYVL}TQ`}hh20}RIPFT^A zYGY%rmA#C!A5Zixb^rNmclRjHXs1QeAcCcGgd1m*7A%~1II!J9I&gatlN7PrDP*t@ zbaf2ySs65;!twM{04>lRC@Ai4V%J>lOY`iXPV{swFlD!v(4WfBd*$cd@T5lRL-f50 zS)TxW7Vt&Di=l5zDY^#^E6qIyd|#iYmz@@VB=GG$X%(+m32lk=i{tVXx}d(c*KP{* zAEd=ANu13VBCyU6KrAZLjo>n%i^{Sq3q2n%sS_sfd<>fW;b;y78?L5W2N($!pgs{S z(*iLL?6yvRtjD5;28$#gGQsyjcO3Fnno{lp!hbF1zqbv2THgoo$(@x_LUtV^weRQO zH=p_)K7KV_c}(6DSuD1#XX81l-zK!J2a)$B<)N%ivO-uN<7rc);q4IOeD4Car4VUl zZzYWG#e9OD8jne`+6lZDb>$Kh1~p{Ft5?;N zZVS3c@JN*&2I-N>6t885U`g{O&1QTREIE9dSroR(w(J$945$l z6?eI4(XfQaFh<@2A8>^Ib0W|)4&UEUa0Ir8e(@Eki#x@0U;Sor0Wen~Aj zFHk?z_r9UmTlYyke9(f@XH0|nOYKKxSsu@JlK2UtB?mYNxj5Y}yc6H60fUhpTA>C7 zvrT+dh^j+h17#$AQZB$tDgrN-V@(YH_0)SLk}; zvET^;ST@}jCI$2fHX68zFvdL{NBI$q3~*W!kR zt{s2MAvy7TiR{FGUlMXH`axEj`jKCU>pC8mCh(cGLUuVl`ypgnIIvJ& z>)x$jK==QN`8T*+x;t?jYMEqEXv+gmBS1Y18P%f2PISQ&jK z7b_PKsq7g2!}wLN3EGb{?+w2nXAqjzVUA}8>zn`O=QBvZu@lOU6GuRZlS9*SaQz7P zxtNV=p&d)JS@pCKgLe4`Otq} z$;G09V6yv-o)qwc*uvehPq3)DVN^Vfd%{|@V!?Ak(=3;+fjB&&wbCCSQ5=x(*`;$w zcbi7VYr)5v4dq#>UHHQ-_Qo8fn+Q|SP~<*kyO1UN#WJ)%kw6}=F(Rq=iJEf%$&1P> z)!$99Vp#8ou+J)(J!m|I{JLAE@T*Pb=hr#tu1JyQQ(SB%C`XgcF~G4YK^)VyoALCe z;*UO`6WF#`d<_dQzU9-xKPr5499H;tRUqFIfN##(i;;6!?p5TRQ?7$;0P@;b#}34K z+VoZjEmg5K(M^f2{b@)n;chSCbTV(JDOthcmDGjfRa`{rq8_&VK^N_OqC|pCwgsdT z$}#f#BnM6I@o#-7^#*4SsGj;hkj2aG^YL1_d#q8pOoxw8IkERVuGYb_Ho1q%np|h4 zycUHU^M59|Pim$8TwDM=gzYY-fYu%lB4ibZ2a4D-+>O$DVJXm{qk@bnQ}1wpG;!|c zuGB5VQO?hP!me>>x;`J{QE&2Sg}|`ulUR>>H{KGN-nIEt{4wS9-Rpkg+<_(%t64fU z8|7qdVlja-?F5P{2W^-{>R%|Z{SxC5yVZ1BFt;Vk0nPaw@t&301+;M;pDIPv?U6a=u4wm*!|*^%(kZXz8@-4$qref zSXD2x{;}84I~|ew6AA*5pdRIfax$vEKzst{$z6_bZ-R}&d@3#lT(-&IxMbT4kXJ=4~1I7*;ne(dVrhueg4#TUq(q5o~ z`DSR-i*u5t9Q;Rt=U00x(RFnn9rc~|)8+X%n%S?THs|0yPCgcGSE)Cl`4#@i8!q*v zwv@>TMze`wen-*NW307!wok8CVnDB@!@FI~LYGR~I5;Hv7Kfys9Foq}4%MbgUxYna zn-_VXOQuiP{tOVq#t_=Q4CG82$L?XJvh1>Z2U40vNwdmnftx677XxkbWQUl~yu@Z$ zem_9Ha31^%zRwx3MJQ&WTP2gNbfPn;gK~GJ&P#kFWWd9S)W1-u5Kn>$Ar@=w4y$MY zMJQS|0{^XW(`liiUvgxmEkG;1>>YHGwQTctZyxSIKQsmA@P=>QdlF%|MvFJ~m-{MC zL(hbHiDF-`wuFl-alhs3jTP4S|qt@O0caM#u3Mja5c{U`A&4_H*Tub!X} zzRld;g<_VPQ3WIJbV?`a=2qa)E93V2*! zpBTD_F%qw1O1DVC_Dc~P(vqbu453l&acYD%jg9`|ZN^afEPlM5{#fEYlfk02RH#Y1 z@;Ogy6D)dRjh249Us6`5z!UXsB6wV+6<)*_+}eQUN65eum(m~QKFj6I&EUte^Ccc^ ztS{g4QwNj{dB2R^=fz>H7GFTZpsGbMn$Nu@t6AP6w&DGa2@X1MzoL5M#f|7b#!2%| z#BDaV(_68KX6)9)~l%M50b~zoo546^Y!PY(~ije zmhWfhz3K0}onEJW@Lxq-Z$o#$L(@TDl$S3MZ_*lT{lu zS;LffpVZ)zoc_eP_Q#C8h(Fr@_uE1GBt1+4A`Fxj=!k(kpH43(Nm^A+f&YVba5-1&`0*6 zjQxBcYx2VTLAamP$p`*Wzy=mAH`bj)V4*Ed)9=C*Jh@9>Th z?6&BoheTD`oBk_Le2%A5ZM9KzKvas=W6@aY#(e`9qpq=0izH8Wn*XMvv*qJOdHYjt z70EFA#O`iO@~6)}qmv>d$j5gD<`067G#)YfjHhtno~lxg(I={ySEy@$3%a_wjS->i z7zVL+y5S9ZPUt$mfmBbM+Cl5y@Sj<8ppm}lmOL)6q$VvOo*P$z@({}s&0QO-9rC3w zx>wHEgK9}fUkWNlpX&BE#QarYlE_6)y5V2u&^LN_mc16DU zRzLb_i8Eb+c6Eu*8)E} zI@@%>Q<)pnUkA>DUWC{i&-Q>VnP|s*^R<e_Squa9*F>Fc^(5mZsht{_#EyDLZ)U9;=|oxVQk=f~><{CIy?Fh8CTo-Ds&%IIz- zldj|6aGv0}a{>Lj%ucIz4zR6T;swgc{0q&KY#Y61rz{>FK0B8{C+-a34vpXGZ-O7@ z-~EQF!D3~bQDN8?i64;w<=;x*dsX4ez>iur()ODnvb|xY_bKK1u~-u7NpSbatR5km zO@Wq6XnFbfur^xmuOdUfSayw=ZKV%M(dNGO6YB}BRlYXHi?O24St*q0ai$JjA`7iQ z6qMgTzoN8unaHld$-k%8v!4J5*l0tPe@rPK`S;U_7rc+9{Qh|edJ->+9^CtS`xRNY z^XXCz>(gKeHcn%Me$FM2Yh;m0IL%H=4E+Abobz)mxI2h zL~LB=KL2H#&VBy;hLPQ{GMopc(mTd|Ubi9MeLkiQ?=U6eQ61hFu~m4Q(kkfMSN*z% z&je~y#GBRDa$nN7+t@)yQUyEMqR0PJ)Rb^&$8lT>eYo;dd*q>~H1y zlKOy)<~}aNUQcTAZ>#!}PD^}E^(FOhWA6GF!_Iy*@r?Vk7>m@1V8BCCMYcyPEl-nL zuJjH*019pYV(C$T7kUDkjnrN}kI#1khCAo%pjK`uhaC@l(K`&@%orwZ zWPtDj+4w63D>iYGQ7**sm+eX!R0-&^gy0yIDBQkGzvTS~>An@TFj33~wkAopn8Y}% zFGq@8XX*)*^^j{h+wsrOQj-S$A z8f))zkyz>Omwf)8dQQIhmM*S6w710uSbt90`LRLuRYHZ#3bi52({PP;zv=6Bg4L@x z9#L*E=s>=4*U9|W`eM-`ALH)E>kMZ<^{54p_V*!o8Kheb)4OmZX7eX_i^1HrdL(@J zxc}zkRX2(i#3sgA>H9A+eT3(|&c(`944?`u)-di!#QsJCc|TzsWB+Iz?s^sUl}a;J zAF7Kk=I>{yrGbPnS=!%d(__8m7gcSz`tW?6o6F4ieEIHWmKYZzn8RVZ4aaL(WAS2P zdA(|Z)Ew%z*^q*gGI*XuZX7Z!_e`;e9-qiu;F8xJzw2&$pKv%*-&aBgVO{lJ%;y)HzI12 zJxz*cr&ax`wnV|AmVPkc{~I6B9R6&MR&O6Li@%3IvjQrTJ!N1S2ova}7Y97}xb8T- zuHbq8Ek{u$`K50~zHdFx~9RdTx}TyF_Cx`ZFY+InKE+}5C9t4D56>Hj>| z|2azkw<-P44C;RgH<7hFp0%64P3fbawHc=Qi)$b4(~q|*_Gz+cNo9XR#@yvUqyc4D zmRcEReEsEr?JvKU9{YFp=PrgzSLeJAyOn;WBy%GNuAsWxQdRs&<+KN{8-W}fw+>9t zsfvXxmNCQq7}Mumf}Iv^^?SPBU9n09k^378c1Jx3l+hQgXcCw~#Z(R2RKBF6+t@`k zFvwEuyMk`SOE!-XBXvL`Hwmwt!8*`w(Xc~ngOrGu(edc$yVys}pRF*SGXF{XqfWWE zX*oykZE9|TXRgLdAK0o0%Jp`!Rcrp5yVhZ+oBXj8#5TQMXw(RedV2m@JfS=Btfb`6 zn!o1Xcd|;3KP$+gJg6 zeKdXXStc&yDw(`2_F8Gfvq}eIM6YyPa53<;2*jXcAD7>8gv%B0Ms{@U!`~iqV{>oU zaPi`Nt@O?J_2O-~B)b(=yOnlzzOXJR8=#k&CO;01X0 z%WknRNegY*#U5Xh9$p|@>I;g(9GZW=srX||-_&C)+{(faS=htE_gHv1CMLm084ngc#$hA~aqkLuD%pZx zwdyT+P3IA!f2;;R>F1cA)w*a=Z$7k<%d)|c7{qwYVfWnrt+}sdjF^DOOTKqlvil2l z@8?!obf#hqSyWlCx@EVPREQ^S;!=%WW0E%u@!Za36W8n-I8d#Vqjr%q> z;w*fRg+(mBgoULnw6ZXdg|k_B3k#R9a2X31vap7QIV{w$P|ZTZ!f#pq{VY7q!af$B zWFckYF%}+W;fE~Lv$81d;buq_q7a2BL?H@Mh(Z*i5QQj2Aqr9W7XXPu6rvD?C`2I& zQHa9-ZrIzovJjtmdTLZ64-A?8|2!!C+TTIge{|I%<1L#BNp%xK+X)#nhL91X3BkYD zwifVyc+Y}31K_>z{vQzc0N`r){slZg0h|MP9MVLWu8GyfnwA%q60z3-e>44Wl`ZT}~01v_UD!`uut^sTTybf@l$HV(_cxJ%!$MC!pa6OcH z0Z;?)j{#1B_j8b549^K!yP=fG)sxz$XEB0KN(MDd0DN+8+}#8E`sa7T_GfGC&95GQc{(I{^j2 z`vD*MG0s*M=(kv+Cc{V^8BR201Q|(25iN-)2}DQqWHcE=E+dH~iHs%VNHQ5uCXk6F zg-jxslgT8NTtTLg?~ybzm0U@#BGbs#d9@Sfvh5pq=__>+etH5+v2LKvCo}Z z)6k%N&8=#zb~RKjZ*VQFTji>8RMl~VlLBL%RUFsitZ}t+Elul!BUie(8W&epUE9i4 zajrpWb&a*ImO8Gry4F=QD3QfBSG82F8X~Ewp{{yxd#%+?&4XKl_N#BJs;OxSpVC@) zM@X5v#?TJ7UZ5|n7wSvv(0ysWKwnzJ_N8^mzO;tx%krw0mO9tq(NW@qx~W92sTv#^ zc8mklfR)XywN)(vy$?(d*N{SXXt`=8W&@v1jZmbesj8;Bs+9|l4yA}i2DQavTI*Ie zR)y5ap>zjzl|>JV3EOjjLYQv*(+1HoWQQRP5UCoNW9yua%>fZ8cm7Y;?R-FITx$bb z0dkKgqYx4G7ZQjSqT zy(=)PZa}p-SMi){?I31Ku|eFDq8gg2ZwrZHqZTf{WnGw9zHxA5*zp`l0S4Sw2XYY5 z>!8HYu?tG%)&` zi1x(+tp-i7(&d!&K}(=`t*L7?W+k#Ovq0=QjHaK1W7^=AZ5m*{@6b>mUziL-A zSJ%`C3~O0k2d#jjt#QdYnwy%P)eWwyMqVk?%(vG1qZr#+HO(z`O|W>cbFQjd8#Wr$ zosZ+#(Bt>K}GkWI~ik@5vXl>h%){{JLqRaFD{&V*FPtY~q8$2>cxT8??0I9)9* zjZp2A#JSwHvaV6O3guc$$ZL?+STpe5N1QA0au6X;sqjit{i<22R{N}LT zJoiR$<*|ZiRRNxVk*m7JwaV29ZA_0@-~tkgSF^9TV(_-OrK!bM*SNC5b@TFiS2agm zF*bjW8JM46yGq>s5x(85~Cvr;v0P~3wtHomnP*dQ0|QkA-@R=ei5)Nysd zLmRYH*VIVJ3Q~-84vMcEsM9K6^&$_%*cx1}X0kP~Z}S`deXAx#d~*X-!?{Y>eK_(B zfm-IWYki#3gR=o~R_XQ|IX5WZe8`zj=CbwAfF1iZj!HkN&IRh79@%6R+TnY)yV14`V%n=8(M++ zc6K{$BAJWV*W`W{Dy5<1oE0lja@O5c)p{EtcMXh}pN|tTcWG5CSKQLl)I!K#R5!y& zDZJ<(%pYLJJee0Z*Q%=K+NKs4P;@28MuV%Wbs!S-4c1)@(m1!NMiH7vk@7jxym<`Y zvE$@+q%44n$1!D|(m(&c6q^lEh(Z*i5QQj2Aqr6l3wlEG;K60ZnXbqYbFRpJG&gnD zx><*2?K2-Y3wclEU6p@LfwAD0f|UhL1se+f*NHy<#+ zXYMhp@+Rdi$h$SKId5~`U3s76ozI(-&*k5d|Kt3J@?Xr~neQyvT<~JSmjxMxIfVs< zHx^n8mlm!lY%F}V@TtOA3cCv5C_GR|3~XzIEH#LR<>~e5KS;kP{a5Lar^jW~0=GLz* z$QWbXYOKm^&wMs>Z|0*}zs-s{;1d_G8&EW`B@Pv(IJUma``3hdGCG zXwJEu1-Ui3+jEcP-Y~0s);qH`+k0E zL1w}Hf}0B#6}SqT3+^oVyx?3xOX24zU(3L^hsPI&8`4*%-;rLPQJ1kTBgfcb^ca6> zd;&)1ps~mJk@1-Eb7P3UO%sm!#{bgOBZX@#l5)M8p|YBRN)erO6i z&!P~8C`2I&QHVkmq7a2BMB!fyW!I-0@QHuZ4)6ZDW-YNUELl)Ir^vQM{<96O%8PyO K%;uWqj}YEB2D2k#io)C(jvOrm&2t`j(77>d)7EzQ%7Fi(W)%5M2sj9wJGeeJg zi)ZP0x^La8({;P5y87PRE4C$y$%!4U>z1p38`j4*Zi;nnh{aU-djB`JrK^jM###aV z2Z-GSw)_liT@376OV~c@;|Id7YlNN{p$~+fF9?0_5_aAo^nOg(lO<%Y5~j0+zCQ_j zejyZ26B6x&u}=v(ANvLfdq;fSBJBH)aO@;u_%A}@GQqh<*xyGOxJDTIl#pp9jNc^; zjuSHP5e{4<^p6q_P5QV)=)X-EzDzi$ZaEx+#wwNi;!PTIQW5&Hp2cd35N#> z=|zNzRzms;;k=I{t%TD{35k1zBNqtU?)u0PPJBZ+_C4YFw}g|Q5l*cloY+AanIz;t zB%JIZ9N$YA{E=|@I^onOg!65Lqc;dcorH;x2&eD)xJ-zDP8j`~5MNIiTSYii@bN2Q zw1;qZjBxHI;p|U@b3=sQHp0$6!tSet%x60exJ}5eCFK7gByagROGxb|II9V%uLuJjgrg&6#N!7J4;~pBiTCXp?j1TXIC5kt zUMNizokZ$*FXHimWBvVM6}(^3A&rs!#|93?`*w}&5_K}ug?P|NJW(nYW|xY1Zc|;iR^6a+ zH}fvjYpKY>%hYvi)h#!k%ojLL5*zrKI-syjzM-&tyxPLe>E% zV*A5P*l>xtrpb!7SuCrFQB-gz5=AG)HzAjsTXAc&;u>3-o+&w(;xoByJ~;)0l&it% zbJ~?VTAD3zH=4w1osuvcm4cP2+PWsM<-9YKkd*vWRc9)bl~m{~(73pKSt*}OX~SF+g>{)}p@|K3LK7lf zVyMYY1-8&opPK}1Avd1YuF5jTj%*)I{iC)*RWz}>jzK!&S}PT2xd~ViGuNyx+mfit zT*^#4sp`Tloigo7r6xI3%gv;7@;p?8jQ)5rpGYMWuFfLKwOZo8{6q=PRjrGeTzS3} z^GU~b0p8&l3~XnmGtVQtY9N7oKyfp&T4BMc>0s-#mWW%4<3$BGv+qATK2 zk@70nR8g6W7t7;Go7{?!)elW;UCz~FmXT0_v7Uj^wvtF1+)`pFHnzbnCWd0xW<_mI zYht#JH{%Tzl`^*W#UfiV5Stkd6_ql!w*GRZiFwB2tf`095>rjnl~zmCn!&AdlM_y= zkk4l1hc8>m)KA;$>xDM{L@_aKqNg%{oi9tgX-22U~EQ?-=mx3mx{Ra-EanYD0GXy`E8SF&T!+>Ce-fR$-?Bcz=+ zYR_hzYzpd$UoIZ@qTYo>cE)!ARnMv#`GS*!bW|-#X7jFJ(Lbz~iP@UTO+h)EF}k7ETa_|3)M+h=7+rnUQG|?s=#^5Hsx|0U2BC9RYcgM+LCRUY;6X> z%^2|W7GUvKVC^nobUW~az%_9k>!A?Z7vlF_@q1$@@NqAY-2+@LN6e;yKZX1kaelf0 zv?qX1#{_b~z&>DPFK|oXJ8^vS81UCHa9QYFb40WI#qWU79RgZ2z}<0Rd=Pj~9A7&i zuA>~mI0W1gxGjz^i@K|YynUFWM0Z9+dk4jJ=YbEzZ=1lEqRqj>z@oHha{{;`ey^Mt z$47vrr-6Hd`+_*W>qor4IRShxuIt<5z-K3cRi}U*LN+Pd{!p~rA!K_+*^lD7u8Vd* z5#?>7y&Fe?PI28I366WB-OB=>$APa$f%W2dm9RnK4DhQ!kC2U>6?Q%c{3L#d#BZCh zVV|(&)!o4FqQ9w0QN9CMBF+cIZ&BFdH*uZ)Q=*P2yFNvso7)0wh28%U*LEujoE6xe z5_S>x{7U?G2z!nk^#Z17!94854m^a1;UI}P7U2=JVgVK+g)xlcaXgC0@Fd#s6qew5 zJcp%NhAzB`RoIA5tjB7s!RuIyZX7}h%keh0BaM|fh#3sv2v*=Nynz?77whl>cHsba zV-I?;AH8DO^kXZAa1t##!_)s4eVmW`jIycAN9`AJ>pOnjwhIoP zly!u<>UkX3c;wfy`$^k^N$JKSV~m0^`smiSK|Na%>-M4E9i&?;pjKC8k+VUaku6)a zjPoEw2=$n?Y6YCkuT+Nch}~Ukaa>#D12(6v-34qau$i%uFn~2WVXuk;nqqKu%}e0be1^0np&f8ur)aw zpspt{%9WXehUP$|p^hQo$!qgB+OSDxijA>z?xyGJ;z!#S&lq$X|-yWAYM1b&#% zk!mkXm`1lan?Y;O;Ak*?tX8s{u>t=?sb6!mYRvGnvDW^U`S|We zdgmW4z#{;D0a_kwc^KBec7b`o0*lK0K(Sr^t^E8?|2k66_)L1`aByD!4lmoH>hz#} zcSlBS7!oTx1KBeIUkJT_`MUExz4bSIy;z{vCU8g6qxP2HnCG?esCWLja?@7h>Gp*P ztOk_re|Onahcn4y-p!vcEnhvfW_kaCfkWW_7Wp+7dS?r~qq3bJ@{SZD^d$4s1#!W5 zmo32Ge+P`got)<(=ywm`UGoIw9?tjROS;NBkafDNlJegxsQ%6K{%=(z$Ho8qj2|^| zMs#*>lxD;{Z$|vHa>Z!jMobFopEP1N2D0*q`A0}^{hW=2dhYH^fZ3+44O?!rY&lv> z{tdh3u0Z{hEY}^#%GZ1=q*s}1U9#S7Mz5I`uE(m&#DB|xY}l@`&OlQB%DBwh-%_^i zT95OQ%43%EC#W;NQRePVJo9TP$L%?0hP2`Sc30#o>q^hMRaVs*60N7PVCZU`Z+N3a z=hR#+5&IkK;;HPGkFWo{JLO%N@mvm-cfliyMd=UUS<(# zCg(F8=f&uIE!!-5mf^H)ej2uM%+TKs!M)hTEqUi6_B=Sy*jEeo=S=KPxXZR)FER1D z&FXcxq1P`9_UC1G-+iol_6}npSHDOxz6~2-UnB(yvF6Q;Xd2;G_SDS z%^1bD9>2=68kfR`xovCVN`<@VgtzGpvl({E%LUtOGFv6`8~F>*KO&DUn}w~gFh zMovVF+jbCJdFCdp8a7*R<5}GYai6yvx##{q?=W&V<38J%cgoD+e7uOvwx@27%~Go2F;|jA=Z<$D&)by#+D6uXhL_!PG(56wtOpoYwyO=Z+D6sEFl#ftX_hz3 zLk8w1`qM0X=zarxGgd8IuMZn|o99!rJ&6Wnb}utJ+WoaXiH@jTO5SxuR?93JWLcZB zx3Kl~sLuL8yih|L>x1z^4eP8;@2uK)cJ`wLY+kXnor{Hdeg? z`TL!yjF$PGkQn99gQ8j4_QW4AGa5cVnmg8{iFHmRBPoTo`jOP!F*;R7w|R_Rh861t z!FayPNFRMg9Iai3XT$S?EA4SrzA1~!Wa-sJz|Li)4C7;o;F=7$ zn&73i@k|9g-q(C{$CC|syl(}g@z_@8X_=?`C1TW3VaYtm1&pRtq{i7S<2_$t^S`5v c%4K-UFBM#cfXn|(GumCVjgEH$CZ= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + + +#if __GNUC__ && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the DLL code, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the DLL, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#ifdef PTW32_BUILD +# define PTW32_DLLPORT __declspec (dllexport) +#else +# define PTW32_DLLPORT __declspec (dllimport) +#endif + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#ifndef PTW32_CONFIG_H +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#ifdef NEED_ERRNO +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#if defined(__MINGW32__) || defined(_UWIN) +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +/* For pid_t */ +# include +/* Required by Unix 98 */ +# include +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ +#else +typedef int pid_t; +#endif + +/* Thread scheduling policies */ + +enum { + SCHED_OTHER = 0, + SCHED_FIFO, + SCHED_RR, + SCHED_MIN = SCHED_OTHER, + SCHED_MAX = SCHED_RR +}; + +struct sched_param { + int sched_priority; +}; + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +PTW32_DLLPORT int sched_yield (void); + +PTW32_DLLPORT int sched_get_priority_min (int policy); + +PTW32_DLLPORT int sched_get_priority_max (int policy); + +PTW32_DLLPORT int sched_setscheduler (pid_t pid, int policy); + +PTW32_DLLPORT int sched_getscheduler (pid_t pid); + +/* + * Note that this macro returns ENOTSUP rather than + * ENOSYS as might be expected. However, returning ENOSYS + * should mean that sched_get_priority_{min,max} are + * not implemented as well as sched_rr_get_interval. + * This is not the case, since we just don't support + * round-robin scheduling. Therefore I have chosen to + * return the same value as sched_setscheduler when + * SCHED_RR is passed to it. + */ +#define sched_rr_get_interval(_pid, _interval) \ + ( errno = ENOTSUP, (int) -1 ) + + +#ifdef __cplusplus +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* !_SCHED_H */ + diff --git a/winpcap/wpcap/libpcap/rpcapd/win32-pthreads/semaphore.h b/winpcap/wpcap/libpcap/rpcapd/win32-pthreads/semaphore.h new file mode 100644 index 0000000..733f0ae --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/win32-pthreads/semaphore.h @@ -0,0 +1,163 @@ +/* + * Module: semaphore.h + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2003 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined( SEMAPHORE_H ) +#define SEMAPHORE_H + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + +#if __GNUC__ && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the DLL code, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the DLL, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#ifdef PTW32_BUILD +# define PTW32_DLLPORT __declspec (dllexport) +#else +# define PTW32_DLLPORT __declspec (dllimport) +#endif + + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#ifndef PTW32_CONFIG_H +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#ifdef NEED_ERRNO +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#define _POSIX_SEMAPHORES + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifndef HAVE_MODE_T +typedef unsigned int mode_t; +#endif + + +typedef struct sem_t_ * sem_t; + +PTW32_DLLPORT int sem_init (sem_t * sem, + int pshared, + unsigned int value); + +PTW32_DLLPORT int sem_destroy (sem_t * sem); + +PTW32_DLLPORT int sem_trywait (sem_t * sem); + +PTW32_DLLPORT int sem_wait (sem_t * sem); + +PTW32_DLLPORT int sem_timedwait (sem_t * sem, + const struct timespec * abstime); + +PTW32_DLLPORT int sem_post (sem_t * sem); + +PTW32_DLLPORT int sem_post_multiple (sem_t * sem, + int count); + +PTW32_DLLPORT int sem_open (const char * name, + int oflag, + mode_t mode, + unsigned int value); + +PTW32_DLLPORT int sem_close (sem_t * sem); + +PTW32_DLLPORT int sem_unlink (const char * name); + +PTW32_DLLPORT int sem_getvalue (sem_t * sem, + int * sval); + +#ifdef __cplusplus +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* !SEMAPHORE_H */ diff --git a/winpcap/wpcap/libpcap/rpcapd/win32-svc.c b/winpcap/wpcap/libpcap/rpcapd/win32-svc.c new file mode 100644 index 0000000..8c740cf --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/win32-svc.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "rpcapd.h" +#include +#define _WINSOCKAPI_ +#include "windows.h" +#include // for PCAP_ERRBUF_SIZE +#include "sockutils.h" // for SOCK_ASSERT +#include "fileconf.h" + + +SERVICE_STATUS_HANDLE service_status_handle; +SERVICE_STATUS service_status; + + +void svc_geterr(char *str); +void WINAPI svc_main(DWORD argc, char **argv); + + + +int svc_start(void) +{ + int rc; + SERVICE_TABLE_ENTRY ste[] = + { + { PROGRAM_NAME, svc_main }, + { NULL, NULL } + }; + + // This call is blocking. A new thread is created which will launch + // the svc_main() function + if ( (rc = StartServiceCtrlDispatcher(ste)) == 0) + svc_geterr("StartServiceCtrlDispatcher()"); + + return rc; // FALSE if this is not started as a service +} + + +void svc_geterr(char *str) +{ +char message[PCAP_ERRBUF_SIZE]; +char string[PCAP_ERRBUF_SIZE]; +int val; + + val= GetLastError(); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_MAX_WIDTH_MASK, + NULL, val, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR) string, PCAP_ERRBUF_SIZE, NULL); + + snprintf(message, PCAP_ERRBUF_SIZE, "%s failed with error %d: %s", str, val, string); + + SOCK_ASSERT(message, 1); +} + + + +void WINAPI svc_control_handler(DWORD Opcode) +{ + service_status.dwWin32ExitCode= 0; + service_status.dwCheckPoint= 0; + service_status.dwWaitHint= 0; + + switch(Opcode) + { + case SERVICE_CONTROL_STOP: + service_status.dwCurrentState= SERVICE_STOPPED; + + /* + Uses ABORT to clean up the service. To be really honest, only the main socket and + such these stuffs are cleared; however the thread which are running are not stopped. + This can be seen by placing a breakpoint at the end of svc_main(), in which you will + see that is never reached. However, as soon as you set the service status to "stopped", + the StartServiceCtrlDispatcher() returns and the main thread ends. Then, Win32 has a good + authomatic cleanup, so that all the threads which are still running are stopped + when the main thread ends. + */ + raise(SIGABRT); + + SetServiceStatus(service_status_handle, &service_status); + break; + + /* + Pause and Continue have an usual meaning and they are used just to be able + to change the running parameters at run-time. In other words, they act + like the SIGHUP signal on UNIX. All the running threads continue to run and + they are not paused at all. + Particularly, + - PAUSE does nothing + - CONTINUE re-reads the configuration file and creates the new threads that + can be needed according to the new configuration. + */ + case SERVICE_CONTROL_PAUSE: + service_status.dwCurrentState= SERVICE_PAUSED; + SetServiceStatus(service_status_handle, &service_status); + break; + + case SERVICE_CONTROL_CONTINUE: + service_status.dwCurrentState= SERVICE_RUNNING; + SetServiceStatus(service_status_handle, &service_status); + fileconf_read(0); + break; + + case SERVICE_CONTROL_INTERROGATE: + // Fall through to send current status. + // WARNING: not implemented + SetServiceStatus(service_status_handle, &service_status); + MessageBox(NULL, "Not implemented", "warning", MB_OK); + break; + } + + // Send current status. + return; +} + + + +void WINAPI svc_main(DWORD argc, char **argv) +{ + service_status_handle = RegisterServiceCtrlHandler(PROGRAM_NAME, svc_control_handler); + + if (!service_status_handle) + return; + + service_status.dwServiceType= SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS; + service_status.dwCurrentState= SERVICE_RUNNING; + service_status.dwControlsAccepted= SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; + // | SERVICE_ACCEPT_SHUTDOWN ; + service_status.dwWin32ExitCode= 0; + service_status.dwServiceSpecificExitCode= 0; + service_status.dwCheckPoint= 0; + service_status.dwWaitHint= 0; + + SetServiceStatus(service_status_handle, &service_status); + + main_startup(); +} + +/* +sc create rpcapd DisplayName= "Remote Packet Capture Protocol v.0 (experimental)" binpath= "C:\cvsroot\winpcap\wpcap\PRJ\Debug\rpcapd -d -f rpcapd.ini" +sc description rpcapd "Allows to capture traffic on this host from a remote machine." +*/ \ No newline at end of file diff --git a/winpcap/wpcap/libpcap/rpcapd/win32-svc.h b/winpcap/wpcap/libpcap/rpcapd/win32-svc.h new file mode 100644 index 0000000..92e6944 --- /dev/null +++ b/winpcap/wpcap/libpcap/rpcapd/win32-svc.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +int svc_start(void); diff --git a/winpcap/wpcap/libpcap/savefile.c b/winpcap/wpcap/libpcap/savefile.c new file mode 100644 index 0000000..0968c35 --- /dev/null +++ b/winpcap/wpcap/libpcap/savefile.c @@ -0,0 +1,1383 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * savefile.c - supports offline use of tcpdump + * Extraction/creation by Jeffrey Mogul, DECWRL + * Modified by Steve McCanne, LBL. + * + * Used to save the received packet headers, after filtering, to + * a file, and then read them later. + * The first record in the file contains saved values for the machine + * dependent values so we can print the dump file on any architecture. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.126.2.17 2006/07/27 21:06:18 gianluca Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include "pcap-int.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +/* + * Standard libpcap format. + */ +#define TCPDUMP_MAGIC 0xa1b2c3d4 + +/* + * Alexey Kuznetzov's modified libpcap format. + */ +#define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34 + +/* + * Reserved for Francisco Mesquita + * for another modified format. + */ +#define FMESQUITA_TCPDUMP_MAGIC 0xa1b234cd + +/* + * Navtel Communcations' format, with nanosecond timestamps, + * as per a request from Dumas Hwang . + */ +#define NAVTEL_TCPDUMP_MAGIC 0xa12b3c4d + +/* + * Normal libpcap format, except for seconds/nanoseconds timestamps, + * as per a request by Ulf Lamping + */ +#define NSEC_TCPDUMP_MAGIC 0xa1b23c4d + +/* + * We use the "receiver-makes-right" approach to byte order, + * because time is at a premium when we are writing the file. + * In other words, the pcap_file_header and pcap_pkthdr, + * records are written in host byte order. + * Note that the bytes of packet data are written out in the order in + * which they were received, so multi-byte fields in packets are not + * written in host byte order, they're written in whatever order the + * sending machine put them in. + * + * ntoh[ls] aren't sufficient because we might need to swap on a big-endian + * machine (if the file was written in little-end order). + */ +#define SWAPLONG(y) \ +((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) +#define SWAPSHORT(y) \ + ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) ) + +#define SFERR_TRUNC 1 +#define SFERR_BADVERSION 2 +#define SFERR_BADF 3 +#define SFERR_EOF 4 /* not really an error, just a status */ + +/* + * Setting O_BINARY on DOS/Windows is a bit tricky + */ +#if defined(WIN32) + #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY) +#elif defined(MSDOS) + #if defined(__HIGHC__) + #define SET_BINMODE(f) setmode(f, O_BINARY) + #else + #define SET_BINMODE(f) setmode(fileno(f), O_BINARY) + #endif +#endif + +/* + * We don't write DLT_* values to the capture file header, because + * they're not the same on all platforms. + * + * Unfortunately, the various flavors of BSD have not always used the same + * numerical values for the same data types, and various patches to + * libpcap for non-BSD OSes have added their own DLT_* codes for link + * layer encapsulation types seen on those OSes, and those codes have had, + * in some cases, values that were also used, on other platforms, for other + * link layer encapsulation types. + * + * This means that capture files of a type whose numerical DLT_* code + * means different things on different BSDs, or with different versions + * of libpcap, can't always be read on systems other than those like + * the one running on the machine on which the capture was made. + * + * Instead, we define here a set of LINKTYPE_* codes, and map DLT_* codes + * to LINKTYPE_* codes when writing a savefile header, and map LINKTYPE_* + * codes to DLT_* codes when reading a savefile header. + * + * For those DLT_* codes that have, as far as we know, the same values on + * all platforms (DLT_NULL through DLT_FDDI), we define LINKTYPE_xxx as + * DLT_xxx; that way, captures of those types can still be read by + * versions of libpcap that map LINKTYPE_* values to DLT_* values, and + * captures of those types written by versions of libpcap that map DLT_ + * values to LINKTYPE_ values can still be read by older versions + * of libpcap. + * + * The other LINKTYPE_* codes are given values starting at 100, in the + * hopes that no DLT_* code will be given one of those values. + * + * In order to ensure that a given LINKTYPE_* code's value will refer to + * the same encapsulation type on all platforms, you should not allocate + * a new LINKTYPE_* value without consulting "tcpdump-workers@tcpdump.org". + * The tcpdump developers will allocate a value for you, and will not + * subsequently allocate it to anybody else; that value will be added to + * the "pcap.h" in the tcpdump.org CVS repository, so that a future + * libpcap release will include it. + * + * You should, if possible, also contribute patches to libpcap and tcpdump + * to handle the new encapsulation type, so that they can also be checked + * into the tcpdump.org CVS repository and so that they will appear in + * future libpcap and tcpdump releases. + * + * Do *NOT* assume that any values after the largest value in this file + * are available; you might not have the most up-to-date version of this + * file, and new values after that one might have been assigned. Also, + * do *NOT* use any values below 100 - those might already have been + * taken by one (or more!) organizations. + */ +#define LINKTYPE_NULL DLT_NULL +#define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */ +#define LINKTYPE_EXP_ETHERNET DLT_EN3MB /* 3Mb experimental Ethernet */ +#define LINKTYPE_AX25 DLT_AX25 +#define LINKTYPE_PRONET DLT_PRONET +#define LINKTYPE_CHAOS DLT_CHAOS +#define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */ +#define LINKTYPE_ARCNET DLT_ARCNET /* BSD-style headers */ +#define LINKTYPE_SLIP DLT_SLIP +#define LINKTYPE_PPP DLT_PPP +#define LINKTYPE_FDDI DLT_FDDI + +/* + * LINKTYPE_PPP is for use when there might, or might not, be an RFC 1662 + * PPP in HDLC-like framing header (with 0xff 0x03 before the PPP protocol + * field) at the beginning of the packet. + * + * This is for use when there is always such a header; the address field + * might be 0xff, for regular PPP, or it might be an address field for Cisco + * point-to-point with HDLC framing as per section 4.3.1 of RFC 1547 ("Cisco + * HDLC"). This is, for example, what you get with NetBSD's DLT_PPP_SERIAL. + * + * We give it the same value as NetBSD's DLT_PPP_SERIAL, in the hopes that + * nobody else will choose a DLT_ value of 50, and so that DLT_PPP_SERIAL + * captures will be written out with a link type that NetBSD's tcpdump + * can read. + */ +#define LINKTYPE_PPP_HDLC 50 /* PPP in HDLC-like framing */ + +#define LINKTYPE_PPP_ETHER 51 /* NetBSD PPP-over-Ethernet */ + +#define LINKTYPE_SYMANTEC_FIREWALL 99 /* Symantec Enterprise Firewall */ + +#define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */ +#define LINKTYPE_RAW 101 /* raw IP */ +#define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */ +#define LINKTYPE_PPP_BSDOS 103 /* BSD/OS PPP BPF header */ +#define LINKTYPE_C_HDLC 104 /* Cisco HDLC */ +#define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */ +#define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */ +#define LINKTYPE_FRELAY 107 /* Frame Relay */ +#define LINKTYPE_LOOP 108 /* OpenBSD loopback */ +#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */ + +/* + * These three types are reserved for future use. + */ +#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */ +#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */ +#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */ + +#define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */ +#define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */ +#define LINKTYPE_ECONET 115 /* Acorn Econet */ + +/* + * Reserved for use with OpenBSD ipfilter. + */ +#define LINKTYPE_IPFILTER 116 + +#define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */ +#define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */ +#define LINKTYPE_PRISM_HEADER 119 /* 802.11+Prism II monitor mode */ +#define LINKTYPE_AIRONET_HEADER 120 /* FreeBSD Aironet driver stuff */ + +/* + * Reserved for Siemens HiPath HDLC. + */ +#define LINKTYPE_HHDLC 121 + +#define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */ +#define LINKTYPE_SUNATM 123 /* Solaris+SunATM */ + +/* + * Reserved as per request from Kent Dahlgren + * for private use. + */ +#define LINKTYPE_RIO 124 /* RapidIO */ +#define LINKTYPE_PCI_EXP 125 /* PCI Express */ +#define LINKTYPE_AURORA 126 /* Xilinx Aurora link layer */ + +#define LINKTYPE_IEEE802_11_RADIO 127 /* 802.11 plus BSD radio header */ + +/* + * Reserved for the TZSP encapsulation, as per request from + * Chris Waters + * TZSP is a generic encapsulation for any other link type, + * which includes a means to include meta-information + * with the packet, e.g. signal strength and channel + * for 802.11 packets. + */ +#define LINKTYPE_TZSP 128 /* Tazmen Sniffer Protocol */ + +#define LINKTYPE_ARCNET_LINUX 129 /* Linux-style headers */ + +/* + * Juniper-private data link types, as per request from + * Hannes Gredler . The corresponding + * DLT_s are used for passing on chassis-internal + * metainformation such as QOS profiles, etc.. + */ +#define LINKTYPE_JUNIPER_MLPPP 130 +#define LINKTYPE_JUNIPER_MLFR 131 +#define LINKTYPE_JUNIPER_ES 132 +#define LINKTYPE_JUNIPER_GGSN 133 +#define LINKTYPE_JUNIPER_MFR 134 +#define LINKTYPE_JUNIPER_ATM2 135 +#define LINKTYPE_JUNIPER_SERVICES 136 +#define LINKTYPE_JUNIPER_ATM1 137 + +#define LINKTYPE_APPLE_IP_OVER_IEEE1394 138 /* Apple IP-over-IEEE 1394 cooked header */ + +#define LINKTYPE_MTP2_WITH_PHDR 139 +#define LINKTYPE_MTP2 140 +#define LINKTYPE_MTP3 141 +#define LINKTYPE_SCCP 142 + +#define LINKTYPE_DOCSIS 143 /* DOCSIS MAC frames */ + +#define LINKTYPE_LINUX_IRDA 144 /* Linux-IrDA */ + +/* + * Reserved for IBM SP switch and IBM Next Federation switch. + */ +#define LINKTYPE_IBM_SP 145 +#define LINKTYPE_IBM_SN 146 + +/* + * Reserved for private use. If you have some link-layer header type + * that you want to use within your organization, with the capture files + * using that link-layer header type not ever be sent outside your + * organization, you can use these values. + * + * No libpcap release will use these for any purpose, nor will any + * tcpdump release use them, either. + * + * Do *NOT* use these in capture files that you expect anybody not using + * your private versions of capture-file-reading tools to read; in + * particular, do *NOT* use them in products, otherwise you may find that + * people won't be able to use tcpdump, or snort, or Ethereal, or... to + * read capture files from your firewall/intrusion detection/traffic + * monitoring/etc. appliance, or whatever product uses that LINKTYPE_ value, + * and you may also find that the developers of those applications will + * not accept patches to let them read those files. + * + * Also, do not use them if somebody might send you a capture using them + * for *their* private type and tools using them for *your* private type + * would have to read them. + * + * Instead, in those cases, ask "tcpdump-workers@tcpdump.org" for a new DLT_ + * and LINKTYPE_ value, as per the comment in pcap-bpf.h, and use the type + * you're given. + */ +#define LINKTYPE_USER0 147 +#define LINKTYPE_USER1 148 +#define LINKTYPE_USER2 149 +#define LINKTYPE_USER3 150 +#define LINKTYPE_USER4 151 +#define LINKTYPE_USER5 152 +#define LINKTYPE_USER6 153 +#define LINKTYPE_USER7 154 +#define LINKTYPE_USER8 155 +#define LINKTYPE_USER9 156 +#define LINKTYPE_USER10 157 +#define LINKTYPE_USER11 158 +#define LINKTYPE_USER12 159 +#define LINKTYPE_USER13 160 +#define LINKTYPE_USER14 161 +#define LINKTYPE_USER15 162 + +/* + * For future use with 802.11 captures - defined by AbsoluteValue + * Systems to store a number of bits of link-layer information + * including radio information: + * + * http://www.shaftnet.org/~pizza/software/capturefrm.txt + * + * but could and arguably should also be used by non-AVS Linux + * 802.11 drivers; that may happen in the future. + */ +#define LINKTYPE_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The corresponding + * DLT_s are used for passing on chassis-internal + * metainformation such as QOS profiles, etc.. + */ +#define LINKTYPE_JUNIPER_MONITOR 164 + +/* + * Reserved for BACnet MS/TP. + */ +#define LINKTYPE_BACNET_MS_TP 165 + +/* + * Another PPP variant as per request from Karsten Keil . + * + * This is used in some OSes to allow a kernel socket filter to distinguish + * between incoming and outgoing packets, on a socket intended to + * supply pppd with outgoing packets so it can do dial-on-demand and + * hangup-on-lack-of-demand; incoming packets are filtered out so they + * don't cause pppd to hold the connection up (you don't want random + * input packets such as port scans, packets from old lost connections, + * etc. to force the connection to stay up). + * + * The first byte of the PPP header (0xff03) is modified to accomodate + * the direction - 0x00 = IN, 0x01 = OUT. + */ +#define LINKTYPE_PPP_PPPD 166 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, cookies, etc.. + */ +#define LINKTYPE_JUNIPER_PPPOE 167 +#define LINKTYPE_JUNIPER_PPPOE_ATM 168 + +#define LINKTYPE_GPRS_LLC 169 /* GPRS LLC */ +#define LINKTYPE_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ +#define LINKTYPE_GPF_F 171 /* GPF-T (ITU-T G.7041/Y.1303) */ + +/* + * Requested by Oolan Zimmer for use in Gcom's T1/E1 line + * monitoring equipment. + */ +#define LINKTYPE_GCOM_T1E1 172 +#define LINKTYPE_GCOM_SERIAL 173 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_ is used + * for internal communication to Physical Interface Cards (PIC) + */ +#define LINKTYPE_JUNIPER_PIC_PEER 174 + +/* + * Link types requested by Gregor Maier of Endace + * Measurement Systems. They add an ERF header (see + * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of + * the link-layer header. + */ +#define LINKTYPE_ERF_ETH 175 /* Ethernet */ +#define LINKTYPE_ERF_POS 176 /* Packet-over-SONET */ + +/* + * Requested by Daniele Orlandi for raw LAPD + * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header + * includes additional information before the LAPD header, so it's + * not necessarily a generic LAPD header. + */ +#define LINKTYPE_LINUX_LAPD 177 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The Link Types are used for prepending meta-information + * like interface index, interface name + * before standard Ethernet, PPP, Frelay & C-HDLC Frames + */ +#define LINKTYPE_JUNIPER_ETHER 178 +#define LINKTYPE_JUNIPER_PPP 179 +#define LINKTYPE_JUNIPER_FRELAY 180 +#define LINKTYPE_JUNIPER_CHDLC 181 + +/* + * Multi Link Frame Relay (FRF.16) + */ +#define LINKTYPE_MFR 182 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for internal communication with a + * voice Adapter Card (PIC) + */ +#define LINKTYPE_JUNIPER_VP 183 + +/* + * Arinc 429 frames. + * DLT_ requested by Gianluca Varenni . + * Every frame contains a 32bit A429 label. + * More documentation on Arinc 429 can be found at + * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf + */ +#define LINKTYPE_A429 184 + +/* + * Arinc 653 Interpartition Communication messages. + * DLT_ requested by Gianluca Varenni . + * Please refer to the A653-1 standard for more information. + */ +#define LINKTYPE_A653_ICM 185 + +/* + * Controller Area Network (CAN) v. 2.0B packets. + * DLT_ requested by Gianluca Varenni . + * Used to dump CAN packets coming from a CAN Vector board. + * More documentation on the CAN v2.0B frames can be found at + * http://www.can-cia.org/downloads/?269 + */ +#define LINKTYPE_CAN20B 190 + +static struct linktype_map { + int dlt; + int linktype; +} map[] = { + /* + * These DLT_* codes have LINKTYPE_* codes with values identical + * to the values of the corresponding DLT_* code. + */ + { DLT_NULL, LINKTYPE_NULL }, + { DLT_EN10MB, LINKTYPE_ETHERNET }, + { DLT_EN3MB, LINKTYPE_EXP_ETHERNET }, + { DLT_AX25, LINKTYPE_AX25 }, + { DLT_PRONET, LINKTYPE_PRONET }, + { DLT_CHAOS, LINKTYPE_CHAOS }, + { DLT_IEEE802, LINKTYPE_TOKEN_RING }, + { DLT_ARCNET, LINKTYPE_ARCNET }, + { DLT_SLIP, LINKTYPE_SLIP }, + { DLT_PPP, LINKTYPE_PPP }, + { DLT_FDDI, LINKTYPE_FDDI }, + + /* + * These DLT_* codes have different values on different + * platforms; we map them to LINKTYPE_* codes that + * have values that should never be equal to any DLT_* + * code. + */ +#ifdef DLT_FR + /* BSD/OS Frame Relay */ + { DLT_FR, LINKTYPE_FRELAY }, +#endif + + { DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL }, + { DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 }, + { DLT_RAW, LINKTYPE_RAW }, + { DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS }, + { DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS }, + + /* BSD/OS Cisco HDLC */ + { DLT_C_HDLC, LINKTYPE_C_HDLC }, + + /* + * These DLT_* codes are not on all platforms, but, so far, + * there don't appear to be any platforms that define + * other codes with those values; we map them to + * different LINKTYPE_* values anyway, just in case. + */ + + /* Linux ATM Classical IP */ + { DLT_ATM_CLIP, LINKTYPE_ATM_CLIP }, + + /* NetBSD sync/async serial PPP (or Cisco HDLC) */ + { DLT_PPP_SERIAL, LINKTYPE_PPP_HDLC }, + + /* NetBSD PPP over Ethernet */ + { DLT_PPP_ETHER, LINKTYPE_PPP_ETHER }, + + /* IEEE 802.11 wireless */ + { DLT_IEEE802_11, LINKTYPE_IEEE802_11 }, + + /* Frame Relay */ + { DLT_FRELAY, LINKTYPE_FRELAY }, + + /* OpenBSD loopback */ + { DLT_LOOP, LINKTYPE_LOOP }, + + /* Linux cooked socket capture */ + { DLT_LINUX_SLL, LINKTYPE_LINUX_SLL }, + + /* Apple LocalTalk hardware */ + { DLT_LTALK, LINKTYPE_LTALK }, + + /* Acorn Econet */ + { DLT_ECONET, LINKTYPE_ECONET }, + + /* OpenBSD DLT_PFLOG */ + { DLT_PFLOG, LINKTYPE_PFLOG }, + + /* For Cisco-internal use */ + { DLT_CISCO_IOS, LINKTYPE_CISCO_IOS }, + + /* Prism II monitor-mode header plus 802.11 header */ + { DLT_PRISM_HEADER, LINKTYPE_PRISM_HEADER }, + + /* FreeBSD Aironet driver stuff */ + { DLT_AIRONET_HEADER, LINKTYPE_AIRONET_HEADER }, + + /* Siemens HiPath HDLC */ + { DLT_HHDLC, LINKTYPE_HHDLC }, + + /* RFC 2625 IP-over-Fibre Channel */ + { DLT_IP_OVER_FC, LINKTYPE_IP_OVER_FC }, + + /* Solaris+SunATM */ + { DLT_SUNATM, LINKTYPE_SUNATM }, + + /* RapidIO */ + { DLT_RIO, LINKTYPE_RIO }, + + /* PCI Express */ + { DLT_PCI_EXP, LINKTYPE_PCI_EXP }, + + /* Xilinx Aurora link layer */ + { DLT_AURORA, LINKTYPE_AURORA }, + + /* 802.11 plus BSD radio header */ + { DLT_IEEE802_11_RADIO, LINKTYPE_IEEE802_11_RADIO }, + + /* Tazmen Sniffer Protocol */ + { DLT_TZSP, LINKTYPE_TZSP }, + + /* Arcnet with Linux-style link-layer headers */ + { DLT_ARCNET_LINUX, LINKTYPE_ARCNET_LINUX }, + + /* Juniper-internal chassis encapsulation */ + { DLT_JUNIPER_MLPPP, LINKTYPE_JUNIPER_MLPPP }, + { DLT_JUNIPER_MLFR, LINKTYPE_JUNIPER_MLFR }, + { DLT_JUNIPER_ES, LINKTYPE_JUNIPER_ES }, + { DLT_JUNIPER_GGSN, LINKTYPE_JUNIPER_GGSN }, + { DLT_JUNIPER_MFR, LINKTYPE_JUNIPER_MFR }, + { DLT_JUNIPER_ATM2, LINKTYPE_JUNIPER_ATM2 }, + { DLT_JUNIPER_SERVICES, LINKTYPE_JUNIPER_SERVICES }, + { DLT_JUNIPER_ATM1, LINKTYPE_JUNIPER_ATM1 }, + + /* Apple IP-over-IEEE 1394 cooked header */ + { DLT_APPLE_IP_OVER_IEEE1394, LINKTYPE_APPLE_IP_OVER_IEEE1394 }, + + /* SS7 */ + { DLT_MTP2_WITH_PHDR, LINKTYPE_MTP2_WITH_PHDR }, + { DLT_MTP2, LINKTYPE_MTP2 }, + { DLT_MTP3, LINKTYPE_MTP3 }, + { DLT_SCCP, LINKTYPE_SCCP }, + + /* DOCSIS MAC frames */ + { DLT_DOCSIS, LINKTYPE_DOCSIS }, + + /* IrDA IrLAP packets + Linux-cooked header */ + { DLT_LINUX_IRDA, LINKTYPE_LINUX_IRDA }, + + /* IBM SP and Next Federation switches */ + { DLT_IBM_SP, LINKTYPE_IBM_SP }, + { DLT_IBM_SN, LINKTYPE_IBM_SN }, + + /* 802.11 plus AVS radio header */ + { DLT_IEEE802_11_RADIO_AVS, LINKTYPE_IEEE802_11_RADIO_AVS }, + + /* + * Any platform that defines additional DLT_* codes should: + * + * request a LINKTYPE_* code and value from tcpdump.org, + * as per the above; + * + * add, in their version of libpcap, an entry to map + * those DLT_* codes to the corresponding LINKTYPE_* + * code; + * + * redefine, in their "net/bpf.h", any DLT_* values + * that collide with the values used by their additional + * DLT_* codes, to remove those collisions (but without + * making them collide with any of the LINKTYPE_* + * values equal to 50 or above; they should also avoid + * defining DLT_* values that collide with those + * LINKTYPE_* values, either). + */ + + /* Juniper-internal chassis encapsulation */ + { DLT_JUNIPER_MONITOR, LINKTYPE_JUNIPER_MONITOR }, + + /* BACnet MS/TP */ + { DLT_BACNET_MS_TP, LINKTYPE_BACNET_MS_TP }, + + /* PPP for pppd, with direction flag in the PPP header */ + { DLT_PPP_PPPD, LINKTYPE_PPP_PPPD}, + + /* Juniper-internal chassis encapsulation */ + { DLT_JUNIPER_PPPOE, LINKTYPE_JUNIPER_PPPOE }, + { DLT_JUNIPER_PPPOE_ATM,LINKTYPE_JUNIPER_PPPOE_ATM }, + + /* GPRS LLC */ + { DLT_GPRS_LLC, LINKTYPE_GPRS_LLC }, + + /* Transparent Generic Framing Procedure (ITU-T G.7041/Y.1303) */ + { DLT_GPF_T, LINKTYPE_GPF_T }, + + /* Framed Generic Framing Procedure (ITU-T G.7041/Y.1303) */ + { DLT_GPF_F, LINKTYPE_GPF_F }, + + { DLT_GCOM_T1E1, LINKTYPE_GCOM_T1E1 }, + { DLT_GCOM_SERIAL, LINKTYPE_GCOM_SERIAL }, + + /* Juniper-internal chassis encapsulation */ + { DLT_JUNIPER_PIC_PEER, LINKTYPE_JUNIPER_PIC_PEER }, + + /* Endace types */ + { DLT_ERF_ETH, LINKTYPE_ERF_ETH }, + { DLT_ERF_POS, LINKTYPE_ERF_POS }, + + /* viSDN LAPD */ + { DLT_LINUX_LAPD, LINKTYPE_LINUX_LAPD }, + + /* Juniper meta-information before Ether, PPP, Frame Relay, C-HDLC Frames */ + { DLT_JUNIPER_ETHER, LINKTYPE_JUNIPER_ETHER }, + { DLT_JUNIPER_PPP, LINKTYPE_JUNIPER_PPP }, + { DLT_JUNIPER_FRELAY, LINKTYPE_JUNIPER_FRELAY }, + { DLT_JUNIPER_CHDLC, LINKTYPE_JUNIPER_CHDLC }, + + /* Multi Link Frame Relay (FRF.16) */ + { DLT_MFR, LINKTYPE_MFR }, + + /* Juniper Voice PIC */ + { DLT_JUNIPER_VP, LINKTYPE_JUNIPER_VP }, + + /* Controller Area Network (CAN) v2.0B */ + { DLT_A429, LINKTYPE_A429 }, + + /* Controller Area Network (CAN) v2.0B */ + { DLT_CAN20B, LINKTYPE_CAN20B }, + + /* Arinc 653 Interpartition Communication messages */ + { DLT_A653_ICM, LINKTYPE_A653_ICM }, + + { -1, -1 } +}; + +static int +dlt_to_linktype(int dlt) +{ + int i; + + for (i = 0; map[i].dlt != -1; i++) { + if (map[i].dlt == dlt) + return (map[i].linktype); + } + + /* + * If we don't have a mapping for this DLT_ code, return an + * error; that means that the table above needs to have an + * entry added. + */ + return (-1); +} + +static int +linktype_to_dlt(int linktype) +{ + int i; + + for (i = 0; map[i].linktype != -1; i++) { + if (map[i].linktype == linktype) + return (map[i].dlt); + } + + /* + * If we don't have an entry for this link type, return + * the link type value; it may be a DLT_ value from an + * older version of libpcap. + */ + return linktype; +} + +static int +sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen) +{ + struct pcap_file_header hdr; + + hdr.magic = TCPDUMP_MAGIC; + hdr.version_major = PCAP_VERSION_MAJOR; + hdr.version_minor = PCAP_VERSION_MINOR; + + hdr.thiszone = thiszone; + hdr.snaplen = snaplen; + hdr.sigfigs = 0; + hdr.linktype = linktype; + + if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1) + return (-1); + + return (0); +} + +static void +swap_hdr(struct pcap_file_header *hp) +{ + hp->version_major = SWAPSHORT(hp->version_major); + hp->version_minor = SWAPSHORT(hp->version_minor); + hp->thiszone = SWAPLONG(hp->thiszone); + hp->sigfigs = SWAPLONG(hp->sigfigs); + hp->snaplen = SWAPLONG(hp->snaplen); + hp->linktype = SWAPLONG(hp->linktype); +} + +static int +sf_getnonblock(pcap_t *p, char *errbuf) +{ + /* + * This is a savefile, not a live capture file, so never say + * it's in non-blocking mode. + */ + return (0); +} + +static int +sf_setnonblock(pcap_t *p, int nonblock, char *errbuf) +{ + /* + * This is a savefile, not a live capture file, so ignore + * requests to put it in non-blocking mode. + */ + return (0); +} + +static int +sf_stats(pcap_t *p, struct pcap_stat *ps) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Statistics aren't available from savefiles"); + return (-1); +} + +static int +sf_inject(pcap_t *p, const void *buf _U_, size_t size _U_) +{ + strlcpy(p->errbuf, "Sending packets isn't supported on savefiles", + PCAP_ERRBUF_SIZE); + return (-1); +} + +/* + * Set direction flag: Which packets do we accept on a forwarding + * single device? IN, OUT or both? + */ +static int +sf_setdirection(pcap_t *p, pcap_direction_t d) +{ + snprintf(p->errbuf, sizeof(p->errbuf), + "Setting direction is not supported on savefiles"); + return (-1); +} + +static void +sf_close(pcap_t *p) +{ + if (p->sf.rfile != stdin) + (void)fclose(p->sf.rfile); + if (p->sf.base != NULL) + free(p->sf.base); +} + +pcap_t * +pcap_open_offline(const char *fname, char *errbuf) +{ + FILE *fp; + pcap_t *p; + + if (fname[0] == '-' && fname[1] == '\0') + { + fp = stdin; +#if defined(WIN32) || defined(MSDOS) + /* + * We're reading from the standard input, so put it in binary + * mode, as savefiles are binary files. + */ + SET_BINMODE(fp); +#endif + } + else { +#if !defined(WIN32) && !defined(MSDOS) + fp = fopen(fname, "r"); +#else + fp = fopen(fname, "rb"); +#endif + if (fp == NULL) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, + pcap_strerror(errno)); + return (NULL); + } + } + p = pcap_fopen_offline(fp, errbuf); + if (p == NULL) { + if (fp != stdin) + fclose(fp); + } + return (p); +} + +pcap_t * +pcap_fopen_offline(FILE *fp, char *errbuf) +{ + register pcap_t *p; + struct pcap_file_header hdr; + size_t amt_read; + bpf_u_int32 magic; + int linklen; + + p = (pcap_t *)malloc(sizeof(*p)); + if (p == NULL) { + strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); + return (NULL); + } + + memset((char *)p, 0, sizeof(*p)); + + amt_read = fread((char *)&hdr, 1, sizeof(hdr), fp); + if (amt_read != sizeof(hdr)) { + if (ferror(fp)) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "error reading dump file: %s", + pcap_strerror(errno)); + } else { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "truncated dump file; tried to read %lu file header bytes, only got %lu", + (unsigned long)sizeof(hdr), + (unsigned long)amt_read); + } + goto bad; + } + magic = hdr.magic; + if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) { + magic = SWAPLONG(magic); + if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "bad dump file format"); + goto bad; + } + p->sf.swapped = 1; + swap_hdr(&hdr); + } + if (magic == KUZNETZOV_TCPDUMP_MAGIC) { + /* + * XXX - the patch that's in some versions of libpcap + * changes the packet header but not the magic number, + * and some other versions with this magic number have + * some extra debugging information in the packet header; + * we'd have to use some hacks^H^H^H^H^Hheuristics to + * detect those variants. + * + * Ethereal does that, but it does so by trying to read + * the first two packets of the file with each of the + * record header formats. That currently means it seeks + * backwards and retries the reads, which doesn't work + * on pipes. We want to be able to read from a pipe, so + * that strategy won't work; we'd have to buffer some + * data ourselves and read from that buffer in order to + * make that work. + */ + p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr); + } else + p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr); + if (hdr.version_major < PCAP_VERSION_MAJOR) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format"); + goto bad; + } + p->tzoff = hdr.thiszone; + p->snapshot = hdr.snaplen; + p->linktype = linktype_to_dlt(hdr.linktype); + p->sf.rfile = fp; +#ifndef WIN32 + p->bufsize = hdr.snaplen; +#else + /* Allocate the space for pcap_pkthdr as well. It will be used by pcap_read_ex */ + p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr); +#endif + + /* Align link header as required for proper data alignment */ + /* XXX should handle all types */ + switch (p->linktype) { + + case DLT_EN10MB: + linklen = 14; + break; + + case DLT_FDDI: + linklen = 13 + 8; /* fddi_header + llc */ + break; + + case DLT_NULL: + default: + linklen = 0; + break; + } + + if (p->bufsize < 0) + p->bufsize = BPF_MAXBUFSIZE; + p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT); + if (p->sf.base == NULL) { + strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); + goto bad; + } + p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT); + p->sf.version_major = hdr.version_major; + p->sf.version_minor = hdr.version_minor; +#ifdef PCAP_FDDIPAD + /* Padding only needed for live capture fcode */ + p->fddipad = 0; +#endif + + /* + * We interchanged the caplen and len fields at version 2.3, + * in order to match the bpf header layout. But unfortunately + * some files were written with version 2.3 in their headers + * but without the interchanged fields. + * + * In addition, DG/UX tcpdump writes out files with a version + * number of 543.0, and with the caplen and len fields in the + * pre-2.3 order. + */ + switch (hdr.version_major) { + + case 2: + if (hdr.version_minor < 3) + p->sf.lengths_swapped = SWAPPED; + else if (hdr.version_minor == 3) + p->sf.lengths_swapped = MAYBE_SWAPPED; + else + p->sf.lengths_swapped = NOT_SWAPPED; + break; + + case 543: + p->sf.lengths_swapped = SWAPPED; + break; + + default: + p->sf.lengths_swapped = NOT_SWAPPED; + break; + } + +#if !defined(WIN32) && !defined(MSDOS) + /* + * You can do "select()" and "poll()" on plain files on most + * platforms, and should be able to do so on pipes. + * + * You can't do "select()" on anything other than sockets in + * Windows, so, on Win32 systems, we don't have "selectable_fd". + */ + p->selectable_fd = fileno(fp); +#endif + + p->read_op = pcap_offline_read; + p->inject_op = sf_inject; + p->setfilter_op = install_bpf_program; + p->setdirection_op = sf_setdirection; + p->set_datalink_op = NULL; /* we don't support munging link-layer headers */ + p->getnonblock_op = sf_getnonblock; + p->setnonblock_op = sf_setnonblock; + p->stats_op = sf_stats; + p->close_op = sf_close; + + return (p); + bad: + free(p); + return (NULL); +} + +/* + * Read sf_readfile and return the next packet. Return the header in hdr + * and the contents in buf. Return 0 on success, SFERR_EOF if there were + * no more packets, and SFERR_TRUNC if a partial packet was encountered. + */ +static int +sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen) +{ + struct pcap_sf_patched_pkthdr sf_hdr; + FILE *fp = p->sf.rfile; + size_t amt_read; + bpf_u_int32 t; + + /* + * Read the packet header; the structure we use as a buffer + * is the longer structure for files generated by the patched + * libpcap, but if the file has the magic number for an + * unpatched libpcap we only read as many bytes as the regular + * header has. + */ + amt_read = fread(&sf_hdr, 1, p->sf.hdrsize, fp); + if (amt_read != p->sf.hdrsize) { + if (ferror(fp)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "error reading dump file: %s", + pcap_strerror(errno)); + return (-1); + } else { + if (amt_read != 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "truncated dump file; tried to read %d header bytes, only got %lu", + p->sf.hdrsize, (unsigned long)amt_read); + return (-1); + } + /* EOF */ + return (1); + } + } + + if (p->sf.swapped) { + /* these were written in opposite byte order */ + hdr->caplen = SWAPLONG(sf_hdr.caplen); + hdr->len = SWAPLONG(sf_hdr.len); + hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec); + hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec); + } else { + hdr->caplen = sf_hdr.caplen; + hdr->len = sf_hdr.len; + hdr->ts.tv_sec = sf_hdr.ts.tv_sec; + hdr->ts.tv_usec = sf_hdr.ts.tv_usec; + } + /* Swap the caplen and len fields, if necessary. */ + switch (p->sf.lengths_swapped) { + + case NOT_SWAPPED: + break; + + case MAYBE_SWAPPED: + if (hdr->caplen <= hdr->len) { + /* + * The captured length is <= the actual length, + * so presumably they weren't swapped. + */ + break; + } + /* FALLTHROUGH */ + + case SWAPPED: + t = hdr->caplen; + hdr->caplen = hdr->len; + hdr->len = t; + break; + } + + if (hdr->caplen > buflen) { + /* + * This can happen due to Solaris 2.3 systems tripping + * over the BUFMOD problem and not setting the snapshot + * correctly in the savefile header. If the caplen isn't + * grossly wrong, try to salvage. + */ + static u_char *tp = NULL; + static size_t tsize = 0; + + if (hdr->caplen > 65535) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "bogus savefile header"); + return (-1); + } + + if (tsize < hdr->caplen) { + tsize = ((hdr->caplen + 1023) / 1024) * 1024; + if (tp != NULL) + free((u_char *)tp); + tp = (u_char *)malloc(tsize); + if (tp == NULL) { + tsize = 0; + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "BUFMOD hack malloc"); + return (-1); + } + } + amt_read = fread((char *)tp, 1, hdr->caplen, fp); + if (amt_read != hdr->caplen) { + if (ferror(fp)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "error reading dump file: %s", + pcap_strerror(errno)); + } else { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "truncated dump file; tried to read %u captured bytes, only got %lu", + hdr->caplen, (unsigned long)amt_read); + } + return (-1); + } + /* + * We can only keep up to buflen bytes. Since caplen > buflen + * is exactly how we got here, we know we can only keep the + * first buflen bytes and must drop the remainder. Adjust + * caplen accordingly, so we don't get confused later as + * to how many bytes we have to play with. + */ + hdr->caplen = buflen; + memcpy((char *)buf, (char *)tp, buflen); + + } else { + /* read the packet itself */ + amt_read = fread((char *)buf, 1, hdr->caplen, fp); + if (amt_read != hdr->caplen) { + if (ferror(fp)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "error reading dump file: %s", + pcap_strerror(errno)); + } else { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "truncated dump file; tried to read %u captured bytes, only got %lu", + hdr->caplen, (unsigned long)amt_read); + } + return (-1); + } + } + return (0); +} + +/* + * Print out packets stored in the file initialized by sf_read_init(). + * If cnt > 0, return after 'cnt' packets, otherwise continue until eof. + */ +int +pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ + struct bpf_insn *fcode; + int status = 0; + int n = 0; + +#ifdef HAVE_REMOTE + static int samp_npkt; // parameter needed for sampling, whtn '1 out of N' method has been requested + static struct timeval samp_time; // parameter needed for sampling, whtn '1 every N ms' method has been requested +#endif /* HAVE_REMOTE */ + + while (status == 0) { + struct pcap_pkthdr h; + + /* + * Has "pcap_breakloop()" been called? + * If so, return immediately - if we haven't read any + * packets, clear the flag and return -2 to indicate + * that we were told to break out of the loop, otherwise + * leave the flag set, so that the *next* call will break + * out of the loop without having read any packets, and + * return the number of packets we've processed so far. + */ + if (p->break_loop) { + if (n == 0) { + p->break_loop = 0; + return (-2); + } else + return (n); + } + + status = sf_next_packet(p, &h, p->buffer, p->bufsize); + if (status) { + if (status == 1) + return (0); + return (status); + } + + if ((fcode = p->fcode.bf_insns) == NULL || + bpf_filter(fcode, p->buffer, h.len, h.caplen)) { + +#ifdef HAVE_REMOTE + if (p->rmt_samp.method == PCAP_SAMP_1_EVERY_N) + { + samp_npkt= (samp_npkt + 1) % p->rmt_samp.value; + + // Discard all packets that are not '1 out of N' + if (samp_npkt != 0) + continue; + } + + if (p->rmt_samp.method == PCAP_SAMP_FIRST_AFTER_N_MS) + { + // Check if the timestamp of the arrived packet is smaller than our target time + if ( (h.ts.tv_sec < samp_time.tv_sec) || + ( (h.ts.tv_sec == samp_time.tv_sec) && (h.ts.tv_usec < samp_time.tv_usec) ) ) + continue; + + // The arrived packet is suitable for being sent to the remote host + // So, let's update the target time + samp_time.tv_usec= h.ts.tv_usec + p->rmt_samp.value * 1000; + if (samp_time.tv_usec > 1000000) + { + samp_time.tv_sec= h.ts.tv_sec + samp_time.tv_usec / 1000000; + samp_time.tv_usec= samp_time.tv_usec % 1000000; + } + + } +#endif /* HAVE_REMOTE */ + + (*callback)(user, &h, p->buffer); + if (++n >= cnt && cnt > 0) + break; + } + } + /*XXX this breaks semantics tcpslice expects */ + return (n); +} + +/* + * Output a packet to the initialized dump file. + */ +void +pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) +{ + register FILE *f; + struct pcap_sf_pkthdr sf_hdr; + + f = (FILE *)user; + sf_hdr.ts.tv_sec = h->ts.tv_sec; + sf_hdr.ts.tv_usec = h->ts.tv_usec; + sf_hdr.caplen = h->caplen; + sf_hdr.len = h->len; + /* XXX we should check the return status */ + (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f); + (void)fwrite((char *)sp, h->caplen, 1, f); +} + +static pcap_dumper_t * +pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname) +{ + +#if defined(WIN32) || defined(MSDOS) + /* + * If we're writing to the standard output, put it in binary + * mode, as savefiles are binary files. + * + * Otherwise, we turn off buffering. + * XXX - why? And why not on the standard output? + */ + if (f == stdout) + SET_BINMODE(f); + else + setbuf(f, NULL); +#endif + if (sf_write_header(f, linktype, p->tzoff, p->snapshot) == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s", + fname, pcap_strerror(errno)); + if (f != stdout) + (void)fclose(f); + return (NULL); + } + return ((pcap_dumper_t *)f); +} + +/* + * Initialize so that sf_write() will output to the file named 'fname'. + */ +pcap_dumper_t * +pcap_dump_open(pcap_t *p, const char *fname) +{ + FILE *f; + int linktype; + + linktype = dlt_to_linktype(p->linktype); + if (linktype == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "%s: link-layer type %d isn't supported in savefiles", + fname, linktype); + return (NULL); + } + + if (fname[0] == '-' && fname[1] == '\0') { + f = stdout; + fname = "standard output"; + } else { +#if !defined(WIN32) && !defined(MSDOS) + f = fopen(fname, "w"); +#else + f = fopen(fname, "wb"); +#endif + if (f == NULL) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", + fname, pcap_strerror(errno)); + return (NULL); + } + } + return (pcap_setup_dump(p, linktype, f, fname)); +} + +/* + * Initialize so that sf_write() will output to the given stream. + */ +pcap_dumper_t * +pcap_dump_fopen(pcap_t *p, FILE *f) +{ + int linktype; + + linktype = dlt_to_linktype(p->linktype); + if (linktype == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "stream: link-layer type %d isn't supported in savefiles", + linktype); + return (NULL); + } + + return (pcap_setup_dump(p, linktype, f, "stream")); +} + +FILE * +pcap_dump_file(pcap_dumper_t *p) +{ + return ((FILE *)p); +} + +long +pcap_dump_ftell(pcap_dumper_t *p) +{ + return (ftell((FILE *)p)); +} + +int +pcap_dump_flush(pcap_dumper_t *p) +{ + + if (fflush((FILE *)p) == EOF) + return (-1); + else + return (0); +} + +void +pcap_dump_close(pcap_dumper_t *p) +{ + +#ifdef notyet + if (ferror((FILE *)p)) + return-an-error; + /* XXX should check return from fclose() too */ +#endif + (void)fclose((FILE *)p); +} diff --git a/winpcap/wpcap/libpcap/scanner.c b/winpcap/wpcap/libpcap/scanner.c new file mode 100644 index 0000000..806d02f --- /dev/null +++ b/winpcap/wpcap/libpcap/scanner.c @@ -0,0 +1,4352 @@ +#define yy_create_buffer pcap__create_buffer +#define yy_delete_buffer pcap__delete_buffer +#define yy_scan_buffer pcap__scan_buffer +#define yy_scan_string pcap__scan_string +#define yy_scan_bytes pcap__scan_bytes +#define yy_flex_debug pcap__flex_debug +#define yy_init_buffer pcap__init_buffer +#define yy_flush_buffer pcap__flush_buffer +#define yy_load_buffer_state pcap__load_buffer_state +#define yy_switch_to_buffer pcap__switch_to_buffer +#define yyin pcap_in +#define yyleng pcap_leng +#define yylex pcap_lex +#define yyout pcap_out +#define yyrestart pcap_restart +#define yytext pcap_text +#define yywrap pcap_wrap + +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +#include +#include + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include +#ifndef _WIN32 +#include +#endif + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 133 +#define YY_END_OF_BUFFER 134 +static yyconst short int yy_accept[1322] = + { 0, + 0, 0, 134, 131, 91, 91, 91, 92, 131, 92, + 92, 92, 132, 100, 100, 92, 92, 92, 92, 129, + 129, 131, 129, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 92, 131, 95, 99, 57, 0, 129, 100, + 0, 129, 129, 129, 103, 97, 94, 96, 93, 98, + 130, 130, 129, 129, 19, 129, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 7, + 129, 33, 34, 129, 129, 129, 129, 129, 129, 129, + + 129, 129, 129, 129, 129, 129, 81, 129, 58, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 75, 129, 129, 129, 129, 129, 129, 129, 4, 129, + 129, 129, 129, 129, 129, 58, 99, 101, 101, 100, + 129, 0, 103, 100, 103, 103, 103, 129, 129, 57, + 5, 129, 70, 129, 129, 129, 129, 129, 129, 89, + 1, 0, 129, 20, 129, 129, 129, 129, 129, 129, + 129, 129, 129, 35, 129, 129, 17, 42, 0, 129, + 28, 129, 24, 60, 129, 129, 68, 36, 129, 129, + 129, 129, 129, 45, 59, 71, 88, 129, 14, 129, + + 3, 129, 129, 129, 129, 129, 83, 129, 129, 25, + 129, 87, 129, 90, 37, 2, 129, 41, 129, 9, + 10, 78, 129, 77, 129, 129, 129, 129, 100, 0, + 129, 0, 104, 103, 103, 0, 103, 0, 103, 0, + 103, 0, 22, 129, 129, 129, 54, 40, 129, 38, + 129, 129, 29, 129, 129, 129, 44, 11, 129, 12, + 13, 129, 129, 129, 31, 67, 129, 52, 3, 46, + 129, 129, 129, 64, 129, 129, 129, 129, 47, 129, + 129, 39, 129, 6, 129, 82, 129, 8, 84, 129, + 0, 129, 63, 15, 101, 101, 101, 100, 0, 103, + + 0, 0, 103, 0, 103, 104, 103, 0, 0, 0, + 0, 103, 103, 103, 103, 103, 0, 129, 21, 129, + 129, 129, 30, 129, 129, 0, 18, 129, 129, 129, + 76, 129, 32, 129, 69, 27, 26, 129, 129, 72, + 129, 129, 129, 49, 16, 129, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 0, 0, + 103, 103, 103, 0, 0, 104, 103, 103, 104, 103, + 0, 0, 103, 103, 103, 103, 103, 0, 0, 0, + 0, 103, 103, 0, 103, 0, 103, 0, 86, 129, + 129, 23, 129, 129, 129, 129, 129, 129, 129, 129, + + 129, 129, 129, 129, 129, 60, 129, 129, 129, 129, + 129, 129, 129, 65, 66, 129, 85, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 101, 101, 101, + 0, 103, 103, 0, 103, 0, 0, 103, 0, 103, + 104, 103, 0, 0, 0, 103, 103, 0, 103, 104, + 103, 0, 0, 0, 0, 0, 0, 0, 103, 103, + 103, 103, 103, 0, 129, 129, 51, 53, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 61, 129, 129, 43, 73, 74, 129, 129, 129, 129, + 127, 123, 129, 125, 124, 128, 129, 129, 0, 0, + + 103, 103, 103, 103, 103, 103, 0, 0, 104, 103, + 103, 103, 0, 0, 103, 103, 103, 103, 103, 0, + 0, 0, 0, 0, 0, 0, 103, 103, 103, 103, + 103, 0, 0, 0, 0, 0, 103, 103, 0, 103, + 0, 103, 0, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 106, 105, 129, 129, 62, + 129, 129, 129, 126, 122, 101, 0, 103, 103, 0, + 103, 103, 0, 103, 0, 0, 103, 0, 103, 104, + 103, 0, 0, 0, 103, 103, 0, 103, 104, 103, + 0, 0, 0, 0, 0, 103, 103, 0, 103, 104, + + 103, 0, 103, 103, 0, 0, 0, 0, 0, 0, + 0, 103, 103, 103, 103, 103, 0, 55, 129, 111, + 118, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 56, 48, 129, 129, 0, 0, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 0, 0, 104, 103, 103, + 103, 0, 0, 103, 103, 103, 103, 103, 0, 0, + 0, 0, 0, 0, 0, 103, 103, 103, 103, 103, + 0, 103, 103, 0, 0, 0, 0, 0, 0, 0, + 103, 103, 103, 103, 103, 0, 0, 0, 0, 0, + 0, 103, 103, 0, 103, 0, 103, 0, 79, 129, + + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 50, 0, 103, 103, 0, 103, 103, 0, 103, 103, + 0, 103, 0, 102, 103, 0, 103, 104, 103, 0, + 0, 0, 103, 103, 0, 103, 104, 103, 0, 0, + 0, 0, 0, 103, 103, 0, 103, 104, 103, 0, + 0, 0, 0, 0, 0, 103, 103, 0, 103, 104, + 103, 0, 103, 103, 103, 0, 0, 0, 0, 0, + 0, 0, 103, 103, 103, 103, 103, 0, 129, 129, + 129, 129, 129, 129, 129, 129, 116, 129, 80, 0, + 0, 103, 103, 103, 103, 103, 103, 103, 103, 103, + + 103, 103, 103, 0, 102, 104, 103, 103, 103, 0, + 0, 103, 103, 103, 103, 103, 0, 0, 0, 0, + 0, 0, 0, 103, 103, 103, 103, 103, 0, 103, + 103, 0, 0, 0, 0, 0, 0, 0, 103, 103, + 103, 103, 103, 0, 103, 103, 103, 0, 0, 0, + 0, 0, 0, 0, 103, 103, 103, 103, 103, 0, + 0, 0, 0, 0, 0, 103, 103, 0, 103, 0, + 103, 0, 129, 129, 129, 120, 129, 129, 129, 129, + 129, 129, 129, 108, 0, 103, 103, 0, 103, 103, + 0, 103, 103, 0, 103, 103, 0, 103, 0, 0, + + 0, 103, 0, 0, 103, 104, 103, 0, 0, 0, + 103, 103, 0, 103, 104, 103, 0, 0, 0, 0, + 0, 103, 103, 0, 103, 104, 103, 0, 0, 0, + 0, 0, 0, 103, 103, 0, 103, 104, 103, 0, + 0, 0, 0, 0, 0, 103, 103, 0, 103, 104, + 103, 0, 103, 103, 103, 0, 0, 0, 0, 0, + 0, 0, 103, 103, 103, 103, 103, 0, 129, 129, + 129, 129, 110, 129, 129, 129, 114, 129, 0, 0, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 0, 0, 0, 104, 0, + + 0, 103, 0, 0, 103, 103, 103, 0, 0, 0, + 0, 0, 0, 0, 103, 103, 103, 0, 103, 103, + 0, 0, 0, 0, 0, 0, 0, 103, 103, 103, + 0, 103, 103, 103, 0, 0, 0, 0, 0, 0, + 0, 103, 103, 103, 0, 103, 103, 103, 0, 0, + 0, 0, 0, 0, 0, 103, 103, 103, 0, 0, + 0, 0, 0, 0, 103, 103, 0, 103, 0, 103, + 0, 107, 119, 121, 115, 129, 129, 129, 129, 0, + 0, 103, 0, 103, 0, 103, 103, 0, 103, 103, + 0, 103, 103, 0, 103, 103, 0, 103, 0, 0, + + 0, 0, 103, 103, 0, 103, 0, 0, 103, 103, + 103, 0, 0, 0, 0, 103, 103, 103, 0, 0, + 0, 0, 0, 103, 103, 103, 0, 0, 0, 0, + 0, 103, 103, 103, 0, 0, 0, 0, 0, 103, + 103, 103, 103, 103, 103, 0, 0, 0, 0, 0, + 0, 0, 103, 103, 103, 0, 129, 129, 129, 129, + 0, 0, 0, 103, 103, 103, 103, 103, 103, 0, + 0, 0, 0, 103, 103, 0, 0, 0, 0, 103, + 103, 103, 0, 0, 0, 0, 0, 103, 103, 103, + 103, 0, 0, 0, 0, 0, 103, 103, 103, 103, + + 0, 0, 0, 0, 0, 103, 103, 103, 103, 0, + 0, 0, 0, 0, 103, 0, 0, 0, 0, 0, + 103, 103, 103, 129, 129, 129, 117, 103, 103, 103, + 103, 103, 103, 103, 103, 0, 0, 0, 0, 103, + 103, 0, 0, 103, 0, 0, 0, 103, 0, 0, + 0, 103, 0, 0, 0, 103, 0, 0, 0, 103, + 103, 103, 103, 0, 0, 0, 0, 0, 103, 112, + 129, 109, 103, 0, 0, 103, 103, 0, 103, 103, + 103, 0, 103, 103, 103, 0, 103, 103, 103, 0, + 103, 103, 103, 0, 0, 0, 0, 103, 113, 103, + + 103, 0, 0, 0, 0, 0, 0, 103, 103, 103, + 0, 0, 103, 103, 103, 103, 103, 0, 103, 103, + 0 + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 5, 1, 1, 6, 1, 7, 1, 8, + 8, 9, 9, 1, 10, 11, 9, 12, 13, 14, + 15, 16, 15, 17, 15, 15, 15, 18, 1, 19, + 20, 21, 1, 1, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, + 25, 26, 25, 1, 27, 1, 28, 29, 30, 31, + + 32, 33, 34, 35, 36, 23, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 23, 1, 52, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst int yy_meta[53] = + { 0, + 1, 2, 2, 1, 2, 1, 3, 2, 1, 4, + 5, 6, 6, 6, 6, 6, 6, 7, 3, 3, + 3, 8, 4, 9, 3, 1, 4, 8, 8, 8, + 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, + 4, 3 + } ; + +static yyconst short int yy_base[1695] = + { 0, + 0, 0, 3429, 52, 6592, 6592, 53, 3407, 59, 3418, + 6592, 63, 6592, 80, 49, 131, 55, 3395, 62, 147, + 186, 147, 106, 36, 129, 134, 55, 3383, 110, 3371, + 190, 193, 140, 101, 149, 198, 205, 148, 125, 3362, + 211, 3354, 3339, 250, 6592, 0, 6592, 0, 248, 266, + 3371, 258, 0, 288, 321, 6592, 6592, 6592, 6592, 6592, + 305, 0, 344, 40, 0, 3356, 3344, 3357, 183, 3329, + 3323, 3328, 3327, 3326, 192, 3334, 3317, 248, 3327, 213, + 3306, 3319, 3285, 3290, 3288, 100, 3291, 3285, 3294, 38, + 305, 0, 0, 165, 135, 3282, 3277, 3264, 3260, 3258, + + 3261, 3263, 3262, 3253, 3243, 3249, 0, 3237, 0, 3220, + 3226, 3217, 3218, 3218, 3204, 282, 3215, 3198, 3209, 3202, + 220, 3197, 326, 3194, 302, 3184, 3196, 3162, 0, 3160, + 3164, 3170, 3161, 3152, 3153, 6592, 6592, 378, 159, 417, + 352, 3162, 439, 3168, 462, 243, 3160, 3133, 3138, 0, + 0, 3135, 361, 3135, 3110, 3099, 3100, 3096, 502, 0, + 0, 3100, 3090, 0, 3102, 107, 3092, 3095, 3056, 3059, + 3072, 3056, 3053, 0, 3058, 3043, 0, 0, 3026, 3016, + 0, 3028, 0, 3024, 3011, 3018, 0, 0, 3017, 3016, + 339, 2998, 2976, 2992, 0, 2987, 0, 2989, 0, 2970, + + 2974, 2968, 2962, 2967, 2940, 2936, 0, 2934, 2946, 0, + 2934, 0, 2933, 0, 0, 0, 2930, 0, 2908, 275, + 0, 0, 2911, 0, 2908, 2909, 384, 531, 554, 2930, + 2928, 2927, 2926, 562, 262, 2877, 2876, 391, 602, 624, + 398, 0, 0, 2852, 2855, 2860, 0, 0, 2857, 0, + 2856, 2842, 0, 2829, 2823, 2825, 0, 479, 2831, 0, + 0, 2839, 2820, 2821, 0, 0, 2819, 0, 0, 0, + 2795, 2786, 2793, 0, 2786, 2789, 2803, 2777, 2773, 2771, + 2761, 0, 2760, 0, 2759, 0, 145, 0, 0, 2752, + 455, 2759, 0, 0, 647, 392, 2785, 2777, 2737, 686, + + 2736, 2735, 708, 405, 731, 753, 515, 0, 2734, 412, + 522, 776, 585, 799, 413, 2733, 2738, 2708, 0, 2717, + 2703, 2686, 0, 2703, 2698, 818, 0, 2688, 2676, 2694, + 0, 2685, 0, 2656, 2649, 0, 0, 2659, 2641, 393, + 2640, 2657, 395, 2654, 0, 2643, 2622, 2636, 2629, 2636, + 2629, 2616, 2617, 2610, 2596, 2611, 491, 854, 2620, 2619, + 877, 435, 2618, 2616, 2615, 2614, 917, 474, 2593, 2592, + 499, 592, 957, 661, 980, 531, 2591, 2597, 2589, 653, + 0, 368, 2587, 667, 1020, 1042, 674, 0, 0, 2576, + 2557, 0, 2551, 2545, 2558, 2543, 2558, 2557, 479, 2542, + + 505, 2542, 2550, 2516, 2526, 0, 2516, 2527, 2517, 2522, + 2521, 2497, 2496, 0, 0, 2500, 0, 2495, 2485, 2498, + 2492, 2466, 2460, 2458, 2463, 2467, 2466, 1064, 532, 2488, + 2467, 1103, 2466, 1125, 2465, 2464, 2460, 1147, 821, 1170, + 1192, 828, 0, 899, 0, 369, 2459, 905, 1215, 1237, + 940, 0, 599, 947, 2451, 1003, 681, 1010, 1260, 1078, + 1283, 533, 2443, 2449, 2414, 2419, 0, 0, 2421, 2423, + 2409, 2395, 2407, 2389, 2387, 2379, 2369, 2370, 2380, 2378, + 0, 2338, 2332, 0, 0, 0, 2345, 2337, 2327, 2314, + 0, 0, 2317, 0, 0, 0, 2304, 1322, 2329, 2319, + + 1345, 561, 2297, 1385, 597, 2296, 2295, 2293, 2290, 1425, + 598, 2289, 682, 1085, 1465, 1092, 1488, 601, 2274, 2280, + 683, 1306, 2278, 1313, 685, 1368, 1528, 1375, 1551, 704, + 2270, 2275, 1070, 0, 1407, 0, 447, 2267, 1413, 1591, + 1613, 1448, 0, 2238, 2229, 2211, 2208, 2213, 2220, 2210, + 2183, 2182, 2175, 2195, 2190, 0, 0, 2189, 2143, 0, + 2156, 2151, 2138, 0, 0, 0, 2165, 1635, 1658, 1680, + 1455, 1703, 1725, 1511, 2164, 2163, 1747, 1517, 1770, 1792, + 1574, 0, 1580, 0, 540, 2153, 1814, 1821, 1843, 1866, + 0, 1872, 0, 1878, 0, 632, 2152, 1884, 1891, 1913, + + 1936, 0, 705, 1942, 2138, 848, 1949, 2137, 1956, 850, + 1963, 1970, 1993, 2000, 726, 2129, 2134, 297, 700, 955, + 956, 1018, 2009, 1019, 746, 318, 414, 2010, 454, 747, + 433, 617, 1103, 2013, 2124, 2123, 2042, 772, 2113, 2082, + 775, 2091, 2122, 776, 2090, 2089, 2087, 2085, 2162, 796, + 2084, 1099, 2030, 2202, 2065, 2225, 823, 2083, 2080, 1100, + 2072, 2079, 2105, 1321, 2112, 2265, 2145, 2288, 827, 2051, + 2057, 828, 2151, 2052, 1382, 2185, 2051, 2192, 1524, 2248, + 2328, 2255, 2351, 829, 2043, 2027, 0, 2310, 0, 2316, + 0, 693, 2017, 2373, 2391, 2413, 2380, 0, 618, 770, + + 848, 974, 1102, 1033, 1321, 1034, 1141, 1589, 913, 1463, + 685, 2009, 2435, 2458, 2480, 2503, 2510, 2532, 2555, 2562, + 2584, 2607, 2007, 2003, 2613, 2635, 2642, 2664, 2687, 0, + 2693, 0, 740, 1979, 2699, 2706, 2728, 2751, 0, 2757, + 0, 2763, 0, 761, 1978, 2769, 2776, 2798, 2821, 0, + 0, 2827, 0, 2833, 0, 837, 1977, 2839, 2846, 2868, + 2891, 0, 0, 953, 2897, 1983, 1587, 2904, 1982, 2911, + 1629, 2918, 2925, 2948, 2955, 957, 1973, 1979, 1590, 2389, + 2390, 1464, 1118, 1526, 2024, 1162, 2200, 1207, 791, 1971, + 1921, 2995, 1017, 1916, 3035, 1102, 1900, 3075, 1143, 1899, + + 3115, 1146, 1851, 1850, 1849, 3154, 3177, 1147, 1830, 1674, + 2978, 3217, 2985, 3240, 1166, 1826, 1786, 2015, 3018, 1784, + 3025, 2119, 3058, 3280, 3065, 3303, 1188, 1776, 1741, 1189, + 3097, 1739, 2324, 3104, 1737, 3138, 2387, 3145, 3343, 3200, + 3366, 1191, 1688, 1643, 0, 1211, 3206, 1623, 2429, 3263, + 1607, 3270, 3072, 3326, 3406, 3333, 3429, 1212, 1597, 1603, + 0, 3388, 0, 3394, 0, 885, 1558, 3451, 3469, 3491, + 3458, 0, 3499, 3500, 3501, 915, 3502, 2263, 1164, 3504, + 1384, 1253, 1254, 1230, 1552, 3534, 3557, 3579, 3602, 3609, + 3631, 3654, 3661, 3683, 3706, 3713, 3735, 3758, 1533, 3765, + + 1259, 1531, 1529, 3787, 3805, 1519, 3794, 0, 3827, 0, + 886, 1495, 3833, 3840, 1489, 3863, 0, 3869, 0, 3875, + 0, 926, 1474, 3881, 3888, 1468, 3911, 0, 0, 3917, + 0, 3923, 0, 1029, 1466, 3929, 3936, 1430, 3959, 0, + 0, 3965, 0, 3971, 0, 1200, 1428, 3977, 3984, 1392, + 4007, 0, 0, 1316, 4013, 1393, 3153, 4020, 1359, 4027, + 3213, 4034, 4041, 4064, 4071, 1318, 1331, 1332, 1650, 1672, + 1695, 1275, 1337, 1718, 3506, 1545, 1423, 3515, 1323, 4110, + 4133, 1322, 1290, 4173, 1384, 1288, 4213, 1461, 1269, 4253, + 1464, 1261, 4293, 1465, 1242, 1240, 4093, 4333, 1238, 4100, + + 0, 1201, 3402, 4156, 4356, 4163, 1148, 1135, 3465, 4196, + 1116, 4203, 3530, 4236, 4379, 4243, 1104, 1110, 1528, 4275, + 1058, 4109, 4282, 1057, 4316, 4250, 4323, 4402, 4425, 1021, + 994, 0, 1586, 4431, 969, 4330, 4438, 967, 4445, 4452, + 4453, 4492, 4466, 958, 927, 0, 1588, 4472, 925, 4487, + 4479, 915, 4515, 4488, 4528, 4535, 4558, 906, 891, 0, + 4564, 0, 4570, 0, 1292, 863, 4576, 4583, 0, 4606, + 0, 1629, 1651, 1673, 1716, 1717, 2471, 4597, 4598, 4627, + 1609, 0, 838, 4667, 0, 4615, 4690, 0, 4650, 4713, + 0, 4657, 4736, 0, 4759, 4766, 0, 4789, 4664, 4796, + + 4803, 4826, 806, 801, 792, 777, 4832, 0, 1394, 734, + 695, 4838, 0, 4844, 0, 1433, 624, 611, 0, 4850, + 0, 4856, 0, 1434, 608, 571, 0, 4862, 0, 4868, + 0, 1644, 570, 569, 0, 4874, 0, 4880, 0, 1756, + 536, 534, 0, 1634, 4886, 529, 4893, 4894, 511, 4907, + 4901, 4915, 4941, 4922, 0, 510, 2201, 1741, 1763, 1762, + 4964, 483, 4933, 0, 0, 0, 0, 0, 0, 4986, + 0, 1800, 469, 448, 0, 4980, 4994, 416, 5001, 0, + 1657, 5007, 374, 5014, 5020, 373, 5028, 0, 0, 1679, + 5034, 371, 5041, 5042, 370, 5055, 0, 0, 1680, 5061, + + 333, 5068, 5069, 329, 5082, 0, 0, 1746, 5088, 318, + 5095, 5096, 281, 5109, 0, 0, 5115, 0, 5121, 0, + 1801, 273, 0, 2324, 2523, 1835, 1836, 0, 6592, 0, + 0, 0, 0, 0, 0, 5128, 5142, 278, 5149, 0, + 6592, 5134, 0, 6592, 0, 5155, 0, 6592, 0, 5167, + 0, 6592, 0, 5173, 0, 6592, 0, 5179, 0, 6592, + 0, 1767, 5185, 276, 5192, 5193, 236, 5206, 0, 1837, + 2326, 1905, 0, 5212, 0, 1791, 5218, 235, 0, 1792, + 5224, 201, 0, 1816, 5231, 199, 0, 1886, 5237, 134, + 0, 1887, 5243, 95, 0, 5249, 0, 6592, 1906, 1888, + + 5255, 94, 0, 0, 0, 0, 0, 0, 1890, 5261, + 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6592, 5278, 5286, 5290, 5293, 5296, 5299, 5302, 5305, 5308, + 5311, 5314, 5317, 5320, 5323, 5326, 5329, 5332, 5336, 5340, + 5343, 5346, 5349, 5352, 5355, 5359, 5363, 5366, 5370, 5372, + 5375, 5378, 5381, 5384, 5387, 5391, 5393, 5397, 5402, 5406, + 5409, 5412, 5415, 5418, 5421, 5424, 5427, 5431, 5435, 5439, + 5444, 5448, 5451, 5454, 5458, 5460, 5463, 5466, 5469, 5472, + 5475, 5479, 5481, 5484, 5487, 5491, 5493, 5496, 5501, 5506, + 5510, 5514, 5518, 5523, 5527, 5530, 5533, 5536, 5539, 5542, + + 5545, 5548, 5552, 5556, 5560, 5564, 5569, 5573, 5577, 5581, + 5584, 5589, 5593, 5598, 5602, 5606, 5610, 5613, 5616, 5619, + 5623, 5625, 5630, 5634, 5637, 5640, 5643, 5646, 5650, 5652, + 5655, 5658, 5662, 5664, 5667, 5670, 5673, 5677, 5679, 5682, + 5685, 5690, 5694, 5699, 5703, 5707, 5711, 5716, 5720, 5723, + 5726, 5729, 5732, 5735, 5738, 5741, 5745, 5749, 5753, 5757, + 5762, 5766, 5770, 5774, 5777, 5782, 5786, 5791, 5795, 5799, + 5803, 5806, 5809, 5814, 5818, 5823, 5827, 5831, 5835, 5838, + 5841, 5844, 5848, 5850, 5855, 5859, 5862, 5865, 5868, 5871, + 5874, 5877, 5881, 5883, 5886, 5889, 5892, 5896, 5898, 5901, + + 5904, 5907, 5910, 5914, 5916, 5919, 5922, 5925, 5928, 5932, + 5934, 5937, 5940, 5943, 5948, 5952, 5957, 5961, 5965, 5969, + 5974, 5978, 5981, 5984, 5987, 5990, 5993, 5996, 5999, 6002, + 6006, 6010, 6014, 6018, 6023, 6027, 6031, 6035, 6038, 6043, + 6047, 6052, 6056, 6060, 6064, 6067, 6070, 6075, 6079, 6084, + 6088, 6092, 6096, 6099, 6102, 6107, 6111, 6116, 6120, 6124, + 6128, 6131, 6134, 6137, 6141, 6143, 6146, 6151, 6155, 6158, + 6161, 6164, 6167, 6170, 6173, 6177, 6181, 6184, 6188, 6191, + 6194, 6198, 6200, 6203, 6206, 6210, 6212, 6215, 6218, 6221, + 6225, 6227, 6230, 6233, 6236, 6240, 6242, 6245, 6248, 6251, + + 6255, 6257, 6260, 6263, 6268, 6272, 6277, 6281, 6285, 6289, + 6294, 6298, 6301, 6304, 6307, 6310, 6313, 6316, 6319, 6323, + 6325, 6328, 6332, 6337, 6340, 6343, 6348, 6352, 6357, 6360, + 6363, 6366, 6371, 6375, 6380, 6383, 6386, 6389, 6394, 6398, + 6403, 6406, 6409, 6412, 6417, 6421, 6426, 6429, 6432, 6435, + 6438, 6442, 6444, 6449, 6453, 6456, 6459, 6462, 6465, 6468, + 6471, 6475, 6480, 6483, 6486, 6489, 6492, 6495, 6498, 6501, + 6504, 6507, 6510, 6513, 6518, 6522, 6525, 6528, 6531, 6535, + 6539, 6543, 6547, 6551, 6554, 6557, 6561, 6564, 6567, 6570, + 6573, 6576, 6580, 6583 + + } ; + +static yyconst short int yy_def[1695] = + { 0, + 1321, 1, 1321, 1321, 1321, 1321, 1321, 1321, 1322, 1321, + 1321, 1321, 1321, 1321, 14, 1321, 1321, 1321, 1321, 14, + 20, 1323, 20, 20, 20, 20, 20, 20, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 1321, 1321, 1321, 1324, 1321, 21, 21, 20, + 1325, 50, 21, 21, 1321, 1321, 1321, 1321, 1321, 1321, + 1323, 1323, 50, 63, 21, 21, 21, 21, 63, 21, + 21, 21, 21, 21, 63, 21, 21, 21, 21, 63, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 1321, 1321, 21, 138, 50, + 140, 1326, 1321, 54, 1321, 145, 1327, 21, 21, 21, + 21, 21, 140, 21, 21, 21, 21, 21, 140, 21, + 21, 21, 21, 21, 21, 159, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 1328, + 21, 1329, 1330, 1321, 234, 1331, 1332, 1321, 1321, 1321, + 239, 1333, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 295, 228, 229, 1334, 1321, + + 1335, 1336, 1321, 1321, 1321, 1321, 305, 1337, 1338, 1339, + 1321, 1321, 312, 1321, 314, 1340, 1333, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 1329, 1341, + 1321, 361, 1342, 1321, 1343, 1344, 1321, 367, 1331, 1345, + 1346, 1321, 1321, 373, 1321, 375, 1347, 1337, 1321, 1321, + 1348, 1349, 1321, 1321, 1321, 1321, 385, 1350, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 428, 358, + 1351, 1321, 305, 1321, 307, 1352, 1353, 1321, 1321, 1321, + 1321, 440, 1354, 1321, 1355, 1356, 1321, 1321, 1321, 1321, + 449, 1357, 1358, 1321, 1348, 1321, 1359, 1321, 1321, 459, + 1321, 461, 1360, 1350, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 1361, 1362, + + 1321, 501, 1363, 1321, 504, 1364, 1321, 1365, 1366, 1321, + 510, 1367, 1368, 1321, 1321, 515, 1321, 517, 1369, 1354, + 1370, 1321, 1355, 1321, 1371, 1321, 1321, 527, 1321, 529, + 1372, 1357, 1321, 1373, 1321, 1374, 1375, 1321, 1321, 1321, + 1321, 540, 1376, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 498, 1377, 1321, 1321, 1321, + 569, 1321, 1321, 572, 1378, 1379, 1321, 1321, 1321, 1321, + 579, 1380, 1321, 1381, 1382, 1321, 1321, 1321, 1321, 588, + 1383, 1321, 1384, 1321, 1385, 1386, 1321, 1321, 1321, 1321, + + 599, 1387, 1388, 1321, 1373, 1389, 1321, 1390, 1321, 1391, + 1321, 1321, 612, 1321, 614, 1392, 1393, 1394, 1394, 1394, + 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, + 1394, 1394, 1394, 1394, 1395, 1396, 1321, 637, 1397, 1321, + 640, 1398, 1321, 643, 1399, 1321, 1400, 1401, 1321, 649, + 1402, 1403, 1321, 1321, 654, 1321, 656, 1404, 1405, 1406, + 1321, 1407, 1321, 1408, 1321, 1321, 666, 1321, 668, 1409, + 1410, 1411, 1321, 1412, 1413, 1321, 1414, 1321, 1415, 1321, + 1321, 681, 1321, 683, 1416, 1417, 1418, 1321, 1419, 1321, + 1420, 1421, 1321, 1321, 1321, 1321, 695, 1422, 1423, 1423, + + 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, + 1423, 1424, 1321, 1321, 1321, 714, 1321, 1321, 717, 1321, + 1321, 720, 1425, 1426, 1321, 1321, 1321, 1321, 727, 1427, + 1321, 1428, 1429, 1321, 1321, 1321, 1321, 736, 1430, 1321, + 1431, 1321, 1432, 1433, 1321, 1321, 1321, 1321, 747, 1434, + 1435, 1321, 1436, 1321, 1437, 1438, 1321, 1321, 1321, 1321, + 759, 1439, 1440, 1441, 1321, 1442, 1443, 1321, 1444, 1321, + 1445, 1321, 1321, 773, 1321, 775, 1446, 1447, 1448, 1448, + 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1449, + 1450, 1321, 792, 1451, 1321, 795, 1452, 1321, 798, 1453, + + 1321, 801, 1454, 1321, 1455, 1321, 1321, 807, 1456, 1457, + 1321, 1321, 812, 1321, 814, 1458, 1459, 1460, 1321, 1461, + 1321, 1462, 1321, 1321, 824, 1321, 826, 1463, 1464, 1465, + 1321, 1466, 1467, 1321, 1468, 1321, 1469, 1321, 1321, 839, + 1321, 841, 1470, 1471, 1472, 1473, 1321, 1474, 1475, 1321, + 1476, 1321, 1477, 1321, 1321, 855, 1321, 857, 1478, 1479, + 1480, 1321, 1481, 1321, 1482, 1483, 1321, 1321, 1321, 1321, + 869, 1484, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, + 1485, 1485, 1485, 1485, 1486, 1321, 1321, 1321, 887, 1321, + 1321, 890, 1321, 1321, 893, 1321, 1321, 896, 1487, 1321, + + 900, 1488, 1489, 1321, 1321, 1490, 905, 1491, 1321, 1492, + 1493, 1321, 1321, 1321, 1494, 914, 1495, 1321, 1496, 1321, + 1497, 1498, 1321, 1321, 1321, 1499, 925, 1500, 1501, 1321, + 1502, 1321, 1503, 1504, 1321, 1321, 1321, 1505, 937, 1506, + 1507, 1321, 1508, 1321, 1509, 1510, 1321, 1321, 1321, 1511, + 949, 1512, 1513, 1514, 1321, 1515, 1516, 1321, 1517, 1321, + 1518, 1321, 1321, 963, 1321, 965, 1519, 1520, 1521, 1521, + 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1522, 1321, + 1321, 981, 1523, 1321, 984, 1524, 1321, 987, 1525, 1321, + 990, 1526, 1321, 993, 1527, 1321, 1321, 1321, 1528, 998, + + 1529, 1530, 1531, 1321, 1321, 1005, 1532, 1533, 1534, 1321, + 1535, 1321, 1536, 1321, 1321, 1015, 1537, 1538, 1539, 1321, + 1540, 1541, 1321, 1542, 1321, 1543, 1321, 1321, 1028, 1544, + 1545, 1546, 1547, 1321, 1548, 1549, 1321, 1550, 1321, 1551, + 1321, 1321, 1042, 1552, 1553, 1554, 1555, 1321, 1556, 1557, + 1321, 1558, 1321, 1559, 1321, 1321, 1056, 1560, 1561, 1562, + 1321, 1563, 1321, 1564, 1565, 1321, 1321, 1321, 1566, 1068, + 1567, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1321, + 1080, 1569, 1570, 1321, 1571, 1084, 1321, 1572, 1087, 1321, + 1573, 1090, 1321, 1574, 1093, 1321, 1575, 1096, 1576, 1321, + + 1321, 1101, 1577, 1578, 1579, 1580, 1321, 1581, 1582, 1321, + 1583, 1321, 1584, 1321, 1585, 1586, 1321, 1587, 1588, 1321, + 1589, 1321, 1590, 1591, 1321, 1592, 1593, 1321, 1594, 1321, + 1595, 1596, 1321, 1597, 1598, 1321, 1599, 1321, 1600, 1601, + 1321, 1602, 1603, 1604, 1321, 1605, 1606, 1321, 1607, 1321, + 1608, 1321, 1321, 1153, 1609, 1610, 1611, 1611, 1611, 1611, + 1321, 1612, 1161, 1613, 1614, 1615, 1616, 1617, 1618, 1321, + 1619, 1620, 1321, 1621, 1622, 1623, 1321, 1624, 1321, 1625, + 1626, 1321, 1627, 1628, 1321, 1629, 1321, 1630, 1631, 1632, + 1321, 1633, 1634, 1321, 1635, 1321, 1636, 1637, 1638, 1321, + + 1639, 1640, 1321, 1641, 1321, 1642, 1643, 1644, 1321, 1645, + 1646, 1321, 1647, 1321, 1648, 1649, 1321, 1650, 1321, 1651, + 1652, 1321, 1653, 1654, 1654, 1654, 1654, 1655, 1321, 1656, + 1657, 1658, 1659, 1660, 1661, 1662, 1321, 1663, 1321, 1664, + 1321, 1321, 1665, 1321, 1666, 1321, 1667, 1321, 1668, 1321, + 1669, 1321, 1670, 1321, 1671, 1321, 1672, 1321, 1673, 1321, + 1649, 1674, 1321, 1650, 1675, 1321, 1651, 1321, 1676, 1654, + 1654, 1654, 1677, 1321, 1678, 1679, 1321, 1665, 1666, 1680, + 1321, 1667, 1668, 1681, 1321, 1669, 1670, 1682, 1321, 1671, + 1672, 1683, 1321, 1673, 1684, 1321, 1685, 1321, 1654, 1686, + + 1321, 1678, 1687, 1688, 1689, 1690, 1691, 1684, 1692, 1321, + 1685, 1693, 1687, 1688, 1689, 1690, 1691, 1694, 1693, 1694, + 0, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321 + + } ; + +static yyconst short int yy_nxt[6645] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 11, + 13, 14, 15, 15, 15, 15, 15, 16, 17, 18, + 19, 20, 21, 21, 11, 22, 13, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 21, 32, 33, 34, + 35, 36, 21, 37, 38, 39, 40, 41, 42, 21, + 21, 43, 44, 44, 177, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 69, 44, 44, 44, 44, + 44, 44, 53, 56, 57, 1296, 44, 44, 44, 70, + 44, 59, 60, 53, 44, 149, 71, 178, 44, 48, + 49, 50, 50, 50, 50, 50, 50, 51, 53, 78, + + 79, 52, 53, 54, 1274, 1258, 48, 52, 52, 52, + 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, + 53, 44, 104, 63, 44, 64, 44, 81, 172, 44, + 65, 105, 129, 173, 1254, 66, 53, 61, 55, 67, + 61, 68, 61, 82, 128, 61, 44, 53, 52, 52, + 52, 52, 52, 52, 61, 75, 72, 99, 129, 73, + 53, 100, 61, 74, 184, 76, 106, 121, 77, 185, + 101, 102, 53, 122, 347, 123, 103, 124, 107, 348, + 108, 125, 109, 126, 127, 110, 53, 53, 53, 53, + + 53, 53, 53, 1321, 182, 92, 93, 53, 53, 1250, + 183, 1246, 153, 53, 53, 53, 53, 53, 53, 84, + 94, 159, 85, 86, 95, 87, 53, 88, 96, 89, + 97, 90, 116, 111, 91, 53, 117, 98, 112, 113, + 131, 114, 115, 166, 118, 1242, 1219, 210, 132, 119, + 44, 120, 133, 44, 134, 44, 53, 162, 44, 138, + 139, 139, 139, 139, 139, 211, 1321, 44, 53, 141, + 141, 141, 141, 141, 141, 44, 49, 140, 140, 140, + 140, 140, 140, 163, 291, 1321, 1217, 141, 1170, 164, + 1069, 1138, 1321, 141, 141, 141, 141, 141, 141, 144, + + 144, 144, 144, 144, 144, 61, 48, 292, 61, 144, + 61, 1321, 204, 61, 179, 144, 144, 144, 144, 144, + 144, 44, 61, 48, 44, 205, 44, 48, 1136, 44, + 61, 216, 145, 146, 146, 146, 146, 146, 44, 1130, + 180, 217, 147, 1128, 48, 181, 44, 706, 147, 147, + 147, 147, 147, 147, 53, 141, 141, 141, 141, 141, + 141, 213, 53, 231, 231, 231, 231, 231, 231, 272, + 214, 53, 231, 231, 231, 231, 231, 231, 238, 304, + 1122, 1120, 273, 1114, 1112, 240, 434, 148, 227, 139, + 139, 139, 139, 139, 139, 295, 296, 296, 296, 296, + + 296, 228, 310, 311, 311, 311, 311, 311, 1321, 313, + 313, 313, 313, 313, 313, 53, 371, 372, 372, 372, + 372, 372, 380, 48, 410, 414, 1107, 228, 229, 229, + 229, 229, 229, 229, 230, 381, 1321, 411, 231, 415, + 48, 53, 48, 707, 231, 231, 231, 231, 231, 231, + 234, 235, 235, 235, 235, 235, 236, 384, 1321, 48, + 237, 381, 1321, 48, 386, 369, 237, 237, 237, 237, + 237, 237, 238, 239, 239, 239, 239, 239, 239, 240, + 48, 709, 350, 241, 1321, 242, 1162, 351, 326, 241, + 241, 241, 241, 241, 241, 327, 352, 1321, 353, 354, + + 1229, 355, 428, 429, 429, 429, 429, 429, 328, 444, + 473, 242, 53, 231, 231, 231, 231, 231, 231, 474, + 1067, 1063, 445, 1321, 329, 1321, 374, 374, 374, 374, + 374, 374, 380, 311, 311, 311, 311, 311, 311, 1061, + 476, 251, 297, 297, 297, 297, 297, 297, 445, 477, + 439, 369, 297, 1097, 1321, 53, 1321, 570, 297, 297, + 297, 297, 297, 297, 49, 298, 298, 298, 298, 298, + 298, 230, 304, 305, 305, 305, 305, 305, 305, 306, + 1321, 53, 1321, 307, 1321, 308, 369, 1094, 369, 307, + 307, 307, 307, 307, 307, 1321, 383, 383, 383, 383, + + 383, 383, 444, 372, 372, 372, 372, 372, 372, 533, + 1321, 308, 238, 312, 312, 312, 312, 312, 312, 240, + 1321, 1321, 534, 313, 1321, 1091, 48, 48, 369, 313, + 313, 313, 313, 313, 313, 314, 315, 315, 315, 315, + 315, 1088, 448, 48, 48, 316, 1321, 1321, 534, 573, + 1321, 316, 316, 316, 316, 316, 316, 357, 296, 296, + 296, 296, 296, 296, 453, 454, 454, 454, 454, 454, + 358, 1321, 447, 447, 447, 447, 447, 447, 457, 458, + 458, 458, 458, 458, 1321, 460, 460, 460, 460, 460, + 460, 535, 583, 592, 48, 594, 358, 361, 362, 362, + + 362, 362, 362, 539, 536, 584, 593, 363, 595, 48, + 541, 48, 369, 363, 363, 363, 363, 363, 363, 367, + 368, 368, 368, 368, 368, 369, 48, 1321, 687, 370, + 536, 584, 593, 699, 595, 370, 370, 370, 370, 370, + 370, 304, 373, 373, 373, 373, 373, 373, 306, 1321, + 578, 1085, 374, 1321, 687, 48, 48, 715, 374, 374, + 374, 374, 374, 374, 375, 376, 376, 376, 376, 376, + 369, 587, 48, 48, 377, 1321, 710, 705, 718, 48, + 377, 377, 377, 377, 377, 377, 238, 382, 382, 382, + 382, 382, 382, 240, 369, 1321, 48, 383, 1321, 1321, + + 48, 779, 997, 383, 383, 383, 383, 383, 383, 384, + 385, 385, 385, 385, 385, 385, 386, 48, 369, 1321, + 387, 1321, 388, 369, 1321, 1321, 387, 387, 387, 387, + 387, 387, 513, 514, 514, 514, 514, 514, 1321, 516, + 516, 516, 516, 516, 516, 1321, 1321, 598, 388, 395, + 1321, 751, 1321, 396, 721, 1162, 397, 48, 688, 398, + 690, 399, 400, 401, 402, 430, 430, 430, 430, 430, + 430, 689, 1321, 691, 48, 430, 1321, 751, 1321, 780, + 870, 430, 430, 430, 430, 430, 430, 304, 433, 433, + 433, 433, 433, 433, 434, 694, 726, 689, 435, 691, + + 308, 948, 696, 888, 435, 435, 435, 435, 435, 435, + 521, 522, 522, 522, 522, 522, 525, 526, 526, 526, + 526, 526, 48, 369, 48, 944, 308, 439, 440, 440, + 440, 440, 440, 440, 441, 942, 735, 936, 442, 48, + 443, 48, 788, 891, 442, 442, 442, 442, 442, 442, + 1321, 528, 528, 528, 528, 528, 528, 533, 454, 454, + 454, 454, 454, 454, 48, 48, 443, 304, 446, 446, + 446, 446, 446, 446, 434, 369, 861, 932, 447, 930, + 1321, 48, 48, 48, 447, 447, 447, 447, 447, 447, + 448, 449, 449, 449, 449, 449, 449, 450, 700, 701, + + 48, 451, 861, 452, 924, 781, 1321, 451, 451, 451, + 451, 451, 451, 238, 456, 456, 456, 456, 456, 456, + 535, 458, 458, 458, 458, 458, 458, 48, 48, 452, + 384, 459, 459, 459, 459, 459, 459, 386, 369, 746, + 1321, 460, 48, 48, 48, 48, 894, 460, 460, 460, + 460, 460, 460, 461, 462, 462, 462, 462, 462, 48, + 48, 702, 704, 463, 783, 785, 1321, 920, 918, 463, + 463, 463, 463, 463, 463, 429, 429, 429, 429, 429, + 429, 603, 604, 604, 604, 604, 604, 498, 1321, 538, + 538, 538, 538, 538, 538, 583, 514, 514, 514, 514, + + 514, 514, 1321, 586, 586, 586, 586, 586, 586, 731, + 740, 48, 48, 498, 501, 502, 502, 502, 502, 502, + 913, 369, 732, 741, 503, 1321, 909, 48, 48, 48, + 503, 503, 503, 503, 503, 503, 504, 505, 505, 505, + 505, 505, 711, 782, 48, 904, 506, 878, 732, 741, + 48, 1321, 506, 506, 506, 506, 506, 506, 510, 511, + 511, 511, 511, 511, 369, 369, 1321, 48, 512, 1321, + 1321, 48, 786, 48, 512, 512, 512, 512, 512, 512, + 439, 515, 515, 515, 515, 515, 515, 441, 48, 1321, + 48, 516, 1321, 882, 974, 1321, 1321, 516, 516, 516, + + 516, 516, 516, 517, 518, 518, 518, 518, 518, 369, + 758, 1321, 929, 519, 1321, 1321, 48, 897, 369, 519, + 519, 519, 519, 519, 519, 448, 527, 527, 527, 527, + 527, 527, 450, 48, 941, 1321, 528, 1321, 929, 48, + 1321, 884, 528, 528, 528, 528, 528, 528, 529, 530, + 530, 530, 530, 530, 369, 1104, 48, 980, 531, 1097, + 941, 1321, 48, 48, 531, 531, 531, 531, 531, 531, + 384, 537, 537, 537, 537, 537, 537, 386, 1094, 48, + 48, 538, 1321, 977, 48, 978, 1091, 538, 538, 538, + 538, 538, 538, 539, 540, 540, 540, 540, 540, 540, + + 541, 48, 868, 1075, 542, 1088, 543, 1085, 1321, 870, + 542, 542, 542, 542, 542, 542, 592, 522, 522, 522, + 522, 522, 522, 304, 524, 524, 524, 524, 524, 524, + 48, 742, 543, 566, 566, 566, 566, 566, 566, 1060, + 980, 1321, 868, 566, 743, 1321, 48, 48, 1069, 566, + 566, 566, 566, 566, 566, 439, 569, 569, 569, 569, + 569, 569, 570, 48, 784, 1060, 571, 1321, 443, 864, + 743, 1321, 571, 571, 571, 571, 571, 571, 594, 526, + 526, 526, 526, 526, 526, 1321, 597, 597, 597, 597, + 597, 597, 752, 48, 443, 448, 572, 572, 572, 572, + + 572, 572, 573, 862, 904, 753, 574, 1321, 452, 369, + 48, 1085, 574, 574, 574, 574, 574, 574, 606, 607, + 607, 607, 607, 607, 610, 611, 611, 611, 611, 611, + 976, 753, 48, 1321, 452, 578, 579, 579, 579, 579, + 579, 579, 580, 913, 924, 897, 581, 369, 582, 48, + 1088, 1091, 581, 581, 581, 581, 581, 581, 1321, 613, + 613, 613, 613, 613, 613, 1321, 516, 516, 516, 516, + 516, 516, 48, 48, 582, 439, 585, 585, 585, 585, + 585, 585, 570, 894, 1321, 369, 586, 1321, 1321, 48, + 48, 891, 586, 586, 586, 586, 586, 586, 587, 588, + + 588, 588, 588, 588, 588, 589, 369, 877, 789, 590, + 1321, 591, 888, 1321, 1321, 590, 590, 590, 590, 590, + 590, 1321, 528, 528, 528, 528, 528, 528, 652, 653, + 653, 653, 653, 653, 754, 48, 369, 591, 448, 596, + 596, 596, 596, 596, 596, 573, 999, 755, 369, 597, + 980, 1119, 48, 879, 48, 597, 597, 597, 597, 597, + 597, 598, 599, 599, 599, 599, 599, 599, 600, 980, + 880, 48, 601, 755, 602, 696, 1078, 1119, 601, 601, + 601, 601, 601, 601, 1321, 655, 655, 655, 655, 655, + 655, 660, 661, 661, 661, 661, 661, 862, 48, 48, + + 602, 539, 612, 612, 612, 612, 612, 612, 541, 1127, + 863, 1135, 613, 758, 950, 48, 48, 754, 613, 613, + 613, 613, 613, 613, 614, 615, 615, 615, 615, 615, + 787, 873, 1321, 752, 616, 1127, 863, 1135, 48, 864, + 616, 616, 616, 616, 616, 616, 637, 638, 638, 638, + 638, 638, 865, 746, 936, 48, 639, 1216, 1321, 48, + 48, 1094, 639, 639, 639, 639, 639, 639, 439, 515, + 515, 515, 515, 515, 515, 570, 48, 48, 865, 516, + 1245, 48, 48, 1216, 909, 516, 516, 516, 516, 516, + 516, 640, 641, 641, 641, 641, 641, 910, 48, 48, + + 1072, 642, 1249, 1253, 48, 938, 1245, 642, 642, 642, + 642, 642, 642, 448, 527, 527, 527, 527, 527, 527, + 573, 48, 1073, 910, 528, 48, 48, 48, 1249, 1253, + 528, 528, 528, 528, 528, 528, 643, 644, 644, 644, + 644, 644, 48, 48, 48, 1074, 645, 742, 1157, 740, + 48, 735, 645, 645, 645, 645, 645, 645, 649, 650, + 650, 650, 650, 650, 369, 1076, 948, 48, 651, 1257, + 1225, 48, 48, 1097, 651, 651, 651, 651, 651, 651, + 578, 654, 654, 654, 654, 654, 654, 580, 48, 48, + 1295, 655, 1226, 926, 731, 1257, 726, 655, 655, 655, + + 655, 655, 655, 656, 657, 657, 657, 657, 657, 369, + 997, 1067, 1227, 658, 1303, 1304, 1295, 1162, 1069, 658, + 658, 658, 658, 658, 658, 664, 665, 665, 665, 665, + 665, 587, 666, 666, 666, 666, 666, 666, 589, 1305, + 1303, 1304, 667, 915, 48, 48, 48, 906, 667, 667, + 667, 667, 667, 667, 668, 669, 669, 669, 669, 669, + 369, 48, 48, 48, 670, 1305, 806, 791, 897, 1272, + 670, 670, 670, 670, 670, 670, 1321, 667, 667, 667, + 667, 667, 667, 672, 673, 673, 673, 673, 673, 675, + 676, 676, 676, 676, 676, 679, 680, 680, 680, 680, + + 680, 598, 681, 681, 681, 681, 681, 681, 600, 1306, + 1307, 1312, 682, 1318, 48, 48, 894, 891, 682, 682, + 682, 682, 682, 682, 683, 684, 684, 684, 684, 684, + 369, 48, 48, 888, 685, 1306, 1307, 1312, 886, 1318, + 685, 685, 685, 685, 685, 685, 1321, 682, 682, 682, + 682, 682, 682, 604, 604, 604, 604, 604, 604, 688, + 607, 607, 607, 607, 607, 607, 384, 609, 609, 609, + 609, 609, 609, 690, 611, 611, 611, 611, 611, 611, + 539, 692, 692, 692, 692, 692, 692, 541, 791, 694, + 870, 693, 690, 688, 721, 718, 715, 693, 693, 693, + + 693, 693, 693, 1321, 693, 693, 693, 693, 693, 693, + 694, 695, 695, 695, 695, 695, 695, 696, 48, 48, + 806, 697, 48, 698, 791, 918, 791, 697, 697, 697, + 697, 697, 697, 48, 541, 48, 48, 598, 919, 48, + 731, 653, 653, 653, 653, 653, 653, 703, 708, 698, + 48, 289, 578, 714, 714, 714, 714, 714, 714, 715, + 760, 594, 592, 716, 919, 582, 881, 587, 748, 716, + 716, 716, 716, 716, 716, 1321, 734, 734, 734, 734, + 734, 734, 740, 661, 661, 661, 661, 661, 661, 583, + 578, 582, 587, 717, 717, 717, 717, 717, 717, 718, + + 737, 728, 725, 719, 648, 591, 636, 721, 718, 719, + 719, 719, 719, 719, 719, 439, 663, 663, 663, 663, + 663, 663, 742, 665, 665, 665, 665, 665, 665, 920, + 715, 591, 598, 720, 720, 720, 720, 720, 720, 721, + 713, 636, 921, 722, 539, 602, 696, 535, 533, 722, + 722, 722, 722, 722, 722, 1321, 745, 745, 745, 745, + 745, 745, 673, 673, 673, 673, 673, 673, 921, 573, + 570, 602, 726, 727, 727, 727, 727, 727, 727, 728, + 648, 636, 636, 729, 634, 730, 633, 632, 631, 729, + 729, 729, 729, 729, 729, 752, 676, 676, 676, 676, + + 676, 676, 448, 678, 678, 678, 678, 678, 678, 48, + 48, 730, 578, 733, 733, 733, 733, 733, 733, 715, + 630, 629, 628, 734, 627, 626, 48, 48, 625, 734, + 734, 734, 734, 734, 734, 735, 736, 736, 736, 736, + 736, 736, 737, 883, 1224, 624, 738, 623, 739, 622, + 621, 620, 738, 738, 738, 738, 738, 738, 754, 680, + 680, 680, 680, 680, 680, 1321, 757, 757, 757, 757, + 757, 757, 48, 619, 739, 587, 744, 744, 744, 744, + 744, 744, 718, 618, 386, 448, 745, 600, 444, 48, + 439, 589, 745, 745, 745, 745, 745, 745, 746, 747, + + 747, 747, 747, 747, 747, 748, 580, 577, 973, 749, + 509, 750, 500, 573, 570, 749, 749, 749, 749, 749, + 749, 764, 765, 765, 765, 765, 765, 767, 768, 768, + 768, 768, 768, 48, 930, 48, 568, 750, 598, 756, + 756, 756, 756, 756, 756, 721, 500, 931, 565, 757, + 48, 564, 48, 563, 562, 757, 757, 757, 757, 757, + 757, 758, 759, 759, 759, 759, 759, 759, 760, 1270, + 561, 1299, 761, 931, 762, 560, 559, 558, 761, 761, + 761, 761, 761, 761, 771, 772, 772, 772, 772, 772, + 1321, 774, 774, 774, 774, 774, 774, 932, 48, 48, + + 762, 694, 773, 773, 773, 773, 773, 773, 696, 557, + 933, 556, 774, 555, 554, 48, 48, 553, 774, 774, + 774, 774, 774, 774, 775, 776, 776, 776, 776, 776, + 874, 875, 876, 552, 777, 551, 933, 550, 549, 942, + 777, 777, 777, 777, 777, 777, 792, 793, 793, 793, + 793, 793, 943, 548, 547, 546, 794, 545, 544, 384, + 541, 380, 794, 794, 794, 794, 794, 794, 578, 654, + 654, 654, 654, 654, 654, 715, 434, 509, 943, 655, + 48, 500, 434, 434, 500, 655, 655, 655, 655, 655, + 655, 795, 796, 796, 796, 796, 796, 48, 357, 497, + + 496, 797, 495, 494, 493, 492, 1158, 797, 797, 797, + 797, 797, 797, 1321, 655, 655, 655, 655, 655, 655, + 587, 666, 666, 666, 666, 666, 666, 718, 491, 490, + 286, 667, 48, 207, 489, 488, 487, 667, 667, 667, + 667, 667, 667, 798, 799, 799, 799, 799, 799, 48, + 486, 485, 484, 800, 483, 482, 481, 480, 1271, 800, + 800, 800, 800, 800, 800, 1321, 667, 667, 667, 667, + 667, 667, 598, 681, 681, 681, 681, 681, 681, 721, + 479, 478, 475, 682, 472, 471, 470, 469, 468, 682, + 682, 682, 682, 682, 682, 801, 802, 802, 802, 802, + + 802, 467, 466, 465, 240, 803, 369, 304, 450, 441, + 369, 803, 803, 803, 803, 803, 803, 1321, 682, 682, + 682, 682, 682, 682, 807, 808, 808, 808, 808, 808, + 369, 438, 366, 360, 809, 434, 432, 360, 427, 426, + 809, 809, 809, 809, 809, 809, 810, 811, 811, 811, + 811, 811, 726, 812, 812, 812, 812, 812, 812, 728, + 425, 424, 423, 813, 422, 421, 420, 419, 418, 813, + 813, 813, 813, 813, 813, 814, 815, 815, 815, 815, + 815, 369, 417, 416, 413, 816, 412, 409, 408, 407, + 406, 816, 816, 816, 816, 816, 816, 1321, 813, 813, + + 813, 813, 813, 813, 818, 819, 819, 819, 819, 819, + 822, 823, 823, 823, 823, 823, 735, 824, 824, 824, + 824, 824, 824, 737, 405, 107, 404, 825, 403, 394, + 393, 392, 391, 825, 825, 825, 825, 825, 825, 826, + 827, 827, 827, 827, 827, 369, 390, 389, 238, 828, + 386, 369, 366, 360, 360, 828, 828, 828, 828, 828, + 828, 1321, 825, 825, 825, 825, 825, 825, 830, 831, + 831, 831, 831, 831, 833, 834, 834, 834, 834, 834, + 837, 838, 838, 838, 838, 838, 746, 839, 839, 839, + 839, 839, 839, 748, 1321, 227, 356, 840, 349, 346, + + 345, 344, 343, 840, 840, 840, 840, 840, 840, 841, + 842, 842, 842, 842, 842, 369, 342, 341, 340, 843, + 339, 338, 337, 336, 335, 843, 843, 843, 843, 843, + 843, 1321, 840, 840, 840, 840, 840, 840, 846, 847, + 847, 847, 847, 847, 849, 850, 850, 850, 850, 850, + 853, 854, 854, 854, 854, 854, 758, 855, 855, 855, + 855, 855, 855, 760, 334, 333, 332, 856, 331, 330, + 325, 324, 269, 856, 856, 856, 856, 856, 856, 857, + 858, 858, 858, 858, 858, 369, 323, 322, 321, 859, + 320, 319, 318, 306, 236, 859, 859, 859, 859, 859, + + 859, 1321, 856, 856, 856, 856, 856, 856, 765, 765, + 765, 765, 765, 765, 862, 768, 768, 768, 768, 768, + 768, 539, 770, 770, 770, 770, 770, 770, 864, 772, + 772, 772, 772, 772, 772, 694, 866, 866, 866, 866, + 866, 866, 696, 303, 233, 230, 867, 300, 129, 294, + 293, 290, 867, 867, 867, 867, 867, 867, 1321, 867, + 867, 867, 867, 867, 867, 868, 869, 869, 869, 869, + 869, 869, 870, 289, 269, 288, 871, 287, 872, 286, + 285, 284, 871, 871, 871, 871, 871, 871, 909, 811, + 811, 811, 811, 811, 811, 1321, 912, 912, 912, 912, + + 912, 912, 283, 282, 872, 726, 887, 887, 887, 887, + 887, 887, 888, 281, 280, 279, 889, 278, 730, 277, + 276, 275, 889, 889, 889, 889, 889, 889, 918, 819, + 819, 819, 819, 819, 819, 578, 821, 821, 821, 821, + 821, 821, 274, 271, 730, 735, 890, 890, 890, 890, + 890, 890, 891, 270, 269, 268, 892, 267, 739, 266, + 265, 264, 892, 892, 892, 892, 892, 892, 920, 823, + 823, 823, 823, 823, 823, 1321, 923, 923, 923, 923, + 923, 923, 944, 263, 739, 746, 893, 893, 893, 893, + 893, 893, 894, 262, 261, 945, 895, 260, 750, 259, + + 258, 257, 895, 895, 895, 895, 895, 895, 831, 831, + 831, 831, 831, 831, 930, 834, 834, 834, 834, 834, + 834, 945, 256, 255, 750, 758, 896, 896, 896, 896, + 896, 896, 897, 254, 253, 252, 898, 250, 762, 249, + 248, 247, 898, 898, 898, 898, 898, 898, 587, 836, + 836, 836, 836, 836, 836, 932, 838, 838, 838, 838, + 838, 838, 246, 1061, 762, 900, 901, 901, 901, 901, + 901, 902, 245, 244, 243, 903, 1062, 240, 49, 233, + 226, 903, 903, 903, 903, 903, 903, 904, 905, 905, + 905, 905, 905, 905, 906, 225, 224, 223, 907, 222, + + 908, 221, 1062, 220, 907, 907, 907, 907, 907, 907, + 1321, 935, 935, 935, 935, 935, 935, 847, 847, 847, + 847, 847, 847, 1063, 219, 218, 908, 726, 911, 911, + 911, 911, 911, 911, 888, 215, 1064, 212, 912, 209, + 208, 207, 206, 203, 912, 912, 912, 912, 912, 912, + 913, 914, 914, 914, 914, 914, 914, 915, 202, 201, + 200, 916, 1064, 917, 199, 198, 197, 916, 916, 916, + 916, 916, 916, 942, 850, 850, 850, 850, 850, 850, + 598, 852, 852, 852, 852, 852, 852, 196, 195, 917, + 735, 922, 922, 922, 922, 922, 922, 891, 194, 193, + + 192, 923, 191, 190, 189, 188, 187, 923, 923, 923, + 923, 923, 923, 924, 925, 925, 925, 925, 925, 925, + 926, 186, 176, 175, 927, 174, 928, 171, 170, 169, + 927, 927, 927, 927, 927, 927, 944, 854, 854, 854, + 854, 854, 854, 1321, 947, 947, 947, 947, 947, 947, + 168, 167, 928, 746, 934, 934, 934, 934, 934, 934, + 894, 165, 161, 160, 935, 158, 157, 156, 155, 154, + 935, 935, 935, 935, 935, 935, 936, 937, 937, 937, + 937, 937, 937, 938, 152, 151, 150, 939, 143, 940, + 136, 135, 130, 939, 939, 939, 939, 939, 939, 954, + + 955, 955, 955, 955, 955, 957, 958, 958, 958, 958, + 958, 83, 1107, 80, 58, 940, 758, 946, 946, 946, + 946, 946, 946, 897, 47, 1108, 45, 947, 1321, 1321, + 1321, 1321, 1321, 947, 947, 947, 947, 947, 947, 948, + 949, 949, 949, 949, 949, 949, 950, 1321, 1321, 1321, + 951, 1108, 952, 1321, 1321, 1321, 951, 951, 951, 951, + 951, 951, 961, 962, 962, 962, 962, 962, 1321, 964, + 964, 964, 964, 964, 964, 1112, 1321, 1321, 952, 868, + 963, 963, 963, 963, 963, 963, 870, 1321, 1113, 1321, + 964, 1321, 1321, 1321, 1321, 1321, 964, 964, 964, 964, + + 964, 964, 965, 966, 966, 966, 966, 966, 48, 48, + 48, 48, 967, 48, 1113, 48, 1321, 1321, 967, 967, + 967, 967, 967, 967, 48, 48, 48, 48, 48, 1321, + 48, 1321, 48, 1321, 1321, 1321, 969, 970, 971, 1321, + 1114, 48, 972, 1077, 975, 981, 982, 982, 982, 982, + 982, 1321, 1321, 1115, 1321, 983, 1079, 1321, 1321, 1321, + 1321, 983, 983, 983, 983, 983, 983, 726, 812, 812, + 812, 812, 812, 812, 888, 1321, 1321, 1321, 813, 1115, + 1321, 1321, 1321, 1321, 813, 813, 813, 813, 813, 813, + 984, 985, 985, 985, 985, 985, 1321, 1321, 1321, 1321, + + 986, 1321, 1321, 1321, 1321, 1321, 986, 986, 986, 986, + 986, 986, 1321, 813, 813, 813, 813, 813, 813, 735, + 824, 824, 824, 824, 824, 824, 891, 1321, 1321, 1321, + 825, 1321, 1321, 1321, 1321, 1321, 825, 825, 825, 825, + 825, 825, 987, 988, 988, 988, 988, 988, 1321, 1321, + 1321, 1321, 989, 1321, 1321, 1321, 1321, 1321, 989, 989, + 989, 989, 989, 989, 1321, 825, 825, 825, 825, 825, + 825, 746, 839, 839, 839, 839, 839, 839, 894, 1321, + 1321, 1321, 840, 1321, 1321, 1321, 1321, 1321, 840, 840, + 840, 840, 840, 840, 990, 991, 991, 991, 991, 991, + + 1321, 1321, 1321, 1321, 992, 1321, 1321, 1321, 1321, 1321, + 992, 992, 992, 992, 992, 992, 1321, 840, 840, 840, + 840, 840, 840, 758, 855, 855, 855, 855, 855, 855, + 897, 1321, 1321, 1321, 856, 1321, 1321, 1321, 1321, 1321, + 856, 856, 856, 856, 856, 856, 993, 994, 994, 994, + 994, 994, 1321, 1321, 1321, 1321, 995, 1321, 1321, 1321, + 1321, 1321, 995, 995, 995, 995, 995, 995, 1321, 856, + 856, 856, 856, 856, 856, 997, 998, 998, 998, 998, + 998, 998, 999, 1321, 1321, 1321, 1000, 1321, 1001, 1321, + 1321, 1321, 1000, 1000, 1000, 1000, 1000, 1000, 1003, 1004, + + 1004, 1004, 1004, 1004, 1321, 1006, 1006, 1006, 1006, 1006, + 1006, 1321, 1321, 1321, 1001, 904, 1005, 1005, 1005, 1005, + 1005, 1005, 906, 1321, 1321, 1321, 1006, 1321, 1321, 1321, + 1321, 1321, 1006, 1006, 1006, 1006, 1006, 1006, 1009, 1010, + 1010, 1010, 1010, 1010, 1013, 1014, 1014, 1014, 1014, 1014, + 913, 1015, 1015, 1015, 1015, 1015, 1015, 915, 1321, 1321, + 1321, 1016, 1321, 1321, 1321, 1321, 1321, 1016, 1016, 1016, + 1016, 1016, 1016, 1321, 1016, 1016, 1016, 1016, 1016, 1016, + 1019, 1020, 1020, 1020, 1020, 1020, 1022, 1023, 1023, 1023, + 1023, 1023, 1026, 1027, 1027, 1027, 1027, 1027, 924, 1028, + + 1028, 1028, 1028, 1028, 1028, 926, 1321, 1321, 1321, 1029, + 1321, 1321, 1321, 1321, 1321, 1029, 1029, 1029, 1029, 1029, + 1029, 1321, 1029, 1029, 1029, 1029, 1029, 1029, 1033, 1034, + 1034, 1034, 1034, 1034, 1036, 1037, 1037, 1037, 1037, 1037, + 1040, 1041, 1041, 1041, 1041, 1041, 936, 1042, 1042, 1042, + 1042, 1042, 1042, 938, 1321, 1321, 1321, 1043, 1321, 1321, + 1321, 1321, 1321, 1043, 1043, 1043, 1043, 1043, 1043, 1321, + 1043, 1043, 1043, 1043, 1043, 1043, 1047, 1048, 1048, 1048, + 1048, 1048, 1050, 1051, 1051, 1051, 1051, 1051, 1054, 1055, + 1055, 1055, 1055, 1055, 948, 1056, 1056, 1056, 1056, 1056, + + 1056, 950, 1321, 1321, 1321, 1057, 1321, 1321, 1321, 1321, + 1321, 1057, 1057, 1057, 1057, 1057, 1057, 1321, 1057, 1057, + 1057, 1057, 1057, 1057, 955, 955, 955, 955, 955, 955, + 1061, 958, 958, 958, 958, 958, 958, 694, 960, 960, + 960, 960, 960, 960, 1063, 962, 962, 962, 962, 962, + 962, 868, 1065, 1065, 1065, 1065, 1065, 1065, 870, 1321, + 1321, 1321, 1066, 1321, 1321, 1321, 1321, 1321, 1066, 1066, + 1066, 1066, 1066, 1066, 1321, 1066, 1066, 1066, 1066, 1066, + 1066, 1067, 1068, 1068, 1068, 1068, 1068, 1068, 1069, 1321, + 1321, 1321, 1070, 1321, 1071, 1321, 1321, 1321, 1070, 1070, + + 1070, 1070, 1070, 1070, 1099, 1100, 1100, 1100, 1100, 1100, + 1321, 1102, 1102, 1102, 1102, 1102, 1102, 1321, 1321, 1120, + 1071, 1080, 1081, 1081, 1081, 1081, 1081, 1082, 1321, 1321, + 1321, 1083, 1121, 1321, 1321, 1321, 1321, 1083, 1083, 1083, + 1083, 1083, 1083, 904, 1084, 1084, 1084, 1084, 1084, 1084, + 1085, 1321, 1321, 1321, 1086, 1321, 908, 1321, 1121, 1321, + 1086, 1086, 1086, 1086, 1086, 1086, 1107, 1004, 1004, 1004, + 1004, 1004, 1004, 1321, 1110, 1110, 1110, 1110, 1110, 1110, + 1321, 1321, 908, 913, 1087, 1087, 1087, 1087, 1087, 1087, + 1088, 1321, 1321, 1321, 1089, 1321, 917, 1321, 1321, 1321, + + 1089, 1089, 1089, 1089, 1089, 1089, 1112, 1010, 1010, 1010, + 1010, 1010, 1010, 726, 1012, 1012, 1012, 1012, 1012, 1012, + 1321, 1321, 917, 924, 1090, 1090, 1090, 1090, 1090, 1090, + 1091, 1321, 1321, 1321, 1092, 1321, 928, 1321, 1321, 1321, + 1092, 1092, 1092, 1092, 1092, 1092, 1114, 1014, 1014, 1014, + 1014, 1014, 1014, 1321, 1117, 1117, 1117, 1117, 1117, 1117, + 1122, 1321, 928, 936, 1093, 1093, 1093, 1093, 1093, 1093, + 1094, 1321, 1321, 1123, 1095, 1321, 940, 1321, 1321, 1321, + 1095, 1095, 1095, 1095, 1095, 1095, 1020, 1020, 1020, 1020, + 1020, 1020, 1120, 1023, 1023, 1023, 1023, 1023, 1023, 1123, + + 1321, 1321, 940, 948, 1096, 1096, 1096, 1096, 1096, 1096, + 1097, 1321, 1321, 1321, 1098, 1321, 952, 1321, 1321, 1321, + 1098, 1098, 1098, 1098, 1098, 1098, 735, 1025, 1025, 1025, + 1025, 1025, 1025, 1122, 1027, 1027, 1027, 1027, 1027, 1027, + 1128, 1321, 952, 997, 1101, 1101, 1101, 1101, 1101, 1101, + 999, 1321, 1321, 1129, 1102, 1321, 1321, 1321, 1321, 1321, + 1102, 1102, 1102, 1102, 1102, 1102, 904, 1109, 1109, 1109, + 1109, 1109, 1109, 1085, 1321, 1321, 1321, 1110, 1321, 1129, + 1321, 1321, 1321, 1110, 1110, 1110, 1110, 1110, 1110, 913, + 1116, 1116, 1116, 1116, 1116, 1116, 1088, 1321, 1321, 1321, + + 1117, 1321, 1321, 1321, 1321, 1321, 1117, 1117, 1117, 1117, + 1117, 1117, 924, 1124, 1124, 1124, 1124, 1124, 1124, 1091, + 1321, 1321, 1321, 1125, 1321, 1321, 1321, 1321, 1321, 1125, + 1125, 1125, 1125, 1125, 1125, 1321, 1125, 1125, 1125, 1125, + 1125, 1125, 1034, 1034, 1034, 1034, 1034, 1034, 1128, 1037, + 1037, 1037, 1037, 1037, 1037, 746, 1039, 1039, 1039, 1039, + 1039, 1039, 1130, 1130, 1041, 1041, 1041, 1041, 1041, 1041, + 1321, 1321, 1321, 1321, 1321, 1131, 1321, 1133, 1133, 1133, + 1133, 1133, 1133, 1048, 1048, 1048, 1048, 1048, 1048, 1136, + 1051, 1051, 1051, 1051, 1051, 1051, 1321, 1136, 1138, 1321, + + 1321, 1131, 936, 1132, 1132, 1132, 1132, 1132, 1132, 1094, + 1137, 1139, 1321, 1133, 1321, 1321, 1321, 1321, 1321, 1133, + 1133, 1133, 1133, 1133, 1133, 758, 1053, 1053, 1053, 1053, + 1053, 1053, 1321, 1321, 1321, 1321, 1137, 1139, 1138, 1055, + 1055, 1055, 1055, 1055, 1055, 948, 1140, 1140, 1140, 1140, + 1140, 1140, 1097, 1321, 1321, 1321, 1141, 1321, 1321, 1321, + 1321, 1321, 1141, 1141, 1141, 1141, 1141, 1141, 1321, 1141, + 1141, 1141, 1141, 1141, 1141, 1144, 1145, 1145, 1145, 1145, + 1145, 1147, 1148, 1148, 1148, 1148, 1148, 1151, 1152, 1152, + 1152, 1152, 1152, 1067, 1153, 1153, 1153, 1153, 1153, 1153, + + 1069, 1321, 1321, 1321, 1154, 1321, 48, 48, 1321, 1321, + 1154, 1154, 1154, 1154, 1154, 1154, 1321, 1154, 1154, 1154, + 1154, 1154, 1154, 48, 48, 1321, 1006, 1006, 1006, 1006, + 1006, 1006, 1321, 1321, 1321, 1160, 1159, 997, 1161, 1161, + 1161, 1161, 1161, 1161, 1162, 1321, 1321, 1321, 1163, 1321, + 1001, 1321, 1321, 1321, 1163, 1163, 1163, 1163, 1163, 1163, + 1321, 1016, 1016, 1016, 1016, 1016, 1016, 1321, 1029, 1029, + 1029, 1029, 1029, 1029, 1170, 1321, 1001, 904, 1005, 1005, + 1005, 1005, 1005, 1005, 1085, 1321, 1321, 1171, 1006, 1321, + 1321, 1321, 1321, 1321, 1006, 1006, 1006, 1006, 1006, 1006, + + 913, 1015, 1015, 1015, 1015, 1015, 1015, 1088, 1321, 1321, + 1321, 1016, 1321, 1171, 1321, 1321, 1321, 1016, 1016, 1016, + 1016, 1016, 1016, 924, 1028, 1028, 1028, 1028, 1028, 1028, + 1091, 1321, 1321, 1321, 1029, 1321, 1321, 1321, 1321, 1321, + 1029, 1029, 1029, 1029, 1029, 1029, 936, 1042, 1042, 1042, + 1042, 1042, 1042, 1094, 1321, 1321, 1321, 1043, 1321, 1321, + 1321, 1321, 1321, 1043, 1043, 1043, 1043, 1043, 1043, 1321, + 1043, 1043, 1043, 1043, 1043, 1043, 948, 1056, 1056, 1056, + 1056, 1056, 1056, 1097, 1321, 1321, 1321, 1057, 1321, 1321, + 1321, 1321, 1321, 1057, 1057, 1057, 1057, 1057, 1057, 1321, + + 1057, 1057, 1057, 1057, 1057, 1057, 1170, 1100, 1100, 1100, + 1100, 1100, 1100, 997, 1172, 1172, 1172, 1172, 1172, 1172, + 1162, 1321, 1321, 1321, 1173, 1321, 1321, 1321, 1321, 1321, + 1173, 1173, 1173, 1173, 1173, 1173, 1321, 1173, 1173, 1173, + 1173, 1173, 1173, 1176, 1177, 1177, 1177, 1177, 1177, 1181, + 1182, 1182, 1182, 1182, 1182, 1184, 1185, 1185, 1185, 1185, + 1185, 1190, 1191, 1191, 1191, 1191, 1191, 1193, 1194, 1194, + 1194, 1194, 1194, 1199, 1200, 1200, 1200, 1200, 1200, 1202, + 1203, 1203, 1203, 1203, 1203, 1208, 1209, 1209, 1209, 1209, + 1209, 1211, 1212, 1212, 1212, 1212, 1212, 1145, 1145, 1145, + + 1145, 1145, 1145, 1217, 1217, 1148, 1148, 1148, 1148, 1148, + 1148, 1219, 1321, 1321, 1321, 1321, 1218, 868, 1150, 1150, + 1150, 1150, 1150, 1150, 1220, 1219, 1152, 1152, 1152, 1152, + 1152, 1152, 1321, 1222, 1222, 1222, 1222, 1222, 1222, 1321, + 1321, 1321, 1218, 1321, 1102, 1102, 1102, 1102, 1102, 1102, + 1220, 1067, 1221, 1221, 1221, 1221, 1221, 1221, 1069, 1321, + 1321, 1321, 1222, 1321, 1321, 1321, 1321, 1321, 1222, 1222, + 1222, 1222, 1222, 1222, 997, 1101, 1101, 1101, 1101, 1101, + 1101, 1162, 1321, 1321, 1321, 1102, 1321, 1321, 1321, 1321, + 1242, 1102, 1102, 1102, 1102, 1102, 1102, 1236, 1237, 1237, + + 1237, 1237, 1237, 1243, 1242, 1177, 1177, 1177, 1177, 1177, + 1177, 904, 1179, 1179, 1179, 1179, 1179, 1179, 1182, 1182, + 1182, 1182, 1182, 1182, 1246, 1321, 1321, 1321, 1321, 1243, + 1246, 1185, 1185, 1185, 1185, 1185, 1185, 1247, 913, 1187, + 1187, 1187, 1187, 1187, 1187, 1191, 1191, 1191, 1191, 1191, + 1191, 1250, 1250, 1194, 1194, 1194, 1194, 1194, 1194, 1321, + 1321, 1321, 1321, 1247, 1251, 924, 1196, 1196, 1196, 1196, + 1196, 1196, 1200, 1200, 1200, 1200, 1200, 1200, 1254, 1254, + 1203, 1203, 1203, 1203, 1203, 1203, 1321, 1321, 1321, 1321, + 1251, 1255, 936, 1205, 1205, 1205, 1205, 1205, 1205, 1209, + + 1209, 1209, 1209, 1209, 1209, 1258, 1258, 1212, 1212, 1212, + 1212, 1212, 1212, 1321, 1321, 1321, 1321, 1255, 1259, 948, + 1214, 1214, 1214, 1214, 1214, 1214, 1262, 1263, 1263, 1263, + 1263, 1263, 1265, 1266, 1266, 1266, 1266, 1266, 1274, 1321, + 1321, 1321, 1321, 1321, 1259, 1276, 1277, 1277, 1277, 1277, + 1277, 1275, 1274, 1237, 1237, 1237, 1237, 1237, 1237, 997, + 1239, 1239, 1239, 1239, 1239, 1239, 1280, 1281, 1281, 1281, + 1281, 1281, 1321, 1321, 1321, 1321, 1321, 1275, 1284, 1285, + 1285, 1285, 1285, 1285, 1288, 1289, 1289, 1289, 1289, 1289, + 1292, 1293, 1293, 1293, 1293, 1293, 1263, 1263, 1263, 1263, + + 1263, 1263, 1296, 1296, 1266, 1266, 1266, 1266, 1266, 1266, + 1321, 1321, 1321, 1321, 1321, 1297, 1067, 1268, 1268, 1268, + 1268, 1268, 1268, 1300, 1301, 1301, 1301, 1301, 1301, 1277, + 1277, 1277, 1277, 1277, 1277, 1281, 1281, 1281, 1281, 1281, + 1281, 1297, 1285, 1285, 1285, 1285, 1285, 1285, 1289, 1289, + 1289, 1289, 1289, 1289, 1293, 1293, 1293, 1293, 1293, 1293, + 1309, 1310, 1310, 1310, 1310, 1310, 1301, 1301, 1301, 1301, + 1301, 1301, 1310, 1310, 1310, 1310, 1310, 1310, 46, 1321, + 1321, 1321, 1321, 46, 46, 46, 62, 1321, 62, 62, + 62, 62, 62, 62, 62, 137, 1321, 137, 142, 142, + + 142, 232, 232, 232, 241, 241, 241, 299, 299, 299, + 301, 301, 301, 302, 302, 302, 309, 309, 309, 307, + 307, 307, 317, 1321, 317, 359, 359, 359, 364, 364, + 364, 365, 365, 365, 378, 1321, 378, 379, 379, 379, + 311, 311, 1321, 1321, 311, 387, 387, 387, 431, 431, + 431, 435, 435, 435, 436, 436, 436, 437, 437, 437, + 442, 442, 442, 372, 372, 1321, 1321, 372, 451, 451, + 451, 455, 1321, 455, 456, 456, 456, 464, 1321, 464, + 499, 499, 499, 507, 507, 507, 508, 508, 508, 520, + 1321, 520, 523, 1321, 523, 524, 524, 524, 532, 1321, + + 532, 454, 454, 1321, 1321, 454, 458, 458, 1321, 1321, + 458, 542, 542, 542, 436, 436, 436, 567, 567, 567, + 571, 571, 571, 574, 574, 574, 575, 575, 575, 576, + 576, 576, 581, 581, 581, 514, 514, 1321, 1321, 514, + 590, 590, 590, 522, 522, 1321, 1321, 522, 526, 526, + 1321, 1321, 526, 601, 601, 601, 605, 1321, 605, 608, + 1321, 608, 609, 609, 609, 617, 1321, 617, 635, 635, + 635, 646, 646, 646, 647, 647, 647, 659, 1321, 659, + 662, 1321, 662, 663, 663, 663, 671, 1321, 671, 674, + 1321, 674, 677, 1321, 677, 678, 678, 678, 686, 1321, + + 686, 604, 1321, 1321, 604, 607, 607, 1321, 1321, 607, + 608, 608, 1321, 608, 611, 611, 1321, 1321, 611, 697, + 697, 697, 617, 617, 1321, 617, 53, 53, 53, 1321, + 53, 53, 575, 575, 575, 712, 712, 712, 716, 716, + 716, 719, 719, 719, 722, 722, 722, 723, 723, 723, + 724, 724, 724, 729, 729, 729, 653, 653, 1321, 1321, + 653, 738, 738, 738, 659, 659, 1321, 659, 661, 661, + 1321, 1321, 661, 662, 662, 1321, 662, 665, 665, 1321, + 1321, 665, 749, 749, 749, 671, 671, 1321, 671, 673, + 1321, 1321, 673, 674, 674, 1321, 674, 676, 676, 1321, + + 1321, 676, 677, 677, 1321, 677, 680, 680, 1321, 1321, + 680, 761, 761, 761, 686, 686, 1321, 686, 763, 1321, + 763, 766, 1321, 766, 769, 1321, 769, 770, 770, 770, + 778, 1321, 778, 53, 53, 53, 1321, 53, 53, 790, + 790, 790, 804, 804, 804, 805, 805, 805, 817, 1321, + 817, 820, 1321, 820, 821, 821, 821, 829, 1321, 829, + 832, 1321, 832, 835, 1321, 835, 836, 836, 836, 844, + 1321, 844, 845, 1321, 845, 848, 1321, 848, 851, 1321, + 851, 852, 852, 852, 860, 1321, 860, 763, 1321, 763, + 765, 1321, 1321, 765, 766, 766, 1321, 766, 768, 768, + + 1321, 1321, 768, 769, 769, 1321, 769, 772, 772, 1321, + 1321, 772, 871, 871, 871, 778, 778, 1321, 778, 53, + 53, 53, 1321, 53, 53, 723, 723, 723, 885, 885, + 885, 889, 889, 889, 892, 892, 892, 895, 895, 895, + 898, 898, 898, 899, 899, 899, 907, 907, 907, 811, + 811, 1321, 1321, 811, 916, 916, 916, 817, 817, 1321, + 817, 819, 819, 1321, 1321, 819, 820, 820, 1321, 820, + 823, 823, 1321, 1321, 823, 927, 927, 927, 829, 829, + 1321, 829, 831, 1321, 1321, 831, 832, 832, 1321, 832, + 834, 834, 1321, 1321, 834, 835, 835, 1321, 835, 838, + + 838, 1321, 1321, 838, 939, 939, 939, 844, 844, 1321, + 844, 845, 1321, 845, 847, 1321, 1321, 847, 848, 848, + 1321, 848, 850, 850, 1321, 1321, 850, 851, 851, 1321, + 851, 854, 854, 1321, 1321, 854, 951, 951, 951, 860, + 860, 1321, 860, 953, 1321, 953, 956, 1321, 956, 959, + 1321, 959, 960, 960, 960, 968, 1321, 968, 53, 53, + 53, 1321, 53, 53, 979, 979, 979, 996, 996, 996, + 1002, 1002, 1002, 1000, 1000, 1000, 1007, 1007, 1007, 1008, + 1321, 1008, 1011, 1321, 1011, 1012, 1012, 1012, 1017, 1017, + 1017, 1018, 1321, 1018, 1021, 1321, 1021, 1024, 1321, 1024, + + 1025, 1025, 1025, 1030, 1030, 1030, 1031, 1321, 1031, 1032, + 1321, 1032, 1035, 1321, 1035, 1038, 1321, 1038, 1039, 1039, + 1039, 1044, 1044, 1044, 1045, 1321, 1045, 1046, 1321, 1046, + 1049, 1321, 1049, 1052, 1321, 1052, 1053, 1053, 1053, 1058, + 1058, 1058, 1059, 1321, 1059, 953, 1321, 953, 955, 1321, + 1321, 955, 956, 956, 1321, 956, 958, 958, 1321, 1321, + 958, 959, 959, 1321, 959, 962, 962, 1321, 1321, 962, + 1070, 1070, 1070, 968, 968, 1321, 968, 53, 53, 53, + 1321, 53, 53, 899, 899, 899, 1086, 1086, 1086, 1089, + 1089, 1089, 1092, 1092, 1092, 1095, 1095, 1095, 1098, 1098, + + 1098, 1103, 1103, 1103, 1105, 1321, 1105, 1106, 1106, 1106, + 1004, 1004, 1321, 1321, 1004, 1111, 1111, 1111, 1008, 1008, + 1321, 1008, 1010, 1010, 1321, 1321, 1010, 1011, 1011, 1321, + 1011, 1014, 1014, 1321, 1321, 1014, 1118, 1118, 1118, 1018, + 1018, 1321, 1018, 1020, 1321, 1321, 1020, 1021, 1021, 1321, + 1021, 1023, 1023, 1321, 1321, 1023, 1024, 1024, 1321, 1024, + 1027, 1027, 1321, 1321, 1027, 1126, 1126, 1126, 1031, 1031, + 1321, 1031, 1032, 1321, 1032, 1034, 1321, 1321, 1034, 1035, + 1035, 1321, 1035, 1037, 1037, 1321, 1321, 1037, 1038, 1038, + 1321, 1038, 1041, 1041, 1321, 1321, 1041, 1134, 1134, 1134, + + 1045, 1045, 1321, 1045, 1046, 1321, 1046, 1048, 1321, 1321, + 1048, 1049, 1049, 1321, 1049, 1051, 1051, 1321, 1321, 1051, + 1052, 1052, 1321, 1052, 1055, 1055, 1321, 1321, 1055, 1142, + 1142, 1142, 1059, 1059, 1321, 1059, 1143, 1321, 1143, 1146, + 1321, 1146, 1149, 1321, 1149, 1150, 1150, 1150, 1155, 1321, + 1155, 1156, 1321, 1156, 53, 53, 53, 1321, 53, 53, + 1164, 1321, 1164, 1163, 1163, 1163, 1165, 1321, 1165, 1166, + 1321, 1166, 1167, 1321, 1167, 1168, 1321, 1168, 1169, 1321, + 1169, 1100, 1100, 1321, 1321, 1100, 1174, 1174, 1174, 309, + 309, 309, 1105, 1105, 1321, 1105, 1175, 1175, 1175, 1178, + + 1321, 1178, 1179, 1179, 1179, 1180, 1180, 1180, 1183, 1321, + 1183, 1186, 1321, 1186, 1187, 1187, 1187, 1188, 1188, 1188, + 1189, 1321, 1189, 1192, 1321, 1192, 1195, 1321, 1195, 1196, + 1196, 1196, 1197, 1197, 1197, 1198, 1321, 1198, 1201, 1321, + 1201, 1204, 1321, 1204, 1205, 1205, 1205, 1206, 1206, 1206, + 1207, 1321, 1207, 1210, 1321, 1210, 1213, 1321, 1213, 1214, + 1214, 1214, 1215, 1215, 1215, 1143, 1321, 1143, 1145, 1321, + 1321, 1145, 1146, 1146, 1321, 1146, 1148, 1148, 1321, 1321, + 1148, 1149, 1149, 1321, 1149, 1152, 1152, 1321, 1321, 1152, + 1223, 1321, 1223, 1156, 1156, 1321, 1156, 53, 53, 53, + + 1321, 53, 53, 1228, 1228, 1228, 1230, 1321, 1230, 1231, + 1321, 1231, 1232, 1321, 1232, 1233, 1321, 1233, 1234, 1321, + 1234, 1235, 1321, 1235, 1238, 1321, 1238, 1239, 1239, 1239, + 1240, 1240, 1240, 1241, 1321, 1241, 1177, 1177, 1321, 1321, + 1177, 1178, 1178, 1321, 1178, 1244, 1321, 1244, 1182, 1321, + 1321, 1182, 1183, 1183, 1321, 1183, 1185, 1185, 1321, 1321, + 1185, 1186, 1186, 1321, 1186, 1248, 1321, 1248, 1189, 1321, + 1189, 1191, 1321, 1321, 1191, 1192, 1192, 1321, 1192, 1194, + 1194, 1321, 1321, 1194, 1195, 1195, 1321, 1195, 1252, 1321, + 1252, 1198, 1321, 1198, 1200, 1321, 1321, 1200, 1201, 1201, + + 1321, 1201, 1203, 1203, 1321, 1321, 1203, 1204, 1204, 1321, + 1204, 1256, 1321, 1256, 1207, 1321, 1207, 1209, 1321, 1321, + 1209, 1210, 1210, 1321, 1210, 1212, 1212, 1321, 1321, 1212, + 1213, 1213, 1321, 1213, 1260, 1321, 1260, 1261, 1321, 1261, + 1264, 1321, 1264, 1267, 1321, 1267, 1268, 1268, 1268, 1269, + 1321, 1269, 53, 53, 53, 1321, 53, 53, 1273, 1321, + 1273, 1175, 1321, 1175, 1180, 1321, 1180, 1188, 1321, 1188, + 1197, 1321, 1197, 1206, 1321, 1206, 1215, 1321, 1215, 1237, + 1237, 1321, 1321, 1237, 1238, 1238, 1321, 1238, 1229, 1321, + 1229, 1278, 1321, 1278, 1279, 1321, 1279, 1282, 1321, 1282, + + 1283, 1321, 1283, 1286, 1321, 1286, 1287, 1321, 1287, 1290, + 1321, 1290, 1291, 1321, 1291, 1294, 1321, 1294, 1263, 1321, + 1321, 1263, 1266, 1266, 1321, 1321, 1266, 1298, 1321, 1298, + 1240, 1321, 1240, 1302, 1321, 1302, 1277, 1321, 1321, 1277, + 1281, 1321, 1321, 1281, 1285, 1321, 1321, 1285, 1289, 1321, + 1321, 1289, 1293, 1321, 1321, 1293, 1308, 1321, 1308, 1311, + 1321, 1311, 1301, 1321, 1321, 1301, 1313, 1321, 1313, 1314, + 1321, 1314, 1315, 1321, 1315, 1316, 1321, 1316, 1317, 1321, + 1317, 1310, 1321, 1321, 1310, 1319, 1321, 1319, 1320, 1321, + 1320, 3, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321 + } ; + +static yyconst short int yy_chk[6645] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 4, 7, 90, 4, 7, 4, 7, 9, + 4, 7, 9, 12, 9, 24, 12, 9, 12, 4, + 7, 12, 15, 17, 17, 1311, 9, 4, 7, 24, + 12, 19, 19, 64, 9, 64, 24, 90, 12, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 15, 27, + + 27, 14, 14, 14, 1302, 1294, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 16, 34, 23, 16, 23, 16, 29, 86, 16, + 23, 34, 166, 86, 1290, 23, 166, 22, 16, 23, + 22, 23, 22, 29, 39, 22, 16, 20, 20, 20, + 20, 20, 20, 20, 22, 26, 25, 33, 39, 25, + 20, 33, 22, 25, 95, 26, 35, 38, 26, 95, + 33, 33, 139, 38, 287, 38, 33, 38, 35, 287, + 35, 38, 35, 38, 38, 35, 20, 21, 21, 21, + + 21, 21, 21, 21, 94, 32, 32, 21, 139, 1286, + 94, 1282, 69, 21, 21, 21, 21, 21, 21, 31, + 32, 75, 31, 31, 32, 31, 69, 31, 32, 31, + 32, 31, 37, 36, 31, 75, 37, 32, 36, 36, + 41, 36, 36, 80, 37, 1278, 1267, 121, 41, 37, + 44, 37, 41, 44, 41, 44, 80, 78, 44, 49, + 49, 49, 49, 49, 49, 121, 146, 44, 52, 52, + 52, 52, 52, 52, 52, 44, 50, 50, 50, 50, + 50, 50, 50, 78, 220, 235, 1264, 50, 1238, 78, + 1222, 1213, 146, 50, 50, 50, 50, 50, 50, 54, + + 54, 54, 54, 54, 54, 61, 618, 220, 61, 54, + 61, 235, 116, 61, 91, 54, 54, 54, 54, 54, + 54, 55, 61, 618, 55, 116, 55, 626, 1210, 55, + 61, 125, 55, 55, 55, 55, 55, 55, 55, 1204, + 91, 125, 55, 1201, 626, 91, 55, 626, 55, 55, + 55, 55, 55, 55, 63, 63, 63, 63, 63, 63, + 63, 123, 141, 141, 141, 141, 141, 141, 141, 191, + 123, 153, 153, 153, 153, 153, 153, 153, 382, 446, + 1195, 1192, 191, 1186, 1183, 382, 446, 63, 138, 138, + 138, 138, 138, 138, 138, 227, 227, 227, 227, 227, + + 227, 138, 238, 238, 238, 238, 238, 238, 241, 241, + 241, 241, 241, 241, 241, 296, 304, 304, 304, 304, + 304, 304, 310, 627, 340, 343, 1178, 138, 140, 140, + 140, 140, 140, 140, 140, 310, 315, 340, 140, 343, + 627, 296, 631, 627, 140, 140, 140, 140, 140, 140, + 143, 143, 143, 143, 143, 143, 143, 537, 362, 631, + 143, 310, 315, 629, 537, 1174, 143, 143, 143, 143, + 143, 143, 145, 145, 145, 145, 145, 145, 145, 145, + 629, 629, 291, 145, 362, 145, 1173, 291, 258, 145, + 145, 145, 145, 145, 145, 258, 291, 368, 291, 291, + + 1162, 291, 357, 357, 357, 357, 357, 357, 258, 371, + 399, 145, 159, 159, 159, 159, 159, 159, 159, 399, + 1156, 1149, 371, 368, 258, 307, 307, 307, 307, 307, + 307, 307, 311, 311, 311, 311, 311, 311, 311, 1146, + 401, 159, 228, 228, 228, 228, 228, 228, 371, 401, + 585, 1142, 228, 1141, 376, 429, 462, 585, 228, 228, + 228, 228, 228, 228, 229, 229, 229, 229, 229, 229, + 229, 229, 234, 234, 234, 234, 234, 234, 234, 234, + 376, 429, 462, 234, 502, 234, 1134, 1133, 1126, 234, + 234, 234, 234, 234, 234, 313, 313, 313, 313, 313, + + 313, 313, 372, 372, 372, 372, 372, 372, 372, 453, + 502, 234, 239, 239, 239, 239, 239, 239, 239, 239, + 505, 511, 453, 239, 518, 1125, 632, 699, 1118, 239, + 239, 239, 239, 239, 239, 240, 240, 240, 240, 240, + 240, 1117, 596, 632, 699, 240, 505, 511, 453, 596, + 518, 240, 240, 240, 240, 240, 240, 295, 295, 295, + 295, 295, 295, 295, 380, 380, 380, 380, 380, 380, + 295, 374, 374, 374, 374, 374, 374, 374, 384, 384, + 384, 384, 384, 384, 387, 387, 387, 387, 387, 387, + 387, 457, 513, 521, 711, 525, 295, 300, 300, 300, + + 300, 300, 300, 692, 457, 513, 521, 300, 525, 619, + 692, 711, 1111, 300, 300, 300, 300, 300, 300, 303, + 303, 303, 303, 303, 303, 303, 619, 530, 603, 303, + 457, 513, 521, 619, 525, 303, 303, 303, 303, 303, + 303, 305, 305, 305, 305, 305, 305, 305, 305, 615, + 733, 1110, 305, 530, 603, 625, 630, 733, 305, 305, + 305, 305, 305, 305, 306, 306, 306, 306, 306, 306, + 306, 744, 625, 630, 306, 615, 630, 625, 744, 700, + 306, 306, 306, 306, 306, 306, 312, 312, 312, 312, + 312, 312, 312, 312, 1106, 638, 700, 312, 641, 644, + + 789, 700, 1105, 312, 312, 312, 312, 312, 312, 314, + 314, 314, 314, 314, 314, 314, 314, 789, 1104, 650, + 314, 638, 314, 1103, 641, 644, 314, 314, 314, 314, + 314, 314, 439, 439, 439, 439, 439, 439, 442, 442, + 442, 442, 442, 442, 442, 650, 657, 756, 314, 326, + 669, 672, 684, 326, 756, 1083, 326, 701, 606, 326, + 610, 326, 326, 326, 326, 358, 358, 358, 358, 358, + 358, 606, 657, 610, 701, 358, 669, 672, 684, 701, + 1066, 358, 358, 358, 358, 358, 358, 361, 361, 361, + 361, 361, 361, 361, 361, 866, 911, 606, 361, 610, + + 361, 1059, 866, 911, 361, 361, 361, 361, 361, 361, + 444, 444, 444, 444, 444, 444, 448, 448, 448, 448, + 448, 448, 709, 1058, 876, 1052, 361, 367, 367, 367, + 367, 367, 367, 367, 367, 1049, 922, 1045, 367, 709, + 367, 876, 709, 922, 367, 367, 367, 367, 367, 367, + 451, 451, 451, 451, 451, 451, 451, 454, 454, 454, + 454, 454, 454, 454, 620, 621, 367, 373, 373, 373, + 373, 373, 373, 373, 373, 1044, 764, 1038, 373, 1035, + 776, 620, 621, 702, 373, 373, 373, 373, 373, 373, + 375, 375, 375, 375, 375, 375, 375, 375, 620, 621, + + 702, 375, 764, 375, 1031, 702, 776, 375, 375, 375, + 375, 375, 375, 456, 456, 456, 456, 456, 456, 456, + 458, 458, 458, 458, 458, 458, 458, 622, 624, 375, + 385, 385, 385, 385, 385, 385, 385, 385, 1030, 934, + 793, 385, 704, 706, 622, 624, 934, 385, 385, 385, + 385, 385, 385, 386, 386, 386, 386, 386, 386, 704, + 706, 622, 624, 386, 704, 706, 793, 1024, 1021, 386, + 386, 386, 386, 386, 386, 428, 428, 428, 428, 428, + 428, 533, 533, 533, 533, 533, 533, 428, 460, 460, + 460, 460, 460, 460, 460, 514, 514, 514, 514, 514, + + 514, 514, 516, 516, 516, 516, 516, 516, 516, 652, + 660, 703, 633, 428, 432, 432, 432, 432, 432, 432, + 1018, 1017, 652, 660, 432, 796, 1011, 783, 703, 633, + 432, 432, 432, 432, 432, 432, 434, 434, 434, 434, + 434, 434, 633, 703, 783, 1008, 434, 783, 652, 660, + 707, 796, 434, 434, 434, 434, 434, 434, 438, 438, + 438, 438, 438, 438, 438, 1007, 799, 707, 438, 802, + 808, 786, 707, 879, 438, 438, 438, 438, 438, 438, + 440, 440, 440, 440, 440, 440, 440, 440, 786, 815, + 879, 440, 799, 786, 879, 802, 808, 440, 440, 440, + + 440, 440, 440, 441, 441, 441, 441, 441, 441, 441, + 946, 827, 830, 441, 842, 815, 788, 946, 1002, 441, + 441, 441, 441, 441, 441, 449, 449, 449, 449, 449, + 449, 449, 449, 788, 846, 858, 449, 827, 830, 884, + 842, 788, 449, 449, 449, 449, 449, 449, 450, 450, + 450, 450, 450, 450, 450, 999, 884, 996, 450, 995, + 846, 858, 882, 883, 450, 450, 450, 450, 450, 450, + 459, 459, 459, 459, 459, 459, 459, 459, 992, 882, + 883, 459, 901, 882, 972, 883, 989, 459, 459, 459, + 459, 459, 459, 461, 461, 461, 461, 461, 461, 461, + + 461, 972, 1065, 972, 461, 986, 461, 983, 901, 1065, + 461, 461, 461, 461, 461, 461, 522, 522, 522, 522, + 522, 522, 522, 524, 524, 524, 524, 524, 524, 524, + 705, 664, 461, 498, 498, 498, 498, 498, 498, 954, + 979, 966, 968, 498, 664, 982, 973, 705, 967, 498, + 498, 498, 498, 498, 498, 501, 501, 501, 501, 501, + 501, 501, 501, 973, 705, 954, 501, 966, 501, 959, + 664, 982, 501, 501, 501, 501, 501, 501, 526, 526, + 526, 526, 526, 526, 526, 528, 528, 528, 528, 528, + 528, 528, 675, 881, 501, 504, 504, 504, 504, 504, + + 504, 504, 504, 956, 1109, 675, 504, 985, 504, 950, + 881, 1109, 504, 504, 504, 504, 504, 504, 535, 535, + 535, 535, 535, 535, 539, 539, 539, 539, 539, 539, + 881, 675, 977, 985, 504, 510, 510, 510, 510, 510, + 510, 510, 510, 1116, 1124, 947, 510, 938, 510, 977, + 1116, 1124, 510, 510, 510, 510, 510, 510, 542, 542, + 542, 542, 542, 542, 542, 571, 571, 571, 571, 571, + 571, 571, 710, 782, 510, 515, 515, 515, 515, 515, + 515, 515, 515, 935, 988, 926, 515, 991, 994, 710, + 782, 923, 515, 515, 515, 515, 515, 515, 517, 517, + + 517, 517, 517, 517, 517, 517, 915, 782, 710, 517, + 988, 517, 912, 991, 994, 517, 517, 517, 517, 517, + 517, 574, 574, 574, 574, 574, 574, 574, 578, 578, + 578, 578, 578, 578, 679, 784, 906, 517, 527, 527, + 527, 527, 527, 527, 527, 527, 903, 679, 902, 527, + 899, 1019, 784, 784, 976, 527, 527, 527, 527, 527, + 527, 529, 529, 529, 529, 529, 529, 529, 529, 885, + 784, 976, 529, 679, 529, 867, 976, 1019, 529, 529, + 529, 529, 529, 529, 581, 581, 581, 581, 581, 581, + 581, 583, 583, 583, 583, 583, 583, 767, 708, 779, + + 529, 540, 540, 540, 540, 540, 540, 540, 540, 1033, + 767, 1047, 540, 860, 859, 708, 779, 851, 540, 540, + 540, 540, 540, 540, 541, 541, 541, 541, 541, 541, + 708, 779, 1081, 848, 541, 1033, 767, 1047, 1072, 771, + 541, 541, 541, 541, 541, 541, 568, 568, 568, 568, + 568, 568, 771, 844, 1132, 1072, 568, 1144, 1081, 969, + 1073, 1132, 568, 568, 568, 568, 568, 568, 569, 569, + 569, 569, 569, 569, 569, 569, 969, 1073, 771, 569, + 1181, 970, 1074, 1144, 810, 569, 569, 569, 569, 569, + 569, 570, 570, 570, 570, 570, 570, 810, 970, 1074, + + 969, 570, 1190, 1199, 971, 843, 1181, 570, 570, 570, + 570, 570, 570, 572, 572, 572, 572, 572, 572, 572, + 572, 971, 970, 810, 572, 1075, 1076, 974, 1190, 1199, + 572, 572, 572, 572, 572, 572, 573, 573, 573, 573, + 573, 573, 1075, 1076, 974, 971, 573, 835, 1076, 832, + 1158, 829, 573, 573, 573, 573, 573, 573, 577, 577, + 577, 577, 577, 577, 577, 974, 1140, 1158, 577, 1208, + 1158, 1160, 1159, 1140, 577, 577, 577, 577, 577, 577, + 579, 579, 579, 579, 579, 579, 579, 579, 1160, 1159, + 1262, 579, 1159, 828, 820, 1208, 817, 579, 579, 579, + + 579, 579, 579, 580, 580, 580, 580, 580, 580, 580, + 1172, 1221, 1160, 580, 1276, 1280, 1262, 1172, 1221, 580, + 580, 580, 580, 580, 580, 587, 587, 587, 587, 587, + 587, 588, 588, 588, 588, 588, 588, 588, 588, 1284, + 1276, 1280, 588, 816, 1226, 1227, 1270, 809, 588, 588, + 588, 588, 588, 588, 589, 589, 589, 589, 589, 589, + 589, 1226, 1227, 1270, 589, 1284, 805, 804, 803, 1226, + 589, 589, 589, 589, 589, 589, 590, 590, 590, 590, + 590, 590, 590, 592, 592, 592, 592, 592, 592, 594, + 594, 594, 594, 594, 594, 598, 598, 598, 598, 598, + + 598, 599, 599, 599, 599, 599, 599, 599, 599, 1288, + 1292, 1300, 599, 1309, 1272, 1299, 800, 797, 599, 599, + 599, 599, 599, 599, 600, 600, 600, 600, 600, 600, + 600, 1272, 1299, 794, 600, 1288, 1292, 1300, 791, 1309, + 600, 600, 600, 600, 600, 600, 601, 601, 601, 601, + 601, 601, 601, 604, 604, 604, 604, 604, 604, 607, + 607, 607, 607, 607, 607, 607, 609, 609, 609, 609, + 609, 609, 609, 611, 611, 611, 611, 611, 611, 611, + 612, 612, 612, 612, 612, 612, 612, 612, 790, 778, + 777, 612, 769, 766, 757, 745, 734, 612, 612, 612, + + 612, 612, 612, 613, 613, 613, 613, 613, 613, 613, + 614, 614, 614, 614, 614, 614, 614, 614, 623, 628, + 724, 614, 634, 614, 723, 818, 712, 614, 614, 614, + 614, 614, 614, 785, 693, 623, 628, 686, 818, 634, + 653, 653, 653, 653, 653, 653, 653, 623, 628, 614, + 785, 634, 637, 637, 637, 637, 637, 637, 637, 637, + 685, 677, 674, 637, 818, 637, 785, 671, 670, 637, + 637, 637, 637, 637, 637, 655, 655, 655, 655, 655, + 655, 655, 661, 661, 661, 661, 661, 661, 661, 662, + 659, 637, 640, 640, 640, 640, 640, 640, 640, 640, + + 658, 651, 648, 640, 647, 640, 646, 645, 642, 640, + 640, 640, 640, 640, 640, 663, 663, 663, 663, 663, + 663, 663, 665, 665, 665, 665, 665, 665, 665, 822, + 639, 640, 643, 643, 643, 643, 643, 643, 643, 643, + 636, 635, 822, 643, 617, 643, 616, 608, 605, 643, + 643, 643, 643, 643, 643, 667, 667, 667, 667, 667, + 667, 667, 673, 673, 673, 673, 673, 673, 822, 597, + 586, 643, 649, 649, 649, 649, 649, 649, 649, 649, + 576, 575, 567, 649, 563, 649, 562, 561, 559, 649, + 649, 649, 649, 649, 649, 676, 676, 676, 676, 676, + + 676, 676, 678, 678, 678, 678, 678, 678, 678, 787, + 1157, 649, 654, 654, 654, 654, 654, 654, 654, 654, + 558, 555, 554, 654, 553, 552, 787, 1157, 551, 654, + 654, 654, 654, 654, 654, 656, 656, 656, 656, 656, + 656, 656, 656, 787, 1157, 550, 656, 549, 656, 548, + 547, 546, 656, 656, 656, 656, 656, 656, 680, 680, + 680, 680, 680, 680, 680, 682, 682, 682, 682, 682, + 682, 682, 878, 545, 656, 666, 666, 666, 666, 666, + 666, 666, 666, 544, 538, 532, 666, 531, 523, 878, + 520, 519, 666, 666, 666, 666, 666, 666, 668, 668, + + 668, 668, 668, 668, 668, 668, 512, 509, 878, 668, + 508, 668, 507, 506, 503, 668, 668, 668, 668, 668, + 668, 688, 688, 688, 688, 688, 688, 690, 690, 690, + 690, 690, 690, 1224, 833, 1271, 500, 668, 681, 681, + 681, 681, 681, 681, 681, 681, 499, 833, 497, 681, + 1224, 493, 1271, 490, 489, 681, 681, 681, 681, 681, + 681, 683, 683, 683, 683, 683, 683, 683, 683, 1224, + 488, 1271, 683, 833, 683, 487, 483, 482, 683, 683, + 683, 683, 683, 683, 694, 694, 694, 694, 694, 694, + 697, 697, 697, 697, 697, 697, 697, 837, 780, 781, + + 683, 695, 695, 695, 695, 695, 695, 695, 695, 480, + 837, 479, 695, 478, 477, 780, 781, 476, 695, 695, + 695, 695, 695, 695, 696, 696, 696, 696, 696, 696, + 780, 781, 781, 475, 696, 474, 837, 473, 472, 849, + 696, 696, 696, 696, 696, 696, 713, 713, 713, 713, + 713, 713, 849, 471, 470, 469, 713, 466, 465, 464, + 463, 455, 713, 713, 713, 713, 713, 713, 714, 714, + 714, 714, 714, 714, 714, 714, 447, 437, 849, 714, + 1077, 436, 435, 433, 431, 714, 714, 714, 714, 714, + 714, 715, 715, 715, 715, 715, 715, 1077, 430, 427, + + 426, 715, 425, 424, 423, 422, 1077, 715, 715, 715, + 715, 715, 715, 716, 716, 716, 716, 716, 716, 716, + 717, 717, 717, 717, 717, 717, 717, 717, 421, 420, + 419, 717, 1225, 418, 416, 413, 412, 717, 717, 717, + 717, 717, 717, 718, 718, 718, 718, 718, 718, 1225, + 411, 410, 409, 718, 408, 407, 405, 404, 1225, 718, + 718, 718, 718, 718, 718, 719, 719, 719, 719, 719, + 719, 719, 720, 720, 720, 720, 720, 720, 720, 720, + 403, 402, 400, 720, 398, 397, 396, 395, 394, 720, + 720, 720, 720, 720, 720, 721, 721, 721, 721, 721, + + 721, 393, 391, 390, 383, 721, 379, 378, 377, 370, + 369, 721, 721, 721, 721, 721, 721, 722, 722, 722, + 722, 722, 722, 722, 725, 725, 725, 725, 725, 725, + 725, 366, 365, 364, 725, 363, 360, 359, 356, 355, + 725, 725, 725, 725, 725, 725, 726, 726, 726, 726, + 726, 726, 727, 727, 727, 727, 727, 727, 727, 727, + 354, 353, 352, 727, 351, 350, 349, 348, 347, 727, + 727, 727, 727, 727, 727, 728, 728, 728, 728, 728, + 728, 728, 346, 344, 342, 728, 341, 339, 338, 335, + 334, 728, 728, 728, 728, 728, 728, 729, 729, 729, + + 729, 729, 729, 729, 731, 731, 731, 731, 731, 731, + 735, 735, 735, 735, 735, 735, 736, 736, 736, 736, + 736, 736, 736, 736, 332, 330, 329, 736, 328, 325, + 324, 322, 321, 736, 736, 736, 736, 736, 736, 737, + 737, 737, 737, 737, 737, 737, 320, 318, 317, 737, + 316, 309, 302, 301, 299, 737, 737, 737, 737, 737, + 737, 738, 738, 738, 738, 738, 738, 738, 740, 740, + 740, 740, 740, 740, 742, 742, 742, 742, 742, 742, + 746, 746, 746, 746, 746, 746, 747, 747, 747, 747, + 747, 747, 747, 747, 298, 297, 292, 747, 290, 285, + + 283, 281, 280, 747, 747, 747, 747, 747, 747, 748, + 748, 748, 748, 748, 748, 748, 279, 278, 277, 748, + 276, 275, 273, 272, 271, 748, 748, 748, 748, 748, + 748, 749, 749, 749, 749, 749, 749, 749, 752, 752, + 752, 752, 752, 752, 754, 754, 754, 754, 754, 754, + 758, 758, 758, 758, 758, 758, 759, 759, 759, 759, + 759, 759, 759, 759, 267, 264, 263, 759, 262, 259, + 256, 255, 254, 759, 759, 759, 759, 759, 759, 760, + 760, 760, 760, 760, 760, 760, 252, 251, 249, 760, + 246, 245, 244, 237, 236, 760, 760, 760, 760, 760, + + 760, 761, 761, 761, 761, 761, 761, 761, 765, 765, + 765, 765, 765, 765, 768, 768, 768, 768, 768, 768, + 768, 770, 770, 770, 770, 770, 770, 770, 772, 772, + 772, 772, 772, 772, 772, 773, 773, 773, 773, 773, + 773, 773, 773, 233, 232, 231, 773, 230, 226, 225, + 223, 219, 773, 773, 773, 773, 773, 773, 774, 774, + 774, 774, 774, 774, 774, 775, 775, 775, 775, 775, + 775, 775, 775, 217, 213, 211, 775, 209, 775, 208, + 206, 205, 775, 775, 775, 775, 775, 775, 811, 811, + 811, 811, 811, 811, 811, 813, 813, 813, 813, 813, + + 813, 813, 204, 203, 775, 792, 792, 792, 792, 792, + 792, 792, 792, 202, 201, 200, 792, 198, 792, 196, + 194, 193, 792, 792, 792, 792, 792, 792, 819, 819, + 819, 819, 819, 819, 819, 821, 821, 821, 821, 821, + 821, 821, 192, 190, 792, 795, 795, 795, 795, 795, + 795, 795, 795, 189, 186, 185, 795, 184, 795, 182, + 180, 179, 795, 795, 795, 795, 795, 795, 823, 823, + 823, 823, 823, 823, 823, 825, 825, 825, 825, 825, + 825, 825, 853, 176, 795, 798, 798, 798, 798, 798, + 798, 798, 798, 175, 173, 853, 798, 172, 798, 171, + + 170, 169, 798, 798, 798, 798, 798, 798, 831, 831, + 831, 831, 831, 831, 834, 834, 834, 834, 834, 834, + 834, 853, 168, 167, 798, 801, 801, 801, 801, 801, + 801, 801, 801, 165, 163, 162, 801, 158, 801, 157, + 156, 155, 801, 801, 801, 801, 801, 801, 836, 836, + 836, 836, 836, 836, 836, 838, 838, 838, 838, 838, + 838, 838, 154, 957, 801, 806, 806, 806, 806, 806, + 806, 806, 152, 149, 148, 806, 957, 147, 144, 142, + 135, 806, 806, 806, 806, 806, 806, 807, 807, 807, + 807, 807, 807, 807, 807, 134, 133, 132, 807, 131, + + 807, 130, 957, 128, 807, 807, 807, 807, 807, 807, + 840, 840, 840, 840, 840, 840, 840, 847, 847, 847, + 847, 847, 847, 961, 127, 126, 807, 812, 812, 812, + 812, 812, 812, 812, 812, 124, 961, 122, 812, 120, + 119, 118, 117, 115, 812, 812, 812, 812, 812, 812, + 814, 814, 814, 814, 814, 814, 814, 814, 114, 113, + 112, 814, 961, 814, 111, 110, 108, 814, 814, 814, + 814, 814, 814, 850, 850, 850, 850, 850, 850, 850, + 852, 852, 852, 852, 852, 852, 852, 106, 105, 814, + 824, 824, 824, 824, 824, 824, 824, 824, 104, 103, + + 102, 824, 101, 100, 99, 98, 97, 824, 824, 824, + 824, 824, 824, 826, 826, 826, 826, 826, 826, 826, + 826, 96, 89, 88, 826, 87, 826, 85, 84, 83, + 826, 826, 826, 826, 826, 826, 854, 854, 854, 854, + 854, 854, 854, 856, 856, 856, 856, 856, 856, 856, + 82, 81, 826, 839, 839, 839, 839, 839, 839, 839, + 839, 79, 77, 76, 839, 74, 73, 72, 71, 70, + 839, 839, 839, 839, 839, 839, 841, 841, 841, 841, + 841, 841, 841, 841, 68, 67, 66, 841, 51, 841, + 43, 42, 40, 841, 841, 841, 841, 841, 841, 862, + + 862, 862, 862, 862, 862, 864, 864, 864, 864, 864, + 864, 30, 1003, 28, 18, 841, 855, 855, 855, 855, + 855, 855, 855, 855, 10, 1003, 8, 855, 3, 0, + 0, 0, 0, 855, 855, 855, 855, 855, 855, 857, + 857, 857, 857, 857, 857, 857, 857, 0, 0, 0, + 857, 1003, 857, 0, 0, 0, 857, 857, 857, 857, + 857, 857, 868, 868, 868, 868, 868, 868, 871, 871, + 871, 871, 871, 871, 871, 1009, 0, 0, 857, 869, + 869, 869, 869, 869, 869, 869, 869, 0, 1009, 0, + 869, 0, 0, 0, 0, 0, 869, 869, 869, 869, + + 869, 869, 870, 870, 870, 870, 870, 870, 873, 874, + 875, 877, 870, 880, 1009, 975, 0, 0, 870, 870, + 870, 870, 870, 870, 978, 873, 874, 875, 877, 0, + 880, 0, 975, 0, 0, 0, 873, 874, 875, 0, + 1013, 978, 877, 975, 880, 886, 886, 886, 886, 886, + 886, 0, 0, 1013, 0, 886, 978, 0, 0, 0, + 0, 886, 886, 886, 886, 886, 886, 887, 887, 887, + 887, 887, 887, 887, 887, 0, 0, 0, 887, 1013, + 0, 0, 0, 0, 887, 887, 887, 887, 887, 887, + 888, 888, 888, 888, 888, 888, 0, 0, 0, 0, + + 888, 0, 0, 0, 0, 0, 888, 888, 888, 888, + 888, 888, 889, 889, 889, 889, 889, 889, 889, 890, + 890, 890, 890, 890, 890, 890, 890, 0, 0, 0, + 890, 0, 0, 0, 0, 0, 890, 890, 890, 890, + 890, 890, 891, 891, 891, 891, 891, 891, 0, 0, + 0, 0, 891, 0, 0, 0, 0, 0, 891, 891, + 891, 891, 891, 891, 892, 892, 892, 892, 892, 892, + 892, 893, 893, 893, 893, 893, 893, 893, 893, 0, + 0, 0, 893, 0, 0, 0, 0, 0, 893, 893, + 893, 893, 893, 893, 894, 894, 894, 894, 894, 894, + + 0, 0, 0, 0, 894, 0, 0, 0, 0, 0, + 894, 894, 894, 894, 894, 894, 895, 895, 895, 895, + 895, 895, 895, 896, 896, 896, 896, 896, 896, 896, + 896, 0, 0, 0, 896, 0, 0, 0, 0, 0, + 896, 896, 896, 896, 896, 896, 897, 897, 897, 897, + 897, 897, 0, 0, 0, 0, 897, 0, 0, 0, + 0, 0, 897, 897, 897, 897, 897, 897, 898, 898, + 898, 898, 898, 898, 898, 900, 900, 900, 900, 900, + 900, 900, 900, 0, 0, 0, 900, 0, 900, 0, + 0, 0, 900, 900, 900, 900, 900, 900, 904, 904, + + 904, 904, 904, 904, 907, 907, 907, 907, 907, 907, + 907, 0, 0, 0, 900, 905, 905, 905, 905, 905, + 905, 905, 905, 0, 0, 0, 905, 0, 0, 0, + 0, 0, 905, 905, 905, 905, 905, 905, 909, 909, + 909, 909, 909, 909, 913, 913, 913, 913, 913, 913, + 914, 914, 914, 914, 914, 914, 914, 914, 0, 0, + 0, 914, 0, 0, 0, 0, 0, 914, 914, 914, + 914, 914, 914, 916, 916, 916, 916, 916, 916, 916, + 918, 918, 918, 918, 918, 918, 920, 920, 920, 920, + 920, 920, 924, 924, 924, 924, 924, 924, 925, 925, + + 925, 925, 925, 925, 925, 925, 0, 0, 0, 925, + 0, 0, 0, 0, 0, 925, 925, 925, 925, 925, + 925, 927, 927, 927, 927, 927, 927, 927, 930, 930, + 930, 930, 930, 930, 932, 932, 932, 932, 932, 932, + 936, 936, 936, 936, 936, 936, 937, 937, 937, 937, + 937, 937, 937, 937, 0, 0, 0, 937, 0, 0, + 0, 0, 0, 937, 937, 937, 937, 937, 937, 939, + 939, 939, 939, 939, 939, 939, 942, 942, 942, 942, + 942, 942, 944, 944, 944, 944, 944, 944, 948, 948, + 948, 948, 948, 948, 949, 949, 949, 949, 949, 949, + + 949, 949, 0, 0, 0, 949, 0, 0, 0, 0, + 0, 949, 949, 949, 949, 949, 949, 951, 951, 951, + 951, 951, 951, 951, 955, 955, 955, 955, 955, 955, + 958, 958, 958, 958, 958, 958, 958, 960, 960, 960, + 960, 960, 960, 960, 962, 962, 962, 962, 962, 962, + 962, 963, 963, 963, 963, 963, 963, 963, 963, 0, + 0, 0, 963, 0, 0, 0, 0, 0, 963, 963, + 963, 963, 963, 963, 964, 964, 964, 964, 964, 964, + 964, 965, 965, 965, 965, 965, 965, 965, 965, 0, + 0, 0, 965, 0, 965, 0, 0, 0, 965, 965, + + 965, 965, 965, 965, 997, 997, 997, 997, 997, 997, + 1000, 1000, 1000, 1000, 1000, 1000, 1000, 0, 0, 1022, + 965, 980, 980, 980, 980, 980, 980, 980, 0, 0, + 0, 980, 1022, 0, 0, 0, 0, 980, 980, 980, + 980, 980, 980, 981, 981, 981, 981, 981, 981, 981, + 981, 0, 0, 0, 981, 0, 981, 0, 1022, 0, + 981, 981, 981, 981, 981, 981, 1004, 1004, 1004, 1004, + 1004, 1004, 1004, 1006, 1006, 1006, 1006, 1006, 1006, 1006, + 0, 0, 981, 984, 984, 984, 984, 984, 984, 984, + 984, 0, 0, 0, 984, 0, 984, 0, 0, 0, + + 984, 984, 984, 984, 984, 984, 1010, 1010, 1010, 1010, + 1010, 1010, 1010, 1012, 1012, 1012, 1012, 1012, 1012, 1012, + 0, 0, 984, 987, 987, 987, 987, 987, 987, 987, + 987, 0, 0, 0, 987, 0, 987, 0, 0, 0, + 987, 987, 987, 987, 987, 987, 1014, 1014, 1014, 1014, + 1014, 1014, 1014, 1016, 1016, 1016, 1016, 1016, 1016, 1016, + 1026, 0, 987, 990, 990, 990, 990, 990, 990, 990, + 990, 0, 0, 1026, 990, 0, 990, 0, 0, 0, + 990, 990, 990, 990, 990, 990, 1020, 1020, 1020, 1020, + 1020, 1020, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1026, + + 0, 0, 990, 993, 993, 993, 993, 993, 993, 993, + 993, 0, 0, 0, 993, 0, 993, 0, 0, 0, + 993, 993, 993, 993, 993, 993, 1025, 1025, 1025, 1025, + 1025, 1025, 1025, 1027, 1027, 1027, 1027, 1027, 1027, 1027, + 1036, 0, 993, 998, 998, 998, 998, 998, 998, 998, + 998, 0, 0, 1036, 998, 0, 0, 0, 0, 0, + 998, 998, 998, 998, 998, 998, 1005, 1005, 1005, 1005, + 1005, 1005, 1005, 1005, 0, 0, 0, 1005, 0, 1036, + 0, 0, 0, 1005, 1005, 1005, 1005, 1005, 1005, 1015, + 1015, 1015, 1015, 1015, 1015, 1015, 1015, 0, 0, 0, + + 1015, 0, 0, 0, 0, 0, 1015, 1015, 1015, 1015, + 1015, 1015, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, + 0, 0, 0, 1028, 0, 0, 0, 0, 0, 1028, + 1028, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1029, + 1029, 1029, 1034, 1034, 1034, 1034, 1034, 1034, 1037, 1037, + 1037, 1037, 1037, 1037, 1037, 1039, 1039, 1039, 1039, 1039, + 1039, 1039, 1040, 1041, 1041, 1041, 1041, 1041, 1041, 1041, + 0, 0, 0, 0, 0, 1040, 1043, 1043, 1043, 1043, + 1043, 1043, 1043, 1048, 1048, 1048, 1048, 1048, 1048, 1051, + 1051, 1051, 1051, 1051, 1051, 1051, 0, 1050, 1054, 0, + + 0, 1040, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, + 1050, 1054, 0, 1042, 0, 0, 0, 0, 0, 1042, + 1042, 1042, 1042, 1042, 1042, 1053, 1053, 1053, 1053, 1053, + 1053, 1053, 0, 0, 0, 0, 1050, 1054, 1055, 1055, + 1055, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1056, + 1056, 1056, 1056, 0, 0, 0, 1056, 0, 0, 0, + 0, 0, 1056, 1056, 1056, 1056, 1056, 1056, 1057, 1057, + 1057, 1057, 1057, 1057, 1057, 1061, 1061, 1061, 1061, 1061, + 1061, 1063, 1063, 1063, 1063, 1063, 1063, 1067, 1067, 1067, + 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1068, 1068, 1068, + + 1068, 0, 0, 0, 1068, 0, 1078, 1079, 0, 0, + 1068, 1068, 1068, 1068, 1068, 1068, 1070, 1070, 1070, 1070, + 1070, 1070, 1070, 1078, 1079, 1086, 1086, 1086, 1086, 1086, + 1086, 1086, 0, 0, 0, 1079, 1078, 1080, 1080, 1080, + 1080, 1080, 1080, 1080, 1080, 0, 0, 0, 1080, 0, + 1080, 0, 0, 0, 1080, 1080, 1080, 1080, 1080, 1080, + 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1092, 1092, 1092, + 1092, 1092, 1092, 1092, 1099, 0, 1080, 1084, 1084, 1084, + 1084, 1084, 1084, 1084, 1084, 0, 0, 1099, 1084, 0, + 0, 0, 0, 0, 1084, 1084, 1084, 1084, 1084, 1084, + + 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 0, 0, + 0, 1087, 0, 1099, 0, 0, 0, 1087, 1087, 1087, + 1087, 1087, 1087, 1090, 1090, 1090, 1090, 1090, 1090, 1090, + 1090, 0, 0, 0, 1090, 0, 0, 0, 0, 0, + 1090, 1090, 1090, 1090, 1090, 1090, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 0, 0, 0, 1093, 0, 0, + 0, 0, 0, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1095, 1095, 1095, 1095, 1095, 1095, 1096, 1096, 1096, 1096, + 1096, 1096, 1096, 1096, 0, 0, 0, 1096, 0, 0, + 0, 0, 0, 1096, 1096, 1096, 1096, 1096, 1096, 1098, + + 1098, 1098, 1098, 1098, 1098, 1098, 1100, 1100, 1100, 1100, + 1100, 1100, 1100, 1101, 1101, 1101, 1101, 1101, 1101, 1101, + 1101, 0, 0, 0, 1101, 0, 0, 0, 0, 0, + 1101, 1101, 1101, 1101, 1101, 1101, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1107, 1107, 1107, 1107, 1107, 1107, 1112, + 1112, 1112, 1112, 1112, 1112, 1114, 1114, 1114, 1114, 1114, + 1114, 1120, 1120, 1120, 1120, 1120, 1120, 1122, 1122, 1122, + 1122, 1122, 1122, 1128, 1128, 1128, 1128, 1128, 1128, 1130, + 1130, 1130, 1130, 1130, 1130, 1136, 1136, 1136, 1136, 1136, + 1136, 1138, 1138, 1138, 1138, 1138, 1138, 1145, 1145, 1145, + + 1145, 1145, 1145, 1147, 1148, 1148, 1148, 1148, 1148, 1148, + 1148, 1151, 0, 0, 0, 0, 1147, 1150, 1150, 1150, + 1150, 1150, 1150, 1150, 1151, 1152, 1152, 1152, 1152, 1152, + 1152, 1152, 1154, 1154, 1154, 1154, 1154, 1154, 1154, 0, + 0, 0, 1147, 1163, 1163, 1163, 1163, 1163, 1163, 1163, + 1151, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 0, + 0, 0, 1153, 0, 0, 0, 0, 0, 1153, 1153, + 1153, 1153, 1153, 1153, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 0, 0, 0, 1161, 0, 0, 0, 0, + 1176, 1161, 1161, 1161, 1161, 1161, 1161, 1170, 1170, 1170, + + 1170, 1170, 1170, 1176, 1177, 1177, 1177, 1177, 1177, 1177, + 1177, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1182, 1182, + 1182, 1182, 1182, 1182, 1184, 0, 0, 0, 0, 1176, + 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1184, 1187, 1187, + 1187, 1187, 1187, 1187, 1187, 1191, 1191, 1191, 1191, 1191, + 1191, 1193, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 0, + 0, 0, 0, 1184, 1193, 1196, 1196, 1196, 1196, 1196, + 1196, 1196, 1200, 1200, 1200, 1200, 1200, 1200, 1202, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 0, 0, 0, 0, + 1193, 1202, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1209, + + 1209, 1209, 1209, 1209, 1209, 1211, 1212, 1212, 1212, 1212, + 1212, 1212, 1212, 0, 0, 0, 0, 1202, 1211, 1214, + 1214, 1214, 1214, 1214, 1214, 1214, 1217, 1217, 1217, 1217, + 1217, 1217, 1219, 1219, 1219, 1219, 1219, 1219, 1236, 0, + 0, 0, 0, 0, 1211, 1242, 1242, 1242, 1242, 1242, + 1242, 1236, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1239, + 1239, 1239, 1239, 1239, 1239, 1239, 1246, 1246, 1246, 1246, + 1246, 1246, 0, 0, 0, 0, 0, 1236, 1250, 1250, + 1250, 1250, 1250, 1250, 1254, 1254, 1254, 1254, 1254, 1254, + 1258, 1258, 1258, 1258, 1258, 1258, 1263, 1263, 1263, 1263, + + 1263, 1263, 1265, 1266, 1266, 1266, 1266, 1266, 1266, 1266, + 0, 0, 0, 0, 0, 1265, 1268, 1268, 1268, 1268, + 1268, 1268, 1268, 1274, 1274, 1274, 1274, 1274, 1274, 1277, + 1277, 1277, 1277, 1277, 1277, 1281, 1281, 1281, 1281, 1281, + 1281, 1265, 1285, 1285, 1285, 1285, 1285, 1285, 1289, 1289, + 1289, 1289, 1289, 1289, 1293, 1293, 1293, 1293, 1293, 1293, + 1296, 1296, 1296, 1296, 1296, 1296, 1301, 1301, 1301, 1301, + 1301, 1301, 1310, 1310, 1310, 1310, 1310, 1310, 1322, 0, + 0, 0, 0, 1322, 1322, 1322, 1323, 0, 1323, 1323, + 1323, 1323, 1323, 1323, 1323, 1324, 0, 1324, 1325, 1325, + + 1325, 1326, 1326, 1326, 1327, 1327, 1327, 1328, 1328, 1328, + 1329, 1329, 1329, 1330, 1330, 1330, 1331, 1331, 1331, 1332, + 1332, 1332, 1333, 0, 1333, 1334, 1334, 1334, 1335, 1335, + 1335, 1336, 1336, 1336, 1337, 0, 1337, 1338, 1338, 1338, + 1339, 1339, 0, 0, 1339, 1340, 1340, 1340, 1341, 1341, + 1341, 1342, 1342, 1342, 1343, 1343, 1343, 1344, 1344, 1344, + 1345, 1345, 1345, 1346, 1346, 0, 0, 1346, 1347, 1347, + 1347, 1348, 0, 1348, 1349, 1349, 1349, 1350, 0, 1350, + 1351, 1351, 1351, 1352, 1352, 1352, 1353, 1353, 1353, 1354, + 0, 1354, 1355, 0, 1355, 1356, 1356, 1356, 1357, 0, + + 1357, 1358, 1358, 0, 0, 1358, 1359, 1359, 0, 0, + 1359, 1360, 1360, 1360, 1361, 1361, 1361, 1362, 1362, 1362, + 1363, 1363, 1363, 1364, 1364, 1364, 1365, 1365, 1365, 1366, + 1366, 1366, 1367, 1367, 1367, 1368, 1368, 0, 0, 1368, + 1369, 1369, 1369, 1370, 1370, 0, 0, 1370, 1371, 1371, + 0, 0, 1371, 1372, 1372, 1372, 1373, 0, 1373, 1374, + 0, 1374, 1375, 1375, 1375, 1376, 0, 1376, 1377, 1377, + 1377, 1378, 1378, 1378, 1379, 1379, 1379, 1380, 0, 1380, + 1381, 0, 1381, 1382, 1382, 1382, 1383, 0, 1383, 1384, + 0, 1384, 1385, 0, 1385, 1386, 1386, 1386, 1387, 0, + + 1387, 1388, 0, 0, 1388, 1389, 1389, 0, 0, 1389, + 1390, 1390, 0, 1390, 1391, 1391, 0, 0, 1391, 1392, + 1392, 1392, 1393, 1393, 0, 1393, 1394, 1394, 1394, 0, + 1394, 1394, 1395, 1395, 1395, 1396, 1396, 1396, 1397, 1397, + 1397, 1398, 1398, 1398, 1399, 1399, 1399, 1400, 1400, 1400, + 1401, 1401, 1401, 1402, 1402, 1402, 1403, 1403, 0, 0, + 1403, 1404, 1404, 1404, 1405, 1405, 0, 1405, 1406, 1406, + 0, 0, 1406, 1407, 1407, 0, 1407, 1408, 1408, 0, + 0, 1408, 1409, 1409, 1409, 1410, 1410, 0, 1410, 1411, + 0, 0, 1411, 1412, 1412, 0, 1412, 1413, 1413, 0, + + 0, 1413, 1414, 1414, 0, 1414, 1415, 1415, 0, 0, + 1415, 1416, 1416, 1416, 1417, 1417, 0, 1417, 1418, 0, + 1418, 1419, 0, 1419, 1420, 0, 1420, 1421, 1421, 1421, + 1422, 0, 1422, 1423, 1423, 1423, 0, 1423, 1423, 1424, + 1424, 1424, 1425, 1425, 1425, 1426, 1426, 1426, 1427, 0, + 1427, 1428, 0, 1428, 1429, 1429, 1429, 1430, 0, 1430, + 1431, 0, 1431, 1432, 0, 1432, 1433, 1433, 1433, 1434, + 0, 1434, 1435, 0, 1435, 1436, 0, 1436, 1437, 0, + 1437, 1438, 1438, 1438, 1439, 0, 1439, 1440, 0, 1440, + 1441, 0, 0, 1441, 1442, 1442, 0, 1442, 1443, 1443, + + 0, 0, 1443, 1444, 1444, 0, 1444, 1445, 1445, 0, + 0, 1445, 1446, 1446, 1446, 1447, 1447, 0, 1447, 1448, + 1448, 1448, 0, 1448, 1448, 1449, 1449, 1449, 1450, 1450, + 1450, 1451, 1451, 1451, 1452, 1452, 1452, 1453, 1453, 1453, + 1454, 1454, 1454, 1455, 1455, 1455, 1456, 1456, 1456, 1457, + 1457, 0, 0, 1457, 1458, 1458, 1458, 1459, 1459, 0, + 1459, 1460, 1460, 0, 0, 1460, 1461, 1461, 0, 1461, + 1462, 1462, 0, 0, 1462, 1463, 1463, 1463, 1464, 1464, + 0, 1464, 1465, 0, 0, 1465, 1466, 1466, 0, 1466, + 1467, 1467, 0, 0, 1467, 1468, 1468, 0, 1468, 1469, + + 1469, 0, 0, 1469, 1470, 1470, 1470, 1471, 1471, 0, + 1471, 1472, 0, 1472, 1473, 0, 0, 1473, 1474, 1474, + 0, 1474, 1475, 1475, 0, 0, 1475, 1476, 1476, 0, + 1476, 1477, 1477, 0, 0, 1477, 1478, 1478, 1478, 1479, + 1479, 0, 1479, 1480, 0, 1480, 1481, 0, 1481, 1482, + 0, 1482, 1483, 1483, 1483, 1484, 0, 1484, 1485, 1485, + 1485, 0, 1485, 1485, 1486, 1486, 1486, 1487, 1487, 1487, + 1488, 1488, 1488, 1489, 1489, 1489, 1490, 1490, 1490, 1491, + 0, 1491, 1492, 0, 1492, 1493, 1493, 1493, 1494, 1494, + 1494, 1495, 0, 1495, 1496, 0, 1496, 1497, 0, 1497, + + 1498, 1498, 1498, 1499, 1499, 1499, 1500, 0, 1500, 1501, + 0, 1501, 1502, 0, 1502, 1503, 0, 1503, 1504, 1504, + 1504, 1505, 1505, 1505, 1506, 0, 1506, 1507, 0, 1507, + 1508, 0, 1508, 1509, 0, 1509, 1510, 1510, 1510, 1511, + 1511, 1511, 1512, 0, 1512, 1513, 0, 1513, 1514, 0, + 0, 1514, 1515, 1515, 0, 1515, 1516, 1516, 0, 0, + 1516, 1517, 1517, 0, 1517, 1518, 1518, 0, 0, 1518, + 1519, 1519, 1519, 1520, 1520, 0, 1520, 1521, 1521, 1521, + 0, 1521, 1521, 1522, 1522, 1522, 1523, 1523, 1523, 1524, + 1524, 1524, 1525, 1525, 1525, 1526, 1526, 1526, 1527, 1527, + + 1527, 1528, 1528, 1528, 1529, 0, 1529, 1530, 1530, 1530, + 1531, 1531, 0, 0, 1531, 1532, 1532, 1532, 1533, 1533, + 0, 1533, 1534, 1534, 0, 0, 1534, 1535, 1535, 0, + 1535, 1536, 1536, 0, 0, 1536, 1537, 1537, 1537, 1538, + 1538, 0, 1538, 1539, 0, 0, 1539, 1540, 1540, 0, + 1540, 1541, 1541, 0, 0, 1541, 1542, 1542, 0, 1542, + 1543, 1543, 0, 0, 1543, 1544, 1544, 1544, 1545, 1545, + 0, 1545, 1546, 0, 1546, 1547, 0, 0, 1547, 1548, + 1548, 0, 1548, 1549, 1549, 0, 0, 1549, 1550, 1550, + 0, 1550, 1551, 1551, 0, 0, 1551, 1552, 1552, 1552, + + 1553, 1553, 0, 1553, 1554, 0, 1554, 1555, 0, 0, + 1555, 1556, 1556, 0, 1556, 1557, 1557, 0, 0, 1557, + 1558, 1558, 0, 1558, 1559, 1559, 0, 0, 1559, 1560, + 1560, 1560, 1561, 1561, 0, 1561, 1562, 0, 1562, 1563, + 0, 1563, 1564, 0, 1564, 1565, 1565, 1565, 1566, 0, + 1566, 1567, 0, 1567, 1568, 1568, 1568, 0, 1568, 1568, + 1569, 0, 1569, 1570, 1570, 1570, 1571, 0, 1571, 1572, + 0, 1572, 1573, 0, 1573, 1574, 0, 1574, 1575, 0, + 1575, 1576, 1576, 0, 0, 1576, 1577, 1577, 1577, 1578, + 1578, 1578, 1579, 1579, 0, 1579, 1580, 1580, 1580, 1581, + + 0, 1581, 1582, 1582, 1582, 1583, 1583, 1583, 1584, 0, + 1584, 1585, 0, 1585, 1586, 1586, 1586, 1587, 1587, 1587, + 1588, 0, 1588, 1589, 0, 1589, 1590, 0, 1590, 1591, + 1591, 1591, 1592, 1592, 1592, 1593, 0, 1593, 1594, 0, + 1594, 1595, 0, 1595, 1596, 1596, 1596, 1597, 1597, 1597, + 1598, 0, 1598, 1599, 0, 1599, 1600, 0, 1600, 1601, + 1601, 1601, 1602, 1602, 1602, 1603, 0, 1603, 1604, 0, + 0, 1604, 1605, 1605, 0, 1605, 1606, 1606, 0, 0, + 1606, 1607, 1607, 0, 1607, 1608, 1608, 0, 0, 1608, + 1609, 0, 1609, 1610, 1610, 0, 1610, 1611, 1611, 1611, + + 0, 1611, 1611, 1612, 1612, 1612, 1613, 0, 1613, 1614, + 0, 1614, 1615, 0, 1615, 1616, 0, 1616, 1617, 0, + 1617, 1618, 0, 1618, 1619, 0, 1619, 1620, 1620, 1620, + 1621, 1621, 1621, 1622, 0, 1622, 1623, 1623, 0, 0, + 1623, 1624, 1624, 0, 1624, 1625, 0, 1625, 1626, 0, + 0, 1626, 1627, 1627, 0, 1627, 1628, 1628, 0, 0, + 1628, 1629, 1629, 0, 1629, 1630, 0, 1630, 1631, 0, + 1631, 1632, 0, 0, 1632, 1633, 1633, 0, 1633, 1634, + 1634, 0, 0, 1634, 1635, 1635, 0, 1635, 1636, 0, + 1636, 1637, 0, 1637, 1638, 0, 0, 1638, 1639, 1639, + + 0, 1639, 1640, 1640, 0, 0, 1640, 1641, 1641, 0, + 1641, 1642, 0, 1642, 1643, 0, 1643, 1644, 0, 0, + 1644, 1645, 1645, 0, 1645, 1646, 1646, 0, 0, 1646, + 1647, 1647, 0, 1647, 1648, 0, 1648, 1649, 0, 1649, + 1650, 0, 1650, 1651, 0, 1651, 1652, 1652, 1652, 1653, + 0, 1653, 1654, 1654, 1654, 0, 1654, 1654, 1655, 0, + 1655, 1656, 0, 1656, 1657, 0, 1657, 1658, 0, 1658, + 1659, 0, 1659, 1660, 0, 1660, 1661, 0, 1661, 1662, + 1662, 0, 0, 1662, 1663, 1663, 0, 1663, 1664, 0, + 1664, 1665, 0, 1665, 1666, 0, 1666, 1667, 0, 1667, + + 1668, 0, 1668, 1669, 0, 1669, 1670, 0, 1670, 1671, + 0, 1671, 1672, 0, 1672, 1673, 0, 1673, 1674, 0, + 0, 1674, 1675, 1675, 0, 0, 1675, 1676, 0, 1676, + 1677, 0, 1677, 1678, 0, 1678, 1679, 0, 0, 1679, + 1680, 0, 0, 1680, 1681, 0, 0, 1681, 1682, 0, + 0, 1682, 1683, 0, 0, 1683, 1684, 0, 1684, 1685, + 0, 1685, 1686, 0, 0, 1686, 1687, 0, 1687, 1688, + 0, 1688, 1689, 0, 1689, 1690, 0, 1690, 1691, 0, + 1691, 1692, 0, 0, 1692, 1693, 0, 1693, 1694, 0, + 1694, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, + 1321, 1321, 1321, 1321 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "../libpcap/scanner.l" +#define INITIAL 0 +#line 2 "../libpcap/scanner.l" +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.99.2.6 2005/11/09 23:49:48 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "pcap-int.h" + +#include "gencode.h" +#ifdef INET6 +#ifdef WIN32 +#include + +#ifdef __MINGW32__ +#include "IP6_misc.h" +#endif +#else /* WIN32 */ +#include /* for "struct sockaddr" in "struct addrinfo" */ +#include /* for "struct addrinfo" */ +#endif /* WIN32 */ + +/* Workaround for AIX 4.3 */ +#if !defined(AI_NUMERICHOST) +#define AI_NUMERICHOST 0x04 +#endif +#endif /*INET6*/ +#include +#include "tokdefs.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +static int stoi(char *); +static inline int xdtoi(int); + +#ifdef FLEX_SCANNER +#define YY_NO_UNPUT +static YY_BUFFER_STATE in_buffer; +#else +static char *in_buffer; + +#undef getc +#define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++) +#endif + +#define yylval pcap_lval +extern YYSTYPE yylval; + + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + } +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 169 "../libpcap/scanner.l" + + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1322 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 6592 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + +do_action: /* This label is used only to access EOF actions. */ + + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 170 "../libpcap/scanner.l" +return DST; + YY_BREAK +case 2: +YY_RULE_SETUP +#line 171 "../libpcap/scanner.l" +return SRC; + YY_BREAK +case 3: +YY_RULE_SETUP +#line 173 "../libpcap/scanner.l" +return LINK; + YY_BREAK +case 4: +YY_RULE_SETUP +#line 174 "../libpcap/scanner.l" +return LINK; + YY_BREAK +case 5: +YY_RULE_SETUP +#line 175 "../libpcap/scanner.l" +return ARP; + YY_BREAK +case 6: +YY_RULE_SETUP +#line 176 "../libpcap/scanner.l" +return RARP; + YY_BREAK +case 7: +YY_RULE_SETUP +#line 177 "../libpcap/scanner.l" +return IP; + YY_BREAK +case 8: +YY_RULE_SETUP +#line 178 "../libpcap/scanner.l" +return SCTP; + YY_BREAK +case 9: +YY_RULE_SETUP +#line 179 "../libpcap/scanner.l" +return TCP; + YY_BREAK +case 10: +YY_RULE_SETUP +#line 180 "../libpcap/scanner.l" +return UDP; + YY_BREAK +case 11: +YY_RULE_SETUP +#line 181 "../libpcap/scanner.l" +return ICMP; + YY_BREAK +case 12: +YY_RULE_SETUP +#line 182 "../libpcap/scanner.l" +return IGMP; + YY_BREAK +case 13: +YY_RULE_SETUP +#line 183 "../libpcap/scanner.l" +return IGRP; + YY_BREAK +case 14: +YY_RULE_SETUP +#line 184 "../libpcap/scanner.l" +return PIM; + YY_BREAK +case 15: +YY_RULE_SETUP +#line 185 "../libpcap/scanner.l" +return VRRP; + YY_BREAK +case 16: +YY_RULE_SETUP +#line 186 "../libpcap/scanner.l" +return RADIO; + YY_BREAK +case 17: +YY_RULE_SETUP +#line 188 "../libpcap/scanner.l" +{ +#ifdef INET6 + return IPV6; +#else + bpf_error("%s not supported", yytext); +#endif + } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 195 "../libpcap/scanner.l" +{ +#ifdef INET6 + return ICMPV6; +#else + bpf_error("%s not supported", yytext); +#endif + } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 202 "../libpcap/scanner.l" +return AH; + YY_BREAK +case 20: +YY_RULE_SETUP +#line 203 "../libpcap/scanner.l" +return ESP; + YY_BREAK +case 21: +YY_RULE_SETUP +#line 205 "../libpcap/scanner.l" +return ATALK; + YY_BREAK +case 22: +YY_RULE_SETUP +#line 206 "../libpcap/scanner.l" +return AARP; + YY_BREAK +case 23: +YY_RULE_SETUP +#line 207 "../libpcap/scanner.l" +return DECNET; + YY_BREAK +case 24: +YY_RULE_SETUP +#line 208 "../libpcap/scanner.l" +return LAT; + YY_BREAK +case 25: +YY_RULE_SETUP +#line 209 "../libpcap/scanner.l" +return SCA; + YY_BREAK +case 26: +YY_RULE_SETUP +#line 210 "../libpcap/scanner.l" +return MOPRC; + YY_BREAK +case 27: +YY_RULE_SETUP +#line 211 "../libpcap/scanner.l" +return MOPDL; + YY_BREAK +case 28: +YY_RULE_SETUP +#line 213 "../libpcap/scanner.l" +return ISO; + YY_BREAK +case 29: +YY_RULE_SETUP +#line 214 "../libpcap/scanner.l" +return ESIS; + YY_BREAK +case 30: +YY_RULE_SETUP +#line 215 "../libpcap/scanner.l" +return ESIS; + YY_BREAK +case 31: +YY_RULE_SETUP +#line 216 "../libpcap/scanner.l" +return ISIS; + YY_BREAK +case 32: +YY_RULE_SETUP +#line 217 "../libpcap/scanner.l" +return ISIS; + YY_BREAK +case 33: +YY_RULE_SETUP +#line 218 "../libpcap/scanner.l" +return L1; + YY_BREAK +case 34: +YY_RULE_SETUP +#line 219 "../libpcap/scanner.l" +return L2; + YY_BREAK +case 35: +YY_RULE_SETUP +#line 220 "../libpcap/scanner.l" +return IIH; + YY_BREAK +case 36: +YY_RULE_SETUP +#line 221 "../libpcap/scanner.l" +return LSP; + YY_BREAK +case 37: +YY_RULE_SETUP +#line 222 "../libpcap/scanner.l" +return SNP; + YY_BREAK +case 38: +YY_RULE_SETUP +#line 223 "../libpcap/scanner.l" +return CSNP; + YY_BREAK +case 39: +YY_RULE_SETUP +#line 224 "../libpcap/scanner.l" +return PSNP; + YY_BREAK +case 40: +YY_RULE_SETUP +#line 226 "../libpcap/scanner.l" +return CLNP; + YY_BREAK +case 41: +YY_RULE_SETUP +#line 228 "../libpcap/scanner.l" +return STP; + YY_BREAK +case 42: +YY_RULE_SETUP +#line 230 "../libpcap/scanner.l" +return IPX; + YY_BREAK +case 43: +YY_RULE_SETUP +#line 232 "../libpcap/scanner.l" +return NETBEUI; + YY_BREAK +case 44: +YY_RULE_SETUP +#line 234 "../libpcap/scanner.l" +return HOST; + YY_BREAK +case 45: +YY_RULE_SETUP +#line 235 "../libpcap/scanner.l" +return NET; + YY_BREAK +case 46: +YY_RULE_SETUP +#line 236 "../libpcap/scanner.l" +return NETMASK; + YY_BREAK +case 47: +YY_RULE_SETUP +#line 237 "../libpcap/scanner.l" +return PORT; + YY_BREAK +case 48: +YY_RULE_SETUP +#line 238 "../libpcap/scanner.l" +return PORTRANGE; + YY_BREAK +case 49: +YY_RULE_SETUP +#line 239 "../libpcap/scanner.l" +return PROTO; + YY_BREAK +case 50: +YY_RULE_SETUP +#line 240 "../libpcap/scanner.l" +{ +#ifdef NO_PROTOCHAIN + bpf_error("%s not supported", yytext); +#else + return PROTOCHAIN; +#endif + } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 248 "../libpcap/scanner.l" +return GATEWAY; + YY_BREAK +case 52: +YY_RULE_SETUP +#line 250 "../libpcap/scanner.l" +return LESS; + YY_BREAK +case 53: +YY_RULE_SETUP +#line 251 "../libpcap/scanner.l" +return GREATER; + YY_BREAK +case 54: +YY_RULE_SETUP +#line 252 "../libpcap/scanner.l" +return CBYTE; + YY_BREAK +case 55: +YY_RULE_SETUP +#line 253 "../libpcap/scanner.l" +return TK_BROADCAST; + YY_BREAK +case 56: +YY_RULE_SETUP +#line 254 "../libpcap/scanner.l" +return TK_MULTICAST; + YY_BREAK +case 57: +YY_RULE_SETUP +#line 256 "../libpcap/scanner.l" +return AND; + YY_BREAK +case 58: +YY_RULE_SETUP +#line 257 "../libpcap/scanner.l" +return OR; + YY_BREAK +case 59: +YY_RULE_SETUP +#line 258 "../libpcap/scanner.l" +return '!'; + YY_BREAK +case 60: +YY_RULE_SETUP +#line 260 "../libpcap/scanner.l" +return LEN; + YY_BREAK +case 61: +YY_RULE_SETUP +#line 261 "../libpcap/scanner.l" +return INBOUND; + YY_BREAK +case 62: +YY_RULE_SETUP +#line 262 "../libpcap/scanner.l" +return OUTBOUND; + YY_BREAK +case 63: +YY_RULE_SETUP +#line 264 "../libpcap/scanner.l" +return VLAN; + YY_BREAK +case 64: +YY_RULE_SETUP +#line 265 "../libpcap/scanner.l" +return MPLS; + YY_BREAK +case 65: +YY_RULE_SETUP +#line 266 "../libpcap/scanner.l" +return PPPOED; + YY_BREAK +case 66: +YY_RULE_SETUP +#line 267 "../libpcap/scanner.l" +return PPPOES; + YY_BREAK +case 67: +YY_RULE_SETUP +#line 269 "../libpcap/scanner.l" +return LANE; + YY_BREAK +case 68: +YY_RULE_SETUP +#line 270 "../libpcap/scanner.l" +return LLC; + YY_BREAK +case 69: +YY_RULE_SETUP +#line 271 "../libpcap/scanner.l" +return METAC; + YY_BREAK +case 70: +YY_RULE_SETUP +#line 272 "../libpcap/scanner.l" +return BCC; + YY_BREAK +case 71: +YY_RULE_SETUP +#line 273 "../libpcap/scanner.l" +return OAM; + YY_BREAK +case 72: +YY_RULE_SETUP +#line 274 "../libpcap/scanner.l" +return OAMF4; + YY_BREAK +case 73: +YY_RULE_SETUP +#line 275 "../libpcap/scanner.l" +return OAMF4EC; + YY_BREAK +case 74: +YY_RULE_SETUP +#line 276 "../libpcap/scanner.l" +return OAMF4SC; + YY_BREAK +case 75: +YY_RULE_SETUP +#line 277 "../libpcap/scanner.l" +return SC; + YY_BREAK +case 76: +YY_RULE_SETUP +#line 278 "../libpcap/scanner.l" +return ILMIC; + YY_BREAK +case 77: +YY_RULE_SETUP +#line 279 "../libpcap/scanner.l" +return VPI; + YY_BREAK +case 78: +YY_RULE_SETUP +#line 280 "../libpcap/scanner.l" +return VCI; + YY_BREAK +case 79: +YY_RULE_SETUP +#line 281 "../libpcap/scanner.l" +return CONNECTMSG; + YY_BREAK +case 80: +YY_RULE_SETUP +#line 282 "../libpcap/scanner.l" +return METACONNECT; + YY_BREAK +case 81: +YY_RULE_SETUP +#line 284 "../libpcap/scanner.l" +return PF_IFNAME; + YY_BREAK +case 82: +YY_RULE_SETUP +#line 285 "../libpcap/scanner.l" +return PF_RSET; + YY_BREAK +case 83: +YY_RULE_SETUP +#line 286 "../libpcap/scanner.l" +return PF_RNR; + YY_BREAK +case 84: +YY_RULE_SETUP +#line 287 "../libpcap/scanner.l" +return PF_SRNR; + YY_BREAK +case 85: +YY_RULE_SETUP +#line 288 "../libpcap/scanner.l" +return PF_REASON; + YY_BREAK +case 86: +YY_RULE_SETUP +#line 289 "../libpcap/scanner.l" +return PF_ACTION; + YY_BREAK +case 87: +YY_RULE_SETUP +#line 291 "../libpcap/scanner.l" +return SIO; + YY_BREAK +case 88: +YY_RULE_SETUP +#line 292 "../libpcap/scanner.l" +return OPC; + YY_BREAK +case 89: +YY_RULE_SETUP +#line 293 "../libpcap/scanner.l" +return DPC; + YY_BREAK +case 90: +YY_RULE_SETUP +#line 294 "../libpcap/scanner.l" +return SLS; + YY_BREAK +case 91: +YY_RULE_SETUP +#line 296 "../libpcap/scanner.l" +; + YY_BREAK +case 92: +YY_RULE_SETUP +#line 297 "../libpcap/scanner.l" +return yytext[0]; + YY_BREAK +case 93: +YY_RULE_SETUP +#line 298 "../libpcap/scanner.l" +return GEQ; + YY_BREAK +case 94: +YY_RULE_SETUP +#line 299 "../libpcap/scanner.l" +return LEQ; + YY_BREAK +case 95: +YY_RULE_SETUP +#line 300 "../libpcap/scanner.l" +return NEQ; + YY_BREAK +case 96: +YY_RULE_SETUP +#line 301 "../libpcap/scanner.l" +return '='; + YY_BREAK +case 97: +YY_RULE_SETUP +#line 302 "../libpcap/scanner.l" +return LSH; + YY_BREAK +case 98: +YY_RULE_SETUP +#line 303 "../libpcap/scanner.l" +return RSH; + YY_BREAK +case 99: +YY_RULE_SETUP +#line 304 "../libpcap/scanner.l" +{ yylval.e = pcap_ether_aton(((char *)yytext)+1); + return AID; } + YY_BREAK +case 100: +YY_RULE_SETUP +#line 306 "../libpcap/scanner.l" +{ yylval.i = stoi((char *)yytext); return NUM; } + YY_BREAK +case 101: +YY_RULE_SETUP +#line 307 "../libpcap/scanner.l" +{ + yylval.s = sdup((char *)yytext); return HID; } + YY_BREAK +case 102: +YY_RULE_SETUP +#line 309 "../libpcap/scanner.l" +{ yylval.e = pcap_ether_aton((char *)yytext); + return EID; } + YY_BREAK +case 103: +YY_RULE_SETUP +#line 311 "../libpcap/scanner.l" +{ +#ifdef INET6 + struct addrinfo hints, *res; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(yytext, NULL, &hints, &res)) + bpf_error("bogus IPv6 address %s", yytext); + else { + yylval.s = sdup((char *)yytext); return HID6; + } +#else + bpf_error("IPv6 address %s not supported", yytext); +#endif /*INET6*/ + } + YY_BREAK +case 104: +YY_RULE_SETUP +#line 326 "../libpcap/scanner.l" +{ bpf_error("bogus ethernet address %s", yytext); } + YY_BREAK +case 105: +YY_RULE_SETUP +#line 327 "../libpcap/scanner.l" +{ yylval.i = 0; return NUM; } + YY_BREAK +case 106: +YY_RULE_SETUP +#line 328 "../libpcap/scanner.l" +{ yylval.i = 1; return NUM; } + YY_BREAK +case 107: +YY_RULE_SETUP +#line 329 "../libpcap/scanner.l" +{ yylval.i = 0; return NUM; } + YY_BREAK +case 108: +YY_RULE_SETUP +#line 330 "../libpcap/scanner.l" +{ yylval.i = 3; return NUM; } + YY_BREAK +case 109: +YY_RULE_SETUP +#line 331 "../libpcap/scanner.l" +{ yylval.i = 4; return NUM; } + YY_BREAK +case 110: +YY_RULE_SETUP +#line 332 "../libpcap/scanner.l" +{ yylval.i = 5; return NUM; } + YY_BREAK +case 111: +YY_RULE_SETUP +#line 333 "../libpcap/scanner.l" +{ yylval.i = 8; return NUM; } + YY_BREAK +case 112: +YY_RULE_SETUP +#line 334 "../libpcap/scanner.l" +{ yylval.i = 9; return NUM; } + YY_BREAK +case 113: +YY_RULE_SETUP +#line 335 "../libpcap/scanner.l" +{ yylval.i = 10; return NUM; } + YY_BREAK +case 114: +YY_RULE_SETUP +#line 336 "../libpcap/scanner.l" +{ yylval.i = 11; return NUM; } + YY_BREAK +case 115: +YY_RULE_SETUP +#line 337 "../libpcap/scanner.l" +{ yylval.i = 12; return NUM; } + YY_BREAK +case 116: +YY_RULE_SETUP +#line 338 "../libpcap/scanner.l" +{ yylval.i = 13; return NUM; } + YY_BREAK +case 117: +YY_RULE_SETUP +#line 339 "../libpcap/scanner.l" +{ yylval.i = 14; return NUM; } + YY_BREAK +case 118: +YY_RULE_SETUP +#line 340 "../libpcap/scanner.l" +{ yylval.i = 15; return NUM; } + YY_BREAK +case 119: +YY_RULE_SETUP +#line 341 "../libpcap/scanner.l" +{ yylval.i = 16; return NUM; } + YY_BREAK +case 120: +YY_RULE_SETUP +#line 342 "../libpcap/scanner.l" +{ yylval.i = 17; return NUM; } + YY_BREAK +case 121: +YY_RULE_SETUP +#line 343 "../libpcap/scanner.l" +{ yylval.i = 18; return NUM; } + YY_BREAK +case 122: +YY_RULE_SETUP +#line 344 "../libpcap/scanner.l" +{ yylval.i = 13; return NUM; } + YY_BREAK +case 123: +YY_RULE_SETUP +#line 345 "../libpcap/scanner.l" +{ yylval.i = 0x01; return NUM; } + YY_BREAK +case 124: +YY_RULE_SETUP +#line 346 "../libpcap/scanner.l" +{ yylval.i = 0x02; return NUM; } + YY_BREAK +case 125: +YY_RULE_SETUP +#line 347 "../libpcap/scanner.l" +{ yylval.i = 0x04; return NUM; } + YY_BREAK +case 126: +YY_RULE_SETUP +#line 348 "../libpcap/scanner.l" +{ yylval.i = 0x08; return NUM; } + YY_BREAK +case 127: +YY_RULE_SETUP +#line 349 "../libpcap/scanner.l" +{ yylval.i = 0x10; return NUM; } + YY_BREAK +case 128: +YY_RULE_SETUP +#line 350 "../libpcap/scanner.l" +{ yylval.i = 0x20; return NUM; } + YY_BREAK +case 129: +YY_RULE_SETUP +#line 351 "../libpcap/scanner.l" +{ + yylval.s = sdup((char *)yytext); return ID; } + YY_BREAK +case 130: +YY_RULE_SETUP +#line 353 "../libpcap/scanner.l" +{ yylval.s = sdup((char *)yytext + 1); return ID; } + YY_BREAK +case 131: +YY_RULE_SETUP +#line 354 "../libpcap/scanner.l" +{ + bpf_error("illegal token: %s", yytext); } + YY_BREAK +case 132: +YY_RULE_SETUP +#line 356 "../libpcap/scanner.l" +{ bpf_error("illegal char '%c'", *yytext); } + YY_BREAK +case 133: +YY_RULE_SETUP +#line 357 "../libpcap/scanner.l" +ECHO; + YY_BREAK +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1322 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1322 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 1321); + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + + return c; + } + + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + +#ifndef _WIN32 +#include +#else +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif +#endif + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +#line 357 "../libpcap/scanner.l" + +void +lex_init(buf) + char *buf; +{ +#ifdef FLEX_SCANNER + in_buffer = yy_scan_string(buf); +#else + in_buffer = buf; +#endif +} + +/* + * Do any cleanup necessary after parsing. + */ +void +lex_cleanup() +{ +#ifdef FLEX_SCANNER + if (in_buffer != NULL) + yy_delete_buffer(in_buffer); + in_buffer = NULL; +#endif +} + +/* + * Also define a yywrap. Note that if we're using flex, it will + * define a macro to map this identifier to pcap_wrap. + */ +int +yywrap() +{ + return 1; +} + +/* Hex digit to integer. */ +static inline int +xdtoi(c) + register int c; +{ + if (isdigit(c)) + return c - '0'; + else if (islower(c)) + return c - 'a' + 10; + else + return c - 'A' + 10; +} + +/* + * Convert string to integer. Just like atoi(), but checks for + * preceding 0x or 0 and uses hex or octal instead of decimal. + */ +static int +stoi(s) + char *s; +{ + int base = 10; + int n = 0; + + if (*s == '0') { + if (s[1] == 'x' || s[1] == 'X') { + s += 2; + base = 16; + } + else { + base = 8; + s += 1; + } + } + while (*s) + n = n * base + xdtoi(*s++); + + return n; +} diff --git a/winpcap/wpcap/libpcap/scanner.l b/winpcap/wpcap/libpcap/scanner.l new file mode 100644 index 0000000..92581ee --- /dev/null +++ b/winpcap/wpcap/libpcap/scanner.l @@ -0,0 +1,430 @@ +%{ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.99.2.6 2005/11/09 23:49:48 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "pcap-int.h" + +#include "gencode.h" +#ifdef INET6 +#ifdef WIN32 +#include + +#ifdef __MINGW32__ +#include "IP6_misc.h" +#endif +#else /* WIN32 */ +#include /* for "struct sockaddr" in "struct addrinfo" */ +#include /* for "struct addrinfo" */ +#endif /* WIN32 */ + +/* Workaround for AIX 4.3 */ +#if !defined(AI_NUMERICHOST) +#define AI_NUMERICHOST 0x04 +#endif +#endif /*INET6*/ +#include +#include "tokdefs.h" + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +static int stoi(char *); +static inline int xdtoi(int); + +#ifdef FLEX_SCANNER +#define YY_NO_UNPUT +static YY_BUFFER_STATE in_buffer; +#else +static char *in_buffer; + +#undef getc +#define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++) +#endif + +#define yylval pcap_lval +extern YYSTYPE yylval; + +%} + +N ([0-9]+|(0X|0x)[0-9A-Fa-f]+) +B ([0-9A-Fa-f][0-9A-Fa-f]?) +W ([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?) + +%a 18400 +%o 21500 +%e 7600 +%k 4550 +%p 27600 +%n 2000 + +V680 {W}:{W}:{W}:{W}:{W}:{W}:{W}:{W} + +V670 ::{W}:{W}:{W}:{W}:{W}:{W}:{W} +V671 {W}::{W}:{W}:{W}:{W}:{W}:{W} +V672 {W}:{W}::{W}:{W}:{W}:{W}:{W} +V673 {W}:{W}:{W}::{W}:{W}:{W}:{W} +V674 {W}:{W}:{W}:{W}::{W}:{W}:{W} +V675 {W}:{W}:{W}:{W}:{W}::{W}:{W} +V676 {W}:{W}:{W}:{W}:{W}:{W}::{W} +V677 {W}:{W}:{W}:{W}:{W}:{W}:{W}:: + +V660 ::{W}:{W}:{W}:{W}:{W}:{W} +V661 {W}::{W}:{W}:{W}:{W}:{W} +V662 {W}:{W}::{W}:{W}:{W}:{W} +V663 {W}:{W}:{W}::{W}:{W}:{W} +V664 {W}:{W}:{W}:{W}::{W}:{W} +V665 {W}:{W}:{W}:{W}:{W}::{W} +V666 {W}:{W}:{W}:{W}:{W}:{W}:: + +V650 ::{W}:{W}:{W}:{W}:{W} +V651 {W}::{W}:{W}:{W}:{W} +V652 {W}:{W}::{W}:{W}:{W} +V653 {W}:{W}:{W}::{W}:{W} +V654 {W}:{W}:{W}:{W}::{W} +V655 {W}:{W}:{W}:{W}:{W}:: + +V640 ::{W}:{W}:{W}:{W} +V641 {W}::{W}:{W}:{W} +V642 {W}:{W}::{W}:{W} +V643 {W}:{W}:{W}::{W} +V644 {W}:{W}:{W}:{W}:: + +V630 ::{W}:{W}:{W} +V631 {W}::{W}:{W} +V632 {W}:{W}::{W} +V633 {W}:{W}:{W}:: + +V620 ::{W}:{W} +V621 {W}::{W} +V622 {W}:{W}:: + +V610 ::{W} +V611 {W}:: + +V600 :: + +V6604 {W}:{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} + +V6504 ::{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} +V6514 {W}::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} +V6524 {W}:{W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} +V6534 {W}:{W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N} +V6544 {W}:{W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N} +V6554 {W}:{W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N} + +V6404 ::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} +V6414 {W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} +V6424 {W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N} +V6434 {W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N} +V6444 {W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N} + +V6304 ::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} +V6314 {W}::{W}:{W}:{N}\.{N}\.{N}\.{N} +V6324 {W}:{W}::{W}:{N}\.{N}\.{N}\.{N} +V6334 {W}:{W}:{W}::{N}\.{N}\.{N}\.{N} + +V6204 ::{W}:{W}:{N}\.{N}\.{N}\.{N} +V6214 {W}::{W}:{N}\.{N}\.{N}\.{N} +V6224 {W}:{W}::{N}\.{N}\.{N}\.{N} + +V6104 ::{W}:{N}\.{N}\.{N}\.{N} +V6114 {W}::{N}\.{N}\.{N}\.{N} + +V6004 ::{N}\.{N}\.{N}\.{N} + + +V6 ({V680}|{V670}|{V671}|{V672}|{V673}|{V674}|{V675}|{V676}|{V677}|{V660}|{V661}|{V662}|{V663}|{V664}|{V665}|{V666}|{V650}|{V651}|{V652}|{V653}|{V654}|{V655}|{V640}|{V641}|{V642}|{V643}|{V644}|{V630}|{V631}|{V632}|{V633}|{V620}|{V621}|{V622}|{V610}|{V611}|{V600}|{V6604}|{V6504}|{V6514}|{V6524}|{V6534}|{V6544}|{V6554}|{V6404}|{V6414}|{V6424}|{V6434}|{V6444}|{V6304}|{V6314}|{V6324}|{V6334}|{V6204}|{V6214}|{V6224}|{V6104}|{V6114}|{V6004}) + +%% +dst return DST; +src return SRC; + +link|ether|ppp|slip return LINK; +fddi|tr|wlan return LINK; +arp return ARP; +rarp return RARP; +ip return IP; +sctp return SCTP; +tcp return TCP; +udp return UDP; +icmp return ICMP; +igmp return IGMP; +igrp return IGRP; +pim return PIM; +vrrp return VRRP; +radio return RADIO; + +ip6 { +#ifdef INET6 + return IPV6; +#else + bpf_error("%s not supported", yytext); +#endif + } +icmp6 { +#ifdef INET6 + return ICMPV6; +#else + bpf_error("%s not supported", yytext); +#endif + } +ah return AH; +esp return ESP; + +atalk return ATALK; +aarp return AARP; +decnet return DECNET; +lat return LAT; +sca return SCA; +moprc return MOPRC; +mopdl return MOPDL; + +iso return ISO; +esis return ESIS; +es-is return ESIS; +isis return ISIS; +is-is return ISIS; +l1 return L1; +l2 return L2; +iih return IIH; +lsp return LSP; +snp return SNP; +csnp return CSNP; +psnp return PSNP; + +clnp return CLNP; + +stp return STP; + +ipx return IPX; + +netbeui return NETBEUI; + +host return HOST; +net return NET; +mask return NETMASK; +port return PORT; +portrange return PORTRANGE; +proto return PROTO; +protochain { +#ifdef NO_PROTOCHAIN + bpf_error("%s not supported", yytext); +#else + return PROTOCHAIN; +#endif + } + +gateway return GATEWAY; + +less return LESS; +greater return GREATER; +byte return CBYTE; +broadcast return TK_BROADCAST; +multicast return TK_MULTICAST; + +and|"&&" return AND; +or|"||" return OR; +not return '!'; + +len|length return LEN; +inbound return INBOUND; +outbound return OUTBOUND; + +vlan return VLAN; +mpls return MPLS; +pppoed return PPPOED; +pppoes return PPPOES; + +lane return LANE; +llc return LLC; +metac return METAC; +bcc return BCC; +oam return OAM; +oamf4 return OAMF4; +oamf4ec return OAMF4EC; +oamf4sc return OAMF4SC; +sc return SC; +ilmic return ILMIC; +vpi return VPI; +vci return VCI; +connectmsg return CONNECTMSG; +metaconnect return METACONNECT; + +on|ifname return PF_IFNAME; +rset|ruleset return PF_RSET; +rnr|rulenum return PF_RNR; +srnr|subrulenum return PF_SRNR; +reason return PF_REASON; +action return PF_ACTION; + +sio return SIO; +opc return OPC; +dpc return DPC; +sls return SLS; + +[ \r\n\t] ; +[+\-*/:\[\]!<>()&|=] return yytext[0]; +">=" return GEQ; +"<=" return LEQ; +"!=" return NEQ; +"==" return '='; +"<<" return LSH; +">>" return RSH; +${B} { yylval.e = pcap_ether_aton(((char *)yytext)+1); + return AID; } +{N} { yylval.i = stoi((char *)yytext); return NUM; } +({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) { + yylval.s = sdup((char *)yytext); return HID; } +{B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char *)yytext); + return EID; } +{V6} { +#ifdef INET6 + struct addrinfo hints, *res; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(yytext, NULL, &hints, &res)) + bpf_error("bogus IPv6 address %s", yytext); + else { + yylval.s = sdup((char *)yytext); return HID6; + } +#else + bpf_error("IPv6 address %s not supported", yytext); +#endif /*INET6*/ + } +{B}:+({B}:+)+ { bpf_error("bogus ethernet address %s", yytext); } +icmptype { yylval.i = 0; return NUM; } +icmpcode { yylval.i = 1; return NUM; } +icmp-echoreply { yylval.i = 0; return NUM; } +icmp-unreach { yylval.i = 3; return NUM; } +icmp-sourcequench { yylval.i = 4; return NUM; } +icmp-redirect { yylval.i = 5; return NUM; } +icmp-echo { yylval.i = 8; return NUM; } +icmp-routeradvert { yylval.i = 9; return NUM; } +icmp-routersolicit { yylval.i = 10; return NUM; } +icmp-timxceed { yylval.i = 11; return NUM; } +icmp-paramprob { yylval.i = 12; return NUM; } +icmp-tstamp { yylval.i = 13; return NUM; } +icmp-tstampreply { yylval.i = 14; return NUM; } +icmp-ireq { yylval.i = 15; return NUM; } +icmp-ireqreply { yylval.i = 16; return NUM; } +icmp-maskreq { yylval.i = 17; return NUM; } +icmp-maskreply { yylval.i = 18; return NUM; } +tcpflags { yylval.i = 13; return NUM; } +tcp-fin { yylval.i = 0x01; return NUM; } +tcp-syn { yylval.i = 0x02; return NUM; } +tcp-rst { yylval.i = 0x04; return NUM; } +tcp-push { yylval.i = 0x08; return NUM; } +tcp-ack { yylval.i = 0x10; return NUM; } +tcp-urg { yylval.i = 0x20; return NUM; } +[A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? { + yylval.s = sdup((char *)yytext); return ID; } +"\\"[^ !()\n\t]+ { yylval.s = sdup((char *)yytext + 1); return ID; } +[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+ { + bpf_error("illegal token: %s", yytext); } +. { bpf_error("illegal char '%c'", *yytext); } +%% +void +lex_init(buf) + char *buf; +{ +#ifdef FLEX_SCANNER + in_buffer = yy_scan_string(buf); +#else + in_buffer = buf; +#endif +} + +/* + * Do any cleanup necessary after parsing. + */ +void +lex_cleanup() +{ +#ifdef FLEX_SCANNER + if (in_buffer != NULL) + yy_delete_buffer(in_buffer); + in_buffer = NULL; +#endif +} + +/* + * Also define a yywrap. Note that if we're using flex, it will + * define a macro to map this identifier to pcap_wrap. + */ +int +yywrap() +{ + return 1; +} + +/* Hex digit to integer. */ +static inline int +xdtoi(c) + register int c; +{ + if (isdigit(c)) + return c - '0'; + else if (islower(c)) + return c - 'a' + 10; + else + return c - 'A' + 10; +} + +/* + * Convert string to integer. Just like atoi(), but checks for + * preceding 0x or 0 and uses hex or octal instead of decimal. + */ +static int +stoi(s) + char *s; +{ + int base = 10; + int n = 0; + + if (*s == '0') { + if (s[1] == 'x' || s[1] == 'X') { + s += 2; + base = 16; + } + else { + base = 8; + s += 1; + } + } + while (*s) + n = n * base + xdtoi(*s++); + + return n; +} diff --git a/winpcap/wpcap/libpcap/sll.h b/winpcap/wpcap/libpcap/sll.h new file mode 100644 index 0000000..85a3a9d --- /dev/null +++ b/winpcap/wpcap/libpcap/sll.h @@ -0,0 +1,124 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#) $Header: /tcpdump/master/libpcap/sll.h,v 1.7 2002/06/11 17:04:48 itojun Exp $ (LBL) + */ + +/* + * For captures on Linux cooked sockets, we construct a fake header + * that includes: + * + * a 2-byte "packet type" which is one of: + * + * LINUX_SLL_HOST packet was sent to us + * LINUX_SLL_BROADCAST packet was broadcast + * LINUX_SLL_MULTICAST packet was multicast + * LINUX_SLL_OTHERHOST packet was sent to somebody else + * LINUX_SLL_OUTGOING packet was sent *by* us; + * + * a 2-byte Ethernet protocol field; + * + * a 2-byte link-layer type; + * + * a 2-byte link-layer address length; + * + * an 8-byte source link-layer address, whose actual length is + * specified by the previous value. + * + * All fields except for the link-layer address are in network byte order. + * + * DO NOT change the layout of this structure, or change any of the + * LINUX_SLL_ values below. If you must change the link-layer header + * for a "cooked" Linux capture, introduce a new DLT_ type (ask + * "tcpdump-workers@tcpdump.org" for one, so that you don't give it a + * value that collides with a value already being used), and use the + * new header in captures of that type, so that programs that can + * handle DLT_LINUX_SLL captures will continue to handle them correctly + * without any change, and so that capture files with different headers + * can be told apart and programs that read them can dissect the + * packets in them. + */ + +/* + * A DLT_LINUX_SLL fake link-layer header. + */ +#define SLL_HDR_LEN 16 /* total header length */ +#define SLL_ADDRLEN 8 /* length of address field */ + +struct sll_header { + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; /* link-layer address type */ + u_int16_t sll_halen; /* link-layer address length */ + u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ + u_int16_t sll_protocol; /* protocol */ +}; + +/* + * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the + * PACKET_ values on Linux, but are defined here so that they're + * available even on systems other than Linux, and so that they + * don't change even if the PACKET_ values change. + */ +#define LINUX_SLL_HOST 0 +#define LINUX_SLL_BROADCAST 1 +#define LINUX_SLL_MULTICAST 2 +#define LINUX_SLL_OTHERHOST 3 +#define LINUX_SLL_OUTGOING 4 + +/* + * The LINUX_SLL_ values for "sll_protocol"; these correspond to the + * ETH_P_ values on Linux, but are defined here so that they're + * available even on systems other than Linux. We assume, for now, + * that the ETH_P_ values won't change in Linux; if they do, then: + * + * if we don't translate them in "pcap-linux.c", capture files + * won't necessarily be readable if captured on a system that + * defines ETH_P_ values that don't match these values; + * + * if we do translate them in "pcap-linux.c", that makes life + * unpleasant for the BPF code generator, as the values you test + * for in the kernel aren't the values that you test for when + * reading a capture file, so the fixup code run on BPF programs + * handed to the kernel ends up having to do more work. + * + * Add other values here as necessary, for handling packet types that + * might show up on non-Ethernet, non-802.x networks. (Not all the ones + * in the Linux "if_ether.h" will, I suspect, actually show up in + * captures.) + */ +#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ +#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ diff --git a/winpcap/wpcap/libpcap/sockutils.c b/winpcap/wpcap/libpcap/sockutils.c new file mode 100644 index 0000000..280cad2 --- /dev/null +++ b/winpcap/wpcap/libpcap/sockutils.c @@ -0,0 +1,1241 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + + +/*! + \file sockutils.c + + The goal of this file is to provide a common set of primitives for socket manipulation. + Although the socket interface defined in the RFC 2553 (and its updates) is excellent, several + minor issues are still hidden in supporting several operating systems. + + These calls do not want to provide a better socket interface; vice versa, they intend to + provide a set of calls that is portable among several operating systems, hiding their + differences. +*/ + + +#include "sockutils.h" +#include // for strerror() +#include // for the errno variable +#include // for the stderr file +#include // for malloc() and free() + + + + + + +// WinSock Initialization +#ifdef WIN32 + #define WINSOCK_MAJOR_VERSION 2 /*!< Ask for Winsock 2.2 */ + #define WINSOCK_MINOR_VERSION 2 /*!< Ask for Winsock 2.2 */ + int sockcount= 0; /*!< Variable that allows calling the WSAStartup() only one time */ +#endif + +// Some minor differences between UNIX and Win32 +#ifdef WIN32 + #define SHUT_WR SD_SEND /*!< The control code for shutdown() is different in Win32 */ + #define snprintf _snprintf /*!< The snprintf is called _snprintf() in Win32 */ +#endif + + +//! Size of the buffer that has to keep error messages +#define SOCK_ERRBUF_SIZE 1024 + + + // Constants; used in order to keep strings here +#define SOCKET_NO_NAME_AVAILABLE "No name available" +#define SOCKET_NO_PORT_AVAILABLE "No port available" +#define SOCKET_NAME_NULL_DAD "Null address (possibly DAD Phase)" + + + + +/**************************************************** + * * + * Locally defined functions * + * * + ****************************************************/ + +int sock_ismcastaddr(const struct sockaddr *saddr); + + + + + +/**************************************************** + * * + * Function bodies * + * * + ****************************************************/ + + +/*! + \brief It retrieves the error message after an error occurred in the socket interface. + + This function is defined because of the different way errors are returned in UNIX + and Win32. This function provides a consistent way to retrieve the error message + (after a socket error occurred) on all the platforms. + + \param caller: a pointer to a user-allocated string which contains a message that has + to be printed *before* the true error message. It could be, for example, 'this error + comes from the recv() call at line 31'. It may be NULL. + + \param errbuf: a pointer to an user-allocated buffer that will contain the complete + error message. This buffer has to be at least 'errbuflen' in length. + It can be NULL; in this case the error cannot be printed. + + \param errbuflen: length of the buffer that will contains the error. The error message cannot be + larger than 'errbuflen - 1' because the last char is reserved for the string terminator. + + \return No return values. The error message is returned in the 'string' parameter. +*/ +void sock_geterror(const char *caller, char *errbuf, int errbuflen) +{ +#ifdef WIN32 + int retval; + int code; + TCHAR message[SOCK_ERRBUF_SIZE]; /* It will be char (if we're using ascii) or wchar_t (if we're using unicode) */ + + code= GetLastError(); + + retval= FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_MAX_WIDTH_MASK, + NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + message, sizeof(message) / sizeof(TCHAR), NULL); + + if (retval == 0) + { + if (errbuf) + { + if ( (caller) && (*caller) ) + snprintf(errbuf, errbuflen, "%sUnable to get the exact error message", caller); + else + snprintf(errbuf, errbuflen, "Unable to get the exact error message"); + + errbuf[errbuflen - 1]= 0; + } + + return; + } + + if (errbuf) + { + if ( (caller) && (*caller) ) + snprintf(errbuf, errbuflen, "%s%s (code %d)", caller, message, code); + else + snprintf(errbuf, errbuflen, "%s (code %d)", message, code); + + errbuf[errbuflen - 1]= 0; + } + + +#else + char *message; + + message= strerror(errno); + + if (errbuf) + { + if ( (caller) && (*caller) ) + snprintf(errbuf, errbuflen, "%s%s (code %d)", caller, message, errno); + else + snprintf(errbuf, errbuflen, "%s (code %d)", message, errno); + + errbuf[errbuflen - 1]= 0; + } + +#endif +} + + + +/*! + \brief It initializes sockets. + + This function is pretty useless on UNIX, since socket initialization is not required. + However it is required on Win32. In UNIX, this function appears to be completely empty. + + \param errbuf: a pointer to an user-allocated buffer that will contain the complete + error message. This buffer has to be at least 'errbuflen' in length. + It can be NULL; in this case the error cannot be printed. + + \param errbuflen: length of the buffer that will contains the error. The error message cannot be + larger than 'errbuflen - 1' because the last char is reserved for the string terminator. + + \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned + in the 'errbuf' variable. +*/ +int sock_init(char *errbuf, int errbuflen) +{ +#ifdef WIN32 + if (sockcount == 0) + { + WSADATA wsaData; // helper variable needed to initialize Winsock + + // Ask for Winsock version 2.2. + if ( WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) + { + if (errbuf) + { + snprintf(errbuf, errbuflen, "Failed to initialize Winsock\n"); + errbuf[errbuflen - 1]= 0; + } + + WSACleanup(); + + return -1; + } + } + + sockcount++; +#endif + + return 0; +} + + + +/*! + \brief It deallocates sockets. + + This function is pretty useless on UNIX, since socket deallocation is not required. + However it is required on Win32. In UNIX, this function appears to be completely empty. + + \return No error values. +*/ +void sock_cleanup() +{ +#ifdef WIN32 + sockcount--; + + if (sockcount == 0) + WSACleanup(); +#endif +} + + + +/*! + \brief It checks if the sockaddr variable contains a multicast address. + + \return '0' if the address is multicast, '-1' if it is not. +*/ +int sock_ismcastaddr(const struct sockaddr *saddr) +{ + if (saddr->sa_family == PF_INET) + { + struct sockaddr_in *saddr4 = (struct sockaddr_in *) saddr; + if (IN_MULTICAST(ntohl(saddr4->sin_addr.s_addr))) return 0; + else return -1; + } + else + { + struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) saddr; + if (IN6_IS_ADDR_MULTICAST(&saddr6->sin6_addr)) return 0; + else return -1; + } +} + + + +/*! + \brief It initializes a network connection both from the client and the server side. + + In case of a client socket, this function calls socket() and connect(). + In the meanwhile, it checks for any socket error. + If an error occurs, it writes the error message into 'errbuf'. + + In case of a server socket, the function calls socket(), bind() and listen(). + + This function is usually preceeded by the sock_initaddress(). + + \param addrinfo: pointer to an addrinfo variable which will be used to + open the socket and such. This variable is the one returned by the previous call to + sock_initaddress(). + + \param server: '1' if this is a server socket, '0' otherwise. + + \param nconn: number of the connections that are allowed to wait into the listen() call. + This value has no meanings in case of a client socket. + + \param errbuf: a pointer to an user-allocated buffer that will contain the complete + error message. This buffer has to be at least 'errbuflen' in length. + It can be NULL; in this case the error cannot be printed. + + \param errbuflen: length of the buffer that will contains the error. The error message cannot be + larger than 'errbuflen - 1' because the last char is reserved for the string terminator. + + \return the socket that has been opened (that has to be used in the following sockets calls) + if everything is fine, '0' if some errors occurred. The error message is returned + in the 'errbuf' variable. +*/ +SOCKET sock_open(struct addrinfo *addrinfo, int server, int nconn, char *errbuf, int errbuflen) +{ +SOCKET sock; + + sock = socket(addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol); + if (sock == -1) + { + sock_geterror("socket(): ", errbuf, errbuflen); + return -1; + } + + + // This is a server socket + if (server) + { +#ifdef BSD + // Force the use of IPv6-only addresses; in BSD you can accept both v4 and v6 + // connections if you have a "NULL" pointer as the nodename in the getaddrinfo() + // This behaviour is not clear in the RFC 2553, so each system implements the + // bind() differently from this point of view + + if (addrinfo->ai_family == PF_INET6) + { + int on; + + if (setsockopt(sock, IPPROTO_IPV6, IPV6_BINDV6ONLY, (char *)&on, sizeof (int)) == -1) + { + if (errbuf) + { + snprintf(errbuf, errbuflen, "setsockopt(IPV6_BINDV6ONLY)"); + errbuf[errbuflen - 1]= 0; + } + return -1; + } + } +#endif + + // WARNING: if the address is a mcast one, I should place the proper Win32 code here + if (bind(sock, addrinfo->ai_addr, addrinfo->ai_addrlen) != 0) + { + sock_geterror("bind(): ", errbuf, errbuflen); + return -1; + } + + if (addrinfo->ai_socktype == SOCK_STREAM) + if (listen(sock, nconn) == -1) + { + sock_geterror("listen(): ", errbuf, errbuflen); + return -1; + } + + // server side ended + return sock; + } + else // we're the client + { + struct addrinfo *tempaddrinfo; + char *errbufptr; + int bufspaceleft; + + tempaddrinfo= addrinfo; + errbufptr= errbuf; + bufspaceleft= errbuflen; + *errbufptr= 0; + + + // We have to loop though all the addinfo returned. + // For instance, we can have both IPv6 and IPv4 addresses, but the service we're trying + // to connect to is unavailable in IPv6, so we have to try in IPv4 as well + while (tempaddrinfo) + { + + if (connect(sock, tempaddrinfo->ai_addr, tempaddrinfo->ai_addrlen) == -1) + { + int msglen; + char TmpBuffer[100]; + char SocketErrorMessage[SOCK_ERRBUF_SIZE]; + + // We have to retrieve the error message before any other socket call completes, otherwise + // the error message is lost + sock_geterror(NULL, SocketErrorMessage, sizeof(SocketErrorMessage) ); + + // Returns the numeric address of the host that triggered the error + sock_getascii_addrport( (struct sockaddr_storage *) tempaddrinfo->ai_addr, TmpBuffer, sizeof(TmpBuffer), NULL, 0, NI_NUMERICHOST, TmpBuffer, sizeof(TmpBuffer) ); + + snprintf(errbufptr, bufspaceleft, "Is the server properly installed on %s? connect() failed: %s", TmpBuffer, SocketErrorMessage); + + // In case more then one 'connect' fails, we manage to keep all the error messages + msglen= strlen(errbufptr); + + errbufptr[msglen]= ' '; + errbufptr[msglen + 1]= 0; + + bufspaceleft= bufspaceleft - (msglen + 1); + errbufptr+= (msglen + 1); + + tempaddrinfo= tempaddrinfo->ai_next; + } + else + break; + } + + // Check how we exit from the previous loop + // If tempaddrinfo is equal to NULL, it means that all the connect() failed. + if (tempaddrinfo == NULL) + { + closesocket(sock); + return -1; + } + else + return sock; + } +} + + + + +/*! + \brief Closes the present (TCP and UDP) socket connection. + + This function sends a shutdown() on the socket in order to disable send() calls + (while recv() ones are still allowed). Then, it closes the socket. + + \param sock: the socket identifier of the connection that has to be closed. + + \param errbuf: a pointer to an user-allocated buffer that will contain the complete + error message. This buffer has to be at least 'errbuflen' in length. + It can be NULL; in this case the error cannot be printed. + + \param errbuflen: length of the buffer that will contains the error. The error message cannot be + larger than 'errbuflen - 1' because the last char is reserved for the string terminator. + + \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned + in the 'errbuf' variable. +*/ +int sock_close(SOCKET sock, char *errbuf, int errbuflen) +{ + // SHUT_WR: subsequent calls to the send function are disallowed. + // For TCP sockets, a FIN will be sent after all data is sent and + // acknowledged by the Server. + if (shutdown(sock, SHUT_WR) ) + { + sock_geterror("shutdown(): ", errbuf, errbuflen); + // close the socket anyway + closesocket(sock); + return -1; + } + + closesocket(sock); + return 0; +} + + + + + + +/*! + \brief Checks that the address, port and flags given are valids and it returns an 'addrinfo' stucture. + + This function basically calls the getaddrinfo() calls, and it performs a set of sanity checks + to control that everything is fine (e.g. a TCP socket cannot have a mcast address, and such). + If an error occurs, it writes the error message into 'errbuf'. + + \param address: a pointer to a user-allocated buffer containing the network address to check. + It could be both a numeric - literal address, and it can be NULL or "" (useful in case of a server + socket which has to bind to all addresses). + + \param port: a pointer to a user-allocated buffer containing the network port to use. + + \param hints: an addrinfo variable (passed by reference) containing the flags needed to create the + addrinfo structure appropriately. + + \param addrinfo: it represents the true returning value. This is a pointer to an addrinfo variable + (passed by reference), which will be allocated by this function and returned back to the caller. + This variable will be used in the next sockets calls. + + \param errbuf: a pointer to an user-allocated buffer that will contain the complete + error message. This buffer has to be at least 'errbuflen' in length. + It can be NULL; in this case the error cannot be printed. + + \param errbuflen: length of the buffer that will contains the error. The error message cannot be + larger than 'errbuflen - 1' because the last char is reserved for the string terminator. + + \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned + in the 'errbuf' variable. The addrinfo variable that has to be used in the following sockets calls is + returned into the addrinfo parameter. + + \warning The 'addrinfo' variable has to be deleted by the programmer by calling freeaddrinfo() when + it is no longer needed. + + \warning This function requires the 'hints' variable as parameter. The semantic of this variable is the same + of the one of the corresponding variable used into the standard getaddrinfo() socket function. We suggest + the programmer to look at that function in order to set the 'hints' variable appropriately. +*/ +int sock_initaddress(const char *address, const char *port, + struct addrinfo *hints, struct addrinfo **addrinfo, char *errbuf, int errbuflen) +{ +int retval; + + retval = getaddrinfo(address, port, hints, addrinfo); + if (retval != 0) + { + // if the getaddrinfo() fails, you have to use gai_strerror(), instead of using the standard + // error routines (errno) in UNIX; WIN32 suggests using the GetLastError() instead. + if (errbuf) +#ifdef WIN32 + sock_geterror("getaddrinfo(): ", errbuf, errbuflen); +#else + if (errbuf) + { + snprintf(errbuf, errbuflen, "getaddrinfo() %s", gai_strerror(retval)); + errbuf[errbuflen - 1]= 0; + } +#endif + return -1; + } +/*! + \warning SOCKET: I should check all the accept() in order to bind to all addresses in case + addrinfo has more han one pointers +*/ + + // This software only supports PF_INET and PF_INET6. + if (( (*addrinfo)->ai_family != PF_INET) && ( (*addrinfo)->ai_family != PF_INET6)) + { + if (errbuf) + { + snprintf(errbuf, errbuflen, "getaddrinfo(): socket type not supported"); + errbuf[errbuflen - 1]= 0; + } + return -1; + } + + if ( ( (*addrinfo)->ai_socktype == SOCK_STREAM) && (sock_ismcastaddr( (*addrinfo)->ai_addr) == 0) ) + { + if (errbuf) + { + snprintf(errbuf, errbuflen, "getaddrinfo(): multicast addresses are not valid when using TCP streams"); + errbuf[errbuflen - 1]= 0; + } + + return -1; + } + + return 0; +} + + + +/*! + \brief It sends the amount of data contained into 'buffer' on the given socket. + + This function basically calls the send() socket function and it checks that all + the data specified in 'buffer' (of size 'size') will be sent. If an error occurs, + it writes the error message into 'errbuf'. + In case the socket buffer does not have enough space, it loops until all data + has been sent. + + \param socket: the connected socket currently opened. + + \param buffer: a char pointer to a user-allocated buffer in which data is contained. + + \param size: number of bytes that have to be sent. + + \param errbuf: a pointer to an user-allocated buffer that will contain the complete + error message. This buffer has to be at least 'errbuflen' in length. + It can be NULL; in this case the error cannot be printed. + + \param errbuflen: length of the buffer that will contains the error. The error message cannot be + larger than 'errbuflen - 1' because the last char is reserved for the string terminator. + + \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned + in the 'errbuf' variable. +*/ +int sock_send(SOCKET socket, const char *buffer, int size, char *errbuf, int errbuflen) +{ +int nsent; + +send: +#ifdef linux +/* + Another pain... in Linux there's this flag + MSG_NOSIGNAL + Requests not to send SIGPIPE on errors on stream-oriented + sockets when the other end breaks the connection. + The EPIPE error is still returned. +*/ + nsent = send(socket, buffer, size, MSG_NOSIGNAL); +#else + nsent = send(socket, buffer, size, 0); +#endif + + if (nsent == -1) + { + sock_geterror("send(): ", errbuf, errbuflen); + return -1; + } + + if (nsent != size) + { + size-= nsent; + buffer+= nsent; + goto send; + } + + return 0; +} + + +/*! + \brief It copies the amount of data contained into 'buffer' into 'tempbuf'. + and it checks for buffer overflows. + + This function basically copies 'size' bytes of data contained into 'buffer' + into 'tempbuf', starting at offset 'offset'. Before that, it checks that the + resulting buffer will not be larger than 'totsize'. Finally, it updates + the 'offset' variable in order to point to the first empty location of the buffer. + + In case the function is called with 'checkonly' equal to 1, it does not copy + the data into the buffer. It only checks for buffer overflows and it updates the + 'offset' variable. This mode can be useful when the buffer already contains the + data (maybe because the producer writes directly into the target buffer), so + only the buffer overflow check has to be made. + In this case, both 'buffer' and 'tempbuf' can be NULL values. + + This function is useful in case the userland application does not know immediately + all the data it has to write into the socket. This function provides a way to create + the "stream" step by step, appendning the new data to the old one. Then, when all the + data has been bufferized, the application can call the sock_send() function. + + \param buffer: a char pointer to a user-allocated buffer that keeps the data + that has to be copied. + + \param size: number of bytes that have to be copied. + + \param tempbuf: user-allocated buffer (of size 'totsize') in which data + has to be copied. + + \param offset: an index into 'tempbuf' which keeps the location of its first + empty location. + + \param totsize: total size of the buffer in which data is being copied. + + \param checkonly: '1' if we do not want to copy data into the buffer and we + want just do a buffer ovreflow control, '0' if data has to be copied as well. + + \param errbuf: a pointer to an user-allocated buffer that will contain the complete + error message. This buffer has to be at least 'errbuflen' in length. + It can be NULL; in this case the error cannot be printed. + + \param errbuflen: length of the buffer that will contains the error. The error message cannot be + larger than 'errbuflen - 1' because the last char is reserved for the string terminator. + + \return '0' if everything is fine, '-1' if some errors occurred. The error message + is returned in the 'errbuf' variable. When the function returns, 'tempbuf' will + have the new string appended, and 'offset' will keep the length of that buffer. + In case of 'checkonly == 1', data is not copied, but 'offset' is updated in any case. + + \warning This function assumes that the buffer in which data has to be stored is + large 'totbuf' bytes. + + \warning In case of 'checkonly', be carefully to call this function *before* copying + the data into the buffer. Otherwise, the control about the buffer overflow is useless. +*/ +int sock_bufferize(const char *buffer, int size, char *tempbuf, int *offset, int totsize, int checkonly, char *errbuf, int errbuflen) +{ + + if ((*offset + size) > totsize) + { + if (errbuf) + { + snprintf(errbuf, errbuflen, "Not enough space in the temporary send buffer."); + errbuf[errbuflen - 1]= 0; + } + + return -1; + }; + + if (!checkonly) + memcpy(tempbuf + (*offset), buffer, size); + + (*offset)+= size; + + return 0; +} + + + +/*! + \brief It waits on a connected socket and it manages to receive data. + + This function basically calls the recv() socket function and it checks that no + error occurred. If that happens, it writes the error message into 'errbuf'. + + This function changes its behaviour according to the 'receiveall' flag: if we + want to receive exactly 'size' byte, it loops on the recv() until all the requested + data is arrived. Otherwise, it returns the data currently available. + + In case the socket does not have enough data available, it cycles on the recv() + util the requested data (of size 'size') is arrived. + In this case, it blocks until the number of bytes read is equal to 'size'. + + \param sock: the connected socket currently opened. + + \param buffer: a char pointer to a user-allocated buffer in which data has to be stored + + \param size: size of the allocated buffer. WARNING: this indicates the number of bytes + that we are expecting to be read. + + \param receiveall: if '0' (or SOCK_RECEIVEALL_NO), it returns as soon as some data + is ready; otherwise, (or SOCK_RECEIVEALL_YES) it waits until 'size' data has been + received (in case the socket does not have enough data available). + + \param errbuf: a pointer to an user-allocated buffer that will contain the complete + error message. This buffer has to be at least 'errbuflen' in length. + It can be NULL; in this case the error cannot be printed. + + \param errbuflen: length of the buffer that will contains the error. The error message cannot be + larger than 'errbuflen - 1' because the last char is reserved for the string terminator. + + \return the number of bytes read if everything is fine, '-1' if some errors occurred. + The error message is returned in the 'errbuf' variable. +*/ +int sock_recv(SOCKET sock, char *buffer, int size, int receiveall, char *errbuf, int errbuflen) +{ +int nread; +int totread= 0; + // We can obtain the same result using the MSG_WAITALL flag + // However, this is not supported by recv() in Win32 + + if (size == 0) + { + SOCK_ASSERT("I have been requested to read zero bytes", 1); + return 0; + } + +again: + nread= recv(sock, &(buffer[totread]), size - totread, 0); + + if (nread == -1) + { + sock_geterror("recv(): ", errbuf, errbuflen); + return -1; + } + + if (nread == 0) + { + if (errbuf) + { + snprintf(errbuf, errbuflen, "The other host terminated the connection."); + errbuf[errbuflen - 1]= 0; + } + + return -1; + } + + // If we want to return as soon as some data has been received, + // let's do the job + if (!receiveall) + return nread; + + totread+= nread; + + if (totread != size) + goto again; + + return totread; +} + + + +/*! + \brief It discards N bytes that are currently waiting to be read on the current socket. + + This function is useful in case we receive a message we cannot undestand (e.g. + wrong version number when receiving a network packet), so that we have to discard all + data before reading a new message. + + This function will read 'size' bytes from the socket and discard them. + It defines an internal buffer in which data will be copied; however, in case + this buffer is not large enough, it will cycle in order to read everything as well. + + \param sock: the connected socket currently opened. + + \param size: number of bytes that have to be discarded. + + \param errbuf: a pointer to an user-allocated buffer that will contain the complete + error message. This buffer has to be at least 'errbuflen' in length. + It can be NULL; in this case the error cannot be printed. + + \param errbuflen: length of the buffer that will contains the error. The error message cannot be + larger than 'errbuflen - 1' because the last char is reserved for the string terminator. + + \return '0' if everything is fine, '-1' if some errors occurred. + The error message is returned in the 'errbuf' variable. +*/ +int sock_discard(SOCKET sock, int size, char *errbuf, int errbuflen) +{ +#define TEMP_BUF_SIZE 32768 + +char buffer[TEMP_BUF_SIZE]; // network buffer, to be used when the message is discarded + + // A static allocation avoids the need of a 'malloc()' each time we want to discard a message + // Our feeling is that a buffer if 32KB is enough for most of the application; + // in case this is not enough, the "while" loop discards the message by calling the + // sockrecv() several times. + // We do not want to create a bigger variable because this causes the program to exit on + // some platforms (e.g. BSD) + + while (size > TEMP_BUF_SIZE) + { + if (sock_recv(sock, buffer, TEMP_BUF_SIZE, SOCK_RECEIVEALL_YES, errbuf, errbuflen) == -1) + return -1; + + size-= TEMP_BUF_SIZE; + } + + // If there is still data to be discarded + // In this case, the data can fit into the temporaty buffer + if (size) + { + if (sock_recv(sock, buffer, size, SOCK_RECEIVEALL_YES, errbuf, errbuflen) == -1) + return -1; + } + + SOCK_ASSERT("I'm currently discarding data\n", 1); + + return 0; +} + + + +/*! + \brief Checks that one host (identified by the sockaddr_storage structure) belongs to an 'allowed list'. + + This function is useful after an accept() call in order to check if the connecting + host is allowed to connect to me. To do that, we have a buffer that keeps the list of the + allowed host; this function checks the sockaddr_storage structure of the connecting host + against this host list, and it returns '0' is the host is included in this list. + + \param hostlist: pointer to a string that contains the list of the allowed host. + + \param sep: a string that keeps the separators used between the hosts (for example the + space character) in the host list. + + \param from: a sockaddr_storage structure, as it is returned by the accept() call. + + \param errbuf: a pointer to an user-allocated buffer that will contain the complete + error message. This buffer has to be at least 'errbuflen' in length. + It can be NULL; in this case the error cannot be printed. + + \param errbuflen: length of the buffer that will contains the error. The error message cannot be + larger than 'errbuflen - 1' because the last char is reserved for the string terminator. + + \return It returns: + - '1' if the host list is empty + - '0' if the host belongs to the host list (and therefore it is allowed to connect) + - '-1' in case the host does not belong to the host list (and therefore it is not allowed to connect + - '-2' in case or error. The error message is returned in the 'errbuf' variable. +*/ +int sock_check_hostlist(char *hostlist, const char *sep, struct sockaddr_storage *from, char *errbuf, int errbuflen) +{ + // checks if the connecting host is among the ones allowed + if ( (hostlist) && (hostlist[0]) ) + { + char *token; // temp, needed to separate items into the hostlist + struct addrinfo *addrinfo, *ai_next; + char *temphostlist; + + temphostlist= (char *) malloc (strlen(hostlist) + 1); + if (temphostlist == NULL) + { + sock_geterror("sock_check_hostlist(), malloc() failed", errbuf, errbuflen); + return -2; + } + + // The problem is that strtok modifies the original variable by putting '0' at the end of each token + // So, we have to create a new temporary string in which the original content is kept + strcpy(temphostlist, hostlist); + + token= strtok(temphostlist, sep); + + // it avoids a warning in the compilation ('addrinfo used but not initialized') + addrinfo = NULL; + + while( token != NULL ) + { + struct addrinfo hints; + int retval; + + addrinfo = NULL; + memset(&hints, 0, sizeof (struct addrinfo) ); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype= SOCK_STREAM; + + retval = getaddrinfo(token, "0", &hints, &addrinfo); + if (retval != 0) + { + if (errbuf) + { + snprintf(errbuf, errbuflen, "getaddrinfo() %s", gai_strerror(retval)); + errbuf[errbuflen - 1]= 0; + } + + SOCK_ASSERT(errbuf, 1); + + // Get next token + token = strtok( NULL, sep); + continue; + } + + // ai_next is required to preserve the content of addrinfo, in order to deallocate it properly + ai_next= addrinfo; + while(ai_next) + { + if (sock_cmpaddr(from, (struct sockaddr_storage *) ai_next->ai_addr) == 0) + { + free(temphostlist); + return 0; + } + + // If we are here, it means that the current address does not matches + // Let's try with the next one in the header chain + ai_next= ai_next->ai_next; + } + + freeaddrinfo(addrinfo); + addrinfo= NULL; + + // Get next token + token = strtok( NULL, sep); + } + + if (addrinfo) + { + freeaddrinfo(addrinfo); + addrinfo= NULL; + } + + if (errbuf) + { + snprintf(errbuf, errbuflen, "The host is not in the allowed host list. Connection refused."); + errbuf[errbuflen - 1]= 0; + } + + free(temphostlist); + return -1; + } + + // No hostlist, so we have to return 'empty list' + return 1; +} + + +/*! + \brief Compares two addresses contained into two sockaddr_storage structures. + + This function is useful to compare two addresses, given their internal representation, + i.e. an sockaddr_storage structure. + + The two structures do not need to be sockaddr_storage; you can have both 'sockaddr_in' and + sockaddr_in6, properly acsted in order to be compliant to the function interface. + + This function will return '0' if the two addresses matches, '-1' if not. + + \param first: a sockaddr_storage structure, (for example the one that is returned by an + accept() call), containing the first address to compare. + + \param second: a sockaddr_storage structure containing the second address to compare. + + \return '0' if the addresses are equal, '-1' if they are different. +*/ +int sock_cmpaddr(struct sockaddr_storage *first, struct sockaddr_storage *second) +{ + if (first->ss_family == second->ss_family) + { + if (first->ss_family == AF_INET) + { + if (memcmp( &(((struct sockaddr_in *) first)->sin_addr), + &(((struct sockaddr_in *) second)->sin_addr), + sizeof(struct in_addr) ) == 0) + return 0; + } + else // address family is AF_INET6 + { + if (memcmp( &(((struct sockaddr_in6 *) first)->sin6_addr), + &(((struct sockaddr_in6 *) second)->sin6_addr), + sizeof(struct in6_addr) ) == 0) + return 0; + } + } + + return -1; +} + + + +/*! + \brief It gets the address/port the system picked for this socket (on connected sockets). + + It is used to return the addess and port the server picked for our socket on the local machine. + It works only on: + - connected sockets + - server sockets + + On unconnected client sockets it does not work because the system dynamically chooses a port + only when the socket calls a send() call. + + \param sock: the connected socket currently opened. + + \param address: it contains the address that will be returned by the function. This buffer + must be properly allocated by the user. The address can be either literal or numeric depending + on the value of 'Flags'. + + \param addrlen: the length of the 'address' buffer. + + \param port: it contains the port that will be returned by the function. This buffer + must be properly allocated by the user. + + \param portlen: the length of the 'port' buffer. + + \param flags: a set of flags (the ones defined into the getnameinfo() standard socket function) + that determine if the resulting address must be in numeric / literal form, and so on. + + \param errbuf: a pointer to an user-allocated buffer that will contain the complete + error message. This buffer has to be at least 'errbuflen' in length. + It can be NULL; in this case the error cannot be printed. + + \param errbuflen: length of the buffer that will contains the error. The error message cannot be + larger than 'errbuflen - 1' because the last char is reserved for the string terminator. + + \return It returns '-1' if this function succeedes, '0' otherwise. + The address and port corresponding are returned back in the buffers 'address' and 'port'. + In any case, the returned strings are '0' terminated. + + \warning If the socket is using a connectionless protocol, the address may not be available + until I/O occurs on the socket. +*/ +int sock_getmyinfo(SOCKET sock, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen) +{ +struct sockaddr_storage mysockaddr; +socklen_t sockaddrlen; + + + sockaddrlen = sizeof(struct sockaddr_storage); + + if (getsockname(sock, (struct sockaddr *) &mysockaddr, &sockaddrlen) == -1) + { + sock_geterror("getsockname(): ", errbuf, errbuflen); + return 0; + } + else + { + // Returns the numeric address of the host that triggered the error + return sock_getascii_addrport(&mysockaddr, address, addrlen, port, portlen, flags, errbuf, errbuflen); + } + + return 0; +} + + + +/*! + \brief It retrieves two strings containing the address and the port of a given 'sockaddr' variable. + + This function is basically an extended version of the inet_ntop(), which does not exist in + WIN32 because the same result can be obtained by using the getnameinfo(). + However, differently from inet_ntop(), this function is able to return also literal names + (e.g. 'locahost') dependingly from the 'Flags' parameter. + + The function accepts a sockaddr_storage variable (which can be returned by several functions + like bind(), connect(), accept(), and more) and it transforms its content into a 'human' + form. So, for instance, it is able to translate an hex address (stored in bynary form) into + a standard IPv6 address like "::1". + + The behaviour of this function depends on the parameters we have in the 'Flags' variable, which + are the ones allowed in the standard getnameinfo() socket function. + + \param sockaddr: a 'sockaddr_in' or 'sockaddr_in6' structure containing the address that + need to be translated from network form into the presentation form. This structure must be + zero-ed prior using it, and the address family field must be filled with the proper value. + The user must cast any 'sockaddr_in' or 'sockaddr_in6' structures to 'sockaddr_storage' before + calling this function. + + \param address: it contains the address that will be returned by the function. This buffer + must be properly allocated by the user. The address can be either literal or numeric depending + on the value of 'Flags'. + + \param addrlen: the length of the 'address' buffer. + + \param port: it contains the port that will be returned by the function. This buffer + must be properly allocated by the user. + + \param portlen: the length of the 'port' buffer. + + \param flags: a set of flags (the ones defined into the getnameinfo() standard socket function) + that determine if the resulting address must be in numeric / literal form, and so on. + + \param errbuf: a pointer to an user-allocated buffer that will contain the complete + error message. This buffer has to be at least 'errbuflen' in length. + It can be NULL; in this case the error cannot be printed. + + \param errbuflen: length of the buffer that will contains the error. The error message cannot be + larger than 'errbuflen - 1' because the last char is reserved for the string terminator. + + \return It returns '-1' if this function succeedes, '0' otherwise. + The address and port corresponding to the given SockAddr are returned back in the buffers 'address' + and 'port'. + In any case, the returned strings are '0' terminated. +*/ +int sock_getascii_addrport(const struct sockaddr_storage *sockaddr, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen) +{ +socklen_t sockaddrlen; +int retval; // Variable that keeps the return value; + + retval= -1; + +#ifdef WIN32 + if (sockaddr->ss_family == AF_INET) + sockaddrlen = sizeof(struct sockaddr_in); + else + sockaddrlen = sizeof(struct sockaddr_in6); +#else + sockaddrlen = sizeof(struct sockaddr_storage); +#endif + + if ((flags & NI_NUMERICHOST) == 0) // Check that we want literal names + { + if ( (sockaddr->ss_family == AF_INET6) && + (memcmp( &((struct sockaddr_in6 *) sockaddr)->sin6_addr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(struct in6_addr) ) == 0) ) + { + if (address) + strncpy(address, SOCKET_NAME_NULL_DAD, addrlen); + return retval; + } + } + + if ( getnameinfo((struct sockaddr *) sockaddr, sockaddrlen, address, addrlen, port, portlen, flags) != 0) + { + // If the user wants to receive an error message + if (errbuf) + { + sock_geterror("getnameinfo(): ", errbuf, errbuflen); + errbuf[errbuflen-1]= 0; + } + + if (address) + { + strncpy(address, SOCKET_NO_NAME_AVAILABLE, addrlen); + address[addrlen-1]= 0; + } + + if (port) + { + strncpy(port, SOCKET_NO_PORT_AVAILABLE, portlen); + port[portlen-1]= 0; + } + + retval= 0; + } + + return retval; +} + + + +/*! + \brief It translates an address from the 'presentation' form into the 'network' form. + + This function basically replaces inet_pton(), which does not exist in WIN32 because + the same result can be obtained by using the getaddrinfo(). + An addictional advantage is that 'Address' can be both a numeric address (e.g. '127.0.0.1', + like in inet_pton() ) and a literal name (e.g. 'localhost'). + + This function does the reverse job of sock_getascii_addrport(). + + \param address: a zero-terminated string which contains the name you have to + translate. The name can be either literal (e.g. 'localhost') or numeric (e.g. '::1'). + + \param sockaddr: a user-allocated sockaddr_storage structure which will contains the + 'network' form of the requested address. + + \param addr_family: a constant which can assume the following values: + - 'AF_INET' if we want to ping an IPv4 host + - 'AF_INET6' if we want to ping an IPv6 host + - 'AF_UNSPEC' if we do not have preferences about the protocol used to ping the host + + \param errbuf: a pointer to an user-allocated buffer that will contain the complete + error message. This buffer has to be at least 'errbuflen' in length. + It can be NULL; in this case the error cannot be printed. + + \param errbuflen: length of the buffer that will contains the error. The error message cannot be + larger than 'errbuflen - 1' because the last char is reserved for the string terminator. + + \return '-1' if the translation succeded, '-2' if there was some non critical error, '0' + otherwise. In case it fails, the content of the SockAddr variable remains unchanged. + A 'non critical error' can occur in case the 'Address' is a literal name, which can be mapped + to several network addresses (e.g. 'foo.bar.com' => '10.2.2.2' and '10.2.2.3'). In this case + the content of the SockAddr parameter will be the address corresponding to the first mapping. + + \warning The sockaddr_storage structure MUST be allocated by the user. +*/ +int sock_present2network(const char *address, struct sockaddr_storage *sockaddr, int addr_family, char *errbuf, int errbuflen) +{ +int retval; +struct addrinfo *addrinfo; +struct addrinfo hints; + + memset(&hints, 0, sizeof(hints) ); + + hints.ai_family= addr_family; + + if ( (retval= sock_initaddress(address, "22222" /* fake port */, &hints, &addrinfo, errbuf, errbuflen)) == -1 ) + return 0; + + if (addrinfo->ai_family == PF_INET) + memcpy(sockaddr, addrinfo->ai_addr, sizeof(struct sockaddr_in) ); + else + memcpy(sockaddr, addrinfo->ai_addr, sizeof(struct sockaddr_in6) ); + + if (addrinfo->ai_next != NULL) + { + freeaddrinfo(addrinfo); + + if (errbuf) + { + snprintf(errbuf, errbuflen, "More than one socket requested; using the first one returned"); + errbuf[errbuflen - 1]= 0; + } + + return -2; + } + + freeaddrinfo(addrinfo); + return -1; +} + + diff --git a/winpcap/wpcap/libpcap/sockutils.h b/winpcap/wpcap/libpcap/sockutils.h new file mode 100644 index 0000000..f0cff31 --- /dev/null +++ b/winpcap/wpcap/libpcap/sockutils.h @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef __SOCKUTILS_H__ +#define __SOCKUTILS_H__ + + +#if _MSC_VER > 1000 +#pragma once +#endif + + +#ifdef WIN32 +/* Prevents a compiler warning in case this was already defined (to avoid that */ +/* windows.h includes winsock.h */ +#ifdef _WINSOCKAPI_ +#undef _WINSOCKAPI_ +#endif +/* Need windef.h for defines used in winsock2.h under MingW32 */ +#ifdef __MINGW32__ +#include +#endif +#include +#include +#else +#include +#include /* for memset() */ +#include +#include +#include /* DNS lookup */ +#include /* close() */ +#include /* errno() */ +#include /* for sockaddr_in, in BSD at least */ +#include +#include +#endif + + +/* MingW headers include this definition, but only for Windows XP and above. + MSDN states that this function is available for most versions on Windows. +*/ +#if ((defined(__MINGW32__)) && (_WIN32_WINNT < 0x0501)) +int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD, + char*,DWORD,int); +#endif + + +/*! + \defgroup SockUtils Cross-platform socket utilities (IPv4-IPv6) +*/ + + +/*! \addtogroup SockUtils + \{ +*/ + + + +/*! + \defgroup ExportedStruct Exported Structures and Definitions +*/ + +/*! \addtogroup ExportedStruct + \{ +*/ + + + + +// Some minor differences between UNIX and Win32 +#ifdef WIN32 +/*! + \brief In Win32, sockets use unsigned integers; in UNIX, they use signed integer. + + So, we define a generic SOCKET in order to be cross-platform compatible. +*/ + #define SOCKET unsigned int +#else +/*! + \brief In Win32, sockets use unsigned integers; in UNIX, they use signed integer. + + So, we define a generic SOCKET in order to be cross-platform compatible. +*/ + + #define SOCKET int + +/*! + \brief In Win32, the close() call cannot be used for socket. + + So, we define a generic closesocket() call in order to be cross-platform compatible. +*/ + #define closesocket(a) close(a) +#endif + + + + + +/*! + \brief DEBUG facility: it prints an error message on the screen (stderr) + + This macro prints the error on the standard error stream (stderr); + if we are working in debug mode (i.e. there is no NDEBUG defined) and we are in + Microsoft Visual C++, the error message will appear on the MSVC console as well. + + When NDEBUG is defined, this macro is empty. + + \param msg: the message you want to print. + + \param expr: 'false' if you want to abort the program, 'true' it you want + to print the message and continue. + + \return No return values. +*/ +#ifdef NDEBUG +#define SOCK_ASSERT(msg, expr) ((void)0) +#else + #include + #if (defined(WIN32) && defined(_MSC_VER)) + #include // for _CrtDbgReport + // Use MessageBox(NULL, msg, "warning", MB_OK)' instead of the other calls if you want to debug a Win32 service + // Remember to activate the 'allow service to interact with desktop' flag of the service + #define SOCK_ASSERT(msg, expr) { _CrtDbgReport(_CRT_WARN, NULL, 0, NULL, "%s\n", msg); fprintf(stderr, "%s\n", msg); assert(expr); } + #else + #define SOCK_ASSERT(msg, expr) { fprintf(stderr, "%s\n", msg); assert(expr); } + #endif +#endif + + + + +/**************************************************** + * * + * Exported functions / definitions * + * * + ****************************************************/ + +//! 'checkonly' flag, into the rpsock_bufferize() +#define SOCKBUF_CHECKONLY 1 +//! no 'checkonly' flag, into the rpsock_bufferize() +#define SOCKBUF_BUFFERIZE 0 + +//! no 'server' flag; it opens a client socket +#define SOCKOPEN_CLIENT 0 +//! 'server' flag; it opens a server socket +#define SOCKOPEN_SERVER 1 + +//! Changes the behaviour of the sock_recv(); it does not wait to receive all data +#define SOCK_RECEIVEALL_NO 0 +//! Changes the behaviour of the sock_recv(); it waits to receive all data +#define SOCK_RECEIVEALL_YES 1 + + +/*! + \} +*/ + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! + \defgroup ExportedFunc Exported Functions +*/ + +/*! \addtogroup ExportedFunc + \{ +*/ + + +int sock_init(char *errbuf, int errbuflen); +void sock_cleanup(); +// It is 'public' because there are calls (like accept() ) which are not managed from inside the sockutils files +void sock_geterror(const char *caller, char *errbuf, int errbufsize); +int sock_initaddress(const char *address, const char *port, + struct addrinfo *hints, struct addrinfo **addrinfo, char *errbuf, int errbuflen); +int sock_recv(SOCKET socket, char *buffer, int size, int receiveall, char *errbuf, int errbuflen); +SOCKET sock_open(struct addrinfo *addrinfo, int server, int nconn, char *errbuf, int errbuflen); +int sock_close(SOCKET sock, char *errbuf, int errbuflen); + +int sock_send(SOCKET socket, const char *buffer, int size, char *errbuf, int errbuflen); +int sock_bufferize(const char *buffer, int size, char *tempbuf, int *offset, int totsize, int checkonly, char *errbuf, int errbuflen); +int sock_discard(SOCKET socket, int size, char *errbuf, int errbuflen); +int sock_check_hostlist(char *hostlist, const char *sep, struct sockaddr_storage *from, char *errbuf, int errbuflen); +int sock_cmpaddr(struct sockaddr_storage *first, struct sockaddr_storage *second); + +int sock_getmyinfo(SOCKET sock, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen); + +int sock_getascii_addrport(const struct sockaddr_storage *sockaddr, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen); +int sock_present2network(const char *address, struct sockaddr_storage *sockaddr, int addr_family, char *errbuf, int errbuflen); + + +#ifdef __cplusplus +} +#endif + + +/*! + \} +*/ + + + +/*! + \} +*/ + + + +#endif diff --git a/winpcap/wpcap/libpcap/sunatmpos.h b/winpcap/wpcap/libpcap/sunatmpos.h new file mode 100644 index 0000000..7538b2a --- /dev/null +++ b/winpcap/wpcap/libpcap/sunatmpos.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 1997 Yen Yen Lim and North Dakota State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Yen Yen Lim and + North Dakota State University + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @(#) $Header: /tcpdump/master/libpcap/sunatmpos.h,v 1.1 2002/07/11 09:06:47 guy Exp $ (LBL) + */ + +/* SunATM header for ATM packet */ +#define SUNATM_DIR_POS 0 +#define SUNATM_VPI_POS 1 +#define SUNATM_VCI_POS 2 +#define SUNATM_PKT_BEGIN_POS 4 /* Start of ATM packet */ + +/* Protocol type values in the bottom for bits of the byte at SUNATM_DIR_POS. */ +#define PT_LANE 0x01 /* LANE */ +#define PT_LLC 0x02 /* LLC encapsulation */ +#define PT_ILMI 0x05 /* ILMI */ +#define PT_QSAAL 0x06 /* Q.SAAL */ diff --git a/winpcap/wpcap/libpcap/tokdefs.h b/winpcap/wpcap/libpcap/tokdefs.h new file mode 100644 index 0000000..1156adb --- /dev/null +++ b/winpcap/wpcap/libpcap/tokdefs.h @@ -0,0 +1,262 @@ +/* A Bison parser, made by GNU Bison 2.1. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + DST = 258, + SRC = 259, + HOST = 260, + GATEWAY = 261, + NET = 262, + NETMASK = 263, + PORT = 264, + PORTRANGE = 265, + LESS = 266, + GREATER = 267, + PROTO = 268, + PROTOCHAIN = 269, + CBYTE = 270, + ARP = 271, + RARP = 272, + IP = 273, + SCTP = 274, + TCP = 275, + UDP = 276, + ICMP = 277, + IGMP = 278, + IGRP = 279, + PIM = 280, + VRRP = 281, + ATALK = 282, + AARP = 283, + DECNET = 284, + LAT = 285, + SCA = 286, + MOPRC = 287, + MOPDL = 288, + TK_BROADCAST = 289, + TK_MULTICAST = 290, + NUM = 291, + INBOUND = 292, + OUTBOUND = 293, + PF_IFNAME = 294, + PF_RSET = 295, + PF_RNR = 296, + PF_SRNR = 297, + PF_REASON = 298, + PF_ACTION = 299, + LINK = 300, + GEQ = 301, + LEQ = 302, + NEQ = 303, + ID = 304, + EID = 305, + HID = 306, + HID6 = 307, + AID = 308, + LSH = 309, + RSH = 310, + LEN = 311, + IPV6 = 312, + ICMPV6 = 313, + AH = 314, + ESP = 315, + VLAN = 316, + MPLS = 317, + PPPOED = 318, + PPPOES = 319, + ISO = 320, + ESIS = 321, + CLNP = 322, + ISIS = 323, + L1 = 324, + L2 = 325, + IIH = 326, + LSP = 327, + SNP = 328, + CSNP = 329, + PSNP = 330, + STP = 331, + IPX = 332, + NETBEUI = 333, + LANE = 334, + LLC = 335, + METAC = 336, + BCC = 337, + SC = 338, + ILMIC = 339, + OAMF4EC = 340, + OAMF4SC = 341, + OAM = 342, + OAMF4 = 343, + CONNECTMSG = 344, + METACONNECT = 345, + VPI = 346, + VCI = 347, + RADIO = 348, + SIO = 349, + OPC = 350, + DPC = 351, + SLS = 352, + AND = 353, + OR = 354, + UMINUS = 355 + }; +#endif +/* Tokens. */ +#define DST 258 +#define SRC 259 +#define HOST 260 +#define GATEWAY 261 +#define NET 262 +#define NETMASK 263 +#define PORT 264 +#define PORTRANGE 265 +#define LESS 266 +#define GREATER 267 +#define PROTO 268 +#define PROTOCHAIN 269 +#define CBYTE 270 +#define ARP 271 +#define RARP 272 +#define IP 273 +#define SCTP 274 +#define TCP 275 +#define UDP 276 +#define ICMP 277 +#define IGMP 278 +#define IGRP 279 +#define PIM 280 +#define VRRP 281 +#define ATALK 282 +#define AARP 283 +#define DECNET 284 +#define LAT 285 +#define SCA 286 +#define MOPRC 287 +#define MOPDL 288 +#define TK_BROADCAST 289 +#define TK_MULTICAST 290 +#define NUM 291 +#define INBOUND 292 +#define OUTBOUND 293 +#define PF_IFNAME 294 +#define PF_RSET 295 +#define PF_RNR 296 +#define PF_SRNR 297 +#define PF_REASON 298 +#define PF_ACTION 299 +#define LINK 300 +#define GEQ 301 +#define LEQ 302 +#define NEQ 303 +#define ID 304 +#define EID 305 +#define HID 306 +#define HID6 307 +#define AID 308 +#define LSH 309 +#define RSH 310 +#define LEN 311 +#define IPV6 312 +#define ICMPV6 313 +#define AH 314 +#define ESP 315 +#define VLAN 316 +#define MPLS 317 +#define PPPOED 318 +#define PPPOES 319 +#define ISO 320 +#define ESIS 321 +#define CLNP 322 +#define ISIS 323 +#define L1 324 +#define L2 325 +#define IIH 326 +#define LSP 327 +#define SNP 328 +#define CSNP 329 +#define PSNP 330 +#define STP 331 +#define IPX 332 +#define NETBEUI 333 +#define LANE 334 +#define LLC 335 +#define METAC 336 +#define BCC 337 +#define SC 338 +#define ILMIC 339 +#define OAMF4EC 340 +#define OAMF4SC 341 +#define OAM 342 +#define OAMF4 343 +#define CONNECTMSG 344 +#define METACONNECT 345 +#define VPI 346 +#define VCI 347 +#define RADIO 348 +#define SIO 349 +#define OPC 350 +#define DPC 351 +#define SLS 352 +#define AND 353 +#define OR 354 +#define UMINUS 355 + + + + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 90 "../libpcap/GRAMMAR.Y" +typedef union YYSTYPE { + int i; + bpf_u_int32 h; + u_char *e; + char *s; + struct stmt *stmt; + struct arth *a; + struct { + struct qual q; + int atmfieldtype; + int mtp3fieldtype; + struct block *b; + } blk; + struct block *rblk; +} YYSTYPE; +/* Line 1447 of yacc.c. */ +#line 254 "y.tab.h" +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +extern YYSTYPE pcap_lval; + + + -- 2.11.4.GIT