int pfring_bundle_read(pfring_bundle *bundle,
		       u_char** buffer, u_int buffer_len,
		       struct pfring_pkthdr *hdr,
		       u_int8_t wait_for_incoming_packet) {
  u_int i, sock_id = 0, num_found, rc;
  struct timeval ts = { 0 };

 redo_pfring_bundle_read:

  switch(bundle->policy) {
  case pick_round_robin:
    for(i=0; i<bundle->num_sockets; i++) {
      bundle->last_read_socket = (bundle->last_read_socket + 1) % bundle->num_sockets;

      if(pfring_there_is_pkt_available(bundle->sockets[bundle->last_read_socket])) {
	return(pfring_recv(bundle->sockets[bundle->last_read_socket], buffer,
			   buffer_len, hdr, wait_for_incoming_packet));
      }
    }
    break;

  case pick_fifo:
    num_found = 0;

    for(i=0; i<bundle->num_sockets; i++) {
      pfring *ring = bundle->sockets[i];

      if(pfring_there_is_pkt_available(ring)) {
	struct pfring_pkthdr *header = (struct pfring_pkthdr*)&ring->slots[ring->slots_info->remove_off];

	if((num_found == 0) || is_before(&header->ts, &ts)) {
	  memcpy(&ts, &header->ts, sizeof(struct timeval));
	  num_found++, sock_id = i;
	}
      }
    }

    if(num_found > 0) {
      return(pfring_recv(bundle->sockets[sock_id], buffer,
			 buffer_len, hdr, wait_for_incoming_packet));
    }
    break;
  }

  if(wait_for_incoming_packet) {
    rc = pfring_bundle_poll(bundle, bundle->sockets[0]->poll_duration);

    if(rc > 0) {
      goto redo_pfring_bundle_read;
    } else
      return(rc);
  }

  return(0);
}
Example #2
0
int pfring_bundle_read(pfring_bundle *bundle,
		       u_char** buffer, u_int buffer_len,
		       struct pfring_pkthdr *hdr,
		       u_int8_t wait_for_incoming_packet) {
  int i, sock_id = -1, found, rc, empty_rings, scans;
  struct timespec ts = { 0 };
  struct timespec tmpts;
  u_int8_t founds[32] = { 0 };

redo_pfring_bundle_read:

  switch(bundle->policy) {
  case pick_round_robin:
    for(i=0; i<bundle->num_sockets; i++) {
      rc = pfring_recv(bundle->sockets[bundle->last_read_socket], buffer, buffer_len, hdr, 0);
      if(++bundle->last_read_socket == bundle->num_sockets) bundle->last_read_socket = 0;
      if(rc > 0) return(rc);
    }
    break;

  case pick_fifo:
    found = 0;
    empty_rings = 0;
    scans = 0;

  sockets_scan:
    scans++;
    for(i=0; i<bundle->num_sockets; i++) {
      if(founds[i] == 0) {
	pfring *ring = bundle->sockets[i];

	rc = pfring_next_pkt_time(ring, &tmpts);

	if(rc == 0) {
	  if(!found || timespec_is_before(&tmpts, &ts)) {
	    memcpy(&ts, &tmpts, sizeof(struct timespec));
	    found = 1, founds[i] = 1;
	    sock_id = i;
	  }
	} else if (rc == PF_RING_ERROR_NO_PKT_AVAILABLE) {
	  empty_rings = 1;
	} else {
	  /* error */
	}
      }
    }

    if(found) {
#ifdef EXTRA_SAFE
      if(empty_rings && (scans == 1))
        goto sockets_scan; /* scanning ring twice (safety check) */
#endif

      return(pfring_recv(bundle->sockets[sock_id], buffer, buffer_len, hdr, 0));
    }
    break;
  }

  if(wait_for_incoming_packet) {
    rc = pfring_bundle_poll(bundle, bundle->sockets[0]->poll_duration);

    if(rc > 0) goto redo_pfring_bundle_read;
    else return(rc);
  }

  return(0);
}