00001 /* 00002 * Copyright (c) 1999 - 2003 00003 * NetGroup, Politecnico di Torino (Italy) 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 2. Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * 3. Neither the name of the Politecnico di Torino nor the names of its 00016 * contributors may be used to endorse or promote products derived from 00017 * this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00020 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00021 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00022 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00023 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00024 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00025 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00026 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00027 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00029 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 * 00031 */ 00032 00033 #define UNICODE 1 00034 00035 #include <packet32.h> 00036 00037 #include <windows.h> 00038 #include <windowsx.h> 00039 00040 #include <ntddndis.h> 00041 00042 00044 TCHAR szWindowTitle[] = TEXT("PACKET.DLL"); 00045 00046 #if _DBG 00047 #define ODS(_x) OutputDebugString(TEXT(_x)) 00048 #define ODSEx(_x, _y) 00049 #else 00050 #ifdef _DEBUG_TO_FILE 00051 #include <stdio.h> 00055 #define ODS(_x) { \ 00056 FILE *f; \ 00057 f = fopen("winpcap_debug.txt", "a"); \ 00058 fprintf(f, "%s", _x); \ 00059 fclose(f); \ 00060 } 00061 00065 #define ODSEx(_x, _y) { \ 00066 FILE *f; \ 00067 f = fopen("winpcap_debug.txt", "a"); \ 00068 fprintf(f, _x, _y); \ 00069 fclose(f); \ 00070 } 00071 00072 00073 00074 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName); 00075 #else 00076 #define ODS(_x) 00077 #define ODSEx(_x, _y) 00078 #endif 00079 #endif 00080 00081 //service handles 00082 SC_HANDLE scmHandle = NULL; 00083 SC_HANDLE srvHandle = NULL; 00084 LPCTSTR NPFServiceName = TEXT("NPF"); 00085 LPCTSTR NPFServiceDesc = TEXT("Netgroup Packet Filter"); 00086 LPCTSTR NPFRegistryLocation = TEXT("SYSTEM\\CurrentControlSet\\Services\\NPF"); 00087 LPCTSTR NPFDriverPath = TEXT("system32\\drivers\\npf.sys"); 00088 00089 //--------------------------------------------------------------------------- 00090 00095 BOOL APIENTRY DllMain (HANDLE DllHandle,DWORD Reason,LPVOID lpReserved) 00096 { 00097 BOOLEAN Status=TRUE; 00098 00099 switch ( Reason ) 00100 { 00101 case DLL_PROCESS_ATTACH: 00102 00103 ODS("************Packet32: DllMain************\n"); 00104 00105 #ifdef _DEBUG_TO_FILE 00106 // dump a bunch of registry keys useful for debug to file 00107 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 00108 "adapters.reg"); 00109 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip", 00110 "tcpip.reg"); 00111 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\NPF", 00112 "npf.reg"); 00113 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services", 00114 "services.reg"); 00115 #endif 00116 break; 00117 00118 case DLL_PROCESS_DETACH: 00119 break; 00120 00121 default: 00122 break; 00123 } 00124 00125 return Status; 00126 } 00127 00134 WCHAR* SChar2WChar(char* string) 00135 { 00136 WCHAR* TmpStr; 00137 TmpStr=(WCHAR*) malloc ((strlen(string)+2)*sizeof(WCHAR)); 00138 00139 MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (strlen(string)+2)); 00140 00141 return TmpStr; 00142 } 00143 00153 BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject) 00154 { 00155 BOOLEAN Status; 00156 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); 00157 PPACKET_OID_DATA OidData; 00158 00159 OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); 00160 if (OidData == NULL) { 00161 ODS("PacketSetMaxLookaheadsize failed\n"); 00162 return FALSE; 00163 } 00164 00165 //set the size of the lookahead buffer to the maximum available by the the NIC driver 00166 OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD; 00167 OidData->Length=sizeof(ULONG); 00168 Status=PacketRequest(AdapterObject,FALSE,OidData); 00169 OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD; 00170 Status=PacketRequest(AdapterObject,TRUE,OidData); 00171 GlobalFreePtr(OidData); 00172 return Status; 00173 } 00174 00185 BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject) 00186 { 00187 DWORD BytesReturned; 00188 TCHAR EventName[39]; 00189 00190 // this tells the terminal service to retrieve the event from the global namespace 00191 wcsncpy(EventName,L"Global\\",sizeof(L"Global\\")); 00192 00193 // retrieve the name of the shared event from the driver 00194 if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName+7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) return FALSE; 00195 00196 EventName[20]=0; // terminate the string 00197 00198 // open the shared event 00199 AdapterObject->ReadEvent=CreateEvent(NULL, 00200 TRUE, 00201 FALSE, 00202 EventName); 00203 00204 // in NT4 "Global\" is not automatically ignored: try to use simply the event name 00205 if(GetLastError()!=ERROR_ALREADY_EXISTS){ 00206 if(AdapterObject->ReadEvent != NULL) 00207 CloseHandle(AdapterObject->ReadEvent); 00208 00209 // open the shared event 00210 AdapterObject->ReadEvent=CreateEvent(NULL, 00211 TRUE, 00212 FALSE, 00213 EventName+7); 00214 } 00215 00216 if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){ 00217 ODS("PacketSetReadEvt: error retrieving the event from the kernel\n"); 00218 return FALSE; 00219 } 00220 00221 AdapterObject->ReadTimeOut=0; 00222 00223 return TRUE; 00224 } 00225 00235 BOOL PacketInstallDriver(SC_HANDLE ascmHandle,SC_HANDLE *srvHandle) 00236 { 00237 BOOL result = FALSE; 00238 ULONG err; 00239 00240 ODS("installdriver\n"); 00241 00242 *srvHandle = CreateService(ascmHandle, 00243 NPFServiceName, 00244 NPFServiceDesc, 00245 SERVICE_ALL_ACCESS, 00246 SERVICE_KERNEL_DRIVER, 00247 SERVICE_DEMAND_START, 00248 SERVICE_ERROR_NORMAL, 00249 NPFDriverPath, 00250 NULL, NULL, NULL, NULL, NULL); 00251 if (*srvHandle == NULL) 00252 { 00253 if (GetLastError() == ERROR_SERVICE_EXISTS) 00254 { 00255 //npf.sys already existed 00256 result = TRUE; 00257 } 00258 } 00259 else 00260 { 00261 //Created service for npf.sys 00262 result = TRUE; 00263 } 00264 if (result == TRUE) 00265 if (*srvHandle != NULL) 00266 CloseServiceHandle(*srvHandle); 00267 00268 if(result == FALSE){ 00269 err = GetLastError(); 00270 if(err != 2) 00271 ODSEx("PacketInstallDriver failed, Error=%d\n",err); 00272 } 00273 return result; 00274 00275 } 00276 00286 ULONG inet_addrU(const WCHAR *cp) 00287 { 00288 ULONG val, part; 00289 WCHAR c; 00290 int i; 00291 00292 val = 0; 00293 for (i = 0; i < 4; i++) { 00294 part = 0; 00295 while ((c = *cp++) != '\0' && c != '.') { 00296 if (c < '0' || c > '9') 00297 return -1; 00298 part = part*10 + (c - '0'); 00299 } 00300 if (part > 255) 00301 return -1; 00302 val = val | (part << i*8); 00303 if (i == 3) { 00304 if (c != '\0') 00305 return -1; // extra gunk at end of string 00306 } else { 00307 if (c == '\0') 00308 return -1; // string ends early 00309 } 00310 } 00311 return val; 00312 } 00313 00323 #ifdef _DEBUG_TO_FILE 00324 00325 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName) 00326 { 00327 CHAR Command[256]; 00328 00329 strcpy(Command, "regedit /e "); 00330 strcat(Command, FileName); 00331 strcat(Command, " "); 00332 strcat(Command, KeyName); 00333 00335 system(Command); 00336 00337 return TRUE; 00338 } 00339 #endif 00340 00341 //--------------------------------------------------------------------------- 00342 // PUBLIC API 00343 //--------------------------------------------------------------------------- 00344 00353 00354 char PacketLibraryVersion[] = "3.0.1 alpha"; 00355 00360 PCHAR PacketGetVersion(){ 00361 return PacketLibraryVersion; 00362 } 00363 00380 BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type) 00381 { 00382 BOOLEAN Status; 00383 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); 00384 PPACKET_OID_DATA OidData; 00385 00386 OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); 00387 if (OidData == NULL) { 00388 ODS("PacketGetNetType failed\n"); 00389 return FALSE; 00390 } 00391 //get the link-layer type 00392 OidData->Oid = OID_GEN_MEDIA_IN_USE; 00393 OidData->Length = sizeof (ULONG); 00394 Status = PacketRequest(AdapterObject,FALSE,OidData); 00395 type->LinkType=*((UINT*)OidData->Data); 00396 00397 //get the link-layer speed 00398 OidData->Oid = OID_GEN_LINK_SPEED; 00399 OidData->Length = sizeof (ULONG); 00400 Status = PacketRequest(AdapterObject,FALSE,OidData); 00401 type->LinkSpeed=*((UINT*)OidData->Data)*100; 00402 GlobalFreePtr (OidData); 00403 00404 ODSEx("Media:%d ",type->LinkType); 00405 ODSEx("Speed=%d\n",type->LinkSpeed); 00406 00407 return Status; 00408 } 00409 00418 BOOL PacketStopDriver() 00419 { 00420 SC_HANDLE scmHandle; 00421 SC_HANDLE schService; 00422 BOOL ret; 00423 SERVICE_STATUS serviceStatus; 00424 00425 scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 00426 00427 if(scmHandle != NULL){ 00428 00429 schService = OpenService (scmHandle, 00430 NPFServiceName, 00431 SERVICE_ALL_ACCESS 00432 ); 00433 00434 if (schService != NULL) 00435 { 00436 00437 ret = ControlService (schService, 00438 SERVICE_CONTROL_STOP, 00439 &serviceStatus 00440 ); 00441 if (!ret) 00442 { 00443 } 00444 00445 CloseServiceHandle (schService); 00446 00447 CloseServiceHandle(scmHandle); 00448 00449 return ret; 00450 } 00451 } 00452 00453 return FALSE; 00454 00455 } 00456 00479 LPADAPTER PacketOpenAdapter(LPTSTR AdapterName) 00480 { 00481 LPADAPTER lpAdapter; 00482 BOOLEAN Result; 00483 char *AdapterNameA; 00484 WCHAR *AdapterNameU; 00485 DWORD error; 00486 SC_HANDLE svcHandle = NULL; 00487 LONG KeyRes; 00488 HKEY PathKey; 00489 SERVICE_STATUS SStat; 00490 BOOLEAN QuerySStat; 00491 WCHAR SymbolicLink[128]; 00492 00493 ODSEx("PacketOpenAdapter: trying to open the adapter=%S\n",AdapterName) 00494 00495 scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 00496 00497 if(scmHandle == NULL){ 00498 error = GetLastError(); 00499 ODSEx("OpenSCManager failed! Error=%d\n", error); 00500 } 00501 else{ 00502 // check if the NPF registry key is already present 00503 // this means that the driver is already installed and that we don't need to call PacketInstallDriver 00504 KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE, 00505 NPFRegistryLocation, 00506 0, 00507 KEY_READ, 00508 &PathKey); 00509 00510 if(KeyRes != ERROR_SUCCESS) 00511 { 00512 Result = PacketInstallDriver(scmHandle,&svcHandle); 00513 } 00514 else 00515 { 00516 Result = TRUE; 00517 RegCloseKey(PathKey); 00518 } 00519 00520 if (Result) 00521 { 00522 00523 srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS ); 00524 if (srvHandle != NULL) 00525 { 00526 QuerySStat = QueryServiceStatus(srvHandle, &SStat); 00527 ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState); 00528 00529 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING) 00530 { 00531 ODS("Calling startservice\n"); 00532 if (StartService(srvHandle, 0, NULL)==0) 00533 { 00534 error = GetLastError(); 00535 if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS) 00536 { 00537 SetLastError(error); 00538 if (scmHandle != NULL) 00539 CloseServiceHandle(scmHandle); 00540 error = GetLastError(); 00541 ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error); 00542 return NULL; 00543 } 00544 } 00545 } 00546 00547 CloseServiceHandle( srvHandle ); 00548 srvHandle = NULL; 00549 00550 } 00551 else 00552 { 00553 error = GetLastError(); 00554 ODSEx("OpenService failed! Error=%d", error); 00555 } 00556 } 00557 else 00558 { 00559 if(KeyRes != ERROR_SUCCESS) 00560 Result = PacketInstallDriver(scmHandle,&svcHandle); 00561 else 00562 Result = TRUE; 00563 00564 if (Result) { 00565 00566 srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START); 00567 if (srvHandle != NULL){ 00568 00569 QuerySStat = QueryServiceStatus(srvHandle, &SStat); 00570 ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState); 00571 00572 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){ 00573 00574 ODS("Calling startservice\n"); 00575 00576 if (StartService(srvHandle, 0, NULL)==0){ 00577 error = GetLastError(); 00578 if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){ 00579 SetLastError(error); 00580 if (scmHandle != NULL) CloseServiceHandle(scmHandle); 00581 ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error); 00582 return NULL; 00583 } 00584 } 00585 } 00586 00587 CloseServiceHandle( srvHandle ); 00588 srvHandle = NULL; 00589 00590 } 00591 else{ 00592 error = GetLastError(); 00593 ODSEx("OpenService failed! Error=%d", error); 00594 } 00595 } 00596 } 00597 } 00598 00599 if (scmHandle != NULL) CloseServiceHandle(scmHandle); 00600 00601 AdapterNameA=(char*)AdapterName; 00602 if(AdapterNameA[1]!=0){ //ASCII 00603 AdapterNameU=SChar2WChar(AdapterNameA); 00604 AdapterName=AdapterNameU; 00605 } else { //Unicode 00606 AdapterNameU=NULL; 00607 } 00608 00609 lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(ADAPTER)); 00610 if (lpAdapter==NULL) 00611 { 00612 ODS("PacketOpenAdapter: GlobalAlloc Failed\n"); 00613 error=GetLastError(); 00614 if (AdapterNameU != NULL) free(AdapterNameU); 00615 //set the error to the one on which we failed 00616 SetLastError(error); 00617 ODS("PacketOpenAdapter: Failed to allocate the adapter structure\n"); 00618 return NULL; 00619 } 00620 lpAdapter->NumWrites=1; 00621 00622 00623 00624 if (LOWORD(GetVersion()) == 4) 00625 wsprintf(SymbolicLink,TEXT("\\\\.\\%s"),&AdapterName[8]); 00626 else 00627 wsprintf(SymbolicLink,TEXT("\\\\.\\Global\\%s"),&AdapterName[8]); 00628 00629 // Copy only the bytes that fit in the adapter structure. 00630 // Note that lpAdapter->SymbolicLink is present for backward compatibility but will 00631 // never be used by the apps 00632 memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH); 00633 00634 //try if it is possible to open the adapter immediately 00635 lpAdapter->hFile=CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ, 00636 0,NULL,OPEN_EXISTING,0,0); 00637 00638 if (lpAdapter->hFile != INVALID_HANDLE_VALUE) 00639 { 00640 00641 if(PacketSetReadEvt(lpAdapter)==FALSE){ 00642 error=GetLastError(); 00643 ODS("PacketOpenAdapter: Unable to open the read event\n"); 00644 if (AdapterNameU != NULL) 00645 free(AdapterNameU); 00646 GlobalFreePtr(lpAdapter); 00647 //set the error to the one on which we failed 00648 SetLastError(error); 00649 ODSEx("PacketOpenAdapter: PacketSetReadEvt failed, Error=%d\n",error); 00650 return NULL; 00651 } 00652 00653 PacketSetMaxLookaheadsize(lpAdapter); 00654 if (AdapterNameU != NULL) 00655 free(AdapterNameU); 00656 return lpAdapter; 00657 } 00658 00659 00660 error=GetLastError(); 00661 if (AdapterNameU != NULL) 00662 free(AdapterNameU); 00663 GlobalFreePtr(lpAdapter); 00664 //set the error to the one on which we failed 00665 SetLastError(error); 00666 ODSEx("PacketOpenAdapter: CreateFile failed, Error=2,%d\n",error); 00667 return NULL; 00668 00669 } 00670 00677 VOID PacketCloseAdapter(LPADAPTER lpAdapter) 00678 { 00679 CloseHandle(lpAdapter->hFile); 00680 SetEvent(lpAdapter->ReadEvent); 00681 CloseHandle(lpAdapter->ReadEvent); 00682 GlobalFreePtr(lpAdapter); 00683 } 00684 00697 LPPACKET PacketAllocatePacket(void) 00698 { 00699 00700 LPPACKET lpPacket; 00701 lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET)); 00702 if (lpPacket==NULL) 00703 { 00704 ODS("PacketAllocatePacket: GlobalAlloc Failed\n"); 00705 return NULL; 00706 } 00707 return lpPacket; 00708 } 00709 00718 VOID PacketFreePacket(LPPACKET lpPacket) 00719 00720 { 00721 GlobalFreePtr(lpPacket); 00722 } 00723 00740 VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length) 00741 00742 { 00743 lpPacket->Buffer = Buffer; 00744 lpPacket->Length = Length; 00745 lpPacket->ulBytesReceived = 0; 00746 lpPacket->bIoComplete = FALSE; 00747 } 00748 00779 BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync) 00780 { 00781 BOOLEAN res; 00782 00783 if((int)AdapterObject->ReadTimeOut != -1) 00784 WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut); 00785 00786 res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL); 00787 00788 return res; 00789 } 00790 00820 BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync) 00821 00822 { 00823 DWORD BytesTransfered; 00824 00825 return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL); 00826 } 00827 00828 00856 INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync) 00857 { 00858 BOOLEAN Res; 00859 DWORD BytesTransfered, TotBytesTransfered=0; 00860 struct timeval BufStartTime; 00861 LARGE_INTEGER StartTicks, CurTicks, TargetTicks, TimeFreq; 00862 00863 ODS("PacketSendPackets"); 00864 00865 // Obtain starting timestamp of the buffer 00866 BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec; 00867 BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec; 00868 00869 // Retrieve the reference time counters 00870 QueryPerformanceCounter(&StartTicks); 00871 QueryPerformanceFrequency(&TimeFreq); 00872 00873 CurTicks.QuadPart = StartTicks.QuadPart; 00874 00875 do{ 00876 // Send the data to the driver 00877 Res = DeviceIoControl(AdapterObject->hFile, 00878 (Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC, 00879 (PCHAR)PacketBuff + TotBytesTransfered, 00880 Size - TotBytesTransfered, 00881 NULL, 00882 0, 00883 &BytesTransfered, 00884 NULL); 00885 00886 TotBytesTransfered += BytesTransfered; 00887 00888 // Exit from the loop on termination or error 00889 if(TotBytesTransfered >= Size || Res != TRUE) 00890 break; 00891 00892 if(Sync){ 00893 00894 // calculate the time interval to wait before sending the next packet 00895 TargetTicks.QuadPart = StartTicks.QuadPart + 00896 (LONGLONG) 00897 ((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 + 00898 (((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) * 00899 (TimeFreq.QuadPart) / 1000000; 00900 00901 // Wait until the time interval has elapsed 00902 while( CurTicks.QuadPart <= TargetTicks.QuadPart ){ 00903 QueryPerformanceCounter(&CurTicks); 00904 } 00905 } 00906 } 00907 while(TRUE); 00908 00909 return TotBytesTransfered; 00910 } 00911 00930 BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes) 00931 { 00932 DWORD BytesReturned; 00933 return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL); 00934 } 00935 00972 BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode) 00973 { 00974 DWORD BytesReturned; 00975 00976 return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL); 00977 } 00978 00993 BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len) 00994 { 00995 DWORD BytesReturned; 00996 WCHAR *FileName; 00997 BOOLEAN res; 00998 WCHAR NameWithPath[1024]; 00999 int TStrLen; 01000 WCHAR *NamePos; 01001 01002 if(((PUCHAR)name)[1]!=0 && len>1){ //ASCII 01003 FileName=SChar2WChar(name); 01004 len*=2; 01005 } 01006 else { //Unicode 01007 FileName=name; 01008 } 01009 01010 TStrLen=GetFullPathName(FileName,1024,NameWithPath,&NamePos); 01011 01012 len=TStrLen*2+2; //add the terminating null character 01013 01014 // Try to catch malformed strings 01015 if(len>2048){ 01016 if(((PUCHAR)name)[1]!=0 && len>1) free(FileName); 01017 return FALSE; 01018 } 01019 01020 res = DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL); 01021 free(FileName); 01022 return res; 01023 } 01024 01040 BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks) 01041 { 01042 DWORD BytesReturned; 01043 UINT valbuff[2]; 01044 01045 valbuff[0] = maxfilesize; 01046 valbuff[1] = maxnpacks; 01047 01048 return DeviceIoControl(AdapterObject->hFile, 01049 pBIOCSETDUMPLIMITS, 01050 valbuff, 01051 sizeof valbuff, 01052 NULL, 01053 0, 01054 &BytesReturned, 01055 NULL); 01056 } 01057 01071 BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync) 01072 { 01073 DWORD BytesReturned; 01074 int IsDumpEnded; 01075 BOOLEAN res; 01076 01077 if(sync) 01078 WaitForSingleObject(AdapterObject->ReadEvent, INFINITE); 01079 01080 res = DeviceIoControl(AdapterObject->hFile, 01081 pBIOCISDUMPENDED, 01082 NULL, 01083 0, 01084 &IsDumpEnded, 01085 4, 01086 &BytesReturned, 01087 NULL); 01088 01089 if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished 01090 01091 return (BOOLEAN)IsDumpEnded; 01092 } 01093 01113 HANDLE PacketGetReadEvent(LPADAPTER AdapterObject) 01114 { 01115 return AdapterObject->ReadEvent; 01116 } 01117 01126 BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites) 01127 { 01128 DWORD BytesReturned; 01129 return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL); 01130 } 01131 01144 BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout) 01145 { 01146 DWORD BytesReturned; 01147 int DriverTimeOut=-1; 01148 01149 AdapterObject->ReadTimeOut=timeout; 01150 01151 return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL); 01152 } 01153 01170 BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim) 01171 { 01172 DWORD BytesReturned; 01173 return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL); 01174 } 01175 01196 BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp) 01197 { 01198 DWORD BytesReturned; 01199 return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL); 01200 } 01201 01215 BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s) 01216 { 01217 BOOLEAN Res; 01218 DWORD BytesReturned; 01219 struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications 01220 01221 Res = DeviceIoControl(AdapterObject->hFile, 01222 pBIOCGSTATS, 01223 NULL, 01224 0, 01225 &tmpstat, 01226 sizeof(struct bpf_stat), 01227 &BytesReturned, 01228 NULL); 01229 01230 // Copy only the first two values retrieved from the driver 01231 s->bs_recv = tmpstat.bs_recv; 01232 s->bs_drop = tmpstat.bs_drop; 01233 01234 return Res; 01235 } 01236 01249 BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s) 01250 { 01251 BOOLEAN Res; 01252 DWORD BytesReturned; 01253 struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications 01254 01255 Res = DeviceIoControl(AdapterObject->hFile, 01256 pBIOCGSTATS, 01257 NULL, 01258 0, 01259 &tmpstat, 01260 sizeof(struct bpf_stat), 01261 &BytesReturned, 01262 NULL); 01263 01264 s->bs_recv = tmpstat.bs_recv; 01265 s->bs_drop = tmpstat.bs_drop; 01266 s->ps_ifdrop = tmpstat.ps_ifdrop; 01267 s->bs_capt = tmpstat.bs_capt; 01268 01269 return Res; 01270 } 01271 01284 BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData) 01285 { 01286 DWORD BytesReturned; 01287 BOOLEAN Result; 01288 01289 Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? (DWORD)pBIOCSETOID : (DWORD)pBIOCQUERYOID, 01290 OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData, 01291 sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL); 01292 01293 // output some debug info 01294 ODSEx("PacketRequest, OID=%d ", OidData->Oid); 01295 ODSEx("Length=%d ", OidData->Length); 01296 ODSEx("Set=%d ", Set); 01297 ODSEx("Res=%d\n", Result); 01298 01299 return Result; 01300 } 01301 01318 BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter) 01319 { 01320 BOOLEAN Status; 01321 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); 01322 PPACKET_OID_DATA OidData; 01323 01324 OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); 01325 if (OidData == NULL) { 01326 ODS("PacketSetHwFilter: GlobalAlloc Failed\n"); 01327 return FALSE; 01328 } 01329 OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER; 01330 OidData->Length=sizeof(ULONG); 01331 *((PULONG)OidData->Data)=Filter; 01332 Status=PacketRequest(AdapterObject,TRUE,OidData); 01333 GlobalFreePtr(OidData); 01334 return Status; 01335 } 01336 01366 BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize) 01367 { 01368 HKEY LinkageKey,AdapKey, OneAdapKey; 01369 DWORD RegKeySize=0; 01370 LONG Status; 01371 ULONG Result; 01372 PTSTR BpStr; 01373 char *TTpStr,*DpStr,*DescBuf; 01374 LPADAPTER adapter; 01375 PPACKET_OID_DATA OidData; 01376 int i=0,k,rewind; 01377 DWORD dim; 01378 TCHAR AdapName[256]; 01379 01380 ODSEx("PacketGetAdapterNames: BufferSize=%d\n",*BufferSize); 01381 01382 OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,512); 01383 if (OidData == NULL) { 01384 ODS("PacketGetAdapterNames: GlobalAlloc Failed\n"); 01385 return FALSE; 01386 } 01387 01388 Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE, 01389 TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"), 01390 0, 01391 KEY_READ, 01392 &AdapKey); 01393 if ( Status != ERROR_SUCCESS ){ 01394 ODS("PacketGetAdapterNames: RegOpenKeyEx ( Class\{networkclassguid} ) Failed\n"); 01395 return FALSE; 01396 } 01397 01398 // Get the size to allocate for the original device names 01399 while((Result=RegEnumKey(AdapKey,i,AdapName,sizeof(AdapName)/2))==ERROR_SUCCESS) 01400 { 01401 Status=RegOpenKeyEx(AdapKey,AdapName,0,KEY_READ,&OneAdapKey); 01402 if ( Status != ERROR_SUCCESS ) 01403 { 01404 RegCloseKey(AdapKey); 01405 ODS("PacketGetAdapterNames: RegOpenKeyEx ( OneAdapKey ) Failed\n"); 01406 i++; 01407 continue; 01408 } 01409 01410 Status=RegOpenKeyEx(OneAdapKey,L"Linkage",0,KEY_READ,&LinkageKey); 01411 if ( Status != ERROR_SUCCESS ) 01412 { 01413 RegCloseKey( OneAdapKey ); 01414 RegCloseKey(AdapKey); 01415 ODS("PacketGetAdapterNames: RegOpenKeyEx ( LinkageKey ) Failed\n"); 01416 i++; 01417 continue; 01418 } 01419 01420 Status=RegQueryValueEx(LinkageKey,L"Export",NULL,NULL,NULL,&dim); 01421 01422 RegCloseKey( OneAdapKey ); 01423 RegCloseKey( LinkageKey ); 01424 01425 i++; 01426 if(Status!=ERROR_SUCCESS) continue; 01427 RegKeySize+=dim; 01428 } // while enum reg key still find keys 01429 01430 // Allocate the memory for the original device names 01431 ODSEx("Need %d bytes for the names\n", RegKeySize+2); 01432 BpStr=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,RegKeySize+2); 01433 if (BpStr == NULL || RegKeySize > *BufferSize) { 01434 ODS("PacketGetAdapterNames: GlobalAlloc Failed\n"); 01435 GlobalFreePtr(OidData); 01436 return FALSE; 01437 } 01438 01439 k=0; 01440 i=0; 01441 01442 ODS("PacketGetAdapterNames: Cycling through the adapters:\n"); 01443 01444 // Copy the names to the buffer 01445 while((Result=RegEnumKey(AdapKey,i,AdapName,sizeof(AdapName)/2))==ERROR_SUCCESS) 01446 { 01447 WCHAR UpperBindStr[64]; 01448 01449 i++; 01450 ODSEx(" %d) ", i); 01451 01452 Status=RegOpenKeyEx(AdapKey,AdapName,0,KEY_READ,&OneAdapKey); 01453 if ( Status != ERROR_SUCCESS ){ 01454 RegCloseKey(AdapKey); 01455 ODS("PacketGetAdapterNames: RegOpenKeyEx ( OneAdapKey ) Failed\n"); 01456 return FALSE; 01457 } 01458 Status=RegOpenKeyEx(OneAdapKey,L"Linkage",0,KEY_READ,&LinkageKey); 01459 if ( Status != ERROR_SUCCESS ){ 01460 RegCloseKey( OneAdapKey ); 01461 RegCloseKey(AdapKey); 01462 ODS("PacketGetAdapterNames: RegOpenKeyEx ( LinkageKey ) Failed\n"); 01463 return FALSE; 01464 } 01465 01466 dim=sizeof(UpperBindStr); 01467 Status=RegQueryValueEx(LinkageKey,L"UpperBind",NULL,NULL,(PUCHAR)UpperBindStr,&dim); 01468 01469 ODSEx("UpperBind=%S ", UpperBindStr); 01470 01471 dim=RegKeySize-k; 01472 Status=RegQueryValueEx(LinkageKey,L"Export",NULL,NULL,(LPBYTE)BpStr+k,&dim); 01473 if(Status!=ERROR_SUCCESS){ 01474 RegCloseKey( OneAdapKey ); 01475 RegCloseKey( LinkageKey ); 01476 ODS("Name = SKIPPED (error reading the key)\n"); 01477 continue; 01478 } 01479 01480 RegCloseKey( OneAdapKey ); 01481 RegCloseKey( LinkageKey ); 01482 ODSEx("Name = %S\n", (LPBYTE)BpStr+k); 01483 01484 k+=dim-2; 01485 } // while enum reg keys 01486 01487 RegCloseKey(AdapKey); 01488 01489 #ifdef _DEBUG_TO_FILE 01490 //dump BpStr for debug purposes 01491 ODS("Dumping BpStr:"); 01492 { 01493 FILE *f; 01494 f = fopen("winpcap_debug.txt", "a"); 01495 for(i=0;i<k;i++){ 01496 if(!(i%32))fprintf(f, "\n "); 01497 fprintf(f, "%c " , *((LPBYTE)BpStr+i)); 01498 } 01499 fclose(f); 01500 } 01501 ODS("\n"); 01502 #endif 01503 01504 01505 if (k != 0) 01506 { 01507 DescBuf=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096); 01508 01509 if (DescBuf == NULL) { 01510 GlobalFreePtr (BpStr); 01511 GlobalFreePtr(OidData); 01512 return FALSE; 01513 } 01514 DpStr=DescBuf; 01515 01516 for(i=0,k=0;BpStr[i]!=0 || BpStr[i+1]!=0;) 01517 { 01518 01519 if(k+wcslen(BpStr+i)+30 > *BufferSize){ 01520 // Input buffer too small 01521 GlobalFreePtr(OidData); 01522 GlobalFreePtr (BpStr); 01523 GlobalFreePtr (DescBuf); 01524 ODS("PacketGetAdapterNames: Input buffer too small!\n"); 01525 return FALSE; 01526 } 01527 01528 // Create the device name 01529 rewind=k; 01530 memcpy(pStr+k,BpStr+i,16); 01531 memcpy(pStr+k+8,TEXT("NPF_"),8); 01532 i+=8; 01533 k+=12; 01534 while(BpStr[i-1]!=0){ 01535 pStr[k++]=BpStr[i++]; 01536 } 01537 01538 // Open the adapter 01539 adapter=PacketOpenAdapter(pStr+rewind); 01540 if(adapter==NULL){ 01541 k=rewind; 01542 continue; 01543 } 01544 01545 // Retrieve the description 01546 OidData->Oid = OID_GEN_VENDOR_DESCRIPTION; 01547 OidData->Length = 256; 01548 ZeroMemory(OidData->Data,256); 01549 Status = PacketRequest(adapter,FALSE,OidData); 01550 if(Status==0 || ((char*)OidData->Data)[0]==0){ 01551 k=rewind; 01552 continue; 01553 } 01554 01555 ODSEx("Adapter Description=%s\n\n",OidData->Data); 01556 01557 // Copy the description 01558 TTpStr=(char*)(OidData->Data); 01559 while(*TTpStr!=0){ 01560 *DpStr++=*TTpStr++; 01561 } 01562 *DpStr++=*TTpStr++; 01563 01564 // Close the adapter 01565 PacketCloseAdapter(adapter); 01566 01567 } // for end - parse through string 01568 *DpStr=0; 01569 01570 pStr[k++]=0; 01571 pStr[k]=0; 01572 01573 if((ULONG)(DpStr-DescBuf+k) < *BufferSize) 01574 memcpy(pStr+k,DescBuf,DpStr-DescBuf); 01575 else{ 01576 GlobalFreePtr(OidData); 01577 GlobalFreePtr (BpStr); 01578 GlobalFreePtr (DescBuf); 01579 ODS("\nPacketGetAdapterNames: ended with failure\n"); 01580 return FALSE; 01581 } 01582 01583 GlobalFreePtr(OidData); 01584 GlobalFreePtr (BpStr); 01585 GlobalFreePtr (DescBuf); 01586 ODS("\nPacketGetAdapterNames: ended correctly\n"); 01587 return TRUE; 01588 } // if k != 0 01589 else{ 01590 DWORD RegType; 01591 01592 ODS("Adapters not found under SYSTEM\\CurrentControlSet\\Control\\Class. Using the TCP/IP bindings.\n"); 01593 01594 GlobalFreePtr (BpStr); 01595 01596 Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage"),0,KEY_READ,&LinkageKey); 01597 if (Status == ERROR_SUCCESS) 01598 { 01599 // Retrieve the length of the key 01600 Status=RegQueryValueEx(LinkageKey,TEXT("bind"),NULL,&RegType,NULL,&RegKeySize); 01601 // Allocate the buffer 01602 BpStr=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,RegKeySize+2); 01603 if (BpStr == NULL || RegKeySize > *BufferSize) { 01604 GlobalFreePtr(OidData); 01605 return FALSE; 01606 } 01607 Status=RegQueryValueEx(LinkageKey,TEXT("bind"),NULL,&RegType,(LPBYTE)BpStr,&RegKeySize); 01608 RegCloseKey(LinkageKey); 01609 } 01610 01611 if (Status==ERROR_SUCCESS){ 01612 01613 DescBuf=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096); 01614 if (DescBuf == NULL) { 01615 GlobalFreePtr (BpStr); 01616 GlobalFreePtr(OidData); 01617 return FALSE; 01618 } 01619 DpStr=DescBuf; 01620 01621 for(i=0,k=0;BpStr[i]!=0 || BpStr[i+1]!=0;){ 01622 01623 if(k+wcslen(BpStr+i)+30 > *BufferSize){ 01624 // Input buffer too small 01625 GlobalFreePtr(OidData); 01626 GlobalFreePtr (BpStr); 01627 GlobalFreePtr (DescBuf); 01628 return FALSE; 01629 } 01630 01631 // Create the device name 01632 rewind=k; 01633 memcpy(pStr+k,BpStr+i,16); 01634 memcpy(pStr+k+8,TEXT("NPF_"),8); 01635 i+=8; 01636 k+=12; 01637 while(BpStr[i-1]!=0){ 01638 pStr[k++]=BpStr[i++]; 01639 } 01640 01641 // Open the adapter 01642 adapter=PacketOpenAdapter(pStr+rewind); 01643 if(adapter==NULL){ 01644 k=rewind; 01645 continue; 01646 } 01647 01648 // Retrieve the description 01649 OidData->Oid = OID_GEN_VENDOR_DESCRIPTION; 01650 OidData->Length = 256; 01651 Status = PacketRequest(adapter,FALSE,OidData); 01652 if(Status==0 || ((char*)OidData->Data)[0]==0){ 01653 k=rewind; 01654 continue; 01655 } 01656 01657 // Copy the description 01658 TTpStr=(char*)(OidData->Data); 01659 while(*TTpStr!=0){ 01660 *DpStr++=*TTpStr++; 01661 } 01662 *DpStr++=*TTpStr++; 01663 01664 // Close the adapter 01665 PacketCloseAdapter(adapter); 01666 01667 } // for end - parse string 01668 *DpStr=0; 01669 01670 pStr[k++]=0; 01671 pStr[k]=0; 01672 01673 if((ULONG)(DpStr-DescBuf+k) < *BufferSize) 01674 memcpy(pStr+k,DescBuf,DpStr-DescBuf); 01675 else{ 01676 GlobalFreePtr(OidData); 01677 GlobalFreePtr (BpStr); 01678 GlobalFreePtr (DescBuf); 01679 return FALSE; 01680 } 01681 01682 GlobalFreePtr(OidData); 01683 GlobalFreePtr (BpStr); 01684 GlobalFreePtr (DescBuf); 01685 return TRUE; 01686 } // if key 'bind' was successfully opened 01687 else{ 01688 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); 01689 ODS("Cannot find the TCP/IP bindings"); 01690 return FALSE; 01691 } 01692 } 01693 } 01707 BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterName, npf_if_addr* buffer, PLONG NEntries) 01708 { 01709 char *AdapterNameA; 01710 WCHAR *AdapterNameU; 01711 WCHAR *ifname; 01712 HKEY SystemKey; 01713 HKEY InterfaceKey; 01714 HKEY ParametersKey; 01715 HKEY TcpIpKey; 01716 HKEY UnderTcpKey; 01717 LONG status; 01718 WCHAR String[1024+1]; 01719 DWORD RegType; 01720 ULONG BufLen; 01721 DWORD DHCPEnabled; 01722 struct sockaddr_in *TmpAddr, *TmpBroad; 01723 LONG naddrs,nmasks,StringPos; 01724 DWORD ZeroBroadcast; 01725 01726 AdapterNameA = (char*)AdapterName; 01727 if(AdapterNameA[1] != 0) { //ASCII 01728 AdapterNameU = SChar2WChar(AdapterNameA); 01729 AdapterName = AdapterNameU; 01730 } else { //Unicode 01731 AdapterNameU = NULL; 01732 } 01733 ifname = wcsrchr(AdapterName, '\\'); 01734 if (ifname == NULL) 01735 ifname = AdapterName; 01736 else 01737 ifname++; 01738 if (wcsncmp(ifname, L"NPF_", 4) == 0) 01739 ifname += 4; 01740 01741 if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"), 0, KEY_READ, &UnderTcpKey) == ERROR_SUCCESS) 01742 { 01743 status = RegOpenKeyEx(UnderTcpKey,ifname,0,KEY_READ,&TcpIpKey); 01744 if (status != ERROR_SUCCESS) { 01745 RegCloseKey(UnderTcpKey); 01746 goto fail; 01747 } 01748 } 01749 else 01750 { 01751 01752 // Query the registry key with the interface's adresses 01753 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey); 01754 if (status != ERROR_SUCCESS) 01755 goto fail; 01756 status = RegOpenKeyEx(SystemKey,ifname,0,KEY_READ,&InterfaceKey); 01757 if (status != ERROR_SUCCESS) { 01758 RegCloseKey(SystemKey); 01759 goto fail; 01760 } 01761 RegCloseKey(SystemKey); 01762 status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey); 01763 if (status != ERROR_SUCCESS) { 01764 RegCloseKey(InterfaceKey); 01765 goto fail; 01766 } 01767 RegCloseKey(InterfaceKey); 01768 status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey); 01769 if (status != ERROR_SUCCESS) { 01770 RegCloseKey(ParametersKey); 01771 goto fail; 01772 } 01773 RegCloseKey(ParametersKey); 01774 BufLen = sizeof String; 01775 } 01776 01777 BufLen = 4; 01778 /* Try to detect if the interface has a zero broadcast addr */ 01779 status=RegQueryValueEx(TcpIpKey,TEXT("UseZeroBroadcast"),NULL,&RegType,(LPBYTE)&ZeroBroadcast,&BufLen); 01780 if (status != ERROR_SUCCESS) 01781 ZeroBroadcast=0; 01782 01783 BufLen = 4; 01784 /* See if DHCP is used by this system */ 01785 status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen); 01786 if (status != ERROR_SUCCESS) 01787 DHCPEnabled=0; 01788 01789 01790 /* Retrieve the adrresses */ 01791 if(DHCPEnabled){ 01792 01793 BufLen = sizeof String; 01794 // Open the key with the addresses 01795 status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen); 01796 if (status != ERROR_SUCCESS) { 01797 RegCloseKey(TcpIpKey); 01798 goto fail; 01799 } 01800 01801 // scan the key to obtain the addresses 01802 StringPos = 0; 01803 for(naddrs = 0;naddrs <* NEntries;naddrs++){ 01804 TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress); 01805 01806 if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ 01807 TmpAddr->sin_family = AF_INET; 01808 01809 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast); 01810 TmpBroad->sin_family = AF_INET; 01811 if(ZeroBroadcast==0) 01812 TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255 01813 else 01814 TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0 01815 01816 while(*(String + StringPos) != 0)StringPos++; 01817 StringPos++; 01818 01819 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen) 01820 break; 01821 } 01822 else break; 01823 } 01824 01825 BufLen = sizeof String; 01826 // Open the key with the netmasks 01827 status = RegQueryValueEx(TcpIpKey,TEXT("DhcpSubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen); 01828 if (status != ERROR_SUCCESS) { 01829 RegCloseKey(TcpIpKey); 01830 goto fail; 01831 } 01832 01833 // scan the key to obtain the masks 01834 StringPos = 0; 01835 for(nmasks = 0;nmasks < *NEntries;nmasks++){ 01836 TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask); 01837 01838 if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ 01839 TmpAddr->sin_family = AF_INET; 01840 01841 while(*(String + StringPos) != 0)StringPos++; 01842 StringPos++; 01843 01844 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen) 01845 break; 01846 } 01847 else break; 01848 } 01849 01850 // The number of masks MUST be equal to the number of adresses 01851 if(nmasks != naddrs){ 01852 RegCloseKey(TcpIpKey); 01853 goto fail; 01854 } 01855 01856 } 01857 else{ 01858 01859 BufLen = sizeof String; 01860 // Open the key with the addresses 01861 status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen); 01862 if (status != ERROR_SUCCESS) { 01863 RegCloseKey(TcpIpKey); 01864 goto fail; 01865 } 01866 01867 // scan the key to obtain the addresses 01868 StringPos = 0; 01869 for(naddrs = 0;naddrs < *NEntries;naddrs++){ 01870 TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress); 01871 01872 if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ 01873 TmpAddr->sin_family = AF_INET; 01874 01875 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast); 01876 TmpBroad->sin_family = AF_INET; 01877 if(ZeroBroadcast==0) 01878 TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255 01879 else 01880 TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0 01881 01882 while(*(String + StringPos) != 0)StringPos++; 01883 StringPos++; 01884 01885 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen) 01886 break; 01887 } 01888 else break; 01889 } 01890 01891 BufLen = sizeof String; 01892 // Open the key with the netmasks 01893 status = RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen); 01894 if (status != ERROR_SUCCESS) { 01895 RegCloseKey(TcpIpKey); 01896 goto fail; 01897 } 01898 01899 // scan the key to obtain the masks 01900 StringPos = 0; 01901 for(nmasks = 0;nmasks <* NEntries;nmasks++){ 01902 TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask); 01903 01904 if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ 01905 TmpAddr->sin_family = AF_INET; 01906 01907 while(*(String + StringPos) != 0)StringPos++; 01908 StringPos++; 01909 01910 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen) 01911 break; 01912 } 01913 else break; 01914 } 01915 01916 // The number of masks MUST be equal to the number of adresses 01917 if(nmasks != naddrs){ 01918 RegCloseKey(TcpIpKey); 01919 goto fail; 01920 } 01921 01922 } 01923 01924 *NEntries = naddrs + 1; 01925 01926 RegCloseKey(TcpIpKey); 01927 01928 if (status != ERROR_SUCCESS) { 01929 goto fail; 01930 } 01931 01932 01933 if (AdapterNameU != NULL) 01934 free(AdapterNameU); 01935 return TRUE; 01936 01937 fail: 01938 if (AdapterNameU != NULL) 01939 free(AdapterNameU); 01940 return FALSE; 01941 } 01942 01953 BOOLEAN PacketGetNetInfo(LPTSTR AdapterName, PULONG netp, PULONG maskp) 01954 { 01955 char *AdapterNameA; 01956 WCHAR *AdapterNameU; 01957 WCHAR *ifname; 01958 HKEY SystemKey; 01959 HKEY InterfaceKey; 01960 HKEY ParametersKey; 01961 HKEY TcpIpKey; 01962 LONG status; 01963 WCHAR String[1024+1]; 01964 DWORD RegType; 01965 ULONG BufLen; 01966 DWORD DHCPEnabled; 01967 ULONG TAddr,i; 01968 01969 AdapterNameA = (char*)AdapterName; 01970 if(AdapterNameA[1] != 0) { //ASCII 01971 AdapterNameU = SChar2WChar(AdapterNameA); 01972 AdapterName = AdapterNameU; 01973 } else { //Unicode 01974 AdapterNameU = NULL; 01975 } 01976 ifname = wcsrchr(AdapterName, '\\'); 01977 if (ifname == NULL) 01978 ifname = AdapterName; 01979 else 01980 ifname++; 01981 if (wcsncmp(ifname, L"NPF_", 4) == 0) 01982 ifname += 4; 01983 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey); 01984 if (status != ERROR_SUCCESS) 01985 goto fail; 01986 status = RegOpenKeyEx(SystemKey,ifname,0,KEY_READ,&InterfaceKey); 01987 if (status != ERROR_SUCCESS) { 01988 RegCloseKey(SystemKey); 01989 goto fail; 01990 } 01991 RegCloseKey(SystemKey); 01992 status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey); 01993 if (status != ERROR_SUCCESS) { 01994 RegCloseKey(InterfaceKey); 01995 goto fail; 01996 } 01997 RegCloseKey(InterfaceKey); 01998 status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey); 01999 if (status != ERROR_SUCCESS) { 02000 RegCloseKey(ParametersKey); 02001 goto fail; 02002 } 02003 RegCloseKey(ParametersKey); 02004 02005 BufLen = 4; 02006 /* See if DHCP is used by this system */ 02007 status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen); 02008 if (status != ERROR_SUCCESS) 02009 DHCPEnabled=0; 02010 02011 02012 /* Retrieve the netmask */ 02013 if(DHCPEnabled){ 02014 02015 BufLen = sizeof String; 02016 status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen); 02017 if (status != ERROR_SUCCESS) { 02018 RegCloseKey(TcpIpKey); 02019 goto fail; 02020 } 02021 02022 TAddr = inet_addrU(String); 02023 // swap bytes for backward compatibility 02024 for(i=0;i<4;i++){ 02025 *((char*)netp+i) = *((char*)&TAddr+3-i); 02026 } 02027 02028 BufLen = sizeof String; 02029 status=RegQueryValueEx(TcpIpKey,TEXT("DHCPSubnetMask"),NULL,&RegType, 02030 (LPBYTE)String,&BufLen); 02031 02032 TAddr = inet_addrU(String); 02033 // swap bytes for backward compatibility 02034 for(i=0;i<4;i++){ 02035 *((char*)maskp+i) = *((char*)&TAddr+3-i); 02036 } 02037 } 02038 else{ 02039 02040 BufLen = sizeof String; 02041 status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen); 02042 if (status != ERROR_SUCCESS) { 02043 RegCloseKey(TcpIpKey); 02044 goto fail; 02045 } 02046 02047 TAddr = inet_addrU(String); 02048 // swap bytes for backward compatibility 02049 for(i=0;i<4;i++){ 02050 *((char*)netp+i) = *((char*)&TAddr+3-i); 02051 } 02052 02053 BufLen = sizeof String; 02054 status=RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType, 02055 (LPBYTE)String,&BufLen); 02056 02057 TAddr = inet_addrU(String); 02058 // swap bytes for backward compatibility 02059 for(i=0;i<4;i++){ 02060 *((char*)maskp+i) = *((char*)&TAddr+3-i); 02061 } 02062 02063 02064 } 02065 02066 RegCloseKey(TcpIpKey); 02067 02068 if (AdapterNameU != NULL) 02069 free(AdapterNameU); 02070 return TRUE; 02071 02072 fail: 02073 if (AdapterNameU != NULL) 02074 free(AdapterNameU); 02075 return FALSE; 02076 } 02077 02078 02079 /* @} */
documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.