1*ee67461eSJoseph Mingrone /* 2*ee67461eSJoseph Mingrone * Copyright (c) 2007 - Andrey "nording" Chernyak <andrew@nording.ru> 3*ee67461eSJoseph Mingrone * 4*ee67461eSJoseph Mingrone * Redistribution and use in source and binary forms, with or without 5*ee67461eSJoseph Mingrone * modification, are permitted provided that: (1) source code distributions 6*ee67461eSJoseph Mingrone * retain the above copyright notice and this paragraph in its entirety, (2) 7*ee67461eSJoseph Mingrone * distributions including binary code include the above copyright notice and 8*ee67461eSJoseph Mingrone * this paragraph in its entirety in the documentation or other materials 9*ee67461eSJoseph Mingrone * provided with the distribution, and (3) all advertising materials mentioning 10*ee67461eSJoseph Mingrone * features or use of this software display the following acknowledgement: 11*ee67461eSJoseph Mingrone * ``This product includes software developed by the University of California, 12*ee67461eSJoseph Mingrone * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 13*ee67461eSJoseph Mingrone * the University nor the names of its contributors may be used to endorse 14*ee67461eSJoseph Mingrone * or promote products derived from this software without specific prior 15*ee67461eSJoseph Mingrone * written permission. 16*ee67461eSJoseph Mingrone * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 17*ee67461eSJoseph Mingrone * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 18*ee67461eSJoseph Mingrone * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19*ee67461eSJoseph Mingrone * 20*ee67461eSJoseph Mingrone * Format and print Realtek Remote Control Protocol (RRCP), Realtek 21*ee67461eSJoseph Mingrone * Loop Detection Protocol (RLDP), and Realtek Echo Protocol (REP) packets, 22*ee67461eSJoseph Mingrone * as well as tag formats used by some Realtek switch chips to supply 23*ee67461eSJoseph Mingrone * tag information to a host CPU for a switch. 24*ee67461eSJoseph Mingrone */ 25*ee67461eSJoseph Mingrone 26*ee67461eSJoseph Mingrone /* \summary: printer for various Realtek protocols */ 27*ee67461eSJoseph Mingrone 28*ee67461eSJoseph Mingrone #include <config.h> 29*ee67461eSJoseph Mingrone 30*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h" 31*ee67461eSJoseph Mingrone 32*ee67461eSJoseph Mingrone #include "netdissect.h" 33*ee67461eSJoseph Mingrone #include "addrtoname.h" 34*ee67461eSJoseph Mingrone #include "extract.h" 35*ee67461eSJoseph Mingrone 36*ee67461eSJoseph Mingrone #define RTL_PROTOCOL_OFFSET 0 /* Protocol and possibly other data - 1 byte */ 37*ee67461eSJoseph Mingrone 38*ee67461eSJoseph Mingrone #define RTL_PROTOCOL_RRCP 0x01 /* RRCP */ 39*ee67461eSJoseph Mingrone #define RTL_PROTOCOL_REP 0x02 /* REP */ 40*ee67461eSJoseph Mingrone #define RTL_PROTOCOL_RLDP 0x03 /* RLDP */ 41*ee67461eSJoseph Mingrone #define RTL_PROTOCOL_RLDP2 0x23 /* also RLDP */ 42*ee67461eSJoseph Mingrone #define RTL_PROTOCOL_XXX_DSA 0x04 /* DSA protocol for some chip(s) */ 43*ee67461eSJoseph Mingrone 44*ee67461eSJoseph Mingrone /* 45*ee67461eSJoseph Mingrone * Values for the upper 4 bits of the protocol field, for 46*ee67461eSJoseph Mingrone * protocols where the lower 4 bits contain protocol data. 47*ee67461eSJoseph Mingrone * 48*ee67461eSJoseph Mingrone * See section 8.10 "CPU Tag Function" of 49*ee67461eSJoseph Mingrone * 50*ee67461eSJoseph Mingrone * http://realtek.info/pdf/rtl8306sd%28m%29_datasheet_1.1.pdf 51*ee67461eSJoseph Mingrone * 52*ee67461eSJoseph Mingrone * for the RTL8306 DSA protocol tag format. 53*ee67461eSJoseph Mingrone */ 54*ee67461eSJoseph Mingrone #define RTL_PROTOCOL_8306_DSA 0x90 /* RTL8306 DSA protocol */ 55*ee67461eSJoseph Mingrone #define RTL_PROTOCOL_8366RB_DSA 0xA0 /* RTL8366RB DSA protocol */ 56*ee67461eSJoseph Mingrone 57*ee67461eSJoseph Mingrone #define RRCP_OPCODE_ISREPLY_OFFSET 1 /* opcode and isreply flag - 1 byte */ 58*ee67461eSJoseph Mingrone 59*ee67461eSJoseph Mingrone #define RRCP_OPCODE_MASK 0x7F /* 0x00 = hello, 0x01 = get, 0x02 = set */ 60*ee67461eSJoseph Mingrone #define RRCP_ISREPLY 0x80 /* 0 = request to switch, 0x80 = reply from switch */ 61*ee67461eSJoseph Mingrone 62*ee67461eSJoseph Mingrone #define RRCP_OPCODE_HELLO 0x00 63*ee67461eSJoseph Mingrone #define RRCP_OPCODE_GET_CONFIGURATION 0x01 64*ee67461eSJoseph Mingrone #define RRCP_OPCODE_SET_CONFIGURATION 0x02 65*ee67461eSJoseph Mingrone 66*ee67461eSJoseph Mingrone #define RRCP_AUTHKEY_OFFSET 2 /* authorization key - 2 bytes, 0x2379 by default */ 67*ee67461eSJoseph Mingrone 68*ee67461eSJoseph Mingrone /* most packets */ 69*ee67461eSJoseph Mingrone #define RRCP_REG_ADDR_OFFSET 4 /* register address - 2 bytes */ 70*ee67461eSJoseph Mingrone #define RRCP_REG_DATA_OFFSET 6 /* register data - 4 bytes */ 71*ee67461eSJoseph Mingrone #define RRCP_COOKIE1_OFFSET 10 /* 4 bytes */ 72*ee67461eSJoseph Mingrone #define RRCP_COOKIE2_OFFSET 14 /* 4 bytes */ 73*ee67461eSJoseph Mingrone 74*ee67461eSJoseph Mingrone /* hello reply packets */ 75*ee67461eSJoseph Mingrone #define RRCP_DOWNLINK_PORT_OFFSET 4 /* 1 byte */ 76*ee67461eSJoseph Mingrone #define RRCP_UPLINK_PORT_OFFSET 5 /* 1 byte */ 77*ee67461eSJoseph Mingrone #define RRCP_UPLINK_MAC_OFFSET 6 /* 6 byte MAC address */ 78*ee67461eSJoseph Mingrone #define RRCP_CHIP_ID_OFFSET 12 /* 2 bytes */ 79*ee67461eSJoseph Mingrone #define RRCP_VENDOR_ID_OFFSET 14 /* 4 bytes */ 80*ee67461eSJoseph Mingrone 81*ee67461eSJoseph Mingrone static const struct tok opcode_values[] = { 82*ee67461eSJoseph Mingrone { RRCP_OPCODE_HELLO, "hello" }, 83*ee67461eSJoseph Mingrone { RRCP_OPCODE_GET_CONFIGURATION, "get" }, 84*ee67461eSJoseph Mingrone { RRCP_OPCODE_SET_CONFIGURATION, "set" }, 85*ee67461eSJoseph Mingrone { 0, NULL } 86*ee67461eSJoseph Mingrone }; 87*ee67461eSJoseph Mingrone 88*ee67461eSJoseph Mingrone /* 89*ee67461eSJoseph Mingrone * Print RRCP packets. 90*ee67461eSJoseph Mingrone * 91*ee67461eSJoseph Mingrone * See, for example, section 8.20 "Realtek Remote Control Protocol" of 92*ee67461eSJoseph Mingrone * 93*ee67461eSJoseph Mingrone * http://realtek.info/pdf/rtl8324.pdf 94*ee67461eSJoseph Mingrone * 95*ee67461eSJoseph Mingrone * and section 7.22 "Realtek Remote Control Protocol" of 96*ee67461eSJoseph Mingrone * 97*ee67461eSJoseph Mingrone * http://realtek.info/pdf/rtl8326.pdf 98*ee67461eSJoseph Mingrone * 99*ee67461eSJoseph Mingrone * and this page on the OpenRRCP Wiki: 100*ee67461eSJoseph Mingrone * 101*ee67461eSJoseph Mingrone * http://openrrcp.org.ru/wiki/rrcp_protocol 102*ee67461eSJoseph Mingrone * 103*ee67461eSJoseph Mingrone * for information on RRCP. 104*ee67461eSJoseph Mingrone */ 105*ee67461eSJoseph Mingrone static void 106*ee67461eSJoseph Mingrone rrcp_print(netdissect_options *ndo, 107*ee67461eSJoseph Mingrone const u_char *cp) 108*ee67461eSJoseph Mingrone { 109*ee67461eSJoseph Mingrone uint8_t rrcp_opcode; 110*ee67461eSJoseph Mingrone 111*ee67461eSJoseph Mingrone ndo->ndo_protocol = "rrcp"; 112*ee67461eSJoseph Mingrone rrcp_opcode = GET_U_1((cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK; 113*ee67461eSJoseph Mingrone ND_PRINT("RRCP %s: %s", 114*ee67461eSJoseph Mingrone ((GET_U_1(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query", 115*ee67461eSJoseph Mingrone tok2str(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode)); 116*ee67461eSJoseph Mingrone if (rrcp_opcode==RRCP_OPCODE_GET_CONFIGURATION || 117*ee67461eSJoseph Mingrone rrcp_opcode==RRCP_OPCODE_SET_CONFIGURATION){ 118*ee67461eSJoseph Mingrone ND_PRINT(" addr=0x%04x, data=0x%08x", 119*ee67461eSJoseph Mingrone GET_LE_U_2(cp + RRCP_REG_ADDR_OFFSET), 120*ee67461eSJoseph Mingrone GET_LE_U_4(cp + RRCP_REG_DATA_OFFSET)); 121*ee67461eSJoseph Mingrone } 122*ee67461eSJoseph Mingrone ND_PRINT(", auth=0x%04x", 123*ee67461eSJoseph Mingrone GET_BE_U_2(cp + RRCP_AUTHKEY_OFFSET)); 124*ee67461eSJoseph Mingrone if (rrcp_opcode==RRCP_OPCODE_HELLO && 125*ee67461eSJoseph Mingrone ((GET_U_1(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){ 126*ee67461eSJoseph Mingrone ND_PRINT(" downlink_port=%u, uplink_port=%u, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ", 127*ee67461eSJoseph Mingrone GET_U_1(cp + RRCP_DOWNLINK_PORT_OFFSET), 128*ee67461eSJoseph Mingrone GET_U_1(cp + RRCP_UPLINK_PORT_OFFSET), 129*ee67461eSJoseph Mingrone GET_ETHERADDR_STRING(cp + RRCP_UPLINK_MAC_OFFSET), 130*ee67461eSJoseph Mingrone GET_BE_U_4(cp + RRCP_VENDOR_ID_OFFSET), 131*ee67461eSJoseph Mingrone GET_BE_U_2(cp + RRCP_CHIP_ID_OFFSET)); 132*ee67461eSJoseph Mingrone }else if (rrcp_opcode==RRCP_OPCODE_GET_CONFIGURATION || 133*ee67461eSJoseph Mingrone rrcp_opcode==RRCP_OPCODE_SET_CONFIGURATION){ 134*ee67461eSJoseph Mingrone ND_PRINT(", cookie=0x%08x%08x ", 135*ee67461eSJoseph Mingrone GET_BE_U_4(cp + RRCP_COOKIE2_OFFSET), 136*ee67461eSJoseph Mingrone GET_BE_U_4(cp + RRCP_COOKIE1_OFFSET)); 137*ee67461eSJoseph Mingrone } 138*ee67461eSJoseph Mingrone } 139*ee67461eSJoseph Mingrone 140*ee67461eSJoseph Mingrone /* 141*ee67461eSJoseph Mingrone * Print Realtek packets. 142*ee67461eSJoseph Mingrone * 143*ee67461eSJoseph Mingrone * See, for example, section 8.22 "Realtek Echo Protocol" of 144*ee67461eSJoseph Mingrone * 145*ee67461eSJoseph Mingrone * http://realtek.info/pdf/rtl8324.pdf 146*ee67461eSJoseph Mingrone * 147*ee67461eSJoseph Mingrone * and section 7.24 "Realtek Echo Protocol" of 148*ee67461eSJoseph Mingrone * 149*ee67461eSJoseph Mingrone * http://realtek.info/pdf/rtl8326.pdf 150*ee67461eSJoseph Mingrone * 151*ee67461eSJoseph Mingrone * for information on REP. 152*ee67461eSJoseph Mingrone * 153*ee67461eSJoseph Mingrone * See section 8.21 "Network Loop Connection Fault Detection" of 154*ee67461eSJoseph Mingrone * 155*ee67461eSJoseph Mingrone * http://realtek.info/pdf/rtl8324.pdf 156*ee67461eSJoseph Mingrone * 157*ee67461eSJoseph Mingrone * and section 7.23 "Network Loop Connection Fault Detection" of 158*ee67461eSJoseph Mingrone * 159*ee67461eSJoseph Mingrone * http://realtek.info/pdf/rtl8326.pdf 160*ee67461eSJoseph Mingrone * 161*ee67461eSJoseph Mingrone * for information on RLDP. 162*ee67461eSJoseph Mingrone * 163*ee67461eSJoseph Mingrone * See also section 7.3.8 "Loop Detection" of 164*ee67461eSJoseph Mingrone * 165*ee67461eSJoseph Mingrone * http://www.ibselectronics.com/ibsstore/datasheet/RTL8306E-CG.pdf 166*ee67461eSJoseph Mingrone * 167*ee67461eSJoseph Mingrone * (revision 1.1 of the RTL8306E-CG datasheet), which describes a loop 168*ee67461eSJoseph Mingrone * detection protocol for which the payload has a 16-bit (presumably 169*ee67461eSJoseph Mingrone * big-endian) field containing the value 0x0300, followed by what is 170*ee67461eSJoseph Mingrone * presumably a 16-bit big-endian field the upper 12 bits of which are 0 171*ee67461eSJoseph Mingrone * and the lower 4 bits of which are a TTL value, followed by zeroes to 172*ee67461eSJoseph Mingrone * pad the packet out to the minimum Ethernet packet size. 173*ee67461eSJoseph Mingrone * 174*ee67461eSJoseph Mingrone * See also section 7.3.13 "Loop Detection" of 175*ee67461eSJoseph Mingrone * 176*ee67461eSJoseph Mingrone * http://realtek.info/pdf/rtl8305sb.pdf 177*ee67461eSJoseph Mingrone * 178*ee67461eSJoseph Mingrone * (revision 1.3 of the RTL8305SB datasheet), which describes a similar 179*ee67461eSJoseph Mingrone * loop detection protocol that lacks the TTL field - all the bytes 180*ee67461eSJoseph Mingrone * after 0x0300 are zero. 181*ee67461eSJoseph Mingrone * 182*ee67461eSJoseph Mingrone * See also section 7.3.7 "Loop Detection" of 183*ee67461eSJoseph Mingrone * 184*ee67461eSJoseph Mingrone * https://datasheet.lcsc.com/lcsc/1810221720_Realtek-Semicon-RTL8305NB-CG_C52146.pdf 185*ee67461eSJoseph Mingrone * 186*ee67461eSJoseph Mingrone * (revision 1.0 of the RTL8305NB-CT datasheet), which describes a loop 187*ee67461eSJoseph Mingrone * detection protocol similar to the one from the RTL8306E-CG datasheet, 188*ee67461eSJoseph Mingrone * except that the first value is 0x2300, not 0x0300. 189*ee67461eSJoseph Mingrone * 190*ee67461eSJoseph Mingrone * And, on top of all that, I've seen packets where the first octet of 191*ee67461eSJoseph Mingrone * the packet is 0x23, and that's followed by 6 unknown octets (a MAC 192*ee67461eSJoseph Mingrone * address of some sort? It differs from packet to packet in a capture), 193*ee67461eSJoseph Mingrone * followed by the MAC address that appears in the source address in the 194*ee67461eSJoseph Mingrone * Ethernet header (possibly the originator, in case the packet is forwarded, 195*ee67461eSJoseph Mingrone * in which case the forwarded packets won't have the source address from 196*ee67461eSJoseph Mingrone * the Ethernet header there), followed by unknown stuff (0x0d followed by 197*ee67461eSJoseph Mingrone * zeroes for all such packets in one capture, 0x01 followed by zeroes for 198*ee67461eSJoseph Mingrone * all such packets in another capture, 0x07 followed by 0x20's for all 199*ee67461eSJoseph Mingrone * such packets in yet another capture). The OpenRRCP issue at 200*ee67461eSJoseph Mingrone * https://github.com/illarionov/OpenRRCP/issues/3 shows a capture 201*ee67461eSJoseph Mingrone * similar to the last of those, but with 0x02 instead of 0x07. Or is that 202*ee67461eSJoseph Mingrone * just crap in the buffer in which the chip constructed the packet, left 203*ee67461eSJoseph Mingrone * over from something else? 204*ee67461eSJoseph Mingrone */ 205*ee67461eSJoseph Mingrone void 206*ee67461eSJoseph Mingrone rtl_print(netdissect_options *ndo, 207*ee67461eSJoseph Mingrone const u_char *cp, 208*ee67461eSJoseph Mingrone u_int length _U_, 209*ee67461eSJoseph Mingrone const struct lladdr_info *src, 210*ee67461eSJoseph Mingrone const struct lladdr_info *dst) 211*ee67461eSJoseph Mingrone { 212*ee67461eSJoseph Mingrone uint8_t rtl_proto; 213*ee67461eSJoseph Mingrone 214*ee67461eSJoseph Mingrone ndo->ndo_protocol = "rtl"; 215*ee67461eSJoseph Mingrone 216*ee67461eSJoseph Mingrone if (src != NULL && dst != NULL) { 217*ee67461eSJoseph Mingrone ND_PRINT("%s > %s, ", 218*ee67461eSJoseph Mingrone (src->addr_string)(ndo, src->addr), 219*ee67461eSJoseph Mingrone (dst->addr_string)(ndo, dst->addr)); 220*ee67461eSJoseph Mingrone } 221*ee67461eSJoseph Mingrone 222*ee67461eSJoseph Mingrone rtl_proto = GET_U_1(cp + RTL_PROTOCOL_OFFSET); 223*ee67461eSJoseph Mingrone 224*ee67461eSJoseph Mingrone if (rtl_proto == RTL_PROTOCOL_RRCP) 225*ee67461eSJoseph Mingrone rrcp_print(ndo, cp); 226*ee67461eSJoseph Mingrone else if (rtl_proto == RTL_PROTOCOL_REP) { 227*ee67461eSJoseph Mingrone /* 228*ee67461eSJoseph Mingrone * REP packets have no payload. 229*ee67461eSJoseph Mingrone */ 230*ee67461eSJoseph Mingrone ND_PRINT("REP"); 231*ee67461eSJoseph Mingrone } else if (rtl_proto == RTL_PROTOCOL_RLDP || 232*ee67461eSJoseph Mingrone rtl_proto == RTL_PROTOCOL_RLDP2) { 233*ee67461eSJoseph Mingrone /* 234*ee67461eSJoseph Mingrone * RLDP packets have no payload. 235*ee67461eSJoseph Mingrone * (XXX - except when they do? See above.) 236*ee67461eSJoseph Mingrone */ 237*ee67461eSJoseph Mingrone ND_PRINT("RLDP"); 238*ee67461eSJoseph Mingrone } else if (rtl_proto == RTL_PROTOCOL_XXX_DSA) 239*ee67461eSJoseph Mingrone ND_PRINT("Realtek 8-byte DSA tag"); 240*ee67461eSJoseph Mingrone else if ((rtl_proto & 0xF0) == RTL_PROTOCOL_8306_DSA) 241*ee67461eSJoseph Mingrone ND_PRINT("Realtek RTL8306 4-byte DSA tag"); 242*ee67461eSJoseph Mingrone else if ((rtl_proto & 0xF0) == RTL_PROTOCOL_8366RB_DSA) 243*ee67461eSJoseph Mingrone ND_PRINT("Realtek RTL8366RB 4-byte DSA tag"); 244*ee67461eSJoseph Mingrone else 245*ee67461eSJoseph Mingrone ND_PRINT("Realtek unknown type 0x%02x", rtl_proto); 246*ee67461eSJoseph Mingrone } 247