mapinapatechdrv.c 21.8 KB
Newer Older
's avatar
committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <pthread.h>
#include <pcap.h>
#include <sys/mman.h>
#include <sys/shm.h>
#include <netinet/in.h>
#include "mapi.h"
#include "mapidrv.h"
#include "mapidlib.h"

#include "mapidevices.h"
#include "flist.h"
#include "debug.h"
#include "mapi_errors.h"

#ifdef PRECLASSIFICATION
#include "mapidflib.h"
#include "parseconf.h"
#include "printfstring.h"
#include "bpfcompiler.h"
#endif

#define bool_t int

/* The NTCommonInterface.h header provides the interface definitions
 *  * for the Napatech NTCI library */
#include <NTCommonInterface.h>

/* These headers are needed when capturing traffic */
#include <packetfeedstructure.h>
#include <packetdescriptor.h>
#include <NTCI_packetfeed.h>
#include <NTCI_errorcode.h>
#include <NTCI_capabilities.h>
#include <capabilitiesstructure.h>
#include <NTCI_packetclassification.h>
#include <packetclassificationstructure.h>
#include <extendeddescriptor05.h>

typedef struct napatech_instance {
  pthread_attr_t th_attr;
  pthread_t th_proc;
  handle_t napatechhandle;
  uint32_t packetfeedhandle;
  uint32_t channelsBitmask;
  FeedBufferInformationType1_t bufferInfo;
  int eventset;
  short skip;
  void *buf;
  int file;
  char *name;
  int id;
  mapi_offline_device_status_t *offline_status;
  mapid_hw_info_t hwinfo;
  mapidlib_instance_t mapidlib;
  u_int8_t *gpp_base;
} napatech_instance_t;

__attribute__ ((constructor)) void init ();
__attribute__ ((destructor))  void fini ();

static flist_t *devlist;

/* for mapidlib errorcode */
75
int
's avatar
committed
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
mapidrv_get_errno(int devid,int fd)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_get_errno"));

  napatech_instance_t *i=flist_get(devlist,devid);
  return mapid_get_errno(&i->mapidlib,fd);
}

#ifdef WITH_AUTHENTICATION
int mapidrv_authenticate(int devid, int fd, char *vo)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_authenticate"));
	napatech_instance_t *i = flist_get(devlist, devid);
	return mapid_authenticate(&i->mapidlib, fd, vo);
}
#endif

int
mapidrv_apply_function (int devid,int fd, int flags, char* function, mapiFunctArg *fargs)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_apply_function"));
97

's avatar
committed
98 99 100
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_apply_function; devid = %d; fd = %d; function = %s", devid, fd, function));

  napatech_instance_t *i=flist_get(devlist,devid);
101

's avatar
committed
102
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_apply_function; &i = %x", (int)i));
103

's avatar
committed
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_apply_function; &i->mapidlib = %x", (int)(&i->mapidlib)));

  int _flags = flags;

  return mapid_apply_function(&i->mapidlib, fd, function, fargs, _flags);
}

int mapidrv_add_device(const char *devname, int file,int devid, global_function_list_t *gflist,void *olstatus)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_add_device"));

  napatech_instance_t *i=malloc(sizeof(napatech_instance_t));

  i->napatechhandle = NULL;
  i->packetfeedhandle = 0;

  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_add_device; devname: %s", devname));
  i->name=strdup(devname);
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_add_device; i->name: %s", i->name));
  i->id=devid;
  // i->dagfd=-1;
  i->file=file;
  // i->th_proc=0;
  i->hwinfo.offline=0;
  i->hwinfo.devfd=i->napatechhandle;
  i->hwinfo.gflist=gflist;
  i->hwinfo.pkt_drop=0;
  i->offline_status = olstatus;
  if(devid<0)
    i->hwinfo.offline = 1;
134

's avatar
committed
135 136 137 138 139 140 141 142 143 144 145 146 147 148
  DEBUG_CMD(Debug_Message("Added device %d: %s", devid, devname));

  flist_append(devlist,devid,i);
  mapid_init(&i->mapidlib);
  return 0;
}

int mapidrv_delete_device(int devid)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_delete_device"));

  napatech_instance_t *i=flist_remove(devlist,devid);

  uint32_t result;
