aboutsummaryrefslogtreecommitdiff
path: root/pcap-netfilter-linux.c
diff options
context:
space:
mode:
authorrongxi.li <rongxi.li@chaitin.com>2017-08-24 08:14:38 +0000
committerrongxi.li <rongxi.li@chaitin.com>2017-08-24 08:32:48 +0000
commit2806e8e3046f77b8376950be2fc78602d9c2b23f (patch)
treeaf709591765c9ddb08de74760e125d7d2d4bdf2a /pcap-netfilter-linux.c
parent934a34709d93d201cf2bbfe4c75c27920451ea38 (diff)
fix linux netfilter with a max packet count
Diffstat (limited to 'pcap-netfilter-linux.c')
-rw-r--r--pcap-netfilter-linux.c60
1 files changed, 42 insertions, 18 deletions
diff --git a/pcap-netfilter-linux.c b/pcap-netfilter-linux.c
index a53cc37e..25df335d 100644
--- a/pcap-netfilter-linux.c
+++ b/pcap-netfilter-linux.c
@@ -89,28 +89,44 @@ static int
netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
struct pcap_netfilter *handlep = handle->priv;
- const unsigned char *buf;
+ register u_char *bp, *ep;
int count = 0;
int len;
+ if (handle->break_loop) {
+ handle->break_loop = 0;
+ return (PCAP_ERROR_BREAK);
+ }
+ len = handle->cc;
+ if (len == 0) {
+ do {
+ len = recv(handle->fd, handle->buffer, handle->bufsize, 0);
+ if(errno == ENOBUFS) handlep->packets_nobufs++;
+ } while ((len == -1) && (errno == EINTR || errno == ENOBUFS));
+
+ if (len < 0) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s", errno, pcap_strerror(errno));
+ return -1;
+ }
+
+ bp = (unsigned char *)handle->buffer;
+ } else
+ bp = handle->bp;
+ ep = bp + len;
/* ignore interrupt system call error */
- do {
- len = recv(handle->fd, handle->buffer, handle->bufsize, 0);
+ while (bp < ep) {
if (handle->break_loop) {
- handle->break_loop = 0;
- return -2;
+ handle->bp = bp;
+ handle->cc = ep - bp;
+ if (handle->cc < 0)
+ handle->cc = 0;
+ if (count == 0) {
+ handle->break_loop = 0;
+ return (PCAP_ERROR_BREAK);
+ } else
+ return (count);
}
- if(errno == ENOBUFS) handlep->packets_nobufs++;
- } while ((len == -1) && (errno == EINTR || errno == ENOBUFS));
-
- if (len < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s", errno, pcap_strerror(errno));
- return -1;
- }
-
- buf = (unsigned char *)handle->buffer;
- while ((u_int)len >= NLMSG_SPACE(0)) {
- const struct nlmsghdr *nlh = (const struct nlmsghdr *) buf;
+ const struct nlmsghdr *nlh = (const struct nlmsghdr *) bp;
u_int32_t msg_len;
nftype_t type = OTHER;
@@ -208,9 +224,17 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
if (msg_len > (u_int)len)
msg_len = (u_int)len;
- len -= msg_len;
- buf += msg_len;
+ bp += msg_len;
+ if (count >= max_packets && !PACKET_COUNT_IS_UNLIMITED(max_packets)) {
+ handle->bp = bp;
+ handle->cc = ep - bp;
+ if (handle->cc < 0)
+ handle->cc = 0;
+ return (count);
+ }
}
+
+ handle->cc = 0;
return count;
}