arp.c revision a12e05a04a5d5850f645c79e7e2c74f8d6b7c5ec
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <sys/hook_event.h>
#include <inet/arp_impl.h>
#include <mdb/mdb_modapi.h>
typedef struct {
char *act_name;
char *act_type;
} arp_cmd_tbl;
/*
* Table of ARP commands and structure types used for messages between ARP and
* IP.
*/
static const arp_cmd_tbl act_list[] = {
{ 0, "unknown command", "arp`arc_t" }
};
/*
* State information kept during walk over ACE hash table and unhashed mask
* list.
*/
typedef struct ace_walk_data {
int awd_idx;
static int
{
mdb_warn("failed to read 'arl_g_head'");
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
{
return (WALK_DONE);
return (WALK_ERR);
}
}
static int
{
mdb_warn("ace supports only global walks\n");
return (WALK_ERR);
}
"ar_ce_hash_tbl") == -1) {
mdb_warn("failed to read 'ar_ce_hash_tbl'");
return (WALK_ERR);
}
mdb_warn("failed to read 'ar_ce_mask_entries'");
return (WALK_ERR);
}
/* The step routine will start off by incrementing to index 0 */
return (WALK_NEXT);
}
static int
{
/*
* If we're at the end of the previous list, then find the start of the
* next list to process.
*/
return (WALK_DONE);
} else {
}
}
return (WALK_ERR);
}
}
static void
{
}
/* Common routine to produce an 'ar' text description */
static void
{
return;
nextip =
if (!ar->ar_on_ill_stream) {
return;
}
if (!nextip ||
return;
}
} else {
return;
return;
return;
return;
return;
}
}
/* ARGSUSED2 */
static int
{
return (WALK_NEXT);
}
/*
* Print out ARP client structures.
*/
/* ARGSUSED2 */
static int
{
mdb_printf("%<u>%?s %?s %?s %s%</u>\n",
"AR", "WQ", "ARL", "TYPE");
}
if (flags & DCMD_ADDRSPEC) {
return (DCMD_ERR);
}
} else {
mdb_warn("cannot walk ar_t structures");
return (DCMD_ERR);
}
}
return (DCMD_OK);
}
/* ARGSUSED2 */
static int
{
char flags[4];
const char *primstr;
else
} else {
sizeof (macstr));
}
/* Print both the link-layer state and the NOARP flag */
flags[0] = '\0';
case ARL_S_DOWN:
break;
case ARL_S_PENDING:
break;
case ARL_S_UP:
break;
default:
break;
}
mdb_printf(" %8d %-3s %-9s %s\n",
macstr);
return (WALK_NEXT);
}
/*
* Print out ARP link-layer elements.
*/
/* ARGSUSED2 */
static int
{
mdb_printf("%<u>%?s %16s %8s %3s %9s %s%</u>\n",
"ARL", "DLPI REQ", "DLPI CNT", "FLG", "INTERFACE",
"HWADDR");
}
if (flags & DCMD_ADDRSPEC) {
return (DCMD_ERR);
}
} else {
mdb_warn("cannot walk arl_t structures");
return (DCMD_ERR);
}
}
return (DCMD_OK);
}
/* ARGSUSED2 */
static int
{
/* The %b format isn't compact enough for long listings */
static const char ace_flags[] = "SPDRMLdA ofya";
const char *cp;
int flg;
char addrstr[sizeof ("255.255.255.255/32")];
/* Walk the list of flags and produce a string */
}
*fp = '\0';
/* If it's not resolved, then it has no hardware address */
ace->ace_hw_addr_length == 0 ||
} else {
sizeof (macstr));
}
/*
* Nothing other than IP uses ARP these days, so we don't try very hard
* here to switch out on ARP protocol type. (Note that ARP protocol
* types are roughly Ethertypes, but are allocated separately at IANA.)
*/
-1) {
/*
* If it's the standard host mask, then print it normally.
* Otherwise, use "/n" notation.
*/
inaddr);
} else {
}
} else {
}
return (WALK_NEXT);
}
/*
* Print out ARP cache entry (ace_t) elements.
*/
/* ARGSUSED2 */
static int
{
mdb_printf("%<u>%?s %-18s %-8s %s%</u>\n",
"ACE", "PROTOADDR", "FLAGS", "HWADDR");
}
if (flags & DCMD_ADDRSPEC) {
return (DCMD_ERR);
}
} else {
mdb_warn("cannot walk ace_t structures");
return (DCMD_ERR);
}
}
return (DCMD_OK);
}
/*
* Print an ARP hardware and protocol address pair; used when printing an ARP
* message.
*/
static void
{
else
} else if (ptype == IP_ARP_PROTO_TYPE) {
} else {
}
}
/*
* Decode an ARP message and display it.
*/
/* ARGSUSED2 */
static int
{
struct {
} arp;
const char *cp;
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("address required to print ARP header\n");
return (DCMD_ERR);
}
return (DCMD_ERR);
}
switch (htype) {
case ARPHRD_ETHER:
cp = "Ether";
break;
case ARPHRD_IEEE802:
cp = "IEEE802";
break;
case ARPHRD_IB:
cp = "InfiniBand";
break;
default:
cp = "Unknown";
break;
}
switch (op) {
case ARPOP_REQUEST:
cp = "ares_op$REQUEST";
break;
case ARPOP_REPLY:
cp = "ares_op$REPLY";
break;
case REVARP_REQUEST:
cp = "arev_op$REQUEST";
break;
case REVARP_REPLY:
cp = "arev_op$REPLY";
break;
default:
cp = "Unknown";
break;
}
/*
* Note that we go to some length to attempt to print out the fixed
* header data before trying to decode the variable-length data. This
* is done to maximize the amount of useful information shown when the
* buffer is truncated or otherwise corrupt.
*/
return (DCMD_ERR);
}
return (DCMD_OK);
}
/*
* Print out an arp command formatted in a reasonable manner. This implements
* the type switch used by ARP.
*
* It could also dump the data that follows the header (using offset and length
* in the various structures), but it currently does not.
*/
/* ARGSUSED2 */
static int
{
const arp_cmd_tbl *tp;
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("address required to print ARP command\n");
return (DCMD_ERR);
}
return (DCMD_ERR);
}
break;
return (DCMD_ERR);
else
return (DCMD_OK);
}
static size_t
{
/*
* size of the allocation. An mi_o_s is thus a size_t plus an mi_o_s.
*/
struct mi_block {
} m;
return (m.mi_nbytes - sizeof (m));
return (0);
}
/*
* This is called when ::stream is used and an ARP module is seen on the
* stream. Determine what sort of ARP usage is involved and show an
* appropriate message.
*/
static void
{
return;
return;
}
static uintptr_t
{
return (NULL);
}
static uintptr_t
{
return (NULL);
}
static const mdb_dcmd_t dcmds[] = {
{ NULL }
};
static const mdb_walker_t walkers[] = {
{ "arl", "walk list of arl_t links",
{ "ace", "walk list of ace_t entries",
{ NULL }
};
const mdb_modinfo_t *
_mdb_init(void)
{
return (&modinfo);
}
void
_mdb_fini(void)
{
}