149

's avatar
committed
150 151 152 153 154 155
  if (i!=NULL) {
    int err=0;

    if (i->th_proc && pthread_equal(i->th_proc, pthread_self())==0) {
      DEBUG_CMD(Debug_Message("Calling thread != th_proc (%lu != %lu), cancelling", i->th_proc, pthread_self()));
      fflush(stdout);
156

's avatar
committed
157 158 159 160 161
      if ((err=pthread_cancel(i->th_proc))!=0) {
        if (!(i->hwinfo.offline==1 && err==ESRCH)) {
          DEBUG_CMD(Debug_Message("WARNING: Could not cancel thread for devid %d (%s)", devid, strerror(err)));
          fflush(stdout);
        }
162
      }
's avatar
committed
163 164 165
    }

    if(i->napatechhandle != NULL) {
's avatar
committed
166 167 168 169
      if((result = NTCI_StopPacketFeed(i->napatechhandle, i->packetfeedhandle)) != NTCI_ERRCODE_SUCCESS) {
        DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_delete_device; Failed to stop packet feed! (%i)\n", result));
      }

170
      if((result = NTCI_DestroyPacketFeed(i->napatechhandle, i->packetfeedhandle)) != NTCI_ERRCODE_SUCCESS) {
's avatar
committed
171 172 173 174 175 176 177 178 179 180 181 182 183
        DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_delete_device; Failed to destroy packet feed! (%i)\n", result));
      }
      NTCI_CloseCard(i->napatechhandle);
      DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_delete_device; Napatech device closed"));
    }

    mapid_destroy(&i->mapidlib);
    free(i->name);
    if(i->offline_status != NULL)
      *(i->offline_status) = DEVICE_DELETED;

    free(i);
  }
184

's avatar
committed
185 186 187
  return 0;
}

188
static unsigned
's avatar
committed
189 190 191 192 193 194 195 196 197 198
// process_pkts(void *buf,unsigned len, napatech_instance_t *i)
process_pkts(BufferInformationSectionType1_t* bufferInformation, napatech_instance_t *i)
{
  /* DEBUG_CMD(Debug_Message("napatechdrv: process_pkts"));
  DEBUG_CMD(Debug_Message("napatechdrv: process_pkts; packet count: %d", bufferInformation->numDescriptorsAvailable)); */

  mapid_pkthdr_t mhdr;

  uint32_t packet = 0;
  uint8_t *frame = NULL;
199

's avatar
committed
200
  PacketDescriptorType2_t *descriptor = (PacketDescriptorType2_t *)(((uint8_t*)(i->bufferInfo.bufferBaseAddress)) + bufferInformation->sectionOffset);
201

's avatar
committed
202 203 204 205 206 207
  // pNetFlow->flowStat.uiTotalDropped+=bufferInformation.numDroppedFrames;

  if(descriptor->ExtensionFormat == EXTENDED_DESCRIPTOR_05_TYPE) {
    for(packet=0; packet < bufferInformation->numDescriptorsAvailable; packet++) {
      i->hwinfo.pkts++;

208 209
      PacketExtDescriptorType05_t *pExtDescr = (PacketExtDescriptorType05_t*)(((uint8_t*)descriptor) + sizeof(PacketDescriptorType2_t));

's avatar
committed
210
      frame = ((uint8_t*)descriptor);
Arne Øslebø's avatar
Arne Øslebø committed
211 212
      
      
213

Arne Øslebø's avatar
Arne Øslebø committed
214
      mhdr.ts = ((4503599*(descriptor->Timestamp>>32))>>20)|(descriptor->Timestamp<<32) ;
215 216 217
      mhdr.ifindex = descriptor->Channel;
      mhdr.caplen = descriptor->StoredLength;
      mhdr.wlen = descriptor->WireLength;
's avatar
committed
218

219 220 221 222 223 224 225 226 227 228 229 230 231
			// Layer 2 type. (0:EtherII, 1:LLC, 2:SNAP, 3:Novell RAW)
			switch(pExtDescr->l2Type) {
				case 0:
					i->hwinfo.link_type = DLT_EN10MB;
					break;
				case 1:
				case 2:
				case 3:
				default:
					DEBUG_CMD(Debug_Message("WARNING: Unexpected Layer 2 type (%d) in Extended Packet Descriptor\n", pExtDescr->l2Type));
					break;
			}

232
      // ? TODO - modify third argument to pass test_packet_read
's avatar
committed
233
      mapid_process_pkt(&i->mapidlib, (unsigned char*)frame, frame + sizeof(PacketDescriptorType2_t) + (descriptor->ExtensionLength << 3), &mhdr);
's avatar
committed
234 235 236 237 238 239 240 241

      /* Avance to the next packet. */
      descriptor = (PacketDescriptorType2_t*)((uint8_t*)descriptor + descriptor->StoredLength);
    }
  } else {
    for(packet=0; packet < bufferInformation->numDescriptorsAvailable; packet++) {
      i->hwinfo.pkts++;

's avatar
committed
242
      frame = ((uint8_t*)descriptor);
's avatar
committed
243

Arne Øslebø's avatar
Arne Øslebø committed
244 245
      //Todo: temporary solution.
      mhdr.ts = ((4503599*(descriptor->Timestamp>>32))>>20)|(descriptor->Timestamp<<32) ;
246 247 248 249 250
      mhdr.ifindex = descriptor->Channel;
      mhdr.caplen = descriptor->StoredLength;
      mhdr.wlen = descriptor->WireLength;

      // ? TODO - modify third argument to pass test_packet_read
's avatar
committed
251
      mapid_process_pkt(&i->mapidlib, (unsigned char*)frame, frame + sizeof(PacketDescriptorType2_t), &mhdr);
's avatar
committed
252 253 254 255

      /* Avance to the next packet. */
      descriptor = (PacketDescriptorType2_t*)((uint8_t*)descriptor + descriptor->StoredLength);
    }
256 257
  }

's avatar
committed
258 259 260
  return 0;
}

