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
    00042 //service handles
    00043 SC_HANDLE scmHandle = NULL;
    00044 SC_HANDLE srvHandle = NULL;
    00045 LPCTSTR NPFServiceName = TEXT("NPF");
    00046 LPCTSTR NPFServiceDesc = TEXT("Netgroup Packet Filter");
    00047 LPCTSTR NPFRegistryLocation = TEXT("SYSTEM\\CurrentControlSet\\Services\\NPF");
    00048 LPCTSTR NPFDriverPath = TEXT("system32\\drivers\\npf.sys");
    00049
    00050 extern PADAPTER_INFO AdaptersInfoList;
    00051 extern HANDLE AdaptersInfoMutex;
    00052 #ifndef _WINNT4
    00053 typedef VOID (*GAAHandler)(
    00054   ULONG,
    00055   DWORD,
    00056   PVOID,
    00057   PIP_ADAPTER_ADDRESSES,
    00058   PULONG);
    00059 GAAHandler GetAdaptersAddressesPointer = NULL;
    00060 #endif // _WINNT4
    00061
    00062 #ifdef HAVE_DAG_API
    00063 /* We load dinamically the dag library in order link it only when it's present on the system */
    00064 dagc_open_handler p_dagc_open = NULL;
    00065 dagc_close_handler p_dagc_close = NULL;
    00066 dagc_getlinktype_handler p_dagc_getlinktype = NULL;
    00067 dagc_getlinkspeed_handler p_dagc_getlinkspeed = NULL;
    00068 dagc_getfcslen_handler p_dagc_getfcslen = NULL;
    00069 dagc_receive_handler p_dagc_receive = NULL;
    00070 dagc_wait_handler p_dagc_wait = NULL;
    00071 dagc_stats_handler p_dagc_stats = NULL;
    00072 dagc_setsnaplen_handler p_dagc_setsnaplen = NULL;
    00073 dagc_finddevs_handler p_dagc_finddevs = NULL;
    00074 dagc_freedevs_handler p_dagc_freedevs = NULL;
    00075 #endif /* HAVE_DAG_API */
    00076
    00077 BOOLEAN PacketAddAdapterDag(PCHAR name, PCHAR description, BOOLEAN IsAFile);
    00078
    00079 //---------------------------------------------------------------------------
    00080
    00085 BOOL APIENTRY DllMain (HANDLE DllHandle,DWORD Reason,LPVOID lpReserved)
    00086 {
    00087     BOOLEAN Status=TRUE;
    00088     HMODULE IPHMod;
    00089 #ifdef HAVE_DAG_API
    00090     HMODULE DagcLib;
    00091 #endif // HAVE_DAG_API
    00092
    00093     switch(Reason)
    00094     {
    00095     case DLL_PROCESS_ATTACH:
    00096
    00097         ODS("************Packet32: DllMain************\n");
    00098
    00099 #ifdef _DEBUG_TO_FILE
    00100         // dump a bunch of registry keys useful for debug to file
    00101         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",
    00102             "adapters.reg");
    00103         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip",
    00104             "tcpip.reg");
    00105         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\NPF",
    00106             "npf.reg");
    00107         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services",
    00108             "services.reg");
    00109 #endif
    00110
    00111         // Create the mutex that will protect the adapter information list
    00112         AdaptersInfoMutex = CreateMutex(NULL, FALSE, NULL);
    00113
    00114         //
    00115         // Retrieve packet.dll version information from the file
    00116         //
    00117         PacketGetFileVersion(TEXT("packet.dll"), PacketLibraryVersion, sizeof(PacketLibraryVersion));
    00118
    00119         //
    00120         // Retrieve NPF.sys version information from the file
    00121         //
    00122         PacketGetFileVersion(TEXT("drivers\\npf.sys"), PacketDriverVersion, sizeof(PacketDriverVersion));
    00123
    00124         //
    00125         // Locate GetAdaptersAddresses dinamically since it is not present in Win2k
    00126         //
    00127         IPHMod = GetModuleHandle(TEXT("Iphlpapi"));
    00128
    00129 #ifndef _WINNT4
    00130         GetAdaptersAddressesPointer = (GAAHandler) GetProcAddress(IPHMod ,"GetAdaptersAddresses");
    00131 #endif // _WINNT4
    00132
    00133 #ifdef HAVE_DAG_API
    00134         /* We load dinamically the dag library in order link it only when it's present on the system */
    00135         if((DagcLib =  LoadLibrary(TEXT("dagc.dll"))) == NULL)
    00136         {
    00137             // Report the error but go on
    00138             ODS("dag capture library not found on this system\n");
    00139             break;
    00140         }
    00141
    00142         p_dagc_open = (dagc_open_handler) GetProcAddress(DagcLib, "dagc_open");
    00143         p_dagc_close = (dagc_close_handler) GetProcAddress(DagcLib, "dagc_close");
    00144         p_dagc_setsnaplen = (dagc_setsnaplen_handler) GetProcAddress(DagcLib, "dagc_setsnaplen");
    00145         p_dagc_getlinktype = (dagc_getlinktype_handler) GetProcAddress(DagcLib, "dagc_getlinktype");
    00146         p_dagc_getlinkspeed = (dagc_getlinkspeed_handler) GetProcAddress(DagcLib, "dagc_getlinkspeed");
    00147         p_dagc_getfcslen = (dagc_getfcslen_handler) GetProcAddress(DagcLib, "dagc_getfcslen");
    00148         p_dagc_receive = (dagc_receive_handler) GetProcAddress(DagcLib, "dagc_receive");
    00149         p_dagc_wait = (dagc_wait_handler) GetProcAddress(DagcLib, "dagc_wait");
    00150         p_dagc_stats = (dagc_stats_handler) GetProcAddress(DagcLib, "dagc_stats");
    00151         p_dagc_finddevs = (dagc_finddevs_handler) GetProcAddress(DagcLib, "dagc_finddevs");
    00152         p_dagc_freedevs = (dagc_freedevs_handler) GetProcAddress(DagcLib, "dagc_freedevs");
    00153
    00154 #endif /* HAVE_DAG_API */
    00155
    00156         break;
    00157
    00158         case DLL_PROCESS_DETACH:
    00159
    00160             CloseHandle(AdaptersInfoMutex);
    00161
    00162             break;
    00163
    00164         default:
    00165             break;
    00166     }
    00167
    00168     return Status;
    00169 }
    00170
    00179 ULONG inet_addrU(const WCHAR *cp)
    00180 {
    00181     ULONG val, part;
    00182     WCHAR c;
    00183     int i;
    00184
    00185     val = 0;
    00186     for (i = 0; i < 4; i++) {
    00187         part = 0;
    00188         while ((c = *cp++) != '\0' && c != '.') {
    00189             if (c < '0' || c > '9')
    00190                 return -1;
    00191             part = part*10 + (c - '0');
    00192         }
    00193         if (part > 255)
    00194             return -1;
    00195         val = val | (part << i*8);
    00196         if (i == 3) {
    00197             if (c != '\0')
    00198                 return -1;  // extra gunk at end of string
    00199         } else {
    00200             if (c == '\0')
    00201                 return -1;  // string ends early
    00202         }
    00203     }
    00204     return val;
    00205 }
    00206
    00213 PWCHAR SChar2WChar(PCHAR string)
    00214 {
    00215     PWCHAR TmpStr;
    00216     TmpStr = (WCHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (strlen(string)+2)*sizeof(WCHAR));
    00217
    00218     MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (strlen(string)+2));
    00219
    00220     return TmpStr;
    00221 }
    00222
    00229 PCHAR WChar2SChar(PWCHAR string)
    00230 {
    00231     PCHAR TmpStr;
    00232     TmpStr = (CHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (wcslen(string)+2));
    00233
    00234     // Conver to ASCII
    00235     WideCharToMultiByte(
    00236         CP_ACP,
    00237         0,
    00238         string,
    00239         -1,
    00240         TmpStr,
    00241         (wcslen(string)+2),          // size of buffer
    00242         NULL,
    00243         NULL);
    00244
    00245     return TmpStr;
    00246 }
    00247
    00257 BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject)
    00258 {
    00259     BOOLEAN    Status;
    00260     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
    00261     PPACKET_OID_DATA  OidData;
    00262
    00263     OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
    00264     if (OidData == NULL) {
    00265         ODS("PacketSetMaxLookaheadsize failed\n");
    00266         return FALSE;
    00267     }
    00268
    00269     //set the size of the lookahead buffer to the maximum available by the the NIC driver
    00270     OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD;
    00271     OidData->Length=sizeof(ULONG);
    00272     Status=PacketRequest(AdapterObject,FALSE,OidData);
    00273     OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD;
    00274     Status=PacketRequest(AdapterObject,TRUE,OidData);
    00275     GlobalFreePtr(OidData);
    00276     return Status;
    00277 }
    00278
    00289 BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject)
    00290 {
    00291     DWORD BytesReturned;
    00292     TCHAR EventName[39];
    00293
    00294     // this tells the terminal service to retrieve the event from the global namespace
    00295     wcsncpy(EventName,L"Global\\",sizeof(L"Global\\"));
    00296
    00297     // retrieve the name of the shared event from the driver
    00298     if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName+7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) return FALSE;
    00299
    00300     EventName[20]=0; // terminate the string
    00301
    00302     // open the shared event
    00303     AdapterObject->ReadEvent=CreateEvent(NULL,
    00304                                          TRUE,
    00305                                          FALSE,
    00306                                          EventName);
    00307
    00308     // in NT4 "Global\" is not automatically ignored: try to use simply the event name
    00309     if(GetLastError()!=ERROR_ALREADY_EXISTS){
    00310         if(AdapterObject->ReadEvent != NULL)
    00311             CloseHandle(AdapterObject->ReadEvent);
    00312
    00313         // open the shared event
    00314         AdapterObject->ReadEvent=CreateEvent(NULL,
    00315             TRUE,
    00316             FALSE,
    00317             EventName+7);
    00318     }
    00319
    00320     if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){
    00321         ODS("PacketSetReadEvt: error retrieving the event from the kernel\n");
    00322         return FALSE;
    00323     }
    00324
    00325     AdapterObject->ReadTimeOut=0;
    00326
    00327     return TRUE;
    00328 }
    00329
    00339 BOOL PacketInstallDriver(SC_HANDLE ascmHandle,SC_HANDLE *srvHandle)
    00340 {
    00341     BOOL result = FALSE;
    00342     ULONG err = 0;
    00343
    00344     ODS("installdriver\n");
    00345
    00346     *srvHandle = CreateService(ascmHandle,
    00347         NPFServiceName,
    00348         NPFServiceDesc,
    00349         SERVICE_ALL_ACCESS,
    00350         SERVICE_KERNEL_DRIVER,
    00351         SERVICE_DEMAND_START,
    00352         SERVICE_ERROR_NORMAL,
    00353         NPFDriverPath,
    00354         NULL, NULL, NULL, NULL, NULL);
    00355     if (*srvHandle == NULL)
    00356     {
    00357         if (GetLastError() == ERROR_SERVICE_EXISTS)
    00358         {
    00359             //npf.sys already existed
    00360             result = TRUE;
    00361         }
    00362     }
    00363     else
    00364     {
    00365         //Created service for npf.sys
    00366         result = TRUE;
    00367     }
    00368     if (result == TRUE)
    00369         if (*srvHandle != NULL)
    00370             CloseServiceHandle(*srvHandle);
    00371
    00372     if(result == FALSE){
    00373         err = GetLastError();
    00374         if(err != 2)
    00375             ODSEx("PacketInstallDriver failed, Error=%d\n",err);
    00376     }
    00377
    00378     SetLastError(err);
    00379     return result;
    00380
    00381 }
    00382
    00392 #ifdef _DEBUG_TO_FILE
    00393
    00394 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName)
    00395 {
    00396     CHAR Command[256];
    00397
    00398     strcpy(Command, "regedit /e ");
    00399     strcat(Command, FileName);
    00400     strcat(Command, " ");
    00401     strcat(Command, KeyName);
    00402
    00404     system(Command);
    00405
    00406     return TRUE;
    00407 }
    00408 #endif
    00409
    00419 BOOL PacketGetFileVersion(LPTSTR FileName, PCHAR VersionBuff, UINT VersionBuffLen)
    00420 {
    00421     DWORD   dwVerInfoSize;  // Size of version information block
    00422     DWORD   dwVerHnd=0;   // An 'ignored' parameter, always '0'
    00423     LPSTR   lpstrVffInfo;
    00424     UINT    cbTranslate, dwBytes;
    00425     TCHAR   SubBlock[64];
    00426     PVOID   lpBuffer;
    00427     PCHAR   TmpStr;
    00428
    00429     // Structure used to store enumerated languages and code pages.
    00430     struct LANGANDCODEPAGE {
    00431       WORD wLanguage;
    00432       WORD wCodePage;
    00433     } *lpTranslate;
    00434
    00435     ODS("PacketGetFileVersion\n");
    00436
    00437     // Now lets dive in and pull out the version information:
    00438     dwVerInfoSize = GetFileVersionInfoSize(FileName, &dwVerHnd);
    00439     if (dwVerInfoSize)
    00440     {
    00441         lpstrVffInfo = GlobalAllocPtr(GMEM_MOVEABLE, dwVerInfoSize);
    00442         if (lpstrVffInfo == NULL)
    00443         {
    00444             ODS("PacketGetFileVersion: failed to allocate memory\n");
    00445             return FALSE;
    00446         }
    00447
    00448         if(!GetFileVersionInfo(FileName, dwVerHnd, dwVerInfoSize, lpstrVffInfo))
    00449         {
    00450             ODS("PacketGetFileVersion: failed to call GetFileVersionInfo\n");
    00451             GlobalFreePtr(lpstrVffInfo);
    00452             return FALSE;
    00453         }
    00454
    00455         // Read the list of languages and code pages.
    00456         if(!VerQueryValue(lpstrVffInfo, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate))
    00457         {
    00458             ODS("PacketGetFileVersion: failed to call VerQueryValue\n");
    00459             GlobalFreePtr(lpstrVffInfo);
    00460             return FALSE;
    00461         }
    00462
    00463         // Create the file version string for the first (i.e. the only one) language.
    00464         wsprintf( SubBlock,
    00465             TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"),
    00466             (*lpTranslate).wLanguage,
    00467             (*lpTranslate).wCodePage);
    00468
    00469         // Retrieve the file version string for the language.
    00470         if(!VerQueryValue(lpstrVffInfo, SubBlock, &lpBuffer, &dwBytes))
    00471         {
    00472             ODS("PacketGetFileVersion: failed to call VerQueryValue\n");
    00473             GlobalFreePtr(lpstrVffInfo);
    00474             return FALSE;
    00475         }
    00476
    00477         // Convert to ASCII
    00478         TmpStr = WChar2SChar(lpBuffer);
    00479
    00480         if(strlen(TmpStr) >= VersionBuffLen)
    00481         {
    00482             ODS("PacketGetFileVersion: Input buffer too small\n");
    00483             GlobalFreePtr(lpstrVffInfo);
    00484             GlobalFreePtr(TmpStr);
    00485             return FALSE;
    00486         }
    00487
    00488         strcpy(VersionBuff, TmpStr);
    00489
    00490         GlobalFreePtr(TmpStr);
    00491
    00492       }
    00493     else
    00494     {
    00495         ODSEx("PacketGetFileVersion: failed to call GetFileVersionInfoSize, LastError = %d\n", GetLastError());
    00496         return FALSE;
    00497
    00498     }
    00499
    00500     return TRUE;
    00501 }
    00502
    00511 LPADAPTER PacketOpenAdapterNPF(PCHAR AdapterName)
    00512 {
    00513     LPADAPTER lpAdapter;
    00514     BOOLEAN Result;
    00515     DWORD error;
    00516     SC_HANDLE svcHandle = NULL;
    00517     LONG KeyRes;
    00518     HKEY PathKey;
    00519     SERVICE_STATUS SStat;
    00520     BOOLEAN QuerySStat;
    00521     WCHAR SymbolicLink[128];
    00522
    00523     ODS("PacketOpenAdapterNPF\n");
    00524
    00525     scmHandle = OpenSCManager(NULL, NULL, GENERIC_READ);
    00526
    00527     if(scmHandle == NULL){
    00528         error = GetLastError();
    00529         ODSEx("OpenSCManager failed! LastError=%d\n", error);
    00530     }
    00531     else{
    00532         // check if the NPF registry key is already present
    00533         // this means that the driver is already installed and that we don't need to call PacketInstallDriver
    00534         KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    00535             NPFRegistryLocation,
    00536             0,
    00537             KEY_READ,
    00538             &PathKey);
    00539
    00540         if(KeyRes != ERROR_SUCCESS)
    00541         {
    00542             Result = PacketInstallDriver(scmHandle,&svcHandle);
    00543         }
    00544         else
    00545         {
    00546             Result = TRUE;
    00547             RegCloseKey(PathKey);
    00548         }
    00549
    00550         if (Result)
    00551         {
    00552
    00553             srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS );
    00554             if (srvHandle != NULL)
    00555             {
    00556                 QuerySStat = QueryServiceStatus(srvHandle, &SStat);
    00557
    00558 #if defined(_DBG) || defined(_DEBUG_TO_FILE)
    00559                 switch (SStat.dwCurrentState)
    00560                 {
    00561                 case SERVICE_CONTINUE_PENDING:
    00562                     ODS("The status of the driver is: SERVICE_CONTINUE_PENDING\n");
    00563                     break;
    00564                 case SERVICE_PAUSE_PENDING:
    00565                     ODS("The status of the driver is: SERVICE_PAUSE_PENDING\n");
    00566                     break;
    00567                 case SERVICE_PAUSED:
    00568                     ODS("The status of the driver is: SERVICE_PAUSED\n");
    00569                     break;
    00570                 case SERVICE_RUNNING:
    00571                     ODS("The status of the driver is: SERVICE_RUNNING\n");
    00572                     break;
    00573                 case SERVICE_START_PENDING:
    00574                     ODS("The status of the driver is: SERVICE_START_PENDING\n");
    00575                     break;
    00576                 case SERVICE_STOP_PENDING:
    00577                     ODS("The status of the driver is: SERVICE_STOP_PENDING\n");
    00578                     break;
    00579                 case SERVICE_STOPPED:
    00580                     ODS("The status of the driver is: SERVICE_STOPPED\n");
    00581                     break;
    00582
    00583                 default:
    00584                     ODS("The status of the driver is: unknown\n");
    00585                     break;
    00586                 }
    00587 #endif
    00588
    00589                 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING)
    00590                 {
    00591                     ODS("Calling startservice\n");
    00592                     if (StartService(srvHandle, 0, NULL)==0)
    00593                     {
    00594                         error = GetLastError();
    00595                         if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS)
    00596                         {
    00597                             SetLastError(error);
    00598                             if (scmHandle != NULL)
    00599                                 CloseServiceHandle(scmHandle);
    00600                             error = GetLastError();
    00601                             ODSEx("PacketOpenAdapterNPF: StartService failed, LastError=%d\n",error);
    00602                             SetLastError(error);
    00603                             return NULL;
    00604                         }
    00605                     }
    00606                 }
    00607
    00608                 CloseServiceHandle( srvHandle );
    00609                 srvHandle = NULL;
    00610
    00611             }
    00612             else
    00613             {
    00614                 error = GetLastError();
    00615                 ODSEx("OpenService failed! Error=%d", error);
    00616                 SetLastError(error);
    00617             }
    00618         }
    00619         else
    00620         {
    00621             if(KeyRes != ERROR_SUCCESS)
    00622                 Result = PacketInstallDriver(scmHandle,&svcHandle);
    00623             else
    00624                 Result = TRUE;
    00625
    00626             if (Result) {
    00627
    00628                 srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START);
    00629                 if (srvHandle != NULL)
    00630                 {
    00631
    00632                     QuerySStat = QueryServiceStatus(srvHandle, &SStat);
    00633
    00634 #if defined(_DBG) || defined(_DEBUG_TO_FILE)
    00635                     switch (SStat.dwCurrentState)
    00636                     {
    00637                     case SERVICE_CONTINUE_PENDING:
    00638                         ODS("The status of the driver is: SERVICE_CONTINUE_PENDING\n");
    00639                         break;
    00640                     case SERVICE_PAUSE_PENDING:
    00641                         ODS("The status of the driver is: SERVICE_PAUSE_PENDING\n");
    00642                         break;
    00643                     case SERVICE_PAUSED:
    00644                         ODS("The status of the driver is: SERVICE_PAUSED\n");
    00645                         break;
    00646                     case SERVICE_RUNNING:
    00647                         ODS("The status of the driver is: SERVICE_RUNNING\n");
    00648                         break;
    00649                     case SERVICE_START_PENDING:
    00650                         ODS("The status of the driver is: SERVICE_START_PENDING\n");
    00651                         break;
    00652                     case SERVICE_STOP_PENDING:
    00653                         ODS("The status of the driver is: SERVICE_STOP_PENDING\n");
    00654                         break;
    00655                     case SERVICE_STOPPED:
    00656                         ODS("The status of the driver is: SERVICE_STOPPED\n");
    00657                         break;
    00658
    00659                     default:
    00660                         ODS("The status of the driver is: unknown\n");
    00661                         break;
    00662                     }
    00663 #endif
    00664
    00665                     if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){
    00666
    00667                         ODS("Calling startservice\n");
    00668
    00669                         if (StartService(srvHandle, 0, NULL)==0){
    00670                             error = GetLastError();
    00671                             if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){
    00672                                 if (scmHandle != NULL) CloseServiceHandle(scmHandle);
    00673                                 ODSEx("PacketOpenAdapterNPF: StartService failed, LastError=%d\n",error);
    00674                                 SetLastError(error);
    00675                                 return NULL;
    00676                             }
    00677                         }
    00678                     }
    00679
    00680                     CloseServiceHandle( srvHandle );
    00681                     srvHandle = NULL;
    00682
    00683                 }
    00684                 else{
    00685                     error = GetLastError();
    00686                     ODSEx("OpenService failed! LastError=%d", error);
    00687                     SetLastError(error);
    00688                 }
    00689             }
    00690         }
    00691     }
    00692
    00693     if (scmHandle != NULL) CloseServiceHandle(scmHandle);
    00694
    00695     lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER));
    00696     if (lpAdapter==NULL)
    00697     {
    00698         ODS("PacketOpenAdapterNPF: GlobalAlloc Failed\n");
    00699         error=GetLastError();
    00700         //set the error to the one on which we failed
    00701         SetLastError(error);
    00702         ODS("PacketOpenAdapterNPF: Failed to allocate the adapter structure\n");
    00703         return NULL;
    00704     }
    00705     lpAdapter->NumWrites=1;
    00706
    00707     wsprintf(SymbolicLink, TEXT("\\\\.\\%s"), &AdapterName[16]);
    00708
    00709     // Copy  only the bytes that fit in the adapter structure.
    00710     // Note that lpAdapter->SymbolicLink is present for backward compatibility but will
    00711     // never be used by the apps
    00712     memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH);
    00713
    00714     //try if it is possible to open the adapter immediately
    00715     lpAdapter->hFile=CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ,
    00716         0,NULL,OPEN_EXISTING,0,0);
    00717
    00718     if (lpAdapter->hFile != INVALID_HANDLE_VALUE)
    00719     {
    00720
    00721         if(PacketSetReadEvt(lpAdapter)==FALSE){
    00722             error=GetLastError();
    00723             ODS("PacketOpenAdapterNPF: Unable to open the read event\n");
    00724             GlobalFreePtr(lpAdapter);
    00725             //set the error to the one on which we failed
    00726             SetLastError(error);
    00727             ODSEx("PacketOpenAdapterNPF: PacketSetReadEvt failed, LastError=%d\n",error);
    00728             return NULL;
    00729         }
    00730
    00731         PacketSetMaxLookaheadsize(lpAdapter);
    00732
    00733         _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%S", AdapterName);
    00734
    00735         return lpAdapter;
    00736     }
    00737
    00738
    00739     error=GetLastError();
    00740     GlobalFreePtr(lpAdapter);
    00741     //set the error to the one on which we failed
    00742     ODSEx("PacketOpenAdapterNPF: CreateFile failed, LastError= %d\n",error);
    00743     SetLastError(error);
    00744     return NULL;
    00745 }
    00746
    00755 #ifdef HAVE_DAG_API
    00756 LPADAPTER PacketOpenAdapterDAG(PCHAR AdapterName, BOOLEAN IsAFile)
    00757 {
    00758     CHAR DagEbuf[DAGC_ERRBUF_SIZE];
    00759     LPADAPTER lpAdapter;
    00760     LONG    status;
    00761     HKEY dagkey;
    00762     DWORD lptype;
    00763     DWORD fpc;
    00764     DWORD lpcbdata = sizeof(fpc);
    00765     WCHAR keyname[512];
    00766     PWCHAR tsn;
    00767
    00768
    00769     lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,
    00770         sizeof(ADAPTER));
    00771     if (lpAdapter == NULL)
    00772     {
    00773         return NULL;
    00774     }
    00775
    00776     if(IsAFile)
    00777     {
    00778         // We must add an entry to the adapter description list, otherwise many function will not
    00779         // be able to work
    00780         if(!PacketAddAdapterDag(AdapterName, "DAG file", IsAFile))
    00781         {
    00782             GlobalFreePtr(lpAdapter);
    00783             return NULL;
    00784         }
    00785
    00786         // Flag that this is a DAG file
    00787         lpAdapter->Flags = INFO_FLAG_DAG_FILE;
    00788     }
    00789     else
    00790     {
    00791         // Flag that this is a DAG card
    00792         lpAdapter->Flags = INFO_FLAG_DAG_CARD;
    00793     }
    00794
    00795     //
    00796     // See if the user is asking for fast capture with this device
    00797     //
    00798
    00799     lpAdapter->DagFastProcess = FALSE;
    00800
    00801     tsn = (strstr(strlwr((char*)AdapterName), "dag") != NULL)?
    00802         SChar2WChar(strstr(strlwr((char*)AdapterName), "dag")):
    00803         L"";
    00804
    00805     _snwprintf(keyname, sizeof(keyname), L"%s\\CardParams\\%ws",
    00806         L"SYSTEM\\CurrentControlSet\\Services\\DAG",
    00807         tsn);
    00808
    00809     GlobalFreePtr(tsn);
    00810
    00811     do
    00812     {
    00813         status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0 , KEY_READ, &dagkey);
    00814         if(status != ERROR_SUCCESS)
    00815             break;
    00816
    00817         status = RegQueryValueEx(dagkey,
    00818             L"FastCap",
    00819             NULL,
    00820             &lptype,
    00821             (char*)&fpc,
    00822             &lpcbdata);
    00823
    00824         if(status == ERROR_SUCCESS)
    00825             lpAdapter->DagFastProcess = fpc;
    00826
    00827         RegCloseKey(dagkey);
    00828     }
    00829     while(FALSE);
    00830
    00831     //
    00832     // Open the card
    00833     //
    00834     lpAdapter->pDagCard = p_dagc_open(AdapterName,
    00835      0,
    00836      DagEbuf);
    00837
    00838     if(lpAdapter->pDagCard == NULL)
    00839     {
    00840         GlobalFreePtr(lpAdapter);
    00841         return NULL;
    00842     }
    00843
    00844     lpAdapter->DagFcsLen = p_dagc_getfcslen(lpAdapter->pDagCard);
    00845
    00846     _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterName);
    00847
    00848     // XXX we could create the read event here
    00849
    00850     return lpAdapter;
    00851 }
    00852 #endif // HAVE_DAG_API
    00853
    00854 //---------------------------------------------------------------------------
    00855 // PUBLIC API
    00856 //---------------------------------------------------------------------------
    00857
    00870 PCHAR PacketGetVersion()
    00871 {
    00872     return PacketLibraryVersion;
    00873 }
    00874
    00879 PCHAR PacketGetDriverVersion()
    00880 {
    00881     return PacketDriverVersion;
    00882 }
    00883
    00892 BOOL PacketStopDriver()
    00893 {
    00894     SC_HANDLE       scmHandle;
    00895     SC_HANDLE       schService;
    00896     BOOL            ret;
    00897     SERVICE_STATUS  serviceStatus;
    00898
    00899     scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    00900
    00901     if(scmHandle != NULL){
    00902
    00903         schService = OpenService (scmHandle,
    00904             NPFServiceName,
    00905             SERVICE_ALL_ACCESS
    00906             );
    00907
    00908         if (schService != NULL)
    00909         {
    00910
    00911             ret = ControlService (schService,
    00912                 SERVICE_CONTROL_STOP,
    00913                 &serviceStatus
    00914                 );
    00915             if (!ret)
    00916             {
    00917             }
    00918
    00919             CloseServiceHandle (schService);
    00920
    00921             CloseServiceHandle(scmHandle);
    00922
    00923             return ret;
    00924         }
    00925     }
    00926
    00927     return FALSE;
    00928
    00929 }
    00930
    00938 LPADAPTER PacketOpenAdapter(PCHAR AdapterName)
    00939 {
    00940     LPADAPTER lpAdapter;
    00941     WCHAR *AdapterNameU;
    00942     SC_HANDLE svcHandle = NULL;
    00943     PCHAR AdapterNameA = NULL;
    00944 #ifndef _WINNT4
    00945     PADAPTER_INFO TAdInfo;
    00946 #endif // _WINNT4
    00947
    00948     ODSEx("PacketOpenAdapter: trying to open the adapter=%s\n",AdapterName)
    00949
    00950     if(AdapterName[1]!=0){ //ASCII
    00951
    00952         AdapterNameU = SChar2WChar(AdapterName);
    00953         AdapterNameA = AdapterName;
    00954         AdapterName = (PCHAR)AdapterNameU;
    00955     } else {            //Unicode
    00956         AdapterNameU = NULL;
    00957         AdapterNameA = WChar2SChar((PWCHAR)AdapterName);
    00958     }
    00959
    00960 #ifndef _WINNT4
    00961
    00962     WaitForSingleObject(AdaptersInfoMutex, INFINITE);
    00963     // Find the PADAPTER_INFO structure associated with this adapter
    00964     TAdInfo = PacketFindAdInfo(AdapterNameA);
    00965     if(TAdInfo == NULL)
    00966     {
    00967         PacketUpdateAdInfo(AdapterNameA);
    00968         TAdInfo = PacketFindAdInfo(AdapterNameA);
    00969         if(TAdInfo == NULL)
    00970         {
    00971
    00972             //can be an ERF file?
    00973             lpAdapter = PacketOpenAdapterDAG(AdapterNameA, TRUE);
    00974
    00975             if (AdapterNameU != NULL)
    00976                 GlobalFreePtr(AdapterNameU);
    00977             else
    00978                 GlobalFreePtr(AdapterNameA);
    00979
    00980             ReleaseMutex(AdaptersInfoMutex);
    00981             if (lpAdapter == NULL)
    00982                 SetLastError(ERROR_BAD_UNIT); //this is the best we can do....
    00983             return lpAdapter;
    00984         }
    00985     }
    00986
    00987     if(TAdInfo->Flags != INFO_FLAG_NDIS_ADAPTER)
    00988     {
    00989         //
    00990         // Not a standard NDIS adapter, we must have specific handling
    00991         //
    00992
    00993
    00994         if(TAdInfo->Flags & INFO_FLAG_NDISWAN_ADAPTER)
    00995         {
    00996             //
    00997             // This is a wan adapter. Open it using the netmon API
    00998             //
    00999
    01000             lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,
    01001                 sizeof(ADAPTER));
    01002             if (lpAdapter == NULL)
    01003             {
    01004                 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU);
    01005                 else GlobalFreePtr(AdapterNameA);
    01006                 ReleaseMutex(AdaptersInfoMutex);
    01007                 SetLastError(ERROR_BAD_UNIT);
    01008                 return NULL;
    01009             }
    01010
    01011             // Backup flags for future usage
    01012             lpAdapter->Flags = TAdInfo->Flags;
    01013
    01014             // Open the adapter
    01015             lpAdapter->pWanAdapter = WanPacketOpenAdapter();
    01016             if (lpAdapter->pWanAdapter == NULL)
    01017             {
    01018                 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU);
    01019                 else GlobalFreePtr(AdapterNameA);
    01020
    01021                 GlobalFreePtr(lpAdapter);
    01022                 ReleaseMutex(AdaptersInfoMutex);
    01023                 SetLastError(ERROR_BAD_UNIT);
    01024                 return NULL;
    01025             }
    01026
    01027             _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterNameA);
    01028
    01029             lpAdapter->ReadEvent = WanPacketGetReadEvent(lpAdapter->pWanAdapter);
    01030
    01031             if (AdapterNameU != NULL)
    01032                 GlobalFreePtr(AdapterNameU);
    01033             else
    01034                 GlobalFreePtr(AdapterNameA);
    01035
    01036             ReleaseMutex(AdaptersInfoMutex);
    01037             return lpAdapter;
    01038         }
    01039         else
    01040             if(TAdInfo->Flags & INFO_FLAG_DAG_CARD)
    01041             {
    01042                 //
    01043                 // This is a Dag card. Open it using the dagc API
    01044                 //
    01045
    01046                 lpAdapter = PacketOpenAdapterDAG(AdapterNameA, FALSE);
    01047
    01048                 if (AdapterNameU != NULL)
    01049                     GlobalFreePtr(AdapterNameU);
    01050                 else
    01051                     GlobalFreePtr(AdapterNameA);
    01052
    01053                 ReleaseMutex(AdaptersInfoMutex);
    01054                 if (lpAdapter == NULL)
    01055                     SetLastError(ERROR_BAD_UNIT);
    01056                 return lpAdapter;
    01057             }
    01058
    01059     }
    01060
    01061     ReleaseMutex(AdaptersInfoMutex);
    01062
    01063 #endif // _WINNT4
    01064
    01065     lpAdapter = PacketOpenAdapterNPF(AdapterName);
    01066
    01067     if (AdapterNameU != NULL)
    01068         GlobalFreePtr(AdapterNameU);
    01069     else
    01070         GlobalFreePtr(AdapterNameA);
    01071
    01072     return lpAdapter;
    01073 }
    01074
    01081 VOID PacketCloseAdapter(LPADAPTER lpAdapter)
    01082 {
    01083
    01084 #ifndef _WINNT4
    01085     if (lpAdapter->pWanAdapter != NULL)
    01086     {
    01087         WanPacketCloseAdapter(lpAdapter->pWanAdapter);
    01088         GlobalFreePtr(lpAdapter);
    01089         return;
    01090     }
    01091 #ifdef HAVE_DAG_API
    01092     else
    01093         if(lpAdapter->pDagCard != NULL)
    01094         {
    01095             if(lpAdapter->Flags & INFO_FLAG_DAG_FILE & ~INFO_FLAG_DAG_CARD)
    01096             {
    01097                 // This is a file. We must remove the entry in the adapter description list
    01098                 PacketUpdateAdInfo(lpAdapter->Name);
    01099             }
    01100             p_dagc_close(lpAdapter->pDagCard);
    01101         }
    01102 #endif // HAVE_DAG_API
    01103 #endif // _WINNT4
    01104
    01105     CloseHandle(lpAdapter->hFile);
    01106     SetEvent(lpAdapter->ReadEvent);
    01107     CloseHandle(lpAdapter->ReadEvent);
    01108     GlobalFreePtr(lpAdapter);
    01109 }
    01110
    01123 LPPACKET PacketAllocatePacket(void)
    01124 {
    01125
    01126     LPPACKET    lpPacket;
    01127     lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET));
    01128     if (lpPacket==NULL)
    01129     {
    01130         ODS("PacketAllocatePacket: GlobalAlloc Failed\n");
    01131         return NULL;
    01132     }
    01133     return lpPacket;
    01134 }
    01135
    01144 VOID PacketFreePacket(LPPACKET lpPacket)
    01145
    01146 {
    01147     GlobalFreePtr(lpPacket);
    01148 }
    01149
    01166 VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length)
    01167
    01168 {
    01169     lpPacket->Buffer = Buffer;
    01170     lpPacket->Length = Length;
    01171     lpPacket->ulBytesReceived = 0;
    01172     lpPacket->bIoComplete = FALSE;
    01173 }
    01174
    01205 BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
    01206 {
    01207     BOOLEAN res;
    01208
    01209 #ifndef _WINNT4
    01210
    01211     if (AdapterObject->pWanAdapter != NULL)
    01212     {
    01213         lpPacket->ulBytesReceived = WanPacketReceivePacket(AdapterObject->pWanAdapter, lpPacket->Buffer, lpPacket->Length);
    01214         return TRUE;
    01215     }
    01216 #ifdef HAVE_DAG_API
    01217     else
    01218         if(AdapterObject->pDagCard != NULL)
    01219         {
    01220
    01221             p_dagc_wait(AdapterObject->pDagCard, &AdapterObject->DagReadTimeout);
    01222
    01223             if(p_dagc_receive(AdapterObject->pDagCard, &AdapterObject->DagBuffer, &lpPacket->ulBytesReceived) == 0)
    01224                 return TRUE;
    01225             else
    01226                 return FALSE;
    01227         }
    01228 #endif // HAVE_DAG_API
    01229 #endif // _WINNT4
    01230
    01231     if((int)AdapterObject->ReadTimeOut != -1)
    01232         WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut);
    01233
    01234     res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL);
    01235
    01236     return res;
    01237 }
    01238
    01268 BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
    01269 {
    01270     DWORD        BytesTransfered;
    01271
    01272
    01273 #ifndef _WINNT4
    01274     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01275     {
    01276         ODS("PacketSendPacket: packet sending not allowed on wan adapters\n");
    01277         return FALSE;
    01278     }
    01279 #endif // _WINNT4
    01280
    01281     return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL);
    01282 }
    01283
    01284
    01312 INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync)
    01313 {
    01314     BOOLEAN         Res;
    01315     DWORD           BytesTransfered, TotBytesTransfered=0;
    01316     struct timeval  BufStartTime;
    01317     LARGE_INTEGER   StartTicks, CurTicks, TargetTicks, TimeFreq;
    01318
    01319
    01320     ODS("PacketSendPackets");
    01321
    01322 #ifndef _WINNT4
    01323     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01324     {
    01325         ODS("PacketSendPackets: packet sending not allowed on wan adapters\n");
    01326         return FALSE;
    01327     }
    01328 #endif // _WINNT4
    01329
    01330     // Obtain starting timestamp of the buffer
    01331     BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec;
    01332     BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec;
    01333
    01334     // Retrieve the reference time counters
    01335     QueryPerformanceCounter(&StartTicks);
    01336     QueryPerformanceFrequency(&TimeFreq);
    01337
    01338     CurTicks.QuadPart = StartTicks.QuadPart;
    01339
    01340     do{
    01341         // Send the data to the driver
    01342         Res = DeviceIoControl(AdapterObject->hFile,
    01343             (Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC,
    01344             (PCHAR)PacketBuff + TotBytesTransfered,
    01345             Size - TotBytesTransfered,
    01346             NULL,
    01347             0,
    01348             &BytesTransfered,
    01349             NULL);
    01350
    01351         TotBytesTransfered += BytesTransfered;
    01352
    01353         // calculate the time interval to wait before sending the next packet
    01354         TargetTicks.QuadPart = StartTicks.QuadPart +
    01355         (LONGLONG)
    01356         ((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 +
    01357         (((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) *
    01358         (TimeFreq.QuadPart) / 1000000;
    01359
    01360         // Exit from the loop on termination or error
    01361         if(TotBytesTransfered >= Size || Res != TRUE)
    01362             break;
    01363
    01364         // Wait until the time interval has elapsed
    01365         while( CurTicks.QuadPart <= TargetTicks.QuadPart )
    01366             QueryPerformanceCounter(&CurTicks);
    01367
    01368     }
    01369     while(TRUE);
    01370
    01371     return TotBytesTransfered;
    01372 }
    01373
    01392 BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes)
    01393 {
    01394     DWORD BytesReturned;
    01395
    01396 #ifndef _WINNT4
    01397    if (AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER)
    01398       return WanPacketSetMinToCopy(AdapterObject->pWanAdapter, nbytes);
    01399 #ifdef HAVE_DAG_API
    01400     else
    01401         if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01402             // No mintocopy with DAGs
    01403             return TRUE;
    01404 #endif // HAVE_DAG_API
    01405 #endif // _WINNT4
    01406
    01407    return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL);
    01408 }
    01409
    01446 BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode)
    01447 {
    01448     DWORD BytesReturned;
    01449
    01450 #ifndef _WINNT4
    01451    if (AdapterObject->pWanAdapter != NULL)
    01452       return WanPacketSetMode(AdapterObject->pWanAdapter, mode);
    01453 #endif // _WINNT4
    01454
    01455     return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL);
    01456 }
    01457
    01472 BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len)
    01473 {
    01474     DWORD       BytesReturned;
    01475     WCHAR   *FileName;
    01476     BOOLEAN res;
    01477     WCHAR   NameWithPath[1024];
    01478     int     TStrLen;
    01479     WCHAR   *NamePos;
    01480
    01481 #ifndef _WINNT4
    01482     if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01483     {
    01484         ODS("PacketSetDumpName: not allowed on wan adapters\n");
    01485         return FALSE;
    01486     }
    01487 #endif // _WINNT4
    01488
    01489     if(((PUCHAR)name)[1]!=0 && len>1){ //ASCII
    01490         FileName=SChar2WChar(name);
    01491         len*=2;
    01492     }
    01493     else {  //Unicode
    01494         FileName=name;
    01495     }
    01496
    01497     TStrLen=GetFullPathName(FileName,1024,NameWithPath,&NamePos);
    01498
    01499     len=TStrLen*2+2;  //add the terminating null character
    01500
    01501     // Try to catch malformed strings
    01502     if(len>2048){
    01503         if(((PUCHAR)name)[1]!=0 && len>1) free(FileName);
    01504         return FALSE;
    01505     }
    01506
    01507     res = DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL);
    01508     free(FileName);
    01509     return res;
    01510 }
    01511
    01527 BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks)
    01528 {
    01529     DWORD       BytesReturned;
    01530     UINT valbuff[2];
    01531
    01532 #ifndef _WINNT4
    01533     if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01534     {
    01535         ODS("PacketSetDumpLimits: not allowed on wan adapters\n");
    01536         return FALSE;
    01537     }
    01538 #endif // _WINNT4
    01539
    01540     valbuff[0] = maxfilesize;
    01541     valbuff[1] = maxnpacks;
    01542
    01543     return DeviceIoControl(AdapterObject->hFile,
    01544         pBIOCSETDUMPLIMITS,
    01545         valbuff,
    01546         sizeof valbuff,
    01547         NULL,
    01548         0,
    01549         &BytesReturned,
    01550         NULL);
    01551 }
    01552
    01566 BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync)
    01567 {
    01568     DWORD       BytesReturned;
    01569     int     IsDumpEnded;
    01570     BOOLEAN res;
    01571
    01572 #ifndef _WINNT4
    01573     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01574     {
    01575         ODS("PacketIsDumpEnded: not allowed on wan adapters\n");
    01576         return FALSE;
    01577     }
    01578 #endif // _WINNT4
    01579
    01580     if(sync)
    01581         WaitForSingleObject(AdapterObject->ReadEvent, INFINITE);
    01582
    01583     res = DeviceIoControl(AdapterObject->hFile,
    01584         pBIOCISDUMPENDED,
    01585         NULL,
    01586         0,
    01587         &IsDumpEnded,
    01588         4,
    01589         &BytesReturned,
    01590         NULL);
    01591
    01592     if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished
    01593
    01594     return (BOOLEAN)IsDumpEnded;
    01595 }
    01596
    01616 HANDLE PacketGetReadEvent(LPADAPTER AdapterObject)
    01617 {
    01618     return AdapterObject->ReadEvent;
    01619 }
    01620
    01629 BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)
    01630 {
    01631     DWORD BytesReturned;
    01632
    01633 #ifndef _WINNT4
    01634     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01635     {
    01636         ODS("PacketSetNumWrites: not allowed on wan adapters\n");
    01637         return FALSE;
    01638     }
    01639 #endif // _WINNT4
    01640
    01641     return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL);
    01642 }
    01643
    01656 BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)
    01657 {
    01658     DWORD BytesReturned;
    01659     int DriverTimeOut=-1;
    01660
    01661 #ifndef _WINNT4
    01662    if (AdapterObject->pWanAdapter != NULL)
    01663       return WanPacketSetReadTimeout(AdapterObject->pWanAdapter,timeout);
    01664 #endif // _WINNT4
    01665
    01666     AdapterObject->ReadTimeOut=timeout;
    01667
    01668 #ifdef HAVE_DAG_API
    01669     // Under DAG, we simply store the timeout value and then
    01670     if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01671     {
    01672         if(timeout == 1)
    01673         {
    01674             // tell DAG card to return immediately
    01675             AdapterObject->DagReadTimeout.tv_sec = 0;
    01676             AdapterObject->DagReadTimeout.tv_usec = 0;
    01677         }
    01678         else
    01679             if(timeout == 1)
    01680             {
    01681                 // tell the DAG card to wait forvever
    01682                 AdapterObject->DagReadTimeout.tv_sec = -1;
    01683                 AdapterObject->DagReadTimeout.tv_usec = -1;
    01684             }
    01685             else
    01686             {
    01687                 // Set the timeout for the DAG card
    01688                 AdapterObject->DagReadTimeout.tv_sec = timeout / 1000;
    01689                 AdapterObject->DagReadTimeout.tv_usec = (timeout * 1000) % 1000000;
    01690             }
    01691
    01692             return TRUE;
    01693     }
    01694 #endif // HAVE_DAG_API
    01695
    01696     return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL);
    01697 }
    01698
    01715 BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)
    01716 {
    01717     DWORD BytesReturned;
    01718
    01719 #ifndef _WINNT4
    01720     if (AdapterObject->pWanAdapter != NULL)
    01721         return WanPacketSetBufferSize(AdapterObject->pWanAdapter, dim);
    01722 #ifdef HAVE_DAG_API
    01723     else
    01724         if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01725             // We can't change DAG buffers
    01726             return TRUE;
    01727 #endif // HAVE_DAG_API
    01728
    01729 #endif // _WINNT4
    01730     return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL);
    01731 }
    01732
    01753 BOOLEAN PacketSetBpf(LPADAPTER AdapterObject, struct bpf_program *fp)
    01754 {
    01755     DWORD BytesReturned;
    01756
    01757 #ifndef _WINNT4
    01758    if (AdapterObject->pWanAdapter != NULL)
    01759       return WanPacketSetBpfFilter(AdapterObject->pWanAdapter, (PUCHAR)fp->bf_insns, fp->bf_len * sizeof(struct bpf_insn));
    01760 #ifdef HAVE_DAG_API
    01761     else
    01762         if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01763             // Delegate the filtering to higher layers since it's too expensive here
    01764             return TRUE;
    01765 #endif // HAVE_DAG_API
    01766 #endif // _WINNT4
    01767
    01768    return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL);
    01769 }
    01770
    01785 INT PacketSetSnapLen(LPADAPTER AdapterObject, int snaplen)
    01786 {
    01787
    01788 #ifdef HAVE_DAG_API
    01789     if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01790         return p_dagc_setsnaplen(AdapterObject->pDagCard, snaplen);
    01791     else
    01792 #endif // HAVE_DAG_API
    01793         return 0;
    01794 }
    01795
    01809 BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)
    01810 {
    01811     BOOLEAN Res;
    01812     DWORD BytesReturned;
    01813     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
    01814
    01815 #ifndef _WINNT4
    01816 #ifdef HAVE_DAG_API
    01817     if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01818     {
    01819         dagc_stats_t DagStats;
    01820
    01821         // Note: DAG cards are currently very limited from the statistics reporting point of view,
    01822         // so most of the values returned by dagc_stats() are zero at the moment
    01823         if(p_dagc_stats(AdapterObject->pDagCard, &DagStats) == 0)
    01824         {
    01825             // XXX: Only copy the dropped packets for now, since the received counter is not supported by
    01826             // DAGS at the moment
    01827
    01828             s->bs_recv = (ULONG)DagStats.received;
    01829             s->bs_drop = (ULONG)DagStats.dropped;
    01830             return TRUE;
    01831         }
    01832         else
    01833             return FALSE;
    01834     }
    01835     else
    01836 #endif // HAVE_DAG_API
    01837         if ( AdapterObject->pWanAdapter != NULL)
    01838             Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat);
    01839         else
    01840 #endif // _WINNT4
    01841
    01842             Res = DeviceIoControl(AdapterObject->hFile,
    01843             pBIOCGSTATS,
    01844             NULL,
    01845             0,
    01846             &tmpstat,
    01847             sizeof(struct bpf_stat),
    01848             &BytesReturned,
    01849             NULL);
    01850
    01851
    01852     // Copy only the first two values retrieved from the driver
    01853     s->bs_recv = tmpstat.bs_recv;
    01854     s->bs_drop = tmpstat.bs_drop;
    01855
    01856     return Res;
    01857 }
    01858
    01871 BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s)
    01872 {
    01873     BOOLEAN Res;
    01874     DWORD BytesReturned;
    01875     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
    01876
    01877 #ifndef _WINNT4
    01878 #ifdef HAVE_DAG_API
    01879         if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
    01880         {
    01881             dagc_stats_t DagStats;
    01882
    01883             // Note: DAG cards are currently very limited from the statistics reporting point of view,
    01884             // so most of the values returned by dagc_stats() are zero at the moment
    01885             p_dagc_stats(AdapterObject->pDagCard, &DagStats);
    01886             s->bs_recv = (ULONG)DagStats.received;
    01887             s->bs_drop = (ULONG)DagStats.dropped;
    01888             s->ps_ifdrop = 0;
    01889             s->bs_capt = (ULONG)DagStats.captured;
    01890         }
    01891 #endif // HAVE_DAG_API
    01892    if(AdapterObject->pWanAdapter != NULL)
    01893         Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat);
    01894     else
    01895 #endif // _WINNT4
    01896
    01897     Res = DeviceIoControl(AdapterObject->hFile,
    01898         pBIOCGSTATS,
    01899         NULL,
    01900         0,
    01901         &tmpstat,
    01902         sizeof(struct bpf_stat),
    01903         &BytesReturned,
    01904         NULL);
    01905
    01906     s->bs_recv = tmpstat.bs_recv;
    01907     s->bs_drop = tmpstat.bs_drop;
    01908     s->ps_ifdrop = tmpstat.ps_ifdrop;
    01909     s->bs_capt = tmpstat.bs_capt;
    01910
    01911     return Res;
    01912 }
    01913
    01926 BOOLEAN PacketRequest(LPADAPTER  AdapterObject,BOOLEAN Set,PPACKET_OID_DATA  OidData)
    01927 {
    01928     DWORD       BytesReturned;
    01929     BOOLEAN     Result;
    01930
    01931 #ifndef _WINNT4
    01932     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01933         return FALSE;
    01934 #endif // _WINNT4
    01935
    01936     Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? (DWORD)pBIOCSETOID : (DWORD)pBIOCQUERYOID,
    01937                            OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData,
    01938                            sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL);
    01939
    01940     // output some debug info
    01941     ODSEx("PacketRequest, OID=%d ", OidData->Oid);
    01942     ODSEx("Length=%d ", OidData->Length);
    01943     ODSEx("Set=%d ", Set);
    01944     ODSEx("Res=%d\n", Result);
    01945
    01946     return Result;
    01947 }
    01948
    01965 BOOLEAN PacketSetHwFilter(LPADAPTER  AdapterObject,ULONG Filter)
    01966 {
    01967     BOOLEAN    Status;
    01968     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
    01969     PPACKET_OID_DATA  OidData;
    01970
    01971 #ifndef _WINNT4
    01972     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
    01973         return TRUE;
    01974 #endif // _WINNT4
    01975
    01976     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
    01977     if (OidData == NULL) {
    01978         ODS("PacketSetHwFilter: GlobalAlloc Failed\n");
    01979         return FALSE;
    01980     }
    01981     OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER;
    01982     OidData->Length=sizeof(ULONG);
    01983     *((PULONG)OidData->Data)=Filter;
    01984     Status=PacketRequest(AdapterObject,TRUE,OidData);
    01985     GlobalFreePtr(OidData);
    01986     return Status;
    01987 }
    01988
    02010 BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG  BufferSize)
    02011 {
    02012     PADAPTER_INFO   TAdInfo;
    02013     ULONG   SizeNeeded = 1;
    02014     ULONG   SizeNames = 1;
    02015     ULONG   SizeDesc;
    02016     ULONG   OffDescriptions;
    02017
    02018     ODSEx("PacketGetAdapterNames: BufferSize=%d\n", *BufferSize);
    02019
    02020     //
    02021     // Create the adapter information list
    02022     //
    02023     PacketPopulateAdaptersInfoList();
    02024
    02025     WaitForSingleObject(AdaptersInfoMutex, INFINITE);
    02026     if(!AdaptersInfoList)
    02027     {
    02028         ReleaseMutex(AdaptersInfoMutex);
    02029         *BufferSize = 0;
    02030         return FALSE;       // No adapters to return
    02031     }
    02032
    02033     //
    02034     // First scan of the list to calculate the offsets and check the sizes
    02035     //
    02036     for(TAdInfo = AdaptersInfoList; TAdInfo != NULL; TAdInfo = TAdInfo->Next)
    02037     {
    02038         // Update the size variables
    02039         SizeNeeded += strlen(TAdInfo->Name) + strlen(TAdInfo->Description) + 2;
    02040         SizeNames += strlen(TAdInfo->Name) + 1;
    02041     }
    02042
    02043     // Chack that we don't overflow the buffer.
    02044     // Note: 2 is the number of additional separators needed inside the list
    02045     if(SizeNeeded + 2 >= *BufferSize || pStr == NULL)
    02046     {
    02047         ReleaseMutex(AdaptersInfoMutex);
    02048
    02049         ODS("PacketGetAdapterNames: input buffer too small\n");
    02050         *BufferSize = SizeNeeded + 4;  // Report the required size
    02051         return FALSE;
    02052     }
    02053
    02054
    02055     OffDescriptions = SizeNames;
    02056
    02057     //
    02058     // Second scan of the list to copy the information
    02059     //
    02060     for(TAdInfo = AdaptersInfoList, SizeNames = 0, SizeDesc = 0; TAdInfo != NULL; TAdInfo = TAdInfo->Next)
    02061     {
    02062         // Copy the data
    02063         strcpy(((PCHAR)pStr) + SizeNames, TAdInfo->Name);
    02064         strcpy(((PCHAR)pStr) + OffDescriptions + SizeDesc, TAdInfo->Description);
    02065
    02066         // Update the size variables
    02067         SizeNames += strlen(TAdInfo->Name) + 1;
    02068         SizeDesc += strlen(TAdInfo->Description) + 1;
    02069     }
    02070
    02071     // Separate the two lists
    02072     ((PCHAR)pStr)[SizeNames] = 0;
    02073
    02074     // End the list with a further \0
    02075     ((PCHAR)pStr)[SizeNeeded] = 0;
    02076
    02077
    02078     ReleaseMutex(AdaptersInfoMutex);
    02079     return TRUE;
    02080 }
    02081
    02095 BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries)
    02096 {
    02097     PADAPTER_INFO TAdInfo;
    02098     PCHAR Tname;
    02099     BOOLEAN Res, FreeBuff;
    02100
    02101     ODS("PacketGetNetInfo\n");
    02102
    02103     // Provide conversion for backward compatibility
    02104     if(AdapterName[1] != 0)
    02105     { //ASCII
    02106         Tname = AdapterName;
    02107         FreeBuff = FALSE;
    02108     }
    02109     else
    02110     {
    02111         Tname = WChar2SChar((PWCHAR)AdapterName);
    02112         FreeBuff = TRUE;
    02113     }
    02114
    02115     //
    02116     // Update the information about this adapter
    02117     //
    02118     if(!PacketUpdateAdInfo(Tname))
    02119     {
    02120         ODS("PacketGetNetInfo: Adapter not found\n");
    02121         if(FreeBuff)GlobalFreePtr(Tname);
    02122         return FALSE;
    02123     }
    02124
    02125     WaitForSingleObject(AdaptersInfoMutex, INFINITE);
    02126     // Find the PADAPTER_INFO structure associated with this adapter
    02127     TAdInfo = PacketFindAdInfo(Tname);
    02128
    02129     if(TAdInfo != NULL)
    02130     {
    02131         *NEntries = (TAdInfo->NNetworkAddresses < *NEntries)? TAdInfo->NNetworkAddresses: *NEntries;
    02132         //TODO what if nentries = 0?
    02133         if (*NEntries > 0)
    02134             memcpy(buffer, TAdInfo->NetworkAddresses, *NEntries * sizeof(npf_if_addr));
    02135         Res = TRUE;
    02136     }
    02137     else
    02138     {
    02139         ODS("PacketGetNetInfo: Adapter not found\n");
    02140         Res = FALSE;
    02141     }
    02142
    02143     ReleaseMutex(AdaptersInfoMutex);
    02144
    02145     if(FreeBuff)GlobalFreePtr(Tname);
    02146
    02147     return Res;
    02148 }
    02149
    02166 BOOLEAN PacketGetNetType(LPADAPTER AdapterObject, NetType *type)
    02167 {
    02168     PADAPTER_INFO TAdInfo;
    02169     BOOLEAN ret;
    02170     ODS("PacketGetNetType\n");
    02171
    02172     WaitForSingleObject(AdaptersInfoMutex, INFINITE);
    02173     // Find the PADAPTER_INFO structure associated with this adapter
    02174     TAdInfo = PacketFindAdInfo(AdapterObject->Name);
    02175
    02176     if(TAdInfo != NULL)
    02177     {
    02178         // Copy the data
    02179         memcpy(type, &(TAdInfo->LinkLayer), sizeof(struct NetType));
    02180         ret = TRUE;
    02181     }
    02182     else
    02183     {
    02184         ODS("PacketGetNetType: Adapter not found\n");
    02185         ret =  FALSE;
    02186     }
    02187
    02188     ReleaseMutex(AdaptersInfoMutex);
    02189
    02190     return ret;
    02191 }
    02192
    02193 /* @} */

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