From: Giuseppe Longo Date: Sun, 3 Mar 2024 17:12:03 +0000 (+0100) Subject: output-json/arp: implement logger X-Git-Tag: suricata-8.0.0-beta1~1309 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=01586d884d64c029d8cf637528a2b6e399773f4e;p=thirdparty%2Fsuricata.git output-json/arp: implement logger This adds a logger for ARP, disabled by default. Ticket #6827 --- diff --git a/etc/schema.json b/etc/schema.json index c9d61b9581..d2af1037ae 100644 --- a/etc/schema.json +++ b/etc/schema.json @@ -334,6 +334,41 @@ }, "additionalProperties": false }, + "arp": { + "type": "object", + "optional": true, + "properties": { + "hw_type": { + "type": "string", + "description": "Network link protocol type" + }, + "proto_type": { + "type": "string", + "description": "Internetwork protocol for which the ARP request is intended" + }, + "opcode": { + "type": "string", + "description": "Specifies the operation that the sender is performing" + }, + "src_mac": { + "type": "string", + "description": "Physical address of the sender" + }, + "src_ip": { + "type": "string", + "description": "Logical address of the sender" + }, + "dest_mac": { + "type": "string", + "description": "Physical address of the intended receiver" + }, + "dest_ip": { + "type": "string", + "description": "Logical address of the intended receiver" + } + }, + "additionalProperties": false + }, "bittorrent_dht": { "type": "object", "properties": { diff --git a/src/Makefile.am b/src/Makefile.am index cbb781ccd0..e28eecb0f9 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -400,6 +400,7 @@ noinst_HEADERS = \ output.h \ output-json-alert.h \ output-json-anomaly.h \ + output-json-arp.h \ output-json-dcerpc.h \ output-json-dhcp.h \ output-json-dnp3.h \ @@ -1006,6 +1007,7 @@ libsuricata_c_a_SOURCES = \ output-flow.c \ output-json-alert.c \ output-json-anomaly.c \ + output-json-arp.c \ output-json.c \ output-json-common.c \ output-json-dcerpc.c \ diff --git a/src/output-json-arp.c b/src/output-json-arp.c new file mode 100644 index 0000000000..597e418d86 --- /dev/null +++ b/src/output-json-arp.c @@ -0,0 +1,111 @@ +/* Copyright (C) 2024 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Giuseppe Longo + * + * Implement JSON/eve logging for ARP Protocol. + */ + +#include "suricata-common.h" +#include "detect.h" +#include "flow.h" +#include "conf.h" + +#include "threads.h" +#include "tm-threads.h" +#include "threadvars.h" +#include "util-debug.h" + +#include "decode-ipv4.h" +#include "detect-parse.h" +#include "detect-engine.h" +#include "detect-reference.h" + +#include "output.h" +#include "output-json.h" +#include "output-json-arp.h" + +#include "util-classification-config.h" +#include "util-privs.h" +#include "util-print.h" +#include "util-proto-name.h" +#include "util-logopenfile.h" +#include "util-time.h" +#include "util-buffer.h" + +static const char *OpcodeToString(uint16_t opcode) +{ + switch (opcode) { + case 1: + return "request"; + case 2: + return "reply"; + case 3: + return "request_reverse"; + case 4: + return "reply_reverse"; + default: + return "unknown"; + } +} + +static int JsonArpLogger(ThreadVars *tv, void *thread_data, const Packet *p) +{ + OutputJsonThreadCtx *thread = thread_data; + char srcip[JSON_ADDR_LEN] = ""; + char dstip[JSON_ADDR_LEN] = ""; + const ARPHdr *arph = PacketGetARP(p); + + JsonBuilder *jb = CreateEveHeader(p, LOG_DIR_PACKET, "arp", NULL, thread->ctx); + if (unlikely(jb == NULL)) { + return TM_ECODE_OK; + } + + PrintInet(AF_INET, arph->source_ip, srcip, sizeof(srcip)); + PrintInet(AF_INET, arph->dest_ip, dstip, sizeof(dstip)); + + jb_open_object(jb, "arp"); + JB_SET_STRING(jb, "hw_type", "ethernet"); + JB_SET_STRING(jb, "proto_type", "ipv4"); + jb_set_string(jb, "opcode", OpcodeToString(ntohs(arph->opcode))); + JSONFormatAndAddMACAddr(jb, "src_mac", arph->source_mac, false); + jb_set_string(jb, "src_ip", srcip); + JSONFormatAndAddMACAddr(jb, "dest_mac", arph->dest_mac, false); + jb_set_string(jb, "dest_ip", dstip); + jb_close(jb); /* arp */ + OutputJsonBuilderBuffer(jb, thread); + jb_free(jb); + + return TM_ECODE_OK; +} + +static bool JsonArpLogCondition(ThreadVars *tv, void *thread_data, const Packet *p) +{ + return PacketIsARP(p); +} + +void JsonArpLogRegister(void) +{ + OutputRegisterPacketSubModule(LOGGER_JSON_ARP, "eve-log", "JsonArpLog", "eve-log.arp", + OutputJsonLogInitSub, JsonArpLogger, JsonArpLogCondition, JsonLogThreadInit, + JsonLogThreadDeinit, NULL); + + SCLogDebug("ARP JSON logger registered."); +} diff --git a/src/output-json-arp.h b/src/output-json-arp.h new file mode 100644 index 0000000000..353f2298ad --- /dev/null +++ b/src/output-json-arp.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2024 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Giuseppe Longo + */ + +#ifndef SURICATA_OUTPUT_JSON_ARP_H +#define SURICATA_OUTPUT_JSON_ARP_H + +void JsonArpLogRegister(void); + +#endif /* SURICATA_OUTPUT_JSON_ARP_H */ diff --git a/src/output.c b/src/output.c index 79524785a7..0661854d22 100644 --- a/src/output.c +++ b/src/output.c @@ -81,6 +81,7 @@ #include "output-json-frame.h" #include "app-layer-parser.h" #include "output-filestore.h" +#include "output-json-arp.h" typedef struct RootLogger_ { OutputLogFunc LogFunc; @@ -1107,6 +1108,8 @@ void OutputRegisterLoggers(void) "eve-log.bittorrent-dht", OutputJsonLogInitSub, ALPROTO_BITTORRENT_DHT, JsonGenericDirPacketLogger, JsonLogThreadInit, JsonLogThreadDeinit, NULL); } + /* ARP JSON logger */ + JsonArpLogRegister(); } static EveJsonSimpleAppLayerLogger simple_json_applayer_loggers[ALPROTO_MAX] = { diff --git a/src/suricata-common.h b/src/suricata-common.h index 30fa7998e0..da4b933cf7 100644 --- a/src/suricata-common.h +++ b/src/suricata-common.h @@ -491,6 +491,7 @@ typedef enum { LOGGER_JSON_FRAME, LOGGER_JSON_STREAM, LOGGER_SIZE, + LOGGER_JSON_ARP, } LoggerId; #ifndef HAVE_LUA diff --git a/src/util-profiling.c b/src/util-profiling.c index 2d344ceadd..46c587d011 100644 --- a/src/util-profiling.c +++ b/src/util-profiling.c @@ -1287,6 +1287,7 @@ const char *PacketProfileLoggerIdToString(LoggerId id) CASE_CODE(LOGGER_JSON_METADATA); CASE_CODE(LOGGER_JSON_FRAME); CASE_CODE(LOGGER_JSON_STREAM); + CASE_CODE(LOGGER_JSON_ARP); case LOGGER_SIZE: return "UNKNOWN"; diff --git a/suricata.yaml.in b/suricata.yaml.in index 879b389f14..414f12f7ea 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -300,6 +300,8 @@ outputs: - rfb - sip - quic + - arp: + enabled: no # Many events can be logged. Disabled by default - dhcp: enabled: yes # When extended mode is on, all DHCP messages are logged