261
static unsigned
's avatar
committed
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
process_pkts_offline(void *buf,unsigned len, napatech_instance_t *i)
{
  DEBUG_CMD(Debug_Message("napatechdrv: process_pkts_offline"));

  /* TODO */

  return 0;

}

static void
mapidrv_offline_proc_loop(void *arg)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_offline_proc_loop"));

  /* TODO */

}

static void
mapidrv_proc_loop (void *arg)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_proc_loop"));
285

's avatar
committed
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
  int devid = *(int *)arg;
  napatech_instance_t *i=flist_get(devlist,devid);
  int err;

  BufferRequestSampledType2_t request;
  // BufferInformationSectionType6_t bufferInformation;
  BufferInformationSectionType1_t bufferInformation;
  uint32_t result;

  request.common.waitTimeoutMS=GET_NEXT_BUFFER_INFINITE_WAIT;

  if ((err=pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) != 0) {
     DEBUG_CMD(Debug_Message("ERROR: pthread_setcanceltype failed (%s)",strerror(err)));
     return;
  }
301

's avatar
committed
302 303 304 305 306 307 308 309
  if ((err=pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) != 0) {
     DEBUG_CMD(Debug_Message("ERROR: pthread_setcancelstate (%s) failed", strerror(err)));
     return;
  }

  while (1)
    {

310 311
    // DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_proc_loop; i->napatechhandle: %d; i->packetfeedhandle: %d", i->napatechhandle, i->packetfeedhandle));

's avatar
committed
312 313 314 315 316 317
    result = NTCI_GetNextBuffer(i->napatechhandle,
                                i->packetfeedhandle,
                                STID_BUFFER_REQUEST_SAMPLED_TYPE2,
                                &request,
                                STID_BUFFER_INFORMATION_SECTION_TYPE1,
                                &bufferInformation);
318

's avatar
committed
319
    if(result == NTCI_ERRCODE_SUCCESS) {
320
    if(bufferInformation.numDescriptorsAvailable > 0) process_pkts(&bufferInformation, i);
's avatar
committed
321 322 323 324

      NTCI_ReleaseBuffer(i->napatechhandle,
                         i->packetfeedhandle,
                         STID_BUFFER_INFORMATION_SECTION_TYPE1,
325
                         &bufferInformation);
's avatar
committed
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
    } else if(result != NTCI_STATUSCODE_NO_PACKETS_AVAILABLE) {
      DEBUG_CMD(Debug_Message("Failed to get buffers. Error code %d\n", result)); //stderr
      break;
    }

    }
 }


