Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/SoftEtherVPN/SoftEtherVPN_Stable.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/SeeDll')
-rw-r--r--src/SeeDll/AdInfo.c1410
-rw-r--r--src/SeeDll/Devioctl.h90
-rw-r--r--src/SeeDll/Ntddndis.h1400
-rw-r--r--src/SeeDll/Ntddpack.h26
-rw-r--r--src/SeeDll/Packet32.c2302
-rw-r--r--src/SeeDll/Packet32.h424
-rw-r--r--src/SeeDll/SeeDll.rc63
-rw-r--r--src/SeeDll/SeeDll.vcproj288
-rw-r--r--src/SeeDll/See_Win32.def34
-rw-r--r--src/SeeDll/See_x64.def34
-rw-r--r--src/SeeDll/dagc.h225
-rw-r--r--src/SeeDll/resource.h84
12 files changed, 6380 insertions, 0 deletions
diff --git a/src/SeeDll/AdInfo.c b/src/SeeDll/AdInfo.c
new file mode 100644
index 00000000..c0dbbc7e
--- /dev/null
+++ b/src/SeeDll/AdInfo.c
@@ -0,0 +1,1410 @@
+/*
+ * Copyright (c) 1999 - 2003
+ * 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 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.
+ */
+
+#include <GlobalConst.h>
+
+/*
+ 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
+
+#include <stdio.h>
+#include <packet32.h>
+
+#if 0
+#include "WanPacket/WanPacket.h"
+#endif
+
+#define _WINNT4
+
+#include <windows.h>
+#include <windowsx.h>
+#include <Iphlpapi.h>
+#include <IPIfCons.h>
+#include <stdio.h>
+
+#include <ntddndis.h>
+
+
+LPADAPTER PacketOpenAdapterNPF(PCHAR AdapterName);
+BOOL PacketAddFakeNdisWanAdapter();
+
+PADAPTER_INFO AdaptersInfoList = NULL; ///< Head of the adapter information list. This list is populated when packet.dll is linked by the application.
+HANDLE AdaptersInfoMutex; ///< 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.
+
+#define FAKE_NDISWAN_ADAPTER_NAME "\\Device\\SEE_GenericDialupAdapter" ///< 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 "Generic dialup adapter" ///< Description of a fake ndiswan adapter that is always available on 2000/XP/2003, used to capture NCP/LCP packets
+
+extern FARPROC GetAdaptersAddressesPointer;
+
+#ifdef HAVE_DAG_API
+extern dagc_open_handler p_dagc_open;
+extern dagc_close_handler p_dagc_close;
+extern dagc_getlinktype_handler p_dagc_getlinktype;
+extern dagc_getlinkspeed_handler p_dagc_getlinkspeed;
+extern dagc_finddevs_handler p_dagc_finddevs;
+extern dagc_freedevs_handler p_dagc_freedevs;
+#endif /* HAVE_DAG_API */
+
+/// Title of error windows
+TCHAR szWindowTitle[] = TEXT("PACKET.DLL");
+
+ULONG inet_addrU(const WCHAR *cp);
+
+/*!
+ \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)
+*/
+BOOLEAN PacketGetLinkLayerFromRegistry(LPADAPTER AdapterObject, NetType *type)
+{
+ BOOLEAN Status;
+ ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
+ PPACKET_OID_DATA OidData;
+
+ OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
+ if (OidData == NULL) {
+ ODS("PacketGetLinkLayerFromRegistry failed\n");
+ 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);
+ type->LinkSpeed=*((UINT*)OidData->Data)*100;
+ GlobalFreePtr (OidData);
+
+ ODSEx("Media:%d\n",type->LinkType);
+ ODSEx("Speed=%d\n",type->LinkSpeed);
+
+ 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.
+*/
+BOOLEAN PacketGetAddressesFromRegistry(LPTSTR AdapterName, npf_if_addr* buffer, PLONG NEntries)
+{
+ char *AdapterNameA;
+ WCHAR *AdapterNameU;
+ WCHAR *ifname;
+ 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;
+
+ AdapterNameA = (char*)AdapterName;
+ if(AdapterNameA[1] != 0) { //ASCII
+ AdapterNameU = SChar2WChar(AdapterNameA);
+ AdapterName = AdapterNameU;
+ } else { //Unicode
+ AdapterNameU = NULL;
+ }
+ ifname = wcsrchr(AdapterName, '\\');
+ if (ifname == NULL)
+ ifname = AdapterName;
+ else
+ ifname++;
+ if (wcsncmp(ifname, L"SEE_", 4) == 0)
+ ifname += 4;
+
+ if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"), 0, KEY_READ, &UnderTcpKey) == ERROR_SUCCESS)
+ {
+ status = RegOpenKeyEx(UnderTcpKey,ifname,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,ifname,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;
+ }
+
+
+ if (AdapterNameU != NULL)
+ GlobalFreePtr(AdapterNameU);
+ return TRUE;
+
+fail:
+ if (AdapterNameU != NULL)
+ GlobalFreePtr(AdapterNameU);
+ return FALSE;
+}
+
+/*!
+ \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 AdaptersInfoMutex mutex
+*/
+#ifndef _WINNT4
+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;
+
+ ODS("PacketAddIP6Addresses\n");
+
+ if(GetAdaptersAddressesPointer == NULL) return TRUE; // GetAdaptersAddresses() not present on this system,
+ // return immediately.
+
+ if(GetAdaptersAddressesPointer(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST| GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_FRIENDLY_NAME, NULL, NULL, &BufLen) != ERROR_BUFFER_OVERFLOW)
+ {
+ ODS("PacketAddIP6Addresses: GetAdaptersAddresses Failed\n");
+ return FALSE;
+ }
+
+ ODS("PacketAddIP6Addresses, retrieved needed storage for the call\n");
+
+ AdBuffer = GlobalAllocPtr(GMEM_MOVEABLE, BufLen);
+ if (AdBuffer == NULL) {
+ ODS("PacketAddIP6Addresses: GlobalAlloc Failed\n");
+ return FALSE;
+ }
+
+ if(GetAdaptersAddressesPointer(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST| GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_FRIENDLY_NAME, NULL, AdBuffer, &BufLen) != ERROR_SUCCESS)
+ {
+ ODS("PacketGetIP6AddressesIPH: GetAdaptersAddresses Failed\n");
+ GlobalFreePtr(AdBuffer);
+ return FALSE;
+ }
+
+ ODS("PacketAddIP6Addresses, retrieved addresses\n");
+
+ //
+ // Scan the list of adddresses obtained from the IP helper API
+ //
+ for(TmpAddr = AdBuffer; TmpAddr != NULL; TmpAddr = TmpAddr->Next)
+ {
+ OrName = AdInfo->Name + sizeof("\\device\\see_") - 1;
+
+ ODS("PacketAddIP6Addresses, external loop\n");
+ if(strcmp(TmpAddr->AdapterName, OrName) == 0)
+ {
+ // Found a corresponding adapter, scan its address list
+ for(UnicastAddr = TmpAddr->FirstUnicastAddress; UnicastAddr != NULL; UnicastAddr = UnicastAddr->Next)
+ {
+ ODS("PacketAddIP6Addresses, internal loop\n");
+
+ 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);
+ 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 ++;
+ }
+ }
+ }
+ }
+
+ ODS("PacketAddIP6Addresses, finished parsing the addresses\n");
+
+ GlobalFreePtr(AdBuffer);
+
+ return TRUE;
+}
+#endif // _WINNT4
+
+/*!
+ \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)
+{
+ if(wcsstr(AdapterDesc, FIREWIRE_SUBSTR) != NULL)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*!
+ \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 AdaptersInfoMutex mutex
+*/
+#ifndef _WINNT4
+BOOLEAN AddAdapterIPH(PIP_ADAPTER_INFO IphAd)
+{
+ PIP_ADAPTER_INFO AdList = NULL;
+ ULONG OutBufLen=0;
+ PADAPTER_INFO TmpAdInfo, SAdInfo;
+ PIP_ADDR_STRING TmpAddrStr;
+ UINT i;
+ struct sockaddr_in *TmpAddr;
+ CHAR TName[256];
+ LPADAPTER adapter;
+ PWCHAR UAdName;
+
+
+ // Create the NPF device name from the original device name
+ strcpy(TName, "\\Device\\SEE_");
+ _snprintf(TName + 12, ADAPTER_NAME_LENGTH - 12, "%s", IphAd->AdapterName);
+
+ // Scan the adapters list to see if this one is already present
+ for(SAdInfo = AdaptersInfoList; SAdInfo != NULL; SAdInfo = SAdInfo->Next)
+ {
+ if(strcmp(TName, SAdInfo->Name) == 0)
+ {
+ ODS("PacketGetAdaptersIPH: Adapter already present in the list\n");
+ goto SkipAd;
+ }
+ }
+
+ if(IphAd->Type == IF_TYPE_PPP || IphAd->Type == IF_TYPE_SLIP)
+ {
+ if (!WanPacketTestAdapter())
+ goto SkipAd;
+ }
+ else
+ {
+ //convert the string to unicode, as OpenAdapterNPF accepts unicode strings, only.
+ UAdName = SChar2WChar(TName);
+ if (UAdName == NULL)
+ {
+ ODS("AddAdapterIPH: unable to convert an ASCII string to UNICODE\n");
+ goto SkipAd;
+ }
+
+ adapter = PacketOpenAdapterNPF((PCHAR)UAdName);
+ GlobalFreePtr(UAdName);
+
+ if(adapter == NULL)
+ {
+ // We are not able to open this adapter. Skip to the next one.
+ ODS("PacketGetAdaptersIPH: unable to open the adapter\n");
+ goto SkipAd;
+ }
+ else
+ {
+ PacketCloseAdapter(adapter);
+ }
+ }
+
+ //
+ // Adapter valid and not yet present in the list. Allocate the ADAPTER_INFO structure
+ //
+ TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO));
+ if (TmpAdInfo == NULL) {
+ ODS("PacketGetAdaptersIPH: GlobalAlloc Failed\n");
+ return FALSE;
+ }
+
+ // Copy the device name
+ strcpy(TmpAdInfo->Name, TName);
+
+ // Copy the description
+ _snprintf(TmpAdInfo->Description, ADAPTER_DESC_LENGTH, "%s", IphAd->Description);
+
+ // Copy the MAC address
+ TmpAdInfo->MacAddressLen = IphAd->AddressLength;
+
+ memcpy(TmpAdInfo->MacAddress,
+ IphAd->Address,
+ (MAX_MAC_ADDR_LENGTH<MAX_ADAPTER_ADDRESS_LENGTH)? MAX_MAC_ADDR_LENGTH:MAX_ADAPTER_ADDRESS_LENGTH);
+
+ // Calculate the number of IP addresses of this interface
+ for(TmpAddrStr = &IphAd->IpAddressList, 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) {
+ ODS("PacketGetAdaptersIPH: GlobalAlloc Failed\n");
+ GlobalFreePtr(TmpAdInfo);
+ return FALSE;
+ }
+
+ // 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;
+
+ // Now Add IPv6 Addresses
+ PacketAddIP6Addresses(TmpAdInfo);
+
+ if(IphAd->Type == IF_TYPE_PPP || IphAd->Type == IF_TYPE_SLIP)
+ {
+ // NdisWan adapter
+ TmpAdInfo->Flags = INFO_FLAG_NDISWAN_ADAPTER;
+ }
+
+ // Update the AdaptersInfo list
+ TmpAdInfo->Next = AdaptersInfoList;
+ AdaptersInfoList = TmpAdInfo;
+
+SkipAd:
+
+ return TRUE;
+}
+#endif // _WINNT4
+
+
+/*!
+ \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().
+*/
+#ifndef _WINNT4
+BOOLEAN PacketGetAdaptersIPH()
+{
+ PIP_ADAPTER_INFO AdList = NULL;
+ PIP_ADAPTER_INFO TmpAd;
+ ULONG OutBufLen=0;
+
+ ODS("PacketGetAdaptersIPH\n");
+
+ // Find the size of the buffer filled by GetAdaptersInfo
+ if(GetAdaptersInfo(AdList, &OutBufLen) == ERROR_NOT_SUPPORTED)
+ {
+ ODS("IP Helper API not supported on this system!\n");
+ return FALSE;
+ }
+
+ ODS("PacketGetAdaptersIPH: retrieved needed bytes for IPH\n");
+
+ // Allocate the buffer
+ AdList = GlobalAllocPtr(GMEM_MOVEABLE, OutBufLen);
+ if (AdList == NULL) {
+ ODS("PacketGetAdaptersIPH: GlobalAlloc Failed\n");
+ return FALSE;
+ }
+
+ // Retrieve the adapters information using the IP helper API
+ GetAdaptersInfo(AdList, &OutBufLen);
+
+ ODS("PacketGetAdaptersIPH: retrieved list from IPH\n");
+
+ // 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)
+ {
+ AddAdapterIPH(TmpAd);
+ }
+
+ GlobalFreePtr(AdList);
+
+ return TRUE;
+}
+#endif // _WINNT4
+
+
+/*!
+ \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.
+*/
+BOOLEAN AddAdapter(PCHAR AdName, UINT flags)
+{
+ //this function should acquire the AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
+ DWORD RegKeySize=0;
+ LONG Status;
+ LPADAPTER adapter;
+ PPACKET_OID_DATA OidData;
+ int i=0;
+ PADAPTER_INFO TmpAdInfo;
+ PADAPTER_INFO TAdInfo;
+ PWCHAR UAdName;
+
+ ODS("AddAdapter\n");
+
+ WaitForSingleObject(AdaptersInfoMutex, INFINITE);
+
+ for(TAdInfo = AdaptersInfoList; TAdInfo != NULL; TAdInfo = TAdInfo->Next)
+ {
+ if(strcmp(AdName, TAdInfo->Name) == 0)
+ {
+ ODS("AddAdapter: Adapter already present in the list\n");
+ ReleaseMutex(AdaptersInfoMutex);
+ return TRUE;
+ }
+ }
+
+ UAdName = SChar2WChar(AdName);
+
+ //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)
+ {
+
+ // Try to Open the adapter
+ adapter = PacketOpenAdapterNPF((PCHAR)UAdName);
+
+ GlobalFreePtr(UAdName);
+
+ if(adapter == NULL)
+ {
+ // We are not able to open this adapter. Skip to the next one.
+ ReleaseMutex(AdaptersInfoMutex);
+ return FALSE;
+ }
+
+ // Allocate a buffer to get the vendor description from the driver
+ OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,512);
+ if (OidData == NULL)
+ {
+ ODS("AddAdapter: GlobalAlloc Failed\n");
+ PacketCloseAdapter(adapter);
+ ReleaseMutex(AdaptersInfoMutex);
+ 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)
+ {
+ ODS("AddAdapter: GlobalAlloc Failed\n");
+ GlobalFreePtr(OidData);
+ PacketCloseAdapter(adapter);
+ ReleaseMutex(AdaptersInfoMutex);
+ return FALSE;
+ }
+
+ // Copy the device name
+ strcpy(TmpAdInfo->Name, AdName);
+
+ 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)
+ {
+ ODS("AddAdapter: unable to get a valid adapter description from the NIC driver\n");
+ }
+
+ ODSEx("Adapter Description=%s\n\n",OidData->Data);
+
+ // Copy the description
+ strcpy(TmpAdInfo->Description, OidData->Data);
+
+ PacketGetLinkLayerFromRegistry(adapter, &(TmpAdInfo->LinkLayer));
+
+ // 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);
+
+ Status = PacketRequest(adapter, FALSE, OidData);
+ if(Status)
+ {
+ memcpy(TmpAdInfo->MacAddress, OidData->Data, 6);
+ TmpAdInfo->MacAddressLen = 6;
+ }
+ else
+ {
+ 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) {
+ ODS("AddAdapter: GlobalAlloc Failed\n");
+ PacketCloseAdapter(adapter);
+ GlobalFreePtr(OidData);
+ GlobalFreePtr(TmpAdInfo);
+ ReleaseMutex(AdaptersInfoMutex);
+ return FALSE;
+ }
+
+ TmpAdInfo->NNetworkAddresses = MAX_NETWORK_ADDRESSES;
+ if(!PacketGetAddressesFromRegistry((LPTSTR)TmpAdInfo->Name, TmpAdInfo->NetworkAddresses, &TmpAdInfo->NNetworkAddresses))
+ {
+#ifndef _WINNT4
+ // Try to see if the interface has some IPv6 addresses
+ TmpAdInfo->NNetworkAddresses = 0; // We have no addresses because PacketGetAddressesFromRegistry() failed
+
+ if(!PacketAddIP6Addresses(TmpAdInfo))
+ {
+#endif // _WINNT4
+ GlobalFreePtr(TmpAdInfo->NetworkAddresses);
+ TmpAdInfo->NetworkAddresses = NULL;
+ TmpAdInfo->NNetworkAddresses = 0;
+#ifndef _WINNT4
+ }
+#endif // _WINNT4
+ }
+
+#ifndef _WINNT4
+ // Now Add IPv6 Addresses
+ PacketAddIP6Addresses(TmpAdInfo);
+#endif // _WINNT4
+
+ 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 = AdaptersInfoList;
+ AdaptersInfoList = TmpAdInfo;
+
+ ReleaseMutex(AdaptersInfoMutex);
+ 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.
+*/
+BOOLEAN PacketGetAdapters()
+{
+ HKEY LinkageKey,AdapKey, OneAdapKey;
+ DWORD RegKeySize=0;
+ LONG Status;
+ ULONG Result;
+ INT i=0,k;
+ DWORD dim;
+ DWORD RegType;
+ WCHAR TName[256];
+ CHAR TAName[256];
+ TCHAR AdapName[256];
+ PTSTR BpStr;
+ UINT FireWireFlag;
+
+ ODS("PacketGetAdapters\n");
+
+ Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"),
+ 0,
+ KEY_READ,
+ &AdapKey);
+
+ if ( Status != ERROR_SUCCESS ){
+ ODS("PacketGetAdapters: RegOpenKeyEx ( Class\\{networkclassguid} ) Failed\n");
+ goto nt4;
+ }
+
+ i=0;
+
+ ODS("PacketGetAdapters: Cycling through the adapters:\n");
+
+ //
+ // 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++;
+ ODSEx(" %d) ", i);
+ FireWireFlag = 0;
+
+ //
+ // Get the adapter name from the registry key
+ //
+ Status=RegOpenKeyEx(AdapKey, AdapName, 0, KEY_READ, &OneAdapKey);
+ if ( Status != ERROR_SUCCESS )
+ {
+ ODS("PacketGetAdapters: RegOpenKeyEx ( OneAdapKey ) Failed\n");
+ 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,
+ L"ComponentId",
+ NULL,
+ NULL,
+ (PBYTE)TName,
+ &dim);
+
+ if(Status == ERROR_SUCCESS)
+ {
+ if(IsFireWire(TName))
+ {
+ FireWireFlag = INFO_FLAG_DONT_EXPORT;
+ }
+ }
+
+ Status=RegOpenKeyEx(OneAdapKey, L"Linkage", 0, KEY_READ, &LinkageKey);
+ if (Status != ERROR_SUCCESS)
+ {
+ RegCloseKey(OneAdapKey);
+ ODS("PacketGetAdapters: RegOpenKeyEx ( LinkageKey ) Failed\n");
+ continue;
+ }
+
+ dim = sizeof(TName);
+ Status=RegQueryValueEx(LinkageKey,
+ L"Export",
+ NULL,
+ NULL,
+ (PBYTE)TName,
+ &dim);
+
+ if(Status != ERROR_SUCCESS)
+ {
+ RegCloseKey(OneAdapKey);
+ RegCloseKey(LinkageKey);
+ ODS("Name = SKIPPED (error reading the key)\n");
+ continue;
+ }
+
+ // Conver to ASCII
+ WideCharToMultiByte(
+ CP_ACP,
+ 0,
+ TName, // wide-character string
+ -1, // number of chars in string
+ TAName + sizeof("\\Device\\SEE_") - sizeof("\\Device\\"), // buffer for new string
+ sizeof(TAName) - sizeof("\\Device\\SEE_") + sizeof("\\Device\\"), // size of buffer
+ NULL,
+ NULL);
+
+ // Put the \Device\NPF_ string at the beginning of the name
+ memcpy(TAName, "\\Device\\SEE_", sizeof("\\Device\\SEE_") - 1);
+
+ // If the adapter is valid, add it to the list.
+ AddAdapter(TAName, FireWireFlag);
+
+ RegCloseKey(OneAdapKey);
+ RegCloseKey(LinkageKey);
+
+ } // while enum reg keys
+
+ RegCloseKey(AdapKey);
+
+nt4:
+ //
+ // 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.
+ //
+
+ ODS("Adapters not found under SYSTEM\\CurrentControlSet\\Control\\Class. Using the TCP/IP bindings.\n");
+
+ 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
+ Status=RegQueryValueEx(LinkageKey,
+ TEXT("bind"),
+ NULL,
+ &RegType,
+ NULL,
+ &RegKeySize);
+
+ // Allocate the buffer
+ BpStr = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, RegKeySize+2);
+
+ if (BpStr == NULL)
+ {
+ return FALSE;
+ }
+
+ // Query the key again to get its content
+ Status = RegQueryValueEx(LinkageKey,
+ TEXT("bind"),
+ NULL,
+ &RegType,
+ (LPBYTE)BpStr,
+ &RegKeySize);
+
+ RegCloseKey(LinkageKey);
+
+ // Scan the buffer with the device names
+ for(i = 0;;)
+ {
+ if((k = _snprintf(TAName + sizeof("\\Device\\SEE_") - sizeof("\\Device\\"), sizeof(TAName), "%S", BpStr + i)) == 0)
+ break;
+
+ // Put the \Device\NPF_ string at the beginning of the name
+ memcpy(TAName, "\\Device\\SEE_", sizeof("\\Device\\SEE_") - 1);
+
+ // If the adapter is valid, add it to the list.
+ AddAdapter(TAName, 0);
+
+ i += k + 1;
+ }
+
+ GlobalFreePtr(BpStr);
+ }
+
+ else{
+#ifdef _WINNT4
+ return FALSE;
+#endif
+ }
+
+ return TRUE;
+}
+
+#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 AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
+ CHAR ebuf[DAGC_ERRBUF_SIZE];
+ PADAPTER_INFO TmpAdInfo;
+ dagc_t *dagfd;
+
+ //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)
+ {
+ ODS("PacketAddAdapterDag: GlobalAlloc Failed\n");
+ return FALSE;
+ }
+
+ // Copy the device name and description
+ _snprintf(TmpAdInfo->Name,
+ sizeof(TmpAdInfo->Name),
+ "%s",
+ name);
+
+ _snprintf(TmpAdInfo->Description,
+ sizeof(TmpAdInfo->Description),
+ "%s",
+ description);
+
+ if(IsAFile)
+ TmpAdInfo->Flags = INFO_FLAG_DAG_FILE;
+ else
+ TmpAdInfo->Flags = INFO_FLAG_DAG_CARD;
+
+ if(p_dagc_open)
+ dagfd = p_dagc_open(name, 0, ebuf);
+ else
+ dagfd = NULL;
+
+ if(!dagfd)
+ {
+ GlobalFreePtr(TmpAdInfo);
+ return FALSE;
+ }
+
+ TmpAdInfo->LinkLayer.LinkType = p_dagc_getlinktype(dagfd);
+
+ switch(p_dagc_getlinktype(dagfd))
+ {
+ case TYPE_HDLC_POS:
+ TmpAdInfo->LinkLayer.LinkType = NdisMediumCHDLC; // Note: custom linktype, NDIS doesn't provide an equivalent
+ break;
+ case -TYPE_HDLC_POS:
+ TmpAdInfo->LinkLayer.LinkType = NdisMediumPPPSerial; // Note: custom linktype, NDIS doesn't provide an equivalent
+ break;
+ case TYPE_ETH:
+ TmpAdInfo->LinkLayer.LinkType = NdisMedium802_3;
+ break;
+ case TYPE_ATM:
+ TmpAdInfo->LinkLayer.LinkType = NdisMediumAtm;
+ break;
+ default:
+ TmpAdInfo->LinkLayer.LinkType = NdisMediumNull; // Note: custom linktype, NDIS doesn't provide an equivalent
+ break;
+ }
+
+ TmpAdInfo->LinkLayer.LinkSpeed = (p_dagc_getlinkspeed(dagfd) == -1)?
+ 100000000: // Unknown speed, default to 100Mbit
+ p_dagc_getlinkspeed(dagfd) * 1000000;
+
+ p_dagc_close(dagfd);
+
+ WaitForSingleObject(AdaptersInfoMutex, INFINITE);
+
+ // Update the AdaptersInfo list
+ TmpAdInfo->Next = AdaptersInfoList;
+ AdaptersInfoList = TmpAdInfo;
+
+ ReleaseMutex(AdaptersInfoMutex);
+
+ 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(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);
+ }
+ }
+
+ 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 AdaptersInfoMutex, since it does return an ADAPTER_INFO structure
+ PADAPTER_INFO TAdInfo;
+
+ if (AdaptersInfoList == NULL)
+ PacketPopulateAdaptersInfoList();
+
+ TAdInfo = AdaptersInfoList;
+
+ while(TAdInfo != NULL)
+ {
+ if(strcmp(TAdInfo->Name, AdapterName) == 0) break;
+
+ TAdInfo = TAdInfo->Next;
+ }
+
+ 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 AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
+ PADAPTER_INFO TAdInfo, PrevAdInfo;
+
+ WaitForSingleObject(AdaptersInfoMutex, INFINITE);
+
+ PrevAdInfo = TAdInfo = AdaptersInfoList;
+
+ //
+ // If an entry for this adapter is present in the list, we destroy it
+ //
+ while(TAdInfo != NULL)
+ {
+ if(strcmp(TAdInfo->Name, AdapterName) == 0)
+ {
+ if (strcmp(AdapterName, FAKE_NDISWAN_ADAPTER_NAME) == 0)
+ {
+ ReleaseMutex(AdaptersInfoMutex);
+ return TRUE;
+ }
+
+ if(TAdInfo == AdaptersInfoList)
+ {
+ AdaptersInfoList = TAdInfo->Next;
+ }
+ else
+ {
+ PrevAdInfo->Next = TAdInfo->Next;
+ }
+
+ if (TAdInfo->NetworkAddresses != NULL)
+ GlobalFreePtr(TAdInfo->NetworkAddresses);
+ GlobalFreePtr(TAdInfo);
+
+ break;
+ }
+
+ PrevAdInfo = TAdInfo;
+
+ TAdInfo = TAdInfo->Next;
+ }
+
+ ReleaseMutex(AdaptersInfoMutex);
+
+ //
+ // Now obtain the information about this adapter
+ //
+ if(AddAdapter(AdapterName, 0) == TRUE)
+ return TRUE;
+#ifndef _WINNT4
+ //
+ // Not a tradiditonal adapter, but possibly a Wan or DAG interface
+ // Gather all the available adapters from IPH API and dagc API
+ //
+ PacketGetAdaptersIPH();
+ PacketAddFakeNdisWanAdapter();
+#ifdef HAVE_DAG_API
+ if(p_dagc_open == NULL)
+ return TRUE; // dagc.dll not present on this system.
+ else
+ PacketGetAdaptersDag();
+#endif // HAVE_DAG_API
+
+#endif // _WINNT4
+
+ // Adapter not found
+ 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 AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
+ PADAPTER_INFO TAdInfo;
+ PVOID Mem1, Mem2;
+
+ WaitForSingleObject(AdaptersInfoMutex, INFINITE);
+
+ if(AdaptersInfoList)
+ {
+ // Free the old list
+ TAdInfo = AdaptersInfoList;
+ while(TAdInfo != NULL)
+ {
+ Mem1 = TAdInfo->NetworkAddresses;
+ Mem2 = TAdInfo;
+
+ TAdInfo = TAdInfo->Next;
+
+ if (Mem1 != NULL)
+ GlobalFreePtr(Mem1);
+ GlobalFreePtr(Mem2);
+ }
+
+ AdaptersInfoList = NULL;
+ }
+
+ //
+ // Fill the new list
+ //
+ if(!PacketGetAdapters())
+ {
+ // No info about adapters in the registry.
+ ODS("PacketPopulateAdaptersInfoList: registry scan for adapters failed!\n");
+ }
+#ifndef _WINNT4
+ if(!PacketGetAdaptersIPH())
+ {
+ // IP Helper API not present. We are under WinNT 4 or TCP/IP is not installed
+ ODS("PacketPopulateAdaptersInfoList: failed to get adapters from the IP Helper API!\n");
+ }
+
+ if (!PacketAddFakeNdisWanAdapter())
+ {
+ ODS("PacketPopulateAdaptersInfoList: adding fake NdisWan adapter failed.\n");
+ }
+
+#ifdef HAVE_DAG_API
+ if(p_dagc_open == NULL)
+ {} // dagc.dll not present on this system.
+ else
+ {
+ if(!PacketGetAdaptersDag())
+ {
+ // No info about adapters in the registry.
+ ODS("PacketPopulateAdaptersInfoList: lookup of dag cards failed!\n");
+ }
+ }
+#endif // HAVE_DAG_API
+
+#endif // _WINNT4
+
+ ReleaseMutex(AdaptersInfoMutex);
+}
+
+#ifndef _WINNT4
+
+BOOL PacketAddFakeNdisWanAdapter()
+{
+ //this function should acquire the AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
+ PADAPTER_INFO TmpAdInfo, SAdInfo;
+
+ // Scan the adapters list to see if this one is already present
+
+ if (!WanPacketTestAdapter())
+ {
+ ODS("Cannot add the adapter, since it cannot be opened.");
+ //the adapter cannot be opened, we do not list it, but we return t
+ return FALSE;
+ }
+
+ WaitForSingleObject(AdaptersInfoMutex, INFINITE);
+
+ for(SAdInfo = AdaptersInfoList; SAdInfo != NULL; SAdInfo = SAdInfo->Next)
+ {
+ if(strcmp(FAKE_NDISWAN_ADAPTER_NAME, SAdInfo->Name) == 0)
+ {
+ ODS("PacketAddFakeNdisWanAdapter: Adapter already present in the list\n");
+ ReleaseMutex(AdaptersInfoMutex);
+ return TRUE;
+ }
+ }
+
+ TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO));
+ if (TmpAdInfo == NULL)
+ {
+ ODS("PacketAddFakeNdisWanAdapter: GlobalAlloc Failed\n");
+ ReleaseMutex(AdaptersInfoMutex);
+ return FALSE;
+ }
+
+ strcpy(TmpAdInfo->Name, FAKE_NDISWAN_ADAPTER_NAME);
+ strcpy(TmpAdInfo->Description, FAKE_NDISWAN_ADAPTER_DESCRIPTION);
+ 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 = AdaptersInfoList;
+ AdaptersInfoList = TmpAdInfo;
+ ReleaseMutex(AdaptersInfoMutex);
+
+ return TRUE;
+}
+
+#endif
diff --git a/src/SeeDll/Devioctl.h b/src/SeeDll/Devioctl.h
new file mode 100644
index 00000000..af8784bf
--- /dev/null
+++ b/src/SeeDll/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/src/SeeDll/Ntddndis.h b/src/SeeDll/Ntddndis.h
new file mode 100644
index 00000000..0b629806
--- /dev/null
+++ b/src/SeeDll/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/src/SeeDll/Ntddpack.h b/src/SeeDll/Ntddpack.h
new file mode 100644
index 00000000..30945c1e
--- /dev/null
+++ b/src/SeeDll/Ntddpack.h
@@ -0,0 +1,26 @@
+
+#ifndef __NTDDPACKET
+#define __NTDDPACKET 1
+#include "devioctl.h"
+/*#include <packon.h> */
+struct _PACKET_OID_DATA {
+ ULONG Oid;
+ ULONG Length;
+ UCHAR Data[1];
+};
+
+typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA;
+
+/*#include <packoff.h> */
+#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/src/SeeDll/Packet32.c b/src/SeeDll/Packet32.c
new file mode 100644
index 00000000..e2647ec2
--- /dev/null
+++ b/src/SeeDll/Packet32.c
@@ -0,0 +1,2302 @@
+/*
+ * Copyright (c) 1999 - 2003
+ * 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 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.
+ */
+
+#include <GlobalConst.h>
+
+#define UNICODE 1
+
+#include <stdio.h>
+#include <packet32.h>
+
+#if 0
+#include "WanPacket/WanPacket.h"
+#endif
+
+#define _WINNT4
+
+
+#include <windows.h>
+#include <windowsx.h>
+#include <Iphlpapi.h>
+#include <IPIfCons.h>
+
+#include <ntddndis.h>
+
+
+/// 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];
+
+LPCTSTR NPFServiceName = TEXT("SEE");
+LPCTSTR NPFServiceDesc = TEXT("SoftEther Ethernet Layer Driver");
+LPCTSTR NPFRegistryLocation = TEXT("SYSTEM\\CurrentControlSet\\Services\\SEE");
+LPCTSTR NPFDriverPath = TEXT("system32\\drivers\\see.sys");
+
+extern PADAPTER_INFO AdaptersInfoList;
+extern HANDLE AdaptersInfoMutex;
+#ifndef _WINNT4
+typedef VOID (*GAAHandler)(
+ ULONG,
+ DWORD,
+ PVOID,
+ PIP_ADAPTER_ADDRESSES,
+ PULONG);
+GAAHandler GetAdaptersAddressesPointer = NULL;
+#endif // _WINNT4
+
+#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 p_dagc_open = NULL;
+dagc_close_handler p_dagc_close = NULL;
+dagc_getlinktype_handler p_dagc_getlinktype = NULL;
+dagc_getlinkspeed_handler p_dagc_getlinkspeed = NULL;
+dagc_getfcslen_handler p_dagc_getfcslen = NULL;
+dagc_receive_handler p_dagc_receive = NULL;
+dagc_wait_handler p_dagc_wait = NULL;
+dagc_stats_handler p_dagc_stats = NULL;
+dagc_setsnaplen_handler p_dagc_setsnaplen = NULL;
+dagc_finddevs_handler p_dagc_finddevs = NULL;
+dagc_freedevs_handler p_dagc_freedevs = NULL;
+#endif /* HAVE_DAG_API */
+
+BOOLEAN PacketAddAdapterDag(PCHAR name, PCHAR description, BOOLEAN IsAFile);
+
+//---------------------------------------------------------------------------
+
+/*!
+ \brief The main dll function.
+*/
+
+BOOL APIENTRY DllMain (HANDLE DllHandle,DWORD Reason,LPVOID lpReserved)
+{
+ BOOLEAN Status=TRUE;
+ HMODULE IPHMod;
+ PADAPTER_INFO NewAdInfo;
+#ifdef HAVE_DAG_API
+ HMODULE DagcLib;
+#endif // HAVE_DAG_API
+
+ switch(Reason)
+ {
+ case DLL_PROCESS_ATTACH:
+
+ ODS("************Packet32: DllMain************\n");
+
+#ifdef _DEBUG_TO_FILE
+ // 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\\SEE",
+ "npf.reg");
+ PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services",
+ "services.reg");
+#endif
+
+ // Create the mutex that will protect the adapter information list
+ AdaptersInfoMutex = CreateMutex(NULL, FALSE, NULL);
+
+ //
+ // Retrieve packet.dll version information from the file
+ //
+ PacketGetFileVersion(TEXT("see.dll"), PacketLibraryVersion, sizeof(PacketLibraryVersion));
+
+ //
+ // Retrieve NPF.sys version information from the file
+ //
+ PacketGetFileVersion(TEXT("drivers\\see.sys"), PacketDriverVersion, sizeof(PacketDriverVersion));
+
+ //
+ // Locate GetAdaptersAddresses dinamically since it is not present in Win2k
+ //
+ IPHMod = GetModuleHandle(TEXT("Iphlpapi"));
+
+#ifndef _WINNT4
+ GetAdaptersAddressesPointer = (GAAHandler) GetProcAddress(IPHMod ,"GetAdaptersAddresses");
+#endif // _WINNT4
+
+#ifdef HAVE_DAG_API
+ /* We load dinamically 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
+ ODS("dag capture library not found on this system\n");
+ break;
+ }
+
+ p_dagc_open = (dagc_open_handler) GetProcAddress(DagcLib, "dagc_open");
+ p_dagc_close = (dagc_close_handler) GetProcAddress(DagcLib, "dagc_close");
+ p_dagc_setsnaplen = (dagc_setsnaplen_handler) GetProcAddress(DagcLib, "dagc_setsnaplen");
+ p_dagc_getlinktype = (dagc_getlinktype_handler) GetProcAddress(DagcLib, "dagc_getlinktype");
+ p_dagc_getlinkspeed = (dagc_getlinkspeed_handler) GetProcAddress(DagcLib, "dagc_getlinkspeed");
+ p_dagc_getfcslen = (dagc_getfcslen_handler) GetProcAddress(DagcLib, "dagc_getfcslen");
+ p_dagc_receive = (dagc_receive_handler) GetProcAddress(DagcLib, "dagc_receive");
+ p_dagc_wait = (dagc_wait_handler) GetProcAddress(DagcLib, "dagc_wait");
+ p_dagc_stats = (dagc_stats_handler) GetProcAddress(DagcLib, "dagc_stats");
+ p_dagc_finddevs = (dagc_finddevs_handler) GetProcAddress(DagcLib, "dagc_finddevs");
+ p_dagc_freedevs = (dagc_freedevs_handler) GetProcAddress(DagcLib, "dagc_freedevs");
+
+#endif /* HAVE_DAG_API */
+
+ break;
+
+ case DLL_PROCESS_DETACH:
+
+ CloseHandle(AdaptersInfoMutex);
+
+ AdaptersInfoList;
+
+ while(AdaptersInfoList != NULL)
+ {
+
+ NewAdInfo = AdaptersInfoList->Next;
+ if (AdaptersInfoList->NetworkAddresses != NULL)
+ GlobalFreePtr(AdaptersInfoList->NetworkAddresses);
+ GlobalFreePtr(AdaptersInfoList);
+
+ AdaptersInfoList = NewAdInfo;
+ }
+
+
+ break;
+
+ default:
+ break;
+ }
+
+ return Status;
+}
+
+/*!
+ \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 -1;
+ part = part*10 + (c - '0');
+ }
+ if (part > 255)
+ return -1;
+ val = val | (part << i*8);
+ if (i == 3) {
+ if (c != '\0')
+ return -1; // extra gunk at end of string
+ } else {
+ if (c == '\0')
+ return -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.
+*/
+
+PWCHAR SChar2WChar(PCHAR string)
+{
+ PWCHAR TmpStr;
+ TmpStr = (WCHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (strlen(string)+2)*sizeof(WCHAR));
+
+ MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, ((int)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.
+*/
+
+PCHAR WChar2SChar(PWCHAR string)
+{
+ PCHAR TmpStr;
+ TmpStr = (CHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (wcslen(string)+2));
+
+ // Conver to ASCII
+ WideCharToMultiByte(
+ CP_ACP,
+ 0,
+ string,
+ -1,
+ TmpStr,
+ ((int)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.
+*/
+
+BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject)
+{
+ BOOLEAN Status;
+ ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
+ PPACKET_OID_DATA OidData;
+
+ OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
+ if (OidData == NULL) {
+ ODS("PacketSetMaxLookaheadsize failed\n");
+ 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;
+}
+
+/*!
+ \brief Retrieves the event associated in the driver with a capture instance and stores it in an
+ _ADAPTER structure.
+ \param AdapterObject Handle to the service control manager.
+ \return If the function succeeds, the return value is nonzero.
+
+ This function is used by PacketOpenAdapter() to retrieve the read event from the driver by means of an ioctl
+ call and set it in the _ADAPTER structure pointed by AdapterObject.
+*/
+
+BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject)
+{
+ DWORD BytesReturned;
+ TCHAR EventName[39];
+
+ if (LOWORD(GetVersion()) == 4)
+ {
+ // retrieve the name of the shared event from the driver without the "Global\\" prefix
+ if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE)
+ return FALSE;
+
+ EventName[BytesReturned/sizeof(TCHAR)]=0; // terminate the string
+ }
+ else
+ {
+ // this tells the terminal service to retrieve the event from the global namespace
+ wcsncpy(EventName,L"Global\\",sizeof(L"Global\\"));
+ // retrieve the name of the shared event from the driver with the "Global\\" prefix
+ if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName + 7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE)
+ return FALSE;
+
+ EventName[BytesReturned/sizeof(TCHAR) + 7]=0; // terminate the string
+ }
+
+ // open the shared event
+ AdapterObject->ReadEvent=CreateEvent(NULL,
+ TRUE,
+ FALSE,
+ EventName);
+
+ if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){
+ ODS("PacketSetReadEvt: error retrieving the event from the kernel\n");
+ return FALSE;
+ }
+
+ AdapterObject->ReadTimeOut=0;
+
+ 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.
+*/
+
+BOOL PacketInstallDriver()
+{
+ BOOL result = FALSE;
+ ULONG err = 0;
+ SC_HANDLE svcHandle;
+ SC_HANDLE scmHandle;
+ ODS("PacketInstallDriver\n");
+
+ scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+
+ if(scmHandle == NULL)
+ return FALSE;
+
+ svcHandle = CreateService(scmHandle,
+ NPFServiceName,
+ NPFServiceDesc,
+ SERVICE_ALL_ACCESS,
+ SERVICE_KERNEL_DRIVER,
+ SERVICE_DEMAND_START,
+ SERVICE_ERROR_NORMAL,
+ NPFDriverPath,
+ NULL, NULL, NULL, NULL, NULL);
+ if (svcHandle == NULL)
+ {
+ err = GetLastError();
+ if (err == ERROR_SERVICE_EXISTS)
+ {
+ //npf.sys already existed
+ err = 0;
+ result = TRUE;
+ }
+ }
+ else
+ {
+ //Created service for npf.sys
+ result = TRUE;
+ }
+
+ if (svcHandle != NULL)
+ CloseServiceHandle(svcHandle);
+
+ if(result == FALSE)
+ {
+ ODSEx("PacketInstallDriver failed, Error=%d\n",err);
+ }
+
+ CloseServiceHandle(scmHandle);
+ SetLastError(err);
+ 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];
+
+ strcpy(Command, "regedit /e ");
+ strcat(Command, FileName);
+ strcat(Command, " ");
+ strcat(Command, KeyName);
+
+ /// Let regedit do the dirt work for us
+ system(Command);
+
+ 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;
+
+ ODS("PacketGetFileVersion\n");
+
+ // Now lets dive in and pull out the version information:
+ dwVerInfoSize = GetFileVersionInfoSize(FileName, &dwVerHnd);
+ if (dwVerInfoSize)
+ {
+ lpstrVffInfo = GlobalAllocPtr(GMEM_MOVEABLE, dwVerInfoSize);
+ if (lpstrVffInfo == NULL)
+ {
+ ODS("PacketGetFileVersion: failed to allocate memory\n");
+ return FALSE;
+ }
+
+ if(!GetFileVersionInfo(FileName, dwVerHnd, dwVerInfoSize, lpstrVffInfo))
+ {
+ ODS("PacketGetFileVersion: failed to call GetFileVersionInfo\n");
+ GlobalFreePtr(lpstrVffInfo);
+ return FALSE;
+ }
+
+ // Read the list of languages and code pages.
+ if(!VerQueryValue(lpstrVffInfo, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate))
+ {
+ ODS("PacketGetFileVersion: failed to call VerQueryValue\n");
+ GlobalFreePtr(lpstrVffInfo);
+ return FALSE;
+ }
+
+ // Create the file version string for the first (i.e. the only one) language.
+ wsprintf( SubBlock,
+ TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"),
+ (*lpTranslate).wLanguage,
+ (*lpTranslate).wCodePage);
+
+ // Retrieve the file version string for the language.
+ if(!VerQueryValue(lpstrVffInfo, SubBlock, &lpBuffer, &dwBytes))
+ {
+ ODS("PacketGetFileVersion: failed to call VerQueryValue\n");
+ GlobalFreePtr(lpstrVffInfo);
+ return FALSE;
+ }
+
+ // Convert to ASCII
+ TmpStr = WChar2SChar(lpBuffer);
+
+ if(strlen(TmpStr) >= VersionBuffLen)
+ {
+ ODS("PacketGetFileVersion: Input buffer too small\n");
+ GlobalFreePtr(lpstrVffInfo);
+ GlobalFreePtr(TmpStr);
+ return FALSE;
+ }
+
+ strcpy(VersionBuff, TmpStr);
+
+ GlobalFreePtr(lpstrVffInfo);
+ GlobalFreePtr(TmpStr);
+
+ }
+ else
+ {
+ ODSEx("PacketGetFileVersion: failed to call GetFileVersionInfoSize, LastError = %d\n", GetLastError());
+ return FALSE;
+
+ }
+
+ 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 AdapterName)
+{
+ LPADAPTER lpAdapter;
+ BOOLEAN Result;
+ DWORD error;
+ SC_HANDLE svcHandle = NULL;
+ SC_HANDLE scmHandle = NULL;
+ LONG KeyRes;
+ HKEY PathKey;
+ SERVICE_STATUS SStat;
+ BOOLEAN QuerySStat;
+ WCHAR SymbolicLink[128];
+
+ ODS("PacketOpenAdapterNPF\n");
+
+ scmHandle = OpenSCManager(NULL, NULL, GENERIC_READ);
+
+ if(scmHandle == NULL)
+ {
+ error = GetLastError();
+ ODSEx("OpenSCManager failed! LastError=%d\n", error);
+ }
+ else
+ {
+ // 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=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ NPFRegistryLocation,
+ 0,
+ KEY_READ,
+ &PathKey);
+
+ if(KeyRes != ERROR_SUCCESS)
+ {
+ Result = PacketInstallDriver();
+ }
+ else
+ {
+ Result = TRUE;
+ RegCloseKey(PathKey);
+ }
+
+ Result = FALSE;
+ svcHandle = OpenService(scmHandle, NPFServiceName, GENERIC_READ);
+ if (svcHandle != NULL)
+ {
+ Result = TRUE;
+
+ CloseServiceHandle(svcHandle);
+ }
+
+ if (Result)
+ {
+
+ svcHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS );
+ if (svcHandle != NULL)
+ {
+ QuerySStat = QueryServiceStatus(svcHandle, &SStat);
+
+#if defined(_DBG) || defined(_DEBUG_TO_FILE)
+ switch (SStat.dwCurrentState)
+ {
+ case SERVICE_CONTINUE_PENDING:
+ ODS("The status of the driver is: SERVICE_CONTINUE_PENDING\n");
+ break;
+ case SERVICE_PAUSE_PENDING:
+ ODS("The status of the driver is: SERVICE_PAUSE_PENDING\n");
+ break;
+ case SERVICE_PAUSED:
+ ODS("The status of the driver is: SERVICE_PAUSED\n");
+ break;
+ case SERVICE_RUNNING:
+ ODS("The status of the driver is: SERVICE_RUNNING\n");
+ break;
+ case SERVICE_START_PENDING:
+ ODS("The status of the driver is: SERVICE_START_PENDING\n");
+ break;
+ case SERVICE_STOP_PENDING:
+ ODS("The status of the driver is: SERVICE_STOP_PENDING\n");
+ break;
+ case SERVICE_STOPPED:
+ ODS("The status of the driver is: SERVICE_STOPPED\n");
+ break;
+
+ default:
+ ODS("The status of the driver is: unknown\n");
+ break;
+ }
+#endif
+
+ if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING)
+ {
+ ODS("Calling startservice\n");
+ 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();
+ ODSEx("PacketOpenAdapterNPF: StartService failed, LastError=%d\n",error);
+ SetLastError(error);
+ return NULL;
+ }
+ }
+ }
+
+ CloseServiceHandle( svcHandle );
+ svcHandle = NULL;
+
+ }
+ else
+ {
+ error = GetLastError();
+ ODSEx("OpenService failed! Error=%d", error);
+ SetLastError(error);
+ }
+ }
+ else
+ {
+ if (KeyRes == FALSE)
+ Result = PacketInstallDriver();
+ else
+ Result = TRUE;
+
+ if (Result) {
+
+ svcHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START);
+ if (svcHandle != NULL)
+ {
+
+ QuerySStat = QueryServiceStatus(svcHandle, &SStat);
+
+#if defined(_DBG) || defined(_DEBUG_TO_FILE)
+ switch (SStat.dwCurrentState)
+ {
+ case SERVICE_CONTINUE_PENDING:
+ ODS("The status of the driver is: SERVICE_CONTINUE_PENDING\n");
+ break;
+ case SERVICE_PAUSE_PENDING:
+ ODS("The status of the driver is: SERVICE_PAUSE_PENDING\n");
+ break;
+ case SERVICE_PAUSED:
+ ODS("The status of the driver is: SERVICE_PAUSED\n");
+ break;
+ case SERVICE_RUNNING:
+ ODS("The status of the driver is: SERVICE_RUNNING\n");
+ break;
+ case SERVICE_START_PENDING:
+ ODS("The status of the driver is: SERVICE_START_PENDING\n");
+ break;
+ case SERVICE_STOP_PENDING:
+ ODS("The status of the driver is: SERVICE_STOP_PENDING\n");
+ break;
+ case SERVICE_STOPPED:
+ ODS("The status of the driver is: SERVICE_STOPPED\n");
+ break;
+
+ default:
+ ODS("The status of the driver is: unknown\n");
+ break;
+ }
+#endif
+
+ if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){
+
+ ODS("Calling startservice\n");
+
+ if (StartService(svcHandle, 0, NULL)==0){
+ error = GetLastError();
+ if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){
+ if (scmHandle != NULL) CloseServiceHandle(scmHandle);
+ ODSEx("PacketOpenAdapterNPF: StartService failed, LastError=%d\n",error);
+ SetLastError(error);
+ return NULL;
+ }
+ }
+ }
+
+ CloseServiceHandle( svcHandle );
+ svcHandle = NULL;
+
+ }
+ else{
+ error = GetLastError();
+ ODSEx("OpenService failed! LastError=%d", error);
+ SetLastError(error);
+ }
+ }
+ }
+ }
+
+ if (scmHandle != NULL) CloseServiceHandle(scmHandle);
+
+ lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER));
+ if (lpAdapter==NULL)
+ {
+ ODS("PacketOpenAdapterNPF: GlobalAlloc Failed\n");
+ error=GetLastError();
+ //set the error to the one on which we failed
+ SetLastError(error);
+ ODS("PacketOpenAdapterNPF: Failed to allocate the adapter structure\n");
+ return NULL;
+ }
+ lpAdapter->NumWrites=1;
+
+ if (LOWORD(GetVersion()) == 4)
+ wsprintf(SymbolicLink,TEXT("\\\\.\\%s"),&AdapterName[16]);
+ else
+ wsprintf(SymbolicLink,TEXT("\\\\.\\Global\\%s"),&AdapterName[16]);
+
+ // Copy only the bytes that fit in the adapter structure.
+ // Note that lpAdapter->SymbolicLink is present for backward compatibility but will
+ // never be used by the apps
+ memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH);
+
+ //try if it is possible to open the adapter immediately
+ lpAdapter->hFile=CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ,
+ 0,NULL,OPEN_EXISTING,0,0);
+
+ if (lpAdapter->hFile != INVALID_HANDLE_VALUE)
+ {
+
+ if(PacketSetReadEvt(lpAdapter)==FALSE){
+ error=GetLastError();
+ ODS("PacketOpenAdapterNPF: Unable to open the read event\n");
+ GlobalFreePtr(lpAdapter);
+ //set the error to the one on which we failed
+ SetLastError(error);
+ ODSEx("PacketOpenAdapterNPF: PacketSetReadEvt failed, LastError=%d\n",error);
+ return NULL;
+ }
+
+ PacketSetMaxLookaheadsize(lpAdapter);
+
+ _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%S", AdapterName);
+
+ return lpAdapter;
+ }
+
+
+ error=GetLastError();
+ GlobalFreePtr(lpAdapter);
+ //set the error to the one on which we failed
+ ODSEx("PacketOpenAdapterNPF: CreateFile failed, LastError= %d\n",error);
+ SetLastError(error);
+ return NULL;
+}
+
+/*!
+ \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
+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;
+
+
+ lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,
+ sizeof(ADAPTER));
+ if (lpAdapter == NULL)
+ {
+ 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))
+ {
+ 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"";
+
+ _snwprintf(keyname, sizeof(keyname), 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,
+ (char*)&fpc,
+ &lpcbdata);
+
+ if(status == ERROR_SUCCESS)
+ lpAdapter->DagFastProcess = fpc;
+
+ RegCloseKey(dagkey);
+ }
+ while(FALSE);
+
+ //
+ // Open the card
+ //
+ lpAdapter->pDagCard = p_dagc_open(AdapterName,
+ 0,
+ DagEbuf);
+
+ if(lpAdapter->pDagCard == NULL)
+ {
+ GlobalFreePtr(lpAdapter);
+ return NULL;
+ }
+
+ lpAdapter->DagFcsLen = p_dagc_getfcslen(lpAdapter->pDagCard);
+
+ _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterName);
+
+ // XXX we could create the read event here
+
+ 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()
+{
+ 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()
+{
+ 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;
+
+ scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+
+ if(scmHandle != NULL){
+
+ schService = OpenService (scmHandle,
+ NPFServiceName,
+ SERVICE_ALL_ACCESS
+ );
+
+ if (schService != NULL)
+ {
+
+ ret = ControlService (schService,
+ SERVICE_CONTROL_STOP,
+ &serviceStatus
+ );
+ if (!ret)
+ {
+ }
+
+ CloseServiceHandle (schService);
+
+ CloseServiceHandle(scmHandle);
+
+ return ret;
+ }
+ }
+
+ return FALSE;
+}
+
+/*!
+ \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 AdapterName)
+{
+ LPADAPTER lpAdapter;
+ WCHAR *AdapterNameU;
+ SC_HANDLE svcHandle = NULL;
+ PCHAR AdapterNameA = NULL;
+#ifndef _WINNT4
+ PADAPTER_INFO TAdInfo;
+#endif // _WINNT4
+ ODSEx("PacketOpenAdapter: trying to open the adapter=%s\n",AdapterName)
+
+ if(AdapterName[1]!=0)
+ {
+ //
+ // ASCII
+ //
+
+ AdapterNameU = SChar2WChar(AdapterName);
+ AdapterNameA = AdapterName;
+ AdapterName = (PCHAR)AdapterNameU;
+ }
+ else
+ {
+ //
+ // Unicode
+ //
+ AdapterNameU = NULL;
+ AdapterNameA = WChar2SChar((PWCHAR)AdapterName);
+ }
+
+#ifndef _WINNT4
+
+ WaitForSingleObject(AdaptersInfoMutex, INFINITE);
+ // Find the PADAPTER_INFO structure associated with this adapter
+ TAdInfo = PacketFindAdInfo(AdapterNameA);
+ if(TAdInfo == NULL)
+ {
+ PacketUpdateAdInfo(AdapterNameA);
+ TAdInfo = PacketFindAdInfo(AdapterNameA);
+ if(TAdInfo == NULL)
+ {
+
+ //can be an ERF file?
+ lpAdapter = PacketOpenAdapterDAG(AdapterNameA, TRUE);
+
+ if (AdapterNameU != NULL)
+ GlobalFreePtr(AdapterNameU);
+ else
+ GlobalFreePtr(AdapterNameA);
+
+ ReleaseMutex(AdaptersInfoMutex);
+ if (lpAdapter == NULL)
+ SetLastError(ERROR_BAD_UNIT); //this is the best we can do....
+ return lpAdapter;
+ }
+ }
+
+ //
+ // Check adapter type
+ //
+ if(TAdInfo->Flags != INFO_FLAG_NDIS_ADAPTER)
+ {
+ //
+ // Not a standard NDIS adapter, we must have specific handling
+ //
+
+ if(TAdInfo->Flags & INFO_FLAG_NDISWAN_ADAPTER)
+ {
+ //
+ // This is a wan adapter. Open it using the netmon API
+ //
+ lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,
+ sizeof(ADAPTER));
+ if (lpAdapter == NULL)
+ {
+ if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU);
+ else GlobalFreePtr(AdapterNameA);
+ ReleaseMutex(AdaptersInfoMutex);
+ SetLastError(ERROR_BAD_UNIT);
+ return NULL;
+ }
+
+ // Backup flags for future usage
+ lpAdapter->Flags = TAdInfo->Flags;
+
+ // Open the adapter
+ lpAdapter->pWanAdapter = WanPacketOpenAdapter();
+ if (lpAdapter->pWanAdapter == NULL)
+ {
+ if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU);
+ else GlobalFreePtr(AdapterNameA);
+
+ GlobalFreePtr(lpAdapter);
+ ReleaseMutex(AdaptersInfoMutex);
+ SetLastError(ERROR_BAD_UNIT);
+ return NULL;
+ }
+
+ _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterNameA);
+
+ lpAdapter->ReadEvent = WanPacketGetReadEvent(lpAdapter->pWanAdapter);
+
+ if (AdapterNameU != NULL)
+ GlobalFreePtr(AdapterNameU);
+ else
+ GlobalFreePtr(AdapterNameA);
+
+ ReleaseMutex(AdaptersInfoMutex);
+ return lpAdapter;
+ }
+ else
+ if(TAdInfo->Flags & INFO_FLAG_DAG_CARD)
+ {
+ //
+ // This is a Dag card. Open it using the dagc API
+ //
+ lpAdapter = PacketOpenAdapterDAG(AdapterNameA, FALSE);
+
+ if (AdapterNameU != NULL)
+ GlobalFreePtr(AdapterNameU);
+ else
+ GlobalFreePtr(AdapterNameA);
+
+ ReleaseMutex(AdaptersInfoMutex);
+ if (lpAdapter == NULL)
+ SetLastError(ERROR_BAD_UNIT);
+ return lpAdapter;
+ }
+ else
+ 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.
+ //
+ ODSEx("The user openend the adapter %s which is flagged as not exported", AdapterNameA);
+ if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU);
+ else GlobalFreePtr(AdapterNameA);
+ ReleaseMutex(AdaptersInfoMutex);
+ SetLastError(ERROR_BAD_UNIT);
+ return NULL;
+ }
+ }
+
+ ReleaseMutex(AdaptersInfoMutex);
+
+#endif // _WINNT4
+
+ lpAdapter = PacketOpenAdapterNPF(AdapterName);
+
+ if (AdapterNameU != NULL)
+ GlobalFreePtr(AdapterNameU);
+ else
+ GlobalFreePtr(AdapterNameA);
+
+ 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)
+{
+ if(!lpAdapter)
+ {
+ ODS("PacketCloseAdapter: attempt to close a NULL adapter\n");
+ return;
+ }
+
+#ifndef _WINNT4
+ if(lpAdapter->pWanAdapter != NULL)
+ {
+ WanPacketCloseAdapter(lpAdapter->pWanAdapter);
+ GlobalFreePtr(lpAdapter);
+ return;
+ }
+#ifdef HAVE_DAG_API
+ else
+ if(lpAdapter->pDagCard != NULL)
+ {
+ 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);
+ }
+ p_dagc_close(lpAdapter->pDagCard);
+ }
+#endif // HAVE_DAG_API
+#endif // _WINNT4
+
+ CloseHandle(lpAdapter->hFile);
+ SetEvent(lpAdapter->ReadEvent);
+ CloseHandle(lpAdapter->ReadEvent);
+ GlobalFreePtr(lpAdapter);
+}
+
+/*!
+ \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;
+ lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET));
+ if (lpPacket==NULL)
+ {
+ ODS("PacketAllocatePacket: GlobalAlloc Failed\n");
+ return NULL;
+ }
+ 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)
+
+{
+ GlobalFreePtr(lpPacket);
+}
+
+/*!
+ \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)
+
+{
+ lpPacket->Buffer = Buffer;
+ lpPacket->Length = Length;
+ lpPacket->ulBytesReceived = 0;
+ lpPacket->bIoComplete = FALSE;
+}
+
+/*!
+ \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 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;
+
+#ifndef _WINNT4
+
+ if (AdapterObject->pWanAdapter != NULL)
+ {
+ lpPacket->ulBytesReceived = WanPacketReceivePacket(AdapterObject->pWanAdapter, lpPacket->Buffer, lpPacket->Length);
+ return TRUE;
+ }
+#ifdef HAVE_DAG_API
+ else
+ if(AdapterObject->pDagCard != NULL)
+ {
+
+ p_dagc_wait(AdapterObject->pDagCard, &AdapterObject->DagReadTimeout);
+
+ if(p_dagc_receive(AdapterObject->pDagCard, &AdapterObject->DagBuffer, &lpPacket->ulBytesReceived) == 0)
+ return TRUE;
+ else
+ return FALSE;
+ }
+#endif // HAVE_DAG_API
+#endif // _WINNT4
+
+ if((int)AdapterObject->ReadTimeOut != -1)
+ WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut);
+
+ res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL);
+
+ 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;
+
+
+#ifndef _WINNT4
+ if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
+ {
+ ODS("PacketSendPacket: packet sending not allowed on wan adapters\n");
+ return FALSE;
+ }
+#endif // _WINNT4
+
+ return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL);
+}
+
+
+/*!
+ \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;
+ DWORD last_total = 0;
+ struct timeval BufStartTime;
+ //LARGE_INTEGER StartTicks, CurTicks, TargetTicks, TimeFreq;
+ UINT num_count = 0;
+
+
+ ODS("PacketSendPackets");
+
+#ifndef _WINNT4
+ if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
+ {
+ ODS("PacketSendPackets: packet sending not allowed on wan adapters\n");
+ return FALSE;
+ }
+#endif // _WINNT4
+
+ // 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
+ Res = 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;
+
+ if (last_total != TotBytesTransfered)
+ {
+ num_count = 0;
+ last_total = TotBytesTransfered;
+ }
+
+ num_count++;
+
+ if (num_count >= 100000)
+ {
+ // Fatal Error: Infinite Loop
+ return 0x7FFFFFFF;
+ }
+
+ // 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);
+
+ 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;
+
+#ifndef _WINNT4
+ if (AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER)
+ return WanPacketSetMinToCopy(AdapterObject->pWanAdapter, nbytes);
+#ifdef HAVE_DAG_API
+ else
+ if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
+ // No mintocopy with DAGs
+ return TRUE;
+#endif // HAVE_DAG_API
+#endif // _WINNT4
+
+ return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL);
+}
+
+/*!
+ \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:<p>
+ \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:<p>
+ \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;
+
+#ifndef _WINNT4
+ if (AdapterObject->pWanAdapter != NULL)
+ return WanPacketSetMode(AdapterObject->pWanAdapter, mode);
+#endif // _WINNT4
+
+ return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL);
+}
+
+/*!
+ \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;
+
+#ifndef _WINNT4
+ if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
+ {
+ ODS("PacketSetDumpName: not allowed on wan adapters\n");
+ return FALSE;
+ }
+#endif // _WINNT4
+
+ 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);
+ return FALSE;
+ }
+
+ res = DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL);
+ free(FileName);
+ 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];
+
+#ifndef _WINNT4
+ if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
+ {
+ ODS("PacketSetDumpLimits: not allowed on wan adapters\n");
+ return FALSE;
+ }
+#endif // _WINNT4
+
+ valbuff[0] = maxfilesize;
+ valbuff[1] = maxnpacks;
+
+ return DeviceIoControl(AdapterObject->hFile,
+ pBIOCSETDUMPLIMITS,
+ valbuff,
+ sizeof valbuff,
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL);
+}
+
+/*!
+ \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;
+
+#ifndef _WINNT4
+ if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
+ {
+ ODS("PacketIsDumpEnded: not allowed on wan adapters\n");
+ return FALSE;
+ }
+#endif // _WINNT4
+
+ if(sync)
+ WaitForSingleObject(AdapterObject->ReadEvent, INFINITE);
+
+ res = DeviceIoControl(AdapterObject->hFile,
+ pBIOCISDUMPENDED,
+ NULL,
+ 0,
+ &IsDumpEnded,
+ 4,
+ &BytesReturned,
+ NULL);
+
+ 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)
+{
+ 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;
+
+#ifndef _WINNT4
+ if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
+ {
+ ODS("PacketSetNumWrites: not allowed on wan adapters\n");
+ return FALSE;
+ }
+#endif // _WINNT4
+
+ return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL);
+}
+
+/*!
+ \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)
+{
+ DWORD BytesReturned;
+ int DriverTimeOut=-1;
+
+#ifndef _WINNT4
+ if (AdapterObject->pWanAdapter != NULL)
+ return WanPacketSetReadTimeout(AdapterObject->pWanAdapter,timeout);
+#endif // _WINNT4
+
+ AdapterObject->ReadTimeOut=timeout;
+
+#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 == 1)
+ {
+ // 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;
+ }
+
+ return TRUE;
+ }
+#endif // HAVE_DAG_API
+
+ return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL);
+}
+
+/*!
+ \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;
+
+#ifndef _WINNT4
+ if (AdapterObject->pWanAdapter != NULL)
+ return WanPacketSetBufferSize(AdapterObject->pWanAdapter, dim);
+#ifdef HAVE_DAG_API
+ else
+ if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
+ // We can't change DAG buffers
+ return TRUE;
+#endif // HAVE_DAG_API
+
+#endif // _WINNT4
+ return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL);
+}
+
+/*!
+ \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 syntax of WinDump (see the manual of WinDump at
+ http://netgroup.polito.it/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 launch WinDump with the -d or -dd or -ddd
+ flags to obtain the pseudocode.
+
+*/
+BOOLEAN PacketSetBpf(LPADAPTER AdapterObject, struct bpf_program *fp)
+{
+ DWORD BytesReturned;
+
+#ifndef _WINNT4
+ if (AdapterObject->pWanAdapter != NULL)
+ return WanPacketSetBpfFilter(AdapterObject->pWanAdapter, (PUCHAR)fp->bf_insns, fp->bf_len * sizeof(struct bpf_insn));
+#ifdef HAVE_DAG_API
+ else
+ if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
+ // Delegate the filtering to higher layers since it's too expensive here
+ return TRUE;
+#endif // HAVE_DAG_API
+#endif // _WINNT4
+
+ return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL);
+}
+
+/*!
+ \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)
+{
+
+#ifdef HAVE_DAG_API
+ if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
+ return p_dagc_setsnaplen(AdapterObject->pDagCard, snaplen);
+ else
+#endif // HAVE_DAG_API
+ return 0;
+}
+
+/*!
+ \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
+
+#ifndef _WINNT4
+#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(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;
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+ else
+#endif // HAVE_DAG_API
+ if ( AdapterObject->pWanAdapter != NULL)
+ Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat);
+ else
+#endif // _WINNT4
+
+ Res = DeviceIoControl(AdapterObject->hFile,
+ pBIOCGSTATS,
+ NULL,
+ 0,
+ &tmpstat,
+ sizeof(struct bpf_stat),
+ &BytesReturned,
+ NULL);
+
+
+ // Copy only the first two values retrieved from the driver
+ s->bs_recv = tmpstat.bs_recv;
+ s->bs_drop = tmpstat.bs_drop;
+
+ 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
+
+#ifndef _WINNT4
+#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
+ 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;
+ }
+#endif // HAVE_DAG_API
+ if(AdapterObject->pWanAdapter != NULL)
+ Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat);
+ else
+#endif // _WINNT4
+
+ Res = DeviceIoControl(AdapterObject->hFile,
+ pBIOCGSTATS,
+ NULL,
+ 0,
+ &tmpstat,
+ sizeof(struct bpf_stat),
+ &BytesReturned,
+ NULL);
+
+ s->bs_recv = tmpstat.bs_recv;
+ s->bs_drop = tmpstat.bs_drop;
+ s->ps_ifdrop = tmpstat.ps_ifdrop;
+ s->bs_capt = tmpstat.bs_capt;
+
+ 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;
+
+#ifndef _WINNT4
+ if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
+ return FALSE;
+#endif // _WINNT4
+
+ Result=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
+ ODSEx("PacketRequest, OID=%d ", OidData->Oid);
+ ODSEx("Length=%d ", OidData->Length);
+ ODSEx("Set=%d ", Set);
+ ODSEx("Res=%d\n", Result);
+
+ 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;
+
+#ifndef _WINNT4
+ if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
+ return TRUE;
+#endif // _WINNT4
+
+ OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
+ if (OidData == NULL) {
+ ODS("PacketSetHwFilter: GlobalAlloc Failed\n");
+ 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;
+}
+
+/*!
+ \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 <B>and supported by WinPcap</B>.
+ 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 = 1;
+ ULONG SizeNames = 1;
+ ULONG SizeDesc;
+ ULONG OffDescriptions;
+
+ ODSEx("PacketGetAdapterNames: BufferSize=%d\n", *BufferSize);
+
+ //
+ // Create the adapter information list
+ //
+ PacketPopulateAdaptersInfoList();
+
+ WaitForSingleObject(AdaptersInfoMutex, INFINITE);
+ if(!AdaptersInfoList)
+ {
+ ReleaseMutex(AdaptersInfoMutex);
+ *BufferSize = 0;
+ return FALSE; // No adapters to return
+ }
+
+ //
+ // First scan of the list to calculate the offsets and check the sizes
+ //
+ for(TAdInfo = AdaptersInfoList; TAdInfo != NULL; TAdInfo = TAdInfo->Next)
+ {
+ if(TAdInfo->Flags != INFO_FLAG_DONT_EXPORT)
+ {
+ // Update the size variables
+ SizeNeeded += (int)strlen(TAdInfo->Name) + (int)strlen(TAdInfo->Description) + 2;
+ SizeNames += (int)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(AdaptersInfoMutex);
+
+ ODS("PacketGetAdapterNames: input buffer too small\n");
+ *BufferSize = SizeNeeded + 4; // Report the required size
+ return FALSE;
+ }
+
+ OffDescriptions = SizeNames;
+
+ //
+ // Second scan of the list to copy the information
+ //
+ for(TAdInfo = AdaptersInfoList, SizeNames = 0, SizeDesc = 0; TAdInfo != NULL; TAdInfo = TAdInfo->Next)
+ {
+ if(TAdInfo->Flags != INFO_FLAG_DONT_EXPORT)
+ {
+ // Copy the data
+ strcpy(((PCHAR)pStr) + SizeNames, TAdInfo->Name);
+ strcpy(((PCHAR)pStr) + OffDescriptions + SizeDesc, TAdInfo->Description);
+
+ // Update the size variables
+ SizeNames += (int)strlen(TAdInfo->Name) + 1;
+ SizeDesc += (int)strlen(TAdInfo->Description) + 1;
+ }
+ }
+
+ // Separate the two lists
+ ((PCHAR)pStr)[SizeNames] = 0;
+
+ // End the list with a further \0
+ ((PCHAR)pStr)[SizeNeeded] = 0;
+
+
+ ReleaseMutex(AdaptersInfoMutex);
+ 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;
+
+ ODS("PacketGetNetInfo\n");
+
+ // 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))
+ {
+ ODS("PacketGetNetInfo: Adapter not found\n");
+ if(FreeBuff)GlobalFreePtr(Tname);
+ return FALSE;
+ }
+
+ WaitForSingleObject(AdaptersInfoMutex, INFINITE);
+ // Find the PADAPTER_INFO structure associated with this adapter
+ TAdInfo = PacketFindAdInfo(Tname);
+
+ if(TAdInfo != NULL)
+ {
+ *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
+ {
+ ODS("PacketGetNetInfo: Adapter not found\n");
+ Res = FALSE;
+ }
+
+ ReleaseMutex(AdaptersInfoMutex);
+
+ if(FreeBuff)GlobalFreePtr(Tname);
+
+ 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;
+ ODS("PacketGetNetType\n");
+
+ WaitForSingleObject(AdaptersInfoMutex, INFINITE);
+ // Find the PADAPTER_INFO structure associated with this adapter
+ TAdInfo = PacketFindAdInfo(AdapterObject->Name);
+
+ if(TAdInfo != NULL)
+ {
+ // Copy the data
+ memcpy(type, &(TAdInfo->LinkLayer), sizeof(struct NetType));
+ ret = TRUE;
+ }
+ else
+ {
+ ODS("PacketGetNetType: Adapter not found\n");
+ ret = FALSE;
+ }
+
+ ReleaseMutex(AdaptersInfoMutex);
+
+ return ret;
+}
+
+/* @} */
+BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior)
+{
+ DWORD BytesReturned;
+ BOOLEAN result;
+
+ if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
+ {
+ return FALSE;
+ }
+
+
+ result = (BOOLEAN)DeviceIoControl(AdapterObject->hFile,
+ pBIOCISETLOBBEH,
+ &LoopbackBehavior,
+ sizeof(UINT),
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL);
+
+ return result;
+}
+
diff --git a/src/SeeDll/Packet32.h b/src/SeeDll/Packet32.h
new file mode 100644
index 00000000..b5cd1cf9
--- /dev/null
+++ b/src/SeeDll/Packet32.h
@@ -0,0 +1,424 @@
+/*
+ * 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.
+ *
+ */
+
+/** @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 <winsock2.h>
+#include "devioctl.h"
+#ifdef HAVE_DAG_API
+#include <dagc.h>
+#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 2147483648 ///< IOCTL code: set an OID value.
+#define pBIOCQUERYOID 2147483652 ///< 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 pBIOCISETLOBBEH 7410
+#define pBIOCISDUMPENDED 7411 ///< IOCTL code: Get the status of the kernel dump process. See the PacketIsDumpEnded() function.
+
+#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
+
+/*!
+ \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 <b>can be different</b>
+ ///< 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
+
+#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
+#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.
+
+/*!
+ \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_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;
+
+
+#if _DBG
+#define ODS(_x) OutputDebugString(TEXT(_x))
+#define ODSEx(_x, _y)
+#else
+#ifdef _DEBUG_TO_FILE
+/*!
+ \brief 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); \
+}
+/*!
+ \brief Macro to print debug data with the printf convention. The behavior differs depending on
+ the debug level
+*/
+#define ODSEx(_x, _y) { \
+ FILE *f; \
+ f = fopen("winpcap_debug.txt", "a"); \
+ fprintf(f, _x, _y); \
+ fclose(f); \
+}
+
+
+
+LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName);
+#else
+#define ODS(_x)
+#define ODSEx(_x, _y)
+#endif
+#endif
+
+/* We load dinamically the dag library in order link it only when it's present on the system */
+#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
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @}
+ */
+
+// The following is used to check the adapter name in PacketOpenAdapterNPF and prevent
+// opening of firewire adapters
+#define FIREWIRE_SUBSTR L"1394"
+
+void PacketPopulateAdaptersInfoList();
+PWCHAR SChar2WChar(PCHAR string);
+PCHAR WChar2SChar(PWCHAR string);
+BOOL PacketGetFileVersion(LPTSTR FileName, PCHAR VersionBuff, UINT VersionBuffLen);
+PADAPTER_INFO PacketFindAdInfo(PCHAR AdapterName);
+BOOLEAN PacketUpdateAdInfo(PCHAR AdapterName);
+BOOLEAN IsFireWire(TCHAR *AdapterDesc);
+
+
+//---------------------------------------------------------------------------
+// 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);
+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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__PACKET32
diff --git a/src/SeeDll/SeeDll.rc b/src/SeeDll/SeeDll.rc
new file mode 100644
index 00000000..2e72f111
--- /dev/null
+++ b/src/SeeDll/SeeDll.rc
@@ -0,0 +1,63 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Japanese resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
+#ifdef _WIN32
+LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
+#pragma code_page(932)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Japanese resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/src/SeeDll/SeeDll.vcproj b/src/SeeDll/SeeDll.vcproj
new file mode 100644
index 00000000..eee9e345
--- /dev/null
+++ b/src/SeeDll/SeeDll.vcproj
@@ -0,0 +1,288 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="SeeDll"
+ ProjectGUID="{B75C0F74-0FE6-4BD4-8E54-F8383C58CB69}"
+ RootNamespace="SeeDll"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)bin"
+ IntermediateDirectory="$(PlatformName)_$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ WholeProgramOptimization="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="0"
+ EnableIntrinsicFunctions="false"
+ FavorSizeOrSpeed="0"
+ AdditionalIncludeDirectories="$(SolutionDir)Mayaqua\win32_inc;.;$(SolutionDir)"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_USE_32BIT_TIME_T;PCDDLL_EXPORTS"
+ StringPooling="false"
+ ExceptionHandling="0"
+ RuntimeLibrary="0"
+ StructMemberAlignment="4"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ CompileAs="1"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:GenerateVersionResource &quot;$(TargetPath)&quot; /OUT:&quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ LinkLibraryDependencies="false"
+ AdditionalDependencies="Version.lib &quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
+ OutputFile="$(OutDir)\hamcore\see.dll"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="&quot;C:\Program Files (x86)\Microsoft Visual Studio 8\VC\lib&quot;"
+ GenerateManifest="false"
+ ModuleDefinitionFile="See_$(PlatformName).def"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(SolutionDir)DebugFiles\pdb\$(PlatformName)_$(ConfigurationName)\$(ProjectName).pdb"
+ GenerateMapFile="true"
+ MapFileName="$(SolutionDir)DebugFiles\map\$(PlatformName)_$(ConfigurationName)\$(ProjectName).map"
+ SubSystem="2"
+ StackReserveSize="100000"
+ OptimizeReferences="1"
+ EnableCOMDATFolding="1"
+ ImportLibrary="$(SolutionDir)tmp\lib\$(PlatformName)_$(ConfigurationName)\$(ProjectName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ EmbedManifest="false"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)bin"
+ IntermediateDirectory="$(PlatformName)_$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ WholeProgramOptimization="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="0"
+ EnableIntrinsicFunctions="false"
+ FavorSizeOrSpeed="0"
+ AdditionalIncludeDirectories="$(SolutionDir)Mayaqua\win32_inc;.;$(SolutionDir)"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PCDDLL_EXPORTS;CPU_64"
+ StringPooling="false"
+ ExceptionHandling="0"
+ RuntimeLibrary="0"
+ StructMemberAlignment="4"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ CompileAs="1"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:GenerateVersionResource &quot;$(TargetPath)&quot; /OUT:&quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ LinkLibraryDependencies="false"
+ AdditionalDependencies="Version.lib &quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
+ OutputFile="$(OutDir)\hamcore\see_x64.dll"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateManifest="false"
+ ModuleDefinitionFile="See_$(PlatformName).def"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(SolutionDir)DebugFiles\pdb\$(PlatformName)_$(ConfigurationName)\$(ProjectName).pdb"
+ GenerateMapFile="true"
+ MapFileName="$(SolutionDir)DebugFiles\map\$(PlatformName)_$(ConfigurationName)\$(ProjectName).map"
+ SubSystem="2"
+ StackReserveSize="100000"
+ OptimizeReferences="1"
+ EnableCOMDATFolding="1"
+ ImportLibrary="$(SolutionDir)tmp\lib\$(PlatformName)_$(ConfigurationName)\$(ProjectName).lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ EmbedManifest="false"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine=""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\AdInfo.c"
+ >
+ </File>
+ <File
+ RelativePath=".\Packet32.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\dagc.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Devioctl.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Ntddndis.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Ntddpack.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Packet32.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\SeeDll.rc"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\See_Win32.def"
+ >
+ </File>
+ <File
+ RelativePath=".\See_x64.def"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/SeeDll/See_Win32.def b/src/SeeDll/See_Win32.def
new file mode 100644
index 00000000..4c5c64f8
--- /dev/null
+++ b/src/SeeDll/See_Win32.def
@@ -0,0 +1,34 @@
+LIBRARY see
+
+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
diff --git a/src/SeeDll/See_x64.def b/src/SeeDll/See_x64.def
new file mode 100644
index 00000000..5f30a5fd
--- /dev/null
+++ b/src/SeeDll/See_x64.def
@@ -0,0 +1,34 @@
+LIBRARY see_x64
+
+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
diff --git a/src/SeeDll/dagc.h b/src/SeeDll/dagc.h
new file mode 100644
index 00000000..6162c4a3
--- /dev/null
+++ b/src/SeeDll/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/src/SeeDll/resource.h b/src/SeeDll/resource.h
new file mode 100644
index 00000000..6e86a4b6
--- /dev/null
+++ b/src/SeeDll/resource.h
@@ -0,0 +1,84 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by SeeDll.rc
+//
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// 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 version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+// 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 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/