00001 /* 00002 * Copyright (c) 1999 - 2003 00003 * Politecnico di Torino. All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that: (1) source code distributions 00007 * retain the above copyright notice and this paragraph in its entirety, (2) 00008 * distributions including binary code include the above copyright notice and 00009 * this paragraph in its entirety in the documentation or other materials 00010 * provided with the distribution, and (3) all advertising materials mentioning 00011 * features or use of this software display the following acknowledgement: 00012 * ``This product includes software developed by the Politecnico 00013 * di Torino, and its contributors.'' Neither the name of 00014 * the University nor the names of its contributors may be used to endorse 00015 * or promote products derived from this software without specific prior 00016 * written permission. 00017 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 00018 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 00019 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00020 */ 00021 00022 #define UNICODE 1 00023 00024 #include <stdio.h> 00025 #include <packet32.h> 00026 #include "wanpacket/wanpacket.h" 00027 00028 00029 #include <windows.h> 00030 #include <windowsx.h> 00031 #include <Iphlpapi.h> 00032 #include <IPIfCons.h> 00033 00034 #include <ntddndis.h> 00035 00036 00038 char PacketLibraryVersion[64]; 00040 char PacketDriverVersion[64]; 00041 00042 //service handles 00043 SC_HANDLE scmHandle = NULL; 00044 SC_HANDLE srvHandle = NULL; 00045 LPCTSTR NPFServiceName = TEXT("NPF"); 00046 LPCTSTR NPFServiceDesc = TEXT("Netgroup Packet Filter"); 00047 LPCTSTR NPFRegistryLocation = TEXT("SYSTEM\\CurrentControlSet\\Services\\NPF"); 00048 LPCTSTR NPFDriverPath = TEXT("system32\\drivers\\npf.sys"); 00049 00050 extern PADAPTER_INFO AdaptersInfoList; 00051 extern HANDLE AdaptersInfoMutex; 00052 #ifndef _WINNT4 00053 typedef VOID (*GAAHandler)( 00054 ULONG, 00055 DWORD, 00056 PVOID, 00057 PIP_ADAPTER_ADDRESSES, 00058 PULONG); 00059 GAAHandler GetAdaptersAddressesPointer = NULL; 00060 #endif // _WINNT4 00061 00062 #ifdef HAVE_DAG_API 00063 /* We load dinamically the dag library in order link it only when it's present on the system */ 00064 dagc_open_handler p_dagc_open = NULL; 00065 dagc_close_handler p_dagc_close = NULL; 00066 dagc_getlinktype_handler p_dagc_getlinktype = NULL; 00067 dagc_getlinkspeed_handler p_dagc_getlinkspeed = NULL; 00068 dagc_getfcslen_handler p_dagc_getfcslen = NULL; 00069 dagc_receive_handler p_dagc_receive = NULL; 00070 dagc_wait_handler p_dagc_wait = NULL; 00071 dagc_stats_handler p_dagc_stats = NULL; 00072 dagc_setsnaplen_handler p_dagc_setsnaplen = NULL; 00073 dagc_finddevs_handler p_dagc_finddevs = NULL; 00074 dagc_freedevs_handler p_dagc_freedevs = NULL; 00075 #endif /* HAVE_DAG_API */ 00076 00077 BOOLEAN PacketAddAdapterDag(PCHAR name, PCHAR description, BOOLEAN IsAFile); 00078 00079 //--------------------------------------------------------------------------- 00080 00085 BOOL APIENTRY DllMain (HANDLE DllHandle,DWORD Reason,LPVOID lpReserved) 00086 { 00087 BOOLEAN Status=TRUE; 00088 HMODULE IPHMod; 00089 PADAPTER_INFO NewAdInfo; 00090 #ifdef HAVE_DAG_API 00091 HMODULE DagcLib; 00092 #endif // HAVE_DAG_API 00093 00094 switch(Reason) 00095 { 00096 case DLL_PROCESS_ATTACH: 00097 00098 ODS("************Packet32: DllMain************\n"); 00099 00100 #ifdef _DEBUG_TO_FILE 00101 // dump a bunch of registry keys useful for debug to file 00102 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 00103 "adapters.reg"); 00104 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip", 00105 "tcpip.reg"); 00106 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\NPF", 00107 "npf.reg"); 00108 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services", 00109 "services.reg"); 00110 #endif 00111 00112 // Create the mutex that will protect the adapter information list 00113 AdaptersInfoMutex = CreateMutex(NULL, FALSE, NULL); 00114 00115 // 00116 // Retrieve packet.dll version information from the file 00117 // 00118 PacketGetFileVersion(TEXT("packet.dll"), PacketLibraryVersion, sizeof(PacketLibraryVersion)); 00119 00120 // 00121 // Retrieve NPF.sys version information from the file 00122 // 00123 PacketGetFileVersion(TEXT("drivers\\npf.sys"), PacketDriverVersion, sizeof(PacketDriverVersion)); 00124 00125 // 00126 // Locate GetAdaptersAddresses dinamically since it is not present in Win2k 00127 // 00128 IPHMod = GetModuleHandle(TEXT("Iphlpapi")); 00129 00130 #ifndef _WINNT4 00131 GetAdaptersAddressesPointer = (GAAHandler) GetProcAddress(IPHMod ,"GetAdaptersAddresses"); 00132 #endif // _WINNT4 00133 00134 #ifdef HAVE_DAG_API 00135 /* We load dinamically the dag library in order link it only when it's present on the system */ 00136 if((DagcLib = LoadLibrary(TEXT("dagc.dll"))) == NULL) 00137 { 00138 // Report the error but go on 00139 ODS("dag capture library not found on this system\n"); 00140 break; 00141 } 00142 00143 p_dagc_open = (dagc_open_handler) GetProcAddress(DagcLib, "dagc_open"); 00144 p_dagc_close = (dagc_close_handler) GetProcAddress(DagcLib, "dagc_close"); 00145 p_dagc_setsnaplen = (dagc_setsnaplen_handler) GetProcAddress(DagcLib, "dagc_setsnaplen"); 00146 p_dagc_getlinktype = (dagc_getlinktype_handler) GetProcAddress(DagcLib, "dagc_getlinktype"); 00147 p_dagc_getlinkspeed = (dagc_getlinkspeed_handler) GetProcAddress(DagcLib, "dagc_getlinkspeed"); 00148 p_dagc_getfcslen = (dagc_getfcslen_handler) GetProcAddress(DagcLib, "dagc_getfcslen"); 00149 p_dagc_receive = (dagc_receive_handler) GetProcAddress(DagcLib, "dagc_receive"); 00150 p_dagc_wait = (dagc_wait_handler) GetProcAddress(DagcLib, "dagc_wait"); 00151 p_dagc_stats = (dagc_stats_handler) GetProcAddress(DagcLib, "dagc_stats"); 00152 p_dagc_finddevs = (dagc_finddevs_handler) GetProcAddress(DagcLib, "dagc_finddevs"); 00153 p_dagc_freedevs = (dagc_freedevs_handler) GetProcAddress(DagcLib, "dagc_freedevs"); 00154 00155 #endif /* HAVE_DAG_API */ 00156 00157 break; 00158 00159 case DLL_PROCESS_DETACH: 00160 00161 CloseHandle(AdaptersInfoMutex); 00162 00163 AdaptersInfoList; 00164 00165 while(AdaptersInfoList != NULL) 00166 { 00167 00168 NewAdInfo = AdaptersInfoList->Next; 00169 if (AdaptersInfoList->NetworkAddresses != NULL) 00170 GlobalFreePtr(AdaptersInfoList->NetworkAddresses); 00171 GlobalFreePtr(AdaptersInfoList); 00172 00173 AdaptersInfoList = NewAdInfo; 00174 } 00175 00176 00177 break; 00178 00179 default: 00180 break; 00181 } 00182 00183 return Status; 00184 } 00185 00194 ULONG inet_addrU(const WCHAR *cp) 00195 { 00196 ULONG val, part; 00197 WCHAR c; 00198 int i; 00199 00200 val = 0; 00201 for (i = 0; i < 4; i++) { 00202 part = 0; 00203 while ((c = *cp++) != '\0' && c != '.') { 00204 if (c < '0' || c > '9') 00205 return -1; 00206 part = part*10 + (c - '0'); 00207 } 00208 if (part > 255) 00209 return -1; 00210 val = val | (part << i*8); 00211 if (i == 3) { 00212 if (c != '\0') 00213 return -1; // extra gunk at end of string 00214 } else { 00215 if (c == '\0') 00216 return -1; // string ends early 00217 } 00218 } 00219 return val; 00220 } 00221 00228 PWCHAR SChar2WChar(PCHAR string) 00229 { 00230 PWCHAR TmpStr; 00231 TmpStr = (WCHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (strlen(string)+2)*sizeof(WCHAR)); 00232 00233 MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (strlen(string)+2)); 00234 00235 return TmpStr; 00236 } 00237 00244 PCHAR WChar2SChar(PWCHAR string) 00245 { 00246 PCHAR TmpStr; 00247 TmpStr = (CHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (wcslen(string)+2)); 00248 00249 // Conver to ASCII 00250 WideCharToMultiByte( 00251 CP_ACP, 00252 0, 00253 string, 00254 -1, 00255 TmpStr, 00256 (wcslen(string)+2), // size of buffer 00257 NULL, 00258 NULL); 00259 00260 return TmpStr; 00261 } 00262 00272 BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject) 00273 { 00274 BOOLEAN Status; 00275 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); 00276 PPACKET_OID_DATA OidData; 00277 00278 OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); 00279 if (OidData == NULL) { 00280 ODS("PacketSetMaxLookaheadsize failed\n"); 00281 return FALSE; 00282 } 00283 00284 //set the size of the lookahead buffer to the maximum available by the the NIC driver 00285 OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD; 00286 OidData->Length=sizeof(ULONG); 00287 Status=PacketRequest(AdapterObject,FALSE,OidData); 00288 OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD; 00289 Status=PacketRequest(AdapterObject,TRUE,OidData); 00290 GlobalFreePtr(OidData); 00291 return Status; 00292 } 00293 00304 BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject) 00305 { 00306 DWORD BytesReturned; 00307 TCHAR EventName[39]; 00308 00309 if (LOWORD(GetVersion()) == 4) 00310 { 00311 // retrieve the name of the shared event from the driver without the "Global\\" prefix 00312 if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) 00313 return FALSE; 00314 00315 EventName[BytesReturned/sizeof(TCHAR)]=0; // terminate the string 00316 } 00317 else 00318 { 00319 // this tells the terminal service to retrieve the event from the global namespace 00320 wcsncpy(EventName,L"Global\\",sizeof(L"Global\\")); 00321 // retrieve the name of the shared event from the driver with the "Global\\" prefix 00322 if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName + 7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) 00323 return FALSE; 00324 00325 EventName[BytesReturned/sizeof(TCHAR) + 7]=0; // terminate the string 00326 } 00327 00328 // open the shared event 00329 AdapterObject->ReadEvent=CreateEvent(NULL, 00330 TRUE, 00331 FALSE, 00332 EventName); 00333 00334 if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){ 00335 ODS("PacketSetReadEvt: error retrieving the event from the kernel\n"); 00336 return FALSE; 00337 } 00338 00339 AdapterObject->ReadTimeOut=0; 00340 00341 return TRUE; 00342 } 00343 00353 BOOL PacketInstallDriver(SC_HANDLE ascmHandle,SC_HANDLE *srvHandle) 00354 { 00355 BOOL result = FALSE; 00356 ULONG err = 0; 00357 00358 ODS("installdriver\n"); 00359 00360 *srvHandle = CreateService(ascmHandle, 00361 NPFServiceName, 00362 NPFServiceDesc, 00363 SERVICE_ALL_ACCESS, 00364 SERVICE_KERNEL_DRIVER, 00365 SERVICE_DEMAND_START, 00366 SERVICE_ERROR_NORMAL, 00367 NPFDriverPath, 00368 NULL, NULL, NULL, NULL, NULL); 00369 if (*srvHandle == NULL) 00370 { 00371 if (GetLastError() == ERROR_SERVICE_EXISTS) 00372 { 00373 //npf.sys already existed 00374 result = TRUE; 00375 } 00376 } 00377 else 00378 { 00379 //Created service for npf.sys 00380 result = TRUE; 00381 } 00382 if (result == TRUE) 00383 if (*srvHandle != NULL) 00384 CloseServiceHandle(*srvHandle); 00385 00386 if(result == FALSE){ 00387 err = GetLastError(); 00388 if(err != 2) 00389 ODSEx("PacketInstallDriver failed, Error=%d\n",err); 00390 } 00391 00392 SetLastError(err); 00393 return result; 00394 00395 } 00396 00406 #ifdef _DEBUG_TO_FILE 00407 00408 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName) 00409 { 00410 CHAR Command[256]; 00411 00412 strcpy(Command, "regedit /e "); 00413 strcat(Command, FileName); 00414 strcat(Command, " "); 00415 strcat(Command, KeyName); 00416 00418 system(Command); 00419 00420 return TRUE; 00421 } 00422 #endif 00423 00433 BOOL PacketGetFileVersion(LPTSTR FileName, PCHAR VersionBuff, UINT VersionBuffLen) 00434 { 00435 DWORD dwVerInfoSize; // Size of version information block 00436 DWORD dwVerHnd=0; // An 'ignored' parameter, always '0' 00437 LPSTR lpstrVffInfo; 00438 UINT cbTranslate, dwBytes; 00439 TCHAR SubBlock[64]; 00440 PVOID lpBuffer; 00441 PCHAR TmpStr; 00442 00443 // Structure used to store enumerated languages and code pages. 00444 struct LANGANDCODEPAGE { 00445 WORD wLanguage; 00446 WORD wCodePage; 00447 } *lpTranslate; 00448 00449 ODS("PacketGetFileVersion\n"); 00450 00451 // Now lets dive in and pull out the version information: 00452 dwVerInfoSize = GetFileVersionInfoSize(FileName, &dwVerHnd); 00453 if (dwVerInfoSize) 00454 { 00455 lpstrVffInfo = GlobalAllocPtr(GMEM_MOVEABLE, dwVerInfoSize); 00456 if (lpstrVffInfo == NULL) 00457 { 00458 ODS("PacketGetFileVersion: failed to allocate memory\n"); 00459 return FALSE; 00460 } 00461 00462 if(!GetFileVersionInfo(FileName, dwVerHnd, dwVerInfoSize, lpstrVffInfo)) 00463 { 00464 ODS("PacketGetFileVersion: failed to call GetFileVersionInfo\n"); 00465 GlobalFreePtr(lpstrVffInfo); 00466 return FALSE; 00467 } 00468 00469 // Read the list of languages and code pages. 00470 if(!VerQueryValue(lpstrVffInfo, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate)) 00471 { 00472 ODS("PacketGetFileVersion: failed to call VerQueryValue\n"); 00473 GlobalFreePtr(lpstrVffInfo); 00474 return FALSE; 00475 } 00476 00477 // Create the file version string for the first (i.e. the only one) language. 00478 wsprintf( SubBlock, 00479 TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"), 00480 (*lpTranslate).wLanguage, 00481 (*lpTranslate).wCodePage); 00482 00483 // Retrieve the file version string for the language. 00484 if(!VerQueryValue(lpstrVffInfo, SubBlock, &lpBuffer, &dwBytes)) 00485 { 00486 ODS("PacketGetFileVersion: failed to call VerQueryValue\n"); 00487 GlobalFreePtr(lpstrVffInfo); 00488 return FALSE; 00489 } 00490 00491 // Convert to ASCII 00492 TmpStr = WChar2SChar(lpBuffer); 00493 00494 if(strlen(TmpStr) >= VersionBuffLen) 00495 { 00496 ODS("PacketGetFileVersion: Input buffer too small\n"); 00497 GlobalFreePtr(lpstrVffInfo); 00498 GlobalFreePtr(TmpStr); 00499 return FALSE; 00500 } 00501 00502 strcpy(VersionBuff, TmpStr); 00503 00504 GlobalFreePtr(lpstrVffInfo); 00505 GlobalFreePtr(TmpStr); 00506 00507 } 00508 else 00509 { 00510 ODSEx("PacketGetFileVersion: failed to call GetFileVersionInfoSize, LastError = %d\n", GetLastError()); 00511 return FALSE; 00512 00513 } 00514 00515 return TRUE; 00516 } 00517 00526 LPADAPTER PacketOpenAdapterNPF(PCHAR AdapterName) 00527 { 00528 LPADAPTER lpAdapter; 00529 BOOLEAN Result; 00530 DWORD error; 00531 SC_HANDLE svcHandle = NULL; 00532 LONG KeyRes; 00533 HKEY PathKey; 00534 SERVICE_STATUS SStat; 00535 BOOLEAN QuerySStat; 00536 WCHAR SymbolicLink[128]; 00537 00538 ODS("PacketOpenAdapterNPF\n"); 00539 00540 scmHandle = OpenSCManager(NULL, NULL, GENERIC_READ); 00541 00542 if(scmHandle == NULL){ 00543 error = GetLastError(); 00544 ODSEx("OpenSCManager failed! LastError=%d\n", error); 00545 } 00546 else{ 00547 // check if the NPF registry key is already present 00548 // this means that the driver is already installed and that we don't need to call PacketInstallDriver 00549 KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE, 00550 NPFRegistryLocation, 00551 0, 00552 KEY_READ, 00553 &PathKey); 00554 00555 if(KeyRes != ERROR_SUCCESS) 00556 { 00557 Result = PacketInstallDriver(scmHandle,&svcHandle); 00558 } 00559 else 00560 { 00561 Result = TRUE; 00562 RegCloseKey(PathKey); 00563 } 00564 00565 if (Result) 00566 { 00567 00568 srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS ); 00569 if (srvHandle != NULL) 00570 { 00571 QuerySStat = QueryServiceStatus(srvHandle, &SStat); 00572 00573 #if defined(_DBG) || defined(_DEBUG_TO_FILE) 00574 switch (SStat.dwCurrentState) 00575 { 00576 case SERVICE_CONTINUE_PENDING: 00577 ODS("The status of the driver is: SERVICE_CONTINUE_PENDING\n"); 00578 break; 00579 case SERVICE_PAUSE_PENDING: 00580 ODS("The status of the driver is: SERVICE_PAUSE_PENDING\n"); 00581 break; 00582 case SERVICE_PAUSED: 00583 ODS("The status of the driver is: SERVICE_PAUSED\n"); 00584 break; 00585 case SERVICE_RUNNING: 00586 ODS("The status of the driver is: SERVICE_RUNNING\n"); 00587 break; 00588 case SERVICE_START_PENDING: 00589 ODS("The status of the driver is: SERVICE_START_PENDING\n"); 00590 break; 00591 case SERVICE_STOP_PENDING: 00592 ODS("The status of the driver is: SERVICE_STOP_PENDING\n"); 00593 break; 00594 case SERVICE_STOPPED: 00595 ODS("The status of the driver is: SERVICE_STOPPED\n"); 00596 break; 00597 00598 default: 00599 ODS("The status of the driver is: unknown\n"); 00600 break; 00601 } 00602 #endif 00603 00604 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING) 00605 { 00606 ODS("Calling startservice\n"); 00607 if (StartService(srvHandle, 0, NULL)==0) 00608 { 00609 error = GetLastError(); 00610 if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS) 00611 { 00612 SetLastError(error); 00613 if (scmHandle != NULL) 00614 CloseServiceHandle(scmHandle); 00615 error = GetLastError(); 00616 ODSEx("PacketOpenAdapterNPF: StartService failed, LastError=%d\n",error); 00617 SetLastError(error); 00618 return NULL; 00619 } 00620 } 00621 } 00622 00623 CloseServiceHandle( srvHandle ); 00624 srvHandle = NULL; 00625 00626 } 00627 else 00628 { 00629 error = GetLastError(); 00630 ODSEx("OpenService failed! Error=%d", error); 00631 SetLastError(error); 00632 } 00633 } 00634 else 00635 { 00636 if(KeyRes != ERROR_SUCCESS) 00637 Result = PacketInstallDriver(scmHandle,&svcHandle); 00638 else 00639 Result = TRUE; 00640 00641 if (Result) { 00642 00643 srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START); 00644 if (srvHandle != NULL) 00645 { 00646 00647 QuerySStat = QueryServiceStatus(srvHandle, &SStat); 00648 00649 #if defined(_DBG) || defined(_DEBUG_TO_FILE) 00650 switch (SStat.dwCurrentState) 00651 { 00652 case SERVICE_CONTINUE_PENDING: 00653 ODS("The status of the driver is: SERVICE_CONTINUE_PENDING\n"); 00654 break; 00655 case SERVICE_PAUSE_PENDING: 00656 ODS("The status of the driver is: SERVICE_PAUSE_PENDING\n"); 00657 break; 00658 case SERVICE_PAUSED: 00659 ODS("The status of the driver is: SERVICE_PAUSED\n"); 00660 break; 00661 case SERVICE_RUNNING: 00662 ODS("The status of the driver is: SERVICE_RUNNING\n"); 00663 break; 00664 case SERVICE_START_PENDING: 00665 ODS("The status of the driver is: SERVICE_START_PENDING\n"); 00666 break; 00667 case SERVICE_STOP_PENDING: 00668 ODS("The status of the driver is: SERVICE_STOP_PENDING\n"); 00669 break; 00670 case SERVICE_STOPPED: 00671 ODS("The status of the driver is: SERVICE_STOPPED\n"); 00672 break; 00673 00674 default: 00675 ODS("The status of the driver is: unknown\n"); 00676 break; 00677 } 00678 #endif 00679 00680 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){ 00681 00682 ODS("Calling startservice\n"); 00683 00684 if (StartService(srvHandle, 0, NULL)==0){ 00685 error = GetLastError(); 00686 if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){ 00687 if (scmHandle != NULL) CloseServiceHandle(scmHandle); 00688 ODSEx("PacketOpenAdapterNPF: StartService failed, LastError=%d\n",error); 00689 SetLastError(error); 00690 return NULL; 00691 } 00692 } 00693 } 00694 00695 CloseServiceHandle( srvHandle ); 00696 srvHandle = NULL; 00697 00698 } 00699 else{ 00700 error = GetLastError(); 00701 ODSEx("OpenService failed! LastError=%d", error); 00702 SetLastError(error); 00703 } 00704 } 00705 } 00706 } 00707 00708 if (scmHandle != NULL) CloseServiceHandle(scmHandle); 00709 00710 lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER)); 00711 if (lpAdapter==NULL) 00712 { 00713 ODS("PacketOpenAdapterNPF: GlobalAlloc Failed\n"); 00714 error=GetLastError(); 00715 //set the error to the one on which we failed 00716 SetLastError(error); 00717 ODS("PacketOpenAdapterNPF: Failed to allocate the adapter structure\n"); 00718 return NULL; 00719 } 00720 lpAdapter->NumWrites=1; 00721 00722 if (LOWORD(GetVersion()) == 4) 00723 wsprintf(SymbolicLink,TEXT("\\\\.\\%s"),&AdapterName[16]); 00724 else 00725 wsprintf(SymbolicLink,TEXT("\\\\.\\Global\\%s"),&AdapterName[16]); 00726 00727 // Copy only the bytes that fit in the adapter structure. 00728 // Note that lpAdapter->SymbolicLink is present for backward compatibility but will 00729 // never be used by the apps 00730 memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH); 00731 00732 //try if it is possible to open the adapter immediately 00733 lpAdapter->hFile=CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ, 00734 0,NULL,OPEN_EXISTING,0,0); 00735 00736 if (lpAdapter->hFile != INVALID_HANDLE_VALUE) 00737 { 00738 00739 if(PacketSetReadEvt(lpAdapter)==FALSE){ 00740 error=GetLastError(); 00741 ODS("PacketOpenAdapterNPF: Unable to open the read event\n"); 00742 GlobalFreePtr(lpAdapter); 00743 //set the error to the one on which we failed 00744 SetLastError(error); 00745 ODSEx("PacketOpenAdapterNPF: PacketSetReadEvt failed, LastError=%d\n",error); 00746 return NULL; 00747 } 00748 00749 PacketSetMaxLookaheadsize(lpAdapter); 00750 00751 _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%S", AdapterName); 00752 00753 return lpAdapter; 00754 } 00755 00756 00757 error=GetLastError(); 00758 GlobalFreePtr(lpAdapter); 00759 //set the error to the one on which we failed 00760 ODSEx("PacketOpenAdapterNPF: CreateFile failed, LastError= %d\n",error); 00761 SetLastError(error); 00762 return NULL; 00763 } 00764 00773 #ifdef HAVE_DAG_API 00774 LPADAPTER PacketOpenAdapterDAG(PCHAR AdapterName, BOOLEAN IsAFile) 00775 { 00776 CHAR DagEbuf[DAGC_ERRBUF_SIZE]; 00777 LPADAPTER lpAdapter; 00778 LONG status; 00779 HKEY dagkey; 00780 DWORD lptype; 00781 DWORD fpc; 00782 DWORD lpcbdata = sizeof(fpc); 00783 WCHAR keyname[512]; 00784 PWCHAR tsn; 00785 00786 00787 lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 00788 sizeof(ADAPTER)); 00789 if (lpAdapter == NULL) 00790 { 00791 return NULL; 00792 } 00793 00794 if(IsAFile) 00795 { 00796 // We must add an entry to the adapter description list, otherwise many function will not 00797 // be able to work 00798 if(!PacketAddAdapterDag(AdapterName, "DAG file", IsAFile)) 00799 { 00800 GlobalFreePtr(lpAdapter); 00801 return NULL; 00802 } 00803 00804 // Flag that this is a DAG file 00805 lpAdapter->Flags = INFO_FLAG_DAG_FILE; 00806 } 00807 else 00808 { 00809 // Flag that this is a DAG card 00810 lpAdapter->Flags = INFO_FLAG_DAG_CARD; 00811 } 00812 00813 // 00814 // See if the user is asking for fast capture with this device 00815 // 00816 00817 lpAdapter->DagFastProcess = FALSE; 00818 00819 tsn = (strstr(strlwr((char*)AdapterName), "dag") != NULL)? 00820 SChar2WChar(strstr(strlwr((char*)AdapterName), "dag")): 00821 L""; 00822 00823 _snwprintf(keyname, sizeof(keyname), L"%s\\CardParams\\%ws", 00824 L"SYSTEM\\CurrentControlSet\\Services\\DAG", 00825 tsn); 00826 00827 GlobalFreePtr(tsn); 00828 00829 do 00830 { 00831 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0 , KEY_READ, &dagkey); 00832 if(status != ERROR_SUCCESS) 00833 break; 00834 00835 status = RegQueryValueEx(dagkey, 00836 L"FastCap", 00837 NULL, 00838 &lptype, 00839 (char*)&fpc, 00840 &lpcbdata); 00841 00842 if(status == ERROR_SUCCESS) 00843 lpAdapter->DagFastProcess = fpc; 00844 00845 RegCloseKey(dagkey); 00846 } 00847 while(FALSE); 00848 00849 // 00850 // Open the card 00851 // 00852 lpAdapter->pDagCard = p_dagc_open(AdapterName, 00853 0, 00854 DagEbuf); 00855 00856 if(lpAdapter->pDagCard == NULL) 00857 { 00858 GlobalFreePtr(lpAdapter); 00859 return NULL; 00860 } 00861 00862 lpAdapter->DagFcsLen = p_dagc_getfcslen(lpAdapter->pDagCard); 00863 00864 _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterName); 00865 00866 // XXX we could create the read event here 00867 00868 return lpAdapter; 00869 } 00870 #endif // HAVE_DAG_API 00871 00872 //--------------------------------------------------------------------------- 00873 // PUBLIC API 00874 //--------------------------------------------------------------------------- 00875 00888 PCHAR PacketGetVersion() 00889 { 00890 return PacketLibraryVersion; 00891 } 00892 00897 PCHAR PacketGetDriverVersion() 00898 { 00899 return PacketDriverVersion; 00900 } 00901 00910 BOOL PacketStopDriver() 00911 { 00912 SC_HANDLE scmHandle; 00913 SC_HANDLE schService; 00914 BOOL ret; 00915 SERVICE_STATUS serviceStatus; 00916 00917 scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 00918 00919 if(scmHandle != NULL){ 00920 00921 schService = OpenService (scmHandle, 00922 NPFServiceName, 00923 SERVICE_ALL_ACCESS 00924 ); 00925 00926 if (schService != NULL) 00927 { 00928 00929 ret = ControlService (schService, 00930 SERVICE_CONTROL_STOP, 00931 &serviceStatus 00932 ); 00933 if (!ret) 00934 { 00935 } 00936 00937 CloseServiceHandle (schService); 00938 00939 CloseServiceHandle(scmHandle); 00940 00941 return ret; 00942 } 00943 } 00944 00945 return FALSE; 00946 00947 } 00948 00956 LPADAPTER PacketOpenAdapter(PCHAR AdapterName) 00957 { 00958 LPADAPTER lpAdapter; 00959 WCHAR *AdapterNameU; 00960 SC_HANDLE svcHandle = NULL; 00961 PCHAR AdapterNameA = NULL; 00962 #ifndef _WINNT4 00963 PADAPTER_INFO TAdInfo; 00964 #endif // _WINNT4 00965 00966 ODSEx("PacketOpenAdapter: trying to open the adapter=%s\n",AdapterName) 00967 00968 if(AdapterName[1]!=0){ //ASCII 00969 00970 AdapterNameU = SChar2WChar(AdapterName); 00971 AdapterNameA = AdapterName; 00972 AdapterName = (PCHAR)AdapterNameU; 00973 } else { //Unicode 00974 AdapterNameU = NULL; 00975 AdapterNameA = WChar2SChar((PWCHAR)AdapterName); 00976 } 00977 00978 #ifndef _WINNT4 00979 00980 WaitForSingleObject(AdaptersInfoMutex, INFINITE); 00981 // Find the PADAPTER_INFO structure associated with this adapter 00982 TAdInfo = PacketFindAdInfo(AdapterNameA); 00983 if(TAdInfo == NULL) 00984 { 00985 PacketUpdateAdInfo(AdapterNameA); 00986 TAdInfo = PacketFindAdInfo(AdapterNameA); 00987 if(TAdInfo == NULL) 00988 { 00989 00990 //can be an ERF file? 00991 lpAdapter = PacketOpenAdapterDAG(AdapterNameA, TRUE); 00992 00993 if (AdapterNameU != NULL) 00994 GlobalFreePtr(AdapterNameU); 00995 else 00996 GlobalFreePtr(AdapterNameA); 00997 00998 ReleaseMutex(AdaptersInfoMutex); 00999 if (lpAdapter == NULL) 01000 SetLastError(ERROR_BAD_UNIT); //this is the best we can do.... 01001 return lpAdapter; 01002 } 01003 } 01004 01005 if(TAdInfo->Flags != INFO_FLAG_NDIS_ADAPTER) 01006 { 01007 // 01008 // Not a standard NDIS adapter, we must have specific handling 01009 // 01010 01011 01012 if(TAdInfo->Flags & INFO_FLAG_NDISWAN_ADAPTER) 01013 { 01014 // 01015 // This is a wan adapter. Open it using the netmon API 01016 // 01017 01018 lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 01019 sizeof(ADAPTER)); 01020 if (lpAdapter == NULL) 01021 { 01022 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU); 01023 else GlobalFreePtr(AdapterNameA); 01024 ReleaseMutex(AdaptersInfoMutex); 01025 SetLastError(ERROR_BAD_UNIT); 01026 return NULL; 01027 } 01028 01029 // Backup flags for future usage 01030 lpAdapter->Flags = TAdInfo->Flags; 01031 01032 // Open the adapter 01033 lpAdapter->pWanAdapter = WanPacketOpenAdapter(); 01034 if (lpAdapter->pWanAdapter == NULL) 01035 { 01036 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU); 01037 else GlobalFreePtr(AdapterNameA); 01038 01039 GlobalFreePtr(lpAdapter); 01040 ReleaseMutex(AdaptersInfoMutex); 01041 SetLastError(ERROR_BAD_UNIT); 01042 return NULL; 01043 } 01044 01045 _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterNameA); 01046 01047 lpAdapter->ReadEvent = WanPacketGetReadEvent(lpAdapter->pWanAdapter); 01048 01049 if (AdapterNameU != NULL) 01050 GlobalFreePtr(AdapterNameU); 01051 else 01052 GlobalFreePtr(AdapterNameA); 01053 01054 ReleaseMutex(AdaptersInfoMutex); 01055 return lpAdapter; 01056 } 01057 else 01058 if(TAdInfo->Flags & INFO_FLAG_DAG_CARD) 01059 { 01060 // 01061 // This is a Dag card. Open it using the dagc API 01062 // 01063 01064 lpAdapter = PacketOpenAdapterDAG(AdapterNameA, FALSE); 01065 01066 if (AdapterNameU != NULL) 01067 GlobalFreePtr(AdapterNameU); 01068 else 01069 GlobalFreePtr(AdapterNameA); 01070 01071 ReleaseMutex(AdaptersInfoMutex); 01072 if (lpAdapter == NULL) 01073 SetLastError(ERROR_BAD_UNIT); 01074 return lpAdapter; 01075 } 01076 01077 } 01078 01079 ReleaseMutex(AdaptersInfoMutex); 01080 01081 #endif // _WINNT4 01082 01083 lpAdapter = PacketOpenAdapterNPF(AdapterName); 01084 01085 if (AdapterNameU != NULL) 01086 GlobalFreePtr(AdapterNameU); 01087 else 01088 GlobalFreePtr(AdapterNameA); 01089 01090 return lpAdapter; 01091 } 01092 01099 VOID PacketCloseAdapter(LPADAPTER lpAdapter) 01100 { 01101 01102 #ifndef _WINNT4 01103 if (lpAdapter->pWanAdapter != NULL) 01104 { 01105 WanPacketCloseAdapter(lpAdapter->pWanAdapter); 01106 GlobalFreePtr(lpAdapter); 01107 return; 01108 } 01109 #ifdef HAVE_DAG_API 01110 else 01111 if(lpAdapter->pDagCard != NULL) 01112 { 01113 if(lpAdapter->Flags & INFO_FLAG_DAG_FILE & ~INFO_FLAG_DAG_CARD) 01114 { 01115 // This is a file. We must remove the entry in the adapter description list 01116 PacketUpdateAdInfo(lpAdapter->Name); 01117 } 01118 p_dagc_close(lpAdapter->pDagCard); 01119 } 01120 #endif // HAVE_DAG_API 01121 #endif // _WINNT4 01122 01123 CloseHandle(lpAdapter->hFile); 01124 SetEvent(lpAdapter->ReadEvent); 01125 CloseHandle(lpAdapter->ReadEvent); 01126 GlobalFreePtr(lpAdapter); 01127 } 01128 01141 LPPACKET PacketAllocatePacket(void) 01142 { 01143 01144 LPPACKET lpPacket; 01145 lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET)); 01146 if (lpPacket==NULL) 01147 { 01148 ODS("PacketAllocatePacket: GlobalAlloc Failed\n"); 01149 return NULL; 01150 } 01151 return lpPacket; 01152 } 01153 01162 VOID PacketFreePacket(LPPACKET lpPacket) 01163 01164 { 01165 GlobalFreePtr(lpPacket); 01166 } 01167 01184 VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length) 01185 01186 { 01187 lpPacket->Buffer = Buffer; 01188 lpPacket->Length = Length; 01189 lpPacket->ulBytesReceived = 0; 01190 lpPacket->bIoComplete = FALSE; 01191 } 01192 01223 BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync) 01224 { 01225 BOOLEAN res; 01226 01227 #ifndef _WINNT4 01228 01229 if (AdapterObject->pWanAdapter != NULL) 01230 { 01231 lpPacket->ulBytesReceived = WanPacketReceivePacket(AdapterObject->pWanAdapter, lpPacket->Buffer, lpPacket->Length); 01232 return TRUE; 01233 } 01234 #ifdef HAVE_DAG_API 01235 else 01236 if(AdapterObject->pDagCard != NULL) 01237 { 01238 01239 p_dagc_wait(AdapterObject->pDagCard, &AdapterObject->DagReadTimeout); 01240 01241 if(p_dagc_receive(AdapterObject->pDagCard, &AdapterObject->DagBuffer, &lpPacket->ulBytesReceived) == 0) 01242 return TRUE; 01243 else 01244 return FALSE; 01245 } 01246 #endif // HAVE_DAG_API 01247 #endif // _WINNT4 01248 01249 if((int)AdapterObject->ReadTimeOut != -1) 01250 WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut); 01251 01252 res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL); 01253 01254 return res; 01255 } 01256 01286 BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync) 01287 { 01288 DWORD BytesTransfered; 01289 01290 01291 #ifndef _WINNT4 01292 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01293 { 01294 ODS("PacketSendPacket: packet sending not allowed on wan adapters\n"); 01295 return FALSE; 01296 } 01297 #endif // _WINNT4 01298 01299 return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL); 01300 } 01301 01302 01330 INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync) 01331 { 01332 BOOLEAN Res; 01333 DWORD BytesTransfered, TotBytesTransfered=0; 01334 struct timeval BufStartTime; 01335 LARGE_INTEGER StartTicks, CurTicks, TargetTicks, TimeFreq; 01336 01337 01338 ODS("PacketSendPackets"); 01339 01340 #ifndef _WINNT4 01341 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01342 { 01343 ODS("PacketSendPackets: packet sending not allowed on wan adapters\n"); 01344 return FALSE; 01345 } 01346 #endif // _WINNT4 01347 01348 // Obtain starting timestamp of the buffer 01349 BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec; 01350 BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec; 01351 01352 // Retrieve the reference time counters 01353 QueryPerformanceCounter(&StartTicks); 01354 QueryPerformanceFrequency(&TimeFreq); 01355 01356 CurTicks.QuadPart = StartTicks.QuadPart; 01357 01358 do{ 01359 // Send the data to the driver 01360 Res = DeviceIoControl(AdapterObject->hFile, 01361 (Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC, 01362 (PCHAR)PacketBuff + TotBytesTransfered, 01363 Size - TotBytesTransfered, 01364 NULL, 01365 0, 01366 &BytesTransfered, 01367 NULL); 01368 01369 TotBytesTransfered += BytesTransfered; 01370 01371 // calculate the time interval to wait before sending the next packet 01372 TargetTicks.QuadPart = StartTicks.QuadPart + 01373 (LONGLONG) 01374 ((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 + 01375 (((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) * 01376 (TimeFreq.QuadPart) / 1000000; 01377 01378 // Exit from the loop on termination or error 01379 if(TotBytesTransfered >= Size || Res != TRUE) 01380 break; 01381 01382 // Wait until the time interval has elapsed 01383 while( CurTicks.QuadPart <= TargetTicks.QuadPart ) 01384 QueryPerformanceCounter(&CurTicks); 01385 01386 } 01387 while(TRUE); 01388 01389 return TotBytesTransfered; 01390 } 01391 01410 BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes) 01411 { 01412 DWORD BytesReturned; 01413 01414 #ifndef _WINNT4 01415 if (AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) 01416 return WanPacketSetMinToCopy(AdapterObject->pWanAdapter, nbytes); 01417 #ifdef HAVE_DAG_API 01418 else 01419 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01420 // No mintocopy with DAGs 01421 return TRUE; 01422 #endif // HAVE_DAG_API 01423 #endif // _WINNT4 01424 01425 return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL); 01426 } 01427 01464 BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode) 01465 { 01466 DWORD BytesReturned; 01467 01468 #ifndef _WINNT4 01469 if (AdapterObject->pWanAdapter != NULL) 01470 return WanPacketSetMode(AdapterObject->pWanAdapter, mode); 01471 #endif // _WINNT4 01472 01473 return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL); 01474 } 01475 01490 BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len) 01491 { 01492 DWORD BytesReturned; 01493 WCHAR *FileName; 01494 BOOLEAN res; 01495 WCHAR NameWithPath[1024]; 01496 int TStrLen; 01497 WCHAR *NamePos; 01498 01499 #ifndef _WINNT4 01500 if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01501 { 01502 ODS("PacketSetDumpName: not allowed on wan adapters\n"); 01503 return FALSE; 01504 } 01505 #endif // _WINNT4 01506 01507 if(((PUCHAR)name)[1]!=0 && len>1){ //ASCII 01508 FileName=SChar2WChar(name); 01509 len*=2; 01510 } 01511 else { //Unicode 01512 FileName=name; 01513 } 01514 01515 TStrLen=GetFullPathName(FileName,1024,NameWithPath,&NamePos); 01516 01517 len=TStrLen*2+2; //add the terminating null character 01518 01519 // Try to catch malformed strings 01520 if(len>2048){ 01521 if(((PUCHAR)name)[1]!=0 && len>1) free(FileName); 01522 return FALSE; 01523 } 01524 01525 res = DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL); 01526 free(FileName); 01527 return res; 01528 } 01529 01545 BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks) 01546 { 01547 DWORD BytesReturned; 01548 UINT valbuff[2]; 01549 01550 #ifndef _WINNT4 01551 if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01552 { 01553 ODS("PacketSetDumpLimits: not allowed on wan adapters\n"); 01554 return FALSE; 01555 } 01556 #endif // _WINNT4 01557 01558 valbuff[0] = maxfilesize; 01559 valbuff[1] = maxnpacks; 01560 01561 return DeviceIoControl(AdapterObject->hFile, 01562 pBIOCSETDUMPLIMITS, 01563 valbuff, 01564 sizeof valbuff, 01565 NULL, 01566 0, 01567 &BytesReturned, 01568 NULL); 01569 } 01570 01584 BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync) 01585 { 01586 DWORD BytesReturned; 01587 int IsDumpEnded; 01588 BOOLEAN res; 01589 01590 #ifndef _WINNT4 01591 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01592 { 01593 ODS("PacketIsDumpEnded: not allowed on wan adapters\n"); 01594 return FALSE; 01595 } 01596 #endif // _WINNT4 01597 01598 if(sync) 01599 WaitForSingleObject(AdapterObject->ReadEvent, INFINITE); 01600 01601 res = DeviceIoControl(AdapterObject->hFile, 01602 pBIOCISDUMPENDED, 01603 NULL, 01604 0, 01605 &IsDumpEnded, 01606 4, 01607 &BytesReturned, 01608 NULL); 01609 01610 if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished 01611 01612 return (BOOLEAN)IsDumpEnded; 01613 } 01614 01634 HANDLE PacketGetReadEvent(LPADAPTER AdapterObject) 01635 { 01636 return AdapterObject->ReadEvent; 01637 } 01638 01647 BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites) 01648 { 01649 DWORD BytesReturned; 01650 01651 #ifndef _WINNT4 01652 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01653 { 01654 ODS("PacketSetNumWrites: not allowed on wan adapters\n"); 01655 return FALSE; 01656 } 01657 #endif // _WINNT4 01658 01659 return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL); 01660 } 01661 01674 BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout) 01675 { 01676 DWORD BytesReturned; 01677 int DriverTimeOut=-1; 01678 01679 #ifndef _WINNT4 01680 if (AdapterObject->pWanAdapter != NULL) 01681 return WanPacketSetReadTimeout(AdapterObject->pWanAdapter,timeout); 01682 #endif // _WINNT4 01683 01684 AdapterObject->ReadTimeOut=timeout; 01685 01686 #ifdef HAVE_DAG_API 01687 // Under DAG, we simply store the timeout value and then 01688 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01689 { 01690 if(timeout == 1) 01691 { 01692 // tell DAG card to return immediately 01693 AdapterObject->DagReadTimeout.tv_sec = 0; 01694 AdapterObject->DagReadTimeout.tv_usec = 0; 01695 } 01696 else 01697 if(timeout == 1) 01698 { 01699 // tell the DAG card to wait forvever 01700 AdapterObject->DagReadTimeout.tv_sec = -1; 01701 AdapterObject->DagReadTimeout.tv_usec = -1; 01702 } 01703 else 01704 { 01705 // Set the timeout for the DAG card 01706 AdapterObject->DagReadTimeout.tv_sec = timeout / 1000; 01707 AdapterObject->DagReadTimeout.tv_usec = (timeout * 1000) % 1000000; 01708 } 01709 01710 return TRUE; 01711 } 01712 #endif // HAVE_DAG_API 01713 01714 return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL); 01715 } 01716 01733 BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim) 01734 { 01735 DWORD BytesReturned; 01736 01737 #ifndef _WINNT4 01738 if (AdapterObject->pWanAdapter != NULL) 01739 return WanPacketSetBufferSize(AdapterObject->pWanAdapter, dim); 01740 #ifdef HAVE_DAG_API 01741 else 01742 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01743 // We can't change DAG buffers 01744 return TRUE; 01745 #endif // HAVE_DAG_API 01746 01747 #endif // _WINNT4 01748 return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL); 01749 } 01750 01771 BOOLEAN PacketSetBpf(LPADAPTER AdapterObject, struct bpf_program *fp) 01772 { 01773 DWORD BytesReturned; 01774 01775 #ifndef _WINNT4 01776 if (AdapterObject->pWanAdapter != NULL) 01777 return WanPacketSetBpfFilter(AdapterObject->pWanAdapter, (PUCHAR)fp->bf_insns, fp->bf_len * sizeof(struct bpf_insn)); 01778 #ifdef HAVE_DAG_API 01779 else 01780 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01781 // Delegate the filtering to higher layers since it's too expensive here 01782 return TRUE; 01783 #endif // HAVE_DAG_API 01784 #endif // _WINNT4 01785 01786 return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL); 01787 } 01788 01803 INT PacketSetSnapLen(LPADAPTER AdapterObject, int snaplen) 01804 { 01805 01806 #ifdef HAVE_DAG_API 01807 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01808 return p_dagc_setsnaplen(AdapterObject->pDagCard, snaplen); 01809 else 01810 #endif // HAVE_DAG_API 01811 return 0; 01812 } 01813 01827 BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s) 01828 { 01829 BOOLEAN Res; 01830 DWORD BytesReturned; 01831 struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications 01832 01833 #ifndef _WINNT4 01834 #ifdef HAVE_DAG_API 01835 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01836 { 01837 dagc_stats_t DagStats; 01838 01839 // Note: DAG cards are currently very limited from the statistics reporting point of view, 01840 // so most of the values returned by dagc_stats() are zero at the moment 01841 if(p_dagc_stats(AdapterObject->pDagCard, &DagStats) == 0) 01842 { 01843 // XXX: Only copy the dropped packets for now, since the received counter is not supported by 01844 // DAGS at the moment 01845 01846 s->bs_recv = (ULONG)DagStats.received; 01847 s->bs_drop = (ULONG)DagStats.dropped; 01848 return TRUE; 01849 } 01850 else 01851 return FALSE; 01852 } 01853 else 01854 #endif // HAVE_DAG_API 01855 if ( AdapterObject->pWanAdapter != NULL) 01856 Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat); 01857 else 01858 #endif // _WINNT4 01859 01860 Res = DeviceIoControl(AdapterObject->hFile, 01861 pBIOCGSTATS, 01862 NULL, 01863 0, 01864 &tmpstat, 01865 sizeof(struct bpf_stat), 01866 &BytesReturned, 01867 NULL); 01868 01869 01870 // Copy only the first two values retrieved from the driver 01871 s->bs_recv = tmpstat.bs_recv; 01872 s->bs_drop = tmpstat.bs_drop; 01873 01874 return Res; 01875 } 01876 01889 BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s) 01890 { 01891 BOOLEAN Res; 01892 DWORD BytesReturned; 01893 struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications 01894 01895 #ifndef _WINNT4 01896 #ifdef HAVE_DAG_API 01897 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01898 { 01899 dagc_stats_t DagStats; 01900 01901 // Note: DAG cards are currently very limited from the statistics reporting point of view, 01902 // so most of the values returned by dagc_stats() are zero at the moment 01903 p_dagc_stats(AdapterObject->pDagCard, &DagStats); 01904 s->bs_recv = (ULONG)DagStats.received; 01905 s->bs_drop = (ULONG)DagStats.dropped; 01906 s->ps_ifdrop = 0; 01907 s->bs_capt = (ULONG)DagStats.captured; 01908 } 01909 #endif // HAVE_DAG_API 01910 if(AdapterObject->pWanAdapter != NULL) 01911 Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat); 01912 else 01913 #endif // _WINNT4 01914 01915 Res = DeviceIoControl(AdapterObject->hFile, 01916 pBIOCGSTATS, 01917 NULL, 01918 0, 01919 &tmpstat, 01920 sizeof(struct bpf_stat), 01921 &BytesReturned, 01922 NULL); 01923 01924 s->bs_recv = tmpstat.bs_recv; 01925 s->bs_drop = tmpstat.bs_drop; 01926 s->ps_ifdrop = tmpstat.ps_ifdrop; 01927 s->bs_capt = tmpstat.bs_capt; 01928 01929 return Res; 01930 } 01931 01944 BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData) 01945 { 01946 DWORD BytesReturned; 01947 BOOLEAN Result; 01948 01949 #ifndef _WINNT4 01950 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01951 return FALSE; 01952 #endif // _WINNT4 01953 01954 Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? (DWORD)pBIOCSETOID : (DWORD)pBIOCQUERYOID, 01955 OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData, 01956 sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL); 01957 01958 // output some debug info 01959 ODSEx("PacketRequest, OID=%d ", OidData->Oid); 01960 ODSEx("Length=%d ", OidData->Length); 01961 ODSEx("Set=%d ", Set); 01962 ODSEx("Res=%d\n", Result); 01963 01964 return Result; 01965 } 01966 01983 BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter) 01984 { 01985 BOOLEAN Status; 01986 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); 01987 PPACKET_OID_DATA OidData; 01988 01989 #ifndef _WINNT4 01990 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01991 return TRUE; 01992 #endif // _WINNT4 01993 01994 OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); 01995 if (OidData == NULL) { 01996 ODS("PacketSetHwFilter: GlobalAlloc Failed\n"); 01997 return FALSE; 01998 } 01999 OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER; 02000 OidData->Length=sizeof(ULONG); 02001 *((PULONG)OidData->Data)=Filter; 02002 Status=PacketRequest(AdapterObject,TRUE,OidData); 02003 GlobalFreePtr(OidData); 02004 return Status; 02005 } 02006 02028 BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize) 02029 { 02030 PADAPTER_INFO TAdInfo; 02031 ULONG SizeNeeded = 1; 02032 ULONG SizeNames = 1; 02033 ULONG SizeDesc; 02034 ULONG OffDescriptions; 02035 02036 ODSEx("PacketGetAdapterNames: BufferSize=%d\n", *BufferSize); 02037 02038 // 02039 // Create the adapter information list 02040 // 02041 PacketPopulateAdaptersInfoList(); 02042 02043 WaitForSingleObject(AdaptersInfoMutex, INFINITE); 02044 if(!AdaptersInfoList) 02045 { 02046 ReleaseMutex(AdaptersInfoMutex); 02047 *BufferSize = 0; 02048 return FALSE; // No adapters to return 02049 } 02050 02051 // 02052 // First scan of the list to calculate the offsets and check the sizes 02053 // 02054 for(TAdInfo = AdaptersInfoList; TAdInfo != NULL; TAdInfo = TAdInfo->Next) 02055 { 02056 // Update the size variables 02057 SizeNeeded += strlen(TAdInfo->Name) + strlen(TAdInfo->Description) + 2; 02058 SizeNames += strlen(TAdInfo->Name) + 1; 02059 } 02060 02061 // Chack that we don't overflow the buffer. 02062 // Note: 2 is the number of additional separators needed inside the list 02063 if(SizeNeeded + 2 >= *BufferSize || pStr == NULL) 02064 { 02065 ReleaseMutex(AdaptersInfoMutex); 02066 02067 ODS("PacketGetAdapterNames: input buffer too small\n"); 02068 *BufferSize = SizeNeeded + 4; // Report the required size 02069 return FALSE; 02070 } 02071 02072 02073 OffDescriptions = SizeNames; 02074 02075 // 02076 // Second scan of the list to copy the information 02077 // 02078 for(TAdInfo = AdaptersInfoList, SizeNames = 0, SizeDesc = 0; TAdInfo != NULL; TAdInfo = TAdInfo->Next) 02079 { 02080 // Copy the data 02081 strcpy(((PCHAR)pStr) + SizeNames, TAdInfo->Name); 02082 strcpy(((PCHAR)pStr) + OffDescriptions + SizeDesc, TAdInfo->Description); 02083 02084 // Update the size variables 02085 SizeNames += strlen(TAdInfo->Name) + 1; 02086 SizeDesc += strlen(TAdInfo->Description) + 1; 02087 } 02088 02089 // Separate the two lists 02090 ((PCHAR)pStr)[SizeNames] = 0; 02091 02092 // End the list with a further \0 02093 ((PCHAR)pStr)[SizeNeeded] = 0; 02094 02095 02096 ReleaseMutex(AdaptersInfoMutex); 02097 return TRUE; 02098 } 02099 02113 BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries) 02114 { 02115 PADAPTER_INFO TAdInfo; 02116 PCHAR Tname; 02117 BOOLEAN Res, FreeBuff; 02118 02119 ODS("PacketGetNetInfo\n"); 02120 02121 // Provide conversion for backward compatibility 02122 if(AdapterName[1] != 0) 02123 { //ASCII 02124 Tname = AdapterName; 02125 FreeBuff = FALSE; 02126 } 02127 else 02128 { 02129 Tname = WChar2SChar((PWCHAR)AdapterName); 02130 FreeBuff = TRUE; 02131 } 02132 02133 // 02134 // Update the information about this adapter 02135 // 02136 if(!PacketUpdateAdInfo(Tname)) 02137 { 02138 ODS("PacketGetNetInfo: Adapter not found\n"); 02139 if(FreeBuff)GlobalFreePtr(Tname); 02140 return FALSE; 02141 } 02142 02143 WaitForSingleObject(AdaptersInfoMutex, INFINITE); 02144 // Find the PADAPTER_INFO structure associated with this adapter 02145 TAdInfo = PacketFindAdInfo(Tname); 02146 02147 if(TAdInfo != NULL) 02148 { 02149 *NEntries = (TAdInfo->NNetworkAddresses < *NEntries)? TAdInfo->NNetworkAddresses: *NEntries; 02150 //TODO what if nentries = 0? 02151 if (*NEntries > 0) 02152 memcpy(buffer, TAdInfo->NetworkAddresses, *NEntries * sizeof(npf_if_addr)); 02153 Res = TRUE; 02154 } 02155 else 02156 { 02157 ODS("PacketGetNetInfo: Adapter not found\n"); 02158 Res = FALSE; 02159 } 02160 02161 ReleaseMutex(AdaptersInfoMutex); 02162 02163 if(FreeBuff)GlobalFreePtr(Tname); 02164 02165 return Res; 02166 } 02167 02184 BOOLEAN PacketGetNetType(LPADAPTER AdapterObject, NetType *type) 02185 { 02186 PADAPTER_INFO TAdInfo; 02187 BOOLEAN ret; 02188 ODS("PacketGetNetType\n"); 02189 02190 WaitForSingleObject(AdaptersInfoMutex, INFINITE); 02191 // Find the PADAPTER_INFO structure associated with this adapter 02192 TAdInfo = PacketFindAdInfo(AdapterObject->Name); 02193 02194 if(TAdInfo != NULL) 02195 { 02196 // Copy the data 02197 memcpy(type, &(TAdInfo->LinkLayer), sizeof(struct NetType)); 02198 ret = TRUE; 02199 } 02200 else 02201 { 02202 ODS("PacketGetNetType: Adapter not found\n"); 02203 ret = FALSE; 02204 } 02205 02206 ReleaseMutex(AdaptersInfoMutex); 02207 02208 return ret; 02209 } 02210 02211 /* @} */
documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.