169bb4bb4Scarlsonj /* 269bb4bb4Scarlsonj * CDDL HEADER START 369bb4bb4Scarlsonj * 469bb4bb4Scarlsonj * The contents of this file are subject to the terms of the 569bb4bb4Scarlsonj * Common Development and Distribution License (the "License"). 669bb4bb4Scarlsonj * You may not use this file except in compliance with the License. 769bb4bb4Scarlsonj * 869bb4bb4Scarlsonj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 969bb4bb4Scarlsonj * or http://www.opensolaris.org/os/licensing. 1069bb4bb4Scarlsonj * See the License for the specific language governing permissions 1169bb4bb4Scarlsonj * and limitations under the License. 1269bb4bb4Scarlsonj * 1369bb4bb4Scarlsonj * When distributing Covered Code, include this CDDL HEADER in each 1469bb4bb4Scarlsonj * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1569bb4bb4Scarlsonj * If applicable, add the following below this CDDL HEADER, with the 1669bb4bb4Scarlsonj * fields enclosed by brackets "[]" replaced with your own identifying 1769bb4bb4Scarlsonj * information: Portions Copyright [yyyy] [name of copyright owner] 1869bb4bb4Scarlsonj * 1969bb4bb4Scarlsonj * CDDL HEADER END 2069bb4bb4Scarlsonj */ 2169bb4bb4Scarlsonj /* 22*bd670b35SErik Nordmark * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2369bb4bb4Scarlsonj * Use is subject to license terms. 2469bb4bb4Scarlsonj */ 2569bb4bb4Scarlsonj 2669bb4bb4Scarlsonj #include <stdio.h> 2769bb4bb4Scarlsonj #include <sys/types.h> 2869bb4bb4Scarlsonj #include <sys/stropts.h> 2969bb4bb4Scarlsonj #include <sys/stream.h> 3069bb4bb4Scarlsonj #include <sys/dlpi.h> 31381a2a9aSdr146992 #include <sys/hook.h> 32381a2a9aSdr146992 #include <sys/hook_event.h> 3369bb4bb4Scarlsonj #include <inet/led.h> 3469bb4bb4Scarlsonj #include <inet/common.h> 3569bb4bb4Scarlsonj #include <inet/mi.h> 3669bb4bb4Scarlsonj #include <inet/arp.h> 3769bb4bb4Scarlsonj #include <inet/ip.h> 3869bb4bb4Scarlsonj #include <netinet/arp.h> 3969bb4bb4Scarlsonj 4069bb4bb4Scarlsonj #include <mdb/mdb_modapi.h> 4169bb4bb4Scarlsonj #include <mdb/mdb_ks.h> 4269bb4bb4Scarlsonj 4369bb4bb4Scarlsonj typedef struct { 4469bb4bb4Scarlsonj uint32_t act_cmd; 4569bb4bb4Scarlsonj char *act_name; 4669bb4bb4Scarlsonj char *act_type; 4769bb4bb4Scarlsonj } arp_cmd_tbl; 4869bb4bb4Scarlsonj 4969bb4bb4Scarlsonj /* 50*bd670b35SErik Nordmark * removed all the ace/arl related stuff. The only thing that remains 51*bd670b35SErik Nordmark * is code for dealing with ioctls and printing out arp header that 52*bd670b35SErik Nordmark * should probably be moved into the ip/mdb module. 5369bb4bb4Scarlsonj */ 5469bb4bb4Scarlsonj 5569bb4bb4Scarlsonj /* 5669bb4bb4Scarlsonj * Print an ARP hardware and protocol address pair; used when printing an ARP 5769bb4bb4Scarlsonj * message. 5869bb4bb4Scarlsonj */ 5969bb4bb4Scarlsonj static void 6069bb4bb4Scarlsonj print_arp(char field_id, const uchar_t *buf, const arh_t *arh, uint16_t ptype) 6169bb4bb4Scarlsonj { 6269bb4bb4Scarlsonj char macstr[ARP_MAX_ADDR_LEN*3]; 6369bb4bb4Scarlsonj in_addr_t inaddr; 6469bb4bb4Scarlsonj 6569bb4bb4Scarlsonj if (arh->arh_hlen == 0) 6669bb4bb4Scarlsonj (void) strcpy(macstr, "(none)"); 6769bb4bb4Scarlsonj else 6869bb4bb4Scarlsonj mdb_mac_addr(buf, arh->arh_hlen, macstr, sizeof (macstr)); 6969bb4bb4Scarlsonj mdb_printf("%?s ar$%cha %s\n", "", field_id, macstr); 7069bb4bb4Scarlsonj if (arh->arh_plen == 0) { 7169bb4bb4Scarlsonj mdb_printf("%?s ar$%cpa (none)\n", "", field_id); 7269bb4bb4Scarlsonj } else if (ptype == IP_ARP_PROTO_TYPE) { 7369bb4bb4Scarlsonj mdb_printf("%?s ar$%cpa (unknown)\n", "", field_id); 7469bb4bb4Scarlsonj } else if (arh->arh_plen == sizeof (in_addr_t)) { 7569bb4bb4Scarlsonj (void) memcpy(&inaddr, buf + arh->arh_hlen, sizeof (inaddr)); 7669bb4bb4Scarlsonj mdb_printf("%?s ar$%cpa %I\n", "", field_id, inaddr); 7769bb4bb4Scarlsonj } else { 7869bb4bb4Scarlsonj mdb_printf("%?s ar$%cpa (malformed IP)\n", "", field_id); 7969bb4bb4Scarlsonj } 8069bb4bb4Scarlsonj } 8169bb4bb4Scarlsonj 8269bb4bb4Scarlsonj /* 8369bb4bb4Scarlsonj * Decode an ARP message and display it. 8469bb4bb4Scarlsonj */ 8569bb4bb4Scarlsonj /* ARGSUSED2 */ 8669bb4bb4Scarlsonj static int 8769bb4bb4Scarlsonj arphdr_cmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 8869bb4bb4Scarlsonj { 8969bb4bb4Scarlsonj struct { 9069bb4bb4Scarlsonj arh_t arh; 9169bb4bb4Scarlsonj uchar_t addrs[4 * ARP_MAX_ADDR_LEN]; 9269bb4bb4Scarlsonj } arp; 9369bb4bb4Scarlsonj size_t blen; 9469bb4bb4Scarlsonj uint16_t htype, ptype, op; 9569bb4bb4Scarlsonj const char *cp; 9669bb4bb4Scarlsonj 9769bb4bb4Scarlsonj if (!(flags & DCMD_ADDRSPEC)) { 9869bb4bb4Scarlsonj mdb_warn("address required to print ARP header\n"); 9969bb4bb4Scarlsonj return (DCMD_ERR); 10069bb4bb4Scarlsonj } 10169bb4bb4Scarlsonj 10269bb4bb4Scarlsonj if (mdb_vread(&arp.arh, sizeof (arp.arh), addr) == -1) { 10369bb4bb4Scarlsonj mdb_warn("unable to read ARP header at %p", addr); 10469bb4bb4Scarlsonj return (DCMD_ERR); 10569bb4bb4Scarlsonj } 10669bb4bb4Scarlsonj mdb_nhconvert(&htype, arp.arh.arh_hardware, sizeof (htype)); 10769bb4bb4Scarlsonj mdb_nhconvert(&ptype, arp.arh.arh_proto, sizeof (ptype)); 10869bb4bb4Scarlsonj mdb_nhconvert(&op, arp.arh.arh_operation, sizeof (op)); 10969bb4bb4Scarlsonj 11069bb4bb4Scarlsonj switch (htype) { 11169bb4bb4Scarlsonj case ARPHRD_ETHER: 11269bb4bb4Scarlsonj cp = "Ether"; 11369bb4bb4Scarlsonj break; 11469bb4bb4Scarlsonj case ARPHRD_IEEE802: 11569bb4bb4Scarlsonj cp = "IEEE802"; 11669bb4bb4Scarlsonj break; 11769bb4bb4Scarlsonj case ARPHRD_IB: 11869bb4bb4Scarlsonj cp = "InfiniBand"; 11969bb4bb4Scarlsonj break; 12069bb4bb4Scarlsonj default: 12169bb4bb4Scarlsonj cp = "Unknown"; 12269bb4bb4Scarlsonj break; 12369bb4bb4Scarlsonj } 12469bb4bb4Scarlsonj mdb_printf("%?p: ar$hrd %x (%s)\n", addr, htype, cp); 12569bb4bb4Scarlsonj mdb_printf("%?s ar$pro %x (%s)\n", "", ptype, 12669bb4bb4Scarlsonj ptype == IP_ARP_PROTO_TYPE ? "IP" : "Unknown"); 12769bb4bb4Scarlsonj 12869bb4bb4Scarlsonj switch (op) { 12969bb4bb4Scarlsonj case ARPOP_REQUEST: 13069bb4bb4Scarlsonj cp = "ares_op$REQUEST"; 13169bb4bb4Scarlsonj break; 13269bb4bb4Scarlsonj case ARPOP_REPLY: 13369bb4bb4Scarlsonj cp = "ares_op$REPLY"; 13469bb4bb4Scarlsonj break; 13569bb4bb4Scarlsonj case REVARP_REQUEST: 13669bb4bb4Scarlsonj cp = "arev_op$REQUEST"; 13769bb4bb4Scarlsonj break; 13869bb4bb4Scarlsonj case REVARP_REPLY: 13969bb4bb4Scarlsonj cp = "arev_op$REPLY"; 14069bb4bb4Scarlsonj break; 14169bb4bb4Scarlsonj default: 14269bb4bb4Scarlsonj cp = "Unknown"; 14369bb4bb4Scarlsonj break; 14469bb4bb4Scarlsonj } 14569bb4bb4Scarlsonj mdb_printf("%?s ar$op %d (%s)\n", "", op, cp); 14669bb4bb4Scarlsonj 14769bb4bb4Scarlsonj /* 14869bb4bb4Scarlsonj * Note that we go to some length to attempt to print out the fixed 14969bb4bb4Scarlsonj * header data before trying to decode the variable-length data. This 15069bb4bb4Scarlsonj * is done to maximize the amount of useful information shown when the 15169bb4bb4Scarlsonj * buffer is truncated or otherwise corrupt. 15269bb4bb4Scarlsonj */ 15369bb4bb4Scarlsonj blen = 2 * (arp.arh.arh_hlen + arp.arh.arh_plen); 15469bb4bb4Scarlsonj if (mdb_vread(&arp.addrs, blen, addr + sizeof (arp.arh)) == -1) { 15569bb4bb4Scarlsonj mdb_warn("unable to read ARP body at %p", addr); 15669bb4bb4Scarlsonj return (DCMD_ERR); 15769bb4bb4Scarlsonj } 15869bb4bb4Scarlsonj 15969bb4bb4Scarlsonj print_arp('s', arp.addrs, &arp.arh, ptype); 16069bb4bb4Scarlsonj print_arp('t', arp.addrs + arp.arh.arh_hlen + arp.arh.arh_plen, 16169bb4bb4Scarlsonj &arp.arh, ptype); 16269bb4bb4Scarlsonj return (DCMD_OK); 16369bb4bb4Scarlsonj } 16469bb4bb4Scarlsonj 16569bb4bb4Scarlsonj static const mdb_dcmd_t dcmds[] = { 16669bb4bb4Scarlsonj { "arphdr", ":", "display an ARP header", arphdr_cmd, NULL }, 16769bb4bb4Scarlsonj { NULL } 16869bb4bb4Scarlsonj }; 16969bb4bb4Scarlsonj 17069bb4bb4Scarlsonj /* Note: ar_t walker is in genunix.c and net.c; generic MI walker */ 17169bb4bb4Scarlsonj static const mdb_walker_t walkers[] = { 17269bb4bb4Scarlsonj { NULL } 17369bb4bb4Scarlsonj }; 17469bb4bb4Scarlsonj 17569bb4bb4Scarlsonj static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers }; 17669bb4bb4Scarlsonj 17769bb4bb4Scarlsonj const mdb_modinfo_t * 17869bb4bb4Scarlsonj _mdb_init(void) 17969bb4bb4Scarlsonj { 18069bb4bb4Scarlsonj return (&modinfo); 18169bb4bb4Scarlsonj } 18269bb4bb4Scarlsonj 18369bb4bb4Scarlsonj void 18469bb4bb4Scarlsonj _mdb_fini(void) 18569bb4bb4Scarlsonj { 18669bb4bb4Scarlsonj } 187