net.c revision d5b6ed4b2ef09ba3e41de5d786a1836943a63613
/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <mdb/mdb_modapi.h>
#include <inet/ipclassifier.h>
#include <sys/tpicommon.h>
#include <sys/socketvar.h>
#include <sys/cred_impl.h>
#include <inet/udp_impl.h>
#include <inet/arp_impl.h>
#include <inet/rawip_impl.h>
#define ADDR_V6_WIDTH 23
#define ADDR_V4_WIDTH 15
#define NETSTAT_ALL 0x01
#define NETSTAT_VERBOSE 0x02
#define NETSTAT_ROUTE 0x04
#define NETSTAT_V4 0x08
#define NETSTAT_V6 0x10
#define NETSTAT_UNIX 0x20
#define NETSTAT_FIRST 0x80000000u
typedef struct netstat_cb_data_s {
int af;
/* Walkers for various *_stack_t */
int
{
mdb_warn("can't walk 'netstack'");
return (WALK_ERR);
}
return (WALK_NEXT);
}
int
{
return (WALK_ERR);
}
}
int
{
mdb_warn("can't walk 'netstack'");
return (WALK_ERR);
}
return (WALK_NEXT);
}
int
{
return (WALK_ERR);
}
}
int
{
mdb_warn("can't walk 'netstack'");
return (WALK_ERR);
}
return (WALK_NEXT);
}
int
{
return (WALK_ERR);
}
}
int
{
mdb_warn("can't walk 'netstack'");
return (WALK_ERR);
}
return (WALK_NEXT);
}
int
{
return (WALK_ERR);
}
}
/*
* Print an IPv4 address and port number in a compact and easy to read format
* The arguments are in network byte order
*/
static void
{
}
/*
* Print an IPv6 address and port number in a compact and easy to read format
* The arguments are in network byte order
*/
static void
{
}
static int
{
}
static int
{
}
static int
{
}
static int
{
}
static int
{
}
static int
{
}
int
{
mdb_warn("failed to lookup sockfs`socklist");
return (WALK_ERR);
}
mdb_warn("failed to read address of initial sonode "
return (WALK_ERR);
}
}
return (WALK_NEXT);
}
int
{
int status;
struct sotpi_sonode *stp;
return (WALK_DONE);
return (WALK_ERR);
}
wsp->walk_cbdata);
return (status);
}
void
{
}
struct mi_walk_data {
};
int
{
struct mi_walk_data *wdp;
mdb_warn("mi doesn't support global walks\n");
return (WALK_ERR);
}
/* So that we do not immediately return WALK_DONE below */
return (WALK_NEXT);
}
int
{
int status;
/* Always false in the first iteration */
return (WALK_DONE);
}
return (WALK_ERR);
}
/* Only true in the first iteration */
} else {
}
return (status);
}
void
{
}
typedef struct mi_payload_walk_arg_s {
const char *mi_pwa_walker; /* Underlying walker */
#define MI_PAYLOAD_DEVICE 0x1
#define MI_PAYLOAD_MODULE 0x2
int
{
return (WALK_ERR);
}
return (WALK_NEXT);
}
int
{
mdb_warn("can't read address of mi head at %p for %s",
return (WALK_ERR);
}
if (kaddr == 0) {
/* Empty list */
return (WALK_DONE);
}
mdb_warn("failed to walk genunix`mi");
return (WALK_ERR);
}
return (WALK_NEXT);
}
const mi_payload_walk_arg_t mi_ar_arg = {
};
const mi_payload_walk_arg_t mi_icmp_arg = {
};
int
{
int filter = 0;
if (!(flags & DCMD_ADDRSPEC)) {
argv) == -1) {
mdb_warn("failed to walk sonode");
return (DCMD_ERR);
}
return (DCMD_OK);
}
return (DCMD_USAGE);
else
filter = 1;
}
type = SOCK_STREAM;
type = SOCK_DGRAM;
else
filter = 1;
}
filter = 1;
}
mdb_printf("%<u>%-?s Family Type Proto State Mode Flag "
"AccessVP%</u>\n", "Sonode:");
}
return (DCMD_ERR);
}
return (DCMD_OK);
return (DCMD_OK);
return (DCMD_OK);
if (filter) {
return (DCMD_OK);
}
case AF_UNIX:
mdb_printf("unix ");
break;
case AF_INET:
mdb_printf("inet ");
break;
case AF_INET6:
mdb_printf("inet6 ");
break;
default:
}
case SOCK_STREAM:
mdb_printf(" strm");
break;
case SOCK_DGRAM:
mdb_printf(" dgrm");
break;
case SOCK_RAW:
mdb_printf(" raw ");
break;
default:
}
mdb_printf(" %5hi %05x %04x %04hx\n",
return (DCMD_OK);
}
#define MI_PAYLOAD 0x1
#define MI_DEVICE 0x2
#define MI_MODULE 0x4
int
{
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
return (DCMD_USAGE);
mdb_warn("at most one filter, d for devices or m "
"for modules, may be specified\n");
return (DCMD_USAGE);
}
mdb_printf("%<u>%-?s %-?s %-?s IsDev Dev%</u>\n",
"MI_O", "Next", "Prev");
}
return (DCMD_ERR);
}
if (opts != 0) {
/* mio is a module */
return (DCMD_OK);
} else {
/* mio is a device */
return (DCMD_OK);
}
if (opts & MI_PAYLOAD)
else
return (DCMD_OK);
}
mdb_printf("FALSE");
else
mdb_printf("TRUE ");
return (DCMD_OK);
}
static int
{
return (0);
}
return (nss.netstack_stackid);
}
static void
{
mdb_printf(" %5i %08x %08x %5i %08x %08x %5li %5i\n",
}
/*ARGSUSED*/
static int
{
return (WALK_ERR);
}
return (WALK_ERR);
}
return (WALK_NEXT);
}
mdb_printf(" ");
mdb_printf(" ");
}
if (opts & NETSTAT_VERBOSE)
return (WALK_NEXT);
}
/*ARGSUSED*/
static int
{
char *state;
return (WALK_ERR);
}
mdb_warn("failed to read conn_udp at %p",
return (WALK_ERR);
}
return (WALK_NEXT);
}
state = "UNBOUND";
state = "IDLE";
state = "CONNECTED";
else
state = "UNKNOWN";
mdb_printf(" ");
mdb_printf(" ");
}
return (WALK_NEXT);
}
/*ARGSUSED*/
static int
{
char *state;
return (WALK_ERR);
}
mdb_warn("failed to read conn_icmp at %p",
return (WALK_ERR);
}
return (WALK_NEXT);
}
state = "UNBOUND";
state = "IDLE";
state = "CONNECTED";
else
state = "UNKNOWN";
}
return (WALK_NEXT);
}
/*
* print the address of a unix domain socket
*
* so is the address of a AF_UNIX struct sonode in mdb's address space
* soa is the address of the struct soaddr to print
*
* returns 0 on success, -1 otherwise
*/
static int
{
const char none[] = " (none)";
} else {
mdb_warn("failed to read unix address "
return (-1);
}
} else {
}
}
} else {
}
return (0);
}
/* based on sockfs_snapshot */
/*ARGSUSED*/
static int
{
return (WALK_NEXT);
return (WALK_ERR);
}
switch (sti->sti_serv_type) {
case T_CLTS:
break;
case T_COTS:
break;
case T_COTS_ORD:
break;
default:
}
} else {
}
} else {
}
return (WALK_ERR);
return (WALK_ERR);
return (WALK_NEXT);
}
static void
{
mdb_printf(" %<u>%-5s %-8s %-8s %-5s %-8s %-8s %5s %5s%</u>\n",
"Swind", "Snext", "Suna", "Rwind", "Rack", "Rnext", "Rto", "Mss");
}
static void
{
*intf = '\0';
-1)
return;
return;
char *cp;
return;
-1)
return;
}
}
}
static void
{
}
static int
{
return (WALK_NEXT);
return (WALK_NEXT);
if (*opts & NETSTAT_FIRST) {
*opts &= ~NETSTAT_FIRST;
mdb_printf("%<u>%s Table: IPv4%</u>\n",
if (*opts & NETSTAT_VERBOSE) {
mdb_printf("%<u>%-?s %-*s %-*s %-*s Device Mxfrg Rtt "
} else {
mdb_printf("%<u>%-?s %-*s %-*s Flags Ref Use "
"Interface%</u>\n",
ADDR_V4_WIDTH, "Gateway");
}
}
if (*opts & NETSTAT_VERBOSE) {
mdb_printf("%?p %-*I %-*I %-*I %-6s %5u%c %4u %3u %-3s %5u "
} else {
}
return (WALK_NEXT);
}
int
{
int plen;
int i;
for (i = 3; i >= 0; i--)
break;
if (i < 0)
return (0);
while (!(val & 1)) {
val >>= 1;
plen--;
}
return (plen);
}
static int
{
const in6_addr_t *gatep;
int masklen;
return (WALK_NEXT);
return (WALK_NEXT);
if (*opts & NETSTAT_FIRST) {
*opts &= ~NETSTAT_FIRST;
mdb_printf("\n%<u>%s Table: IPv6%</u>\n",
if (*opts & NETSTAT_VERBOSE) {
mdb_printf("%<u>%-?s %-*s %-*s If PMTU Rtt Ref "
ADDR_V6_WIDTH, "Gateway");
} else {
mdb_printf("%<u>%-?s %-*s %-*s Flags Ref Use If"
"%</u>\n",
ADDR_V6_WIDTH, "Gateway");
}
}
if (masklen == IPV6_ABITS)
if (*opts & NETSTAT_VERBOSE) {
mdb_printf("%?p %-*s %-*N %-5s %5u%c %5u %3u %-5s %6u %u\n",
} else {
}
return (WALK_NEXT);
}
static void
netstat_header_v4(int proto)
{
if (proto == IPPROTO_TCP)
else if (proto == IPPROTO_UDP)
else if (proto == IPPROTO_ICMP)
mdb_printf("State %6s%*s %6s%*s %-5s %-4s%</u>\n",
}
static void
netstat_header_v6(int proto)
{
if (proto == IPPROTO_TCP)
else if (proto == IPPROTO_UDP)
else if (proto == IPPROTO_ICMP)
mdb_printf("State %6s%*s %6s%*s %-5s %-4s%</u>\n",
}
static int
void *cbdata)
{
return (DCMD_ERR);
}
return (DCMD_OK);
}
static int
void *cbdata)
{
}
}
return (status);
}
/*ARGSUSED*/
int
{
int status;
int af = 0;
return (DCMD_USAGE);
return (DCMD_USAGE);
if (opts & NETSTAT_ROUTE)
return (DCMD_USAGE);
}
opts |= NETSTAT_V4;
opts |= NETSTAT_V6;
opts |= NETSTAT_UNIX;
else
return (DCMD_USAGE);
if (opts & NETSTAT_ROUTE) {
return (DCMD_USAGE);
if (opts & NETSTAT_V4) {
opts |= NETSTAT_FIRST;
mdb_warn("failed to walk ip`ire");
return (DCMD_ERR);
}
}
if (opts & NETSTAT_V6) {
opts |= NETSTAT_FIRST;
mdb_warn("failed to walk ip`ire");
return (DCMD_ERR);
}
}
return (DCMD_OK);
}
/* Print Unix Domain Sockets */
mdb_printf("%<u>%-?s %-10s %-?s %-?s %-14s %-14s %s%</u>\n",
"AF_UNIX", "Type", "Vnode", "Conn", "Local Addr",
"Remote Addr", "Zone");
mdb_warn("failed to walk genunix`sonode");
return (DCMD_ERR);
}
return (DCMD_OK);
}
goto out;
}
goto out;
}
goto out;
}
out:
return (status);
}