1190203Srpaulo/* 2190203Srpaulo * Copyright (c) 2007 - Andrey "nording" Chernyak <andrew@nording.ru> 3190203Srpaulo * 4190203Srpaulo * Redistribution and use in source and binary forms, with or without 5190203Srpaulo * modification, are permitted provided that: (1) source code distributions 6190203Srpaulo * retain the above copyright notice and this paragraph in its entirety, (2) 7190203Srpaulo * distributions including binary code include the above copyright notice and 8190203Srpaulo * this paragraph in its entirety in the documentation or other materials 9190203Srpaulo * provided with the distribution, and (3) all advertising materials mentioning 10190203Srpaulo * features or use of this software display the following acknowledgement: 11190203Srpaulo * ``This product includes software developed by the University of California, 12190203Srpaulo * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 13190203Srpaulo * the University nor the names of its contributors may be used to endorse 14190203Srpaulo * or promote products derived from this software without specific prior 15190203Srpaulo * written permission. 16190203Srpaulo * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 17190203Srpaulo * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 18190203Srpaulo * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19190203Srpaulo * 20190203Srpaulo * Format and print Realtek Remote Control Protocol (RRCP) 21190203Srpaulo * and Realtek Echo Protocol (RRCP-REP) packets. 22190203Srpaulo */ 23190203Srpaulo 24190203Srpaulo#ifndef lint 25190203Srpaulostatic const char rcsid[] _U_ = 26214478Srpaulo "@(#) $Header: /tcpdump/master/tcpdump/print-rrcp.c,v 1.2 2008-04-11 17:21:34 gianluca Exp $"; 27190203Srpaulo#endif 28190203Srpaulo 29190203Srpaulo#ifdef HAVE_CONFIG_H 30190203Srpaulo#include "config.h" 31190203Srpaulo#endif 32190203Srpaulo 33190203Srpaulo#include <tcpdump-stdinc.h> 34190203Srpaulo 35190203Srpaulo#include <stdio.h> 36190203Srpaulo#include <string.h> 37190203Srpaulo 38190203Srpaulo#include "netdissect.h" 39190203Srpaulo#include "addrtoname.h" 40190203Srpaulo#include "extract.h" 41190203Srpaulo#include "ether.h" 42190203Srpaulo 43190203Srpaulo#ifndef ETH_ALEN 44190203Srpaulo#define ETH_ALEN 6 45190203Srpaulo#endif 46190203Srpaulo 47214478Srpaulo#define RRCP_OPCODE_MASK 0x7F /* 0x00 = hello, 0x01 = get, 0x02 = set */ 48214478Srpaulo#define RRCP_ISREPLY 0x80 /* 0 = request to switch, 0x80 = reply from switch */ 49214478Srpaulo 50214478Srpaulo#define RRCP_PROTO_OFFSET 0 /* proto - 1 byte, must be 1 */ 51214478Srpaulo#define RRCP_OPCODE_ISREPLY_OFFSET 1 /* opcode and isreply flag - 1 byte */ 52214478Srpaulo#define RRCP_AUTHKEY_OFFSET 2 /* authorization key - 2 bytes, 0x2379 by default */ 53214478Srpaulo 54214478Srpaulo/* most packets */ 55214478Srpaulo#define RRCP_REG_ADDR_OFFSET 4 /* register address - 2 bytes */ 56214478Srpaulo#define RRCP_REG_DATA_OFFSET 6 /* register data - 4 bytes */ 57214478Srpaulo#define RRCP_COOKIE1_OFFSET 10 /* 4 bytes */ 58214478Srpaulo#define RRCP_COOKIE2_OFFSET 14 /* 4 bytes */ 59214478Srpaulo 60214478Srpaulo/* hello reply packets */ 61214478Srpaulo#define RRCP_DOWNLINK_PORT_OFFSET 4 /* 1 byte */ 62214478Srpaulo#define RRCP_UPLINK_PORT_OFFSET 5 /* 1 byte */ 63214478Srpaulo#define RRCP_UPLINK_MAC_OFFSET 6 /* 6 byte MAC address */ 64214478Srpaulo#define RRCP_CHIP_ID_OFFSET 12 /* 2 bytes */ 65214478Srpaulo#define RRCP_VENDOR_ID_OFFSET 14 /* 4 bytes */ 66214478Srpaulo 67214478Srpaulostatic const struct tok proto_values[] = { 68214478Srpaulo { 1, "RRCP" }, 69214478Srpaulo { 2, "RRCP-REP" }, 70214478Srpaulo { 0, NULL } 71190203Srpaulo}; 72190203Srpaulo 73214478Srpaulostatic const struct tok opcode_values[] = { 74214478Srpaulo { 0, "hello" }, 75214478Srpaulo { 1, "get" }, 76214478Srpaulo { 2, "set" }, 77214478Srpaulo { 0, NULL } 78190203Srpaulo}; 79190203Srpaulo 80190203Srpaulo/* 81190203Srpaulo * Print RRCP requests 82190203Srpaulo */ 83190203Srpaulovoid 84190203Srpaulorrcp_print(netdissect_options *ndo, 85190203Srpaulo register const u_char *cp, 86190203Srpaulo u_int length _U_) 87190203Srpaulo{ 88214478Srpaulo const u_char *rrcp; 89214478Srpaulo u_int8_t rrcp_proto; 90214478Srpaulo u_int8_t rrcp_opcode; 91190203Srpaulo register const struct ether_header *ep; 92190203Srpaulo char proto_str[16]; 93190203Srpaulo char opcode_str[32]; 94190203Srpaulo 95190203Srpaulo ep = (const struct ether_header *)cp; 96214478Srpaulo rrcp = cp + ETHER_HDRLEN; 97190203Srpaulo 98214478Srpaulo ND_TCHECK(*(rrcp + RRCP_PROTO_OFFSET)); 99214478Srpaulo rrcp_proto = *(rrcp + RRCP_PROTO_OFFSET); 100214478Srpaulo ND_TCHECK(*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)); 101214478Srpaulo rrcp_opcode = (*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK; 102190203Srpaulo ND_PRINT((ndo, "%s > %s, %s %s", 103190203Srpaulo etheraddr_string(ESRC(ep)), 104190203Srpaulo etheraddr_string(EDST(ep)), 105241235Sdelphij tok2strbuf(proto_values,"RRCP-0x%02x",rrcp_proto,proto_str,sizeof(proto_str)), 106214478Srpaulo ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query")); 107214478Srpaulo if (rrcp_proto==1){ 108214478Srpaulo ND_PRINT((ndo, ": %s", 109241235Sdelphij tok2strbuf(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode,opcode_str,sizeof(opcode_str)))); 110190203Srpaulo } 111214478Srpaulo if (rrcp_opcode==1 || rrcp_opcode==2){ 112214478Srpaulo ND_TCHECK2(*(rrcp + RRCP_REG_ADDR_OFFSET), 6); 113214478Srpaulo ND_PRINT((ndo, " addr=0x%04x, data=0x%08x", 114235530Sdelphij EXTRACT_LE_16BITS(rrcp + RRCP_REG_ADDR_OFFSET), 115235530Sdelphij EXTRACT_LE_32BITS(rrcp + RRCP_REG_DATA_OFFSET))); 116190203Srpaulo } 117214478Srpaulo if (rrcp_proto==1){ 118214478Srpaulo ND_TCHECK2(*(rrcp + RRCP_AUTHKEY_OFFSET), 2); 119190203Srpaulo ND_PRINT((ndo, ", auth=0x%04x", 120214478Srpaulo EXTRACT_16BITS(rrcp + RRCP_AUTHKEY_OFFSET))); 121190203Srpaulo } 122214478Srpaulo if (rrcp_proto==1 && rrcp_opcode==0 && 123214478Srpaulo ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){ 124214478Srpaulo ND_TCHECK2(*(rrcp + RRCP_VENDOR_ID_OFFSET), 4); 125214478Srpaulo ND_PRINT((ndo, " downlink_port=%d, uplink_port=%d, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ", 126214478Srpaulo *(rrcp + RRCP_DOWNLINK_PORT_OFFSET), 127214478Srpaulo *(rrcp + RRCP_UPLINK_PORT_OFFSET), 128214478Srpaulo etheraddr_string(rrcp + RRCP_UPLINK_MAC_OFFSET), 129214478Srpaulo EXTRACT_32BITS(rrcp + RRCP_VENDOR_ID_OFFSET), 130214478Srpaulo EXTRACT_16BITS(rrcp + RRCP_CHIP_ID_OFFSET))); 131214478Srpaulo }else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){ 132214478Srpaulo ND_TCHECK2(*(rrcp + RRCP_COOKIE2_OFFSET), 4); 133214478Srpaulo ND_PRINT((ndo, ", cookie=0x%08x%08x ", 134214478Srpaulo EXTRACT_32BITS(rrcp + RRCP_COOKIE2_OFFSET), 135214478Srpaulo EXTRACT_32BITS(rrcp + RRCP_COOKIE1_OFFSET))); 136190203Srpaulo } 137190203Srpaulo if (!ndo->ndo_vflag) 138190203Srpaulo return; 139214478Srpaulo return; 140214478Srpaulo 141214478Srpaulotrunc: 142214478Srpaulo ND_PRINT((ndo, "[|rrcp]")); 143190203Srpaulo} 144