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.