Main Page Modules Data Structures File List Data Fields Globals Related Pages

# Packet32.c

Go to the documentation of this file.

    00001 /*
    00002  * Copyright (c) 1999 - 2003
    00003  *  Politecnico di Torino.  All rights reserved.
    00004  *
    00005  * Redistribution and use in source and binary forms, with or without
    00006  * modification, are permitted provided that: (1) source code distributions
    00007  * retain the above copyright notice and this paragraph in its entirety, (2)
    00008  * distributions including binary code include the above copyright notice and
    00009  * this paragraph in its entirety in the documentation or other materials
    00010  * provided with the distribution, and (3) all advertising materials mentioning
    00011  * features or use of this software display the following acknowledgement:
    00012  * ``This product includes software developed by the Politecnico
    00013  * di Torino, and its contributors.'' Neither the name of
    00014  * the University nor the names of its contributors may be used to endorse
    00015  * or promote products derived from this software without specific prior
    00016  * written permission.
    00017  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
    00018  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
    00019  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    00020  */
    00021
    00022 #define UNICODE 1
    00023
    00024 #include <stdio.h>
    00025 #include <packet32.h>
    00026 #include "wanpacket/wanpacket.h"
    00027
    00028
    00029 #include <windows.h>
    00030 #include <windowsx.h>
    00031 #include <Iphlpapi.h>
    00032 #include <IPIfCons.h>
    00033
    00034 #include <ntddndis.h>
    00035
    00036
    00038 char PacketLibraryVersion[64];
    00040 char PacketDriverVersion[64];
    00041
    00043 TCHAR   szWindowTitle[] = TEXT("PACKET.DLL");
    00044
    00045 //service handles
    00046 SC_HANDLE scmHandle = NULL;
    00047 SC_HANDLE srvHandle = NULL;
    00048 LPCTSTR NPFServiceName = TEXT("NPF");
    00049 LPCTSTR NPFServiceDesc = TEXT("Netgroup Packet Filter");
    00050 LPCTSTR NPFRegistryLocation = TEXT("SYSTEM\\CurrentControlSet\\Services\\NPF");
    00051 LPCTSTR NPFDriverPath = TEXT("system32\\drivers\\npf.sys");
    00052
    00053 extern PADAPTER_INFO AdaptersInfoList;
    00054 extern HANDLE AdaptersInfoMutex;
    00055 #ifndef _WINNT4
    00056 typedef VOID (*GAAHandler)(
    00057   ULONG,
    00058   DWORD,
    00059   PVOID,
    00060   PIP_ADAPTER_ADDRESSES,
    00061   PULONG);
    00062 GAAHandler GetAdaptersAddressesPointer = NULL;
    00063 #endif // _WINNT4
    00064
    00065 #ifdef HAVE_DAG_API
    00066 /* We load dinamically the dag library in order link it only when it's present on the system */
    00067 dagc_open_handler p_dagc_open = NULL;
    00068 dagc_close_handler p_dagc_close = NULL;
    00069 dagc_getlinktype_handler p_dagc_getlinktype = NULL;
    00070 dagc_getlinkspeed_handler p_dagc_getlinkspeed = NULL;
    00071 dagc_getfcslen_handler p_dagc_getfcslen = NULL;
    00072 dagc_receive_handler p_dagc_receive = NULL;
    00073 dagc_wait_handler p_dagc_wait = NULL;
    00074 dagc_stats_handler p_dagc_stats = NULL;
    00075 dagc_setsnaplen_handler p_dagc_setsnaplen = NULL;
    00076 dagc_finddevs_handler p_dagc_finddevs = NULL;
    00077 dagc_freedevs_handler p_dagc_freedevs = NULL;
    00078 #endif /* HAVE_DAG_API */
    00079
    00080 BOOLEAN PacketAddAdapterDag(PCHAR name, PCHAR description, BOOLEAN IsAFile);
    00081
    00082 //---------------------------------------------------------------------------
    00083
    00088 BOOL APIENTRY DllMain (HANDLE DllHandle,DWORD Reason,LPVOID lpReserved)
    00089 {
    00090     BOOLEAN Status=TRUE;
    00091     HMODULE IPHMod;
    00092 #ifdef HAVE_DAG_API
    00093     HMODULE DagcLib;
    00094 #endif // HAVE_DAG_API
    00095
    00096     switch(Reason)
    00097     {
    00098     case DLL_PROCESS_ATTACH:
    00099
    00100         ODS("************Packet32: DllMain************\n");
    00101
    00102 #ifdef _DEBUG_TO_FILE
    00103         // dump a bunch of registry keys useful for debug to file
    00104         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",
    00105             "adapters.reg");
    00106         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip",
    00107             "tcpip.reg");
    00108         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\NPF",
    00109             "npf.reg");
    00110         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services",
    00111             "services.reg");
    00112 #endif
    00113
    00114         // Create the mutex that will protect the adapter information list
    00115         AdaptersInfoMutex = CreateMutex(NULL, TRUE, NULL);
    00116         ReleaseMutex(AdaptersInfoMutex);
    00117
    00118         //
    00119         // Retrieve packet.dll version information from the file
    00120         //
    00121         PacketGetFileVersion(TEXT("packet.dll"), PacketLibraryVersion, sizeof(PacketLibraryVersion));
    00122
    00123         //
    00124         // Retrieve NPF.sys version information from the file
    00125         //
    00126         PacketGetFileVersion(TEXT("drivers\\npf.sys"), PacketDriverVersion, sizeof(PacketDriverVersion));
    00127
    00128         //
    00129         // Locate GetAdaptersAddresses dinamically since it is not present in Win2k
    00130         //
    00131         IPHMod = GetModuleHandle(TEXT("Iphlpapi"));
    00132
    00133 #ifndef _WINNT4
    00134         GetAdaptersAddressesPointer = (GAAHandler) GetProcAddress(IPHMod ,"GetAdaptersAddresses");
    00135 #endif // _WINNT4
    00136
    00137 #ifdef HAVE_DAG_API
    00138         /* We load dinamically the dag library in order link it only when it's present on the system */
    00139         if((DagcLib =  LoadLibrary(TEXT("dagc.dll"))) == NULL)
    00140         {
    00141             // Report the error but go on
    00142             ODS("dag capture library not found on this system\n");
    00143             break;
    00144         }
    00145
    00146         p_dagc_open = (dagc_open_handler) GetProcAddress(DagcLib, "dagc_open");
    00147         p_dagc_close = (dagc_close_handler) GetProcAddress(DagcLib, "dagc_close");
    00148         p_dagc_setsnaplen = (dagc_setsnaplen_handler) GetProcAddress(DagcLib, "dagc_setsnaplen");
    00149         p_dagc_getlinktype = (dagc_getlinktype_handler) GetProcAddress(DagcLib, "dagc_getlinktype");
    00150         p_dagc_getlinkspeed = (dagc_getlinkspeed_handler) GetProcAddress(DagcLib, "dagc_getlinkspeed");
    00151         p_dagc_getfcslen = (dagc_getfcslen_handler) GetProcAddress(DagcLib, "dagc_getfcslen");
    00152         p_dagc_receive = (dagc_receive_handler) GetProcAddress(DagcLib, "dagc_receive");
    00153         p_dagc_wait = (dagc_wait_handler) GetProcAddress(DagcLib, "dagc_wait");
    00154         p_dagc_stats = (dagc_stats_handler) GetProcAddress(DagcLib, "dagc_stats");
    00155         p_dagc_finddevs = (dagc_finddevs_handler) GetProcAddress(DagcLib, "dagc_finddevs");
    00156         p_dagc_freedevs = (dagc_freedevs_handler) GetProcAddress(DagcLib, "dagc_freedevs");
    00157
    00158 #endif /* HAVE_DAG_API */
    00159
    00160         break;
    00161
    00162         case DLL_PROCESS_DETACH:
    00163
    00164             CloseHandle(AdaptersInfoMutex);
    00165
    00166             break;
    00167
    00168         default:
    00169             break;
    00170     }
    00171
    00172     return Status;
    00173 }
    00174
    00183 ULONG inet_addrU(const WCHAR *cp)
    00184 {
    00185     ULONG val, part;
    00186     WCHAR c;
    00187     int i;
    00188
    00189     val = 0;
    00190     for (i = 0; i < 4; i++) {
    00191         part = 0;
    00192         while ((c = *cp++) != '\0' && c != '.') {
    00193             if (c < '0' || c > '9')
    00194                 return -1;
    00195             part = part*10 + (c - '0');
    00196         }
    00197         if (part > 255)
    00198             return -1;
    00199         val = val | (part << i*8);
    00200         if (i == 3) {
    00201             if (c != '\0')
    00202                 return -1;  // extra gunk at end of string
    00203         } else {
    00204             if (c == '\0')
    00205                 return -1;  // string ends early
    00206         }
    00207     }
    00208     return val;
    00209 }
    00210
    00217 PWCHAR SChar2WChar(PCHAR string)
    00218 {
    00219     PWCHAR TmpStr;
    00220     TmpStr = (WCHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (strlen(string)+2)*sizeof(WCHAR));
    00221
    00222     MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (strlen(string)+2));
    00223
    00224     return TmpStr;
    00225 }
    00226
    00233 PCHAR WChar2SChar(PWCHAR string)
    00234 {
    00235     PCHAR TmpStr;
    00236     TmpStr = (CHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (wcslen(string)+2));
    00237
    00238     // Conver to ASCII
    00239     WideCharToMultiByte(
    00240         CP_ACP,
    00241         0,
    00242         string,
    00243         -1,
    00244         TmpStr,
    00245         (wcslen(string)+2),          // size of buffer
    00246         NULL,
    00247         NULL);
    00248
    00249     return TmpStr;
    00250 }
    00251
    00261 BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject)
    00262 {
    00263     BOOLEAN    Status;
    00264     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
    00265     PPACKET_OID_DATA  OidData;
    00266
    00267     OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
    00268     if (OidData == NULL) {
    00269         ODS("PacketSetMaxLookaheadsize failed\n");
    00270         return FALSE;
    00271     }
    00272
    00273     //set the size of the lookahead buffer to the maximum available by the the NIC driver
    00274     OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD;
    00275     OidData->Length=sizeof(ULONG);
    00276     Status=PacketRequest(AdapterObject,FALSE,OidData);
    00277     OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD;
    00278     Status=PacketRequest(AdapterObject,TRUE,OidData);
    00279     GlobalFreePtr(OidData);
    00280     return Status;
    00281 }
    00282
    00293 BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject)
    00294 {
    00295     DWORD BytesReturned;
    00296     TCHAR EventName[39];
    00297
    00298     // this tells the terminal service to retrieve the event from the global namespace
    00299     wcsncpy(EventName,L"Global\\",sizeof(L"Global\\"));
    00300
    00301     // retrieve the name of the shared event from the driver
    00302     if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName+7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) return FALSE;
    00303
    00304     EventName[20]=0; // terminate the string
    00305
    00306     // open the shared event
    00307     AdapterObject->ReadEvent=CreateEvent(NULL,
    00308                                          TRUE,
    00309                                          FALSE,
    00310                                          EventName);
    00311
    00312     // in NT4 "Global\" is not automatically ignored: try to use simply the event name
    00313     if(GetLastError()!=ERROR_ALREADY_EXISTS){
    00314         if(AdapterObject->ReadEvent != NULL)
    00315             CloseHandle(AdapterObject->ReadEvent);
    00316
    00317         // open the shared event
    00318         AdapterObject->ReadEvent=CreateEvent(NULL,
    00319             TRUE,
    00320             FALSE,
    00321             EventName+7);
    00322     }
    00323
    00324     if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){
    00325         ODS("PacketSetReadEvt: error retrieving the event from the kernel\n");
    00326         return FALSE;
    00327     }
    00328
    00329     AdapterObject->ReadTimeOut=0;
    00330
    00331     return TRUE;
    00332 }
    00333
    00343 BOOL PacketInstallDriver(SC_HANDLE ascmHandle,SC_HANDLE *srvHandle)
    00344 {
    00345     BOOL result = FALSE;
    00346     ULONG err;
    00347
    00348     ODS("installdriver\n");
    00349
    00350     *srvHandle = CreateService(ascmHandle,
    00351         NPFServiceName,
    00352         NPFServiceDesc,
    00353         SERVICE_ALL_ACCESS,
    00354         SERVICE_KERNEL_DRIVER,
    00355         SERVICE_DEMAND_START,
    00356         SERVICE_ERROR_NORMAL,
    00357         NPFDriverPath,
    00358         NULL, NULL, NULL, NULL, NULL);
    00359     if (*srvHandle == NULL)
    00360     {
    00361         if (GetLastError() == ERROR_SERVICE_EXISTS)
    00362         {
    00363             //npf.sys already existed
    00364             result = TRUE;
    00365         }
    00366     }
    00367     else
    00368     {
    00369         //Created service for npf.sys
    00370         result = TRUE;
    00371     }
    00372     if (result == TRUE)
    00373         if (*srvHandle != NULL)
    00374             CloseServiceHandle(*srvHandle);
    00375
    00376     if(result == FALSE){
    00377         err = GetLastError();
    00378         if(err != 2)
    00379             ODSEx("PacketInstallDriver failed, Error=%d\n",err);
    00380     }
    00381     return result;
    00382
    00383 }
    00384
    00394 #ifdef _DEBUG_TO_FILE
    00395
    00396 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName)
    00397 {
    00398     CHAR Command[256];
    00399
    00400     strcpy(Command, "regedit /e ");
    00401     strcat(Command, FileName);
    00402     strcat(Command, " ");
    00403     strcat(Command, KeyName);
    00404
    00406     system(Command);
    00407
    00408     return TRUE;
    00409 }
    00410 #endif
    00411
    00421 BOOL PacketGetFileVersion(LPTSTR FileName, PCHAR VersionBuff, UINT VersionBuffLen)
    00422 {
    00423     DWORD   dwVerInfoSize;  // Size of version information block
    00424     DWORD   dwVerHnd=0;   // An 'ignored' parameter, always '0'
    00425     LPSTR   lpstrVffInfo;
    00426     UINT    cbTranslate, dwBytes;
    00427     TCHAR   SubBlock[64];
    00428     PVOID   lpBuffer;
    00429     PCHAR   TmpStr;
    00430
    00431     // Structure used to store enumerated languages and code pages.
    00432     struct LANGANDCODEPAGE {
    00433       WORD wLanguage;
    00434       WORD wCodePage;
    00435     } *lpTranslate;
    00436
    00437     ODS("PacketGetFileVersion\n");
    00438
    00439     // Now lets dive in and pull out the version information:
    00440     dwVerInfoSize = GetFileVersionInfoSize(FileName, &dwVerHnd);
    00441     if (dwVerInfoSize)
    00442     {
    00443         lpstrVffInfo = GlobalAllocPtr(GMEM_MOVEABLE, dwVerInfoSize);
    00444         if (lpstrVffInfo == NULL)
    00445         {
    00446             ODS("PacketGetFileVersion: failed to allocate memory\n");
    00447             return FALSE;
    00448         }
    00449
    00450         if(!GetFileVersionInfo(FileName, dwVerHnd, dwVerInfoSize, lpstrVffInfo))
    00451         {
    00452             ODS("PacketGetFileVersion: failed to call GetFileVersionInfo\n");
    00453             GlobalFreePtr(lpstrVffInfo);
    00454             return FALSE;
    00455         }
    00456
    00457         // Read the list of languages and code pages.
    00458         if(!VerQueryValue(lpstrVffInfo, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate))
    00459         {
    00460             ODS("PacketGetFileVersion: failed to call VerQueryValue\n");
    00461             GlobalFreePtr(lpstrVffInfo);
    00462             return FALSE;
    00463         }
    00464
    00465         // Create the file version string for the first (i.e. the only one) language.
    00466         wsprintf( SubBlock,
    00467             TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"),
    00468             (*lpTranslate).wLanguage,
    00469             (*lpTranslate).wCodePage);
    00470
    00471         // Retrieve the file version string for the language.
    00472         if(!VerQueryValue(lpstrVffInfo, SubBlock, &lpBuffer, &dwBytes))
    00473         {
    00474             ODS("PacketGetFileVersion: failed to call VerQueryValue\n");
    00475             GlobalFreePtr(lpstrVffInfo);
    00476             return FALSE;
    00477         }
    00478
    00479         // Convert to ASCII
    00480         TmpStr = WChar2SChar(lpBuffer);
    00481
    00482         if(strlen(TmpStr) >= VersionBuffLen)
    00483         {
    00484             ODS("PacketGetFileVersion: Input buffer too small\n");
    00485             GlobalFreePtr(lpstrVffInfo);
    00486             GlobalFreePtr(TmpStr);
    00487             return FALSE;
    00488         }
    00489
    00490         strcpy(VersionBuff, TmpStr);
    00491
    00492         GlobalFreePtr(TmpStr);
    00493
    00494       }
    00495     else
    00496     {
    00497         ODSEx("PacketGetFileVersion: failed to call GetFileVersionInfoSize, error = %d\n", GetLastError());
    00498         return FALSE;
    00499
    00500     }
    00501
    00502     return TRUE;
    00503 }
    00504
    00513 LPADAPTER PacketOpenAdapterNPF(PCHAR AdapterName)
    00514 {
    00515     LPADAPTER lpAdapter;
    00516     BOOLEAN Result;
    00517     DWORD error;
    00518     SC_HANDLE svcHandle = NULL;
    00519     LONG KeyRes;
    00520     HKEY PathKey;
    00521     SERVICE_STATUS SStat;
    00522     BOOLEAN QuerySStat;
    00523     WCHAR SymbolicLink[128];
    00524
    00525     ODS("PacketOpenAdapterNPF\n");
    00526
    00527     scmHandle = OpenSCManager(NULL, NULL, GENERIC_READ);
    00528
    00529     if(scmHandle == NULL){
    00530         error = GetLastError();
    00531         ODSEx("OpenSCManager failed! Error=%d\n", error);
    00532     }
    00533     else{
    00534         // check if the NPF registry key is already present
    00535         // this means that the driver is already installed and that we don't need to call PacketInstallDriver
    00536         KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    00537             NPFRegistryLocation,
    00538             0,
    00539             KEY_READ,
    00540             &PathKey);
    00541
    00542         if(KeyRes != ERROR_SUCCESS)
    00543         {
    00544             Result = PacketInstallDriver(scmHandle,&svcHandle);
    00545         }
    00546         else
    00547         {
    00548             Result = TRUE;
    00549             RegCloseKey(PathKey);
    00550         }
    00551
    00552         if (Result)
    00553         {
    00554
    00555             srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS );
    00556             if (srvHandle != NULL)
    00557             {
    00558                 QuerySStat = QueryServiceStatus(srvHandle, &SStat);
    00559                 ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
    00560
    00561                 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING)
    00562                 {
    00563                     ODS("Calling startservice\n");
    00564                     if (StartService(srvHandle, 0, NULL)==0)
    00565                     {
    00566                         error = GetLastError();
    00567                         if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS)
    00568                         {
    00569                             SetLastError(error);
    00570                             if (scmHandle != NULL)
    00571                                 CloseServiceHandle(scmHandle);
    00572                             error = GetLastError();
    00573                             ODSEx("PacketOpenAdapterNPF: StartService failed, Error=%d\n",error);
    00574                             return NULL;
    00575                         }
    00576                     }
    00577                 }
    00578
    00579                 CloseServiceHandle( srvHandle );
    00580                 srvHandle = NULL;
    00581
    00582             }
    00583             else
    00584             {
    00585                 error = GetLastError();
    00586                 ODSEx("OpenService failed! Error=%d", error);
    00587             }
    00588         }
    00589         else
    00590         {
    00591             if(KeyRes != ERROR_SUCCESS)
    00592                 Result = PacketInstallDriver(scmHandle,&svcHandle);
    00593             else
    00594                 Result = TRUE;
    00595
    00596             if (Result) {
    00597
    00598                 srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START);
    00599                 if (srvHandle != NULL){
    00600
    00601                     QuerySStat = QueryServiceStatus(srvHandle, &SStat);
    00602                     ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
    00603
    00604                     if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){
    00605
    00606                         ODS("Calling startservice\n");
    00607
    00608                         if (StartService(srvHandle, 0, NULL)==0){
    00609                             error = GetLastError();
    00610                             if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){
    00611                                 SetLastError(error);
    00612                                 if (scmHandle != NULL) CloseServiceHandle(scmHandle);
    00613                                 ODSEx("PacketOpenAdapterNPF: StartService failed, Error=%d\n",error);
    00614                                 return NULL;
    00615                             }
    00616                         }
    00617                     }
    00618
    00619                     CloseServiceHandle( srvHandle );
    00620                     srvHandle = NULL;
    00621
    00622                 }
    00623                 else{
    00624                     error = GetLastError();
    00625                     ODSEx("OpenService failed! Error=%d", error);
    00626                 }
    00627             }
    00628         }
    00629     }
    00630
    00631     if (scmHandle != NULL) CloseServiceHandle(scmHandle);
    00632
    00633     lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER));
    00634     if (lpAdapter==NULL)
    00635     {
    00636         ODS("PacketOpenAdapterNPF: GlobalAlloc Failed\n");
    00637         error=GetLastError();
    00638         //set the error to the one on which we failed
    00639         SetLastError(error);
    00640         ODS("PacketOpenAdapterNPF: Failed to allocate the adapter structure\n");
    00641         return NULL;
    00642     }
    00643     lpAdapter->NumWrites=1;
    00644
    00645     wsprintf(SymbolicLink, TEXT("\\\\.\\%s"), &AdapterName[16]);
    00646
    00647     // Copy  only the bytes that fit in the adapter structure.
    00648     // Note that lpAdapter->SymbolicLink is present for backward compatibility but will
    00649     // never be used by the apps
    00650     memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH);
    00651
    00652     //try if it is possible to open the adapter immediately
    00653     lpAdapter->hFile=CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ,
    00654         0,NULL,OPEN_EXISTING,0,0);
    00655
    00656     if (lpAdapter->hFile != INVALID_HANDLE_VALUE)
    00657     {
    00658
    00659         if(PacketSetReadEvt(lpAdapter)==FALSE){
    00660             error=GetLastError();
    00661             ODS("PacketOpenAdapterNPF: Unable to open the read event\n");
    00662             GlobalFreePtr(lpAdapter);
    00663             //set the error to the one on which we failed
    00664             SetLastError(error);
    00665             ODSEx("PacketOpenAdapterNPF: PacketSetReadEvt failed, Error=%d\n",error);
    00666             return NULL;
    00667         }
    00668
    00669         PacketSetMaxLookaheadsize(lpAdapter);
    00670
    00671         _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%S", AdapterName);
    00672
    00673         return lpAdapter;
    00674     }
    00675
    00676
    00677     error=GetLastError();
    00678     GlobalFreePtr(lpAdapter);
    00679     //set the error to the one on which we failed
    00680     SetLastError(error);
    00681     ODSEx("PacketOpenAdapterNPF: CreateFile failed, Error=2,%d\n",error);
    00682     return NULL;
    00683 }
    00684
    00693 #ifdef HAVE_DAG_API
    00694 LPADAPTER PacketOpenAdapterDAG(PCHAR AdapterName, BOOLEAN IsAFile)
    00695 {
    00696     CHAR DagEbuf[DAGC_ERRBUF_SIZE];
    00697     LPADAPTER lpAdapter;
    00698     LONG    status;
    00699     HKEY dagkey;
    00700     DWORD lptype;
    00701     DWORD fpc;
    00702     DWORD lpcbdata = sizeof(fpc);
    00703     WCHAR keyname[512];
    00704     PWCHAR tsn;
    00705
    00706
    00707     lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,
    00708         sizeof(ADAPTER));
    00709     if (lpAdapter == NULL)
    00710     {
    00711         return NULL;
    00712     }
    00713
    00714     if(IsAFile)
    00715     {
    00716         // We must add an entry to the adapter description list, otherwise many function will not
    00717         // be able to work
    00718         if(!PacketAddAdapterDag(AdapterName, "DAG file", IsAFile))
    00719         {
    00720             GlobalFreePtr(lpAdapter);
    00721             return NULL;
    00722         }
    00723
    00724         // Flag that this is a DAG file
    00725         lpAdapter->Flags = INFO_FLAG_DAG_FILE;
    00726     }
    00727     else
    00728     {
    00729         // Flag that this is a DAG card
    00730         lpAdapter->Flags = INFO_FLAG_DAG_CARD;
    00731     }
    00732
    00733     //
    00734     // See if the user is asking for fast capture with this device
    00735     //
    00736
    00737     lpAdapter->DagFastProcess = FALSE;
    00738
    00739     tsn = SChar2WChar(strstr(strlwr((char*)AdapterName), "dag"));
    00740
    00741     _snwprintf(keyname, sizeof(keyname), L"%s\\CardParams\\%ws",
    00742         L"SYSTEM\\CurrentControlSet\\Services\\DAG",
    00743         tsn);
    00744
    00745     GlobalFreePtr(tsn);
    00746
    00747     do
    00748     {
    00749         status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0 , KEY_READ, &dagkey);
    00750         if(status != ERROR_SUCCESS)
    00751             break;
    00752
    00753         status = RegQueryValueEx(dagkey,
    00754             L"FastCap",
    00755             NULL,
    00756             &lptype,
    00757             (char*)&fpc,
    00758             &lpcbdata);
    00759
    00760         if(status == ERROR_SUCCESS)
    00761             lpAdapter->DagFastProcess = fpc;
    00762
    00763         RegCloseKey(dagkey);
    00764     }
    00765     while(FALSE);
    00766
    00767     //
    00768     // Open the card
    00769     //
    00770     lpAdapter->pDagCard = p_dagc_open(AdapterName,
    00771      0,
    00772      DagEbuf);
    00773
    00774     if(lpAdapter->pDagCard == NULL)
    00775     {
    00776         GlobalFreePtr(lpAdapter);
    00777         return NULL;
    00778     }
    00779
    00780     lpAdapter->DagFcsLen = p_dagc_getfcslen(lpAdapter->pDagCard);
    00781
    00782     _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterName);
    00783
    00784     // XXX we could create the read event here
    00785
    00786     return lpAdapter;
    00787 }
    00788 #endif // HAVE_DAG_API
    00789
    00790 //---------------------------------------------------------------------------
    00791 // PUBLIC API
    00792 //---------------------------------------------------------------------------
    00793
    00806 PCHAR PacketGetVersion()
    00807 {
    00808     return PacketLibraryVersion;
    00809 }
    00810
    00815 PCHAR PacketGetDriverVersion()
    00816 {
    00817     return PacketDriverVersion;
    00818 }
    00819
    00828 BOOL PacketStopDriver()
    00829 {
    00830     SC_HANDLE       scmHandle;
    00831     SC_HANDLE       schService;
    00832     BOOL            ret;
    00833     SERVICE_STATUS  serviceStatus;
    00834
    00835     scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    00836
    00837     if(scmHandle != NULL){
    00838
    00839         schService = OpenService (scmHandle,
    00840             NPFServiceName,
    00841             SERVICE_ALL_ACCESS
    00842             );
    00843
    00844         if (schService != NULL)
    00845         {
    00846
    00847             ret = ControlService (schService,
    00848                 SERVICE_CONTROL_STOP,
    00849                 &serviceStatus
    00850                 );
    00851             if (!ret)
    00852             {
    00853             }
    00854
    00855             CloseServiceHandle (schService);
    00856
    00857             CloseServiceHandle(scmHandle);
    00858
    00859             return ret;
    00860         }
    00861     }
    00862
    00863     return FALSE;
    00864
    00865 }
    00866
    00874 LPADAPTER PacketOpenAdapter(PCHAR AdapterName)
    00875 {
    00876     LPADAPTER lpAdapter;
    00877     WCHAR *AdapterNameU;
    00878     SC_HANDLE svcHandle = NULL;
    00879     PCHAR AdapterNameA = NULL;
    00880 #ifndef _WINNT4
    00881     PADAPTER_INFO TAdInfo;
    00882 #endif // _WINNT4
    00883
    00884     ODSEx("PacketOpenAdapter: trying to open the adapter=%S\n",AdapterName)
    00885
    00886     if(AdapterName[1]!=0){ //ASCII
    00887         AdapterNameU = SChar2WChar(AdapterName);
    00888         AdapterNameA = AdapterName;
    00889         AdapterName = (PCHAR)AdapterNameU;
    00890     } else {            //Unicode
    00891         AdapterNameU = NULL;
    00892         AdapterNameA = WChar2SChar((PWCHAR)AdapterName);
    00893     }
    00894
    00895 #ifndef _WINNT4
    00896
    00897     // Find the PADAPTER_INFO structure associated with this adapter
    00898     TAdInfo = PacketFindAdInfo(AdapterNameA);
    00899     if(TAdInfo == NULL)
    00900     {
    00901         PacketUpdateAdInfo(AdapterNameA);
    00902         TAdInfo = PacketFindAdInfo(AdapterNameA);
    00903         if(TAdInfo == NULL)
    00904         {
    00905             //can be an ERF file?
    00906             lpAdapter = PacketOpenAdapterDAG(AdapterNameA, TRUE);
    00907
    00908             if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU);
    00909             else GlobalFreePtr(AdapterNameA);
    00910
    00911             return lpAdapter;
    00912         }
    00913     }
    00914
    00915     if(TAdInfo->Flags != INFO_FLAG_NDIS_ADAPTER)
    00916     {
    00917         //
    00918         // Not a standard NDIS adapter, we must have specific handling
    00919         //
    00920
    00921         if(TAdInfo->Flags & INFO_FLAG_NDISWAN_ADAPTER)
    00922         {
    00923             //
    00924             // This is a wan adapter. Open it using the netmon API
    00925             //
    00926
    00927             lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,
    00928                 sizeof(ADAPTER));
    00929             if (lpAdapter == NULL)
    00930             {
    00931                 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU);
    00932                 else GlobalFreePtr(AdapterNameA);
    00933                 return NULL;
    00934             }
    00935
    00936             // Backup flags for future usage
    00937             lpAdapter->Flags = TAdInfo->Flags;
    00938
    00939             // Open the adapter
    00940             lpAdapter->pWanAdapter = WanPacketOpenAdapter();
    00941             if (lpAdapter->pWanAdapter == NULL)
    00942             {
    00943                 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU);
    00944                 else GlobalFreePtr(AdapterNameA);
    00945
    00946                 GlobalFreePtr(lpAdapter);
    00947                 return NULL;
    00948             }
    00949
    00950             _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterNameA);
    00951
    00952             lpAdapter->ReadEvent = WanPacketGetReadEvent(lpAdapter->pWanAdapter);
    00953
    00954             if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU);
    00955             else GlobalFreePtr(AdapterNameA);
    00956
    00957             return lpAdapter;
    00958         }
    00959         else
    00960             if(TAdInfo->Flags & INFO_FLAG_DAG_CARD)
    00961             {
    00962                 //
    00963                 // This is a Dag card. Open it using the dagc API
    00964                 //
    00965
    00966                 lpAdapter = PacketOpenAdapterDAG(AdapterNameA, FALSE);
    00967
    00968                 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU);
    00969                 else GlobalFreePtr(AdapterNameA);
    00970
    00971                 return lpAdapter;
    00972             }
    00973
    00974     }
    00975 #endif // _WINNT4
    00976
    00977     lpAdapter = PacketOpenAdapterNPF(AdapterName);
    00978
    00979     if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU);
    00980     else GlobalFreePtr(AdapterNameA);
    00981
    00982     return lpAdapter;
    00983 }
    00984
    00991 VOID PacketCloseAdapter(LPADAPTER lpAdapter)
    00992 {
    00993
    00994 #ifndef _WINNT4
    00995     if (lpAdapter->pWanAdapter != NULL)
    00996     {
    00997         WanPacketCloseAdapter(lpAdapter->pWanAdapter);
    00998         GlobalFreePtr(lpAdapter);
    00999         return;
    01000     }
    01001 #ifdef HAVE_DAG_API
    01002     else
    01003         if(lpAdapter->pDagCard != NULL)
    01004         {
    01005             if(lpAdapter->Flags & INFO_FLAG_DAG_FILE & ~INFO_FLAG_DAG_CARD)
    01006             {
    01007                 // This is a file. We must remove the entry in the adapter description list
    01008                 PacketUpdateAdInfo(lpAdapter->Name);
    01009             }
    01010             p_dagc_close(lpAdapter->pDagCard);
    01011         }
    01012 #endif // HAVE_DAG_API
    01013 #endif // _WINNT4
    01014
    01015     CloseHandle(lpAdapter->hFile);
    01016     SetEvent(lpAdapter->ReadEvent);
    01017     CloseHandle(lpAdapter->ReadEvent);
    01018     GlobalFreePtr(lpAdapter);
    01019 }
    01020
    01033 LPPACKET PacketAllocatePacket(void)
    01034 {
    01035
    01036     LPPACKET    lpPacket;
    01037     lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET));
    01038     if (lpPacket==NULL)
    01039     {
    01040         ODS("PacketAllocatePacket: GlobalAlloc Failed\n");
    01041         return NULL;
    01042     }
    01043     return lpPacket;
    01044 }
    01045
    01054 VOID PacketFreePacket(LPPACKET lpPacket)
    01055
    01056 {
    01057     GlobalFreePtr(lpPacket);
    01058 }
    01059
    01076 VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length)
    01077
    01078 {
    01079     lpPacket->Buffer = Buffer;
    01080     lpPacket->Length = Length;
    01081     lpPacket->ulBytesReceived = 0;
    01082     lpPacket->bIoComplete = FALSE;
    01083 }
    01084
    01115 BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
    01116 {
    01117     BOOLEAN res;
    01118
    01119 #ifndef _WINNT4
    01120
    01121     if (AdapterObject->pWanAdapter != NULL)
    01122     {
    01123         lpPacket->ulBytesReceived = WanPacketReceivePacket(AdapterObject->pWanAdapter, lpPacket->Buffer, lpPacket->Length);
    01124         return TRUE;
    01125     }
    01126 #ifdef HAVE_DAG_API
    01127     else
    01128         if(AdapterObject->pDagCard != NULL)
    01129         {
    01130
    01131             p_dagc_wait(AdapterObject->pDagCard, &AdapterObject->DagReadTimeout);
    01132
    01133             if(p_dagc_receive(AdapterObject->pDagCard, &AdapterObject->DagBuffer, &lpPacket->ulBytesReceived) == 0)
    01134                 return TRUE;
    01135             else
    01136                 return FALSE;
    01137         }
    01138 #endif // HAVE_DAG_API
    01139 #endif // _WINNT4
    01140
    01141     if((int)AdapterObject->ReadTimeOut != -1)
    01142         WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut);
    01143
    01144     res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL);
    01145
    01146     return res;
    01147 }
    01148
    01178 BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
    01179 {
    01180     DWORD        BytesTransfered;
    01181
    01182
    01183 #ifndef _WINNT4
    01184     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01185     {
    01186         ODS("PacketSendPacket: packet sending not allowed on wan adapters\n");
    01187         return FALSE;
    01188     }
    01189 #endif // _WINNT4
    01190
    01191     return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL);
    01192 }
    01193
    01194
    01222 INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync)
    01223 {
    01224     BOOLEAN         Res;
    01225     DWORD           BytesTransfered, TotBytesTransfered=0;
    01226     struct timeval  BufStartTime;
    01227     LARGE_INTEGER   StartTicks, CurTicks, TargetTicks, TimeFreq;
    01228
    01229
    01230     ODS("PacketSendPackets");
    01231
    01232 #ifndef _WINNT4
    01233     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01234     {
    01235         ODS("PacketSendPackets: packet sending not allowed on wan adapters\n");
    01236         return FALSE;
    01237     }
    01238 #endif // _WINNT4
    01239
    01240     // Obtain starting timestamp of the buffer
    01241     BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec;
    01242     BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec;
    01243
    01244     // Retrieve the reference time counters
    01245     QueryPerformanceCounter(&StartTicks);
    01246     QueryPerformanceFrequency(&TimeFreq);
    01247
    01248     CurTicks.QuadPart = StartTicks.QuadPart;
    01249
    01250     do{
    01251         // Send the data to the driver
    01252         Res = DeviceIoControl(AdapterObject->hFile,
    01253             (Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC,
    01254             (PCHAR)PacketBuff + TotBytesTransfered,
    01255             Size - TotBytesTransfered,
    01256             NULL,
    01257             0,
    01258             &BytesTransfered,
    01259             NULL);
    01260
    01261         TotBytesTransfered += BytesTransfered;
    01262
    01263         // calculate the time interval to wait before sending the next packet
    01264         TargetTicks.QuadPart = StartTicks.QuadPart +
    01265         (LONGLONG)
    01266         ((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 +
    01267         (((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) *
    01268         (TimeFreq.QuadPart) / 1000000;
    01269
    01270         // Exit from the loop on termination or error
    01271         if(TotBytesTransfered >= Size || Res != TRUE)
    01272             break;
    01273
    01274         // Wait until the time interval has elapsed
    01275         while( CurTicks.QuadPart <= TargetTicks.QuadPart )
    01276             QueryPerformanceCounter(&CurTicks);
    01277
    01278     }
    01279     while(TRUE);
    01280
    01281     return TotBytesTransfered;
    01282 }
    01283
    01302 BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes)
    01303 {
    01304     DWORD BytesReturned;
    01305
    01306 #ifndef _WINNT4
    01307    if (AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER)
    01308       return WanPacketSetMinToCopy(AdapterObject->pWanAdapter, nbytes);
    01309 #ifdef HAVE_DAG_API
    01310     else
    01311         if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01312             // No mintocopy with DAGs
    01313             return TRUE;
    01314 #endif // HAVE_DAG_API
    01315 #endif // _WINNT4
    01316
    01317    return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL);
    01318 }
    01319
    01356 BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode)
    01357 {
    01358     DWORD BytesReturned;
    01359
    01360 #ifndef _WINNT4
    01361    if (AdapterObject->pWanAdapter != NULL)
    01362       return WanPacketSetMode(AdapterObject->pWanAdapter, mode);
    01363 #endif // _WINNT4
    01364
    01365     return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL);
    01366 }
    01367
    01382 BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len)
    01383 {
    01384     DWORD       BytesReturned;
    01385     WCHAR   *FileName;
    01386     BOOLEAN res;
    01387     WCHAR   NameWithPath[1024];
    01388     int     TStrLen;
    01389     WCHAR   *NamePos;
    01390
    01391 #ifndef _WINNT4
    01392     if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01393     {
    01394         ODS("PacketSetDumpName: not allowed on wan adapters\n");
    01395         return FALSE;
    01396     }
    01397 #endif // _WINNT4
    01398
    01399     if(((PUCHAR)name)[1]!=0 && len>1){ //ASCII
    01400         FileName=SChar2WChar(name);
    01401         len*=2;
    01402     }
    01403     else {  //Unicode
    01404         FileName=name;
    01405     }
    01406
    01407     TStrLen=GetFullPathName(FileName,1024,NameWithPath,&NamePos);
    01408
    01409     len=TStrLen*2+2;  //add the terminating null character
    01410
    01411     // Try to catch malformed strings
    01412     if(len>2048){
    01413         if(((PUCHAR)name)[1]!=0 && len>1) free(FileName);
    01414         return FALSE;
    01415     }
    01416
    01417     res = DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL);
    01418     free(FileName);
    01419     return res;
    01420 }
    01421
    01437 BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks)
    01438 {
    01439     DWORD       BytesReturned;
    01440     UINT valbuff[2];
    01441
    01442 #ifndef _WINNT4
    01443     if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01444     {
    01445         ODS("PacketSetDumpLimits: not allowed on wan adapters\n");
    01446         return FALSE;
    01447     }
    01448 #endif // _WINNT4
    01449
    01450     valbuff[0] = maxfilesize;
    01451     valbuff[1] = maxnpacks;
    01452
    01453     return DeviceIoControl(AdapterObject->hFile,
    01454         pBIOCSETDUMPLIMITS,
    01455         valbuff,
    01456         sizeof valbuff,
    01457         NULL,
    01458         0,
    01459         &BytesReturned,
    01460         NULL);
    01461 }
    01462
    01476 BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync)
    01477 {
    01478     DWORD       BytesReturned;
    01479     int     IsDumpEnded;
    01480     BOOLEAN res;
    01481
    01482 #ifndef _WINNT4
    01483     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01484     {
    01485         ODS("PacketIsDumpEnded: not allowed on wan adapters\n");
    01486         return FALSE;
    01487     }
    01488 #endif // _WINNT4
    01489
    01490     if(sync)
    01491         WaitForSingleObject(AdapterObject->ReadEvent, INFINITE);
    01492
    01493     res = DeviceIoControl(AdapterObject->hFile,
    01494         pBIOCISDUMPENDED,
    01495         NULL,
    01496         0,
    01497         &IsDumpEnded,
    01498         4,
    01499         &BytesReturned,
    01500         NULL);
    01501
    01502     if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished
    01503
    01504     return (BOOLEAN)IsDumpEnded;
    01505 }
    01506
    01526 HANDLE PacketGetReadEvent(LPADAPTER AdapterObject)
    01527 {
    01528     return AdapterObject->ReadEvent;
    01529 }
    01530
    01539 BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)
    01540 {
    01541     DWORD BytesReturned;
    01542
    01543 #ifndef _WINNT4
    01544     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01545     {
    01546         ODS("PacketSetNumWrites: not allowed on wan adapters\n");
    01547         return FALSE;
    01548     }
    01549 #endif // _WINNT4
    01550
    01551     return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL);
    01552 }
    01553
    01566 BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)
    01567 {
    01568     DWORD BytesReturned;
    01569     int DriverTimeOut=-1;
    01570
    01571 #ifndef _WINNT4
    01572    if (AdapterObject->pWanAdapter != NULL)
    01573       return WanPacketSetReadTimeout(AdapterObject->pWanAdapter,timeout);
    01574 #endif // _WINNT4
    01575
    01576     AdapterObject->ReadTimeOut=timeout;
    01577
    01578 #ifdef HAVE_DAG_API
    01579     // Under DAG, we simply store the timeout value and then
    01580     if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01581     {
    01582         if(timeout == 1)
    01583         {
    01584             // tell DAG card to return immediately
    01585             AdapterObject->DagReadTimeout.tv_sec = 0;
    01586             AdapterObject->DagReadTimeout.tv_usec = 0;
    01587         }
    01588         else
    01589             if(timeout == 1)
    01590             {
    01591                 // tell the DAG card to wait forvever
    01592                 AdapterObject->DagReadTimeout.tv_sec = -1;
    01593                 AdapterObject->DagReadTimeout.tv_usec = -1;
    01594             }
    01595             else
    01596             {
    01597                 // Set the timeout for the DAG card
    01598                 AdapterObject->DagReadTimeout.tv_sec = timeout / 1000;
    01599                 AdapterObject->DagReadTimeout.tv_usec = (timeout * 1000) % 1000000;
    01600             }
    01601
    01602             return TRUE;
    01603     }
    01604 #endif // HAVE_DAG_API
    01605
    01606     return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL);
    01607 }
    01608
    01625 BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)
    01626 {
    01627     DWORD BytesReturned;
    01628
    01629 #ifndef _WINNT4
    01630     if (AdapterObject->pWanAdapter != NULL)
    01631         return WanPacketSetBufferSize(AdapterObject->pWanAdapter, dim);
    01632 #ifdef HAVE_DAG_API
    01633     else
    01634         if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01635             // We can't change DAG buffers
    01636             return TRUE;
    01637 #endif // HAVE_DAG_API
    01638
    01639 #endif // _WINNT4
    01640     return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL);
    01641 }
    01642
    01663 BOOLEAN PacketSetBpf(LPADAPTER AdapterObject, struct bpf_program *fp)
    01664 {
    01665     DWORD BytesReturned;
    01666
    01667 #ifndef _WINNT4
    01668    if (AdapterObject->pWanAdapter != NULL)
    01669       return WanPacketSetBpfFilter(AdapterObject->pWanAdapter, (PUCHAR)fp->bf_insns, fp->bf_len * sizeof(struct bpf_insn));
    01670 #ifdef HAVE_DAG_API
    01671     else
    01672         if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01673             // Delegate the filtering to higher layers since it's too expensive here
    01674             return TRUE;
    01675 #endif // HAVE_DAG_API
    01676 #endif // _WINNT4
    01677
    01678    return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL);
    01679 }
    01680
    01695 INT PacketSetSnapLen(LPADAPTER AdapterObject, int snaplen)
    01696 {
    01697
    01698 #ifdef HAVE_DAG_API
    01699     if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01700         return p_dagc_setsnaplen(AdapterObject->pDagCard, snaplen);
    01701     else
    01702 #endif // HAVE_DAG_API
    01703         return 0;
    01704 }
    01705
    01719 BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)
    01720 {
    01721     BOOLEAN Res;
    01722     DWORD BytesReturned;
    01723     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
    01724
    01725 #ifndef _WINNT4
    01726 #ifdef HAVE_DAG_API
    01727     if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01728     {
    01729         dagc_stats_t DagStats;
    01730
    01731         // Note: DAG cards are currently very limited from the statistics reporting point of view,
    01732         // so most of the values returned by dagc_stats() are zero at the moment
    01733         if(p_dagc_stats(AdapterObject->pDagCard, &DagStats) == 0)
    01734         {
    01735             // XXX: Only copy the dropped packets for now, since the received counter is not supported by
    01736             // DAGS at the moment
    01737
    01738             s->bs_recv = (ULONG)DagStats.received;
    01739             s->bs_drop = (ULONG)DagStats.dropped;
    01740             return TRUE;
    01741         }
    01742         else
    01743             return FALSE;
    01744     }
    01745     else
    01746 #endif // HAVE_DAG_API
    01747         if ( AdapterObject->pWanAdapter != NULL)
    01748             Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat);
    01749         else
    01750 #endif // _WINNT4
    01751
    01752             Res = DeviceIoControl(AdapterObject->hFile,
    01753             pBIOCGSTATS,
    01754             NULL,
    01755             0,
    01756             &tmpstat,
    01757             sizeof(struct bpf_stat),
    01758             &BytesReturned,
    01759             NULL);
    01760
    01761
    01762     // Copy only the first two values retrieved from the driver
    01763     s->bs_recv = tmpstat.bs_recv;
    01764     s->bs_drop = tmpstat.bs_drop;
    01765
    01766     return Res;
    01767 }
    01768
    01781 BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s)
    01782 {
    01783     BOOLEAN Res;
    01784     DWORD BytesReturned;
    01785     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
    01786
    01787 #ifndef _WINNT4
    01788 #ifdef HAVE_DAG_API
    01789         if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01790         {
    01791             dagc_stats_t DagStats;
    01792
    01793             // Note: DAG cards are currently very limited from the statistics reporting point of view,
    01794             // so most of the values returned by dagc_stats() are zero at the moment
    01795             p_dagc_stats(AdapterObject->pDagCard, &DagStats);
    01796             s->bs_recv = (ULONG)DagStats.received;
    01797             s->bs_drop = (ULONG)DagStats.dropped;
    01798             s->ps_ifdrop = 0;
    01799             s->bs_capt = (ULONG)DagStats.captured;
    01800         }
    01801 #endif // HAVE_DAG_API
    01802    if(AdapterObject->pWanAdapter != NULL)
    01803         Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat);
    01804     else
    01805 #endif // _WINNT4
    01806
    01807     Res = DeviceIoControl(AdapterObject->hFile,
    01808         pBIOCGSTATS,
    01809         NULL,
    01810         0,
    01811         &tmpstat,
    01812         sizeof(struct bpf_stat),
    01813         &BytesReturned,
    01814         NULL);
    01815
    01816     s->bs_recv = tmpstat.bs_recv;
    01817     s->bs_drop = tmpstat.bs_drop;
    01818     s->ps_ifdrop = tmpstat.ps_ifdrop;
    01819     s->bs_capt = tmpstat.bs_capt;
    01820
    01821     return Res;
    01822 }
    01823
    01836 BOOLEAN PacketRequest(LPADAPTER  AdapterObject,BOOLEAN Set,PPACKET_OID_DATA  OidData)
    01837 {
    01838     DWORD       BytesReturned;
    01839     BOOLEAN     Result;
    01840
    01841 #ifndef _WINNT4
    01842     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01843         return FALSE;
    01844 #endif // _WINNT4
    01845
    01846     Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? (DWORD)pBIOCSETOID : (DWORD)pBIOCQUERYOID,
    01847                            OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData,
    01848                            sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL);
    01849
    01850     // output some debug info
    01851     ODSEx("PacketRequest, OID=%d ", OidData->Oid);
    01852     ODSEx("Length=%d ", OidData->Length);
    01853     ODSEx("Set=%d ", Set);
    01854     ODSEx("Res=%d\n", Result);
    01855
    01856     return Result;
    01857 }
    01858
    01875 BOOLEAN PacketSetHwFilter(LPADAPTER  AdapterObject,ULONG Filter)
    01876 {
    01877     BOOLEAN    Status;
    01878     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
    01879     PPACKET_OID_DATA  OidData;
    01880
    01881 #ifndef _WINNT4
    01882     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01883         return TRUE;
    01884 #endif // _WINNT4
    01885
    01886     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
    01887     if (OidData == NULL) {
    01888         ODS("PacketSetHwFilter: GlobalAlloc Failed\n");
    01889         return FALSE;
    01890     }
    01891     OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER;
    01892     OidData->Length=sizeof(ULONG);
    01893     *((PULONG)OidData->Data)=Filter;
    01894     Status=PacketRequest(AdapterObject,TRUE,OidData);
    01895     GlobalFreePtr(OidData);
    01896     return Status;
    01897 }
    01898
    01920 BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG  BufferSize)
    01921 {
    01922     PADAPTER_INFO   TAdInfo;
    01923     ULONG   SizeNeeded = 1;
    01924     ULONG   SizeNames = 1;
    01925     ULONG   SizeDesc;
    01926     ULONG   OffDescriptions;
    01927
    01928     ODSEx("PacketGetAdapterNames: BufferSize=%d\n", *BufferSize);
    01929
    01930     //
    01931     // Create the adapter information list
    01932     //
    01933     PacketPopulateAdaptersInfoList();
    01934
    01935     if(!AdaptersInfoList){
    01936         *BufferSize = 0;
    01937         return FALSE;       // No adapters to return
    01938     }
    01939
    01940     //
    01941     // First scan of the list to calculate the offsets and check the sizes
    01942     //
    01943     for(TAdInfo = AdaptersInfoList; TAdInfo != NULL; TAdInfo = TAdInfo->Next)
    01944     {
    01945         // Update the size variables
    01946         SizeNeeded += strlen(TAdInfo->Name) + strlen(TAdInfo->Description) + 1;
    01947         SizeNames += strlen(TAdInfo->Name) + 1;
    01948
    01949         // Check not to overflow the buffer
    01950         if(SizeNeeded >= *BufferSize)
    01951         {
    01952             *BufferSize = SizeNeeded;
    01953             ODS("PacketGetAdapterNames: input buffer too small\n");
    01954             return FALSE;
    01955         }
    01956     }
    01957
    01958     OffDescriptions = SizeNames;
    01959
    01960     //
    01961     // Second scan of the list to copy the information
    01962     //
    01963     for(TAdInfo = AdaptersInfoList, SizeNames = 0, SizeDesc = 0; TAdInfo != NULL; TAdInfo = TAdInfo->Next)
    01964     {
    01965         // Copy the data
    01966         strcpy(((PCHAR)pStr) + SizeNames, TAdInfo->Name);
    01967         strcpy(((PCHAR)pStr) + OffDescriptions + SizeDesc, TAdInfo->Description);
    01968
    01969         // Update the size variables
    01970         SizeNames += strlen(TAdInfo->Name) + 1;
    01971         SizeDesc += strlen(TAdInfo->Description) + 1;
    01972     }
    01973
    01974     // Separate the two lists
    01975     ((PCHAR)pStr)[SizeNames] = 0;
    01976
    01977     return TRUE;
    01978 }
    01979
    01993 BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries)
    01994 {
    01995     PADAPTER_INFO TAdInfo;
    01996     PCHAR Tname;
    01997     BOOLEAN Res, FreeBuff;
    01998
    01999     ODS("PacketGetNetInfo\n");
    02000
    02001     // Provide conversion for backward compatibility
    02002     if(AdapterName[1] != 0)
    02003     { //ASCII
    02004         Tname = AdapterName;
    02005         FreeBuff = FALSE;
    02006     }
    02007     else
    02008     {
    02009         Tname = WChar2SChar((PWCHAR)AdapterName);
    02010         FreeBuff = TRUE;
    02011     }
    02012
    02013     //
    02014     // Update the information about this adapter
    02015     //
    02016     if(!PacketUpdateAdInfo(Tname))
    02017     {
    02018         ODS("PacketGetNetInfo: Adapter not found\n");
    02019         if(FreeBuff)GlobalFreePtr(Tname);
    02020         return FALSE;
    02021     }
    02022
    02023     // Find the PADAPTER_INFO structure associated with this adapter
    02024     TAdInfo = PacketFindAdInfo(Tname);
    02025
    02026     if(TAdInfo != NULL)
    02027     {
    02028         *NEntries = (TAdInfo->NNetworkAddresses < *NEntries)? TAdInfo->NNetworkAddresses: *NEntries;
    02029         memcpy(buffer, TAdInfo->NetworkAddresses, *NEntries * sizeof(npf_if_addr));
    02030         Res = TRUE;
    02031     }
    02032     else
    02033     {
    02034         ODS("PacketGetNetInfo: Adapter not found\n");
    02035         Res = FALSE;
    02036     }
    02037
    02038     if(FreeBuff)GlobalFreePtr(Tname);
    02039
    02040     return Res;
    02041 }
    02042
    02059 BOOLEAN PacketGetNetType(LPADAPTER AdapterObject, NetType *type)
    02060 {
    02061     PADAPTER_INFO TAdInfo;
    02062
    02063     ODS("PacketGetNetType\n");
    02064
    02065     // Find the PADAPTER_INFO structure associated with this adapter
    02066     TAdInfo = PacketFindAdInfo(AdapterObject->Name);
    02067
    02068     if(TAdInfo != NULL)
    02069     {
    02070         // Copy the data
    02071         memcpy(type, &(TAdInfo->LinkLayer), sizeof(struct NetType));
    02072     }
    02073     else
    02074     {
    02075         ODS("PacketGetNetType: Adapter not found\n");
    02076         return FALSE;
    02077     }
    02078
    02079     return TRUE;
    02080 }
    02081
    02082 /* @} */

documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.