#define ACTION_REJECT_ANY (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)
+#define ACTION_DROP_REJECT (ACTION_REJECT_ANY | ACTION_DROP)
+
#endif /* __ACTION_GLOBALS_H__ */
return "threshold detection_filter";
case PKT_DROP_REASON_NFQ_ERROR:
return "nfq error";
+ case PKT_DROP_REASON_INNER_PACKET:
+ return "tunnel packet drop";
case PKT_DROP_REASON_NOT_SET:
return NULL;
}
/* TODO drop reason stats! */
void CaptureStatsUpdate(ThreadVars *tv, CaptureStats *s, const Packet *p)
{
- if (unlikely(PacketTestAction(p, (ACTION_REJECT | ACTION_REJECT_DST | ACTION_REJECT_BOTH)))) {
+ if (unlikely(PacketCheckAction(p, ACTION_REJECT_ANY))) {
StatsIncr(tv, s->counter_ips_rejected);
- } else if (unlikely(PacketTestAction(p, ACTION_DROP))) {
+ } else if (unlikely(PacketCheckAction(p, ACTION_DROP))) {
StatsIncr(tv, s->counter_ips_blocked);
} else if (unlikely(p->flags & PKT_STREAM_MODIFIED)) {
StatsIncr(tv, s->counter_ips_replaced);
(a)->addr_data32[3] = 0; \
} while (0)
-/* clear the address structure by setting all fields to 0 */
-#define CLEAR_ADDR(a) do { \
- (a)->family = 0; \
- (a)->addr_data32[0] = 0; \
- (a)->addr_data32[1] = 0; \
- (a)->addr_data32[2] = 0; \
- (a)->addr_data32[3] = 0; \
- } while (0)
-
/* Set the IPv6 addresses into the Addrs of the Packet.
* Make sure p->ip6h is initialized and validated. */
#define SET_IPV6_SRC_ADDR(p, a) do { \
#define GET_TCP_SRC_PORT(p) ((p)->sp)
#define GET_TCP_DST_PORT(p) ((p)->dp)
-#define RESET_PKT_LEN(p) ((p)->pktlen = 0)
#define GET_PKT_LEN(p) ((p)->pktlen)
#define GET_PKT_DATA(p) ((((p)->ext_pkt) == NULL ) ? (uint8_t *)((p) + 1) : (p)->ext_pkt)
#define GET_PKT_DIRECT_DATA(p) (uint8_t *)((p) + 1)
PKT_DROP_REASON_STREAM_ERROR,
PKT_DROP_REASON_STREAM_MEMCAP,
PKT_DROP_REASON_STREAM_MIDSTREAM,
- PKT_DROP_REASON_NFQ_ERROR, /**< no nfq verdict, must be error */
+ PKT_DROP_REASON_NFQ_ERROR, /**< no nfq verdict, must be error */
+ PKT_DROP_REASON_INNER_PACKET, /**< drop issued by inner (tunnel) packet */
};
/* forward declaration since Packet struct definition requires this */
} \
} while(0)
-/* macro's for setting the action
- * handle the case of a root packet
- * for tunnels */
+/** \brief issue drop action
+ *
+ * Set drop (+reject) flags in both current and root packet.
+ *
+ * \param action action bit flags. Must be limited to ACTION_DROP_REJECT
+ */
+static inline void PacketDrop(Packet *p, const uint8_t action, enum PacketDropReason r)
+{
+ BUG_ON((action & ~ACTION_DROP_REJECT) != 0);
-#define PACKET_SET_ACTION(p, a) (p)->action = (a)
+ if (p->drop_reason == PKT_DROP_REASON_NOT_SET)
+ p->drop_reason = (uint8_t)r;
-static inline void PacketSetAction(Packet *p, const uint8_t a)
-{
- if (likely(p->root == NULL)) {
- PACKET_SET_ACTION(p, a);
- } else {
- PACKET_SET_ACTION(p->root, a);
+ if (p->root) {
+ p->root->action |= action;
+ if (p->root->drop_reason == PKT_DROP_REASON_NOT_SET) {
+ p->root->drop_reason = PKT_DROP_REASON_INNER_PACKET;
+ }
}
+ p->action |= action;
}
-#define PACKET_ALERT(p) PACKET_SET_ACTION(p, ACTION_ALERT)
-
-#define PACKET_ACCEPT(p) PACKET_SET_ACTION(p, ACTION_ACCEPT)
-
-#define PACKET_TEST_ACTION(p, a) (p)->action &(a)
-
-#define PACKET_UPDATE_ACTION(p, a) (p)->action |= (a)
-static inline void PacketUpdateAction(Packet *p, const uint8_t a)
+static inline uint8_t PacketCheckAction(const Packet *p, const uint8_t a)
{
if (likely(p->root == NULL)) {
- PACKET_UPDATE_ACTION(p, a);
+ return (p->action & a) != 0;
} else {
- PACKET_UPDATE_ACTION(p->root, a);
+ /* check against both */
+ const uint8_t actions = p->action | p->root->action;
+ return (actions & a) != 0;
}
}
-static inline void PacketDrop(Packet *p, const uint8_t action, enum PacketDropReason r)
-{
- if (p->drop_reason == PKT_DROP_REASON_NOT_SET)
- p->drop_reason = (uint8_t)r;
-
- PACKET_UPDATE_ACTION(p, action);
-}
-
-static inline void PacketPass(Packet *p)
-{
- PACKET_SET_ACTION(p, ACTION_PASS);
-}
-
+#ifdef UNITTESTS
static inline uint8_t PacketTestAction(const Packet *p, const uint8_t a)
{
- if (likely(p->root == NULL)) {
- return PACKET_TEST_ACTION(p, a);
- } else {
- return PACKET_TEST_ACTION(p->root, a);
- }
+ return PacketCheckAction(p, a);
}
+#endif
#define TUNNEL_INCR_PKT_RTV_NOLOCK(p) do { \
((p)->root ? (p)->root->tunnel_rtv_cnt++ : (p)->tunnel_rtv_cnt++); \
}
/** \brief Apply action(s) and Set 'drop' sig info,
- * if applicable */
-static void PacketApplySignatureActions(Packet *p, const Signature *s, const uint8_t alert_flags)
+ * if applicable
+ * \param p packet
+ * \param s signature -- for id, sig pointer, not actions
+ * \param pa packet alert struct -- match, including actions after thresholding (rate_filter) */
+static void PacketApplySignatureActions(Packet *p, const Signature *s, const PacketAlert *pa)
{
SCLogDebug("packet %" PRIu64 " sid %u action %02x alert_flags %02x", p->pcap_cnt, s->id,
- s->action, alert_flags);
+ pa->action, pa->flags);
/* REJECT also sets ACTION_DROP, just make it more visible with this check */
- if (s->action & (ACTION_DROP | ACTION_REJECT_ANY)) {
+ if (pa->action & ACTION_DROP_REJECT) {
/* PacketDrop will update the packet action, too */
- PacketDrop(p, s->action, PKT_DROP_REASON_RULES);
+ PacketDrop(p, pa->action,
+ (pa->flags & PACKET_ALERT_RATE_FILTER_MODIFIED) ? PKT_DROP_REASON_RULES_THRESHOLD
+ : PKT_DROP_REASON_RULES);
+ SCLogDebug("[packet %p][DROP sid %u]", p, s->id);
if (p->alerts.drop.action == 0) {
p->alerts.drop.num = s->num;
- p->alerts.drop.action = s->action;
+ p->alerts.drop.action = pa->action;
p->alerts.drop.s = (Signature *)s;
}
- if ((p->flow != NULL) && (alert_flags & PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)) {
- RuleActionToFlow(s->action, p->flow);
+ if ((p->flow != NULL) && (pa->flags & PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)) {
+ RuleActionToFlow(pa->action, p->flow);
}
- DEBUG_VALIDATE_BUG_ON(!PacketTestAction(p, ACTION_DROP));
+ DEBUG_VALIDATE_BUG_ON(!PacketCheckAction(p, ACTION_DROP));
} else {
- PacketUpdateAction(p, s->action);
+ if (pa->action & ACTION_PASS) {
+ SCLogDebug("[packet %p][PASS sid %u]", p, s->id);
+ // nothing to set in the packet
+ } else if (pa->action & (ACTION_ALERT | ACTION_CONFIG)) {
+ // nothing to set in the packet
+ } else {
+ DEBUG_VALIDATE_BUG_ON(1); // should be unreachable
+ }
- if ((s->action & ACTION_PASS) && (p->flow != NULL) &&
- (alert_flags & PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)) {
- RuleActionToFlow(s->action, p->flow);
+ if ((pa->action & ACTION_PASS) && (p->flow != NULL) &&
+ (pa->flags & PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)) {
+ RuleActionToFlow(pa->action, p->flow);
}
}
}
uint16_t max_pos = det_ctx->alert_queue_size;
while (i < max_pos) {
- const Signature *s = de_ctx->sig_array[det_ctx->alert_queue[i].num];
- int res = PacketAlertHandle(de_ctx, det_ctx, s, p, &det_ctx->alert_queue[i]);
-
+ PacketAlert *pa = &det_ctx->alert_queue[i];
+ const Signature *s = de_ctx->sig_array[pa->num];
+ int res = PacketAlertHandle(de_ctx, det_ctx, s, p, pa);
if (res > 0) {
/* Now, if we have an alert, we have to check if we want
* to tag this session or src/dst host */
}
/* set actions on the flow */
- FlowApplySignatureActions(
- p, &det_ctx->alert_queue[i], s, det_ctx->alert_queue[i].flags);
+ FlowApplySignatureActions(p, pa, s, pa->flags);
+
+ SCLogDebug("det_ctx->alert_queue[i].action %02x (DROP %s, PASS %s)", pa->action,
+ BOOL2STR(pa->action & ACTION_DROP), BOOL2STR(pa->action & ACTION_PASS));
/* set actions on packet */
- PacketApplySignatureActions(p, s, det_ctx->alert_queue[i].flags);
+ PacketApplySignatureActions(p, s, pa);
}
/* Thresholding removes this alert */
/* we will not copy this to the AlertQueue */
p->alerts.suppressed++;
} else if (p->alerts.cnt < packet_alert_max) {
- p->alerts.alerts[p->alerts.cnt] = det_ctx->alert_queue[i];
+ p->alerts.alerts[p->alerts.cnt] = *pa;
SCLogDebug("Appending sid %" PRIu32 " alert to Packet::alerts at pos %u", s->id, i);
- if (PacketTestAction(p, ACTION_PASS)) {
- /* Ok, reset the alert cnt to end in the previous of pass
- * so we ignore the rest with less prio */
+ /* pass "alert" found, we're done */
+ if (pa->action & ACTION_PASS) {
break;
}
p->alerts.cnt++;
{
switch (new_action) {
case TH_ACTION_ALERT:
- PACKET_ALERT(p);
pa->flags |= PACKET_ALERT_RATE_FILTER_MODIFIED;
+ pa->action = ACTION_ALERT;
break;
case TH_ACTION_DROP:
- PacketDrop(p, ACTION_DROP, PKT_DROP_REASON_RULES_THRESHOLD);
pa->flags |= PACKET_ALERT_RATE_FILTER_MODIFIED;
+ pa->action = ACTION_DROP;
break;
case TH_ACTION_REJECT:
- PacketDrop(p, (ACTION_REJECT | ACTION_DROP), PKT_DROP_REASON_RULES_THRESHOLD);
pa->flags |= PACKET_ALERT_RATE_FILTER_MODIFIED;
+ pa->action = (ACTION_REJECT | ACTION_DROP);
break;
case TH_ACTION_PASS:
- PacketPass(p);
pa->flags |= PACKET_ALERT_RATE_FILTER_MODIFIED;
+ pa->action = ACTION_PASS;
break;
default:
/* Weird, leave the default action */
Packet *p)
{
/* No need to perform any detection on this packet, if the the given flag is set.*/
- if ((p->flags & PKT_NOPACKET_INSPECTION) || (PacketTestAction(p, ACTION_DROP))) {
+ if ((p->flags & PKT_NOPACKET_INSPECTION) || (PacketCheckAction(p, ACTION_DROP))) {
return;
}
const char *action = "allowed";
/* use packet action if rate_filter modified the action */
if (unlikely(pa->flags & PACKET_ALERT_RATE_FILTER_MODIFIED)) {
- if (PacketTestAction(
+ if (PacketCheckAction(
p, (ACTION_DROP | ACTION_REJECT | ACTION_REJECT_DST | ACTION_REJECT_BOTH))) {
action = "blocked";
}
ret = TRUE;
return ret;
- } else if (PacketTestAction(p, ACTION_DROP)) {
+ } else if (PacketCheckAction(p, ACTION_DROP)) {
return TRUE;
}
*/
void PacketReinit(Packet *p)
{
+/* clear the address structure by setting all fields to 0 */
+#define CLEAR_ADDR(a) \
+ do { \
+ (a)->family = 0; \
+ (a)->addr_data32[0] = 0; \
+ (a)->addr_data32[1] = 0; \
+ (a)->addr_data32[2] = 0; \
+ (a)->addr_data32[3] = 0; \
+ } while (0)
+
CLEAR_ADDR(&p->src);
CLEAR_ADDR(&p->dst);
p->sp = 0;
p->ts.tv_usec = 0;
p->datalink = 0;
p->drop_reason = 0;
- PACKET_SET_ACTION(p, 0);
+#define PACKET_RESET_ACTION(p) (p)->action = 0
+ PACKET_RESET_ACTION(p);
if (p->pktvar != NULL) {
PktVarFree(p->pktvar);
p->pktvar = NULL;
p->payload = NULL;
p->payload_len = 0;
p->BypassPacketsFlow = NULL;
+#define RESET_PKT_LEN(p) ((p)->pktlen = 0)
RESET_PKT_LEN(p);
p->alerts.cnt = 0;
p->alerts.discarded = 0;
static TmEcode RespondRejectFunc(ThreadVars *tv, Packet *p, void *data)
{
/* ACTION_REJECT defaults to rejecting the SRC */
- if (likely(PacketTestAction(p, ACTION_REJECT_ANY) == 0)) {
+ if (likely(PacketCheckAction(p, ACTION_REJECT_ANY) == 0)) {
return TM_ECODE_OK;
}
int RejectSendIPv4TCP(ThreadVars *tv, Packet *p, void *data)
{
SCEnter();
- if (PacketTestAction(p, ACTION_REJECT)) {
+ if (PacketCheckAction(p, ACTION_REJECT)) {
int r = RejectSendLibnet11IPv4TCP(tv, p, data, REJECT_DIR_SRC);
SCReturnInt(r);
- } else if (PacketTestAction(p, ACTION_REJECT_DST)) {
+ } else if (PacketCheckAction(p, ACTION_REJECT_DST)) {
int r = RejectSendLibnet11IPv4TCP(tv, p, data, REJECT_DIR_DST);
SCReturnInt(r);
- } else if (PacketTestAction(p, ACTION_REJECT_BOTH)) {
+ } else if (PacketCheckAction(p, ACTION_REJECT_BOTH)) {
int r = RejectSendLibnet11IPv4TCP(tv, p, data, REJECT_DIR_SRC);
r |= RejectSendLibnet11IPv4TCP(tv, p, data, REJECT_DIR_DST);
SCReturnInt(r);
int RejectSendIPv4ICMP(ThreadVars *tv, Packet *p, void *data)
{
SCEnter();
- if (PacketTestAction(p, ACTION_REJECT)) {
+ if (PacketCheckAction(p, ACTION_REJECT)) {
int r = RejectSendLibnet11IPv4ICMP(tv, p, data, REJECT_DIR_SRC);
SCReturnInt(r);
- } else if (PacketTestAction(p, ACTION_REJECT_DST)) {
+ } else if (PacketCheckAction(p, ACTION_REJECT_DST)) {
int r = RejectSendLibnet11IPv4ICMP(tv, p, data, REJECT_DIR_DST);
SCReturnInt(r);
- } else if (PacketTestAction(p, ACTION_REJECT_BOTH)) {
+ } else if (PacketCheckAction(p, ACTION_REJECT_BOTH)) {
int r = RejectSendLibnet11IPv4ICMP(tv, p, data, REJECT_DIR_SRC);
r |= RejectSendLibnet11IPv4ICMP(tv, p, data, REJECT_DIR_DST);
SCReturnInt(r);
int RejectSendIPv6TCP(ThreadVars *tv, Packet *p, void *data)
{
SCEnter();
- if (PacketTestAction(p, ACTION_REJECT)) {
+ if (PacketCheckAction(p, ACTION_REJECT)) {
int r = RejectSendLibnet11IPv6TCP(tv, p, data, REJECT_DIR_SRC);
SCReturnInt(r);
- } else if (PacketTestAction(p, ACTION_REJECT_DST)) {
+ } else if (PacketCheckAction(p, ACTION_REJECT_DST)) {
int r = RejectSendLibnet11IPv6TCP(tv, p, data, REJECT_DIR_DST);
SCReturnInt(r);
- } else if (PacketTestAction(p, ACTION_REJECT_BOTH)) {
+ } else if (PacketCheckAction(p, ACTION_REJECT_BOTH)) {
int r = RejectSendLibnet11IPv6TCP(tv, p, data, REJECT_DIR_SRC);
r |= RejectSendLibnet11IPv6TCP(tv, p, data, REJECT_DIR_DST);
SCReturnInt(r);
int RejectSendIPv6ICMP(ThreadVars *tv, Packet *p, void *data)
{
SCEnter();
- if (PacketTestAction(p, ACTION_REJECT)) {
+ if (PacketCheckAction(p, ACTION_REJECT)) {
int r = RejectSendLibnet11IPv6ICMP(tv, p, data, REJECT_DIR_SRC);
SCReturnInt(r);
- } else if (PacketTestAction(p, ACTION_REJECT_DST)) {
+ } else if (PacketCheckAction(p, ACTION_REJECT_DST)) {
int r = RejectSendLibnet11IPv6ICMP(tv, p, data, REJECT_DIR_DST);
SCReturnInt(r);
- } else if (PacketTestAction(p, ACTION_REJECT_BOTH)) {
+ } else if (PacketCheckAction(p, ACTION_REJECT_BOTH)) {
int r = RejectSendLibnet11IPv6ICMP(tv, p, data, REJECT_DIR_SRC);
r |= RejectSendLibnet11IPv6ICMP(tv, p, data, REJECT_DIR_DST);
SCReturnInt(r);
int socket;
if (p->afp_v.copy_mode == AFP_COPY_MODE_IPS) {
- if (PacketTestAction(p, ACTION_DROP)) {
+ if (PacketCheckAction(p, ACTION_DROP)) {
return;
}
}
When enabling promiscuous mode on Intel cards, 2 ICMPv6 packets are generated.
These get into the infinite cycle between the NIC and the switch in some cases */
if ((p->dpdk_v.copy_mode == DPDK_COPY_MODE_TAP ||
- (p->dpdk_v.copy_mode == DPDK_COPY_MODE_IPS && !PacketTestAction(p, ACTION_DROP)))
+ (p->dpdk_v.copy_mode == DPDK_COPY_MODE_IPS && !PacketCheckAction(p, ACTION_DROP)))
#if defined(RTE_LIBRTE_I40E_PMD) || defined(RTE_LIBRTE_IXGBE_PMD) || defined(RTE_LIBRTE_ICE_PMD)
&& !(PKT_IS_ICMPV6(p) && p->icmpv6h->type == 143)
#endif
IPFWpoll.events = POLLWRNORM;
#endif
- if (PacketTestAction(p, ACTION_DROP)) {
+ if (PacketCheckAction(p, ACTION_DROP)) {
verdict = IPFW_DROP;
} else {
verdict = IPFW_ACCEPT;
flow_match.gfi = 1; /* Generate FlowInfo records */
flow_match.tau = 1; /* tcp automatic unlearn */
- if (PacketTestAction(p, ACTION_DROP)) {
+ if (PacketCheckAction(p, ACTION_DROP)) {
flow_match.keySetId = NAPATECH_FLOWTYPE_DROP;
} else {
if (is_inline) {
* before releasing the Napatech buffer back to NTService.
*/
#ifdef NAPATECH_ENABLE_BYPASS
- if (is_inline && PacketTestAction(p, ACTION_DROP)) {
+ if (is_inline && PacketCheckAction(p, ACTION_DROP)) {
p->ntpv.dyn3->wireLength = 0;
}
static TmEcode NetmapWritePacket(NetmapThreadVars *ntv, Packet *p)
{
if (ntv->copy_mode == NETMAP_COPY_MODE_IPS) {
- if (PacketTestAction(p, ACTION_DROP)) {
+ if (PacketCheckAction(p, ACTION_DROP)) {
return TM_ECODE_OK;
}
}
{
uint32_t verdict = NF_ACCEPT;
- if (PacketTestAction(p, ACTION_DROP)) {
+ if (PacketCheckAction(p, ACTION_DROP)) {
verdict = NF_DROP;
} else {
switch (nfq_config.mode) {
#ifdef COUNTERS
static inline void UpdateCounters(NFQQueueVars *t, const Packet *p)
{
- if (PacketTestAction(p, ACTION_DROP)) {
+ if (PacketCheckAction(p, ACTION_DROP)) {
t->dropped++;
} else {
if (p->flags & PKT_STREAM_MODIFIED) {
/* DROP simply means we do nothing; the WinDivert driver does the rest.
*/
- if (PacketTestAction(p, ACTION_DROP)) {
+ if (PacketCheckAction(p, ACTION_DROP)) {
#ifdef COUNTERS
SCMutexLock(&wd_qv->counters_mutex);
wd_qv->dropped++;
SCLogDebug("EXCEPTION_POLICY_PASS_PACKET");
DecodeSetNoPayloadInspectionFlag(p);
DecodeSetNoPacketInspectionFlag(p);
- PacketPass(p);
break;
}
}