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 #ifdef HAVE_DAG_API 00090 HMODULE DagcLib; 00091 #endif // HAVE_DAG_API 00092 00093 switch(Reason) 00094 { 00095 case DLL_PROCESS_ATTACH: 00096 00097 ODS("************Packet32: DllMain************\n"); 00098 00099 #ifdef _DEBUG_TO_FILE 00100 // dump a bunch of registry keys useful for debug to file 00101 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 00102 "adapters.reg"); 00103 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip", 00104 "tcpip.reg"); 00105 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\NPF", 00106 "npf.reg"); 00107 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services", 00108 "services.reg"); 00109 #endif 00110 00111 // Create the mutex that will protect the adapter information list 00112 AdaptersInfoMutex = CreateMutex(NULL, FALSE, NULL); 00113 00114 // 00115 // Retrieve packet.dll version information from the file 00116 // 00117 PacketGetFileVersion(TEXT("packet.dll"), PacketLibraryVersion, sizeof(PacketLibraryVersion)); 00118 00119 // 00120 // Retrieve NPF.sys version information from the file 00121 // 00122 PacketGetFileVersion(TEXT("drivers\\npf.sys"), PacketDriverVersion, sizeof(PacketDriverVersion)); 00123 00124 // 00125 // Locate GetAdaptersAddresses dinamically since it is not present in Win2k 00126 // 00127 IPHMod = GetModuleHandle(TEXT("Iphlpapi")); 00128 00129 #ifndef _WINNT4 00130 GetAdaptersAddressesPointer = (GAAHandler) GetProcAddress(IPHMod ,"GetAdaptersAddresses"); 00131 #endif // _WINNT4 00132 00133 #ifdef HAVE_DAG_API 00134 /* We load dinamically the dag library in order link it only when it's present on the system */ 00135 if((DagcLib = LoadLibrary(TEXT("dagc.dll"))) == NULL) 00136 { 00137 // Report the error but go on 00138 ODS("dag capture library not found on this system\n"); 00139 break; 00140 } 00141 00142 p_dagc_open = (dagc_open_handler) GetProcAddress(DagcLib, "dagc_open"); 00143 p_dagc_close = (dagc_close_handler) GetProcAddress(DagcLib, "dagc_close"); 00144 p_dagc_setsnaplen = (dagc_setsnaplen_handler) GetProcAddress(DagcLib, "dagc_setsnaplen"); 00145 p_dagc_getlinktype = (dagc_getlinktype_handler) GetProcAddress(DagcLib, "dagc_getlinktype"); 00146 p_dagc_getlinkspeed = (dagc_getlinkspeed_handler) GetProcAddress(DagcLib, "dagc_getlinkspeed"); 00147 p_dagc_getfcslen = (dagc_getfcslen_handler) GetProcAddress(DagcLib, "dagc_getfcslen"); 00148 p_dagc_receive = (dagc_receive_handler) GetProcAddress(DagcLib, "dagc_receive"); 00149 p_dagc_wait = (dagc_wait_handler) GetProcAddress(DagcLib, "dagc_wait"); 00150 p_dagc_stats = (dagc_stats_handler) GetProcAddress(DagcLib, "dagc_stats"); 00151 p_dagc_finddevs = (dagc_finddevs_handler) GetProcAddress(DagcLib, "dagc_finddevs"); 00152 p_dagc_freedevs = (dagc_freedevs_handler) GetProcAddress(DagcLib, "dagc_freedevs"); 00153 00154 #endif /* HAVE_DAG_API */ 00155 00156 break; 00157 00158 case DLL_PROCESS_DETACH: 00159 00160 CloseHandle(AdaptersInfoMutex); 00161 00162 break; 00163 00164 default: 00165 break; 00166 } 00167 00168 return Status; 00169 } 00170 00179 ULONG inet_addrU(const WCHAR *cp) 00180 { 00181 ULONG val, part; 00182 WCHAR c; 00183 int i; 00184 00185 val = 0; 00186 for (i = 0; i < 4; i++) { 00187 part = 0; 00188 while ((c = *cp++) != '\0' && c != '.') { 00189 if (c < '0' || c > '9') 00190 return -1; 00191 part = part*10 + (c - '0'); 00192 } 00193 if (part > 255) 00194 return -1; 00195 val = val | (part << i*8); 00196 if (i == 3) { 00197 if (c != '\0') 00198 return -1; // extra gunk at end of string 00199 } else { 00200 if (c == '\0') 00201 return -1; // string ends early 00202 } 00203 } 00204 return val; 00205 } 00206 00213 PWCHAR SChar2WChar(PCHAR string) 00214 { 00215 PWCHAR TmpStr; 00216 TmpStr = (WCHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (strlen(string)+2)*sizeof(WCHAR)); 00217 00218 MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (strlen(string)+2)); 00219 00220 return TmpStr; 00221 } 00222 00229 PCHAR WChar2SChar(PWCHAR string) 00230 { 00231 PCHAR TmpStr; 00232 TmpStr = (CHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (wcslen(string)+2)); 00233 00234 // Conver to ASCII 00235 WideCharToMultiByte( 00236 CP_ACP, 00237 0, 00238 string, 00239 -1, 00240 TmpStr, 00241 (wcslen(string)+2), // size of buffer 00242 NULL, 00243 NULL); 00244 00245 return TmpStr; 00246 } 00247 00257 BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject) 00258 { 00259 BOOLEAN Status; 00260 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); 00261 PPACKET_OID_DATA OidData; 00262 00263 OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); 00264 if (OidData == NULL) { 00265 ODS("PacketSetMaxLookaheadsize failed\n"); 00266 return FALSE; 00267 } 00268 00269 //set the size of the lookahead buffer to the maximum available by the the NIC driver 00270 OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD; 00271 OidData->Length=sizeof(ULONG); 00272 Status=PacketRequest(AdapterObject,FALSE,OidData); 00273 OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD; 00274 Status=PacketRequest(AdapterObject,TRUE,OidData); 00275 GlobalFreePtr(OidData); 00276 return Status; 00277 } 00278 00289 BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject) 00290 { 00291 DWORD BytesReturned; 00292 TCHAR EventName[39]; 00293 00294 // this tells the terminal service to retrieve the event from the global namespace 00295 wcsncpy(EventName,L"Global\\",sizeof(L"Global\\")); 00296 00297 // retrieve the name of the shared event from the driver 00298 if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName+7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) return FALSE; 00299 00300 EventName[20]=0; // terminate the string 00301 00302 // open the shared event 00303 AdapterObject->ReadEvent=CreateEvent(NULL, 00304 TRUE, 00305 FALSE, 00306 EventName); 00307 00308 // in NT4 "Global\" is not automatically ignored: try to use simply the event name 00309 if(GetLastError()!=ERROR_ALREADY_EXISTS){ 00310 if(AdapterObject->ReadEvent != NULL) 00311 CloseHandle(AdapterObject->ReadEvent); 00312 00313 // open the shared event 00314 AdapterObject->ReadEvent=CreateEvent(NULL, 00315 TRUE, 00316 FALSE, 00317 EventName+7); 00318 } 00319 00320 if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){ 00321 ODS("PacketSetReadEvt: error retrieving the event from the kernel\n"); 00322 return FALSE; 00323 } 00324 00325 AdapterObject->ReadTimeOut=0; 00326 00327 return TRUE; 00328 } 00329 00339 BOOL PacketInstallDriver(SC_HANDLE ascmHandle,SC_HANDLE *srvHandle) 00340 { 00341 BOOL result = FALSE; 00342 ULONG err = 0; 00343 00344 ODS("installdriver\n"); 00345 00346 *srvHandle = CreateService(ascmHandle, 00347 NPFServiceName, 00348 NPFServiceDesc, 00349 SERVICE_ALL_ACCESS, 00350 SERVICE_KERNEL_DRIVER, 00351 SERVICE_DEMAND_START, 00352 SERVICE_ERROR_NORMAL, 00353 NPFDriverPath, 00354 NULL, NULL, NULL, NULL, NULL); 00355 if (*srvHandle == NULL) 00356 { 00357 if (GetLastError() == ERROR_SERVICE_EXISTS) 00358 { 00359 //npf.sys already existed 00360 result = TRUE; 00361 } 00362 } 00363 else 00364 { 00365 //Created service for npf.sys 00366 result = TRUE; 00367 } 00368 if (result == TRUE) 00369 if (*srvHandle != NULL) 00370 CloseServiceHandle(*srvHandle); 00371 00372 if(result == FALSE){ 00373 err = GetLastError(); 00374 if(err != 2) 00375 ODSEx("PacketInstallDriver failed, Error=%d\n",err); 00376 } 00377 00378 SetLastError(err); 00379 return result; 00380 00381 } 00382 00392 #ifdef _DEBUG_TO_FILE 00393 00394 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName) 00395 { 00396 CHAR Command[256]; 00397 00398 strcpy(Command, "regedit /e "); 00399 strcat(Command, FileName); 00400 strcat(Command, " "); 00401 strcat(Command, KeyName); 00402 00404 system(Command); 00405 00406 return TRUE; 00407 } 00408 #endif 00409 00419 BOOL PacketGetFileVersion(LPTSTR FileName, PCHAR VersionBuff, UINT VersionBuffLen) 00420 { 00421 DWORD dwVerInfoSize; // Size of version information block 00422 DWORD dwVerHnd=0; // An 'ignored' parameter, always '0' 00423 LPSTR lpstrVffInfo; 00424 UINT cbTranslate, dwBytes; 00425 TCHAR SubBlock[64]; 00426 PVOID lpBuffer; 00427 PCHAR TmpStr; 00428 00429 // Structure used to store enumerated languages and code pages. 00430 struct LANGANDCODEPAGE { 00431 WORD wLanguage; 00432 WORD wCodePage; 00433 } *lpTranslate; 00434 00435 ODS("PacketGetFileVersion\n"); 00436 00437 // Now lets dive in and pull out the version information: 00438 dwVerInfoSize = GetFileVersionInfoSize(FileName, &dwVerHnd); 00439 if (dwVerInfoSize) 00440 { 00441 lpstrVffInfo = GlobalAllocPtr(GMEM_MOVEABLE, dwVerInfoSize); 00442 if (lpstrVffInfo == NULL) 00443 { 00444 ODS("PacketGetFileVersion: failed to allocate memory\n"); 00445 return FALSE; 00446 } 00447 00448 if(!GetFileVersionInfo(FileName, dwVerHnd, dwVerInfoSize, lpstrVffInfo)) 00449 { 00450 ODS("PacketGetFileVersion: failed to call GetFileVersionInfo\n"); 00451 GlobalFreePtr(lpstrVffInfo); 00452 return FALSE; 00453 } 00454 00455 // Read the list of languages and code pages. 00456 if(!VerQueryValue(lpstrVffInfo, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate)) 00457 { 00458 ODS("PacketGetFileVersion: failed to call VerQueryValue\n"); 00459 GlobalFreePtr(lpstrVffInfo); 00460 return FALSE; 00461 } 00462 00463 // Create the file version string for the first (i.e. the only one) language. 00464 wsprintf( SubBlock, 00465 TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"), 00466 (*lpTranslate).wLanguage, 00467 (*lpTranslate).wCodePage); 00468 00469 // Retrieve the file version string for the language. 00470 if(!VerQueryValue(lpstrVffInfo, SubBlock, &lpBuffer, &dwBytes)) 00471 { 00472 ODS("PacketGetFileVersion: failed to call VerQueryValue\n"); 00473 GlobalFreePtr(lpstrVffInfo); 00474 return FALSE; 00475 } 00476 00477 // Convert to ASCII 00478 TmpStr = WChar2SChar(lpBuffer); 00479 00480 if(strlen(TmpStr) >= VersionBuffLen) 00481 { 00482 ODS("PacketGetFileVersion: Input buffer too small\n"); 00483 GlobalFreePtr(lpstrVffInfo); 00484 GlobalFreePtr(TmpStr); 00485 return FALSE; 00486 } 00487 00488 strcpy(VersionBuff, TmpStr); 00489 00490 GlobalFreePtr(TmpStr); 00491 00492 } 00493 else 00494 { 00495 ODSEx("PacketGetFileVersion: failed to call GetFileVersionInfoSize, LastError = %d\n", GetLastError()); 00496 return FALSE; 00497 00498 } 00499 00500 return TRUE; 00501 } 00502 00511 LPADAPTER PacketOpenAdapterNPF(PCHAR AdapterName) 00512 { 00513 LPADAPTER lpAdapter; 00514 BOOLEAN Result; 00515 DWORD error; 00516 SC_HANDLE svcHandle = NULL; 00517 LONG KeyRes; 00518 HKEY PathKey; 00519 SERVICE_STATUS SStat; 00520 BOOLEAN QuerySStat; 00521 WCHAR SymbolicLink[128]; 00522 00523 ODS("PacketOpenAdapterNPF\n"); 00524 00525 scmHandle = OpenSCManager(NULL, NULL, GENERIC_READ); 00526 00527 if(scmHandle == NULL){ 00528 error = GetLastError(); 00529 ODSEx("OpenSCManager failed! LastError=%d\n", error); 00530 } 00531 else{ 00532 // check if the NPF registry key is already present 00533 // this means that the driver is already installed and that we don't need to call PacketInstallDriver 00534 KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE, 00535 NPFRegistryLocation, 00536 0, 00537 KEY_READ, 00538 &PathKey); 00539 00540 if(KeyRes != ERROR_SUCCESS) 00541 { 00542 Result = PacketInstallDriver(scmHandle,&svcHandle); 00543 } 00544 else 00545 { 00546 Result = TRUE; 00547 RegCloseKey(PathKey); 00548 } 00549 00550 if (Result) 00551 { 00552 00553 srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS ); 00554 if (srvHandle != NULL) 00555 { 00556 QuerySStat = QueryServiceStatus(srvHandle, &SStat); 00557 00558 #if defined(_DBG) || defined(_DEBUG_TO_FILE) 00559 switch (SStat.dwCurrentState) 00560 { 00561 case SERVICE_CONTINUE_PENDING: 00562 ODS("The status of the driver is: SERVICE_CONTINUE_PENDING\n"); 00563 break; 00564 case SERVICE_PAUSE_PENDING: 00565 ODS("The status of the driver is: SERVICE_PAUSE_PENDING\n"); 00566 break; 00567 case SERVICE_PAUSED: 00568 ODS("The status of the driver is: SERVICE_PAUSED\n"); 00569 break; 00570 case SERVICE_RUNNING: 00571 ODS("The status of the driver is: SERVICE_RUNNING\n"); 00572 break; 00573 case SERVICE_START_PENDING: 00574 ODS("The status of the driver is: SERVICE_START_PENDING\n"); 00575 break; 00576 case SERVICE_STOP_PENDING: 00577 ODS("The status of the driver is: SERVICE_STOP_PENDING\n"); 00578 break; 00579 case SERVICE_STOPPED: 00580 ODS("The status of the driver is: SERVICE_STOPPED\n"); 00581 break; 00582 00583 default: 00584 ODS("The status of the driver is: unknown\n"); 00585 break; 00586 } 00587 #endif 00588 00589 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING) 00590 { 00591 ODS("Calling startservice\n"); 00592 if (StartService(srvHandle, 0, NULL)==0) 00593 { 00594 error = GetLastError(); 00595 if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS) 00596 { 00597 SetLastError(error); 00598 if (scmHandle != NULL) 00599 CloseServiceHandle(scmHandle); 00600 error = GetLastError(); 00601 ODSEx("PacketOpenAdapterNPF: StartService failed, LastError=%d\n",error); 00602 SetLastError(error); 00603 return NULL; 00604 } 00605 } 00606 } 00607 00608 CloseServiceHandle( srvHandle ); 00609 srvHandle = NULL; 00610 00611 } 00612 else 00613 { 00614 error = GetLastError(); 00615 ODSEx("OpenService failed! Error=%d", error); 00616 SetLastError(error); 00617 } 00618 } 00619 else 00620 { 00621 if(KeyRes != ERROR_SUCCESS) 00622 Result = PacketInstallDriver(scmHandle,&svcHandle); 00623 else 00624 Result = TRUE; 00625 00626 if (Result) { 00627 00628 srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START); 00629 if (srvHandle != NULL) 00630 { 00631 00632 QuerySStat = QueryServiceStatus(srvHandle, &SStat); 00633 00634 #if defined(_DBG) || defined(_DEBUG_TO_FILE) 00635 switch (SStat.dwCurrentState) 00636 { 00637 case SERVICE_CONTINUE_PENDING: 00638 ODS("The status of the driver is: SERVICE_CONTINUE_PENDING\n"); 00639 break; 00640 case SERVICE_PAUSE_PENDING: 00641 ODS("The status of the driver is: SERVICE_PAUSE_PENDING\n"); 00642 break; 00643 case SERVICE_PAUSED: 00644 ODS("The status of the driver is: SERVICE_PAUSED\n"); 00645 break; 00646 case SERVICE_RUNNING: 00647 ODS("The status of the driver is: SERVICE_RUNNING\n"); 00648 break; 00649 case SERVICE_START_PENDING: 00650 ODS("The status of the driver is: SERVICE_START_PENDING\n"); 00651 break; 00652 case SERVICE_STOP_PENDING: 00653 ODS("The status of the driver is: SERVICE_STOP_PENDING\n"); 00654 break; 00655 case SERVICE_STOPPED: 00656 ODS("The status of the driver is: SERVICE_STOPPED\n"); 00657 break; 00658 00659 default: 00660 ODS("The status of the driver is: unknown\n"); 00661 break; 00662 } 00663 #endif 00664 00665 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){ 00666 00667 ODS("Calling startservice\n"); 00668 00669 if (StartService(srvHandle, 0, NULL)==0){ 00670 error = GetLastError(); 00671 if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){ 00672 if (scmHandle != NULL) CloseServiceHandle(scmHandle); 00673 ODSEx("PacketOpenAdapterNPF: StartService failed, LastError=%d\n",error); 00674 SetLastError(error); 00675 return NULL; 00676 } 00677 } 00678 } 00679 00680 CloseServiceHandle( srvHandle ); 00681 srvHandle = NULL; 00682 00683 } 00684 else{ 00685 error = GetLastError(); 00686 ODSEx("OpenService failed! LastError=%d", error); 00687 SetLastError(error); 00688 } 00689 } 00690 } 00691 } 00692 00693 if (scmHandle != NULL) CloseServiceHandle(scmHandle); 00694 00695 lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER)); 00696 if (lpAdapter==NULL) 00697 { 00698 ODS("PacketOpenAdapterNPF: GlobalAlloc Failed\n"); 00699 error=GetLastError(); 00700 //set the error to the one on which we failed 00701 SetLastError(error); 00702 ODS("PacketOpenAdapterNPF: Failed to allocate the adapter structure\n"); 00703 return NULL; 00704 } 00705 lpAdapter->NumWrites=1; 00706 00707 wsprintf(SymbolicLink, TEXT("\\\\.\\%s"), &AdapterName[16]); 00708 00709 // Copy only the bytes that fit in the adapter structure. 00710 // Note that lpAdapter->SymbolicLink is present for backward compatibility but will 00711 // never be used by the apps 00712 memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH); 00713 00714 //try if it is possible to open the adapter immediately 00715 lpAdapter->hFile=CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ, 00716 0,NULL,OPEN_EXISTING,0,0); 00717 00718 if (lpAdapter->hFile != INVALID_HANDLE_VALUE) 00719 { 00720 00721 if(PacketSetReadEvt(lpAdapter)==FALSE){ 00722 error=GetLastError(); 00723 ODS("PacketOpenAdapterNPF: Unable to open the read event\n"); 00724 GlobalFreePtr(lpAdapter); 00725 //set the error to the one on which we failed 00726 SetLastError(error); 00727 ODSEx("PacketOpenAdapterNPF: PacketSetReadEvt failed, LastError=%d\n",error); 00728 return NULL; 00729 } 00730 00731 PacketSetMaxLookaheadsize(lpAdapter); 00732 00733 _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%S", AdapterName); 00734 00735 return lpAdapter; 00736 } 00737 00738 00739 error=GetLastError(); 00740 GlobalFreePtr(lpAdapter); 00741 //set the error to the one on which we failed 00742 ODSEx("PacketOpenAdapterNPF: CreateFile failed, LastError= %d\n",error); 00743 SetLastError(error); 00744 return NULL; 00745 } 00746 00755 #ifdef HAVE_DAG_API 00756 LPADAPTER PacketOpenAdapterDAG(PCHAR AdapterName, BOOLEAN IsAFile) 00757 { 00758 CHAR DagEbuf[DAGC_ERRBUF_SIZE]; 00759 LPADAPTER lpAdapter; 00760 LONG status; 00761 HKEY dagkey; 00762 DWORD lptype; 00763 DWORD fpc; 00764 DWORD lpcbdata = sizeof(fpc); 00765 WCHAR keyname[512]; 00766 PWCHAR tsn; 00767 00768 00769 lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 00770 sizeof(ADAPTER)); 00771 if (lpAdapter == NULL) 00772 { 00773 return NULL; 00774 } 00775 00776 if(IsAFile) 00777 { 00778 // We must add an entry to the adapter description list, otherwise many function will not 00779 // be able to work 00780 if(!PacketAddAdapterDag(AdapterName, "DAG file", IsAFile)) 00781 { 00782 GlobalFreePtr(lpAdapter); 00783 return NULL; 00784 } 00785 00786 // Flag that this is a DAG file 00787 lpAdapter->Flags = INFO_FLAG_DAG_FILE; 00788 } 00789 else 00790 { 00791 // Flag that this is a DAG card 00792 lpAdapter->Flags = INFO_FLAG_DAG_CARD; 00793 } 00794 00795 // 00796 // See if the user is asking for fast capture with this device 00797 // 00798 00799 lpAdapter->DagFastProcess = FALSE; 00800 00801 tsn = (strstr(strlwr((char*)AdapterName), "dag") != NULL)? 00802 SChar2WChar(strstr(strlwr((char*)AdapterName), "dag")): 00803 L""; 00804 00805 _snwprintf(keyname, sizeof(keyname), L"%s\\CardParams\\%ws", 00806 L"SYSTEM\\CurrentControlSet\\Services\\DAG", 00807 tsn); 00808 00809 GlobalFreePtr(tsn); 00810 00811 do 00812 { 00813 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0 , KEY_READ, &dagkey); 00814 if(status != ERROR_SUCCESS) 00815 break; 00816 00817 status = RegQueryValueEx(dagkey, 00818 L"FastCap", 00819 NULL, 00820 &lptype, 00821 (char*)&fpc, 00822 &lpcbdata); 00823 00824 if(status == ERROR_SUCCESS) 00825 lpAdapter->DagFastProcess = fpc; 00826 00827 RegCloseKey(dagkey); 00828 } 00829 while(FALSE); 00830 00831 // 00832 // Open the card 00833 // 00834 lpAdapter->pDagCard = p_dagc_open(AdapterName, 00835 0, 00836 DagEbuf); 00837 00838 if(lpAdapter->pDagCard == NULL) 00839 { 00840 GlobalFreePtr(lpAdapter); 00841 return NULL; 00842 } 00843 00844 lpAdapter->DagFcsLen = p_dagc_getfcslen(lpAdapter->pDagCard); 00845 00846 _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterName); 00847 00848 // XXX we could create the read event here 00849 00850 return lpAdapter; 00851 } 00852 #endif // HAVE_DAG_API 00853 00854 //--------------------------------------------------------------------------- 00855 // PUBLIC API 00856 //--------------------------------------------------------------------------- 00857 00870 PCHAR PacketGetVersion() 00871 { 00872 return PacketLibraryVersion; 00873 } 00874 00879 PCHAR PacketGetDriverVersion() 00880 { 00881 return PacketDriverVersion; 00882 } 00883 00892 BOOL PacketStopDriver() 00893 { 00894 SC_HANDLE scmHandle; 00895 SC_HANDLE schService; 00896 BOOL ret; 00897 SERVICE_STATUS serviceStatus; 00898 00899 scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 00900 00901 if(scmHandle != NULL){ 00902 00903 schService = OpenService (scmHandle, 00904 NPFServiceName, 00905 SERVICE_ALL_ACCESS 00906 ); 00907 00908 if (schService != NULL) 00909 { 00910 00911 ret = ControlService (schService, 00912 SERVICE_CONTROL_STOP, 00913 &serviceStatus 00914 ); 00915 if (!ret) 00916 { 00917 } 00918 00919 CloseServiceHandle (schService); 00920 00921 CloseServiceHandle(scmHandle); 00922 00923 return ret; 00924 } 00925 } 00926 00927 return FALSE; 00928 00929 } 00930 00938 LPADAPTER PacketOpenAdapter(PCHAR AdapterName) 00939 { 00940 LPADAPTER lpAdapter; 00941 WCHAR *AdapterNameU; 00942 SC_HANDLE svcHandle = NULL; 00943 PCHAR AdapterNameA = NULL; 00944 #ifndef _WINNT4 00945 PADAPTER_INFO TAdInfo; 00946 #endif // _WINNT4 00947 00948 ODSEx("PacketOpenAdapter: trying to open the adapter=%s\n",AdapterName) 00949 00950 if(AdapterName[1]!=0){ //ASCII 00951 00952 AdapterNameU = SChar2WChar(AdapterName); 00953 AdapterNameA = AdapterName; 00954 AdapterName = (PCHAR)AdapterNameU; 00955 } else { //Unicode 00956 AdapterNameU = NULL; 00957 AdapterNameA = WChar2SChar((PWCHAR)AdapterName); 00958 } 00959 00960 #ifndef _WINNT4 00961 00962 WaitForSingleObject(AdaptersInfoMutex, INFINITE); 00963 // Find the PADAPTER_INFO structure associated with this adapter 00964 TAdInfo = PacketFindAdInfo(AdapterNameA); 00965 if(TAdInfo == NULL) 00966 { 00967 PacketUpdateAdInfo(AdapterNameA); 00968 TAdInfo = PacketFindAdInfo(AdapterNameA); 00969 if(TAdInfo == NULL) 00970 { 00971 00972 //can be an ERF file? 00973 lpAdapter = PacketOpenAdapterDAG(AdapterNameA, TRUE); 00974 00975 if (AdapterNameU != NULL) 00976 GlobalFreePtr(AdapterNameU); 00977 else 00978 GlobalFreePtr(AdapterNameA); 00979 00980 ReleaseMutex(AdaptersInfoMutex); 00981 if (lpAdapter == NULL) 00982 SetLastError(ERROR_BAD_UNIT); //this is the best we can do.... 00983 return lpAdapter; 00984 } 00985 } 00986 00987 if(TAdInfo->Flags != INFO_FLAG_NDIS_ADAPTER) 00988 { 00989 // 00990 // Not a standard NDIS adapter, we must have specific handling 00991 // 00992 00993 00994 if(TAdInfo->Flags & INFO_FLAG_NDISWAN_ADAPTER) 00995 { 00996 // 00997 // This is a wan adapter. Open it using the netmon API 00998 // 00999 01000 lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 01001 sizeof(ADAPTER)); 01002 if (lpAdapter == NULL) 01003 { 01004 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU); 01005 else GlobalFreePtr(AdapterNameA); 01006 ReleaseMutex(AdaptersInfoMutex); 01007 SetLastError(ERROR_BAD_UNIT); 01008 return NULL; 01009 } 01010 01011 // Backup flags for future usage 01012 lpAdapter->Flags = TAdInfo->Flags; 01013 01014 // Open the adapter 01015 lpAdapter->pWanAdapter = WanPacketOpenAdapter(); 01016 if (lpAdapter->pWanAdapter == NULL) 01017 { 01018 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU); 01019 else GlobalFreePtr(AdapterNameA); 01020 01021 GlobalFreePtr(lpAdapter); 01022 ReleaseMutex(AdaptersInfoMutex); 01023 SetLastError(ERROR_BAD_UNIT); 01024 return NULL; 01025 } 01026 01027 _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterNameA); 01028 01029 lpAdapter->ReadEvent = WanPacketGetReadEvent(lpAdapter->pWanAdapter); 01030 01031 if (AdapterNameU != NULL) 01032 GlobalFreePtr(AdapterNameU); 01033 else 01034 GlobalFreePtr(AdapterNameA); 01035 01036 ReleaseMutex(AdaptersInfoMutex); 01037 return lpAdapter; 01038 } 01039 else 01040 if(TAdInfo->Flags & INFO_FLAG_DAG_CARD) 01041 { 01042 // 01043 // This is a Dag card. Open it using the dagc API 01044 // 01045 01046 lpAdapter = PacketOpenAdapterDAG(AdapterNameA, FALSE); 01047 01048 if (AdapterNameU != NULL) 01049 GlobalFreePtr(AdapterNameU); 01050 else 01051 GlobalFreePtr(AdapterNameA); 01052 01053 ReleaseMutex(AdaptersInfoMutex); 01054 if (lpAdapter == NULL) 01055 SetLastError(ERROR_BAD_UNIT); 01056 return lpAdapter; 01057 } 01058 01059 } 01060 01061 ReleaseMutex(AdaptersInfoMutex); 01062 01063 #endif // _WINNT4 01064 01065 lpAdapter = PacketOpenAdapterNPF(AdapterName); 01066 01067 if (AdapterNameU != NULL) 01068 GlobalFreePtr(AdapterNameU); 01069 else 01070 GlobalFreePtr(AdapterNameA); 01071 01072 return lpAdapter; 01073 } 01074 01081 VOID PacketCloseAdapter(LPADAPTER lpAdapter) 01082 { 01083 01084 #ifndef _WINNT4 01085 if (lpAdapter->pWanAdapter != NULL) 01086 { 01087 WanPacketCloseAdapter(lpAdapter->pWanAdapter); 01088 GlobalFreePtr(lpAdapter); 01089 return; 01090 } 01091 #ifdef HAVE_DAG_API 01092 else 01093 if(lpAdapter->pDagCard != NULL) 01094 { 01095 if(lpAdapter->Flags & INFO_FLAG_DAG_FILE & ~INFO_FLAG_DAG_CARD) 01096 { 01097 // This is a file. We must remove the entry in the adapter description list 01098 PacketUpdateAdInfo(lpAdapter->Name); 01099 } 01100 p_dagc_close(lpAdapter->pDagCard); 01101 } 01102 #endif // HAVE_DAG_API 01103 #endif // _WINNT4 01104 01105 CloseHandle(lpAdapter->hFile); 01106 SetEvent(lpAdapter->ReadEvent); 01107 CloseHandle(lpAdapter->ReadEvent); 01108 GlobalFreePtr(lpAdapter); 01109 } 01110 01123 LPPACKET PacketAllocatePacket(void) 01124 { 01125 01126 LPPACKET lpPacket; 01127 lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET)); 01128 if (lpPacket==NULL) 01129 { 01130 ODS("PacketAllocatePacket: GlobalAlloc Failed\n"); 01131 return NULL; 01132 } 01133 return lpPacket; 01134 } 01135 01144 VOID PacketFreePacket(LPPACKET lpPacket) 01145 01146 { 01147 GlobalFreePtr(lpPacket); 01148 } 01149 01166 VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length) 01167 01168 { 01169 lpPacket->Buffer = Buffer; 01170 lpPacket->Length = Length; 01171 lpPacket->ulBytesReceived = 0; 01172 lpPacket->bIoComplete = FALSE; 01173 } 01174 01205 BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync) 01206 { 01207 BOOLEAN res; 01208 01209 #ifndef _WINNT4 01210 01211 if (AdapterObject->pWanAdapter != NULL) 01212 { 01213 lpPacket->ulBytesReceived = WanPacketReceivePacket(AdapterObject->pWanAdapter, lpPacket->Buffer, lpPacket->Length); 01214 return TRUE; 01215 } 01216 #ifdef HAVE_DAG_API 01217 else 01218 if(AdapterObject->pDagCard != NULL) 01219 { 01220 01221 p_dagc_wait(AdapterObject->pDagCard, &AdapterObject->DagReadTimeout); 01222 01223 if(p_dagc_receive(AdapterObject->pDagCard, &AdapterObject->DagBuffer, &lpPacket->ulBytesReceived) == 0) 01224 return TRUE; 01225 else 01226 return FALSE; 01227 } 01228 #endif // HAVE_DAG_API 01229 #endif // _WINNT4 01230 01231 if((int)AdapterObject->ReadTimeOut != -1) 01232 WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut); 01233 01234 res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL); 01235 01236 return res; 01237 } 01238 01268 BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync) 01269 { 01270 DWORD BytesTransfered; 01271 01272 01273 #ifndef _WINNT4 01274 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01275 { 01276 ODS("PacketSendPacket: packet sending not allowed on wan adapters\n"); 01277 return FALSE; 01278 } 01279 #endif // _WINNT4 01280 01281 return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL); 01282 } 01283 01284 01312 INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync) 01313 { 01314 BOOLEAN Res; 01315 DWORD BytesTransfered, TotBytesTransfered=0; 01316 struct timeval BufStartTime; 01317 LARGE_INTEGER StartTicks, CurTicks, TargetTicks, TimeFreq; 01318 01319 01320 ODS("PacketSendPackets"); 01321 01322 #ifndef _WINNT4 01323 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01324 { 01325 ODS("PacketSendPackets: packet sending not allowed on wan adapters\n"); 01326 return FALSE; 01327 } 01328 #endif // _WINNT4 01329 01330 // Obtain starting timestamp of the buffer 01331 BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec; 01332 BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec; 01333 01334 // Retrieve the reference time counters 01335 QueryPerformanceCounter(&StartTicks); 01336 QueryPerformanceFrequency(&TimeFreq); 01337 01338 CurTicks.QuadPart = StartTicks.QuadPart; 01339 01340 do{ 01341 // Send the data to the driver 01342 Res = DeviceIoControl(AdapterObject->hFile, 01343 (Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC, 01344 (PCHAR)PacketBuff + TotBytesTransfered, 01345 Size - TotBytesTransfered, 01346 NULL, 01347 0, 01348 &BytesTransfered, 01349 NULL); 01350 01351 TotBytesTransfered += BytesTransfered; 01352 01353 // calculate the time interval to wait before sending the next packet 01354 TargetTicks.QuadPart = StartTicks.QuadPart + 01355 (LONGLONG) 01356 ((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 + 01357 (((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) * 01358 (TimeFreq.QuadPart) / 1000000; 01359 01360 // Exit from the loop on termination or error 01361 if(TotBytesTransfered >= Size || Res != TRUE) 01362 break; 01363 01364 // Wait until the time interval has elapsed 01365 while( CurTicks.QuadPart <= TargetTicks.QuadPart ) 01366 QueryPerformanceCounter(&CurTicks); 01367 01368 } 01369 while(TRUE); 01370 01371 return TotBytesTransfered; 01372 } 01373 01392 BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes) 01393 { 01394 DWORD BytesReturned; 01395 01396 #ifndef _WINNT4 01397 if (AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) 01398 return WanPacketSetMinToCopy(AdapterObject->pWanAdapter, nbytes); 01399 #ifdef HAVE_DAG_API 01400 else 01401 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01402 // No mintocopy with DAGs 01403 return TRUE; 01404 #endif // HAVE_DAG_API 01405 #endif // _WINNT4 01406 01407 return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL); 01408 } 01409 01446 BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode) 01447 { 01448 DWORD BytesReturned; 01449 01450 #ifndef _WINNT4 01451 if (AdapterObject->pWanAdapter != NULL) 01452 return WanPacketSetMode(AdapterObject->pWanAdapter, mode); 01453 #endif // _WINNT4 01454 01455 return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL); 01456 } 01457 01472 BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len) 01473 { 01474 DWORD BytesReturned; 01475 WCHAR *FileName; 01476 BOOLEAN res; 01477 WCHAR NameWithPath[1024]; 01478 int TStrLen; 01479 WCHAR *NamePos; 01480 01481 #ifndef _WINNT4 01482 if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01483 { 01484 ODS("PacketSetDumpName: not allowed on wan adapters\n"); 01485 return FALSE; 01486 } 01487 #endif // _WINNT4 01488 01489 if(((PUCHAR)name)[1]!=0 && len>1){ //ASCII 01490 FileName=SChar2WChar(name); 01491 len*=2; 01492 } 01493 else { //Unicode 01494 FileName=name; 01495 } 01496 01497 TStrLen=GetFullPathName(FileName,1024,NameWithPath,&NamePos); 01498 01499 len=TStrLen*2+2; //add the terminating null character 01500 01501 // Try to catch malformed strings 01502 if(len>2048){ 01503 if(((PUCHAR)name)[1]!=0 && len>1) free(FileName); 01504 return FALSE; 01505 } 01506 01507 res = DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL); 01508 free(FileName); 01509 return res; 01510 } 01511 01527 BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks) 01528 { 01529 DWORD BytesReturned; 01530 UINT valbuff[2]; 01531 01532 #ifndef _WINNT4 01533 if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01534 { 01535 ODS("PacketSetDumpLimits: not allowed on wan adapters\n"); 01536 return FALSE; 01537 } 01538 #endif // _WINNT4 01539 01540 valbuff[0] = maxfilesize; 01541 valbuff[1] = maxnpacks; 01542 01543 return DeviceIoControl(AdapterObject->hFile, 01544 pBIOCSETDUMPLIMITS, 01545 valbuff, 01546 sizeof valbuff, 01547 NULL, 01548 0, 01549 &BytesReturned, 01550 NULL); 01551 } 01552 01566 BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync) 01567 { 01568 DWORD BytesReturned; 01569 int IsDumpEnded; 01570 BOOLEAN res; 01571 01572 #ifndef _WINNT4 01573 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01574 { 01575 ODS("PacketIsDumpEnded: not allowed on wan adapters\n"); 01576 return FALSE; 01577 } 01578 #endif // _WINNT4 01579 01580 if(sync) 01581 WaitForSingleObject(AdapterObject->ReadEvent, INFINITE); 01582 01583 res = DeviceIoControl(AdapterObject->hFile, 01584 pBIOCISDUMPENDED, 01585 NULL, 01586 0, 01587 &IsDumpEnded, 01588 4, 01589 &BytesReturned, 01590 NULL); 01591 01592 if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished 01593 01594 return (BOOLEAN)IsDumpEnded; 01595 } 01596 01616 HANDLE PacketGetReadEvent(LPADAPTER AdapterObject) 01617 { 01618 return AdapterObject->ReadEvent; 01619 } 01620 01629 BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites) 01630 { 01631 DWORD BytesReturned; 01632 01633 #ifndef _WINNT4 01634 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01635 { 01636 ODS("PacketSetNumWrites: not allowed on wan adapters\n"); 01637 return FALSE; 01638 } 01639 #endif // _WINNT4 01640 01641 return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL); 01642 } 01643 01656 BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout) 01657 { 01658 DWORD BytesReturned; 01659 int DriverTimeOut=-1; 01660 01661 #ifndef _WINNT4 01662 if (AdapterObject->pWanAdapter != NULL) 01663 return WanPacketSetReadTimeout(AdapterObject->pWanAdapter,timeout); 01664 #endif // _WINNT4 01665 01666 AdapterObject->ReadTimeOut=timeout; 01667 01668 #ifdef HAVE_DAG_API 01669 // Under DAG, we simply store the timeout value and then 01670 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01671 { 01672 if(timeout == 1) 01673 { 01674 // tell DAG card to return immediately 01675 AdapterObject->DagReadTimeout.tv_sec = 0; 01676 AdapterObject->DagReadTimeout.tv_usec = 0; 01677 } 01678 else 01679 if(timeout == 1) 01680 { 01681 // tell the DAG card to wait forvever 01682 AdapterObject->DagReadTimeout.tv_sec = -1; 01683 AdapterObject->DagReadTimeout.tv_usec = -1; 01684 } 01685 else 01686 { 01687 // Set the timeout for the DAG card 01688 AdapterObject->DagReadTimeout.tv_sec = timeout / 1000; 01689 AdapterObject->DagReadTimeout.tv_usec = (timeout * 1000) % 1000000; 01690 } 01691 01692 return TRUE; 01693 } 01694 #endif // HAVE_DAG_API 01695 01696 return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL); 01697 } 01698 01715 BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim) 01716 { 01717 DWORD BytesReturned; 01718 01719 #ifndef _WINNT4 01720 if (AdapterObject->pWanAdapter != NULL) 01721 return WanPacketSetBufferSize(AdapterObject->pWanAdapter, dim); 01722 #ifdef HAVE_DAG_API 01723 else 01724 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01725 // We can't change DAG buffers 01726 return TRUE; 01727 #endif // HAVE_DAG_API 01728 01729 #endif // _WINNT4 01730 return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL); 01731 } 01732 01753 BOOLEAN PacketSetBpf(LPADAPTER AdapterObject, struct bpf_program *fp) 01754 { 01755 DWORD BytesReturned; 01756 01757 #ifndef _WINNT4 01758 if (AdapterObject->pWanAdapter != NULL) 01759 return WanPacketSetBpfFilter(AdapterObject->pWanAdapter, (PUCHAR)fp->bf_insns, fp->bf_len * sizeof(struct bpf_insn)); 01760 #ifdef HAVE_DAG_API 01761 else 01762 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01763 // Delegate the filtering to higher layers since it's too expensive here 01764 return TRUE; 01765 #endif // HAVE_DAG_API 01766 #endif // _WINNT4 01767 01768 return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL); 01769 } 01770 01785 INT PacketSetSnapLen(LPADAPTER AdapterObject, int snaplen) 01786 { 01787 01788 #ifdef HAVE_DAG_API 01789 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01790 return p_dagc_setsnaplen(AdapterObject->pDagCard, snaplen); 01791 else 01792 #endif // HAVE_DAG_API 01793 return 0; 01794 } 01795 01809 BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s) 01810 { 01811 BOOLEAN Res; 01812 DWORD BytesReturned; 01813 struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications 01814 01815 #ifndef _WINNT4 01816 #ifdef HAVE_DAG_API 01817 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01818 { 01819 dagc_stats_t DagStats; 01820 01821 // Note: DAG cards are currently very limited from the statistics reporting point of view, 01822 // so most of the values returned by dagc_stats() are zero at the moment 01823 if(p_dagc_stats(AdapterObject->pDagCard, &DagStats) == 0) 01824 { 01825 // XXX: Only copy the dropped packets for now, since the received counter is not supported by 01826 // DAGS at the moment 01827 01828 s->bs_recv = (ULONG)DagStats.received; 01829 s->bs_drop = (ULONG)DagStats.dropped; 01830 return TRUE; 01831 } 01832 else 01833 return FALSE; 01834 } 01835 else 01836 #endif // HAVE_DAG_API 01837 if ( AdapterObject->pWanAdapter != NULL) 01838 Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat); 01839 else 01840 #endif // _WINNT4 01841 01842 Res = DeviceIoControl(AdapterObject->hFile, 01843 pBIOCGSTATS, 01844 NULL, 01845 0, 01846 &tmpstat, 01847 sizeof(struct bpf_stat), 01848 &BytesReturned, 01849 NULL); 01850 01851 01852 // Copy only the first two values retrieved from the driver 01853 s->bs_recv = tmpstat.bs_recv; 01854 s->bs_drop = tmpstat.bs_drop; 01855 01856 return Res; 01857 } 01858 01871 BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s) 01872 { 01873 BOOLEAN Res; 01874 DWORD BytesReturned; 01875 struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications 01876 01877 #ifndef _WINNT4 01878 #ifdef HAVE_DAG_API 01879 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01880 { 01881 dagc_stats_t DagStats; 01882 01883 // Note: DAG cards are currently very limited from the statistics reporting point of view, 01884 // so most of the values returned by dagc_stats() are zero at the moment 01885 p_dagc_stats(AdapterObject->pDagCard, &DagStats); 01886 s->bs_recv = (ULONG)DagStats.received; 01887 s->bs_drop = (ULONG)DagStats.dropped; 01888 s->ps_ifdrop = 0; 01889 s->bs_capt = (ULONG)DagStats.captured; 01890 } 01891 #endif // HAVE_DAG_API 01892 if(AdapterObject->pWanAdapter != NULL) 01893 Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat); 01894 else 01895 #endif // _WINNT4 01896 01897 Res = DeviceIoControl(AdapterObject->hFile, 01898 pBIOCGSTATS, 01899 NULL, 01900 0, 01901 &tmpstat, 01902 sizeof(struct bpf_stat), 01903 &BytesReturned, 01904 NULL); 01905 01906 s->bs_recv = tmpstat.bs_recv; 01907 s->bs_drop = tmpstat.bs_drop; 01908 s->ps_ifdrop = tmpstat.ps_ifdrop; 01909 s->bs_capt = tmpstat.bs_capt; 01910 01911 return Res; 01912 } 01913 01926 BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData) 01927 { 01928 DWORD BytesReturned; 01929 BOOLEAN Result; 01930 01931 #ifndef _WINNT4 01932 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01933 return FALSE; 01934 #endif // _WINNT4 01935 01936 Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? (DWORD)pBIOCSETOID : (DWORD)pBIOCQUERYOID, 01937 OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData, 01938 sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL); 01939 01940 // output some debug info 01941 ODSEx("PacketRequest, OID=%d ", OidData->Oid); 01942 ODSEx("Length=%d ", OidData->Length); 01943 ODSEx("Set=%d ", Set); 01944 ODSEx("Res=%d\n", Result); 01945 01946 return Result; 01947 } 01948 01965 BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter) 01966 { 01967 BOOLEAN Status; 01968 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); 01969 PPACKET_OID_DATA OidData; 01970 01971 #ifndef _WINNT4 01972 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01973 return TRUE; 01974 #endif // _WINNT4 01975 01976 OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); 01977 if (OidData == NULL) { 01978 ODS("PacketSetHwFilter: GlobalAlloc Failed\n"); 01979 return FALSE; 01980 } 01981 OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER; 01982 OidData->Length=sizeof(ULONG); 01983 *((PULONG)OidData->Data)=Filter; 01984 Status=PacketRequest(AdapterObject,TRUE,OidData); 01985 GlobalFreePtr(OidData); 01986 return Status; 01987 } 01988 02010 BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize) 02011 { 02012 PADAPTER_INFO TAdInfo; 02013 ULONG SizeNeeded = 1; 02014 ULONG SizeNames = 1; 02015 ULONG SizeDesc; 02016 ULONG OffDescriptions; 02017 02018 ODSEx("PacketGetAdapterNames: BufferSize=%d\n", *BufferSize); 02019 02020 // 02021 // Create the adapter information list 02022 // 02023 PacketPopulateAdaptersInfoList(); 02024 02025 WaitForSingleObject(AdaptersInfoMutex, INFINITE); 02026 if(!AdaptersInfoList) 02027 { 02028 ReleaseMutex(AdaptersInfoMutex); 02029 *BufferSize = 0; 02030 return FALSE; // No adapters to return 02031 } 02032 02033 // 02034 // First scan of the list to calculate the offsets and check the sizes 02035 // 02036 for(TAdInfo = AdaptersInfoList; TAdInfo != NULL; TAdInfo = TAdInfo->Next) 02037 { 02038 // Update the size variables 02039 SizeNeeded += strlen(TAdInfo->Name) + strlen(TAdInfo->Description) + 2; 02040 SizeNames += strlen(TAdInfo->Name) + 1; 02041 } 02042 02043 // Chack that we don't overflow the buffer. 02044 // Note: 2 is the number of additional separators needed inside the list 02045 if(SizeNeeded + 2 >= *BufferSize || pStr == NULL) 02046 { 02047 ReleaseMutex(AdaptersInfoMutex); 02048 02049 ODS("PacketGetAdapterNames: input buffer too small\n"); 02050 *BufferSize = SizeNeeded + 4; // Report the required size 02051 return FALSE; 02052 } 02053 02054 02055 OffDescriptions = SizeNames; 02056 02057 // 02058 // Second scan of the list to copy the information 02059 // 02060 for(TAdInfo = AdaptersInfoList, SizeNames = 0, SizeDesc = 0; TAdInfo != NULL; TAdInfo = TAdInfo->Next) 02061 { 02062 // Copy the data 02063 strcpy(((PCHAR)pStr) + SizeNames, TAdInfo->Name); 02064 strcpy(((PCHAR)pStr) + OffDescriptions + SizeDesc, TAdInfo->Description); 02065 02066 // Update the size variables 02067 SizeNames += strlen(TAdInfo->Name) + 1; 02068 SizeDesc += strlen(TAdInfo->Description) + 1; 02069 } 02070 02071 // Separate the two lists 02072 ((PCHAR)pStr)[SizeNames] = 0; 02073 02074 // End the list with a further \0 02075 ((PCHAR)pStr)[SizeNeeded] = 0; 02076 02077 02078 ReleaseMutex(AdaptersInfoMutex); 02079 return TRUE; 02080 } 02081 02095 BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries) 02096 { 02097 PADAPTER_INFO TAdInfo; 02098 PCHAR Tname; 02099 BOOLEAN Res, FreeBuff; 02100 02101 ODS("PacketGetNetInfo\n"); 02102 02103 // Provide conversion for backward compatibility 02104 if(AdapterName[1] != 0) 02105 { //ASCII 02106 Tname = AdapterName; 02107 FreeBuff = FALSE; 02108 } 02109 else 02110 { 02111 Tname = WChar2SChar((PWCHAR)AdapterName); 02112 FreeBuff = TRUE; 02113 } 02114 02115 // 02116 // Update the information about this adapter 02117 // 02118 if(!PacketUpdateAdInfo(Tname)) 02119 { 02120 ODS("PacketGetNetInfo: Adapter not found\n"); 02121 if(FreeBuff)GlobalFreePtr(Tname); 02122 return FALSE; 02123 } 02124 02125 WaitForSingleObject(AdaptersInfoMutex, INFINITE); 02126 // Find the PADAPTER_INFO structure associated with this adapter 02127 TAdInfo = PacketFindAdInfo(Tname); 02128 02129 if(TAdInfo != NULL) 02130 { 02131 *NEntries = (TAdInfo->NNetworkAddresses < *NEntries)? TAdInfo->NNetworkAddresses: *NEntries; 02132 //TODO what if nentries = 0? 02133 if (*NEntries > 0) 02134 memcpy(buffer, TAdInfo->NetworkAddresses, *NEntries * sizeof(npf_if_addr)); 02135 Res = TRUE; 02136 } 02137 else 02138 { 02139 ODS("PacketGetNetInfo: Adapter not found\n"); 02140 Res = FALSE; 02141 } 02142 02143 ReleaseMutex(AdaptersInfoMutex); 02144 02145 if(FreeBuff)GlobalFreePtr(Tname); 02146 02147 return Res; 02148 } 02149 02166 BOOLEAN PacketGetNetType(LPADAPTER AdapterObject, NetType *type) 02167 { 02168 PADAPTER_INFO TAdInfo; 02169 BOOLEAN ret; 02170 ODS("PacketGetNetType\n"); 02171 02172 WaitForSingleObject(AdaptersInfoMutex, INFINITE); 02173 // Find the PADAPTER_INFO structure associated with this adapter 02174 TAdInfo = PacketFindAdInfo(AdapterObject->Name); 02175 02176 if(TAdInfo != NULL) 02177 { 02178 // Copy the data 02179 memcpy(type, &(TAdInfo->LinkLayer), sizeof(struct NetType)); 02180 ret = TRUE; 02181 } 02182 else 02183 { 02184 ODS("PacketGetNetType: Adapter not found\n"); 02185 ret = FALSE; 02186 } 02187 02188 ReleaseMutex(AdaptersInfoMutex); 02189 02190 return ret; 02191 } 02192 02193 /* @} */
documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.