static void PcapCallbackLoop(char *user, struct pcap_pkthdr *h, u_char *pkt) { SCEnter(); PcapThreadVars *ptv = (PcapThreadVars *)user; Packet *p = PacketGetFromQueueOrAlloc(); struct timeval current_time; if (unlikely(p == NULL)) { SCReturn; } PKT_SET_SRC(p, PKT_SRC_WIRE); p->ts.tv_sec = h->ts.tv_sec; p->ts.tv_usec = h->ts.tv_usec; SCLogDebug("p->ts.tv_sec %"PRIuMAX"", (uintmax_t)p->ts.tv_sec); p->datalink = ptv->datalink; ptv->pkts++; ptv->bytes += h->caplen; (void) SC_ATOMIC_ADD(ptv->livedev->pkts, 1); p->livedev = ptv->livedev; if (unlikely(PacketCopyData(p, pkt, h->caplen))) { TmqhOutputPacketpool(ptv->tv, p); SCReturn; } switch (ptv->checksum_mode) { case CHECKSUM_VALIDATION_AUTO: if (ptv->livedev->ignore_checksum) { p->flags |= PKT_IGNORE_CHECKSUM; } else if (ChecksumAutoModeCheck(ptv->pkts, SC_ATOMIC_GET(ptv->livedev->pkts), SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) { ptv->livedev->ignore_checksum = 1; p->flags |= PKT_IGNORE_CHECKSUM; } break; case CHECKSUM_VALIDATION_DISABLE: p->flags |= PKT_IGNORE_CHECKSUM; break; default: break; } if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) { pcap_breakloop(ptv->pcap_handle); ptv->cb_result = TM_ECODE_FAILED; } /* Trigger one dump of stats every second */ TimeGet(¤t_time); if (current_time.tv_sec != ptv->last_stats_dump) { PcapDumpCounters(ptv); ptv->last_stats_dump = current_time.tv_sec; } SCReturn; }
/** * \brief Pfring Packet Process function. * * This function fills in our packet structure from libpfring. * From here the packets are picked up by the DecodePfring thread. * * \param user pointer to PfringThreadVars * \param h pointer to pfring packet header * \param p pointer to the current packet */ static inline void PfringProcessPacket(void *user, struct pfring_pkthdr *h, Packet *p) { PfringThreadVars *ptv = (PfringThreadVars *)user; ptv->bytes += h->caplen; ptv->pkts++; p->livedev = ptv->livedev; /* PF_RING may fail to set timestamp */ if (h->ts.tv_sec == 0) { gettimeofday((struct timeval *)&h->ts, NULL); } p->ts.tv_sec = h->ts.tv_sec; p->ts.tv_usec = h->ts.tv_usec; /* PF_RING all packets are marked as a link type of ethernet * so that is what we do here. */ p->datalink = LINKTYPE_ETHERNET; /* get vlan id from header. Check on vlan_id not null even if comment in * header announce NO_VLAN is used when there is no VLAN. But NO_VLAN * is not defined nor used in PF_RING code. And vlan_id is set to 0 * in PF_RING kernel code when there is no VLAN. */ if ((!ptv->vlan_disabled) && h->extended_hdr.parsed_pkt.vlan_id) { p->vlan_id[0] = h->extended_hdr.parsed_pkt.vlan_id & 0x0fff; p->vlan_idx = 1; p->vlanh[0] = NULL; } switch (ptv->checksum_mode) { case CHECKSUM_VALIDATION_RXONLY: if (h->extended_hdr.rx_direction == 0) { p->flags |= PKT_IGNORE_CHECKSUM; } break; case CHECKSUM_VALIDATION_DISABLE: p->flags |= PKT_IGNORE_CHECKSUM; break; case CHECKSUM_VALIDATION_AUTO: if (ptv->livedev->ignore_checksum) { p->flags |= PKT_IGNORE_CHECKSUM; } else if (ChecksumAutoModeCheck(ptv->pkts, SC_ATOMIC_GET(ptv->livedev->pkts), SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) { ptv->livedev->ignore_checksum = 1; p->flags |= PKT_IGNORE_CHECKSUM; } break; default: break; } SET_PKT_LEN(p, h->caplen); }
void PcapFileCallbackLoop(char *user, struct pcap_pkthdr *h, u_char *pkt) { SCEnter(); PcapFileFileVars *ptv = (PcapFileFileVars *)user; Packet *p = PacketGetFromQueueOrAlloc(); if (unlikely(p == NULL)) { SCReturn; } PACKET_PROFILING_TMM_START(p, TMM_RECEIVEPCAPFILE); PKT_SET_SRC(p, PKT_SRC_WIRE); p->ts.tv_sec = h->ts.tv_sec; p->ts.tv_usec = h->ts.tv_usec; SCLogDebug("p->ts.tv_sec %"PRIuMAX"", (uintmax_t)p->ts.tv_sec); p->datalink = ptv->datalink; p->pcap_cnt = ++pcap_g.cnt; p->pcap_v.tenant_id = ptv->shared->tenant_id; ptv->shared->pkts++; ptv->shared->bytes += h->caplen; if (unlikely(PacketCopyData(p, pkt, h->caplen))) { TmqhOutputPacketpool(ptv->shared->tv, p); PACKET_PROFILING_TMM_END(p, TMM_RECEIVEPCAPFILE); SCReturn; } /* We only check for checksum disable */ if (pcap_g.checksum_mode == CHECKSUM_VALIDATION_DISABLE) { p->flags |= PKT_IGNORE_CHECKSUM; } else if (pcap_g.checksum_mode == CHECKSUM_VALIDATION_AUTO) { if (ChecksumAutoModeCheck(ptv->shared->pkts, p->pcap_cnt, SC_ATOMIC_GET(pcap_g.invalid_checksums))) { pcap_g.checksum_mode = CHECKSUM_VALIDATION_DISABLE; p->flags |= PKT_IGNORE_CHECKSUM; } } PACKET_PROFILING_TMM_END(p, TMM_RECEIVEPCAPFILE); if (TmThreadsSlotProcessPkt(ptv->shared->tv, ptv->shared->slot, p) != TM_ECODE_OK) { pcap_breakloop(ptv->pcap_handle); ptv->shared->cb_result = TM_ECODE_FAILED; } SCReturn; }
/** * \brief Pfring Packet Process function. * * This function fills in our packet structure from libpfring. * From here the packets are picked up by the DecodePfring thread. * * \param user pointer to PfringThreadVars * \param h pointer to pfring packet header * \param p pointer to the current packet */ static inline void PfringProcessPacket(void *user, struct pfring_pkthdr *h, Packet *p) { PfringThreadVars *ptv = (PfringThreadVars *)user; ptv->bytes += h->caplen; ptv->pkts++; p->livedev = ptv->livedev; /* PF_RING may fail to set timestamp */ if (h->ts.tv_sec == 0) { gettimeofday((struct timeval *)&h->ts, NULL); } p->ts.tv_sec = h->ts.tv_sec; p->ts.tv_usec = h->ts.tv_usec; /* PF_RING all packets are marked as a link type of ethernet * so that is what we do here. */ p->datalink = LINKTYPE_ETHERNET; switch (ptv->checksum_mode) { case CHECKSUM_VALIDATION_RXONLY: if (h->extended_hdr.rx_direction == 0) { p->flags |= PKT_IGNORE_CHECKSUM; } break; case CHECKSUM_VALIDATION_DISABLE: p->flags |= PKT_IGNORE_CHECKSUM; break; case CHECKSUM_VALIDATION_AUTO: if (ptv->livedev->ignore_checksum) { p->flags |= PKT_IGNORE_CHECKSUM; } else if (ChecksumAutoModeCheck(ptv->pkts, SC_ATOMIC_GET(ptv->livedev->pkts), SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) { ptv->livedev->ignore_checksum = 1; p->flags |= PKT_IGNORE_CHECKSUM; } break; default: break; } SET_PKT_LEN(p, h->caplen); }
/** * \brief Pfring Packet Process function. * * This function fills in our packet structure from libpfring. * From here the packets are picked up by the DecodePfring thread. * * \param user pointer to PfringThreadVars * \param h pointer to pfring packet header * \param p pointer to the current packet */ static inline void PfringProcessPacket(void *user, struct pfring_pkthdr *h, Packet *p) { PfringThreadVars *ptv = (PfringThreadVars *)user; ptv->bytes += h->caplen; ptv->pkts++; p->livedev = ptv->livedev; /* PF_RING may fail to set timestamp */ if (h->ts.tv_sec == 0) { gettimeofday((struct timeval *)&h->ts, NULL); } p->ts.tv_sec = h->ts.tv_sec; p->ts.tv_usec = h->ts.tv_usec; /* PF_RING all packets are marked as a link type of ethernet * so that is what we do here. */ p->datalink = LINKTYPE_ETHERNET; /* In the past, we needed this vlan handling in cases * where the vlan header was stripped from the raw packet. * With modern (at least >= 6) versions of PF_RING, the * 'copy_data_to_ring' function (kernel/pf_ring.c) makes * sure that if the hardware stripped the vlan header, * it is put back by PF_RING. * * PF_RING should put it back in all cases, but as a extra * precaution keep the check here. If the vlan header is * part of the raw packet, the vlan_offset will be set. * So is it is not set, use the parsed info from PF_RING's * extended header. */ if ((!ptv->vlan_disabled) && h->extended_hdr.parsed_pkt.offset.vlan_offset == 0 && h->extended_hdr.parsed_pkt.vlan_id) { p->vlan_id[0] = h->extended_hdr.parsed_pkt.vlan_id & 0x0fff; p->vlan_idx = 1; p->vlanh[0] = NULL; if (!ptv->vlan_hdr_warned) { SCLogWarning(SC_ERR_PF_RING_VLAN, "no VLAN header in the raw " "packet. See #2355."); ptv->vlan_hdr_warned = true; } } switch (ptv->checksum_mode) { case CHECKSUM_VALIDATION_RXONLY: if (h->extended_hdr.rx_direction == 0) { p->flags |= PKT_IGNORE_CHECKSUM; } break; case CHECKSUM_VALIDATION_DISABLE: p->flags |= PKT_IGNORE_CHECKSUM; break; case CHECKSUM_VALIDATION_AUTO: if (ptv->livedev->ignore_checksum) { p->flags |= PKT_IGNORE_CHECKSUM; } else if (ChecksumAutoModeCheck(ptv->pkts, SC_ATOMIC_GET(ptv->livedev->pkts), SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) { ptv->livedev->ignore_checksum = 1; p->flags |= PKT_IGNORE_CHECKSUM; } break; default: break; } SET_PKT_LEN(p, h->caplen); }