1 /* 2 * Copyright (c) 2001 William C. Fenner. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code 7 * distributions retain the above copyright notice and this paragraph 8 * in its entirety, and (2) distributions including binary code include 9 * the above copyright notice and this paragraph in its entirety in 10 * the documentation or other materials provided with the distribution. 11 * The name of William C. Fenner may not be used to endorse or 12 * promote products derived from this software without specific prior 13 * written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND 14 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 15 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 16 * FOR A PARTICULAR PURPOSE. 17 */ 18 19 #include <sys/cdefs.h> 20 #ifndef lint 21 __RCSID("$NetBSD: print-msdp.c,v 1.9 2026/03/19 00:05:13 christos Exp $"); 22 #endif 23 24 /* \summary: Multicast Source Discovery Protocol (MSDP) printer */ 25 26 #include <config.h> 27 28 #define ND_LONGJMP_FROM_TCHECK 29 #include "netdissect-stdinc.h" 30 31 #include "netdissect.h" 32 #include "addrtoname.h" 33 #include "extract.h" 34 35 #define MSDP_TYPE_MAX 7 36 37 void 38 msdp_print(netdissect_options *ndo, const u_char *sp, u_int length) 39 { 40 unsigned int type, len; 41 42 ndo->ndo_protocol = "msdp"; 43 ND_PRINT(": "); 44 nd_print_protocol(ndo); 45 /* See if we think we're at the beginning of a compound packet */ 46 type = GET_U_1(sp); 47 len = GET_BE_U_2(sp + 1); 48 if (len > 1500 || len < 3 || type == 0 || type > MSDP_TYPE_MAX) 49 goto trunc; /* not really truncated, but still not decodable */ 50 while (length != 0) { 51 unsigned int entry_count; 52 53 if (length < 3) 54 goto trunc; 55 type = GET_U_1(sp); 56 len = GET_BE_U_2(sp + 1); 57 if (len > 1400 || ndo->ndo_vflag) 58 ND_PRINT(" [len %u]", len); 59 if (len < 3) 60 goto trunc; 61 if (length < len) 62 goto trunc; 63 switch (type) { 64 case 1: /* IPv4 Source-Active */ 65 case 3: /* IPv4 Source-Active Response */ 66 if (type == 1) 67 ND_PRINT(" SA"); 68 else 69 ND_PRINT(" SA-Response"); 70 71 /* Entry Count */ 72 if (len < 4) 73 goto trunc; 74 entry_count = GET_U_1(sp + 3); 75 ND_PRINT(" %u entries", entry_count); 76 77 /* RP Address */ 78 if (len < 8) 79 goto trunc; 80 /* XXX -print this based on ndo_vflag? */ 81 ND_TCHECK_LEN(sp + 4, 4); 82 83 /* Entries */ 84 ND_TCHECK_LEN(sp + 8, entry_count*12); 85 86 if (len > (8 + entry_count*12)) { 87 /* Encapsulated IP packet */ 88 ND_PRINT(" [w/data]"); 89 if (ndo->ndo_vflag > 1) { 90 ND_PRINT(" "); 91 ip_print(ndo, sp + (8 + entry_count*12), 92 len - (8 + entry_count*12)); 93 } 94 } 95 break; 96 case 2: 97 /* draft-ietf-msdp-spec-13 */ 98 ND_PRINT(" SA-Request"); 99 100 /* Reserved */ 101 if (len < 4) 102 goto trunc; 103 ND_TCHECK_1(sp + 3); 104 105 /* Group Address */ 106 if (len < 8) 107 goto trunc; 108 if (len != 8) 109 ND_PRINT("[len=%u] ", len); 110 ND_PRINT(" for %s", GET_IPADDR_STRING(sp + 4)); 111 break; 112 case 4: 113 ND_PRINT(" Keepalive"); 114 if (len != 3) 115 ND_PRINT("[len=%u] ", len); 116 break; 117 case 5: 118 ND_PRINT(" Notification"); 119 break; 120 default: 121 ND_PRINT(" [type=%u len=%u]", type, len); 122 break; 123 } 124 ND_TCHECK_LEN(sp, len); 125 sp += len; 126 length -= len; 127 } 128 return; 129 trunc: 130 nd_print_trunc(ndo); 131 } 132