xref: /onnv-gate/usr/src/cmd/dlstat/dlstat.c (revision 11878:ac93462db6d7)
1*11878SVenu.Iyer@Sun.COM /*
2*11878SVenu.Iyer@Sun.COM  * CDDL HEADER START
3*11878SVenu.Iyer@Sun.COM  *
4*11878SVenu.Iyer@Sun.COM  * The contents of this file are subject to the terms of the
5*11878SVenu.Iyer@Sun.COM  * Common Development and Distribution License (the "License").
6*11878SVenu.Iyer@Sun.COM  * You may not use this file except in compliance with the License.
7*11878SVenu.Iyer@Sun.COM  *
8*11878SVenu.Iyer@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*11878SVenu.Iyer@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*11878SVenu.Iyer@Sun.COM  * See the License for the specific language governing permissions
11*11878SVenu.Iyer@Sun.COM  * and limitations under the License.
12*11878SVenu.Iyer@Sun.COM  *
13*11878SVenu.Iyer@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*11878SVenu.Iyer@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*11878SVenu.Iyer@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*11878SVenu.Iyer@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*11878SVenu.Iyer@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*11878SVenu.Iyer@Sun.COM  *
19*11878SVenu.Iyer@Sun.COM  * CDDL HEADER END
20*11878SVenu.Iyer@Sun.COM  */
21*11878SVenu.Iyer@Sun.COM /*
22*11878SVenu.Iyer@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23*11878SVenu.Iyer@Sun.COM  * Use is subject to license terms.
24*11878SVenu.Iyer@Sun.COM  */
25*11878SVenu.Iyer@Sun.COM 
26*11878SVenu.Iyer@Sun.COM #include <stdio.h>
27*11878SVenu.Iyer@Sun.COM #include <ctype.h>
28*11878SVenu.Iyer@Sun.COM #include <locale.h>
29*11878SVenu.Iyer@Sun.COM #include <signal.h>
30*11878SVenu.Iyer@Sun.COM #include <stdarg.h>
31*11878SVenu.Iyer@Sun.COM #include <stdlib.h>
32*11878SVenu.Iyer@Sun.COM #include <fcntl.h>
33*11878SVenu.Iyer@Sun.COM #include <string.h>
34*11878SVenu.Iyer@Sun.COM #include <stropts.h>
35*11878SVenu.Iyer@Sun.COM #include <sys/stat.h>
36*11878SVenu.Iyer@Sun.COM #include <errno.h>
37*11878SVenu.Iyer@Sun.COM #include <strings.h>
38*11878SVenu.Iyer@Sun.COM #include <getopt.h>
39*11878SVenu.Iyer@Sun.COM #include <unistd.h>
40*11878SVenu.Iyer@Sun.COM #include <priv.h>
41*11878SVenu.Iyer@Sun.COM #include <termios.h>
42*11878SVenu.Iyer@Sun.COM #include <pwd.h>
43*11878SVenu.Iyer@Sun.COM #include <auth_attr.h>
44*11878SVenu.Iyer@Sun.COM #include <auth_list.h>
45*11878SVenu.Iyer@Sun.COM #include <libintl.h>
46*11878SVenu.Iyer@Sun.COM #include <libdevinfo.h>
47*11878SVenu.Iyer@Sun.COM #include <libdlpi.h>
48*11878SVenu.Iyer@Sun.COM #include <libdladm.h>
49*11878SVenu.Iyer@Sun.COM #include <libdllink.h>
50*11878SVenu.Iyer@Sun.COM #include <libdlstat.h>
51*11878SVenu.Iyer@Sun.COM #include <libdlaggr.h>
52*11878SVenu.Iyer@Sun.COM #include <libinetutil.h>
53*11878SVenu.Iyer@Sun.COM #include <bsm/adt.h>
54*11878SVenu.Iyer@Sun.COM #include <bsm/adt_event.h>
55*11878SVenu.Iyer@Sun.COM #include <stddef.h>
56*11878SVenu.Iyer@Sun.COM #include <ofmt.h>
57*11878SVenu.Iyer@Sun.COM 
58*11878SVenu.Iyer@Sun.COM typedef struct link_chain_s {
59*11878SVenu.Iyer@Sun.COM 	datalink_id_t		lc_linkid;
60*11878SVenu.Iyer@Sun.COM 	boolean_t		lc_visited;
61*11878SVenu.Iyer@Sun.COM 	dladm_stat_chain_t	*lc_statchain[DLADM_STAT_NUM_STATS];
62*11878SVenu.Iyer@Sun.COM 	struct link_chain_s	*lc_next;
63*11878SVenu.Iyer@Sun.COM } link_chain_t;
64*11878SVenu.Iyer@Sun.COM 
65*11878SVenu.Iyer@Sun.COM typedef void *	(*stats2str_t)(const char *, void *,
66*11878SVenu.Iyer@Sun.COM 		    char, boolean_t);
67*11878SVenu.Iyer@Sun.COM 
68*11878SVenu.Iyer@Sun.COM typedef struct show_state {
69*11878SVenu.Iyer@Sun.COM 	link_chain_t	*ls_linkchain;
70*11878SVenu.Iyer@Sun.COM 	boolean_t	ls_stattype[DLADM_STAT_NUM_STATS];
71*11878SVenu.Iyer@Sun.COM 	stats2str_t	ls_stats2str[DLADM_STAT_NUM_STATS];
72*11878SVenu.Iyer@Sun.COM 	ofmt_handle_t	ls_ofmt;
73*11878SVenu.Iyer@Sun.COM 	char		ls_unit;
74*11878SVenu.Iyer@Sun.COM 	boolean_t	ls_parsable;
75*11878SVenu.Iyer@Sun.COM } show_state_t;
76*11878SVenu.Iyer@Sun.COM 
77*11878SVenu.Iyer@Sun.COM typedef struct show_history_state_s {
78*11878SVenu.Iyer@Sun.COM 	boolean_t	hs_plot;
79*11878SVenu.Iyer@Sun.COM 	boolean_t	hs_parsable;
80*11878SVenu.Iyer@Sun.COM 	boolean_t	hs_printheader;
81*11878SVenu.Iyer@Sun.COM 	boolean_t	hs_first;
82*11878SVenu.Iyer@Sun.COM 	boolean_t	hs_showall;
83*11878SVenu.Iyer@Sun.COM 	ofmt_handle_t	hs_ofmt;
84*11878SVenu.Iyer@Sun.COM } show_history_state_t;
85*11878SVenu.Iyer@Sun.COM 
86*11878SVenu.Iyer@Sun.COM /*
87*11878SVenu.Iyer@Sun.COM  * callback functions for printing output and error diagnostics.
88*11878SVenu.Iyer@Sun.COM  */
89*11878SVenu.Iyer@Sun.COM static ofmt_cb_t print_default_cb;
90*11878SVenu.Iyer@Sun.COM 
91*11878SVenu.Iyer@Sun.COM static void dlstat_ofmt_check(ofmt_status_t, boolean_t, ofmt_handle_t);
92*11878SVenu.Iyer@Sun.COM 
93*11878SVenu.Iyer@Sun.COM typedef void cmdfunc_t(int, char **, const char *);
94*11878SVenu.Iyer@Sun.COM 
95*11878SVenu.Iyer@Sun.COM static cmdfunc_t do_show, do_show_history, do_show_phys, do_show_link;
96*11878SVenu.Iyer@Sun.COM static cmdfunc_t do_show_aggr;
97*11878SVenu.Iyer@Sun.COM 
98*11878SVenu.Iyer@Sun.COM static void	die(const char *, ...);
99*11878SVenu.Iyer@Sun.COM static void	die_optdup(int);
100*11878SVenu.Iyer@Sun.COM static void	die_opterr(int, int, const char *);
101*11878SVenu.Iyer@Sun.COM static void	die_dlerr(dladm_status_t, const char *, ...);
102*11878SVenu.Iyer@Sun.COM static void	warn(const char *, ...);
103*11878SVenu.Iyer@Sun.COM 
104*11878SVenu.Iyer@Sun.COM typedef struct	cmd {
105*11878SVenu.Iyer@Sun.COM 	char		*c_name;
106*11878SVenu.Iyer@Sun.COM 	cmdfunc_t	*c_fn;
107*11878SVenu.Iyer@Sun.COM 	const char	*c_usage;
108*11878SVenu.Iyer@Sun.COM } cmd_t;
109*11878SVenu.Iyer@Sun.COM 
110*11878SVenu.Iyer@Sun.COM static cmd_t	cmds[] = {
111*11878SVenu.Iyer@Sun.COM 	{ "",		do_show,
112*11878SVenu.Iyer@Sun.COM 	    "dlstat [-r | -t] [-i <interval>] [link]\n"
113*11878SVenu.Iyer@Sun.COM 	    "       dlstat [-a | -A] [-i <interval>] [-p] [ -o field[,...]]\n"
114*11878SVenu.Iyer@Sun.COM 	    "              [-u R|K|M|G|T|P] [link]"},
115*11878SVenu.Iyer@Sun.COM 	{ "show-phys", do_show_phys,
116*11878SVenu.Iyer@Sun.COM 	    "dlstat show-phys [-r | -t] [-i interval] [-a]\n"
117*11878SVenu.Iyer@Sun.COM 	    "                 [-p] [ -o field[,...]] [-u R|K|M|G|T|P] "
118*11878SVenu.Iyer@Sun.COM 	    "[link]"},
119*11878SVenu.Iyer@Sun.COM 	{ "show-link", do_show_link,
120*11878SVenu.Iyer@Sun.COM 	    "dlstat show-link [-r [-F] | -t] [-i interval] [-a]\n"
121*11878SVenu.Iyer@Sun.COM 	    "                 [-p] [ -o field[,...]] [-u R|K|M|G|T|P] "
122*11878SVenu.Iyer@Sun.COM 	    "[link]\n"
123*11878SVenu.Iyer@Sun.COM 	    "       dlstat show-link -h [-a] [-d] [-F <format>]\n"
124*11878SVenu.Iyer@Sun.COM 	    "                 [-s <DD/MM/YYYY,HH:MM:SS>] "
125*11878SVenu.Iyer@Sun.COM 	    "[-e <DD/MM/YYYY,HH:MM:SS>]\n"
126*11878SVenu.Iyer@Sun.COM 	    "                 -f <logfile> [<link>]" },
127*11878SVenu.Iyer@Sun.COM 	{ "show-aggr", do_show_aggr,
128*11878SVenu.Iyer@Sun.COM 	    "dlstat show-aggr [-r | -t] [-i interval] [-p]\n"
129*11878SVenu.Iyer@Sun.COM 	    "                 [ -o field[,...]] [-u R|K|M|G|T|P] "
130*11878SVenu.Iyer@Sun.COM 	    " [link]" }
131*11878SVenu.Iyer@Sun.COM };
132*11878SVenu.Iyer@Sun.COM 
133*11878SVenu.Iyer@Sun.COM #define	MAXSTATLEN 15
134*11878SVenu.Iyer@Sun.COM 
135*11878SVenu.Iyer@Sun.COM /*
136*11878SVenu.Iyer@Sun.COM  * dlstat : total stat fields
137*11878SVenu.Iyer@Sun.COM  */
138*11878SVenu.Iyer@Sun.COM typedef struct total_fields_buf_s {
139*11878SVenu.Iyer@Sun.COM 	char t_linkname[MAXLINKNAMELEN];
140*11878SVenu.Iyer@Sun.COM 	char t_ipackets[MAXSTATLEN];
141*11878SVenu.Iyer@Sun.COM 	char t_rbytes[MAXSTATLEN];
142*11878SVenu.Iyer@Sun.COM 	char t_opackets[MAXSTATLEN];
143*11878SVenu.Iyer@Sun.COM 	char t_obytes[MAXSTATLEN];
144*11878SVenu.Iyer@Sun.COM } total_fields_buf_t;
145*11878SVenu.Iyer@Sun.COM 
146*11878SVenu.Iyer@Sun.COM static ofmt_field_t total_s_fields[] = {
147*11878SVenu.Iyer@Sun.COM { "LINK",	15,
148*11878SVenu.Iyer@Sun.COM     offsetof(total_fields_buf_t, t_linkname),	print_default_cb},
149*11878SVenu.Iyer@Sun.COM { "IPKTS",	8,
150*11878SVenu.Iyer@Sun.COM     offsetof(total_fields_buf_t, t_ipackets),	print_default_cb},
151*11878SVenu.Iyer@Sun.COM { "RBYTES",	8,
152*11878SVenu.Iyer@Sun.COM     offsetof(total_fields_buf_t, t_rbytes),	print_default_cb},
153*11878SVenu.Iyer@Sun.COM { "OPKTS",	8,
154*11878SVenu.Iyer@Sun.COM     offsetof(total_fields_buf_t, t_opackets),	print_default_cb},
155*11878SVenu.Iyer@Sun.COM { "OBYTES",	8,
156*11878SVenu.Iyer@Sun.COM     offsetof(total_fields_buf_t, t_obytes),	print_default_cb},
157*11878SVenu.Iyer@Sun.COM { NULL,		0,	0,		NULL}};
158*11878SVenu.Iyer@Sun.COM 
159*11878SVenu.Iyer@Sun.COM /*
160*11878SVenu.Iyer@Sun.COM  * dlstat show-phys: both Rx and Tx stat fields
161*11878SVenu.Iyer@Sun.COM  */
162*11878SVenu.Iyer@Sun.COM typedef struct ring_fields_buf_s {
163*11878SVenu.Iyer@Sun.COM 	char r_linkname[MAXLINKNAMELEN];
164*11878SVenu.Iyer@Sun.COM 	char r_type[MAXSTATLEN];
165*11878SVenu.Iyer@Sun.COM 	char r_id[MAXSTATLEN];
166*11878SVenu.Iyer@Sun.COM 	char r_index[MAXSTATLEN];
167*11878SVenu.Iyer@Sun.COM 	char r_packets[MAXSTATLEN];
168*11878SVenu.Iyer@Sun.COM 	char r_bytes[MAXSTATLEN];
169*11878SVenu.Iyer@Sun.COM } ring_fields_buf_t;
170*11878SVenu.Iyer@Sun.COM 
171*11878SVenu.Iyer@Sun.COM static ofmt_field_t ring_s_fields[] = {
172*11878SVenu.Iyer@Sun.COM { "LINK",	15,
173*11878SVenu.Iyer@Sun.COM     offsetof(ring_fields_buf_t, r_linkname),	print_default_cb},
174*11878SVenu.Iyer@Sun.COM { "TYPE",	5,
175*11878SVenu.Iyer@Sun.COM     offsetof(ring_fields_buf_t, r_type),	print_default_cb},
176*11878SVenu.Iyer@Sun.COM { "ID",		7,
177*11878SVenu.Iyer@Sun.COM     offsetof(ring_fields_buf_t, r_id),		print_default_cb},
178*11878SVenu.Iyer@Sun.COM { "INDEX",	6,
179*11878SVenu.Iyer@Sun.COM     offsetof(ring_fields_buf_t, r_index),	print_default_cb},
180*11878SVenu.Iyer@Sun.COM { "PKTS",	8,
181*11878SVenu.Iyer@Sun.COM     offsetof(ring_fields_buf_t, r_packets),	print_default_cb},
182*11878SVenu.Iyer@Sun.COM { "BYTES",	8,
183*11878SVenu.Iyer@Sun.COM     offsetof(ring_fields_buf_t, r_bytes),	print_default_cb},
184*11878SVenu.Iyer@Sun.COM { NULL,		0,		0,		NULL}};
185*11878SVenu.Iyer@Sun.COM 
186*11878SVenu.Iyer@Sun.COM /*
187*11878SVenu.Iyer@Sun.COM  * dlstat show-phys -r: Rx Ring stat fields
188*11878SVenu.Iyer@Sun.COM  */
189*11878SVenu.Iyer@Sun.COM typedef struct rx_ring_fields_buf_s {
190*11878SVenu.Iyer@Sun.COM 	char rr_linkname[MAXLINKNAMELEN];
191*11878SVenu.Iyer@Sun.COM 	char rr_type[MAXSTATLEN];
192*11878SVenu.Iyer@Sun.COM 	char rr_id[MAXSTATLEN];
193*11878SVenu.Iyer@Sun.COM 	char rr_index[MAXSTATLEN];
194*11878SVenu.Iyer@Sun.COM 	char rr_ipackets[MAXSTATLEN];
195*11878SVenu.Iyer@Sun.COM 	char rr_rbytes[MAXSTATLEN];
196*11878SVenu.Iyer@Sun.COM } rx_ring_fields_buf_t;
197*11878SVenu.Iyer@Sun.COM 
198*11878SVenu.Iyer@Sun.COM static ofmt_field_t rx_ring_s_fields[] = {
199*11878SVenu.Iyer@Sun.COM { "LINK",	15,
200*11878SVenu.Iyer@Sun.COM     offsetof(rx_ring_fields_buf_t, rr_linkname),	print_default_cb},
201*11878SVenu.Iyer@Sun.COM { "TYPE",	5,
202*11878SVenu.Iyer@Sun.COM     offsetof(rx_ring_fields_buf_t, rr_type),		print_default_cb},
203*11878SVenu.Iyer@Sun.COM { "ID",		7,
204*11878SVenu.Iyer@Sun.COM     offsetof(rx_ring_fields_buf_t, rr_id),		print_default_cb},
205*11878SVenu.Iyer@Sun.COM { "INDEX",	6,
206*11878SVenu.Iyer@Sun.COM     offsetof(rx_ring_fields_buf_t, rr_index),		print_default_cb},
207*11878SVenu.Iyer@Sun.COM { "IPKTS",	8,
208*11878SVenu.Iyer@Sun.COM     offsetof(rx_ring_fields_buf_t, rr_ipackets),	print_default_cb},
209*11878SVenu.Iyer@Sun.COM { "RBYTES",	8,
210*11878SVenu.Iyer@Sun.COM     offsetof(rx_ring_fields_buf_t, rr_rbytes),		print_default_cb},
211*11878SVenu.Iyer@Sun.COM { NULL,		0,		0,		NULL}};
212*11878SVenu.Iyer@Sun.COM 
213*11878SVenu.Iyer@Sun.COM /*
214*11878SVenu.Iyer@Sun.COM  * dlstat show-phys -t: Tx Ring stat fields
215*11878SVenu.Iyer@Sun.COM  */
216*11878SVenu.Iyer@Sun.COM typedef struct tx_ring_fields_buf_s {
217*11878SVenu.Iyer@Sun.COM 	char tr_linkname[MAXLINKNAMELEN];
218*11878SVenu.Iyer@Sun.COM 	char tr_type[MAXSTATLEN];
219*11878SVenu.Iyer@Sun.COM 	char tr_id[MAXSTATLEN];
220*11878SVenu.Iyer@Sun.COM 	char tr_index[MAXSTATLEN];
221*11878SVenu.Iyer@Sun.COM 	char tr_opackets[MAXSTATLEN];
222*11878SVenu.Iyer@Sun.COM 	char tr_obytes[MAXSTATLEN];
223*11878SVenu.Iyer@Sun.COM } tx_ring_fields_buf_t;
224*11878SVenu.Iyer@Sun.COM 
225*11878SVenu.Iyer@Sun.COM static ofmt_field_t tx_ring_s_fields[] = {
226*11878SVenu.Iyer@Sun.COM { "LINK",	15,
227*11878SVenu.Iyer@Sun.COM     offsetof(tx_ring_fields_buf_t, tr_linkname),	print_default_cb},
228*11878SVenu.Iyer@Sun.COM { "TYPE",	5,
229*11878SVenu.Iyer@Sun.COM     offsetof(tx_ring_fields_buf_t, tr_type),		print_default_cb},
230*11878SVenu.Iyer@Sun.COM { "ID",		7,
231*11878SVenu.Iyer@Sun.COM     offsetof(tx_ring_fields_buf_t, tr_id),		print_default_cb},
232*11878SVenu.Iyer@Sun.COM { "INDEX",	6,
233*11878SVenu.Iyer@Sun.COM     offsetof(tx_ring_fields_buf_t, tr_index),		print_default_cb},
234*11878SVenu.Iyer@Sun.COM { "OPKTS",	8,
235*11878SVenu.Iyer@Sun.COM     offsetof(tx_ring_fields_buf_t, tr_opackets),	print_default_cb},
236*11878SVenu.Iyer@Sun.COM { "OBYTES",	8,
237*11878SVenu.Iyer@Sun.COM     offsetof(tx_ring_fields_buf_t, tr_obytes),		print_default_cb},
238*11878SVenu.Iyer@Sun.COM { NULL,		0,		0,		NULL}};
239*11878SVenu.Iyer@Sun.COM 
240*11878SVenu.Iyer@Sun.COM /*
241*11878SVenu.Iyer@Sun.COM  * dlstat show-link: both Rx and Tx lane fields
242*11878SVenu.Iyer@Sun.COM  */
243*11878SVenu.Iyer@Sun.COM typedef struct lane_fields_buf_s {
244*11878SVenu.Iyer@Sun.COM 	char l_linkname[MAXLINKNAMELEN];
245*11878SVenu.Iyer@Sun.COM 	char l_type[MAXSTATLEN];
246*11878SVenu.Iyer@Sun.COM 	char l_id[MAXSTATLEN];
247*11878SVenu.Iyer@Sun.COM 	char l_index[MAXSTATLEN];
248*11878SVenu.Iyer@Sun.COM 	char l_packets[MAXSTATLEN];
249*11878SVenu.Iyer@Sun.COM 	char l_bytes[MAXSTATLEN];
250*11878SVenu.Iyer@Sun.COM } lane_fields_buf_t;
251*11878SVenu.Iyer@Sun.COM 
252*11878SVenu.Iyer@Sun.COM static ofmt_field_t lane_s_fields[] = {
253*11878SVenu.Iyer@Sun.COM { "LINK",	15,
254*11878SVenu.Iyer@Sun.COM     offsetof(lane_fields_buf_t, l_linkname),	print_default_cb},
255*11878SVenu.Iyer@Sun.COM { "TYPE",	5,
256*11878SVenu.Iyer@Sun.COM     offsetof(lane_fields_buf_t, l_type),	print_default_cb},
257*11878SVenu.Iyer@Sun.COM { "ID",		7,
258*11878SVenu.Iyer@Sun.COM     offsetof(lane_fields_buf_t, l_id),		print_default_cb},
259*11878SVenu.Iyer@Sun.COM { "INDEX",	6,
260*11878SVenu.Iyer@Sun.COM     offsetof(lane_fields_buf_t, l_index),	print_default_cb},
261*11878SVenu.Iyer@Sun.COM { "PKTS",	8,
262*11878SVenu.Iyer@Sun.COM     offsetof(lane_fields_buf_t, l_packets),	print_default_cb},
263*11878SVenu.Iyer@Sun.COM { "BYTES",	8,
264*11878SVenu.Iyer@Sun.COM     offsetof(lane_fields_buf_t, l_bytes),	print_default_cb},
265*11878SVenu.Iyer@Sun.COM { NULL,		0,		0,		NULL}};
266*11878SVenu.Iyer@Sun.COM 
267*11878SVenu.Iyer@Sun.COM /*
268*11878SVenu.Iyer@Sun.COM  * dlstat show-link -r, dlstat -r: Rx Lane stat fields
269*11878SVenu.Iyer@Sun.COM  */
270*11878SVenu.Iyer@Sun.COM typedef struct rx_lane_fields_buf_s {
271*11878SVenu.Iyer@Sun.COM 	char rl_linkname[MAXLINKNAMELEN];
272*11878SVenu.Iyer@Sun.COM 	char rl_type[MAXSTATLEN];
273*11878SVenu.Iyer@Sun.COM 	char rl_id[MAXSTATLEN];
274*11878SVenu.Iyer@Sun.COM 	char rl_index[MAXSTATLEN];
275*11878SVenu.Iyer@Sun.COM 	char rl_ipackets[MAXSTATLEN];
276*11878SVenu.Iyer@Sun.COM 	char rl_rbytes[MAXSTATLEN];
277*11878SVenu.Iyer@Sun.COM 	char rl_intrs[MAXSTATLEN];
278*11878SVenu.Iyer@Sun.COM 	char rl_polls[MAXSTATLEN];
279*11878SVenu.Iyer@Sun.COM 	char rl_sdrops[MAXSTATLEN];
280*11878SVenu.Iyer@Sun.COM 	char rl_chl10[MAXSTATLEN];
281*11878SVenu.Iyer@Sun.COM 	char rl_ch10_50[MAXSTATLEN];
282*11878SVenu.Iyer@Sun.COM 	char rl_chg50[MAXSTATLEN];
283*11878SVenu.Iyer@Sun.COM } rx_lane_fields_buf_t;
284*11878SVenu.Iyer@Sun.COM 
285*11878SVenu.Iyer@Sun.COM static ofmt_field_t rx_lane_s_fields[] = {
286*11878SVenu.Iyer@Sun.COM { "LINK",	10,
287*11878SVenu.Iyer@Sun.COM     offsetof(rx_lane_fields_buf_t, rl_linkname),	print_default_cb},
288*11878SVenu.Iyer@Sun.COM { "TYPE",	5,
289*11878SVenu.Iyer@Sun.COM     offsetof(rx_lane_fields_buf_t, rl_type),		print_default_cb},
290*11878SVenu.Iyer@Sun.COM { "ID",		7,
291*11878SVenu.Iyer@Sun.COM     offsetof(rx_lane_fields_buf_t, rl_id),		print_default_cb},
292*11878SVenu.Iyer@Sun.COM { "INDEX",	6,
293*11878SVenu.Iyer@Sun.COM     offsetof(rx_lane_fields_buf_t, rl_index),		print_default_cb},
294*11878SVenu.Iyer@Sun.COM { "IPKTS",	8,
295*11878SVenu.Iyer@Sun.COM     offsetof(rx_lane_fields_buf_t, rl_ipackets),	print_default_cb},
296*11878SVenu.Iyer@Sun.COM { "RBYTES",	8,
297*11878SVenu.Iyer@Sun.COM     offsetof(rx_lane_fields_buf_t, rl_rbytes),		print_default_cb},
298*11878SVenu.Iyer@Sun.COM { "INTRS",	8,
299*11878SVenu.Iyer@Sun.COM     offsetof(rx_lane_fields_buf_t, rl_intrs),		print_default_cb},
300*11878SVenu.Iyer@Sun.COM { "POLLS",	8,
301*11878SVenu.Iyer@Sun.COM     offsetof(rx_lane_fields_buf_t, rl_polls),		print_default_cb},
302*11878SVenu.Iyer@Sun.COM { "SDROPS",	8,
303*11878SVenu.Iyer@Sun.COM     offsetof(rx_lane_fields_buf_t, rl_sdrops),		print_default_cb},
304*11878SVenu.Iyer@Sun.COM { "CH<10",	8,
305*11878SVenu.Iyer@Sun.COM     offsetof(rx_lane_fields_buf_t, rl_chl10),		print_default_cb},
306*11878SVenu.Iyer@Sun.COM { "CH10-50",	8,
307*11878SVenu.Iyer@Sun.COM     offsetof(rx_lane_fields_buf_t, rl_ch10_50),		print_default_cb},
308*11878SVenu.Iyer@Sun.COM { "CH>50",	8,
309*11878SVenu.Iyer@Sun.COM     offsetof(rx_lane_fields_buf_t, rl_chg50),		print_default_cb},
310*11878SVenu.Iyer@Sun.COM { NULL,		0,		0,		NULL}};
311*11878SVenu.Iyer@Sun.COM 
312*11878SVenu.Iyer@Sun.COM /*
313*11878SVenu.Iyer@Sun.COM  * dlstat show-link -r -F: Rx fanout stat fields
314*11878SVenu.Iyer@Sun.COM  */
315*11878SVenu.Iyer@Sun.COM typedef struct rx_fanout_lane_fields_buf_s {
316*11878SVenu.Iyer@Sun.COM 	char rfl_linkname[MAXLINKNAMELEN];
317*11878SVenu.Iyer@Sun.COM 	char rfl_type[MAXSTATLEN];
318*11878SVenu.Iyer@Sun.COM 	char rfl_id[MAXSTATLEN];
319*11878SVenu.Iyer@Sun.COM 	char rfl_index[MAXSTATLEN];
320*11878SVenu.Iyer@Sun.COM 	char rfl_fout[MAXSTATLEN];
321*11878SVenu.Iyer@Sun.COM 	char rfl_ipackets[MAXSTATLEN];
322*11878SVenu.Iyer@Sun.COM 	char rfl_rbytes[MAXSTATLEN];
323*11878SVenu.Iyer@Sun.COM } rx_fanout_lane_fields_buf_t;
324*11878SVenu.Iyer@Sun.COM 
325*11878SVenu.Iyer@Sun.COM static ofmt_field_t rx_fanout_lane_s_fields[] = {
326*11878SVenu.Iyer@Sun.COM { "LINK",	15,
327*11878SVenu.Iyer@Sun.COM     offsetof(rx_fanout_lane_fields_buf_t, rfl_linkname), print_default_cb},
328*11878SVenu.Iyer@Sun.COM { "TYPE",	5,
329*11878SVenu.Iyer@Sun.COM     offsetof(rx_fanout_lane_fields_buf_t, rfl_type),	print_default_cb},
330*11878SVenu.Iyer@Sun.COM { "ID",		7,
331*11878SVenu.Iyer@Sun.COM     offsetof(rx_fanout_lane_fields_buf_t, rfl_id),	print_default_cb},
332*11878SVenu.Iyer@Sun.COM { "INDEX",	6,
333*11878SVenu.Iyer@Sun.COM     offsetof(rx_fanout_lane_fields_buf_t, rfl_index),	print_default_cb},
334*11878SVenu.Iyer@Sun.COM { "FOUT",	6,
335*11878SVenu.Iyer@Sun.COM     offsetof(rx_fanout_lane_fields_buf_t, rfl_fout),	print_default_cb},
336*11878SVenu.Iyer@Sun.COM { "IPKTS",	8,
337*11878SVenu.Iyer@Sun.COM     offsetof(rx_fanout_lane_fields_buf_t, rfl_ipackets), print_default_cb},
338*11878SVenu.Iyer@Sun.COM { "RBYTES",	8,
339*11878SVenu.Iyer@Sun.COM     offsetof(rx_fanout_lane_fields_buf_t, rfl_rbytes),	print_default_cb},
340*11878SVenu.Iyer@Sun.COM { NULL,		0,		0,		NULL}};
341*11878SVenu.Iyer@Sun.COM 
342*11878SVenu.Iyer@Sun.COM /*
343*11878SVenu.Iyer@Sun.COM  * dlstat show-link -t: Tx Lane stat fields
344*11878SVenu.Iyer@Sun.COM  */
345*11878SVenu.Iyer@Sun.COM typedef struct tx_lane_fields_buf_s {
346*11878SVenu.Iyer@Sun.COM 	char tl_linkname[MAXLINKNAMELEN];
347*11878SVenu.Iyer@Sun.COM 	char tl_index[MAXSTATLEN];
348*11878SVenu.Iyer@Sun.COM 	char tl_type[MAXSTATLEN];
349*11878SVenu.Iyer@Sun.COM 	char tl_id[MAXSTATLEN];
350*11878SVenu.Iyer@Sun.COM 	char tl_opackets[MAXSTATLEN];
351*11878SVenu.Iyer@Sun.COM 	char tl_obytes[MAXSTATLEN];
352*11878SVenu.Iyer@Sun.COM 	char tl_blockcnt[MAXSTATLEN];
353*11878SVenu.Iyer@Sun.COM 	char tl_unblockcnt[MAXSTATLEN];
354*11878SVenu.Iyer@Sun.COM 	char tl_sdrops[MAXSTATLEN];
355*11878SVenu.Iyer@Sun.COM } tx_lane_fields_buf_t;
356*11878SVenu.Iyer@Sun.COM 
357*11878SVenu.Iyer@Sun.COM static ofmt_field_t tx_lane_s_fields[] = {
358*11878SVenu.Iyer@Sun.COM { "LINK",	15,
359*11878SVenu.Iyer@Sun.COM     offsetof(tx_lane_fields_buf_t, tl_linkname),	print_default_cb},
360*11878SVenu.Iyer@Sun.COM { "TYPE",	5,
361*11878SVenu.Iyer@Sun.COM     offsetof(tx_lane_fields_buf_t, tl_type),		print_default_cb},
362*11878SVenu.Iyer@Sun.COM { "ID",		7,
363*11878SVenu.Iyer@Sun.COM     offsetof(tx_lane_fields_buf_t, tl_id),		print_default_cb},
364*11878SVenu.Iyer@Sun.COM { "INDEX",	6,
365*11878SVenu.Iyer@Sun.COM     offsetof(tx_lane_fields_buf_t, tl_index),		print_default_cb},
366*11878SVenu.Iyer@Sun.COM { "OPKTS",	8,
367*11878SVenu.Iyer@Sun.COM     offsetof(tx_lane_fields_buf_t, tl_opackets),	print_default_cb},
368*11878SVenu.Iyer@Sun.COM { "OBYTES",	8,
369*11878SVenu.Iyer@Sun.COM     offsetof(tx_lane_fields_buf_t, tl_obytes),		print_default_cb},
370*11878SVenu.Iyer@Sun.COM { "BLKCNT",	8,
371*11878SVenu.Iyer@Sun.COM     offsetof(tx_lane_fields_buf_t, tl_blockcnt),	print_default_cb},
372*11878SVenu.Iyer@Sun.COM { "UBLKCNT",	8,
373*11878SVenu.Iyer@Sun.COM     offsetof(tx_lane_fields_buf_t, tl_unblockcnt),	print_default_cb},
374*11878SVenu.Iyer@Sun.COM { "SDROPS",	8,
375*11878SVenu.Iyer@Sun.COM     offsetof(tx_lane_fields_buf_t, tl_sdrops),		print_default_cb},
376*11878SVenu.Iyer@Sun.COM { NULL,		0,		0,		NULL}};
377*11878SVenu.Iyer@Sun.COM 
378*11878SVenu.Iyer@Sun.COM /*
379*11878SVenu.Iyer@Sun.COM  * dlstat show-aggr: aggr port stat fields
380*11878SVenu.Iyer@Sun.COM  */
381*11878SVenu.Iyer@Sun.COM typedef struct aggr_port_fields_buf_s {
382*11878SVenu.Iyer@Sun.COM 	char ap_linkname[MAXLINKNAMELEN];
383*11878SVenu.Iyer@Sun.COM 	char ap_portname[MAXLINKNAMELEN];
384*11878SVenu.Iyer@Sun.COM 	char ap_ipackets[MAXSTATLEN];
385*11878SVenu.Iyer@Sun.COM 	char ap_rbytes[MAXSTATLEN];
386*11878SVenu.Iyer@Sun.COM 	char ap_opackets[MAXSTATLEN];
387*11878SVenu.Iyer@Sun.COM 	char ap_obytes[MAXSTATLEN];
388*11878SVenu.Iyer@Sun.COM } aggr_port_fields_buf_t;
389*11878SVenu.Iyer@Sun.COM 
390*11878SVenu.Iyer@Sun.COM static ofmt_field_t aggr_port_s_fields[] = {
391*11878SVenu.Iyer@Sun.COM { "LINK",	15,
392*11878SVenu.Iyer@Sun.COM     offsetof(aggr_port_fields_buf_t, ap_linkname),	print_default_cb},
393*11878SVenu.Iyer@Sun.COM { "PORT",	15,
394*11878SVenu.Iyer@Sun.COM     offsetof(aggr_port_fields_buf_t, ap_portname),	print_default_cb},
395*11878SVenu.Iyer@Sun.COM { "IPKTS",	8,
396*11878SVenu.Iyer@Sun.COM     offsetof(aggr_port_fields_buf_t, ap_ipackets),	print_default_cb},
397*11878SVenu.Iyer@Sun.COM { "RBYTES",	8,
398*11878SVenu.Iyer@Sun.COM     offsetof(aggr_port_fields_buf_t, ap_rbytes),	print_default_cb},
399*11878SVenu.Iyer@Sun.COM { "OPKTS",	8,
400*11878SVenu.Iyer@Sun.COM     offsetof(aggr_port_fields_buf_t, ap_opackets),	print_default_cb},
401*11878SVenu.Iyer@Sun.COM { "OBYTES",	8,
402*11878SVenu.Iyer@Sun.COM     offsetof(aggr_port_fields_buf_t, ap_obytes),	print_default_cb},
403*11878SVenu.Iyer@Sun.COM { NULL,		0,		0,		NULL}};
404*11878SVenu.Iyer@Sun.COM 
405*11878SVenu.Iyer@Sun.COM /*
406*11878SVenu.Iyer@Sun.COM  * structures for 'dlstat show-link -h'
407*11878SVenu.Iyer@Sun.COM  */
408*11878SVenu.Iyer@Sun.COM typedef struct  history_fields_buf_s {
409*11878SVenu.Iyer@Sun.COM 	char	h_link[12];
410*11878SVenu.Iyer@Sun.COM 	char	h_duration[10];
411*11878SVenu.Iyer@Sun.COM 	char	h_ipackets[9];
412*11878SVenu.Iyer@Sun.COM 	char	h_rbytes[10];
413*11878SVenu.Iyer@Sun.COM 	char	h_opackets[9];
414*11878SVenu.Iyer@Sun.COM 	char	h_obytes[10];
415*11878SVenu.Iyer@Sun.COM 	char	h_bandwidth[14];
416*11878SVenu.Iyer@Sun.COM } history_fields_buf_t;
417*11878SVenu.Iyer@Sun.COM 
418*11878SVenu.Iyer@Sun.COM static ofmt_field_t history_fields[] = {
419*11878SVenu.Iyer@Sun.COM { "LINK",	13,
420*11878SVenu.Iyer@Sun.COM 	offsetof(history_fields_buf_t, h_link), print_default_cb},
421*11878SVenu.Iyer@Sun.COM { "DURATION",	11,
422*11878SVenu.Iyer@Sun.COM 	offsetof(history_fields_buf_t, h_duration), print_default_cb},
423*11878SVenu.Iyer@Sun.COM { "IPKTS",	10,
424*11878SVenu.Iyer@Sun.COM 	offsetof(history_fields_buf_t, h_ipackets), print_default_cb},
425*11878SVenu.Iyer@Sun.COM { "RBYTES",	11,
426*11878SVenu.Iyer@Sun.COM 	offsetof(history_fields_buf_t, h_rbytes), print_default_cb},
427*11878SVenu.Iyer@Sun.COM { "OPKTS",	10,
428*11878SVenu.Iyer@Sun.COM 	offsetof(history_fields_buf_t, h_opackets), print_default_cb},
429*11878SVenu.Iyer@Sun.COM { "OBYTES",	11,
430*11878SVenu.Iyer@Sun.COM 	offsetof(history_fields_buf_t, h_obytes), print_default_cb},
431*11878SVenu.Iyer@Sun.COM { "BANDWIDTH",	15,
432*11878SVenu.Iyer@Sun.COM 	offsetof(history_fields_buf_t, h_bandwidth), print_default_cb},
433*11878SVenu.Iyer@Sun.COM { NULL,		0, 0, NULL}};
434*11878SVenu.Iyer@Sun.COM 
435*11878SVenu.Iyer@Sun.COM /*
436*11878SVenu.Iyer@Sun.COM  * structures for 'dlstat show-link -h link'
437*11878SVenu.Iyer@Sun.COM  */
438*11878SVenu.Iyer@Sun.COM typedef struct  history_l_fields_buf_s {
439*11878SVenu.Iyer@Sun.COM 	char	hl_link[12];
440*11878SVenu.Iyer@Sun.COM 	char	hl_stime[13];
441*11878SVenu.Iyer@Sun.COM 	char	hl_etime[13];
442*11878SVenu.Iyer@Sun.COM 	char	hl_rbytes[8];
443*11878SVenu.Iyer@Sun.COM 	char	hl_obytes[8];
444*11878SVenu.Iyer@Sun.COM 	char	hl_bandwidth[14];
445*11878SVenu.Iyer@Sun.COM } history_l_fields_buf_t;
446*11878SVenu.Iyer@Sun.COM 
447*11878SVenu.Iyer@Sun.COM static ofmt_field_t history_l_fields[] = {
448*11878SVenu.Iyer@Sun.COM /* name,	field width,	offset */
449*11878SVenu.Iyer@Sun.COM { "LINK",	13,
450*11878SVenu.Iyer@Sun.COM 	offsetof(history_l_fields_buf_t, hl_link), print_default_cb},
451*11878SVenu.Iyer@Sun.COM { "START",	14,
452*11878SVenu.Iyer@Sun.COM 	offsetof(history_l_fields_buf_t, hl_stime), print_default_cb},
453*11878SVenu.Iyer@Sun.COM { "END",	14,
454*11878SVenu.Iyer@Sun.COM 	offsetof(history_l_fields_buf_t, hl_etime), print_default_cb},
455*11878SVenu.Iyer@Sun.COM { "RBYTES",	9,
456*11878SVenu.Iyer@Sun.COM 	offsetof(history_l_fields_buf_t, hl_rbytes), print_default_cb},
457*11878SVenu.Iyer@Sun.COM { "OBYTES",	9,
458*11878SVenu.Iyer@Sun.COM 	offsetof(history_l_fields_buf_t, hl_obytes), print_default_cb},
459*11878SVenu.Iyer@Sun.COM { "BANDWIDTH",	15,
460*11878SVenu.Iyer@Sun.COM 	offsetof(history_l_fields_buf_t, hl_bandwidth), print_default_cb},
461*11878SVenu.Iyer@Sun.COM { NULL,		0, 0, NULL}}
462*11878SVenu.Iyer@Sun.COM ;
463*11878SVenu.Iyer@Sun.COM 
464*11878SVenu.Iyer@Sun.COM static char *progname;
465*11878SVenu.Iyer@Sun.COM 
466*11878SVenu.Iyer@Sun.COM /*
467*11878SVenu.Iyer@Sun.COM  * Handle to libdladm.  Opened in main() before the sub-command
468*11878SVenu.Iyer@Sun.COM  * specific function is called.
469*11878SVenu.Iyer@Sun.COM  */
470*11878SVenu.Iyer@Sun.COM static dladm_handle_t handle = NULL;
471*11878SVenu.Iyer@Sun.COM 
472*11878SVenu.Iyer@Sun.COM static void
usage(void)473*11878SVenu.Iyer@Sun.COM usage(void)
474*11878SVenu.Iyer@Sun.COM {
475*11878SVenu.Iyer@Sun.COM 	int	i;
476*11878SVenu.Iyer@Sun.COM 	cmd_t	*cmdp;
477*11878SVenu.Iyer@Sun.COM 
478*11878SVenu.Iyer@Sun.COM 	(void) fprintf(stderr, gettext("usage: "));
479*11878SVenu.Iyer@Sun.COM 	for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) {
480*11878SVenu.Iyer@Sun.COM 		cmdp = &cmds[i];
481*11878SVenu.Iyer@Sun.COM 		if (cmdp->c_usage != NULL)
482*11878SVenu.Iyer@Sun.COM 			(void) fprintf(stderr, "%s\n", gettext(cmdp->c_usage));
483*11878SVenu.Iyer@Sun.COM 	}
484*11878SVenu.Iyer@Sun.COM 
485*11878SVenu.Iyer@Sun.COM 	/* close dladm handle if it was opened */
486*11878SVenu.Iyer@Sun.COM 	if (handle != NULL)
487*11878SVenu.Iyer@Sun.COM 		dladm_close(handle);
488*11878SVenu.Iyer@Sun.COM 
489*11878SVenu.Iyer@Sun.COM 	exit(1);
490*11878SVenu.Iyer@Sun.COM }
491*11878SVenu.Iyer@Sun.COM 
492*11878SVenu.Iyer@Sun.COM int
main(int argc,char * argv[])493*11878SVenu.Iyer@Sun.COM main(int argc, char *argv[])
494*11878SVenu.Iyer@Sun.COM {
495*11878SVenu.Iyer@Sun.COM 	int		i;
496*11878SVenu.Iyer@Sun.COM 	cmd_t		*cmdp;
497*11878SVenu.Iyer@Sun.COM 	dladm_status_t	status;
498*11878SVenu.Iyer@Sun.COM 
499*11878SVenu.Iyer@Sun.COM 	(void) setlocale(LC_ALL, "");
500*11878SVenu.Iyer@Sun.COM #if !defined(TEXT_DOMAIN)
501*11878SVenu.Iyer@Sun.COM #define	TEXT_DOMAIN "SYS_TEST"
502*11878SVenu.Iyer@Sun.COM #endif
503*11878SVenu.Iyer@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
504*11878SVenu.Iyer@Sun.COM 
505*11878SVenu.Iyer@Sun.COM 	progname = argv[0];
506*11878SVenu.Iyer@Sun.COM 
507*11878SVenu.Iyer@Sun.COM 	/* Open the libdladm handle */
508*11878SVenu.Iyer@Sun.COM 	if ((status = dladm_open(&handle)) != DLADM_STATUS_OK)
509*11878SVenu.Iyer@Sun.COM 		die_dlerr(status, "could not open /dev/dld");
510*11878SVenu.Iyer@Sun.COM 
511*11878SVenu.Iyer@Sun.COM 	if (argc == 1) {
512*11878SVenu.Iyer@Sun.COM 		do_show(argc - 1, NULL, cmds[0].c_usage);
513*11878SVenu.Iyer@Sun.COM 		goto done;
514*11878SVenu.Iyer@Sun.COM 	}
515*11878SVenu.Iyer@Sun.COM 
516*11878SVenu.Iyer@Sun.COM 	for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) {
517*11878SVenu.Iyer@Sun.COM 		cmdp = &cmds[i];
518*11878SVenu.Iyer@Sun.COM 		if (strcmp(argv[1], cmdp->c_name) == 0) {
519*11878SVenu.Iyer@Sun.COM 			cmdp->c_fn(argc - 1, &argv[1], cmdp->c_usage);
520*11878SVenu.Iyer@Sun.COM 			goto done;
521*11878SVenu.Iyer@Sun.COM 		}
522*11878SVenu.Iyer@Sun.COM 	}
523*11878SVenu.Iyer@Sun.COM 
524*11878SVenu.Iyer@Sun.COM 	do_show(argc, &argv[0], cmds[0].c_usage);
525*11878SVenu.Iyer@Sun.COM 
526*11878SVenu.Iyer@Sun.COM done:
527*11878SVenu.Iyer@Sun.COM 	dladm_close(handle);
528*11878SVenu.Iyer@Sun.COM 	return (0);
529*11878SVenu.Iyer@Sun.COM }
530*11878SVenu.Iyer@Sun.COM 
531*11878SVenu.Iyer@Sun.COM /*ARGSUSED*/
532*11878SVenu.Iyer@Sun.COM static int
show_history_date(dladm_usage_t * history,void * arg)533*11878SVenu.Iyer@Sun.COM show_history_date(dladm_usage_t *history, void *arg)
534*11878SVenu.Iyer@Sun.COM {
535*11878SVenu.Iyer@Sun.COM 	show_history_state_t	*state = arg;
536*11878SVenu.Iyer@Sun.COM 	time_t			stime;
537*11878SVenu.Iyer@Sun.COM 	char			timebuf[20];
538*11878SVenu.Iyer@Sun.COM 	dladm_status_t		status;
539*11878SVenu.Iyer@Sun.COM 	uint32_t		flags;
540*11878SVenu.Iyer@Sun.COM 
541*11878SVenu.Iyer@Sun.COM 	/*
542*11878SVenu.Iyer@Sun.COM 	 * Only show history information for existing links unless '-a'
543*11878SVenu.Iyer@Sun.COM 	 * is specified.
544*11878SVenu.Iyer@Sun.COM 	 */
545*11878SVenu.Iyer@Sun.COM 	if (!state->hs_showall) {
546*11878SVenu.Iyer@Sun.COM 		if ((status = dladm_name2info(handle, history->du_name,
547*11878SVenu.Iyer@Sun.COM 		    NULL, &flags, NULL, NULL)) != DLADM_STATUS_OK) {
548*11878SVenu.Iyer@Sun.COM 			return (status);
549*11878SVenu.Iyer@Sun.COM 		}
550*11878SVenu.Iyer@Sun.COM 		if ((flags & DLADM_OPT_ACTIVE) == 0)
551*11878SVenu.Iyer@Sun.COM 			return (DLADM_STATUS_LINKINVAL);
552*11878SVenu.Iyer@Sun.COM 	}
553*11878SVenu.Iyer@Sun.COM 
554*11878SVenu.Iyer@Sun.COM 	stime = history->du_stime;
555*11878SVenu.Iyer@Sun.COM 	(void) strftime(timebuf, sizeof (timebuf), "%m/%d/%Y",
556*11878SVenu.Iyer@Sun.COM 	    localtime(&stime));
557*11878SVenu.Iyer@Sun.COM 	(void) printf("%s\n", timebuf);
558*11878SVenu.Iyer@Sun.COM 
559*11878SVenu.Iyer@Sun.COM 	return (DLADM_STATUS_OK);
560*11878SVenu.Iyer@Sun.COM }
561*11878SVenu.Iyer@Sun.COM 
562*11878SVenu.Iyer@Sun.COM static int
show_history_time(dladm_usage_t * history,void * arg)563*11878SVenu.Iyer@Sun.COM show_history_time(dladm_usage_t *history, void *arg)
564*11878SVenu.Iyer@Sun.COM {
565*11878SVenu.Iyer@Sun.COM 	show_history_state_t	*state = arg;
566*11878SVenu.Iyer@Sun.COM 	char			buf[DLADM_STRSIZE];
567*11878SVenu.Iyer@Sun.COM 	history_l_fields_buf_t 	ubuf;
568*11878SVenu.Iyer@Sun.COM 	time_t			time;
569*11878SVenu.Iyer@Sun.COM 	double			bw;
570*11878SVenu.Iyer@Sun.COM 	dladm_status_t		status;
571*11878SVenu.Iyer@Sun.COM 	uint32_t		flags;
572*11878SVenu.Iyer@Sun.COM 
573*11878SVenu.Iyer@Sun.COM 	/*
574*11878SVenu.Iyer@Sun.COM 	 * Only show history information for existing links unless '-a'
575*11878SVenu.Iyer@Sun.COM 	 * is specified.
576*11878SVenu.Iyer@Sun.COM 	 */
577*11878SVenu.Iyer@Sun.COM 	if (!state->hs_showall) {
578*11878SVenu.Iyer@Sun.COM 		if ((status = dladm_name2info(handle, history->du_name,
579*11878SVenu.Iyer@Sun.COM 		    NULL, &flags, NULL, NULL)) != DLADM_STATUS_OK) {
580*11878SVenu.Iyer@Sun.COM 			return (status);
581*11878SVenu.Iyer@Sun.COM 		}
582*11878SVenu.Iyer@Sun.COM 		if ((flags & DLADM_OPT_ACTIVE) == 0)
583*11878SVenu.Iyer@Sun.COM 			return (DLADM_STATUS_LINKINVAL);
584*11878SVenu.Iyer@Sun.COM 	}
585*11878SVenu.Iyer@Sun.COM 
586*11878SVenu.Iyer@Sun.COM 	if (state->hs_plot) {
587*11878SVenu.Iyer@Sun.COM 		if (!state->hs_printheader) {
588*11878SVenu.Iyer@Sun.COM 			if (state->hs_first) {
589*11878SVenu.Iyer@Sun.COM 				(void) printf("# Time");
590*11878SVenu.Iyer@Sun.COM 				state->hs_first = B_FALSE;
591*11878SVenu.Iyer@Sun.COM 			}
592*11878SVenu.Iyer@Sun.COM 			(void) printf(" %s", history->du_name);
593*11878SVenu.Iyer@Sun.COM 			if (history->du_last) {
594*11878SVenu.Iyer@Sun.COM 				(void) printf("\n");
595*11878SVenu.Iyer@Sun.COM 				state->hs_first = B_TRUE;
596*11878SVenu.Iyer@Sun.COM 				state->hs_printheader = B_TRUE;
597*11878SVenu.Iyer@Sun.COM 			}
598*11878SVenu.Iyer@Sun.COM 		} else {
599*11878SVenu.Iyer@Sun.COM 			if (state->hs_first) {
600*11878SVenu.Iyer@Sun.COM 				time = history->du_etime;
601*11878SVenu.Iyer@Sun.COM 				(void) strftime(buf, sizeof (buf), "%T",
602*11878SVenu.Iyer@Sun.COM 				    localtime(&time));
603*11878SVenu.Iyer@Sun.COM 				state->hs_first = B_FALSE;
604*11878SVenu.Iyer@Sun.COM 				(void) printf("%s", buf);
605*11878SVenu.Iyer@Sun.COM 			}
606*11878SVenu.Iyer@Sun.COM 			bw = (double)history->du_bandwidth/1000;
607*11878SVenu.Iyer@Sun.COM 			(void) printf(" %.2f", bw);
608*11878SVenu.Iyer@Sun.COM 			if (history->du_last) {
609*11878SVenu.Iyer@Sun.COM 				(void) printf("\n");
610*11878SVenu.Iyer@Sun.COM 				state->hs_first = B_TRUE;
611*11878SVenu.Iyer@Sun.COM 			}
612*11878SVenu.Iyer@Sun.COM 		}
613*11878SVenu.Iyer@Sun.COM 		return (DLADM_STATUS_OK);
614*11878SVenu.Iyer@Sun.COM 	}
615*11878SVenu.Iyer@Sun.COM 
616*11878SVenu.Iyer@Sun.COM 	bzero(&ubuf, sizeof (ubuf));
617*11878SVenu.Iyer@Sun.COM 
618*11878SVenu.Iyer@Sun.COM 	(void) snprintf(ubuf.hl_link, sizeof (ubuf.hl_link), "%s",
619*11878SVenu.Iyer@Sun.COM 	    history->du_name);
620*11878SVenu.Iyer@Sun.COM 	time = history->du_stime;
621*11878SVenu.Iyer@Sun.COM 	(void) strftime(buf, sizeof (buf), "%T", localtime(&time));
622*11878SVenu.Iyer@Sun.COM 	(void) snprintf(ubuf.hl_stime, sizeof (ubuf.hl_stime), "%s",
623*11878SVenu.Iyer@Sun.COM 	    buf);
624*11878SVenu.Iyer@Sun.COM 	time = history->du_etime;
625*11878SVenu.Iyer@Sun.COM 	(void) strftime(buf, sizeof (buf), "%T", localtime(&time));
626*11878SVenu.Iyer@Sun.COM 	(void) snprintf(ubuf.hl_etime, sizeof (ubuf.hl_etime), "%s",
627*11878SVenu.Iyer@Sun.COM 	    buf);
628*11878SVenu.Iyer@Sun.COM 	(void) snprintf(ubuf.hl_rbytes, sizeof (ubuf.hl_rbytes),
629*11878SVenu.Iyer@Sun.COM 	    "%llu", history->du_rbytes);
630*11878SVenu.Iyer@Sun.COM 	(void) snprintf(ubuf.hl_obytes, sizeof (ubuf.hl_obytes),
631*11878SVenu.Iyer@Sun.COM 	    "%llu", history->du_obytes);
632*11878SVenu.Iyer@Sun.COM 	(void) snprintf(ubuf.hl_bandwidth, sizeof (ubuf.hl_bandwidth),
633*11878SVenu.Iyer@Sun.COM 	    "%s Mbps", dladm_bw2str(history->du_bandwidth, buf));
634*11878SVenu.Iyer@Sun.COM 
635*11878SVenu.Iyer@Sun.COM 	ofmt_print(state->hs_ofmt, &ubuf);
636*11878SVenu.Iyer@Sun.COM 	return (DLADM_STATUS_OK);
637*11878SVenu.Iyer@Sun.COM }
638*11878SVenu.Iyer@Sun.COM 
639*11878SVenu.Iyer@Sun.COM static int
show_history_res(dladm_usage_t * history,void * arg)640*11878SVenu.Iyer@Sun.COM show_history_res(dladm_usage_t *history, void *arg)
641*11878SVenu.Iyer@Sun.COM {
642*11878SVenu.Iyer@Sun.COM 	show_history_state_t	*state = arg;
643*11878SVenu.Iyer@Sun.COM 	char			buf[DLADM_STRSIZE];
644*11878SVenu.Iyer@Sun.COM 	history_fields_buf_t	ubuf;
645*11878SVenu.Iyer@Sun.COM 	dladm_status_t		status;
646*11878SVenu.Iyer@Sun.COM 	uint32_t		flags;
647*11878SVenu.Iyer@Sun.COM 
648*11878SVenu.Iyer@Sun.COM 	/*
649*11878SVenu.Iyer@Sun.COM 	 * Only show history information for existing links unless '-a'
650*11878SVenu.Iyer@Sun.COM 	 * is specified.
651*11878SVenu.Iyer@Sun.COM 	 */
652*11878SVenu.Iyer@Sun.COM 	if (!state->hs_showall) {
653*11878SVenu.Iyer@Sun.COM 		if ((status = dladm_name2info(handle, history->du_name,
654*11878SVenu.Iyer@Sun.COM 		    NULL, &flags, NULL, NULL)) != DLADM_STATUS_OK) {
655*11878SVenu.Iyer@Sun.COM 			return (status);
656*11878SVenu.Iyer@Sun.COM 		}
657*11878SVenu.Iyer@Sun.COM 		if ((flags & DLADM_OPT_ACTIVE) == 0)
658*11878SVenu.Iyer@Sun.COM 			return (DLADM_STATUS_LINKINVAL);
659*11878SVenu.Iyer@Sun.COM 	}
660*11878SVenu.Iyer@Sun.COM 
661*11878SVenu.Iyer@Sun.COM 	bzero(&ubuf, sizeof (ubuf));
662*11878SVenu.Iyer@Sun.COM 
663*11878SVenu.Iyer@Sun.COM 	(void) snprintf(ubuf.h_link, sizeof (ubuf.h_link), "%s",
664*11878SVenu.Iyer@Sun.COM 	    history->du_name);
665*11878SVenu.Iyer@Sun.COM 	(void) snprintf(ubuf.h_duration, sizeof (ubuf.h_duration),
666*11878SVenu.Iyer@Sun.COM 	    "%llu", history->du_duration);
667*11878SVenu.Iyer@Sun.COM 	(void) snprintf(ubuf.h_ipackets, sizeof (ubuf.h_ipackets),
668*11878SVenu.Iyer@Sun.COM 	    "%llu", history->du_ipackets);
669*11878SVenu.Iyer@Sun.COM 	(void) snprintf(ubuf.h_rbytes, sizeof (ubuf.h_rbytes),
670*11878SVenu.Iyer@Sun.COM 	    "%llu", history->du_rbytes);
671*11878SVenu.Iyer@Sun.COM 	(void) snprintf(ubuf.h_opackets, sizeof (ubuf.h_opackets),
672*11878SVenu.Iyer@Sun.COM 	    "%llu", history->du_opackets);
673*11878SVenu.Iyer@Sun.COM 	(void) snprintf(ubuf.h_obytes, sizeof (ubuf.h_obytes),
674*11878SVenu.Iyer@Sun.COM 	    "%llu", history->du_obytes);
675*11878SVenu.Iyer@Sun.COM 	(void) snprintf(ubuf.h_bandwidth, sizeof (ubuf.h_bandwidth),
676*11878SVenu.Iyer@Sun.COM 	    "%s Mbps", dladm_bw2str(history->du_bandwidth, buf));
677*11878SVenu.Iyer@Sun.COM 
678*11878SVenu.Iyer@Sun.COM 	ofmt_print(state->hs_ofmt, &ubuf);
679*11878SVenu.Iyer@Sun.COM 
680*11878SVenu.Iyer@Sun.COM 	return (DLADM_STATUS_OK);
681*11878SVenu.Iyer@Sun.COM }
682*11878SVenu.Iyer@Sun.COM 
683*11878SVenu.Iyer@Sun.COM static boolean_t
valid_formatspec(char * formatspec_str)684*11878SVenu.Iyer@Sun.COM valid_formatspec(char *formatspec_str)
685*11878SVenu.Iyer@Sun.COM {
686*11878SVenu.Iyer@Sun.COM 	return (strcmp(formatspec_str, "gnuplot") == 0);
687*11878SVenu.Iyer@Sun.COM }
688*11878SVenu.Iyer@Sun.COM 
689*11878SVenu.Iyer@Sun.COM /*ARGSUSED*/
690*11878SVenu.Iyer@Sun.COM static void
do_show_history(int argc,char * argv[],const char * use)691*11878SVenu.Iyer@Sun.COM do_show_history(int argc, char *argv[], const char *use)
692*11878SVenu.Iyer@Sun.COM {
693*11878SVenu.Iyer@Sun.COM 	char			*file = NULL;
694*11878SVenu.Iyer@Sun.COM 	int			opt;
695*11878SVenu.Iyer@Sun.COM 	dladm_status_t		status;
696*11878SVenu.Iyer@Sun.COM 	boolean_t		d_arg = B_FALSE;
697*11878SVenu.Iyer@Sun.COM 	char			*stime = NULL;
698*11878SVenu.Iyer@Sun.COM 	char			*etime = NULL;
699*11878SVenu.Iyer@Sun.COM 	char			*resource = NULL;
700*11878SVenu.Iyer@Sun.COM 	show_history_state_t	state;
701*11878SVenu.Iyer@Sun.COM 	boolean_t		o_arg = B_FALSE;
702*11878SVenu.Iyer@Sun.COM 	boolean_t		F_arg = B_FALSE;
703*11878SVenu.Iyer@Sun.COM 	char			*fields_str = NULL;
704*11878SVenu.Iyer@Sun.COM 	char			*formatspec_str = NULL;
705*11878SVenu.Iyer@Sun.COM 	char			*all_l_fields =
706*11878SVenu.Iyer@Sun.COM 	    "link,start,end,rbytes,obytes,bandwidth";
707*11878SVenu.Iyer@Sun.COM 	ofmt_handle_t		ofmt;
708*11878SVenu.Iyer@Sun.COM 	ofmt_status_t		oferr;
709*11878SVenu.Iyer@Sun.COM 	uint_t			ofmtflags = 0;
710*11878SVenu.Iyer@Sun.COM 
711*11878SVenu.Iyer@Sun.COM 	bzero(&state, sizeof (show_history_state_t));
712*11878SVenu.Iyer@Sun.COM 	state.hs_parsable = B_FALSE;
713*11878SVenu.Iyer@Sun.COM 	state.hs_printheader = B_FALSE;
714*11878SVenu.Iyer@Sun.COM 	state.hs_plot = B_FALSE;
715*11878SVenu.Iyer@Sun.COM 	state.hs_first = B_TRUE;
716*11878SVenu.Iyer@Sun.COM 
717*11878SVenu.Iyer@Sun.COM 	while ((opt = getopt(argc, argv, "das:e:o:f:F:")) != -1) {
718*11878SVenu.Iyer@Sun.COM 		switch (opt) {
719*11878SVenu.Iyer@Sun.COM 		case 'd':
720*11878SVenu.Iyer@Sun.COM 			d_arg = B_TRUE;
721*11878SVenu.Iyer@Sun.COM 			break;
722*11878SVenu.Iyer@Sun.COM 		case 'a':
723*11878SVenu.Iyer@Sun.COM 			state.hs_showall = B_TRUE;
724*11878SVenu.Iyer@Sun.COM 			break;
725*11878SVenu.Iyer@Sun.COM 		case 'f':
726*11878SVenu.Iyer@Sun.COM 			file = optarg;
727*11878SVenu.Iyer@Sun.COM 			break;
728*11878SVenu.Iyer@Sun.COM 		case 's':
729*11878SVenu.Iyer@Sun.COM 			stime = optarg;
730*11878SVenu.Iyer@Sun.COM 			break;
731*11878SVenu.Iyer@Sun.COM 		case 'e':
732*11878SVenu.Iyer@Sun.COM 			etime = optarg;
733*11878SVenu.Iyer@Sun.COM 			break;
734*11878SVenu.Iyer@Sun.COM 		case 'o':
735*11878SVenu.Iyer@Sun.COM 			o_arg = B_TRUE;
736*11878SVenu.Iyer@Sun.COM 			fields_str = optarg;
737*11878SVenu.Iyer@Sun.COM 			break;
738*11878SVenu.Iyer@Sun.COM 		case 'F':
739*11878SVenu.Iyer@Sun.COM 			state.hs_plot = F_arg = B_TRUE;
740*11878SVenu.Iyer@Sun.COM 			formatspec_str = optarg;
741*11878SVenu.Iyer@Sun.COM 			break;
742*11878SVenu.Iyer@Sun.COM 		default:
743*11878SVenu.Iyer@Sun.COM 			die_opterr(optopt, opt, use);
744*11878SVenu.Iyer@Sun.COM 			break;
745*11878SVenu.Iyer@Sun.COM 		}
746*11878SVenu.Iyer@Sun.COM 	}
747*11878SVenu.Iyer@Sun.COM 
748*11878SVenu.Iyer@Sun.COM 	if (file == NULL)
749*11878SVenu.Iyer@Sun.COM 		die("show-link -h requires a file");
750*11878SVenu.Iyer@Sun.COM 
751*11878SVenu.Iyer@Sun.COM 	if (optind == (argc-1)) {
752*11878SVenu.Iyer@Sun.COM 		uint32_t 	flags;
753*11878SVenu.Iyer@Sun.COM 
754*11878SVenu.Iyer@Sun.COM 		resource = argv[optind];
755*11878SVenu.Iyer@Sun.COM 		if (!state.hs_showall &&
756*11878SVenu.Iyer@Sun.COM 		    (((status = dladm_name2info(handle, resource, NULL, &flags,
757*11878SVenu.Iyer@Sun.COM 		    NULL, NULL)) != DLADM_STATUS_OK) ||
758*11878SVenu.Iyer@Sun.COM 		    ((flags & DLADM_OPT_ACTIVE) == 0))) {
759*11878SVenu.Iyer@Sun.COM 			die("invalid link: '%s'", resource);
760*11878SVenu.Iyer@Sun.COM 		}
761*11878SVenu.Iyer@Sun.COM 	}
762*11878SVenu.Iyer@Sun.COM 
763*11878SVenu.Iyer@Sun.COM 	if (F_arg && d_arg)
764*11878SVenu.Iyer@Sun.COM 		die("incompatible -d and -F options");
765*11878SVenu.Iyer@Sun.COM 
766*11878SVenu.Iyer@Sun.COM 	if (F_arg && !valid_formatspec(formatspec_str))
767*11878SVenu.Iyer@Sun.COM 		die("Format specifier %s not supported", formatspec_str);
768*11878SVenu.Iyer@Sun.COM 
769*11878SVenu.Iyer@Sun.COM 	if (state.hs_parsable)
770*11878SVenu.Iyer@Sun.COM 		ofmtflags |= OFMT_PARSABLE;
771*11878SVenu.Iyer@Sun.COM 
772*11878SVenu.Iyer@Sun.COM 	if (resource == NULL && stime == NULL && etime == NULL) {
773*11878SVenu.Iyer@Sun.COM 		oferr = ofmt_open(fields_str, history_fields, ofmtflags, 0,
774*11878SVenu.Iyer@Sun.COM 		    &ofmt);
775*11878SVenu.Iyer@Sun.COM 	} else {
776*11878SVenu.Iyer@Sun.COM 		if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0))
777*11878SVenu.Iyer@Sun.COM 			fields_str = all_l_fields;
778*11878SVenu.Iyer@Sun.COM 		oferr = ofmt_open(fields_str, history_l_fields, ofmtflags, 0,
779*11878SVenu.Iyer@Sun.COM 		    &ofmt);
780*11878SVenu.Iyer@Sun.COM 
781*11878SVenu.Iyer@Sun.COM 	}
782*11878SVenu.Iyer@Sun.COM 	dlstat_ofmt_check(oferr, state.hs_parsable, ofmt);
783*11878SVenu.Iyer@Sun.COM 	state.hs_ofmt = ofmt;
784*11878SVenu.Iyer@Sun.COM 
785*11878SVenu.Iyer@Sun.COM 	if (d_arg) {
786*11878SVenu.Iyer@Sun.COM 		/* Print log dates */
787*11878SVenu.Iyer@Sun.COM 		status = dladm_usage_dates(show_history_date,
788*11878SVenu.Iyer@Sun.COM 		    DLADM_LOGTYPE_LINK, file, resource, &state);
789*11878SVenu.Iyer@Sun.COM 	} else if (resource == NULL && stime == NULL && etime == NULL &&
790*11878SVenu.Iyer@Sun.COM 	    !F_arg) {
791*11878SVenu.Iyer@Sun.COM 		/* Print summary */
792*11878SVenu.Iyer@Sun.COM 		status = dladm_usage_summary(show_history_res,
793*11878SVenu.Iyer@Sun.COM 		    DLADM_LOGTYPE_LINK, file, &state);
794*11878SVenu.Iyer@Sun.COM 	} else if (resource != NULL) {
795*11878SVenu.Iyer@Sun.COM 		/* Print log entries for named resource */
796*11878SVenu.Iyer@Sun.COM 		status = dladm_walk_usage_res(show_history_time,
797*11878SVenu.Iyer@Sun.COM 		    DLADM_LOGTYPE_LINK, file, resource, stime, etime, &state);
798*11878SVenu.Iyer@Sun.COM 	} else {
799*11878SVenu.Iyer@Sun.COM 		/* Print time and information for each link */
800*11878SVenu.Iyer@Sun.COM 		status = dladm_walk_usage_time(show_history_time,
801*11878SVenu.Iyer@Sun.COM 		    DLADM_LOGTYPE_LINK, file, stime, etime, &state);
802*11878SVenu.Iyer@Sun.COM 	}
803*11878SVenu.Iyer@Sun.COM 
804*11878SVenu.Iyer@Sun.COM 	if (status != DLADM_STATUS_OK)
805*11878SVenu.Iyer@Sun.COM 		die_dlerr(status, "show-link -h");
806*11878SVenu.Iyer@Sun.COM 	ofmt_close(ofmt);
807*11878SVenu.Iyer@Sun.COM }
808*11878SVenu.Iyer@Sun.COM 
809*11878SVenu.Iyer@Sun.COM boolean_t
dlstat_unit(char * oarg,char * unit)810*11878SVenu.Iyer@Sun.COM dlstat_unit(char *oarg, char *unit)
811*11878SVenu.Iyer@Sun.COM {
812*11878SVenu.Iyer@Sun.COM 	if ((strcmp(oarg, "R") == 0) || (strcmp(oarg, "K") == 0) ||
813*11878SVenu.Iyer@Sun.COM 	    (strcmp(oarg, "M") == 0) || (strcmp(oarg, "G") == 0) ||
814*11878SVenu.Iyer@Sun.COM 	    (strcmp(oarg, "T") == 0) || (strcmp(oarg, "P") == 0)) {
815*11878SVenu.Iyer@Sun.COM 		*unit = oarg[0];
816*11878SVenu.Iyer@Sun.COM 		return (B_TRUE);
817*11878SVenu.Iyer@Sun.COM 	}
818*11878SVenu.Iyer@Sun.COM 
819*11878SVenu.Iyer@Sun.COM 	return (B_FALSE);
820*11878SVenu.Iyer@Sun.COM }
821*11878SVenu.Iyer@Sun.COM 
822*11878SVenu.Iyer@Sun.COM void
map_to_units(char * buf,uint_t bufsize,double num,char unit,boolean_t parsable)823*11878SVenu.Iyer@Sun.COM map_to_units(char *buf, uint_t bufsize, double num, char unit,
824*11878SVenu.Iyer@Sun.COM     boolean_t parsable)
825*11878SVenu.Iyer@Sun.COM {
826*11878SVenu.Iyer@Sun.COM 	if (parsable) {
827*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf, bufsize, "%.0lf", num);
828*11878SVenu.Iyer@Sun.COM 		return;
829*11878SVenu.Iyer@Sun.COM 	}
830*11878SVenu.Iyer@Sun.COM 
831*11878SVenu.Iyer@Sun.COM 	if (unit == '\0') {
832*11878SVenu.Iyer@Sun.COM 		int index;
833*11878SVenu.Iyer@Sun.COM 
834*11878SVenu.Iyer@Sun.COM 		for (index = 0; (int)(num/1000) != 0; index++, num /= 1000)
835*11878SVenu.Iyer@Sun.COM 			;
836*11878SVenu.Iyer@Sun.COM 
837*11878SVenu.Iyer@Sun.COM 		switch (index) {
838*11878SVenu.Iyer@Sun.COM 			case 0:
839*11878SVenu.Iyer@Sun.COM 				unit = '\0';
840*11878SVenu.Iyer@Sun.COM 				break;
841*11878SVenu.Iyer@Sun.COM 			case 1:
842*11878SVenu.Iyer@Sun.COM 				unit = 'K';
843*11878SVenu.Iyer@Sun.COM 				break;
844*11878SVenu.Iyer@Sun.COM 			case 2:
845*11878SVenu.Iyer@Sun.COM 				unit = 'M';
846*11878SVenu.Iyer@Sun.COM 				break;
847*11878SVenu.Iyer@Sun.COM 			case 3:
848*11878SVenu.Iyer@Sun.COM 				unit = 'G';
849*11878SVenu.Iyer@Sun.COM 				break;
850*11878SVenu.Iyer@Sun.COM 			case 4:
851*11878SVenu.Iyer@Sun.COM 				unit = 'T';
852*11878SVenu.Iyer@Sun.COM 				break;
853*11878SVenu.Iyer@Sun.COM 			case 5:
854*11878SVenu.Iyer@Sun.COM 				/* Largest unit supported */
855*11878SVenu.Iyer@Sun.COM 			default:
856*11878SVenu.Iyer@Sun.COM 				unit = 'P';
857*11878SVenu.Iyer@Sun.COM 				break;
858*11878SVenu.Iyer@Sun.COM 		}
859*11878SVenu.Iyer@Sun.COM 	} else  {
860*11878SVenu.Iyer@Sun.COM 		switch (unit) {
861*11878SVenu.Iyer@Sun.COM 			case 'R':
862*11878SVenu.Iyer@Sun.COM 				/* Already raw numbers */
863*11878SVenu.Iyer@Sun.COM 				unit = '\0';
864*11878SVenu.Iyer@Sun.COM 				break;
865*11878SVenu.Iyer@Sun.COM 			case 'K':
866*11878SVenu.Iyer@Sun.COM 				num /= 1000;
867*11878SVenu.Iyer@Sun.COM 				break;
868*11878SVenu.Iyer@Sun.COM 			case 'M':
869*11878SVenu.Iyer@Sun.COM 				num /= (1000*1000);
870*11878SVenu.Iyer@Sun.COM 				break;
871*11878SVenu.Iyer@Sun.COM 			case 'G':
872*11878SVenu.Iyer@Sun.COM 				num /= (1000*1000*1000);
873*11878SVenu.Iyer@Sun.COM 				break;
874*11878SVenu.Iyer@Sun.COM 			case 'T':
875*11878SVenu.Iyer@Sun.COM 				num /= (1000.0*1000.0*1000.0*1000.0);
876*11878SVenu.Iyer@Sun.COM 				break;
877*11878SVenu.Iyer@Sun.COM 			case 'P':
878*11878SVenu.Iyer@Sun.COM 				/* Largest unit supported */
879*11878SVenu.Iyer@Sun.COM 			default:
880*11878SVenu.Iyer@Sun.COM 				num /= (1000.0*1000.0*1000.0*1000.0*1000.0);
881*11878SVenu.Iyer@Sun.COM 				break;
882*11878SVenu.Iyer@Sun.COM 		}
883*11878SVenu.Iyer@Sun.COM 	}
884*11878SVenu.Iyer@Sun.COM 
885*11878SVenu.Iyer@Sun.COM 	if (unit == '\0')
886*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf, bufsize, " %7.0lf%c", num, unit);
887*11878SVenu.Iyer@Sun.COM 	else
888*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf, bufsize, " %6.2lf%c", num, unit);
889*11878SVenu.Iyer@Sun.COM }
890*11878SVenu.Iyer@Sun.COM 
891*11878SVenu.Iyer@Sun.COM link_chain_t *
get_link_prev_stat(datalink_id_t linkid,void * arg)892*11878SVenu.Iyer@Sun.COM get_link_prev_stat(datalink_id_t linkid, void *arg)
893*11878SVenu.Iyer@Sun.COM {
894*11878SVenu.Iyer@Sun.COM 	show_state_t	*state = (show_state_t *)arg;
895*11878SVenu.Iyer@Sun.COM 	link_chain_t	*link_curr = NULL;
896*11878SVenu.Iyer@Sun.COM 
897*11878SVenu.Iyer@Sun.COM 	/* Scan prev linkid list and look for entry matching this entry */
898*11878SVenu.Iyer@Sun.COM 	for (link_curr = state->ls_linkchain; link_curr;
899*11878SVenu.Iyer@Sun.COM 	    link_curr = link_curr->lc_next) {
900*11878SVenu.Iyer@Sun.COM 		if (link_curr->lc_linkid == linkid)
901*11878SVenu.Iyer@Sun.COM 			break;
902*11878SVenu.Iyer@Sun.COM 	}
903*11878SVenu.Iyer@Sun.COM 				/* New link, add it */
904*11878SVenu.Iyer@Sun.COM 	if (link_curr == NULL) {
905*11878SVenu.Iyer@Sun.COM 		link_curr = (link_chain_t *)malloc(sizeof (link_chain_t));
906*11878SVenu.Iyer@Sun.COM 		if (link_curr == NULL)
907*11878SVenu.Iyer@Sun.COM 			goto done;
908*11878SVenu.Iyer@Sun.COM 		link_curr->lc_linkid = linkid;
909*11878SVenu.Iyer@Sun.COM 		bzero(&link_curr->lc_statchain,
910*11878SVenu.Iyer@Sun.COM 		    sizeof (link_curr->lc_statchain));
911*11878SVenu.Iyer@Sun.COM 		link_curr->lc_next = state->ls_linkchain;
912*11878SVenu.Iyer@Sun.COM 		state->ls_linkchain = link_curr;
913*11878SVenu.Iyer@Sun.COM 	}
914*11878SVenu.Iyer@Sun.COM done:
915*11878SVenu.Iyer@Sun.COM 	return (link_curr);
916*11878SVenu.Iyer@Sun.COM }
917*11878SVenu.Iyer@Sun.COM 
918*11878SVenu.Iyer@Sun.COM /*
919*11878SVenu.Iyer@Sun.COM  * Number of links may change while dlstat with -i is executing.
920*11878SVenu.Iyer@Sun.COM  * Free memory allocated for links that are no longer there.
921*11878SVenu.Iyer@Sun.COM  * Prepare for next iteration by marking visited = false for existing stat
922*11878SVenu.Iyer@Sun.COM  * entries.
923*11878SVenu.Iyer@Sun.COM  */
924*11878SVenu.Iyer@Sun.COM static void
cleanup_removed_links(show_state_t * state)925*11878SVenu.Iyer@Sun.COM cleanup_removed_links(show_state_t *state)
926*11878SVenu.Iyer@Sun.COM {
927*11878SVenu.Iyer@Sun.COM 	link_chain_t	*lcurr;
928*11878SVenu.Iyer@Sun.COM 	link_chain_t	*lprev;
929*11878SVenu.Iyer@Sun.COM 	link_chain_t	*tofree;
930*11878SVenu.Iyer@Sun.COM 	int		i;
931*11878SVenu.Iyer@Sun.COM 
932*11878SVenu.Iyer@Sun.COM 	/* Delete all nodes from the list that have lc_visited marked false */
933*11878SVenu.Iyer@Sun.COM 	lcurr = state->ls_linkchain;
934*11878SVenu.Iyer@Sun.COM 	while (lcurr != NULL) {
935*11878SVenu.Iyer@Sun.COM 		if (lcurr->lc_visited) {
936*11878SVenu.Iyer@Sun.COM 			lcurr->lc_visited = B_FALSE;
937*11878SVenu.Iyer@Sun.COM 			lprev = lcurr;
938*11878SVenu.Iyer@Sun.COM 			lcurr = lcurr->lc_next;
939*11878SVenu.Iyer@Sun.COM 			continue;
940*11878SVenu.Iyer@Sun.COM 		}
941*11878SVenu.Iyer@Sun.COM 				/* Is it head of the list? */
942*11878SVenu.Iyer@Sun.COM 		if (lcurr == state->ls_linkchain)
943*11878SVenu.Iyer@Sun.COM 			state->ls_linkchain = lcurr->lc_next;
944*11878SVenu.Iyer@Sun.COM 		else
945*11878SVenu.Iyer@Sun.COM 			lprev->lc_next = lcurr->lc_next;
946*11878SVenu.Iyer@Sun.COM 				/* lprev remains the same */
947*11878SVenu.Iyer@Sun.COM 		tofree = lcurr;
948*11878SVenu.Iyer@Sun.COM 		lcurr = lcurr->lc_next;
949*11878SVenu.Iyer@Sun.COM 
950*11878SVenu.Iyer@Sun.COM 				/* Free stats memory for the removed link */
951*11878SVenu.Iyer@Sun.COM 		for (i = 0; i < DLADM_STAT_NUM_STATS; i++) {
952*11878SVenu.Iyer@Sun.COM 			if (state->ls_stattype[i])
953*11878SVenu.Iyer@Sun.COM 				dladm_link_stat_free(tofree->lc_statchain[i]);
954*11878SVenu.Iyer@Sun.COM 		}
955*11878SVenu.Iyer@Sun.COM 		free(tofree);
956*11878SVenu.Iyer@Sun.COM 	}
957*11878SVenu.Iyer@Sun.COM }
958*11878SVenu.Iyer@Sun.COM 
959*11878SVenu.Iyer@Sun.COM void *
print_total_stats(const char * linkname,void * statentry,char unit,boolean_t parsable)960*11878SVenu.Iyer@Sun.COM print_total_stats(const char *linkname, void *statentry, char unit,
961*11878SVenu.Iyer@Sun.COM     boolean_t parsable)
962*11878SVenu.Iyer@Sun.COM {
963*11878SVenu.Iyer@Sun.COM 	total_stat_entry_t	*sentry = statentry;
964*11878SVenu.Iyer@Sun.COM 	total_stat_t		*link_stats = &sentry->tse_stats;
965*11878SVenu.Iyer@Sun.COM 	total_fields_buf_t	*buf;
966*11878SVenu.Iyer@Sun.COM 
967*11878SVenu.Iyer@Sun.COM 	buf = malloc(sizeof (total_fields_buf_t));
968*11878SVenu.Iyer@Sun.COM 	if (buf == NULL)
969*11878SVenu.Iyer@Sun.COM 		goto done;
970*11878SVenu.Iyer@Sun.COM 
971*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->t_linkname, sizeof (buf->t_linkname), "%s",
972*11878SVenu.Iyer@Sun.COM 	    linkname);
973*11878SVenu.Iyer@Sun.COM 
974*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->t_ipackets, sizeof (buf->t_ipackets),
975*11878SVenu.Iyer@Sun.COM 	    link_stats->ts_ipackets, unit, parsable);
976*11878SVenu.Iyer@Sun.COM 
977*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->t_rbytes, sizeof (buf->t_rbytes),
978*11878SVenu.Iyer@Sun.COM 	    link_stats->ts_rbytes, unit, parsable);
979*11878SVenu.Iyer@Sun.COM 
980*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->t_opackets, sizeof (buf->t_opackets),
981*11878SVenu.Iyer@Sun.COM 	    link_stats->ts_opackets, unit, parsable);
982*11878SVenu.Iyer@Sun.COM 
983*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->t_obytes, sizeof (buf->t_obytes),
984*11878SVenu.Iyer@Sun.COM 	    link_stats->ts_obytes, unit, parsable);
985*11878SVenu.Iyer@Sun.COM 
986*11878SVenu.Iyer@Sun.COM done:
987*11878SVenu.Iyer@Sun.COM 	return (buf);
988*11878SVenu.Iyer@Sun.COM }
989*11878SVenu.Iyer@Sun.COM 
990*11878SVenu.Iyer@Sun.COM void *
print_rx_generic_ring_stats(const char * linkname,void * statentry,char unit,boolean_t parsable)991*11878SVenu.Iyer@Sun.COM print_rx_generic_ring_stats(const char *linkname, void *statentry, char unit,
992*11878SVenu.Iyer@Sun.COM     boolean_t parsable)
993*11878SVenu.Iyer@Sun.COM {
994*11878SVenu.Iyer@Sun.COM 	ring_stat_entry_t	*sentry = statentry;
995*11878SVenu.Iyer@Sun.COM 	ring_stat_t		*link_stats = &sentry->re_stats;
996*11878SVenu.Iyer@Sun.COM 	ring_fields_buf_t	*buf;
997*11878SVenu.Iyer@Sun.COM 
998*11878SVenu.Iyer@Sun.COM 	buf = malloc(sizeof (ring_fields_buf_t));
999*11878SVenu.Iyer@Sun.COM 	if (buf == NULL)
1000*11878SVenu.Iyer@Sun.COM 		goto done;
1001*11878SVenu.Iyer@Sun.COM 
1002*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->r_linkname, sizeof (buf->r_linkname), "%s",
1003*11878SVenu.Iyer@Sun.COM 	    linkname);
1004*11878SVenu.Iyer@Sun.COM 
1005*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->r_type, sizeof (buf->r_type), "rx");
1006*11878SVenu.Iyer@Sun.COM 
1007*11878SVenu.Iyer@Sun.COM 	if (sentry->re_index == DLSTAT_INVALID_ENTRY) {
1008*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->r_index, sizeof (buf->r_index), "--");
1009*11878SVenu.Iyer@Sun.COM 	} else {
1010*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->r_index, sizeof (buf->r_index),
1011*11878SVenu.Iyer@Sun.COM 		    "%llu", sentry->re_index);
1012*11878SVenu.Iyer@Sun.COM 	}
1013*11878SVenu.Iyer@Sun.COM 
1014*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->r_packets, sizeof (buf->r_packets),
1015*11878SVenu.Iyer@Sun.COM 	    link_stats->r_packets, unit, parsable);
1016*11878SVenu.Iyer@Sun.COM 
1017*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->r_bytes, sizeof (buf->r_bytes),
1018*11878SVenu.Iyer@Sun.COM 	    link_stats->r_bytes, unit, parsable);
1019*11878SVenu.Iyer@Sun.COM 
1020*11878SVenu.Iyer@Sun.COM done:
1021*11878SVenu.Iyer@Sun.COM 	return (buf);
1022*11878SVenu.Iyer@Sun.COM }
1023*11878SVenu.Iyer@Sun.COM 
1024*11878SVenu.Iyer@Sun.COM void *
print_tx_generic_ring_stats(const char * linkname,void * statentry,char unit,boolean_t parsable)1025*11878SVenu.Iyer@Sun.COM print_tx_generic_ring_stats(const char *linkname, void *statentry, char unit,
1026*11878SVenu.Iyer@Sun.COM     boolean_t parsable)
1027*11878SVenu.Iyer@Sun.COM {
1028*11878SVenu.Iyer@Sun.COM 	ring_stat_entry_t	*sentry = statentry;
1029*11878SVenu.Iyer@Sun.COM 	ring_stat_t		*link_stats = &sentry->re_stats;
1030*11878SVenu.Iyer@Sun.COM 	ring_fields_buf_t	*buf;
1031*11878SVenu.Iyer@Sun.COM 
1032*11878SVenu.Iyer@Sun.COM 	buf = malloc(sizeof (ring_fields_buf_t));
1033*11878SVenu.Iyer@Sun.COM 	if (buf == NULL)
1034*11878SVenu.Iyer@Sun.COM 		goto done;
1035*11878SVenu.Iyer@Sun.COM 
1036*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->r_linkname, sizeof (buf->r_linkname), "%s",
1037*11878SVenu.Iyer@Sun.COM 	    linkname);
1038*11878SVenu.Iyer@Sun.COM 
1039*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->r_type, sizeof (buf->r_type), "tx");
1040*11878SVenu.Iyer@Sun.COM 
1041*11878SVenu.Iyer@Sun.COM 	if (sentry->re_index == DLSTAT_INVALID_ENTRY) {
1042*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->r_index, sizeof (buf->r_index), "--");
1043*11878SVenu.Iyer@Sun.COM 	} else {
1044*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->r_index, sizeof (buf->r_index),
1045*11878SVenu.Iyer@Sun.COM 		    "%llu", sentry->re_index);
1046*11878SVenu.Iyer@Sun.COM 	}
1047*11878SVenu.Iyer@Sun.COM 
1048*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->r_packets, sizeof (buf->r_packets),
1049*11878SVenu.Iyer@Sun.COM 	    link_stats->r_packets, unit, parsable);
1050*11878SVenu.Iyer@Sun.COM 
1051*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->r_bytes, sizeof (buf->r_bytes),
1052*11878SVenu.Iyer@Sun.COM 	    link_stats->r_bytes, unit, parsable);
1053*11878SVenu.Iyer@Sun.COM 
1054*11878SVenu.Iyer@Sun.COM done:
1055*11878SVenu.Iyer@Sun.COM 	return (buf);
1056*11878SVenu.Iyer@Sun.COM }
1057*11878SVenu.Iyer@Sun.COM 
1058*11878SVenu.Iyer@Sun.COM void *
print_rx_ring_stats(const char * linkname,void * statentry,char unit,boolean_t parsable)1059*11878SVenu.Iyer@Sun.COM print_rx_ring_stats(const char *linkname, void *statentry, char unit,
1060*11878SVenu.Iyer@Sun.COM     boolean_t parsable)
1061*11878SVenu.Iyer@Sun.COM {
1062*11878SVenu.Iyer@Sun.COM 	ring_stat_entry_t	*sentry = statentry;
1063*11878SVenu.Iyer@Sun.COM 	ring_stat_t		*link_stats = &sentry->re_stats;
1064*11878SVenu.Iyer@Sun.COM 	rx_ring_fields_buf_t	*buf;
1065*11878SVenu.Iyer@Sun.COM 
1066*11878SVenu.Iyer@Sun.COM 	buf = malloc(sizeof (rx_ring_fields_buf_t));
1067*11878SVenu.Iyer@Sun.COM 	if (buf == NULL)
1068*11878SVenu.Iyer@Sun.COM 		goto done;
1069*11878SVenu.Iyer@Sun.COM 
1070*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->rr_linkname, sizeof (buf->rr_linkname), "%s",
1071*11878SVenu.Iyer@Sun.COM 	    linkname);
1072*11878SVenu.Iyer@Sun.COM 
1073*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->rr_type, sizeof (buf->rr_type), "rx");
1074*11878SVenu.Iyer@Sun.COM 
1075*11878SVenu.Iyer@Sun.COM 	if (sentry->re_index == DLSTAT_INVALID_ENTRY) {
1076*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rr_index, sizeof (buf->rr_index), "--");
1077*11878SVenu.Iyer@Sun.COM 	} else {
1078*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rr_index, sizeof (buf->rr_index),
1079*11878SVenu.Iyer@Sun.COM 		    "%llu", sentry->re_index);
1080*11878SVenu.Iyer@Sun.COM 	}
1081*11878SVenu.Iyer@Sun.COM 
1082*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->rr_ipackets, sizeof (buf->rr_ipackets),
1083*11878SVenu.Iyer@Sun.COM 	    link_stats->r_packets, unit, parsable);
1084*11878SVenu.Iyer@Sun.COM 
1085*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->rr_rbytes, sizeof (buf->rr_rbytes),
1086*11878SVenu.Iyer@Sun.COM 	    link_stats->r_bytes, unit, parsable);
1087*11878SVenu.Iyer@Sun.COM 
1088*11878SVenu.Iyer@Sun.COM done:
1089*11878SVenu.Iyer@Sun.COM 	return (buf);
1090*11878SVenu.Iyer@Sun.COM }
1091*11878SVenu.Iyer@Sun.COM 
1092*11878SVenu.Iyer@Sun.COM void *
print_tx_ring_stats(const char * linkname,void * statentry,char unit,boolean_t parsable)1093*11878SVenu.Iyer@Sun.COM print_tx_ring_stats(const char *linkname, void *statentry, char unit,
1094*11878SVenu.Iyer@Sun.COM     boolean_t parsable)
1095*11878SVenu.Iyer@Sun.COM {
1096*11878SVenu.Iyer@Sun.COM 	ring_stat_entry_t	*sentry = statentry;
1097*11878SVenu.Iyer@Sun.COM 	ring_stat_t		*link_stats = &sentry->re_stats;
1098*11878SVenu.Iyer@Sun.COM 	tx_ring_fields_buf_t	*buf;
1099*11878SVenu.Iyer@Sun.COM 
1100*11878SVenu.Iyer@Sun.COM 	buf = malloc(sizeof (tx_ring_fields_buf_t));
1101*11878SVenu.Iyer@Sun.COM 	if (buf == NULL)
1102*11878SVenu.Iyer@Sun.COM 		goto done;
1103*11878SVenu.Iyer@Sun.COM 
1104*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->tr_linkname, sizeof (buf->tr_linkname), "%s",
1105*11878SVenu.Iyer@Sun.COM 	    linkname);
1106*11878SVenu.Iyer@Sun.COM 
1107*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->tr_type, sizeof (buf->tr_type), "tx");
1108*11878SVenu.Iyer@Sun.COM 
1109*11878SVenu.Iyer@Sun.COM 	if (sentry->re_index == DLSTAT_INVALID_ENTRY) {
1110*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->tr_index, sizeof (buf->tr_index), "--");
1111*11878SVenu.Iyer@Sun.COM 	} else {
1112*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->tr_index, sizeof (buf->tr_index),
1113*11878SVenu.Iyer@Sun.COM 		    "%llu", sentry->re_index);
1114*11878SVenu.Iyer@Sun.COM 	}
1115*11878SVenu.Iyer@Sun.COM 
1116*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->tr_opackets, sizeof (buf->tr_opackets),
1117*11878SVenu.Iyer@Sun.COM 	    link_stats->r_packets, unit, parsable);
1118*11878SVenu.Iyer@Sun.COM 
1119*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->tr_obytes, sizeof (buf->tr_obytes),
1120*11878SVenu.Iyer@Sun.COM 	    link_stats->r_bytes, unit, parsable);
1121*11878SVenu.Iyer@Sun.COM 
1122*11878SVenu.Iyer@Sun.COM done:
1123*11878SVenu.Iyer@Sun.COM 	return (buf);
1124*11878SVenu.Iyer@Sun.COM }
1125*11878SVenu.Iyer@Sun.COM 
1126*11878SVenu.Iyer@Sun.COM void *
print_rx_generic_lane_stats(const char * linkname,void * statentry,char unit,boolean_t parsable)1127*11878SVenu.Iyer@Sun.COM print_rx_generic_lane_stats(const char *linkname, void *statentry, char unit,
1128*11878SVenu.Iyer@Sun.COM     boolean_t parsable)
1129*11878SVenu.Iyer@Sun.COM {
1130*11878SVenu.Iyer@Sun.COM 	rx_lane_stat_entry_t	*sentry = statentry;
1131*11878SVenu.Iyer@Sun.COM 	rx_lane_stat_t		*link_stats = &sentry->rle_stats;
1132*11878SVenu.Iyer@Sun.COM 	lane_fields_buf_t	*buf;
1133*11878SVenu.Iyer@Sun.COM 
1134*11878SVenu.Iyer@Sun.COM 	if (sentry->rle_id == L_DFNCT)
1135*11878SVenu.Iyer@Sun.COM 		return (NULL);
1136*11878SVenu.Iyer@Sun.COM 
1137*11878SVenu.Iyer@Sun.COM 	buf = malloc(sizeof (lane_fields_buf_t));
1138*11878SVenu.Iyer@Sun.COM 	if (buf == NULL)
1139*11878SVenu.Iyer@Sun.COM 		goto done;
1140*11878SVenu.Iyer@Sun.COM 
1141*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->l_linkname, sizeof (buf->l_linkname), "%s",
1142*11878SVenu.Iyer@Sun.COM 	    linkname);
1143*11878SVenu.Iyer@Sun.COM 
1144*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->l_type, sizeof (buf->l_type), "rx");
1145*11878SVenu.Iyer@Sun.COM 
1146*11878SVenu.Iyer@Sun.COM 	if (sentry->rle_id == L_HWLANE)
1147*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->l_id, sizeof (buf->l_id), "hw");
1148*11878SVenu.Iyer@Sun.COM 	else if (sentry->rle_id == L_SWLANE)
1149*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->l_id, sizeof (buf->l_id), "sw");
1150*11878SVenu.Iyer@Sun.COM 	else if (sentry->rle_id == L_LOCAL)
1151*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->l_id, sizeof (buf->l_id), "local");
1152*11878SVenu.Iyer@Sun.COM 	else if (sentry->rle_id == L_BCAST)
1153*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->l_id, sizeof (buf->l_id), "bcast");
1154*11878SVenu.Iyer@Sun.COM 	else
1155*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->l_id, sizeof (buf->l_id), "--");
1156*11878SVenu.Iyer@Sun.COM 
1157*11878SVenu.Iyer@Sun.COM 	if (sentry->rle_index == DLSTAT_INVALID_ENTRY) {
1158*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->l_index, sizeof (buf->l_index), "--");
1159*11878SVenu.Iyer@Sun.COM 	} else {
1160*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->l_index, sizeof (buf->l_index),
1161*11878SVenu.Iyer@Sun.COM 		    "%llu", sentry->rle_index);
1162*11878SVenu.Iyer@Sun.COM 	}
1163*11878SVenu.Iyer@Sun.COM 
1164*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->l_packets, sizeof (buf->l_packets),
1165*11878SVenu.Iyer@Sun.COM 	    link_stats->rl_ipackets, unit, parsable);
1166*11878SVenu.Iyer@Sun.COM 
1167*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->l_bytes, sizeof (buf->l_bytes),
1168*11878SVenu.Iyer@Sun.COM 	    link_stats->rl_rbytes, unit, parsable);
1169*11878SVenu.Iyer@Sun.COM 
1170*11878SVenu.Iyer@Sun.COM done:
1171*11878SVenu.Iyer@Sun.COM 	return (buf);
1172*11878SVenu.Iyer@Sun.COM }
1173*11878SVenu.Iyer@Sun.COM 
1174*11878SVenu.Iyer@Sun.COM void *
print_tx_generic_lane_stats(const char * linkname,void * statentry,char unit,boolean_t parsable)1175*11878SVenu.Iyer@Sun.COM print_tx_generic_lane_stats(const char *linkname, void *statentry, char unit,
1176*11878SVenu.Iyer@Sun.COM     boolean_t parsable)
1177*11878SVenu.Iyer@Sun.COM {
1178*11878SVenu.Iyer@Sun.COM 	tx_lane_stat_entry_t	*sentry = statentry;
1179*11878SVenu.Iyer@Sun.COM 	tx_lane_stat_t		*link_stats = &sentry->tle_stats;
1180*11878SVenu.Iyer@Sun.COM 	lane_fields_buf_t	*buf;
1181*11878SVenu.Iyer@Sun.COM 
1182*11878SVenu.Iyer@Sun.COM 	if (sentry->tle_id == L_DFNCT)
1183*11878SVenu.Iyer@Sun.COM 		return (NULL);
1184*11878SVenu.Iyer@Sun.COM 
1185*11878SVenu.Iyer@Sun.COM 	buf = malloc(sizeof (lane_fields_buf_t));
1186*11878SVenu.Iyer@Sun.COM 	if (buf == NULL)
1187*11878SVenu.Iyer@Sun.COM 		goto done;
1188*11878SVenu.Iyer@Sun.COM 
1189*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->l_linkname, sizeof (buf->l_linkname), "%s",
1190*11878SVenu.Iyer@Sun.COM 	    linkname);
1191*11878SVenu.Iyer@Sun.COM 
1192*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->l_type, sizeof (buf->l_type), "tx");
1193*11878SVenu.Iyer@Sun.COM 
1194*11878SVenu.Iyer@Sun.COM 	if (sentry->tle_id == L_HWLANE)
1195*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->l_id, sizeof (buf->l_id), "hw");
1196*11878SVenu.Iyer@Sun.COM 	else if (sentry->tle_id == L_SWLANE)
1197*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->l_id, sizeof (buf->l_id), "sw");
1198*11878SVenu.Iyer@Sun.COM 	else if (sentry->tle_id == L_BCAST)
1199*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->l_id, sizeof (buf->l_id), "bcast");
1200*11878SVenu.Iyer@Sun.COM 	else
1201*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->l_id, sizeof (buf->l_id), "--");
1202*11878SVenu.Iyer@Sun.COM 
1203*11878SVenu.Iyer@Sun.COM 	if (sentry->tle_index == DLSTAT_INVALID_ENTRY) {
1204*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->l_index, sizeof (buf->l_index), "--");
1205*11878SVenu.Iyer@Sun.COM 	} else {
1206*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->l_index, sizeof (buf->l_index),
1207*11878SVenu.Iyer@Sun.COM 		    "%llu", sentry->tle_index);
1208*11878SVenu.Iyer@Sun.COM 	}
1209*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->l_packets, sizeof (buf->l_packets),
1210*11878SVenu.Iyer@Sun.COM 	    link_stats->tl_opackets, unit, parsable);
1211*11878SVenu.Iyer@Sun.COM 
1212*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->l_bytes, sizeof (buf->l_bytes),
1213*11878SVenu.Iyer@Sun.COM 	    link_stats->tl_obytes, unit, parsable);
1214*11878SVenu.Iyer@Sun.COM 
1215*11878SVenu.Iyer@Sun.COM done:
1216*11878SVenu.Iyer@Sun.COM 	return (buf);
1217*11878SVenu.Iyer@Sun.COM }
1218*11878SVenu.Iyer@Sun.COM 
1219*11878SVenu.Iyer@Sun.COM void *
print_rx_lane_stats(const char * linkname,void * statentry,char unit,boolean_t parsable)1220*11878SVenu.Iyer@Sun.COM print_rx_lane_stats(const char *linkname, void *statentry, char unit,
1221*11878SVenu.Iyer@Sun.COM     boolean_t parsable)
1222*11878SVenu.Iyer@Sun.COM {
1223*11878SVenu.Iyer@Sun.COM 	rx_lane_stat_entry_t	*sentry = statentry;
1224*11878SVenu.Iyer@Sun.COM 	rx_lane_stat_t		*link_stats = &sentry->rle_stats;
1225*11878SVenu.Iyer@Sun.COM 	rx_lane_fields_buf_t	*buf;
1226*11878SVenu.Iyer@Sun.COM 
1227*11878SVenu.Iyer@Sun.COM 	if (sentry->rle_id == L_DFNCT)
1228*11878SVenu.Iyer@Sun.COM 		return (NULL);
1229*11878SVenu.Iyer@Sun.COM 
1230*11878SVenu.Iyer@Sun.COM 	buf = malloc(sizeof (rx_lane_fields_buf_t));
1231*11878SVenu.Iyer@Sun.COM 	if (buf == NULL)
1232*11878SVenu.Iyer@Sun.COM 		goto done;
1233*11878SVenu.Iyer@Sun.COM 
1234*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->rl_linkname, sizeof (buf->rl_linkname), "%s",
1235*11878SVenu.Iyer@Sun.COM 	    linkname);
1236*11878SVenu.Iyer@Sun.COM 
1237*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->rl_type, sizeof (buf->rl_type), "rx");
1238*11878SVenu.Iyer@Sun.COM 
1239*11878SVenu.Iyer@Sun.COM 	if (sentry->rle_id == L_HWLANE)
1240*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rl_id, sizeof (buf->rl_id), "hw");
1241*11878SVenu.Iyer@Sun.COM 	else if (sentry->rle_id == L_SWLANE)
1242*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rl_id, sizeof (buf->rl_id), "sw");
1243*11878SVenu.Iyer@Sun.COM 	else if (sentry->rle_id == L_LOCAL)
1244*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rl_id, sizeof (buf->rl_id), "local");
1245*11878SVenu.Iyer@Sun.COM 	else if (sentry->rle_id == L_BCAST)
1246*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rl_id, sizeof (buf->rl_id), "bcast");
1247*11878SVenu.Iyer@Sun.COM 	else
1248*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rl_id, sizeof (buf->rl_id), "--");
1249*11878SVenu.Iyer@Sun.COM 
1250*11878SVenu.Iyer@Sun.COM 	if (sentry->rle_index == DLSTAT_INVALID_ENTRY) {
1251*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rl_index, sizeof (buf->rl_index), "--");
1252*11878SVenu.Iyer@Sun.COM 	} else {
1253*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rl_index, sizeof (buf->rl_index),
1254*11878SVenu.Iyer@Sun.COM 		    "%llu", sentry->rle_index);
1255*11878SVenu.Iyer@Sun.COM 	}
1256*11878SVenu.Iyer@Sun.COM 
1257*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->rl_ipackets, sizeof (buf->rl_ipackets),
1258*11878SVenu.Iyer@Sun.COM 	    link_stats->rl_ipackets, unit, parsable);
1259*11878SVenu.Iyer@Sun.COM 
1260*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->rl_rbytes, sizeof (buf->rl_rbytes),
1261*11878SVenu.Iyer@Sun.COM 	    link_stats->rl_rbytes, unit, parsable);
1262*11878SVenu.Iyer@Sun.COM 
1263*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->rl_intrs, sizeof (buf->rl_intrs),
1264*11878SVenu.Iyer@Sun.COM 	    link_stats->rl_intrs, unit, parsable);
1265*11878SVenu.Iyer@Sun.COM 
1266*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->rl_polls, sizeof (buf->rl_polls),
1267*11878SVenu.Iyer@Sun.COM 	    link_stats->rl_polls, unit, parsable);
1268*11878SVenu.Iyer@Sun.COM 
1269*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->rl_sdrops, sizeof (buf->rl_sdrops),
1270*11878SVenu.Iyer@Sun.COM 	    link_stats->rl_sdrops, unit, parsable);
1271*11878SVenu.Iyer@Sun.COM 
1272*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->rl_chl10, sizeof (buf->rl_chl10),
1273*11878SVenu.Iyer@Sun.COM 	    link_stats->rl_chl10, unit, parsable);
1274*11878SVenu.Iyer@Sun.COM 
1275*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->rl_ch10_50, sizeof (buf->rl_ch10_50),
1276*11878SVenu.Iyer@Sun.COM 	    link_stats->rl_ch10_50, unit, parsable);
1277*11878SVenu.Iyer@Sun.COM 
1278*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->rl_chg50, sizeof (buf->rl_chg50),
1279*11878SVenu.Iyer@Sun.COM 	    link_stats->rl_chg50, unit, parsable);
1280*11878SVenu.Iyer@Sun.COM 
1281*11878SVenu.Iyer@Sun.COM done:
1282*11878SVenu.Iyer@Sun.COM 	return (buf);
1283*11878SVenu.Iyer@Sun.COM }
1284*11878SVenu.Iyer@Sun.COM 
1285*11878SVenu.Iyer@Sun.COM void *
print_tx_lane_stats(const char * linkname,void * statentry,char unit,boolean_t parsable)1286*11878SVenu.Iyer@Sun.COM print_tx_lane_stats(const char *linkname, void *statentry, char unit,
1287*11878SVenu.Iyer@Sun.COM     boolean_t parsable)
1288*11878SVenu.Iyer@Sun.COM {
1289*11878SVenu.Iyer@Sun.COM 	tx_lane_stat_entry_t	*sentry = statentry;
1290*11878SVenu.Iyer@Sun.COM 	tx_lane_stat_t		*link_stats = &sentry->tle_stats;
1291*11878SVenu.Iyer@Sun.COM 	tx_lane_fields_buf_t	*buf = NULL;
1292*11878SVenu.Iyer@Sun.COM 
1293*11878SVenu.Iyer@Sun.COM 	if (sentry->tle_id == L_DFNCT)
1294*11878SVenu.Iyer@Sun.COM 		return (NULL);
1295*11878SVenu.Iyer@Sun.COM 
1296*11878SVenu.Iyer@Sun.COM 	buf = malloc(sizeof (tx_lane_fields_buf_t));
1297*11878SVenu.Iyer@Sun.COM 	if (buf == NULL)
1298*11878SVenu.Iyer@Sun.COM 		goto done;
1299*11878SVenu.Iyer@Sun.COM 
1300*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->tl_linkname, sizeof (buf->tl_linkname), "%s",
1301*11878SVenu.Iyer@Sun.COM 	    linkname);
1302*11878SVenu.Iyer@Sun.COM 
1303*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->tl_type, sizeof (buf->tl_type), "tx");
1304*11878SVenu.Iyer@Sun.COM 
1305*11878SVenu.Iyer@Sun.COM 	if (sentry->tle_id == L_HWLANE)
1306*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->tl_id, sizeof (buf->tl_id), "hw");
1307*11878SVenu.Iyer@Sun.COM 	else if (sentry->tle_id == L_SWLANE)
1308*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->tl_id, sizeof (buf->tl_id), "sw");
1309*11878SVenu.Iyer@Sun.COM 	else if (sentry->tle_id == L_BCAST)
1310*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->tl_id, sizeof (buf->tl_id), "bcast");
1311*11878SVenu.Iyer@Sun.COM 	else
1312*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->tl_id, sizeof (buf->tl_id), "--");
1313*11878SVenu.Iyer@Sun.COM 
1314*11878SVenu.Iyer@Sun.COM 	if (sentry->tle_index == DLSTAT_INVALID_ENTRY) {
1315*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->tl_index, sizeof (buf->tl_index), "--");
1316*11878SVenu.Iyer@Sun.COM 	} else {
1317*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->tl_index, sizeof (buf->tl_index),
1318*11878SVenu.Iyer@Sun.COM 		    "%llu", sentry->tle_index);
1319*11878SVenu.Iyer@Sun.COM 	}
1320*11878SVenu.Iyer@Sun.COM 
1321*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->tl_opackets, sizeof (buf->tl_opackets),
1322*11878SVenu.Iyer@Sun.COM 	    link_stats->tl_opackets, unit, parsable);
1323*11878SVenu.Iyer@Sun.COM 
1324*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->tl_obytes, sizeof (buf->tl_obytes),
1325*11878SVenu.Iyer@Sun.COM 	    link_stats->tl_obytes, unit, parsable);
1326*11878SVenu.Iyer@Sun.COM 
1327*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->tl_blockcnt, sizeof (buf->tl_blockcnt),
1328*11878SVenu.Iyer@Sun.COM 	    link_stats->tl_blockcnt, unit, parsable);
1329*11878SVenu.Iyer@Sun.COM 
1330*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->tl_unblockcnt, sizeof (buf->tl_unblockcnt),
1331*11878SVenu.Iyer@Sun.COM 	    link_stats->tl_unblockcnt, unit, parsable);
1332*11878SVenu.Iyer@Sun.COM 
1333*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->tl_sdrops, sizeof (buf->tl_sdrops),
1334*11878SVenu.Iyer@Sun.COM 	    link_stats->tl_sdrops, unit, parsable);
1335*11878SVenu.Iyer@Sun.COM 
1336*11878SVenu.Iyer@Sun.COM done:
1337*11878SVenu.Iyer@Sun.COM 	return (buf);
1338*11878SVenu.Iyer@Sun.COM }
1339*11878SVenu.Iyer@Sun.COM 
1340*11878SVenu.Iyer@Sun.COM void *
print_fanout_stats(const char * linkname,void * statentry,char unit,boolean_t parsable)1341*11878SVenu.Iyer@Sun.COM print_fanout_stats(const char *linkname, void *statentry, char unit,
1342*11878SVenu.Iyer@Sun.COM     boolean_t parsable)
1343*11878SVenu.Iyer@Sun.COM {
1344*11878SVenu.Iyer@Sun.COM 	fanout_stat_entry_t		*sentry = statentry;
1345*11878SVenu.Iyer@Sun.COM 	fanout_stat_t			*link_stats = &sentry->fe_stats;
1346*11878SVenu.Iyer@Sun.COM 	rx_fanout_lane_fields_buf_t	*buf;
1347*11878SVenu.Iyer@Sun.COM 
1348*11878SVenu.Iyer@Sun.COM 	buf = malloc(sizeof (rx_fanout_lane_fields_buf_t));
1349*11878SVenu.Iyer@Sun.COM 	if (buf == NULL)
1350*11878SVenu.Iyer@Sun.COM 		goto done;
1351*11878SVenu.Iyer@Sun.COM 
1352*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->rfl_linkname, sizeof (buf->rfl_linkname), "%s",
1353*11878SVenu.Iyer@Sun.COM 	    linkname);
1354*11878SVenu.Iyer@Sun.COM 
1355*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->rfl_type, sizeof (buf->rfl_type), "rx");
1356*11878SVenu.Iyer@Sun.COM 
1357*11878SVenu.Iyer@Sun.COM 	if (sentry->fe_id == L_HWLANE)
1358*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rfl_id, sizeof (buf->rfl_id), "hw");
1359*11878SVenu.Iyer@Sun.COM 	else if (sentry->fe_id == L_SWLANE)
1360*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rfl_id, sizeof (buf->rfl_id), "sw");
1361*11878SVenu.Iyer@Sun.COM 	else if (sentry->fe_id == L_LCLSWLANE)
1362*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rfl_id, sizeof (buf->rfl_id), "lcl/sw");
1363*11878SVenu.Iyer@Sun.COM 	else if (sentry->fe_id == L_LOCAL)
1364*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rfl_id, sizeof (buf->rfl_id), "local");
1365*11878SVenu.Iyer@Sun.COM 	else if (sentry->fe_id == L_BCAST)
1366*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rfl_id, sizeof (buf->rfl_id), "bcast");
1367*11878SVenu.Iyer@Sun.COM 	else
1368*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rfl_id, sizeof (buf->rfl_id), "--");
1369*11878SVenu.Iyer@Sun.COM 
1370*11878SVenu.Iyer@Sun.COM 	if (sentry->fe_index == DLSTAT_INVALID_ENTRY) {
1371*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rfl_index, sizeof (buf->rfl_index), "--");
1372*11878SVenu.Iyer@Sun.COM 	} else {
1373*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rfl_index, sizeof (buf->rfl_index),
1374*11878SVenu.Iyer@Sun.COM 		    "%llu", sentry->fe_index);
1375*11878SVenu.Iyer@Sun.COM 	}
1376*11878SVenu.Iyer@Sun.COM 
1377*11878SVenu.Iyer@Sun.COM 	if (sentry->fe_foutindex == DLSTAT_INVALID_ENTRY)
1378*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rfl_fout, sizeof (buf->rfl_fout), "--");
1379*11878SVenu.Iyer@Sun.COM 	else {
1380*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->rfl_fout, sizeof (buf->rfl_fout), "%llu",
1381*11878SVenu.Iyer@Sun.COM 		    sentry->fe_foutindex);
1382*11878SVenu.Iyer@Sun.COM 	}
1383*11878SVenu.Iyer@Sun.COM 
1384*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->rfl_ipackets, sizeof (buf->rfl_ipackets),
1385*11878SVenu.Iyer@Sun.COM 	    link_stats->f_ipackets, unit, parsable);
1386*11878SVenu.Iyer@Sun.COM 
1387*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->rfl_rbytes, sizeof (buf->rfl_rbytes),
1388*11878SVenu.Iyer@Sun.COM 	    link_stats->f_rbytes, unit, parsable);
1389*11878SVenu.Iyer@Sun.COM 
1390*11878SVenu.Iyer@Sun.COM done:
1391*11878SVenu.Iyer@Sun.COM 	return (buf);
1392*11878SVenu.Iyer@Sun.COM }
1393*11878SVenu.Iyer@Sun.COM 
1394*11878SVenu.Iyer@Sun.COM void *
print_aggr_port_stats(const char * linkname,void * statentry,char unit,boolean_t parsable)1395*11878SVenu.Iyer@Sun.COM print_aggr_port_stats(const char *linkname, void *statentry, char unit,
1396*11878SVenu.Iyer@Sun.COM     boolean_t parsable)
1397*11878SVenu.Iyer@Sun.COM {
1398*11878SVenu.Iyer@Sun.COM 	aggr_port_stat_entry_t	*sentry = statentry;
1399*11878SVenu.Iyer@Sun.COM 	aggr_port_stat_t	*link_stats = &sentry->ape_stats;
1400*11878SVenu.Iyer@Sun.COM 	aggr_port_fields_buf_t	*buf;
1401*11878SVenu.Iyer@Sun.COM 	char			portname[MAXLINKNAMELEN];
1402*11878SVenu.Iyer@Sun.COM 
1403*11878SVenu.Iyer@Sun.COM 	buf = malloc(sizeof (aggr_port_fields_buf_t));
1404*11878SVenu.Iyer@Sun.COM 	if (buf == NULL)
1405*11878SVenu.Iyer@Sun.COM 		goto done;
1406*11878SVenu.Iyer@Sun.COM 
1407*11878SVenu.Iyer@Sun.COM 	(void) snprintf(buf->ap_linkname, sizeof (buf->ap_linkname), "%s",
1408*11878SVenu.Iyer@Sun.COM 	    linkname);
1409*11878SVenu.Iyer@Sun.COM 
1410*11878SVenu.Iyer@Sun.COM 	if (dladm_datalink_id2info(handle, sentry->ape_portlinkid, NULL,
1411*11878SVenu.Iyer@Sun.COM 	    NULL, NULL, portname, DLPI_LINKNAME_MAX)
1412*11878SVenu.Iyer@Sun.COM 	    != DLADM_STATUS_OK) {
1413*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->ap_portname,
1414*11878SVenu.Iyer@Sun.COM 		    sizeof (buf->ap_portname), "--");
1415*11878SVenu.Iyer@Sun.COM 	} else {
1416*11878SVenu.Iyer@Sun.COM 		(void) snprintf(buf->ap_portname,
1417*11878SVenu.Iyer@Sun.COM 		    sizeof (buf->ap_portname), "%s", portname);
1418*11878SVenu.Iyer@Sun.COM 	}
1419*11878SVenu.Iyer@Sun.COM 
1420*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->ap_ipackets, sizeof (buf->ap_ipackets),
1421*11878SVenu.Iyer@Sun.COM 	    link_stats->ap_ipackets, unit, parsable);
1422*11878SVenu.Iyer@Sun.COM 
1423*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->ap_rbytes, sizeof (buf->ap_rbytes),
1424*11878SVenu.Iyer@Sun.COM 	    link_stats->ap_rbytes, unit, parsable);
1425*11878SVenu.Iyer@Sun.COM 
1426*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->ap_opackets, sizeof (buf->ap_opackets),
1427*11878SVenu.Iyer@Sun.COM 	    link_stats->ap_opackets, unit, parsable);
1428*11878SVenu.Iyer@Sun.COM 
1429*11878SVenu.Iyer@Sun.COM 	map_to_units(buf->ap_obytes, sizeof (buf->ap_obytes),
1430*11878SVenu.Iyer@Sun.COM 	    link_stats->ap_obytes, unit, parsable);
1431*11878SVenu.Iyer@Sun.COM 
1432*11878SVenu.Iyer@Sun.COM done:
1433*11878SVenu.Iyer@Sun.COM 	return (buf);
1434*11878SVenu.Iyer@Sun.COM }
1435*11878SVenu.Iyer@Sun.COM 
1436*11878SVenu.Iyer@Sun.COM dladm_stat_chain_t *
query_link_stats(dladm_handle_t dh,datalink_id_t linkid,void * arg,dladm_stat_type_t stattype)1437*11878SVenu.Iyer@Sun.COM query_link_stats(dladm_handle_t dh, datalink_id_t linkid, void *arg,
1438*11878SVenu.Iyer@Sun.COM     dladm_stat_type_t stattype)
1439*11878SVenu.Iyer@Sun.COM {
1440*11878SVenu.Iyer@Sun.COM 	link_chain_t		*link_node;
1441*11878SVenu.Iyer@Sun.COM 	dladm_stat_chain_t	*curr_stat;
1442*11878SVenu.Iyer@Sun.COM 	dladm_stat_chain_t	*prev_stat = NULL;
1443*11878SVenu.Iyer@Sun.COM 	dladm_stat_chain_t	*diff_stat = NULL;
1444*11878SVenu.Iyer@Sun.COM 
1445*11878SVenu.Iyer@Sun.COM 	/*  Get prev iteration stat for this link */
1446*11878SVenu.Iyer@Sun.COM 	link_node = get_link_prev_stat(linkid, arg);
1447*11878SVenu.Iyer@Sun.COM 	if (link_node == NULL)
1448*11878SVenu.Iyer@Sun.COM 		goto done;
1449*11878SVenu.Iyer@Sun.COM 
1450*11878SVenu.Iyer@Sun.COM 	link_node->lc_visited = B_TRUE;
1451*11878SVenu.Iyer@Sun.COM 	prev_stat = link_node->lc_statchain[stattype];
1452*11878SVenu.Iyer@Sun.COM 
1453*11878SVenu.Iyer@Sun.COM 	/* Query library for current stats */
1454*11878SVenu.Iyer@Sun.COM 	curr_stat = dladm_link_stat_query(dh, linkid, stattype);
1455*11878SVenu.Iyer@Sun.COM 	if (curr_stat == NULL)
1456*11878SVenu.Iyer@Sun.COM 		goto done;
1457*11878SVenu.Iyer@Sun.COM 
1458*11878SVenu.Iyer@Sun.COM 	/* current stats - prev iteration stats */
1459*11878SVenu.Iyer@Sun.COM 	diff_stat = dladm_link_stat_diffchain(curr_stat, prev_stat, stattype);
1460*11878SVenu.Iyer@Sun.COM 
1461*11878SVenu.Iyer@Sun.COM 	/* Free prev stats */
1462*11878SVenu.Iyer@Sun.COM 	dladm_link_stat_free(prev_stat);
1463*11878SVenu.Iyer@Sun.COM 
1464*11878SVenu.Iyer@Sun.COM 	/* Prev <- curr stats */
1465*11878SVenu.Iyer@Sun.COM 	link_node->lc_statchain[stattype] = curr_stat;
1466*11878SVenu.Iyer@Sun.COM 
1467*11878SVenu.Iyer@Sun.COM done:
1468*11878SVenu.Iyer@Sun.COM 	return (diff_stat);
1469*11878SVenu.Iyer@Sun.COM }
1470*11878SVenu.Iyer@Sun.COM 
1471*11878SVenu.Iyer@Sun.COM void
walk_dlstat_stats(show_state_t * state,const char * linkname,dladm_stat_type_t stattype,dladm_stat_chain_t * diff_stat)1472*11878SVenu.Iyer@Sun.COM walk_dlstat_stats(show_state_t *state, const char *linkname,
1473*11878SVenu.Iyer@Sun.COM     dladm_stat_type_t stattype, dladm_stat_chain_t *diff_stat)
1474*11878SVenu.Iyer@Sun.COM {
1475*11878SVenu.Iyer@Sun.COM 	dladm_stat_chain_t  *curr;
1476*11878SVenu.Iyer@Sun.COM 
1477*11878SVenu.Iyer@Sun.COM 	/* Unpack invidual stat entry and call library consumer's callback */
1478*11878SVenu.Iyer@Sun.COM 	for (curr = diff_stat; curr != NULL; curr = curr->dc_next) {
1479*11878SVenu.Iyer@Sun.COM 		void	*fields_buf;
1480*11878SVenu.Iyer@Sun.COM 
1481*11878SVenu.Iyer@Sun.COM 		/* Format the raw numbers for printing */
1482*11878SVenu.Iyer@Sun.COM 		fields_buf = state->ls_stats2str[stattype](linkname,
1483*11878SVenu.Iyer@Sun.COM 		    curr->dc_statentry, state->ls_unit, state->ls_parsable);
1484*11878SVenu.Iyer@Sun.COM 		/* Print the stats */
1485*11878SVenu.Iyer@Sun.COM 		if (fields_buf != NULL)
1486*11878SVenu.Iyer@Sun.COM 			ofmt_print(state->ls_ofmt, fields_buf);
1487*11878SVenu.Iyer@Sun.COM 		free(fields_buf);
1488*11878SVenu.Iyer@Sun.COM 	}
1489*11878SVenu.Iyer@Sun.COM }
1490*11878SVenu.Iyer@Sun.COM 
1491*11878SVenu.Iyer@Sun.COM static int
show_queried_stats(dladm_handle_t dh,datalink_id_t linkid,void * arg)1492*11878SVenu.Iyer@Sun.COM show_queried_stats(dladm_handle_t dh, datalink_id_t linkid, void *arg)
1493*11878SVenu.Iyer@Sun.COM {
1494*11878SVenu.Iyer@Sun.COM 	show_state_t		*state = arg;
1495*11878SVenu.Iyer@Sun.COM 	int 			i;
1496*11878SVenu.Iyer@Sun.COM 	dladm_stat_chain_t	*diff_stat;
1497*11878SVenu.Iyer@Sun.COM 	char			linkname[DLPI_LINKNAME_MAX];
1498*11878SVenu.Iyer@Sun.COM 
1499*11878SVenu.Iyer@Sun.COM 	if (dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, linkname,
1500*11878SVenu.Iyer@Sun.COM 	    DLPI_LINKNAME_MAX) != DLADM_STATUS_OK) {
1501*11878SVenu.Iyer@Sun.COM 		goto done;
1502*11878SVenu.Iyer@Sun.COM 	}
1503*11878SVenu.Iyer@Sun.COM 
1504*11878SVenu.Iyer@Sun.COM 	for (i = 0; i < DLADM_STAT_NUM_STATS; i++) {
1505*11878SVenu.Iyer@Sun.COM 		if (state->ls_stattype[i]) {
1506*11878SVenu.Iyer@Sun.COM 			/*
1507*11878SVenu.Iyer@Sun.COM 			 * Query library for stats
1508*11878SVenu.Iyer@Sun.COM 			 * Stats are returned as chain of raw numbers
1509*11878SVenu.Iyer@Sun.COM 			 */
1510*11878SVenu.Iyer@Sun.COM 			diff_stat = query_link_stats(handle, linkid, arg, i);
1511*11878SVenu.Iyer@Sun.COM 			walk_dlstat_stats(state, linkname, i, diff_stat);
1512*11878SVenu.Iyer@Sun.COM 			dladm_link_stat_free(diff_stat);
1513*11878SVenu.Iyer@Sun.COM 		}
1514*11878SVenu.Iyer@Sun.COM 	}
1515*11878SVenu.Iyer@Sun.COM done:
1516*11878SVenu.Iyer@Sun.COM 	return (DLADM_WALK_CONTINUE);
1517*11878SVenu.Iyer@Sun.COM }
1518*11878SVenu.Iyer@Sun.COM 
1519*11878SVenu.Iyer@Sun.COM void
show_link_stats(datalink_id_t linkid,show_state_t state,uint32_t interval)1520*11878SVenu.Iyer@Sun.COM show_link_stats(datalink_id_t linkid, show_state_t state, uint32_t interval)
1521*11878SVenu.Iyer@Sun.COM {
1522*11878SVenu.Iyer@Sun.COM 	for (;;) {
1523*11878SVenu.Iyer@Sun.COM 		if (linkid == DATALINK_ALL_LINKID) {
1524*11878SVenu.Iyer@Sun.COM 			(void) dladm_walk_datalink_id(show_queried_stats,
1525*11878SVenu.Iyer@Sun.COM 			    handle, &state, DATALINK_CLASS_ALL,
1526*11878SVenu.Iyer@Sun.COM 			    DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE);
1527*11878SVenu.Iyer@Sun.COM 		} else {
1528*11878SVenu.Iyer@Sun.COM 			(void) show_queried_stats(handle, linkid, &state);
1529*11878SVenu.Iyer@Sun.COM 		}
1530*11878SVenu.Iyer@Sun.COM 
1531*11878SVenu.Iyer@Sun.COM 		if (interval == 0)
1532*11878SVenu.Iyer@Sun.COM 			break;
1533*11878SVenu.Iyer@Sun.COM 
1534*11878SVenu.Iyer@Sun.COM 		cleanup_removed_links(&state);
1535*11878SVenu.Iyer@Sun.COM 		(void) sleep(interval);
1536*11878SVenu.Iyer@Sun.COM 	}
1537*11878SVenu.Iyer@Sun.COM }
1538*11878SVenu.Iyer@Sun.COM 
1539*11878SVenu.Iyer@Sun.COM void
print_all_stats(dladm_handle_t dh,datalink_id_t linkid,dladm_stat_chain_t * stat_chain)1540*11878SVenu.Iyer@Sun.COM print_all_stats(dladm_handle_t dh, datalink_id_t linkid,
1541*11878SVenu.Iyer@Sun.COM     dladm_stat_chain_t *stat_chain)
1542*11878SVenu.Iyer@Sun.COM {
1543*11878SVenu.Iyer@Sun.COM 	dladm_stat_chain_t	*curr;
1544*11878SVenu.Iyer@Sun.COM 	name_value_stat_entry_t	*stat_entry;
1545*11878SVenu.Iyer@Sun.COM 	name_value_stat_t	*curr_stat;
1546*11878SVenu.Iyer@Sun.COM 	boolean_t		stat_printed = B_FALSE;
1547*11878SVenu.Iyer@Sun.COM 	char			linkname[MAXLINKNAMELEN];
1548*11878SVenu.Iyer@Sun.COM 	char			prev_linkname[MAXLINKNAMELEN];
1549*11878SVenu.Iyer@Sun.COM 
1550*11878SVenu.Iyer@Sun.COM 	if (dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, linkname,
1551*11878SVenu.Iyer@Sun.COM 	    DLPI_LINKNAME_MAX) != DLADM_STATUS_OK)
1552*11878SVenu.Iyer@Sun.COM 		return;
1553*11878SVenu.Iyer@Sun.COM 
1554*11878SVenu.Iyer@Sun.COM 	for (curr = stat_chain; curr != NULL; curr = curr->dc_next) {
1555*11878SVenu.Iyer@Sun.COM 		stat_entry = curr->dc_statentry;
1556*11878SVenu.Iyer@Sun.COM 		/*
1557*11878SVenu.Iyer@Sun.COM 		 * Print header
1558*11878SVenu.Iyer@Sun.COM 		 * If link name is already printed in previous iteration,
1559*11878SVenu.Iyer@Sun.COM 		 * don't print again
1560*11878SVenu.Iyer@Sun.COM 		 */
1561*11878SVenu.Iyer@Sun.COM 		if (strcmp(prev_linkname, linkname) != 0)
1562*11878SVenu.Iyer@Sun.COM 			printf("%s \n", linkname);
1563*11878SVenu.Iyer@Sun.COM 		printf("  %s \n", stat_entry->nve_header);
1564*11878SVenu.Iyer@Sun.COM 
1565*11878SVenu.Iyer@Sun.COM 		/* Print stat fields */
1566*11878SVenu.Iyer@Sun.COM 		for (curr_stat = stat_entry->nve_stats; curr_stat != NULL;
1567*11878SVenu.Iyer@Sun.COM 		    curr_stat = curr_stat->nv_nextstat) {
1568*11878SVenu.Iyer@Sun.COM 			printf("\t%15s", curr_stat->nv_statname);
1569*11878SVenu.Iyer@Sun.COM 			printf("\t\t%15llu\n", curr_stat->nv_statval);
1570*11878SVenu.Iyer@Sun.COM 		}
1571*11878SVenu.Iyer@Sun.COM 
1572*11878SVenu.Iyer@Sun.COM 		strncpy(prev_linkname, linkname, MAXLINKNAMELEN);
1573*11878SVenu.Iyer@Sun.COM 		stat_printed = B_TRUE;
1574*11878SVenu.Iyer@Sun.COM 	}
1575*11878SVenu.Iyer@Sun.COM 	if (stat_printed)
1576*11878SVenu.Iyer@Sun.COM 		printf("---------------------------------------------------\n");
1577*11878SVenu.Iyer@Sun.COM }
1578*11878SVenu.Iyer@Sun.COM 
1579*11878SVenu.Iyer@Sun.COM static int
dump_queried_stats(dladm_handle_t dh,datalink_id_t linkid,void * arg)1580*11878SVenu.Iyer@Sun.COM dump_queried_stats(dladm_handle_t dh, datalink_id_t linkid, void *arg)
1581*11878SVenu.Iyer@Sun.COM {
1582*11878SVenu.Iyer@Sun.COM 	boolean_t		*stattype = arg;
1583*11878SVenu.Iyer@Sun.COM 	int			i;
1584*11878SVenu.Iyer@Sun.COM 	dladm_stat_chain_t	*stat_chain;
1585*11878SVenu.Iyer@Sun.COM 
1586*11878SVenu.Iyer@Sun.COM 	for (i = 0; i < DLADM_STAT_NUM_STATS; i++) {
1587*11878SVenu.Iyer@Sun.COM 		if (stattype[i]) {
1588*11878SVenu.Iyer@Sun.COM 			stat_chain = dladm_link_stat_query_all(dh, linkid, i);
1589*11878SVenu.Iyer@Sun.COM 			print_all_stats(dh, linkid, stat_chain);
1590*11878SVenu.Iyer@Sun.COM 			dladm_link_stat_query_all_free(stat_chain);
1591*11878SVenu.Iyer@Sun.COM 		}
1592*11878SVenu.Iyer@Sun.COM 	}
1593*11878SVenu.Iyer@Sun.COM done:
1594*11878SVenu.Iyer@Sun.COM 	return (DLADM_WALK_CONTINUE);
1595*11878SVenu.Iyer@Sun.COM }
1596*11878SVenu.Iyer@Sun.COM 
1597*11878SVenu.Iyer@Sun.COM void
dump_all_link_stats(datalink_id_t linkid,boolean_t * stattype)1598*11878SVenu.Iyer@Sun.COM dump_all_link_stats(datalink_id_t linkid, boolean_t *stattype)
1599*11878SVenu.Iyer@Sun.COM {
1600*11878SVenu.Iyer@Sun.COM 	if (linkid == DATALINK_ALL_LINKID) {
1601*11878SVenu.Iyer@Sun.COM 		(void) dladm_walk_datalink_id(dump_queried_stats,
1602*11878SVenu.Iyer@Sun.COM 		    handle, stattype, DATALINK_CLASS_ALL,
1603*11878SVenu.Iyer@Sun.COM 		    DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE);
1604*11878SVenu.Iyer@Sun.COM 	} else {
1605*11878SVenu.Iyer@Sun.COM 		(void) dump_queried_stats(handle, linkid, stattype);
1606*11878SVenu.Iyer@Sun.COM 	}
1607*11878SVenu.Iyer@Sun.COM }
1608*11878SVenu.Iyer@Sun.COM 
1609*11878SVenu.Iyer@Sun.COM static void
do_show(int argc,char * argv[],const char * use)1610*11878SVenu.Iyer@Sun.COM do_show(int argc, char *argv[], const char *use)
1611*11878SVenu.Iyer@Sun.COM {
1612*11878SVenu.Iyer@Sun.COM 	int			option;
1613*11878SVenu.Iyer@Sun.COM 	boolean_t		r_arg = B_FALSE;
1614*11878SVenu.Iyer@Sun.COM 	boolean_t		t_arg = B_FALSE;
1615*11878SVenu.Iyer@Sun.COM 	boolean_t		i_arg = B_FALSE;
1616*11878SVenu.Iyer@Sun.COM 	boolean_t		p_arg = B_FALSE;
1617*11878SVenu.Iyer@Sun.COM 	boolean_t		o_arg = B_FALSE;
1618*11878SVenu.Iyer@Sun.COM 	boolean_t		u_arg = B_FALSE;
1619*11878SVenu.Iyer@Sun.COM 	boolean_t		a_arg = B_FALSE;
1620*11878SVenu.Iyer@Sun.COM 	boolean_t		A_arg = B_FALSE;
1621*11878SVenu.Iyer@Sun.COM 	uint32_t		flags = DLADM_OPT_ACTIVE;
1622*11878SVenu.Iyer@Sun.COM 	datalink_id_t		linkid = DATALINK_ALL_LINKID;
1623*11878SVenu.Iyer@Sun.COM 	uint32_t		interval = 0;
1624*11878SVenu.Iyer@Sun.COM 	char			unit = '\0';
1625*11878SVenu.Iyer@Sun.COM 	show_state_t		state;
1626*11878SVenu.Iyer@Sun.COM 	dladm_status_t		status;
1627*11878SVenu.Iyer@Sun.COM 	char			*fields_str = NULL;
1628*11878SVenu.Iyer@Sun.COM 	char			*o_fields_str = NULL;
1629*11878SVenu.Iyer@Sun.COM 
1630*11878SVenu.Iyer@Sun.COM 	char			*total_stat_fields =
1631*11878SVenu.Iyer@Sun.COM 	    "link,ipkts,rbytes,opkts,obytes";
1632*11878SVenu.Iyer@Sun.COM 	char			*rx_total_stat_fields =
1633*11878SVenu.Iyer@Sun.COM 	    "link,ipkts,rbytes,intrs,polls,ch<10,ch10-50,ch>50";
1634*11878SVenu.Iyer@Sun.COM 	char			*tx_total_stat_fields =
1635*11878SVenu.Iyer@Sun.COM 	    "link,opkts,obytes,blkcnt,ublkcnt";
1636*11878SVenu.Iyer@Sun.COM 
1637*11878SVenu.Iyer@Sun.COM 	ofmt_handle_t		ofmt;
1638*11878SVenu.Iyer@Sun.COM 	ofmt_status_t		oferr;
1639*11878SVenu.Iyer@Sun.COM 	uint_t			ofmtflags = OFMT_RIGHTJUST;
1640*11878SVenu.Iyer@Sun.COM 	ofmt_field_t 		*oftemplate;
1641*11878SVenu.Iyer@Sun.COM 
1642*11878SVenu.Iyer@Sun.COM 	bzero(&state, sizeof (state));
1643*11878SVenu.Iyer@Sun.COM 	opterr = 0;
1644*11878SVenu.Iyer@Sun.COM 	while ((option = getopt_long(argc, argv, ":rtaApi:o:u:",
1645*11878SVenu.Iyer@Sun.COM 	    NULL, NULL)) != -1) {
1646*11878SVenu.Iyer@Sun.COM 		switch (option) {
1647*11878SVenu.Iyer@Sun.COM 		case 'r':
1648*11878SVenu.Iyer@Sun.COM 			if (r_arg)
1649*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
1650*11878SVenu.Iyer@Sun.COM 
1651*11878SVenu.Iyer@Sun.COM 			r_arg = B_TRUE;
1652*11878SVenu.Iyer@Sun.COM 			break;
1653*11878SVenu.Iyer@Sun.COM 		case 't':
1654*11878SVenu.Iyer@Sun.COM 			if (t_arg)
1655*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
1656*11878SVenu.Iyer@Sun.COM 
1657*11878SVenu.Iyer@Sun.COM 			t_arg = B_TRUE;
1658*11878SVenu.Iyer@Sun.COM 			break;
1659*11878SVenu.Iyer@Sun.COM 		case 'a':
1660*11878SVenu.Iyer@Sun.COM 			if (a_arg)
1661*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
1662*11878SVenu.Iyer@Sun.COM 
1663*11878SVenu.Iyer@Sun.COM 			a_arg = B_TRUE;
1664*11878SVenu.Iyer@Sun.COM 			break;
1665*11878SVenu.Iyer@Sun.COM 		case 'A':
1666*11878SVenu.Iyer@Sun.COM 			if (A_arg)
1667*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
1668*11878SVenu.Iyer@Sun.COM 
1669*11878SVenu.Iyer@Sun.COM 			A_arg = B_TRUE;
1670*11878SVenu.Iyer@Sun.COM 			break;
1671*11878SVenu.Iyer@Sun.COM 		case 'i':
1672*11878SVenu.Iyer@Sun.COM 			if (i_arg)
1673*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
1674*11878SVenu.Iyer@Sun.COM 
1675*11878SVenu.Iyer@Sun.COM 			i_arg = B_TRUE;
1676*11878SVenu.Iyer@Sun.COM 			if (!dladm_str2interval(optarg, &interval))
1677*11878SVenu.Iyer@Sun.COM 				die("invalid interval value '%s'", optarg);
1678*11878SVenu.Iyer@Sun.COM 			break;
1679*11878SVenu.Iyer@Sun.COM 		case 'p':
1680*11878SVenu.Iyer@Sun.COM 			if (p_arg)
1681*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
1682*11878SVenu.Iyer@Sun.COM 
1683*11878SVenu.Iyer@Sun.COM 			p_arg = B_TRUE;
1684*11878SVenu.Iyer@Sun.COM 			break;
1685*11878SVenu.Iyer@Sun.COM 		case 'o':
1686*11878SVenu.Iyer@Sun.COM 			o_arg = B_TRUE;
1687*11878SVenu.Iyer@Sun.COM 			o_fields_str = optarg;
1688*11878SVenu.Iyer@Sun.COM 			break;
1689*11878SVenu.Iyer@Sun.COM 		case 'u':
1690*11878SVenu.Iyer@Sun.COM 			if (u_arg)
1691*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
1692*11878SVenu.Iyer@Sun.COM 
1693*11878SVenu.Iyer@Sun.COM 			u_arg = B_TRUE;
1694*11878SVenu.Iyer@Sun.COM 			if (!dlstat_unit(optarg, &unit))
1695*11878SVenu.Iyer@Sun.COM 				die("invalid unit value '%s',"
1696*11878SVenu.Iyer@Sun.COM 				    "unit must be R|K|M|G|T|P", optarg);
1697*11878SVenu.Iyer@Sun.COM 			break;
1698*11878SVenu.Iyer@Sun.COM 		default:
1699*11878SVenu.Iyer@Sun.COM 			die_opterr(optopt, option, use);
1700*11878SVenu.Iyer@Sun.COM 			break;
1701*11878SVenu.Iyer@Sun.COM 		}
1702*11878SVenu.Iyer@Sun.COM 	}
1703*11878SVenu.Iyer@Sun.COM 
1704*11878SVenu.Iyer@Sun.COM 	if (r_arg && t_arg)
1705*11878SVenu.Iyer@Sun.COM 		die("the options -t and -r are not compatible");
1706*11878SVenu.Iyer@Sun.COM 
1707*11878SVenu.Iyer@Sun.COM 	if (u_arg && p_arg)
1708*11878SVenu.Iyer@Sun.COM 		die("the options -u and -p are not compatible");
1709*11878SVenu.Iyer@Sun.COM 
1710*11878SVenu.Iyer@Sun.COM 	if (p_arg && !o_arg)
1711*11878SVenu.Iyer@Sun.COM 		die("-p requires -o");
1712*11878SVenu.Iyer@Sun.COM 
1713*11878SVenu.Iyer@Sun.COM 	if (p_arg && strcasecmp(o_fields_str, "all") == 0)
1714*11878SVenu.Iyer@Sun.COM 		die("\"-o all\" is invalid with -p");
1715*11878SVenu.Iyer@Sun.COM 
1716*11878SVenu.Iyer@Sun.COM 	if (a_arg && A_arg)
1717*11878SVenu.Iyer@Sun.COM 		die("the options -a and -A are not compatible");
1718*11878SVenu.Iyer@Sun.COM 
1719*11878SVenu.Iyer@Sun.COM 	if (a_arg &&
1720*11878SVenu.Iyer@Sun.COM 	    (p_arg || o_arg || u_arg || i_arg)) {
1721*11878SVenu.Iyer@Sun.COM 		die("the option -a is not compatible with "
1722*11878SVenu.Iyer@Sun.COM 		    "-p, -o, -u, -i");
1723*11878SVenu.Iyer@Sun.COM 	}
1724*11878SVenu.Iyer@Sun.COM 
1725*11878SVenu.Iyer@Sun.COM 	if (A_arg &&
1726*11878SVenu.Iyer@Sun.COM 	    (r_arg || t_arg || p_arg || o_arg || u_arg || i_arg)) {
1727*11878SVenu.Iyer@Sun.COM 		die("the option -A is not compatible with "
1728*11878SVenu.Iyer@Sun.COM 		    "-r, -t, -p, -o, -u, -i");
1729*11878SVenu.Iyer@Sun.COM 	}
1730*11878SVenu.Iyer@Sun.COM 
1731*11878SVenu.Iyer@Sun.COM 	/* get link name (optional last argument) */
1732*11878SVenu.Iyer@Sun.COM 	if (optind == (argc-1)) {
1733*11878SVenu.Iyer@Sun.COM 		if (strlen(argv[optind]) >= MAXLINKNAMELEN)
1734*11878SVenu.Iyer@Sun.COM 			die("link name too long");
1735*11878SVenu.Iyer@Sun.COM 
1736*11878SVenu.Iyer@Sun.COM 		if ((status = dladm_name2info(handle, argv[optind], &linkid,
1737*11878SVenu.Iyer@Sun.COM 		    NULL, NULL, NULL)) != DLADM_STATUS_OK) {
1738*11878SVenu.Iyer@Sun.COM 			die_dlerr(status, "link %s is not valid", argv[optind]);
1739*11878SVenu.Iyer@Sun.COM 		}
1740*11878SVenu.Iyer@Sun.COM 	} else if (optind != argc) {
1741*11878SVenu.Iyer@Sun.COM 		if (argc != 0)
1742*11878SVenu.Iyer@Sun.COM 			usage();
1743*11878SVenu.Iyer@Sun.COM 	}
1744*11878SVenu.Iyer@Sun.COM 
1745*11878SVenu.Iyer@Sun.COM 	if (a_arg) {
1746*11878SVenu.Iyer@Sun.COM 		boolean_t	stattype[DLADM_STAT_NUM_STATS];
1747*11878SVenu.Iyer@Sun.COM 
1748*11878SVenu.Iyer@Sun.COM 		bzero(&stattype, sizeof (stattype));
1749*11878SVenu.Iyer@Sun.COM 		if (r_arg) {
1750*11878SVenu.Iyer@Sun.COM 			stattype[DLADM_STAT_RX_LANE_TOTAL] = B_TRUE;
1751*11878SVenu.Iyer@Sun.COM 		} else if (t_arg) {
1752*11878SVenu.Iyer@Sun.COM 			stattype[DLADM_STAT_TX_LANE_TOTAL] = B_TRUE;
1753*11878SVenu.Iyer@Sun.COM 		} else {		/* Display both Rx and Tx lanes */
1754*11878SVenu.Iyer@Sun.COM 			stattype[DLADM_STAT_TOTAL] = B_TRUE;
1755*11878SVenu.Iyer@Sun.COM 		}
1756*11878SVenu.Iyer@Sun.COM 
1757*11878SVenu.Iyer@Sun.COM 		dump_all_link_stats(linkid, stattype);
1758*11878SVenu.Iyer@Sun.COM 		return;
1759*11878SVenu.Iyer@Sun.COM 	}
1760*11878SVenu.Iyer@Sun.COM 
1761*11878SVenu.Iyer@Sun.COM 	if (A_arg) {
1762*11878SVenu.Iyer@Sun.COM 		boolean_t	stattype[DLADM_STAT_NUM_STATS];
1763*11878SVenu.Iyer@Sun.COM 		int		i;
1764*11878SVenu.Iyer@Sun.COM 
1765*11878SVenu.Iyer@Sun.COM 		for (i = 0; i < DLADM_STAT_NUM_STATS; i++)
1766*11878SVenu.Iyer@Sun.COM 			stattype[i] = B_TRUE;
1767*11878SVenu.Iyer@Sun.COM 
1768*11878SVenu.Iyer@Sun.COM 		dump_all_link_stats(linkid, stattype);
1769*11878SVenu.Iyer@Sun.COM 		return;
1770*11878SVenu.Iyer@Sun.COM 	}
1771*11878SVenu.Iyer@Sun.COM 
1772*11878SVenu.Iyer@Sun.COM 	state.ls_unit = unit;
1773*11878SVenu.Iyer@Sun.COM 	state.ls_parsable = p_arg;
1774*11878SVenu.Iyer@Sun.COM 
1775*11878SVenu.Iyer@Sun.COM 	if (state.ls_parsable)
1776*11878SVenu.Iyer@Sun.COM 		ofmtflags |= OFMT_PARSABLE;
1777*11878SVenu.Iyer@Sun.COM 
1778*11878SVenu.Iyer@Sun.COM 	if (r_arg) {
1779*11878SVenu.Iyer@Sun.COM 		fields_str = rx_total_stat_fields;
1780*11878SVenu.Iyer@Sun.COM 		oftemplate = rx_lane_s_fields;
1781*11878SVenu.Iyer@Sun.COM 		state.ls_stattype[DLADM_STAT_RX_LANE_TOTAL] = B_TRUE;
1782*11878SVenu.Iyer@Sun.COM 		state.ls_stats2str[DLADM_STAT_RX_LANE_TOTAL] =
1783*11878SVenu.Iyer@Sun.COM 		    print_rx_lane_stats;
1784*11878SVenu.Iyer@Sun.COM 	} else if (t_arg) {
1785*11878SVenu.Iyer@Sun.COM 		fields_str = tx_total_stat_fields;
1786*11878SVenu.Iyer@Sun.COM 		oftemplate = tx_lane_s_fields;
1787*11878SVenu.Iyer@Sun.COM 		state.ls_stattype[DLADM_STAT_TX_LANE_TOTAL] = B_TRUE;
1788*11878SVenu.Iyer@Sun.COM 		state.ls_stats2str[DLADM_STAT_TX_LANE_TOTAL] =
1789*11878SVenu.Iyer@Sun.COM 		    print_tx_lane_stats;
1790*11878SVenu.Iyer@Sun.COM 	} else {		/* Display both Rx and Tx lanes total */
1791*11878SVenu.Iyer@Sun.COM 		fields_str = total_stat_fields;
1792*11878SVenu.Iyer@Sun.COM 		oftemplate = total_s_fields;
1793*11878SVenu.Iyer@Sun.COM 		state.ls_stattype[DLADM_STAT_TOTAL] = B_TRUE;
1794*11878SVenu.Iyer@Sun.COM 		state.ls_stats2str[DLADM_STAT_TOTAL] = print_total_stats;
1795*11878SVenu.Iyer@Sun.COM 	}
1796*11878SVenu.Iyer@Sun.COM 
1797*11878SVenu.Iyer@Sun.COM 	if (o_arg) {
1798*11878SVenu.Iyer@Sun.COM 		fields_str = (strcasecmp(o_fields_str, "all") == 0) ?
1799*11878SVenu.Iyer@Sun.COM 		    fields_str : o_fields_str;
1800*11878SVenu.Iyer@Sun.COM 	}
1801*11878SVenu.Iyer@Sun.COM 
1802*11878SVenu.Iyer@Sun.COM 	oferr = ofmt_open(fields_str, oftemplate, ofmtflags, 0, &ofmt);
1803*11878SVenu.Iyer@Sun.COM 	dlstat_ofmt_check(oferr, state.ls_parsable, ofmt);
1804*11878SVenu.Iyer@Sun.COM 	state.ls_ofmt = ofmt;
1805*11878SVenu.Iyer@Sun.COM 
1806*11878SVenu.Iyer@Sun.COM 	show_link_stats(linkid, state, interval);
1807*11878SVenu.Iyer@Sun.COM 
1808*11878SVenu.Iyer@Sun.COM 	ofmt_close(ofmt);
1809*11878SVenu.Iyer@Sun.COM }
1810*11878SVenu.Iyer@Sun.COM 
1811*11878SVenu.Iyer@Sun.COM static void
do_show_phys(int argc,char * argv[],const char * use)1812*11878SVenu.Iyer@Sun.COM do_show_phys(int argc, char *argv[], const char *use)
1813*11878SVenu.Iyer@Sun.COM {
1814*11878SVenu.Iyer@Sun.COM 	int			option;
1815*11878SVenu.Iyer@Sun.COM 	boolean_t		r_arg = B_FALSE;
1816*11878SVenu.Iyer@Sun.COM 	boolean_t		t_arg = B_FALSE;
1817*11878SVenu.Iyer@Sun.COM 	boolean_t		i_arg = B_FALSE;
1818*11878SVenu.Iyer@Sun.COM 	boolean_t		p_arg = B_FALSE;
1819*11878SVenu.Iyer@Sun.COM 	boolean_t		o_arg = B_FALSE;
1820*11878SVenu.Iyer@Sun.COM 	boolean_t		u_arg = B_FALSE;
1821*11878SVenu.Iyer@Sun.COM 	boolean_t		a_arg = B_FALSE;
1822*11878SVenu.Iyer@Sun.COM 	uint32_t		flags = DLADM_OPT_ACTIVE;
1823*11878SVenu.Iyer@Sun.COM 	datalink_id_t		linkid = DATALINK_ALL_LINKID;
1824*11878SVenu.Iyer@Sun.COM 	char			linkname[MAXLINKNAMELEN];
1825*11878SVenu.Iyer@Sun.COM 	uint32_t		interval = 0;
1826*11878SVenu.Iyer@Sun.COM 	char			unit = '\0';
1827*11878SVenu.Iyer@Sun.COM 	show_state_t		state;
1828*11878SVenu.Iyer@Sun.COM 	dladm_status_t		status;
1829*11878SVenu.Iyer@Sun.COM 	char			*fields_str = NULL;
1830*11878SVenu.Iyer@Sun.COM 	char			*o_fields_str = NULL;
1831*11878SVenu.Iyer@Sun.COM 	char			*ring_stat_fields =
1832*11878SVenu.Iyer@Sun.COM 	    "link,type,index,pkts,bytes";
1833*11878SVenu.Iyer@Sun.COM 	char			*rx_ring_stat_fields =
1834*11878SVenu.Iyer@Sun.COM 	    "link,type,index,ipkts,rbytes";
1835*11878SVenu.Iyer@Sun.COM 	char			*tx_ring_stat_fields =
1836*11878SVenu.Iyer@Sun.COM 	    "link,type,index,opkts,obytes";
1837*11878SVenu.Iyer@Sun.COM 
1838*11878SVenu.Iyer@Sun.COM 	ofmt_handle_t		ofmt;
1839*11878SVenu.Iyer@Sun.COM 	ofmt_status_t		oferr;
1840*11878SVenu.Iyer@Sun.COM 	uint_t			ofmtflags = OFMT_RIGHTJUST;
1841*11878SVenu.Iyer@Sun.COM 	ofmt_field_t 		*oftemplate;
1842*11878SVenu.Iyer@Sun.COM 
1843*11878SVenu.Iyer@Sun.COM 	bzero(&state, sizeof (state));
1844*11878SVenu.Iyer@Sun.COM 	opterr = 0;
1845*11878SVenu.Iyer@Sun.COM 	while ((option = getopt_long(argc, argv, ":rtapi:o:u:",
1846*11878SVenu.Iyer@Sun.COM 	    NULL, NULL)) != -1) {
1847*11878SVenu.Iyer@Sun.COM 		switch (option) {
1848*11878SVenu.Iyer@Sun.COM 		case 'r':
1849*11878SVenu.Iyer@Sun.COM 			if (r_arg)
1850*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
1851*11878SVenu.Iyer@Sun.COM 
1852*11878SVenu.Iyer@Sun.COM 			r_arg = B_TRUE;
1853*11878SVenu.Iyer@Sun.COM 			break;
1854*11878SVenu.Iyer@Sun.COM 		case 't':
1855*11878SVenu.Iyer@Sun.COM 			if (t_arg)
1856*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
1857*11878SVenu.Iyer@Sun.COM 
1858*11878SVenu.Iyer@Sun.COM 			t_arg = B_TRUE;
1859*11878SVenu.Iyer@Sun.COM 			break;
1860*11878SVenu.Iyer@Sun.COM 		case 'a':
1861*11878SVenu.Iyer@Sun.COM 			if (a_arg)
1862*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
1863*11878SVenu.Iyer@Sun.COM 
1864*11878SVenu.Iyer@Sun.COM 			a_arg = B_TRUE;
1865*11878SVenu.Iyer@Sun.COM 			break;
1866*11878SVenu.Iyer@Sun.COM 		case 'i':
1867*11878SVenu.Iyer@Sun.COM 			if (i_arg)
1868*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
1869*11878SVenu.Iyer@Sun.COM 
1870*11878SVenu.Iyer@Sun.COM 			i_arg = B_TRUE;
1871*11878SVenu.Iyer@Sun.COM 			if (!dladm_str2interval(optarg, &interval))
1872*11878SVenu.Iyer@Sun.COM 				die("invalid interval value '%s'", optarg);
1873*11878SVenu.Iyer@Sun.COM 			break;
1874*11878SVenu.Iyer@Sun.COM 		case 'p':
1875*11878SVenu.Iyer@Sun.COM 			if (p_arg)
1876*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
1877*11878SVenu.Iyer@Sun.COM 
1878*11878SVenu.Iyer@Sun.COM 			p_arg = B_TRUE;
1879*11878SVenu.Iyer@Sun.COM 			break;
1880*11878SVenu.Iyer@Sun.COM 		case 'o':
1881*11878SVenu.Iyer@Sun.COM 			o_arg = B_TRUE;
1882*11878SVenu.Iyer@Sun.COM 			o_fields_str = optarg;
1883*11878SVenu.Iyer@Sun.COM 			break;
1884*11878SVenu.Iyer@Sun.COM 		case 'u':
1885*11878SVenu.Iyer@Sun.COM 			if (u_arg)
1886*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
1887*11878SVenu.Iyer@Sun.COM 
1888*11878SVenu.Iyer@Sun.COM 			u_arg = B_TRUE;
1889*11878SVenu.Iyer@Sun.COM 			if (!dlstat_unit(optarg, &unit))
1890*11878SVenu.Iyer@Sun.COM 				die("invalid unit value '%s',"
1891*11878SVenu.Iyer@Sun.COM 				    "unit must be R|K|M|G|T|P", optarg);
1892*11878SVenu.Iyer@Sun.COM 			break;
1893*11878SVenu.Iyer@Sun.COM 		default:
1894*11878SVenu.Iyer@Sun.COM 			die_opterr(optopt, option, use);
1895*11878SVenu.Iyer@Sun.COM 			break;
1896*11878SVenu.Iyer@Sun.COM 		}
1897*11878SVenu.Iyer@Sun.COM 	}
1898*11878SVenu.Iyer@Sun.COM 
1899*11878SVenu.Iyer@Sun.COM 	if (r_arg && t_arg)
1900*11878SVenu.Iyer@Sun.COM 		die("the options -t and -r are not compatible");
1901*11878SVenu.Iyer@Sun.COM 
1902*11878SVenu.Iyer@Sun.COM 	if (u_arg && p_arg)
1903*11878SVenu.Iyer@Sun.COM 		die("the options -u and -p are not compatible");
1904*11878SVenu.Iyer@Sun.COM 
1905*11878SVenu.Iyer@Sun.COM 	if (p_arg && !o_arg)
1906*11878SVenu.Iyer@Sun.COM 		die("-p requires -o");
1907*11878SVenu.Iyer@Sun.COM 
1908*11878SVenu.Iyer@Sun.COM 	if (p_arg && strcasecmp(o_fields_str, "all") == 0)
1909*11878SVenu.Iyer@Sun.COM 		die("\"-o all\" is invalid with -p");
1910*11878SVenu.Iyer@Sun.COM 
1911*11878SVenu.Iyer@Sun.COM 	if (a_arg &&
1912*11878SVenu.Iyer@Sun.COM 	    (p_arg || o_arg || u_arg || i_arg)) {
1913*11878SVenu.Iyer@Sun.COM 		die("the option -a is not compatible with "
1914*11878SVenu.Iyer@Sun.COM 		    "-p, -o, -u, -i");
1915*11878SVenu.Iyer@Sun.COM 	}
1916*11878SVenu.Iyer@Sun.COM 
1917*11878SVenu.Iyer@Sun.COM 
1918*11878SVenu.Iyer@Sun.COM 	/* get link name (optional last argument) */
1919*11878SVenu.Iyer@Sun.COM 	if (optind == (argc-1)) {
1920*11878SVenu.Iyer@Sun.COM 		if (strlen(argv[optind]) >= MAXLINKNAMELEN)
1921*11878SVenu.Iyer@Sun.COM 			die("link name too long");
1922*11878SVenu.Iyer@Sun.COM 
1923*11878SVenu.Iyer@Sun.COM 		if ((status = dladm_name2info(handle, argv[optind], &linkid,
1924*11878SVenu.Iyer@Sun.COM 		    NULL, NULL, NULL)) != DLADM_STATUS_OK) {
1925*11878SVenu.Iyer@Sun.COM 			die_dlerr(status, "link %s is not valid", argv[optind]);
1926*11878SVenu.Iyer@Sun.COM 		}
1927*11878SVenu.Iyer@Sun.COM 	} else if (optind != argc) {
1928*11878SVenu.Iyer@Sun.COM 		usage();
1929*11878SVenu.Iyer@Sun.COM 	}
1930*11878SVenu.Iyer@Sun.COM 
1931*11878SVenu.Iyer@Sun.COM 	if (a_arg) {
1932*11878SVenu.Iyer@Sun.COM 		boolean_t	stattype[DLADM_STAT_NUM_STATS];
1933*11878SVenu.Iyer@Sun.COM 
1934*11878SVenu.Iyer@Sun.COM 		bzero(&stattype, sizeof (stattype));
1935*11878SVenu.Iyer@Sun.COM 
1936*11878SVenu.Iyer@Sun.COM 		if (r_arg) {
1937*11878SVenu.Iyer@Sun.COM 			stattype[DLADM_STAT_RX_RING] = B_TRUE;
1938*11878SVenu.Iyer@Sun.COM 		} else if (t_arg) {
1939*11878SVenu.Iyer@Sun.COM 			stattype[DLADM_STAT_TX_RING] = B_TRUE;
1940*11878SVenu.Iyer@Sun.COM 		} else {		/* Display both Rx and Tx lanes */
1941*11878SVenu.Iyer@Sun.COM 			stattype[DLADM_STAT_RX_RING] = B_TRUE;
1942*11878SVenu.Iyer@Sun.COM 			stattype[DLADM_STAT_TX_RING] = B_TRUE;
1943*11878SVenu.Iyer@Sun.COM 		}
1944*11878SVenu.Iyer@Sun.COM 
1945*11878SVenu.Iyer@Sun.COM 		dump_all_link_stats(linkid, stattype);
1946*11878SVenu.Iyer@Sun.COM 		return;
1947*11878SVenu.Iyer@Sun.COM 	}
1948*11878SVenu.Iyer@Sun.COM 
1949*11878SVenu.Iyer@Sun.COM 	state.ls_unit = unit;
1950*11878SVenu.Iyer@Sun.COM 	state.ls_parsable = p_arg;
1951*11878SVenu.Iyer@Sun.COM 
1952*11878SVenu.Iyer@Sun.COM 	if (state.ls_parsable)
1953*11878SVenu.Iyer@Sun.COM 		ofmtflags |= OFMT_PARSABLE;
1954*11878SVenu.Iyer@Sun.COM 
1955*11878SVenu.Iyer@Sun.COM 	if (r_arg) {
1956*11878SVenu.Iyer@Sun.COM 		fields_str = rx_ring_stat_fields;
1957*11878SVenu.Iyer@Sun.COM 		oftemplate = rx_ring_s_fields;
1958*11878SVenu.Iyer@Sun.COM 		state.ls_stattype[DLADM_STAT_RX_RING] = B_TRUE;
1959*11878SVenu.Iyer@Sun.COM 		state.ls_stats2str[DLADM_STAT_RX_RING] = print_rx_ring_stats;
1960*11878SVenu.Iyer@Sun.COM 	} else if (t_arg) {
1961*11878SVenu.Iyer@Sun.COM 		fields_str = tx_ring_stat_fields;
1962*11878SVenu.Iyer@Sun.COM 		oftemplate = tx_ring_s_fields;
1963*11878SVenu.Iyer@Sun.COM 		state.ls_stattype[DLADM_STAT_TX_RING] = B_TRUE;
1964*11878SVenu.Iyer@Sun.COM 		state.ls_stats2str[DLADM_STAT_TX_RING] = print_tx_ring_stats;
1965*11878SVenu.Iyer@Sun.COM 	} else {		/* Display both Rx and Tx lanes */
1966*11878SVenu.Iyer@Sun.COM 		fields_str = ring_stat_fields;
1967*11878SVenu.Iyer@Sun.COM 		oftemplate = ring_s_fields;
1968*11878SVenu.Iyer@Sun.COM 		state.ls_stattype[DLADM_STAT_RX_RING] = B_TRUE;
1969*11878SVenu.Iyer@Sun.COM 		state.ls_stattype[DLADM_STAT_TX_RING] = B_TRUE;
1970*11878SVenu.Iyer@Sun.COM 		state.ls_stats2str[DLADM_STAT_RX_RING] =
1971*11878SVenu.Iyer@Sun.COM 		    print_rx_generic_ring_stats;
1972*11878SVenu.Iyer@Sun.COM 		state.ls_stats2str[DLADM_STAT_TX_RING] =
1973*11878SVenu.Iyer@Sun.COM 		    print_tx_generic_ring_stats;
1974*11878SVenu.Iyer@Sun.COM 	}
1975*11878SVenu.Iyer@Sun.COM 
1976*11878SVenu.Iyer@Sun.COM 	if (o_arg) {
1977*11878SVenu.Iyer@Sun.COM 		fields_str = (strcasecmp(o_fields_str, "all") == 0) ?
1978*11878SVenu.Iyer@Sun.COM 		    fields_str : o_fields_str;
1979*11878SVenu.Iyer@Sun.COM 	}
1980*11878SVenu.Iyer@Sun.COM 
1981*11878SVenu.Iyer@Sun.COM 	oferr = ofmt_open(fields_str, oftemplate, ofmtflags, 0, &ofmt);
1982*11878SVenu.Iyer@Sun.COM 	dlstat_ofmt_check(oferr, state.ls_parsable, ofmt);
1983*11878SVenu.Iyer@Sun.COM 	state.ls_ofmt = ofmt;
1984*11878SVenu.Iyer@Sun.COM 
1985*11878SVenu.Iyer@Sun.COM 	show_link_stats(linkid, state, interval);
1986*11878SVenu.Iyer@Sun.COM 
1987*11878SVenu.Iyer@Sun.COM 	ofmt_close(ofmt);
1988*11878SVenu.Iyer@Sun.COM }
1989*11878SVenu.Iyer@Sun.COM 
1990*11878SVenu.Iyer@Sun.COM static void
do_show_link(int argc,char * argv[],const char * use)1991*11878SVenu.Iyer@Sun.COM do_show_link(int argc, char *argv[], const char *use)
1992*11878SVenu.Iyer@Sun.COM {
1993*11878SVenu.Iyer@Sun.COM 	int			option;
1994*11878SVenu.Iyer@Sun.COM 	boolean_t		r_arg = B_FALSE;
1995*11878SVenu.Iyer@Sun.COM 	boolean_t		F_arg = B_FALSE;
1996*11878SVenu.Iyer@Sun.COM 	boolean_t		t_arg = B_FALSE;
1997*11878SVenu.Iyer@Sun.COM 	boolean_t		i_arg = B_FALSE;
1998*11878SVenu.Iyer@Sun.COM 	boolean_t		p_arg = B_FALSE;
1999*11878SVenu.Iyer@Sun.COM 	boolean_t		o_arg = B_FALSE;
2000*11878SVenu.Iyer@Sun.COM 	boolean_t		u_arg = B_FALSE;
2001*11878SVenu.Iyer@Sun.COM 	boolean_t		a_arg = B_FALSE;
2002*11878SVenu.Iyer@Sun.COM 	uint32_t		flags = DLADM_OPT_ACTIVE;
2003*11878SVenu.Iyer@Sun.COM 	datalink_id_t		linkid = DATALINK_ALL_LINKID;
2004*11878SVenu.Iyer@Sun.COM 	uint32_t		interval = 0;
2005*11878SVenu.Iyer@Sun.COM 	char			unit = '\0';
2006*11878SVenu.Iyer@Sun.COM 	show_state_t		state;
2007*11878SVenu.Iyer@Sun.COM 	dladm_status_t		status;
2008*11878SVenu.Iyer@Sun.COM 	char			*fields_str = NULL;
2009*11878SVenu.Iyer@Sun.COM 	char			*o_fields_str = NULL;
2010*11878SVenu.Iyer@Sun.COM 
2011*11878SVenu.Iyer@Sun.COM 	char			*lane_stat_fields =
2012*11878SVenu.Iyer@Sun.COM 	    "link,type,id,index,pkts,bytes";
2013*11878SVenu.Iyer@Sun.COM 	char			*rx_lane_stat_fields =
2014*11878SVenu.Iyer@Sun.COM 	    "link,type,id,index,ipkts,rbytes,intrs,polls,ch<10,ch10-50,ch>50";
2015*11878SVenu.Iyer@Sun.COM 	char			*tx_lane_stat_fields =
2016*11878SVenu.Iyer@Sun.COM 	    "link,type,id,index,opkts,obytes,blkcnt,ublkcnt";
2017*11878SVenu.Iyer@Sun.COM 	char			*rx_fanout_stat_fields =
2018*11878SVenu.Iyer@Sun.COM 	    "link,id,index,fout,ipkts,rbytes";
2019*11878SVenu.Iyer@Sun.COM 
2020*11878SVenu.Iyer@Sun.COM 	ofmt_handle_t		ofmt;
2021*11878SVenu.Iyer@Sun.COM 	ofmt_status_t		oferr;
2022*11878SVenu.Iyer@Sun.COM 	uint_t			ofmtflags = OFMT_RIGHTJUST;
2023*11878SVenu.Iyer@Sun.COM 	ofmt_field_t 		*oftemplate;
2024*11878SVenu.Iyer@Sun.COM 
2025*11878SVenu.Iyer@Sun.COM 	bzero(&state, sizeof (state));
2026*11878SVenu.Iyer@Sun.COM 	opterr = 0;
2027*11878SVenu.Iyer@Sun.COM 	while ((option = getopt_long(argc, argv, ":hrtFapi:o:u:",
2028*11878SVenu.Iyer@Sun.COM 	    NULL, NULL)) != -1) {
2029*11878SVenu.Iyer@Sun.COM 		switch (option) {
2030*11878SVenu.Iyer@Sun.COM 		case 'h':
2031*11878SVenu.Iyer@Sun.COM 			if (r_arg || F_arg || t_arg || i_arg || p_arg ||
2032*11878SVenu.Iyer@Sun.COM 			    o_arg || u_arg || a_arg) {
2033*11878SVenu.Iyer@Sun.COM 				die("the option -h is not compatible with "
2034*11878SVenu.Iyer@Sun.COM 				    "-r, -F, -t, -i, -p, -o, -u, -a");
2035*11878SVenu.Iyer@Sun.COM 			}
2036*11878SVenu.Iyer@Sun.COM 			do_show_history(argc, &argv[0], use);
2037*11878SVenu.Iyer@Sun.COM 			return;
2038*11878SVenu.Iyer@Sun.COM 		case 'r':
2039*11878SVenu.Iyer@Sun.COM 			if (r_arg)
2040*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
2041*11878SVenu.Iyer@Sun.COM 
2042*11878SVenu.Iyer@Sun.COM 			r_arg = B_TRUE;
2043*11878SVenu.Iyer@Sun.COM 			break;
2044*11878SVenu.Iyer@Sun.COM 		case 'F':
2045*11878SVenu.Iyer@Sun.COM 			if (F_arg)
2046*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
2047*11878SVenu.Iyer@Sun.COM 
2048*11878SVenu.Iyer@Sun.COM 			F_arg = B_TRUE;
2049*11878SVenu.Iyer@Sun.COM 			break;
2050*11878SVenu.Iyer@Sun.COM 		case 't':
2051*11878SVenu.Iyer@Sun.COM 			if (t_arg)
2052*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
2053*11878SVenu.Iyer@Sun.COM 
2054*11878SVenu.Iyer@Sun.COM 			t_arg = B_TRUE;
2055*11878SVenu.Iyer@Sun.COM 			break;
2056*11878SVenu.Iyer@Sun.COM 		case 'a':
2057*11878SVenu.Iyer@Sun.COM 			if (a_arg)
2058*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
2059*11878SVenu.Iyer@Sun.COM 
2060*11878SVenu.Iyer@Sun.COM 			a_arg = B_TRUE;
2061*11878SVenu.Iyer@Sun.COM 			break;
2062*11878SVenu.Iyer@Sun.COM 		case 'i':
2063*11878SVenu.Iyer@Sun.COM 			if (i_arg)
2064*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
2065*11878SVenu.Iyer@Sun.COM 
2066*11878SVenu.Iyer@Sun.COM 			i_arg = B_TRUE;
2067*11878SVenu.Iyer@Sun.COM 			if (!dladm_str2interval(optarg, &interval))
2068*11878SVenu.Iyer@Sun.COM 				die("invalid interval value '%s'", optarg);
2069*11878SVenu.Iyer@Sun.COM 			break;
2070*11878SVenu.Iyer@Sun.COM 		case 'p':
2071*11878SVenu.Iyer@Sun.COM 			if (p_arg)
2072*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
2073*11878SVenu.Iyer@Sun.COM 
2074*11878SVenu.Iyer@Sun.COM 			p_arg = B_TRUE;
2075*11878SVenu.Iyer@Sun.COM 			break;
2076*11878SVenu.Iyer@Sun.COM 		case 'o':
2077*11878SVenu.Iyer@Sun.COM 			o_arg = B_TRUE;
2078*11878SVenu.Iyer@Sun.COM 			o_fields_str = optarg;
2079*11878SVenu.Iyer@Sun.COM 			break;
2080*11878SVenu.Iyer@Sun.COM 		case 'u':
2081*11878SVenu.Iyer@Sun.COM 			if (u_arg)
2082*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
2083*11878SVenu.Iyer@Sun.COM 
2084*11878SVenu.Iyer@Sun.COM 			u_arg = B_TRUE;
2085*11878SVenu.Iyer@Sun.COM 			if (!dlstat_unit(optarg, &unit))
2086*11878SVenu.Iyer@Sun.COM 				die("invalid unit value '%s',"
2087*11878SVenu.Iyer@Sun.COM 				    "unit must be R|K|M|G|T|P", optarg);
2088*11878SVenu.Iyer@Sun.COM 			break;
2089*11878SVenu.Iyer@Sun.COM 		default:
2090*11878SVenu.Iyer@Sun.COM 			die_opterr(optopt, option, use);
2091*11878SVenu.Iyer@Sun.COM 			break;
2092*11878SVenu.Iyer@Sun.COM 		}
2093*11878SVenu.Iyer@Sun.COM 	}
2094*11878SVenu.Iyer@Sun.COM 
2095*11878SVenu.Iyer@Sun.COM 	if (r_arg && t_arg)
2096*11878SVenu.Iyer@Sun.COM 		die("the options -t and -r are not compatible");
2097*11878SVenu.Iyer@Sun.COM 
2098*11878SVenu.Iyer@Sun.COM 	if (u_arg && p_arg)
2099*11878SVenu.Iyer@Sun.COM 		die("the options -u and -p are not compatible");
2100*11878SVenu.Iyer@Sun.COM 
2101*11878SVenu.Iyer@Sun.COM 	if (F_arg && !r_arg)
2102*11878SVenu.Iyer@Sun.COM 		die("-F must be used with -r");
2103*11878SVenu.Iyer@Sun.COM 
2104*11878SVenu.Iyer@Sun.COM 	if (p_arg && !o_arg)
2105*11878SVenu.Iyer@Sun.COM 		die("-p requires -o");
2106*11878SVenu.Iyer@Sun.COM 
2107*11878SVenu.Iyer@Sun.COM 	if (p_arg && strcasecmp(o_fields_str, "all") == 0)
2108*11878SVenu.Iyer@Sun.COM 		die("\"-o all\" is invalid with -p");
2109*11878SVenu.Iyer@Sun.COM 
2110*11878SVenu.Iyer@Sun.COM 	if (a_arg &&
2111*11878SVenu.Iyer@Sun.COM 	    (p_arg || o_arg || u_arg || i_arg)) {
2112*11878SVenu.Iyer@Sun.COM 		die("the option -a is not compatible with "
2113*11878SVenu.Iyer@Sun.COM 		    "-p, -o, -u, -i");
2114*11878SVenu.Iyer@Sun.COM 	}
2115*11878SVenu.Iyer@Sun.COM 
2116*11878SVenu.Iyer@Sun.COM 	/* get link name (optional last argument) */
2117*11878SVenu.Iyer@Sun.COM 	if (optind == (argc-1)) {
2118*11878SVenu.Iyer@Sun.COM 		if (strlen(argv[optind]) >= MAXLINKNAMELEN)
2119*11878SVenu.Iyer@Sun.COM 			die("link name too long");
2120*11878SVenu.Iyer@Sun.COM 
2121*11878SVenu.Iyer@Sun.COM 		if ((status = dladm_name2info(handle, argv[optind], &linkid,
2122*11878SVenu.Iyer@Sun.COM 		    NULL, NULL, NULL)) != DLADM_STATUS_OK) {
2123*11878SVenu.Iyer@Sun.COM 			die_dlerr(status, "link %s is not valid", argv[optind]);
2124*11878SVenu.Iyer@Sun.COM 		}
2125*11878SVenu.Iyer@Sun.COM 	} else if (optind != argc) {
2126*11878SVenu.Iyer@Sun.COM 		usage();
2127*11878SVenu.Iyer@Sun.COM 	}
2128*11878SVenu.Iyer@Sun.COM 
2129*11878SVenu.Iyer@Sun.COM 	if (a_arg) {
2130*11878SVenu.Iyer@Sun.COM 		boolean_t	stattype[DLADM_STAT_NUM_STATS];
2131*11878SVenu.Iyer@Sun.COM 
2132*11878SVenu.Iyer@Sun.COM 		bzero(&stattype, sizeof (stattype));
2133*11878SVenu.Iyer@Sun.COM 
2134*11878SVenu.Iyer@Sun.COM 		if (r_arg) {
2135*11878SVenu.Iyer@Sun.COM 			if (F_arg) {
2136*11878SVenu.Iyer@Sun.COM 				stattype[DLADM_STAT_RX_LANE_FOUT] = B_TRUE;
2137*11878SVenu.Iyer@Sun.COM 			} else {
2138*11878SVenu.Iyer@Sun.COM 				stattype[DLADM_STAT_RX_LANE] = B_TRUE;
2139*11878SVenu.Iyer@Sun.COM 			}
2140*11878SVenu.Iyer@Sun.COM 		} else if (t_arg) {
2141*11878SVenu.Iyer@Sun.COM 			stattype[DLADM_STAT_TX_LANE] = B_TRUE;
2142*11878SVenu.Iyer@Sun.COM 		} else {		/* Display both Rx and Tx lanes */
2143*11878SVenu.Iyer@Sun.COM 			stattype[DLADM_STAT_RX_LANE] = B_TRUE;
2144*11878SVenu.Iyer@Sun.COM 			stattype[DLADM_STAT_TX_LANE] = B_TRUE;
2145*11878SVenu.Iyer@Sun.COM 		}
2146*11878SVenu.Iyer@Sun.COM 
2147*11878SVenu.Iyer@Sun.COM 		dump_all_link_stats(linkid, stattype);
2148*11878SVenu.Iyer@Sun.COM 		return;
2149*11878SVenu.Iyer@Sun.COM 	}
2150*11878SVenu.Iyer@Sun.COM 
2151*11878SVenu.Iyer@Sun.COM 	state.ls_unit = unit;
2152*11878SVenu.Iyer@Sun.COM 	state.ls_parsable = p_arg;
2153*11878SVenu.Iyer@Sun.COM 
2154*11878SVenu.Iyer@Sun.COM 	if (state.ls_parsable)
2155*11878SVenu.Iyer@Sun.COM 		ofmtflags |= OFMT_PARSABLE;
2156*11878SVenu.Iyer@Sun.COM 
2157*11878SVenu.Iyer@Sun.COM 	if (r_arg) {
2158*11878SVenu.Iyer@Sun.COM 		if (F_arg) {
2159*11878SVenu.Iyer@Sun.COM 			fields_str = rx_fanout_stat_fields;
2160*11878SVenu.Iyer@Sun.COM 			oftemplate = rx_fanout_lane_s_fields;
2161*11878SVenu.Iyer@Sun.COM 			state.ls_stattype[DLADM_STAT_RX_LANE_FOUT] = B_TRUE;
2162*11878SVenu.Iyer@Sun.COM 			state.ls_stats2str[DLADM_STAT_RX_LANE_FOUT] =
2163*11878SVenu.Iyer@Sun.COM 			    print_fanout_stats;
2164*11878SVenu.Iyer@Sun.COM 		} else {
2165*11878SVenu.Iyer@Sun.COM 			fields_str = rx_lane_stat_fields;
2166*11878SVenu.Iyer@Sun.COM 			oftemplate = rx_lane_s_fields;
2167*11878SVenu.Iyer@Sun.COM 			state.ls_stattype[DLADM_STAT_RX_LANE] = B_TRUE;
2168*11878SVenu.Iyer@Sun.COM 			state.ls_stats2str[DLADM_STAT_RX_LANE] =
2169*11878SVenu.Iyer@Sun.COM 			    print_rx_lane_stats;
2170*11878SVenu.Iyer@Sun.COM 		}
2171*11878SVenu.Iyer@Sun.COM 	} else if (t_arg) {
2172*11878SVenu.Iyer@Sun.COM 		fields_str = tx_lane_stat_fields;
2173*11878SVenu.Iyer@Sun.COM 		oftemplate = tx_lane_s_fields;
2174*11878SVenu.Iyer@Sun.COM 		state.ls_stattype[DLADM_STAT_TX_LANE] = B_TRUE;
2175*11878SVenu.Iyer@Sun.COM 		state.ls_stats2str[DLADM_STAT_TX_LANE] = print_tx_lane_stats;
2176*11878SVenu.Iyer@Sun.COM 	} else {		/* Display both Rx and Tx lanes */
2177*11878SVenu.Iyer@Sun.COM 		fields_str = lane_stat_fields;
2178*11878SVenu.Iyer@Sun.COM 		oftemplate = lane_s_fields;
2179*11878SVenu.Iyer@Sun.COM 		state.ls_stattype[DLADM_STAT_RX_LANE] = B_TRUE;
2180*11878SVenu.Iyer@Sun.COM 		state.ls_stattype[DLADM_STAT_TX_LANE] = B_TRUE;
2181*11878SVenu.Iyer@Sun.COM 		state.ls_stats2str[DLADM_STAT_RX_LANE] =
2182*11878SVenu.Iyer@Sun.COM 		    print_rx_generic_lane_stats;
2183*11878SVenu.Iyer@Sun.COM 		state.ls_stats2str[DLADM_STAT_TX_LANE] =
2184*11878SVenu.Iyer@Sun.COM 		    print_tx_generic_lane_stats;
2185*11878SVenu.Iyer@Sun.COM 	}
2186*11878SVenu.Iyer@Sun.COM 	if (o_arg) {
2187*11878SVenu.Iyer@Sun.COM 		fields_str = (strcasecmp(o_fields_str, "all") == 0) ?
2188*11878SVenu.Iyer@Sun.COM 		    fields_str : o_fields_str;
2189*11878SVenu.Iyer@Sun.COM 	}
2190*11878SVenu.Iyer@Sun.COM 
2191*11878SVenu.Iyer@Sun.COM 	oferr = ofmt_open(fields_str, oftemplate, ofmtflags, 0, &ofmt);
2192*11878SVenu.Iyer@Sun.COM 	dlstat_ofmt_check(oferr, state.ls_parsable, ofmt);
2193*11878SVenu.Iyer@Sun.COM 
2194*11878SVenu.Iyer@Sun.COM 	state.ls_ofmt = ofmt;
2195*11878SVenu.Iyer@Sun.COM 
2196*11878SVenu.Iyer@Sun.COM 	show_link_stats(linkid, state, interval);
2197*11878SVenu.Iyer@Sun.COM 
2198*11878SVenu.Iyer@Sun.COM 	ofmt_close(ofmt);
2199*11878SVenu.Iyer@Sun.COM }
2200*11878SVenu.Iyer@Sun.COM 
2201*11878SVenu.Iyer@Sun.COM static void
do_show_aggr(int argc,char * argv[],const char * use)2202*11878SVenu.Iyer@Sun.COM do_show_aggr(int argc, char *argv[], const char *use)
2203*11878SVenu.Iyer@Sun.COM {
2204*11878SVenu.Iyer@Sun.COM 	int			option;
2205*11878SVenu.Iyer@Sun.COM 	boolean_t		r_arg = B_FALSE;
2206*11878SVenu.Iyer@Sun.COM 	boolean_t		t_arg = B_FALSE;
2207*11878SVenu.Iyer@Sun.COM 	boolean_t		i_arg = B_FALSE;
2208*11878SVenu.Iyer@Sun.COM 	boolean_t		p_arg = B_FALSE;
2209*11878SVenu.Iyer@Sun.COM 	boolean_t		o_arg = B_FALSE;
2210*11878SVenu.Iyer@Sun.COM 	boolean_t		u_arg = B_FALSE;
2211*11878SVenu.Iyer@Sun.COM 	uint32_t		flags = DLADM_OPT_ACTIVE;
2212*11878SVenu.Iyer@Sun.COM 	datalink_id_t		linkid = DATALINK_ALL_LINKID;
2213*11878SVenu.Iyer@Sun.COM 	uint32_t		interval = 0;
2214*11878SVenu.Iyer@Sun.COM 	char			unit = '\0';
2215*11878SVenu.Iyer@Sun.COM 	show_state_t		state;
2216*11878SVenu.Iyer@Sun.COM 	dladm_status_t		status;
2217*11878SVenu.Iyer@Sun.COM 	char			*fields_str = NULL;
2218*11878SVenu.Iyer@Sun.COM 	char			*o_fields_str = NULL;
2219*11878SVenu.Iyer@Sun.COM 
2220*11878SVenu.Iyer@Sun.COM 	char			*aggr_stat_fields =
2221*11878SVenu.Iyer@Sun.COM 	    "link,port,ipkts,rbytes,opkts,obytes";
2222*11878SVenu.Iyer@Sun.COM 	char			*rx_aggr_stat_fields = "link,port,ipkts,rbytes";
2223*11878SVenu.Iyer@Sun.COM 	char			*tx_aggr_stat_fields = "link,port,opkts,obytes";
2224*11878SVenu.Iyer@Sun.COM 
2225*11878SVenu.Iyer@Sun.COM 	ofmt_handle_t		ofmt;
2226*11878SVenu.Iyer@Sun.COM 	ofmt_status_t		oferr;
2227*11878SVenu.Iyer@Sun.COM 	uint_t			ofmtflags = OFMT_RIGHTJUST;
2228*11878SVenu.Iyer@Sun.COM 	ofmt_field_t 		*oftemplate;
2229*11878SVenu.Iyer@Sun.COM 
2230*11878SVenu.Iyer@Sun.COM 	bzero(&state, sizeof (state));
2231*11878SVenu.Iyer@Sun.COM 	opterr = 0;
2232*11878SVenu.Iyer@Sun.COM 	while ((option = getopt_long(argc, argv, ":rtpi:o:u:",
2233*11878SVenu.Iyer@Sun.COM 	    NULL, NULL)) != -1) {
2234*11878SVenu.Iyer@Sun.COM 		switch (option) {
2235*11878SVenu.Iyer@Sun.COM 		case 'r':
2236*11878SVenu.Iyer@Sun.COM 			if (r_arg)
2237*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
2238*11878SVenu.Iyer@Sun.COM 
2239*11878SVenu.Iyer@Sun.COM 			r_arg = B_TRUE;
2240*11878SVenu.Iyer@Sun.COM 			break;
2241*11878SVenu.Iyer@Sun.COM 		case 't':
2242*11878SVenu.Iyer@Sun.COM 			if (t_arg)
2243*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
2244*11878SVenu.Iyer@Sun.COM 
2245*11878SVenu.Iyer@Sun.COM 			t_arg = B_TRUE;
2246*11878SVenu.Iyer@Sun.COM 			break;
2247*11878SVenu.Iyer@Sun.COM 		case 'i':
2248*11878SVenu.Iyer@Sun.COM 			if (i_arg)
2249*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
2250*11878SVenu.Iyer@Sun.COM 
2251*11878SVenu.Iyer@Sun.COM 			i_arg = B_TRUE;
2252*11878SVenu.Iyer@Sun.COM 			if (!dladm_str2interval(optarg, &interval))
2253*11878SVenu.Iyer@Sun.COM 				die("invalid interval value '%s'", optarg);
2254*11878SVenu.Iyer@Sun.COM 			break;
2255*11878SVenu.Iyer@Sun.COM 		case 'p':
2256*11878SVenu.Iyer@Sun.COM 			if (p_arg)
2257*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
2258*11878SVenu.Iyer@Sun.COM 
2259*11878SVenu.Iyer@Sun.COM 			p_arg = B_TRUE;
2260*11878SVenu.Iyer@Sun.COM 			break;
2261*11878SVenu.Iyer@Sun.COM 		case 'o':
2262*11878SVenu.Iyer@Sun.COM 			o_arg = B_TRUE;
2263*11878SVenu.Iyer@Sun.COM 			o_fields_str = optarg;
2264*11878SVenu.Iyer@Sun.COM 			break;
2265*11878SVenu.Iyer@Sun.COM 		case 'u':
2266*11878SVenu.Iyer@Sun.COM 			if (u_arg)
2267*11878SVenu.Iyer@Sun.COM 				die_optdup(option);
2268*11878SVenu.Iyer@Sun.COM 
2269*11878SVenu.Iyer@Sun.COM 			u_arg = B_TRUE;
2270*11878SVenu.Iyer@Sun.COM 			if (!dlstat_unit(optarg, &unit))
2271*11878SVenu.Iyer@Sun.COM 				die("invalid unit value '%s',"
2272*11878SVenu.Iyer@Sun.COM 				    "unit must be R|K|M|G|T|P", optarg);
2273*11878SVenu.Iyer@Sun.COM 			break;
2274*11878SVenu.Iyer@Sun.COM 		default:
2275*11878SVenu.Iyer@Sun.COM 			die_opterr(optopt, option, use);
2276*11878SVenu.Iyer@Sun.COM 			break;
2277*11878SVenu.Iyer@Sun.COM 		}
2278*11878SVenu.Iyer@Sun.COM 	}
2279*11878SVenu.Iyer@Sun.COM 
2280*11878SVenu.Iyer@Sun.COM 	if (r_arg && t_arg)
2281*11878SVenu.Iyer@Sun.COM 		die("the options -t and -r are not compatible");
2282*11878SVenu.Iyer@Sun.COM 
2283*11878SVenu.Iyer@Sun.COM 	if (u_arg && p_arg)
2284*11878SVenu.Iyer@Sun.COM 		die("the options -u and -p are not compatible");
2285*11878SVenu.Iyer@Sun.COM 
2286*11878SVenu.Iyer@Sun.COM 	if (p_arg && !o_arg)
2287*11878SVenu.Iyer@Sun.COM 		die("-p requires -o");
2288*11878SVenu.Iyer@Sun.COM 
2289*11878SVenu.Iyer@Sun.COM 	if (p_arg && strcasecmp(o_fields_str, "all") == 0)
2290*11878SVenu.Iyer@Sun.COM 		die("\"-o all\" is invalid with -p");
2291*11878SVenu.Iyer@Sun.COM 
2292*11878SVenu.Iyer@Sun.COM 
2293*11878SVenu.Iyer@Sun.COM 	/* get link name (optional last argument) */
2294*11878SVenu.Iyer@Sun.COM 	if (optind == (argc-1)) {
2295*11878SVenu.Iyer@Sun.COM 		if (strlen(argv[optind]) >= MAXLINKNAMELEN)
2296*11878SVenu.Iyer@Sun.COM 			die("link name too long");
2297*11878SVenu.Iyer@Sun.COM 
2298*11878SVenu.Iyer@Sun.COM 		if ((status = dladm_name2info(handle, argv[optind], &linkid,
2299*11878SVenu.Iyer@Sun.COM 		    NULL, NULL, NULL)) != DLADM_STATUS_OK) {
2300*11878SVenu.Iyer@Sun.COM 			die_dlerr(status, "link %s is not valid", argv[optind]);
2301*11878SVenu.Iyer@Sun.COM 		}
2302*11878SVenu.Iyer@Sun.COM 	} else if (optind != argc) {
2303*11878SVenu.Iyer@Sun.COM 		usage();
2304*11878SVenu.Iyer@Sun.COM 	}
2305*11878SVenu.Iyer@Sun.COM 
2306*11878SVenu.Iyer@Sun.COM 	state.ls_unit = unit;
2307*11878SVenu.Iyer@Sun.COM 	state.ls_parsable = p_arg;
2308*11878SVenu.Iyer@Sun.COM 
2309*11878SVenu.Iyer@Sun.COM 	if (state.ls_parsable)
2310*11878SVenu.Iyer@Sun.COM 		ofmtflags |= OFMT_PARSABLE;
2311*11878SVenu.Iyer@Sun.COM 
2312*11878SVenu.Iyer@Sun.COM 	oftemplate = aggr_port_s_fields;
2313*11878SVenu.Iyer@Sun.COM 	state.ls_stattype[DLADM_STAT_AGGR_PORT] = B_TRUE;
2314*11878SVenu.Iyer@Sun.COM 	state.ls_stats2str[DLADM_STAT_AGGR_PORT] = print_aggr_port_stats;
2315*11878SVenu.Iyer@Sun.COM 
2316*11878SVenu.Iyer@Sun.COM 	if (r_arg)
2317*11878SVenu.Iyer@Sun.COM 		fields_str = rx_aggr_stat_fields;
2318*11878SVenu.Iyer@Sun.COM 	else if (t_arg)
2319*11878SVenu.Iyer@Sun.COM 		fields_str = tx_aggr_stat_fields;
2320*11878SVenu.Iyer@Sun.COM 	else
2321*11878SVenu.Iyer@Sun.COM 		fields_str = aggr_stat_fields;
2322*11878SVenu.Iyer@Sun.COM 
2323*11878SVenu.Iyer@Sun.COM 	if (o_arg) {
2324*11878SVenu.Iyer@Sun.COM 		fields_str = (strcasecmp(o_fields_str, "all") == 0) ?
2325*11878SVenu.Iyer@Sun.COM 		    fields_str : o_fields_str;
2326*11878SVenu.Iyer@Sun.COM 	}
2327*11878SVenu.Iyer@Sun.COM 
2328*11878SVenu.Iyer@Sun.COM 	oferr = ofmt_open(fields_str, oftemplate, ofmtflags, 0, &ofmt);
2329*11878SVenu.Iyer@Sun.COM 	dlstat_ofmt_check(oferr, state.ls_parsable, ofmt);
2330*11878SVenu.Iyer@Sun.COM 	state.ls_ofmt = ofmt;
2331*11878SVenu.Iyer@Sun.COM 
2332*11878SVenu.Iyer@Sun.COM 	show_link_stats(linkid, state, interval);
2333*11878SVenu.Iyer@Sun.COM 
2334*11878SVenu.Iyer@Sun.COM 	ofmt_close(ofmt);
2335*11878SVenu.Iyer@Sun.COM }
2336*11878SVenu.Iyer@Sun.COM 
2337*11878SVenu.Iyer@Sun.COM /* PRINTFLIKE1 */
2338*11878SVenu.Iyer@Sun.COM static void
warn(const char * format,...)2339*11878SVenu.Iyer@Sun.COM warn(const char *format, ...)
2340*11878SVenu.Iyer@Sun.COM {
2341*11878SVenu.Iyer@Sun.COM 	va_list alist;
2342*11878SVenu.Iyer@Sun.COM 
2343*11878SVenu.Iyer@Sun.COM 	format = gettext(format);
2344*11878SVenu.Iyer@Sun.COM 	(void) fprintf(stderr, "%s: warning: ", progname);
2345*11878SVenu.Iyer@Sun.COM 
2346*11878SVenu.Iyer@Sun.COM 	va_start(alist, format);
2347*11878SVenu.Iyer@Sun.COM 	(void) vfprintf(stderr, format, alist);
2348*11878SVenu.Iyer@Sun.COM 	va_end(alist);
2349*11878SVenu.Iyer@Sun.COM 
2350*11878SVenu.Iyer@Sun.COM 	(void) putc('\n', stderr);
2351*11878SVenu.Iyer@Sun.COM }
2352*11878SVenu.Iyer@Sun.COM 
2353*11878SVenu.Iyer@Sun.COM /*
2354*11878SVenu.Iyer@Sun.COM  * Also closes the dladm handle if it is not NULL.
2355*11878SVenu.Iyer@Sun.COM  */
2356*11878SVenu.Iyer@Sun.COM /* PRINTFLIKE2 */
2357*11878SVenu.Iyer@Sun.COM static void
die_dlerr(dladm_status_t err,const char * format,...)2358*11878SVenu.Iyer@Sun.COM die_dlerr(dladm_status_t err, const char *format, ...)
2359*11878SVenu.Iyer@Sun.COM {
2360*11878SVenu.Iyer@Sun.COM 	va_list alist;
2361*11878SVenu.Iyer@Sun.COM 	char	errmsg[DLADM_STRSIZE];
2362*11878SVenu.Iyer@Sun.COM 
2363*11878SVenu.Iyer@Sun.COM 	format = gettext(format);
2364*11878SVenu.Iyer@Sun.COM 	(void) fprintf(stderr, "%s: ", progname);
2365*11878SVenu.Iyer@Sun.COM 
2366*11878SVenu.Iyer@Sun.COM 	va_start(alist, format);
2367*11878SVenu.Iyer@Sun.COM 	(void) vfprintf(stderr, format, alist);
2368*11878SVenu.Iyer@Sun.COM 	va_end(alist);
2369*11878SVenu.Iyer@Sun.COM 	(void) fprintf(stderr, ": %s\n", dladm_status2str(err, errmsg));
2370*11878SVenu.Iyer@Sun.COM 
2371*11878SVenu.Iyer@Sun.COM 	/* close dladm handle if it was opened */
2372*11878SVenu.Iyer@Sun.COM 	if (handle != NULL)
2373*11878SVenu.Iyer@Sun.COM 		dladm_close(handle);
2374*11878SVenu.Iyer@Sun.COM 
2375*11878SVenu.Iyer@Sun.COM 	exit(EXIT_FAILURE);
2376*11878SVenu.Iyer@Sun.COM }
2377*11878SVenu.Iyer@Sun.COM 
2378*11878SVenu.Iyer@Sun.COM /* PRINTFLIKE1 */
2379*11878SVenu.Iyer@Sun.COM static void
die(const char * format,...)2380*11878SVenu.Iyer@Sun.COM die(const char *format, ...)
2381*11878SVenu.Iyer@Sun.COM {
2382*11878SVenu.Iyer@Sun.COM 	va_list alist;
2383*11878SVenu.Iyer@Sun.COM 
2384*11878SVenu.Iyer@Sun.COM 	format = gettext(format);
2385*11878SVenu.Iyer@Sun.COM 	(void) fprintf(stderr, "%s: ", progname);
2386*11878SVenu.Iyer@Sun.COM 
2387*11878SVenu.Iyer@Sun.COM 	va_start(alist, format);
2388*11878SVenu.Iyer@Sun.COM 	(void) vfprintf(stderr, format, alist);
2389*11878SVenu.Iyer@Sun.COM 	va_end(alist);
2390*11878SVenu.Iyer@Sun.COM 
2391*11878SVenu.Iyer@Sun.COM 	(void) putc('\n', stderr);
2392*11878SVenu.Iyer@Sun.COM 
2393*11878SVenu.Iyer@Sun.COM 	/* close dladm handle if it was opened */
2394*11878SVenu.Iyer@Sun.COM 	if (handle != NULL)
2395*11878SVenu.Iyer@Sun.COM 		dladm_close(handle);
2396*11878SVenu.Iyer@Sun.COM 
2397*11878SVenu.Iyer@Sun.COM 	exit(EXIT_FAILURE);
2398*11878SVenu.Iyer@Sun.COM }
2399*11878SVenu.Iyer@Sun.COM 
2400*11878SVenu.Iyer@Sun.COM static void
die_optdup(int opt)2401*11878SVenu.Iyer@Sun.COM die_optdup(int opt)
2402*11878SVenu.Iyer@Sun.COM {
2403*11878SVenu.Iyer@Sun.COM 	die("the option -%c cannot be specified more than once", opt);
2404*11878SVenu.Iyer@Sun.COM }
2405*11878SVenu.Iyer@Sun.COM 
2406*11878SVenu.Iyer@Sun.COM static void
die_opterr(int opt,int opterr,const char * usage)2407*11878SVenu.Iyer@Sun.COM die_opterr(int opt, int opterr, const char *usage)
2408*11878SVenu.Iyer@Sun.COM {
2409*11878SVenu.Iyer@Sun.COM 	switch (opterr) {
2410*11878SVenu.Iyer@Sun.COM 	case ':':
2411*11878SVenu.Iyer@Sun.COM 		die("option '-%c' requires a value\nusage: %s", opt,
2412*11878SVenu.Iyer@Sun.COM 		    gettext(usage));
2413*11878SVenu.Iyer@Sun.COM 		break;
2414*11878SVenu.Iyer@Sun.COM 	case '?':
2415*11878SVenu.Iyer@Sun.COM 	default:
2416*11878SVenu.Iyer@Sun.COM 		die("unrecognized option '-%c'\nusage: %s", opt,
2417*11878SVenu.Iyer@Sun.COM 		    gettext(usage));
2418*11878SVenu.Iyer@Sun.COM 		break;
2419*11878SVenu.Iyer@Sun.COM 	}
2420*11878SVenu.Iyer@Sun.COM }
2421*11878SVenu.Iyer@Sun.COM 
2422*11878SVenu.Iyer@Sun.COM /*
2423*11878SVenu.Iyer@Sun.COM  * default output callback function that, when invoked,
2424*11878SVenu.Iyer@Sun.COM  * prints string which is offset by ofmt_arg->ofmt_id within buf.
2425*11878SVenu.Iyer@Sun.COM  */
2426*11878SVenu.Iyer@Sun.COM static boolean_t
print_default_cb(ofmt_arg_t * ofarg,char * buf,uint_t bufsize)2427*11878SVenu.Iyer@Sun.COM print_default_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize)
2428*11878SVenu.Iyer@Sun.COM {
2429*11878SVenu.Iyer@Sun.COM 	char *value;
2430*11878SVenu.Iyer@Sun.COM 
2431*11878SVenu.Iyer@Sun.COM 	value = (char *)ofarg->ofmt_cbarg + ofarg->ofmt_id;
2432*11878SVenu.Iyer@Sun.COM 	(void) strlcpy(buf, value, bufsize);
2433*11878SVenu.Iyer@Sun.COM 	return (B_TRUE);
2434*11878SVenu.Iyer@Sun.COM }
2435*11878SVenu.Iyer@Sun.COM 
2436*11878SVenu.Iyer@Sun.COM static void
dlstat_ofmt_check(ofmt_status_t oferr,boolean_t parsable,ofmt_handle_t ofmt)2437*11878SVenu.Iyer@Sun.COM dlstat_ofmt_check(ofmt_status_t oferr, boolean_t parsable,
2438*11878SVenu.Iyer@Sun.COM     ofmt_handle_t ofmt)
2439*11878SVenu.Iyer@Sun.COM {
2440*11878SVenu.Iyer@Sun.COM 	char buf[OFMT_BUFSIZE];
2441*11878SVenu.Iyer@Sun.COM 
2442*11878SVenu.Iyer@Sun.COM 	if (oferr == OFMT_SUCCESS)
2443*11878SVenu.Iyer@Sun.COM 		return;
2444*11878SVenu.Iyer@Sun.COM 	(void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf));
2445*11878SVenu.Iyer@Sun.COM 	/*
2446*11878SVenu.Iyer@Sun.COM 	 * All errors are considered fatal in parsable mode.
2447*11878SVenu.Iyer@Sun.COM 	 * NOMEM errors are always fatal, regardless of mode.
2448*11878SVenu.Iyer@Sun.COM 	 * For other errors, we print diagnostics in human-readable
2449*11878SVenu.Iyer@Sun.COM 	 * mode and processs what we can.
2450*11878SVenu.Iyer@Sun.COM 	 */
2451*11878SVenu.Iyer@Sun.COM 	if (parsable || oferr == OFMT_ENOFIELDS) {
2452*11878SVenu.Iyer@Sun.COM 		ofmt_close(ofmt);
2453*11878SVenu.Iyer@Sun.COM 		die(buf);
2454*11878SVenu.Iyer@Sun.COM 	} else {
2455*11878SVenu.Iyer@Sun.COM 		warn(buf);
2456*11878SVenu.Iyer@Sun.COM 	}
2457*11878SVenu.Iyer@Sun.COM }
2458