From fb1006d0379fc12b0f152f9e9a547699553e4591 Mon Sep 17 00:00:00 2001 From: fooinha Date: Sun, 20 Nov 2016 23:19:33 +0000 Subject: [PATCH] irc: output logging wip #6 --- src/app-layer-irc.c | 95 ++++++++++++++++++++++++++++++++------------- src/app-layer-irc.h | 2 + src/log-irclog.c | 6 +-- 3 files changed, 74 insertions(+), 29 deletions(-) diff --git a/src/app-layer-irc.c b/src/app-layer-irc.c index cf60f1831d96..571bc17a4bd0 100644 --- a/src/app-layer-irc.c +++ b/src/app-layer-irc.c @@ -206,7 +206,7 @@ static void IRCTransactionFree(IRCTransaction *tx, IRCState *state) if (tx->response_cmd_line != NULL) SCFree(tx->response_cmd_line); //TODO: DNSDecrMemcap((sizeof(DNSQueryEntry) + q->len), state); - + /* AppLayerDecoderEventsFreeEvents(&tx->decoder_events); @@ -285,9 +285,9 @@ static char * IRCCopyInput(uint8_t *input, uint32_t input_len) /** \brief Function to parse IRC client command . * - * \param input - - * \param input_len - - * \param cmd_len - + * \param input - + * \param input_len - + * \param cmd_len - */ static char * IRCParseCommandAlloc(uint8_t *input, uint32_t input_len, uint32_t* cmd_len) { @@ -395,7 +395,7 @@ static int IRCParseRequest(Flow *f, void *state, AppLayerParserState *pstate, //TODO: dns_state->curr = tx; SCLogDebug("IRC = new tx with internal num %u", tx->tx_num); //TODO: dns_state->unreplied_cnt++; - + uint32_t command_size = 0; char * cmd = IRCParseCommandAlloc(input, input_len, &command_size); @@ -418,7 +418,6 @@ static int IRCParseRequest(Flow *f, void *state, AppLayerParserState *pstate, memcpy(save, input+command_size+1, cmd_arg_sz); IRCParseCommandArgTrim(save, cmd_arg_sz); } - irc_state->transaction_max++; goto end; } } @@ -437,7 +436,7 @@ static int IRCParseRequest(Flow *f, void *state, AppLayerParserState *pstate, int cmd_not_found = 1; /* Check for unknown command and */ for (size_t i = 0 ; i < num_irc_commands -1 ; ++i) { - if (command_size == irc_commands[i].size && + if (command_size == irc_commands[i].size && SCMemcmp(input, irc_commands[i].name, command_size) == 0 ) { cmd_not_found = 0; break; @@ -457,9 +456,10 @@ static int IRCParseRequest(Flow *f, void *state, AppLayerParserState *pstate, tx->request_cmd_line = IRCParseRequestCopyLine(input); tx->request_len = input_len; tx->request = IRCCopyInput(input, input_len); - SCLogInfo("IRC REQUEST TXLIST:[%p] CMD:[%s] INPUT:[%s] LEN:[%d] BAD_CMD=[%d]", + SCLogInfo("IRC REQUEST TXLIST:[%p] CMD:[%s] INPUT:[%s] LEN:[%d] BAD_CMD=[%d]", &irc_state->tx_list, tx->request_cmd, tx->request, tx->request_len, tx->bad_cmd); + irc_state->curr_tx = tx; TAILQ_INSERT_TAIL(&irc_state->tx_list, tx, next); } SCReturnInt(1); @@ -474,7 +474,7 @@ static int IRCParseResponse(Flow *f, void *state, AppLayerParserState *pstate, { SCEnter(); -//#ifdef DEBUG +#ifdef DEBUG // AppLayerParserStatePrintDetails(pstate); char * cpy = IRCCopyInput(input, input_len); @@ -492,7 +492,7 @@ static int IRCParseResponse(Flow *f, void *state, AppLayerParserState *pstate, SCLogInfo("IRC = RSP INPUT NULL OR EMPTY "); SCReturnInt(-1); } -//#endif +#endif IRCState *irc_state = (IRCState *)state; if (irc_state == NULL) { @@ -501,20 +501,13 @@ static int IRCParseResponse(Flow *f, void *state, AppLayerParserState *pstate, IRCTransaction *tx = TAILQ_LAST(&irc_state->tx_list, _list); if (tx) { - /* Update response on last transaction */ tx->response_len = input_len; tx->response = IRCCopyInput(input, input_len); SCLogInfo("TX=%d, IRC RESPONSE INPUT: %s [%d]", tx->tx_num, tx->response, tx->response_len); - - } else { - SCLogInfo("IRC : Failed to get last transaction"); } - if (irc_state->cli.quitted) { - SCReturnInt(1); - } - if (*input == ':') { + if (input && *input == ':') { if (irc_state->srv.hostname == NULL) { /* Sets irc hostanme */ uint32_t host_size = IRCParseCommandEndOffset(input+1, input_len-1); @@ -537,6 +530,8 @@ void IRCSetTxLogged(void *alstate, void *tx, uint32_t logger) { IRCTransaction *irc_tx = (IRCTransaction *)tx; irc_tx->logged |= logger; + SCLogInfo("SetTxLogger: id:[%d] cli:[%s] srv:[%s] val:[%d]", + irc_tx->tx_num, irc_tx->request_cmd_line, irc_tx->response_cmd_line, logger); } /** @@ -545,9 +540,12 @@ void IRCSetTxLogged(void *alstate, void *tx, uint32_t logger) int IRCGetTxLogged(void *alstate, void *tx, uint32_t logger) { IRCTransaction *irc_tx = (IRCTransaction *)tx; - if (irc_tx->logged & logger) + SCLogInfo("GetTxLogger: id:[%d] cli:[%s] srv:[%s] logged:[%d] val:[%d]", + irc_tx->tx_num, irc_tx->request_cmd_line, irc_tx->response_cmd_line, + irc_tx->logged, logger); + if (irc_tx->logged & logger) { return 1; - + } return 0; } @@ -560,10 +558,11 @@ void *IRCGetTx(void *alstate, uint64_t tx_id) IRCState *irc_state = (IRCState *)alstate; IRCTransaction *tx = NULL; - /* fast track: try the current tx */ - //TODO: fast track - - /* no luck with the fast tracks, do the full list walk */ + if (irc_state->curr_tx == NULL) + return NULL; + if (irc_state->curr_tx->tx_num == tx_id) + return irc_state->curr_tx; + TAILQ_FOREACH(tx, &irc_state->tx_list, next) { SCLogDebug("tx->tx_num %u, tx_id %"PRIu64, tx->tx_num, (tx_id+1)); if ((tx_id+1) != tx->tx_num) @@ -586,6 +585,30 @@ uint64_t IRCGetTxCnt(void *alstate) return (uint64_t)irc_state->transaction_max; } +static void IRCStateTransactionFree (void *state, uint64_t tx_id) +{ + IRCState *irc_state = state; + + if (irc_state == NULL) { + return; + } + + IRCTransaction *tx = NULL; + TAILQ_FOREACH(tx, &irc_state->tx_list, next) { + if (tx_id < tx->tx_num) + break; + else if (tx_id > tx->tx_num) + continue; + + if (tx == irc_state->curr_tx) + irc_state->curr_tx = NULL; + + TAILQ_REMOVE(&irc_state->tx_list, tx, next); + IRCTransactionFree(tx, state); + break; + } +} + /** * \brief TODO: */ @@ -642,7 +665,11 @@ static void IRCStateFree(void *state) int IRCGetAlstateProgress(void *tx, uint8_t direction) { - if (direction & STREAM_TOCLIENT) { + IRCTransaction *irc_tx = (IRCTransaction *)tx; + + if (irc_tx && + (irc_tx->request_cmd_line || irc_tx->response_cmd_line) && + (direction & STREAM_TOCLIENT)) { return 1; } return 0; @@ -691,6 +718,19 @@ static int IRCRegisterPatternsForProtocolDetection(void) return 0; } +static DetectEngineState *IRCGetTxDetectState(void *vtx) +{ + IRCTransaction *tx = (IRCTransaction *)vtx; + return tx->de_state; +} + +static int IRCSetTxDetectState(void *state, void *vtx, DetectEngineState *s) +{ + IRCTransaction *tx = (IRCTransaction *)vtx; + tx->de_state = s; + return 0; +} + /** \brief Function to register the IRC protocol parsers and other functions */ void RegisterIRCParsers(void) @@ -704,11 +744,14 @@ void RegisterIRCParsers(void) } if (AppLayerParserConfParserEnabled("tcp", proto_name)) { + AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_IRC, IRCStateAlloc, IRCStateFree); AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_IRC, STREAM_TOSERVER, IRCParseRequest); AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_IRC, STREAM_TOCLIENT, IRCParseResponse); - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_IRC, IRCStateAlloc, IRCStateFree); AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_IRC, STREAM_TOSERVER | STREAM_TOCLIENT) ; + AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_IRC, NULL, + IRCGetTxDetectState, IRCSetTxDetectState); + AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_IRC, IRCStateTransactionFree); AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_IRC, IRCGetTx); AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_IRC, IRCGetTxCnt); AppLayerParserRegisterLoggerFuncs(IPPROTO_TCP, ALPROTO_IRC, IRCGetTxLogged, IRCSetTxLogged); diff --git a/src/app-layer-irc.h b/src/app-layer-irc.h index 56d5acffae11..c7857e894ad5 100644 --- a/src/app-layer-irc.h +++ b/src/app-layer-irc.h @@ -47,10 +47,12 @@ typedef struct IRCTransaction_ { char *response_cmd_line; /**< irc server response code/command line */ uint32_t logged; /**< flags for loggers done logging */ uint8_t bad_cmd; /**< irc command */ + DetectEngineState *de_state; TAILQ_ENTRY(IRCTransaction_) next; /**< the next transaction */ } IRCTransaction; typedef struct IRCState_ { + IRCTransaction *curr_tx; IRCServer srv; IRCClient cli; TAILQ_HEAD(_list, IRCTransaction_) tx_list; /**< transaction list */ diff --git a/src/log-irclog.c b/src/log-irclog.c index 393b9a9ce17c..4ed6c2bb16b5 100644 --- a/src/log-irclog.c +++ b/src/log-irclog.c @@ -52,7 +52,6 @@ int LogIrcLogger(ThreadVars *tv, void *data, const Packet *p, Flow *f, void *sta { SCEnter(); - if (!(PKT_IS_TCP(p))) { SCReturnInt(TM_ECODE_OK); } @@ -100,7 +99,7 @@ int LogIrcLogger(ThreadVars *tv, void *data, const Packet *p, Flow *f, void *sta char timebuf[64] = {0}; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - MemBufferWriteString( aft->buffer, + MemBufferWriteString( aft->buffer, "%s [**] " /* timestamp */ "%s:%" PRIu16 " -> %s:%" PRIu16 " [**] " /* flow */ "%s [**] " /* server name */ @@ -125,12 +124,13 @@ int LogIrcLogger(ThreadVars *tv, void *data, const Packet *p, Flow *f, void *sta irctx->bad_cmd); SCMutexLock(&irclog->file_ctx->fp_mutex); + ++aft->cmds_cnt; irclog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), MEMBUFFER_OFFSET(aft->buffer), irclog->file_ctx); SCMutexUnlock(&irclog->file_ctx->fp_mutex); end: - SCReturnInt(TM_ECODE_OK); + SCReturnInt(0); }