1/* 2 * Copyright (c) 1998-2007 The TCPDUMP project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that: (1) source code 6 * distributions retain the above copyright notice and this paragraph 7 * in its entirety, and (2) distributions including binary code include 8 * the above copyright notice and this paragraph in its entirety in 9 * the documentation or other materials provided with the distribution. 10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 11 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 12 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13 * FOR A PARTICULAR PURPOSE. 14 * 15 * Original code by Carles Kishimoto <carles.kishimoto@gmail.com> 16 */ 17 18/* \summary: Dynamic Trunking Protocol (DTP) printer */ 19 20#include <sys/cdefs.h> 21#ifndef lint 22__RCSID("$NetBSD: print-dtp.c,v 1.4 2023/08/17 20:19:40 christos Exp $"); 23#endif 24 25#ifdef HAVE_CONFIG_H 26#include <config.h> 27#endif 28 29#include "netdissect-stdinc.h" 30 31#define ND_LONGJMP_FROM_TCHECK 32#include "netdissect.h" 33#include "addrtoname.h" 34#include "extract.h" 35 36 37#define DTP_HEADER_LEN 1 38#define DTP_DOMAIN_TLV 0x0001 39#define DTP_STATUS_TLV 0x0002 40#define DTP_DTP_TYPE_TLV 0x0003 41#define DTP_NEIGHBOR_TLV 0x0004 42 43static const struct tok dtp_tlv_values[] = { 44 { DTP_DOMAIN_TLV, "Domain" }, 45 { DTP_STATUS_TLV, "Status" }, 46 { DTP_DTP_TYPE_TLV, "DTP type" }, 47 { DTP_NEIGHBOR_TLV, "Neighbor" }, 48 { 0, NULL} 49}; 50 51void 52dtp_print(netdissect_options *ndo, const u_char *tptr, u_int length) 53{ 54 ndo->ndo_protocol = "dtp"; 55 if (length < DTP_HEADER_LEN) { 56 ND_PRINT("[zero packet length]"); 57 goto invalid; 58 } 59 60 ND_PRINT("DTPv%u, length %u", 61 GET_U_1(tptr), 62 length); 63 64 /* 65 * In non-verbose mode, just print version. 66 */ 67 if (ndo->ndo_vflag < 1) { 68 return; 69 } 70 71 tptr += DTP_HEADER_LEN; 72 length -= DTP_HEADER_LEN; 73 74 while (length) { 75 uint16_t type, len; 76 77 if (length < 4) { 78 ND_PRINT("[%u bytes remaining]", length); 79 goto invalid; 80 } 81 type = GET_BE_U_2(tptr); 82 len = GET_BE_U_2(tptr + 2); 83 /* XXX: should not be but sometimes it is, see the test captures */ 84 if (type == 0) 85 return; 86 ND_PRINT("\n\t%s (0x%04x) TLV, length %u", 87 tok2str(dtp_tlv_values, "Unknown", type), 88 type, len); 89 90 /* infinite loop check */ 91 if (len < 4 || len > length) { 92 ND_PRINT("[invalid TLV length %u]", len); 93 goto invalid; 94 } 95 96 switch (type) { 97 case DTP_DOMAIN_TLV: 98 ND_PRINT(", "); 99 nd_printjnp(ndo, tptr+4, len-4); 100 break; 101 102 case DTP_STATUS_TLV: 103 case DTP_DTP_TYPE_TLV: 104 if (len != 5) 105 goto invalid; 106 ND_PRINT(", 0x%x", GET_U_1(tptr + 4)); 107 break; 108 109 case DTP_NEIGHBOR_TLV: 110 if (len != 10) 111 goto invalid; 112 ND_PRINT(", %s", GET_ETHERADDR_STRING(tptr+4)); 113 break; 114 115 default: 116 ND_TCHECK_LEN(tptr, len); 117 break; 118 } 119 tptr += len; 120 length -= len; 121 } 122 return; 123 124 invalid: 125 nd_print_invalid(ndo); 126 ND_TCHECK_LEN(tptr, length); 127} 128