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

Packet32.c

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

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