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.