int
mapidrv_read_results (int devid,int fd, int fid, mapid_result_t** result)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_read_results"));

  napatech_instance_t *i=flist_get(devlist,devid);
  return mapid_read_results(&i->mapidlib,fd,fid,result);
}

mapid_funct_info_t* mapidrv_get_flow_functions(int devid,int fd)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_get_flow_functions"));

  napatech_instance_t *i=flist_get(devlist,devid);
  return mapid_get_flow_functions(&i->mapidlib,fd);
}

int mapidrv_get_flow_info(int devid,int fd,mapi_flow_info_t *info) {
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_get_flow_info"));

  napatech_instance_t *i=flist_get(devlist,devid);
  return mapid_get_flow_info(&i->mapidlib,fd,info);
}

int
mapidrv_create_offline_flow (int devid, int format,int fd,char **devtype)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_create_offline_flow"));

  napatech_instance_t *i=flist_get(devlist,devid);

  /* TODO */

  return 0;
}

int
mapidrv_create_flow (int devid, int fd, char **devtype)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_create_flow"));

  napatech_instance_t *i;

  uint32_t result=0;
  uint32_t feedPriorities[] = { 1 };
  FeedConfigSampledType2_t feedConfig;
  // BufferInformationSectionType6_t bufferInformation;
  // FeedBufferInformationType1_t bufferInfo;
  // BufferRequestSampledType2_t request;
  CardHardwareCapabilitiesType1_t cardCapabilities;
  uint32_t channelsBitmask=0;
  CardHardwareVersionCapabilitiesType3_t data3;

  if(devid < 0)
    {
      napatech_instance_t *inst=flist_get(devlist,devid);
391

's avatar
committed
392 393
      *devtype=MAPI_DEVICE_NAPATECH;
      inst->hwinfo.offline=1;
394

's avatar
committed
395
      inst->hwinfo.cap_length=1500;
396
			inst->hwinfo.link_type=DLT_EN10MB;
's avatar
committed
397 398 399
      inst->hwinfo.devtype=MAPI_DEVICE_NAPATECH;
      inst->hwinfo.devid=inst->id;
      inst->hwinfo.pkts=0;
400

's avatar
committed
401 402 403 404 405 406 407 408
      DEBUG_CMD(Debug_Message("Reading from trace file: %s", inst->name));

      return mapid_add_flow(&inst->mapidlib,fd,&inst->hwinfo,NULL);
    }

  i=flist_get(devlist,devid);

  i->hwinfo.offline=0;
409

's avatar
committed
410
  *devtype=MAPI_DEVICE_NAPATECH;
411

