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, 2000
    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 <packet32.h>
    00025
    00026 #include <windows.h>
    00027 #include <windowsx.h>
    00028
    00029 #include <ntddndis.h>
    00030
    00031
    00033 TCHAR   szWindowTitle[] = TEXT("PACKET.DLL");
    00034
    00035 #if _DBG
    00036 #define ODS(_x) OutputDebugString(TEXT(_x))
    00037 #define ODSEx(_x, _y)
    00038 #else
    00039 #ifdef _DEBUG_TO_FILE
    00040 #include <stdio.h>
    00044 #define ODS(_x) { \
    00045     FILE *f; \
    00046     f = fopen("winpcap_debug.txt", "a"); \
    00047     fprintf(f, "%s", _x); \
    00048     fclose(f); \
    00049 }
    00050
    00054 #define ODSEx(_x, _y) { \
    00055     FILE *f; \
    00056     f = fopen("winpcap_debug.txt", "a"); \
    00057     fprintf(f, _x, _y); \
    00058     fclose(f); \
    00059 }
    00060
    00061
    00062
    00063 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName);
    00064 #else
    00065 #define ODS(_x)
    00066 #define ODSEx(_x, _y)
    00067 #endif
    00068 #endif
    00069
    00070 //service handles
    00071 SC_HANDLE scmHandle = NULL;
    00072 SC_HANDLE srvHandle = NULL;
    00073 LPCTSTR NPFServiceName = TEXT("NPF");
    00074 LPCTSTR NPFServiceDesc = TEXT("Netgroup Packet Filter");
    00075 LPCTSTR NPFRegistryLocation = TEXT("SYSTEM\\CurrentControlSet\\Services\\NPF");
    00076 LPCTSTR NPFDriverPath = TEXT("system32\\drivers\\npf.sys");
    00077
    00078 //---------------------------------------------------------------------------
    00079
    00084 BOOL APIENTRY DllMain (HANDLE DllHandle,DWORD Reason,LPVOID lpReserved)
    00085 {
    00086     BOOLEAN Status=TRUE;
    00087
    00088     switch ( Reason )
    00089     {
    00090     case DLL_PROCESS_ATTACH:
    00091
    00092         ODS("************Packet32: DllMain************\n");
    00093
    00094 #ifdef _DEBUG_TO_FILE
    00095         // dump a bunch of registry keys useful for debug to file
    00096         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",
    00097             "adapters.reg");
    00098         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip",
    00099             "tcpip.reg");
    00100         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\NPF",
    00101             "npf.reg");
    00102         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services",
    00103             "services.reg");
    00104 #endif
    00105         break;
    00106
    00107         case DLL_PROCESS_DETACH:
    00108             break;
    00109
    00110         default:
    00111             break;
    00112     }
    00113
    00114     return Status;
    00115 }
    00116
    00123 WCHAR* SChar2WChar(char* string)
    00124 {
    00125     WCHAR* TmpStr;
    00126     TmpStr=(WCHAR*) malloc ((strlen(string)+2)*sizeof(WCHAR));
    00127
    00128     MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (strlen(string)+2));
    00129
    00130     return TmpStr;
    00131 }
    00132
    00142 BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject)
    00143 {
    00144     BOOLEAN    Status;
    00145     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
    00146     PPACKET_OID_DATA  OidData;
    00147
    00148     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
    00149     if (OidData == NULL) {
    00150         ODS("PacketSetMaxLookaheadsize failed\n");
    00151         return FALSE;
    00152     }
    00153
    00154     //set the size of the lookahead buffer to the maximum available by the the NIC driver
    00155     OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD;
    00156     OidData->Length=sizeof(ULONG);
    00157     Status=PacketRequest(AdapterObject,FALSE,OidData);
    00158     OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD;
    00159     Status=PacketRequest(AdapterObject,TRUE,OidData);
    00160     GlobalFreePtr(OidData);
    00161     return Status;
    00162 }
    00163
    00174 BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject)
    00175 {
    00176     DWORD BytesReturned;
    00177     TCHAR EventName[39];
    00178
    00179     // this tells the terminal service to retrieve the event from the global namespace
    00180     wcsncpy(EventName,L"Global\\",sizeof(L"Global\\"));
    00181
    00182     // retrieve the name of the shared event from the driver
    00183     if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName+7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) return FALSE;
    00184
    00185     EventName[20]=0; // terminate the string
    00186
    00187     // open the shared event
    00188     AdapterObject->ReadEvent=CreateEvent(NULL,
    00189                                          TRUE,
    00190                                          FALSE,
    00191                                          EventName);
    00192
    00193     // in NT4 "Global\" is not automatically ignored: try to use simply the event name
    00194     if(GetLastError()!=ERROR_ALREADY_EXISTS){
    00195         if(AdapterObject->ReadEvent != NULL)
    00196             CloseHandle(AdapterObject->ReadEvent);
    00197
    00198         // open the shared event
    00199         AdapterObject->ReadEvent=CreateEvent(NULL,
    00200             TRUE,
    00201             FALSE,
    00202             EventName+7);
    00203     }
    00204
    00205     if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){
    00206         ODS("PacketSetReadEvt: error retrieving the event from the kernel\n");
    00207         return FALSE;
    00208     }
    00209
    00210     AdapterObject->ReadTimeOut=0;
    00211
    00212     return TRUE;
    00213 }
    00214
    00224 BOOL PacketInstallDriver(SC_HANDLE ascmHandle,SC_HANDLE *srvHandle)
    00225 {
    00226     BOOL result = FALSE;
    00227     ULONG err;
    00228
    00229     ODS("installdriver\n");
    00230
    00231     *srvHandle = CreateService(ascmHandle,
    00232         NPFServiceName,
    00233         NPFServiceDesc,
    00234         SERVICE_ALL_ACCESS,
    00235         SERVICE_KERNEL_DRIVER,
    00236         SERVICE_DEMAND_START,
    00237         SERVICE_ERROR_NORMAL,
    00238         NPFDriverPath,
    00239         NULL, NULL, NULL, NULL, NULL);
    00240     if (*srvHandle == NULL)
    00241     {
    00242         if (GetLastError() == ERROR_SERVICE_EXISTS)
    00243         {
    00244             //npf.sys already existed
    00245             result = TRUE;
    00246         }
    00247     }
    00248     else
    00249     {
    00250         //Created service for npf.sys
    00251         result = TRUE;
    00252     }
    00253     if (result == TRUE)
    00254         if (*srvHandle != NULL)
    00255             CloseServiceHandle(*srvHandle);
    00256
    00257     if(result == FALSE){
    00258         err = GetLastError();
    00259         if(err != 2)
    00260             ODSEx("PacketInstallDriver failed, Error=%d\n",err);
    00261     }
    00262     return result;
    00263
    00264 }
    00265
    00275 ULONG inet_addrU(const WCHAR *cp)
    00276 {
    00277     ULONG val, part;
    00278     WCHAR c;
    00279     int i;
    00280
    00281     val = 0;
    00282     for (i = 0; i < 4; i++) {
    00283         part = 0;
    00284         while ((c = *cp++) != '\0' && c != '.') {
    00285             if (c < '0' || c > '9')
    00286                 return -1;
    00287             part = part*10 + (c - '0');
    00288         }
    00289         if (part > 255)
    00290             return -1;
    00291         val = val | (part << i*8);
    00292         if (i == 3) {
    00293             if (c != '\0')
    00294                 return -1;  // extra gunk at end of string
    00295         } else {
    00296             if (c == '\0')
    00297                 return -1;  // string ends early
    00298         }
    00299     }
    00300     return val;
    00301 }
    00302
    00312 #ifdef _DEBUG_TO_FILE
    00313
    00314 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName)
    00315 {
    00316     CHAR Command[256];
    00317
    00318     strcpy(Command, "regedit /e ");
    00319     strcat(Command, FileName);
    00320     strcat(Command, " ");
    00321     strcat(Command, KeyName);
    00322
    00324     system(Command);
    00325
    00326     return TRUE;
    00327 }
    00328 #endif
    00329
    00330 //---------------------------------------------------------------------------
    00331 // PUBLIC API
    00332 //---------------------------------------------------------------------------
    00333
    00342
    00343 char PacketLibraryVersion[] = "3.0 alpha3";
    00344
    00349 PCHAR PacketGetVersion(){
    00350     return PacketLibraryVersion;
    00351 }
    00352
    00369 BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type)
    00370 {
    00371     BOOLEAN    Status;
    00372     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
    00373     PPACKET_OID_DATA  OidData;
    00374
    00375     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
    00376     if (OidData == NULL) {
    00377         ODS("PacketGetNetType failed\n");
    00378         return FALSE;
    00379     }
    00380     //get the link-layer type
    00381     OidData->Oid = OID_GEN_MEDIA_IN_USE;
    00382     OidData->Length = sizeof (ULONG);
    00383     Status = PacketRequest(AdapterObject,FALSE,OidData);
    00384     type->LinkType=*((UINT*)OidData->Data);
    00385
    00386     //get the link-layer speed
    00387     OidData->Oid = OID_GEN_LINK_SPEED;
    00388     OidData->Length = sizeof (ULONG);
    00389     Status = PacketRequest(AdapterObject,FALSE,OidData);
    00390     type->LinkSpeed=*((UINT*)OidData->Data)*100;
    00391     GlobalFreePtr (OidData);
    00392
    00393     ODSEx("Media:%d ",type->LinkType);
    00394     ODSEx("Speed=%d\n",type->LinkSpeed);
    00395
    00396     return Status;
    00397 }
    00398
    00407 BOOL PacketStopDriver()
    00408 {
    00409     SC_HANDLE       scmHandle;
    00410     SC_HANDLE       schService;
    00411     BOOL            ret;
    00412     SERVICE_STATUS  serviceStatus;
    00413
    00414     scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    00415
    00416     if(scmHandle != NULL){
    00417
    00418         schService = OpenService (scmHandle,
    00419             NPFServiceName,
    00420             SERVICE_ALL_ACCESS
    00421             );
    00422
    00423         if (schService != NULL)
    00424         {
    00425
    00426             ret = ControlService (schService,
    00427                 SERVICE_CONTROL_STOP,
    00428                 &serviceStatus
    00429                 );
    00430             if (!ret)
    00431             {
    00432             }
    00433
    00434             CloseServiceHandle (schService);
    00435
    00436             CloseServiceHandle(scmHandle);
    00437
    00438             return ret;
    00439         }
    00440     }
    00441
    00442     return FALSE;
    00443
    00444 }
    00445
    00468 LPADAPTER PacketOpenAdapter(LPTSTR AdapterName)
    00469 {
    00470     LPADAPTER lpAdapter;
    00471     BOOLEAN Result;
    00472     char *AdapterNameA;
    00473     WCHAR *AdapterNameU;
    00474     DWORD error;
    00475     SC_HANDLE svcHandle = NULL;
    00476     LONG KeyRes;
    00477     HKEY PathKey;
    00478     SERVICE_STATUS SStat;
    00479     BOOLEAN QuerySStat;
    00480     WCHAR SymbolicLink[128];
    00481
    00482     ODSEx("PacketOpenAdapter: trying to open the adapter=%S\n",AdapterName)
    00483
    00484     scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    00485
    00486     if(scmHandle == NULL){
    00487         error = GetLastError();
    00488         ODSEx("OpenSCManager failed! Error=%d\n", error);
    00489     }
    00490     else{
    00491         // check if the NPF registry key is already present
    00492         // this means that the driver is already installed and that we don't need to call PacketInstallDriver
    00493         KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    00494             NPFRegistryLocation,
    00495             0,
    00496             KEY_READ,
    00497             &PathKey);
    00498
    00499         if(KeyRes != ERROR_SUCCESS)
    00500         {
    00501             Result = PacketInstallDriver(scmHandle,&svcHandle);
    00502         }
    00503         else
    00504         {
    00505             Result = TRUE;
    00506             RegCloseKey(PathKey);
    00507         }
    00508
    00509         if (Result)
    00510         {
    00511
    00512             srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS );
    00513             if (srvHandle != NULL)
    00514             {
    00515                 QuerySStat = QueryServiceStatus(srvHandle, &SStat);
    00516                 ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
    00517
    00518                 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING)
    00519                 {
    00520                     ODS("Calling startservice\n");
    00521                     if (StartService(srvHandle, 0, NULL)==0)
    00522                     {
    00523                         error = GetLastError();
    00524                         if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS)
    00525                         {
    00526                             SetLastError(error);
    00527                             if (scmHandle != NULL)
    00528                                 CloseServiceHandle(scmHandle);
    00529                             error = GetLastError();
    00530                             ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
    00531                             return NULL;
    00532                         }
    00533                     }
    00534                 }
    00535
    00536                 CloseServiceHandle( srvHandle );
    00537                 srvHandle = NULL;
    00538
    00539             }
    00540             else
    00541             {
    00542                 error = GetLastError();
    00543                 ODSEx("OpenService failed! Error=%d", error);
    00544             }
    00545         }
    00546         else
    00547         {
    00548             if(KeyRes != ERROR_SUCCESS)
    00549                 Result = PacketInstallDriver(scmHandle,&svcHandle);
    00550             else
    00551                 Result = TRUE;
    00552
    00553             if (Result) {
    00554
    00555                 srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START);
    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
    00565                         if (StartService(srvHandle, 0, NULL)==0){
    00566                             error = GetLastError();
    00567                             if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){
    00568                                 SetLastError(error);
    00569                                 if (scmHandle != NULL) CloseServiceHandle(scmHandle);
    00570                                 ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
    00571                                 return NULL;
    00572                             }
    00573                         }
    00574                     }
    00575
    00576                     CloseServiceHandle( srvHandle );
    00577                     srvHandle = NULL;
    00578
    00579                 }
    00580                 else{
    00581                     error = GetLastError();
    00582                     ODSEx("OpenService failed! Error=%d", error);
    00583                 }
    00584             }
    00585         }
    00586     }
    00587
    00588     if (scmHandle != NULL) CloseServiceHandle(scmHandle);
    00589
    00590     AdapterNameA=(char*)AdapterName;
    00591     if(AdapterNameA[1]!=0){ //ASCII
    00592         AdapterNameU=SChar2WChar(AdapterNameA);
    00593         AdapterName=AdapterNameU;
    00594     } else {            //Unicode
    00595         AdapterNameU=NULL;
    00596     }
    00597
    00598     lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(ADAPTER));
    00599     if (lpAdapter==NULL)
    00600     {
    00601         ODS("PacketOpenAdapter: GlobalAlloc Failed\n");
    00602         error=GetLastError();
    00603         if (AdapterNameU != NULL) free(AdapterNameU);
    00604         //set the error to the one on which we failed
    00605         SetLastError(error);
    00606         ODS("PacketOpenAdapter: Failed to allocate the adapter structure\n");
    00607         return NULL;
    00608     }
    00609     lpAdapter->NumWrites=1;
    00610
    00611
    00612
    00613     if (LOWORD(GetVersion()) == 4)
    00614         wsprintf(SymbolicLink,TEXT("\\\\.\\%s"),&AdapterName[8]);
    00615     else
    00616         wsprintf(SymbolicLink,TEXT("\\\\.\\Global\\%s"),&AdapterName[8]);
    00617
    00618     // Copy  only the bytes that fit in the adapter structure.
    00619     // Note that lpAdapter->SymbolicLink is present for backward compatibility but will
    00620     // never be used by the apps
    00621     memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH);
    00622
    00623     //try if it is possible to open the adapter immediately
    00624     lpAdapter->hFile=CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ,
    00625         0,NULL,OPEN_EXISTING,0,0);
    00626
    00627     if (lpAdapter->hFile != INVALID_HANDLE_VALUE)
    00628     {
    00629
    00630         if(PacketSetReadEvt(lpAdapter)==FALSE){
    00631             error=GetLastError();
    00632             ODS("PacketOpenAdapter: Unable to open the read event\n");
    00633             if (AdapterNameU != NULL)
    00634                 free(AdapterNameU);
    00635             GlobalFreePtr(lpAdapter);
    00636             //set the error to the one on which we failed
    00637             SetLastError(error);
    00638             ODSEx("PacketOpenAdapter: PacketSetReadEvt failed, Error=%d\n",error);
    00639             return NULL;
    00640         }
    00641
    00642         PacketSetMaxLookaheadsize(lpAdapter);
    00643         if (AdapterNameU != NULL)
    00644             free(AdapterNameU);
    00645         return lpAdapter;
    00646     }
    00647
    00648
    00649     error=GetLastError();
    00650     if (AdapterNameU != NULL)
    00651         free(AdapterNameU);
    00652     GlobalFreePtr(lpAdapter);
    00653     //set the error to the one on which we failed
    00654     SetLastError(error);
    00655     ODSEx("PacketOpenAdapter: CreateFile failed, Error=2,%d\n",error);
    00656     return NULL;
    00657
    00658 }
    00659
    00666 VOID PacketCloseAdapter(LPADAPTER lpAdapter)
    00667 {
    00668     CloseHandle(lpAdapter->hFile);
    00669     SetEvent(lpAdapter->ReadEvent);
    00670     CloseHandle(lpAdapter->ReadEvent);
    00671     GlobalFreePtr(lpAdapter);
    00672 }
    00673
    00686 LPPACKET PacketAllocatePacket(void)
    00687 {
    00688
    00689     LPPACKET    lpPacket;
    00690     lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET));
    00691     if (lpPacket==NULL)
    00692     {
    00693         ODS("PacketAllocatePacket: GlobalAlloc Failed\n");
    00694         return NULL;
    00695     }
    00696     return lpPacket;
    00697 }
    00698
    00707 VOID PacketFreePacket(LPPACKET lpPacket)
    00708
    00709 {
    00710     GlobalFreePtr(lpPacket);
    00711 }
    00712
    00729 VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length)
    00730
    00731 {
    00732     lpPacket->Buffer = Buffer;
    00733     lpPacket->Length = Length;
    00734     lpPacket->ulBytesReceived = 0;
    00735     lpPacket->bIoComplete = FALSE;
    00736 }
    00737
    00768 BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
    00769 {
    00770     BOOLEAN res;
    00771
    00772     if((int)AdapterObject->ReadTimeOut != -1)
    00773         WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut);
    00774
    00775     res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL);
    00776
    00777     return res;
    00778 }
    00779
    00809 BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
    00810
    00811 {
    00812     DWORD        BytesTransfered;
    00813
    00814     return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL);
    00815 }
    00816
    00817
    00845 INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync)
    00846 {
    00847     BOOLEAN         Res;
    00848     DWORD           BytesTransfered, TotBytesTransfered=0;
    00849     struct timeval  BufStartTime;
    00850     LARGE_INTEGER   StartTicks, CurTicks, TargetTicks, TimeFreq;
    00851
    00852
    00853     ODS("PacketSendPackets");
    00854
    00855     // Obtain starting timestamp of the buffer
    00856     BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec;
    00857     BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec;
    00858
    00859     // Retrieve the reference time counters
    00860     QueryPerformanceCounter(&StartTicks);
    00861     QueryPerformanceFrequency(&TimeFreq);
    00862
    00863     CurTicks.QuadPart = StartTicks.QuadPart;
    00864
    00865     do{
    00866         // Send the data to the driver
    00867         Res = DeviceIoControl(AdapterObject->hFile,
    00868             (Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC,
    00869             (PCHAR)PacketBuff + TotBytesTransfered,
    00870             Size - TotBytesTransfered,
    00871             NULL,
    00872             0,
    00873             &BytesTransfered,
    00874             NULL);
    00875
    00876         TotBytesTransfered += BytesTransfered;
    00877
    00878         // calculate the time interval to wait before sending the next packet
    00879         TargetTicks.QuadPart = StartTicks.QuadPart +
    00880         (LONGLONG)
    00881         ((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 +
    00882         (((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) *
    00883         (TimeFreq.QuadPart) / 1000000;
    00884
    00885         // Exit from the loop on termination or error
    00886         if(TotBytesTransfered >= Size || Res != TRUE)
    00887             break;
    00888
    00889         // Wait until the time interval has elapsed
    00890         while( CurTicks.QuadPart <= TargetTicks.QuadPart )
    00891             QueryPerformanceCounter(&CurTicks);
    00892
    00893     }
    00894     while(TRUE);
    00895
    00896     return TotBytesTransfered;
    00897 }
    00898
    00917 BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes)
    00918 {
    00919     DWORD BytesReturned;
    00920     return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL);
    00921 }
    00922
    00959 BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode)
    00960 {
    00961     DWORD BytesReturned;
    00962
    00963     return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL);
    00964 }
    00965
    00980 BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len)
    00981 {
    00982     DWORD       BytesReturned;
    00983     WCHAR   *FileName;
    00984     BOOLEAN res;
    00985     WCHAR   NameWithPath[1024];
    00986     int     TStrLen;
    00987     WCHAR   *NamePos;
    00988
    00989     if(((PUCHAR)name)[1]!=0 && len>1){ //ASCII
    00990         FileName=SChar2WChar(name);
    00991         len*=2;
    00992     }
    00993     else {  //Unicode
    00994         FileName=name;
    00995     }
    00996
    00997     TStrLen=GetFullPathName(FileName,1024,NameWithPath,&NamePos);
    00998
    00999     len=TStrLen*2+2;  //add the terminating null character
    01000
    01001     // Try to catch malformed strings
    01002     if(len>2048){
    01003         if(((PUCHAR)name)[1]!=0 && len>1) free(FileName);
    01004         return FALSE;
    01005     }
    01006
    01007     res = DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL);
    01008     free(FileName);
    01009     return res;
    01010 }
    01011
    01027 BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks)
    01028 {
    01029     DWORD       BytesReturned;
    01030     UINT valbuff[2];
    01031
    01032     valbuff[0] = maxfilesize;
    01033     valbuff[1] = maxnpacks;
    01034
    01035     return DeviceIoControl(AdapterObject->hFile,
    01036         pBIOCSETDUMPLIMITS,
    01037         valbuff,
    01038         sizeof valbuff,
    01039         NULL,
    01040         0,
    01041         &BytesReturned,
    01042         NULL);
    01043 }
    01044
    01058 BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync)
    01059 {
    01060     DWORD       BytesReturned;
    01061     int     IsDumpEnded;
    01062     BOOLEAN res;
    01063
    01064     if(sync)
    01065         WaitForSingleObject(AdapterObject->ReadEvent, INFINITE);
    01066
    01067     res = DeviceIoControl(AdapterObject->hFile,
    01068         pBIOCISDUMPENDED,
    01069         NULL,
    01070         0,
    01071         &IsDumpEnded,
    01072         4,
    01073         &BytesReturned,
    01074         NULL);
    01075
    01076     if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished
    01077
    01078     return (BOOLEAN)IsDumpEnded;
    01079 }
    01080
    01100 HANDLE PacketGetReadEvent(LPADAPTER AdapterObject)
    01101 {
    01102     return AdapterObject->ReadEvent;
    01103 }
    01104
    01113 BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)
    01114 {
    01115     DWORD BytesReturned;
    01116     return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL);
    01117 }
    01118
    01131 BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)
    01132 {
    01133     DWORD BytesReturned;
    01134     int DriverTimeOut=-1;
    01135
    01136     AdapterObject->ReadTimeOut=timeout;
    01137
    01138     return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL);
    01139 }
    01140
    01157 BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)
    01158 {
    01159     DWORD BytesReturned;
    01160     return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL);
    01161 }
    01162
    01183 BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp)
    01184 {
    01185     DWORD BytesReturned;
    01186     return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL);
    01187 }
    01188
    01202 BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)
    01203 {
    01204     BOOLEAN Res;
    01205     DWORD BytesReturned;
    01206     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
    01207
    01208     Res = DeviceIoControl(AdapterObject->hFile,
    01209         pBIOCGSTATS,
    01210         NULL,
    01211         0,
    01212         &tmpstat,
    01213         sizeof(struct bpf_stat),
    01214         &BytesReturned,
    01215         NULL);
    01216
    01217     // Copy only the first two values retrieved from the driver
    01218     s->bs_recv = tmpstat.bs_recv;
    01219     s->bs_drop = tmpstat.bs_drop;
    01220
    01221     return Res;
    01222 }
    01223
    01236 BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s)
    01237 {
    01238     BOOLEAN Res;
    01239     DWORD BytesReturned;
    01240     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
    01241
    01242     Res = DeviceIoControl(AdapterObject->hFile,
    01243         pBIOCGSTATS,
    01244         NULL,
    01245         0,
    01246         &tmpstat,
    01247         sizeof(struct bpf_stat),
    01248         &BytesReturned,
    01249         NULL);
    01250
    01251     s->bs_recv = tmpstat.bs_recv;
    01252     s->bs_drop = tmpstat.bs_drop;
    01253     s->ps_ifdrop = tmpstat.ps_ifdrop;
    01254     s->bs_capt = tmpstat.bs_capt;
    01255
    01256     return Res;
    01257 }
    01258
    01271 BOOLEAN PacketRequest(LPADAPTER  AdapterObject,BOOLEAN Set,PPACKET_OID_DATA  OidData)
    01272 {
    01273     DWORD       BytesReturned;
    01274     BOOLEAN     Result;
    01275
    01276     Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? (DWORD)pBIOCSETOID : (DWORD)pBIOCQUERYOID,
    01277                            OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData,
    01278                            sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL);
    01279
    01280     // output some debug info
    01281     ODSEx("PacketRequest, OID=%d ", OidData->Oid);
    01282     ODSEx("Length=%d ", OidData->Length);
    01283     ODSEx("Set=%d ", Set);
    01284     ODSEx("Res=%d\n", Result);
    01285
    01286     return Result;
    01287 }
    01288
    01305 BOOLEAN PacketSetHwFilter(LPADAPTER  AdapterObject,ULONG Filter)
    01306 {
    01307     BOOLEAN    Status;
    01308     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
    01309     PPACKET_OID_DATA  OidData;
    01310
    01311     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
    01312     if (OidData == NULL) {
    01313         ODS("PacketSetHwFilter: GlobalAlloc Failed\n");
    01314         return FALSE;
    01315     }
    01316     OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER;
    01317     OidData->Length=sizeof(ULONG);
    01318     *((PULONG)OidData->Data)=Filter;
    01319     Status=PacketRequest(AdapterObject,TRUE,OidData);
    01320     GlobalFreePtr(OidData);
    01321     return Status;
    01322 }
    01323
    01353 BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG  BufferSize)
    01354 {
    01355   HKEY      LinkageKey,AdapKey, OneAdapKey;
    01356     DWORD       RegKeySize=0;
    01357   LONG      Status;
    01358     ULONG       Result;
    01359     PTSTR       BpStr;
    01360     char        *TTpStr,*DpStr,*DescBuf;
    01361     LPADAPTER   adapter;
    01362   PPACKET_OID_DATA  OidData;
    01363     int         i=0,k,rewind;
    01364     DWORD       dim;
    01365     TCHAR       AdapName[256];
    01366
    01367   ODSEx("PacketGetAdapterNames: BufferSize=%d\n",*BufferSize);
    01368
    01369   OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,512);
    01370   if (OidData == NULL) {
    01371       ODS("PacketGetAdapterNames: GlobalAlloc Failed\n");
    01372       return FALSE;
    01373   }
    01374
    01375   Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    01376                       TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"),
    01377                         0,
    01378                         KEY_READ,
    01379                         &AdapKey);
    01380   if ( Status != ERROR_SUCCESS ){
    01381     ODS("PacketGetAdapterNames: RegOpenKeyEx ( Class\{networkclassguid} ) Failed\n");
    01382     return FALSE;
    01383   }
    01384
    01385     // Get the size to allocate for the original device names
    01386     while((Result=RegEnumKey(AdapKey,i,AdapName,sizeof(AdapName)/2))==ERROR_SUCCESS)
    01387     {
    01388         Status=RegOpenKeyEx(AdapKey,AdapName,0,KEY_READ,&OneAdapKey);
    01389     if ( Status != ERROR_SUCCESS ){
    01390         RegCloseKey(AdapKey);
    01391       ODS("PacketGetAdapterNames: RegOpenKeyEx ( OneAdapKey ) Failed\n");
    01392       return FALSE;
    01393     }
    01394
    01395         Status=RegOpenKeyEx(OneAdapKey,L"Linkage",0,KEY_READ,&LinkageKey);
    01396     if ( Status != ERROR_SUCCESS ){
    01397       RegCloseKey( OneAdapKey );
    01398         RegCloseKey(AdapKey);
    01399       ODS("PacketGetAdapterNames: RegOpenKeyEx ( LinkageKey ) Failed\n");
    01400       return FALSE;
    01401     }
    01402
    01403     Status=RegQueryValueEx(LinkageKey,L"Export",NULL,NULL,NULL,&dim);
    01404
    01405     RegCloseKey( OneAdapKey );
    01406     RegCloseKey( LinkageKey );
    01407
    01408         i++;
    01409         if(Status!=ERROR_SUCCESS) continue;
    01410         RegKeySize+=dim;
    01411   } // while enum reg key still find keys
    01412
    01413     // Allocate the memory for the original device names
    01414     ODSEx("Need %d bytes for the names\n", RegKeySize+2);
    01415     BpStr=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,RegKeySize+2);
    01416     if (BpStr == NULL || RegKeySize > *BufferSize) {
    01417         ODS("PacketGetAdapterNames: GlobalAlloc Failed\n");
    01418         GlobalFreePtr(OidData);
    01419         return FALSE;
    01420     }
    01421
    01422     k=0;
    01423     i=0;
    01424
    01425   ODS("PacketGetAdapterNames: Cycling through the adapters:\n");
    01426
    01427     // Copy the names to the buffer
    01428     while((Result=RegEnumKey(AdapKey,i,AdapName,sizeof(AdapName)/2))==ERROR_SUCCESS)
    01429     {
    01430         WCHAR UpperBindStr[64];
    01431
    01432         i++;
    01433         ODSEx(" %d) ", i);
    01434
    01435         Status=RegOpenKeyEx(AdapKey,AdapName,0,KEY_READ,&OneAdapKey);
    01436     if ( Status != ERROR_SUCCESS ){
    01437         RegCloseKey(AdapKey);
    01438       ODS("PacketGetAdapterNames: RegOpenKeyEx ( OneAdapKey ) Failed\n");
    01439       return FALSE;
    01440     }
    01441         Status=RegOpenKeyEx(OneAdapKey,L"Linkage",0,KEY_READ,&LinkageKey);
    01442     if ( Status != ERROR_SUCCESS ){
    01443       RegCloseKey( OneAdapKey );
    01444         RegCloseKey(AdapKey);
    01445       ODS("PacketGetAdapterNames: RegOpenKeyEx ( LinkageKey ) Failed\n");
    01446       return FALSE;
    01447     }
    01448
    01449         dim=sizeof(UpperBindStr);
    01450         Status=RegQueryValueEx(LinkageKey,L"UpperBind",NULL,NULL,(PUCHAR)UpperBindStr,&dim);
    01451
    01452         ODSEx("UpperBind=%S ", UpperBindStr);
    01453
    01454         dim=RegKeySize-k;
    01455         Status=RegQueryValueEx(LinkageKey,L"Export",NULL,NULL,(LPBYTE)BpStr+k,&dim);
    01456         if(Status!=ERROR_SUCCESS){
    01457       RegCloseKey( OneAdapKey );
    01458       RegCloseKey( LinkageKey );
    01459             ODS("Name = SKIPPED (error reading the key)\n");
    01460             continue;
    01461         }
    01462
    01463     RegCloseKey( OneAdapKey );
    01464     RegCloseKey( LinkageKey );
    01465         ODSEx("Name = %S\n", (LPBYTE)BpStr+k);
    01466
    01467         k+=dim-2;
    01468   } // while enum reg keys
    01469
    01470     RegCloseKey(AdapKey);
    01471
    01472 #ifdef _DEBUG_TO_FILE
    01473     //dump BpStr for debug purposes
    01474     ODS("Dumping BpStr:");
    01475     {
    01476         FILE *f;
    01477         f = fopen("winpcap_debug.txt", "a");
    01478         for(i=0;i<k;i++){
    01479             if(!(i%32))fprintf(f, "\n ");
    01480             fprintf(f, "%c " , *((LPBYTE)BpStr+i));
    01481         }
    01482         fclose(f);
    01483     }
    01484     ODS("\n");
    01485 #endif
    01486
    01487
    01488     if (k != 0)
    01489   {
    01490     DescBuf=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096);
    01491
    01492         if (DescBuf == NULL) {
    01493             GlobalFreePtr (BpStr);
    01494           GlobalFreePtr(OidData);
    01495             return FALSE;
    01496         }
    01497         DpStr=DescBuf;
    01498
    01499         for(i=0,k=0;BpStr[i]!=0 || BpStr[i+1]!=0;)
    01500     {
    01501
    01502             if(k+wcslen(BpStr+i)+30 > *BufferSize){
    01503                 // Input buffer too small
    01504                 GlobalFreePtr(OidData);
    01505                 GlobalFreePtr (BpStr);
    01506                 GlobalFreePtr (DescBuf);
    01507                 ODS("PacketGetAdapterNames: Input buffer too small!\n");
    01508                 return FALSE;
    01509             }
    01510
    01511             // Create the device name
    01512             rewind=k;
    01513             memcpy(pStr+k,BpStr+i,16);
    01514             memcpy(pStr+k+8,TEXT("NPF_"),8);
    01515             i+=8;
    01516             k+=12;
    01517             while(BpStr[i-1]!=0){
    01518                 pStr[k++]=BpStr[i++];
    01519             }
    01520
    01521             // Open the adapter
    01522             adapter=PacketOpenAdapter(pStr+rewind);
    01523             if(adapter==NULL){
    01524                 k=rewind;
    01525                 continue;
    01526             }
    01527
    01528             // Retrieve the description
    01529             OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
    01530             OidData->Length = 256;
    01531             ZeroMemory(OidData->Data,256);
    01532             Status = PacketRequest(adapter,FALSE,OidData);
    01533             if(Status==0 || ((char*)OidData->Data)[0]==0){
    01534                 k=rewind;
    01535                 continue;
    01536             }
    01537
    01538             ODSEx("Adapter Description=%s\n\n",OidData->Data);
    01539
    01540             // Copy the description
    01541             TTpStr=(char*)(OidData->Data);
    01542             while(*TTpStr!=0){
    01543                 *DpStr++=*TTpStr++;
    01544             }
    01545             *DpStr++=*TTpStr++;
    01546
    01547             // Close the adapter
    01548             PacketCloseAdapter(adapter);
    01549
    01550     } // for end - parse through string
    01551         *DpStr=0;
    01552
    01553         pStr[k++]=0;
    01554         pStr[k]=0;
    01555
    01556         if((ULONG)(DpStr-DescBuf+k) < *BufferSize)
    01557             memcpy(pStr+k,DescBuf,DpStr-DescBuf);
    01558         else{
    01559           GlobalFreePtr(OidData);
    01560             GlobalFreePtr (BpStr);
    01561             GlobalFreePtr (DescBuf);
    01562             ODS("\nPacketGetAdapterNames: ended with failure\n");
    01563             return FALSE;
    01564         }
    01565
    01566       GlobalFreePtr(OidData);
    01567         GlobalFreePtr (BpStr);
    01568         GlobalFreePtr (DescBuf);
    01569         ODS("\nPacketGetAdapterNames: ended correctly\n");
    01570         return TRUE;
    01571   } // if k != 0
    01572     else{
    01573       DWORD      RegType;
    01574
    01575         ODS("Adapters not found under SYSTEM\\CurrentControlSet\\Control\\Class. Using the TCP/IP bindings.\n");
    01576
    01577         GlobalFreePtr (BpStr);
    01578
    01579         Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage"),0,KEY_READ,&LinkageKey);
    01580         if (Status == ERROR_SUCCESS)
    01581         {
    01582             // Retrieve the length of the key
    01583             Status=RegQueryValueEx(LinkageKey,TEXT("bind"),NULL,&RegType,NULL,&RegKeySize);
    01584             // Allocate the buffer
    01585             BpStr=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,RegKeySize+2);
    01586             if (BpStr == NULL || RegKeySize > *BufferSize) {
    01587                 GlobalFreePtr(OidData);
    01588                 return FALSE;
    01589             }
    01590             Status=RegQueryValueEx(LinkageKey,TEXT("bind"),NULL,&RegType,(LPBYTE)BpStr,&RegKeySize);
    01591             RegCloseKey(LinkageKey);
    01592         }
    01593
    01594         if (Status==ERROR_SUCCESS){
    01595
    01596             DescBuf=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096);
    01597             if (DescBuf == NULL) {
    01598                 GlobalFreePtr (BpStr);
    01599                 GlobalFreePtr(OidData);
    01600                 return FALSE;
    01601             }
    01602             DpStr=DescBuf;
    01603
    01604             for(i=0,k=0;BpStr[i]!=0 || BpStr[i+1]!=0;){
    01605
    01606                 if(k+wcslen(BpStr+i)+30 > *BufferSize){
    01607                     // Input buffer too small
    01608                     GlobalFreePtr(OidData);
    01609                     GlobalFreePtr (BpStr);
    01610                     GlobalFreePtr (DescBuf);
    01611                     return FALSE;
    01612                 }
    01613
    01614                 // Create the device name
    01615                 rewind=k;
    01616                 memcpy(pStr+k,BpStr+i,16);
    01617                 memcpy(pStr+k+8,TEXT("NPF_"),8);
    01618                 i+=8;
    01619                 k+=12;
    01620                 while(BpStr[i-1]!=0){
    01621                     pStr[k++]=BpStr[i++];
    01622                 }
    01623
    01624                 // Open the adapter
    01625                 adapter=PacketOpenAdapter(pStr+rewind);
    01626                 if(adapter==NULL){
    01627                     k=rewind;
    01628                     continue;
    01629                 }
    01630
    01631                 // Retrieve the description
    01632                 OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
    01633                 OidData->Length = 256;
    01634                 Status = PacketRequest(adapter,FALSE,OidData);
    01635                 if(Status==0 || ((char*)OidData->Data)[0]==0){
    01636                     k=rewind;
    01637                     continue;
    01638                 }
    01639
    01640                 // Copy the description
    01641                 TTpStr=(char*)(OidData->Data);
    01642                 while(*TTpStr!=0){
    01643                     *DpStr++=*TTpStr++;
    01644                 }
    01645                 *DpStr++=*TTpStr++;
    01646
    01647                 // Close the adapter
    01648                 PacketCloseAdapter(adapter);
    01649
    01650       } // for end - parse string
    01651             *DpStr=0;
    01652
    01653             pStr[k++]=0;
    01654             pStr[k]=0;
    01655
    01656             if((ULONG)(DpStr-DescBuf+k) < *BufferSize)
    01657                 memcpy(pStr+k,DescBuf,DpStr-DescBuf);
    01658             else{
    01659                 GlobalFreePtr(OidData);
    01660                 GlobalFreePtr (BpStr);
    01661                 GlobalFreePtr (DescBuf);
    01662                 return FALSE;
    01663             }
    01664
    01665             GlobalFreePtr(OidData);
    01666             GlobalFreePtr (BpStr);
    01667             GlobalFreePtr (DescBuf);
    01668             return TRUE;
    01669     } // if key 'bind' was successfully opened
    01670         else{
    01671             MessageBox(NULL,TEXT("Can not find TCP/IP bindings.\nIn order to run the packet capture driver you must install TCP/IP."),szWindowTitle,MB_OK);
    01672             ODS("Cannot find the TCP/IP bindings");
    01673             return FALSE;
    01674         }
    01675     }
    01676 }
    01690 BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterName, npf_if_addr* buffer, PLONG NEntries)
    01691 {
    01692     char    *AdapterNameA;
    01693     WCHAR   *AdapterNameU;
    01694     WCHAR   *ifname;
    01695     HKEY    SystemKey;
    01696     HKEY    InterfaceKey;
    01697     HKEY    ParametersKey;
    01698     HKEY    TcpIpKey;
    01699     HKEY    UnderTcpKey;
    01700     LONG    status;
    01701     WCHAR   String[1024+1];
    01702     DWORD   RegType;
    01703     ULONG   BufLen;
    01704     DWORD   DHCPEnabled;
    01705     struct  sockaddr_in *TmpAddr, *TmpBroad;
    01706     LONG    naddrs,nmasks,StringPos;
    01707     DWORD   ZeroBroadcast;
    01708
    01709     AdapterNameA = (char*)AdapterName;
    01710     if(AdapterNameA[1] != 0) {  //ASCII
    01711         AdapterNameU = SChar2WChar(AdapterNameA);
    01712         AdapterName = AdapterNameU;
    01713     } else {                //Unicode
    01714         AdapterNameU = NULL;
    01715     }
    01716     ifname = wcsrchr(AdapterName, '\\');
    01717     if (ifname == NULL)
    01718         ifname = AdapterName;
    01719     else
    01720         ifname++;
    01721     if (wcsncmp(ifname, L"NPF_", 4) == 0)
    01722         ifname += 4;
    01723
    01724     if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"), 0, KEY_READ, &UnderTcpKey) == ERROR_SUCCESS)
    01725     {
    01726         status = RegOpenKeyEx(UnderTcpKey,ifname,0,KEY_READ,&TcpIpKey);
    01727         if (status != ERROR_SUCCESS) {
    01728             RegCloseKey(UnderTcpKey);
    01729             goto fail;
    01730         }
    01731     }
    01732     else
    01733     {
    01734
    01735         // Query the registry key with the interface's adresses
    01736         status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey);
    01737         if (status != ERROR_SUCCESS)
    01738             goto fail;
    01739         status = RegOpenKeyEx(SystemKey,ifname,0,KEY_READ,&InterfaceKey);
    01740         if (status != ERROR_SUCCESS) {
    01741             RegCloseKey(SystemKey);
    01742             goto fail;
    01743         }
    01744         RegCloseKey(SystemKey);
    01745         status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey);
    01746         if (status != ERROR_SUCCESS) {
    01747             RegCloseKey(InterfaceKey);
    01748             goto fail;
    01749         }
    01750         RegCloseKey(InterfaceKey);
    01751         status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey);
    01752         if (status != ERROR_SUCCESS) {
    01753             RegCloseKey(ParametersKey);
    01754             goto fail;
    01755         }
    01756         RegCloseKey(ParametersKey);
    01757         BufLen = sizeof String;
    01758     }
    01759
    01760     BufLen = 4;
    01761     /* Try to detect if the interface has a zero broadcast addr */
    01762     status=RegQueryValueEx(TcpIpKey,TEXT("UseZeroBroadcast"),NULL,&RegType,(LPBYTE)&ZeroBroadcast,&BufLen);
    01763     if (status != ERROR_SUCCESS)
    01764         ZeroBroadcast=0;
    01765
    01766     BufLen = 4;
    01767     /* See if DHCP is used by this system */
    01768     status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen);
    01769     if (status != ERROR_SUCCESS)
    01770         DHCPEnabled=0;
    01771
    01772
    01773     /* Retrieve the adrresses */
    01774     if(DHCPEnabled){
    01775
    01776         BufLen = sizeof String;
    01777         // Open the key with the addresses
    01778         status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
    01779         if (status != ERROR_SUCCESS) {
    01780             RegCloseKey(TcpIpKey);
    01781             goto fail;
    01782         }
    01783
    01784         // scan the key to obtain the addresses
    01785         StringPos = 0;
    01786         for(naddrs = 0;naddrs <* NEntries;naddrs++){
    01787             TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
    01788
    01789             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
    01790                 TmpAddr->sin_family = AF_INET;
    01791
    01792                 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
    01793                 TmpBroad->sin_family = AF_INET;
    01794                 if(ZeroBroadcast==0)
    01795                     TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
    01796                 else
    01797                     TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
    01798
    01799                 while(*(String + StringPos) != 0)StringPos++;
    01800                 StringPos++;
    01801
    01802                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
    01803                     break;
    01804             }
    01805             else break;
    01806         }
    01807
    01808         BufLen = sizeof String;
    01809         // Open the key with the netmasks
    01810         status = RegQueryValueEx(TcpIpKey,TEXT("DhcpSubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
    01811         if (status != ERROR_SUCCESS) {
    01812             RegCloseKey(TcpIpKey);
    01813             goto fail;
    01814         }
    01815
    01816         // scan the key to obtain the masks
    01817         StringPos = 0;
    01818         for(nmasks = 0;nmasks < *NEntries;nmasks++){
    01819             TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
    01820
    01821             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
    01822                 TmpAddr->sin_family = AF_INET;
    01823
    01824                 while(*(String + StringPos) != 0)StringPos++;
    01825                 StringPos++;
    01826
    01827                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
    01828                     break;
    01829             }
    01830             else break;
    01831         }
    01832
    01833         // The number of masks MUST be equal to the number of adresses
    01834         if(nmasks != naddrs){
    01835             RegCloseKey(TcpIpKey);
    01836             goto fail;
    01837         }
    01838
    01839     }
    01840     else{
    01841
    01842         BufLen = sizeof String;
    01843         // Open the key with the addresses
    01844         status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
    01845         if (status != ERROR_SUCCESS) {
    01846             RegCloseKey(TcpIpKey);
    01847             goto fail;
    01848         }
    01849
    01850         // scan the key to obtain the addresses
    01851         StringPos = 0;
    01852         for(naddrs = 0;naddrs < *NEntries;naddrs++){
    01853             TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
    01854
    01855             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
    01856                 TmpAddr->sin_family = AF_INET;
    01857
    01858                 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
    01859                 TmpBroad->sin_family = AF_INET;
    01860                 if(ZeroBroadcast==0)
    01861                     TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
    01862                 else
    01863                     TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
    01864
    01865                 while(*(String + StringPos) != 0)StringPos++;
    01866                 StringPos++;
    01867
    01868                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
    01869                     break;
    01870             }
    01871             else break;
    01872         }
    01873
    01874         BufLen = sizeof String;
    01875         // Open the key with the netmasks
    01876         status = RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
    01877         if (status != ERROR_SUCCESS) {
    01878             RegCloseKey(TcpIpKey);
    01879             goto fail;
    01880         }
    01881
    01882         // scan the key to obtain the masks
    01883         StringPos = 0;
    01884         for(nmasks = 0;nmasks <* NEntries;nmasks++){
    01885             TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
    01886
    01887             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
    01888                 TmpAddr->sin_family = AF_INET;
    01889
    01890                 while(*(String + StringPos) != 0)StringPos++;
    01891                 StringPos++;
    01892
    01893                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
    01894                     break;
    01895             }
    01896             else break;
    01897         }
    01898
    01899         // The number of masks MUST be equal to the number of adresses
    01900         if(nmasks != naddrs){
    01901             RegCloseKey(TcpIpKey);
    01902             goto fail;
    01903         }
    01904
    01905     }
    01906
    01907     *NEntries = naddrs + 1;
    01908
    01909     RegCloseKey(TcpIpKey);
    01910
    01911     if (status != ERROR_SUCCESS) {
    01912         goto fail;
    01913     }
    01914
    01915
    01916     if (AdapterNameU != NULL)
    01917         free(AdapterNameU);
    01918     return TRUE;
    01919
    01920 fail:
    01921     if (AdapterNameU != NULL)
    01922         free(AdapterNameU);
    01923     return FALSE;
    01924 }
    01925
    01936 BOOLEAN PacketGetNetInfo(LPTSTR AdapterName, PULONG netp, PULONG maskp)
    01937 {
    01938     char    *AdapterNameA;
    01939     WCHAR   *AdapterNameU;
    01940     WCHAR   *ifname;
    01941     HKEY    SystemKey;
    01942     HKEY    InterfaceKey;
    01943     HKEY    ParametersKey;
    01944     HKEY    TcpIpKey;
    01945     LONG    status;
    01946     WCHAR   String[1024+1];
    01947     DWORD   RegType;
    01948     ULONG   BufLen;
    01949     DWORD   DHCPEnabled;
    01950     ULONG   TAddr,i;
    01951
    01952     AdapterNameA = (char*)AdapterName;
    01953     if(AdapterNameA[1] != 0) {  //ASCII
    01954         AdapterNameU = SChar2WChar(AdapterNameA);
    01955         AdapterName = AdapterNameU;
    01956     } else {                //Unicode
    01957         AdapterNameU = NULL;
    01958     }
    01959     ifname = wcsrchr(AdapterName, '\\');
    01960     if (ifname == NULL)
    01961         ifname = AdapterName;
    01962     else
    01963         ifname++;
    01964     if (wcsncmp(ifname, L"NPF_", 4) == 0)
    01965         ifname += 4;
    01966     status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey);
    01967     if (status != ERROR_SUCCESS)
    01968         goto fail;
    01969     status = RegOpenKeyEx(SystemKey,ifname,0,KEY_READ,&InterfaceKey);
    01970     if (status != ERROR_SUCCESS) {
    01971         RegCloseKey(SystemKey);
    01972         goto fail;
    01973     }
    01974     RegCloseKey(SystemKey);
    01975     status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey);
    01976     if (status != ERROR_SUCCESS) {
    01977         RegCloseKey(InterfaceKey);
    01978         goto fail;
    01979     }
    01980     RegCloseKey(InterfaceKey);
    01981     status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey);
    01982     if (status != ERROR_SUCCESS) {
    01983         RegCloseKey(ParametersKey);
    01984         goto fail;
    01985     }
    01986     RegCloseKey(ParametersKey);
    01987
    01988     BufLen = 4;
    01989     /* See if DHCP is used by this system */
    01990     status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen);
    01991     if (status != ERROR_SUCCESS)
    01992         DHCPEnabled=0;
    01993
    01994
    01995     /* Retrieve the netmask */
    01996     if(DHCPEnabled){
    01997
    01998         BufLen = sizeof String;
    01999         status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
    02000         if (status != ERROR_SUCCESS) {
    02001             RegCloseKey(TcpIpKey);
    02002             goto fail;
    02003         }
    02004
    02005         TAddr = inet_addrU(String);
    02006         // swap bytes for backward compatibility
    02007         for(i=0;i<4;i++){
    02008             *((char*)netp+i) = *((char*)&TAddr+3-i);
    02009         }
    02010
    02011         BufLen = sizeof String;
    02012         status=RegQueryValueEx(TcpIpKey,TEXT("DHCPSubnetMask"),NULL,&RegType,
    02013             (LPBYTE)String,&BufLen);
    02014
    02015         TAddr = inet_addrU(String);
    02016         // swap bytes for backward compatibility
    02017         for(i=0;i<4;i++){
    02018             *((char*)maskp+i) = *((char*)&TAddr+3-i);
    02019         }
    02020     }
    02021     else{
    02022
    02023         BufLen = sizeof String;
    02024         status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
    02025         if (status != ERROR_SUCCESS) {
    02026             RegCloseKey(TcpIpKey);
    02027             goto fail;
    02028         }
    02029
    02030         TAddr = inet_addrU(String);
    02031         // swap bytes for backward compatibility
    02032         for(i=0;i<4;i++){
    02033             *((char*)netp+i) = *((char*)&TAddr+3-i);
    02034         }
    02035
    02036         BufLen = sizeof String;
    02037         status=RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,
    02038             (LPBYTE)String,&BufLen);
    02039
    02040         TAddr = inet_addrU(String);
    02041         // swap bytes for backward compatibility
    02042         for(i=0;i<4;i++){
    02043             *((char*)maskp+i) = *((char*)&TAddr+3-i);
    02044         }
    02045
    02046
    02047     }
    02048
    02049     RegCloseKey(TcpIpKey);
    02050
    02051     if (AdapterNameU != NULL)
    02052         free(AdapterNameU);
    02053     return TRUE;
    02054
    02055 fail:
    02056     if (AdapterNameU != NULL)
    02057         free(AdapterNameU);
    02058     return FALSE;
    02059 }
    02060
    02061
    02062 /* @} */

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