139092Srnordier/* 239092Srnordier * Copyright (c) 2007 - Andrey "nording" Chernyak <andrew@nording.ru> 339092Srnordier * 439092Srnordier * Redistribution and use in source and binary forms, with or without 539092Srnordier * modification, are permitted provided that: (1) source code distributions 639092Srnordier * retain the above copyright notice and this paragraph in its entirety, (2) 739092Srnordier * distributions including binary code include the above copyright notice and 839092Srnordier * this paragraph in its entirety in the documentation or other materials 939092Srnordier * provided with the distribution, and (3) all advertising materials mentioning 1039092Srnordier * features or use of this software display the following acknowledgement: 1139092Srnordier * ``This product includes software developed by the University of California, 1239092Srnordier * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1339092Srnordier * the University nor the names of its contributors may be used to endorse 1439092Srnordier * or promote products derived from this software without specific prior 1539092Srnordier * written permission. 1639092Srnordier * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1739092Srnordier * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1839092Srnordier * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1939092Srnordier * 2039092Srnordier * Format and print Realtek Remote Control Protocol (RRCP) 2139092Srnordier * and Realtek Echo Protocol (RRCP-REP) packets. 2239092Srnordier */ 2339092Srnordier 2439092Srnordier#ifndef lint 2539092Srnordierstatic const char rcsid[] _U_ = 2639092Srnordier "@(#) $Header: /tcpdump/master/tcpdump/print-rrcp.c,v 1.2 2008-04-11 17:21:34 gianluca Exp $"; 2739092Srnordier#endif 2839092Srnordier 2950479Speter#ifdef HAVE_CONFIG_H 3039092Srnordier#include "config.h" 3139092Srnordier#endif 32103917Smike 33130927Sobrien#include <tcpdump-stdinc.h> 3439092Srnordier 3539092Srnordier#include <stdio.h> 3639092Srnordier#include <string.h> 37142108Sru 38142108Sru#include "netdissect.h" 39142108Sru#include "addrtoname.h" 40142108Sru#include "extract.h" 41142108Sru#include "ether.h" 42154711Sdelphij 43154711Sdelphij#ifndef ETH_ALEN 44130927Sobrien#define ETH_ALEN 6 4539092Srnordier#endif 4639092Srnordier 4739092Srnordier#define RRCP_OPCODE_MASK 0x7F /* 0x00 = hello, 0x01 = get, 0x02 = set */ 4839092Srnordier#define RRCP_ISREPLY 0x80 /* 0 = request to switch, 0x80 = reply from switch */ 4939092Srnordier 5039092Srnordier#define RRCP_PROTO_OFFSET 0 /* proto - 1 byte, must be 1 */ 5139092Srnordier#define RRCP_OPCODE_ISREPLY_OFFSET 1 /* opcode and isreply flag - 1 byte */ 5239092Srnordier#define RRCP_AUTHKEY_OFFSET 2 /* authorization key - 2 bytes, 0x2379 by default */ 5339092Srnordier 5439092Srnordier/* most packets */ 5539092Srnordier#define RRCP_REG_ADDR_OFFSET 4 /* register address - 2 bytes */ 5639092Srnordier#define RRCP_REG_DATA_OFFSET 6 /* register data - 4 bytes */ 5739092Srnordier#define RRCP_COOKIE1_OFFSET 10 /* 4 bytes */ 5839092Srnordier#define RRCP_COOKIE2_OFFSET 14 /* 4 bytes */ 5939092Srnordier 6039092Srnordier/* hello reply packets */ 6139092Srnordier#define RRCP_DOWNLINK_PORT_OFFSET 4 /* 1 byte */ 6239092Srnordier#define RRCP_UPLINK_PORT_OFFSET 5 /* 1 byte */ 6339092Srnordier#define RRCP_UPLINK_MAC_OFFSET 6 /* 6 byte MAC address */ 6439092Srnordier#define RRCP_CHIP_ID_OFFSET 12 /* 2 bytes */ 6539092Srnordier#define RRCP_VENDOR_ID_OFFSET 14 /* 4 bytes */ 6639092Srnordier 6739092Srnordierstatic const struct tok proto_values[] = { 6839092Srnordier { 1, "RRCP" }, 6939092Srnordier { 2, "RRCP-REP" }, 7039092Srnordier { 0, NULL } 7139092Srnordier}; 7239092Srnordier 7339092Srnordierstatic const struct tok opcode_values[] = { 7455416Smarcel { 0, "hello" }, 7555416Smarcel { 1, "get" }, 7655416Smarcel { 2, "set" }, 7755416Smarcel { 0, NULL } 7855416Smarcel}; 7955416Smarcel 8055416Smarcel/* 8155416Smarcel * Print RRCP requests 8239092Srnordier */ 8339092Srnordiervoid 8439092Srnordierrrcp_print(netdissect_options *ndo, 8539092Srnordier register const u_char *cp, 8639092Srnordier u_int length _U_) 8739092Srnordier{ 8839092Srnordier const u_char *rrcp; 8939092Srnordier u_int8_t rrcp_proto; 9039092Srnordier u_int8_t rrcp_opcode; 9139092Srnordier register const struct ether_header *ep; 9239092Srnordier char proto_str[16]; 9339092Srnordier char opcode_str[32]; 9439092Srnordier 9539092Srnordier ep = (const struct ether_header *)cp; 9639092Srnordier rrcp = cp + ETHER_HDRLEN; 9739092Srnordier 9839092Srnordier ND_TCHECK(*(rrcp + RRCP_PROTO_OFFSET)); 9939092Srnordier rrcp_proto = *(rrcp + RRCP_PROTO_OFFSET); 10039092Srnordier ND_TCHECK(*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)); 10139092Srnordier rrcp_opcode = (*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK; 10239092Srnordier ND_PRINT((ndo, "%s > %s, %s %s", 10339092Srnordier etheraddr_string(ESRC(ep)), 10455416Smarcel etheraddr_string(EDST(ep)), 10539092Srnordier tok2strbuf(proto_values,"RRCP-0x%02x",rrcp_proto,proto_str,sizeof(proto_str)), 10639092Srnordier ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query")); 10739092Srnordier if (rrcp_proto==1){ 10839092Srnordier ND_PRINT((ndo, ": %s", 10939125Srnordier tok2strbuf(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode,opcode_str,sizeof(opcode_str)))); 11039125Srnordier } 11139092Srnordier if (rrcp_opcode==1 || rrcp_opcode==2){ 11239092Srnordier ND_TCHECK2(*(rrcp + RRCP_REG_ADDR_OFFSET), 6); 11339092Srnordier ND_PRINT((ndo, " addr=0x%04x, data=0x%08x", 11439092Srnordier EXTRACT_LE_16BITS(rrcp + RRCP_REG_ADDR_OFFSET), 11539092Srnordier EXTRACT_LE_32BITS(rrcp + RRCP_REG_DATA_OFFSET))); 11639092Srnordier } 11739092Srnordier if (rrcp_proto==1){ 11839092Srnordier ND_TCHECK2(*(rrcp + RRCP_AUTHKEY_OFFSET), 2); 11939092Srnordier ND_PRINT((ndo, ", auth=0x%04x", 12039092Srnordier EXTRACT_16BITS(rrcp + RRCP_AUTHKEY_OFFSET))); 12139092Srnordier } 12239092Srnordier if (rrcp_proto==1 && rrcp_opcode==0 && 12339092Srnordier ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){ 12439092Srnordier ND_TCHECK2(*(rrcp + RRCP_VENDOR_ID_OFFSET), 4); 12539092Srnordier ND_PRINT((ndo, " downlink_port=%d, uplink_port=%d, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ", 12655416Smarcel *(rrcp + RRCP_DOWNLINK_PORT_OFFSET), 12739092Srnordier *(rrcp + RRCP_UPLINK_PORT_OFFSET), 12839092Srnordier etheraddr_string(rrcp + RRCP_UPLINK_MAC_OFFSET), 12939092Srnordier EXTRACT_32BITS(rrcp + RRCP_VENDOR_ID_OFFSET), 13039092Srnordier EXTRACT_16BITS(rrcp + RRCP_CHIP_ID_OFFSET))); 13139092Srnordier }else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){ 13239092Srnordier ND_TCHECK2(*(rrcp + RRCP_COOKIE2_OFFSET), 4); 13339092Srnordier ND_PRINT((ndo, ", cookie=0x%08x%08x ", 13439092Srnordier EXTRACT_32BITS(rrcp + RRCP_COOKIE2_OFFSET), 13539092Srnordier EXTRACT_32BITS(rrcp + RRCP_COOKIE1_OFFSET))); 13639092Srnordier } 13739092Srnordier if (!ndo->ndo_vflag) 13839092Srnordier return; 13939092Srnordier return; 14039092Srnordier 14139092Srnordiertrunc: 14239092Srnordier ND_PRINT((ndo, "[|rrcp]")); 14339092Srnordier} 14439092Srnordier