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