Skip to content

Commit 1a09124

Browse files
committed
pcap-usb-linux: clean up the calculation of the packets-to-fetch value.
This should produce the same results as the previous code, but it's a little clearer what's going on. Add comments to explain what's being done (from which one can infer that it produces the same results). Add more comments explaining other things in the code and noting a potential issue with allowing pcap_breakloop() to break out of the packet-processing inner loop.
1 parent c60ebf1 commit 1a09124

File tree

1 file changed

+52
-7
lines changed

1 file changed

+52
-7
lines changed

pcap-usb-linux.c

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -767,13 +767,40 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
767767

768768
for (;;) {
769769
int i, ret;
770-
int limit = max_packets - packets;
771-
if (limit <= 0)
772-
limit = VEC_SIZE;
773-
if (limit > VEC_SIZE)
770+
int limit;
771+
772+
if (PACKET_COUNT_IS_UNLIMITED(max_packets)) {
773+
/*
774+
* There's no limit on the number of packets
775+
* to process, so try to fetch VEC_SIZE packets.
776+
*/
774777
limit = VEC_SIZE;
778+
} else {
779+
/*
780+
* Try to fetch as many packets as we have left
781+
* to process, or VEC_SIZE packets, whichever
782+
* is less.
783+
*
784+
* At this point, max_packets > 0 (otherwise,
785+
* PACKET_COUNT_IS_UNLIMITED(max_packets)
786+
* would be true) and max_packets > packets
787+
* (packet starts out as 0, and the test
788+
* at the bottom of the loop exits if
789+
* max_packets <= packets), so limit is
790+
* guaranteed to be > 0.
791+
*/
792+
limit = max_packets - packets;
793+
if (limit > VEC_SIZE)
794+
limit = VEC_SIZE;
795+
}
775796

776-
/* try to fetch as many events as possible*/
797+
/*
798+
* Try to fetch as many events as possible, up to
799+
* the limit, and flush the events we've processed
800+
* earlier (nflush) - MON_IOCX_MFETCH does both
801+
* (presumably to reduce the number of system
802+
* calls in loops like this).
803+
*/
777804
fetch.offvec = vec;
778805
fetch.nfetch = limit;
779806
fetch.nflush = nflush;
@@ -800,6 +827,20 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
800827
/* keep track of processed events, we will flush them later */
801828
nflush = fetch.nfetch;
802829
for (i=0; i<fetch.nfetch; ++i) {
830+
/*
831+
* XXX - we can't check break_loop here, as
832+
* we read the indices of packets into a
833+
* local variable, so if we're later called
834+
* to fetch more packets, those packets will
835+
* not be seen - and won't be flushed, either.
836+
*
837+
* Instead, we would have to keep the array
838+
* of indices in our private data, along
839+
* with the count of packets to flush - or
840+
* would have to flush the already-processed
841+
* packets if we break out of the loop here.
842+
*/
843+
803844
/* discard filler */
804845
hdr = (pcap_usb_header_mmapped*) &handlep->mmapbuf[vec[i]];
805846
if (hdr->event_type == '@')
@@ -859,8 +900,12 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
859900
}
860901
}
861902

862-
/* with max_packets specifying "unlimited" we stop after the first chunk*/
863-
if (PACKET_COUNT_IS_UNLIMITED(max_packets) || (packets == max_packets))
903+
/*
904+
* If max_packets specifiesg "unlimited", we stop after
905+
* the first chunk.
906+
*/
907+
if (PACKET_COUNT_IS_UNLIMITED(max_packets) ||
908+
(packets >= max_packets))
864909
break;
865910
}
866911

0 commit comments

Comments
 (0)