From 051b5751e279ca22346a627d047d228535b72925 Mon Sep 17 00:00:00 2001 From: fooinha Date: Sun, 20 Nov 2016 16:46:20 +0000 Subject: [PATCH] irc: output logging wip #5 --- src/app-layer-irc.c | 141 ++++++++++++++++++++++++++------------------ src/app-layer-irc.h | 27 ++++----- src/log-irclog.c | 33 +++++++++-- 3 files changed, 122 insertions(+), 79 deletions(-) diff --git a/src/app-layer-irc.c b/src/app-layer-irc.c index 581ef3b7b1db..cf60f1831d96 100644 --- a/src/app-layer-irc.c +++ b/src/app-layer-irc.c @@ -199,29 +199,15 @@ static void IRCTransactionFree(IRCTransaction *tx, IRCState *state) SCFree(tx->request); if (tx->response != NULL) SCFree(tx->response); - + if (tx->request_cmd != NULL) + SCFree(tx->request_cmd); + if (tx->request_cmd_line != NULL) + SCFree(tx->request_cmd_line); + if (tx->response_cmd_line != NULL) + SCFree(tx->response_cmd_line); //TODO: DNSDecrMemcap((sizeof(DNSQueryEntry) + q->len), state); /* - DNSQueryEntry *q = NULL; - while ((q = TAILQ_FIRST(&tx->query_list))) { - TAILQ_REMOVE(&tx->query_list, q, next); - DNSDecrMemcap((sizeof(DNSQueryEntry) + q->len), state); - SCFree(q); - } - - DNSAnswerEntry *a = NULL; - while ((a = TAILQ_FIRST(&tx->answer_list))) { - TAILQ_REMOVE(&tx->answer_list, a, next); - DNSDecrMemcap((sizeof(DNSAnswerEntry) + a->fqdn_len + a->data_len), state); - SCFree(a); - } - while ((a = TAILQ_FIRST(&tx->authority_list))) { - TAILQ_REMOVE(&tx->authority_list, a, next); - DNSDecrMemcap((sizeof(DNSAnswerEntry) + a->fqdn_len + a->data_len), state); - SCFree(a); - } - AppLayerDecoderEventsFreeEvents(&tx->decoder_events); if (tx->de_state != NULL) { @@ -277,7 +263,8 @@ static uint32_t IRCParseCommandEndOffset(uint8_t *input, uint32_t input_len) } return 0; } - +/** + */ static char * IRCCopyInput(uint8_t *input, uint32_t input_len) { if (! input) @@ -290,7 +277,7 @@ static char * IRCCopyInput(uint8_t *input, uint32_t input_len) if (!ret) return NULL; - memset(ret,0, input_len+1); + memset(ret, 0, input_len+1); memcpy(ret, input, input_len); return ret; @@ -324,6 +311,45 @@ static char * IRCParseCommandAlloc(uint8_t *input, uint32_t input_len, uint32_t* } +static char * IRCParseRequestCopyLine(uint8_t *input) +{ + + if (! input) { + return NULL; + } + + char *end = strchr((char *)input, '\r'); + if (end == NULL) + end = strchr((char *)input, '\n'); + if (end != NULL) { + uint32_t len = end-(char *)input; + return IRCCopyInput((uint8_t *)input, len); + } + + return NULL; +} + +static char * IRCParseResponseCopyLine(uint8_t *input) +{ + if (! input) { + return NULL; + } + + char * sep = strchr((char *)input, ' '); + if (sep != NULL) { + sep++; + char *end = strchr(sep, '\r'); + if (end == NULL) + end = strchr(sep, '\n'); + if (end != NULL) { + uint32_t len = end-sep; + return IRCCopyInput((uint8_t *)sep, len); + } + } + + return NULL; +} + /** \brief Function to parse IRC client command request */ static int IRCParseRequest(Flow *f, void *state, AppLayerParserState *pstate, @@ -368,8 +394,8 @@ 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); @@ -411,28 +437,35 @@ 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 && SCMemcmp(input, irc_commands[i].name, command_size) == 0 ) { + if (command_size == irc_commands[i].size && + SCMemcmp(input, irc_commands[i].name, command_size) == 0 ) { cmd_not_found = 0; + break; } } if (cmd_not_found) { irc_state->cli.num_bad_cmds++; - tx->bad_cmd = 1; + if (tx) { + tx->bad_cmd = 1; + } } end: /* Insert transaction in queue*/ if (tx != NULL) { - tx->cmd = cmd; + tx->request_cmd = cmd; + 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] ", - &irc_state->tx_list, tx->cmd, tx->request, tx->request_len); + 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); TAILQ_INSERT_TAIL(&irc_state->tx_list, tx, next); } SCReturnInt(1); } + /** \brief Function to parse IRC server response */ static int IRCParseResponse(Flow *f, void *state, AppLayerParserState *pstate, @@ -441,25 +474,25 @@ static int IRCParseResponse(Flow *f, void *state, AppLayerParserState *pstate, { SCEnter(); -#ifdef DEBUG - AppLayerParserStatePrintDetails(pstate); +//#ifdef DEBUG +// AppLayerParserStatePrintDetails(pstate); char * cpy = IRCCopyInput(input, input_len); if (cpy) { - SCLogDebug("IRC = RSP :[%s]", cpy); + SCLogInfo("IRC = RSP :[%s]", cpy); SCFree(cpy); } else { - SCLogDebug("IRC = RSP :[%s]", ""); + SCLogInfo("IRC = RSP :[%s]", ""); } if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCLogDebug("IRC = RSP NULL AND EOF "); + SCLogInfo("IRC = RSP NULL AND EOF "); SCReturnInt(1); } else if (input == NULL || input_len == 0) { - SCLogDebug("IRC = RSP INPUT NULL OR EMPTY "); + SCLogInfo("IRC = RSP INPUT NULL OR EMPTY "); SCReturnInt(-1); } -#endif +//#endif IRCState *irc_state = (IRCState *)state; if (irc_state == NULL) { @@ -481,18 +514,19 @@ static int IRCParseResponse(Flow *f, void *state, AppLayerParserState *pstate, if (irc_state->cli.quitted) { SCReturnInt(1); } - if (irc_state->srv.hostname == NULL) { - /* Sets irc hostanme */ - if (*input == ':') { + if (*input == ':') { + if (irc_state->srv.hostname == NULL) { + /* Sets irc hostanme */ uint32_t host_size = IRCParseCommandEndOffset(input+1, input_len-1); - irc_state->srv.hostname = SCMalloc(host_size); - if (irc_state->srv.hostname != NULL) { - memset(irc_state->srv.hostname, 0, host_size); - memcpy(irc_state->srv.hostname, input+1, host_size); - IRCParseCommandArgTrim(irc_state->srv.hostname, host_size); - } + irc_state->srv.hostname = IRCCopyInput(input+1, host_size); } + + if (tx) { + tx->response_cmd_line = IRCParseResponseCopyLine(input); + } + } + SCReturnInt(1); } @@ -608,21 +642,10 @@ static void IRCStateFree(void *state) int IRCGetAlstateProgress(void *tx, uint8_t direction) { -// //IRCTransaction *irc_tx = (IRCTransaction *)tx; -// if (direction & STREAM_TOCLIENT) { -// /* response side of the tx is done if we parsed a reply -// * or if we tagged this tx as 'reply lost'. */ -// //TODO: return (dns_tx->replied|dns_tx->reply_lost) ? 1 : 0; -// return 1; -// } -// else { -// /* tx is only created if we have a complete request, -// * or if we lost the request. Either way, if we have -// * a tx it we consider the request complete. */ -// return 1; -// } - SCLogInfo("IRCGetAlstateProgress"); - return 0; //1; + if (direction & STREAM_TOCLIENT) { + return 1; + } + return 0; } diff --git a/src/app-layer-irc.h b/src/app-layer-irc.h index 74a60081392e..56d5acffae11 100644 --- a/src/app-layer-irc.h +++ b/src/app-layer-irc.h @@ -33,24 +33,21 @@ typedef struct IRCClient_ { } IRCClient; typedef struct IRCServer_ { - uint8_t *hostname; + char *hostname; } IRCServer; typedef struct IRCTransaction_ { - uint16_t tx_num; /**< internal: id */ - char *cmd; - - char *request; - uint8_t request_len; - - char *response; - uint8_t response_len; - - uint32_t logged; /**< flags for loggers done logging */ - uint8_t bad_cmd; - - TAILQ_ENTRY(IRCTransaction_) next; - //TODO: dns_state->unreplied_cnt++; + uint16_t tx_num; /**< internal: id */ + char *request; /**< irc client full request */ + uint8_t request_len; /**< irc client request len */ + char *request_cmd; /**< irc client command */ + char *request_cmd_line; /**< irc client command line*/ + char *response; /**< irc server response */ + uint8_t response_len; /**< irc server response len */ + char *response_cmd_line; /**< irc server response code/command line */ + uint32_t logged; /**< flags for loggers done logging */ + uint8_t bad_cmd; /**< irc command */ + TAILQ_ENTRY(IRCTransaction_) next; /**< the next transaction */ } IRCTransaction; typedef struct IRCState_ { diff --git a/src/log-irclog.c b/src/log-irclog.c index 5488236ebbe8..393b9a9ce17c 100644 --- a/src/log-irclog.c +++ b/src/log-irclog.c @@ -52,6 +52,7 @@ int LogIrcLogger(ThreadVars *tv, void *data, const Packet *p, Flow *f, void *sta { SCEnter(); + if (!(PKT_IS_TCP(p))) { SCReturnInt(TM_ECODE_OK); } @@ -59,6 +60,7 @@ int LogIrcLogger(ThreadVars *tv, void *data, const Packet *p, Flow *f, void *sta LogIrcLogThread *aft = (LogIrcLogThread *)data; LogIrcFileCtx *irclog = aft->irclog_ctx; IRCTransaction *irctx = (IRCTransaction *) tx; + IRCState *ircstate = (IRCState *) state; int ipproto = PKT_IS_IPV4(p) ? AF_INET: AF_INET6; char srcip[46], dstip[46]; @@ -95,11 +97,32 @@ int LogIrcLogger(ThreadVars *tv, void *data, const Packet *p, Flow *f, void *sta dp = p->sp; } - SCLogInfo( "[**][**] %s:%" PRIu16 " -> %s:%" PRIu16 " %lu: [%s] [%s] - [%s] \n", - srcip, sp, dstip, dp, tx_id, irctx->cmd, irctx->request, irctx->response); - - MemBufferWriteString( aft->buffer, "[**][**] %s:%" PRIu16 " -> %s:%" PRIu16 " %lu: [%s] [%s] - [%s] \n", - srcip, sp, dstip, dp, tx_id, irctx->cmd, irctx->request, irctx->response); + char timebuf[64] = {0}; + CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); + + MemBufferWriteString( aft->buffer, + "%s [**] " /* timestamp */ + "%s:%" PRIu16 " -> %s:%" PRIu16 " [**] " /* flow */ + "%s [**] " /* server name */ + "%s [**] " /* cmd */ + "%s [**] " /* client cmd line */ + "%s [**] " /* server cmd line */ +#ifdef DEBUG + "%s [**] " /* request */ + "%s [**] " /* response */ +#endif + "%d" /* bad command ? */ + "\n", + timebuf, + srcip, sp, dstip, dp, + ircstate->srv.hostname, + irctx->request_cmd, + irctx->request_cmd_line, + irctx->response_cmd_line, +#ifdef DEBUG + irctx->request, irctx->response, +#endif + irctx->bad_cmd); SCMutexLock(&irclog->file_ctx->fp_mutex); irclog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer),