10f74e101Schristos /* 20f74e101Schristos * Copyright (c) 1998-2007 The TCPDUMP project 30f74e101Schristos * 40f74e101Schristos * Redistribution and use in source and binary forms, with or without 50f74e101Schristos * modification, are permitted provided that: (1) source code 60f74e101Schristos * distributions retain the above copyright notice and this paragraph 70f74e101Schristos * in its entirety, and (2) distributions including binary code include 80f74e101Schristos * the above copyright notice and this paragraph in its entirety in 90f74e101Schristos * the documentation or other materials provided with the distribution. 100f74e101Schristos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 110f74e101Schristos * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 120f74e101Schristos * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 130f74e101Schristos * FOR A PARTICULAR PURPOSE. 140f74e101Schristos * 150f74e101Schristos * Original code by Carles Kishimoto <carles.kishimoto@gmail.com> 160f74e101Schristos */ 170f74e101Schristos 18dc860a36Sspz /* \summary: Dynamic Trunking Protocol (DTP) printer */ 19dc860a36Sspz 20fdccd7e4Schristos #include <sys/cdefs.h> 21fdccd7e4Schristos #ifndef lint 22*26ba0b50Schristos __RCSID("$NetBSD: print-dtp.c,v 1.5 2024/09/02 16:15:31 christos Exp $"); 23fdccd7e4Schristos #endif 24fdccd7e4Schristos 25c74ad251Schristos #include <config.h> 260f74e101Schristos 27c74ad251Schristos #include "netdissect-stdinc.h" 280f74e101Schristos 29c74ad251Schristos #define ND_LONGJMP_FROM_TCHECK 30784088dfSchristos #include "netdissect.h" 310f74e101Schristos #include "addrtoname.h" 320f74e101Schristos #include "extract.h" 330f74e101Schristos 34784088dfSchristos 350f74e101Schristos #define DTP_HEADER_LEN 1 360f74e101Schristos #define DTP_DOMAIN_TLV 0x0001 370f74e101Schristos #define DTP_STATUS_TLV 0x0002 380f74e101Schristos #define DTP_DTP_TYPE_TLV 0x0003 390f74e101Schristos #define DTP_NEIGHBOR_TLV 0x0004 400f74e101Schristos 41026d7285Schristos static const struct tok dtp_tlv_values[] = { 42c74ad251Schristos { DTP_DOMAIN_TLV, "Domain" }, 43c74ad251Schristos { DTP_STATUS_TLV, "Status" }, 44c74ad251Schristos { DTP_DTP_TYPE_TLV, "DTP type" }, 45c74ad251Schristos { DTP_NEIGHBOR_TLV, "Neighbor" }, 460f74e101Schristos { 0, NULL} 470f74e101Schristos }; 480f74e101Schristos 490f74e101Schristos void 50c74ad251Schristos dtp_print(netdissect_options *ndo, const u_char *tptr, u_int length) 510f74e101Schristos { 52c74ad251Schristos ndo->ndo_protocol = "dtp"; 53c74ad251Schristos if (length < DTP_HEADER_LEN) { 54c74ad251Schristos ND_PRINT("[zero packet length]"); 55c74ad251Schristos goto invalid; 56c74ad251Schristos } 570f74e101Schristos 58c74ad251Schristos ND_PRINT("DTPv%u, length %u", 59c74ad251Schristos GET_U_1(tptr), 60c74ad251Schristos length); 610f74e101Schristos 620f74e101Schristos /* 630f74e101Schristos * In non-verbose mode, just print version. 640f74e101Schristos */ 65c47fd378Schristos if (ndo->ndo_vflag < 1) { 660f74e101Schristos return; 670f74e101Schristos } 680f74e101Schristos 690f74e101Schristos tptr += DTP_HEADER_LEN; 70c74ad251Schristos length -= DTP_HEADER_LEN; 710f74e101Schristos 72c74ad251Schristos while (length) { 73c74ad251Schristos uint16_t type, len; 740f74e101Schristos 75c74ad251Schristos if (length < 4) { 76c74ad251Schristos ND_PRINT("[%u bytes remaining]", length); 77c74ad251Schristos goto invalid; 78c74ad251Schristos } 79c74ad251Schristos type = GET_BE_U_2(tptr); 80c74ad251Schristos len = GET_BE_U_2(tptr + 2); 81784088dfSchristos /* XXX: should not be but sometimes it is, see the test captures */ 82784088dfSchristos if (type == 0) 830f74e101Schristos return; 84c74ad251Schristos ND_PRINT("\n\t%s (0x%04x) TLV, length %u", 850f74e101Schristos tok2str(dtp_tlv_values, "Unknown", type), 86c74ad251Schristos type, len); 870f74e101Schristos 88784088dfSchristos /* infinite loop check */ 89c74ad251Schristos if (len < 4 || len > length) { 90*26ba0b50Schristos ND_PRINT("[TLV length %u]", len); 91784088dfSchristos goto invalid; 92c74ad251Schristos } 93784088dfSchristos 940f74e101Schristos switch (type) { 950f74e101Schristos case DTP_DOMAIN_TLV: 96c74ad251Schristos ND_PRINT(", "); 97c74ad251Schristos nd_printjnp(ndo, tptr+4, len-4); 980f74e101Schristos break; 990f74e101Schristos 1000f74e101Schristos case DTP_STATUS_TLV: 1010f74e101Schristos case DTP_DTP_TYPE_TLV: 102c74ad251Schristos if (len != 5) 103784088dfSchristos goto invalid; 104c74ad251Schristos ND_PRINT(", 0x%x", GET_U_1(tptr + 4)); 1050f74e101Schristos break; 1060f74e101Schristos 1070f74e101Schristos case DTP_NEIGHBOR_TLV: 108c74ad251Schristos if (len != 10) 109784088dfSchristos goto invalid; 110c74ad251Schristos ND_PRINT(", %s", GET_ETHERADDR_STRING(tptr+4)); 1110f74e101Schristos break; 1120f74e101Schristos 1130f74e101Schristos default: 114c74ad251Schristos ND_TCHECK_LEN(tptr, len); 1150f74e101Schristos break; 1160f74e101Schristos } 1170f74e101Schristos tptr += len; 118c74ad251Schristos length -= len; 1190f74e101Schristos } 1200f74e101Schristos return; 1210f74e101Schristos 122784088dfSchristos invalid: 123c74ad251Schristos nd_print_invalid(ndo); 124c74ad251Schristos ND_TCHECK_LEN(tptr, length); 1250f74e101Schristos } 126