mapinapatechdrv.c 20.8 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) {
166
      if((result = NTCI_DestroyPacketFeed(i->napatechhandle, i->packetfeedhandle)) != NTCI_ERRCODE_SUCCESS) {
167 168 169 170 171 172 173 174 175 176 177 178 179
        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);
  }
180

181 182 183
  return 0;
}

184
static unsigned
185 186 187 188 189 190 191 192 193 194
// 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;
195

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

198 199 200 201 202 203
  // pNetFlow->flowStat.uiTotalDropped+=bufferInformation.numDroppedFrames;

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

204 205 206 207 208 209 210 211
      PacketExtDescriptorType05_t *pExtDescr = (PacketExtDescriptorType05_t*)(((uint8_t*)descriptor) + sizeof(PacketDescriptorType2_t));

      frame = ((uint8_t*)descriptor) + sizeof(PacketDescriptorType2_t) + (descriptor->ExtensionLength << 3);

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

213 214
      // ? TODO - modify third argument to pass test_packet_read
      mapid_process_pkt(&i->mapidlib, (unsigned char*)frame, frame + (descriptor->StoredLength - descriptor->WireLength), &mhdr);
215 216 217 218 219 220 221 222

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

223
      frame = ((uint8_t*)descriptor) + sizeof(PacketDescriptorType2_t);
224

225 226 227 228 229 230 231
      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
      mapid_process_pkt(&i->mapidlib, (unsigned char*)frame, frame + (descriptor->StoredLength - descriptor->WireLength), &mhdr);
232 233 234 235

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

238 239 240
  return 0;
}

241
static unsigned
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
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"));
265

266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
  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;
  }
281

282 283 284 285 286 287 288 289
  if ((err=pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) != 0) {
     DEBUG_CMD(Debug_Message("ERROR: pthread_setcancelstate (%s) failed", strerror(err)));
     return;
  }

  while (1)
    {

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

292 293 294 295 296 297
    result = NTCI_GetNextBuffer(i->napatechhandle,
                                i->packetfeedhandle,
                                STID_BUFFER_REQUEST_SAMPLED_TYPE2,
                                &request,
                                STID_BUFFER_INFORMATION_SECTION_TYPE1,
                                &bufferInformation);
298

299
    if(result == NTCI_ERRCODE_SUCCESS) {
300
    if(bufferInformation.numDescriptorsAvailable > 0) process_pkts(&bufferInformation, i);
301 302 303 304

      NTCI_ReleaseBuffer(i->napatechhandle,
                         i->packetfeedhandle,
                         STID_BUFFER_INFORMATION_SECTION_TYPE1,
305
                         &bufferInformation);
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 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
    } 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);
371

372 373
      *devtype=MAPI_DEVICE_NAPATECH;
      inst->hwinfo.offline=1;
374

375 376 377 378
      inst->hwinfo.cap_length=1500;
      inst->hwinfo.devtype=MAPI_DEVICE_NAPATECH;
      inst->hwinfo.devid=inst->id;
      inst->hwinfo.pkts=0;
379

380 381 382 383 384 385 386 387
      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;
388

389
  *devtype=MAPI_DEVICE_NAPATECH;
390

391 392 393 394 395 396 397 398
  //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. */
399
    DEBUG_CMD(Debug_Message("mapinapatechdrv: mapidrv_create_flow; Opening X card series."));
400 401
    i->napatechhandle = NTCI_OpenCard(NTCI_CARD_TYPE_ANY, i->name[strlen(i->name) - 1] - '0');
  } else if(strstr(i->name, "ntx") != NULL) {
402
    DEBUG_CMD(Debug_Message("mapinapatechdrv: mapidrv_create_flow; Opening ntxc card series."));
403 404 405 406
    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"));
407 408
    return NTCI_ERRCODE_NO_DEVICE_OPEN; // TODO
  }
409 410 411

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

412 413
  i->hwinfo.cap_length=0;
  /* TODO cap_length from hw */
414 415 416 417 418
  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;
  }

419

420 421 422
  DEBUG_CMD(Debug_Message("mapinapatechdrv: mapidrv_create_flow; NTCI_CardIdentification() = %d", NTCI_CardIdentification(i->napatechhandle)));


423
  if((result = NTCI_GetCapabilities(i->napatechhandle,
424 425 426 427 428 429 430
                                    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));
  }
431

432
  channelsBitmask = cardCapabilities.totalChannelsBitmask;
433

's avatar
committed
434
  if (NTCI_CardIdentification(i->napatechhandle)==NT_CARD_TYPE) {
435

436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 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:
    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 | grep 0 > /dev/null") == 0) {
          channelsBitmask = 0;
        }
      } else {
        channelsBitmask = 0;
      }
    }
    break;
  case 2:
    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 | grep 0 > /dev/null") == 0) {
          channelsBitmask = 0;
        }
      } else {
        channelsBitmask = 0;
      }
466
    }
467 468 469 470 471 472
    break;
  default:
    // DEBUG_MSG(Debug_Message("Unsupported FPGA!")); // ?
    return;
  }

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

475 476 477 478 479 480 481
  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.
   *
482 483 484 485
   * 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 */
486 487 488 489 490 491 492 493 494

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

495

496 497 498 499 500
  /* Create the packet feed.
   *
   * First, initialise the feedConfig structure */
  /* provide packets in sections */
  feedConfig.bufferType = BUFFER_SECTION;
501

502
  /* hardware native timestamps */
503 504
  feedConfig.timestampType = TIMESTAMP_NATIVE;

505
  /* do not deliver corrupted packets */
506 507
  feedConfig.dropErroredPacketsFlag = 0;

508 509
  /* slicing is disabled */
  feedConfig.sliceLength = 0;
510

511 512 513
  /* large samples are used: these better handle network
   * traffic fluctuations */
  feedConfig.bufferBehaviour = SMALL_REGULAR_SAMPLES;
514

515
  /* Create the packet feed.
516 517 518
   *
   * PACKET_FEED_SOURCE_SAMPLED is used to specify real time
   * sampling of network traffic. */
519 520 521 522 523 524 525 526 527 528
  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);
529
    return -1;
530 531
  }

's avatar
committed
532 533 534 535 536
  if(channelsBitmask == 0) {
    PassFilter_t command;
    command.WriteHW = TRUE;
    sprintf(command.achFilterString, "Capture[Priority=0;Feed=0]=ALL");
	/* TODO - preclasification ^^^ */
537

's avatar
committed
538 539 540 541 542 543 544
    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);
545

's avatar
committed
546 547 548 549 550 551 552 553
      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;
    }
  }

554
  // i->packetfeedhandle = packetFeedHandle;
555

's avatar
committed
556 557 558 559
  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;
560
  }
's avatar
committed
561

562 563
  /* find the location of the feed buffer where new
   * data will be stored */
564
  if((result = NTCI_GetPacketFeedBuffers(i->napatechhandle,
565 566 567 568 569 570 571
                                         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
572

573 574 575 576 577 578 579

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

581 582 583 584 585 586
      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
    	}
     }
587

588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
  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;
616
      }
617 618 619 620
  }
  return ret;
}

621
int
622 623 624 625 626
mapidrv_start_offline_device( int devid)
{
  DEBUG_CMD(Debug_Message("napatechdrv: mapidrv_start_offline_device"));

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

628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
  /* 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;
}

645
int
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691
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;
}