/** * \internal * \brief Write meta data on a single line json record */ static void FileWriteJsonRecord(JsonFileLogThread *aft, const Packet *p, const File *ff) { MemBuffer *buffer = (MemBuffer *)aft->buffer; json_t *js = CreateJSONHeader((Packet *)p, 0, "file"); //TODO const if (unlikely(js == NULL)) return; /* reset */ MemBufferReset(buffer); json_t *hjs = json_object(); if (unlikely(hjs == NULL)) { json_decref(js); return; } json_object_set_new(hjs, "url", LogFileMetaGetUri(p, ff)); json_object_set_new(hjs, "hostname", LogFileMetaGetHost(p, ff)); json_object_set_new(hjs, "http_refer", LogFileMetaGetReferer(p, ff)); json_object_set_new(hjs, "http_user_agent", LogFileMetaGetUserAgent(p, ff)); json_object_set_new(js, "http", hjs); json_t *fjs = json_object(); if (unlikely(fjs == NULL)) { json_decref(hjs); json_decref(js); return; } char *s = BytesToString(ff->name, ff->name_len); json_object_set_new(fjs, "filename", json_string(s)); if (s != NULL) SCFree(s); if (ff->magic) json_object_set_new(fjs, "magic", json_string((char *)ff->magic)); else json_object_set_new(fjs, "magic", json_string("unknown")); switch (ff->state) { case FILE_STATE_CLOSED: json_object_set_new(fjs, "state", json_string("CLOSED")); #ifdef HAVE_NSS if (ff->flags & FILE_MD5) { size_t x; int i; char *s = SCMalloc(256); if (likely(s != NULL)) { for (i = 0, x = 0; x < sizeof(ff->md5); x++) { i += snprintf(&s[i], 255-i, "%02x", ff->md5[x]); } json_object_set_new(fjs, "md5", json_string(s)); SCFree(s); } } #endif break; case FILE_STATE_TRUNCATED: json_object_set_new(fjs, "state", json_string("TRUNCATED")); break; case FILE_STATE_ERROR: json_object_set_new(fjs, "state", json_string("ERROR")); break; default: json_object_set_new(fjs, "state", json_string("UNKNOWN")); break; } json_object_set_new(fjs, "stored", (ff->flags & FILE_STORED) ? json_true() : json_false()); json_object_set_new(fjs, "size", json_integer(ff->size)); json_object_set_new(js, "file", fjs); OutputJSONBuffer(js, aft->filelog_ctx->file_ctx, buffer); json_object_del(js, "file"); json_object_del(js, "http"); json_object_clear(js); json_decref(js); }
/** * \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); }
/** * \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); }