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