12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307 |
- /*
- * Copyright (c) 2008 CACE Technologies, Davis (California)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of CACE Technologies nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <pcap.h>
- #include <pcap-int.h>
- #include "pcap-tc.h"
- #include <malloc.h>
- #include <memory.h>
- #include <string.h>
- #include <errno.h>
- #ifdef _WIN32
- #include <tchar.h>
- #endif
- typedef TC_STATUS (TC_CALLCONV *TcFcnQueryPortList) (PTC_PORT *ppPorts, PULONG pLength);
- typedef TC_STATUS (TC_CALLCONV *TcFcnFreePortList) (TC_PORT *pPorts);
- typedef PCHAR (TC_CALLCONV *TcFcnStatusGetString) (TC_STATUS status);
- typedef PCHAR (TC_CALLCONV *TcFcnPortGetName) (TC_PORT port);
- typedef PCHAR (TC_CALLCONV *TcFcnPortGetDescription) (TC_PORT port);
- typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceOpenByName) (PCHAR name, PTC_INSTANCE pInstance);
- typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceClose) (TC_INSTANCE instance);
- typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceSetFeature) (TC_INSTANCE instance, ULONG feature, ULONG value);
- typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceQueryFeature) (TC_INSTANCE instance, ULONG feature, PULONG pValue);
- typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceReceivePackets) (TC_INSTANCE instance, PTC_PACKETS_BUFFER pBuffer);
- typedef HANDLE (TC_CALLCONV *TcFcnInstanceGetReceiveWaitHandle) (TC_INSTANCE instance);
- typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceTransmitPackets) (TC_INSTANCE instance, TC_PACKETS_BUFFER pBuffer);
- typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceQueryStatistics) (TC_INSTANCE instance, PTC_STATISTICS pStatistics);
- typedef TC_STATUS (TC_CALLCONV *TcFcnPacketsBufferCreate) (ULONG size, PTC_PACKETS_BUFFER pBuffer);
- typedef VOID (TC_CALLCONV *TcFcnPacketsBufferDestroy) (TC_PACKETS_BUFFER buffer);
- typedef TC_STATUS (TC_CALLCONV *TcFcnPacketsBufferQueryNextPacket)(TC_PACKETS_BUFFER buffer, PTC_PACKET_HEADER pHeader, PVOID *ppData);
- typedef TC_STATUS (TC_CALLCONV *TcFcnPacketsBufferCommitNextPacket)(TC_PACKETS_BUFFER buffer, PTC_PACKET_HEADER pHeader, PVOID pData);
- typedef VOID (TC_CALLCONV *TcFcnStatisticsDestroy) (TC_STATISTICS statistics);
- typedef TC_STATUS (TC_CALLCONV *TcFcnStatisticsUpdate) (TC_STATISTICS statistics);
- typedef TC_STATUS (TC_CALLCONV *TcFcnStatisticsQueryValue) (TC_STATISTICS statistics, ULONG counterId, PULONGLONG pValue);
- typedef enum LONG
- {
- TC_API_UNLOADED = 0,
- TC_API_LOADED,
- TC_API_CANNOT_LOAD,
- TC_API_LOADING
- }
- TC_API_LOAD_STATUS;
- typedef struct _TC_FUNCTIONS
- {
- TC_API_LOAD_STATUS LoadStatus;
- #ifdef _WIN32
- HMODULE hTcApiDllHandle;
- #endif
- TcFcnQueryPortList QueryPortList;
- TcFcnFreePortList FreePortList;
- TcFcnStatusGetString StatusGetString;
- TcFcnPortGetName PortGetName;
- TcFcnPortGetDescription PortGetDescription;
- TcFcnInstanceOpenByName InstanceOpenByName;
- TcFcnInstanceClose InstanceClose;
- TcFcnInstanceSetFeature InstanceSetFeature;
- TcFcnInstanceQueryFeature InstanceQueryFeature;
- TcFcnInstanceReceivePackets InstanceReceivePackets;
- #ifdef _WIN32
- TcFcnInstanceGetReceiveWaitHandle InstanceGetReceiveWaitHandle;
- #endif
- TcFcnInstanceTransmitPackets InstanceTransmitPackets;
- TcFcnInstanceQueryStatistics InstanceQueryStatistics;
- TcFcnPacketsBufferCreate PacketsBufferCreate;
- TcFcnPacketsBufferDestroy PacketsBufferDestroy;
- TcFcnPacketsBufferQueryNextPacket PacketsBufferQueryNextPacket;
- TcFcnPacketsBufferCommitNextPacket PacketsBufferCommitNextPacket;
- TcFcnStatisticsDestroy StatisticsDestroy;
- TcFcnStatisticsUpdate StatisticsUpdate;
- TcFcnStatisticsQueryValue StatisticsQueryValue;
- }
- TC_FUNCTIONS;
- static pcap_if_t* TcCreatePcapIfFromPort(TC_PORT port);
- static int TcSetDatalink(pcap_t *p, int dlt);
- static int TcGetNonBlock(pcap_t *p);
- static int TcSetNonBlock(pcap_t *p, int nonblock);
- static void TcCleanup(pcap_t *p);
- static int TcInject(pcap_t *p, const void *buf, size_t size);
- static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user);
- static int TcStats(pcap_t *p, struct pcap_stat *ps);
- static int TcSetFilter(pcap_t *p, struct bpf_program *fp);
- #ifdef _WIN32
- static struct pcap_stat *TcStatsEx(pcap_t *p, int *pcap_stat_size);
- static int TcSetBuff(pcap_t *p, int dim);
- static int TcSetMode(pcap_t *p, int mode);
- static int TcSetMinToCopy(pcap_t *p, int size);
- static HANDLE TcGetReceiveWaitHandle(pcap_t *p);
- static int TcOidGetRequest(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp);
- static int TcOidSetRequest(pcap_t *p, bpf_u_int32 oid, const void *data, size_t *lenp);
- static u_int TcSendqueueTransmit(pcap_t *p, pcap_send_queue *queue, int sync);
- static int TcSetUserBuffer(pcap_t *p, int size);
- static int TcLiveDump(pcap_t *p, char *filename, int maxsize, int maxpacks);
- static int TcLiveDumpEnded(pcap_t *p, int sync);
- static PAirpcapHandle TcGetAirPcapHandle(pcap_t *p);
- #endif
- #ifdef _WIN32
- TC_FUNCTIONS g_TcFunctions =
- {
- TC_API_UNLOADED, /* LoadStatus */
- NULL, /* hTcApiDllHandle */
- NULL, /* QueryPortList */
- NULL, /* FreePortList */
- NULL, /* StatusGetString */
- NULL, /* PortGetName */
- NULL, /* PortGetDescription */
- NULL, /* InstanceOpenByName */
- NULL, /* InstanceClose */
- NULL, /* InstanceSetFeature */
- NULL, /* InstanceQueryFeature */
- NULL, /* InstanceReceivePackets */
- NULL, /* InstanceGetReceiveWaitHandle */
- NULL, /* InstanceTransmitPackets */
- NULL, /* InstanceQueryStatistics */
- NULL, /* PacketsBufferCreate */
- NULL, /* PacketsBufferDestroy */
- NULL, /* PacketsBufferQueryNextPacket */
- NULL, /* PacketsBufferCommitNextPacket */
- NULL, /* StatisticsDestroy */
- NULL, /* StatisticsUpdate */
- NULL /* StatisticsQueryValue */
- };
- #else
- TC_FUNCTIONS g_TcFunctions =
- {
- TC_API_LOADED, /* LoadStatus */
- TcQueryPortList,
- TcFreePortList,
- TcStatusGetString,
- TcPortGetName,
- TcPortGetDescription,
- TcInstanceOpenByName,
- TcInstanceClose,
- TcInstanceSetFeature,
- TcInstanceQueryFeature,
- TcInstanceReceivePackets,
- #ifdef _WIN32
- TcInstanceGetReceiveWaitHandle,
- #endif
- TcInstanceTransmitPackets,
- TcInstanceQueryStatistics,
- TcPacketsBufferCreate,
- TcPacketsBufferDestroy,
- TcPacketsBufferQueryNextPacket,
- TcPacketsBufferCommitNextPacket,
- TcStatisticsDestroy,
- TcStatisticsUpdate,
- TcStatisticsQueryValue,
- };
- #endif
- #define MAX_TC_PACKET_SIZE 9500
- #pragma pack(push, 1)
- #define PPH_PH_FLAG_PADDING ((UCHAR)0x01)
- #define PPH_PH_VERSION ((UCHAR)0x00)
- typedef struct _PPI_PACKET_HEADER
- {
- UCHAR PphVersion;
- UCHAR PphFlags;
- USHORT PphLength;
- ULONG PphDlt;
- }
- PPI_PACKET_HEADER, *PPPI_PACKET_HEADER;
- typedef struct _PPI_FIELD_HEADER
- {
- USHORT PfhType;
- USHORT PfhLength;
- }
- PPI_FIELD_HEADER, *PPPI_FIELD_HEADER;
- #define PPI_FIELD_TYPE_AGGREGATION_EXTENSION ((UCHAR)0x08)
- typedef struct _PPI_FIELD_AGGREGATION_EXTENSION
- {
- ULONG InterfaceId;
- }
- PPI_FIELD_AGGREGATION_EXTENSION, *PPPI_FIELD_AGGREGATION_EXTENSION;
- #define PPI_FIELD_TYPE_802_3_EXTENSION ((UCHAR)0x09)
- #define PPI_FLD_802_3_EXT_FLAG_FCS_PRESENT ((ULONG)0x00000001)
- typedef struct _PPI_FIELD_802_3_EXTENSION
- {
- ULONG Flags;
- ULONG Errors;
- }
- PPI_FIELD_802_3_EXTENSION, *PPPI_FIELD_802_3_EXTENSION;
- typedef struct _PPI_HEADER
- {
- PPI_PACKET_HEADER PacketHeader;
- PPI_FIELD_HEADER AggregationFieldHeader;
- PPI_FIELD_AGGREGATION_EXTENSION AggregationField;
- PPI_FIELD_HEADER Dot3FieldHeader;
- PPI_FIELD_802_3_EXTENSION Dot3Field;
- }
- PPI_HEADER, *PPPI_HEADER;
- #pragma pack(pop)
- #ifdef _WIN32
- //
- // This wrapper around loadlibrary appends the system folder (usually c:\windows\system32)
- // to the relative path of the DLL, so that the DLL is always loaded from an absolute path
- // (It's no longer possible to load airpcap.dll from the application folder).
- // This solves the DLL Hijacking issue discovered in August 2010
- // http://blog.metasploit.com/2010/08/exploiting-dll-hijacking-flaws.html
- //
- HMODULE LoadLibrarySafe(LPCTSTR lpFileName)
- {
- TCHAR path[MAX_PATH];
- TCHAR fullFileName[MAX_PATH];
- UINT res;
- HMODULE hModule = NULL;
- do
- {
- res = GetSystemDirectory(path, MAX_PATH);
- if (res == 0)
- {
- //
- // some bad failure occurred;
- //
- break;
- }
- if (res > MAX_PATH)
- {
- //
- // the buffer was not big enough
- //
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- break;
- }
- if (res + 1 + _tcslen(lpFileName) + 1 < MAX_PATH)
- {
- memcpy(fullFileName, path, res * sizeof(TCHAR));
- fullFileName[res] = _T('\\');
- memcpy(&fullFileName[res + 1], lpFileName, (_tcslen(lpFileName) + 1) * sizeof(TCHAR));
- hModule = LoadLibrary(fullFileName);
- }
- else
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- }
- }while(FALSE);
- return hModule;
- }
- /*
- * NOTE: this function should be called by the pcap functions that can theoretically
- * deal with the Tc library for the first time, namely listing the adapters and
- * opening one. All the other ones (close, read, write, set parameters) work
- * on an open instance of TC, so we do not care to call this function
- */
- TC_API_LOAD_STATUS LoadTcFunctions(void)
- {
- TC_API_LOAD_STATUS currentStatus;
- do
- {
- currentStatus = InterlockedCompareExchange((LONG*)&g_TcFunctions.LoadStatus, TC_API_LOADING, TC_API_UNLOADED);
- while(currentStatus == TC_API_LOADING)
- {
- currentStatus = InterlockedCompareExchange((LONG*)&g_TcFunctions.LoadStatus, TC_API_LOADING, TC_API_LOADING);
- Sleep(10);
- }
- /*
- * at this point we are either in the LOADED state, unloaded state (i.e. we are the ones loading everything)
- * or in cannot load
- */
- if(currentStatus == TC_API_LOADED)
- {
- return TC_API_LOADED;
- }
- if (currentStatus == TC_API_CANNOT_LOAD)
- {
- return TC_API_CANNOT_LOAD;
- }
- currentStatus = TC_API_CANNOT_LOAD;
- g_TcFunctions.hTcApiDllHandle = LoadLibrarySafe("TcApi.dll");
- if (g_TcFunctions.hTcApiDllHandle == NULL) break;
- g_TcFunctions.QueryPortList = (TcFcnQueryPortList) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcQueryPortList");
- g_TcFunctions.FreePortList = (TcFcnFreePortList) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcFreePortList");
- g_TcFunctions.StatusGetString = (TcFcnStatusGetString) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcStatusGetString");
- g_TcFunctions.PortGetName = (TcFcnPortGetName) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPortGetName");
- g_TcFunctions.PortGetDescription = (TcFcnPortGetDescription) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPortGetDescription");
- g_TcFunctions.InstanceOpenByName = (TcFcnInstanceOpenByName) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceOpenByName");
- g_TcFunctions.InstanceClose = (TcFcnInstanceClose) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceClose");
- g_TcFunctions.InstanceSetFeature = (TcFcnInstanceSetFeature) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceSetFeature");
- g_TcFunctions.InstanceQueryFeature = (TcFcnInstanceQueryFeature) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceQueryFeature");
- g_TcFunctions.InstanceReceivePackets = (TcFcnInstanceReceivePackets) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceReceivePackets");
- g_TcFunctions.InstanceGetReceiveWaitHandle = (TcFcnInstanceGetReceiveWaitHandle)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceGetReceiveWaitHandle");
- g_TcFunctions.InstanceTransmitPackets = (TcFcnInstanceTransmitPackets)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceTransmitPackets");
- g_TcFunctions.InstanceQueryStatistics = (TcFcnInstanceQueryStatistics)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceQueryStatistics");
- g_TcFunctions.PacketsBufferCreate = (TcFcnPacketsBufferCreate) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferCreate");
- g_TcFunctions.PacketsBufferDestroy = (TcFcnPacketsBufferDestroy) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferDestroy");
- g_TcFunctions.PacketsBufferQueryNextPacket = (TcFcnPacketsBufferQueryNextPacket)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferQueryNextPacket");
- g_TcFunctions.PacketsBufferCommitNextPacket = (TcFcnPacketsBufferCommitNextPacket)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferCommitNextPacket");
- g_TcFunctions.StatisticsDestroy = (TcFcnStatisticsDestroy) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcStatisticsDestroy");
- g_TcFunctions.StatisticsUpdate = (TcFcnStatisticsUpdate) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcStatisticsUpdate");
- g_TcFunctions.StatisticsQueryValue = (TcFcnStatisticsQueryValue) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcStatisticsQueryValue");
- if ( g_TcFunctions.QueryPortList == NULL
- || g_TcFunctions.FreePortList == NULL
- || g_TcFunctions.StatusGetString == NULL
- || g_TcFunctions.PortGetName == NULL
- || g_TcFunctions.PortGetDescription == NULL
- || g_TcFunctions.InstanceOpenByName == NULL
- || g_TcFunctions.InstanceClose == NULL
- || g_TcFunctions.InstanceSetFeature == NULL
- || g_TcFunctions.InstanceQueryFeature == NULL
- || g_TcFunctions.InstanceReceivePackets == NULL
- || g_TcFunctions.InstanceGetReceiveWaitHandle == NULL
- || g_TcFunctions.InstanceTransmitPackets == NULL
- || g_TcFunctions.InstanceQueryStatistics == NULL
- || g_TcFunctions.PacketsBufferCreate == NULL
- || g_TcFunctions.PacketsBufferDestroy == NULL
- || g_TcFunctions.PacketsBufferQueryNextPacket == NULL
- || g_TcFunctions.PacketsBufferCommitNextPacket == NULL
- || g_TcFunctions.StatisticsDestroy == NULL
- || g_TcFunctions.StatisticsUpdate == NULL
- || g_TcFunctions.StatisticsQueryValue == NULL
- )
- {
- break;
- }
- /*
- * everything got loaded, yay!!
- */
- currentStatus = TC_API_LOADED;
- }while(FALSE);
- if (currentStatus != TC_API_LOADED)
- {
- if (g_TcFunctions.hTcApiDllHandle != NULL)
- {
- FreeLibrary(g_TcFunctions.hTcApiDllHandle);
- g_TcFunctions.hTcApiDllHandle = NULL;
- }
- }
- InterlockedExchange((LONG*)&g_TcFunctions.LoadStatus, currentStatus);
- return currentStatus;
- }
- #else
- // static linking
- TC_API_LOAD_STATUS LoadTcFunctions(void)
- {
- return TC_API_LOADED;
- }
- #endif
- /*
- * Private data for capturing on TurboCap devices.
- */
- struct pcap_tc {
- TC_INSTANCE TcInstance;
- TC_PACKETS_BUFFER TcPacketsBuffer;
- ULONG TcAcceptedCount;
- u_char *PpiPacket;
- };
- int
- TcFindAllDevs(pcap_if_list_t *devlist, char *errbuf)
- {
- TC_API_LOAD_STATUS loadStatus;
- ULONG numPorts;
- PTC_PORT pPorts = NULL;
- TC_STATUS status;
- int result = 0;
- pcap_if_t *dev, *cursor;
- ULONG i;
- do
- {
- loadStatus = LoadTcFunctions();
- if (loadStatus != TC_API_LOADED)
- {
- result = 0;
- break;
- }
- /*
- * enumerate the ports, and add them to the list
- */
- status = g_TcFunctions.QueryPortList(&pPorts, &numPorts);
- if (status != TC_SUCCESS)
- {
- result = 0;
- break;
- }
- for (i = 0; i < numPorts; i++)
- {
- /*
- * transform the port into an entry in the list
- */
- dev = TcCreatePcapIfFromPort(pPorts[i]);
- if (dev != NULL)
- {
- /*
- * append it at the end
- */
- if (devlistp->beginning == NULL)
- {
- devlistp->beginning = dev;
- }
- else
- {
- for (cursor = devlistp->beginning;
- cursor->next != NULL;
- cursor = cursor->next);
- cursor->next = dev;
- }
- }
- }
- if (numPorts > 0)
- {
- /*
- * ignore the result here
- */
- status = g_TcFunctions.FreePortList(pPorts);
- }
- }while(FALSE);
- return result;
- }
- static pcap_if_t* TcCreatePcapIfFromPort(TC_PORT port)
- {
- CHAR *name;
- CHAR *description;
- pcap_if_t *newIf = NULL;
- newIf = (pcap_if_t*)malloc(sizeof(*newIf));
- if (newIf == NULL)
- {
- return NULL;
- }
- memset(newIf, 0, sizeof(*newIf));
- name = g_TcFunctions.PortGetName(port);
- description = g_TcFunctions.PortGetDescription(port);
- newIf->name = (char*)malloc(strlen(name) + 1);
- if (newIf->name == NULL)
- {
- free(newIf);
- return NULL;
- }
- newIf->description = (char*)malloc(strlen(description) + 1);
- if (newIf->description == NULL)
- {
- free(newIf->name);
- free(newIf);
- return NULL;
- }
- strcpy(newIf->name, name);
- strcpy(newIf->description, description);
- newIf->addresses = NULL;
- newIf->next = NULL;
- newIf->flags = 0;
- return newIf;
- }
- static int
- TcActivate(pcap_t *p)
- {
- struct pcap_tc *pt = p->priv;
- TC_STATUS status;
- ULONG timeout;
- PPPI_HEADER pPpiHeader;
- if (p->opt.rfmon)
- {
- /*
- * No monitor mode on Tc cards; they're Ethernet
- * capture adapters.
- */
- return PCAP_ERROR_RFMON_NOTSUP;
- }
- pt->PpiPacket = malloc(sizeof(PPI_HEADER) + MAX_TC_PACKET_SIZE);
- if (pt->PpiPacket == NULL)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error allocating memory");
- return PCAP_ERROR;
- }
- /*
- * Turn a negative snapshot value (invalid), a snapshot value of
- * 0 (unspecified), or a value bigger than the normal maximum
- * value, into the maximum allowed value.
- *
- * If some application really *needs* a bigger snapshot
- * length, we should just increase MAXIMUM_SNAPLEN.
- */
- if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
- p->snapshot = MAXIMUM_SNAPLEN;
- /*
- * Initialize the PPI fixed fields
- */
- pPpiHeader = (PPPI_HEADER)pt->PpiPacket;
- pPpiHeader->PacketHeader.PphDlt = DLT_EN10MB;
- pPpiHeader->PacketHeader.PphLength = sizeof(PPI_HEADER);
- pPpiHeader->PacketHeader.PphFlags = 0;
- pPpiHeader->PacketHeader.PphVersion = 0;
- pPpiHeader->AggregationFieldHeader.PfhLength = sizeof(PPI_FIELD_AGGREGATION_EXTENSION);
- pPpiHeader->AggregationFieldHeader.PfhType = PPI_FIELD_TYPE_AGGREGATION_EXTENSION;
- pPpiHeader->Dot3FieldHeader.PfhLength = sizeof(PPI_FIELD_802_3_EXTENSION);
- pPpiHeader->Dot3FieldHeader.PfhType = PPI_FIELD_TYPE_802_3_EXTENSION;
- status = g_TcFunctions.InstanceOpenByName(p->opt.device, &pt->TcInstance);
- if (status != TC_SUCCESS)
- {
- /* Adapter detected but we are not able to open it. Return failure. */
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening TurboCap adapter: %s", g_TcFunctions.StatusGetString(status));
- return PCAP_ERROR;
- }
- p->linktype = DLT_EN10MB;
- p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
- /*
- * If that fails, just leave the list empty.
- */
- if (p->dlt_list != NULL) {
- p->dlt_list[0] = DLT_EN10MB;
- p->dlt_list[1] = DLT_PPI;
- p->dlt_count = 2;
- }
- /*
- * ignore promiscuous mode
- * p->opt.promisc
- */
- /*
- * ignore all the buffer sizes
- */
- /*
- * enable reception
- */
- status = g_TcFunctions.InstanceSetFeature(pt->TcInstance, TC_INST_FT_RX_STATUS, 1);
- if (status != TC_SUCCESS)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error enabling reception on a TurboCap instance: %s", g_TcFunctions.StatusGetString(status));
- goto bad;
- }
- /*
- * enable transmission
- */
- status = g_TcFunctions.InstanceSetFeature(pt->TcInstance, TC_INST_FT_TX_STATUS, 1);
- /*
- * Ignore the error here.
- */
- p->inject_op = TcInject;
- /*
- * if the timeout is -1, it means immediate return, no timeout
- * if the timeout is 0, it means INFINITE
- */
- if (p->opt.timeout == 0)
- {
- timeout = 0xFFFFFFFF;
- }
- else
- if (p->opt.timeout < 0)
- {
- /*
- * we insert a minimal timeout here
- */
- timeout = 10;
- }
- else
- {
- timeout = p->opt.timeout;
- }
- status = g_TcFunctions.InstanceSetFeature(pt->TcInstance, TC_INST_FT_READ_TIMEOUT, timeout);
- if (status != TC_SUCCESS)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error setting the read timeout a TurboCap instance: %s", g_TcFunctions.StatusGetString(status));
- goto bad;
- }
- p->read_op = TcRead;
- p->setfilter_op = TcSetFilter;
- p->setdirection_op = NULL; /* Not implemented. */
- p->set_datalink_op = TcSetDatalink;
- p->getnonblock_op = TcGetNonBlock;
- p->setnonblock_op = TcSetNonBlock;
- p->stats_op = TcStats;
- #ifdef _WIN32
- p->stats_ex_op = TcStatsEx;
- p->setbuff_op = TcSetBuff;
- p->setmode_op = TcSetMode;
- p->setmintocopy_op = TcSetMinToCopy;
- p->getevent_op = TcGetReceiveWaitHandle;
- p->oid_get_request_op = TcOidGetRequest;
- p->oid_set_request_op = TcOidSetRequest;
- p->sendqueue_transmit_op = TcSendqueueTransmit;
- p->setuserbuffer_op = TcSetUserBuffer;
- p->live_dump_op = TcLiveDump;
- p->live_dump_ended_op = TcLiveDumpEnded;
- p->get_airpcap_handle_op = TcGetAirPcapHandle;
- #else
- p->selectable_fd = -1;
- #endif
- p->cleanup_op = TcCleanup;
- return 0;
- bad:
- TcCleanup(p);
- return PCAP_ERROR;
- }
- pcap_t *
- TcCreate(const char *device, char *ebuf, int *is_ours)
- {
- ULONG numPorts;
- PTC_PORT pPorts = NULL;
- TC_STATUS status;
- int is_tc;
- ULONG i;
- pcap_t *p;
- if (LoadTcFunctions() != TC_API_LOADED)
- {
- /*
- * XXX - report this as an error rather than as
- * "not a TurboCap device"?
- */
- *is_ours = 0;
- return NULL;
- }
- /*
- * enumerate the ports, and add them to the list
- */
- status = g_TcFunctions.QueryPortList(&pPorts, &numPorts);
- if (status != TC_SUCCESS)
- {
- /*
- * XXX - report this as an error rather than as
- * "not a TurboCap device"?
- */
- *is_ours = 0;
- return NULL;
- }
- is_tc = FALSE;
- for (i = 0; i < numPorts; i++)
- {
- if (strcmp(g_TcFunctions.PortGetName(pPorts[i]), device) == 0)
- {
- is_tc = TRUE;
- break;
- }
- }
- if (numPorts > 0)
- {
- /*
- * ignore the result here
- */
- (void)g_TcFunctions.FreePortList(pPorts);
- }
- if (!is_tc)
- {
- *is_ours = 0;
- return NULL;
- }
- /* OK, it's probably ours. */
- *is_ours = 1;
- p = pcap_create_common(ebuf, sizeof (struct pcap_tc));
- if (p == NULL)
- return NULL;
- p->activate_op = TcActivate;
- /*
- * Set these up front, so that, even if our client tries
- * to set non-blocking mode before we're activated, or
- * query the state of non-blocking mode, they get an error,
- * rather than having the non-blocking mode option set
- * for use later.
- */
- p->getnonblock_op = TcGetNonBlock;
- p->setnonblock_op = TcSetNonBlock;
- return p;
- }
- static int TcSetDatalink(pcap_t *p, int dlt)
- {
- /*
- * We don't have to do any work here; pcap_set_datalink() checks
- * whether the value is in the list of DLT_ values we
- * supplied, so we don't have to, and, if it is valid, sets
- * p->linktype to the new value; we don't have to do anything
- * in hardware, we just use what's in p->linktype.
- *
- * We do have to have a routine, however, so that pcap_set_datalink()
- * doesn't think we don't support setting the link-layer header
- * type at all.
- */
- return 0;
- }
- static int TcGetNonBlock(pcap_t *p)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Non-blocking mode isn't supported for TurboCap ports");
- return -1;
- }
- static int TcSetNonBlock(pcap_t *p, int nonblock)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Non-blocking mode isn't supported for TurboCap ports");
- return -1;
- }
- static void TcCleanup(pcap_t *p)
- {
- struct pcap_tc *pt = p->priv;
- if (pt->TcPacketsBuffer != NULL)
- {
- g_TcFunctions.PacketsBufferDestroy(pt->TcPacketsBuffer);
- pt->TcPacketsBuffer = NULL;
- }
- if (pt->TcInstance != NULL)
- {
- /*
- * here we do not check for the error values
- */
- g_TcFunctions.InstanceClose(pt->TcInstance);
- pt->TcInstance = NULL;
- }
- if (pt->PpiPacket != NULL)
- {
- free(pt->PpiPacket);
- pt->PpiPacket = NULL;
- }
- pcap_cleanup_live_common(p);
- }
- /* Send a packet to the network */
- static int TcInject(pcap_t *p, const void *buf, size_t size)
- {
- struct pcap_tc *pt = p->priv;
- TC_STATUS status;
- TC_PACKETS_BUFFER buffer;
- TC_PACKET_HEADER header;
- if (size >= 0xFFFF)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: the TurboCap API does not support packets larger than 64k");
- return -1;
- }
- status = g_TcFunctions.PacketsBufferCreate(sizeof(TC_PACKET_HEADER) + TC_ALIGN_USHORT_TO_64BIT((USHORT)size), &buffer);
- if (status != TC_SUCCESS)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCreate failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
- return -1;
- }
- /*
- * we assume that the packet is without the checksum, as common with WinPcap
- */
- memset(&header, 0, sizeof(header));
- header.Length = (USHORT)size;
- header.CapturedLength = header.Length;
- status = g_TcFunctions.PacketsBufferCommitNextPacket(buffer, &header, (PVOID)buf);
- if (status == TC_SUCCESS)
- {
- status = g_TcFunctions.InstanceTransmitPackets(pt->TcInstance, buffer);
- if (status != TC_SUCCESS)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcInstanceTransmitPackets failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
- }
- }
- else
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCommitNextPacket failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
- }
- g_TcFunctions.PacketsBufferDestroy(buffer);
- if (status != TC_SUCCESS)
- {
- return -1;
- }
- else
- {
- return 0;
- }
- }
- static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
- {
- struct pcap_tc *pt = p->priv;
- TC_STATUS status;
- int n = 0;
- /*
- * Has "pcap_breakloop()" been called?
- */
- if (p->break_loop)
- {
- /*
- * Yes - clear the flag that indicates that it
- * has, and return -2 to indicate that we were
- * told to break out of the loop.
- */
- p->break_loop = 0;
- return -2;
- }
- if (pt->TcPacketsBuffer == NULL)
- {
- status = g_TcFunctions.InstanceReceivePackets(pt->TcInstance, &pt->TcPacketsBuffer);
- if (status != TC_SUCCESS)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error, TcInstanceReceivePackets failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
- return -1;
- }
- }
- while (TRUE)
- {
- struct pcap_pkthdr hdr;
- TC_PACKET_HEADER tcHeader;
- PVOID data;
- ULONG filterResult;
- /*
- * Has "pcap_breakloop()" been called?
- * If so, return immediately - if we haven't read any
- * packets, clear the flag and return -2 to indicate
- * that we were told to break out of the loop, otherwise
- * leave the flag set, so that the *next* call will break
- * out of the loop without having read any packets, and
- * return the number of packets we've processed so far.
- */
- if (p->break_loop)
- {
- if (n == 0)
- {
- p->break_loop = 0;
- return -2;
- }
- else
- {
- return n;
- }
- }
- if (pt->TcPacketsBuffer == NULL)
- {
- break;
- }
- status = g_TcFunctions.PacketsBufferQueryNextPacket(pt->TcPacketsBuffer, &tcHeader, &data);
- if (status == TC_ERROR_END_OF_BUFFER)
- {
- g_TcFunctions.PacketsBufferDestroy(pt->TcPacketsBuffer);
- pt->TcPacketsBuffer = NULL;
- break;
- }
- if (status != TC_SUCCESS)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error, TcPacketsBufferQueryNextPacket failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
- return -1;
- }
- /* No underlaying filtering system. We need to filter on our own */
- if (p->fcode.bf_insns)
- {
- filterResult = bpf_filter(p->fcode.bf_insns, data, tcHeader.Length, tcHeader.CapturedLength);
- if (filterResult == 0)
- {
- continue;
- }
- if (filterResult > tcHeader.CapturedLength)
- {
- filterResult = tcHeader.CapturedLength;
- }
- }
- else
- {
- filterResult = tcHeader.CapturedLength;
- }
- pt->TcAcceptedCount ++;
- hdr.ts.tv_sec = (bpf_u_int32)(tcHeader.Timestamp / (ULONGLONG)(1000 * 1000 * 1000));
- hdr.ts.tv_usec = (bpf_u_int32)((tcHeader.Timestamp % (ULONGLONG)(1000 * 1000 * 1000)) / 1000);
- if (p->linktype == DLT_EN10MB)
- {
- hdr.caplen = filterResult;
- hdr.len = tcHeader.Length;
- (*callback)(user, &hdr, data);
- }
- else
- {
- PPPI_HEADER pPpiHeader = (PPPI_HEADER)pt->PpiPacket;
- PVOID data2 = pPpiHeader + 1;
- pPpiHeader->AggregationField.InterfaceId = TC_PH_FLAGS_RX_PORT_ID(tcHeader.Flags);
- pPpiHeader->Dot3Field.Errors = tcHeader.Errors;
- if (tcHeader.Flags & TC_PH_FLAGS_CHECKSUM)
- {
- pPpiHeader->Dot3Field.Flags = PPI_FLD_802_3_EXT_FLAG_FCS_PRESENT;
- }
- else
- {
- pPpiHeader->Dot3Field.Flags = 0;
- }
- if (filterResult <= MAX_TC_PACKET_SIZE)
- {
- memcpy(data2, data, filterResult);
- hdr.caplen = sizeof(PPI_HEADER) + filterResult;
- hdr.len = sizeof(PPI_HEADER) + tcHeader.Length;
- }
- else
- {
- memcpy(data2, data, MAX_TC_PACKET_SIZE);
- hdr.caplen = sizeof(PPI_HEADER) + MAX_TC_PACKET_SIZE;
- hdr.len = sizeof(PPI_HEADER) + tcHeader.Length;
- }
- (*callback)(user, &hdr, pt->PpiPacket);
- }
- if (++n >= cnt && cnt > 0)
- {
- return n;
- }
- }
- return n;
- }
- static int
- TcStats(pcap_t *p, struct pcap_stat *ps)
- {
- struct pcap_tc *pt = p->priv;
- TC_STATISTICS statistics;
- TC_STATUS status;
- ULONGLONG counter;
- struct pcap_stat s;
- status = g_TcFunctions.InstanceQueryStatistics(pt->TcInstance, &statistics);
- if (status != TC_SUCCESS)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
- return -1;
- }
- memset(&s, 0, sizeof(s));
- status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_TOTAL_RX_PACKETS, &counter);
- if (status != TC_SUCCESS)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
- return -1;
- }
- if (counter <= (ULONGLONG)0xFFFFFFFF)
- {
- s.ps_recv = (ULONG)counter;
- }
- else
- {
- s.ps_recv = 0xFFFFFFFF;
- }
- status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_RX_DROPPED_PACKETS, &counter);
- if (status != TC_SUCCESS)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
- return -1;
- }
- if (counter <= (ULONGLONG)0xFFFFFFFF)
- {
- s.ps_ifdrop = (ULONG)counter;
- s.ps_drop = (ULONG)counter;
- }
- else
- {
- s.ps_ifdrop = 0xFFFFFFFF;
- s.ps_drop = 0xFFFFFFFF;
- }
- #if defined(_WIN32) && defined(ENABLE_REMOTE)
- s.ps_capt = pt->TcAcceptedCount;
- #endif
- *ps = s;
- return 0;
- }
- /*
- * We filter at user level, since the kernel driver does't process the packets
- */
- static int
- TcSetFilter(pcap_t *p, struct bpf_program *fp)
- {
- if(!fp)
- {
- strncpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
- return -1;
- }
- /* Install a user level filter */
- if (install_bpf_program(p, fp) < 0)
- {
- return -1;
- }
- return 0;
- }
- #ifdef _WIN32
- static struct pcap_stat *
- TcStatsEx(pcap_t *p, int *pcap_stat_size)
- {
- struct pcap_tc *pt = p->priv;
- TC_STATISTICS statistics;
- TC_STATUS status;
- ULONGLONG counter;
- *pcap_stat_size = sizeof (p->stat);
- status = g_TcFunctions.InstanceQueryStatistics(pt->TcInstance, &statistics);
- if (status != TC_SUCCESS)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
- return NULL;
- }
- memset(&p->stat, 0, sizeof(p->stat));
- status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_TOTAL_RX_PACKETS, &counter);
- if (status != TC_SUCCESS)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
- return NULL;
- }
- if (counter <= (ULONGLONG)0xFFFFFFFF)
- {
- p->stat.ps_recv = (ULONG)counter;
- }
- else
- {
- p->stat.ps_recv = 0xFFFFFFFF;
- }
- status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_RX_DROPPED_PACKETS, &counter);
- if (status != TC_SUCCESS)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
- return NULL;
- }
- if (counter <= (ULONGLONG)0xFFFFFFFF)
- {
- p->stat.ps_ifdrop = (ULONG)counter;
- p->stat.ps_drop = (ULONG)counter;
- }
- else
- {
- p->stat.ps_ifdrop = 0xFFFFFFFF;
- p->stat.ps_drop = 0xFFFFFFFF;
- }
- #if defined(_WIN32) && defined(ENABLE_REMOTE)
- p->stat.ps_capt = pt->TcAcceptedCount;
- #endif
- return &p->stat;
- }
- /* Set the dimension of the kernel-level capture buffer */
- static int
- TcSetBuff(pcap_t *p, int dim)
- {
- /*
- * XXX turbocap has an internal way of managing buffers.
- * And at the moment it's not configurable, so we just
- * silently ignore the request to set the buffer.
- */
- return 0;
- }
- static int
- TcSetMode(pcap_t *p, int mode)
- {
- if (mode != MODE_CAPT)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Mode %u not supported by TurboCap devices. TurboCap only supports capture.", mode);
- return -1;
- }
- return 0;
- }
- static int
- TcSetMinToCopy(pcap_t *p, int size)
- {
- struct pcap_tc *pt = p->priv;
- TC_STATUS status;
- if (size < 0)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Mintocopy cannot be less than 0.");
- return -1;
- }
- status = g_TcFunctions.InstanceSetFeature(pt->TcInstance, TC_INST_FT_MINTOCOPY, (ULONG)size);
- if (status != TC_SUCCESS)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error setting the mintocopy: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
- }
- return 0;
- }
- static HANDLE
- TcGetReceiveWaitHandle(pcap_t *p)
- {
- struct pcap_tc *pt = p->priv;
- return g_TcFunctions.InstanceGetReceiveWaitHandle(pt->TcInstance);
- }
- static int
- TcOidGetRequest(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_, size_t *lenp _U_)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "An OID get request cannot be performed on a TurboCap device");
- return PCAP_ERROR;
- }
- static int
- TcOidSetRequest(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_,
- size_t *lenp _U_)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "An OID set request cannot be performed on a TurboCap device");
- return PCAP_ERROR;
- }
- static u_int
- TcSendqueueTransmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Packets cannot be bulk transmitted on a TurboCap device");
- return 0;
- }
- static int
- TcSetUserBuffer(pcap_t *p, int size _U_)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "The user buffer cannot be set on a TurboCap device");
- return -1;
- }
- static int
- TcLiveDump(pcap_t *p, char *filename _U_, int maxsize _U_, int maxpacks _U_)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Live packet dumping cannot be performed on a TurboCap device");
- return -1;
- }
- static int
- TcLiveDumpEnded(pcap_t *p, int sync _U_)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Live packet dumping cannot be performed on a TurboCap device");
- return -1;
- }
- static PAirpcapHandle
- TcGetAirPcapHandle(pcap_t *p _U_)
- {
- return NULL;
- }
- #endif
|