's avatar
committed
412 413 414 415 416 417 418 419
  //Open device if it is not already open
  if (i->napatechhandle == NULL)
    {

  /* Open the correct card. */
  DEBUG_CMD(Debug_Message("mapinapatechdrv: mapidrv_create_flow; Trying to open NTCI based adapter #%d\n", i->name[strlen(i->name) - 1] - '0'));
  if(strstr(i->name, "xyxs") != NULL) {
    /* X card series. */
420
    DEBUG_CMD(Debug_Message("mapinapatechdrv: mapidrv_create_flow; Opening X card series."));
's avatar
committed
421 422
    i->napatechhandle = NTCI_OpenCard(NTCI_CARD_TYPE_ANY, i->name[strlen(i->name) - 1] - '0');
  } else if(strstr(i->name, "ntx") != NULL) {
423
    DEBUG_CMD(Debug_Message("mapinapatechdrv: mapidrv_create_flow; Opening ntxc card series."));
's avatar
committed
424 425 426 427
    i->napatechhandle = NTCI_OpenCard(NTCI_ANY_NAPATECH_CARD_TYPE, i->name[strlen(i->name) - 1] - '0');
  }
  if(i->napatechhandle==NULL) {
    DEBUG_CMD(Debug_Message("mapinapatechdrv: mapidrv_create_flow; Failed to open adapter.\n"));
428 429
    return NTCI_ERRCODE_NO_DEVICE_OPEN; // TODO
  }
's avatar
committed
430 431 432

  i->hwinfo.devfd = (int)i->napatechhandle;

's avatar
committed
433 434
  i->hwinfo.cap_length=0;
  /* TODO cap_length from hw */
435 436 437 438
  if (i->hwinfo.cap_length==0) {
    DEBUG_CMD(Debug_Message("WARNING: Could not get info hardware-info, using default = 1500"));
    i->hwinfo.cap_length=1500;
  }
439
  i->hwinfo.link_type=DLT_EN10MB; // TODO
440

's avatar
committed
441

's avatar
committed
442 443 444
  DEBUG_CMD(Debug_Message("mapinapatechdrv: mapidrv_create_flow; NTCI_CardIdentification() = %d", NTCI_CardIdentification(i->napatechhandle)));


445
  if((result = NTCI_GetCapabilities(i->napatechhandle,
's avatar
committed
446 447 448 449 450 451 452
                                    CAPID_HARDWARE,
                                    NOT_SUB_CAPABILITIES,
                                    STID_CARD_HARDWARE_CAPABILITIES_TYPE1,
                                    &cardCapabilities)) != NTCI_ERRCODE_SUCCESS) {

    DEBUG_CMD(Debug_Message(stderr, "Error finding adapter capabilities: %i\n", result));
  }
453

's avatar
committed
454
  channelsBitmask = cardCapabilities.totalChannelsBitmask;
455

's avatar
committed
456
  if (NTCI_CardIdentification(i->napatechhandle)==NT_CARD_TYPE) {
457

's avatar
committed
458 459 460 461 462 463 464 465 466 467 468
  /* Check if we need to use NTPL to set up feeds. */
  if((result = NTCI_GetCapabilities(i->napatechhandle,
                                    CAPID_VERSION,
                                    NOT_SUB_CAPABILITIES,
                                    STID_CARD_HARDWARE_VERSION_CAPABILITIES_TYPE3,
                                    &data3)) != NTCI_ERRCODE_SUCCESS) {
    DEBUG_CMD(Debug_Message(stderr, "Error finding HW capabilities: %i\n", result));
  }

  switch (data3.AdapterCard.dwInfoType) {
  case 1:
's avatar
committed
469 470 471 472 473 474 475
    if((uint16_t)((data3.AdapterCard.u.InfoType1.qwFpgaId>>8)&0xFF) == 32) {
      if(system("grep \"disableMultiFeed\" /opt/napatech/config/default.cfg > /dev/null") == 0) {
        if(system("grep \"#disableMultiFeed\" /opt/napatech/config/default.cfg > /dev/null") != 0) {
          if(system("grep disableMultiFeed /opt/napatech/config/default.cfg | grep 0 > /dev/null") == 0) {
            channelsBitmask = 0;
          }
        } else {
's avatar
committed
476 477 478 479 480 481 482 483
          channelsBitmask = 0;
        }
      } else {
        channelsBitmask = 0;
      }
    }
    break;
  case 2:
's avatar
committed
484 485 486 487 488 489 490
    if((uint16_t)((data3.AdapterCard.u.InfoType2.qwFpgaId>>8)&0xFF) == 32) {
      if(system("grep \"disableMultiFeed\" /opt/napatech/config/default.cfg > /dev/null") == 0) {
        if(system("grep \"#disableMultiFeed\" /opt/napatech/config/default.cfg > /dev/null") != 0) {
          if(system("grep disableMultiFeed /opt/napatech/config/default.cfg | grep 0 > /dev/null") == 0) {
            channelsBitmask = 0;
          }
        } else {
's avatar
committed
491 492 493 494 495
          channelsBitmask = 0;
        }
      } else {
        channelsBitmask = 0;
      }
496
    }
's avatar
committed
497 498 499 500 501 502
    break;
  default:
    // DEBUG_MSG(Debug_Message("Unsupported FPGA!")); // ?
    return;
  }

's avatar
committed
503 504
  } /* if (NTCI_CardIdentification(i->napatechhandle)==NT_CARD_TYPE) */

's avatar
committed
505 506 507 508 509 510 511
  i->hwinfo.devtype=MAPI_DEVICE_NAPATECH;
  i->hwinfo.devid=i->id;
  i->hwinfo.pkts=0;


  /* Set up the packet feed engine for a single feed.
   *
512 513 514 515
   * The feedPriorities array is used to assign the
   * priorities of different feeds when creating multiple
   * simultaneous feeds; in this example it is redundant
   * as only one entry is required */
's avatar
committed
516 517 518 519 520 521 522 523 524

  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_create_flow; NTCI_SetupPacketFeedEngine(%d, %d, %d)", i->napatechhandle, 1, feedPriorities[0]));

  if((result = NTCI_SetupPacketFeedEngine(i->napatechhandle, 1, feedPriorities)) != NTCI_ERRCODE_SUCCESS) {
    DEBUG_CMD(Debug_Message("Failed to initialise packet feed engine (%i)\n", result)); //stderr
    NTCI_CloseCard(i->napatechhandle);
    return -1;
  }

525

's avatar
committed
526 527 528 529 530
  /* Create the packet feed.
   *
   * First, initialise the feedConfig structure */
  /* provide packets in sections */
  feedConfig.bufferType = BUFFER_SECTION;
531

's avatar
committed
532
  /* hardware native timestamps */
Arne Øslebø's avatar
Arne Øslebø committed
533
  feedConfig.timestampType = TIMESTAMP_PCAP_NANOTIME;
534

's avatar
committed
535
  /* do not deliver corrupted packets */
536 537
  feedConfig.dropErroredPacketsFlag = 0;

's avatar
committed
538 539
  /* slicing is disabled */
  feedConfig.sliceLength = 0;
540

's avatar
committed
541 542 543
  /* large samples are used: these better handle network
   * traffic fluctuations */
  feedConfig.bufferBehaviour = SMALL_REGULAR_SAMPLES;
544

's avatar
committed
545
  /* Create the packet feed.
546 547 548
   *
   * PACKET_FEED_SOURCE_SAMPLED is used to specify real time
   * sampling of network traffic. */
's avatar
committed
549 550 551 552 553 554 555 556 557 558
  if((result = NTCI_CreatePacketFeed(i->napatechhandle,
                                     0,
                                     channelsBitmask,
                                     PACKET_FEED_SOURCE_SAMPLED,
                                     PACKET_FEED_DESTINATION_EXTERNAL,
                                     STID_FEED_CONFIG_SAMPLED_TYPE2,
                                     &feedConfig,
                                     &i->packetfeedhandle)) != NTCI_ERRCODE_SUCCESS) {
    DEBUG_CMD(Debug_Message("Failed to create a packet feed (%i)\n", result)); //stderr
    NTCI_CloseCard(i->napatechhandle);
559
    return -1;
's avatar
committed
560 561
  }

's avatar
committed
562 563 564 565 566
  if(channelsBitmask == 0) {
    PassFilter_t command;
    command.WriteHW = TRUE;
    sprintf(command.achFilterString, "Capture[Priority=0;Feed=0]=ALL");
	/* TODO - preclasification ^^^ */
567

's avatar
committed
568 569 570 571 572 573 574
    if((result = NTCI_PacketClassification(i->napatechhandle,
                                           STID_PASS_FILTER,
                                           &command)) != NTCI_ERRCODE_SUCCESS) {
      FilterError_t error;
      result = NTCI_PacketClassification(i->napatechhandle,
                                         STID_GET_FILTER_ERROR,
                                         &error);
575

's avatar
committed
576 577 578 579 580 581 582 583
      DEBUG_CMD(Debug_Message("%s\n",error.achFilterError1)); // stderr
      DEBUG_CMD(Debug_Message("%s\n",error.achFilterError2)); // stderr
      DEBUG_CMD(Debug_Message("%s\n",error.achFilterError3)); // stderr
      NTCI_CloseCard(i->napatechhandle);
      return -1;
    }
  }

's avatar
committed
584
  // i->packetfeedhandle = packetFeedHandle;
585

's avatar
committed
586 587 588 589
  if((result = NTCI_StartPacketFeed(i->napatechhandle, i->packetfeedhandle)) != NTCI_ERRCODE_SUCCESS) {
    DEBUG_CMD(Debug_Message("Error while starting packet feed (%i)\n", result)); // stderr
    NTCI_CloseCard(i->napatechhandle);
    return -1;
590
  }
's avatar
committed
591

's avatar
committed
592 593
  /* find the location of the feed buffer where new
   * data will be stored */
594
  if((result = NTCI_GetPacketFeedBuffers(i->napatechhandle,
's avatar
committed
595 596 597 598 599 600 601
                                         i->packetfeedhandle,
                                         STID_FEED_BUFFER_INFORMATION_TYPE1,
                                         &i->bufferInfo)) != NTCI_ERRCODE_SUCCESS) {
    DEBUG_CMD(Debug_Message("Unable to retrieve the location of the feed buffer.\n")); // stderr
    NTCI_CloseCard(i->napatechhandle);
    return -1;
  }
's avatar
committed
602

's avatar
committed
603 604 605 606 607 608 609

      //Start processing thread
      if (pthread_attr_init (&i->th_attr) != 0)
        {
          DEBUG_CMD(Debug_Message("ERROR: pthread_attr_init failed"));
          return DAGDRV_PTHR_ERR; // TODO
        }
610

's avatar
committed
611 612 613 614
      if (pthread_create(&i->th_proc, &i->th_attr, (void *) mapidrv_proc_loop, (void *) &(i->id)) != 0)
        {
          DEBUG_CMD(Debug_Message("ERROR: pthread_create failed"));
          return DAGDRV_PTHR_ERR; // TODO
's avatar
committed
615
        }
's avatar
committed
616
     }
