int ReCalculateChecksum(Packet *p) { if (PKT_IS_IPV4(p)) { if (PKT_IS_TCP(p)) { /* TCP */ p->tcph->th_sum = 0; p->tcph->th_sum = TCPChecksum(p->ip4h->s_ip_addrs, (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p)), 0); } else if (PKT_IS_UDP(p)) { p->udph->uh_sum = 0; p->udph->uh_sum = UDPV4Checksum(p->ip4h->s_ip_addrs, (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN), 0); } /* IPV4 */ p->ip4h->ip_csum = 0; p->ip4h->ip_csum = IPV4Checksum((uint16_t *)p->ip4h, IPV4_GET_RAW_HLEN(p->ip4h), 0); } else if (PKT_IS_IPV6(p)) { /* just TCP for IPV6 */ if (PKT_IS_TCP(p)) { p->tcph->th_sum = 0; p->tcph->th_sum = TCPV6Checksum(p->ip6h->s_ip6_addrs, (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p)), 0); } else if (PKT_IS_UDP(p)) { p->udph->uh_sum = 0; p->udph->uh_sum = UDPV6Checksum(p->ip6h->s_ip6_addrs, (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN), 0); } } return 0; }
/** * \brief Pfring bypass callback function * * \param p a Packet to use information from to trigger bypass * \return 1 if bypass is successful, 0 if not */ static int PfringBypassCallback(Packet *p) { hw_filtering_rule r; /* Only bypass TCP and UDP */ if (!(PKT_IS_TCP(p) || PKT_IS_UDP(p))) { return 0; } /* Bypassing tunneled packets is currently not supported */ if (IS_TUNNEL_PKT(p)) { return 0; } r.rule_family_type = generic_flow_id_rule; r.rule_family.flow_id_rule.action = flow_drop_rule; r.rule_family.flow_id_rule.thread = 0; r.rule_family.flow_id_rule.flow_id = p->pfring_v.flow_id; SCLogDebug("Bypass set for flow ID = %u", p->pfring_v.flow_id); if (pfring_add_hw_rule(p->pfring_v.ptv->pd, &r) < 0) { return 0; } return 1; }
/** * \brief This function is used to match ftpbounce attacks * * \param t pointer to thread vars * \param det_ctx pointer to the pattern matcher thread * \param p pointer to the current packet * \param m pointer to the sigmatch but we don't use it since ftpbounce * has no options * \retval 0 no match, 1 if match */ int DetectFtpbounceMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m) { /** \todo VJ broken and no longer used */ #if 0 SCEnter(); uint16_t offset = 0; if (!(PKT_IS_TCP(p))) return 0; SigMatch *sm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); if (sm == NULL) return 0; DetectContentData *co = sm->ctx; if (co == NULL) return 0; MpmMatch *mm = det_ctx->mtc.match[co->id].top; SCLogDebug("Starting Offset: %u",mm->offset + co->content_len); offset = mm->offset + co->content_len; SCLogDebug("Payload: \"%s\"\nLen: %u Offset: %u\n", p->payload, p->payload_len, offset); return DetectFtpbounceMatchArgs(p->payload, p->payload_len, p->src.addr_data32[0], offset); #endif return 0; }
/** * \brief Recalculate the csum for a modified packet * * \param p packet to inspect */ void StreamTcpInlineRecalcCsum(Packet *p) { if (!(p->flags & PKT_STREAM_MODIFIED)) { SCReturn; } if (!(PKT_IS_TCP(p))) { SCReturn; } if (PKT_IS_IPV4(p)) { /* TCP */ p->tcph->th_sum = 0; p->tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p->ip4h->ip_src), (uint16_t *)p->tcph, (p->payload_len + p->tcpvars.hlen)); /* IPV4 */ p->ip4h->ip_csum = 0; p->ip4h->ip_csum = IPV4CalculateChecksum((uint16_t *)p->ip4h, IPV4_GET_RAW_HLEN(p->ip4h)); } else if (PKT_IS_IPV6(p)) { /* just TCP for IPV6 */ p->tcph->th_sum = 0; p->tcph->th_sum = TCPV6CalculateChecksum((uint16_t *)&(p->ip6h->ip6_src), (uint16_t *)p->tcph, (p->payload_len + p->tcpvars.hlen)); } SCReturn; }
static void LogFilestoreLogCreateMetaFile(Packet *p, File *ff, char *filename, int ipver) { char metafilename[PATH_MAX] = ""; snprintf(metafilename, sizeof(metafilename), "%s.meta", filename); FILE *fp = fopen(metafilename, "w+"); if (fp != NULL) { char timebuf[64]; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); fprintf(fp, "TIME: %s\n", timebuf); if (p->pcap_cnt > 0) { fprintf(fp, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt); } char srcip[46], dstip[46]; Port sp, dp; switch (ipver) { case AF_INET: PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); break; case AF_INET6: PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); break; default: strlcpy(srcip, "<unknown>", sizeof(srcip)); strlcpy(dstip, "<unknown>", sizeof(dstip)); break; } sp = p->sp; dp = p->dp; fprintf(fp, "SRC IP: %s\n", srcip); fprintf(fp, "DST IP: %s\n", dstip); fprintf(fp, "PROTO: %" PRIu32 "\n", p->proto); if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) { fprintf(fp, "SRC PORT: %" PRIu16 "\n", sp); fprintf(fp, "DST PORT: %" PRIu16 "\n", dp); } fprintf(fp, "HTTP URI: "); LogFilestoreMetaGetUri(fp, p, ff); fprintf(fp, "\n"); fprintf(fp, "HTTP HOST: "); LogFilestoreMetaGetHost(fp, p, ff); fprintf(fp, "\n"); fprintf(fp, "HTTP REFERER: "); LogFilestoreMetaGetReferer(fp, p, ff); fprintf(fp, "\n"); fprintf(fp, "FILENAME: "); PrintRawUriFp(fp, ff->name, ff->name_len); fprintf(fp, "\n"); fclose(fp); } }
/** * \internal * \brief This function is used to match packets with a given Seq number * * \param t pointer to thread vars * \param det_ctx pointer to the pattern matcher thread * \param p pointer to the current packet * \param m pointer to the sigmatch that we will cast into DetectSeqData * * \retval 0 no match * \retval 1 match */ static int DetectSeqMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m) { DetectSeqData *data = (DetectSeqData *)m->ctx; /* This is only needed on TCP packets */ if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) { return 0; } return (data->seq == TCP_GET_SEQ(p)) ? 1 : 0; }
/** * \internal * \brief This function is used to match packets with a given Ack number * * \param t pointer to thread vars * \param det_ctx pointer to the pattern matcher thread * \param p pointer to the current packet * \param m pointer to the sigmatch that we will cast into DetectAckData * * \retval 0 no match * \retval 1 match */ static int DetectAckMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) { const DetectAckData *data = (const DetectAckData *)ctx; /* This is only needed on TCP packets */ if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) { return 0; } return (data->ack == TCP_GET_ACK(p)) ? 1 : 0; }
/** * \internal * \brief This function is used to match flags on a packet with those passed via flags: * * \param t pointer to thread vars * \param det_ctx pointer to the pattern matcher thread * \param p pointer to the current packet * \param s pointer to the Signature * \param m pointer to the sigmatch * * \retval 0 no match * \retval 1 match */ static int DetectFlagsMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx) { SCEnter(); if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) { SCReturnInt(0); } const DetectFlagsData *de = (const DetectFlagsData *)ctx; const uint8_t flags = p->tcph->th_flags; return FlagsMatch(flags, de->modifier, de->flags, de->ignored_flags); }
/** * \brief Convert IP packet to an IDMEF alert (RFC 4765). * This function stores the alert SID (description and reference), * the payload of the packet, and pre-processed data. * * \return 0 if ok */ static int PacketToData(Packet *p, PacketAlert *pa, idmef_alert_t *alert, AlertPreludeCtx *ctx) { SCEnter(); if ( ! p ) SCReturnInt(0); AddIntData(alert, "snort_rule_sid", pa->s->id); AddIntData(alert, "snort_rule_rev", pa->s->rev); if (ctx->log_packet_header) { if ( PKT_IS_IPV4(p) ) PacketToDataV4(p, pa, alert); else if ( PKT_IS_IPV6(p) ) PacketToDataV6(p, pa, alert); if ( PKT_IS_TCP(p) ) { AddIntData(alert, "tcp_seq", ntohl(p->tcph->th_seq)); AddIntData(alert, "tcp_ack", ntohl(p->tcph->th_ack)); AddIntData(alert, "tcp_off", TCP_GET_RAW_OFFSET(p->tcph)); AddIntData(alert, "tcp_res", TCP_GET_RAW_X2(p->tcph)); AddIntData(alert, "tcp_flags", p->tcph->th_flags); AddIntData(alert, "tcp_win", ntohs(p->tcph->th_win)); AddIntData(alert, "tcp_sum", ntohs(p->tcph->th_sum)); AddIntData(alert, "tcp_urp", ntohs(p->tcph->th_urp)); } else if ( PKT_IS_UDP(p) ) { AddIntData(alert, "udp_len", ntohs(p->udph->uh_len)); AddIntData(alert, "udp_sum", ntohs(p->udph->uh_sum)); } else if ( PKT_IS_ICMPV4(p) ) { AddIntData(alert, "icmp_type", p->icmpv4h->type); AddIntData(alert, "icmp_code", p->icmpv4h->code); AddIntData(alert, "icmp_sum", ntohs(p->icmpv4h->checksum)); } } if (ctx->log_packet_content) AddByteData(alert, "payload", p->payload, p->payload_len); SCReturnInt(0); }
TmEcode RespondRejectFunc(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { int ret = 0; /* ACTION_REJECT defaults to rejecting the SRC */ if (!(p->action & ACTION_REJECT) && !(p->action & ACTION_REJECT_DST) && !(p->action & ACTION_REJECT_BOTH)) { return TM_ECODE_OK; } if (PKT_IS_IPV4(p)) { if (PKT_IS_TCP(p)) { ret = RejectSendIPv4TCP(tv, p, data); } else if(PKT_IS_UDP(p)) { ret = RejectSendIPv4ICMP(tv, p, data); } else { return TM_ECODE_OK; } } else if (PKT_IS_IPV6(p)) { if (PKT_IS_TCP(p)) { ret = RejectSendIPv6TCP(tv, p, data); } else if(PKT_IS_UDP(p)){ ret = RejectSendIPv6ICMP(tv, p, data); } else { return TM_ECODE_OK; } } else { /* we're only supporting IPv4 and IPv6 */ return TM_ECODE_OK; } if (ret) return TM_ECODE_FAILED; else return TM_ECODE_OK; }
int LogHttpLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id) { SCEnter(); if (!(PKT_IS_TCP(p))) { SCReturnInt(TM_ECODE_OK); } int r = 0; if (PKT_IS_IPV4(p)) { r = LogHttpLogIPWrapper(tv, thread_data, p, f, (HtpState *)state, (htp_tx_t *)tx, tx_id, AF_INET); } else if (PKT_IS_IPV6(p)) { r = LogHttpLogIPWrapper(tv, thread_data, p, f, (HtpState *)state, (htp_tx_t *)tx, tx_id, AF_INET6); } SCReturnInt(r); }
/** * \brief This function is used to match rpc request set on a packet with those passed via rpc * * \param t pointer to thread vars * \param det_ctx pointer to the pattern matcher thread * \param p pointer to the current packet * \param m pointer to the sigmatch that we will cast into DetectRpcData * * \retval 0 no match * \retval 1 match */ static int DetectRpcMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx) { /* PrintRawDataFp(stdout, p->payload, p->payload_len); */ const DetectRpcData *rd = (const DetectRpcData *)ctx; char *rpcmsg = (char *)p->payload; if (PKT_IS_TCP(p)) { /* if Rpc msg too small */ if (p->payload_len < 28) { SCLogDebug("TCP packet to small for the rpc msg (%u)", p->payload_len); return 0; } rpcmsg += 4; } else if (PKT_IS_UDP(p)) { /* if Rpc msg too small */ if (p->payload_len < 24) { SCLogDebug("UDP packet to small for the rpc msg (%u)", p->payload_len); return 0; } } else { SCLogDebug("No valid proto for the rpc message"); return 0; } /* Point through the rpc msg structure. Use ntohl() to compare values */ RpcMsg *msg = (RpcMsg *)rpcmsg; /* If its not a call, no match */ if (ntohl(msg->type) != 0) { SCLogDebug("RPC message type is not a call"); return 0; } if (ntohl(msg->prog) != rd->program) return 0; if ((rd->flags & DETECT_RPC_CHECK_VERSION) && ntohl(msg->vers) != rd->program_version) return 0; if ((rd->flags & DETECT_RPC_CHECK_PROCEDURE) && ntohl(msg->proc) != rd->procedure) return 0; SCLogDebug("prog:%u pver:%u proc:%u matched", ntohl(msg->prog), ntohl(msg->vers), ntohl(msg->proc)); return 1; }
static void PrefilterPacketFlagsMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx) { if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) { SCReturn; } const PrefilterPacketHeaderCtx *ctx = pectx; if (PrefilterPacketHeaderExtraMatch(ctx, p) == FALSE) return; const uint8_t flags = p->tcph->th_flags; if (FlagsMatch(flags, ctx->v1.u8[0], ctx->v1.u8[1], ctx->v1.u8[2])) { SCLogDebug("packet matches TCP flags %02x", ctx->v1.u8[1]); PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt); } }
/** * \brief This function is used to match Stream size rule option on a packet with those passed via stream_size: * * \param t pointer to thread vars * \param det_ctx pointer to the pattern matcher thread * \param p pointer to the current packet * \param m pointer to the sigmatch that we will cast into DetectStreamSizeData * * \retval 0 no match * \retval 1 match */ int DetectStreamSizeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m) { int ret = 0; DetectStreamSizeData *sd = (DetectStreamSizeData *) m->ctx; if (!(PKT_IS_TCP(p))) return ret; uint32_t csdiff = 0; uint32_t ssdiff = 0; if (p->flow == NULL) return ret; TcpSession *ssn = (TcpSession *)p->flow->protoctx; if (ssn == NULL) return ret; if (sd->flags & STREAM_SIZE_SERVER) { /* get the server stream size */ ssdiff = ssn->server.next_seq - ssn->server.isn; ret = DetectStreamSizeCompare(ssdiff, sd->ssize, sd->mode); } else if (sd->flags & STREAM_SIZE_CLIENT) { /* get the client stream size */ csdiff = ssn->client.next_seq - ssn->client.isn; ret = DetectStreamSizeCompare(csdiff, sd->ssize, sd->mode); } else if (sd->flags & STREAM_SIZE_BOTH) { ssdiff = ssn->server.next_seq - ssn->server.isn; csdiff = ssn->client.next_seq - ssn->client.isn; if (DetectStreamSizeCompare(ssdiff, sd->ssize, sd->mode) && DetectStreamSizeCompare(csdiff, sd->ssize, sd->mode)) ret = 1; } else if (sd->flags & STREAM_SIZE_EITHER) { ssdiff = ssn->server.next_seq - ssn->server.isn; csdiff = ssn->client.next_seq - ssn->client.isn; if (DetectStreamSizeCompare(ssdiff, sd->ssize, sd->mode) || DetectStreamSizeCompare(csdiff, sd->ssize, sd->mode)) ret = 1; } return ret; }
TmEcode LogHttpLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { SCEnter(); /* no flow, no htp state */ if (p->flow == NULL) { SCReturnInt(TM_ECODE_OK); } if (!(PKT_IS_TCP(p))) { SCReturnInt(TM_ECODE_OK); } if (PKT_IS_IPV4(p)) { SCReturnInt(LogHttpLogIPv4(tv, p, data, pq, postpq)); } else if (PKT_IS_IPV6(p)) { SCReturnInt(LogHttpLogIPv6(tv, p, data, pq, postpq)); } SCReturnInt(TM_ECODE_OK); }
/** \internal * \brief Condition function for TLS logger * \retval bool true or false -- log now? */ static int LogTlsCondition(ThreadVars *tv, const Packet *p) { if (p->flow == NULL) { return FALSE; } if (!(PKT_IS_TCP(p))) { return FALSE; } FLOWLOCK_RDLOCK(p->flow); uint16_t proto = FlowGetAppProtocol(p->flow); if (proto != ALPROTO_TLS) goto dontlog; SSLState *ssl_state = (SSLState *)FlowGetAppState(p->flow); if (ssl_state == NULL) { SCLogDebug("no tls state, so no request logging"); goto dontlog; } /* we only log the state once if we don't have to write * the cert due to tls.store keyword. */ if (!(ssl_state->server_connp.cert_log_flag & SSL_TLS_LOG_PEM) && (ssl_state->flags & SSL_AL_FLAG_STATE_LOGGED)) goto dontlog; if (ssl_state->server_connp.cert0_issuerdn == NULL || ssl_state->server_connp.cert0_subject == NULL) goto dontlog; /* todo: logic to log once */ FLOWLOCK_UNLOCK(p->flow); return TRUE; dontlog: FLOWLOCK_UNLOCK(p->flow); return FALSE; }
/** \internal * \brief Condition function for SSH logger * \retval bool true or false -- log now? */ static int JsonSshCondition(ThreadVars *tv, const Packet *p) { if (p->flow == NULL) { return FALSE; } if (!(PKT_IS_TCP(p))) { return FALSE; } FLOWLOCK_RDLOCK(p->flow); uint16_t proto = FlowGetAppProtocol(p->flow); if (proto != ALPROTO_SSH) goto dontlog; SshState *ssh_state = (SshState *)FlowGetAppState(p->flow); if (ssh_state == NULL) { SCLogDebug("no ssh state, so no logging"); goto dontlog; } /* we only log the state once */ if (ssh_state->cli_hdr.flags & SSH_FLAG_STATE_LOGGED) goto dontlog; if (ssh_state->cli_hdr.software_version == NULL || ssh_state->srv_hdr.software_version == NULL) goto dontlog; /* todo: logic to log once */ FLOWLOCK_UNLOCK(p->flow); return TRUE; dontlog: FLOWLOCK_UNLOCK(p->flow); return FALSE; }
TmEcode LogFilestoreLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { SCEnter(); int r = TM_ECODE_OK; /* no flow, no htp state */ if (p->flow == NULL) { SCReturnInt(TM_ECODE_OK); } if (!(PKT_IS_TCP(p))) { SCReturnInt(TM_ECODE_OK); } SCLogDebug("p->pcap_cnt %"PRIu64, p->pcap_cnt); if (PKT_IS_IPV4(p)) { r = LogFilestoreLogIPv4(tv, p, data, pq, postpq); } else if (PKT_IS_IPV6(p)) { r = LogFilestoreLogIPv6(tv, p, data, pq, postpq); } SCReturnInt(r); }
static TmEcode FlowWorker(ThreadVars *tv, Packet *p, void *data, PacketQueue *preq, PacketQueue *unused) { FlowWorkerThreadData *fw = data; void *detect_thread = SC_ATOMIC_GET(fw->detect_thread); SCLogDebug("packet %"PRIu64, p->pcap_cnt); /* update time */ if (!(PKT_IS_PSEUDOPKT(p))) { TimeSetByThread(tv->id, &p->ts); } /* handle Flow */ if (p->flags & PKT_WANTS_FLOW) { FLOWWORKER_PROFILING_START(p, PROFILE_FLOWWORKER_FLOW); FlowHandlePacket(tv, fw->dtv, p); if (likely(p->flow != NULL)) { DEBUG_ASSERT_FLOW_LOCKED(p->flow); if (FlowUpdate(p) == TM_ECODE_DONE) { FLOWLOCK_UNLOCK(p->flow); return TM_ECODE_OK; } } /* Flow is now LOCKED */ FLOWWORKER_PROFILING_END(p, PROFILE_FLOWWORKER_FLOW); /* if PKT_WANTS_FLOW is not set, but PKT_HAS_FLOW is, then this is a * pseudo packet created by the flow manager. */ } else if (p->flags & PKT_HAS_FLOW) { FLOWLOCK_WRLOCK(p->flow); } SCLogDebug("packet %"PRIu64" has flow? %s", p->pcap_cnt, p->flow ? "yes" : "no"); /* handle TCP and app layer */ if (p->flow && PKT_IS_TCP(p)) { SCLogDebug("packet %"PRIu64" is TCP. Direction %s", p->pcap_cnt, PKT_IS_TOSERVER(p) ? "TOSERVER" : "TOCLIENT"); DEBUG_ASSERT_FLOW_LOCKED(p->flow); /* if detect is disabled, we need to apply file flags to the flow * here on the first packet. */ if (detect_thread == NULL && ((PKT_IS_TOSERVER(p) && (p->flowflags & FLOW_PKT_TOSERVER_FIRST)) || (PKT_IS_TOCLIENT(p) && (p->flowflags & FLOW_PKT_TOCLIENT_FIRST)))) { DisableDetectFlowFileFlags(p->flow); } FLOWWORKER_PROFILING_START(p, PROFILE_FLOWWORKER_STREAM); StreamTcp(tv, p, fw->stream_thread, &fw->pq, NULL); FLOWWORKER_PROFILING_END(p, PROFILE_FLOWWORKER_STREAM); if (FlowChangeProto(p->flow)) { StreamTcpDetectLogFlush(tv, fw->stream_thread, p->flow, p, &fw->pq); } /* Packets here can safely access p->flow as it's locked */ SCLogDebug("packet %"PRIu64": extra packets %u", p->pcap_cnt, fw->pq.len); Packet *x; while ((x = PacketDequeue(&fw->pq))) { SCLogDebug("packet %"PRIu64" extra packet %p", p->pcap_cnt, x); // TODO do we need to call StreamTcp on these pseudo packets or not? //StreamTcp(tv, x, fw->stream_thread, &fw->pq, NULL); if (detect_thread != NULL) { FLOWWORKER_PROFILING_START(x, PROFILE_FLOWWORKER_DETECT); Detect(tv, x, detect_thread, NULL, NULL); FLOWWORKER_PROFILING_END(x, PROFILE_FLOWWORKER_DETECT); } // Outputs OutputLoggerLog(tv, x, fw->output_thread); /* put these packets in the preq queue so that they are * by the other thread modules before packet 'p'. */ PacketEnqueue(preq, x); } /* handle the app layer part of the UDP packet payload */ } else if (p->flow && p->proto == IPPROTO_UDP) { FLOWWORKER_PROFILING_START(p, PROFILE_FLOWWORKER_APPLAYERUDP); AppLayerHandleUdp(tv, fw->stream_thread->ra_ctx->app_tctx, p, p->flow); FLOWWORKER_PROFILING_END(p, PROFILE_FLOWWORKER_APPLAYERUDP); } /* handle Detect */ DEBUG_ASSERT_FLOW_LOCKED(p->flow); SCLogDebug("packet %"PRIu64" calling Detect", p->pcap_cnt); if (detect_thread != NULL) { FLOWWORKER_PROFILING_START(p, PROFILE_FLOWWORKER_DETECT); Detect(tv, p, detect_thread, NULL, NULL); FLOWWORKER_PROFILING_END(p, PROFILE_FLOWWORKER_DETECT); } // Outputs. OutputLoggerLog(tv, p, fw->output_thread); /* Release tcp segments. Done here after alerting can use them. */ if (p->flow != NULL && p->proto == IPPROTO_TCP) { FLOWWORKER_PROFILING_START(p, PROFILE_FLOWWORKER_TCPPRUNE); StreamTcpPruneSession(p->flow, p->flowflags & FLOW_PKT_TOSERVER ? STREAM_TOSERVER : STREAM_TOCLIENT); FLOWWORKER_PROFILING_END(p, PROFILE_FLOWWORKER_TCPPRUNE); } if (p->flow) { DEBUG_ASSERT_FLOW_LOCKED(p->flow); FLOWLOCK_UNLOCK(p->flow); } return TM_ECODE_OK; }
/** * \internal * \brief Write meta data on a single line json record */ static void LogFileWriteJsonRecord(LogFileLogThread *aft, const Packet *p, const File *ff, int ipver) { SCMutexLock(&aft->file_ctx->fp_mutex); /* As writes are done via the LogFileCtx, check for rotation here. */ if (aft->file_ctx->rotation_flag) { aft->file_ctx->rotation_flag = 0; if (SCConfLogReopen(aft->file_ctx) != 0) { SCLogWarning(SC_ERR_FOPEN, "Failed to re-open log file. " "Logging for this module will be disabled."); } } /* Bail early if no file pointer to write to (in the unlikely * event file rotation failed. */ if (aft->file_ctx->fp == NULL) { SCMutexUnlock(&aft->file_ctx->fp_mutex); return; } FILE *fp = aft->file_ctx->fp; char timebuf[64]; AppProto alproto = FlowGetAppProtocol(p->flow); CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); fprintf(fp, "{ "); if (ff->file_id > 0) fprintf(fp, "\"id\": %u, ", ff->file_id); fprintf(fp, "\"timestamp\": \""); PrintRawJsonFp(fp, (uint8_t *)timebuf, strlen(timebuf)); fprintf(fp, "\", "); if (p->pcap_cnt > 0) { fprintf(fp, "\"pcap_pkt_num\": %"PRIu64", ", p->pcap_cnt); } fprintf(fp, "\"ipver\": %d, ", ipver == AF_INET ? 4 : 6); char srcip[46], dstip[46]; Port sp, dp; switch (ipver) { case AF_INET: PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); break; case AF_INET6: PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); break; default: strlcpy(srcip, "<unknown>", sizeof(srcip)); strlcpy(dstip, "<unknown>", sizeof(dstip)); break; } sp = p->sp; dp = p->dp; fprintf(fp, "\"srcip\": \"%s\", ", srcip); fprintf(fp, "\"dstip\": \"%s\", ", dstip); fprintf(fp, "\"protocol\": %" PRIu32 ", ", p->proto); if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) { fprintf(fp, "\"sp\": %" PRIu16 ", ", sp); fprintf(fp, "\"dp\": %" PRIu16 ", ", dp); } if (alproto == ALPROTO_HTTP) { fprintf(fp, "\"http_uri\": \""); LogFileMetaGetUri(fp, p, ff); fprintf(fp, "\", "); fprintf(fp, "\"http_host\": \""); LogFileMetaGetHost(fp, p, ff); fprintf(fp, "\", "); fprintf(fp, "\"http_referer\": \""); LogFileMetaGetReferer(fp, p, ff); fprintf(fp, "\", "); fprintf(fp, "\"http_user_agent\": \""); LogFileMetaGetUserAgent(fp, p, ff); fprintf(fp, "\", "); } else if (p->flow->alproto == ALPROTO_SMTP) { /* Only applicable to SMTP */ LogFileMetaGetSmtp(fp, p, ff); } fprintf(fp, "\"filename\": \""); PrintRawJsonFp(fp, ff->name, ff->name_len); fprintf(fp, "\", "); #ifdef HAVE_MAGIC fprintf(fp, "\"magic\": \""); if (ff->magic) { PrintRawJsonFp(fp, (uint8_t *)ff->magic, strlen(ff->magic)); } else { fprintf(fp, "unknown"); } fprintf(fp, "\", "); #endif switch (ff->state) { case FILE_STATE_CLOSED: fprintf(fp, "\"state\": \"CLOSED\", "); #ifdef HAVE_NSS if (ff->flags & FILE_MD5) { fprintf(fp, "\"md5\": \""); size_t x; for (x = 0; x < sizeof(ff->md5); x++) { fprintf(fp, "%02x", ff->md5[x]); } fprintf(fp, "\", "); } if (ff->flags & FILE_SHA1) { fprintf(fp, "\"sha1\": \""); size_t x; for (x = 0; x < sizeof(ff->sha1); x++) { fprintf(fp, "%02x", ff->sha1[x]); } fprintf(fp, "\", "); } if (ff->flags & FILE_SHA256) { fprintf(fp, "\"sha256\": \""); size_t x; for (x = 0; x < sizeof(ff->sha256); x++) { fprintf(fp, "%02x", ff->sha256[x]); } fprintf(fp, "\", "); } #endif break; case FILE_STATE_TRUNCATED: fprintf(fp, "\"state\": \"TRUNCATED\", "); break; case FILE_STATE_ERROR: fprintf(fp, "\"state\": \"ERROR\", "); break; default: fprintf(fp, "\"state\": \"UNKNOWN\", "); break; } fprintf(fp, "\"stored\": %s, ", ff->flags & FILE_STORED ? "true" : "false"); fprintf(fp, "\"size\": %"PRIu64" ", FileSize(ff)); fprintf(fp, "}\n"); fflush(fp); SCMutexUnlock(&aft->file_ctx->fp_mutex); }
static TmEcode AlertDebugLogger(ThreadVars *tv, const Packet *p, void *thread_data) { AlertDebugLogThread *aft = (AlertDebugLogThread *)thread_data; int i; char timebuf[64]; const char *pkt_src_str = NULL; if (p->alerts.cnt == 0) return TM_ECODE_OK; MemBufferReset(aft->buffer); CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); MemBufferWriteString(aft->buffer, "+================\n" "TIME: %s\n", timebuf); if (p->pcap_cnt > 0) { MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt); } pkt_src_str = PktSrcToString(p->pkt_src); MemBufferWriteString(aft->buffer, "PKT SRC: %s\n", pkt_src_str); char srcip[46], dstip[46]; if (PKT_IS_IPV4(p)) { PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); } else if (PKT_IS_IPV6(p)) { PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); } MemBufferWriteString(aft->buffer, "SRC IP: %s\n" "DST IP: %s\n" "PROTO: %" PRIu32 "\n", srcip, dstip, p->proto); if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) { MemBufferWriteString(aft->buffer, "SRC PORT: %" PRIu32 "\n" "DST PORT: %" PRIu32 "\n", p->sp, p->dp); if (PKT_IS_TCP(p)) { MemBufferWriteString(aft->buffer, "TCP SEQ: %"PRIu32"\n" "TCP ACK: %"PRIu32"\n", TCP_GET_SEQ(p), TCP_GET_ACK(p)); } } /* flow stuff */ MemBufferWriteString(aft->buffer, "FLOW: to_server: %s, " "to_client: %s\n", p->flowflags & FLOW_PKT_TOSERVER ? "TRUE" : "FALSE", p->flowflags & FLOW_PKT_TOCLIENT ? "TRUE" : "FALSE"); if (p->flow != NULL) { int applayer = 0; applayer = StreamTcpAppLayerIsDisabled(p->flow); CreateTimeString(&p->flow->startts, timebuf, sizeof(timebuf)); MemBufferWriteString(aft->buffer, "FLOW Start TS: %s\n", timebuf); MemBufferWriteString(aft->buffer, "FLOW PKTS TODST: %"PRIu32"\n" "FLOW PKTS TOSRC: %"PRIu32"\n" "FLOW Total Bytes: %"PRIu64"\n", p->flow->todstpktcnt, p->flow->tosrcpktcnt, p->flow->todstbytecnt + p->flow->tosrcbytecnt); MemBufferWriteString(aft->buffer, "FLOW IPONLY SET: TOSERVER: %s, TOCLIENT: %s\n" "FLOW ACTION: DROP: %s\n" "FLOW NOINSPECTION: PACKET: %s, PAYLOAD: %s, APP_LAYER: %s\n" "FLOW APP_LAYER: DETECTED: %s, PROTO %"PRIu16"\n", p->flow->flags & FLOW_TOSERVER_IPONLY_SET ? "TRUE" : "FALSE", p->flow->flags & FLOW_TOCLIENT_IPONLY_SET ? "TRUE" : "FALSE", p->flow->flags & FLOW_ACTION_DROP ? "TRUE" : "FALSE", p->flow->flags & FLOW_NOPACKET_INSPECTION ? "TRUE" : "FALSE", p->flow->flags & FLOW_NOPAYLOAD_INSPECTION ? "TRUE" : "FALSE", applayer ? "TRUE" : "FALSE", (p->flow->alproto != ALPROTO_UNKNOWN) ? "TRUE" : "FALSE", p->flow->alproto); AlertDebugLogFlowVars(aft, p); } AlertDebugLogPktVars(aft, p); /* any stuff */ /* Sig details? */ MemBufferWriteString(aft->buffer, "PACKET LEN: %" PRIu32 "\n" "PACKET:\n", GET_PKT_LEN(p)); PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, GET_PKT_DATA(p), GET_PKT_LEN(p)); MemBufferWriteString(aft->buffer, "ALERT CNT: %" PRIu32 "\n", p->alerts.cnt); for (i = 0; i < p->alerts.cnt; i++) { const PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } MemBufferWriteString(aft->buffer, "ALERT MSG [%02d]: %s\n" "ALERT GID [%02d]: %" PRIu32 "\n" "ALERT SID [%02d]: %" PRIu32 "\n" "ALERT REV [%02d]: %" PRIu32 "\n" "ALERT CLASS [%02d]: %s\n" "ALERT PRIO [%02d]: %" PRIu32 "\n" "ALERT FOUND IN [%02d]: %s\n", i, pa->s->msg, i, pa->s->gid, i, pa->s->id, i, pa->s->rev, i, pa->s->class_msg ? pa->s->class_msg : "<none>", i, pa->s->prio, i, pa->flags & PACKET_ALERT_FLAG_STREAM_MATCH ? "STREAM" : (pa->flags & PACKET_ALERT_FLAG_STATE_MATCH ? "STATE" : "PACKET")); if (pa->flags & PACKET_ALERT_FLAG_TX) { MemBufferWriteString(aft->buffer, "ALERT IN TX [%02d]: %"PRIu64"\n", i, pa->tx_id); } else { MemBufferWriteString(aft->buffer, "ALERT IN TX [%02d]: N/A\n", i); } if (p->payload_len > 0) { MemBufferWriteString(aft->buffer, "PAYLOAD LEN: %" PRIu32 "\n" "PAYLOAD:\n", p->payload_len); PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, p->payload, p->payload_len); } if ((pa->flags & PACKET_ALERT_FLAG_STATE_MATCH) || (pa->flags & PACKET_ALERT_FLAG_STREAM_MATCH)) { /* This is an app layer or stream alert */ int ret; uint8_t flag; if (!(PKT_IS_TCP(p)) || p->flow == NULL || p->flow->protoctx == NULL) { return TM_ECODE_OK; } /* IDS mode reverse the data */ /** \todo improve the order selection policy */ if (p->flowflags & FLOW_PKT_TOSERVER) { flag = FLOW_PKT_TOCLIENT; } else { flag = FLOW_PKT_TOSERVER; } ret = StreamSegmentForEach((const Packet *)p, flag, AlertDebugPrintStreamSegmentCallback, (void *)aft); if (ret < 0) { return TM_ECODE_FAILED; } } } aft->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), MEMBUFFER_OFFSET(aft->buffer), aft->file_ctx); return TM_ECODE_OK; }
/** * \brief Convert IP packet to an IDMEF alert (RFC 4765). * This function stores the alert SID (description and reference), * the payload of the packet, and pre-processed data. * * \return 0 if ok */ static int PacketToData(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert, AlertPreludeCtx *ctx) { SCEnter(); if (unlikely(p == NULL)) SCReturnInt(0); AddIntData(alert, "snort_rule_sid", pa->s->id); AddIntData(alert, "snort_rule_rev", pa->s->rev); if (ctx->log_packet_header) { if ( PKT_IS_IPV4(p) ) PacketToDataV4(p, pa, alert); else if ( PKT_IS_IPV6(p) ) PacketToDataV6(p, pa, alert); if ( PKT_IS_TCP(p) ) { AddIntData(alert, "tcp_seq", TCP_GET_SEQ(p)); AddIntData(alert, "tcp_ack", TCP_GET_ACK(p)); AddIntData(alert, "tcp_off", TCP_GET_OFFSET(p)); AddIntData(alert, "tcp_res", TCP_GET_X2(p)); AddIntData(alert, "tcp_flags", TCP_GET_FLAGS(p)); AddIntData(alert, "tcp_win", TCP_GET_WINDOW(p)); AddIntData(alert, "tcp_sum", TCP_GET_SUM(p)); AddIntData(alert, "tcp_urp", TCP_GET_URG_POINTER(p)); if (p->tcpvars.ts_val != 0) { AddIntData(alert, "tcp_tsval", TCP_GET_TSVAL(p)); } if (p->tcpvars.ts_ecr != 0) { AddIntData(alert, "tcp_tsecr", TCP_GET_TSECR(p)); } if (p->tcph != NULL) { AddIntData(alert, "tcp_wscale", TCP_GET_WSCALE(p)); } if (TCP_HAS_SACKOK(p)) { AddIntData(alert, "tcp_sackok", TCP_GET_SACKOK(p)); } if (TCP_HAS_SACK(p)) { AddIntData(alert, "tcp_sack_cnt", TCP_GET_SACK_CNT(p)); } AddIntData(alert, "tcp_hlen", TCP_GET_HLEN(p)); } else if ( PKT_IS_UDP(p) ) { AddIntData(alert, "udp_len", UDP_GET_LEN(p)); AddIntData(alert, "udp_sum", UDP_GET_SUM(p)); } else if ( PKT_IS_ICMPV4(p) ) { AddIntData(alert, "icmp_type", ICMPV4_GET_TYPE(p)); AddIntData(alert, "icmp_code", ICMPV4_GET_CODE(p)); AddIntData(alert, "icmp_sum", ICMPV4_GET_RAW_CSUM(p)); } else if ( PKT_IS_ICMPV6(p) ) { AddIntData(alert, "icmp_type", ICMPV6_GET_TYPE(p)); AddIntData(alert, "icmp_code", ICMPV6_GET_CODE(p)); AddIntData(alert, "icmp_csum", ICMPV6_GET_RAW_CSUM(p)); } } if (ctx->log_packet_content) AddByteData(alert, "payload", p->payload, p->payload_len); SCReturnInt(0); }
/** * \brief This function is used to match packets via the eDDOS rule * * \param t pointer to thread vars * \param det_ctx pointer to the pattern matcher thread * \param p pointer to the current packet * \param m pointer to the sigmatch that we will cast into DetectDummyData * * \retval 0 no match * \retval 1 match */ int DetecteDDOSMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m) { int ret = 0; DetecteDDOSSig *dsig = (DetecteDDOSSig *) m->ctx; DetecteDDOSData *ddata; Host *h; time_t t1; double time_diff_ms; if (PKT_IS_PSEUDOPKT(p) || !PKT_IS_IPV4(p) || p->flags & PKT_HOST_SRC_LOOKED_UP) { return 0; } /* TODO: Inspect the packet contents here. * Suricata defines a `Packet` structure in decode.h which already defines * many useful elements -- have a look! */ h = HostGetHostFromHash(&(p->src)); // Only SRC or can DEST be used too? p->flags |= PKT_HOST_SRC_LOOKED_UP; if (h == NULL) { printf("host not found!\n"); return 0; } ddata = (DetecteDDOSData *) h->eddos; if (!ddata) { /* initialize fresh dummydata */ ddata = SCMalloc(sizeof (DetecteDDOSData)); bzero(ddata, sizeof (DetecteDDOSData)); h->eddos = ddata; } /** * Start counting for evaluation */ (ddata->cnt_packets)++; if (PKT_IS_TCP(p)) { //counter host (ddata->cnt_tcp)++; //counter global tcp_pkts_gesamt++; //printf("\nPakets TCP Flag: %d\n", p->tcph->th_flags); if (p->tcph->th_flags == tcp_syn_ack_flag) { (ddata->cnt_tcp_syn_ack)++; tcp_syn_ack_gesamt++; //printf("TCP_SYN_ACK"); } if (p->tcph->th_flags == tcp_fin_ack_flag) { (ddata->cnt_tcp_fin_ack)++; tcp_fin_ack_gesamt++; //printf("TCP_FIN_ACK"); } if (p->tcph->th_flags == TH_SYN) { (ddata->cnt_tcp_syn)++; tcp_syn_gesamt++; //printf("TCP_SYN"); } } if (PKT_IS_UDP(p)) { (ddata->cnt_udp)++; udp_pkt_gesamt++; } if (PKT_IS_ICMPV4(p) && p->icmpv4h->type == ICMP_ECHO) { (ddata->cnt_icmp_echo_req)++; icmp_gesamt++; } /** * End Counting */ /** * Start evaluation */ if (PKT_IS_UDP(p) || PKT_IS_TCP(p)) { t1 = p->ts.tv_sec; time_diff_ms = difftime(t1, ddata->PeriodStart); if (time_diff_ms > (60)) { /*check for alarm here*/ // abweichung vom 1:2 verhältnis SYN/ACK zu FIN/ACK float ver_syn_ack; float abw_syn_ack; // verhältnis von ICMP echo req paketen zu allen paketen float ver_echoreq_norm; // verhältnis von udp pakten zu allen paketen float ver_udp_norm; if (ddata->cnt_tcp_fin_ack != 0) { ver_syn_ack = ((float) (ddata->cnt_tcp_syn_ack) / ddata->cnt_tcp_fin_ack); } else { // we have syn but no syn_acks if ((((ddata->cnt_tcp_syn - ddata->cnt_tcp_syn_ack)*2) > dsig->max_abweichung_syn_ack ) && ddata->cnt_tcp_syn > 250) { printf("\nSYN zu SYN/ACK Host\n"); printf("\n SYN: %llu SYN/ACK: %llu \n", ddata->cnt_tcp_syn, ddata->cnt_tcp_syn_ack ); ver_syn_ack = -1; } ver_syn_ack = 0; } abw_syn_ack = (((1 / 2) - ver_syn_ack))*2; //printf("\nSYN/ACK zu FIN/ACK Host Value: %f # SYN/ACK: %llu - FIN/ACK: %llu\n", (abw_syn_ack), ddata->cnt_tcp_syn_ack, ddata->cnt_tcp_fin_ack); if (abw_syn_ack < 0) { // check if abweichung größer als in signatur angegeben if (fabs(abw_syn_ack) > dsig->max_abweichung_syn_ack) { ret = 1; printf("\nSYN/ACK zu FIN/ACK Host Value: %f # SYN/ACK: %llu - FIN/ACK: %llu\n", fabs(abw_syn_ack), ddata->cnt_tcp_syn_ack, ddata->cnt_tcp_fin_ack); } } // verhältnis icmp echo request berechnen ver_echoreq_norm = ((float) (ddata->cnt_icmp_echo_req) / ddata->cnt_packets)*100; // check if ICMP echo request pakete zu viel im verhältnis zu allen if (ver_echoreq_norm > (float) (dsig->max_icmp_echo_req_packets)) { ret = 1; //printf("\nICMP Host\n"); } /** // verhältnis udp paketen berechnen ver_udp_norm = ((float)(ddata->cnt_udp) / ddata->cnt_packets); // check if udp pakete zu viel im verhältnis zu allen if ( ver_udp_norm > (float)(dsig->max_udp_packets) ) { ret = 1; } */ /** * gesamtauswertung */ time_diff_ms = difftime(t1, start_time); if (time_diff_ms > (300)) { // auswertung udp pakete // verhältnis udp paketen berechnen ver_udp_norm = ((float) (udp_pkt_gesamt) / (udp_pkt_gesamt + tcp_pkts_gesamt))*100; //printf("UDP Pakete Verhaeltnis: %f", ver_udp_norm); // check if udp pakete zu viel im verhältnis zu allen if (ver_udp_norm > (float) (dsig->max_verhaeltnis_udp_packets)) { ret = 1; //printf("\nUDP ALL\n"); } // auswertung echo requests ver_echoreq_norm = ((float) (icmp_gesamt) / (udp_pkt_gesamt + tcp_pkts_gesamt))*100; if (ver_echoreq_norm > (float) (icmp_gesamt)) { ret = 1; printf("\nICMP ALL\n"); } // auswertung syn/ack if (tcp_fin_ack_gesamt != 0) { ver_syn_ack = ((float) (tcp_syn_ack_gesamt) / tcp_fin_ack_gesamt); } else { // we have syn but no syn_acks if (fabs((float)((tcp_syn_gesamt - tcp_syn_gesamt)*2)) > dsig->max_abweichung_syn_ack) { printf("\nSYN zu SYN/ACK ALL\n"); ver_syn_ack = -1; } ver_syn_ack = 0; } abw_syn_ack = (((1 / 2) - ver_syn_ack))*2; if (abw_syn_ack < 0) { // check if abweichung größer als in signatur angegeben if (fabs(abw_syn_ack) > dsig->max_abweichung_syn_ack) { ret = 1; printf("\nSYN/ACK zu FIN/ACK ALL\n"); } } // reset global counter for new interval tcp_pkts_gesamt = 0; udp_pkt_gesamt = 0; tcp_fin_ack_gesamt = 0; tcp_syn_ack_gesamt = 0; icmp_gesamt = 0; } /**printf("host found, packets now %d\n", (int)(ddata->cnt_packets)); ret = (ddata->cnt_packets > dsig->max_numpackets); */ // reset der parameter, da neuer zeitraum beginnt ddata->PeriodStart = p->ts.tv_sec; ddata->cnt_icmp_echo_req = 0; ddata->cnt_packets = 0; ddata->cnt_tcp = 0; ddata->cnt_tcp_fin_ack = 0; ddata->cnt_tcp_syn_ack = 0; ddata->cnt_udp = 0; } else { ret = 0; } } /** * End of evaluation */ //printf("\nHost: %d - %d\n", (int)h, ddata->cnt_packets); /** printf("#################################\n"); printf("Host: %d\n",(int)h); printf("\n TCP-SYN: %d \n", ddata->cnt_tcp_syn); printf("\n TCP-ACK: %d \n", ddata->cnt_tcp_ack); printf("\n Packets gesamt: %d \n", ddata->cnt_packets); printf("\n Packets TCP gesamt: %d \n", ddata->cnt_tcp); printf("\n Packets UDP gesamt: %d \n", ddata->cnt_udp); printf("\n ICMP ECHO REQUEST Packets: %d \n", ddata->cnt_icmp_echo_req); printf("#################################\n"); printf("\n\nTCP Gesamt: %llu\n",tcp_pkts_gesamt); printf("UDP Gesamt: %llu\n",udp_pkt_gesamt); printf("SYN: %llu\n",tcp_syn_gesamt); printf("ICMP: %llu\n",icmp_gesamt); printf("SYN_ACK gesamt %d\n",(int)tcp_syn_ack_gesamt); printf("FIN_ACK_gesamt %d\n\n",(int)tcp_fin_ack_gesamt); */ HostRelease(h); return ret; }
static void LogFilestoreLogCreateMetaFile(const Packet *p, const File *ff, char *base_filename, int ipver) { if (!FileWriteMeta()) return; char metafilename[PATH_MAX] = ""; if (snprintf(metafilename, sizeof(metafilename), "%s.meta%s", base_filename, g_working_file_suffix) == sizeof(metafilename)) return; FILE *fp = fopen(metafilename, "w+"); if (fp != NULL) { char timebuf[64]; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); fprintf(fp, "TIME: %s\n", timebuf); if (p->pcap_cnt > 0) { fprintf(fp, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt); } char srcip[46], dstip[46]; Port sp, dp; switch (ipver) { case AF_INET: PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); break; case AF_INET6: PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); break; default: strlcpy(srcip, "<unknown>", sizeof(srcip)); strlcpy(dstip, "<unknown>", sizeof(dstip)); break; } sp = p->sp; dp = p->dp; fprintf(fp, "SRC IP: %s\n", srcip); fprintf(fp, "DST IP: %s\n", dstip); fprintf(fp, "PROTO: %" PRIu32 "\n", p->proto); if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) { fprintf(fp, "SRC PORT: %" PRIu16 "\n", sp); fprintf(fp, "DST PORT: %" PRIu16 "\n", dp); } fprintf(fp, "APP PROTO: %s\n", AppProtoToString(p->flow->alproto)); /* Only applicable to HTTP traffic */ if (p->flow->alproto == ALPROTO_HTTP) { fprintf(fp, "HTTP URI: "); LogFilestoreMetaGetUri(fp, p, ff); fprintf(fp, "\n"); fprintf(fp, "HTTP HOST: "); LogFilestoreMetaGetHost(fp, p, ff); fprintf(fp, "\n"); fprintf(fp, "HTTP REFERER: "); LogFilestoreMetaGetReferer(fp, p, ff); fprintf(fp, "\n"); fprintf(fp, "HTTP USER AGENT: "); LogFilestoreMetaGetUserAgent(fp, p, ff); fprintf(fp, "\n"); } else if (p->flow->alproto == ALPROTO_SMTP) { /* Only applicable to SMTP */ LogFilestoreMetaGetSmtp(fp, p, ff); } fprintf(fp, "FILENAME: "); PrintRawUriFp(fp, ff->name, ff->name_len); fprintf(fp, "\n"); fclose(fp); } }
/** * \brief Log the dropped packets in netfilter format when engine is running * in inline mode * * \param tv Pointer the current thread variables * \param p Pointer the packet which is being logged * \param data Pointer to the droplog struct * * \return return TM_EODE_OK on success */ static int LogDropLogNetFilter (ThreadVars *tv, const Packet *p, void *data) { LogDropLogThread *dlt = (LogDropLogThread *)data; uint16_t proto = 0; char timebuf[64]; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); SCMutexLock(&dlt->file_ctx->fp_mutex); if (dlt->file_ctx->rotation_flag) { dlt->file_ctx->rotation_flag = 0; if (SCConfLogReopen(dlt->file_ctx) != 0) { /* Rotation failed, error already logged. */ SCMutexUnlock(&dlt->file_ctx->fp_mutex); return TM_ECODE_FAILED; } } char srcip[46] = ""; char dstip[46] = ""; if (PKT_IS_IPV4(p)) { PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, 16); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, 16); fprintf(dlt->file_ctx->fp, "%s: IN= OUT= SRC=%s DST=%s LEN=%"PRIu16" " "TOS=0x%02"PRIu8" TTL=%"PRIu8" ID=%"PRIu16"", timebuf, srcip, dstip, IPV4_GET_IPLEN(p), IPV4_GET_IPTOS(p), IPV4_GET_IPTTL(p), IPV4_GET_IPID(p)); proto = IPV4_GET_IPPROTO(p); } else if (PKT_IS_IPV6(p)) { PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); fprintf(dlt->file_ctx->fp, "%s: IN= OUT= SRC=%s DST=%s LEN=%"PRIu16"" " TC=%"PRIu32" HOPLIMIT=%"PRIu8" FLOWLBL=%"PRIu32"", timebuf, srcip, dstip, IPV6_GET_PLEN(p), IPV6_GET_CLASS(p), IPV6_GET_HLIM(p), IPV6_GET_FLOW(p)); proto = IPV6_GET_L4PROTO(p); } if (SCProtoNameValid(proto) == TRUE) { fprintf(dlt->file_ctx->fp, " PROTO=%s",known_proto[proto]); } else { fprintf(dlt->file_ctx->fp, " PROTO=%03"PRIu16"",proto); } switch (proto) { case IPPROTO_TCP: if (PKT_IS_TCP(p)) { fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16" " "SEQ=%"PRIu32" ACK=%"PRIu32" WINDOW=%"PRIu32"", GET_TCP_SRC_PORT(p), GET_TCP_DST_PORT(p), TCP_GET_SEQ(p), TCP_GET_ACK(p), TCP_GET_WINDOW(p)); fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_SYN(p) ? " SYN" : ""); fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_ACK(p) ? " ACK" : ""); fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_PUSH(p) ? " PSH" : ""); fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_RST(p) ? " RST" : ""); fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_URG(p) ? " URG" : ""); fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_FIN(p) ? " FIN" : ""); fprintf(dlt->file_ctx->fp, " RES=0x%02"PRIu8" URGP=%"PRIu16"", TCP_GET_RAW_X2(p->tcph), TCP_GET_URG_POINTER(p)); } break; case IPPROTO_UDP: if (PKT_IS_UDP(p)) { fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16"" " LEN=%"PRIu16"", UDP_GET_SRC_PORT(p), UDP_GET_DST_PORT(p), UDP_GET_LEN(p)); } break; case IPPROTO_ICMP: if (PKT_IS_ICMPV4(p)) { fprintf(dlt->file_ctx->fp, " TYPE=%"PRIu8" CODE=%"PRIu8"" " ID=%"PRIu16" SEQ=%"PRIu16"", ICMPV4_GET_TYPE(p), ICMPV4_GET_CODE(p), ICMPV4_GET_ID(p), ICMPV4_GET_SEQ(p)); } else if (PKT_IS_ICMPV6(p)) { fprintf(dlt->file_ctx->fp, " TYPE=%"PRIu8" CODE=%"PRIu8"" " ID=%"PRIu16" SEQ=%"PRIu16"", ICMPV6_GET_TYPE(p), ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p)); } break; default: fprintf(dlt->file_ctx->fp," Unknown protocol"); } fprintf(dlt->file_ctx->fp,"\n"); fflush(dlt->file_ctx->fp); dlt->drop_cnt++; SCMutexUnlock(&dlt->file_ctx->fp_mutex); return TM_ECODE_OK; }
/** * \brief Log the dropped packets in netfilter format when engine is running * in inline mode * * \param tv Pointer the current thread variables * \param p Pointer the packet which is being logged * * \return return TM_EODE_OK on success */ static int DropLogJSON (JsonDropLogThread *aft, const Packet *p) { JsonDropOutputCtx *drop_ctx = aft->drop_ctx; json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "drop"); if (unlikely(js == NULL)) return TM_ECODE_OK; JsonAddCommonOptions(&drop_ctx->cfg, p, p->flow, js); json_t *djs = json_object(); if (unlikely(djs == NULL)) { json_decref(js); return TM_ECODE_OK; } /* reset */ MemBufferReset(aft->buffer); uint16_t proto = 0; if (PKT_IS_IPV4(p)) { json_object_set_new(djs, "len", json_integer(IPV4_GET_IPLEN(p))); json_object_set_new(djs, "tos", json_integer(IPV4_GET_IPTOS(p))); json_object_set_new(djs, "ttl", json_integer(IPV4_GET_IPTTL(p))); json_object_set_new(djs, "ipid", json_integer(IPV4_GET_IPID(p))); proto = IPV4_GET_IPPROTO(p); } else if (PKT_IS_IPV6(p)) { json_object_set_new(djs, "len", json_integer(IPV6_GET_PLEN(p))); json_object_set_new(djs, "tc", json_integer(IPV6_GET_CLASS(p))); json_object_set_new(djs, "hoplimit", json_integer(IPV6_GET_HLIM(p))); json_object_set_new(djs, "flowlbl", json_integer(IPV6_GET_FLOW(p))); proto = IPV6_GET_L4PROTO(p); } switch (proto) { case IPPROTO_TCP: if (PKT_IS_TCP(p)) { json_object_set_new(djs, "tcpseq", json_integer(TCP_GET_SEQ(p))); json_object_set_new(djs, "tcpack", json_integer(TCP_GET_ACK(p))); json_object_set_new(djs, "tcpwin", json_integer(TCP_GET_WINDOW(p))); json_object_set_new(djs, "syn", TCP_ISSET_FLAG_SYN(p) ? json_true() : json_false()); json_object_set_new(djs, "ack", TCP_ISSET_FLAG_ACK(p) ? json_true() : json_false()); json_object_set_new(djs, "psh", TCP_ISSET_FLAG_PUSH(p) ? json_true() : json_false()); json_object_set_new(djs, "rst", TCP_ISSET_FLAG_RST(p) ? json_true() : json_false()); json_object_set_new(djs, "urg", TCP_ISSET_FLAG_URG(p) ? json_true() : json_false()); json_object_set_new(djs, "fin", TCP_ISSET_FLAG_FIN(p) ? json_true() : json_false()); json_object_set_new(djs, "tcpres", json_integer(TCP_GET_RAW_X2(p->tcph))); json_object_set_new(djs, "tcpurgp", json_integer(TCP_GET_URG_POINTER(p))); } break; case IPPROTO_UDP: if (PKT_IS_UDP(p)) { json_object_set_new(djs, "udplen", json_integer(UDP_GET_LEN(p))); } break; case IPPROTO_ICMP: if (PKT_IS_ICMPV4(p)) { json_object_set_new(djs, "icmp_id", json_integer(ICMPV4_GET_ID(p))); json_object_set_new(djs, "icmp_seq", json_integer(ICMPV4_GET_SEQ(p))); } else if(PKT_IS_ICMPV6(p)) { json_object_set_new(djs, "icmp_id", json_integer(ICMPV6_GET_ID(p))); json_object_set_new(djs, "icmp_seq", json_integer(ICMPV6_GET_SEQ(p))); } break; } json_object_set_new(js, "drop", djs); if (aft->drop_ctx->flags & LOG_DROP_ALERTS) { int logged = 0; int i; for (i = 0; i < p->alerts.cnt; i++) { const PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } if ((pa->action & (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)) || ((pa->action & ACTION_DROP) && EngineModeIsIPS())) { AlertJsonHeader(NULL, p, pa, js, 0); logged = 1; } } if (logged == 0) { if (p->alerts.drop.action != 0) { const PacketAlert *pa = &p->alerts.drop; AlertJsonHeader(NULL, p, pa, js, 0); } } } OutputJSONBuffer(js, aft->drop_ctx->file_ctx, &aft->buffer); json_object_del(js, "drop"); json_object_clear(js); json_decref(js); return TM_ECODE_OK; }
TmEcode AlertDebugLogger(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { AlertDebugLogThread *aft = (AlertDebugLogThread *)data; int i; char timebuf[64]; if (p->alerts.cnt == 0) return TM_ECODE_OK; MemBufferReset(aft->buffer); CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); MemBufferWriteString(aft->buffer, "+================\n" "TIME: %s\n", timebuf); if (p->pcap_cnt > 0) { MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt); } char srcip[46], dstip[46]; if (PKT_IS_IPV4(p)) { PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); } else if (PKT_IS_IPV6(p)) { PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); } MemBufferWriteString(aft->buffer, "SRC IP: %s\n" "DST IP: %s\n" "PROTO: %" PRIu32 "\n", srcip, dstip, p->proto); if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) { MemBufferWriteString(aft->buffer, "SRC PORT: %" PRIu32 "\n" "DST PORT: %" PRIu32 "\n", p->sp, p->dp); if (PKT_IS_TCP(p)) { MemBufferWriteString(aft->buffer, "TCP SEQ: %"PRIu32"\n" "TCP ACK: %"PRIu32"\n", TCP_GET_SEQ(p), TCP_GET_ACK(p)); } } /* flow stuff */ MemBufferWriteString(aft->buffer, "FLOW: to_server: %s, " "to_client: %s\n", p->flowflags & FLOW_PKT_TOSERVER ? "TRUE" : "FALSE", p->flowflags & FLOW_PKT_TOCLIENT ? "TRUE" : "FALSE"); if (p->flow != NULL) { FLOWLOCK_RDLOCK(p->flow); CreateTimeString(&p->flow->startts, timebuf, sizeof(timebuf)); MemBufferWriteString(aft->buffer, "FLOW Start TS: %s\n", timebuf); #ifdef DEBUG MemBufferWriteString(aft->buffer, "FLOW PKTS TODST: %"PRIu32"\n" "FLOW PKTS TOSRC: %"PRIu32"\n" "FLOW Total Bytes: %"PRIu64"\n", p->flow->todstpktcnt, p->flow->tosrcpktcnt, p->flow->bytecnt); #endif MemBufferWriteString(aft->buffer, "FLOW IPONLY SET: TOSERVER: %s, TOCLIENT: %s\n" "FLOW ACTION: DROP: %s, PASS %s\n" "FLOW NOINSPECTION: PACKET: %s, PAYLOAD: %s, APP_LAYER: %s\n" "FLOW APP_LAYER: DETECTED: %s, PROTO %"PRIu16"\n", p->flow->flags & FLOW_TOSERVER_IPONLY_SET ? "TRUE" : "FALSE", p->flow->flags & FLOW_TOCLIENT_IPONLY_SET ? "TRUE" : "FALSE", p->flow->flags & FLOW_ACTION_DROP ? "TRUE" : "FALSE", p->flow->flags & FLOW_ACTION_PASS ? "TRUE" : "FALSE", p->flow->flags & FLOW_NOPACKET_INSPECTION ? "TRUE" : "FALSE", p->flow->flags & FLOW_NOPAYLOAD_INSPECTION ? "TRUE" : "FALSE", p->flow->flags & FLOW_NO_APPLAYER_INSPECTION ? "TRUE" : "FALSE", (p->flow->alproto != ALPROTO_UNKNOWN) ? "TRUE" : "FALSE", p->flow->alproto); AlertDebugLogFlowVars(aft, p); AlertDebugLogFlowBits(aft, p); FLOWLOCK_UNLOCK(p->flow); } AlertDebugLogPktVars(aft, p); /* any stuff */ /* Sig details? */ MemBufferWriteString(aft->buffer, "PACKET LEN: %" PRIu32 "\n" "PACKET:\n", GET_PKT_LEN(p)); PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, GET_PKT_DATA(p), GET_PKT_LEN(p)); MemBufferWriteString(aft->buffer, "ALERT CNT: %" PRIu32 "\n", p->alerts.cnt); for (i = 0; i < p->alerts.cnt; i++) { PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } MemBufferWriteString(aft->buffer, "ALERT MSG [%02d]: %s\n" "ALERT GID [%02d]: %" PRIu32 "\n" "ALERT SID [%02d]: %" PRIu32 "\n" "ALERT REV [%02d]: %" PRIu32 "\n" "ALERT CLASS [%02d]: %s\n" "ALERT PRIO [%02d]: %" PRIu32 "\n" "ALERT FOUND IN [%02d]: %s\n", i, pa->s->msg, i, pa->s->gid, i, pa->s->id, i, pa->s->rev, i, pa->s->class_msg ? pa->s->class_msg : "<none>", i, pa->s->prio, i, pa->flags & PACKET_ALERT_FLAG_STREAM_MATCH ? "STREAM" : (pa->flags & PACKET_ALERT_FLAG_STATE_MATCH ? "STATE" : "PACKET")); if (p->payload_len > 0) { MemBufferWriteString(aft->buffer, "PAYLOAD LEN: %" PRIu32 "\n" "PAYLOAD:\n", p->payload_len); PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, p->payload, p->payload_len); } if (pa->flags & PACKET_ALERT_FLAG_STATE_MATCH || pa->flags & PACKET_ALERT_FLAG_STREAM_MATCH) { /* This is an app layer or stream alert */ int ret; uint8_t flag; if ((! PKT_IS_TCP(p)) || p->flow == NULL || p->flow->protoctx == NULL) { return TM_ECODE_OK; } /* IDS mode reverse the data */ /** \todo improve the order selection policy */ if (p->flowflags & FLOW_PKT_TOSERVER) { flag = FLOW_PKT_TOCLIENT; } else { flag = FLOW_PKT_TOSERVER; } ret = StreamSegmentForEach(p, flag, AlertDebugPrintStreamSegmentCallback, (void *)aft); if (ret < 0) { return TM_ECODE_FAILED; } } } SCMutexLock(&aft->file_ctx->fp_mutex); (void)MemBufferPrintToFPAsString(aft->buffer, aft->file_ctx->fp); fflush(aft->file_ctx->fp); aft->file_ctx->alerts += p->alerts.cnt; SCMutexUnlock(&aft->file_ctx->fp_mutex); return TM_ECODE_OK; }
/** * \internal * \brief Write meta data on a single line json record */ static void LogFileWriteJsonRecord(LogFileLogThread *aft, Packet *p, File *ff, int ipver) { SCMutexLock(&aft->file_ctx->fp_mutex); FILE *fp = aft->file_ctx->fp; char timebuf[64]; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); fprintf(fp, "{ "); if (ff->file_id > 0) fprintf(fp, "\"id\": %u, ", ff->file_id); fprintf(fp, "\"timestamp\": \""); PrintRawJsonFp(fp, (uint8_t *)timebuf, strlen(timebuf)); fprintf(fp, "\", "); if (p->pcap_cnt > 0) { fprintf(fp, "\"pcap_pkt_num\": %"PRIu64", ", p->pcap_cnt); } fprintf(fp, "\"ipver\": %d, ", ipver == AF_INET ? 4 : 6); char srcip[46], dstip[46]; Port sp, dp; switch (ipver) { case AF_INET: PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); break; case AF_INET6: PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); break; default: strlcpy(srcip, "<unknown>", sizeof(srcip)); strlcpy(dstip, "<unknown>", sizeof(dstip)); break; } sp = p->sp; dp = p->dp; fprintf(fp, "\"srcip\": \"%s\", ", srcip); fprintf(fp, "\"dstip\": \"%s\", ", dstip); fprintf(fp, "\"protocol\": %" PRIu32 ", ", p->proto); if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) { fprintf(fp, "\"sp\": %" PRIu16 ", ", sp); fprintf(fp, "\"dp\": %" PRIu16 ", ", dp); } fprintf(fp, "\"http_uri\": \""); LogFileMetaGetUri(fp, p, ff); fprintf(fp, "\", "); fprintf(fp, "\"http_host\": \""); LogFileMetaGetHost(fp, p, ff); fprintf(fp, "\", "); fprintf(fp, "\"http_referer\": \""); LogFileMetaGetReferer(fp, p, ff); fprintf(fp, "\", "); fprintf(fp, "\"http_user_agent\": \""); LogFileMetaGetUserAgent(fp, p, ff); fprintf(fp, "\", "); fprintf(fp, "\"filename\": \""); PrintRawJsonFp(fp, ff->name, ff->name_len); fprintf(fp, "\", "); fprintf(fp, "\"magic\": \""); if (ff->magic) { PrintRawJsonFp(fp, (uint8_t *)ff->magic, strlen(ff->magic)); } else { fprintf(fp, "unknown"); } fprintf(fp, "\", "); switch (ff->state) { case FILE_STATE_CLOSED: fprintf(fp, "\"state\": \"CLOSED\", "); #ifdef HAVE_NSS if (ff->flags & FILE_MD5) { fprintf(fp, "\"md5\": \""); size_t x; for (x = 0; x < sizeof(ff->md5); x++) { fprintf(fp, "%02x", ff->md5[x]); } fprintf(fp, "\", "); } #endif break; case FILE_STATE_TRUNCATED: fprintf(fp, "\"state\": \"TRUNCATED\", "); break; case FILE_STATE_ERROR: fprintf(fp, "\"state\": \"ERROR\", "); break; default: fprintf(fp, "\"state\": \"UNKNOWN\", "); break; } fprintf(fp, "\"stored\": %s, ", ff->flags & FILE_STORED ? "true" : "false"); fprintf(fp, "\"size\": %"PRIu64" ", ff->size); fprintf(fp, "}\n"); fflush(fp); SCMutexUnlock(&aft->file_ctx->fp_mutex); }
TmEcode AlertDebugLogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { AlertDebugLogThread *aft = (AlertDebugLogThread *)data; int i; char timebuf[64]; if (p->alerts.cnt == 0) return TM_ECODE_OK; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); SCMutexLock(&aft->file_ctx->fp_mutex); fprintf(aft->file_ctx->fp, "+================\n"); fprintf(aft->file_ctx->fp, "TIME: %s\n", timebuf); if (p->pcap_cnt > 0) { fprintf(aft->file_ctx->fp, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt); } fprintf(aft->file_ctx->fp, "ALERT CNT: %" PRIu32 "\n", p->alerts.cnt); for (i = 0; i < p->alerts.cnt; i++) { PacketAlert *pa = &p->alerts.alerts[i]; fprintf(aft->file_ctx->fp, "ALERT MSG [%02d]: %s\n", i, pa->msg); fprintf(aft->file_ctx->fp, "ALERT GID [%02d]: %" PRIu32 "\n", i, pa->gid); fprintf(aft->file_ctx->fp, "ALERT SID [%02d]: %" PRIu32 "\n", i, pa->sid); fprintf(aft->file_ctx->fp, "ALERT REV [%02d]: %" PRIu32 "\n", i, pa->rev); fprintf(aft->file_ctx->fp, "ALERT CLASS [%02d]: %s\n", i, pa->class_msg); fprintf(aft->file_ctx->fp, "ALERT PRIO [%02d]: %" PRIu32 "\n", i, pa->prio); } char srcip[16], dstip[16]; inet_ntop(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); inet_ntop(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); fprintf(aft->file_ctx->fp, "SRC IP: %s\n", srcip); fprintf(aft->file_ctx->fp, "DST IP: %s\n", dstip); fprintf(aft->file_ctx->fp, "PROTO: %" PRIu32 "\n", IPV4_GET_IPPROTO(p)); if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) { fprintf(aft->file_ctx->fp, "SRC PORT: %" PRIu32 "\n", p->sp); fprintf(aft->file_ctx->fp, "DST PORT: %" PRIu32 "\n", p->dp); if (PKT_IS_TCP(p)) { fprintf(aft->file_ctx->fp, "TCP SEQ: %"PRIu32"\n", TCP_GET_SEQ(p)); fprintf(aft->file_ctx->fp, "TCP ACK: %"PRIu32"\n", TCP_GET_ACK(p)); } } /* flow stuff */ fprintf(aft->file_ctx->fp, "FLOW: to_server: %s, to_client: %s\n", p->flowflags & FLOW_PKT_TOSERVER ? "TRUE" : "FALSE", p->flowflags & FLOW_PKT_TOCLIENT ? "TRUE" : "FALSE"); if (p->flow != NULL) { SCMutexLock(&p->flow->m); CreateTimeString(&p->flow->startts, timebuf, sizeof(timebuf)); fprintf(aft->file_ctx->fp, "FLOW Start TS: %s\n",timebuf); fprintf(aft->file_ctx->fp, "FLOW PKTS TODST: %"PRIu32"\n",p->flow->todstpktcnt); fprintf(aft->file_ctx->fp, "FLOW PKTS TOSRC: %"PRIu32"\n",p->flow->tosrcpktcnt); fprintf(aft->file_ctx->fp, "FLOW Total Bytes: %"PRIu64"\n",p->flow->bytecnt); fprintf(aft->file_ctx->fp, "FLOW IPONLY SET: TOSERVER: %s, TOCLIENT: %s\n", p->flow->flags & FLOW_TOSERVER_IPONLY_SET ? "TRUE" : "FALSE", p->flow->flags & FLOW_TOCLIENT_IPONLY_SET ? "TRUE" : "FALSE"); fprintf(aft->file_ctx->fp, "FLOW ACTION: DROP: %s, PASS %s\n", p->flow->flags & FLOW_ACTION_DROP ? "TRUE" : "FALSE", p->flow->flags & FLOW_ACTION_PASS ? "TRUE" : "FALSE"); fprintf(aft->file_ctx->fp, "FLOW NOINSPECTION: PACKET: %s, PAYLOAD: %s, APP_LAYER: %s\n", p->flow->flags & FLOW_NOPACKET_INSPECTION ? "TRUE" : "FALSE", p->flow->flags & FLOW_NOPAYLOAD_INSPECTION ? "TRUE" : "FALSE", p->flow->alflags & FLOW_AL_NO_APPLAYER_INSPECTION ? "TRUE" : "FALSE"); fprintf(aft->file_ctx->fp, "FLOW APP_LAYER: DETECTED: %s, PROTO %"PRIu16"\n", p->flow->alflags & FLOW_AL_PROTO_DETECT_DONE ? "TRUE" : "FALSE", p->flow->alproto); AlertDebugLogFlowVars(aft, p); AlertDebugLogFlowBits(aft, p); SCMutexUnlock(&p->flow->m); } AlertDebugLogPktVars(aft, p); /* any stuff */ /* Sig details? */ aft->file_ctx->alerts += p->alerts.cnt; fprintf(aft->file_ctx->fp, "PACKET LEN: %" PRIu32 "\n", GET_PKT_LEN(p)); fprintf(aft->file_ctx->fp, "PACKET:\n"); PrintRawDataFp(aft->file_ctx->fp, GET_PKT_DATA(p), GET_PKT_LEN(p)); fflush(aft->file_ctx->fp); SCMutexUnlock(&aft->file_ctx->fp_mutex); return TM_ECODE_OK; }