static void DBLogAlState(void *alstate, AppProto proto, const Packet *p, json_t *js, const char *name) { if ((PKT_IS_TOCLIENT(p))) { /* drop server -> client log */ return; } char timebuf[64]; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); char srcip[46], dstip[46]; json_t *dbjs = json_object(); if (dbjs == NULL) return; 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 { 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)); } #if 0 char *dbtype = AlstateGetDBType(alstate, proto); char *username = AlstateGetUsername(alstate, proto); char *dbname = AlstateGetDBname(alstate, proto); char *dbopr = AlstateGetDBOpr(alstate, proto); char *action = AlstateGetAction(alstate, proto); char *meta = AlstateGetMetaInfo(alstate, proto); if (dbtype != NULL) { json_object_set_new(dbjs, "time", timebuf); } if (username != NULL) { json_object_set_new(dbjs, "user", username); } if (dbname != NULL) { json_object_set_new(dbjs, "db_name", dbname); } if (dbopr != NULL) { json_object_set_new(dbjs, "db_operation", dbopr); } if (action != NULL) { json_object_set_new(dbjs, "action", action); } if (meta != NULL) { json_object_set_new(dbjs, "meta_info", meta); } #endif json_object_set_new(js, name, dbjs); }
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); } }
TmEcode AlertFastLogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { AlertFastLogThread *aft = (AlertFastLogThread *)data; int i; char timebuf[64]; char *action = ""; extern uint8_t engine_mode; if (p->alerts.cnt == 0) return TM_ECODE_OK; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); char srcip[46], dstip[46]; 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)); for (i = 0; i < p->alerts.cnt; i++) { PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } if ((pa->action & ACTION_DROP) && IS_ENGINE_MODE_IPS(engine_mode)) { action = "[Drop] "; } else if (pa->action & ACTION_DROP) { action = "[wDrop] "; } 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), "PROTO:%03" PRIu32, IP_GET_IPPROTO(p)); } SCMutexLock(&aft->file_ctx->fp_mutex); fprintf(aft->file_ctx->fp, "%s %s[**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: %s] [Priority: %" PRIu32 "] {%s} %s:%" PRIu32 " -> %s:%" PRIu32 "\n", timebuf, action, pa->s->gid, pa->s->id, pa->s->rev, pa->s->msg, pa->s->class_msg, pa->s->prio, proto, srcip, p->sp, dstip, p->dp); fflush(aft->file_ctx->fp); aft->file_ctx->alerts++; SCMutexUnlock(&aft->file_ctx->fp_mutex); } return TM_ECODE_OK; }
/** * \brief Function which is called to print the IPv6 alerts to the syslog * * \param tv Pointer to the threadvars * \param p Pointer to the packet * \param data pointer to the AlertSyslogThread * * \return On succes return TM_ECODE_OK */ static TmEcode AlertSyslogIPv6(ThreadVars *tv, const Packet *p, void *data) { AlertSyslogThread *ast = (AlertSyslogThread *)data; int i; char *action = ""; if (p->alerts.cnt == 0) return TM_ECODE_OK; SCMutexLock(&ast->file_ctx->fp_mutex); ast->file_ctx->alerts += p->alerts.cnt; for (i = 0; i < p->alerts.cnt; i++) { const PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } char srcip[46], dstip[46]; 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)); if ((pa->action & ACTION_DROP) && EngineModeIsIPS()) { action = "[Drop] "; } else if (pa->action & ACTION_DROP) { action = "[wDrop] "; } if (SCProtoNameValid(IPV6_GET_L4PROTO(p)) == TRUE) { syslog(alert_syslog_level, "%s[%" PRIu32 ":%" PRIu32 ":%" "" PRIu32 "] %s [Classification: %s] [Priority: %" "" PRIu32 "] {%s} %s:%" PRIu32 " -> %s:%" PRIu32 "", action, pa->s->gid, pa->s->id, pa->s->rev, pa->s->msg, pa->s->class_msg, pa->s->prio, known_proto[IPV6_GET_L4PROTO(p)], srcip, p->sp, dstip, p->dp); } else { syslog(alert_syslog_level, "%s[%" PRIu32 ":%" PRIu32 ":%" "" PRIu32 "] %s [Classification: %s] [Priority: %" "" PRIu32 "] {PROTO:%03" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 "", action, pa->s->gid, pa->s->id, pa->s->rev, pa->s->msg, pa->s->class_msg, pa->s->prio, IPV6_GET_L4PROTO(p), srcip, p->sp, dstip, p->dp); } } SCMutexUnlock(&ast->file_ctx->fp_mutex); return TM_ECODE_OK; }
static int LogTcpDataLoggerDir(ThreadVars *tv, void *thread_data, const Flow *f, const uint8_t *data, uint32_t data_len, uint64_t tx_id, uint8_t flags) { SCEnter(); LogTcpDataLogThread *aft = thread_data; LogTcpDataFileCtx *td = aft->tcpdatalog_ctx; const char *mode = "a"; if (flags & OUTPUT_STREAMING_FLAG_OPEN) mode = "w"; if (data && data_len) { char srcip[46] = "", dstip[46] = ""; if (FLOW_IS_IPV4(f)) { PrintInet(AF_INET, (const void *)&f->src.addr_data32[0], srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)&f->dst.addr_data32[0], dstip, sizeof(dstip)); } else if (FLOW_IS_IPV6(f)) { PrintInet(AF_INET6, (const void *)f->src.addr_data32, srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)f->dst.addr_data32, dstip, sizeof(dstip)); } char name[PATH_MAX]; char tx[64] = { 0 }; if (flags & OUTPUT_STREAMING_FLAG_TRANSACTION) { snprintf(tx, sizeof(tx), "%"PRIu64, tx_id); } snprintf(name, sizeof(name), "%s/%s/%s_%u-%s_%u-%s-%s.data", td->log_dir, td->type == STREAMING_HTTP_BODIES ? "http" : "tcp", srcip, f->sp, dstip, f->dp, tx, flags & OUTPUT_STREAMING_FLAG_TOSERVER ? "ts" : "tc"); FILE *fp = fopen(name, mode); BUG_ON(fp == NULL); // PrintRawDataFp(stdout, (uint8_t *)data, data_len); fwrite(data, data_len, 1, fp); fclose(fp); } SCReturnInt(TM_ECODE_OK); }
/** \internal * \brief fill lua stack with header info * \param luastate the lua state * \param f flow, locked * \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 LuaCallbackTuplePushToStackFromFlow(lua_State *luastate, const Flow *f) { int ipver = 0; if (FLOW_IS_IPV4(f)) { ipver = 4; } else if (FLOW_IS_IPV6(f)) { ipver = 6; } lua_pushnumber (luastate, ipver); if (ipver == 0) return 1; char srcip[46] = "", dstip[46] = ""; if (FLOW_IS_IPV4(f)) { PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), dstip, sizeof(dstip)); } else if (FLOW_IS_IPV6(f)) { PrintInet(AF_INET6, (const void *)&(f->src.address), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)&(f->dst.address), dstip, sizeof(dstip)); } lua_pushstring (luastate, srcip); lua_pushstring (luastate, dstip); /* proto and ports (or type/code) */ lua_pushnumber (luastate, f->proto); if (f->proto == IPPROTO_TCP || f->proto == IPPROTO_UDP) { lua_pushnumber (luastate, f->sp); lua_pushnumber (luastate, f->dp); } else if (f->proto == IPPROTO_ICMP || f->proto == IPPROTO_ICMPV6) { lua_pushnumber (luastate, f->type); lua_pushnumber (luastate, f->code); } else { lua_pushnumber (luastate, 0); lua_pushnumber (luastate, 0); } return 6; }
/** \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 Debug print function for printing addresses * * \param Address object * * \todo IPv6 */ void AddressDebugPrint(Address *a) { if (a == NULL) return; switch (a->family) { case AF_INET: { char s[16]; PrintInet(AF_INET, (const void *)&a->addr_data32[0], s, sizeof(s)); SCLogDebug("%s", s); break; } } }
static int LogTcpDataLoggerFile(ThreadVars *tv, void *thread_data, const Flow *f, const uint8_t *data, uint32_t data_len, uint64_t tx_id, uint8_t flags) { SCEnter(); LogTcpDataLogThread *aft = thread_data; LogTcpDataFileCtx *td = aft->tcpdatalog_ctx; if (data && data_len) { MemBufferReset(aft->buffer); char srcip[46] = "", dstip[46] = ""; if (FLOW_IS_IPV4(f)) { PrintInet(AF_INET, (const void *)&f->src.addr_data32[0], srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)&f->dst.addr_data32[0], dstip, sizeof(dstip)); } else if (FLOW_IS_IPV6(f)) { PrintInet(AF_INET6, (const void *)f->src.addr_data32, srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)f->dst.addr_data32, dstip, sizeof(dstip)); } char name[PATH_MAX]; snprintf(name, sizeof(name), "%s_%u-%s_%u-%s:", srcip, f->sp, dstip, f->dp, flags & OUTPUT_STREAMING_FLAG_TOSERVER ? "ts" : "tc"); PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)name,strlen(name)); MemBufferWriteString(aft->buffer, "\n"); PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)data,data_len); td->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), MEMBUFFER_OFFSET(aft->buffer), td->file_ctx); } SCReturnInt(TM_ECODE_OK); }
int TLSGetIPInformations(const Packet *p, char* srcip, size_t srcip_len, Port* sp, char* dstip, size_t dstip_len, Port* dp, int ipproto) { if ((PKT_IS_TOSERVER(p))) { switch (ipproto) { case AF_INET: PrintInet(AF_INET, (const void *) GET_IPV4_SRC_ADDR_PTR(p), srcip, srcip_len); PrintInet(AF_INET, (const void *) GET_IPV4_DST_ADDR_PTR(p), dstip, dstip_len); break; case AF_INET6: PrintInet(AF_INET6, (const void *) GET_IPV6_SRC_ADDR(p), srcip, srcip_len); PrintInet(AF_INET6, (const void *) GET_IPV6_DST_ADDR(p), dstip, dstip_len); break; default: return 0; } *sp = p->sp; *dp = p->dp; } else { switch (ipproto) { case AF_INET: PrintInet(AF_INET, (const void *) GET_IPV4_DST_ADDR_PTR(p), srcip, srcip_len); PrintInet(AF_INET, (const void *) GET_IPV4_SRC_ADDR_PTR(p), dstip, dstip_len); break; case AF_INET6: PrintInet(AF_INET6, (const void *) GET_IPV6_DST_ADDR(p), srcip, srcip_len); PrintInet(AF_INET6, (const void *) GET_IPV6_SRC_ADDR(p), dstip, dstip_len); break; default: return 0; } *sp = p->dp; *dp = p->sp; } return 1; }
/** DecodeICMPV4test05 * \brief dest. unreachable, administratively prohibited * \retval 1 Expected test value */ static int DecodeICMPV4test05(void) { uint8_t raw_icmpv4[] = { 0x0b, 0x00, 0x5c, 0x46, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x30, 0x02, 0x17, 0x40, 0x00, 0x01, 0x06, 0xd6, 0xbd, 0xc0, 0xa8, 0x02, 0x05, 0x3d, 0x23, 0xa1, 0x23, 0x04, 0x18, 0x00, 0x50, 0xd2, 0x08, 0xc2, 0x48, }; Packet *p = SCMalloc(SIZE_OF_PACKET); if (unlikely(p == NULL)) return 0; ThreadVars tv; DecodeThreadVars dtv; int ret = 0; IPV4Hdr ip4h; memset(&ip4h, 0, sizeof(IPV4Hdr)); memset(&tv, 0, sizeof(ThreadVars)); memset(p, 0, SIZE_OF_PACKET); memset(&dtv, 0, sizeof(DecodeThreadVars)); FlowInitConfig(FLOW_QUIET); p->src.family = AF_INET; p->dst.family = AF_INET; p->src.addr_data32[0] = UTHSetIPv4Address("4.3.2.1");; p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4");; ip4h.s_ip_src.s_addr = p->src.addr_data32[0]; ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0]; p->ip4h = &ip4h; DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4), NULL); if (NULL == p->icmpv4h) { goto end; } /* check the type,code pair is correct - type 11, code 0 */ if (p->icmpv4h->type != 11 || p->icmpv4h->code != 0) { goto end; } /* check it's src port 1048 to dst port 80 */ if (p->icmpv4vars.emb_sport != 1048 || p->icmpv4vars.emb_dport != 80) { goto end; } // check the src,dst IPs contained inside char s[16], d[16]; PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_src), s, sizeof(s)); PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_dst), d, sizeof(d)); // ICMPv4 embedding IPV4 192.168.2.5->61.35.161.35 if (strcmp(s, "192.168.2.5") == 0 && strcmp(d, "61.35.161.35") == 0) { ret = 1; } end: FlowShutdown(); SCFree(p); return ret; }
/** DecodeICMPV4test04 * \brief dest. unreachable, administratively prohibited * \retval 1 Expected test value */ static int DecodeICMPV4test04(void) { uint8_t raw_icmpv4[] = { 0x03, 0x0a, 0x36, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x3c, 0x62, 0xee, 0x40, 0x00, 0x33, 0x06, 0xb4, 0x8f, 0xc0, 0xa8, 0x01, 0x0d, 0x58, 0x60, 0x16, 0x29, 0xb1, 0x0a, 0x00, 0x32, 0x3e, 0x36, 0x38, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0, 0x72, 0x04, 0x00, 0x00, 0x02, 0x04, 0x05, 0x8a, 0x04, 0x02, 0x08, 0x0a }; Packet *p = SCMalloc(SIZE_OF_PACKET); if (unlikely(p == NULL)) return 0; ThreadVars tv; DecodeThreadVars dtv; int ret = 0; IPV4Hdr ip4h; memset(&ip4h, 0, sizeof(IPV4Hdr)); memset(&tv, 0, sizeof(ThreadVars)); memset(p, 0, SIZE_OF_PACKET); memset(&dtv, 0, sizeof(DecodeThreadVars)); FlowInitConfig(FLOW_QUIET); p->src.family = AF_INET; p->dst.family = AF_INET; p->src.addr_data32[0] = UTHSetIPv4Address("4.3.2.1");; p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4");; ip4h.s_ip_src.s_addr = p->src.addr_data32[0]; ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0]; p->ip4h = &ip4h; DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4), NULL); if (NULL == p->icmpv4h) { goto end; } /* check the type,code pair is correct - type 3, code 10 */ if (p->icmpv4h->type != 3 || p->icmpv4h->code != 10) { goto end; } /* check it's src port 45322 to dst port 50 */ if (p->icmpv4vars.emb_sport != 45322 || p->icmpv4vars.emb_dport != 50) { goto end; } // check the src,dst IPs contained inside char s[16], d[16]; PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_src), s, sizeof(s)); PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_dst), d, sizeof(d)); // ICMPv4 embedding IPV4 192.168.1.13->88.96.22.41 if (strcmp(s, "192.168.1.13") == 0 && strcmp(d, "88.96.22.41") == 0) { ret = 1; } end: FlowShutdown(); SCFree(p); return ret; }
/** * Note, this is the IP header, plus a bit of the original packet, not the whole thing! */ int DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len ) { /** Check the sizes, the header must fit at least */ if (len < IPV4_HEADER_LEN) { SCLogDebug("DecodePartialIPV4: ICMPV4_IPV4_TRUNC_PKT"); ENGINE_SET_INVALID_EVENT(p, ICMPV4_IPV4_TRUNC_PKT); return -1; } IPV4Hdr *icmp4_ip4h = (IPV4Hdr*)partial_packet; /** Check the embedded version */ if (IPV4_GET_RAW_VER(icmp4_ip4h) != 4) { /** Check the embedded version */ SCLogDebug("DecodePartialIPV4: ICMPv4 contains Unknown IPV4 version " "ICMPV4_IPV4_UNKNOWN_VER"); ENGINE_SET_INVALID_EVENT(p, ICMPV4_IPV4_UNKNOWN_VER); return -1; } /** We need to fill icmpv4vars */ p->icmpv4vars.emb_ipv4h = icmp4_ip4h; /** Get the IP address from the contained packet */ p->icmpv4vars.emb_ip4_src = IPV4_GET_RAW_IPSRC(icmp4_ip4h); p->icmpv4vars.emb_ip4_dst = IPV4_GET_RAW_IPDST(icmp4_ip4h); p->icmpv4vars.emb_ip4_hlen=IPV4_GET_RAW_HLEN(icmp4_ip4h) << 2; switch (IPV4_GET_RAW_IPPROTO(icmp4_ip4h)) { case IPPROTO_TCP: if (len >= IPV4_HEADER_LEN + TCP_HEADER_LEN ) { p->icmpv4vars.emb_tcph = (TCPHdr*)(partial_packet + IPV4_HEADER_LEN); p->icmpv4vars.emb_sport = ntohs(p->icmpv4vars.emb_tcph->th_sport); p->icmpv4vars.emb_dport = ntohs(p->icmpv4vars.emb_tcph->th_dport); p->icmpv4vars.emb_ip4_proto = IPPROTO_TCP; SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->TCP header sport: " "%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport, p->icmpv4vars.emb_dport); } else if (len >= IPV4_HEADER_LEN + 4) { /* only access th_sport and th_dport */ TCPHdr *emb_tcph = (TCPHdr*)(partial_packet + IPV4_HEADER_LEN); p->icmpv4vars.emb_tcph = NULL; p->icmpv4vars.emb_sport = ntohs(emb_tcph->th_sport); p->icmpv4vars.emb_dport = ntohs(emb_tcph->th_dport); p->icmpv4vars.emb_ip4_proto = IPPROTO_TCP; SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->TCP partial header sport: " "%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport, p->icmpv4vars.emb_dport); } else { SCLogDebug("DecodePartialIPV4: Warning, ICMPV4->IPV4->TCP " "header Didn't fit in the packet!"); p->icmpv4vars.emb_sport = 0; p->icmpv4vars.emb_dport = 0; } break; case IPPROTO_UDP: if (len >= IPV4_HEADER_LEN + UDP_HEADER_LEN ) { p->icmpv4vars.emb_udph = (UDPHdr*)(partial_packet + IPV4_HEADER_LEN); p->icmpv4vars.emb_sport = ntohs(p->icmpv4vars.emb_udph->uh_sport); p->icmpv4vars.emb_dport = ntohs(p->icmpv4vars.emb_udph->uh_dport); p->icmpv4vars.emb_ip4_proto = IPPROTO_UDP; SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->UDP header sport: " "%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport, p->icmpv4vars.emb_dport); } else { SCLogDebug("DecodePartialIPV4: Warning, ICMPV4->IPV4->UDP " "header Didn't fit in the packet!"); p->icmpv4vars.emb_sport = 0; p->icmpv4vars.emb_dport = 0; } break; case IPPROTO_ICMP: if (len >= IPV4_HEADER_LEN + ICMPV4_HEADER_LEN ) { p->icmpv4vars.emb_icmpv4h = (ICMPV4Hdr*)(partial_packet + IPV4_HEADER_LEN); p->icmpv4vars.emb_sport = 0; p->icmpv4vars.emb_dport = 0; p->icmpv4vars.emb_ip4_proto = IPPROTO_ICMP; SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->ICMP header"); } break; } /* debug print */ #ifdef DEBUG char s[16], d[16]; PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_src), s, sizeof(s)); PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_dst), d, sizeof(d)); SCLogDebug("ICMPv4 embedding IPV4 %s->%s - PROTO: %" PRIu32 " ID: %" PRIu32 "", s,d, IPV4_GET_RAW_IPPROTO(icmp4_ip4h), IPV4_GET_RAW_IPID(icmp4_ip4h)); #endif return 0; }
/** DecodeICMPV4test03 * \brief TTL exceeded * \retval Expected test value: 1 */ static int DecodeICMPV4test03(void) { uint8_t raw_icmpv4[] = { 0x0b, 0x00, 0x6a, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x3c, 0x64, 0x15, 0x00, 0x00, 0x01, 0x11, 0xde, 0xfd, 0xc0, 0xa8, 0x01, 0x0d, 0xd1, 0x55, 0xe3, 0x93, 0x8b, 0x12, 0x82, 0xaa, 0x00, 0x28, 0x7c, 0xdd }; Packet *p = SCMalloc(SIZE_OF_PACKET); if (unlikely(p == NULL)) return 0; ThreadVars tv; DecodeThreadVars dtv; int ret = 0; IPV4Hdr ip4h; memset(&ip4h, 0, sizeof(IPV4Hdr)); memset(&tv, 0, sizeof(ThreadVars)); memset(p, 0, SIZE_OF_PACKET); memset(&dtv, 0, sizeof(DecodeThreadVars)); FlowInitConfig(FLOW_QUIET); p->src.family = AF_INET; p->dst.family = AF_INET; p->src.addr_data32[0] = UTHSetIPv4Address("4.3.2.1");; p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4");; ip4h.s_ip_src.s_addr = p->src.addr_data32[0]; ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0]; p->ip4h = &ip4h; DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4), NULL); if (NULL == p->icmpv4h) { printf("NULL == p->icmpv4h: "); goto end; } /* check it's type 11 code 0 */ if (p->icmpv4h->type != 11 || p->icmpv4h->code != 0) { printf("p->icmpv4h->type %u, p->icmpv4h->code %u: ", p->icmpv4h->type, p->icmpv4h->code); goto end; } /* check it's source port 35602 to port 33450 */ if (p->icmpv4vars.emb_sport != 35602 || p->icmpv4vars.emb_dport != 33450) { printf("p->icmpv4vars.emb_sport %u, p->icmpv4vars.emb_dport %u: ", p->icmpv4vars.emb_sport, p->icmpv4vars.emb_dport); goto end; } /* check the src,dst IPs contained inside */ char s[16], d[16]; PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_src), s, sizeof(s)); PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_dst), d, sizeof(d)); /* ICMPv4 embedding IPV4 192.168.1.13->209.85.227.147 pass */ if (strcmp(s, "192.168.1.13") == 0 && strcmp(d, "209.85.227.147") == 0) { ret = 1; } else { printf("s %s, d %s: ", s, d); } end: FlowShutdown(); SCFree(p); return ret; }
static TmEcode LogHttpLogIPWrapper(ThreadVars *tv, void *data, const Packet *p, Flow *f, HtpState *htp_state, htp_tx_t *tx, uint64_t tx_id, int ipproto) { SCEnter(); LogHttpLogThread *aft = (LogHttpLogThread *)data; LogHttpFileCtx *hlog = aft->httplog_ctx; char timebuf[64]; /* check if we have HTTP state or not */ CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); char srcip[46], dstip[46]; Port sp, dp; if ((PKT_IS_TOSERVER(p))) { switch (ipproto) { 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: goto end; } sp = p->sp; dp = p->dp; } else { switch (ipproto) { case AF_INET: 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)); break; case AF_INET6: 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)); break; default: goto end; } sp = p->dp; dp = p->sp; } SCLogDebug("got a HTTP request and now logging !!"); /* reset */ MemBufferReset(aft->buffer); if (hlog->flags & LOG_HTTP_CUSTOM) { LogHttpLogCustom(aft, tx, &p->ts, srcip, sp, dstip, dp); } else { /* time */ MemBufferWriteString(aft->buffer, "%s ", timebuf); /* hostname */ if (tx->request_hostname != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_hostname), bstr_len(tx->request_hostname)); } else { MemBufferWriteString(aft->buffer, "<hostname unknown>"); } MemBufferWriteString(aft->buffer, " [**] "); /* uri */ if (tx->request_uri != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_uri), bstr_len(tx->request_uri)); } MemBufferWriteString(aft->buffer, " [**] "); /* user agent */ htp_header_t *h_user_agent = NULL; if (tx->request_headers != NULL) { h_user_agent = htp_table_get_c(tx->request_headers, "user-agent"); } if (h_user_agent != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(h_user_agent->value), bstr_len(h_user_agent->value)); } else { MemBufferWriteString(aft->buffer, "<useragent unknown>"); } if (hlog->flags & LOG_HTTP_EXTENDED) { LogHttpLogExtended(aft, tx); } /* ip/tcp header info */ MemBufferWriteString(aft->buffer, " [**] %s:%" PRIu16 " -> %s:%" PRIu16 "\n", srcip, sp, dstip, dp); } aft->uri_cnt ++; SCMutexLock(&hlog->file_ctx->fp_mutex); hlog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), MEMBUFFER_OFFSET(aft->buffer), hlog->file_ctx); SCMutexUnlock(&hlog->file_ctx->fp_mutex); end: SCReturnInt(0); }
int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { int ret; StatsIncr(tv, dtv->counter_ipv6); /* do the actual decoding */ ret = DecodeIPV6Packet (tv, dtv, p, pkt, len); if (unlikely(ret < 0)) { p->ip6h = NULL; return TM_ECODE_FAILED; } #ifdef DEBUG if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */ /* debug print */ char s[46], d[46]; PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), s, sizeof(s)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), d, sizeof(d)); SCLogDebug("IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: %" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32 "", s,d, IPV6_GET_CLASS(p), IPV6_GET_FLOW(p), IPV6_GET_NH(p), IPV6_GET_PLEN(p), IPV6_GET_HLIM(p)); } #endif /* DEBUG */ /* now process the Ext headers and/or the L4 Layer */ switch(IPV6_GET_NH(p)) { case IPPROTO_TCP: IPV6_SET_L4PROTO (p, IPPROTO_TCP); DecodeTCP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); return TM_ECODE_OK; case IPPROTO_UDP: IPV6_SET_L4PROTO (p, IPPROTO_UDP); DecodeUDP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); return TM_ECODE_OK; case IPPROTO_ICMPV6: IPV6_SET_L4PROTO (p, IPPROTO_ICMPV6); DecodeICMPV6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); return TM_ECODE_OK; case IPPROTO_SCTP: IPV6_SET_L4PROTO (p, IPPROTO_SCTP); DecodeSCTP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); return TM_ECODE_OK; case IPPROTO_IPIP: IPV6_SET_L4PROTO(p, IPPROTO_IPIP); DecodeIPv4inIPv6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); return TM_ECODE_OK; case IPPROTO_IPV6: DecodeIP6inIP6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); return TM_ECODE_OK; case IPPROTO_FRAGMENT: case IPPROTO_HOPOPTS: case IPPROTO_ROUTING: case IPPROTO_NONE: case IPPROTO_DSTOPTS: case IPPROTO_AH: case IPPROTO_ESP: case IPPROTO_MH: case IPPROTO_HIP: case IPPROTO_SHIM6: DecodeIPV6ExtHdrs(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); break; case IPPROTO_ICMP: ENGINE_SET_EVENT(p,IPV6_WITH_ICMPV4); break; default: ENGINE_SET_EVENT(p, IPV6_UNKNOWN_NEXT_HEADER); IPV6_SET_L4PROTO (p, IPV6_GET_NH(p)); break; } p->proto = IPV6_GET_L4PROTO (p); /* Pass to defragger if a fragment. */ if (IPV6_EXTHDR_ISSET_FH(p)) { Packet *rp = Defrag(tv, dtv, p, pq); if (rp != NULL) { PacketEnqueue(pq,rp); } } return TM_ECODE_OK; }
static TmEcode LogHttpLogIPWrapper(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq, int ipproto) { SCEnter(); LogHttpLogThread *aft = (LogHttpLogThread *)data; LogHttpFileCtx *hlog = aft->httplog_ctx; char timebuf[64]; size_t idx = 0; /* no flow, no htp state */ if (p->flow == NULL) { SCReturnInt(TM_ECODE_OK); } /* check if we have HTTP state or not */ FLOWLOCK_WRLOCK(p->flow); /* WRITE lock before we updated flow logged id */ uint16_t proto = AppLayerGetProtoFromPacket(p); if (proto != ALPROTO_HTTP) goto end; int r = AppLayerTransactionGetLoggedId(p->flow); if (r < 0) { goto end; } size_t logged = (size_t)r; r = HtpTransactionGetLoggableId(p->flow); if (r < 0) { goto end; } size_t loggable = (size_t)r; /* nothing to do */ if (logged >= loggable) { goto end; } HtpState *htp_state = (HtpState *)AppLayerGetProtoStateFromPacket(p); if (htp_state == NULL) { SCLogDebug("no http state, so no request logging"); goto end; } if (htp_state->connp == NULL || htp_state->connp->conn == NULL) goto end; htp_tx_t *tx = NULL; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); char srcip[46], dstip[46]; Port sp, dp; if ((PKT_IS_TOSERVER(p))) { switch (ipproto) { 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: goto end; } sp = p->sp; dp = p->dp; } else { switch (ipproto) { case AF_INET: 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)); break; case AF_INET6: 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)); break; default: goto end; } sp = p->dp; dp = p->sp; } for (idx = logged; idx < loggable; idx++) { tx = list_get(htp_state->connp->conn->transactions, idx); if (tx == NULL) { SCLogDebug("tx is NULL not logging !!"); continue; } SCLogDebug("got a HTTP request and now logging !!"); /* reset */ MemBufferReset(aft->buffer); if (hlog->flags & LOG_HTTP_CUSTOM) { LogHttpLogCustom(aft, tx, &p->ts, srcip, sp, dstip, dp); } else { /* time */ MemBufferWriteString(aft->buffer, "%s ", timebuf); /* hostname */ if (tx->parsed_uri != NULL && tx->parsed_uri->hostname != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->parsed_uri->hostname), bstr_len(tx->parsed_uri->hostname)); } else { MemBufferWriteString(aft->buffer, "<hostname unknown>"); } MemBufferWriteString(aft->buffer, " [**] "); /* uri */ if (tx->request_uri != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_uri), bstr_len(tx->request_uri)); } MemBufferWriteString(aft->buffer, " [**] "); /* user agent */ htp_header_t *h_user_agent = NULL; if (tx->request_headers != NULL) { h_user_agent = table_getc(tx->request_headers, "user-agent"); } if (h_user_agent != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(h_user_agent->value), bstr_len(h_user_agent->value)); } else { MemBufferWriteString(aft->buffer, "<useragent unknown>"); } if (hlog->flags & LOG_HTTP_EXTENDED) { LogHttpLogExtended(aft, tx); } /* ip/tcp header info */ MemBufferWriteString(aft->buffer, " [**] %s:%" PRIu16 " -> %s:%" PRIu16 "\n", srcip, sp, dstip, dp); } aft->uri_cnt ++; SCMutexLock(&hlog->file_ctx->fp_mutex); MemBufferPrintToFPAsString(aft->buffer, hlog->file_ctx->fp); fflush(hlog->file_ctx->fp); SCMutexUnlock(&hlog->file_ctx->fp_mutex); AppLayerTransactionUpdateLoggedId(p->flow); } end: FLOWLOCK_UNLOCK(p->flow); SCReturnInt(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); }
/** * \brief Get variables and do some checks of the embedded IPV6 packet * * \param p Pointer to the packet we are filling * \param partial_packet Pointer to the raw packet buffer * \param len the len of the rest of the packet not processed yet * * \retval void No return value */ void DecodePartialIPV6(Packet *p, uint8_t *partial_packet, uint16_t len ) { /** Check the sizes, the header must fit at least */ if (len < IPV6_HEADER_LEN) { SCLogDebug("ICMPV6_IPV6_TRUNC_PKT"); ENGINE_SET_EVENT(p, ICMPV6_IPV6_TRUNC_PKT); return; } IPV6Hdr *icmp6_ip6h = (IPV6Hdr*)partial_packet; /** Check the embedded version */ if(((icmp6_ip6h->s_ip6_vfc & 0xf0) >> 4) != 6) { SCLogDebug("ICMPv6 contains Unknown IPV6 version " "ICMPV6_IPV6_UNKNOWN_VER"); ENGINE_SET_EVENT(p, ICMPV6_IPV6_UNKNOWN_VER); return; } /** We need to fill icmpv6vars */ p->icmpv6vars.emb_ipv6h = icmp6_ip6h; /** Get the IP6 address */ p->icmpv6vars.emb_ip6_src[0] = icmp6_ip6h->s_ip6_src[0]; p->icmpv6vars.emb_ip6_src[1] = icmp6_ip6h->s_ip6_src[1]; p->icmpv6vars.emb_ip6_src[2] = icmp6_ip6h->s_ip6_src[2]; p->icmpv6vars.emb_ip6_src[3] = icmp6_ip6h->s_ip6_src[3]; p->icmpv6vars.emb_ip6_dst[0] = icmp6_ip6h->s_ip6_dst[0]; p->icmpv6vars.emb_ip6_dst[1] = icmp6_ip6h->s_ip6_dst[1]; p->icmpv6vars.emb_ip6_dst[2] = icmp6_ip6h->s_ip6_dst[2]; p->icmpv6vars.emb_ip6_dst[3] = icmp6_ip6h->s_ip6_dst[3]; /** Get protocol and ports inside the embedded ipv6 packet and set the pointers */ p->icmpv6vars.emb_ip6_proto_next = icmp6_ip6h->s_ip6_nxt; switch (icmp6_ip6h->s_ip6_nxt) { case IPPROTO_TCP: if (len >= IPV6_HEADER_LEN + TCP_HEADER_LEN ) { p->icmpv6vars.emb_tcph = (TCPHdr*)(partial_packet + IPV6_HEADER_LEN); p->icmpv6vars.emb_sport = p->icmpv6vars.emb_tcph->th_sport; p->icmpv6vars.emb_dport = p->icmpv6vars.emb_tcph->th_dport; SCLogDebug("ICMPV6->IPV6->TCP header sport: " "%"PRIu8" dport %"PRIu8"", p->icmpv6vars.emb_sport, p->icmpv6vars.emb_dport); } else { SCLogDebug("Warning, ICMPV6->IPV6->TCP " "header Didn't fit in the packet!"); p->icmpv6vars.emb_sport = 0; p->icmpv6vars.emb_dport = 0; } break; case IPPROTO_UDP: if (len >= IPV6_HEADER_LEN + UDP_HEADER_LEN ) { p->icmpv6vars.emb_udph = (UDPHdr*)(partial_packet + IPV6_HEADER_LEN); p->icmpv6vars.emb_sport = p->icmpv6vars.emb_udph->uh_sport; p->icmpv6vars.emb_dport = p->icmpv6vars.emb_udph->uh_dport; SCLogDebug("ICMPV6->IPV6->UDP header sport: " "%"PRIu8" dport %"PRIu8"", p->icmpv6vars.emb_sport, p->icmpv6vars.emb_dport); } else { SCLogDebug("Warning, ICMPV6->IPV6->UDP " "header Didn't fit in the packet!"); p->icmpv6vars.emb_sport = 0; p->icmpv6vars.emb_dport = 0; } break; case IPPROTO_ICMPV6: p->icmpv6vars.emb_icmpv6h = (ICMPV6Hdr*)(partial_packet + IPV6_HEADER_LEN); p->icmpv6vars.emb_sport = 0; p->icmpv6vars.emb_dport = 0; SCLogDebug("ICMPV6->IPV6->ICMP header"); break; } /* debug print */ #ifdef DEBUG char s[46], d[46]; PrintInet(AF_INET6, (const void *)p->icmpv6vars.emb_ip6_src, s, sizeof(s)); PrintInet(AF_INET6, (const void *)p->icmpv6vars.emb_ip6_dst, d, sizeof(d)); SCLogDebug("ICMPv6 embedding IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: " "%" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32, s, d, IPV6_GET_RAW_CLASS(icmp6_ip6h), IPV6_GET_RAW_FLOW(icmp6_ip6h), IPV6_GET_RAW_NH(icmp6_ip6h), IPV6_GET_RAW_PLEN(icmp6_ip6h), IPV6_GET_RAW_HLIM(icmp6_ip6h)); #endif return; }
int AlertFastLogger(ThreadVars *tv, void *data, const Packet *p) { AlertFastLogThread *aft = (AlertFastLogThread *)data; int i; char timebuf[64]; int decoder_event = 0; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); 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)); } else { decoder_event = 1; } /* Buffer to store the generated alert strings. The buffer is * filled with alert strings until it doesn't have room to store * another full alert, only then is the buffer written. This is * more efficient for multiple alerts and only slightly slower for * single alerts. */ char alert_buffer[MAX_FASTLOG_BUFFER_SIZE]; for (i = 0; i < p->alerts.cnt; i++) { const PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } char *action = ""; if ((pa->action & ACTION_DROP) && EngineModeIsIPS()) { action = "[Drop] "; } else if (pa->action & ACTION_DROP) { action = "[wDrop] "; } char proto[16] = ""; if (likely(decoder_event == 0)) { if (SCProtoNameValid(IP_GET_IPPROTO(p)) == TRUE) { strlcpy(proto, known_proto[IP_GET_IPPROTO(p)], sizeof(proto)); } else { snprintf(proto, sizeof(proto), "PROTO:%03" PRIu32, IP_GET_IPPROTO(p)); } } /* Create the alert string without locking. */ int size = 0; if (likely(decoder_event == 0)) { PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, "%s %s[**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: %s] [Priority: %"PRIu32"]" " {%s} %s:%" PRIu32 " -> %s:%" PRIu32 "\n", timebuf, action, pa->s->gid, pa->s->id, pa->s->rev, pa->s->msg, pa->s->class_msg, pa->s->prio, proto, srcip, p->sp, dstip, p->dp); } else { PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, "%s %s[**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: %s] [Priority: " "%" PRIu32 "] [**] [Raw pkt: ", timebuf, action, pa->s->gid, pa->s->id, pa->s->rev, pa->s->msg, pa->s->class_msg, pa->s->prio); PrintBufferRawLineHex(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, GET_PKT_DATA(p), GET_PKT_LEN(p) < 32 ? GET_PKT_LEN(p) : 32); if (p->pcap_cnt != 0) { PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, "] [pcap file packet: %"PRIu64"]\n", p->pcap_cnt); } else { PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, "]\n"); } } /* Write the alert to output file */ AlertFastLogOutputAlert(aft, alert_buffer, size); } 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; }
static json_t *CreateJSONHeaderFromFlow(const Flow *f, const char *event_type) { char timebuf[64]; char srcip[46] = {0}, dstip[46] = {0}; Port sp, dp; json_t *js = json_object(); if (unlikely(js == NULL)) return NULL; struct timeval tv; memset(&tv, 0x00, sizeof(tv)); TimeGet(&tv); CreateIsoTimeString(&tv, timebuf, sizeof(timebuf)); if ((f->flags & FLOW_DIR_REVERSED) == 0) { if (FLOW_IS_IPV4(f)) { PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), dstip, sizeof(dstip)); } else if (FLOW_IS_IPV6(f)) { PrintInet(AF_INET6, (const void *)&(f->src.address), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)&(f->dst.address), dstip, sizeof(dstip)); } sp = f->sp; dp = f->dp; } else { if (FLOW_IS_IPV4(f)) { PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), dstip, sizeof(dstip)); } else if (FLOW_IS_IPV6(f)) { PrintInet(AF_INET6, (const void *)&(f->dst.address), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)&(f->src.address), dstip, sizeof(dstip)); } sp = f->dp; dp = f->sp; } char proto[16]; if (SCProtoNameValid(f->proto) == TRUE) { strlcpy(proto, known_proto[f->proto], sizeof(proto)); } else { snprintf(proto, sizeof(proto), "%03" PRIu32, f->proto); } /* time */ json_object_set_new(js, "timestamp", json_string(timebuf)); CreateJSONFlowId(js, (const Flow *)f); #if 0 // TODO /* sensor id */ if (sensor_id >= 0) json_object_set_new(js, "sensor_id", json_integer(sensor_id)); #endif /* input interface */ if (f->livedev) { json_object_set_new(js, "in_iface", json_string(f->livedev->dev)); } if (event_type) { json_object_set_new(js, "event_type", json_string(event_type)); } /* vlan */ if (f->vlan_idx > 0) { json_t *js_vlan = json_array(); json_array_append_new(js_vlan, json_integer(f->vlan_id[0])); if (f->vlan_idx > 1) { json_array_append_new(js_vlan, json_integer(f->vlan_id[1])); } json_object_set_new(js, "vlan", js_vlan); } /* tuple */ json_object_set_new(js, "src_ip", json_string(srcip)); switch(f->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(f->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 (f->proto) { case IPPROTO_ICMP: case IPPROTO_ICMPV6: json_object_set_new(js, "icmp_type", json_integer(f->icmp_s.type)); json_object_set_new(js, "icmp_code", json_integer(f->icmp_s.code)); if (f->tosrcpktcnt) { json_object_set_new(js, "response_icmp_type", json_integer(f->icmp_d.type)); json_object_set_new(js, "response_icmp_code", json_integer(f->icmp_d.code)); } break; } return js; }
static json_t *CreateJSONHeaderFromFlow(Flow *f, char *event_type, int dir) { char timebuf[64]; char srcip[46], dstip[46]; Port sp, dp; json_t *js = json_object(); if (unlikely(js == NULL)) return NULL; struct timeval tv; memset(&tv, 0x00, sizeof(tv)); TimeGet(&tv); CreateIsoTimeString(&tv, timebuf, sizeof(timebuf)); srcip[0] = '\0'; dstip[0] = '\0'; if (FLOW_IS_IPV4(f)) { if (dir == 0) { PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), dstip, sizeof(dstip)); } else { PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), dstip, sizeof(dstip)); } } else if (FLOW_IS_IPV6(f)) { if (dir == 0) { PrintInet(AF_INET6, (const void *)&(f->src.address), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)&(f->dst.address), dstip, sizeof(dstip)); } else { PrintInet(AF_INET6, (const void *)&(f->dst.address), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)&(f->src.address), dstip, sizeof(dstip)); } } if (dir == 0) { sp = f->sp; dp = f->dp; } else { sp = f->dp; dp = f->sp; } char proto[16]; if (SCProtoNameValid(f->proto) == TRUE) { strlcpy(proto, known_proto[f->proto], sizeof(proto)); } else { snprintf(proto, sizeof(proto), "%03" PRIu32, f->proto); } /* time */ json_object_set_new(js, "timestamp", json_string(timebuf)); CreateJSONFlowId(js, (const Flow *)f); #if 0 // TODO /* sensor id */ if (sensor_id >= 0) json_object_set_new(js, "sensor_id", json_integer(sensor_id)); #endif if (event_type) { json_object_set_new(js, "event_type", json_string(event_type)); } #if 0 /* vlan */ if (f->vlan_id[0] > 0) { json_t *js_vlan; switch (f->vlan_idx) { case 1: json_object_set_new(js, "vlan", json_integer(f->vlan_id[0])); break; case 2: js_vlan = json_array(); if (unlikely(js != NULL)) { json_array_append_new(js_vlan, json_integer(VLAN_GET_ID1(p))); json_array_append_new(js_vlan, json_integer(VLAN_GET_ID2(p))); json_object_set_new(js, "vlan", js_vlan); } break; default: /* shouldn't get here */ break; } } #endif /* tuple */ json_object_set_new(js, "src_ip", json_string(srcip)); switch(f->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(f->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 (f->proto) { case IPPROTO_ICMP: case IPPROTO_ICMPV6: json_object_set_new(js, "icmp_type", json_integer(f->type)); json_object_set_new(js, "icmp_code", json_integer(f->code)); break; } return js; }
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; }
void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { int ret; SCPerfCounterIncr(dtv->counter_ipv6, tv->sc_perf_pca); /* do the actual decoding */ ret = DecodeIPV6Packet (tv, dtv, p, pkt, len); if (ret < 0) { p->ip6h = NULL; return; } #ifdef DEBUG if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */ /* debug print */ char s[46], d[46]; PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), s, sizeof(s)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), d, sizeof(d)); SCLogDebug("IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: %" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32 "", s,d, IPV6_GET_CLASS(p), IPV6_GET_FLOW(p), IPV6_GET_NH(p), IPV6_GET_PLEN(p), IPV6_GET_HLIM(p)); } #endif /* DEBUG */ /* now process the Ext headers and/or the L4 Layer */ switch(IPV6_GET_NH(p)) { case IPPROTO_TCP: IPV6_SET_L4PROTO (p, IPPROTO_TCP); return DecodeTCP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); case IPPROTO_UDP: IPV6_SET_L4PROTO (p, IPPROTO_UDP); return DecodeUDP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); break; case IPPROTO_ICMPV6: IPV6_SET_L4PROTO (p, IPPROTO_ICMPV6); return DecodeICMPV6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); case IPPROTO_SCTP: IPV6_SET_L4PROTO (p, IPPROTO_SCTP); return DecodeSCTP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); case IPPROTO_IPIP: IPV6_SET_L4PROTO(p, IPPROTO_IPIP); return DecodeIPv4inIPv6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); case IPPROTO_IPV6: return DecodeIP6inIP6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); case IPPROTO_FRAGMENT: case IPPROTO_HOPOPTS: case IPPROTO_ROUTING: case IPPROTO_NONE: case IPPROTO_DSTOPTS: case IPPROTO_AH: case IPPROTO_ESP: DecodeIPV6ExtHdrs(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); break; default: p->proto = IPV6_GET_NH(p); break; } /* Pass to defragger if a fragment. */ if (IPV6_EXTHDR_ISSET_FH(p)) { Packet *rp = Defrag(tv, dtv, NULL, p); if (rp != NULL) { DecodeIPV6(tv, dtv, rp, (uint8_t *)rp->ip6h, IPV6_GET_PLEN(rp) + IPV6_HEADER_LEN, pq); PacketEnqueue(pq, rp); /* Not really a tunnel packet, but we're piggybacking that * functionality for now. */ SET_TUNNEL_PKT(p); } } #ifdef DEBUG if (IPV6_EXTHDR_ISSET_FH(p)) { SCLogDebug("IPV6 FRAG - HDRLEN: %" PRIuMAX " NH: %" PRIu32 " OFFSET: %" PRIu32 " ID: %" PRIu32 "", (uintmax_t)IPV6_EXTHDR_GET_FH_HDRLEN(p), IPV6_EXTHDR_GET_FH_NH(p), IPV6_EXTHDR_GET_FH_OFFSET(p), IPV6_EXTHDR_GET_FH_ID(p)); } if (IPV6_EXTHDR_ISSET_RH(p)) { SCLogDebug("IPV6 ROUTE - HDRLEN: %" PRIu32 " NH: %" PRIu32 " TYPE: %" PRIu32 "", IPV6_EXTHDR_GET_RH_HDRLEN(p), IPV6_EXTHDR_GET_RH_NH(p), IPV6_EXTHDR_GET_RH_TYPE(p)); } if (IPV6_EXTHDR_ISSET_HH(p)) { SCLogDebug("IPV6 HOPOPT - HDRLEN: %" PRIu32 " NH: %" PRIu32 "", IPV6_EXTHDR_GET_HH_HDRLEN(p), IPV6_EXTHDR_GET_HH_NH(p)); } if (IPV6_EXTHDR_ISSET_DH1(p)) { SCLogDebug("IPV6 DSTOPT1 - HDRLEN: %" PRIu32 " NH: %" PRIu32 "", IPV6_EXTHDR_GET_DH1_HDRLEN(p), IPV6_EXTHDR_GET_DH1_NH(p)); } if (IPV6_EXTHDR_ISSET_DH2(p)) { SCLogDebug("IPV6 DSTOPT2 - HDRLEN: %" PRIu32 " NH: %" PRIu32 "", IPV6_EXTHDR_GET_DH2_HDRLEN(p), IPV6_EXTHDR_GET_DH2_NH(p)); } #endif return; }
/** * \brief Add Source and Target fields to the IDMEF alert. * These objects contains IP addresses, source and destination * ports (see sections 4.2.4.3 and 4.2.4.4 of RFC 4765). * * \return 0 if ok */ static int EventToSourceTarget(Packet *p, idmef_alert_t *alert) { int ret; idmef_node_t *node; idmef_source_t *source; idmef_target_t *target; idmef_address_t *address; idmef_service_t *service; prelude_string_t *string; static char saddr[128], daddr[128]; uint8_t ip_vers; uint8_t ip_proto; SCEnter(); if ( !p ) SCReturnInt(0); if ( ! IPH_IS_VALID(p) ) SCReturnInt(0); if (PKT_IS_IPV4(p)) { ip_vers = 4; ip_proto = IPV4_GET_RAW_IPPROTO(p->ip4h); PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), saddr, sizeof(saddr)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), daddr, sizeof(daddr)); } else if (PKT_IS_IPV6(p)) { ip_vers = 6; ip_proto = IPV6_GET_L4PROTO(p); PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), saddr, sizeof(saddr)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), daddr, sizeof(daddr)); } else SCReturnInt(0); ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND); if ( ret < 0 ) SCReturnInt(ret); ret = idmef_source_new_service(source, &service); if ( ret < 0 ) SCReturnInt(ret); if ( p->tcph || p->udph ) idmef_service_set_port(service, p->sp); idmef_service_set_ip_version(service, ip_vers); idmef_service_set_iana_protocol_number(service, ip_proto); ret = idmef_source_new_node(source, &node); if ( ret < 0 ) SCReturnInt(ret); ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND); if ( ret < 0 ) SCReturnInt(ret); ret = idmef_address_new_address(address, &string); if ( ret < 0 ) SCReturnInt(ret); prelude_string_set_ref(string, saddr); ret = idmef_alert_new_target(alert, &target, IDMEF_LIST_APPEND); if ( ret < 0 ) SCReturnInt(ret); ret = idmef_target_new_service(target, &service); if ( ret < 0 ) SCReturnInt(ret); if ( p->tcph || p->udph ) idmef_service_set_port(service, p->dp); idmef_service_set_ip_version(service, ip_vers); idmef_service_set_iana_protocol_number(service, ip_proto); ret = idmef_target_new_node(target, &node); if ( ret < 0 ) SCReturnInt(ret); ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND); if ( ret < 0 ) SCReturnInt(ret); ret = idmef_address_new_address(address, &string); if ( ret < 0 ) SCReturnInt(ret); prelude_string_set_ref(string, daddr); SCReturnInt(0); }
/** * \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); }
/** * \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; }
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; }
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); } }