*
* \return 0 if ok
*/
-static int EventToImpact(PacketAlert *pa, Packet *p, idmef_alert_t *alert)
+static int EventToImpact(const PacketAlert *pa, const Packet *p, idmef_alert_t *alert)
{
int ret;
prelude_string_t *str;
*
* \return 0 if ok
*/
-static int EventToSourceTarget(Packet *p, idmef_alert_t *alert)
+static int EventToSourceTarget(const Packet *p, idmef_alert_t *alert)
{
int ret;
idmef_node_t *node;
*
* \return 0 if ok
*/
-static int PacketToDataV4(Packet *p, PacketAlert *pa, idmef_alert_t *alert)
+static int PacketToDataV4(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert)
{
SCEnter();
*
* \return 0 if ok
*/
-static int PacketToDataV6(Packet *p, PacketAlert *pa, idmef_alert_t *alert)
+static int PacketToDataV6(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert)
{
return 0;
}
*
* \return 0 if ok
*/
-static int PacketToData(Packet *p, PacketAlert *pa, idmef_alert_t *alert, AlertPreludeCtx *ctx)
+static int PacketToData(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert, AlertPreludeCtx *ctx)
{
SCEnter();
*
* \return 0 if ok
*/
-static int EventToReference(PacketAlert *pa, Packet *p, idmef_classification_t *class)
+static int EventToReference(const PacketAlert *pa, const Packet *p, idmef_classification_t *class)
{
int ret;
prelude_string_t *str;
return -1;
}
-
-/**
- * \brief Handle Suricata alert: convert it to and IDMEF alert (see RFC 4765)
- * and send it asynchronously (so, this function does not block and returns
- * immediately).
- * If the destination Prelude Manager is not available, the alert is spooled
- * (and the function also returns immediately).
- * An IDMEF object is created, and all available information is added: IP packet
- * header and data, rule signature ID, additional data like URL pointing to
- * rule description, CVE, etc.
- * The IDMEF alert has a reference to all created objects, so freeing it will
- * automatically free all allocated memory.
- *
- * \note This function is thread safe.
- *
- * \return TM_ECODE_OK if ok, else TM_ECODE_FAILED
- */
-static TmEcode AlertPrelude (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
-{
- AlertPreludeThread *apn = (AlertPreludeThread *)data;
- int ret;
- idmef_time_t *time;
- idmef_alert_t *alert;
- prelude_string_t *str;
- idmef_message_t *idmef = NULL;
- idmef_classification_t *class;
- PacketAlert *pa;
-
- SCEnter();
-
- if (apn == NULL || apn->ctx == NULL) {
- SCReturnInt(TM_ECODE_FAILED);
- }
-
- if (p->alerts.cnt == 0)
- SCReturnInt(TM_ECODE_OK);
-
- if ( !IPH_IS_VALID(p) )
- SCReturnInt(TM_ECODE_OK);
-
- /* XXX which one to add to this alert? Lets see how Snort solves this.
- * For now just take last alert. */
- pa = &p->alerts.alerts[p->alerts.cnt-1];
- if (pa->s == NULL)
- goto err;
-
- ret = idmef_message_new(&idmef);
- if ( ret < 0 )
- SCReturnInt(TM_ECODE_FAILED);
-
- ret = idmef_message_new_alert(idmef, &alert);
- if ( ret < 0 )
- goto err;
-
- ret = idmef_alert_new_classification(alert, &class);
- if ( ret < 0 )
- goto err;
-
- if (pa->s->msg) {
- ret = idmef_classification_new_text(class, &str);
- if ( ret < 0 )
- goto err;
-
- prelude_string_set_ref(str, pa->s->msg);
- }
-
- ret = EventToImpact(pa, p, alert);
- if ( ret < 0 )
- goto err;
-
- ret = EventToReference(pa, p, class);
- if ( ret < 0 )
- goto err;
-
- ret = EventToSourceTarget(p, alert);
- if ( ret < 0 )
- goto err;
-
- ret = PacketToData(p, pa, alert, apn->ctx);
- if ( ret < 0 )
- goto err;
-
- if (PKT_IS_TCP(p) && (pa->flags & PACKET_ALERT_FLAG_STATE_MATCH)) {
- uint8_t flag;
- if (p->flowflags & FLOW_PKT_TOSERVER) {
- flag = FLOW_PKT_TOCLIENT;
- } else {
- flag = FLOW_PKT_TOSERVER;
- }
- ret = StreamSegmentForEach(p, flag,
- PreludePrintStreamSegmentCallback,
- (void *)alert);
- }
- if (ret < 0)
- goto err;
-
- ret = idmef_alert_new_detect_time(alert, &time);
- if ( ret < 0 )
- goto err;
- idmef_time_set_from_timeval(time, &p->ts);
-
- ret = idmef_time_new_from_gettimeofday(&time);
- if ( ret < 0 )
- goto err;
- idmef_alert_set_create_time(alert, time);
-
- idmef_alert_set_analyzer(alert, idmef_analyzer_ref(prelude_client_get_analyzer(apn->ctx->client)), IDMEF_LIST_PREPEND);
-
- /* finally, send event */
- prelude_client_send_idmef(apn->ctx->client, idmef);
- idmef_message_destroy(idmef);
-
- SCReturnInt(TM_ECODE_OK);
-
-err:
- if (idmef != NULL)
- idmef_message_destroy(idmef);
- SCReturnInt(TM_ECODE_FAILED);
-}
-
/**
* \brief Initialize thread-specific data. Each thread structure contains
* a pointer to the \a AlertPreludeCtx context.
SCReturnPtr((void*)output_ctx, "OutputCtx");
}
+static int AlertPreludeCondition(ThreadVars *tv, const Packet *p) {
+ if (p->alerts.cnt == 0)
+ return FALSE;
+ if (!IPH_IS_VALID(p))
+ return FALSE;
+ return TRUE;
+}
+
+/**
+ * \brief Handle Suricata alert: convert it to and IDMEF alert (see RFC 4765)
+ * and send it asynchronously (so, this function does not block and returns
+ * immediately).
+ * If the destination Prelude Manager is not available, the alert is spooled
+ * (and the function also returns immediately).
+ * An IDMEF object is created, and all available information is added: IP packet
+ * header and data, rule signature ID, additional data like URL pointing to
+ * rule description, CVE, etc.
+ * The IDMEF alert has a reference to all created objects, so freeing it will
+ * automatically free all allocated memory.
+ *
+ * \note This function is thread safe.
+ *
+ * \return TM_ECODE_OK if ok, else TM_ECODE_FAILED
+ */
+static int AlertPreludeLogger(ThreadVars *tv, void *thread_data, const Packet *p) {
+ AlertPreludeThread *apn = (AlertPreludeThread *)thread_data;
+ int ret;
+ idmef_time_t *time;
+ idmef_alert_t *alert;
+ prelude_string_t *str;
+ idmef_message_t *idmef = NULL;
+ idmef_classification_t *class;
+ const PacketAlert *pa;
+
+ SCEnter();
+
+ if (apn == NULL || apn->ctx == NULL) {
+ SCReturnInt(TM_ECODE_FAILED);
+ }
+
+ if (p->alerts.cnt == 0)
+ SCReturnInt(TM_ECODE_OK);
+
+ if ( !IPH_IS_VALID(p) )
+ SCReturnInt(TM_ECODE_OK);
+
+ /* XXX which one to add to this alert? Lets see how Snort solves this.
+ * For now just take last alert. */
+ pa = &p->alerts.alerts[p->alerts.cnt-1];
+ if (pa->s == NULL)
+ goto err;
+
+ ret = idmef_message_new(&idmef);
+ if ( ret < 0 )
+ SCReturnInt(TM_ECODE_FAILED);
+
+ ret = idmef_message_new_alert(idmef, &alert);
+ if ( ret < 0 )
+ goto err;
+
+ ret = idmef_alert_new_classification(alert, &class);
+ if ( ret < 0 )
+ goto err;
+
+ if (pa->s->msg) {
+ ret = idmef_classification_new_text(class, &str);
+ if ( ret < 0 )
+ goto err;
+
+ prelude_string_set_ref(str, pa->s->msg);
+ }
+
+ ret = EventToImpact(pa, p, alert);
+ if ( ret < 0 )
+ goto err;
+
+ ret = EventToReference(pa, p, class);
+ if ( ret < 0 )
+ goto err;
+
+ ret = EventToSourceTarget(p, alert);
+ if ( ret < 0 )
+ goto err;
+
+ ret = PacketToData(p, pa, alert, apn->ctx);
+ if ( ret < 0 )
+ goto err;
+
+ if (PKT_IS_TCP(p) && (pa->flags & PACKET_ALERT_FLAG_STATE_MATCH)) {
+ uint8_t flag;
+ if (p->flowflags & FLOW_PKT_TOSERVER) {
+ flag = FLOW_PKT_TOCLIENT;
+ } else {
+ flag = FLOW_PKT_TOSERVER;
+ }
+ ret = StreamSegmentForEach(p, flag,
+ PreludePrintStreamSegmentCallback,
+ (void *)alert);
+ }
+ if (ret < 0)
+ goto err;
+
+ ret = idmef_alert_new_detect_time(alert, &time);
+ if ( ret < 0 )
+ goto err;
+ idmef_time_set_from_timeval(time, &p->ts);
+
+ ret = idmef_time_new_from_gettimeofday(&time);
+ if ( ret < 0 )
+ goto err;
+ idmef_alert_set_create_time(alert, time);
+
+ idmef_alert_set_analyzer(alert, idmef_analyzer_ref(prelude_client_get_analyzer(apn->ctx->client)), IDMEF_LIST_PREPEND);
+
+ /* finally, send event */
+ prelude_client_send_idmef(apn->ctx->client, idmef);
+ idmef_message_destroy(idmef);
+
+ SCReturnInt(TM_ECODE_OK);
+
+err:
+ if (idmef != NULL)
+ idmef_message_destroy(idmef);
+ SCReturnInt(TM_ECODE_FAILED);
+
+}
+
void TmModuleAlertPreludeRegister (void) {
tmm_modules[TMM_ALERTPRELUDE].name = "AlertPrelude";
tmm_modules[TMM_ALERTPRELUDE].ThreadInit = AlertPreludeThreadInit;
- tmm_modules[TMM_ALERTPRELUDE].Func = AlertPrelude;
+ tmm_modules[TMM_ALERTPRELUDE].Func = NULL;
tmm_modules[TMM_ALERTPRELUDE].ThreadDeinit = AlertPreludeThreadDeinit;
tmm_modules[TMM_ALERTPRELUDE].cap_flags = 0;
- OutputRegisterModule("AlertPrelude", "alert-prelude", AlertPreludeInitCtx);
+ OutputRegisterPacketModule("AlertPrelude", "alert-prelude", AlertPreludeInitCtx,
+ AlertPreludeLogger, AlertPreludeCondition);
}
#endif /* PRELUDE */