/** * \brief Search for a threshold data into threshold hash table * * \param de_ctx Dectection Context * \param tsh_ptr Threshold element * \param p Packet structure * * \retval lookup_tsh Return the threshold element */ DetectThresholdEntry *ThresholdHashSearch(DetectEngineCtx *de_ctx, DetectThresholdEntry *tsh_ptr, Packet *p) { SCEnter(); DetectThresholdEntry *lookup_tsh = NULL; SCLogDebug("tsh_ptr->track %u", tsh_ptr->track); if (tsh_ptr->track == TRACK_DST) { if (PKT_IS_IPV4(p)) { SCLogDebug("ipv4 dst"); lookup_tsh = HashListTableLookup(de_ctx->ths_ctx.threshold_hash_table_dst, tsh_ptr, sizeof(DetectThresholdEntry)); } else if (PKT_IS_IPV6(p)) { lookup_tsh = HashListTableLookup(de_ctx->ths_ctx.threshold_hash_table_dst_ipv6, tsh_ptr, sizeof(DetectThresholdEntry)); } } else if (tsh_ptr->track == TRACK_SRC) { if (PKT_IS_IPV4(p)) { SCLogDebug("ipv4 src"); lookup_tsh = HashListTableLookup(de_ctx->ths_ctx.threshold_hash_table_src, tsh_ptr, sizeof(DetectThresholdEntry)); } else if (PKT_IS_IPV6(p)) lookup_tsh = HashListTableLookup(de_ctx->ths_ctx.threshold_hash_table_src_ipv6, tsh_ptr, sizeof(DetectThresholdEntry)); } else { SCLogDebug("no track, weird"); } SCReturnPtr(lookup_tsh, "DetectThresholdEntry"); }
/** * \brief This function is used to match TEMPLATE rule option on a packet * * \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 with context that we will cast into DetectTemplateData * * \retval 0 no match * \retval 1 match */ static int DetectTemplateMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) { int ret = 0; const DetectTemplateData *templated = (const DetectTemplateData *) ctx; #if 0 if (PKT_IS_PSEUDOPKT(p)) { /* fake pkt */ } if (PKT_IS_IPV4(p)) { /* ipv4 pkt */ } else if (PKT_IS_IPV6(p)) { /* ipv6 pkt */ } else { SCLogDebug("packet is of not IPv4 or IPv6"); return ret; } #endif /* packet payload access */ if (p->payload != NULL && p->payload_len > 0) { if (templated->arg1 == p->payload[0] && templated->arg2 == p->payload[p->payload_len - 1]) { ret = 1; } } return ret; }
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 This function is used to match TTL rule option on a packet with those passed via ttl: * * \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 DetectTtlData * * \retval 0 no match * \retval 1 match */ int DetectTtlMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m) { int ret = 0; uint8_t pttl; DetectTtlData *ttld = (DetectTtlData *) m->ctx; if (PKT_IS_PSEUDOPKT(p)) return 0; if (PKT_IS_IPV4(p)) { pttl = IPV4_GET_IPTTL(p); } else if (PKT_IS_IPV6(p)) { pttl = IPV6_GET_HLIM(p); } else { SCLogDebug("Packet is of not IPv4 or IPv6"); return ret; } if (ttld->mode == DETECT_TTL_EQ && pttl == ttld->ttl1) ret = 1; else if (ttld->mode == DETECT_TTL_LT && pttl < ttld->ttl1) ret = 1; else if (ttld->mode == DETECT_TTL_GT && pttl > ttld->ttl1) ret = 1; else if (ttld->mode == DETECT_TTL_RA && (pttl > ttld->ttl1 && pttl < ttld->ttl2)) ret = 1; return ret; }
static inline DetectThresholdEntry *DetectThresholdEntryAlloc(DetectThresholdData *td, Packet *p, Signature *s) { SCEnter(); DetectThresholdEntry *ste = SCMalloc(sizeof(DetectThresholdEntry)); if (ste == NULL) { SCReturnPtr(NULL, "DetectThresholdEntry"); } if (PKT_IS_IPV4(p)) ste->ipv = 4; else if (PKT_IS_IPV6(p)) ste->ipv = 6; ste->sid = s->id; ste->gid = s->gid; if (td->track == TRACK_DST) { COPY_ADDRESS(&p->dst, &ste->addr); } else if (td->track == TRACK_SRC) { COPY_ADDRESS(&p->src, &ste->addr); } ste->track = td->track; ste->seconds = td->seconds; ste->tv_timeout = 0; SCReturnPtr(ste, "DetectThresholdEntry"); }
static int LogFilestoreLogger(ThreadVars *tv, void *thread_data, const Packet *p, const File *ff, const FileData *ffd, uint8_t flags) { SCEnter(); LogFilestoreLogThread *aft = (LogFilestoreLogThread *)thread_data; char filename[PATH_MAX] = ""; int file_fd = -1; int ipver = -1; /* no flow, no htp state */ if (p->flow == NULL) { SCReturnInt(TM_ECODE_OK); } if (PKT_IS_IPV4(p)) { ipver = AF_INET; } else if (PKT_IS_IPV6(p)) { ipver = AF_INET6; } else { return 0; } SCLogDebug("ff %p, ffd %p", ff, ffd); snprintf(filename, sizeof(filename), "%s/file.%u", g_logfile_base_dir, ff->file_id); if (flags & OUTPUT_FILEDATA_FLAG_OPEN) { aft->file_cnt++; /* create a .meta file that contains time, src/dst/sp/dp/proto */ LogFilestoreLogCreateMetaFile(p, ff, filename, ipver); file_fd = open(filename, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644); if (file_fd == -1) { SCLogDebug("failed to create file"); return -1; } /* we can get called with a NULL ffd when we need to close */ } else if (ffd != NULL) { file_fd = open(filename, O_APPEND | O_NOFOLLOW | O_WRONLY); if (file_fd == -1) { SCLogDebug("failed to open file %s: %s", filename, strerror(errno)); return -1; } } if (file_fd != -1) { ssize_t r = write(file_fd, (const void *)ffd->data, (size_t)ffd->len); if (r == -1) { SCLogDebug("write failed: %s", strerror(errno)); } close(file_fd); } if (flags & OUTPUT_FILEDATA_FLAG_CLOSE) { LogFilestoreLogCloseMetaFile(ff); } 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 PrefilterPacketFragOffsetMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx) { if (PKT_IS_PSEUDOPKT(p)) return; uint16_t frag; if (PKT_IS_IPV4(p)) { frag = IPV4_GET_IPOFFSET(p); } else if (PKT_IS_IPV6(p)) { if (IPV6_EXTHDR_ISSET_FH(p)) { frag = IPV6_EXTHDR_GET_FH_OFFSET(p); } else { return; } } else { SCLogDebug("No IPv4 or IPv6 packet"); return; } const PrefilterPacketHeaderCtx *ctx = pectx; if (FragOffsetMatch(frag, ctx->v1.u8[0], ctx->v1.u16[1])) { PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt); } }
/** * \brief This function is used to match fragoffset rule option set on a packet * * \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 DetectFragOffsetData * * \retval 0 no match or frag is not set * \retval 1 match * */ int DetectFragOffsetMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) { uint16_t frag = 0; const DetectFragOffsetData *fragoff = (const DetectFragOffsetData *)ctx; if (PKT_IS_PSEUDOPKT(p)) return 0; if (PKT_IS_IPV4(p)) { frag = IPV4_GET_IPOFFSET(p); } else if (PKT_IS_IPV6(p)) { if(IPV6_EXTHDR_FH(p)) { frag = IPV6_EXTHDR_GET_FH_OFFSET(p); } else { return 0; } } else { SCLogDebug("No IPv4 or IPv6 packet"); return 0; } switch (fragoff->mode) { case FRAG_LESS: if (frag < fragoff->frag_off) return 1; break; case FRAG_MORE: if (frag > fragoff->frag_off) return 1; break; default: if (frag == fragoff->frag_off) return 1; } return 0; }
/** * \brief Handle a packet and check if needs a threshold logic * * \param de_ctx Detection Context * \param sig Signature pointer * \param p Packet structure * * \retval 1 alert is not suppressed * \retval 0 alert is suppressed */ static int PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, uint16_t pos) { SCEnter(); int ret = 1; DetectThresholdData *td = NULL; SigMatch *sm = NULL; if (!(PKT_IS_IPV4(p) || PKT_IS_IPV6(p))) { SCReturnInt(1); } do { td = SigGetThresholdTypeIter(s, p, &sm); if (td != NULL) { SCLogDebug("td %p", td); ret = PacketAlertThreshold(de_ctx, det_ctx, td, p, s); if (ret == 0) { /* It doesn't match threshold, remove it */ PacketAlertRemove(p, pos); break; } } } while (sm != NULL); SCReturnInt(ret); }
/** * \brief Handle a packet and check if needs a threshold logic * Also apply rule action if necessary. * * \param de_ctx Detection Context * \param sig Signature pointer * \param p Packet structure * * \retval 1 alert is not suppressed * \retval 0 alert is suppressed */ static int PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, uint16_t pos) { SCEnter(); int ret = 1; DetectThresholdData *td = NULL; SigMatch *sm = NULL; if (!(PKT_IS_IPV4(p) || PKT_IS_IPV6(p))) { SCReturnInt(1); } do { td = SigGetThresholdTypeIter(s, p, &sm); if (td != NULL) { SCLogDebug("td %p", td); /* PacketAlertThreshold returns 2 if the alert is suppressed but * we do need to apply rule actions to the packet. */ ret = PacketAlertThreshold(de_ctx, det_ctx, td, p, s); if (ret == 0 || ret == 2) { /* It doesn't match threshold, remove it */ SCReturnInt(ret); } } } while (sm != NULL); SCReturnInt(1); }
static void PrefilterPacketTtlMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx) { if (PKT_IS_PSEUDOPKT(p)) { SCReturn; } uint8_t pttl; if (PKT_IS_IPV4(p)) { pttl = IPV4_GET_IPTTL(p); } else if (PKT_IS_IPV6(p)) { pttl = IPV6_GET_HLIM(p); } else { SCLogDebug("Packet is of not IPv4 or IPv6"); return; } const PrefilterPacketHeaderCtx *ctx = pectx; if (PrefilterPacketHeaderExtraMatch(ctx, p) == FALSE) return; if (TtlMatch(pttl, ctx->v1.u8[0], ctx->v1.u8[1], ctx->v1.u8[2])) { SCLogDebug("packet matches ttl/hl %u", pttl); PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt); } }
static int AlertDebugLogLogger(ThreadVars *tv, void *thread_data, const Packet *p) { if (PKT_IS_IPV4(p) || PKT_IS_IPV6(p)) { return AlertDebugLogger(tv, p, thread_data); } else if (p->events.cnt > 0) { return AlertDebugLogDecoderEvent(tv, p, thread_data); } return TM_ECODE_OK; }
void SCProfilingPrintPacketProfile(Packet *p) { if (profiling_packets_csv_enabled == 0 || p == NULL || packet_profile_csv_fp == NULL || p->profile == NULL) { return; } uint64_t delta = p->profile->ticks_end - p->profile->ticks_start; fprintf(packet_profile_csv_fp, "%"PRIu64",%c,%"PRIu8",%"PRIu64",", p->pcap_cnt, PKT_IS_IPV4(p) ? '4' : (PKT_IS_IPV6(p) ? '6' : '?'), p->proto, delta); int i; uint64_t tmm_total = 0; uint64_t tmm_streamtcp_tcp = 0; for (i = 0; i < TMM_SIZE; i++) { PktProfilingTmmData *pdt = &p->profile->tmm[i]; uint64_t tmm_delta = pdt->ticks_end - pdt->ticks_start; fprintf(packet_profile_csv_fp, "%"PRIu64",", tmm_delta); tmm_total += tmm_delta; if (p->proto == IPPROTO_TCP && i == TMM_STREAMTCP) { tmm_streamtcp_tcp = tmm_delta; } } fprintf(packet_profile_csv_fp, "%"PRIu64",", delta - tmm_total); uint64_t app_total = 0; for (i = 0; i < ALPROTO_MAX; i++) { PktProfilingAppData *pdt = &p->profile->app[i]; fprintf(packet_profile_csv_fp,"%"PRIu64",", pdt->ticks_spent); if (p->proto == IPPROTO_TCP) { app_total += pdt->ticks_spent; } } uint64_t real_tcp = 0; if (tmm_streamtcp_tcp > app_total) real_tcp = tmm_streamtcp_tcp - app_total; fprintf(packet_profile_csv_fp, "%"PRIu64",", real_tcp); fprintf(packet_profile_csv_fp, "%"PRIu64",", p->profile->proto_detect); for (i = 0; i < PROF_DETECT_SIZE; i++) { PktProfilingDetectData *pdt = &p->profile->detect[i]; fprintf(packet_profile_csv_fp,"%"PRIu64",", pdt->ticks_spent); } fprintf(packet_profile_csv_fp,"\n"); }
static int JsonAlertLogger(ThreadVars *tv, void *thread_data, const Packet *p) { JsonAlertLogThread *aft = thread_data; if (PKT_IS_IPV4(p) || PKT_IS_IPV6(p)) { return AlertJson(tv, aft, p); } else if (p->alerts.cnt > 0) { return AlertJsonDecoderEvent(tv, aft, p); } return 0; }
TmEcode AlertFastLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { if (PKT_IS_IPV4(p)) { return AlertFastLogIPv4(tv, p, data, pq, postpq); } else if (PKT_IS_IPV6(p)) { return AlertFastLogIPv6(tv, p, data, pq, postpq); } else if (p->events.cnt > 0) { return AlertFastLogDecoderEvent(tv, p, data, pq, postpq); } return TM_ECODE_OK; }
/* initialize the flow from the first packet * we see from it. */ void FlowInit(Flow *f, const Packet *p) { SCEnter(); SCLogDebug("flow %p", f); f->proto = p->proto; f->recursion_level = p->recursion_level; f->vlan_id[0] = p->vlan_id[0]; f->vlan_id[1] = p->vlan_id[1]; if (PKT_IS_IPV4(p)) { FLOW_SET_IPV4_SRC_ADDR_FROM_PACKET(p, &f->src); FLOW_SET_IPV4_DST_ADDR_FROM_PACKET(p, &f->dst); f->flags |= FLOW_IPV4; } else if (PKT_IS_IPV6(p)) { FLOW_SET_IPV6_SRC_ADDR_FROM_PACKET(p, &f->src); FLOW_SET_IPV6_DST_ADDR_FROM_PACKET(p, &f->dst); f->flags |= FLOW_IPV6; } #ifdef DEBUG /* XXX handle default */ else { printf("FIXME: %s:%s:%" PRId32 "\n", __FILE__, __FUNCTION__, __LINE__); } #endif if (p->tcph != NULL) { /* XXX MACRO */ SET_TCP_SRC_PORT(p,&f->sp); SET_TCP_DST_PORT(p,&f->dp); } else if (p->udph != NULL) { /* XXX MACRO */ SET_UDP_SRC_PORT(p,&f->sp); SET_UDP_DST_PORT(p,&f->dp); } else if (p->icmpv4h != NULL) { f->type = p->type; f->code = p->code; } else if (p->icmpv6h != NULL) { f->type = p->type; f->code = p->code; } else if (p->sctph != NULL) { /* XXX MACRO */ SET_SCTP_SRC_PORT(p,&f->sp); SET_SCTP_DST_PORT(p,&f->dp); } /* XXX handle default */ #ifdef DEBUG else { printf("FIXME: %s:%s:%" PRId32 "\n", __FILE__, __FUNCTION__, __LINE__); } #endif COPY_TIMESTAMP(&p->ts, &f->startts); f->protomap = FlowGetProtoMapping(f->proto); SCReturn; }
/** \internal * \brief fill lua stack with header info * \param luastate the lua state * \param p packet * \retval cnt number of data items placed on the stack * * Places: ipver (number), src ip (string), dst ip (string), protocol (number), * sp or icmp type (number), dp or icmp code (number). */ static int LuaCallbackTuplePushToStackFromPacket(lua_State *luastate, const Packet *p) { int ipver = 0; if (PKT_IS_IPV4(p)) { ipver = 4; } else if (PKT_IS_IPV6(p)) { ipver = 6; } lua_pushnumber (luastate, ipver); if (ipver == 0) return 1; 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)); } lua_pushstring (luastate, srcip); lua_pushstring (luastate, dstip); /* proto and ports (or type/code) */ lua_pushnumber (luastate, p->proto); if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP) { lua_pushnumber (luastate, p->sp); lua_pushnumber (luastate, p->dp); } else if (p->proto == IPPROTO_ICMP || p->proto == IPPROTO_ICMPV6) { lua_pushnumber (luastate, p->type); lua_pushnumber (luastate, p->code); } else { lua_pushnumber (luastate, 0); lua_pushnumber (luastate, 0); } return 6; }
/** * \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); }
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 TTL rule option on a packet with those passed via ttl: * * \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 DetectTtlData * * \retval 0 no match * \retval 1 match */ int DetectTtlMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) { if (PKT_IS_PSEUDOPKT(p)) return 0; uint8_t pttl; if (PKT_IS_IPV4(p)) { pttl = IPV4_GET_IPTTL(p); } else if (PKT_IS_IPV6(p)) { pttl = IPV6_GET_HLIM(p); } else { SCLogDebug("Packet is of not IPv4 or IPv6"); return 0; } const DetectTtlData *ttld = (const DetectTtlData *)ctx; return TtlMatch(pttl, ttld->mode, ttld->ttl1, ttld->ttl2); }
/** * \brief Unified2 main entry function * * \retval TM_ECODE_OK all is good * \retval TM_ECODE_FAILED serious error */ TmEcode Unified2Alert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { int ret = 0; if (PKT_IS_IPV4(p)) { ret = Unified2IPv4TypeAlert (t, p, data, pq); } else if(PKT_IS_IPV6(p)) { ret = Unified2IPv6TypeAlert (t, p, data, pq); } else { /* we're only supporting IPv4 and IPv6 */ return TM_ECODE_OK; } if (ret != 0) { return TM_ECODE_FAILED; } return TM_ECODE_OK; }
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); }
static int LogFileLogger(ThreadVars *tv, void *thread_data, const Packet *p, const File *ff) { SCEnter(); LogFileLogThread *aft = (LogFileLogThread *)thread_data; int ipver = -1; if (PKT_IS_IPV4(p)) { ipver = AF_INET; } else if (PKT_IS_IPV6(p)) { ipver = AF_INET6; } else { return 0; } BUG_ON(ff->flags & FILE_LOGGED); SCLogDebug("ff %p", ff); LogFileWriteJsonRecord(aft, p, ff, ipver); aft->file_cnt++; return 0; }
/** * \brief This function is used to match fragoffset rule option set on a packet * * \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 DetectFragOffsetData * * \retval 0 no match or frag is not set * \retval 1 match * */ int DetectFragOffsetMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) { uint16_t frag = 0; const DetectFragOffsetData *fragoff = (const DetectFragOffsetData *)ctx; if (PKT_IS_PSEUDOPKT(p)) return 0; if (PKT_IS_IPV4(p)) { frag = IPV4_GET_IPOFFSET(p); } else if (PKT_IS_IPV6(p)) { if (IPV6_EXTHDR_ISSET_FH(p)) { frag = IPV6_EXTHDR_GET_FH_OFFSET(p); } else { return 0; } } else { SCLogDebug("No IPv4 or IPv6 packet"); return 0; } return FragOffsetMatch(frag, fragoff->mode, fragoff->frag_off);; }
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); }
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; }
json_t *CreateJSONHeader(Packet *p, int direction_sensitive, char *event_type) { char timebuf[64]; char srcip[46], dstip[46]; Port sp, dp; json_t *js = json_object(); if (unlikely(js == NULL)) return NULL; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); srcip[0] = '\0'; dstip[0] = '\0'; if (direction_sensitive) { if ((PKT_IS_TOCLIENT(p))) { 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)); } sp = p->sp; dp = p->dp; } else { if (PKT_IS_IPV4(p)) { PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), dstip, sizeof(dstip)); } else if (PKT_IS_IPV6(p)) { PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), dstip, sizeof(dstip)); } sp = p->dp; dp = p->sp; } } else { 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)); } sp = p->sp; dp = p->dp; } char proto[16]; if (SCProtoNameValid(IP_GET_IPPROTO(p)) == TRUE) { strlcpy(proto, known_proto[IP_GET_IPPROTO(p)], sizeof(proto)); } else { snprintf(proto, sizeof(proto), "%03" PRIu32, IP_GET_IPPROTO(p)); } /* time & tx */ json_object_set_new(js, "time", json_string(timebuf)); /* sensor id */ if (sensor_id >= 0) json_object_set_new(js, "sensor_id", json_integer(sensor_id)); /* pcap_cnt */ if (p->pcap_cnt != 0) { json_object_set_new(js, "pcap_cnt", json_integer(p->pcap_cnt)); } if (event_type) { json_object_set_new(js, "event_type", json_string(event_type)); } /* vlan */ if (p->vlan_idx > 0) { json_t *js_vlan; switch (p->vlan_idx) { case 1: json_object_set_new(js, "vlan", json_integer(ntohs(GET_VLAN_ID(p->vlanh[0])))); break; case 2: js_vlan = json_array(); if (unlikely(js != NULL)) { json_array_append_new(js_vlan, json_integer(ntohs(GET_VLAN_ID(p->vlanh[0])))); json_array_append_new(js_vlan, json_integer(ntohs(GET_VLAN_ID(p->vlanh[1])))); json_object_set_new(js, "vlan", js_vlan); } break; default: /* shouldn't get here */ break; } } /* tuple */ json_object_set_new(js, "src_ip", json_string(srcip)); switch(p->proto) { case IPPROTO_ICMP: break; case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_SCTP: json_object_set_new(js, "src_port", json_integer(sp)); break; } json_object_set_new(js, "dest_ip", json_string(dstip)); switch(p->proto) { case IPPROTO_ICMP: break; case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_SCTP: json_object_set_new(js, "dest_port", json_integer(dp)); break; } json_object_set_new(js, "proto", json_string(proto)); switch (p->proto) { case IPPROTO_ICMP: if (p->icmpv4h) { json_object_set_new(js, "icmp_type", json_integer(p->icmpv4h->type)); json_object_set_new(js, "icmp_code", json_integer(p->icmpv4h->code)); } break; case IPPROTO_ICMPV6: if (p->icmpv6h) { json_object_set_new(js, "icmp_type", json_integer(p->icmpv6h->type)); json_object_set_new(js, "icmp_code", json_integer(p->icmpv6h->code)); } break; } return js; }
void SCProfilingAddPacket(Packet *p) { if (p == NULL || p->profile == NULL || p->profile->ticks_start == 0 || p->profile->ticks_end == 0 || p->profile->ticks_start > p->profile->ticks_end) return; pthread_mutex_lock(&packet_profile_lock); { if (profiling_packets_csv_enabled) SCProfilingPrintPacketProfile(p); if (PKT_IS_IPV4(p)) { SCProfilePacketData *pd = &packet_profile_data4[p->proto]; uint64_t delta = p->profile->ticks_end - p->profile->ticks_start; if (pd->min == 0 || delta < pd->min) { pd->min = delta; } if (pd->max < delta) { pd->max = delta; } pd->tot += delta; pd->cnt ++; if (IS_TUNNEL_PKT(p)) { pd = &packet_profile_data4[256]; if (pd->min == 0 || delta < pd->min) { pd->min = delta; } if (pd->max < delta) { pd->max = delta; } pd->tot += delta; pd->cnt ++; } SCProfilingUpdatePacketGenericRecords(p, p->profile->flowworker, packet_profile_flowworker_data, PROFILE_FLOWWORKER_SIZE); SCProfilingUpdatePacketTmmRecords(p); SCProfilingUpdatePacketAppRecords(p); SCProfilingUpdatePacketDetectRecords(p); SCProfilingUpdatePacketLogRecords(p); } else if (PKT_IS_IPV6(p)) { SCProfilePacketData *pd = &packet_profile_data6[p->proto]; uint64_t delta = p->profile->ticks_end - p->profile->ticks_start; if (pd->min == 0 || delta < pd->min) { pd->min = delta; } if (pd->max < delta) { pd->max = delta; } pd->tot += delta; pd->cnt ++; if (IS_TUNNEL_PKT(p)) { pd = &packet_profile_data6[256]; if (pd->min == 0 || delta < pd->min) { pd->min = delta; } if (pd->max < delta) { pd->max = delta; } pd->tot += delta; pd->cnt ++; } SCProfilingUpdatePacketGenericRecords(p, p->profile->flowworker, packet_profile_flowworker_data, PROFILE_FLOWWORKER_SIZE); SCProfilingUpdatePacketTmmRecords(p); SCProfilingUpdatePacketAppRecords(p); SCProfilingUpdatePacketDetectRecords(p); SCProfilingUpdatePacketLogRecords(p); } } pthread_mutex_unlock(&packet_profile_lock); }
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; }