mapinapatechdrv.c 21.7 KB
Newer Older
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
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

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

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

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

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

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

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
      }
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) {
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

185 186 187
  return 0;
}

188
static unsigned
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

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

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);
211 212 213 214 215

      mhdr.ts = descriptor->Timestamp;
      mhdr.ifindex = descriptor->Channel;
      mhdr.caplen = descriptor->StoredLength;
      mhdr.wlen = descriptor->WireLength;
216

217 218 219 220 221 222 223 224 225 226 227 228 229
			// 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;
			}

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

      /* 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
240
      frame = ((uint8_t*)descriptor);
241

242 243 244 245 246 247
      mhdr.ts = descriptor->Timestamp;
      mhdr.ifindex = descriptor->Channel;
      mhdr.caplen = descriptor->StoredLength;
      mhdr.wlen = descriptor->WireLength;

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

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

255 256 257
  return 0;
}

258
static unsigned
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
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"));
282

283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
  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;
  }
298

299 300 301 302 303 304 305 306
  if ((err=pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) != 0) {
     DEBUG_CMD(Debug_Message("ERROR: pthread_setcancelstate (%s) failed", strerror(err)));
     return;
  }

  while (1)
    {

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

309 310 311 312 313 314
    result = NTCI_GetNextBuffer(i->napatechhandle,
                                i->packetfeedhandle,
                                STID_BUFFER_REQUEST_SAMPLED_TYPE2,
                                &request,
                                STID_BUFFER_INFORMATION_SECTION_TYPE1,
                                &bufferInformation);
315

316
    if(result == NTCI_ERRCODE_SUCCESS) {
317
    if(bufferInformation.numDescriptorsAvailable > 0) process_pkts(&bufferInformation, i);
318 319 320 321

      NTCI_ReleaseBuffer(i->napatechhandle,
                         i->packetfeedhandle,
                         STID_BUFFER_INFORMATION_SECTION_TYPE1,
322
                         &bufferInformation);
323 324 325 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
    } 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);
388

389 390
      *devtype=MAPI_DEVICE_NAPATECH;
      inst->hwinfo.offline=1;
391

392
      inst->hwinfo.cap_length=1500;
393
			inst->hwinfo.link_type=DLT_EN10MB;
394 395 396
      inst->hwinfo.devtype=MAPI_DEVICE_NAPATECH;
      inst->hwinfo.devid=inst->id;
      inst->hwinfo.pkts=0;
397

398 399 400 401 402 403 404 405
      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;
406

407
  *devtype=MAPI_DEVICE_NAPATECH;
408

409 410 411 412 413 414 415 416
  //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. */
417
    DEBUG_CMD(Debug_Message("mapinapatechdrv: mapidrv_create_flow; Opening X card series."));
418 419
    i->napatechhandle = NTCI_OpenCard(NTCI_CARD_TYPE_ANY, i->name[strlen(i->name) - 1] - '0');
  } else if(strstr(i->name, "ntx") != NULL) {
420
    DEBUG_CMD(Debug_Message("mapinapatechdrv: mapidrv_create_flow; Opening ntxc card series."));
421 422 423 424
    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"));
425 426
    return NTCI_ERRCODE_NO_DEVICE_OPEN; // TODO
  }
427 428 429

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

's avatar
committed
430 431
  i->hwinfo.cap_length=0;
  /* TODO cap_length from hw */
432 433 434 435
  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;
  }
436
  i->hwinfo.link_type=DLT_EN10MB; // TODO
437

's avatar
committed
438

439 440 441
  DEBUG_CMD(Debug_Message("mapinapatechdrv: mapidrv_create_flow; NTCI_CardIdentification() = %d", NTCI_CardIdentification(i->napatechhandle)));


442
  if((result = NTCI_GetCapabilities(i->napatechhandle,
443 444 445 446 447 448 449
                                    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));
  }
450

451
  channelsBitmask = cardCapabilities.totalChannelsBitmask;
452

's avatar
committed
453
  if (NTCI_CardIdentification(i->napatechhandle)==NT_CARD_TYPE) {
454

455 456 457 458 459 460 461 462 463 464 465
  /* 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
466 467 468 469 470 471 472
    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 {
473 474 475 476 477 478 479 480
          channelsBitmask = 0;
        }
      } else {
        channelsBitmask = 0;
      }
    }
    break;
  case 2:
's avatar
committed
481 482 483 484 485 486 487
    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 {
488 489 490 491 492
          channelsBitmask = 0;
        }
      } else {
        channelsBitmask = 0;
      }
493
    }
494 495 496 497 498 499
    break;
  default:
    // DEBUG_MSG(Debug_Message("Unsupported FPGA!")); // ?
    return;
  }

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

502 503 504 505 506 507 508
  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.
   *
509 510 511 512
   * 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 */
513 514 515 516 517 518 519 520 521

  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;
  }

522

523 524 525 526 527
  /* Create the packet feed.
   *
   * First, initialise the feedConfig structure */
  /* provide packets in sections */
  feedConfig.bufferType = BUFFER_SECTION;
528

529
  /* hardware native timestamps */
530 531
  feedConfig.timestampType = TIMESTAMP_NATIVE;

532
  /* do not deliver corrupted packets */
533 534
  feedConfig.dropErroredPacketsFlag = 0;

535 536
  /* slicing is disabled */
  feedConfig.sliceLength = 0;
537

538 539 540
  /* large samples are used: these better handle network
   * traffic fluctuations */
  feedConfig.bufferBehaviour = SMALL_REGULAR_SAMPLES;
541

542
  /* Create the packet feed.
543 544 545
   *
   * PACKET_FEED_SOURCE_SAMPLED is used to specify real time
   * sampling of network traffic. */
546 547 548 549 550 551 552 553 554 555
  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);
556
    return -1;
557 558
  }

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

's avatar
committed
565 566 567 568 569 570 571
    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);
572

's avatar
committed
573 574 575 576 577 578 579 580
      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;
    }
  }

581
  // i->packetfeedhandle = packetFeedHandle;
582

's avatar
committed
583 584 585 586
  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;
587
  }
's avatar
committed
588

589 590
  /* find the location of the feed buffer where new
   * data will be stored */
591
  if((result = NTCI_GetPacketFeedBuffers(i->napatechhandle,
592 593 594 595 596 597 598
                                         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
599

600 601 602 603 604 605 606

      //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
        }
607

608 609 610 611
      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
612
        }
613
     }
614

615 616 617 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
  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;
643
      }
644 645 646 647
  }
  return ret;
}

648
int
649 650 651 652 653
mapidrv_start_offline_device( int devid)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_start_offline_device"));

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

655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
  /* 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;
}

672
int
673 674 675 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
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;
}