1a5779b6eSRui Paulo /* 2a5779b6eSRui Paulo * Copyright (c) 1998-2007 The TCPDUMP project 3a5779b6eSRui Paulo * 4a5779b6eSRui Paulo * Redistribution and use in source and binary forms, with or without 5a5779b6eSRui Paulo * modification, are permitted provided that: (1) source code 6a5779b6eSRui Paulo * distributions retain the above copyright notice and this paragraph 7a5779b6eSRui Paulo * in its entirety, and (2) distributions including binary code include 8a5779b6eSRui Paulo * the above copyright notice and this paragraph in its entirety in 9a5779b6eSRui Paulo * the documentation or other materials provided with the distribution. 10a5779b6eSRui Paulo * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 11a5779b6eSRui Paulo * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 12a5779b6eSRui Paulo * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13a5779b6eSRui Paulo * FOR A PARTICULAR PURPOSE. 14a5779b6eSRui Paulo * 15a5779b6eSRui Paulo * UNIDIRECTIONAL LINK DETECTION (UDLD) as per 16a5779b6eSRui Paulo * http://www.ietf.org/internet-drafts/draft-foschiano-udld-02.txt 17a5779b6eSRui Paulo * 18a5779b6eSRui Paulo * Original code by Carles Kishimoto <carles.kishimoto@gmail.com> 19a5779b6eSRui Paulo */ 20a5779b6eSRui Paulo 21*3c602fabSXin LI #define NETDISSECT_REWORKED 22a5779b6eSRui Paulo #ifdef HAVE_CONFIG_H 23a5779b6eSRui Paulo #include "config.h" 24a5779b6eSRui Paulo #endif 25a5779b6eSRui Paulo 26a5779b6eSRui Paulo #include <tcpdump-stdinc.h> 27a5779b6eSRui Paulo 28a5779b6eSRui Paulo #include "interface.h" 29a5779b6eSRui Paulo #include "extract.h" 30a5779b6eSRui Paulo 31a5779b6eSRui Paulo #define UDLD_HEADER_LEN 4 32a5779b6eSRui Paulo #define UDLD_DEVICE_ID_TLV 0x0001 33a5779b6eSRui Paulo #define UDLD_PORT_ID_TLV 0x0002 34a5779b6eSRui Paulo #define UDLD_ECHO_TLV 0x0003 35a5779b6eSRui Paulo #define UDLD_MESSAGE_INTERVAL_TLV 0x0004 36a5779b6eSRui Paulo #define UDLD_TIMEOUT_INTERVAL_TLV 0x0005 37a5779b6eSRui Paulo #define UDLD_DEVICE_NAME_TLV 0x0006 38a5779b6eSRui Paulo #define UDLD_SEQ_NUMBER_TLV 0x0007 39a5779b6eSRui Paulo 40*3c602fabSXin LI static const struct tok udld_tlv_values[] = { 41a5779b6eSRui Paulo { UDLD_DEVICE_ID_TLV, "Device-ID TLV"}, 42a5779b6eSRui Paulo { UDLD_PORT_ID_TLV, "Port-ID TLV"}, 43a5779b6eSRui Paulo { UDLD_ECHO_TLV, "Echo TLV"}, 44a5779b6eSRui Paulo { UDLD_MESSAGE_INTERVAL_TLV, "Message Interval TLV"}, 45a5779b6eSRui Paulo { UDLD_TIMEOUT_INTERVAL_TLV, "Timeout Interval TLV"}, 46a5779b6eSRui Paulo { UDLD_DEVICE_NAME_TLV, "Device Name TLV"}, 47a5779b6eSRui Paulo { UDLD_SEQ_NUMBER_TLV,"Sequence Number TLV"}, 48a5779b6eSRui Paulo { 0, NULL} 49a5779b6eSRui Paulo }; 50a5779b6eSRui Paulo 51*3c602fabSXin LI static const struct tok udld_code_values[] = { 52a5779b6eSRui Paulo { 0x00, "Reserved"}, 53a5779b6eSRui Paulo { 0x01, "Probe message"}, 54a5779b6eSRui Paulo { 0x02, "Echo message"}, 55a5779b6eSRui Paulo { 0x03, "Flush message"}, 56a5779b6eSRui Paulo { 0, NULL} 57a5779b6eSRui Paulo }; 58a5779b6eSRui Paulo 59*3c602fabSXin LI static const struct tok udld_flags_values[] = { 60a5779b6eSRui Paulo { 0x00, "RT"}, 61a5779b6eSRui Paulo { 0x01, "RSY"}, 62a5779b6eSRui Paulo { 0, NULL} 63a5779b6eSRui Paulo }; 64a5779b6eSRui Paulo 65a5779b6eSRui Paulo /* 66a5779b6eSRui Paulo * 67a5779b6eSRui Paulo * 0 1 2 3 68a5779b6eSRui Paulo * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 69a5779b6eSRui Paulo * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 70a5779b6eSRui Paulo * | Ver | Opcode | Flags | Checksum | 71a5779b6eSRui Paulo * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 72a5779b6eSRui Paulo * | List of TLVs (variable length list) | 73a5779b6eSRui Paulo * | ... | 74a5779b6eSRui Paulo * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 75a5779b6eSRui Paulo * 76a5779b6eSRui Paulo */ 77a5779b6eSRui Paulo 78a5779b6eSRui Paulo #define UDLD_EXTRACT_VERSION(x) (((x)&0xe0)>>5) 79a5779b6eSRui Paulo #define UDLD_EXTRACT_OPCODE(x) ((x)&0x1f) 80a5779b6eSRui Paulo 81a5779b6eSRui Paulo void 82*3c602fabSXin LI udld_print (netdissect_options *ndo, const u_char *pptr, u_int length) 83a5779b6eSRui Paulo { 84a5779b6eSRui Paulo int code, type, len; 85a5779b6eSRui Paulo const u_char *tptr; 86a5779b6eSRui Paulo 87a5779b6eSRui Paulo if (length < UDLD_HEADER_LEN) 88a5779b6eSRui Paulo goto trunc; 89a5779b6eSRui Paulo 90a5779b6eSRui Paulo tptr = pptr; 91a5779b6eSRui Paulo 92*3c602fabSXin LI ND_TCHECK2(*tptr, UDLD_HEADER_LEN); 93a5779b6eSRui Paulo 94a5779b6eSRui Paulo code = UDLD_EXTRACT_OPCODE(*tptr); 95a5779b6eSRui Paulo 96*3c602fabSXin LI ND_PRINT((ndo, "UDLDv%u, Code %s (%x), Flags [%s] (0x%02x), length %u", 97a5779b6eSRui Paulo UDLD_EXTRACT_VERSION(*tptr), 98a5779b6eSRui Paulo tok2str(udld_code_values, "Reserved", code), 99a5779b6eSRui Paulo code, 100a5779b6eSRui Paulo bittok2str(udld_flags_values, "none", *(tptr+1)), 101a5779b6eSRui Paulo *(tptr+1), 102*3c602fabSXin LI length)); 103a5779b6eSRui Paulo 104a5779b6eSRui Paulo /* 105a5779b6eSRui Paulo * In non-verbose mode, just print version and opcode type 106a5779b6eSRui Paulo */ 107*3c602fabSXin LI if (ndo->ndo_vflag < 1) { 108a5779b6eSRui Paulo return; 109a5779b6eSRui Paulo } 110a5779b6eSRui Paulo 111*3c602fabSXin LI ND_PRINT((ndo, "\n\tChecksum 0x%04x (unverified)", EXTRACT_16BITS(tptr+2))); 112a5779b6eSRui Paulo 113a5779b6eSRui Paulo tptr += UDLD_HEADER_LEN; 114a5779b6eSRui Paulo 115a5779b6eSRui Paulo while (tptr < (pptr+length)) { 116a5779b6eSRui Paulo 117*3c602fabSXin LI ND_TCHECK2(*tptr, 4); 118a5779b6eSRui Paulo 119a5779b6eSRui Paulo type = EXTRACT_16BITS(tptr); 120a5779b6eSRui Paulo len = EXTRACT_16BITS(tptr+2); 121a5779b6eSRui Paulo len -= 4; 122a5779b6eSRui Paulo tptr += 4; 123a5779b6eSRui Paulo 124a5779b6eSRui Paulo /* infinite loop check */ 125a5779b6eSRui Paulo if (type == 0 || len == 0) { 126a5779b6eSRui Paulo return; 127a5779b6eSRui Paulo } 128a5779b6eSRui Paulo 129*3c602fabSXin LI ND_PRINT((ndo, "\n\t%s (0x%04x) TLV, length %u", 130a5779b6eSRui Paulo tok2str(udld_tlv_values, "Unknown", type), 131*3c602fabSXin LI type, len)); 132a5779b6eSRui Paulo 133a5779b6eSRui Paulo switch (type) { 134a5779b6eSRui Paulo case UDLD_DEVICE_ID_TLV: 135a5779b6eSRui Paulo case UDLD_PORT_ID_TLV: 136a5779b6eSRui Paulo case UDLD_ECHO_TLV: 137a5779b6eSRui Paulo case UDLD_DEVICE_NAME_TLV: 138*3c602fabSXin LI ND_PRINT((ndo, ", %s", tptr)); 139a5779b6eSRui Paulo break; 140a5779b6eSRui Paulo 141a5779b6eSRui Paulo case UDLD_MESSAGE_INTERVAL_TLV: 142a5779b6eSRui Paulo case UDLD_TIMEOUT_INTERVAL_TLV: 143*3c602fabSXin LI ND_PRINT((ndo, ", %us", (*tptr))); 144a5779b6eSRui Paulo break; 145a5779b6eSRui Paulo 146a5779b6eSRui Paulo case UDLD_SEQ_NUMBER_TLV: 147*3c602fabSXin LI ND_PRINT((ndo, ", %u", EXTRACT_32BITS(tptr))); 148a5779b6eSRui Paulo break; 149a5779b6eSRui Paulo 150a5779b6eSRui Paulo default: 151a5779b6eSRui Paulo break; 152a5779b6eSRui Paulo } 153a5779b6eSRui Paulo tptr += len; 154a5779b6eSRui Paulo } 155a5779b6eSRui Paulo 156a5779b6eSRui Paulo return; 157a5779b6eSRui Paulo 158a5779b6eSRui Paulo trunc: 159*3c602fabSXin LI ND_PRINT((ndo, "[|udld]")); 160a5779b6eSRui Paulo } 161a5779b6eSRui Paulo 162a5779b6eSRui Paulo /* 163a5779b6eSRui Paulo * Local Variables: 164a5779b6eSRui Paulo * c-style: whitesmith 165a5779b6eSRui Paulo * c-basic-offset: 4 166a5779b6eSRui Paulo * End: 167a5779b6eSRui Paulo */ 168