summaryrefslogtreecommitdiffstats
path: root/eigrpd/eigrp_dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'eigrpd/eigrp_dump.c')
-rw-r--r--eigrpd/eigrp_dump.c580
1 files changed, 580 insertions, 0 deletions
diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c
new file mode 100644
index 0000000..e1ad51a
--- /dev/null
+++ b/eigrpd/eigrp_dump.c
@@ -0,0 +1,580 @@
+/*
+ * EIGRP Dump Functions and Debugging.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra 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 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra 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 this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "linklist.h"
+#include "thread.h"
+#include "prefix.h"
+#include "command.h"
+#include "stream.h"
+#include "log.h"
+#include "sockopt.h"
+#include "table.h"
+#include "keychain.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_network.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_topology.h"
+
+/* Enable debug option variables -- valid only session. */
+unsigned long term_debug_eigrp = 0;
+unsigned long term_debug_eigrp_nei = 0;
+unsigned long term_debug_eigrp_packet[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+unsigned long term_debug_eigrp_zebra = 6;
+unsigned long term_debug_eigrp_transmit = 0;
+
+/* Configuration debug option variables. */
+unsigned long conf_debug_eigrp = 0;
+unsigned long conf_debug_eigrp_nei = 0;
+unsigned long conf_debug_eigrp_packet[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+unsigned long conf_debug_eigrp_zebra = 0;
+unsigned long conf_debug_eigrp_transmit = 0;
+
+
+static int config_write_debug(struct vty *vty)
+{
+ int write = 0;
+ int i;
+
+ const char *type_str[] = {"update", "request", "query", "reply",
+ "hello", "", "probe", "ack",
+ "", "SIA query", "SIA reply", "stub",
+ "all"};
+ const char *detail_str[] = {
+ "", " send", " recv", "",
+ " detail", " send detail", " recv detail", " detail"};
+
+
+ /* debug eigrp event. */
+
+ /* debug eigrp packet */
+ for (i = 0; i < 10; i++) {
+ if (conf_debug_eigrp_packet[i] == 0
+ && term_debug_eigrp_packet[i] == 0)
+ continue;
+
+ vty_out(vty, "debug eigrp packet %s%s\n", type_str[i],
+ detail_str[conf_debug_eigrp_packet[i]]);
+ write = 1;
+ }
+
+ return write;
+}
+
+static int eigrp_neighbor_packet_queue_sum(struct eigrp_interface *ei)
+{
+ struct eigrp_neighbor *nbr;
+ struct listnode *node, *nnode;
+ int sum;
+ sum = 0;
+
+ for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) {
+ sum += nbr->retrans_queue->count;
+ }
+
+ return sum;
+}
+
+/*
+ * Expects header to be in host order
+ */
+void eigrp_ip_header_dump(struct ip *iph)
+{
+ /* IP Header dump. */
+ zlog_debug("ip_v %u", iph->ip_v);
+ zlog_debug("ip_hl %u", iph->ip_hl);
+ zlog_debug("ip_tos %u", iph->ip_tos);
+ zlog_debug("ip_len %u", iph->ip_len);
+ zlog_debug("ip_id %u", (uint32_t)iph->ip_id);
+ zlog_debug("ip_off %u", (uint32_t)iph->ip_off);
+ zlog_debug("ip_ttl %u", iph->ip_ttl);
+ zlog_debug("ip_p %u", iph->ip_p);
+ zlog_debug("ip_sum 0x%x", (uint32_t)iph->ip_sum);
+ zlog_debug("ip_src %pI4", &iph->ip_src);
+ zlog_debug("ip_dst %pI4", &iph->ip_dst);
+}
+
+/*
+ * Expects header to be in host order
+ */
+void eigrp_header_dump(struct eigrp_header *eigrph)
+{
+ /* EIGRP Header dump. */
+ zlog_debug("eigrp_version %u", eigrph->version);
+ zlog_debug("eigrp_opcode %u", eigrph->opcode);
+ zlog_debug("eigrp_checksum 0x%x", ntohs(eigrph->checksum));
+ zlog_debug("eigrp_flags 0x%x", ntohl(eigrph->flags));
+ zlog_debug("eigrp_sequence %u", ntohl(eigrph->sequence));
+ zlog_debug("eigrp_ack %u", ntohl(eigrph->ack));
+ zlog_debug("eigrp_vrid %u", ntohs(eigrph->vrid));
+ zlog_debug("eigrp_AS %u", ntohs(eigrph->ASNumber));
+}
+
+const char *eigrp_if_name_string(struct eigrp_interface *ei)
+{
+ if (!ei)
+ return "inactive";
+
+ return ei->ifp->name;
+}
+
+void show_ip_eigrp_interface_header(struct vty *vty, struct eigrp *eigrp)
+{
+
+ vty_out(vty,
+ "\nEIGRP interfaces for AS(%d)\n\n%-16s %-10s %-10s %-6s %-12s %-7s %-14s %-12s %-8s %-8s %-8s\n %-44s %-12s %-7s %-14s %-12s %-8s\n",
+ eigrp->AS, "Interface", "Bandwidth", "Delay", "Peers",
+ "Xmit Queue", "Mean", "Pacing Time", "Multicast", "Pending",
+ "Hello", "Holdtime", "", "Un/Reliable", "SRTT", "Un/Reliable",
+ "Flow Timer", "Routes");
+}
+
+void show_ip_eigrp_interface_sub(struct vty *vty, struct eigrp *eigrp,
+ struct eigrp_interface *ei)
+{
+ vty_out(vty, "%-16s ", IF_NAME(ei));
+ vty_out(vty, "%-11u", ei->params.bandwidth);
+ vty_out(vty, "%-11u", ei->params.delay);
+ vty_out(vty, "%-7u", ei->nbrs->count);
+ vty_out(vty, "%u %c %-10u", 0, '/',
+ eigrp_neighbor_packet_queue_sum(ei));
+ vty_out(vty, "%-7u %-14u %-12u %-8u", 0, 0, 0, 0);
+ vty_out(vty, "%-8u %-8u \n", ei->params.v_hello, ei->params.v_wait);
+}
+
+void show_ip_eigrp_interface_detail(struct vty *vty, struct eigrp *eigrp,
+ struct eigrp_interface *ei)
+{
+ vty_out(vty, "%-2s %s %d %-3s \n", "", "Hello interval is ", 0, " sec");
+ vty_out(vty, "%-2s %s %s \n", "", "Next xmit serial", "<none>");
+ vty_out(vty, "%-2s %s %d %s %d %s %d %s %d \n", "",
+ "Un/reliable mcasts: ", 0, "/", 0, "Un/reliable ucasts: ", 0,
+ "/", 0);
+ vty_out(vty, "%-2s %s %d %s %d %s %d \n", "", "Mcast exceptions: ", 0,
+ " CR packets: ", 0, " ACKs suppressed: ", 0);
+ vty_out(vty, "%-2s %s %d %s %d \n", "", "Retransmissions sent: ", 0,
+ "Out-of-sequence rcvd: ", 0);
+ vty_out(vty, "%-2s %s %s %s \n", "", "Authentication mode is ", "not",
+ "set");
+ vty_out(vty, "%-2s %s \n", "", "Use multicast");
+}
+
+void show_ip_eigrp_neighbor_header(struct vty *vty, struct eigrp *eigrp)
+{
+ vty_out(vty,
+ "\nEIGRP neighbors for AS(%d)\n\n%-3s %-17s %-20s %-6s %-8s %-6s %-5s %-5s %-5s\n %-41s %-6s %-8s %-6s %-4s %-6s %-5s \n",
+ eigrp->AS, "H", "Address", "Interface", "Hold", "Uptime",
+ "SRTT", "RTO", "Q", "Seq", "", "(sec)", "", "(ms)", "", "Cnt",
+ "Num");
+}
+
+void show_ip_eigrp_neighbor_sub(struct vty *vty, struct eigrp_neighbor *nbr,
+ int detail)
+{
+
+ vty_out(vty, "%-3u %-17pI4 %-21s", 0, &nbr->src, IF_NAME(nbr->ei));
+ if (nbr->t_holddown)
+ vty_out(vty, "%-7lu",
+ thread_timer_remain_second(nbr->t_holddown));
+ else
+ vty_out(vty, "- ");
+ vty_out(vty, "%-8u %-6u %-5u", 0, 0, EIGRP_PACKET_RETRANS_TIME);
+ vty_out(vty, "%-7lu", nbr->retrans_queue->count);
+ vty_out(vty, "%u\n", nbr->recv_sequence_number);
+
+
+ if (detail) {
+ vty_out(vty, " Version %u.%u/%u.%u", nbr->os_rel_major,
+ nbr->os_rel_minor, nbr->tlv_rel_major,
+ nbr->tlv_rel_minor);
+ vty_out(vty, ", Retrans: %lu, Retries: %lu",
+ nbr->retrans_queue->count, 0UL);
+ vty_out(vty, ", %s\n", eigrp_nbr_state_str(nbr));
+ }
+}
+
+/*
+ * Print standard header for show EIGRP topology output
+ */
+void show_ip_eigrp_topology_header(struct vty *vty, struct eigrp *eigrp)
+{
+ vty_out(vty, "\nEIGRP Topology Table for AS(%d)/ID(%pI4)\n\n",
+ eigrp->AS, &eigrp->router_id);
+ vty_out(vty,
+ "Codes: P - Passive, A - Active, U - Update, Q - Query, R - Reply\n r - reply Status, s - sia Status\n\n");
+}
+
+void show_ip_eigrp_prefix_descriptor(struct vty *vty,
+ struct eigrp_prefix_descriptor *tn)
+{
+ struct list *successors = eigrp_topology_get_successor(tn);
+
+ vty_out(vty, "%-3c", (tn->state > 0) ? 'A' : 'P');
+
+ vty_out(vty, "%pFX, ", tn->destination);
+ vty_out(vty, "%u successors, ", (successors) ? successors->count : 0);
+ vty_out(vty, "FD is %u, serno: %" PRIu64 " \n", tn->fdistance,
+ tn->serno);
+
+ if (successors)
+ list_delete(&successors);
+}
+
+void show_ip_eigrp_route_descriptor(struct vty *vty, struct eigrp *eigrp,
+ struct eigrp_route_descriptor *te,
+ bool *first)
+{
+ if (te->reported_distance == EIGRP_MAX_METRIC)
+ return;
+
+ if (*first) {
+ show_ip_eigrp_prefix_descriptor(vty, te->prefix);
+ *first = false;
+ }
+
+ if (te->adv_router == eigrp->neighbor_self)
+ vty_out(vty, "%-7s%s, %s\n", " ", "via Connected",
+ IF_NAME(te->ei));
+ else {
+ vty_out(vty, "%-7s%s%pI4 (%u/%u), %s\n", " ", "via ",
+ &te->adv_router->src, te->distance,
+ te->reported_distance, IF_NAME(te->ei));
+ }
+}
+
+
+DEFUN_NOSH (show_debugging_eigrp,
+ show_debugging_eigrp_cmd,
+ "show debugging [eigrp]",
+ SHOW_STR
+ DEBUG_STR
+ EIGRP_STR)
+{
+ int i;
+
+ vty_out(vty, "EIGRP debugging status:\n");
+
+ /* Show debug status for events. */
+ if (IS_DEBUG_EIGRP(event, EVENT))
+ vty_out(vty, " EIGRP event debugging is on\n");
+
+ /* Show debug status for EIGRP Packets. */
+ for (i = 0; i < 11; i++) {
+ if (i == 8)
+ continue;
+
+ if (IS_DEBUG_EIGRP_PACKET(i, SEND)
+ && IS_DEBUG_EIGRP_PACKET(i, RECV)) {
+ vty_out(vty, " EIGRP packet %s%s debugging is on\n",
+ lookup_msg(eigrp_packet_type_str, i + 1, NULL),
+ IS_DEBUG_EIGRP_PACKET(i, PACKET_DETAIL)
+ ? " detail"
+ : "");
+ } else {
+ if (IS_DEBUG_EIGRP_PACKET(i, SEND))
+ vty_out(vty,
+ " EIGRP packet %s send%s debugging is on\n",
+ lookup_msg(eigrp_packet_type_str, i + 1,
+ NULL),
+ IS_DEBUG_EIGRP_PACKET(i, PACKET_DETAIL)
+ ? " detail"
+ : "");
+ if (IS_DEBUG_EIGRP_PACKET(i, RECV))
+ vty_out(vty,
+ " EIGRP packet %s receive%s debugging is on\n",
+ lookup_msg(eigrp_packet_type_str, i + 1,
+ NULL),
+ IS_DEBUG_EIGRP_PACKET(i, PACKET_DETAIL)
+ ? " detail"
+ : "");
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+
+/*
+ [no] debug eigrp packet (hello|dd|ls-request|ls-update|ls-ack|all)
+ [send|recv [detail]]
+*/
+
+DEFUN (debug_eigrp_transmit,
+ debug_eigrp_transmit_cmd,
+ "debug eigrp transmit <send|recv|all> [detail]",
+ DEBUG_STR
+ EIGRP_STR
+ "EIGRP transmission events\n"
+ "packet sent\n"
+ "packet received\n"
+ "all packets\n"
+ "Detailed Information\n")
+{
+ int flag = 0;
+ int idx = 2;
+
+ /* send or recv. */
+ if (argv_find(argv, argc, "send", &idx))
+ flag = EIGRP_DEBUG_SEND;
+ else if (argv_find(argv, argc, "recv", &idx))
+ flag = EIGRP_DEBUG_RECV;
+ else if (argv_find(argv, argc, "all", &idx))
+ flag = EIGRP_DEBUG_SEND_RECV;
+
+ /* detail option */
+ if (argv_find(argv, argc, "detail", &idx))
+ flag = EIGRP_DEBUG_PACKET_DETAIL;
+
+ if (vty->node == CONFIG_NODE)
+ DEBUG_TRANSMIT_ON(0, flag);
+ else
+ TERM_DEBUG_TRANSMIT_ON(0, flag);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_eigrp_transmit,
+ no_debug_eigrp_transmit_cmd,
+ "no debug eigrp transmit <send|recv|all> [detail]",
+ NO_STR
+ UNDEBUG_STR
+ EIGRP_STR
+ "EIGRP transmission events\n"
+ "packet sent\n"
+ "packet received\n"
+ "all packets\n"
+ "Detailed Information\n")
+{
+ int flag = 0;
+ int idx = 3;
+
+ /* send or recv. */
+ if (argv_find(argv, argc, "send", &idx))
+ flag = EIGRP_DEBUG_SEND;
+ else if (argv_find(argv, argc, "recv", &idx))
+ flag = EIGRP_DEBUG_RECV;
+ else if (argv_find(argv, argc, "all", &idx))
+ flag = EIGRP_DEBUG_SEND_RECV;
+
+ /* detail option */
+ if (argv_find(argv, argc, "detail", &idx))
+ flag = EIGRP_DEBUG_PACKET_DETAIL;
+
+ if (vty->node == CONFIG_NODE)
+ DEBUG_TRANSMIT_OFF(0, flag);
+ else
+ TERM_DEBUG_TRANSMIT_OFF(0, flag);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (debug_eigrp_packets,
+ debug_eigrp_packets_all_cmd,
+ "debug eigrp packets <siaquery|siareply|ack|hello|probe|query|reply|request|retry|stub|terse|update|all> [send|receive] [detail]",
+ DEBUG_STR
+ EIGRP_STR
+ "EIGRP packets\n"
+ "EIGRP SIA-Query packets\n"
+ "EIGRP SIA-Reply packets\n"
+ "EIGRP ack packets\n"
+ "EIGRP hello packets\n"
+ "EIGRP probe packets\n"
+ "EIGRP query packets\n"
+ "EIGRP reply packets\n"
+ "EIGRP request packets\n"
+ "EIGRP retransmissions\n"
+ "EIGRP stub packets\n"
+ "Display all EIGRP packets except Hellos\n"
+ "EIGRP update packets\n"
+ "Display all EIGRP packets\n"
+ "Send Packets\n"
+ "Receive Packets\n"
+ "Detail Information\n")
+{
+ int type = 0;
+ int flag = 0;
+ int i;
+ int idx = 0;
+
+ /* Check packet type. */
+ if (argv_find(argv, argc, "hello", &idx))
+ type = EIGRP_DEBUG_HELLO;
+ if (argv_find(argv, argc, "update", &idx))
+ type = EIGRP_DEBUG_UPDATE;
+ if (argv_find(argv, argc, "query", &idx))
+ type = EIGRP_DEBUG_QUERY;
+ if (argv_find(argv, argc, "ack", &idx))
+ type = EIGRP_DEBUG_ACK;
+ if (argv_find(argv, argc, "probe", &idx))
+ type = EIGRP_DEBUG_PROBE;
+ if (argv_find(argv, argc, "stub", &idx))
+ type = EIGRP_DEBUG_STUB;
+ if (argv_find(argv, argc, "reply", &idx))
+ type = EIGRP_DEBUG_REPLY;
+ if (argv_find(argv, argc, "request", &idx))
+ type = EIGRP_DEBUG_REQUEST;
+ if (argv_find(argv, argc, "siaquery", &idx))
+ type = EIGRP_DEBUG_SIAQUERY;
+ if (argv_find(argv, argc, "siareply", &idx))
+ type = EIGRP_DEBUG_SIAREPLY;
+ if (argv_find(argv, argc, "all", &idx))
+ type = EIGRP_DEBUG_PACKETS_ALL;
+
+
+ /* All packet types, both send and recv. */
+ flag = EIGRP_DEBUG_SEND_RECV;
+
+ /* send or recv. */
+ if (argv_find(argv, argc, "s", &idx))
+ flag = EIGRP_DEBUG_SEND;
+ else if (argv_find(argv, argc, "r", &idx))
+ flag = EIGRP_DEBUG_RECV;
+
+ /* detail. */
+ if (argv_find(argv, argc, "detail", &idx))
+ flag |= EIGRP_DEBUG_PACKET_DETAIL;
+
+ for (i = 0; i < 11; i++)
+ if (type & (0x01 << i)) {
+ if (vty->node == CONFIG_NODE)
+ DEBUG_PACKET_ON(i, flag);
+ else
+ TERM_DEBUG_PACKET_ON(i, flag);
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_eigrp_packets,
+ no_debug_eigrp_packets_all_cmd,
+ "no debug eigrp packets <siaquery|siareply|ack|hello|probe|query|reply|request|retry|stub|terse|update|all> [send|receive] [detail]",
+ NO_STR
+ UNDEBUG_STR
+ EIGRP_STR
+ "EIGRP packets\n"
+ "EIGRP SIA-Query packets\n"
+ "EIGRP SIA-Reply packets\n"
+ "EIGRP ack packets\n"
+ "EIGRP hello packets\n"
+ "EIGRP probe packets\n"
+ "EIGRP query packets\n"
+ "EIGRP reply packets\n"
+ "EIGRP request packets\n"
+ "EIGRP retransmissions\n"
+ "EIGRP stub packets\n"
+ "Display all EIGRP packets except Hellos\n"
+ "EIGRP update packets\n"
+ "Display all EIGRP packets\n"
+ "Send Packets\n"
+ "Receive Packets\n"
+ "Detailed Information\n")
+{
+ int type = 0;
+ int flag = 0;
+ int i;
+ int idx = 0;
+
+ /* Check packet type. */
+ if (argv_find(argv, argc, "hello", &idx))
+ type = EIGRP_DEBUG_HELLO;
+ if (argv_find(argv, argc, "update", &idx))
+ type = EIGRP_DEBUG_UPDATE;
+ if (argv_find(argv, argc, "query", &idx))
+ type = EIGRP_DEBUG_QUERY;
+ if (argv_find(argv, argc, "ack", &idx))
+ type = EIGRP_DEBUG_ACK;
+ if (argv_find(argv, argc, "probe", &idx))
+ type = EIGRP_DEBUG_PROBE;
+ if (argv_find(argv, argc, "stub", &idx))
+ type = EIGRP_DEBUG_STUB;
+ if (argv_find(argv, argc, "reply", &idx))
+ type = EIGRP_DEBUG_REPLY;
+ if (argv_find(argv, argc, "request", &idx))
+ type = EIGRP_DEBUG_REQUEST;
+ if (argv_find(argv, argc, "siaquery", &idx))
+ type = EIGRP_DEBUG_SIAQUERY;
+ if (argv_find(argv, argc, "siareply", &idx))
+ type = EIGRP_DEBUG_SIAREPLY;
+
+ /* Default, both send and recv. */
+ flag = EIGRP_DEBUG_SEND_RECV;
+
+ /* send or recv. */
+ if (argv_find(argv, argc, "send", &idx))
+ flag = EIGRP_DEBUG_SEND;
+ else if (argv_find(argv, argc, "reply", &idx))
+ flag = EIGRP_DEBUG_RECV;
+
+ /* detail. */
+ if (argv_find(argv, argc, "detail", &idx))
+ flag |= EIGRP_DEBUG_PACKET_DETAIL;
+
+ for (i = 0; i < 11; i++)
+ if (type & (0x01 << i)) {
+ if (vty->node == CONFIG_NODE)
+ DEBUG_PACKET_OFF(i, flag);
+ else
+ TERM_DEBUG_PACKET_OFF(i, flag);
+ }
+
+ return CMD_SUCCESS;
+}
+
+/* Debug node. */
+static int config_write_debug(struct vty *vty);
+static struct cmd_node eigrp_debug_node = {
+ .name = "debug",
+ .node = DEBUG_NODE,
+ .prompt = "",
+ .config_write = config_write_debug,
+};
+
+/* Initialize debug commands. */
+void eigrp_debug_init(void)
+{
+ install_node(&eigrp_debug_node);
+
+ install_element(ENABLE_NODE, &show_debugging_eigrp_cmd);
+ install_element(ENABLE_NODE, &debug_eigrp_packets_all_cmd);
+ install_element(ENABLE_NODE, &no_debug_eigrp_packets_all_cmd);
+ install_element(ENABLE_NODE, &debug_eigrp_transmit_cmd);
+ install_element(ENABLE_NODE, &no_debug_eigrp_transmit_cmd);
+
+ install_element(CONFIG_NODE, &show_debugging_eigrp_cmd);
+ install_element(CONFIG_NODE, &debug_eigrp_packets_all_cmd);
+ install_element(CONFIG_NODE, &no_debug_eigrp_packets_all_cmd);
+ install_element(CONFIG_NODE, &debug_eigrp_transmit_cmd);
+ install_element(CONFIG_NODE, &no_debug_eigrp_transmit_cmd);
+}