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, TRUE, NULL); 00116 ReleaseMutex(AdaptersInfoMutex); 00117 00118 // 00119 // Retrieve packet.dll version information from the file 00120 // 00121 PacketGetFileVersion(TEXT("packet.dll"), PacketLibraryVersion, sizeof(PacketLibraryVersion)); 00122 00123 // 00124 // Retrieve NPF.sys version information from the file 00125 // 00126 PacketGetFileVersion(TEXT("drivers\\npf.sys"), PacketDriverVersion, sizeof(PacketDriverVersion)); 00127 00128 // 00129 // Locate GetAdaptersAddresses dinamically since it is not present in Win2k 00130 // 00131 IPHMod = GetModuleHandle(TEXT("Iphlpapi")); 00132 00133 #ifndef _WINNT4 00134 GetAdaptersAddressesPointer = (GAAHandler) GetProcAddress(IPHMod ,"GetAdaptersAddresses"); 00135 #endif // _WINNT4 00136 00137 #ifdef HAVE_DAG_API 00138 /* We load dinamically the dag library in order link it only when it's present on the system */ 00139 if((DagcLib = LoadLibrary(TEXT("dagc.dll"))) == NULL) 00140 { 00141 // Report the error but go on 00142 ODS("dag capture library not found on this system\n"); 00143 break; 00144 } 00145 00146 p_dagc_open = (dagc_open_handler) GetProcAddress(DagcLib, "dagc_open"); 00147 p_dagc_close = (dagc_close_handler) GetProcAddress(DagcLib, "dagc_close"); 00148 p_dagc_setsnaplen = (dagc_setsnaplen_handler) GetProcAddress(DagcLib, "dagc_setsnaplen"); 00149 p_dagc_getlinktype = (dagc_getlinktype_handler) GetProcAddress(DagcLib, "dagc_getlinktype"); 00150 p_dagc_getlinkspeed = (dagc_getlinkspeed_handler) GetProcAddress(DagcLib, "dagc_getlinkspeed"); 00151 p_dagc_getfcslen = (dagc_getfcslen_handler) GetProcAddress(DagcLib, "dagc_getfcslen"); 00152 p_dagc_receive = (dagc_receive_handler) GetProcAddress(DagcLib, "dagc_receive"); 00153 p_dagc_wait = (dagc_wait_handler) GetProcAddress(DagcLib, "dagc_wait"); 00154 p_dagc_stats = (dagc_stats_handler) GetProcAddress(DagcLib, "dagc_stats"); 00155 p_dagc_finddevs = (dagc_finddevs_handler) GetProcAddress(DagcLib, "dagc_finddevs"); 00156 p_dagc_freedevs = (dagc_freedevs_handler) GetProcAddress(DagcLib, "dagc_freedevs"); 00157 00158 #endif /* HAVE_DAG_API */ 00159 00160 break; 00161 00162 case DLL_PROCESS_DETACH: 00163 00164 CloseHandle(AdaptersInfoMutex); 00165 00166 break; 00167 00168 default: 00169 break; 00170 } 00171 00172 return Status; 00173 } 00174 00183 ULONG inet_addrU(const WCHAR *cp) 00184 { 00185 ULONG val, part; 00186 WCHAR c; 00187 int i; 00188 00189 val = 0; 00190 for (i = 0; i < 4; i++) { 00191 part = 0; 00192 while ((c = *cp++) != '\0' && c != '.') { 00193 if (c < '0' || c > '9') 00194 return -1; 00195 part = part*10 + (c - '0'); 00196 } 00197 if (part > 255) 00198 return -1; 00199 val = val | (part << i*8); 00200 if (i == 3) { 00201 if (c != '\0') 00202 return -1; // extra gunk at end of string 00203 } else { 00204 if (c == '\0') 00205 return -1; // string ends early 00206 } 00207 } 00208 return val; 00209 } 00210 00217 PWCHAR SChar2WChar(PCHAR string) 00218 { 00219 PWCHAR TmpStr; 00220 TmpStr = (WCHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (strlen(string)+2)*sizeof(WCHAR)); 00221 00222 MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (strlen(string)+2)); 00223 00224 return TmpStr; 00225 } 00226 00233 PCHAR WChar2SChar(PWCHAR string) 00234 { 00235 PCHAR TmpStr; 00236 TmpStr = (CHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (wcslen(string)+2)); 00237 00238 // Conver to ASCII 00239 WideCharToMultiByte( 00240 CP_ACP, 00241 0, 00242 string, 00243 -1, 00244 TmpStr, 00245 (wcslen(string)+2), // size of buffer 00246 NULL, 00247 NULL); 00248 00249 return TmpStr; 00250 } 00251 00261 BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject) 00262 { 00263 BOOLEAN Status; 00264 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); 00265 PPACKET_OID_DATA OidData; 00266 00267 OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); 00268 if (OidData == NULL) { 00269 ODS("PacketSetMaxLookaheadsize failed\n"); 00270 return FALSE; 00271 } 00272 00273 //set the size of the lookahead buffer to the maximum available by the the NIC driver 00274 OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD; 00275 OidData->Length=sizeof(ULONG); 00276 Status=PacketRequest(AdapterObject,FALSE,OidData); 00277 OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD; 00278 Status=PacketRequest(AdapterObject,TRUE,OidData); 00279 GlobalFreePtr(OidData); 00280 return Status; 00281 } 00282 00293 BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject) 00294 { 00295 DWORD BytesReturned; 00296 TCHAR EventName[39]; 00297 00298 // this tells the terminal service to retrieve the event from the global namespace 00299 wcsncpy(EventName,L"Global\\",sizeof(L"Global\\")); 00300 00301 // retrieve the name of the shared event from the driver 00302 if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName+7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) return FALSE; 00303 00304 EventName[20]=0; // terminate the string 00305 00306 // open the shared event 00307 AdapterObject->ReadEvent=CreateEvent(NULL, 00308 TRUE, 00309 FALSE, 00310 EventName); 00311 00312 // in NT4 "Global\" is not automatically ignored: try to use simply the event name 00313 if(GetLastError()!=ERROR_ALREADY_EXISTS){ 00314 if(AdapterObject->ReadEvent != NULL) 00315 CloseHandle(AdapterObject->ReadEvent); 00316 00317 // open the shared event 00318 AdapterObject->ReadEvent=CreateEvent(NULL, 00319 TRUE, 00320 FALSE, 00321 EventName+7); 00322 } 00323 00324 if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){ 00325 ODS("PacketSetReadEvt: error retrieving the event from the kernel\n"); 00326 return FALSE; 00327 } 00328 00329 AdapterObject->ReadTimeOut=0; 00330 00331 return TRUE; 00332 } 00333 00343 BOOL PacketInstallDriver(SC_HANDLE ascmHandle,SC_HANDLE *srvHandle) 00344 { 00345 BOOL result = FALSE; 00346 ULONG err; 00347 00348 ODS("installdriver\n"); 00349 00350 *srvHandle = CreateService(ascmHandle, 00351 NPFServiceName, 00352 NPFServiceDesc, 00353 SERVICE_ALL_ACCESS, 00354 SERVICE_KERNEL_DRIVER, 00355 SERVICE_DEMAND_START, 00356 SERVICE_ERROR_NORMAL, 00357 NPFDriverPath, 00358 NULL, NULL, NULL, NULL, NULL); 00359 if (*srvHandle == NULL) 00360 { 00361 if (GetLastError() == ERROR_SERVICE_EXISTS) 00362 { 00363 //npf.sys already existed 00364 result = TRUE; 00365 } 00366 } 00367 else 00368 { 00369 //Created service for npf.sys 00370 result = TRUE; 00371 } 00372 if (result == TRUE) 00373 if (*srvHandle != NULL) 00374 CloseServiceHandle(*srvHandle); 00375 00376 if(result == FALSE){ 00377 err = GetLastError(); 00378 if(err != 2) 00379 ODSEx("PacketInstallDriver failed, Error=%d\n",err); 00380 } 00381 return result; 00382 00383 } 00384 00394 #ifdef _DEBUG_TO_FILE 00395 00396 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName) 00397 { 00398 CHAR Command[256]; 00399 00400 strcpy(Command, "regedit /e "); 00401 strcat(Command, FileName); 00402 strcat(Command, " "); 00403 strcat(Command, KeyName); 00404 00406 system(Command); 00407 00408 return TRUE; 00409 } 00410 #endif 00411 00421 BOOL PacketGetFileVersion(LPTSTR FileName, PCHAR VersionBuff, UINT VersionBuffLen) 00422 { 00423 DWORD dwVerInfoSize; // Size of version information block 00424 DWORD dwVerHnd=0; // An 'ignored' parameter, always '0' 00425 LPSTR lpstrVffInfo; 00426 UINT cbTranslate, dwBytes; 00427 TCHAR SubBlock[64]; 00428 PVOID lpBuffer; 00429 PCHAR TmpStr; 00430 00431 // Structure used to store enumerated languages and code pages. 00432 struct LANGANDCODEPAGE { 00433 WORD wLanguage; 00434 WORD wCodePage; 00435 } *lpTranslate; 00436 00437 ODS("PacketGetFileVersion\n"); 00438 00439 // Now lets dive in and pull out the version information: 00440 dwVerInfoSize = GetFileVersionInfoSize(FileName, &dwVerHnd); 00441 if (dwVerInfoSize) 00442 { 00443 lpstrVffInfo = GlobalAllocPtr(GMEM_MOVEABLE, dwVerInfoSize); 00444 if (lpstrVffInfo == NULL) 00445 { 00446 ODS("PacketGetFileVersion: failed to allocate memory\n"); 00447 return FALSE; 00448 } 00449 00450 if(!GetFileVersionInfo(FileName, dwVerHnd, dwVerInfoSize, lpstrVffInfo)) 00451 { 00452 ODS("PacketGetFileVersion: failed to call GetFileVersionInfo\n"); 00453 GlobalFreePtr(lpstrVffInfo); 00454 return FALSE; 00455 } 00456 00457 // Read the list of languages and code pages. 00458 if(!VerQueryValue(lpstrVffInfo, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate)) 00459 { 00460 ODS("PacketGetFileVersion: failed to call VerQueryValue\n"); 00461 GlobalFreePtr(lpstrVffInfo); 00462 return FALSE; 00463 } 00464 00465 // Create the file version string for the first (i.e. the only one) language. 00466 wsprintf( SubBlock, 00467 TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"), 00468 (*lpTranslate).wLanguage, 00469 (*lpTranslate).wCodePage); 00470 00471 // Retrieve the file version string for the language. 00472 if(!VerQueryValue(lpstrVffInfo, SubBlock, &lpBuffer, &dwBytes)) 00473 { 00474 ODS("PacketGetFileVersion: failed to call VerQueryValue\n"); 00475 GlobalFreePtr(lpstrVffInfo); 00476 return FALSE; 00477 } 00478 00479 // Convert to ASCII 00480 TmpStr = WChar2SChar(lpBuffer); 00481 00482 if(strlen(TmpStr) >= VersionBuffLen) 00483 { 00484 ODS("PacketGetFileVersion: Input buffer too small\n"); 00485 GlobalFreePtr(lpstrVffInfo); 00486 GlobalFreePtr(TmpStr); 00487 return FALSE; 00488 } 00489 00490 strcpy(VersionBuff, TmpStr); 00491 00492 GlobalFreePtr(TmpStr); 00493 00494 } 00495 else 00496 { 00497 ODSEx("PacketGetFileVersion: failed to call GetFileVersionInfoSize, error = %d\n", GetLastError()); 00498 return FALSE; 00499 00500 } 00501 00502 return TRUE; 00503 } 00504 00513 LPADAPTER PacketOpenAdapterNPF(PCHAR AdapterName) 00514 { 00515 LPADAPTER lpAdapter; 00516 BOOLEAN Result; 00517 DWORD error; 00518 SC_HANDLE svcHandle = NULL; 00519 LONG KeyRes; 00520 HKEY PathKey; 00521 SERVICE_STATUS SStat; 00522 BOOLEAN QuerySStat; 00523 WCHAR SymbolicLink[128]; 00524 00525 ODS("PacketOpenAdapterNPF\n"); 00526 00527 scmHandle = OpenSCManager(NULL, NULL, GENERIC_READ); 00528 00529 if(scmHandle == NULL){ 00530 error = GetLastError(); 00531 ODSEx("OpenSCManager failed! Error=%d\n", error); 00532 } 00533 else{ 00534 // check if the NPF registry key is already present 00535 // this means that the driver is already installed and that we don't need to call PacketInstallDriver 00536 KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE, 00537 NPFRegistryLocation, 00538 0, 00539 KEY_READ, 00540 &PathKey); 00541 00542 if(KeyRes != ERROR_SUCCESS) 00543 { 00544 Result = PacketInstallDriver(scmHandle,&svcHandle); 00545 } 00546 else 00547 { 00548 Result = TRUE; 00549 RegCloseKey(PathKey); 00550 } 00551 00552 if (Result) 00553 { 00554 00555 srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS ); 00556 if (srvHandle != NULL) 00557 { 00558 QuerySStat = QueryServiceStatus(srvHandle, &SStat); 00559 ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState); 00560 00561 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING) 00562 { 00563 ODS("Calling startservice\n"); 00564 if (StartService(srvHandle, 0, NULL)==0) 00565 { 00566 error = GetLastError(); 00567 if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS) 00568 { 00569 SetLastError(error); 00570 if (scmHandle != NULL) 00571 CloseServiceHandle(scmHandle); 00572 error = GetLastError(); 00573 ODSEx("PacketOpenAdapterNPF: StartService failed, Error=%d\n",error); 00574 return NULL; 00575 } 00576 } 00577 } 00578 00579 CloseServiceHandle( srvHandle ); 00580 srvHandle = NULL; 00581 00582 } 00583 else 00584 { 00585 error = GetLastError(); 00586 ODSEx("OpenService failed! Error=%d", error); 00587 } 00588 } 00589 else 00590 { 00591 if(KeyRes != ERROR_SUCCESS) 00592 Result = PacketInstallDriver(scmHandle,&svcHandle); 00593 else 00594 Result = TRUE; 00595 00596 if (Result) { 00597 00598 srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START); 00599 if (srvHandle != NULL){ 00600 00601 QuerySStat = QueryServiceStatus(srvHandle, &SStat); 00602 ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState); 00603 00604 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){ 00605 00606 ODS("Calling startservice\n"); 00607 00608 if (StartService(srvHandle, 0, NULL)==0){ 00609 error = GetLastError(); 00610 if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){ 00611 SetLastError(error); 00612 if (scmHandle != NULL) CloseServiceHandle(scmHandle); 00613 ODSEx("PacketOpenAdapterNPF: StartService failed, Error=%d\n",error); 00614 return NULL; 00615 } 00616 } 00617 } 00618 00619 CloseServiceHandle( srvHandle ); 00620 srvHandle = NULL; 00621 00622 } 00623 else{ 00624 error = GetLastError(); 00625 ODSEx("OpenService failed! Error=%d", error); 00626 } 00627 } 00628 } 00629 } 00630 00631 if (scmHandle != NULL) CloseServiceHandle(scmHandle); 00632 00633 lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER)); 00634 if (lpAdapter==NULL) 00635 { 00636 ODS("PacketOpenAdapterNPF: GlobalAlloc Failed\n"); 00637 error=GetLastError(); 00638 //set the error to the one on which we failed 00639 SetLastError(error); 00640 ODS("PacketOpenAdapterNPF: Failed to allocate the adapter structure\n"); 00641 return NULL; 00642 } 00643 lpAdapter->NumWrites=1; 00644 00645 wsprintf(SymbolicLink, TEXT("\\\\.\\%s"), &AdapterName[16]); 00646 00647 // Copy only the bytes that fit in the adapter structure. 00648 // Note that lpAdapter->SymbolicLink is present for backward compatibility but will 00649 // never be used by the apps 00650 memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH); 00651 00652 //try if it is possible to open the adapter immediately 00653 lpAdapter->hFile=CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ, 00654 0,NULL,OPEN_EXISTING,0,0); 00655 00656 if (lpAdapter->hFile != INVALID_HANDLE_VALUE) 00657 { 00658 00659 if(PacketSetReadEvt(lpAdapter)==FALSE){ 00660 error=GetLastError(); 00661 ODS("PacketOpenAdapterNPF: Unable to open the read event\n"); 00662 GlobalFreePtr(lpAdapter); 00663 //set the error to the one on which we failed 00664 SetLastError(error); 00665 ODSEx("PacketOpenAdapterNPF: PacketSetReadEvt failed, Error=%d\n",error); 00666 return NULL; 00667 } 00668 00669 PacketSetMaxLookaheadsize(lpAdapter); 00670 00671 _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%S", AdapterName); 00672 00673 return lpAdapter; 00674 } 00675 00676 00677 error=GetLastError(); 00678 GlobalFreePtr(lpAdapter); 00679 //set the error to the one on which we failed 00680 SetLastError(error); 00681 ODSEx("PacketOpenAdapterNPF: CreateFile failed, Error=2,%d\n",error); 00682 return NULL; 00683 } 00684 00693 #ifdef HAVE_DAG_API 00694 LPADAPTER PacketOpenAdapterDAG(PCHAR AdapterName, BOOLEAN IsAFile) 00695 { 00696 CHAR DagEbuf[DAGC_ERRBUF_SIZE]; 00697 LPADAPTER lpAdapter; 00698 LONG status; 00699 HKEY dagkey; 00700 DWORD lptype; 00701 DWORD fpc; 00702 DWORD lpcbdata = sizeof(fpc); 00703 WCHAR keyname[512]; 00704 PWCHAR tsn; 00705 00706 00707 lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 00708 sizeof(ADAPTER)); 00709 if (lpAdapter == NULL) 00710 { 00711 return NULL; 00712 } 00713 00714 if(IsAFile) 00715 { 00716 // We must add an entry to the adapter description list, otherwise many function will not 00717 // be able to work 00718 if(!PacketAddAdapterDag(AdapterName, "DAG file", IsAFile)) 00719 { 00720 GlobalFreePtr(lpAdapter); 00721 return NULL; 00722 } 00723 00724 // Flag that this is a DAG file 00725 lpAdapter->Flags = INFO_FLAG_DAG_FILE; 00726 } 00727 else 00728 { 00729 // Flag that this is a DAG card 00730 lpAdapter->Flags = INFO_FLAG_DAG_CARD; 00731 } 00732 00733 // 00734 // See if the user is asking for fast capture with this device 00735 // 00736 00737 lpAdapter->DagFastProcess = FALSE; 00738 00739 tsn = SChar2WChar(strstr(strlwr((char*)AdapterName), "dag")); 00740 00741 _snwprintf(keyname, sizeof(keyname), L"%s\\CardParams\\%ws", 00742 L"SYSTEM\\CurrentControlSet\\Services\\DAG", 00743 tsn); 00744 00745 GlobalFreePtr(tsn); 00746 00747 do 00748 { 00749 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0 , KEY_READ, &dagkey); 00750 if(status != ERROR_SUCCESS) 00751 break; 00752 00753 status = RegQueryValueEx(dagkey, 00754 L"FastCap", 00755 NULL, 00756 &lptype, 00757 (char*)&fpc, 00758 &lpcbdata); 00759 00760 if(status == ERROR_SUCCESS) 00761 lpAdapter->DagFastProcess = fpc; 00762 00763 RegCloseKey(dagkey); 00764 } 00765 while(FALSE); 00766 00767 // 00768 // Open the card 00769 // 00770 lpAdapter->pDagCard = p_dagc_open(AdapterName, 00771 0, 00772 DagEbuf); 00773 00774 if(lpAdapter->pDagCard == NULL) 00775 { 00776 GlobalFreePtr(lpAdapter); 00777 return NULL; 00778 } 00779 00780 lpAdapter->DagFcsLen = p_dagc_getfcslen(lpAdapter->pDagCard); 00781 00782 _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterName); 00783 00784 // XXX we could create the read event here 00785 00786 return lpAdapter; 00787 } 00788 #endif // HAVE_DAG_API 00789 00790 //--------------------------------------------------------------------------- 00791 // PUBLIC API 00792 //--------------------------------------------------------------------------- 00793 00806 PCHAR PacketGetVersion() 00807 { 00808 return PacketLibraryVersion; 00809 } 00810 00815 PCHAR PacketGetDriverVersion() 00816 { 00817 return PacketDriverVersion; 00818 } 00819 00828 BOOL PacketStopDriver() 00829 { 00830 SC_HANDLE scmHandle; 00831 SC_HANDLE schService; 00832 BOOL ret; 00833 SERVICE_STATUS serviceStatus; 00834 00835 scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 00836 00837 if(scmHandle != NULL){ 00838 00839 schService = OpenService (scmHandle, 00840 NPFServiceName, 00841 SERVICE_ALL_ACCESS 00842 ); 00843 00844 if (schService != NULL) 00845 { 00846 00847 ret = ControlService (schService, 00848 SERVICE_CONTROL_STOP, 00849 &serviceStatus 00850 ); 00851 if (!ret) 00852 { 00853 } 00854 00855 CloseServiceHandle (schService); 00856 00857 CloseServiceHandle(scmHandle); 00858 00859 return ret; 00860 } 00861 } 00862 00863 return FALSE; 00864 00865 } 00866 00874 LPADAPTER PacketOpenAdapter(PCHAR AdapterName) 00875 { 00876 LPADAPTER lpAdapter; 00877 WCHAR *AdapterNameU; 00878 SC_HANDLE svcHandle = NULL; 00879 PCHAR AdapterNameA = NULL; 00880 #ifndef _WINNT4 00881 PADAPTER_INFO TAdInfo; 00882 #endif // _WINNT4 00883 00884 ODSEx("PacketOpenAdapter: trying to open the adapter=%S\n",AdapterName) 00885 00886 if(AdapterName[1]!=0){ //ASCII 00887 AdapterNameU = SChar2WChar(AdapterName); 00888 AdapterNameA = AdapterName; 00889 AdapterName = (PCHAR)AdapterNameU; 00890 } else { //Unicode 00891 AdapterNameU = NULL; 00892 AdapterNameA = WChar2SChar((PWCHAR)AdapterName); 00893 } 00894 00895 #ifndef _WINNT4 00896 00897 // Find the PADAPTER_INFO structure associated with this adapter 00898 TAdInfo = PacketFindAdInfo(AdapterNameA); 00899 if(TAdInfo == NULL) 00900 { 00901 PacketUpdateAdInfo(AdapterNameA); 00902 TAdInfo = PacketFindAdInfo(AdapterNameA); 00903 if(TAdInfo == NULL) 00904 { 00905 //can be an ERF file? 00906 lpAdapter = PacketOpenAdapterDAG(AdapterNameA, TRUE); 00907 00908 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU); 00909 else GlobalFreePtr(AdapterNameA); 00910 00911 return lpAdapter; 00912 } 00913 } 00914 00915 if(TAdInfo->Flags != INFO_FLAG_NDIS_ADAPTER) 00916 { 00917 // 00918 // Not a standard NDIS adapter, we must have specific handling 00919 // 00920 00921 if(TAdInfo->Flags & INFO_FLAG_NDISWAN_ADAPTER) 00922 { 00923 // 00924 // This is a wan adapter. Open it using the netmon API 00925 // 00926 00927 lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 00928 sizeof(ADAPTER)); 00929 if (lpAdapter == NULL) 00930 { 00931 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU); 00932 else GlobalFreePtr(AdapterNameA); 00933 return NULL; 00934 } 00935 00936 // Backup flags for future usage 00937 lpAdapter->Flags = TAdInfo->Flags; 00938 00939 // Open the adapter 00940 lpAdapter->pWanAdapter = WanPacketOpenAdapter(); 00941 if (lpAdapter->pWanAdapter == NULL) 00942 { 00943 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU); 00944 else GlobalFreePtr(AdapterNameA); 00945 00946 GlobalFreePtr(lpAdapter); 00947 return NULL; 00948 } 00949 00950 _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterNameA); 00951 00952 lpAdapter->ReadEvent = WanPacketGetReadEvent(lpAdapter->pWanAdapter); 00953 00954 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU); 00955 else GlobalFreePtr(AdapterNameA); 00956 00957 return lpAdapter; 00958 } 00959 else 00960 if(TAdInfo->Flags & INFO_FLAG_DAG_CARD) 00961 { 00962 // 00963 // This is a Dag card. Open it using the dagc API 00964 // 00965 00966 lpAdapter = PacketOpenAdapterDAG(AdapterNameA, FALSE); 00967 00968 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU); 00969 else GlobalFreePtr(AdapterNameA); 00970 00971 return lpAdapter; 00972 } 00973 00974 } 00975 #endif // _WINNT4 00976 00977 lpAdapter = PacketOpenAdapterNPF(AdapterName); 00978 00979 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU); 00980 else GlobalFreePtr(AdapterNameA); 00981 00982 return lpAdapter; 00983 } 00984 00991 VOID PacketCloseAdapter(LPADAPTER lpAdapter) 00992 { 00993 00994 #ifndef _WINNT4 00995 if (lpAdapter->pWanAdapter != NULL) 00996 { 00997 WanPacketCloseAdapter(lpAdapter->pWanAdapter); 00998 GlobalFreePtr(lpAdapter); 00999 return; 01000 } 01001 #ifdef HAVE_DAG_API 01002 else 01003 if(lpAdapter->pDagCard != NULL) 01004 { 01005 if(lpAdapter->Flags & INFO_FLAG_DAG_FILE & ~INFO_FLAG_DAG_CARD) 01006 { 01007 // This is a file. We must remove the entry in the adapter description list 01008 PacketUpdateAdInfo(lpAdapter->Name); 01009 } 01010 p_dagc_close(lpAdapter->pDagCard); 01011 } 01012 #endif // HAVE_DAG_API 01013 #endif // _WINNT4 01014 01015 CloseHandle(lpAdapter->hFile); 01016 SetEvent(lpAdapter->ReadEvent); 01017 CloseHandle(lpAdapter->ReadEvent); 01018 GlobalFreePtr(lpAdapter); 01019 } 01020 01033 LPPACKET PacketAllocatePacket(void) 01034 { 01035 01036 LPPACKET lpPacket; 01037 lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET)); 01038 if (lpPacket==NULL) 01039 { 01040 ODS("PacketAllocatePacket: GlobalAlloc Failed\n"); 01041 return NULL; 01042 } 01043 return lpPacket; 01044 } 01045 01054 VOID PacketFreePacket(LPPACKET lpPacket) 01055 01056 { 01057 GlobalFreePtr(lpPacket); 01058 } 01059 01076 VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length) 01077 01078 { 01079 lpPacket->Buffer = Buffer; 01080 lpPacket->Length = Length; 01081 lpPacket->ulBytesReceived = 0; 01082 lpPacket->bIoComplete = FALSE; 01083 } 01084 01115 BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync) 01116 { 01117 BOOLEAN res; 01118 01119 #ifndef _WINNT4 01120 01121 if (AdapterObject->pWanAdapter != NULL) 01122 { 01123 lpPacket->ulBytesReceived = WanPacketReceivePacket(AdapterObject->pWanAdapter, lpPacket->Buffer, lpPacket->Length); 01124 return TRUE; 01125 } 01126 #ifdef HAVE_DAG_API 01127 else 01128 if(AdapterObject->pDagCard != NULL) 01129 { 01130 01131 p_dagc_wait(AdapterObject->pDagCard, &AdapterObject->DagReadTimeout); 01132 01133 if(p_dagc_receive(AdapterObject->pDagCard, &AdapterObject->DagBuffer, &lpPacket->ulBytesReceived) == 0) 01134 return TRUE; 01135 else 01136 return FALSE; 01137 } 01138 #endif // HAVE_DAG_API 01139 #endif // _WINNT4 01140 01141 if((int)AdapterObject->ReadTimeOut != -1) 01142 WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut); 01143 01144 res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL); 01145 01146 return res; 01147 } 01148 01178 BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync) 01179 { 01180 DWORD BytesTransfered; 01181 01182 01183 #ifndef _WINNT4 01184 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01185 { 01186 ODS("PacketSendPacket: packet sending not allowed on wan adapters\n"); 01187 return FALSE; 01188 } 01189 #endif // _WINNT4 01190 01191 return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL); 01192 } 01193 01194 01222 INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync) 01223 { 01224 BOOLEAN Res; 01225 DWORD BytesTransfered, TotBytesTransfered=0; 01226 struct timeval BufStartTime; 01227 LARGE_INTEGER StartTicks, CurTicks, TargetTicks, TimeFreq; 01228 01229 01230 ODS("PacketSendPackets"); 01231 01232 #ifndef _WINNT4 01233 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01234 { 01235 ODS("PacketSendPackets: packet sending not allowed on wan adapters\n"); 01236 return FALSE; 01237 } 01238 #endif // _WINNT4 01239 01240 // Obtain starting timestamp of the buffer 01241 BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec; 01242 BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec; 01243 01244 // Retrieve the reference time counters 01245 QueryPerformanceCounter(&StartTicks); 01246 QueryPerformanceFrequency(&TimeFreq); 01247 01248 CurTicks.QuadPart = StartTicks.QuadPart; 01249 01250 do{ 01251 // Send the data to the driver 01252 Res = DeviceIoControl(AdapterObject->hFile, 01253 (Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC, 01254 (PCHAR)PacketBuff + TotBytesTransfered, 01255 Size - TotBytesTransfered, 01256 NULL, 01257 0, 01258 &BytesTransfered, 01259 NULL); 01260 01261 TotBytesTransfered += BytesTransfered; 01262 01263 // calculate the time interval to wait before sending the next packet 01264 TargetTicks.QuadPart = StartTicks.QuadPart + 01265 (LONGLONG) 01266 ((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 + 01267 (((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) * 01268 (TimeFreq.QuadPart) / 1000000; 01269 01270 // Exit from the loop on termination or error 01271 if(TotBytesTransfered >= Size || Res != TRUE) 01272 break; 01273 01274 // Wait until the time interval has elapsed 01275 while( CurTicks.QuadPart <= TargetTicks.QuadPart ) 01276 QueryPerformanceCounter(&CurTicks); 01277 01278 } 01279 while(TRUE); 01280 01281 return TotBytesTransfered; 01282 } 01283 01302 BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes) 01303 { 01304 DWORD BytesReturned; 01305 01306 #ifndef _WINNT4 01307 if (AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER) 01308 return WanPacketSetMinToCopy(AdapterObject->pWanAdapter, nbytes); 01309 #ifdef HAVE_DAG_API 01310 else 01311 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01312 // No mintocopy with DAGs 01313 return TRUE; 01314 #endif // HAVE_DAG_API 01315 #endif // _WINNT4 01316 01317 return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL); 01318 } 01319 01356 BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode) 01357 { 01358 DWORD BytesReturned; 01359 01360 #ifndef _WINNT4 01361 if (AdapterObject->pWanAdapter != NULL) 01362 return WanPacketSetMode(AdapterObject->pWanAdapter, mode); 01363 #endif // _WINNT4 01364 01365 return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL); 01366 } 01367 01382 BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len) 01383 { 01384 DWORD BytesReturned; 01385 WCHAR *FileName; 01386 BOOLEAN res; 01387 WCHAR NameWithPath[1024]; 01388 int TStrLen; 01389 WCHAR *NamePos; 01390 01391 #ifndef _WINNT4 01392 if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01393 { 01394 ODS("PacketSetDumpName: not allowed on wan adapters\n"); 01395 return FALSE; 01396 } 01397 #endif // _WINNT4 01398 01399 if(((PUCHAR)name)[1]!=0 && len>1){ //ASCII 01400 FileName=SChar2WChar(name); 01401 len*=2; 01402 } 01403 else { //Unicode 01404 FileName=name; 01405 } 01406 01407 TStrLen=GetFullPathName(FileName,1024,NameWithPath,&NamePos); 01408 01409 len=TStrLen*2+2; //add the terminating null character 01410 01411 // Try to catch malformed strings 01412 if(len>2048){ 01413 if(((PUCHAR)name)[1]!=0 && len>1) free(FileName); 01414 return FALSE; 01415 } 01416 01417 res = DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL); 01418 free(FileName); 01419 return res; 01420 } 01421 01437 BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks) 01438 { 01439 DWORD BytesReturned; 01440 UINT valbuff[2]; 01441 01442 #ifndef _WINNT4 01443 if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01444 { 01445 ODS("PacketSetDumpLimits: not allowed on wan adapters\n"); 01446 return FALSE; 01447 } 01448 #endif // _WINNT4 01449 01450 valbuff[0] = maxfilesize; 01451 valbuff[1] = maxnpacks; 01452 01453 return DeviceIoControl(AdapterObject->hFile, 01454 pBIOCSETDUMPLIMITS, 01455 valbuff, 01456 sizeof valbuff, 01457 NULL, 01458 0, 01459 &BytesReturned, 01460 NULL); 01461 } 01462 01476 BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync) 01477 { 01478 DWORD BytesReturned; 01479 int IsDumpEnded; 01480 BOOLEAN res; 01481 01482 #ifndef _WINNT4 01483 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01484 { 01485 ODS("PacketIsDumpEnded: not allowed on wan adapters\n"); 01486 return FALSE; 01487 } 01488 #endif // _WINNT4 01489 01490 if(sync) 01491 WaitForSingleObject(AdapterObject->ReadEvent, INFINITE); 01492 01493 res = DeviceIoControl(AdapterObject->hFile, 01494 pBIOCISDUMPENDED, 01495 NULL, 01496 0, 01497 &IsDumpEnded, 01498 4, 01499 &BytesReturned, 01500 NULL); 01501 01502 if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished 01503 01504 return (BOOLEAN)IsDumpEnded; 01505 } 01506 01526 HANDLE PacketGetReadEvent(LPADAPTER AdapterObject) 01527 { 01528 return AdapterObject->ReadEvent; 01529 } 01530 01539 BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites) 01540 { 01541 DWORD BytesReturned; 01542 01543 #ifndef _WINNT4 01544 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01545 { 01546 ODS("PacketSetNumWrites: not allowed on wan adapters\n"); 01547 return FALSE; 01548 } 01549 #endif // _WINNT4 01550 01551 return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL); 01552 } 01553 01566 BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout) 01567 { 01568 DWORD BytesReturned; 01569 int DriverTimeOut=-1; 01570 01571 #ifndef _WINNT4 01572 if (AdapterObject->pWanAdapter != NULL) 01573 return WanPacketSetReadTimeout(AdapterObject->pWanAdapter,timeout); 01574 #endif // _WINNT4 01575 01576 AdapterObject->ReadTimeOut=timeout; 01577 01578 #ifdef HAVE_DAG_API 01579 // Under DAG, we simply store the timeout value and then 01580 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01581 { 01582 if(timeout == 1) 01583 { 01584 // tell DAG card to return immediately 01585 AdapterObject->DagReadTimeout.tv_sec = 0; 01586 AdapterObject->DagReadTimeout.tv_usec = 0; 01587 } 01588 else 01589 if(timeout == 1) 01590 { 01591 // tell the DAG card to wait forvever 01592 AdapterObject->DagReadTimeout.tv_sec = -1; 01593 AdapterObject->DagReadTimeout.tv_usec = -1; 01594 } 01595 else 01596 { 01597 // Set the timeout for the DAG card 01598 AdapterObject->DagReadTimeout.tv_sec = timeout / 1000; 01599 AdapterObject->DagReadTimeout.tv_usec = (timeout * 1000) % 1000000; 01600 } 01601 01602 return TRUE; 01603 } 01604 #endif // HAVE_DAG_API 01605 01606 return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL); 01607 } 01608 01625 BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim) 01626 { 01627 DWORD BytesReturned; 01628 01629 #ifndef _WINNT4 01630 if (AdapterObject->pWanAdapter != NULL) 01631 return WanPacketSetBufferSize(AdapterObject->pWanAdapter, dim); 01632 #ifdef HAVE_DAG_API 01633 else 01634 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01635 // We can't change DAG buffers 01636 return TRUE; 01637 #endif // HAVE_DAG_API 01638 01639 #endif // _WINNT4 01640 return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL); 01641 } 01642 01663 BOOLEAN PacketSetBpf(LPADAPTER AdapterObject, struct bpf_program *fp) 01664 { 01665 DWORD BytesReturned; 01666 01667 #ifndef _WINNT4 01668 if (AdapterObject->pWanAdapter != NULL) 01669 return WanPacketSetBpfFilter(AdapterObject->pWanAdapter, (PUCHAR)fp->bf_insns, fp->bf_len * sizeof(struct bpf_insn)); 01670 #ifdef HAVE_DAG_API 01671 else 01672 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01673 // Delegate the filtering to higher layers since it's too expensive here 01674 return TRUE; 01675 #endif // HAVE_DAG_API 01676 #endif // _WINNT4 01677 01678 return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL); 01679 } 01680 01695 INT PacketSetSnapLen(LPADAPTER AdapterObject, int snaplen) 01696 { 01697 01698 #ifdef HAVE_DAG_API 01699 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01700 return p_dagc_setsnaplen(AdapterObject->pDagCard, snaplen); 01701 else 01702 #endif // HAVE_DAG_API 01703 return 0; 01704 } 01705 01719 BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s) 01720 { 01721 BOOLEAN Res; 01722 DWORD BytesReturned; 01723 struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications 01724 01725 #ifndef _WINNT4 01726 #ifdef HAVE_DAG_API 01727 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01728 { 01729 dagc_stats_t DagStats; 01730 01731 // Note: DAG cards are currently very limited from the statistics reporting point of view, 01732 // so most of the values returned by dagc_stats() are zero at the moment 01733 if(p_dagc_stats(AdapterObject->pDagCard, &DagStats) == 0) 01734 { 01735 // XXX: Only copy the dropped packets for now, since the received counter is not supported by 01736 // DAGS at the moment 01737 01738 s->bs_recv = (ULONG)DagStats.received; 01739 s->bs_drop = (ULONG)DagStats.dropped; 01740 return TRUE; 01741 } 01742 else 01743 return FALSE; 01744 } 01745 else 01746 #endif // HAVE_DAG_API 01747 if ( AdapterObject->pWanAdapter != NULL) 01748 Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat); 01749 else 01750 #endif // _WINNT4 01751 01752 Res = DeviceIoControl(AdapterObject->hFile, 01753 pBIOCGSTATS, 01754 NULL, 01755 0, 01756 &tmpstat, 01757 sizeof(struct bpf_stat), 01758 &BytesReturned, 01759 NULL); 01760 01761 01762 // Copy only the first two values retrieved from the driver 01763 s->bs_recv = tmpstat.bs_recv; 01764 s->bs_drop = tmpstat.bs_drop; 01765 01766 return Res; 01767 } 01768 01781 BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s) 01782 { 01783 BOOLEAN Res; 01784 DWORD BytesReturned; 01785 struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications 01786 01787 #ifndef _WINNT4 01788 #ifdef HAVE_DAG_API 01789 if(AdapterObject->Flags & INFO_FLAG_DAG_CARD) 01790 { 01791 dagc_stats_t DagStats; 01792 01793 // Note: DAG cards are currently very limited from the statistics reporting point of view, 01794 // so most of the values returned by dagc_stats() are zero at the moment 01795 p_dagc_stats(AdapterObject->pDagCard, &DagStats); 01796 s->bs_recv = (ULONG)DagStats.received; 01797 s->bs_drop = (ULONG)DagStats.dropped; 01798 s->ps_ifdrop = 0; 01799 s->bs_capt = (ULONG)DagStats.captured; 01800 } 01801 #endif // HAVE_DAG_API 01802 if(AdapterObject->pWanAdapter != NULL) 01803 Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat); 01804 else 01805 #endif // _WINNT4 01806 01807 Res = DeviceIoControl(AdapterObject->hFile, 01808 pBIOCGSTATS, 01809 NULL, 01810 0, 01811 &tmpstat, 01812 sizeof(struct bpf_stat), 01813 &BytesReturned, 01814 NULL); 01815 01816 s->bs_recv = tmpstat.bs_recv; 01817 s->bs_drop = tmpstat.bs_drop; 01818 s->ps_ifdrop = tmpstat.ps_ifdrop; 01819 s->bs_capt = tmpstat.bs_capt; 01820 01821 return Res; 01822 } 01823 01836 BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData) 01837 { 01838 DWORD BytesReturned; 01839 BOOLEAN Result; 01840 01841 #ifndef _WINNT4 01842 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01843 return FALSE; 01844 #endif // _WINNT4 01845 01846 Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? (DWORD)pBIOCSETOID : (DWORD)pBIOCQUERYOID, 01847 OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData, 01848 sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL); 01849 01850 // output some debug info 01851 ODSEx("PacketRequest, OID=%d ", OidData->Oid); 01852 ODSEx("Length=%d ", OidData->Length); 01853 ODSEx("Set=%d ", Set); 01854 ODSEx("Res=%d\n", Result); 01855 01856 return Result; 01857 } 01858 01875 BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter) 01876 { 01877 BOOLEAN Status; 01878 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); 01879 PPACKET_OID_DATA OidData; 01880 01881 #ifndef _WINNT4 01882 if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER) 01883 return TRUE; 01884 #endif // _WINNT4 01885 01886 OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); 01887 if (OidData == NULL) { 01888 ODS("PacketSetHwFilter: GlobalAlloc Failed\n"); 01889 return FALSE; 01890 } 01891 OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER; 01892 OidData->Length=sizeof(ULONG); 01893 *((PULONG)OidData->Data)=Filter; 01894 Status=PacketRequest(AdapterObject,TRUE,OidData); 01895 GlobalFreePtr(OidData); 01896 return Status; 01897 } 01898 01920 BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize) 01921 { 01922 PADAPTER_INFO TAdInfo; 01923 ULONG SizeNeeded = 1; 01924 ULONG SizeNames = 1; 01925 ULONG SizeDesc; 01926 ULONG OffDescriptions; 01927 01928 ODSEx("PacketGetAdapterNames: BufferSize=%d\n", *BufferSize); 01929 01930 // 01931 // Create the adapter information list 01932 // 01933 PacketPopulateAdaptersInfoList(); 01934 01935 if(!AdaptersInfoList){ 01936 *BufferSize = 0; 01937 return FALSE; // No adapters to return 01938 } 01939 01940 // 01941 // First scan of the list to calculate the offsets and check the sizes 01942 // 01943 for(TAdInfo = AdaptersInfoList; TAdInfo != NULL; TAdInfo = TAdInfo->Next) 01944 { 01945 // Update the size variables 01946 SizeNeeded += strlen(TAdInfo->Name) + strlen(TAdInfo->Description) + 1; 01947 SizeNames += strlen(TAdInfo->Name) + 1; 01948 01949 // Check not to overflow the buffer 01950 if(SizeNeeded >= *BufferSize) 01951 { 01952 *BufferSize = SizeNeeded; 01953 ODS("PacketGetAdapterNames: input buffer too small\n"); 01954 return FALSE; 01955 } 01956 } 01957 01958 OffDescriptions = SizeNames; 01959 01960 // 01961 // Second scan of the list to copy the information 01962 // 01963 for(TAdInfo = AdaptersInfoList, SizeNames = 0, SizeDesc = 0; TAdInfo != NULL; TAdInfo = TAdInfo->Next) 01964 { 01965 // Copy the data 01966 strcpy(((PCHAR)pStr) + SizeNames, TAdInfo->Name); 01967 strcpy(((PCHAR)pStr) + OffDescriptions + SizeDesc, TAdInfo->Description); 01968 01969 // Update the size variables 01970 SizeNames += strlen(TAdInfo->Name) + 1; 01971 SizeDesc += strlen(TAdInfo->Description) + 1; 01972 } 01973 01974 // Separate the two lists 01975 ((PCHAR)pStr)[SizeNames] = 0; 01976 01977 return TRUE; 01978 } 01979 01993 BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries) 01994 { 01995 PADAPTER_INFO TAdInfo; 01996 PCHAR Tname; 01997 BOOLEAN Res, FreeBuff; 01998 01999 ODS("PacketGetNetInfo\n"); 02000 02001 // Provide conversion for backward compatibility 02002 if(AdapterName[1] != 0) 02003 { //ASCII 02004 Tname = AdapterName; 02005 FreeBuff = FALSE; 02006 } 02007 else 02008 { 02009 Tname = WChar2SChar((PWCHAR)AdapterName); 02010 FreeBuff = TRUE; 02011 } 02012 02013 // 02014 // Update the information about this adapter 02015 // 02016 if(!PacketUpdateAdInfo(Tname)) 02017 { 02018 ODS("PacketGetNetInfo: Adapter not found\n"); 02019 if(FreeBuff)GlobalFreePtr(Tname); 02020 return FALSE; 02021 } 02022 02023 // Find the PADAPTER_INFO structure associated with this adapter 02024 TAdInfo = PacketFindAdInfo(Tname); 02025 02026 if(TAdInfo != NULL) 02027 { 02028 *NEntries = (TAdInfo->NNetworkAddresses < *NEntries)? TAdInfo->NNetworkAddresses: *NEntries; 02029 memcpy(buffer, TAdInfo->NetworkAddresses, *NEntries * sizeof(npf_if_addr)); 02030 Res = TRUE; 02031 } 02032 else 02033 { 02034 ODS("PacketGetNetInfo: Adapter not found\n"); 02035 Res = FALSE; 02036 } 02037 02038 if(FreeBuff)GlobalFreePtr(Tname); 02039 02040 return Res; 02041 } 02042 02059 BOOLEAN PacketGetNetType(LPADAPTER AdapterObject, NetType *type) 02060 { 02061 PADAPTER_INFO TAdInfo; 02062 02063 ODS("PacketGetNetType\n"); 02064 02065 // Find the PADAPTER_INFO structure associated with this adapter 02066 TAdInfo = PacketFindAdInfo(AdapterObject->Name); 02067 02068 if(TAdInfo != NULL) 02069 { 02070 // Copy the data 02071 memcpy(type, &(TAdInfo->LinkLayer), sizeof(struct NetType)); 02072 } 02073 else 02074 { 02075 ODS("PacketGetNetType: Adapter not found\n"); 02076 return FALSE; 02077 } 02078 02079 return TRUE; 02080 } 02081 02082 /* @} */
documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.