617

's avatar
committed
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_create_flow_; i->napatechhandle: %d; i->packetfeedhandle: %d", i->napatechhandle, i->packetfeedhandle));

  return   mapid_add_flow(&i->mapidlib,fd,&i->hwinfo,NULL);
}

int
mapidrv_connect (int devid,int fd)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_connect"));

  int ret;
  napatech_instance_t *i=flist_get(devlist,devid);
  if(i == NULL)
  	return -1;

  ret=mapid_connect(&i->mapidlib,fd);

  if(i->hwinfo.offline==4) {
    if (pthread_attr_init (&i->th_attr) != 0)
      {
		DEBUG_CMD(Debug_Message("ERROR: pthread_attr_init failed"));
		return NICDRV_PTHR_ERR;
      }
    if (pthread_create
		(&i->th_proc, &i->th_attr, (void *) mapidrv_offline_proc_loop, (void *) &(i->id)) != 0)
      {
		DEBUG_CMD(Debug_Message("ERROR: pthread_create failed"));
		return NICDRV_PTHR_ERR;
646
      }
's avatar
committed
647 648 649 650
  }
  return ret;
}

651
int
's avatar
committed
652 653 654 655 656
mapidrv_start_offline_device( int devid)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_start_offline_device"));

  napatech_instance_t *i = flist_get(devlist,devid);
