libpcap  1.10.1
About: libpcap is a packet filter library used by tools like tcpdump.
  Fossies Dox: libpcap-1.10.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

pcap-tc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 CACE Technologies, Davis (California)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of CACE Technologies nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  */
31 
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35 
36 #include <pcap.h>
37 #include <pcap-int.h>
38 
39 #include "pcap-tc.h"
40 
41 #include <malloc.h>
42 #include <memory.h>
43 #include <string.h>
44 #include <errno.h>
45 
46 #ifdef _WIN32
47 #include <tchar.h>
48 #endif
49 
50 typedef TC_STATUS (TC_CALLCONV *TcFcnQueryPortList) (PTC_PORT *ppPorts, PULONG pLength);
51 typedef TC_STATUS (TC_CALLCONV *TcFcnFreePortList) (TC_PORT *pPorts);
52 
53 typedef PCHAR (TC_CALLCONV *TcFcnStatusGetString) (TC_STATUS status);
54 
55 typedef PCHAR (TC_CALLCONV *TcFcnPortGetName) (TC_PORT port);
56 typedef PCHAR (TC_CALLCONV *TcFcnPortGetDescription) (TC_PORT port);
57 
58 typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceOpenByName) (PCHAR name, PTC_INSTANCE pInstance);
59 typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceClose) (TC_INSTANCE instance);
60 typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceSetFeature) (TC_INSTANCE instance, ULONG feature, ULONG value);
61 typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceQueryFeature) (TC_INSTANCE instance, ULONG feature, PULONG pValue);
62 typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceReceivePackets) (TC_INSTANCE instance, PTC_PACKETS_BUFFER pBuffer);
63 typedef HANDLE (TC_CALLCONV *TcFcnInstanceGetReceiveWaitHandle) (TC_INSTANCE instance);
64 typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceTransmitPackets) (TC_INSTANCE instance, TC_PACKETS_BUFFER pBuffer);
65 typedef TC_STATUS (TC_CALLCONV *TcFcnInstanceQueryStatistics) (TC_INSTANCE instance, PTC_STATISTICS pStatistics);
66 
67 typedef TC_STATUS (TC_CALLCONV *TcFcnPacketsBufferCreate) (ULONG size, PTC_PACKETS_BUFFER pBuffer);
68 typedef VOID (TC_CALLCONV *TcFcnPacketsBufferDestroy) (TC_PACKETS_BUFFER buffer);
69 typedef TC_STATUS (TC_CALLCONV *TcFcnPacketsBufferQueryNextPacket)(TC_PACKETS_BUFFER buffer, PTC_PACKET_HEADER pHeader, PVOID *ppData);
70 typedef TC_STATUS (TC_CALLCONV *TcFcnPacketsBufferCommitNextPacket)(TC_PACKETS_BUFFER buffer, PTC_PACKET_HEADER pHeader, PVOID pData);
71 
72 typedef VOID (TC_CALLCONV *TcFcnStatisticsDestroy) (TC_STATISTICS statistics);
73 typedef TC_STATUS (TC_CALLCONV *TcFcnStatisticsUpdate) (TC_STATISTICS statistics);
74 typedef TC_STATUS (TC_CALLCONV *TcFcnStatisticsQueryValue) (TC_STATISTICS statistics, ULONG counterId, PULONGLONG pValue);
75 
76 typedef enum LONG
77 {
82 }
84 
85 
86 typedef struct _TC_FUNCTIONS
87 {
89 #ifdef _WIN32
90  HMODULE hTcApiDllHandle;
91 #endif
95 
98 
104 #ifdef _WIN32
105  TcFcnInstanceGetReceiveWaitHandle InstanceGetReceiveWaitHandle;
106 #endif
109 
114 
118 }
120 
121 static pcap_if_t* TcCreatePcapIfFromPort(TC_PORT port);
122 static int TcSetDatalink(pcap_t *p, int dlt);
123 static int TcGetNonBlock(pcap_t *p);
124 static int TcSetNonBlock(pcap_t *p, int nonblock);
125 static void TcCleanup(pcap_t *p);
126 static int TcInject(pcap_t *p, const void *buf, int size);
127 static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user);
128 static int TcStats(pcap_t *p, struct pcap_stat *ps);
129 #ifdef _WIN32
130 static struct pcap_stat *TcStatsEx(pcap_t *p, int *pcap_stat_size);
131 static int TcSetBuff(pcap_t *p, int dim);
132 static int TcSetMode(pcap_t *p, int mode);
133 static int TcSetMinToCopy(pcap_t *p, int size);
134 static HANDLE TcGetReceiveWaitHandle(pcap_t *p);
135 static int TcOidGetRequest(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp);
136 static int TcOidSetRequest(pcap_t *p, bpf_u_int32 oid, const void *data, size_t *lenp);
137 static u_int TcSendqueueTransmit(pcap_t *p, pcap_send_queue *queue, int sync);
138 static int TcSetUserBuffer(pcap_t *p, int size);
139 static int TcLiveDump(pcap_t *p, char *filename, int maxsize, int maxpacks);
140 static int TcLiveDumpEnded(pcap_t *p, int sync);
141 static PAirpcapHandle TcGetAirPcapHandle(pcap_t *p);
142 #endif
143 
144 #ifdef _WIN32
146 {
147  TC_API_UNLOADED, /* LoadStatus */
148  NULL, /* hTcApiDllHandle */
149  NULL, /* QueryPortList */
150  NULL, /* FreePortList */
151  NULL, /* StatusGetString */
152  NULL, /* PortGetName */
153  NULL, /* PortGetDescription */
154  NULL, /* InstanceOpenByName */
155  NULL, /* InstanceClose */
156  NULL, /* InstanceSetFeature */
157  NULL, /* InstanceQueryFeature */
158  NULL, /* InstanceReceivePackets */
159  NULL, /* InstanceGetReceiveWaitHandle */
160  NULL, /* InstanceTransmitPackets */
161  NULL, /* InstanceQueryStatistics */
162  NULL, /* PacketsBufferCreate */
163  NULL, /* PacketsBufferDestroy */
164  NULL, /* PacketsBufferQueryNextPacket */
165  NULL, /* PacketsBufferCommitNextPacket */
166  NULL, /* StatisticsDestroy */
167  NULL, /* StatisticsUpdate */
168  NULL /* StatisticsQueryValue */
169 };
170 #else
172 {
173  TC_API_LOADED, /* LoadStatus */
174  TcQueryPortList,
175  TcFreePortList,
176  TcStatusGetString,
177  TcPortGetName,
178  TcPortGetDescription,
179  TcInstanceOpenByName,
180  TcInstanceClose,
181  TcInstanceSetFeature,
182  TcInstanceQueryFeature,
183  TcInstanceReceivePackets,
184 #ifdef _WIN32
185  TcInstanceGetReceiveWaitHandle,
186 #endif
187  TcInstanceTransmitPackets,
188  TcInstanceQueryStatistics,
189  TcPacketsBufferCreate,
190  TcPacketsBufferDestroy,
191  TcPacketsBufferQueryNextPacket,
192  TcPacketsBufferCommitNextPacket,
193  TcStatisticsDestroy,
194  TcStatisticsUpdate,
195  TcStatisticsQueryValue,
196 };
197 #endif
198 
199 #define MAX_TC_PACKET_SIZE 9500
200 
201 #pragma pack(push, 1)
202 
203 #define PPH_PH_FLAG_PADDING ((UCHAR)0x01)
204 #define PPH_PH_VERSION ((UCHAR)0x00)
205 
206 typedef struct _PPI_PACKET_HEADER
207 {
208  UCHAR PphVersion;
209  UCHAR PphFlags;
210  USHORT PphLength;
211  ULONG PphDlt;
212 }
214 
215 typedef struct _PPI_FIELD_HEADER
216 {
217  USHORT PfhType;
218  USHORT PfhLength;
219 }
221 
222 
223 #define PPI_FIELD_TYPE_AGGREGATION_EXTENSION ((UCHAR)0x08)
224 
226 {
227  ULONG InterfaceId;
228 }
230 
231 
232 #define PPI_FIELD_TYPE_802_3_EXTENSION ((UCHAR)0x09)
233 
234 #define PPI_FLD_802_3_EXT_FLAG_FCS_PRESENT ((ULONG)0x00000001)
235 
237 {
238  ULONG Flags;
239  ULONG Errors;
240 }
242 
243 typedef struct _PPI_HEADER
244 {
250 }
252 #pragma pack(pop)
253 
254 #ifdef _WIN32
255 /*
256  * NOTE: this function should be called by the pcap functions that can theoretically
257  * deal with the Tc library for the first time, namely listing the adapters and
258  * opening one. All the other ones (close, read, write, set parameters) work
259  * on an open instance of TC, so we do not care to call this function
260  */
262 {
263  TC_API_LOAD_STATUS currentStatus;
264 
265  do
266  {
267  currentStatus = InterlockedCompareExchange((LONG*)&g_TcFunctions.LoadStatus, TC_API_LOADING, TC_API_UNLOADED);
268 
269  while(currentStatus == TC_API_LOADING)
270  {
271  currentStatus = InterlockedCompareExchange((LONG*)&g_TcFunctions.LoadStatus, TC_API_LOADING, TC_API_LOADING);
272  Sleep(10);
273  }
274 
275  /*
276  * at this point we are either in the LOADED state, unloaded state (i.e. we are the ones loading everything)
277  * or in cannot load
278  */
279  if(currentStatus == TC_API_LOADED)
280  {
281  return TC_API_LOADED;
282  }
283 
284  if (currentStatus == TC_API_CANNOT_LOAD)
285  {
286  return TC_API_CANNOT_LOAD;
287  }
288 
289  currentStatus = TC_API_CANNOT_LOAD;
290 
291  g_TcFunctions.hTcApiDllHandle = pcap_load_code("TcApi.dll");
292  if (g_TcFunctions.hTcApiDllHandle == NULL) break;
293 
294  g_TcFunctions.QueryPortList = (TcFcnQueryPortList) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcQueryPortList");
295  g_TcFunctions.FreePortList = (TcFcnFreePortList) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcFreePortList");
296 
297  g_TcFunctions.StatusGetString = (TcFcnStatusGetString) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcStatusGetString");
298 
299  g_TcFunctions.PortGetName = (TcFcnPortGetName) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPortGetName");
300  g_TcFunctions.PortGetDescription = (TcFcnPortGetDescription) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPortGetDescription");
301 
302  g_TcFunctions.InstanceOpenByName = (TcFcnInstanceOpenByName) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceOpenByName");
303  g_TcFunctions.InstanceClose = (TcFcnInstanceClose) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceClose");
304  g_TcFunctions.InstanceSetFeature = (TcFcnInstanceSetFeature) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceSetFeature");
305  g_TcFunctions.InstanceQueryFeature = (TcFcnInstanceQueryFeature) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceQueryFeature");
306  g_TcFunctions.InstanceReceivePackets = (TcFcnInstanceReceivePackets) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceReceivePackets");
307  g_TcFunctions.InstanceGetReceiveWaitHandle = (TcFcnInstanceGetReceiveWaitHandle)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceGetReceiveWaitHandle");
308  g_TcFunctions.InstanceTransmitPackets = (TcFcnInstanceTransmitPackets)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceTransmitPackets");
309  g_TcFunctions.InstanceQueryStatistics = (TcFcnInstanceQueryStatistics)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceQueryStatistics");
310 
311  g_TcFunctions.PacketsBufferCreate = (TcFcnPacketsBufferCreate) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferCreate");
312  g_TcFunctions.PacketsBufferDestroy = (TcFcnPacketsBufferDestroy) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferDestroy");
313  g_TcFunctions.PacketsBufferQueryNextPacket = (TcFcnPacketsBufferQueryNextPacket)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferQueryNextPacket");
314  g_TcFunctions.PacketsBufferCommitNextPacket = (TcFcnPacketsBufferCommitNextPacket)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferCommitNextPacket");
315 
316  g_TcFunctions.StatisticsDestroy = (TcFcnStatisticsDestroy) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcStatisticsDestroy");
317  g_TcFunctions.StatisticsUpdate = (TcFcnStatisticsUpdate) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcStatisticsUpdate");
318  g_TcFunctions.StatisticsQueryValue = (TcFcnStatisticsQueryValue) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcStatisticsQueryValue");
319 
320  if ( g_TcFunctions.QueryPortList == NULL
321  || g_TcFunctions.FreePortList == NULL
322  || g_TcFunctions.StatusGetString == NULL
323  || g_TcFunctions.PortGetName == NULL
326  || g_TcFunctions.InstanceClose == NULL
330  || g_TcFunctions.InstanceGetReceiveWaitHandle == NULL
340  )
341  {
342  break;
343  }
344 
345  /*
346  * everything got loaded, yay!!
347  */
348  currentStatus = TC_API_LOADED;
349  }while(FALSE);
350 
351  if (currentStatus != TC_API_LOADED)
352  {
353  if (g_TcFunctions.hTcApiDllHandle != NULL)
354  {
355  FreeLibrary(g_TcFunctions.hTcApiDllHandle);
356  g_TcFunctions.hTcApiDllHandle = NULL;
357  }
358  }
359 
360  InterlockedExchange((LONG*)&g_TcFunctions.LoadStatus, currentStatus);
361 
362  return currentStatus;
363 }
364 #else
365 // static linking
367 {
368  return TC_API_LOADED;
369 }
370 #endif
371 
372 /*
373  * Private data for capturing on TurboCap devices.
374  */
375 struct pcap_tc {
376  TC_INSTANCE TcInstance;
377  TC_PACKETS_BUFFER TcPacketsBuffer;
379  u_char *PpiPacket;
380 };
381 
382 int
383 TcFindAllDevs(pcap_if_list_t *devlist, char *errbuf)
384 {
385  TC_API_LOAD_STATUS loadStatus;
386  ULONG numPorts;
387  PTC_PORT pPorts = NULL;
388  TC_STATUS status;
389  int result = 0;
390  pcap_if_t *dev;
391  ULONG i;
392 
393  do
394  {
395  loadStatus = LoadTcFunctions();
396 
397  if (loadStatus != TC_API_LOADED)
398  {
399  result = 0;
400  break;
401  }
402 
403  /*
404  * enumerate the ports, and add them to the list
405  */
406  status = g_TcFunctions.QueryPortList(&pPorts, &numPorts);
407 
408  if (status != TC_SUCCESS)
409  {
410  result = 0;
411  break;
412  }
413 
414  for (i = 0; i < numPorts; i++)
415  {
416  /*
417  * transform the port into an entry in the list
418  */
419  dev = TcCreatePcapIfFromPort(pPorts[i]);
420 
421  if (dev != NULL)
422  add_dev(devlist, dev->name, dev->flags, dev->description, errbuf);
423  }
424 
425  if (numPorts > 0)
426  {
427  /*
428  * ignore the result here
429  */
430  status = g_TcFunctions.FreePortList(pPorts);
431  }
432 
433  }while(FALSE);
434 
435  return result;
436 }
437 
439 {
440  CHAR *name;
441  CHAR *description;
442  pcap_if_t *newIf = NULL;
443 
444  newIf = (pcap_if_t*)malloc(sizeof(*newIf));
445  if (newIf == NULL)
446  {
447  return NULL;
448  }
449 
450  memset(newIf, 0, sizeof(*newIf));
451 
453  description = g_TcFunctions.PortGetDescription(port);
454 
455  newIf->name = (char*)malloc(strlen(name) + 1);
456  if (newIf->name == NULL)
457  {
458  free(newIf);
459  return NULL;
460  }
461 
462  newIf->description = (char*)malloc(strlen(description) + 1);
463  if (newIf->description == NULL)
464  {
465  free(newIf->name);
466  free(newIf);
467  return NULL;
468  }
469 
470  strcpy(newIf->name, name);
471  strcpy(newIf->description, description);
472 
473  newIf->addresses = NULL;
474  newIf->next = NULL;
475  newIf->flags = 0;
476 
477  return newIf;
478 
479 }
480 
481 static int
483 {
484  struct pcap_tc *pt = p->priv;
485  TC_STATUS status;
486  ULONG timeout;
487  PPPI_HEADER pPpiHeader;
488 
489  if (p->opt.rfmon)
490  {
491  /*
492  * No monitor mode on Tc cards; they're Ethernet
493  * capture adapters.
494  */
496  }
497 
498  pt->PpiPacket = malloc(sizeof(PPI_HEADER) + MAX_TC_PACKET_SIZE);
499 
500  if (pt->PpiPacket == NULL)
501  {
502  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error allocating memory");
503  return PCAP_ERROR;
504  }
505 
506  /*
507  * Turn a negative snapshot value (invalid), a snapshot value of
508  * 0 (unspecified), or a value bigger than the normal maximum
509  * value, into the maximum allowed value.
510  *
511  * If some application really *needs* a bigger snapshot
512  * length, we should just increase MAXIMUM_SNAPLEN.
513  */
514  if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
516 
517  /*
518  * Initialize the PPI fixed fields
519  */
520  pPpiHeader = (PPPI_HEADER)pt->PpiPacket;
521  pPpiHeader->PacketHeader.PphDlt = DLT_EN10MB;
522  pPpiHeader->PacketHeader.PphLength = sizeof(PPI_HEADER);
523  pPpiHeader->PacketHeader.PphFlags = 0;
524  pPpiHeader->PacketHeader.PphVersion = 0;
525 
528 
531 
533 
534  if (status != TC_SUCCESS)
535  {
536  /* Adapter detected but we are not able to open it. Return failure. */
537  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening TurboCap adapter: %s", g_TcFunctions.StatusGetString(status));
538  return PCAP_ERROR;
539  }
540 
541  p->linktype = DLT_EN10MB;
542  p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
543  /*
544  * If that fails, just leave the list empty.
545  */
546  if (p->dlt_list != NULL) {
547  p->dlt_list[0] = DLT_EN10MB;
548  p->dlt_list[1] = DLT_PPI;
549  p->dlt_count = 2;
550  }
551 
552  /*
553  * ignore promiscuous mode
554  * p->opt.promisc
555  */
556 
557 
558  /*
559  * ignore all the buffer sizes
560  */
561 
562  /*
563  * enable reception
564  */
565  status = g_TcFunctions.InstanceSetFeature(pt->TcInstance, TC_INST_FT_RX_STATUS, 1);
566 
567  if (status != TC_SUCCESS)
568  {
569  snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error enabling reception on a TurboCap instance: %s", g_TcFunctions.StatusGetString(status));
570  goto bad;
571  }
572 
573  /*
574  * enable transmission
575  */
576  status = g_TcFunctions.InstanceSetFeature(pt->TcInstance, TC_INST_FT_TX_STATUS, 1);
577  /*
578  * Ignore the error here.
579  */
580 
581  p->inject_op = TcInject;
582  /*
583  * if the timeout is -1, it means immediate return, no timeout
584  * if the timeout is 0, it means INFINITE
585  */
586 
587  if (p->opt.timeout == 0)
588  {
589  timeout = 0xFFFFFFFF;
590  }
591  else
592  if (p->opt.timeout < 0)
593  {
594  /*
595  * we insert a minimal timeout here
596  */
597  timeout = 10;
598  }
599  else
600  {
601  timeout = p->opt.timeout;
602  }
603 
604  status = g_TcFunctions.InstanceSetFeature(pt->TcInstance, TC_INST_FT_READ_TIMEOUT, timeout);
605 
606  if (status != TC_SUCCESS)
607  {
608  snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error setting the read timeout a TurboCap instance: %s", g_TcFunctions.StatusGetString(status));
609  goto bad;
610  }
611 
612  p->read_op = TcRead;
614  p->setdirection_op = NULL; /* Not implemented. */
618  p->stats_op = TcStats;
619 #ifdef _WIN32
620  p->stats_ex_op = TcStatsEx;
621  p->setbuff_op = TcSetBuff;
622  p->setmode_op = TcSetMode;
623  p->setmintocopy_op = TcSetMinToCopy;
624  p->getevent_op = TcGetReceiveWaitHandle;
625  p->oid_get_request_op = TcOidGetRequest;
626  p->oid_set_request_op = TcOidSetRequest;
627  p->sendqueue_transmit_op = TcSendqueueTransmit;
628  p->setuserbuffer_op = TcSetUserBuffer;
629  p->live_dump_op = TcLiveDump;
630  p->live_dump_ended_op = TcLiveDumpEnded;
631  p->get_airpcap_handle_op = TcGetAirPcapHandle;
632 #else
633  p->selectable_fd = -1;
634 #endif
635 
636  p->cleanup_op = TcCleanup;
637 
638  return 0;
639 bad:
640  TcCleanup(p);
641  return PCAP_ERROR;
642 }
643 
644 pcap_t *
645 TcCreate(const char *device, char *ebuf, int *is_ours)
646 {
647  ULONG numPorts;
648  PTC_PORT pPorts = NULL;
649  TC_STATUS status;
650  int is_tc;
651  ULONG i;
652  pcap_t *p;
653 
655  {
656  /*
657  * XXX - report this as an error rather than as
658  * "not a TurboCap device"?
659  */
660  *is_ours = 0;
661  return NULL;
662  }
663 
664  /*
665  * enumerate the ports, and add them to the list
666  */
667  status = g_TcFunctions.QueryPortList(&pPorts, &numPorts);
668 
669  if (status != TC_SUCCESS)
670  {
671  /*
672  * XXX - report this as an error rather than as
673  * "not a TurboCap device"?
674  */
675  *is_ours = 0;
676  return NULL;
677  }
678 
679  is_tc = FALSE;
680  for (i = 0; i < numPorts; i++)
681  {
682  if (strcmp(g_TcFunctions.PortGetName(pPorts[i]), device) == 0)
683  {
684  is_tc = TRUE;
685  break;
686  }
687  }
688 
689  if (numPorts > 0)
690  {
691  /*
692  * ignore the result here
693  */
694  (void)g_TcFunctions.FreePortList(pPorts);
695  }
696 
697  if (!is_tc)
698  {
699  *is_ours = 0;
700  return NULL;
701  }
702 
703  /* OK, it's probably ours. */
704  *is_ours = 1;
705 
706  p = PCAP_CREATE_COMMON(ebuf, struct pcap_tc);
707  if (p == NULL)
708  return NULL;
709 
710  p->activate_op = TcActivate;
711  /*
712  * Set these up front, so that, even if our client tries
713  * to set non-blocking mode before we're activated, or
714  * query the state of non-blocking mode, they get an error,
715  * rather than having the non-blocking mode option set
716  * for use later.
717  */
720  return p;
721 }
722 
723 static int TcSetDatalink(pcap_t *p, int dlt)
724 {
725  /*
726  * We don't have to do any work here; pcap_set_datalink() checks
727  * whether the value is in the list of DLT_ values we
728  * supplied, so we don't have to, and, if it is valid, sets
729  * p->linktype to the new value; we don't have to do anything
730  * in hardware, we just use what's in p->linktype.
731  *
732  * We do have to have a routine, however, so that pcap_set_datalink()
733  * doesn't think we don't support setting the link-layer header
734  * type at all.
735  */
736  return 0;
737 }
738 
739 static int TcGetNonBlock(pcap_t *p)
740 {
742  "Non-blocking mode isn't supported for TurboCap ports");
743  return -1;
744 }
745 
746 static int TcSetNonBlock(pcap_t *p, int nonblock)
747 {
749  "Non-blocking mode isn't supported for TurboCap ports");
750  return -1;
751 }
752 
753 static void TcCleanup(pcap_t *p)
754 {
755  struct pcap_tc *pt = p->priv;
756 
757  if (pt->TcPacketsBuffer != NULL)
758  {
760  pt->TcPacketsBuffer = NULL;
761  }
762  if (pt->TcInstance != NULL)
763  {
764  /*
765  * here we do not check for the error values
766  */
768  pt->TcInstance = NULL;
769  }
770 
771  if (pt->PpiPacket != NULL)
772  {
773  free(pt->PpiPacket);
774  pt->PpiPacket = NULL;
775  }
776 
778 }
779 
780 /* Send a packet to the network */
781 static int TcInject(pcap_t *p, const void *buf, int size)
782 {
783  struct pcap_tc *pt = p->priv;
784  TC_STATUS status;
785  TC_PACKETS_BUFFER buffer;
786  TC_PACKET_HEADER header;
787 
788  if (size >= 0xFFFF)
789  {
790  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: the TurboCap API does not support packets larger than 64k");
791  return -1;
792  }
793 
794  status = g_TcFunctions.PacketsBufferCreate(sizeof(TC_PACKET_HEADER) + TC_ALIGN_USHORT_TO_64BIT((USHORT)size), &buffer);
795 
796  if (status != TC_SUCCESS)
797  {
798  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCreate failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
799  return -1;
800  }
801 
802  /*
803  * we assume that the packet is without the checksum, as common with WinPcap
804  */
805  memset(&header, 0, sizeof(header));
806 
807  header.Length = (USHORT)size;
808  header.CapturedLength = header.Length;
809 
810  status = g_TcFunctions.PacketsBufferCommitNextPacket(buffer, &header, (PVOID)buf);
811 
812  if (status == TC_SUCCESS)
813  {
814  status = g_TcFunctions.InstanceTransmitPackets(pt->TcInstance, buffer);
815 
816  if (status != TC_SUCCESS)
817  {
818  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcInstanceTransmitPackets failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
819  }
820  }
821  else
822  {
823  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCommitNextPacket failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
824  }
825 
827 
828  if (status != TC_SUCCESS)
829  {
830  return -1;
831  }
832  else
833  {
834  return 0;
835  }
836 }
837 
838 static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
839 {
840  struct pcap_tc *pt = p->priv;
841  TC_STATUS status;
842  int n = 0;
843 
844  /*
845  * Has "pcap_breakloop()" been called?
846  */
847  if (p->break_loop)
848  {
849  /*
850  * Yes - clear the flag that indicates that it
851  * has, and return -2 to indicate that we were
852  * told to break out of the loop.
853  */
854  p->break_loop = 0;
855  return -2;
856  }
857 
858  if (pt->TcPacketsBuffer == NULL)
859  {
861  if (status != TC_SUCCESS)
862  {
863  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error, TcInstanceReceivePackets failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
864  return -1;
865  }
866  }
867 
868  while (TRUE)
869  {
870  struct pcap_pkthdr hdr;
871  TC_PACKET_HEADER tcHeader;
872  PVOID data;
873  ULONG filterResult;
874 
875  /*
876  * Has "pcap_breakloop()" been called?
877  * If so, return immediately - if we haven't read any
878  * packets, clear the flag and return -2 to indicate
879  * that we were told to break out of the loop, otherwise
880  * leave the flag set, so that the *next* call will break
881  * out of the loop without having read any packets, and
882  * return the number of packets we've processed so far.
883  */
884  if (p->break_loop)
885  {
886  if (n == 0)
887  {
888  p->break_loop = 0;
889  return -2;
890  }
891  else
892  {
893  return n;
894  }
895  }
896 
897  if (pt->TcPacketsBuffer == NULL)
898  {
899  break;
900  }
901 
902  status = g_TcFunctions.PacketsBufferQueryNextPacket(pt->TcPacketsBuffer, &tcHeader, &data);
903 
904  if (status == TC_ERROR_END_OF_BUFFER)
905  {
907  pt->TcPacketsBuffer = NULL;
908  break;
909  }
910 
911  if (status != TC_SUCCESS)
912  {
913  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error, TcPacketsBufferQueryNextPacket failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
914  return -1;
915  }
916 
917  /* No underlaying filtering system. We need to filter on our own */
918  if (p->fcode.bf_insns)
919  {
920  filterResult = pcap_filter(p->fcode.bf_insns, data, tcHeader.Length, tcHeader.CapturedLength);
921 
922  if (filterResult == 0)
923  {
924  continue;
925  }
926 
927  if (filterResult > tcHeader.CapturedLength)
928  {
929  filterResult = tcHeader.CapturedLength;
930  }
931  }
932  else
933  {
934  filterResult = tcHeader.CapturedLength;
935  }
936 
937  pt->TcAcceptedCount ++;
938 
939  hdr.ts.tv_sec = (bpf_u_int32)(tcHeader.Timestamp / (ULONGLONG)(1000 * 1000 * 1000));
940  hdr.ts.tv_usec = (bpf_u_int32)((tcHeader.Timestamp % (ULONGLONG)(1000 * 1000 * 1000)) / 1000);
941 
942  if (p->linktype == DLT_EN10MB)
943  {
944  hdr.caplen = filterResult;
945  hdr.len = tcHeader.Length;
946  (*callback)(user, &hdr, data);
947  }
948  else
949  {
950  PPPI_HEADER pPpiHeader = (PPPI_HEADER)pt->PpiPacket;
951  PVOID data2 = pPpiHeader + 1;
952 
953  pPpiHeader->AggregationField.InterfaceId = TC_PH_FLAGS_RX_PORT_ID(tcHeader.Flags);
954  pPpiHeader->Dot3Field.Errors = tcHeader.Errors;
955  if (tcHeader.Flags & TC_PH_FLAGS_CHECKSUM)
956  {
958  }
959  else
960  {
961  pPpiHeader->Dot3Field.Flags = 0;
962  }
963 
964  if (filterResult <= MAX_TC_PACKET_SIZE)
965  {
966  memcpy(data2, data, filterResult);
967  hdr.caplen = sizeof(PPI_HEADER) + filterResult;
968  hdr.len = sizeof(PPI_HEADER) + tcHeader.Length;
969  }
970  else
971  {
972  memcpy(data2, data, MAX_TC_PACKET_SIZE);
973  hdr.caplen = sizeof(PPI_HEADER) + MAX_TC_PACKET_SIZE;
974  hdr.len = sizeof(PPI_HEADER) + tcHeader.Length;
975  }
976 
977  (*callback)(user, &hdr, pt->PpiPacket);
978 
979  }
980 
981  if (++n >= cnt && cnt > 0)
982  {
983  return n;
984  }
985  }
986 
987  return n;
988 }
989 
990 static int
991 TcStats(pcap_t *p, struct pcap_stat *ps)
992 {
993  struct pcap_tc *pt = p->priv;
994  TC_STATISTICS statistics;
995  TC_STATUS status;
996  ULONGLONG counter;
997  struct pcap_stat s;
998 
999  status = g_TcFunctions.InstanceQueryStatistics(pt->TcInstance, &statistics);
1000 
1001  if (status != TC_SUCCESS)
1002  {
1003  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
1004  return -1;
1005  }
1006 
1007  memset(&s, 0, sizeof(s));
1008 
1009  status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_TOTAL_RX_PACKETS, &counter);
1010  if (status != TC_SUCCESS)
1011  {
1012  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
1013  return -1;
1014  }
1015  if (counter <= (ULONGLONG)0xFFFFFFFF)
1016  {
1017  s.ps_recv = (ULONG)counter;
1018  }
1019  else
1020  {
1021  s.ps_recv = 0xFFFFFFFF;
1022  }
1023 
1024  status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_RX_DROPPED_PACKETS, &counter);
1025  if (status != TC_SUCCESS)
1026  {
1027  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
1028  return -1;
1029  }
1030  if (counter <= (ULONGLONG)0xFFFFFFFF)
1031  {
1032  s.ps_ifdrop = (ULONG)counter;
1033  s.ps_drop = (ULONG)counter;
1034  }
1035  else
1036  {
1037  s.ps_ifdrop = 0xFFFFFFFF;
1038  s.ps_drop = 0xFFFFFFFF;
1039  }
1040 
1041 #if defined(_WIN32) && defined(ENABLE_REMOTE)
1042  s.ps_capt = pt->TcAcceptedCount;
1043 #endif
1044  *ps = s;
1045 
1046  return 0;
1047 }
1048 
1049 
1050 #ifdef _WIN32
1051 static struct pcap_stat *
1052 TcStatsEx(pcap_t *p, int *pcap_stat_size)
1053 {
1054  struct pcap_tc *pt = p->priv;
1055  TC_STATISTICS statistics;
1056  TC_STATUS status;
1057  ULONGLONG counter;
1058 
1059  *pcap_stat_size = sizeof (p->stat);
1060 
1061  status = g_TcFunctions.InstanceQueryStatistics(pt->TcInstance, &statistics);
1062 
1063  if (status != TC_SUCCESS)
1064  {
1065  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
1066  return NULL;
1067  }
1068 
1069  memset(&p->stat, 0, sizeof(p->stat));
1070 
1071  status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_TOTAL_RX_PACKETS, &counter);
1072  if (status != TC_SUCCESS)
1073  {
1074  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
1075  return NULL;
1076  }
1077  if (counter <= (ULONGLONG)0xFFFFFFFF)
1078  {
1079  p->stat.ps_recv = (ULONG)counter;
1080  }
1081  else
1082  {
1083  p->stat.ps_recv = 0xFFFFFFFF;
1084  }
1085 
1086  status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_RX_DROPPED_PACKETS, &counter);
1087  if (status != TC_SUCCESS)
1088  {
1089  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
1090  return NULL;
1091  }
1092  if (counter <= (ULONGLONG)0xFFFFFFFF)
1093  {
1094  p->stat.ps_ifdrop = (ULONG)counter;
1095  p->stat.ps_drop = (ULONG)counter;
1096  }
1097  else
1098  {
1099  p->stat.ps_ifdrop = 0xFFFFFFFF;
1100  p->stat.ps_drop = 0xFFFFFFFF;
1101  }
1102 
1103 #if defined(_WIN32) && defined(ENABLE_REMOTE)
1104  p->stat.ps_capt = pt->TcAcceptedCount;
1105 #endif
1106 
1107  return &p->stat;
1108 }
1109 
1110 /* Set the dimension of the kernel-level capture buffer */
1111 static int
1112 TcSetBuff(pcap_t *p, int dim)
1113 {
1114  /*
1115  * XXX turbocap has an internal way of managing buffers.
1116  * And at the moment it's not configurable, so we just
1117  * silently ignore the request to set the buffer.
1118  */
1119  return 0;
1120 }
1121 
1122 static int
1123 TcSetMode(pcap_t *p, int mode)
1124 {
1125  if (mode != MODE_CAPT)
1126  {
1127  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Mode %u not supported by TurboCap devices. TurboCap only supports capture.", mode);
1128  return -1;
1129  }
1130 
1131  return 0;
1132 }
1133 
1134 static int
1135 TcSetMinToCopy(pcap_t *p, int size)
1136 {
1137  struct pcap_tc *pt = p->priv;
1138  TC_STATUS status;
1139 
1140  if (size < 0)
1141  {
1142  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Mintocopy cannot be less than 0.");
1143  return -1;
1144  }
1145 
1146  status = g_TcFunctions.InstanceSetFeature(pt->TcInstance, TC_INST_FT_MINTOCOPY, (ULONG)size);
1147 
1148  if (status != TC_SUCCESS)
1149  {
1150  snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error setting the mintocopy: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
1151  }
1152 
1153  return 0;
1154 }
1155 
1156 static HANDLE
1157 TcGetReceiveWaitHandle(pcap_t *p)
1158 {
1159  struct pcap_tc *pt = p->priv;
1160 
1161  return g_TcFunctions.InstanceGetReceiveWaitHandle(pt->TcInstance);
1162 }
1163 
1164 static int
1165 TcOidGetRequest(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_, size_t *lenp _U_)
1166 {
1168  "An OID get request cannot be performed on a TurboCap device");
1169  return PCAP_ERROR;
1170 }
1171 
1172 static int
1173 TcOidSetRequest(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_,
1174  size_t *lenp _U_)
1175 {
1177  "An OID set request cannot be performed on a TurboCap device");
1178  return PCAP_ERROR;
1179 }
1180 
1181 static u_int
1182 TcSendqueueTransmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_)
1183 {
1185  "Packets cannot be bulk transmitted on a TurboCap device");
1186  return 0;
1187 }
1188 
1189 static int
1190 TcSetUserBuffer(pcap_t *p, int size _U_)
1191 {
1193  "The user buffer cannot be set on a TurboCap device");
1194  return -1;
1195 }
1196 
1197 static int
1198 TcLiveDump(pcap_t *p, char *filename _U_, int maxsize _U_, int maxpacks _U_)
1199 {
1201  "Live packet dumping cannot be performed on a TurboCap device");
1202  return -1;
1203 }
1204 
1205 static int
1206 TcLiveDumpEnded(pcap_t *p, int sync _U_)
1207 {
1209  "Live packet dumping cannot be performed on a TurboCap device");
1210  return -1;
1211 }
1212 
1213 static PAirpcapHandle
1214 TcGetAirPcapHandle(pcap_t *p _U_)
1215 {
1216  return NULL;
1217 }
1218 #endif
u_int bpf_u_int32
Definition: bpf.h:98
u_int pcap_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen, u_int buflen)
Definition: bpf_filter.c:391
#define DLT_EN10MB
Definition: dlt.h:63
#define DLT_PPI
Definition: dlt.h:722
int install_bpf_program(pcap_t *p, struct bpf_program *fp)
Definition: optimize.c:2939
int snprintf(char *, size_t, const char *,...)
void sync(void)
LONG
Definition: pcap-airpcap.c:91
#define TRUE
Definition: pcap-dos.h:28
#define FALSE
Definition: pcap-dos.h:29
#define _U_
Definition: pcap-dos.h:93
#define MAXIMUM_SNAPLEN
Definition: pcap-int.h:131
pcap_if_t * add_dev(pcap_if_list_t *, const char *, bpf_u_int32, const char *, char *)
Definition: pcap.c:1308
void pcap_cleanup_live_common(pcap_t *)
Definition: pcap.c:3987
#define PCAP_CREATE_COMMON(ebuf, type)
Definition: pcap-int.h:474
static void TcCleanup(pcap_t *p)
Definition: pcap-tc.c:753
TC_STATUS(TC_CALLCONV * TcFcnPacketsBufferCommitNextPacket)(TC_PACKETS_BUFFER buffer, PTC_PACKET_HEADER pHeader, PVOID pData)
Definition: pcap-tc.c:70
struct _TC_FUNCTIONS TC_FUNCTIONS
TC_STATUS(TC_CALLCONV * TcFcnQueryPortList)(PTC_PORT *ppPorts, PULONG pLength)
Definition: pcap-tc.c:50
TC_STATUS(TC_CALLCONV * TcFcnFreePortList)(TC_PORT *pPorts)
Definition: pcap-tc.c:51
#define PPI_FLD_802_3_EXT_FLAG_FCS_PRESENT
Definition: pcap-tc.c:234
static int TcSetNonBlock(pcap_t *p, int nonblock)
Definition: pcap-tc.c:746
TC_STATUS(TC_CALLCONV * TcFcnStatisticsQueryValue)(TC_STATISTICS statistics, ULONG counterId, PULONGLONG pValue)
Definition: pcap-tc.c:74
TC_API_LOAD_STATUS LoadTcFunctions(void)
Definition: pcap-tc.c:366
static pcap_if_t * TcCreatePcapIfFromPort(TC_PORT port)
Definition: pcap-tc.c:438
static int TcSetDatalink(pcap_t *p, int dlt)
Definition: pcap-tc.c:723
static int TcInject(pcap_t *p, const void *buf, int size)
Definition: pcap-tc.c:781
pcap_t * TcCreate(const char *device, char *ebuf, int *is_ours)
Definition: pcap-tc.c:645
struct _PPI_FIELD_802_3_EXTENSION * PPPI_FIELD_802_3_EXTENSION
enum LONG TC_API_LOAD_STATUS
struct _PPI_HEADER * PPPI_HEADER
TC_FUNCTIONS g_TcFunctions
Definition: pcap-tc.c:171
TC_STATUS(TC_CALLCONV * TcFcnPacketsBufferCreate)(ULONG size, PTC_PACKETS_BUFFER pBuffer)
Definition: pcap-tc.c:67
struct _PPI_FIELD_AGGREGATION_EXTENSION PPI_FIELD_AGGREGATION_EXTENSION
struct _PPI_FIELD_802_3_EXTENSION PPI_FIELD_802_3_EXTENSION
TC_STATUS(TC_CALLCONV * TcFcnInstanceTransmitPackets)(TC_INSTANCE instance, TC_PACKETS_BUFFER pBuffer)
Definition: pcap-tc.c:64
static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
Definition: pcap-tc.c:838
static int TcGetNonBlock(pcap_t *p)
Definition: pcap-tc.c:739
TC_STATUS(TC_CALLCONV * TcFcnInstanceQueryStatistics)(TC_INSTANCE instance, PTC_STATISTICS pStatistics)
Definition: pcap-tc.c:65
struct _PPI_PACKET_HEADER * PPPI_PACKET_HEADER
TC_STATUS(TC_CALLCONV * TcFcnInstanceSetFeature)(TC_INSTANCE instance, ULONG feature, ULONG value)
Definition: pcap-tc.c:60
PCHAR(TC_CALLCONV * TcFcnPortGetDescription)(TC_PORT port)
Definition: pcap-tc.c:56
struct _PPI_FIELD_HEADER PPI_FIELD_HEADER
struct _PPI_HEADER PPI_HEADER
struct _PPI_FIELD_AGGREGATION_EXTENSION * PPPI_FIELD_AGGREGATION_EXTENSION
struct _PPI_FIELD_HEADER * PPPI_FIELD_HEADER
#define PPI_FIELD_TYPE_802_3_EXTENSION
Definition: pcap-tc.c:232
static int TcStats(pcap_t *p, struct pcap_stat *ps)
Definition: pcap-tc.c:991
TC_STATUS(TC_CALLCONV * TcFcnStatisticsUpdate)(TC_STATISTICS statistics)
Definition: pcap-tc.c:73
static int TcActivate(pcap_t *p)
Definition: pcap-tc.c:482
HANDLE(TC_CALLCONV * TcFcnInstanceGetReceiveWaitHandle)(TC_INSTANCE instance)
Definition: pcap-tc.c:63
VOID(TC_CALLCONV * TcFcnPacketsBufferDestroy)(TC_PACKETS_BUFFER buffer)
Definition: pcap-tc.c:68
TC_STATUS(TC_CALLCONV * TcFcnInstanceQueryFeature)(TC_INSTANCE instance, ULONG feature, PULONG pValue)
Definition: pcap-tc.c:61
TC_STATUS(TC_CALLCONV * TcFcnInstanceReceivePackets)(TC_INSTANCE instance, PTC_PACKETS_BUFFER pBuffer)
Definition: pcap-tc.c:62
int TcFindAllDevs(pcap_if_list_t *devlist, char *errbuf)
Definition: pcap-tc.c:383
#define MAX_TC_PACKET_SIZE
Definition: pcap-tc.c:199
TC_STATUS(TC_CALLCONV * TcFcnPacketsBufferQueryNextPacket)(TC_PACKETS_BUFFER buffer, PTC_PACKET_HEADER pHeader, PVOID *ppData)
Definition: pcap-tc.c:69
#define PPI_FIELD_TYPE_AGGREGATION_EXTENSION
Definition: pcap-tc.c:223
TC_STATUS(TC_CALLCONV * TcFcnInstanceClose)(TC_INSTANCE instance)
Definition: pcap-tc.c:59
PCHAR(TC_CALLCONV * TcFcnPortGetName)(TC_PORT port)
Definition: pcap-tc.c:55
@ TC_API_LOADING
Definition: pcap-tc.c:81
@ TC_API_CANNOT_LOAD
Definition: pcap-tc.c:80
@ TC_API_UNLOADED
Definition: pcap-tc.c:78
@ TC_API_LOADED
Definition: pcap-tc.c:79
VOID(TC_CALLCONV * TcFcnStatisticsDestroy)(TC_STATISTICS statistics)
Definition: pcap-tc.c:72
struct _PPI_PACKET_HEADER PPI_PACKET_HEADER
TC_STATUS(TC_CALLCONV * TcFcnInstanceOpenByName)(PCHAR name, PTC_INSTANCE pInstance)
Definition: pcap-tc.c:58
PCHAR(TC_CALLCONV * TcFcnStatusGetString)(TC_STATUS status)
Definition: pcap-tc.c:53
#define PCAP_ERROR_RFMON_NOTSUP
Definition: pcap.h:344
void(* pcap_handler)(u_char *, const struct pcap_pkthdr *, const u_char *)
Definition: pcap.h:330
#define PCAP_ERRBUF_SIZE
Definition: pcap.h:152
#define PCAP_ERROR
Definition: pcap.h:339
static char port[2048+1]
keeps the network port to bind to
Definition: rpcapd.c:88
USHORT PfhType
Definition: pcap-tc.c:217
USHORT PfhLength
Definition: pcap-tc.c:218
PPI_FIELD_802_3_EXTENSION Dot3Field
Definition: pcap-tc.c:249
PPI_FIELD_HEADER Dot3FieldHeader
Definition: pcap-tc.c:248
PPI_FIELD_HEADER AggregationFieldHeader
Definition: pcap-tc.c:246
PPI_FIELD_AGGREGATION_EXTENSION AggregationField
Definition: pcap-tc.c:247
PPI_PACKET_HEADER PacketHeader
Definition: pcap-tc.c:245
USHORT PphLength
Definition: pcap-tc.c:210
TcFcnQueryPortList QueryPortList
Definition: pcap-tc.c:92
TcFcnInstanceReceivePackets InstanceReceivePackets
Definition: pcap-tc.c:103
TcFcnStatusGetString StatusGetString
Definition: pcap-tc.c:94
TcFcnInstanceQueryStatistics InstanceQueryStatistics
Definition: pcap-tc.c:108
TcFcnStatisticsQueryValue StatisticsQueryValue
Definition: pcap-tc.c:117
TcFcnStatisticsDestroy StatisticsDestroy
Definition: pcap-tc.c:115
TcFcnPacketsBufferDestroy PacketsBufferDestroy
Definition: pcap-tc.c:111
TcFcnPortGetName PortGetName
Definition: pcap-tc.c:96
TcFcnInstanceTransmitPackets InstanceTransmitPackets
Definition: pcap-tc.c:107
TcFcnFreePortList FreePortList
Definition: pcap-tc.c:93
TcFcnInstanceQueryFeature InstanceQueryFeature
Definition: pcap-tc.c:102
TcFcnPortGetDescription PortGetDescription
Definition: pcap-tc.c:97
TC_API_LOAD_STATUS LoadStatus
Definition: pcap-tc.c:88
TcFcnPacketsBufferQueryNextPacket PacketsBufferQueryNextPacket
Definition: pcap-tc.c:112
TcFcnInstanceOpenByName InstanceOpenByName
Definition: pcap-tc.c:99
TcFcnStatisticsUpdate StatisticsUpdate
Definition: pcap-tc.c:116
TcFcnPacketsBufferCommitNextPacket PacketsBufferCommitNextPacket
Definition: pcap-tc.c:113
TcFcnInstanceClose InstanceClose
Definition: pcap-tc.c:100
TcFcnPacketsBufferCreate PacketsBufferCreate
Definition: pcap-tc.c:110
TcFcnInstanceSetFeature InstanceSetFeature
Definition: pcap-tc.c:101
struct bpf_insn * bf_insns
Definition: bpf.h:119
Definition: pcap.h:301
char * name
Definition: pcap.h:303
bpf_u_int32 flags
Definition: pcap.h:306
struct pcap_if * next
Definition: pcap.h:302
char * description
Definition: pcap.h:304
struct pcap_addr * addresses
Definition: pcap.h:305
int timeout
Definition: pcap-int.h:147
char * device
Definition: pcap-int.h:146
int rfmon
Definition: pcap-int.h:150
bpf_u_int32 caplen
Definition: pcap.h:247
struct timeval ts
Definition: pcap.h:246
bpf_u_int32 len
Definition: pcap.h:248
u_int ps_drop
Definition: pcap.h:256
u_int ps_recv
Definition: pcap.h:255
u_int ps_ifdrop
Definition: pcap.h:257
TC_PACKETS_BUFFER TcPacketsBuffer
Definition: pcap-tc.c:377
TC_INSTANCE TcInstance
Definition: pcap-tc.c:376
u_char * PpiPacket
Definition: pcap-tc.c:379
ULONG TcAcceptedCount
Definition: pcap-tc.c:378
Definition: pcap-int.h:200
stats_op_t stats_op
Definition: pcap-int.h:320
activate_op_t activate_op
Definition: pcap-int.h:311
setnonblock_op_t setnonblock_op
Definition: pcap-int.h:319
setfilter_op_t setfilter_op
Definition: pcap-int.h:315
sig_atomic_t break_loop
Definition: pcap-int.h:225
int dlt_count
Definition: pcap-int.h:299
void * priv
Definition: pcap-int.h:227
getnonblock_op_t getnonblock_op
Definition: pcap-int.h:318
u_int * dlt_list
Definition: pcap-int.h:300
read_op_t read_op
Definition: pcap-int.h:204
int snapshot
Definition: pcap-int.h:247
cleanup_op_t cleanup_op
Definition: pcap-int.h:346
setdirection_op_t setdirection_op
Definition: pcap-int.h:316
inject_op_t inject_op
Definition: pcap-int.h:313
struct bpf_program fcode
Definition: pcap-int.h:293
set_datalink_op_t set_datalink_op
Definition: pcap-int.h:317
char errbuf[256+1]
Definition: pcap-int.h:295
int linktype
Definition: pcap-int.h:248
int selectable_fd
Definition: pcap-int.h:274
struct pcap_opt opt
Definition: pcap-int.h:254