enum {
AFP_READ_OK,
AFP_READ_FAILURE,
- AFP_FAILURE,
+ /** Error during treatment by other functions of Suricata */
+ AFP_SURI_FAILURE,
AFP_KERNEL_DROP,
};
/* references to packet and drop counters */
uint16_t capture_kernel_packets;
uint16_t capture_kernel_drops;
+ uint16_t capture_errors;
/* handle state */
uint8_t afp_state;
p = PacketGetFromQueueOrAlloc();
if (p == NULL) {
- SCReturnInt(AFP_FAILURE);
+ SCReturnInt(AFP_SURI_FAILURE);
}
PKT_SET_SRC(p, PKT_SRC_WIRE);
SET_PKT_LEN(p, caplen + offset);
if (PacketCopyData(p, ptv->data, GET_PKT_LEN(p)) == -1) {
TmqhOutputPacketpool(ptv->tv, p);
- SCReturnInt(AFP_FAILURE);
+ SCReturnInt(AFP_SURI_FAILURE);
}
SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)",
GET_PKT_LEN(p), p, GET_PKT_DATA(p));
if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
TmqhOutputPacketpool(ptv->tv, p);
- SCReturnInt(AFP_FAILURE);
+ SCReturnInt(AFP_SURI_FAILURE);
}
SCReturnInt(AFP_READ_OK);
}
/* Read packet from ring */
h.raw = (((union thdr **)ptv->ring_v2)[ptv->frame_offset]);
- if (h.raw == NULL) {
- SCReturnInt(AFP_FAILURE);
+ if (unlikely(h.raw == NULL)) {
+ /* Impossible we reach this point in normal condition, so trigger
+ * a failure in reading */
+ SCReturnInt(AFP_READ_FAILURE);
}
if ((! h.h2->tp_status) || (h.h2->tp_status & TP_STATUS_USER_BUSY)) {
p = PacketGetFromQueueOrAlloc();
if (p == NULL) {
- SCReturnInt(AFP_FAILURE);
+ SCReturnInt(AFP_SURI_FAILURE);
}
PKT_SET_SRC(p, PKT_SRC_WIRE);
if (ptv->flags & AFP_ZERO_COPY) {
if (PacketSetData(p, (unsigned char*)h.raw + h.h2->tp_mac, h.h2->tp_snaplen) == -1) {
TmqhOutputPacketpool(ptv->tv, p);
- SCReturnInt(AFP_FAILURE);
+ SCReturnInt(AFP_SURI_FAILURE);
} else {
p->afp_v.relptr = h.raw;
p->ReleasePacket = AFPReleasePacket;
}
} else {
if (PacketCopyData(p, (unsigned char*)h.raw + h.h2->tp_mac, h.h2->tp_snaplen) == -1) {
+ /* As we can possibly fail to copy the data due to invalid data, let's
+ * skip this packet and switch to the next one.
+ */
+ h.h2->tp_status = TP_STATUS_KERNEL;
+ if (++ptv->frame_offset >= ptv->req.tp_frame_nr) {
+ ptv->frame_offset = 0;
+ }
TmqhOutputPacketpool(ptv->tv, p);
- SCReturnInt(AFP_FAILURE);
+ SCReturnInt(AFP_SURI_FAILURE);
}
}
/* Timestamp */
ptv->frame_offset = 0;
}
TmqhOutputPacketpool(ptv->tv, p);
- SCReturnInt(AFP_FAILURE);
+ SCReturnInt(AFP_SURI_FAILURE);
}
next_frame:
{
Packet *p = PacketGetFromQueueOrAlloc();
if (p == NULL) {
- SCReturnInt(AFP_FAILURE);
+ SCReturnInt(AFP_SURI_FAILURE);
}
PKT_SET_SRC(p, PKT_SRC_WIRE);
if (ptv->flags & AFP_ZERO_COPY) {
if (PacketSetData(p, (unsigned char*)ppd + ppd->tp_mac, ppd->tp_snaplen) == -1) {
TmqhOutputPacketpool(ptv->tv, p);
- SCReturnInt(AFP_FAILURE);
+ SCReturnInt(AFP_SURI_FAILURE);
}
p->afp_v.relptr = ppd;
p->ReleasePacket = AFPReleasePacketV3;
} else {
if (PacketCopyData(p, (unsigned char*)ppd + ppd->tp_mac, ppd->tp_snaplen) == -1) {
TmqhOutputPacketpool(ptv->tv, p);
- SCReturnInt(AFP_FAILURE);
+ SCReturnInt(AFP_SURI_FAILURE);
}
}
/* Timestamp */
if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
TmqhOutputPacketpool(ptv->tv, p);
- SCReturnInt(AFP_FAILURE);
+ SCReturnInt(AFP_SURI_FAILURE);
}
SCReturnInt(AFP_READ_OK);
{
int num_pkts = pbd->hdr.bh1.num_pkts, i;
uint8_t *ppd;
+ int ret = 0;
ppd = (uint8_t *)pbd + pbd->hdr.bh1.offset_to_first_pkt;
for (i = 0; i < num_pkts; ++i) {
- if (unlikely(AFPParsePacketV3(ptv, pbd,
- (struct tpacket3_hdr *)ppd) == AFP_FAILURE)) {
- SCReturnInt(AFP_READ_FAILURE);
+ ret = AFPParsePacketV3(ptv, pbd,
+ (struct tpacket3_hdr *)ppd);
+ switch (ret) {
+ case AFP_READ_OK:
+ break;
+ case AFP_SURI_FAILURE:
+ /* Internal error but let's just continue and
+ * treat thenext packet */
+ break;
+ case AFP_READ_FAILURE:
+ SCReturnInt(AFP_READ_FAILURE);
+ default:
+ SCReturnInt(ret);
}
ppd = ppd + ((struct tpacket3_hdr *)ppd)->tp_next_offset;
}
{
#ifdef HAVE_TPACKET_V3
struct tpacket_block_desc *pbd;
+ int ret = 0;
/* Loop till we have packets available */
while (1) {
SCReturnInt(AFP_READ_OK);
}
- if (unlikely(AFPWalkBlock(ptv, pbd) != AFP_READ_OK)) {
+ ret = AFPWalkBlock(ptv, pbd);
+ if (unlikely(ret != AFP_READ_OK)) {
AFPFlushBlock(pbd);
- SCReturnInt(AFP_READ_FAILURE);
+ SCReturnInt(ret);
}
AFPFlushBlock(pbd);
ptv->iface, errno, strerror(errno));
AFPSwitchState(ptv, AFP_STATE_DOWN);
continue;
- case AFP_FAILURE:
- AFPSwitchState(ptv, AFP_STATE_DOWN);
- SCReturnInt(TM_ECODE_FAILED);
+ case AFP_SURI_FAILURE:
+ StatsIncr(ptv->tv, ptv->capture_errors);
break;
case AFP_KERNEL_DROP:
AFPDumpCounters(ptv);
ptv->tv);
ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops",
ptv->tv);
+ ptv->capture_errors = StatsRegisterCounter("capture.errors",
+ ptv->tv);
#endif
ptv->copy_mode = afpconfig->copy_mode;