dladm.c revision d62bc4badc1c1f1549c961cfb8b420e650e1272b
/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <ctype.h>
#include <locale.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <stropts.h>
#include <errno.h>
#include <kstat.h>
#include <strings.h>
#include <getopt.h>
#include <unistd.h>
#include <priv.h>
#include <termios.h>
#include <pwd.h>
#include <auth_attr.h>
#include <auth_list.h>
#include <libintl.h>
#include <libdevinfo.h>
#include <libdlpi.h>
#include <libdllink.h>
#include <libdlaggr.h>
#include <libdlwlan.h>
#include <libdlvlan.h>
#include <libdlvnic.h>
#include <libinetutil.h>
#include <bsm/adt_event.h>
#define AGGR_DRV "aggr"
#define MAXPORT 256
#define MAXLINELEN 1024
#define SMF_UPGRADE_FILE "/var/svc/profile/upgrade"
#define SMF_UPGRADEDATALINK_FILE "/var/svc/profile/upgrade_datalink"
#define SMF_DLADM_UPGRADE_MSG " # added by dladm(1M)"
typedef struct pktsum_s {
} pktsum_t;
typedef struct show_state {
} show_state_t;
typedef struct show_grp_state {
typedef void cmdfunc_t(int, char **);
static cmdfunc_t do_show_linkmap;
static void altroot_cmd(char *, int, char **);
static int show_linkprop_onelink(datalink_id_t, void *);
static int get_one_kstat(const char *, const char *, uint8_t,
void *, boolean_t);
static void get_mac_stats(const char *, pktsum_t *);
static void get_link_stats(const char *, pktsum_t *);
static const char *get_linkstate(const char *, boolean_t, char *);
static const char *get_linkduplex(const char *, boolean_t, char *);
static void die(const char *, ...);
static void die_optdup(int);
static void die_opterr(int, int);
static void die_dlerr(dladm_status_t, const char *, ...);
static void warn(const char *, ...);
static void warn_dlerr(dladm_status_t, const char *, ...);
typedef struct cmd {
char *c_name;
} cmd_t;
{ "show-link", do_show_link },
{ "show-dev", do_show_dev },
{ "create-aggr", do_create_aggr },
{ "delete-aggr", do_delete_aggr },
{ "add-aggr", do_add_aggr },
{ "remove-aggr", do_remove_aggr },
{ "modify-aggr", do_modify_aggr },
{ "show-aggr", do_show_aggr },
{ "up-aggr", do_up_aggr },
{ "scan-wifi", do_scan_wifi },
{ "connect-wifi", do_connect_wifi },
{ "disconnect-wifi", do_disconnect_wifi },
{ "show-wifi", do_show_wifi },
{ "show-linkprop", do_show_linkprop },
{ "set-linkprop", do_set_linkprop },
{ "reset-linkprop", do_reset_linkprop },
{ "create-secobj", do_create_secobj },
{ "delete-secobj", do_delete_secobj },
{ "show-secobj", do_show_secobj },
{ "init-linkprop", do_init_linkprop },
{ "init-secobj", do_init_secobj },
{ "create-vlan", do_create_vlan },
{ "delete-vlan", do_delete_vlan },
{ "show-vlan", do_show_vlan },
{ "up-vlan", do_up_vlan },
{ "rename-link", do_rename_link },
{ "delete-phys", do_delete_phys },
{ "show-phys", do_show_phys },
{ "init-phys", do_init_phys },
{ "show-linkmap", do_show_linkmap }
};
{ 0, 0, 0, 0 }
};
static const struct option show_lopts[] = {
{ 0, 0, 0, 0 }
};
static const struct option prop_longopts[] = {
{ 0, 0, 0, 0 }
};
static const struct option wifi_longopts[] = {
{ 0, 0, 0, 0 }
};
static char *progname;
static sig_atomic_t signalled;
static void
usage(void)
{
"\tshow-link [-pP] [-s [-i <interval>]] [<link>]\n"
"\trename-link [-R <root-dir>] <oldlink> <newlink>\n"
"\n"
"\tdelete-phys <link>\n"
"\tshow-phys [-pP] [<link>]\n"
"\tshow-dev [-p] [-s [-i <interval>]] [<dev>]\n"
"\n"
"\tcreate-aggr [-t] [-R <root-dir>] [-P <policy>] [-L <mode>]\n"
"\t [-T <time>] [-u <address>] [-l <link>] ... <link>\n"
"\tmodify-aggr [-t] [-R <root-dir>] [-P <policy>] [-L <mode>]\n"
"\t [-T <time>] [-u <address>] <link>\n"
"\tdelete-aggr [-t] [-R <root-dir>] <link>\n"
"\tadd-aggr [-t] [-R <root-dir>] [-l <link>] ... <link>\n"
"\tremove-aggr [-t] [-R <root-dir>] [-l <link>] ... <link>"
"\n\tshow-aggr [-pPLx][-s [-i <interval>]] [<link>]\n"
"\n"
"\tcreate-vlan [-ft] [-R <root-dir>] -l <link> -v <vid> [link]"
"\n\tdelete-vlan [-t] [-R <root-dir>] <link>\n"
"\tshow-vlan [-pP] [<link>]\n"
"\n"
"\tscan-wifi [-p] [-o <field>,...] [<link>]\n"
"\tconnect-wifi [-e <essid>] [-i <bssid>] [-k <key>,...]"
" [-s wep|wpa]\n"
"\t [-a open|shared] [-b bss|ibss] [-c] [-m a|b|g]\n"
"\t [-T <time>] [<link>]\n"
"\tdisconnect-wifi [-a] [<link>]\n"
"\tshow-wifi [-p] [-o <field>,...] [<link>]\n"
"\n"
"\tset-linkprop [-t] [-R <root-dir>] -p <prop>=<value>[,...]"
" <name>\n"
"\treset-linkprop [-t] [-R <root-dir>] [-p <prop>,...] <name>\n"
"\tshow-linkprop [-cP][-p <prop>,...] <name>\n"
"\n"
"\tcreate-secobj [-t] [-R <root-dir>] [-f <file>] -c <class>"
" <secobj>\n"
"\tdelete-secobj [-t] [-R <root-dir>] <secobj>[,...]\n"
"\tshow-secobj [-pP][<secobj>,...]\n"));
exit(1);
}
int
{
int i;
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
if (argc < 2)
usage();
if (!priv_ineffect(PRIV_SYS_NET_CONFIG) ||
die("insufficient privileges");
exit(0);
}
}
usage();
return (0);
}
static void
{
char option;
int key = 0;
char name[MAXLINKNAMELEN];
switch (option) {
case 'd':
die("too many ports specified");
break;
case 'P':
if (P_arg)
break;
case 'u':
if (u_arg)
mac_addr))
break;
case 'l':
/*
* Ended with digit, possibly a link name.
*/
die("too many ports specified");
break;
}
/* FALLTHROUGH */
case 'L':
if (l_arg)
break;
case 'T':
if (T_arg)
break;
case 't':
flags &= ~DLADM_OPT_PERSIST;
break;
case 'f':
flags |= DLADM_OPT_FORCE;
break;
case 'R':
break;
default:
break;
}
}
usage();
/* get key value or the aggregation name (required last argument) */
usage();
}
if (!dladm_valid_linkname(name))
} else {
}
for (n = 0; n < ndev; n++) {
}
}
for (n = 0; n < nlink; n++) {
}
}
lacp_timer, flags);
done:
if (status != DLADM_STATUS_OK) {
if (status == DLADM_STATUS_NONOTIF) {
"detection; must use -f (see dladm(1M))\n");
} else {
}
}
}
/*
* arg is either the key or the aggr name. Validate it and convert it to
* the linkid if altroot is NULL.
*/
static dladm_status_t
{
int key = 0;
return (DLADM_STATUS_LINKINVAL);
return (DLADM_STATUS_OK);
} else {
}
return (status);
}
static void
{
char option;
opterr = 0;
switch (option) {
case 't':
flags &= ~DLADM_OPT_PERSIST;
break;
case 'R':
break;
default:
break;
}
}
/* get key value or the aggregation name (required last argument) */
usage();
if (status != DLADM_STATUS_OK)
goto done;
done:
if (status != DLADM_STATUS_OK)
}
static void
{
char option;
NULL)) != -1) {
switch (option) {
case 'd':
die("too many ports specified");
break;
case 'l':
die("too many ports specified");
break;
case 't':
flags &= ~DLADM_OPT_PERSIST;
break;
case 'f':
flags |= DLADM_OPT_FORCE;
break;
case 'R':
break;
default:
break;
}
}
usage();
/* get key value or the aggregation name (required last argument) */
usage();
goto done;
}
for (n = 0; n < ndev; n++) {
}
}
for (n = 0; n < nlink; n++) {
}
}
done:
if (status != DLADM_STATUS_OK) {
/*
* checking DLADM_STATUS_NOTSUP is a temporary workaround
* and should be removed once 6399681 is fixed.
*/
if (status == DLADM_STATUS_NOTSUP) {
gettext("%s: add operation failed: %s\n"),
gettext("link capabilities don't match"));
} else if (status == DLADM_STATUS_NONOTIF) {
"detection; must use -f (see dladm(1M))\n");
} else {
}
}
}
static void
{
char option;
switch (option) {
case 'd':
die("too many ports specified");
break;
case 'l':
die("too many ports specified");
break;
case 't':
flags &= ~DLADM_OPT_PERSIST;
break;
case 'R':
break;
default:
break;
}
}
usage();
/* get key value or the aggregation name (required last argument) */
usage();
if (status != DLADM_STATUS_OK)
goto done;
for (n = 0; n < ndev; n++) {
}
}
for (n = 0; n < nlink; n++) {
}
}
done:
if (status != DLADM_STATUS_OK)
}
static void
{
char option;
uint8_t modify_mask = 0;
opterr = 0;
NULL)) != -1) {
switch (option) {
case 'P':
break;
case 'u':
if (modify_mask & DLADM_AGGR_MODIFY_MAC)
mac_addr))
break;
case 'l':
case 'L':
break;
case 'T':
break;
case 't':
flags &= ~DLADM_OPT_PERSIST;
break;
case 'R':
break;
default:
break;
}
}
if (modify_mask == 0)
die("at least one of the -PulT options must be specified");
/* get key value or the aggregation name (required last argument) */
usage();
if (status != DLADM_STATUS_OK)
goto done;
done:
if (status != DLADM_STATUS_OK)
}
static void
{
/*
* get the key or the name of the aggregation (optional last argument)
*/
if (argc == 2) {
DLADM_OPT_PERSIST)) != DLADM_STATUS_OK) {
goto done;
}
} else if (argc > 2) {
usage();
}
done:
if (status != DLADM_STATUS_OK) {
if (argc == 2) {
} else {
}
}
}
static void
{
char drv[DLPI_LINKNAME_MAX];
int vid = 0;
char option;
char vlan[MAXLINKNAMELEN];
opterr = 0;
switch (option) {
case 'v':
if (vid != 0)
break;
case 'l':
break;
case 'f':
flags |= DLADM_OPT_FORCE;
break;
case 't':
flags &= ~DLADM_OPT_PERSIST;
break;
case 'R':
break;
default:
break;
}
}
/* get vlan name if there is any */
usage();
}
} else {
(ppa >= 1000) ||
DLPI_SUCCESS)) {
}
}
}
if (status == DLADM_STATUS_NOTSUP) {
"MTU; must use -f (see dladm(1M))\n", link);
} else {
}
}
}
static void
{
char option;
opterr = 0;
switch (option) {
case 't':
flags &= ~DLADM_OPT_PERSIST;
break;
case 'R':
break;
default:
break;
}
}
/* get VLAN link name (required last argument) */
usage();
if (status != DLADM_STATUS_OK)
goto done;
done:
if (status != DLADM_STATUS_OK)
}
static void
{
/*
* get the name of the VLAN (optional last argument)
*/
if (argc > 2)
usage();
if (argc == 2) {
if (status != DLADM_STATUS_OK)
goto done;
}
done:
if (status != DLADM_STATUS_OK) {
if (argc == 2) {
} else {
}
}
}
static void
{
char option;
opterr = 0;
switch (option) {
case 'R':
break;
default:
break;
}
}
/* get link1 and link2 name (required the last 2 arguments) */
usage();
}
static void
{
/* get link name (required the last argument) */
if (argc > 2)
usage();
if (argc == 2) {
if (status != DLADM_STATUS_OK)
}
if (argc == 2)
else
}
}
/*ARGSUSED*/
static int
{
char name[MAXLINKNAMELEN];
char mediabuf[DLADM_STRSIZE];
char classbuf[DLADM_STRSIZE];
MAXLINKNAMELEN) == DLADM_STATUS_OK) {
}
return (DLADM_WALK_CONTINUE);
}
/*ARGSUSED*/
static void
{
if (argc != 1)
die("invalid arguments");
"CLASS", "MEDIA", "FLAGS");
}
/*
* Delete inactive physical links.
*/
/*ARGSUSED*/
static int
{
NULL, 0) != DLADM_STATUS_OK) {
return (DLADM_WALK_CONTINUE);
}
(void) dladm_phys_delete(linkid);
return (DLADM_WALK_CONTINUE);
}
/*ARGSUSED*/
static void
{
if (argc > 1)
usage();
/*
* Force all the devices to attach, therefore all the network physical
* devices can be known to the dlmgmtd daemon.
*/
}
static void
{
if (state->ls_donefirst)
return;
if (state->ls_parseable)
return;
"STATE", "OVER");
} else {
}
}
/*
* Print the active topology information.
*/
static dladm_status_t
{
char *fmt;
char over[MAXLINKNAMELEN];
if (state->ls_parseable)
fmt = "OVER=\"%s";
else
fmt = "%s";
if (class == DATALINK_CLASS_VLAN) {
if (status != DLADM_STATUS_OK)
goto done;
if (status != DLADM_STATUS_OK)
goto done;
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
} else if (class == DATALINK_CLASS_AGGR) {
int i;
if (status != DLADM_STATUS_OK)
goto done;
goto done;
}
sizeof (over));
if (status != DLADM_STATUS_OK) {
goto done;
}
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
fmt = " %s";
}
} else if (class == DATALINK_CLASS_VNIC) {
sizeof (over))) != DLADM_STATUS_OK) {
goto done;
}
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
} else {
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
}
if (state->ls_parseable)
else
done:
return (status);
}
static dladm_status_t
{
char link[MAXLINKNAMELEN];
char buf[DLADM_STRSIZE];
char *fmt;
goto done;
}
goto done;
}
if (class == DATALINK_CLASS_PHYS) {
DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK) {
goto done;
}
if (!dpa.dp_novanity)
goto link_mtu;
/*
* This is a physical link that does not have
* vanity naming support.
*/
DLPI_SUCCESS) {
goto done;
}
dlpi_close(dh);
goto done;
}
dlpi_close(dh);
} else {
if (status != DLADM_STATUS_OK)
goto done;
}
}
if (state->ls_parseable)
fmt = "LINK=\"%s\" CLASS=\"%s\" MTU=\"%d\" ";
else
fmt = "%-12s%-8s%6d ";
} else {
if (state->ls_parseable)
fmt = "LINK=\"%s\" CLASS=\"%s\" ";
else
fmt = "%-12s%-8s";
}
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
} else {
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
}
if (state->ls_parseable) {
"STATE=\"%s\" ", buf);
} else {
"%-9s", buf);
}
}
if (status != DLADM_STATUS_OK)
goto done;
done:
return (status);
}
static int
{
char buf[MAXLINELEN];
if (status != DLADM_STATUS_OK)
goto done;
done:
return (DLADM_WALK_CONTINUE);
}
static int
{
char link[MAXLINKNAMELEN];
if (state->ls_firstonly) {
if (state->ls_donefirst)
return (DLADM_WALK_CONTINUE);
} else {
}
sizeof (link)) != DLADM_STATUS_OK) {
return (DLADM_WALK_CONTINUE);
}
if (class == DATALINK_CLASS_PHYS) {
return (DLADM_WALK_CONTINUE);
}
if (dpa.dp_novanity)
else
} else {
}
return (DLADM_WALK_CONTINUE);
}
static void
{
} else {
(double)diff_stats.ipackets/
}
} else {
(double)diff_stats.opackets/
}
*old_stats = *port_stats;
}
static void
{
if (state->gs_donefirst)
return;
if (state->gs_parseable)
return;
"PORT", "AGGREGATABLE", "SYNC", "COLL", "DIST",
"DEFAULTED", "EXPIRED");
} else if (state->gs_extended) {
"PORT", "SPEED", "DUPLEX", "STATE", "ADDRESS", "PORTSTATE");
"ADDRPOLICY", "LACPACTIVITY", "LACPTIMER", "FLAGS");
}
}
static dladm_status_t
{
char buf[DLADM_STRSIZE];
char *fmt;
if (state->gs_parseable)
fmt = "LINK=\"%s\" POLICY=\"%s\" ADDRPOLICY=\"%s%s\" ";
else
fmt = "%-12s%-8s%-6s%-18s";
if (ginfop->lg_mac_fixed) {
} else {
str[0] = '\0';
}
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
if (state->gs_parseable) {
"LACPACTIVITY=\"%s\" ", buf);
} else {
}
if (state->gs_parseable) {
"LACPTIMER=\"%s\" FLAGS=\"%c----\"\n", buf,
} else {
}
return (DLADM_STATUS_OK);
}
static dladm_status_t
{
char port[MAXLINKNAMELEN];
char buf[DLADM_STRSIZE];
char *fmt;
int i;
if (state->gs_parseable)
fmt = "LINK=\"%s\" PORT=\"%s\" SPEED=\"%uMb\" DUPLEX=\"%s\" ";
else
fmt = "%-12s%-14s%4uMb %-9s";
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
if (state->gs_parseable) {
"STATE=\"%s\" ADDRESS=\"%s\" PORTSTATE=\"%s\"\n", buf,
addr_str, "");
} else {
}
const char *tmp;
goto done;
}
DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK) {
goto done;
}
if (state->gs_parseable)
else
tmp = "";
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
if (state->gs_parseable) {
} else {
}
(void) dladm_aggr_portstate2str(
if (state->gs_parseable) {
"PORTSTATE=\"%s\"\n", buf);
} else {
"%s\n", buf);
}
}
done:
return (status);
}
static dladm_status_t
{
char port[MAXLINKNAMELEN];
char *fmt;
int i;
if (state->gs_parseable) {
fmt = "LINK=\"%s\" PORT=\"%s\" AGGREGATABLE=\"%s\" SYNC=\"%s\" "
"COLL=\"%s\" DIST=\"%s\" DEFAULTED=\"%s\" EXPITED=\"%s\"\n";
} else {
fmt = "%-12s%-12s%-13s%-5s%-5s%-5s%-10s%s\n";
}
if (status != DLADM_STATUS_OK)
goto done;
/*
* Only display link for the first port.
*/
if ((i > 0) && !(state->gs_parseable))
dlink = "";
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
}
done:
return (status);
}
static dladm_status_t
{
char port[MAXLINKNAMELEN];
int i;
if (state->gs_firstonly) {
if (state->gs_donefirst)
return (DLADM_WALK_CONTINUE);
} else {
}
/* sum the ports statistics */
DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK) {
goto done;
}
}
DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK) {
goto done;
}
goto done;
}
}
done:
return (status);
}
static dladm_status_t
char *lim)
{
char link[MAXLINKNAMELEN];
sizeof (link))) != DLADM_STATUS_OK) {
return (status);
}
return (DLADM_STATUS_NOTFOUND);
if (status != DLADM_STATUS_OK)
return (status);
else if (state->gs_extended)
else
done:
return (status);
}
static int
{
char buf[MAXLINELEN];
if (status != DLADM_STATUS_OK)
goto done;
done:
return (DLADM_WALK_CONTINUE);
}
static int
{
return (-1);
return (-1);
switch (type) {
case KSTAT_DATA_UINT64:
break;
case KSTAT_DATA_UINT32:
break;
default:
return (-1);
}
return (0);
}
static int
{
char buf[DLADM_STRSIZE];
char *fmt;
if (state->ls_parseable)
fmt = "DEV=\"%s\" STATE=\"%s\" SPEED=\"%u\" ";
else
fmt = "%-12s%-10s%4uMb ";
if (!state->ls_donefirst) {
if (!state->ls_parseable) {
"SPEED", "DUPLEX");
}
}
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
if (state->ls_parseable)
else
return (DLADM_WALK_CONTINUE);
}
static int
{
if (state->ls_firstonly) {
if (state->ls_donefirst)
return (DLADM_WALK_CONTINUE);
} else {
}
return (DLADM_WALK_CONTINUE);
}
static void
{
int option;
int interval = 0;
opterr = 0;
switch (option) {
case 'p':
if (p_arg)
break;
case 's':
if (s_arg)
break;
case 'P':
if (flags != DLADM_OPT_ACTIVE)
break;
case 'i':
if (i_arg)
break;
default:
break;
}
}
die("the option -i can be used only with -s");
/* get link name (optional last argument) */
uint32_t f;
}
if (!(f & flags)) {
"a temporary link" : "temporarily removed");
}
usage();
}
if (s_arg) {
return;
}
if (linkid == DATALINK_ALL_LINKID) {
} else {
}
}
}
static void
{
int option;
int interval = 0;
int key;
opterr = 0;
switch (option) {
case 'L':
if (L_arg)
break;
case 'p':
if (p_arg)
break;
case 'x':
if (x_arg)
break;
case 'P':
if (flags != DLADM_OPT_ACTIVE)
break;
case 's':
if (s_arg)
break;
case 'i':
if (i_arg)
break;
default:
break;
}
}
die("the option -i can be used only with -s");
die("the option -%c cannot be used with -s",
}
die("the option -P cannot be used with -L");
/* get aggregation key or aggrname (optional last argument) */
} else {
}
if (status != DLADM_STATUS_OK)
usage();
}
if (s_arg) {
return;
}
if (linkid == DATALINK_ALL_LINKID) {
} else {
}
}
}
static void
{
int option;
int interval = 0;
opterr = 0;
switch (option) {
case 'p':
if (p_arg)
break;
case 's':
if (s_arg)
break;
case 'i':
if (i_arg)
break;
default:
break;
}
}
die("the option -i can be used only with -s");
die("the option -s cannot be used with -p");
/* get dev name (optional last argument) */
NULL, 0) != DLADM_STATUS_OK) ||
!(flags & DLADM_OPT_ACTIVE)) {
}
usage();
}
if (s_arg) {
return;
}
} else {
}
}
static void
{
if (state->ls_donefirst)
return;
if (state->ls_parseable)
return;
"MEDIA", "STATE", "SPEED", "DUPLEX", "DEVICE");
} else {
"MEDIA", "FLAGS");
}
}
static dladm_status_t
{
char link[MAXLINKNAMELEN];
char buf[DLADM_STRSIZE];
goto done;
}
if (class != DATALINK_CLASS_PHYS) {
goto done;
}
goto done;
}
if (status != DLADM_STATUS_OK)
goto done;
char name[MAXLINKNAMELEN];
if (!dpa.dp_novanity) {
} else {
/*
* This is a physical link that does not have
* vanity naming support.
*/
}
if (state->ls_parseable) {
"LINK=\"%s\" MEDIA=\"%s\" ", link,
"STATE=\"%s\" SPEED=\"%uMb\" ",
"DUPLEX=\"%s\" DEVICE=\"%s\"\n",
} else {
"%-12s%-20s", link,
"%-10s%4uMb ",
}
} else {
if (state->ls_parseable) {
"LINK=\"%s\" DEVICE=\"%s\" MEDIA=\"%s\" "
} else {
"%-12s%-12s%-20s%c----\n", link,
}
}
done:
return (status);
}
static int
{
char buf[MAXLINELEN];
if (status != DLADM_STATUS_OK)
goto done;
done:
return (DLADM_WALK_CONTINUE);
}
static void
{
if (state->ls_donefirst)
return;
if (state->ls_parseable)
return;
}
/*
* Print the active topology information.
*/
static dladm_status_t
{
char link[MAXLINKNAMELEN];
char over[MAXLINKNAMELEN];
char *fmt;
sizeof (link))) != DLADM_STATUS_OK) {
goto done;
}
goto done;
}
goto done;
}
if (state->ls_parseable)
fmt = "LINK=\"%s\" VID=\"%d\" OVER=\"%s\" FLAGS=\"%c%c---\"\n";
else
fmt = "%-12s%5d %-12s%c%c---\n";
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
done:
return (status);
}
static int
{
char buf[MAXLINELEN];
if (status != DLADM_STATUS_OK)
goto done;
done:
return (DLADM_WALK_CONTINUE);
}
static void
{
int option;
opterr = 0;
switch (option) {
case 'p':
if (p_arg)
break;
case 'P':
if (flags != DLADM_OPT_ACTIVE)
break;
default:
break;
}
}
/* get link name (optional last argument) */
}
usage();
}
if (linkid == DATALINK_ALL_LINKID) {
} else {
}
}
}
static void
{
int option;
opterr = 0;
switch (option) {
case 'p':
if (p_arg)
break;
case 'P':
if (flags != DLADM_OPT_ACTIVE)
break;
default:
break;
}
}
/* get link name (optional last argument) */
}
usage();
}
if (linkid == DATALINK_ALL_LINKID) {
} else {
}
}
}
static void
{
/*
* If an interval is specified, continuously show the stats
* only for the first MAC port.
*/
for (;;) {
(void) printf("%-12s%-10s%-12s%-8s%-10s%-12s%-8s\n",
"LINK", "IPACKETS", "RBYTES", "IERRORS", "OPACKETS",
"OBYTES", "OERRORS");
if (linkid == DATALINK_ALL_LINKID) {
} else {
}
if (interval == 0)
break;
}
}
static void
{
/*
* If an interval is specified, continuously show the stats
* only for the first group.
*/
for (;;) {
(void) printf("%-12s%-10s%8s %8s %8s %8s %-9s%s\n",
"LINK", "PORT", "IPACKETS", "RBYTES", "OPACKETS",
"OBYTES", "IPKTDIST", "OPKTDIST");
if (linkid == DATALINK_ALL_LINKID)
else
if (interval == 0)
break;
}
}
static void
{
/*
* If an interval is specified, continuously show the stats
* only for the first MAC port.
*/
for (;;) {
(void) printf("%-12s%-10s%-12s%-8s%-10s%-12s%-8s\n",
"DEV", "IPACKETS", "RBYTES", "IERRORS", "OPACKETS",
"OBYTES", "OERRORS");
else
if (interval == 0)
break;
}
}
/* accumulate stats (s1 += (s2 - s3)) */
static void
{
}
/* compute stats differences (s1 = s2 - s3) */
static void
{
}
static void
{
warn("kstat open operation failed");
return;
}
/*
* The kstat query could fail if the underlying MAC
* driver was already detached.
*/
(void) kstat_close(kcp);
return;
}
goto bail;
goto bail;
goto bail;
goto bail;
goto bail;
goto bail;
goto bail;
bail:
(void) kstat_close(kcp);
return;
}
static void
{
char module[DLPI_LINKNAME_MAX];
return;
}
static void
{
}
static int
{
warn("kstat open operation failed");
return (-1);
}
/*
* The kstat query could fail if the underlying MAC
* driver was already detached.
*/
goto bail;
}
warn("kstat read failed");
goto bail;
}
goto bail;
(void) kstat_close(kcp);
return (0);
bail:
(void) kstat_close(kcp);
return (-1);
}
static int
{
char module[DLPI_LINKNAME_MAX];
if (islink) {
} else {
return (-1);
}
}
static uint64_t
{
return (ifspeed);
}
static const char *
{
return (buf);
}
}
static const char *
{
&linkduplex, islink) != 0) {
return (buf);
}
}
#define WIFI_CMD_SCAN 0x00000001
#define WIFI_CMD_SHOW 0x00000002
typedef struct wifi_field {
const char *wf_name;
const char *wf_header;
} wifi_field_t;
static wifi_field_t wifi_fields[] = {
;
static char *all_scan_wifi_fields =
"link,essid,bssid,sec,strength,mode,speed,bsstype";
static char *all_show_wifi_fields =
"link,status,essid,sec,strength,mode,speed,auth,bssid,bsstype";
static char *def_scan_wifi_fields =
"link,essid,bssid,sec,strength,mode,speed";
static char *def_show_wifi_fields =
"link,status,essid,sec,strength,mode,speed";
#define WIFI_MAX_FIELD_LEN 32
typedef struct {
char *s_buf;
char **s_fields; /* array of pointer to the fields in s_buf */
} split_t;
/*
* Free the split_t structure pointed to by `sp'.
*/
static void
{
}
/*
* Split `str' into at most `maxfields' fields, each field at most `maxlen' in
* length. Return a pointer to a split_t containing the split fields, or NULL
* on failure.
*/
static split_t *
{
return (NULL);
return (NULL);
goto fail;
goto fail;
}
return (sp);
fail:
return (NULL);
}
static int
{
uint_t i, j;
if (cmdtype == WIFI_CMD_SCAN) {
} else if (cmdtype == WIFI_CMD_SHOW) {
} else {
return (-1);
}
return (-1);
goto fail;
for (j = 0; j < WIFI_MAX_FIELDS; j++) {
wifi_fields[j].wf_name) == 0) {
good_match = wifi_fields[j].
break;
}
}
if (!good_match)
goto fail;
wf[i] = &wifi_fields[j];
}
*countp = i;
return (0);
fail:
return (-1);
}
typedef struct print_wifi_state {
char *ws_link;
static void
{
int i;
for (i = 0; i < statep->ws_nfields; i++) {
else
}
(void) printf("\n");
}
static void
const char *value)
{
if (statep->ws_parseable) {
} else {
if (value[0] == '\0')
value = "--";
if (statep->ws_lastfield) {
return;
}
}
}
if (!statep->ws_lastfield)
(void) putchar(' ');
}
static void
{
char buf[DLADM_STRSIZE];
const char *str = "";
return;
}
return;
}
case DLADM_WLAN_ATTR_ESSID:
break;
case DLADM_WLAN_ATTR_BSSID:
break;
case DLADM_WLAN_ATTR_SECMODE:
break;
case DLADM_WLAN_ATTR_STRENGTH:
break;
case DLADM_WLAN_ATTR_MODE:
break;
case DLADM_WLAN_ATTR_SPEED:
break;
case DLADM_WLAN_ATTR_AUTH:
break;
case DLADM_WLAN_ATTR_BSSTYPE:
break;
}
}
static boolean_t
{
int i;
if (!statep->ws_parseable)
}
statep->ws_overflow = 0;
for (i = 0; i < statep->ws_nfields; i++) {
}
(void) putchar('\n');
return (B_TRUE);
}
static int
{
char link[MAXLINKNAMELEN];
sizeof (link)) != DLADM_STATUS_OK) {
return (DLADM_WALK_CONTINUE);
}
if (status != DLADM_STATUS_OK)
return (DLADM_WALK_CONTINUE);
}
static void
{
char buf[DLADM_STRSIZE];
const char *str = "";
return;
}
}
static int
{
int i;
char link[MAXLINKNAMELEN];
sizeof (link)) != DLADM_STATUS_OK) {
return (DLADM_WALK_CONTINUE);
}
if (status != DLADM_STATUS_OK)
if (!statep->ws_parseable)
}
statep->ws_overflow = 0;
for (i = 0; i < statep->ws_nfields; i++) {
}
(void) putchar('\n');
return (DLADM_WALK_CONTINUE);
}
static void
{
int option;
char *fields_str = NULL;
int (*callback)(datalink_id_t, void *);
if (cmd == WIFI_CMD_SCAN)
else if (cmd == WIFI_CMD_SHOW)
else
return;
opterr = 0;
switch (option) {
case 'o':
fields_str = optarg;
break;
case 'p':
if (fields_str == NULL)
fields_str = "all";
break;
default:
break;
}
}
}
usage();
}
die("invalid field(s) specified");
if (linkid == DATALINK_ALL_LINKID) {
} else {
}
}
static void
{
}
static void
{
}
typedef struct wlan_count_attr {
static int
{
return (DLADM_WALK_CONTINUE);
}
static int
{
uint_t i;
return (-1);
goto fail;
char *s;
goto fail;
*s = '\0';
}
if (status != DLADM_STATUS_OK) {
if (status == DLADM_STATUS_NOTFOUND) {
}
if (status != DLADM_STATUS_OK)
goto fail;
}
}
*key_countp = i;
return (0);
fail:
return (-1);
}
static void
{
int option;
char buf[DLADM_STRSIZE];
opterr = 0;
switch (option) {
case 'e':
if (status != DLADM_STATUS_OK)
/*
* Try to connect without doing a scan.
*/
break;
case 'i':
if (status != DLADM_STATUS_OK)
break;
case 'a':
if (status != DLADM_STATUS_OK)
break;
case 'm':
if (status != DLADM_STATUS_OK)
break;
case 'b':
}
break;
case 's':
}
break;
case 'k':
else
break;
case 'T':
timeout = -1;
break;
}
break;
case 'c':
break;
default:
break;
}
}
if (keysecmode == DLADM_WLAN_SECMODE_NONE) {
die("key required for security mode '%s'",
}
} else {
die("incompatible -s and -k options");
}
}
usage();
}
if (linkid == DATALINK_ALL_LINKID) {
die("no wifi links are available");
die("link name is required when more than one wifi "
"link is available");
}
}
if ((flags & DLADM_WLAN_CONNECT_NOSCAN) != 0) {
/*
* Try again with scanning and filtering.
*/
goto again;
}
if (status == DLADM_STATUS_NOTFOUND) {
die("no wifi networks are available");
} else {
die("no wifi networks with the specified "
"criteria are available");
}
}
}
}
/* ARGSUSED */
static int
{
if (status != DLADM_STATUS_OK)
return (DLADM_WALK_CONTINUE);
}
static void
{
int option;
opterr = 0;
switch (option) {
case 'a':
break;
default:
break;
}
}
}
usage();
}
if (linkid == DATALINK_ALL_LINKID) {
if (!all_links) {
die("no wifi links are available");
die("link name is required when more than "
"one wifi link is available");
}
} else {
return;
}
}
if (status != DLADM_STATUS_OK)
}
#define MAX_PROPS 32
#define MAX_PROP_LINE 512
typedef struct prop_info {
char *pi_name;
char *pi_val[DLADM_MAX_PROP_VALCNT];
} prop_info_t;
typedef struct prop_list {
char *pl_buf;
} prop_list_t;
typedef struct show_linkprop_state {
char ls_link[MAXLINKNAMELEN];
char *ls_line;
char **ls_propvals;
ls_persist : 1,
ls_header : 1,
ls_pad_bits : 29;
static void
{
}
}
static int
{
int len, i;
return (-1);
goto fail;
for (i = 0; i < len; i++) {
char c = buf[i];
continue;
if (match) {
buf[i] = '\0';
if (*curr == '\0')
goto fail;
}
goto fail;
if (novalues)
goto fail;
} else {
goto fail;
if (c == ',')
}
}
return (0);
fail:
return (-1);
}
static void
print_linkprop_head(void)
{
(void) printf("%-12s %-15s %-14s %-14s %-20s \n",
"LINK", "PROPERTY", "VALUE", "DEFAULT", "POSSIBLE");
}
static void
{
int i;
char buf[DLADM_STRSIZE];
if (status != DLADM_STATUS_OK) {
if (status == DLADM_STATUS_TEMPONLY) {
if (type == DLADM_PROP_VAL_MODIFIABLE &&
statep->ls_persist) {
valcnt = 1;
} else {
return;
}
} else if (status == DLADM_STATUS_NOTSUP ||
statep->ls_persist) {
valcnt = 1;
if (type == DLADM_PROP_VAL_CURRENT)
else
} else {
if (statep->ls_proplist) {
"cannot get link property '%s' for %s",
}
return;
}
}
for (i = 0; i < valcnt; i++) {
else
break;
}
if (valcnt > 0)
if (statep->ls_parseable) {
} else {
}
}
static int
{
if (statep->ls_parseable)
else
if (statep->ls_parseable)
else
/*
* If we failed to query the link property, for example, query
* the persistent value of a non-persistable link property, simply
* skip the output.
*/
return (DLADM_WALK_CONTINUE);
return (DLADM_WALK_CONTINUE);
return (DLADM_WALK_CONTINUE);
if (!statep->ls_parseable)
}
return (DLADM_WALK_CONTINUE);
}
static void
{
int option;
opterr = 0;
switch (option) {
case 'p':
die("invalid link properties specified");
break;
case 'c':
break;
case 'P':
break;
default:
break;
}
}
}
usage();
}
if (linkid == DATALINK_ALL_LINKID) {
} else {
}
}
}
}
static int
{
int i;
char *buf;
MAXLINKNAMELEN) != DLADM_STATUS_OK) {
return (DLADM_WALK_CONTINUE);
}
return (DLADM_WALK_CONTINUE);
}
/*
* When some WiFi links are opened for the first time, their hardware
* automatically scans for APs and does other slow operations. Thus,
* if there are no open links, the retrieval of link properties
* (below) will proceed slowly unless we hold the link open.
*
* Note that failure of dlpi_open() does not necessarily mean invalid
* link properties, because dlpi_open() may fail because of incorrect
* autopush configuration. Therefore, we ingore the return value of
* dlpi_open().
*/
if (!statep->ls_persist)
die("insufficient memory");
for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) {
sizeof (char *) * DLADM_MAX_PROP_VALCNT +
i * DLADM_PROP_VAL_MAX;
}
(sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT;
(void) show_linkprop(linkid,
}
} else {
}
dlpi_close(dh);
return (DLADM_WALK_CONTINUE);
}
static dladm_status_t
{
if (status != DLADM_STATUS_OK) {
}
return (status);
}
static void
{
int i, option;
char errmsg[DLADM_STRSIZE];
opterr = 0;
switch (option) {
case 'p':
die("invalid link properties specified");
break;
case 't':
break;
case 'R':
break;
default:
break;
}
}
/* get link name (required last argument) */
usage();
die("link property must be specified");
}
if (status != DLADM_STATUS_OK)
DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK) {
}
if (!temp) {
if (s != DLADM_STATUS_OK)
status = s;
}
goto done;
}
char **val;
if (reset) {
count = 0;
} else {
if (count == 0) {
warn("no value specified for '%s'",
continue;
}
}
if (s == DLADM_STATUS_OK) {
if (!temp) {
if (s != DLADM_STATUS_OK)
status = s;
}
continue;
}
status = s;
switch (s) {
case DLADM_STATUS_NOTFOUND:
break;
case DLADM_STATUS_BADVAL: {
int j;
die("insufficient memory");
for (j = 0; j < DLADM_MAX_PROP_VALCNT; j++) {
j * DLADM_PROP_VAL_MAX;
}
s = dladm_get_linkprop(linkid,
&valcnt);
if (s != DLADM_STATUS_OK) {
break;
}
*ptr = '\0';
for (j = 0; j < valcnt; j++) {
propvals[j]);
break;
}
warn("link property '%s' must be one of: %s",
} else
break;
}
default:
if (reset) {
} else {
}
break;
}
}
done:
if (status != DLADM_STATUS_OK)
exit(1);
}
static void
{
}
static void
{
}
static int
{
int error = 0;
if (class == DLADM_SECOBJ_CLASS_WPA) {
return (EINVAL);
return (error);
}
if (class == DLADM_SECOBJ_CLASS_WEP) {
switch (len) {
case 5: /* ASCII key sizes */
case 13:
break;
case 10: /* Hex key sizes, not preceded by 0x */
case 26:
break;
case 12: /* Hex key sizes, preceded by 0x */
case 28:
return (EINVAL);
break;
default:
return (EINVAL);
}
return (error);
}
return (ENOENT);
}
/* ARGSUSED */
static void
{
}
static int
{
int c;
void (*sigfunc)(int);
/*
* Turn off echo -- but before we do so, defer SIGINT handling
* so that a ^C doesn't leave the terminal corrupted.
*/
if (try == 1)
else
while (signalled == 0) {
c = getchar();
if (c == '\n' || c == '\r') {
if (len != 0)
break;
(void) putchar('\n');
goto again;
}
break;
(void) putchar('*');
}
(void) putchar('\n');
/*
* Restore terminal setting and handle deferred signals.
*/
if (signalled != 0)
return (len);
}
static int
{
int rval;
if (rval == 0) {
}
return (rval);
} else {
for (;;) {
break;
continue;
len--;
}
break;
}
}
}
static boolean_t
check_auth(const char *auth)
{
return (B_FALSE);
}
static void
{
char *errstr;
if (create) {
errstr = "ADT_dladm_create_secobj";
} else {
errstr = "ADT_dladm_delete_secobj";
}
/* fill in audit info */
if (create) {
} else {
}
if (success) {
}
} else {
ADT_FAIL_VALUE_AUTH) != 0) {
}
}
(void) adt_end_session(ah);
}
#define MAX_SECOBJS 32
#define MAX_SECOBJ_NAMELEN 32
static void
{
char *class_name = NULL;
opterr = 0;
switch (option) {
case 'f':
}
break;
case 'c':
class_name = optarg;
if (status != DLADM_STATUS_OK) {
die("invalid secure object class '%s', "
"valid values are: wep, wpa", optarg);
}
break;
case 't':
break;
case 'R':
if (status != DLADM_STATUS_OK) {
"specified");
}
break;
default:
break;
}
}
usage();
if (class == -1)
die("secure object class required");
die("secure object name required");
if (!success)
if (rval != 0) {
switch (rval) {
case ENOENT:
die("invalid secure object class");
break;
case EINVAL:
die("invalid secure object value");
break;
case ENOTSUP:
die("verification failed");
break;
default:
break;
}
}
if (status != DLADM_STATUS_OK) {
obj_name);
}
if (temp)
return;
if (status != DLADM_STATUS_OK) {
"object '%s'", obj_name);
}
}
static void
{
int i, option;
opterr = 0;
switch (option) {
case 't':
break;
case 'R':
if (status != DLADM_STATUS_OK) {
"specified");
}
break;
default:
break;
}
}
die("invalid secure object name(s): '%s'",
}
usage();
die("secure object name required");
if (!success)
if (!temp) {
} else {
}
if (status != DLADM_STATUS_OK) {
}
if (pstatus != DLADM_STATUS_OK) {
}
}
exit(1);
}
typedef struct show_secobj_state {
static void
{
(void) putchar('\n');
}
static boolean_t
{
char buf[DLADM_STRSIZE];
if (statep->ss_persist)
if (status != DLADM_STATUS_OK)
if (!statep->ss_parseable)
}
if (statep->ss_parseable) {
} else {
}
if (statep->ss_parseable)
else
}
}
(void) putchar('\n');
return (B_TRUE);
}
static void
{
int option;
uint_t i;
opterr = 0;
switch (option) {
case 'p':
break;
case 'P':
break;
case 'd':
if (getuid() != 0)
die("insufficient privileges");
break;
default:
break;
}
}
die("invalid secure object name(s): '%s'",
}
break;
}
return;
usage();
if (status != DLADM_STATUS_OK)
}
/*ARGSUSED*/
static int
{
(void) dladm_init_linkprop(linkid);
return (DLADM_WALK_CONTINUE);
}
/* ARGSUSED */
static void
{
/*
* linkprops of links of other classes have been initialized as a
* part of the dladm up-xxx operation.
*/
}
/* ARGSUSED */
static void
{
status = dladm_init_secobj();
if (status != DLADM_STATUS_OK)
}
/*
* "-R" option support. It is used for live upgrading. Append dladm commands
* to a upgrade script which will be run when the alternative root boots up:
*
* - If the dlmgmtd door file exists on the alternative root, append dladm
* commands to the <altroot>/var/svc/profile/upgrade_datalink script. This
*
* - If the dlmgmtd door file does not exist on the alternative root, append
* be run in the manifest-import service.
*
* Note that the SMF team is considering to move the manifest-import service
* to be run at the very begining of boot. Once that is done, the need for
* the /var/svc/profile/upgrade_datalink script will not exist any more.
*/
static void
{
char path[MAXPATHLEN];
int i;
/*
* Check for the existence of the dlmgmtd door file, and determine
* the name of script file.
*/
} else {
}
for (i = 0; i < argc; i++) {
/*
* Directly write to the file if it is not the "-R <altroot>"
* option. In which case, skip it.
*/
else
i ++;
}
exit(0);
}
/*
* Convert the string to an integer. Note that the string must not have any
* trailing non-integer characters.
*/
static boolean_t
{
int val;
errno = 0;
return (B_FALSE);
return (B_TRUE);
}
/* PRINTFLIKE1 */
static void
{
(void) putchar('\n');
}
/* PRINTFLIKE2 */
static void
{
char errmsg[DLADM_STRSIZE];
}
/* PRINTFLIKE2 */
static void
{
char errmsg[DLADM_STRSIZE];
}
/* PRINTFLIKE1 */
static void
{
(void) putchar('\n');
}
static void
die_optdup(int opt)
{
}
static void
{
switch (opterr) {
case ':':
break;
case '?':
default:
break;
}
}