summaryrefslogtreecommitdiffstats
path: root/src/icmp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/icmp.cpp')
-rw-r--r--src/icmp.cpp238
1 files changed, 238 insertions, 0 deletions
diff --git a/src/icmp.cpp b/src/icmp.cpp
new file mode 100644
index 0000000..108d66d
--- /dev/null
+++ b/src/icmp.cpp
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2017-2024 OARC, Inc.
+ * Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
+ * All rights reserved.
+ *
+ * This file is part of PacketQ.
+ *
+ * PacketQ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PacketQ 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
+ * along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "icmp.h"
+#include "output.h"
+#include "packet_handler.h"
+#include "packetq.h"
+#include "tcp.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+namespace packetq {
+
+Parse_icmp::Parse_icmp()
+{
+ table_name = "icmp";
+
+ add_packet_columns();
+ add_lookup_tables();
+}
+
+void Parse_icmp::add_packet_columns()
+{
+ m_ip_helper.add_packet_columns(*this);
+
+ add_packet_column("type", "", Coltype::_int, COLUMN_TYPE);
+ add_packet_column("code", "", Coltype::_int, COLUMN_CODE);
+ add_packet_column("echo_identifier", "", Coltype::_int, COLUMN_ECHO_IDENTIFIER);
+ add_packet_column("echo_sequence", "", Coltype::_int, COLUMN_ECHO_SEQUENCE);
+ add_packet_column("du_protocol", "", Coltype::_int, COLUMN_DU_PROTOCOL);
+ add_packet_column("du_src_addr", "", Coltype::_text, COLUMN_DU_SRC_ADDR);
+ add_packet_column("du_dst_addr", "", Coltype::_text, COLUMN_DU_DST_ADDR);
+ add_packet_column("desc", "", Coltype::_text, COLUMN_DESC);
+}
+
+void Parse_icmp::add_lookup_tables()
+{
+}
+
+Packet::ParseResult Parse_icmp::parse(Packet& packet, const std::vector<int>& columns, Row& destination_row, bool sample)
+{
+ if (packet.m_ip_header.proto != IPPROTO_ICMP)
+ return Packet::ERROR;
+ if (packet.m_ip_header.ethertype != 2048) // we dont support ICMPv6 yet
+ return Packet::ERROR;
+
+ if (!sample)
+ return Packet::NOT_SAMPLED;
+
+ if (packet.m_len < 2)
+ return Packet::ERROR;
+
+ Row* r = &destination_row;
+
+ m_ip_helper.assign(r, &packet.m_ip_header, columns);
+
+ unsigned char* raw = packet.m_data;
+ int type = raw[0];
+ int code = raw[1];
+ int identifier = 0, sequence = 0, protocol = 0;
+ RefCountString *src_addr = 0, *dst_addr = 0;
+ bool src_addr_used = false, dst_addr_used = false;
+
+ switch (type) {
+ case 0:
+ if (packet.m_len < 8)
+ return Packet::ERROR;
+ identifier = get_short(&raw[4]);
+ sequence = get_short(&raw[6]);
+ break;
+ case 3: {
+ IP_header head;
+ if (packet.m_len < 8 + 20)
+ return Packet::ERROR;
+ head.decode(&raw[8], packet.m_ip_header.ethertype, 0);
+ protocol = head.proto;
+ src_addr = v4_addr2str(head.src_ip);
+ dst_addr = v4_addr2str(head.dst_ip);
+ } break;
+ case 8:
+ if (packet.m_len < 8)
+ return Packet::ERROR;
+ identifier = get_short(&raw[4]);
+ sequence = get_short(&raw[6]);
+ break;
+ }
+
+ for (auto i = columns.begin(), end = columns.end(); i != end; ++i) {
+ switch (*i) {
+ case COLUMN_TYPE:
+ acc_type.value(r) = type;
+ break;
+
+ case COLUMN_CODE:
+ acc_code.value(r) = code;
+ break;
+
+ case COLUMN_ECHO_IDENTIFIER:
+ acc_echo_identifier.value(r) = identifier;
+ break;
+
+ case COLUMN_ECHO_SEQUENCE:
+ acc_echo_sequence.value(r) = sequence;
+ break;
+
+ case COLUMN_DU_PROTOCOL:
+ acc_du_protocol.value(r) = protocol;
+ break;
+
+ case COLUMN_DU_SRC_ADDR:
+ acc_du_src_addr.value(r) = src_addr ? src_addr : RefCountString::construct("");
+ src_addr_used = true;
+ break;
+
+ case COLUMN_DU_DST_ADDR:
+ acc_du_dst_addr.value(r) = dst_addr ? dst_addr : RefCountString::construct("");
+ dst_addr_used = true;
+ break;
+
+ case COLUMN_DESC:
+ switch (type) {
+ case 0:
+ acc_desc.value(r) = RefCountString::construct("Echo Reply");
+ break;
+ case 3:
+ switch (code) {
+ case 0:
+ acc_desc.value(r) = RefCountString::construct("Destination network unreachable");
+ break;
+ case 1:
+ acc_desc.value(r) = RefCountString::construct("Destination host unreachable");
+ break;
+ case 2:
+ acc_desc.value(r) = RefCountString::construct("Destination protocol unreachable");
+ break;
+ case 3:
+ acc_desc.value(r) = RefCountString::construct("Destination port unreachable");
+ break;
+ default:
+ acc_desc.value(r) = RefCountString::construct("Destination unreachable");
+ break;
+ }
+ break;
+ case 4:
+ acc_desc.value(r) = RefCountString::construct("Source quench");
+ break;
+ case 5:
+ acc_desc.value(r) = RefCountString::construct("Redirect Message");
+ break;
+ case 6:
+ acc_desc.value(r) = RefCountString::construct("Alternate Host Address");
+ break;
+ case 8:
+ acc_desc.value(r) = RefCountString::construct("Echo Request");
+ break;
+ case 9:
+ acc_desc.value(r) = RefCountString::construct("Router Advertisement");
+ break;
+ case 10:
+ acc_desc.value(r) = RefCountString::construct("Router Solicitation");
+ break;
+ case 11:
+ acc_desc.value(r) = RefCountString::construct("Time Exceeded");
+ break;
+ case 12:
+ acc_desc.value(r) = RefCountString::construct("Bad IP header");
+ break;
+ case 13:
+ acc_desc.value(r) = RefCountString::construct("Timestamp");
+ break;
+ case 14:
+ acc_desc.value(r) = RefCountString::construct("Timestamp Reply");
+ break;
+ case 15:
+ acc_desc.value(r) = RefCountString::construct("Information Request");
+ break;
+ case 16:
+ acc_desc.value(r) = RefCountString::construct("Information Reply");
+ break;
+ case 17:
+ acc_desc.value(r) = RefCountString::construct("Address Mask Request");
+ break;
+ case 18:
+ acc_desc.value(r) = RefCountString::construct("Address Mask Reply");
+ break;
+ case 30:
+ acc_desc.value(r) = RefCountString::construct("Traceroute");
+ break;
+ default:
+ acc_desc.value(r) = RefCountString::construct("UNKNOWN TYPE");
+ }
+ break;
+ }
+ }
+
+ if (src_addr && !src_addr_used)
+ src_addr->dec_refcount();
+ if (dst_addr && !dst_addr_used)
+ dst_addr->dec_refcount();
+
+ return Packet::OK;
+}
+
+void Parse_icmp::on_table_created(Table* table, const std::vector<int>& columns)
+{
+ m_ip_helper.on_table_created(table, columns);
+
+ acc_type = table->get_accessor<int_column>("type");
+ acc_code = table->get_accessor<int_column>("code");
+ acc_echo_identifier = table->get_accessor<int_column>("echo_identifier");
+ acc_echo_sequence = table->get_accessor<int_column>("echo_sequence");
+ acc_du_protocol = table->get_accessor<int_column>("du_protocol");
+ acc_du_src_addr = table->get_accessor<text_column>("du_src_addr");
+ acc_du_dst_addr = table->get_accessor<text_column>("du_dst_addr");
+ acc_desc = table->get_accessor<text_column>("desc");
+}
+
+} // namespace packetq