Main Page   Modules   Data Structures   File List   Data Fields   Globals  

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 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName);
00062 #else
00063 #define ODS(_x)     
00064 #define ODSEx(_x, _y)
00065 #endif
00066 #endif
00067 
00068 //service handles
00069 SC_HANDLE scmHandle = NULL;
00070 SC_HANDLE srvHandle = NULL;
00071 LPCTSTR NPFServiceName = TEXT("NPF");
00072 LPCTSTR NPFServiceDesc = TEXT("Netgroup Packet Filter");
00073 LPCTSTR NPFDriverName = TEXT("\\npf.sys");
00074 LPCTSTR NPFRegistryLocation = TEXT("SYSTEM\\CurrentControlSet\\Services\\NPF");
00075 
00076 
00077 //---------------------------------------------------------------------------
00078 
00083 BOOL APIENTRY DllMain (HANDLE DllHandle,DWORD Reason,LPVOID lpReserved)
00084 {
00085     BOOLEAN Status=TRUE;
00086 
00087     switch ( Reason )
00088     {
00089     case DLL_PROCESS_ATTACH:
00090         
00091         ODS("************Packet32: DllMain************\n");
00092         
00093 #ifdef _DEBUG_TO_FILE
00094         // dump a bunch of registry keys useful for debug to file
00095         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",
00096             "adapters.reg");
00097         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip",
00098             "tcpip.reg");
00099         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\NPF",
00100             "npf.reg");
00101         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services",
00102             "services.reg");
00103 #endif
00104         break;
00105 
00106         case DLL_PROCESS_DETACH:
00107             break;
00108 
00109         default:
00110             break;
00111     }
00112 
00113     return Status;
00114 }
00115 
00122 WCHAR* SChar2WChar(char* string)
00123 {
00124     WCHAR* TmpStr;
00125     TmpStr=(WCHAR*) malloc ((strlen(string)+2)*sizeof(WCHAR));
00126 
00127     MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (strlen(string)+2));
00128 
00129     return TmpStr;
00130 }
00131 
00141 BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject)
00142 {
00143     BOOLEAN    Status;
00144     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
00145     PPACKET_OID_DATA  OidData;
00146 
00147     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
00148     if (OidData == NULL) {
00149         ODS("PacketSetMaxLookaheadsize failed\n");
00150         return FALSE;
00151     }
00152 
00153     //set the size of the lookahead buffer to the maximum available by the the NIC driver
00154     OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD;
00155     OidData->Length=sizeof(ULONG);
00156     Status=PacketRequest(AdapterObject,FALSE,OidData);
00157     OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD;
00158     Status=PacketRequest(AdapterObject,TRUE,OidData);
00159     GlobalFreePtr(OidData);
00160     return Status;
00161 }
00162 
00173 BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject)
00174 {
00175     DWORD BytesReturned;
00176     TCHAR EventName[39];
00177 
00178     // this tells the terminal service to retrieve the event from the global namespace
00179     wcsncpy(EventName,L"Global\\",sizeof(L"Global\\"));
00180 
00181     // retrieve the name of the shared event from the driver
00182     if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName+7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) return FALSE;
00183 
00184     EventName[20]=0; // terminate the string
00185 
00186     // open the shared event
00187     AdapterObject->ReadEvent=CreateEvent(NULL,
00188                                          TRUE,
00189                                          FALSE,
00190                                          EventName);
00191 
00192     // in NT4 "Global\" is not automatically ignored: try to use simply the event name
00193     if(GetLastError()!=ERROR_ALREADY_EXISTS){
00194         if(AdapterObject->ReadEvent != NULL)
00195             CloseHandle(AdapterObject->ReadEvent);
00196         
00197         // open the shared event
00198         AdapterObject->ReadEvent=CreateEvent(NULL,
00199             TRUE,
00200             FALSE,
00201             EventName+7);
00202     }   
00203 
00204     if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){
00205         ODS("PacketSetReadEvt: error retrieving the event from the kernel\n");
00206         return FALSE;
00207     }
00208 
00209     AdapterObject->ReadTimeOut=0;
00210 
00211     return TRUE;
00212 }
00213 
00224 BOOL PacketInstallDriver(SC_HANDLE ascmHandle,SC_HANDLE *srvHandle,TCHAR *driverPath)
00225 {
00226     BOOL result = FALSE;
00227     ULONG err;
00228     
00229     ODS("installdriver\n");
00230     
00231     if (GetFileAttributes(driverPath) != 0xffffffff) {
00232         *srvHandle = CreateService(ascmHandle, 
00233             NPFServiceName,
00234             NPFServiceDesc,
00235             SERVICE_ALL_ACCESS,
00236             SERVICE_KERNEL_DRIVER,
00237             SERVICE_DEMAND_START,
00238             SERVICE_ERROR_NORMAL,
00239             driverPath,
00240             NULL, NULL, NULL, NULL, NULL);
00241         if (*srvHandle == NULL) {
00242             if (GetLastError() == ERROR_SERVICE_EXISTS) {
00243                 //npf.sys already existed
00244                 result = TRUE;
00245             }
00246         }
00247         else {
00248             //Created service for npf.sys
00249             result = TRUE;
00250         }
00251     }
00252     if (result == TRUE) 
00253         if (*srvHandle != NULL)
00254             CloseServiceHandle(*srvHandle);
00255 
00256     if(result == FALSE){
00257         err = GetLastError();
00258         if(err != 2)
00259             ODSEx("PacketInstallDriver failed, Error=%d\n",err);
00260     }
00261     return result;
00262     
00263 }
00264 
00274 ULONG inet_addrU(const WCHAR *cp)
00275 {
00276     ULONG val, part;
00277     WCHAR c;
00278     int i;
00279 
00280     val = 0;
00281     for (i = 0; i < 4; i++) {
00282         part = 0;
00283         while ((c = *cp++) != '\0' && c != '.') {
00284             if (c < '0' || c > '9')
00285                 return -1;
00286             part = part*10 + (c - '0');
00287         }
00288         if (part > 255)
00289             return -1;  
00290         val = val | (part << i*8);
00291         if (i == 3) {
00292             if (c != '\0')
00293                 return -1;  // extra gunk at end of string 
00294         } else {
00295             if (c == '\0')
00296                 return -1;  // string ends early 
00297         }
00298     }
00299     return val;
00300 }
00301 
00311 #ifdef _DEBUG_TO_FILE
00312 
00313 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName)
00314 {
00315     CHAR Command[256];
00316 
00317     strcpy(Command, "regedit /e ");
00318     strcat(Command, FileName);
00319     strcat(Command, " ");
00320     strcat(Command, KeyName);
00321 
00323     system(Command);
00324 
00325     return TRUE;
00326 }
00327 #endif
00328 
00329 //---------------------------------------------------------------------------
00330 // PUBLIC API
00331 //---------------------------------------------------------------------------
00332 
00341 
00342 char PacketLibraryVersion[] = "2.3"; 
00343 
00348 PCHAR PacketGetVersion(){
00349     return PacketLibraryVersion;
00350 }
00351 
00368 BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type)
00369 {
00370     BOOLEAN    Status;
00371     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
00372     PPACKET_OID_DATA  OidData;
00373 
00374     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
00375     if (OidData == NULL) {
00376         ODS("PacketGetNetType failed\n");
00377         return FALSE;
00378     }
00379     //get the link-layer type
00380     OidData->Oid = OID_GEN_MEDIA_IN_USE;
00381     OidData->Length = sizeof (ULONG);
00382     Status = PacketRequest(AdapterObject,FALSE,OidData);
00383     type->LinkType=*((UINT*)OidData->Data);
00384 
00385     //get the link-layer speed
00386     OidData->Oid = OID_GEN_LINK_SPEED;
00387     OidData->Length = sizeof (ULONG);
00388     Status = PacketRequest(AdapterObject,FALSE,OidData);
00389     type->LinkSpeed=*((UINT*)OidData->Data)*100;
00390     GlobalFreePtr (OidData);
00391 
00392     ODSEx("Media:%d ",type->LinkType);
00393     ODSEx("Speed=%d\n",type->LinkSpeed);
00394 
00395     return Status;
00396 }
00397 
00406 BOOL PacketStopDriver()
00407 {
00408     SC_HANDLE       scmHandle;
00409     SC_HANDLE       schService;
00410     BOOL            ret;
00411     SERVICE_STATUS  serviceStatus;
00412 
00413     scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
00414     
00415     if(scmHandle != NULL){
00416         
00417         schService = OpenService (scmHandle,
00418             NPFServiceName,
00419             SERVICE_ALL_ACCESS
00420             );
00421         
00422         if (schService != NULL)
00423         {
00424             
00425             ret = ControlService (schService,
00426                 SERVICE_CONTROL_STOP,
00427                 &serviceStatus
00428                 );
00429             if (!ret)
00430             {
00431             }
00432             
00433             CloseServiceHandle (schService);
00434             
00435             CloseServiceHandle(scmHandle);
00436             
00437             return ret;
00438         }
00439     }
00440     
00441     return FALSE;
00442 
00443 }
00444 
00467 LPADAPTER PacketOpenAdapter(LPTSTR AdapterName)
00468 {
00469     LPADAPTER lpAdapter;
00470     BOOLEAN Result;
00471     char *AdapterNameA;
00472     WCHAR *AdapterNameU;
00473     DWORD error;
00474     SC_HANDLE svcHandle = NULL;
00475     TCHAR driverPath[512];
00476     TCHAR WinPath[256];
00477     LONG KeyRes;
00478     HKEY PathKey;
00479     SERVICE_STATUS SStat;
00480     BOOLEAN QuerySStat;
00481     WCHAR SymbolicLink[128];
00482 
00483     ODSEx("PacketOpenAdapter: trying to open the adapter=%S\n",AdapterName)
00484 
00485     scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
00486     
00487     if(scmHandle == NULL){
00488         error = GetLastError();
00489         ODSEx("OpenSCManager failed! Error=%d\n", error);
00490     }
00491     else{
00492         *driverPath = 0;
00493         GetCurrentDirectory(512, driverPath);
00494         wsprintf(driverPath + wcslen(driverPath), 
00495             NPFDriverName);
00496         
00497         // check if the NPF registry key is already present
00498         // this means that the driver is already installed and that we don't need to call PacketInstallDriver
00499         KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
00500             NPFRegistryLocation,
00501             0,
00502             KEY_READ,
00503             &PathKey);
00504         
00505         if(KeyRes != ERROR_SUCCESS){
00506             Result = PacketInstallDriver(scmHandle,&svcHandle,driverPath);
00507         }
00508         else{
00509             Result = TRUE;
00510             RegCloseKey(PathKey);
00511         }
00512         
00513         if (Result) {
00514             
00515             srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS );
00516             if (srvHandle != NULL){
00517                 
00518                 QuerySStat = QueryServiceStatus(srvHandle, &SStat);
00519                 ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
00520                 
00521                 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){
00522                     ODS("Calling startservice\n");
00523                     if (StartService(srvHandle, 0, NULL)==0){ 
00524                         error = GetLastError();
00525                         if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){
00526                             SetLastError(error);
00527                             if (scmHandle != NULL) CloseServiceHandle(scmHandle);
00528                             error = GetLastError();
00529                             ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
00530                             return NULL;
00531                         }
00532                     }               
00533                 }
00534             }
00535             else{
00536                 error = GetLastError();
00537                 ODSEx("OpenService failed! Error=%d", error);
00538             }
00539         }
00540         else{
00541             if( GetSystemDirectory(WinPath, sizeof(WinPath)/sizeof(TCHAR)) == 0) return FALSE;
00542             wsprintf(driverPath,
00543                 TEXT("%s\\drivers%s"), 
00544                 WinPath,NPFDriverName);
00545             
00546             if(KeyRes != ERROR_SUCCESS)
00547                 Result = PacketInstallDriver(scmHandle,&svcHandle,driverPath);
00548             else
00549                 Result = TRUE;
00550             
00551             if (Result) {
00552                 
00553                 srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START);
00554                 if (srvHandle != NULL){
00555                     
00556                     QuerySStat = QueryServiceStatus(srvHandle, &SStat);
00557                     ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
00558                     
00559                     if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){
00560                         
00561                         ODS("Calling startservice\n");
00562                         
00563                         if (StartService(srvHandle, 0, NULL)==0){ 
00564                             error = GetLastError();
00565                             if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){
00566                                 SetLastError(error);
00567                                 if (scmHandle != NULL) CloseServiceHandle(scmHandle);
00568                                 ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
00569                                 return NULL;
00570                             }
00571                         }
00572                     }
00573                 }
00574                 else{
00575                     error = GetLastError();
00576                     ODSEx("OpenService failed! Error=%d", error);
00577                 }
00578             }
00579         }
00580     }
00581 
00582     if (scmHandle != NULL) CloseServiceHandle(scmHandle);
00583 
00584     AdapterNameA=(char*)AdapterName;
00585     if(AdapterNameA[1]!=0){ //ASCII
00586         AdapterNameU=SChar2WChar(AdapterNameA);
00587         AdapterName=AdapterNameU;
00588     } else {            //Unicode
00589         AdapterNameU=NULL;
00590     }
00591     
00592     lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(ADAPTER));
00593     if (lpAdapter==NULL)
00594     {
00595         ODS("PacketOpenAdapter: GlobalAlloc Failed\n");
00596         error=GetLastError();
00597         if (AdapterNameU != NULL) free(AdapterNameU);
00598         //set the error to the one on which we failed
00599         SetLastError(error);
00600         ODS("PacketOpenAdapter: Failed to allocate the adapter structure\n");
00601         return NULL;
00602     }
00603     lpAdapter->NumWrites=1;
00604 
00605     wsprintf(SymbolicLink,TEXT("\\\\.\\%s%s"),DOSNAMEPREFIX,&AdapterName[8]);
00606     
00607     // Copy  only the bytes that fit in the adapter structure.
00608     // Note that lpAdapter->SymbolicLink is present for backward compatibility but will
00609     // never be used by the apps
00610     memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH);
00611 
00612     //try if it is possible to open the adapter immediately
00613     lpAdapter->hFile=CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ,
00614         0,NULL,OPEN_EXISTING,0,0);
00615     
00616     if (lpAdapter->hFile != INVALID_HANDLE_VALUE) {
00617 
00618         if(PacketSetReadEvt(lpAdapter)==FALSE){
00619             error=GetLastError();
00620             ODS("PacketOpenAdapter: Unable to open the read event\n");
00621             if (AdapterNameU != NULL)
00622                 free(AdapterNameU);
00623             GlobalFreePtr(lpAdapter);
00624             //set the error to the one on which we failed
00625             SetLastError(error);
00626             ODSEx("PacketOpenAdapter: PacketSetReadEvt failed, Error=%d\n",error);
00627             return NULL;
00628         }       
00629         
00630         PacketSetMaxLookaheadsize(lpAdapter);
00631         if (AdapterNameU != NULL)
00632             free(AdapterNameU);
00633         return lpAdapter;
00634     }
00635     //this is probably the first request on the packet driver. 
00636     //We must create the dos device and set the access rights on it
00637     else{
00638         Result=DefineDosDevice(DDD_RAW_TARGET_PATH,&SymbolicLink[4],AdapterName);
00639         if (Result)
00640         {
00641 
00642             lpAdapter->hFile=CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ,
00643                 0,NULL,OPEN_EXISTING,0,0);
00644             if (lpAdapter->hFile != INVALID_HANDLE_VALUE)
00645             {       
00646                 
00647                 if(PacketSetReadEvt(lpAdapter)==FALSE){
00648                     error=GetLastError();
00649                     ODS("PacketOpenAdapter: Unable to open the read event\n");
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: PacketSetReadEvt failed, Error=1,%d\n",error);
00656                     return NULL;                    
00657                 }
00658 
00659                 PacketSetMaxLookaheadsize(lpAdapter);
00660                 if (AdapterNameU != NULL)
00661                     free(AdapterNameU);
00662                 return lpAdapter;
00663             }
00664         }
00665     }
00666 
00667     error=GetLastError();
00668     if (AdapterNameU != NULL)
00669         free(AdapterNameU);
00670     GlobalFreePtr(lpAdapter);
00671     //set the error to the one on which we failed
00672     SetLastError(error);
00673     ODSEx("PacketOpenAdapter: CreateFile failed, Error=2,%d\n",error);
00674     return NULL;
00675 
00676 }
00677 
00684 VOID PacketCloseAdapter(LPADAPTER lpAdapter)
00685 {
00686     CloseHandle(lpAdapter->hFile);
00687     SetEvent(lpAdapter->ReadEvent);
00688     CloseHandle(lpAdapter->ReadEvent);
00689     GlobalFreePtr(lpAdapter);
00690 }
00691 
00704 LPPACKET PacketAllocatePacket(void)
00705 {
00706 
00707     LPPACKET    lpPacket;
00708     lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET));
00709     if (lpPacket==NULL)
00710     {
00711         ODS("PacketAllocatePacket: GlobalAlloc Failed\n");
00712         return NULL;
00713     }
00714     return lpPacket;
00715 }
00716 
00725 VOID PacketFreePacket(LPPACKET lpPacket)
00726 
00727 {
00728     GlobalFreePtr(lpPacket);
00729 }
00730 
00747 VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length)
00748 
00749 {
00750     lpPacket->Buffer = Buffer;
00751     lpPacket->Length = Length;
00752     lpPacket->ulBytesReceived = 0;
00753     lpPacket->bIoComplete = FALSE;
00754 }
00755 
00786 BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
00787 {
00788     BOOLEAN res;
00789 
00790     if((int)AdapterObject->ReadTimeOut != -1)
00791         WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut);
00792 
00793     res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL);
00794 
00795     return res;
00796 }
00797 
00827 BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
00828 
00829 {
00830     DWORD        BytesTransfered;
00831     
00832     return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL);
00833 }
00834 
00835 
00863 INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync)
00864 {
00865     BOOLEAN         Res;
00866     DWORD           BytesTransfered, TotBytesTransfered=0;
00867     struct timeval  BufStartTime;
00868     LARGE_INTEGER   StartTicks, CurTicks, TargetTicks, TimeFreq;
00869 
00870 
00871     ODS("PacketSendPackets");
00872 
00873     // Obtain starting timestamp of the buffer
00874     BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec;
00875     BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec;
00876 
00877     // Retrieve the reference time counters
00878     QueryPerformanceCounter(&StartTicks);
00879     QueryPerformanceFrequency(&TimeFreq);
00880 
00881     CurTicks.QuadPart = StartTicks.QuadPart;
00882 
00883     do{
00884         // Send the data to the driver
00885         Res = DeviceIoControl(AdapterObject->hFile,
00886             (Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC,
00887             (PCHAR)PacketBuff + TotBytesTransfered,
00888             Size - TotBytesTransfered,
00889             NULL,
00890             0,
00891             &BytesTransfered,
00892             NULL);
00893 
00894         TotBytesTransfered += BytesTransfered;
00895 
00896         // calculate the time interval to wait before sending the next packet
00897         TargetTicks.QuadPart = StartTicks.QuadPart +
00898         (LONGLONG)
00899         ((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 +
00900         (((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) *
00901         (TimeFreq.QuadPart) / 1000000;
00902 
00903         // Exit from the loop on termination or error
00904         if(TotBytesTransfered >= Size || Res != TRUE)
00905             break;
00906         
00907         // Wait until the time interval has elapsed
00908         while( CurTicks.QuadPart <= TargetTicks.QuadPart )
00909             QueryPerformanceCounter(&CurTicks);
00910 
00911     }
00912     while(TRUE);
00913 
00914     return TotBytesTransfered;
00915 }
00916 
00935 BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes)
00936 {
00937     DWORD BytesReturned;
00938     return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL);
00939 }
00940 
00977 BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode)
00978 {
00979     DWORD BytesReturned;
00980 
00981     return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL);
00982 }
00983 
00998 BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len)
00999 {
01000     DWORD       BytesReturned;
01001     WCHAR   *FileName;
01002     BOOLEAN res;
01003     WCHAR   NameWithPath[1024];
01004     int     TStrLen;
01005     WCHAR   *NamePos;
01006 
01007     if(((PUCHAR)name)[1]!=0 && len>1){ //ASCII
01008         FileName=SChar2WChar(name);
01009         len*=2;
01010     } 
01011     else {  //Unicode
01012         FileName=name;
01013     }
01014 
01015     TStrLen=GetFullPathName(FileName,1024,NameWithPath,&NamePos);
01016 
01017     len=TStrLen*2+2;  //add the terminating null character
01018 
01019     // Try to catch malformed strings
01020     if(len>2048){
01021         if(((PUCHAR)name)[1]!=0 && len>1) free(FileName);
01022         return FALSE;
01023     }
01024 
01025     res = DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL);
01026     free(FileName);
01027     return res;
01028 }
01029 
01045 BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks)
01046 {
01047     DWORD       BytesReturned;
01048     UINT valbuff[2];
01049 
01050     valbuff[0] = maxfilesize;
01051     valbuff[1] = maxnpacks;
01052 
01053     return DeviceIoControl(AdapterObject->hFile,
01054         pBIOCSETDUMPLIMITS,
01055         valbuff,
01056         sizeof valbuff,
01057         NULL,
01058         0,
01059         &BytesReturned,
01060         NULL);  
01061 }
01062 
01076 BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync)
01077 {
01078     DWORD       BytesReturned;
01079     int     IsDumpEnded;
01080     BOOLEAN res;
01081 
01082     if(sync)
01083         WaitForSingleObject(AdapterObject->ReadEvent, INFINITE);
01084 
01085     res = DeviceIoControl(AdapterObject->hFile,
01086         pBIOCISDUMPENDED,
01087         NULL,
01088         0,
01089         &IsDumpEnded,
01090         4,
01091         &BytesReturned,
01092         NULL);
01093 
01094     if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished
01095 
01096     return (BOOLEAN)IsDumpEnded;
01097 }
01098 
01118 HANDLE PacketGetReadEvent(LPADAPTER AdapterObject)
01119 {
01120     return AdapterObject->ReadEvent;
01121 }
01122 
01131 BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)
01132 {
01133     DWORD BytesReturned;
01134     return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL);
01135 }
01136 
01149 BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)
01150 {
01151     DWORD BytesReturned;
01152     int DriverTimeOut=-1;
01153 
01154     AdapterObject->ReadTimeOut=timeout;
01155 
01156     return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL);
01157 }
01158 
01175 BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)
01176 {
01177     DWORD BytesReturned;
01178     return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL);
01179 }
01180 
01201 BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp)
01202 {
01203     DWORD BytesReturned;
01204     return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL);
01205 }
01206 
01220 BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)
01221 {
01222     BOOLEAN Res;
01223     DWORD BytesReturned;
01224     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
01225 
01226     Res = DeviceIoControl(AdapterObject->hFile,
01227         pBIOCGSTATS,
01228         NULL,
01229         0,
01230         &tmpstat,
01231         sizeof(struct bpf_stat),
01232         &BytesReturned,
01233         NULL);
01234 
01235     // Copy only the first two values retrieved from the driver
01236     s->bs_recv = tmpstat.bs_recv;
01237     s->bs_drop = tmpstat.bs_drop;
01238 
01239     return Res;
01240 }
01241 
01254 BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s)
01255 {
01256     BOOLEAN Res;
01257     DWORD BytesReturned;
01258     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
01259 
01260     Res = DeviceIoControl(AdapterObject->hFile,
01261         pBIOCGSTATS,
01262         NULL,
01263         0,
01264         &tmpstat,
01265         sizeof(struct bpf_stat),
01266         &BytesReturned,
01267         NULL);
01268 
01269     s->bs_recv = tmpstat.bs_recv;
01270     s->bs_drop = tmpstat.bs_drop;
01271     s->ps_ifdrop = tmpstat.ps_ifdrop;
01272     s->bs_capt = tmpstat.bs_capt;
01273 
01274     return Res;
01275 }
01276 
01289 BOOLEAN PacketRequest(LPADAPTER  AdapterObject,BOOLEAN Set,PPACKET_OID_DATA  OidData)
01290 {
01291     DWORD       BytesReturned;
01292     BOOLEAN     Result;
01293 
01294     Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? pBIOCSETOID : pBIOCQUERYOID,
01295                            OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData,
01296                            sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL);
01297     
01298     // output some debug info
01299     ODSEx("PacketRequest, OID=%d ", OidData->Oid);
01300     ODSEx("Length=%d ", OidData->Length);
01301     ODSEx("Set=%d ", Set);
01302     ODSEx("Res=%d\n", Result);
01303 
01304     return Result;
01305 }
01306 
01323 BOOLEAN PacketSetHwFilter(LPADAPTER  AdapterObject,ULONG Filter)
01324 {
01325     BOOLEAN    Status;
01326     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
01327     PPACKET_OID_DATA  OidData;
01328 
01329     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
01330     if (OidData == NULL) {
01331         ODS("PacketSetHwFilter: GlobalAlloc Failed\n");
01332         return FALSE;
01333     }
01334     OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER;
01335     OidData->Length=sizeof(ULONG);
01336     *((PULONG)OidData->Data)=Filter;
01337     Status=PacketRequest(AdapterObject,TRUE,OidData);
01338     GlobalFreePtr(OidData);
01339     return Status;
01340 }
01341 
01371 BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG  BufferSize)
01372 {
01373     HKEY        LinkageKey,AdapKey;
01374     DWORD       RegKeySize=0;
01375     LONG        Status;
01376     ULONG       Result;
01377     PTSTR       BpStr;
01378     char        *TTpStr,*DpStr,*DescBuf;
01379     LPADAPTER   adapter;
01380     PPACKET_OID_DATA  OidData;
01381     int         i=0,k,rewind;
01382     DWORD       dim;
01383     TCHAR       AdapName[256];
01384 
01385     ODSEx("PacketGetAdapterNames: BufferSize=%d\n",*BufferSize);
01386 
01387     OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,512);
01388     if (OidData == NULL) {
01389         ODS("PacketGetAdapterNames: GlobalAlloc Failed\n");
01390         return FALSE;
01391     }
01392 
01393     Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
01394                         TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"),
01395                         0,
01396                         KEY_READ,
01397                         &AdapKey);
01398 
01399     // Get the size to allocate for the original device names
01400     while((Result=RegEnumKey(AdapKey,i,AdapName,sizeof(AdapName)/2))==ERROR_SUCCESS)
01401     {
01402         Status=RegOpenKeyEx(AdapKey,AdapName,0,KEY_READ,&LinkageKey);
01403         Status=RegOpenKeyEx(LinkageKey,L"Linkage",0,KEY_READ,&LinkageKey);
01404         Status=RegQueryValueEx(LinkageKey,L"Export",NULL,NULL,NULL,&dim);
01405         i++;
01406         if(Status!=ERROR_SUCCESS) continue;
01407         RegKeySize+=dim;
01408     }
01409     
01410     // Allocate the memory for the original device names
01411     ODSEx("Need %d bytes for the names\n", RegKeySize+2);
01412     BpStr=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,RegKeySize+2);
01413     if (BpStr == NULL || RegKeySize > *BufferSize) {
01414         ODS("PacketGetAdapterNames: GlobalAlloc Failed\n");
01415         GlobalFreePtr(OidData);
01416         return FALSE;
01417     }
01418 
01419     k=0;
01420     i=0;
01421 
01422     ODS("PacketGetAdapterNames: Cycling through the adapters:\n");
01423 
01424     // Copy the names to the buffer
01425     while((Result=RegEnumKey(AdapKey,i,AdapName,sizeof(AdapName)/2))==ERROR_SUCCESS)
01426     {
01427         WCHAR UpperBindStr[64];
01428 
01429         i++;
01430         ODSEx(" %d) ", i);
01431 
01432         Status=RegOpenKeyEx(AdapKey,AdapName,0,KEY_READ,&LinkageKey);
01433         Status=RegOpenKeyEx(LinkageKey,L"Linkage",0,KEY_READ,&LinkageKey);
01434 
01435         dim=sizeof(UpperBindStr);
01436         Status=RegQueryValueEx(LinkageKey,L"UpperBind",NULL,NULL,(PUCHAR)UpperBindStr,&dim);
01437         
01438         ODSEx("UpperBind=%S ", UpperBindStr);
01439 
01440         if( Status!=ERROR_SUCCESS || _wcsicmp(UpperBindStr,L"NdisWan")==0 ){
01441             ODS("Name = SKIPPED\n");
01442             continue;
01443         }
01444 
01445         dim=RegKeySize-k;
01446         Status=RegQueryValueEx(LinkageKey,L"Export",NULL,NULL,(LPBYTE)BpStr+k,&dim);
01447         if(Status!=ERROR_SUCCESS){
01448             ODS("Name = SKIPPED (error reading the key)\n");
01449             continue;
01450         }
01451 
01452         ODSEx("Name = %S\n", (LPBYTE)BpStr+k);
01453 
01454         k+=dim-2;
01455     }
01456 
01457     CloseHandle(AdapKey);
01458 
01459 #ifdef _DEBUG_TO_FILE
01460     //dump BpStr for debug purposes
01461     ODS("Dumping BpStr:");
01462     {
01463         FILE *f;
01464         f = fopen("winpcap_debug.txt", "a");
01465         for(i=0;i<k;i++){
01466             if(!(i%32))fprintf(f, "\n ");
01467             fprintf(f, "%c " , *((LPBYTE)BpStr+i));
01468         }
01469         fclose(f);
01470     }
01471     ODS("\n");
01472 #endif
01473 
01474     
01475     if (k != 0){
01476         
01477         DescBuf=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096);
01478         if (DescBuf == NULL) {
01479             GlobalFreePtr (BpStr);
01480             GlobalFreePtr(OidData);
01481             return FALSE;
01482         }
01483         DpStr=DescBuf;
01484                 
01485         for(i=0,k=0;BpStr[i]!=0 || BpStr[i+1]!=0;){
01486             
01487             if(k+wcslen(BpStr+i)+30 > *BufferSize){
01488                 // Input buffer too small
01489                 GlobalFreePtr(OidData);
01490                 GlobalFreePtr (BpStr);
01491                 GlobalFreePtr (DescBuf);
01492                 ODS("PacketGetAdapterNames: Input buffer too small!\n");
01493                 return FALSE;
01494             }
01495 
01496             // Create the device name
01497             rewind=k;
01498             memcpy(pStr+k,BpStr+i,16);
01499             memcpy(pStr+k+8,TEXT("NPF_"),8);
01500             i+=8;
01501             k+=12;
01502             while(BpStr[i-1]!=0){
01503                 pStr[k++]=BpStr[i++];
01504             }
01505 
01506             // Open the adapter
01507             adapter=PacketOpenAdapter(pStr+rewind);
01508             if(adapter==NULL){
01509                 k=rewind;
01510                 continue;
01511             }
01512 
01513             // Retrieve the description
01514             OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
01515             OidData->Length = 256;
01516             ZeroMemory(OidData->Data,256);
01517             Status = PacketRequest(adapter,FALSE,OidData);
01518             if(Status==0 || ((char*)OidData->Data)[0]==0){
01519                 k=rewind;
01520                 continue;
01521             }
01522 
01523             ODSEx("Adapter Description=%s\n\n",OidData->Data);
01524 
01525             // Copy the description
01526             TTpStr=(char*)(OidData->Data);
01527             while(*TTpStr!=0){
01528                 *DpStr++=*TTpStr++;
01529             }
01530             *DpStr++=*TTpStr++;
01531             
01532             // Close the adapter
01533             PacketCloseAdapter(adapter);
01534             
01535         }
01536         *DpStr=0;
01537 
01538         pStr[k++]=0;
01539         pStr[k]=0;
01540 
01541         if((ULONG)(DpStr-DescBuf+k) < *BufferSize)
01542             memcpy(pStr+k,DescBuf,DpStr-DescBuf);
01543         else{
01544             GlobalFreePtr(OidData);
01545             GlobalFreePtr (BpStr);
01546             GlobalFreePtr (DescBuf);
01547             ODS("\nPacketGetAdapterNames: ended with failure\n");
01548             return FALSE;
01549         }
01550 
01551         GlobalFreePtr(OidData);
01552         GlobalFreePtr (BpStr);
01553         GlobalFreePtr (DescBuf);
01554         ODS("\nPacketGetAdapterNames: ended correctly\n");
01555         return TRUE;
01556     }
01557     else{
01558         DWORD      RegType;
01559 
01560         ODS("Adapters not found under SYSTEM\\CurrentControlSet\\Control\\Class. Using the TCP/IP bindings.\n");
01561 
01562         GlobalFreePtr (BpStr);
01563 
01564         Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage"),0,KEY_READ,&LinkageKey);
01565         if (Status == ERROR_SUCCESS)
01566         {
01567             // Retrieve the length of the key
01568             Status=RegQueryValueEx(LinkageKey,TEXT("bind"),NULL,&RegType,NULL,&RegKeySize);
01569             // Allocate the buffer
01570             BpStr=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,RegKeySize+2);
01571             if (BpStr == NULL || RegKeySize > *BufferSize) {
01572                 GlobalFreePtr(OidData);
01573                 return FALSE;
01574             }
01575             Status=RegQueryValueEx(LinkageKey,TEXT("bind"),NULL,&RegType,(LPBYTE)BpStr,&RegKeySize);
01576             RegCloseKey(LinkageKey);
01577         }
01578         
01579         if (Status==ERROR_SUCCESS){
01580             
01581             DescBuf=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096);
01582             if (DescBuf == NULL) {
01583                 GlobalFreePtr (BpStr);
01584                 GlobalFreePtr(OidData);
01585                 return FALSE;
01586             }
01587             DpStr=DescBuf;
01588             
01589             for(i=0,k=0;BpStr[i]!=0 || BpStr[i+1]!=0;){
01590                 
01591                 if(k+wcslen(BpStr+i)+30 > *BufferSize){
01592                     // Input buffer too small
01593                     GlobalFreePtr(OidData);
01594                     GlobalFreePtr (BpStr);
01595                     GlobalFreePtr (DescBuf);
01596                     return FALSE;
01597                 }
01598                 
01599                 // Create the device name
01600                 rewind=k;
01601                 memcpy(pStr+k,BpStr+i,16);
01602                 memcpy(pStr+k+8,TEXT("NPF_"),8);
01603                 i+=8;
01604                 k+=12;
01605                 while(BpStr[i-1]!=0){
01606                     pStr[k++]=BpStr[i++];
01607                 }
01608                 
01609                 // Open the adapter
01610                 adapter=PacketOpenAdapter(pStr+rewind);
01611                 if(adapter==NULL){
01612                     k=rewind;
01613                     continue;
01614                 }
01615                 
01616                 // Retrieve the description
01617                 OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
01618                 OidData->Length = 256;
01619                 Status = PacketRequest(adapter,FALSE,OidData);
01620                 if(Status==0 || ((char*)OidData->Data)[0]==0){
01621                     k=rewind;
01622                     continue;
01623                 }
01624                 
01625                 // Copy the description
01626                 TTpStr=(char*)(OidData->Data);
01627                 while(*TTpStr!=0){
01628                     *DpStr++=*TTpStr++;
01629                 }
01630                 *DpStr++=*TTpStr++;
01631                 
01632                 // Close the adapter
01633                 PacketCloseAdapter(adapter);
01634                 
01635             }
01636             *DpStr=0;
01637             
01638             pStr[k++]=0;
01639             pStr[k]=0;
01640             
01641             if((ULONG)(DpStr-DescBuf+k) < *BufferSize)
01642                 memcpy(pStr+k,DescBuf,DpStr-DescBuf);
01643             else{
01644                 GlobalFreePtr(OidData);
01645                 GlobalFreePtr (BpStr);
01646                 GlobalFreePtr (DescBuf);
01647                 return FALSE;
01648             }
01649             
01650             GlobalFreePtr(OidData);
01651             GlobalFreePtr (BpStr);
01652             GlobalFreePtr (DescBuf);
01653             return TRUE;
01654         }
01655         else{
01656             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);
01657             ODS("Cannot find the TCP/IP bindings");
01658             return FALSE;
01659         }
01660     }
01661 }
01662 
01677 BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterName, npf_if_addr* buffer, PLONG NEntries)
01678 {
01679     char    *AdapterNameA;
01680     WCHAR   *AdapterNameU;
01681     WCHAR   *ifname;
01682     HKEY    SystemKey;
01683     HKEY    InterfaceKey;
01684     HKEY    ParametersKey;
01685     HKEY    TcpIpKey;
01686     HKEY    UnderTcpKey;
01687     LONG    status;
01688     WCHAR   String[1024+1];
01689     DWORD   RegType;
01690     ULONG   BufLen;
01691     DWORD   DHCPEnabled;
01692     struct  sockaddr_in *TmpAddr, *TmpBroad;
01693     LONG    naddrs,nmasks,StringPos;
01694     DWORD   ZeroBroadcast;
01695 
01696     AdapterNameA = (char*)AdapterName;
01697     if(AdapterNameA[1] != 0) {  //ASCII
01698         AdapterNameU = SChar2WChar(AdapterNameA);
01699         AdapterName = AdapterNameU;
01700     } else {                //Unicode
01701         AdapterNameU = NULL;
01702     }
01703     ifname = wcsrchr(AdapterName, '\\');
01704     if (ifname == NULL)
01705         ifname = AdapterName;
01706     else
01707         ifname++;
01708     if (wcsncmp(ifname, L"NPF_", 4) == 0)
01709         ifname += 4;
01710 
01711     if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"), 0, KEY_READ, &UnderTcpKey) == ERROR_SUCCESS)
01712     {
01713         status = RegOpenKeyEx(UnderTcpKey,ifname,0,KEY_READ,&TcpIpKey);
01714         if (status != ERROR_SUCCESS) {
01715             RegCloseKey(UnderTcpKey);
01716             goto fail;
01717         }
01718     }
01719     else
01720     {
01721         
01722         // Query the registry key with the interface's adresses
01723         status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey);
01724         if (status != ERROR_SUCCESS)
01725             goto fail;
01726         status = RegOpenKeyEx(SystemKey,ifname,0,KEY_READ,&InterfaceKey);
01727         if (status != ERROR_SUCCESS) {
01728             RegCloseKey(SystemKey);
01729             goto fail;
01730         }
01731         RegCloseKey(SystemKey);
01732         status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey);
01733         if (status != ERROR_SUCCESS) {
01734             RegCloseKey(InterfaceKey);
01735             goto fail;
01736         }
01737         RegCloseKey(InterfaceKey);
01738         status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey);
01739         if (status != ERROR_SUCCESS) {
01740             RegCloseKey(ParametersKey);
01741             goto fail;
01742         }
01743         RegCloseKey(ParametersKey);
01744         BufLen = sizeof String;
01745     }
01746 
01747     BufLen = 4;
01748     /* Try to detect if the interface has a zero broadcast addr */
01749     status=RegQueryValueEx(TcpIpKey,TEXT("UseZeroBroadcast"),NULL,&RegType,(LPBYTE)&ZeroBroadcast,&BufLen);
01750     if (status != ERROR_SUCCESS)
01751         ZeroBroadcast=0;
01752     
01753     BufLen = 4;
01754     /* See if DHCP is used by this system */
01755     status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen);
01756     if (status != ERROR_SUCCESS)
01757         DHCPEnabled=0;
01758     
01759     
01760     /* Retrieve the adrresses */
01761     if(DHCPEnabled){
01762         
01763         BufLen = sizeof String;
01764         // Open the key with the addresses
01765         status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
01766         if (status != ERROR_SUCCESS) {
01767             RegCloseKey(TcpIpKey);
01768             goto fail;
01769         }
01770 
01771         // scan the key to obtain the addresses
01772         StringPos = 0;
01773         for(naddrs = 0;naddrs <* NEntries;naddrs++){
01774             TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
01775             
01776             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
01777                 TmpAddr->sin_family = AF_INET;
01778                 
01779                 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
01780                 TmpBroad->sin_family = AF_INET;
01781                 if(ZeroBroadcast==0)
01782                     TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
01783                 else
01784                     TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
01785 
01786                 while(*(String + StringPos) != 0)StringPos++;
01787                 StringPos++;
01788                 
01789                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
01790                     break;              
01791             }
01792             else break;
01793         }       
01794         
01795         BufLen = sizeof String;
01796         // Open the key with the netmasks
01797         status = RegQueryValueEx(TcpIpKey,TEXT("DhcpSubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
01798         if (status != ERROR_SUCCESS) {
01799             RegCloseKey(TcpIpKey);
01800             goto fail;
01801         }
01802         
01803         // scan the key to obtain the masks
01804         StringPos = 0;
01805         for(nmasks = 0;nmasks < *NEntries;nmasks++){
01806             TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
01807             
01808             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
01809                 TmpAddr->sin_family = AF_INET;
01810                 
01811                 while(*(String + StringPos) != 0)StringPos++;
01812                 StringPos++;
01813                                 
01814                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
01815                     break;
01816             }
01817             else break;
01818         }       
01819         
01820         // The number of masks MUST be equal to the number of adresses
01821         if(nmasks != naddrs){
01822             RegCloseKey(TcpIpKey);
01823             goto fail;
01824         }
01825                 
01826     }
01827     else{
01828         
01829         BufLen = sizeof String;
01830         // Open the key with the addresses
01831         status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
01832         if (status != ERROR_SUCCESS) {
01833             RegCloseKey(TcpIpKey);
01834             goto fail;
01835         }
01836         
01837         // scan the key to obtain the addresses
01838         StringPos = 0;
01839         for(naddrs = 0;naddrs < *NEntries;naddrs++){
01840             TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
01841             
01842             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
01843                 TmpAddr->sin_family = AF_INET;
01844 
01845                 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
01846                 TmpBroad->sin_family = AF_INET;
01847                 if(ZeroBroadcast==0)
01848                     TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
01849                 else
01850                     TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
01851                 
01852                 while(*(String + StringPos) != 0)StringPos++;
01853                 StringPos++;
01854                 
01855                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
01856                     break;
01857             }
01858             else break;
01859         }       
01860         
01861         BufLen = sizeof String;
01862         // Open the key with the netmasks
01863         status = RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
01864         if (status != ERROR_SUCCESS) {
01865             RegCloseKey(TcpIpKey);
01866             goto fail;
01867         }
01868         
01869         // scan the key to obtain the masks
01870         StringPos = 0;
01871         for(nmasks = 0;nmasks <* NEntries;nmasks++){
01872             TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
01873             
01874             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
01875                 TmpAddr->sin_family = AF_INET;
01876                 
01877                 while(*(String + StringPos) != 0)StringPos++;
01878                 StringPos++;
01879                 
01880                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
01881                     break;
01882             }
01883             else break;
01884         }       
01885         
01886         // The number of masks MUST be equal to the number of adresses
01887         if(nmasks != naddrs){
01888             RegCloseKey(TcpIpKey);
01889             goto fail;
01890         }
01891                 
01892     }
01893     
01894     *NEntries = naddrs + 1;
01895 
01896     RegCloseKey(TcpIpKey);
01897     
01898     if (status != ERROR_SUCCESS) {
01899         goto fail;
01900     }
01901     
01902     
01903     if (AdapterNameU != NULL)
01904         free(AdapterNameU);
01905     return TRUE;
01906     
01907 fail:
01908     if (AdapterNameU != NULL)
01909         free(AdapterNameU);
01910     return FALSE;
01911 }
01912 
01923 BOOLEAN PacketGetNetInfo(LPTSTR AdapterName, PULONG netp, PULONG maskp)
01924 {
01925     char    *AdapterNameA;
01926     WCHAR   *AdapterNameU;
01927     WCHAR   *ifname;
01928     HKEY    SystemKey;
01929     HKEY    InterfaceKey;
01930     HKEY    ParametersKey;
01931     HKEY    TcpIpKey;
01932     LONG    status;
01933     WCHAR   String[1024+1];
01934     DWORD   RegType;
01935     ULONG   BufLen;
01936     DWORD   DHCPEnabled;
01937     ULONG   TAddr,i;
01938 
01939     AdapterNameA = (char*)AdapterName;
01940     if(AdapterNameA[1] != 0) {  //ASCII
01941         AdapterNameU = SChar2WChar(AdapterNameA);
01942         AdapterName = AdapterNameU;
01943     } else {                //Unicode
01944         AdapterNameU = NULL;
01945     }
01946     ifname = wcsrchr(AdapterName, '\\');
01947     if (ifname == NULL)
01948         ifname = AdapterName;
01949     else
01950         ifname++;
01951     if (wcsncmp(ifname, L"NPF_", 4) == 0)
01952         ifname += 4;
01953     status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey);
01954     if (status != ERROR_SUCCESS)
01955         goto fail;
01956     status = RegOpenKeyEx(SystemKey,ifname,0,KEY_READ,&InterfaceKey);
01957     if (status != ERROR_SUCCESS) {
01958         RegCloseKey(SystemKey);
01959         goto fail;
01960     }
01961     RegCloseKey(SystemKey);
01962     status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey);
01963     if (status != ERROR_SUCCESS) {
01964         RegCloseKey(InterfaceKey);
01965         goto fail;
01966     }
01967     RegCloseKey(InterfaceKey);
01968     status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey);
01969     if (status != ERROR_SUCCESS) {
01970         RegCloseKey(ParametersKey);
01971         goto fail;
01972     }
01973     RegCloseKey(ParametersKey);
01974         
01975     BufLen = 4;
01976     /* See if DHCP is used by this system */
01977     status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen);
01978     if (status != ERROR_SUCCESS)
01979         DHCPEnabled=0;
01980 
01981     
01982     /* Retrieve the netmask */
01983     if(DHCPEnabled){
01984         
01985         BufLen = sizeof String;
01986         status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
01987         if (status != ERROR_SUCCESS) {
01988             RegCloseKey(TcpIpKey);
01989             goto fail;
01990         }
01991 
01992         TAddr = inet_addrU(String);
01993         // swap bytes for backward compatibility
01994         for(i=0;i<4;i++){
01995             *((char*)netp+i) = *((char*)&TAddr+3-i);
01996         }
01997         
01998         BufLen = sizeof String;
01999         status=RegQueryValueEx(TcpIpKey,TEXT("DHCPSubnetMask"),NULL,&RegType,
02000             (LPBYTE)String,&BufLen);
02001         
02002         TAddr = inet_addrU(String);
02003         // swap bytes for backward compatibility
02004         for(i=0;i<4;i++){
02005             *((char*)maskp+i) = *((char*)&TAddr+3-i);
02006         }
02007         
02008         
02009     }
02010     else{
02011 
02012         BufLen = sizeof String;
02013         status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
02014         if (status != ERROR_SUCCESS) {
02015             RegCloseKey(TcpIpKey);
02016             goto fail;
02017         }
02018 
02019         TAddr = inet_addrU(String);
02020         // swap bytes for backward compatibility
02021         for(i=0;i<4;i++){
02022             *((char*)netp+i) = *((char*)&TAddr+3-i);
02023         }
02024         
02025         BufLen = sizeof String;
02026         status=RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,
02027             (LPBYTE)String,&BufLen);
02028         
02029         TAddr = inet_addrU(String);
02030         // swap bytes for backward compatibility
02031         for(i=0;i<4;i++){
02032             *((char*)maskp+i) = *((char*)&TAddr+3-i);
02033         }
02034 
02035 
02036     }
02037     
02038     if (status != ERROR_SUCCESS) {
02039         RegCloseKey(TcpIpKey);
02040         goto fail;
02041     }
02042     
02043         
02044     if (AdapterNameU != NULL)
02045         free(AdapterNameU);
02046     return TRUE;
02047     
02048 fail:
02049     if (AdapterNameU != NULL)
02050         free(AdapterNameU);
02051     return FALSE;
02052 }
02053 
02054 /* @} */

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