657

's avatar
committed
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
  /* TODO */

  return 0;
}


int
mapidrv_close_flow (int devid,int fd)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_close_flow"));

  napatech_instance_t *i=flist_get(devlist,devid);
  int rc = mapid_close_flow(&i->mapidlib,fd);

  return rc;
}

675
int
's avatar
committed
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721
mapidrv_load_library(MAPI_UNUSED int devid,char* lib)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_load_library"));

  return mapid_load_library(lib);
}

__attribute__ ((constructor))
     void init ()
{
  DEBUG_CMD(Debug_Message("napatechdrv: init"));

  devlist=malloc(sizeof(flist_t));
  flist_init(devlist);
  printf ("DAG driver loaded [%s:%d]\n",__FILE__,__LINE__);
}

__attribute__ ((destructor))
     void fini ()
{
  DEBUG_CMD(Debug_Message("napatechdrv: fini"));

  free(devlist);
  printf ("NAPATECH driver unloaded [%s:%d]\n",__FILE__,__LINE__);
}

int
mapidrv_stats (int devid, char **devtype, struct mapi_stat *stats)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_stats"));

  napatech_instance_t *i=flist_get(devlist,devid);

  *devtype=MAPI_DEVICE_NAPATECH;

  if (i!=NULL)
  {
	stats->ps_recv=i->hwinfo.pkts + i->hwinfo.pkt_drop;
	stats->ps_drop=i->hwinfo.pkt_drop;
	stats->ps_ifdrop=0;
	return 0;
  }

  return MAPI_STATS_ERROR;
}