Print this page
XXXX adding PID information to netstat output
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c
+++ new/usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23 23 * Copyright (c) 1990 Mentat Inc.
24 24 * netstat.c 2.2, last change 9/9/91
25 25 * MROUTING Revision 3.5
26 26 */
27 27
28 28 /*
29 29 * simple netstat based on snmp/mib-2 interface to the TCP/IP stack
30 30 *
31 31 * NOTES:
32 32 * 1. A comment "LINTED: (note 1)" appears before certain lines where
33 33 * lint would have complained, "pointer cast may result in improper
34 34 * alignment". These are lines where lint had suspected potential
35 35 * improper alignment of a data structure; in each such situation
36 36 * we have relied on the kernel guaranteeing proper alignment.
37 37 * 2. Some 'for' loops have been commented as "'for' loop 1", etc
38 38 * because they have 'continue' or 'break' statements in their
39 39 * bodies. 'continue' statements have been used inside some loops
40 40 * where avoiding them would have led to deep levels of indentation.
41 41 *
42 42 * TODO:
43 43 * Add ability to request subsets from kernel (with level = MIB2_IP;
44 44 * name = 0 meaning everything for compatibility)
45 45 */
46 46
47 47 #include <stdio.h>
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
48 48 #include <stdlib.h>
49 49 #include <stdarg.h>
50 50 #include <unistd.h>
51 51 #include <strings.h>
52 52 #include <string.h>
53 53 #include <errno.h>
54 54 #include <ctype.h>
55 55 #include <kstat.h>
56 56 #include <assert.h>
57 57 #include <locale.h>
58 +#include <pwd.h>
59 +#include <limits.h>
58 60
59 61 #include <sys/types.h>
62 +#include <sys/stat.h>
60 63 #include <sys/stream.h>
61 64 #include <stropts.h>
62 65 #include <sys/strstat.h>
63 66 #include <sys/tihdr.h>
67 +#include <procfs.h>
64 68
65 69 #include <sys/socket.h>
70 +#include <sys/socketvar.h>
66 71 #include <sys/sockio.h>
67 72 #include <netinet/in.h>
68 73 #include <net/if.h>
69 74 #include <net/route.h>
70 75
71 76 #include <inet/mib2.h>
72 77 #include <inet/ip.h>
73 78 #include <inet/arp.h>
74 79 #include <inet/tcp.h>
75 80 #include <netinet/igmp_var.h>
76 81 #include <netinet/ip_mroute.h>
77 82
78 83 #include <arpa/inet.h>
79 84 #include <netdb.h>
80 85 #include <fcntl.h>
81 86 #include <sys/systeminfo.h>
82 87 #include <arpa/inet.h>
83 88
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
84 89 #include <netinet/dhcp.h>
85 90 #include <dhcpagent_ipc.h>
86 91 #include <dhcpagent_util.h>
87 92 #include <compat.h>
88 93
89 94 #include <libtsnet.h>
90 95 #include <tsol/label.h>
91 96
92 97 #include "statcommon.h"
93 98
94 -extern void unixpr(kstat_ctl_t *kc);
95 99
96 100 #define STR_EXPAND 4
97 101
98 102 #define V4MASK_TO_V6(v4, v6) ((v6)._S6_un._S6_u32[0] = 0xfffffffful, \
99 103 (v6)._S6_un._S6_u32[1] = 0xfffffffful, \
100 104 (v6)._S6_un._S6_u32[2] = 0xfffffffful, \
101 105 (v6)._S6_un._S6_u32[3] = (v4))
102 106
103 107 #define IN6_IS_V4MASK(v6) ((v6)._S6_un._S6_u32[0] == 0xfffffffful && \
104 108 (v6)._S6_un._S6_u32[1] == 0xfffffffful && \
105 109 (v6)._S6_un._S6_u32[2] == 0xfffffffful)
106 110
107 111 /*
108 112 * This is used as a cushion in the buffer allocation directed by SIOCGLIFNUM.
109 113 * Because there's no locking between SIOCGLIFNUM and SIOCGLIFCONF, it's
110 114 * possible for an administrator to plumb new interfaces between those two
111 115 * calls, resulting in the failure of the latter. This addition makes that
112 116 * less likely.
113 117 */
114 118 #define LIFN_GUARD_VALUE 10
115 119
116 120 typedef struct mib_item_s {
117 121 struct mib_item_s *next_item;
118 122 int group;
119 123 int mib_id;
120 124 int length;
121 125 void *valp;
122 126 } mib_item_t;
123 127
124 128 struct ifstat {
125 129 uint64_t ipackets;
126 130 uint64_t ierrors;
127 131 uint64_t opackets;
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
128 132 uint64_t oerrors;
129 133 uint64_t collisions;
130 134 };
131 135
132 136 struct iflist {
133 137 struct iflist *next_if;
134 138 char ifname[LIFNAMSIZ];
135 139 struct ifstat tot;
136 140 };
137 141
142 +typedef struct proc_info {
143 + char *pr_user;
144 + char *pr_fname;
145 + char *pr_psargs;
146 +} proc_info_t;
147 +
138 148 static mib_item_t *mibget(int sd);
139 149 static void mibfree(mib_item_t *firstitem);
140 150 static int mibopen(void);
141 151 static void mib_get_constants(mib_item_t *item);
142 152 static mib_item_t *mib_item_dup(mib_item_t *item);
143 153 static mib_item_t *mib_item_diff(mib_item_t *item1,
144 154 mib_item_t *item2);
145 155 static void mib_item_destroy(mib_item_t **item);
146 156
147 157 static boolean_t octetstrmatch(const Octet_t *a, const Octet_t *b);
148 158 static char *octetstr(const Octet_t *op, int code,
149 159 char *dst, uint_t dstlen);
150 160 static char *pr_addr(uint_t addr,
151 161 char *dst, uint_t dstlen);
152 162 static char *pr_addrnz(ipaddr_t addr, char *dst, uint_t dstlen);
153 163 static char *pr_addr6(const in6_addr_t *addr,
154 164 char *dst, uint_t dstlen);
155 165 static char *pr_mask(uint_t addr,
156 166 char *dst, uint_t dstlen);
157 167 static char *pr_prefix6(const struct in6_addr *addr,
158 168 uint_t prefixlen, char *dst, uint_t dstlen);
159 169 static char *pr_ap(uint_t addr, uint_t port,
160 170 char *proto, char *dst, uint_t dstlen);
161 171 static char *pr_ap6(const in6_addr_t *addr, uint_t port,
162 172 char *proto, char *dst, uint_t dstlen);
163 173 static char *pr_net(uint_t addr, uint_t mask,
164 174 char *dst, uint_t dstlen);
165 175 static char *pr_netaddr(uint_t addr, uint_t mask,
166 176 char *dst, uint_t dstlen);
167 177 static char *fmodestr(uint_t fmode);
168 178 static char *portname(uint_t port, char *proto,
169 179 char *dst, uint_t dstlen);
170 180
171 181 static const char *mitcp_state(int code,
172 182 const mib2_transportMLPEntry_t *attr);
173 183 static const char *miudp_state(int code,
174 184 const mib2_transportMLPEntry_t *attr);
175 185
176 186 static void stat_report(mib_item_t *item);
177 187 static void mrt_stat_report(mib_item_t *item);
178 188 static void arp_report(mib_item_t *item);
179 189 static void ndp_report(mib_item_t *item);
180 190 static void mrt_report(mib_item_t *item);
181 191 static void if_stat_total(struct ifstat *oldstats,
182 192 struct ifstat *newstats, struct ifstat *sumstats);
183 193 static void if_report(mib_item_t *item, char *ifname,
↓ open down ↓ |
36 lines elided |
↑ open up ↑ |
184 194 int Iflag_only, boolean_t once_only);
185 195 static void if_report_ip4(mib2_ipAddrEntry_t *ap,
186 196 char ifname[], char logintname[],
187 197 struct ifstat *statptr, boolean_t ksp_not_null);
188 198 static void if_report_ip6(mib2_ipv6AddrEntry_t *ap6,
189 199 char ifname[], char logintname[],
190 200 struct ifstat *statptr, boolean_t ksp_not_null);
191 201 static void ire_report(const mib_item_t *item);
192 202 static void tcp_report(const mib_item_t *item);
193 203 static void udp_report(const mib_item_t *item);
204 +static void uds_report(kstat_ctl_t *);
194 205 static void group_report(mib_item_t *item);
195 206 static void dce_report(mib_item_t *item);
196 207 static void print_ip_stats(mib2_ip_t *ip);
197 208 static void print_icmp_stats(mib2_icmp_t *icmp);
198 209 static void print_ip6_stats(mib2_ipv6IfStatsEntry_t *ip6);
199 210 static void print_icmp6_stats(mib2_ipv6IfIcmpEntry_t *icmp6);
200 211 static void print_sctp_stats(mib2_sctp_t *tcp);
201 212 static void print_tcp_stats(mib2_tcp_t *tcp);
202 213 static void print_udp_stats(mib2_udp_t *udp);
203 214 static void print_rawip_stats(mib2_rawip_t *rawip);
204 215 static void print_igmp_stats(struct igmpstat *igps);
205 216 static void print_mrt_stats(struct mrtstat *mrts);
206 217 static void sctp_report(const mib_item_t *item);
207 218 static void sum_ip6_stats(mib2_ipv6IfStatsEntry_t *ip6,
208 219 mib2_ipv6IfStatsEntry_t *sum6);
209 220 static void sum_icmp6_stats(mib2_ipv6IfIcmpEntry_t *icmp6,
210 221 mib2_ipv6IfIcmpEntry_t *sum6);
211 222 static void m_report(void);
212 223 static void dhcp_report(char *);
213 224
214 225 static uint64_t kstat_named_value(kstat_t *, char *);
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
215 226 static kid_t safe_kstat_read(kstat_ctl_t *, kstat_t *, void *);
216 227 static int isnum(char *);
217 228 static char *plural(int n);
218 229 static char *pluraly(int n);
219 230 static char *plurales(int n);
220 231 static void process_filter(char *arg);
221 232 static char *ifindex2str(uint_t, char *);
222 233 static boolean_t family_selected(int family);
223 234
224 235 static void usage(char *);
236 +static char *get_username(uid_t);
237 +proc_info_t *get_proc_info(uint32_t);
225 238 static void fatal(int errcode, char *str1, ...);
226 239
227 240 #define PLURAL(n) plural((int)n)
228 241 #define PLURALY(n) pluraly((int)n)
229 242 #define PLURALES(n) plurales((int)n)
230 243 #define IFLAGMOD(flg, val1, val2) if (flg == val1) flg = val2
231 244 #define MDIFF(diff, elem2, elem1, member) (diff)->member = \
232 245 (elem2)->member - (elem1)->member
233 246
234 247
235 248 static boolean_t Aflag = B_FALSE; /* All sockets/ifs/rtng-tbls */
236 249 static boolean_t Dflag = B_FALSE; /* DCE info */
237 250 static boolean_t Iflag = B_FALSE; /* IP Traffic Interfaces */
238 251 static boolean_t Mflag = B_FALSE; /* STREAMS Memory Statistics */
239 252 static boolean_t Nflag = B_FALSE; /* Numeric Network Addresses */
240 253 static boolean_t Rflag = B_FALSE; /* Routing Tables */
241 254 static boolean_t RSECflag = B_FALSE; /* Security attributes */
242 255 static boolean_t Sflag = B_FALSE; /* Per-protocol Statistics */
243 256 static boolean_t Vflag = B_FALSE; /* Verbose */
257 +static boolean_t Uflag = B_FALSE; /* Show PID and UID info. */
244 258 static boolean_t Pflag = B_FALSE; /* Net to Media Tables */
245 259 static boolean_t Gflag = B_FALSE; /* Multicast group membership */
246 260 static boolean_t MMflag = B_FALSE; /* Multicast routing table */
247 261 static boolean_t DHCPflag = B_FALSE; /* DHCP statistics */
248 262 static boolean_t Xflag = B_FALSE; /* Debug Info */
249 263
250 264 static int v4compat = 0; /* Compatible printing format for status */
251 265
252 266 static int proto = IPPROTO_MAX; /* all protocols */
253 267 kstat_ctl_t *kc = NULL;
254 268
255 269 /*
256 270 * Sizes of data structures extracted from the base mib.
257 271 * This allows the size of the tables entries to grow while preserving
258 272 * binary compatibility.
259 273 */
260 274 static int ipAddrEntrySize;
261 275 static int ipRouteEntrySize;
262 276 static int ipNetToMediaEntrySize;
263 277 static int ipMemberEntrySize;
264 278 static int ipGroupSourceEntrySize;
265 279 static int ipRouteAttributeSize;
266 280 static int vifctlSize;
267 281 static int mfcctlSize;
268 282
269 283 static int ipv6IfStatsEntrySize;
270 284 static int ipv6IfIcmpEntrySize;
271 285 static int ipv6AddrEntrySize;
272 286 static int ipv6RouteEntrySize;
273 287 static int ipv6NetToMediaEntrySize;
274 288 static int ipv6MemberEntrySize;
275 289 static int ipv6GroupSourceEntrySize;
276 290
277 291 static int ipDestEntrySize;
278 292
279 293 static int transportMLPSize;
280 294 static int tcpConnEntrySize;
281 295 static int tcp6ConnEntrySize;
282 296 static int udpEntrySize;
283 297 static int udp6EntrySize;
284 298 static int sctpEntrySize;
285 299 static int sctpLocalEntrySize;
286 300 static int sctpRemoteEntrySize;
287 301
288 302 #define protocol_selected(p) (proto == IPPROTO_MAX || proto == (p))
289 303
290 304 /* Machinery used for -f (filter) option */
291 305 enum { FK_AF = 0, FK_OUTIF, FK_DST, FK_FLAGS, NFILTERKEYS };
292 306
293 307 static const char *filter_keys[NFILTERKEYS] = {
294 308 "af", "outif", "dst", "flags"
295 309 };
296 310
297 311 static m_label_t *zone_security_label = NULL;
298 312
299 313 /* Flags on routes */
300 314 #define FLF_A 0x00000001
301 315 #define FLF_b 0x00000002
302 316 #define FLF_D 0x00000004
303 317 #define FLF_G 0x00000008
304 318 #define FLF_H 0x00000010
305 319 #define FLF_L 0x00000020
306 320 #define FLF_U 0x00000040
307 321 #define FLF_M 0x00000080
308 322 #define FLF_S 0x00000100
309 323 #define FLF_C 0x00000200 /* IRE_IF_CLONE */
310 324 #define FLF_I 0x00000400 /* RTF_INDIRECT */
311 325 #define FLF_R 0x00000800 /* RTF_REJECT */
312 326 #define FLF_B 0x00001000 /* RTF_BLACKHOLE */
313 327 #define FLF_Z 0x00100000 /* RTF_ZONE */
314 328
315 329 static const char flag_list[] = "AbDGHLUMSCIRBZ";
316 330
317 331 typedef struct filter_rule filter_t;
318 332
319 333 struct filter_rule {
320 334 filter_t *f_next;
321 335 union {
322 336 int f_family;
323 337 const char *f_ifname;
324 338 struct {
325 339 struct hostent *f_address;
326 340 in6_addr_t f_mask;
327 341 } a;
328 342 struct {
329 343 uint_t f_flagset;
330 344 uint_t f_flagclear;
331 345 } f;
332 346 } u;
333 347 };
334 348
335 349 /*
336 350 * The user-specified filters are linked into lists separated by
337 351 * keyword (type of filter). Thus, the matching algorithm is:
338 352 * For each non-empty filter list
339 353 * If no filters in the list match
340 354 * then stop here; route doesn't match
341 355 * If loop above completes, then route does match and will be
342 356 * displayed.
343 357 */
344 358 static filter_t *filters[NFILTERKEYS];
345 359
346 360 static uint_t timestamp_fmt = NODATE;
347 361
348 362 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
349 363 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't */
350 364 #endif
351 365
352 366 int
353 367 main(int argc, char **argv)
354 368 {
355 369 char *name;
356 370 mib_item_t *item = NULL;
357 371 mib_item_t *previtem = NULL;
358 372 int sd = -1;
359 373 char *ifname = NULL;
360 374 int interval = 0; /* Single time by default */
361 375 int count = -1; /* Forever */
362 376 int c;
363 377 int d;
364 378 /*
365 379 * Possible values of 'Iflag_only':
366 380 * -1, no feature-flags;
367 381 * 0, IFlag and other feature-flags enabled
368 382 * 1, IFlag is the only feature-flag enabled
369 383 * : trinary variable, modified using IFLAGMOD()
370 384 */
371 385 int Iflag_only = -1;
372 386 boolean_t once_only = B_FALSE; /* '-i' with count > 1 */
373 387 extern char *optarg;
374 388 extern int optind;
375 389 char *default_ip_str = NULL;
376 390
377 391 name = argv[0];
↓ open down ↓ |
124 lines elided |
↑ open up ↑ |
378 392
379 393 v4compat = get_compat_flag(&default_ip_str);
380 394 if (v4compat == DEFAULT_PROT_BAD_VALUE)
381 395 fatal(2, "%s: %s: Bad value for %s in %s\n", name,
382 396 default_ip_str, DEFAULT_IP, INET_DEFAULT_FILE);
383 397 free(default_ip_str);
384 398
385 399 (void) setlocale(LC_ALL, "");
386 400 (void) textdomain(TEXT_DOMAIN);
387 401
388 - while ((c = getopt(argc, argv, "adimnrspMgvxf:P:I:DRT:")) != -1) {
402 + while ((c = getopt(argc, argv, "adimnrspMgvuxf:P:I:DRT:")) != -1) {
389 403 switch ((char)c) {
390 404 case 'a': /* all connections */
391 405 Aflag = B_TRUE;
392 406 break;
393 407
394 408 case 'd': /* DCE info */
395 409 Dflag = B_TRUE;
396 410 IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
397 411 break;
398 412
399 413 case 'i': /* interface (ill/ipif report) */
400 414 Iflag = B_TRUE;
401 415 IFLAGMOD(Iflag_only, -1, 1); /* '-i' exists */
402 416 break;
403 417
404 418 case 'm': /* streams msg report */
405 419 Mflag = B_TRUE;
406 420 IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
407 421 break;
408 422
409 423 case 'n': /* numeric format */
410 424 Nflag = B_TRUE;
411 425 break;
412 426
413 427 case 'r': /* route tables */
414 428 Rflag = B_TRUE;
415 429 IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
416 430 break;
417 431
418 432 case 'R': /* security attributes */
419 433 RSECflag = B_TRUE;
420 434 IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
421 435 break;
422 436
423 437 case 's': /* per-protocol statistics */
424 438 Sflag = B_TRUE;
425 439 IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
426 440 break;
427 441
428 442 case 'p': /* arp/ndp table */
429 443 Pflag = B_TRUE;
430 444 IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
431 445 break;
432 446
433 447 case 'M': /* multicast routing tables */
434 448 MMflag = B_TRUE;
435 449 IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
436 450 break;
437 451
↓ open down ↓ |
39 lines elided |
↑ open up ↑ |
438 452 case 'g': /* multicast group membership */
439 453 Gflag = B_TRUE;
440 454 IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
441 455 break;
442 456
443 457 case 'v': /* verbose output format */
444 458 Vflag = B_TRUE;
445 459 IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
446 460 break;
447 461
462 + case 'u': /* show pid and uid information */
463 + Uflag = B_TRUE;
464 + break;
465 +
448 466 case 'x': /* turn on debugging */
449 467 Xflag = B_TRUE;
450 468 break;
451 469
452 470 case 'f':
453 471 process_filter(optarg);
454 472 break;
455 473
456 474 case 'P':
457 475 if (strcmp(optarg, "ip") == 0) {
458 476 proto = IPPROTO_IP;
459 477 } else if (strcmp(optarg, "ipv6") == 0 ||
460 478 strcmp(optarg, "ip6") == 0) {
461 479 v4compat = 0; /* Overridden */
462 480 proto = IPPROTO_IPV6;
463 481 } else if (strcmp(optarg, "icmp") == 0) {
464 482 proto = IPPROTO_ICMP;
465 483 } else if (strcmp(optarg, "icmpv6") == 0 ||
466 484 strcmp(optarg, "icmp6") == 0) {
467 485 v4compat = 0; /* Overridden */
468 486 proto = IPPROTO_ICMPV6;
469 487 } else if (strcmp(optarg, "igmp") == 0) {
470 488 proto = IPPROTO_IGMP;
471 489 } else if (strcmp(optarg, "udp") == 0) {
472 490 proto = IPPROTO_UDP;
473 491 } else if (strcmp(optarg, "tcp") == 0) {
474 492 proto = IPPROTO_TCP;
475 493 } else if (strcmp(optarg, "sctp") == 0) {
476 494 proto = IPPROTO_SCTP;
477 495 } else if (strcmp(optarg, "raw") == 0 ||
478 496 strcmp(optarg, "rawip") == 0) {
479 497 proto = IPPROTO_RAW;
480 498 } else {
481 499 fatal(1, "%s: unknown protocol.\n", optarg);
482 500 }
483 501 break;
484 502
485 503 case 'I':
486 504 ifname = optarg;
487 505 Iflag = B_TRUE;
488 506 IFLAGMOD(Iflag_only, -1, 1); /* see macro def'n */
489 507 break;
490 508
491 509 case 'D':
492 510 DHCPflag = B_TRUE;
493 511 Iflag_only = 0;
494 512 break;
495 513
496 514 case 'T':
497 515 if (optarg) {
498 516 if (*optarg == 'u')
499 517 timestamp_fmt = UDATE;
500 518 else if (*optarg == 'd')
501 519 timestamp_fmt = DDATE;
502 520 else
503 521 usage(name);
504 522 } else {
505 523 usage(name);
506 524 }
507 525 break;
508 526
509 527 case '?':
510 528 default:
511 529 usage(name);
512 530 }
513 531 }
514 532
515 533 /*
516 534 * Make sure -R option is set only on a labeled system.
517 535 */
518 536 if (RSECflag && !is_system_labeled()) {
519 537 (void) fprintf(stderr, "-R set but labeling is not enabled\n");
520 538 usage(name);
521 539 }
522 540
523 541 /*
524 542 * Handle other arguments: find interval, count; the
525 543 * flags that accept 'interval' and 'count' are OR'd
526 544 * in the outermost 'if'; more flags may be added as
527 545 * required
528 546 */
529 547 if (Iflag || Sflag || Mflag) {
530 548 for (d = optind; d < argc; d++) {
531 549 if (isnum(argv[d])) {
532 550 interval = atoi(argv[d]);
533 551 if (d + 1 < argc &&
534 552 isnum(argv[d + 1])) {
535 553 count = atoi(argv[d + 1]);
536 554 optind++;
537 555 }
538 556 optind++;
539 557 if (interval == 0 || count == 0)
540 558 usage(name);
541 559 break;
542 560 }
543 561 }
544 562 }
545 563 if (optind < argc) {
546 564 if (Iflag && isnum(argv[optind])) {
547 565 count = atoi(argv[optind]);
548 566 if (count == 0)
549 567 usage(name);
550 568 optind++;
551 569 }
552 570 }
553 571 if (optind < argc) {
554 572 (void) fprintf(stderr,
555 573 "%s: extra arguments\n", name);
556 574 usage(name);
557 575 }
558 576 if (interval)
559 577 setbuf(stdout, NULL);
560 578
561 579 if (DHCPflag) {
562 580 dhcp_report(Iflag ? ifname : NULL);
563 581 exit(0);
564 582 }
565 583
566 584 /*
567 585 * Get this process's security label if the -R switch is set.
568 586 * We use this label as the current zone's security label.
569 587 */
570 588 if (RSECflag) {
571 589 zone_security_label = m_label_alloc(MAC_LABEL);
572 590 if (zone_security_label == NULL)
573 591 fatal(errno, "m_label_alloc() failed");
574 592 if (getplabel(zone_security_label) < 0)
575 593 fatal(errno, "getplabel() failed");
576 594 }
577 595
578 596 /* Get data structures: priming before iteration */
579 597 if (family_selected(AF_INET) || family_selected(AF_INET6)) {
580 598 sd = mibopen();
581 599 if (sd == -1)
582 600 fatal(1, "can't open mib stream\n");
583 601 if ((item = mibget(sd)) == NULL) {
584 602 (void) close(sd);
585 603 fatal(1, "mibget() failed\n");
586 604 }
587 605 /* Extract constant sizes - need do once only */
588 606 mib_get_constants(item);
589 607 }
590 608 if ((kc = kstat_open()) == NULL) {
591 609 mibfree(item);
592 610 (void) close(sd);
593 611 fail(1, "kstat_open(): can't open /dev/kstat");
594 612 }
595 613
596 614 if (interval <= 0) {
597 615 count = 1;
598 616 once_only = B_TRUE;
599 617 }
600 618 /* 'for' loop 1: */
601 619 for (;;) {
602 620 mib_item_t *curritem = NULL; /* only for -[M]s */
603 621
604 622 if (timestamp_fmt != NODATE)
605 623 print_timestamp(timestamp_fmt);
606 624
607 625 /* netstat: AF_INET[6] behaviour */
608 626 if (family_selected(AF_INET) || family_selected(AF_INET6)) {
609 627 if (Sflag) {
610 628 curritem = mib_item_diff(previtem, item);
611 629 if (curritem == NULL)
612 630 fatal(1, "can't process mib data, "
613 631 "out of memory\n");
614 632 mib_item_destroy(&previtem);
615 633 }
616 634
617 635 if (!(Dflag || Iflag || Rflag || Sflag || Mflag ||
618 636 MMflag || Pflag || Gflag || DHCPflag)) {
619 637 if (protocol_selected(IPPROTO_UDP))
620 638 udp_report(item);
621 639 if (protocol_selected(IPPROTO_TCP))
622 640 tcp_report(item);
623 641 if (protocol_selected(IPPROTO_SCTP))
624 642 sctp_report(item);
625 643 }
626 644 if (Iflag)
627 645 if_report(item, ifname, Iflag_only, once_only);
628 646 if (Mflag)
629 647 m_report();
630 648 if (Rflag)
631 649 ire_report(item);
632 650 if (Sflag && MMflag) {
633 651 mrt_stat_report(curritem);
634 652 } else {
635 653 if (Sflag)
636 654 stat_report(curritem);
637 655 if (MMflag)
638 656 mrt_report(item);
639 657 }
640 658 if (Gflag)
641 659 group_report(item);
642 660 if (Pflag) {
643 661 if (family_selected(AF_INET))
644 662 arp_report(item);
645 663 if (family_selected(AF_INET6))
646 664 ndp_report(item);
↓ open down ↓ |
189 lines elided |
↑ open up ↑ |
647 665 }
648 666 if (Dflag)
649 667 dce_report(item);
650 668 mib_item_destroy(&curritem);
651 669 }
652 670
653 671 /* netstat: AF_UNIX behaviour */
654 672 if (family_selected(AF_UNIX) &&
655 673 (!(Dflag || Iflag || Rflag || Sflag || Mflag ||
656 674 MMflag || Pflag || Gflag)))
657 - unixpr(kc);
675 + uds_report(kc);
658 676 (void) kstat_close(kc);
659 677
660 678 /* iteration handling code */
661 679 if (count > 0 && --count == 0)
662 680 break;
663 681 (void) sleep(interval);
664 682
665 683 /* re-populating of data structures */
666 684 if (family_selected(AF_INET) || family_selected(AF_INET6)) {
667 685 if (Sflag) {
668 686 /* previtem is a cut-down list */
669 687 previtem = mib_item_dup(item);
670 688 if (previtem == NULL)
671 689 fatal(1, "can't process mib data, "
672 690 "out of memory\n");
673 691 }
674 692 mibfree(item);
675 693 (void) close(sd);
676 694 if ((sd = mibopen()) == -1)
677 695 fatal(1, "can't open mib stream anymore\n");
678 696 if ((item = mibget(sd)) == NULL) {
679 697 (void) close(sd);
680 698 fatal(1, "mibget() failed\n");
681 699 }
682 700 }
683 701 if ((kc = kstat_open()) == NULL)
684 702 fail(1, "kstat_open(): can't open /dev/kstat");
685 703
686 704 } /* 'for' loop 1 ends */
687 705 mibfree(item);
688 706 (void) close(sd);
689 707 if (zone_security_label != NULL)
690 708 m_label_free(zone_security_label);
691 709
692 710 return (0);
693 711 }
694 712
695 713
696 714 static int
697 715 isnum(char *p)
698 716 {
699 717 int len;
700 718 int i;
701 719
702 720 len = strlen(p);
703 721 for (i = 0; i < len; i++)
704 722 if (!isdigit(p[i]))
705 723 return (0);
706 724 return (1);
707 725 }
708 726
709 727
710 728 /* --------------------------------- MIBGET -------------------------------- */
711 729
712 730 static mib_item_t *
713 731 mibget(int sd)
714 732 {
715 733 /*
716 734 * buf is an automatic for this function, so the
717 735 * compiler has complete control over its alignment;
718 736 * it is assumed this alignment is satisfactory for
719 737 * it to be casted to certain other struct pointers
720 738 * here, such as struct T_optmgmt_ack * .
721 739 */
722 740 uintptr_t buf[512 / sizeof (uintptr_t)];
723 741 int flags;
724 742 int i, j, getcode;
725 743 struct strbuf ctlbuf, databuf;
726 744 struct T_optmgmt_req *tor = (struct T_optmgmt_req *)buf;
727 745 struct T_optmgmt_ack *toa = (struct T_optmgmt_ack *)buf;
728 746 struct T_error_ack *tea = (struct T_error_ack *)buf;
729 747 struct opthdr *req;
730 748 mib_item_t *first_item = NULL;
731 749 mib_item_t *last_item = NULL;
732 750 mib_item_t *temp;
733 751
734 752 tor->PRIM_type = T_SVR4_OPTMGMT_REQ;
735 753 tor->OPT_offset = sizeof (struct T_optmgmt_req);
736 754 tor->OPT_length = sizeof (struct opthdr);
737 755 tor->MGMT_flags = T_CURRENT;
738 756
739 757
740 758 /*
741 759 * Note: we use the special level value below so that IP will return
742 760 * us information concerning IRE_MARK_TESTHIDDEN routes.
743 761 */
744 762 req = (struct opthdr *)&tor[1];
745 763 req->level = EXPER_IP_AND_ALL_IRES;
746 764 req->name = 0;
747 765 req->len = 1;
748 766
749 767 ctlbuf.buf = (char *)buf;
750 768 ctlbuf.len = tor->OPT_length + tor->OPT_offset;
751 769 flags = 0;
752 770 if (putmsg(sd, &ctlbuf, (struct strbuf *)0, flags) == -1) {
753 771 perror("mibget: putmsg(ctl) failed");
754 772 goto error_exit;
755 773 }
756 774
757 775 /*
758 776 * Each reply consists of a ctl part for one fixed structure
759 777 * or table, as defined in mib2.h. The format is a T_OPTMGMT_ACK,
760 778 * containing an opthdr structure. level/name identify the entry,
761 779 * len is the size of the data part of the message.
762 780 */
763 781 req = (struct opthdr *)&toa[1];
764 782 ctlbuf.maxlen = sizeof (buf);
765 783 j = 1;
766 784 for (;;) {
767 785 flags = 0;
768 786 getcode = getmsg(sd, &ctlbuf, (struct strbuf *)0, &flags);
769 787 if (getcode == -1) {
770 788 perror("mibget getmsg(ctl) failed");
771 789 if (Xflag) {
772 790 (void) fputs("# level name len\n",
773 791 stderr);
774 792 i = 0;
775 793 for (last_item = first_item; last_item;
776 794 last_item = last_item->next_item)
777 795 (void) printf("%d %4d %5d %d\n",
778 796 ++i,
779 797 last_item->group,
780 798 last_item->mib_id,
781 799 last_item->length);
782 800 }
783 801 goto error_exit;
784 802 }
785 803 if (getcode == 0 &&
786 804 ctlbuf.len >= sizeof (struct T_optmgmt_ack) &&
787 805 toa->PRIM_type == T_OPTMGMT_ACK &&
788 806 toa->MGMT_flags == T_SUCCESS &&
789 807 req->len == 0) {
790 808 if (Xflag)
791 809 (void) printf("mibget getmsg() %d returned "
792 810 "EOD (level %ld, name %ld)\n",
793 811 j, req->level, req->name);
794 812 return (first_item); /* this is EOD msg */
795 813 }
796 814
797 815 if (ctlbuf.len >= sizeof (struct T_error_ack) &&
798 816 tea->PRIM_type == T_ERROR_ACK) {
799 817 (void) fprintf(stderr,
800 818 "mibget %d gives T_ERROR_ACK: TLI_error = 0x%lx, "
801 819 "UNIX_error = 0x%lx\n",
802 820 j, tea->TLI_error, tea->UNIX_error);
803 821
804 822 errno = (tea->TLI_error == TSYSERR) ?
805 823 tea->UNIX_error : EPROTO;
806 824 goto error_exit;
807 825 }
808 826
809 827 if (getcode != MOREDATA ||
810 828 ctlbuf.len < sizeof (struct T_optmgmt_ack) ||
811 829 toa->PRIM_type != T_OPTMGMT_ACK ||
812 830 toa->MGMT_flags != T_SUCCESS) {
813 831 (void) printf("mibget getmsg(ctl) %d returned %d, "
814 832 "ctlbuf.len = %d, PRIM_type = %ld\n",
815 833 j, getcode, ctlbuf.len, toa->PRIM_type);
816 834
817 835 if (toa->PRIM_type == T_OPTMGMT_ACK)
818 836 (void) printf("T_OPTMGMT_ACK: "
819 837 "MGMT_flags = 0x%lx, req->len = %ld\n",
820 838 toa->MGMT_flags, req->len);
821 839 errno = ENOMSG;
822 840 goto error_exit;
823 841 }
824 842
825 843 temp = (mib_item_t *)malloc(sizeof (mib_item_t));
826 844 if (temp == NULL) {
827 845 perror("mibget malloc failed");
828 846 goto error_exit;
829 847 }
830 848 if (last_item != NULL)
831 849 last_item->next_item = temp;
832 850 else
833 851 first_item = temp;
834 852 last_item = temp;
835 853 last_item->next_item = NULL;
836 854 last_item->group = req->level;
837 855 last_item->mib_id = req->name;
838 856 last_item->length = req->len;
839 857 last_item->valp = malloc((int)req->len);
840 858 if (last_item->valp == NULL)
841 859 goto error_exit;
842 860 if (Xflag)
843 861 (void) printf("msg %d: group = %4d mib_id = %5d"
844 862 "length = %d\n",
845 863 j, last_item->group, last_item->mib_id,
846 864 last_item->length);
847 865
848 866 databuf.maxlen = last_item->length;
849 867 databuf.buf = (char *)last_item->valp;
850 868 databuf.len = 0;
851 869 flags = 0;
852 870 getcode = getmsg(sd, (struct strbuf *)0, &databuf, &flags);
853 871 if (getcode == -1) {
854 872 perror("mibget getmsg(data) failed");
855 873 goto error_exit;
856 874 } else if (getcode != 0) {
857 875 (void) printf("mibget getmsg(data) returned %d, "
858 876 "databuf.maxlen = %d, databuf.len = %d\n",
859 877 getcode, databuf.maxlen, databuf.len);
860 878 goto error_exit;
861 879 }
862 880 j++;
863 881 }
864 882 /* NOTREACHED */
865 883
866 884 error_exit:;
867 885 mibfree(first_item);
868 886 return (NULL);
869 887 }
870 888
871 889 /*
872 890 * mibfree: frees a linked list of type (mib_item_t *)
873 891 * returned by mibget(); this is NOT THE SAME AS
874 892 * mib_item_destroy(), so should be used for objects
875 893 * returned by mibget() only
876 894 */
877 895 static void
878 896 mibfree(mib_item_t *firstitem)
879 897 {
880 898 mib_item_t *lastitem;
881 899
882 900 while (firstitem != NULL) {
883 901 lastitem = firstitem;
884 902 firstitem = firstitem->next_item;
885 903 if (lastitem->valp != NULL)
886 904 free(lastitem->valp);
887 905 free(lastitem);
888 906 }
889 907 }
890 908
891 909 static int
892 910 mibopen(void)
893 911 {
894 912 int sd;
895 913
896 914 sd = open("/dev/arp", O_RDWR);
897 915 if (sd == -1) {
898 916 perror("arp open");
899 917 return (-1);
900 918 }
901 919 if (ioctl(sd, I_PUSH, "tcp") == -1) {
902 920 perror("tcp I_PUSH");
903 921 (void) close(sd);
904 922 return (-1);
905 923 }
906 924 if (ioctl(sd, I_PUSH, "udp") == -1) {
907 925 perror("udp I_PUSH");
908 926 (void) close(sd);
909 927 return (-1);
910 928 }
911 929 if (ioctl(sd, I_PUSH, "icmp") == -1) {
912 930 perror("icmp I_PUSH");
913 931 (void) close(sd);
914 932 return (-1);
915 933 }
916 934 return (sd);
917 935 }
918 936
919 937 /*
920 938 * mib_item_dup: returns a clean mib_item_t * linked
921 939 * list, so that for every element item->mib_id is 0;
922 940 * to deallocate this linked list, use mib_item_destroy
923 941 */
924 942 static mib_item_t *
925 943 mib_item_dup(mib_item_t *item)
926 944 {
927 945 int c = 0;
928 946 mib_item_t *localp;
929 947 mib_item_t *tempp;
930 948
931 949 for (tempp = item; tempp; tempp = tempp->next_item)
932 950 if (tempp->mib_id == 0)
933 951 c++;
934 952 tempp = NULL;
935 953
936 954 localp = (mib_item_t *)malloc(c * sizeof (mib_item_t));
937 955 if (localp == NULL)
938 956 return (NULL);
939 957 c = 0;
940 958 for (; item; item = item->next_item) {
941 959 if (item->mib_id == 0) {
942 960 /* Replicate item in localp */
943 961 (localp[c]).next_item = NULL;
944 962 (localp[c]).group = item->group;
945 963 (localp[c]).mib_id = item->mib_id;
946 964 (localp[c]).length = item->length;
947 965 (localp[c]).valp = (uintptr_t *)malloc(
948 966 item->length);
949 967 if ((localp[c]).valp == NULL) {
950 968 mib_item_destroy(&localp);
951 969 return (NULL);
952 970 }
953 971 (void *) memcpy((localp[c]).valp,
954 972 item->valp,
955 973 item->length);
956 974 tempp = &(localp[c]);
957 975 if (c > 0)
958 976 (localp[c - 1]).next_item = tempp;
959 977 c++;
960 978 }
961 979 }
962 980 return (localp);
963 981 }
964 982
965 983 /*
966 984 * mib_item_diff: takes two (mib_item_t *) linked lists
967 985 * item1 and item2 and computes the difference between
968 986 * differentiable values in item2 against item1 for every
969 987 * given member of item2; returns an mib_item_t * linked
970 988 * list of diff's, or a copy of item2 if item1 is NULL;
971 989 * will return NULL if system out of memory; works only
972 990 * for item->mib_id == 0
973 991 */
974 992 static mib_item_t *
975 993 mib_item_diff(mib_item_t *item1, mib_item_t *item2) {
976 994 int nitems = 0; /* no. of items in item2 */
977 995 mib_item_t *tempp2; /* walking copy of item2 */
978 996 mib_item_t *tempp1; /* walking copy of item1 */
979 997 mib_item_t *diffp;
980 998 mib_item_t *diffptr; /* walking copy of diffp */
981 999 mib_item_t *prevp = NULL;
982 1000
983 1001 if (item1 == NULL) {
984 1002 diffp = mib_item_dup(item2);
985 1003 return (diffp);
986 1004 }
987 1005
988 1006 for (tempp2 = item2;
989 1007 tempp2;
990 1008 tempp2 = tempp2->next_item) {
991 1009 if (tempp2->mib_id == 0)
992 1010 switch (tempp2->group) {
993 1011 /*
994 1012 * upon adding a case here, the same
995 1013 * must also be added in the next
996 1014 * switch statement, alongwith
997 1015 * appropriate code
998 1016 */
999 1017 case MIB2_IP:
1000 1018 case MIB2_IP6:
1001 1019 case EXPER_DVMRP:
1002 1020 case EXPER_IGMP:
1003 1021 case MIB2_ICMP:
1004 1022 case MIB2_ICMP6:
1005 1023 case MIB2_TCP:
1006 1024 case MIB2_UDP:
1007 1025 case MIB2_SCTP:
1008 1026 case EXPER_RAWIP:
1009 1027 nitems++;
1010 1028 }
1011 1029 }
1012 1030 tempp2 = NULL;
1013 1031 if (nitems == 0) {
1014 1032 diffp = mib_item_dup(item2);
1015 1033 return (diffp);
1016 1034 }
1017 1035
1018 1036 diffp = (mib_item_t *)calloc(nitems, sizeof (mib_item_t));
1019 1037 if (diffp == NULL)
1020 1038 return (NULL);
1021 1039 diffptr = diffp;
1022 1040 /* 'for' loop 1: */
1023 1041 for (tempp2 = item2; tempp2 != NULL; tempp2 = tempp2->next_item) {
1024 1042 if (tempp2->mib_id != 0)
1025 1043 continue; /* 'for' loop 1 */
1026 1044 /* 'for' loop 2: */
1027 1045 for (tempp1 = item1; tempp1 != NULL;
1028 1046 tempp1 = tempp1->next_item) {
1029 1047 if (!(tempp1->mib_id == 0 &&
1030 1048 tempp1->group == tempp2->group &&
1031 1049 tempp1->mib_id == tempp2->mib_id))
1032 1050 continue; /* 'for' loop 2 */
1033 1051 /* found comparable data sets */
1034 1052 if (prevp != NULL)
1035 1053 prevp->next_item = diffptr;
1036 1054 switch (tempp2->group) {
1037 1055 /*
1038 1056 * Indenting note: Because of long variable names
1039 1057 * in cases MIB2_IP6 and MIB2_ICMP6, their contents
1040 1058 * have been indented by one tab space only
1041 1059 */
1042 1060 case MIB2_IP: {
1043 1061 mib2_ip_t *i2 = (mib2_ip_t *)tempp2->valp;
1044 1062 mib2_ip_t *i1 = (mib2_ip_t *)tempp1->valp;
1045 1063 mib2_ip_t *d;
1046 1064
1047 1065 diffptr->group = tempp2->group;
1048 1066 diffptr->mib_id = tempp2->mib_id;
1049 1067 diffptr->length = tempp2->length;
1050 1068 d = (mib2_ip_t *)calloc(tempp2->length, 1);
1051 1069 if (d == NULL)
1052 1070 goto mibdiff_out_of_memory;
1053 1071 diffptr->valp = d;
1054 1072 d->ipForwarding = i2->ipForwarding;
1055 1073 d->ipDefaultTTL = i2->ipDefaultTTL;
1056 1074 MDIFF(d, i2, i1, ipInReceives);
1057 1075 MDIFF(d, i2, i1, ipInHdrErrors);
1058 1076 MDIFF(d, i2, i1, ipInAddrErrors);
1059 1077 MDIFF(d, i2, i1, ipInCksumErrs);
1060 1078 MDIFF(d, i2, i1, ipForwDatagrams);
1061 1079 MDIFF(d, i2, i1, ipForwProhibits);
1062 1080 MDIFF(d, i2, i1, ipInUnknownProtos);
1063 1081 MDIFF(d, i2, i1, ipInDiscards);
1064 1082 MDIFF(d, i2, i1, ipInDelivers);
1065 1083 MDIFF(d, i2, i1, ipOutRequests);
1066 1084 MDIFF(d, i2, i1, ipOutDiscards);
1067 1085 MDIFF(d, i2, i1, ipOutNoRoutes);
1068 1086 MDIFF(d, i2, i1, ipReasmTimeout);
1069 1087 MDIFF(d, i2, i1, ipReasmReqds);
1070 1088 MDIFF(d, i2, i1, ipReasmOKs);
1071 1089 MDIFF(d, i2, i1, ipReasmFails);
1072 1090 MDIFF(d, i2, i1, ipReasmDuplicates);
1073 1091 MDIFF(d, i2, i1, ipReasmPartDups);
1074 1092 MDIFF(d, i2, i1, ipFragOKs);
1075 1093 MDIFF(d, i2, i1, ipFragFails);
1076 1094 MDIFF(d, i2, i1, ipFragCreates);
1077 1095 MDIFF(d, i2, i1, ipRoutingDiscards);
1078 1096 MDIFF(d, i2, i1, tcpInErrs);
1079 1097 MDIFF(d, i2, i1, udpNoPorts);
1080 1098 MDIFF(d, i2, i1, udpInCksumErrs);
1081 1099 MDIFF(d, i2, i1, udpInOverflows);
1082 1100 MDIFF(d, i2, i1, rawipInOverflows);
1083 1101 MDIFF(d, i2, i1, ipsecInSucceeded);
1084 1102 MDIFF(d, i2, i1, ipsecInFailed);
1085 1103 MDIFF(d, i2, i1, ipInIPv6);
1086 1104 MDIFF(d, i2, i1, ipOutIPv6);
1087 1105 MDIFF(d, i2, i1, ipOutSwitchIPv6);
1088 1106 prevp = diffptr++;
1089 1107 break;
1090 1108 }
1091 1109 case MIB2_IP6: {
1092 1110 mib2_ipv6IfStatsEntry_t *i2;
1093 1111 mib2_ipv6IfStatsEntry_t *i1;
1094 1112 mib2_ipv6IfStatsEntry_t *d;
1095 1113
1096 1114 i2 = (mib2_ipv6IfStatsEntry_t *)tempp2->valp;
1097 1115 i1 = (mib2_ipv6IfStatsEntry_t *)tempp1->valp;
1098 1116 diffptr->group = tempp2->group;
1099 1117 diffptr->mib_id = tempp2->mib_id;
1100 1118 diffptr->length = tempp2->length;
1101 1119 d = (mib2_ipv6IfStatsEntry_t *)calloc(
1102 1120 tempp2->length, 1);
1103 1121 if (d == NULL)
1104 1122 goto mibdiff_out_of_memory;
1105 1123 diffptr->valp = d;
1106 1124 d->ipv6Forwarding = i2->ipv6Forwarding;
1107 1125 d->ipv6DefaultHopLimit =
1108 1126 i2->ipv6DefaultHopLimit;
1109 1127
1110 1128 MDIFF(d, i2, i1, ipv6InReceives);
1111 1129 MDIFF(d, i2, i1, ipv6InHdrErrors);
1112 1130 MDIFF(d, i2, i1, ipv6InTooBigErrors);
1113 1131 MDIFF(d, i2, i1, ipv6InNoRoutes);
1114 1132 MDIFF(d, i2, i1, ipv6InAddrErrors);
1115 1133 MDIFF(d, i2, i1, ipv6InUnknownProtos);
1116 1134 MDIFF(d, i2, i1, ipv6InTruncatedPkts);
1117 1135 MDIFF(d, i2, i1, ipv6InDiscards);
1118 1136 MDIFF(d, i2, i1, ipv6InDelivers);
1119 1137 MDIFF(d, i2, i1, ipv6OutForwDatagrams);
1120 1138 MDIFF(d, i2, i1, ipv6OutRequests);
1121 1139 MDIFF(d, i2, i1, ipv6OutDiscards);
1122 1140 MDIFF(d, i2, i1, ipv6OutNoRoutes);
1123 1141 MDIFF(d, i2, i1, ipv6OutFragOKs);
1124 1142 MDIFF(d, i2, i1, ipv6OutFragFails);
1125 1143 MDIFF(d, i2, i1, ipv6OutFragCreates);
1126 1144 MDIFF(d, i2, i1, ipv6ReasmReqds);
1127 1145 MDIFF(d, i2, i1, ipv6ReasmOKs);
1128 1146 MDIFF(d, i2, i1, ipv6ReasmFails);
1129 1147 MDIFF(d, i2, i1, ipv6InMcastPkts);
1130 1148 MDIFF(d, i2, i1, ipv6OutMcastPkts);
1131 1149 MDIFF(d, i2, i1, ipv6ReasmDuplicates);
1132 1150 MDIFF(d, i2, i1, ipv6ReasmPartDups);
1133 1151 MDIFF(d, i2, i1, ipv6ForwProhibits);
1134 1152 MDIFF(d, i2, i1, udpInCksumErrs);
1135 1153 MDIFF(d, i2, i1, udpInOverflows);
1136 1154 MDIFF(d, i2, i1, rawipInOverflows);
1137 1155 MDIFF(d, i2, i1, ipv6InIPv4);
1138 1156 MDIFF(d, i2, i1, ipv6OutIPv4);
1139 1157 MDIFF(d, i2, i1, ipv6OutSwitchIPv4);
1140 1158 prevp = diffptr++;
1141 1159 break;
1142 1160 }
1143 1161 case EXPER_DVMRP: {
1144 1162 struct mrtstat *m2;
1145 1163 struct mrtstat *m1;
1146 1164 struct mrtstat *d;
1147 1165
1148 1166 m2 = (struct mrtstat *)tempp2->valp;
1149 1167 m1 = (struct mrtstat *)tempp1->valp;
1150 1168 diffptr->group = tempp2->group;
1151 1169 diffptr->mib_id = tempp2->mib_id;
1152 1170 diffptr->length = tempp2->length;
1153 1171 d = (struct mrtstat *)calloc(tempp2->length, 1);
1154 1172 if (d == NULL)
1155 1173 goto mibdiff_out_of_memory;
1156 1174 diffptr->valp = d;
1157 1175 MDIFF(d, m2, m1, mrts_mfc_hits);
1158 1176 MDIFF(d, m2, m1, mrts_mfc_misses);
1159 1177 MDIFF(d, m2, m1, mrts_fwd_in);
1160 1178 MDIFF(d, m2, m1, mrts_fwd_out);
1161 1179 d->mrts_upcalls = m2->mrts_upcalls;
1162 1180 MDIFF(d, m2, m1, mrts_fwd_drop);
1163 1181 MDIFF(d, m2, m1, mrts_bad_tunnel);
1164 1182 MDIFF(d, m2, m1, mrts_cant_tunnel);
1165 1183 MDIFF(d, m2, m1, mrts_wrong_if);
1166 1184 MDIFF(d, m2, m1, mrts_upq_ovflw);
1167 1185 MDIFF(d, m2, m1, mrts_cache_cleanups);
1168 1186 MDIFF(d, m2, m1, mrts_drop_sel);
1169 1187 MDIFF(d, m2, m1, mrts_q_overflow);
1170 1188 MDIFF(d, m2, m1, mrts_pkt2large);
1171 1189 MDIFF(d, m2, m1, mrts_pim_badversion);
1172 1190 MDIFF(d, m2, m1, mrts_pim_rcv_badcsum);
1173 1191 MDIFF(d, m2, m1, mrts_pim_badregisters);
1174 1192 MDIFF(d, m2, m1, mrts_pim_regforwards);
1175 1193 MDIFF(d, m2, m1, mrts_pim_regsend_drops);
1176 1194 MDIFF(d, m2, m1, mrts_pim_malformed);
1177 1195 MDIFF(d, m2, m1, mrts_pim_nomemory);
1178 1196 prevp = diffptr++;
1179 1197 break;
1180 1198 }
1181 1199 case EXPER_IGMP: {
1182 1200 struct igmpstat *i2;
1183 1201 struct igmpstat *i1;
1184 1202 struct igmpstat *d;
1185 1203
1186 1204 i2 = (struct igmpstat *)tempp2->valp;
1187 1205 i1 = (struct igmpstat *)tempp1->valp;
1188 1206 diffptr->group = tempp2->group;
1189 1207 diffptr->mib_id = tempp2->mib_id;
1190 1208 diffptr->length = tempp2->length;
1191 1209 d = (struct igmpstat *)calloc(
1192 1210 tempp2->length, 1);
1193 1211 if (d == NULL)
1194 1212 goto mibdiff_out_of_memory;
1195 1213 diffptr->valp = d;
1196 1214 MDIFF(d, i2, i1, igps_rcv_total);
1197 1215 MDIFF(d, i2, i1, igps_rcv_tooshort);
1198 1216 MDIFF(d, i2, i1, igps_rcv_badsum);
1199 1217 MDIFF(d, i2, i1, igps_rcv_queries);
1200 1218 MDIFF(d, i2, i1, igps_rcv_badqueries);
1201 1219 MDIFF(d, i2, i1, igps_rcv_reports);
1202 1220 MDIFF(d, i2, i1, igps_rcv_badreports);
1203 1221 MDIFF(d, i2, i1, igps_rcv_ourreports);
1204 1222 MDIFF(d, i2, i1, igps_snd_reports);
1205 1223 prevp = diffptr++;
1206 1224 break;
1207 1225 }
1208 1226 case MIB2_ICMP: {
1209 1227 mib2_icmp_t *i2;
1210 1228 mib2_icmp_t *i1;
1211 1229 mib2_icmp_t *d;
1212 1230
1213 1231 i2 = (mib2_icmp_t *)tempp2->valp;
1214 1232 i1 = (mib2_icmp_t *)tempp1->valp;
1215 1233 diffptr->group = tempp2->group;
1216 1234 diffptr->mib_id = tempp2->mib_id;
1217 1235 diffptr->length = tempp2->length;
1218 1236 d = (mib2_icmp_t *)calloc(tempp2->length, 1);
1219 1237 if (d == NULL)
1220 1238 goto mibdiff_out_of_memory;
1221 1239 diffptr->valp = d;
1222 1240 MDIFF(d, i2, i1, icmpInMsgs);
1223 1241 MDIFF(d, i2, i1, icmpInErrors);
1224 1242 MDIFF(d, i2, i1, icmpInCksumErrs);
1225 1243 MDIFF(d, i2, i1, icmpInUnknowns);
1226 1244 MDIFF(d, i2, i1, icmpInDestUnreachs);
1227 1245 MDIFF(d, i2, i1, icmpInTimeExcds);
1228 1246 MDIFF(d, i2, i1, icmpInParmProbs);
1229 1247 MDIFF(d, i2, i1, icmpInSrcQuenchs);
1230 1248 MDIFF(d, i2, i1, icmpInRedirects);
1231 1249 MDIFF(d, i2, i1, icmpInBadRedirects);
1232 1250 MDIFF(d, i2, i1, icmpInEchos);
1233 1251 MDIFF(d, i2, i1, icmpInEchoReps);
1234 1252 MDIFF(d, i2, i1, icmpInTimestamps);
1235 1253 MDIFF(d, i2, i1, icmpInAddrMasks);
1236 1254 MDIFF(d, i2, i1, icmpInAddrMaskReps);
1237 1255 MDIFF(d, i2, i1, icmpInFragNeeded);
1238 1256 MDIFF(d, i2, i1, icmpOutMsgs);
1239 1257 MDIFF(d, i2, i1, icmpOutDrops);
1240 1258 MDIFF(d, i2, i1, icmpOutErrors);
1241 1259 MDIFF(d, i2, i1, icmpOutDestUnreachs);
1242 1260 MDIFF(d, i2, i1, icmpOutTimeExcds);
1243 1261 MDIFF(d, i2, i1, icmpOutParmProbs);
1244 1262 MDIFF(d, i2, i1, icmpOutSrcQuenchs);
1245 1263 MDIFF(d, i2, i1, icmpOutRedirects);
1246 1264 MDIFF(d, i2, i1, icmpOutEchos);
1247 1265 MDIFF(d, i2, i1, icmpOutEchoReps);
1248 1266 MDIFF(d, i2, i1, icmpOutTimestamps);
1249 1267 MDIFF(d, i2, i1, icmpOutTimestampReps);
1250 1268 MDIFF(d, i2, i1, icmpOutAddrMasks);
1251 1269 MDIFF(d, i2, i1, icmpOutAddrMaskReps);
1252 1270 MDIFF(d, i2, i1, icmpOutFragNeeded);
1253 1271 MDIFF(d, i2, i1, icmpInOverflows);
1254 1272 prevp = diffptr++;
1255 1273 break;
1256 1274 }
1257 1275 case MIB2_ICMP6: {
1258 1276 mib2_ipv6IfIcmpEntry_t *i2;
1259 1277 mib2_ipv6IfIcmpEntry_t *i1;
1260 1278 mib2_ipv6IfIcmpEntry_t *d;
1261 1279
1262 1280 i2 = (mib2_ipv6IfIcmpEntry_t *)tempp2->valp;
1263 1281 i1 = (mib2_ipv6IfIcmpEntry_t *)tempp1->valp;
1264 1282 diffptr->group = tempp2->group;
1265 1283 diffptr->mib_id = tempp2->mib_id;
1266 1284 diffptr->length = tempp2->length;
1267 1285 d = (mib2_ipv6IfIcmpEntry_t *)calloc(tempp2->length, 1);
1268 1286 if (d == NULL)
1269 1287 goto mibdiff_out_of_memory;
1270 1288 diffptr->valp = d;
1271 1289 MDIFF(d, i2, i1, ipv6IfIcmpInMsgs);
1272 1290 MDIFF(d, i2, i1, ipv6IfIcmpInErrors);
1273 1291 MDIFF(d, i2, i1, ipv6IfIcmpInDestUnreachs);
1274 1292 MDIFF(d, i2, i1, ipv6IfIcmpInAdminProhibs);
1275 1293 MDIFF(d, i2, i1, ipv6IfIcmpInTimeExcds);
1276 1294 MDIFF(d, i2, i1, ipv6IfIcmpInParmProblems);
1277 1295 MDIFF(d, i2, i1, ipv6IfIcmpInPktTooBigs);
1278 1296 MDIFF(d, i2, i1, ipv6IfIcmpInEchos);
1279 1297 MDIFF(d, i2, i1, ipv6IfIcmpInEchoReplies);
1280 1298 MDIFF(d, i2, i1, ipv6IfIcmpInRouterSolicits);
1281 1299 MDIFF(d, i2, i1, ipv6IfIcmpInRouterAdvertisements);
1282 1300 MDIFF(d, i2, i1, ipv6IfIcmpInNeighborSolicits);
1283 1301 MDIFF(d, i2, i1, ipv6IfIcmpInNeighborAdvertisements);
1284 1302 MDIFF(d, i2, i1, ipv6IfIcmpInRedirects);
1285 1303 MDIFF(d, i2, i1, ipv6IfIcmpInBadRedirects);
1286 1304 MDIFF(d, i2, i1, ipv6IfIcmpInGroupMembQueries);
1287 1305 MDIFF(d, i2, i1, ipv6IfIcmpInGroupMembResponses);
1288 1306 MDIFF(d, i2, i1, ipv6IfIcmpInGroupMembReductions);
1289 1307 MDIFF(d, i2, i1, ipv6IfIcmpInOverflows);
1290 1308 MDIFF(d, i2, i1, ipv6IfIcmpOutMsgs);
1291 1309 MDIFF(d, i2, i1, ipv6IfIcmpOutErrors);
1292 1310 MDIFF(d, i2, i1, ipv6IfIcmpOutDestUnreachs);
1293 1311 MDIFF(d, i2, i1, ipv6IfIcmpOutAdminProhibs);
1294 1312 MDIFF(d, i2, i1, ipv6IfIcmpOutTimeExcds);
1295 1313 MDIFF(d, i2, i1, ipv6IfIcmpOutParmProblems);
1296 1314 MDIFF(d, i2, i1, ipv6IfIcmpOutPktTooBigs);
1297 1315 MDIFF(d, i2, i1, ipv6IfIcmpOutEchos);
1298 1316 MDIFF(d, i2, i1, ipv6IfIcmpOutEchoReplies);
1299 1317 MDIFF(d, i2, i1, ipv6IfIcmpOutRouterSolicits);
1300 1318 MDIFF(d, i2, i1, ipv6IfIcmpOutRouterAdvertisements);
1301 1319 MDIFF(d, i2, i1, ipv6IfIcmpOutNeighborSolicits);
1302 1320 MDIFF(d, i2, i1, ipv6IfIcmpOutNeighborAdvertisements);
1303 1321 MDIFF(d, i2, i1, ipv6IfIcmpOutRedirects);
1304 1322 MDIFF(d, i2, i1, ipv6IfIcmpOutGroupMembQueries);
1305 1323 MDIFF(d, i2, i1, ipv6IfIcmpOutGroupMembResponses);
1306 1324 MDIFF(d, i2, i1, ipv6IfIcmpOutGroupMembReductions);
1307 1325 prevp = diffptr++;
1308 1326 break;
1309 1327 }
1310 1328 case MIB2_TCP: {
1311 1329 mib2_tcp_t *t2;
1312 1330 mib2_tcp_t *t1;
1313 1331 mib2_tcp_t *d;
1314 1332
1315 1333 t2 = (mib2_tcp_t *)tempp2->valp;
1316 1334 t1 = (mib2_tcp_t *)tempp1->valp;
1317 1335 diffptr->group = tempp2->group;
1318 1336 diffptr->mib_id = tempp2->mib_id;
1319 1337 diffptr->length = tempp2->length;
1320 1338 d = (mib2_tcp_t *)calloc(tempp2->length, 1);
1321 1339 if (d == NULL)
1322 1340 goto mibdiff_out_of_memory;
1323 1341 diffptr->valp = d;
1324 1342 d->tcpRtoMin = t2->tcpRtoMin;
1325 1343 d->tcpRtoMax = t2->tcpRtoMax;
1326 1344 d->tcpMaxConn = t2->tcpMaxConn;
1327 1345 MDIFF(d, t2, t1, tcpActiveOpens);
1328 1346 MDIFF(d, t2, t1, tcpPassiveOpens);
1329 1347 MDIFF(d, t2, t1, tcpAttemptFails);
1330 1348 MDIFF(d, t2, t1, tcpEstabResets);
1331 1349 d->tcpCurrEstab = t2->tcpCurrEstab;
1332 1350 MDIFF(d, t2, t1, tcpHCOutSegs);
1333 1351 MDIFF(d, t2, t1, tcpOutDataSegs);
1334 1352 MDIFF(d, t2, t1, tcpOutDataBytes);
1335 1353 MDIFF(d, t2, t1, tcpRetransSegs);
1336 1354 MDIFF(d, t2, t1, tcpRetransBytes);
1337 1355 MDIFF(d, t2, t1, tcpOutAck);
1338 1356 MDIFF(d, t2, t1, tcpOutAckDelayed);
1339 1357 MDIFF(d, t2, t1, tcpOutUrg);
1340 1358 MDIFF(d, t2, t1, tcpOutWinUpdate);
1341 1359 MDIFF(d, t2, t1, tcpOutWinProbe);
1342 1360 MDIFF(d, t2, t1, tcpOutControl);
1343 1361 MDIFF(d, t2, t1, tcpOutRsts);
1344 1362 MDIFF(d, t2, t1, tcpOutFastRetrans);
1345 1363 MDIFF(d, t2, t1, tcpHCInSegs);
1346 1364 MDIFF(d, t2, t1, tcpInAckSegs);
1347 1365 MDIFF(d, t2, t1, tcpInAckBytes);
1348 1366 MDIFF(d, t2, t1, tcpInDupAck);
1349 1367 MDIFF(d, t2, t1, tcpInAckUnsent);
1350 1368 MDIFF(d, t2, t1, tcpInDataInorderSegs);
1351 1369 MDIFF(d, t2, t1, tcpInDataInorderBytes);
1352 1370 MDIFF(d, t2, t1, tcpInDataUnorderSegs);
1353 1371 MDIFF(d, t2, t1, tcpInDataUnorderBytes);
1354 1372 MDIFF(d, t2, t1, tcpInDataDupSegs);
1355 1373 MDIFF(d, t2, t1, tcpInDataDupBytes);
1356 1374 MDIFF(d, t2, t1, tcpInDataPartDupSegs);
1357 1375 MDIFF(d, t2, t1, tcpInDataPartDupBytes);
1358 1376 MDIFF(d, t2, t1, tcpInDataPastWinSegs);
1359 1377 MDIFF(d, t2, t1, tcpInDataPastWinBytes);
1360 1378 MDIFF(d, t2, t1, tcpInWinProbe);
1361 1379 MDIFF(d, t2, t1, tcpInWinUpdate);
1362 1380 MDIFF(d, t2, t1, tcpInClosed);
1363 1381 MDIFF(d, t2, t1, tcpRttNoUpdate);
1364 1382 MDIFF(d, t2, t1, tcpRttUpdate);
1365 1383 MDIFF(d, t2, t1, tcpTimRetrans);
1366 1384 MDIFF(d, t2, t1, tcpTimRetransDrop);
1367 1385 MDIFF(d, t2, t1, tcpTimKeepalive);
1368 1386 MDIFF(d, t2, t1, tcpTimKeepaliveProbe);
1369 1387 MDIFF(d, t2, t1, tcpTimKeepaliveDrop);
1370 1388 MDIFF(d, t2, t1, tcpListenDrop);
1371 1389 MDIFF(d, t2, t1, tcpListenDropQ0);
1372 1390 MDIFF(d, t2, t1, tcpHalfOpenDrop);
1373 1391 MDIFF(d, t2, t1, tcpOutSackRetransSegs);
1374 1392 prevp = diffptr++;
1375 1393 break;
1376 1394 }
1377 1395 case MIB2_UDP: {
1378 1396 mib2_udp_t *u2;
1379 1397 mib2_udp_t *u1;
1380 1398 mib2_udp_t *d;
1381 1399
1382 1400 u2 = (mib2_udp_t *)tempp2->valp;
1383 1401 u1 = (mib2_udp_t *)tempp1->valp;
1384 1402 diffptr->group = tempp2->group;
1385 1403 diffptr->mib_id = tempp2->mib_id;
1386 1404 diffptr->length = tempp2->length;
1387 1405 d = (mib2_udp_t *)calloc(tempp2->length, 1);
1388 1406 if (d == NULL)
1389 1407 goto mibdiff_out_of_memory;
1390 1408 diffptr->valp = d;
1391 1409 MDIFF(d, u2, u1, udpHCInDatagrams);
1392 1410 MDIFF(d, u2, u1, udpInErrors);
1393 1411 MDIFF(d, u2, u1, udpHCOutDatagrams);
1394 1412 MDIFF(d, u2, u1, udpOutErrors);
1395 1413 prevp = diffptr++;
1396 1414 break;
1397 1415 }
1398 1416 case MIB2_SCTP: {
1399 1417 mib2_sctp_t *s2;
1400 1418 mib2_sctp_t *s1;
1401 1419 mib2_sctp_t *d;
1402 1420
1403 1421 s2 = (mib2_sctp_t *)tempp2->valp;
1404 1422 s1 = (mib2_sctp_t *)tempp1->valp;
1405 1423 diffptr->group = tempp2->group;
1406 1424 diffptr->mib_id = tempp2->mib_id;
1407 1425 diffptr->length = tempp2->length;
1408 1426 d = (mib2_sctp_t *)calloc(tempp2->length, 1);
1409 1427 if (d == NULL)
1410 1428 goto mibdiff_out_of_memory;
1411 1429 diffptr->valp = d;
1412 1430 d->sctpRtoAlgorithm = s2->sctpRtoAlgorithm;
1413 1431 d->sctpRtoMin = s2->sctpRtoMin;
1414 1432 d->sctpRtoMax = s2->sctpRtoMax;
1415 1433 d->sctpRtoInitial = s2->sctpRtoInitial;
1416 1434 d->sctpMaxAssocs = s2->sctpMaxAssocs;
1417 1435 d->sctpValCookieLife = s2->sctpValCookieLife;
1418 1436 d->sctpMaxInitRetr = s2->sctpMaxInitRetr;
1419 1437 d->sctpCurrEstab = s2->sctpCurrEstab;
1420 1438 MDIFF(d, s2, s1, sctpActiveEstab);
1421 1439 MDIFF(d, s2, s1, sctpPassiveEstab);
1422 1440 MDIFF(d, s2, s1, sctpAborted);
1423 1441 MDIFF(d, s2, s1, sctpShutdowns);
1424 1442 MDIFF(d, s2, s1, sctpOutOfBlue);
1425 1443 MDIFF(d, s2, s1, sctpChecksumError);
1426 1444 MDIFF(d, s2, s1, sctpOutCtrlChunks);
1427 1445 MDIFF(d, s2, s1, sctpOutOrderChunks);
1428 1446 MDIFF(d, s2, s1, sctpOutUnorderChunks);
1429 1447 MDIFF(d, s2, s1, sctpRetransChunks);
1430 1448 MDIFF(d, s2, s1, sctpOutAck);
1431 1449 MDIFF(d, s2, s1, sctpOutAckDelayed);
1432 1450 MDIFF(d, s2, s1, sctpOutWinUpdate);
1433 1451 MDIFF(d, s2, s1, sctpOutFastRetrans);
1434 1452 MDIFF(d, s2, s1, sctpOutWinProbe);
1435 1453 MDIFF(d, s2, s1, sctpInCtrlChunks);
1436 1454 MDIFF(d, s2, s1, sctpInOrderChunks);
1437 1455 MDIFF(d, s2, s1, sctpInUnorderChunks);
1438 1456 MDIFF(d, s2, s1, sctpInAck);
1439 1457 MDIFF(d, s2, s1, sctpInDupAck);
1440 1458 MDIFF(d, s2, s1, sctpInAckUnsent);
1441 1459 MDIFF(d, s2, s1, sctpFragUsrMsgs);
1442 1460 MDIFF(d, s2, s1, sctpReasmUsrMsgs);
1443 1461 MDIFF(d, s2, s1, sctpOutSCTPPkts);
1444 1462 MDIFF(d, s2, s1, sctpInSCTPPkts);
1445 1463 MDIFF(d, s2, s1, sctpInInvalidCookie);
1446 1464 MDIFF(d, s2, s1, sctpTimRetrans);
1447 1465 MDIFF(d, s2, s1, sctpTimRetransDrop);
1448 1466 MDIFF(d, s2, s1, sctpTimHeartBeatProbe);
1449 1467 MDIFF(d, s2, s1, sctpTimHeartBeatDrop);
1450 1468 MDIFF(d, s2, s1, sctpListenDrop);
1451 1469 MDIFF(d, s2, s1, sctpInClosed);
1452 1470 prevp = diffptr++;
1453 1471 break;
1454 1472 }
1455 1473 case EXPER_RAWIP: {
1456 1474 mib2_rawip_t *r2;
1457 1475 mib2_rawip_t *r1;
1458 1476 mib2_rawip_t *d;
1459 1477
1460 1478 r2 = (mib2_rawip_t *)tempp2->valp;
1461 1479 r1 = (mib2_rawip_t *)tempp1->valp;
1462 1480 diffptr->group = tempp2->group;
1463 1481 diffptr->mib_id = tempp2->mib_id;
1464 1482 diffptr->length = tempp2->length;
1465 1483 d = (mib2_rawip_t *)calloc(tempp2->length, 1);
1466 1484 if (d == NULL)
1467 1485 goto mibdiff_out_of_memory;
1468 1486 diffptr->valp = d;
1469 1487 MDIFF(d, r2, r1, rawipInDatagrams);
1470 1488 MDIFF(d, r2, r1, rawipInErrors);
1471 1489 MDIFF(d, r2, r1, rawipInCksumErrs);
1472 1490 MDIFF(d, r2, r1, rawipOutDatagrams);
1473 1491 MDIFF(d, r2, r1, rawipOutErrors);
1474 1492 prevp = diffptr++;
1475 1493 break;
1476 1494 }
1477 1495 /*
1478 1496 * there are more "group" types but they aren't
1479 1497 * required for the -s and -Ms options
1480 1498 */
1481 1499 }
1482 1500 } /* 'for' loop 2 ends */
1483 1501 tempp1 = NULL;
1484 1502 } /* 'for' loop 1 ends */
1485 1503 tempp2 = NULL;
1486 1504 diffptr--;
1487 1505 diffptr->next_item = NULL;
1488 1506 return (diffp);
1489 1507
1490 1508 mibdiff_out_of_memory:;
1491 1509 mib_item_destroy(&diffp);
1492 1510 return (NULL);
1493 1511 }
1494 1512
1495 1513 /*
1496 1514 * mib_item_destroy: cleans up a mib_item_t *
1497 1515 * that was created by calling mib_item_dup or
1498 1516 * mib_item_diff
1499 1517 */
1500 1518 static void
1501 1519 mib_item_destroy(mib_item_t **itemp) {
1502 1520 int nitems = 0;
1503 1521 int c = 0;
1504 1522 mib_item_t *tempp;
1505 1523
1506 1524 if (itemp == NULL || *itemp == NULL)
1507 1525 return;
1508 1526
1509 1527 for (tempp = *itemp; tempp != NULL; tempp = tempp->next_item)
1510 1528 if (tempp->mib_id == 0)
1511 1529 nitems++;
1512 1530 else
1513 1531 return; /* cannot destroy! */
1514 1532
1515 1533 if (nitems == 0)
1516 1534 return; /* cannot destroy! */
1517 1535
1518 1536 for (c = nitems - 1; c >= 0; c--) {
1519 1537 if ((itemp[0][c]).valp != NULL)
1520 1538 free((itemp[0][c]).valp);
1521 1539 }
1522 1540 free(*itemp);
1523 1541
1524 1542 *itemp = NULL;
1525 1543 }
1526 1544
1527 1545 /* Compare two Octet_ts. Return B_TRUE if they match, B_FALSE if not. */
1528 1546 static boolean_t
1529 1547 octetstrmatch(const Octet_t *a, const Octet_t *b)
1530 1548 {
1531 1549 if (a == NULL || b == NULL)
1532 1550 return (B_FALSE);
1533 1551
1534 1552 if (a->o_length != b->o_length)
1535 1553 return (B_FALSE);
1536 1554
1537 1555 return (memcmp(a->o_bytes, b->o_bytes, a->o_length) == 0);
1538 1556 }
1539 1557
1540 1558 /* If octetstr() changes make an appropriate change to STR_EXPAND */
1541 1559 static char *
1542 1560 octetstr(const Octet_t *op, int code, char *dst, uint_t dstlen)
1543 1561 {
1544 1562 int i;
1545 1563 char *cp;
1546 1564
1547 1565 cp = dst;
1548 1566 if (op) {
1549 1567 for (i = 0; i < op->o_length; i++) {
1550 1568 switch (code) {
1551 1569 case 'd':
1552 1570 if (cp - dst + 4 > dstlen) {
1553 1571 *cp = '\0';
1554 1572 return (dst);
1555 1573 }
1556 1574 (void) snprintf(cp, 5, "%d.",
1557 1575 0xff & op->o_bytes[i]);
1558 1576 cp = strchr(cp, '\0');
1559 1577 break;
1560 1578 case 'a':
1561 1579 if (cp - dst + 1 > dstlen) {
1562 1580 *cp = '\0';
1563 1581 return (dst);
1564 1582 }
1565 1583 *cp++ = op->o_bytes[i];
1566 1584 break;
1567 1585 case 'h':
1568 1586 default:
1569 1587 if (cp - dst + 3 > dstlen) {
1570 1588 *cp = '\0';
1571 1589 return (dst);
1572 1590 }
1573 1591 (void) snprintf(cp, 4, "%02x:",
1574 1592 0xff & op->o_bytes[i]);
1575 1593 cp += 3;
1576 1594 break;
1577 1595 }
1578 1596 }
1579 1597 }
1580 1598 if (code != 'a' && cp != dst)
1581 1599 cp--;
1582 1600 *cp = '\0';
1583 1601 return (dst);
1584 1602 }
1585 1603
1586 1604 static const char *
1587 1605 mitcp_state(int state, const mib2_transportMLPEntry_t *attr)
1588 1606 {
1589 1607 static char tcpsbuf[50];
1590 1608 const char *cp;
1591 1609
1592 1610 switch (state) {
1593 1611 case TCPS_CLOSED:
1594 1612 cp = "CLOSED";
1595 1613 break;
1596 1614 case TCPS_IDLE:
1597 1615 cp = "IDLE";
1598 1616 break;
1599 1617 case TCPS_BOUND:
1600 1618 cp = "BOUND";
1601 1619 break;
1602 1620 case TCPS_LISTEN:
1603 1621 cp = "LISTEN";
1604 1622 break;
1605 1623 case TCPS_SYN_SENT:
1606 1624 cp = "SYN_SENT";
1607 1625 break;
1608 1626 case TCPS_SYN_RCVD:
1609 1627 cp = "SYN_RCVD";
1610 1628 break;
1611 1629 case TCPS_ESTABLISHED:
1612 1630 cp = "ESTABLISHED";
1613 1631 break;
1614 1632 case TCPS_CLOSE_WAIT:
1615 1633 cp = "CLOSE_WAIT";
1616 1634 break;
1617 1635 case TCPS_FIN_WAIT_1:
1618 1636 cp = "FIN_WAIT_1";
1619 1637 break;
1620 1638 case TCPS_CLOSING:
1621 1639 cp = "CLOSING";
1622 1640 break;
1623 1641 case TCPS_LAST_ACK:
1624 1642 cp = "LAST_ACK";
1625 1643 break;
1626 1644 case TCPS_FIN_WAIT_2:
1627 1645 cp = "FIN_WAIT_2";
1628 1646 break;
1629 1647 case TCPS_TIME_WAIT:
1630 1648 cp = "TIME_WAIT";
1631 1649 break;
1632 1650 default:
1633 1651 (void) snprintf(tcpsbuf, sizeof (tcpsbuf),
1634 1652 "UnknownState(%d)", state);
1635 1653 cp = tcpsbuf;
1636 1654 break;
1637 1655 }
1638 1656
1639 1657 if (RSECflag && attr != NULL && attr->tme_flags != 0) {
1640 1658 if (cp != tcpsbuf) {
1641 1659 (void) strlcpy(tcpsbuf, cp, sizeof (tcpsbuf));
1642 1660 cp = tcpsbuf;
1643 1661 }
1644 1662 if (attr->tme_flags & MIB2_TMEF_PRIVATE)
1645 1663 (void) strlcat(tcpsbuf, " P", sizeof (tcpsbuf));
1646 1664 if (attr->tme_flags & MIB2_TMEF_SHARED)
1647 1665 (void) strlcat(tcpsbuf, " S", sizeof (tcpsbuf));
1648 1666 }
1649 1667
1650 1668 return (cp);
1651 1669 }
1652 1670
1653 1671 static const char *
1654 1672 miudp_state(int state, const mib2_transportMLPEntry_t *attr)
1655 1673 {
1656 1674 static char udpsbuf[50];
1657 1675 const char *cp;
1658 1676
1659 1677 switch (state) {
1660 1678 case MIB2_UDP_unbound:
1661 1679 cp = "Unbound";
1662 1680 break;
1663 1681 case MIB2_UDP_idle:
1664 1682 cp = "Idle";
1665 1683 break;
1666 1684 case MIB2_UDP_connected:
1667 1685 cp = "Connected";
1668 1686 break;
1669 1687 default:
1670 1688 (void) snprintf(udpsbuf, sizeof (udpsbuf),
1671 1689 "Unknown State(%d)", state);
1672 1690 cp = udpsbuf;
1673 1691 break;
1674 1692 }
1675 1693
1676 1694 if (RSECflag && attr != NULL && attr->tme_flags != 0) {
1677 1695 if (cp != udpsbuf) {
1678 1696 (void) strlcpy(udpsbuf, cp, sizeof (udpsbuf));
1679 1697 cp = udpsbuf;
1680 1698 }
1681 1699 if (attr->tme_flags & MIB2_TMEF_PRIVATE)
1682 1700 (void) strlcat(udpsbuf, " P", sizeof (udpsbuf));
1683 1701 if (attr->tme_flags & MIB2_TMEF_SHARED)
1684 1702 (void) strlcat(udpsbuf, " S", sizeof (udpsbuf));
1685 1703 }
1686 1704
1687 1705 return (cp);
1688 1706 }
1689 1707
1690 1708 static int odd;
1691 1709
1692 1710 static void
1693 1711 prval_init(void)
1694 1712 {
1695 1713 odd = 0;
1696 1714 }
1697 1715
1698 1716 static void
1699 1717 prval(char *str, Counter val)
1700 1718 {
1701 1719 (void) printf("\t%-20s=%6u", str, val);
1702 1720 if (odd++ & 1)
1703 1721 (void) putchar('\n');
1704 1722 }
1705 1723
1706 1724 static void
1707 1725 prval64(char *str, Counter64 val)
1708 1726 {
1709 1727 (void) printf("\t%-20s=%6llu", str, val);
1710 1728 if (odd++ & 1)
1711 1729 (void) putchar('\n');
1712 1730 }
1713 1731
1714 1732 static void
1715 1733 pr_int_val(char *str, int val)
1716 1734 {
1717 1735 (void) printf("\t%-20s=%6d", str, val);
1718 1736 if (odd++ & 1)
1719 1737 (void) putchar('\n');
1720 1738 }
1721 1739
1722 1740 static void
1723 1741 pr_sctp_rtoalgo(char *str, int val)
1724 1742 {
1725 1743 (void) printf("\t%-20s=", str);
1726 1744 switch (val) {
1727 1745 case MIB2_SCTP_RTOALGO_OTHER:
1728 1746 (void) printf("%6.6s", "other");
1729 1747 break;
1730 1748
1731 1749 case MIB2_SCTP_RTOALGO_VANJ:
1732 1750 (void) printf("%6.6s", "vanj");
1733 1751 break;
1734 1752
1735 1753 default:
1736 1754 (void) printf("%6d", val);
1737 1755 break;
1738 1756 }
1739 1757 if (odd++ & 1)
1740 1758 (void) putchar('\n');
1741 1759 }
1742 1760
1743 1761 static void
1744 1762 prval_end(void)
1745 1763 {
1746 1764 if (odd++ & 1)
1747 1765 (void) putchar('\n');
1748 1766 }
1749 1767
1750 1768 /* Extract constant sizes */
1751 1769 static void
1752 1770 mib_get_constants(mib_item_t *item)
1753 1771 {
1754 1772 /* 'for' loop 1: */
1755 1773 for (; item; item = item->next_item) {
1756 1774 if (item->mib_id != 0)
1757 1775 continue; /* 'for' loop 1 */
1758 1776
1759 1777 switch (item->group) {
1760 1778 case MIB2_IP: {
1761 1779 mib2_ip_t *ip = (mib2_ip_t *)item->valp;
1762 1780
1763 1781 ipAddrEntrySize = ip->ipAddrEntrySize;
1764 1782 ipRouteEntrySize = ip->ipRouteEntrySize;
1765 1783 ipNetToMediaEntrySize = ip->ipNetToMediaEntrySize;
1766 1784 ipMemberEntrySize = ip->ipMemberEntrySize;
1767 1785 ipGroupSourceEntrySize = ip->ipGroupSourceEntrySize;
1768 1786 ipRouteAttributeSize = ip->ipRouteAttributeSize;
1769 1787 transportMLPSize = ip->transportMLPSize;
1770 1788 ipDestEntrySize = ip->ipDestEntrySize;
1771 1789 assert(IS_P2ALIGNED(ipAddrEntrySize,
1772 1790 sizeof (mib2_ipAddrEntry_t *)));
1773 1791 assert(IS_P2ALIGNED(ipRouteEntrySize,
1774 1792 sizeof (mib2_ipRouteEntry_t *)));
1775 1793 assert(IS_P2ALIGNED(ipNetToMediaEntrySize,
1776 1794 sizeof (mib2_ipNetToMediaEntry_t *)));
1777 1795 assert(IS_P2ALIGNED(ipMemberEntrySize,
1778 1796 sizeof (ip_member_t *)));
1779 1797 assert(IS_P2ALIGNED(ipGroupSourceEntrySize,
1780 1798 sizeof (ip_grpsrc_t *)));
1781 1799 assert(IS_P2ALIGNED(ipRouteAttributeSize,
1782 1800 sizeof (mib2_ipAttributeEntry_t *)));
1783 1801 assert(IS_P2ALIGNED(transportMLPSize,
1784 1802 sizeof (mib2_transportMLPEntry_t *)));
1785 1803 break;
1786 1804 }
1787 1805 case EXPER_DVMRP: {
1788 1806 struct mrtstat *mrts = (struct mrtstat *)item->valp;
1789 1807
1790 1808 vifctlSize = mrts->mrts_vifctlSize;
1791 1809 mfcctlSize = mrts->mrts_mfcctlSize;
1792 1810 assert(IS_P2ALIGNED(vifctlSize,
1793 1811 sizeof (struct vifclt *)));
1794 1812 assert(IS_P2ALIGNED(mfcctlSize,
1795 1813 sizeof (struct mfcctl *)));
1796 1814 break;
1797 1815 }
1798 1816 case MIB2_IP6: {
1799 1817 mib2_ipv6IfStatsEntry_t *ip6;
1800 1818 /* Just use the first entry */
1801 1819
1802 1820 ip6 = (mib2_ipv6IfStatsEntry_t *)item->valp;
1803 1821 ipv6IfStatsEntrySize = ip6->ipv6IfStatsEntrySize;
1804 1822 ipv6AddrEntrySize = ip6->ipv6AddrEntrySize;
1805 1823 ipv6RouteEntrySize = ip6->ipv6RouteEntrySize;
1806 1824 ipv6NetToMediaEntrySize = ip6->ipv6NetToMediaEntrySize;
1807 1825 ipv6MemberEntrySize = ip6->ipv6MemberEntrySize;
1808 1826 ipv6GroupSourceEntrySize =
1809 1827 ip6->ipv6GroupSourceEntrySize;
1810 1828 assert(IS_P2ALIGNED(ipv6IfStatsEntrySize,
1811 1829 sizeof (mib2_ipv6IfStatsEntry_t *)));
1812 1830 assert(IS_P2ALIGNED(ipv6AddrEntrySize,
1813 1831 sizeof (mib2_ipv6AddrEntry_t *)));
1814 1832 assert(IS_P2ALIGNED(ipv6RouteEntrySize,
1815 1833 sizeof (mib2_ipv6RouteEntry_t *)));
1816 1834 assert(IS_P2ALIGNED(ipv6NetToMediaEntrySize,
1817 1835 sizeof (mib2_ipv6NetToMediaEntry_t *)));
1818 1836 assert(IS_P2ALIGNED(ipv6MemberEntrySize,
1819 1837 sizeof (ipv6_member_t *)));
1820 1838 assert(IS_P2ALIGNED(ipv6GroupSourceEntrySize,
1821 1839 sizeof (ipv6_grpsrc_t *)));
1822 1840 break;
1823 1841 }
1824 1842 case MIB2_ICMP6: {
1825 1843 mib2_ipv6IfIcmpEntry_t *icmp6;
1826 1844 /* Just use the first entry */
1827 1845
1828 1846 icmp6 = (mib2_ipv6IfIcmpEntry_t *)item->valp;
1829 1847 ipv6IfIcmpEntrySize = icmp6->ipv6IfIcmpEntrySize;
1830 1848 assert(IS_P2ALIGNED(ipv6IfIcmpEntrySize,
1831 1849 sizeof (mib2_ipv6IfIcmpEntry_t *)));
1832 1850 break;
1833 1851 }
1834 1852 case MIB2_TCP: {
1835 1853 mib2_tcp_t *tcp = (mib2_tcp_t *)item->valp;
1836 1854
1837 1855 tcpConnEntrySize = tcp->tcpConnTableSize;
1838 1856 tcp6ConnEntrySize = tcp->tcp6ConnTableSize;
1839 1857 assert(IS_P2ALIGNED(tcpConnEntrySize,
1840 1858 sizeof (mib2_tcpConnEntry_t *)));
1841 1859 assert(IS_P2ALIGNED(tcp6ConnEntrySize,
1842 1860 sizeof (mib2_tcp6ConnEntry_t *)));
1843 1861 break;
1844 1862 }
1845 1863 case MIB2_UDP: {
1846 1864 mib2_udp_t *udp = (mib2_udp_t *)item->valp;
1847 1865
1848 1866 udpEntrySize = udp->udpEntrySize;
1849 1867 udp6EntrySize = udp->udp6EntrySize;
1850 1868 assert(IS_P2ALIGNED(udpEntrySize,
1851 1869 sizeof (mib2_udpEntry_t *)));
1852 1870 assert(IS_P2ALIGNED(udp6EntrySize,
1853 1871 sizeof (mib2_udp6Entry_t *)));
1854 1872 break;
1855 1873 }
1856 1874 case MIB2_SCTP: {
1857 1875 mib2_sctp_t *sctp = (mib2_sctp_t *)item->valp;
1858 1876
1859 1877 sctpEntrySize = sctp->sctpEntrySize;
1860 1878 sctpLocalEntrySize = sctp->sctpLocalEntrySize;
1861 1879 sctpRemoteEntrySize = sctp->sctpRemoteEntrySize;
1862 1880 break;
1863 1881 }
1864 1882 }
1865 1883 } /* 'for' loop 1 ends */
1866 1884
1867 1885 if (Xflag) {
1868 1886 (void) puts("mib_get_constants:");
1869 1887 (void) printf("\tipv6IfStatsEntrySize %d\n",
1870 1888 ipv6IfStatsEntrySize);
1871 1889 (void) printf("\tipAddrEntrySize %d\n", ipAddrEntrySize);
1872 1890 (void) printf("\tipRouteEntrySize %d\n", ipRouteEntrySize);
1873 1891 (void) printf("\tipNetToMediaEntrySize %d\n",
1874 1892 ipNetToMediaEntrySize);
1875 1893 (void) printf("\tipMemberEntrySize %d\n", ipMemberEntrySize);
1876 1894 (void) printf("\tipRouteAttributeSize %d\n",
1877 1895 ipRouteAttributeSize);
1878 1896 (void) printf("\tvifctlSize %d\n", vifctlSize);
1879 1897 (void) printf("\tmfcctlSize %d\n", mfcctlSize);
1880 1898
1881 1899 (void) printf("\tipv6AddrEntrySize %d\n", ipv6AddrEntrySize);
1882 1900 (void) printf("\tipv6RouteEntrySize %d\n", ipv6RouteEntrySize);
1883 1901 (void) printf("\tipv6NetToMediaEntrySize %d\n",
1884 1902 ipv6NetToMediaEntrySize);
1885 1903 (void) printf("\tipv6MemberEntrySize %d\n",
1886 1904 ipv6MemberEntrySize);
1887 1905 (void) printf("\tipv6IfIcmpEntrySize %d\n",
1888 1906 ipv6IfIcmpEntrySize);
1889 1907 (void) printf("\tipDestEntrySize %d\n", ipDestEntrySize);
1890 1908 (void) printf("\ttransportMLPSize %d\n", transportMLPSize);
1891 1909 (void) printf("\ttcpConnEntrySize %d\n", tcpConnEntrySize);
1892 1910 (void) printf("\ttcp6ConnEntrySize %d\n", tcp6ConnEntrySize);
1893 1911 (void) printf("\tudpEntrySize %d\n", udpEntrySize);
1894 1912 (void) printf("\tudp6EntrySize %d\n", udp6EntrySize);
1895 1913 (void) printf("\tsctpEntrySize %d\n", sctpEntrySize);
1896 1914 (void) printf("\tsctpLocalEntrySize %d\n", sctpLocalEntrySize);
1897 1915 (void) printf("\tsctpRemoteEntrySize %d\n",
1898 1916 sctpRemoteEntrySize);
1899 1917 }
1900 1918 }
1901 1919
1902 1920
1903 1921 /* ----------------------------- STAT_REPORT ------------------------------- */
1904 1922
1905 1923 static void
1906 1924 stat_report(mib_item_t *item)
1907 1925 {
1908 1926 int jtemp = 0;
1909 1927 char ifname[LIFNAMSIZ + 1];
1910 1928
1911 1929 /* 'for' loop 1: */
1912 1930 for (; item; item = item->next_item) {
1913 1931 if (Xflag) {
1914 1932 (void) printf("\n--- Entry %d ---\n", ++jtemp);
1915 1933 (void) printf("Group = %d, mib_id = %d, "
1916 1934 "length = %d, valp = 0x%p\n",
1917 1935 item->group, item->mib_id,
1918 1936 item->length, item->valp);
1919 1937 }
1920 1938 if (item->mib_id != 0)
1921 1939 continue; /* 'for' loop 1 */
1922 1940
1923 1941 switch (item->group) {
1924 1942 case MIB2_IP: {
1925 1943 mib2_ip_t *ip = (mib2_ip_t *)item->valp;
1926 1944
1927 1945 if (protocol_selected(IPPROTO_IP) &&
1928 1946 family_selected(AF_INET)) {
1929 1947 (void) fputs(v4compat ? "\nIP" : "\nIPv4",
1930 1948 stdout);
1931 1949 print_ip_stats(ip);
1932 1950 }
1933 1951 break;
1934 1952 }
1935 1953 case MIB2_ICMP: {
1936 1954 mib2_icmp_t *icmp =
1937 1955 (mib2_icmp_t *)item->valp;
1938 1956
1939 1957 if (protocol_selected(IPPROTO_ICMP) &&
1940 1958 family_selected(AF_INET)) {
1941 1959 (void) fputs(v4compat ? "\nICMP" : "\nICMPv4",
1942 1960 stdout);
1943 1961 print_icmp_stats(icmp);
1944 1962 }
1945 1963 break;
1946 1964 }
1947 1965 case MIB2_IP6: {
1948 1966 mib2_ipv6IfStatsEntry_t *ip6;
1949 1967 mib2_ipv6IfStatsEntry_t sum6;
1950 1968
1951 1969 if (!(protocol_selected(IPPROTO_IPV6)) ||
1952 1970 !(family_selected(AF_INET6)))
1953 1971 break;
1954 1972 bzero(&sum6, sizeof (sum6));
1955 1973 /* 'for' loop 2a: */
1956 1974 for (ip6 = (mib2_ipv6IfStatsEntry_t *)item->valp;
1957 1975 (char *)ip6 < (char *)item->valp + item->length;
1958 1976 /* LINTED: (note 1) */
1959 1977 ip6 = (mib2_ipv6IfStatsEntry_t *)((char *)ip6 +
1960 1978 ipv6IfStatsEntrySize)) {
1961 1979 if (ip6->ipv6IfIndex == 0) {
1962 1980 /*
1963 1981 * The "unknown interface" ip6
1964 1982 * mib. Just add to the sum.
1965 1983 */
1966 1984 sum_ip6_stats(ip6, &sum6);
1967 1985 continue; /* 'for' loop 2a */
1968 1986 }
1969 1987 if (Aflag) {
1970 1988 (void) printf("\nIPv6 for %s\n",
1971 1989 ifindex2str(ip6->ipv6IfIndex,
1972 1990 ifname));
1973 1991 print_ip6_stats(ip6);
1974 1992 }
1975 1993 sum_ip6_stats(ip6, &sum6);
1976 1994 } /* 'for' loop 2a ends */
1977 1995 (void) fputs("\nIPv6", stdout);
1978 1996 print_ip6_stats(&sum6);
1979 1997 break;
1980 1998 }
1981 1999 case MIB2_ICMP6: {
1982 2000 mib2_ipv6IfIcmpEntry_t *icmp6;
1983 2001 mib2_ipv6IfIcmpEntry_t sum6;
1984 2002
1985 2003 if (!(protocol_selected(IPPROTO_ICMPV6)) ||
1986 2004 !(family_selected(AF_INET6)))
1987 2005 break;
1988 2006 bzero(&sum6, sizeof (sum6));
1989 2007 /* 'for' loop 2b: */
1990 2008 for (icmp6 = (mib2_ipv6IfIcmpEntry_t *)item->valp;
1991 2009 (char *)icmp6 < (char *)item->valp + item->length;
1992 2010 icmp6 = (void *)((char *)icmp6 +
1993 2011 ipv6IfIcmpEntrySize)) {
1994 2012 if (icmp6->ipv6IfIcmpIfIndex == 0) {
1995 2013 /*
1996 2014 * The "unknown interface" icmp6
1997 2015 * mib. Just add to the sum.
1998 2016 */
1999 2017 sum_icmp6_stats(icmp6, &sum6);
2000 2018 continue; /* 'for' loop 2b: */
2001 2019 }
2002 2020 if (Aflag) {
2003 2021 (void) printf("\nICMPv6 for %s\n",
2004 2022 ifindex2str(
2005 2023 icmp6->ipv6IfIcmpIfIndex, ifname));
2006 2024 print_icmp6_stats(icmp6);
2007 2025 }
2008 2026 sum_icmp6_stats(icmp6, &sum6);
2009 2027 } /* 'for' loop 2b ends */
2010 2028 (void) fputs("\nICMPv6", stdout);
2011 2029 print_icmp6_stats(&sum6);
2012 2030 break;
2013 2031 }
2014 2032 case MIB2_TCP: {
2015 2033 mib2_tcp_t *tcp = (mib2_tcp_t *)item->valp;
2016 2034
2017 2035 if (protocol_selected(IPPROTO_TCP) &&
2018 2036 (family_selected(AF_INET) ||
2019 2037 family_selected(AF_INET6))) {
2020 2038 (void) fputs("\nTCP", stdout);
2021 2039 print_tcp_stats(tcp);
2022 2040 }
2023 2041 break;
2024 2042 }
2025 2043 case MIB2_UDP: {
2026 2044 mib2_udp_t *udp = (mib2_udp_t *)item->valp;
2027 2045
2028 2046 if (protocol_selected(IPPROTO_UDP) &&
2029 2047 (family_selected(AF_INET) ||
2030 2048 family_selected(AF_INET6))) {
2031 2049 (void) fputs("\nUDP", stdout);
2032 2050 print_udp_stats(udp);
2033 2051 }
2034 2052 break;
2035 2053 }
2036 2054 case MIB2_SCTP: {
2037 2055 mib2_sctp_t *sctp = (mib2_sctp_t *)item->valp;
2038 2056
2039 2057 if (protocol_selected(IPPROTO_SCTP) &&
2040 2058 (family_selected(AF_INET) ||
2041 2059 family_selected(AF_INET6))) {
2042 2060 (void) fputs("\nSCTP", stdout);
2043 2061 print_sctp_stats(sctp);
2044 2062 }
2045 2063 break;
2046 2064 }
2047 2065 case EXPER_RAWIP: {
2048 2066 mib2_rawip_t *rawip =
2049 2067 (mib2_rawip_t *)item->valp;
2050 2068
2051 2069 if (protocol_selected(IPPROTO_RAW) &&
2052 2070 (family_selected(AF_INET) ||
2053 2071 family_selected(AF_INET6))) {
2054 2072 (void) fputs("\nRAWIP", stdout);
2055 2073 print_rawip_stats(rawip);
2056 2074 }
2057 2075 break;
2058 2076 }
2059 2077 case EXPER_IGMP: {
2060 2078 struct igmpstat *igps =
2061 2079 (struct igmpstat *)item->valp;
2062 2080
2063 2081 if (protocol_selected(IPPROTO_IGMP) &&
2064 2082 (family_selected(AF_INET))) {
2065 2083 (void) fputs("\nIGMP:\n", stdout);
2066 2084 print_igmp_stats(igps);
2067 2085 }
2068 2086 break;
2069 2087 }
2070 2088 }
2071 2089 } /* 'for' loop 1 ends */
2072 2090 (void) putchar('\n');
2073 2091 (void) fflush(stdout);
2074 2092 }
2075 2093
2076 2094 static void
2077 2095 print_ip_stats(mib2_ip_t *ip)
2078 2096 {
2079 2097 prval_init();
2080 2098 pr_int_val("ipForwarding", ip->ipForwarding);
2081 2099 pr_int_val("ipDefaultTTL", ip->ipDefaultTTL);
2082 2100 prval("ipInReceives", ip->ipInReceives);
2083 2101 prval("ipInHdrErrors", ip->ipInHdrErrors);
2084 2102 prval("ipInAddrErrors", ip->ipInAddrErrors);
2085 2103 prval("ipInCksumErrs", ip->ipInCksumErrs);
2086 2104 prval("ipForwDatagrams", ip->ipForwDatagrams);
2087 2105 prval("ipForwProhibits", ip->ipForwProhibits);
2088 2106 prval("ipInUnknownProtos", ip->ipInUnknownProtos);
2089 2107 prval("ipInDiscards", ip->ipInDiscards);
2090 2108 prval("ipInDelivers", ip->ipInDelivers);
2091 2109 prval("ipOutRequests", ip->ipOutRequests);
2092 2110 prval("ipOutDiscards", ip->ipOutDiscards);
2093 2111 prval("ipOutNoRoutes", ip->ipOutNoRoutes);
2094 2112 pr_int_val("ipReasmTimeout", ip->ipReasmTimeout);
2095 2113 prval("ipReasmReqds", ip->ipReasmReqds);
2096 2114 prval("ipReasmOKs", ip->ipReasmOKs);
2097 2115 prval("ipReasmFails", ip->ipReasmFails);
2098 2116 prval("ipReasmDuplicates", ip->ipReasmDuplicates);
2099 2117 prval("ipReasmPartDups", ip->ipReasmPartDups);
2100 2118 prval("ipFragOKs", ip->ipFragOKs);
2101 2119 prval("ipFragFails", ip->ipFragFails);
2102 2120 prval("ipFragCreates", ip->ipFragCreates);
2103 2121 prval("ipRoutingDiscards", ip->ipRoutingDiscards);
2104 2122
2105 2123 prval("tcpInErrs", ip->tcpInErrs);
2106 2124 prval("udpNoPorts", ip->udpNoPorts);
2107 2125 prval("udpInCksumErrs", ip->udpInCksumErrs);
2108 2126 prval("udpInOverflows", ip->udpInOverflows);
2109 2127 prval("rawipInOverflows", ip->rawipInOverflows);
2110 2128 prval("ipsecInSucceeded", ip->ipsecInSucceeded);
2111 2129 prval("ipsecInFailed", ip->ipsecInFailed);
2112 2130 prval("ipInIPv6", ip->ipInIPv6);
2113 2131 prval("ipOutIPv6", ip->ipOutIPv6);
2114 2132 prval("ipOutSwitchIPv6", ip->ipOutSwitchIPv6);
2115 2133 prval_end();
2116 2134 }
2117 2135
2118 2136 static void
2119 2137 print_icmp_stats(mib2_icmp_t *icmp)
2120 2138 {
2121 2139 prval_init();
2122 2140 prval("icmpInMsgs", icmp->icmpInMsgs);
2123 2141 prval("icmpInErrors", icmp->icmpInErrors);
2124 2142 prval("icmpInCksumErrs", icmp->icmpInCksumErrs);
2125 2143 prval("icmpInUnknowns", icmp->icmpInUnknowns);
2126 2144 prval("icmpInDestUnreachs", icmp->icmpInDestUnreachs);
2127 2145 prval("icmpInTimeExcds", icmp->icmpInTimeExcds);
2128 2146 prval("icmpInParmProbs", icmp->icmpInParmProbs);
2129 2147 prval("icmpInSrcQuenchs", icmp->icmpInSrcQuenchs);
2130 2148 prval("icmpInRedirects", icmp->icmpInRedirects);
2131 2149 prval("icmpInBadRedirects", icmp->icmpInBadRedirects);
2132 2150 prval("icmpInEchos", icmp->icmpInEchos);
2133 2151 prval("icmpInEchoReps", icmp->icmpInEchoReps);
2134 2152 prval("icmpInTimestamps", icmp->icmpInTimestamps);
2135 2153 prval("icmpInTimestampReps", icmp->icmpInTimestampReps);
2136 2154 prval("icmpInAddrMasks", icmp->icmpInAddrMasks);
2137 2155 prval("icmpInAddrMaskReps", icmp->icmpInAddrMaskReps);
2138 2156 prval("icmpInFragNeeded", icmp->icmpInFragNeeded);
2139 2157 prval("icmpOutMsgs", icmp->icmpOutMsgs);
2140 2158 prval("icmpOutDrops", icmp->icmpOutDrops);
2141 2159 prval("icmpOutErrors", icmp->icmpOutErrors);
2142 2160 prval("icmpOutDestUnreachs", icmp->icmpOutDestUnreachs);
2143 2161 prval("icmpOutTimeExcds", icmp->icmpOutTimeExcds);
2144 2162 prval("icmpOutParmProbs", icmp->icmpOutParmProbs);
2145 2163 prval("icmpOutSrcQuenchs", icmp->icmpOutSrcQuenchs);
2146 2164 prval("icmpOutRedirects", icmp->icmpOutRedirects);
2147 2165 prval("icmpOutEchos", icmp->icmpOutEchos);
2148 2166 prval("icmpOutEchoReps", icmp->icmpOutEchoReps);
2149 2167 prval("icmpOutTimestamps", icmp->icmpOutTimestamps);
2150 2168 prval("icmpOutTimestampReps", icmp->icmpOutTimestampReps);
2151 2169 prval("icmpOutAddrMasks", icmp->icmpOutAddrMasks);
2152 2170 prval("icmpOutAddrMaskReps", icmp->icmpOutAddrMaskReps);
2153 2171 prval("icmpOutFragNeeded", icmp->icmpOutFragNeeded);
2154 2172 prval("icmpInOverflows", icmp->icmpInOverflows);
2155 2173 prval_end();
2156 2174 }
2157 2175
2158 2176 static void
2159 2177 print_ip6_stats(mib2_ipv6IfStatsEntry_t *ip6)
2160 2178 {
2161 2179 prval_init();
2162 2180 prval("ipv6Forwarding", ip6->ipv6Forwarding);
2163 2181 prval("ipv6DefaultHopLimit", ip6->ipv6DefaultHopLimit);
2164 2182
2165 2183 prval("ipv6InReceives", ip6->ipv6InReceives);
2166 2184 prval("ipv6InHdrErrors", ip6->ipv6InHdrErrors);
2167 2185 prval("ipv6InTooBigErrors", ip6->ipv6InTooBigErrors);
2168 2186 prval("ipv6InNoRoutes", ip6->ipv6InNoRoutes);
2169 2187 prval("ipv6InAddrErrors", ip6->ipv6InAddrErrors);
2170 2188 prval("ipv6InUnknownProtos", ip6->ipv6InUnknownProtos);
2171 2189 prval("ipv6InTruncatedPkts", ip6->ipv6InTruncatedPkts);
2172 2190 prval("ipv6InDiscards", ip6->ipv6InDiscards);
2173 2191 prval("ipv6InDelivers", ip6->ipv6InDelivers);
2174 2192 prval("ipv6OutForwDatagrams", ip6->ipv6OutForwDatagrams);
2175 2193 prval("ipv6OutRequests", ip6->ipv6OutRequests);
2176 2194 prval("ipv6OutDiscards", ip6->ipv6OutDiscards);
2177 2195 prval("ipv6OutNoRoutes", ip6->ipv6OutNoRoutes);
2178 2196 prval("ipv6OutFragOKs", ip6->ipv6OutFragOKs);
2179 2197 prval("ipv6OutFragFails", ip6->ipv6OutFragFails);
2180 2198 prval("ipv6OutFragCreates", ip6->ipv6OutFragCreates);
2181 2199 prval("ipv6ReasmReqds", ip6->ipv6ReasmReqds);
2182 2200 prval("ipv6ReasmOKs", ip6->ipv6ReasmOKs);
2183 2201 prval("ipv6ReasmFails", ip6->ipv6ReasmFails);
2184 2202 prval("ipv6InMcastPkts", ip6->ipv6InMcastPkts);
2185 2203 prval("ipv6OutMcastPkts", ip6->ipv6OutMcastPkts);
2186 2204 prval("ipv6ReasmDuplicates", ip6->ipv6ReasmDuplicates);
2187 2205 prval("ipv6ReasmPartDups", ip6->ipv6ReasmPartDups);
2188 2206 prval("ipv6ForwProhibits", ip6->ipv6ForwProhibits);
2189 2207 prval("udpInCksumErrs", ip6->udpInCksumErrs);
2190 2208 prval("udpInOverflows", ip6->udpInOverflows);
2191 2209 prval("rawipInOverflows", ip6->rawipInOverflows);
2192 2210 prval("ipv6InIPv4", ip6->ipv6InIPv4);
2193 2211 prval("ipv6OutIPv4", ip6->ipv6OutIPv4);
2194 2212 prval("ipv6OutSwitchIPv4", ip6->ipv6OutSwitchIPv4);
2195 2213 prval_end();
2196 2214 }
2197 2215
2198 2216 static void
2199 2217 print_icmp6_stats(mib2_ipv6IfIcmpEntry_t *icmp6)
2200 2218 {
2201 2219 prval_init();
2202 2220 prval("icmp6InMsgs", icmp6->ipv6IfIcmpInMsgs);
2203 2221 prval("icmp6InErrors", icmp6->ipv6IfIcmpInErrors);
2204 2222 prval("icmp6InDestUnreachs", icmp6->ipv6IfIcmpInDestUnreachs);
2205 2223 prval("icmp6InAdminProhibs", icmp6->ipv6IfIcmpInAdminProhibs);
2206 2224 prval("icmp6InTimeExcds", icmp6->ipv6IfIcmpInTimeExcds);
2207 2225 prval("icmp6InParmProblems", icmp6->ipv6IfIcmpInParmProblems);
2208 2226 prval("icmp6InPktTooBigs", icmp6->ipv6IfIcmpInPktTooBigs);
2209 2227 prval("icmp6InEchos", icmp6->ipv6IfIcmpInEchos);
2210 2228 prval("icmp6InEchoReplies", icmp6->ipv6IfIcmpInEchoReplies);
2211 2229 prval("icmp6InRouterSols", icmp6->ipv6IfIcmpInRouterSolicits);
2212 2230 prval("icmp6InRouterAds",
2213 2231 icmp6->ipv6IfIcmpInRouterAdvertisements);
2214 2232 prval("icmp6InNeighborSols", icmp6->ipv6IfIcmpInNeighborSolicits);
2215 2233 prval("icmp6InNeighborAds",
2216 2234 icmp6->ipv6IfIcmpInNeighborAdvertisements);
2217 2235 prval("icmp6InRedirects", icmp6->ipv6IfIcmpInRedirects);
2218 2236 prval("icmp6InBadRedirects", icmp6->ipv6IfIcmpInBadRedirects);
2219 2237 prval("icmp6InGroupQueries", icmp6->ipv6IfIcmpInGroupMembQueries);
2220 2238 prval("icmp6InGroupResps", icmp6->ipv6IfIcmpInGroupMembResponses);
2221 2239 prval("icmp6InGroupReds", icmp6->ipv6IfIcmpInGroupMembReductions);
2222 2240 prval("icmp6InOverflows", icmp6->ipv6IfIcmpInOverflows);
2223 2241 prval_end();
2224 2242 prval_init();
2225 2243 prval("icmp6OutMsgs", icmp6->ipv6IfIcmpOutMsgs);
2226 2244 prval("icmp6OutErrors", icmp6->ipv6IfIcmpOutErrors);
2227 2245 prval("icmp6OutDestUnreachs", icmp6->ipv6IfIcmpOutDestUnreachs);
2228 2246 prval("icmp6OutAdminProhibs", icmp6->ipv6IfIcmpOutAdminProhibs);
2229 2247 prval("icmp6OutTimeExcds", icmp6->ipv6IfIcmpOutTimeExcds);
2230 2248 prval("icmp6OutParmProblems", icmp6->ipv6IfIcmpOutParmProblems);
2231 2249 prval("icmp6OutPktTooBigs", icmp6->ipv6IfIcmpOutPktTooBigs);
2232 2250 prval("icmp6OutEchos", icmp6->ipv6IfIcmpOutEchos);
2233 2251 prval("icmp6OutEchoReplies", icmp6->ipv6IfIcmpOutEchoReplies);
2234 2252 prval("icmp6OutRouterSols", icmp6->ipv6IfIcmpOutRouterSolicits);
2235 2253 prval("icmp6OutRouterAds",
2236 2254 icmp6->ipv6IfIcmpOutRouterAdvertisements);
2237 2255 prval("icmp6OutNeighborSols", icmp6->ipv6IfIcmpOutNeighborSolicits);
2238 2256 prval("icmp6OutNeighborAds",
2239 2257 icmp6->ipv6IfIcmpOutNeighborAdvertisements);
2240 2258 prval("icmp6OutRedirects", icmp6->ipv6IfIcmpOutRedirects);
2241 2259 prval("icmp6OutGroupQueries", icmp6->ipv6IfIcmpOutGroupMembQueries);
2242 2260 prval("icmp6OutGroupResps",
2243 2261 icmp6->ipv6IfIcmpOutGroupMembResponses);
2244 2262 prval("icmp6OutGroupReds",
2245 2263 icmp6->ipv6IfIcmpOutGroupMembReductions);
2246 2264 prval_end();
2247 2265 }
2248 2266
2249 2267 static void
2250 2268 print_sctp_stats(mib2_sctp_t *sctp)
2251 2269 {
2252 2270 prval_init();
2253 2271 pr_sctp_rtoalgo("sctpRtoAlgorithm", sctp->sctpRtoAlgorithm);
2254 2272 prval("sctpRtoMin", sctp->sctpRtoMin);
2255 2273 prval("sctpRtoMax", sctp->sctpRtoMax);
2256 2274 prval("sctpRtoInitial", sctp->sctpRtoInitial);
2257 2275 pr_int_val("sctpMaxAssocs", sctp->sctpMaxAssocs);
2258 2276 prval("sctpValCookieLife", sctp->sctpValCookieLife);
2259 2277 prval("sctpMaxInitRetr", sctp->sctpMaxInitRetr);
2260 2278 prval("sctpCurrEstab", sctp->sctpCurrEstab);
2261 2279 prval("sctpActiveEstab", sctp->sctpActiveEstab);
2262 2280 prval("sctpPassiveEstab", sctp->sctpPassiveEstab);
2263 2281 prval("sctpAborted", sctp->sctpAborted);
2264 2282 prval("sctpShutdowns", sctp->sctpShutdowns);
2265 2283 prval("sctpOutOfBlue", sctp->sctpOutOfBlue);
2266 2284 prval("sctpChecksumError", sctp->sctpChecksumError);
2267 2285 prval64("sctpOutCtrlChunks", sctp->sctpOutCtrlChunks);
2268 2286 prval64("sctpOutOrderChunks", sctp->sctpOutOrderChunks);
2269 2287 prval64("sctpOutUnorderChunks", sctp->sctpOutUnorderChunks);
2270 2288 prval64("sctpRetransChunks", sctp->sctpRetransChunks);
2271 2289 prval("sctpOutAck", sctp->sctpOutAck);
2272 2290 prval("sctpOutAckDelayed", sctp->sctpOutAckDelayed);
2273 2291 prval("sctpOutWinUpdate", sctp->sctpOutWinUpdate);
2274 2292 prval("sctpOutFastRetrans", sctp->sctpOutFastRetrans);
2275 2293 prval("sctpOutWinProbe", sctp->sctpOutWinProbe);
2276 2294 prval64("sctpInCtrlChunks", sctp->sctpInCtrlChunks);
2277 2295 prval64("sctpInOrderChunks", sctp->sctpInOrderChunks);
2278 2296 prval64("sctpInUnorderChunks", sctp->sctpInUnorderChunks);
2279 2297 prval("sctpInAck", sctp->sctpInAck);
2280 2298 prval("sctpInDupAck", sctp->sctpInDupAck);
2281 2299 prval("sctpInAckUnsent", sctp->sctpInAckUnsent);
2282 2300 prval64("sctpFragUsrMsgs", sctp->sctpFragUsrMsgs);
2283 2301 prval64("sctpReasmUsrMsgs", sctp->sctpReasmUsrMsgs);
2284 2302 prval64("sctpOutSCTPPkts", sctp->sctpOutSCTPPkts);
2285 2303 prval64("sctpInSCTPPkts", sctp->sctpInSCTPPkts);
2286 2304 prval("sctpInInvalidCookie", sctp->sctpInInvalidCookie);
2287 2305 prval("sctpTimRetrans", sctp->sctpTimRetrans);
2288 2306 prval("sctpTimRetransDrop", sctp->sctpTimRetransDrop);
2289 2307 prval("sctpTimHearBeatProbe", sctp->sctpTimHeartBeatProbe);
2290 2308 prval("sctpTimHearBeatDrop", sctp->sctpTimHeartBeatDrop);
2291 2309 prval("sctpListenDrop", sctp->sctpListenDrop);
2292 2310 prval("sctpInClosed", sctp->sctpInClosed);
2293 2311 prval_end();
2294 2312 }
2295 2313
2296 2314 static void
2297 2315 print_tcp_stats(mib2_tcp_t *tcp)
2298 2316 {
2299 2317 prval_init();
2300 2318 pr_int_val("tcpRtoAlgorithm", tcp->tcpRtoAlgorithm);
2301 2319 pr_int_val("tcpRtoMin", tcp->tcpRtoMin);
2302 2320 pr_int_val("tcpRtoMax", tcp->tcpRtoMax);
2303 2321 pr_int_val("tcpMaxConn", tcp->tcpMaxConn);
2304 2322 prval("tcpActiveOpens", tcp->tcpActiveOpens);
2305 2323 prval("tcpPassiveOpens", tcp->tcpPassiveOpens);
2306 2324 prval("tcpAttemptFails", tcp->tcpAttemptFails);
2307 2325 prval("tcpEstabResets", tcp->tcpEstabResets);
2308 2326 prval("tcpCurrEstab", tcp->tcpCurrEstab);
2309 2327 prval64("tcpOutSegs", tcp->tcpHCOutSegs);
2310 2328 prval("tcpOutDataSegs", tcp->tcpOutDataSegs);
2311 2329 prval("tcpOutDataBytes", tcp->tcpOutDataBytes);
2312 2330 prval("tcpRetransSegs", tcp->tcpRetransSegs);
2313 2331 prval("tcpRetransBytes", tcp->tcpRetransBytes);
2314 2332 prval("tcpOutAck", tcp->tcpOutAck);
2315 2333 prval("tcpOutAckDelayed", tcp->tcpOutAckDelayed);
2316 2334 prval("tcpOutUrg", tcp->tcpOutUrg);
2317 2335 prval("tcpOutWinUpdate", tcp->tcpOutWinUpdate);
2318 2336 prval("tcpOutWinProbe", tcp->tcpOutWinProbe);
2319 2337 prval("tcpOutControl", tcp->tcpOutControl);
2320 2338 prval("tcpOutRsts", tcp->tcpOutRsts);
2321 2339 prval("tcpOutFastRetrans", tcp->tcpOutFastRetrans);
2322 2340 prval64("tcpInSegs", tcp->tcpHCInSegs);
2323 2341 prval_end();
2324 2342 prval("tcpInAckSegs", tcp->tcpInAckSegs);
2325 2343 prval("tcpInAckBytes", tcp->tcpInAckBytes);
2326 2344 prval("tcpInDupAck", tcp->tcpInDupAck);
2327 2345 prval("tcpInAckUnsent", tcp->tcpInAckUnsent);
2328 2346 prval("tcpInInorderSegs", tcp->tcpInDataInorderSegs);
2329 2347 prval("tcpInInorderBytes", tcp->tcpInDataInorderBytes);
2330 2348 prval("tcpInUnorderSegs", tcp->tcpInDataUnorderSegs);
2331 2349 prval("tcpInUnorderBytes", tcp->tcpInDataUnorderBytes);
2332 2350 prval("tcpInDupSegs", tcp->tcpInDataDupSegs);
2333 2351 prval("tcpInDupBytes", tcp->tcpInDataDupBytes);
2334 2352 prval("tcpInPartDupSegs", tcp->tcpInDataPartDupSegs);
2335 2353 prval("tcpInPartDupBytes", tcp->tcpInDataPartDupBytes);
2336 2354 prval("tcpInPastWinSegs", tcp->tcpInDataPastWinSegs);
2337 2355 prval("tcpInPastWinBytes", tcp->tcpInDataPastWinBytes);
2338 2356 prval("tcpInWinProbe", tcp->tcpInWinProbe);
2339 2357 prval("tcpInWinUpdate", tcp->tcpInWinUpdate);
2340 2358 prval("tcpInClosed", tcp->tcpInClosed);
2341 2359 prval("tcpRttNoUpdate", tcp->tcpRttNoUpdate);
2342 2360 prval("tcpRttUpdate", tcp->tcpRttUpdate);
2343 2361 prval("tcpTimRetrans", tcp->tcpTimRetrans);
2344 2362 prval("tcpTimRetransDrop", tcp->tcpTimRetransDrop);
2345 2363 prval("tcpTimKeepalive", tcp->tcpTimKeepalive);
2346 2364 prval("tcpTimKeepaliveProbe", tcp->tcpTimKeepaliveProbe);
2347 2365 prval("tcpTimKeepaliveDrop", tcp->tcpTimKeepaliveDrop);
2348 2366 prval("tcpListenDrop", tcp->tcpListenDrop);
2349 2367 prval("tcpListenDropQ0", tcp->tcpListenDropQ0);
2350 2368 prval("tcpHalfOpenDrop", tcp->tcpHalfOpenDrop);
2351 2369 prval("tcpOutSackRetrans", tcp->tcpOutSackRetransSegs);
2352 2370 prval_end();
2353 2371
2354 2372 }
2355 2373
2356 2374 static void
2357 2375 print_udp_stats(mib2_udp_t *udp)
2358 2376 {
2359 2377 prval_init();
2360 2378 prval64("udpInDatagrams", udp->udpHCInDatagrams);
2361 2379 prval("udpInErrors", udp->udpInErrors);
2362 2380 prval64("udpOutDatagrams", udp->udpHCOutDatagrams);
2363 2381 prval("udpOutErrors", udp->udpOutErrors);
2364 2382 prval_end();
2365 2383 }
2366 2384
2367 2385 static void
2368 2386 print_rawip_stats(mib2_rawip_t *rawip)
2369 2387 {
2370 2388 prval_init();
2371 2389 prval("rawipInDatagrams", rawip->rawipInDatagrams);
2372 2390 prval("rawipInErrors", rawip->rawipInErrors);
2373 2391 prval("rawipInCksumErrs", rawip->rawipInCksumErrs);
2374 2392 prval("rawipOutDatagrams", rawip->rawipOutDatagrams);
2375 2393 prval("rawipOutErrors", rawip->rawipOutErrors);
2376 2394 prval_end();
2377 2395 }
2378 2396
2379 2397 void
2380 2398 print_igmp_stats(struct igmpstat *igps)
2381 2399 {
2382 2400 (void) printf(" %10u message%s received\n",
2383 2401 igps->igps_rcv_total, PLURAL(igps->igps_rcv_total));
2384 2402 (void) printf(" %10u message%s received with too few bytes\n",
2385 2403 igps->igps_rcv_tooshort, PLURAL(igps->igps_rcv_tooshort));
2386 2404 (void) printf(" %10u message%s received with bad checksum\n",
2387 2405 igps->igps_rcv_badsum, PLURAL(igps->igps_rcv_badsum));
2388 2406 (void) printf(" %10u membership quer%s received\n",
2389 2407 igps->igps_rcv_queries, PLURALY(igps->igps_rcv_queries));
2390 2408 (void) printf(" %10u membership quer%s received with invalid "
2391 2409 "field(s)\n",
2392 2410 igps->igps_rcv_badqueries, PLURALY(igps->igps_rcv_badqueries));
2393 2411 (void) printf(" %10u membership report%s received\n",
2394 2412 igps->igps_rcv_reports, PLURAL(igps->igps_rcv_reports));
2395 2413 (void) printf(" %10u membership report%s received with invalid "
2396 2414 "field(s)\n",
2397 2415 igps->igps_rcv_badreports, PLURAL(igps->igps_rcv_badreports));
2398 2416 (void) printf(" %10u membership report%s received for groups to "
2399 2417 "which we belong\n",
2400 2418 igps->igps_rcv_ourreports, PLURAL(igps->igps_rcv_ourreports));
2401 2419 (void) printf(" %10u membership report%s sent\n",
2402 2420 igps->igps_snd_reports, PLURAL(igps->igps_snd_reports));
2403 2421 }
2404 2422
2405 2423 static void
2406 2424 print_mrt_stats(struct mrtstat *mrts)
2407 2425 {
2408 2426 (void) puts("DVMRP multicast routing:");
2409 2427 (void) printf(" %10u hit%s - kernel forwarding cache hits\n",
2410 2428 mrts->mrts_mfc_hits, PLURAL(mrts->mrts_mfc_hits));
2411 2429 (void) printf(" %10u miss%s - kernel forwarding cache misses\n",
2412 2430 mrts->mrts_mfc_misses, PLURALES(mrts->mrts_mfc_misses));
2413 2431 (void) printf(" %10u packet%s potentially forwarded\n",
2414 2432 mrts->mrts_fwd_in, PLURAL(mrts->mrts_fwd_in));
2415 2433 (void) printf(" %10u packet%s actually sent out\n",
2416 2434 mrts->mrts_fwd_out, PLURAL(mrts->mrts_fwd_out));
2417 2435 (void) printf(" %10u upcall%s - upcalls made to mrouted\n",
2418 2436 mrts->mrts_upcalls, PLURAL(mrts->mrts_upcalls));
2419 2437 (void) printf(" %10u packet%s not sent out due to lack of resources\n",
2420 2438 mrts->mrts_fwd_drop, PLURAL(mrts->mrts_fwd_drop));
2421 2439 (void) printf(" %10u datagram%s with malformed tunnel options\n",
2422 2440 mrts->mrts_bad_tunnel, PLURAL(mrts->mrts_bad_tunnel));
2423 2441 (void) printf(" %10u datagram%s with no room for tunnel options\n",
2424 2442 mrts->mrts_cant_tunnel, PLURAL(mrts->mrts_cant_tunnel));
2425 2443 (void) printf(" %10u datagram%s arrived on wrong interface\n",
2426 2444 mrts->mrts_wrong_if, PLURAL(mrts->mrts_wrong_if));
2427 2445 (void) printf(" %10u datagram%s dropped due to upcall Q overflow\n",
2428 2446 mrts->mrts_upq_ovflw, PLURAL(mrts->mrts_upq_ovflw));
2429 2447 (void) printf(" %10u datagram%s cleaned up by the cache\n",
2430 2448 mrts->mrts_cache_cleanups, PLURAL(mrts->mrts_cache_cleanups));
2431 2449 (void) printf(" %10u datagram%s dropped selectively by ratelimiter\n",
2432 2450 mrts->mrts_drop_sel, PLURAL(mrts->mrts_drop_sel));
2433 2451 (void) printf(" %10u datagram%s dropped - bucket Q overflow\n",
2434 2452 mrts->mrts_q_overflow, PLURAL(mrts->mrts_q_overflow));
2435 2453 (void) printf(" %10u datagram%s dropped - larger than bkt size\n",
2436 2454 mrts->mrts_pkt2large, PLURAL(mrts->mrts_pkt2large));
2437 2455 (void) printf("\nPIM multicast routing:\n");
2438 2456 (void) printf(" %10u datagram%s dropped - bad version number\n",
2439 2457 mrts->mrts_pim_badversion, PLURAL(mrts->mrts_pim_badversion));
2440 2458 (void) printf(" %10u datagram%s dropped - bad checksum\n",
2441 2459 mrts->mrts_pim_rcv_badcsum, PLURAL(mrts->mrts_pim_rcv_badcsum));
2442 2460 (void) printf(" %10u datagram%s dropped - bad register packets\n",
2443 2461 mrts->mrts_pim_badregisters, PLURAL(mrts->mrts_pim_badregisters));
2444 2462 (void) printf(
2445 2463 " %10u datagram%s potentially forwarded - register packets\n",
2446 2464 mrts->mrts_pim_regforwards, PLURAL(mrts->mrts_pim_regforwards));
2447 2465 (void) printf(" %10u datagram%s dropped - register send drops\n",
2448 2466 mrts->mrts_pim_regsend_drops, PLURAL(mrts->mrts_pim_regsend_drops));
2449 2467 (void) printf(" %10u datagram%s dropped - packet malformed\n",
2450 2468 mrts->mrts_pim_malformed, PLURAL(mrts->mrts_pim_malformed));
2451 2469 (void) printf(" %10u datagram%s dropped - no memory to forward\n",
2452 2470 mrts->mrts_pim_nomemory, PLURAL(mrts->mrts_pim_nomemory));
2453 2471 }
2454 2472
2455 2473 static void
2456 2474 sum_ip6_stats(mib2_ipv6IfStatsEntry_t *ip6, mib2_ipv6IfStatsEntry_t *sum6)
2457 2475 {
2458 2476 /* First few are not additive */
2459 2477 sum6->ipv6Forwarding = ip6->ipv6Forwarding;
2460 2478 sum6->ipv6DefaultHopLimit = ip6->ipv6DefaultHopLimit;
2461 2479
2462 2480 sum6->ipv6InReceives += ip6->ipv6InReceives;
2463 2481 sum6->ipv6InHdrErrors += ip6->ipv6InHdrErrors;
2464 2482 sum6->ipv6InTooBigErrors += ip6->ipv6InTooBigErrors;
2465 2483 sum6->ipv6InNoRoutes += ip6->ipv6InNoRoutes;
2466 2484 sum6->ipv6InAddrErrors += ip6->ipv6InAddrErrors;
2467 2485 sum6->ipv6InUnknownProtos += ip6->ipv6InUnknownProtos;
2468 2486 sum6->ipv6InTruncatedPkts += ip6->ipv6InTruncatedPkts;
2469 2487 sum6->ipv6InDiscards += ip6->ipv6InDiscards;
2470 2488 sum6->ipv6InDelivers += ip6->ipv6InDelivers;
2471 2489 sum6->ipv6OutForwDatagrams += ip6->ipv6OutForwDatagrams;
2472 2490 sum6->ipv6OutRequests += ip6->ipv6OutRequests;
2473 2491 sum6->ipv6OutDiscards += ip6->ipv6OutDiscards;
2474 2492 sum6->ipv6OutFragOKs += ip6->ipv6OutFragOKs;
2475 2493 sum6->ipv6OutFragFails += ip6->ipv6OutFragFails;
2476 2494 sum6->ipv6OutFragCreates += ip6->ipv6OutFragCreates;
2477 2495 sum6->ipv6ReasmReqds += ip6->ipv6ReasmReqds;
2478 2496 sum6->ipv6ReasmOKs += ip6->ipv6ReasmOKs;
2479 2497 sum6->ipv6ReasmFails += ip6->ipv6ReasmFails;
2480 2498 sum6->ipv6InMcastPkts += ip6->ipv6InMcastPkts;
2481 2499 sum6->ipv6OutMcastPkts += ip6->ipv6OutMcastPkts;
2482 2500 sum6->ipv6OutNoRoutes += ip6->ipv6OutNoRoutes;
2483 2501 sum6->ipv6ReasmDuplicates += ip6->ipv6ReasmDuplicates;
2484 2502 sum6->ipv6ReasmPartDups += ip6->ipv6ReasmPartDups;
2485 2503 sum6->ipv6ForwProhibits += ip6->ipv6ForwProhibits;
2486 2504 sum6->udpInCksumErrs += ip6->udpInCksumErrs;
2487 2505 sum6->udpInOverflows += ip6->udpInOverflows;
2488 2506 sum6->rawipInOverflows += ip6->rawipInOverflows;
2489 2507 }
2490 2508
2491 2509 static void
2492 2510 sum_icmp6_stats(mib2_ipv6IfIcmpEntry_t *icmp6, mib2_ipv6IfIcmpEntry_t *sum6)
2493 2511 {
2494 2512 sum6->ipv6IfIcmpInMsgs += icmp6->ipv6IfIcmpInMsgs;
2495 2513 sum6->ipv6IfIcmpInErrors += icmp6->ipv6IfIcmpInErrors;
2496 2514 sum6->ipv6IfIcmpInDestUnreachs += icmp6->ipv6IfIcmpInDestUnreachs;
2497 2515 sum6->ipv6IfIcmpInAdminProhibs += icmp6->ipv6IfIcmpInAdminProhibs;
2498 2516 sum6->ipv6IfIcmpInTimeExcds += icmp6->ipv6IfIcmpInTimeExcds;
2499 2517 sum6->ipv6IfIcmpInParmProblems += icmp6->ipv6IfIcmpInParmProblems;
2500 2518 sum6->ipv6IfIcmpInPktTooBigs += icmp6->ipv6IfIcmpInPktTooBigs;
2501 2519 sum6->ipv6IfIcmpInEchos += icmp6->ipv6IfIcmpInEchos;
2502 2520 sum6->ipv6IfIcmpInEchoReplies += icmp6->ipv6IfIcmpInEchoReplies;
2503 2521 sum6->ipv6IfIcmpInRouterSolicits += icmp6->ipv6IfIcmpInRouterSolicits;
2504 2522 sum6->ipv6IfIcmpInRouterAdvertisements +=
2505 2523 icmp6->ipv6IfIcmpInRouterAdvertisements;
2506 2524 sum6->ipv6IfIcmpInNeighborSolicits +=
2507 2525 icmp6->ipv6IfIcmpInNeighborSolicits;
2508 2526 sum6->ipv6IfIcmpInNeighborAdvertisements +=
2509 2527 icmp6->ipv6IfIcmpInNeighborAdvertisements;
2510 2528 sum6->ipv6IfIcmpInRedirects += icmp6->ipv6IfIcmpInRedirects;
2511 2529 sum6->ipv6IfIcmpInGroupMembQueries +=
2512 2530 icmp6->ipv6IfIcmpInGroupMembQueries;
2513 2531 sum6->ipv6IfIcmpInGroupMembResponses +=
2514 2532 icmp6->ipv6IfIcmpInGroupMembResponses;
2515 2533 sum6->ipv6IfIcmpInGroupMembReductions +=
2516 2534 icmp6->ipv6IfIcmpInGroupMembReductions;
2517 2535 sum6->ipv6IfIcmpOutMsgs += icmp6->ipv6IfIcmpOutMsgs;
2518 2536 sum6->ipv6IfIcmpOutErrors += icmp6->ipv6IfIcmpOutErrors;
2519 2537 sum6->ipv6IfIcmpOutDestUnreachs += icmp6->ipv6IfIcmpOutDestUnreachs;
2520 2538 sum6->ipv6IfIcmpOutAdminProhibs += icmp6->ipv6IfIcmpOutAdminProhibs;
2521 2539 sum6->ipv6IfIcmpOutTimeExcds += icmp6->ipv6IfIcmpOutTimeExcds;
2522 2540 sum6->ipv6IfIcmpOutParmProblems += icmp6->ipv6IfIcmpOutParmProblems;
2523 2541 sum6->ipv6IfIcmpOutPktTooBigs += icmp6->ipv6IfIcmpOutPktTooBigs;
2524 2542 sum6->ipv6IfIcmpOutEchos += icmp6->ipv6IfIcmpOutEchos;
2525 2543 sum6->ipv6IfIcmpOutEchoReplies += icmp6->ipv6IfIcmpOutEchoReplies;
2526 2544 sum6->ipv6IfIcmpOutRouterSolicits +=
2527 2545 icmp6->ipv6IfIcmpOutRouterSolicits;
2528 2546 sum6->ipv6IfIcmpOutRouterAdvertisements +=
2529 2547 icmp6->ipv6IfIcmpOutRouterAdvertisements;
2530 2548 sum6->ipv6IfIcmpOutNeighborSolicits +=
2531 2549 icmp6->ipv6IfIcmpOutNeighborSolicits;
2532 2550 sum6->ipv6IfIcmpOutNeighborAdvertisements +=
2533 2551 icmp6->ipv6IfIcmpOutNeighborAdvertisements;
2534 2552 sum6->ipv6IfIcmpOutRedirects += icmp6->ipv6IfIcmpOutRedirects;
2535 2553 sum6->ipv6IfIcmpOutGroupMembQueries +=
2536 2554 icmp6->ipv6IfIcmpOutGroupMembQueries;
2537 2555 sum6->ipv6IfIcmpOutGroupMembResponses +=
2538 2556 icmp6->ipv6IfIcmpOutGroupMembResponses;
2539 2557 sum6->ipv6IfIcmpOutGroupMembReductions +=
2540 2558 icmp6->ipv6IfIcmpOutGroupMembReductions;
2541 2559 sum6->ipv6IfIcmpInOverflows += icmp6->ipv6IfIcmpInOverflows;
2542 2560 }
2543 2561
2544 2562 /* ----------------------------- MRT_STAT_REPORT --------------------------- */
2545 2563
2546 2564 static void
2547 2565 mrt_stat_report(mib_item_t *curritem)
2548 2566 {
2549 2567 int jtemp = 0;
2550 2568 mib_item_t *tempitem;
2551 2569
2552 2570 if (!(family_selected(AF_INET)))
2553 2571 return;
2554 2572
2555 2573 (void) putchar('\n');
2556 2574 /* 'for' loop 1: */
2557 2575 for (tempitem = curritem;
2558 2576 tempitem;
2559 2577 tempitem = tempitem->next_item) {
2560 2578 if (Xflag) {
2561 2579 (void) printf("\n--- Entry %d ---\n", ++jtemp);
2562 2580 (void) printf("Group = %d, mib_id = %d, "
2563 2581 "length = %d, valp = 0x%p\n",
2564 2582 tempitem->group, tempitem->mib_id,
2565 2583 tempitem->length, tempitem->valp);
2566 2584 }
2567 2585
2568 2586 if (tempitem->mib_id == 0) {
2569 2587 switch (tempitem->group) {
2570 2588 case EXPER_DVMRP: {
2571 2589 struct mrtstat *mrts;
2572 2590 mrts = (struct mrtstat *)tempitem->valp;
2573 2591
2574 2592 if (!(family_selected(AF_INET)))
2575 2593 continue; /* 'for' loop 1 */
2576 2594
2577 2595 print_mrt_stats(mrts);
2578 2596 break;
2579 2597 }
2580 2598 }
2581 2599 }
2582 2600 } /* 'for' loop 1 ends */
2583 2601 (void) putchar('\n');
2584 2602 (void) fflush(stdout);
2585 2603 }
2586 2604
2587 2605 /*
2588 2606 * if_stat_total() - Computes totals for interface statistics
2589 2607 * and returns result by updating sumstats.
2590 2608 */
2591 2609 static void
2592 2610 if_stat_total(struct ifstat *oldstats, struct ifstat *newstats,
2593 2611 struct ifstat *sumstats)
2594 2612 {
2595 2613 sumstats->ipackets += newstats->ipackets - oldstats->ipackets;
2596 2614 sumstats->opackets += newstats->opackets - oldstats->opackets;
2597 2615 sumstats->ierrors += newstats->ierrors - oldstats->ierrors;
2598 2616 sumstats->oerrors += newstats->oerrors - oldstats->oerrors;
2599 2617 sumstats->collisions += newstats->collisions - oldstats->collisions;
2600 2618 }
2601 2619
2602 2620 /* --------------------- IF_REPORT (netstat -i) -------------------------- */
2603 2621
2604 2622 static struct ifstat zerostat = {
2605 2623 0LL, 0LL, 0LL, 0LL, 0LL
2606 2624 };
2607 2625
2608 2626 static void
2609 2627 if_report(mib_item_t *item, char *matchname,
2610 2628 int Iflag_only, boolean_t once_only)
2611 2629 {
2612 2630 static boolean_t reentry = B_FALSE;
2613 2631 boolean_t alreadydone = B_FALSE;
2614 2632 int jtemp = 0;
2615 2633 uint32_t ifindex_v4 = 0;
2616 2634 uint32_t ifindex_v6 = 0;
2617 2635 boolean_t first_header = B_TRUE;
2618 2636
2619 2637 /* 'for' loop 1: */
2620 2638 for (; item; item = item->next_item) {
2621 2639 if (Xflag) {
2622 2640 (void) printf("\n--- Entry %d ---\n", ++jtemp);
2623 2641 (void) printf("Group = %d, mib_id = %d, "
2624 2642 "length = %d, valp = 0x%p\n",
2625 2643 item->group, item->mib_id, item->length,
2626 2644 item->valp);
2627 2645 }
2628 2646
2629 2647 switch (item->group) {
2630 2648 case MIB2_IP:
2631 2649 if (item->mib_id != MIB2_IP_ADDR ||
2632 2650 !family_selected(AF_INET))
2633 2651 continue; /* 'for' loop 1 */
2634 2652 {
2635 2653 static struct ifstat old = {0L, 0L, 0L, 0L, 0L};
2636 2654 static struct ifstat new = {0L, 0L, 0L, 0L, 0L};
2637 2655 struct ifstat sum;
2638 2656 struct iflist *newlist = NULL;
2639 2657 static struct iflist *oldlist = NULL;
2640 2658 kstat_t *ksp;
2641 2659
2642 2660 if (once_only) {
2643 2661 char ifname[LIFNAMSIZ + 1];
2644 2662 char logintname[LIFNAMSIZ + 1];
2645 2663 mib2_ipAddrEntry_t *ap;
2646 2664 struct ifstat stat = {0L, 0L, 0L, 0L, 0L};
2647 2665 boolean_t first = B_TRUE;
2648 2666 uint32_t new_ifindex;
2649 2667
2650 2668 if (Xflag)
2651 2669 (void) printf("if_report: %d items\n",
2652 2670 (item->length)
2653 2671 / sizeof (mib2_ipAddrEntry_t));
2654 2672
2655 2673 /* 'for' loop 2a: */
2656 2674 for (ap = (mib2_ipAddrEntry_t *)item->valp;
2657 2675 (char *)ap < (char *)item->valp
2658 2676 + item->length;
2659 2677 ap++) {
2660 2678 (void) octetstr(&ap->ipAdEntIfIndex,
2661 2679 'a', logintname,
2662 2680 sizeof (logintname));
2663 2681 (void) strcpy(ifname, logintname);
2664 2682 (void) strtok(ifname, ":");
2665 2683 if (matchname != NULL &&
2666 2684 strcmp(matchname, ifname) != 0 &&
2667 2685 strcmp(matchname, logintname) != 0)
2668 2686 continue; /* 'for' loop 2a */
2669 2687 new_ifindex =
2670 2688 if_nametoindex(logintname);
2671 2689 /*
2672 2690 * First lookup the "link" kstats in
2673 2691 * case the link is renamed. Then
2674 2692 * fallback to the legacy kstats for
2675 2693 * those non-GLDv3 links.
2676 2694 */
2677 2695 if (new_ifindex != ifindex_v4 &&
2678 2696 (((ksp = kstat_lookup(kc, "link", 0,
2679 2697 ifname)) != NULL) ||
2680 2698 ((ksp = kstat_lookup(kc, NULL, -1,
2681 2699 ifname)) != NULL))) {
2682 2700 (void) safe_kstat_read(kc, ksp,
2683 2701 NULL);
2684 2702 stat.ipackets =
2685 2703 kstat_named_value(ksp,
2686 2704 "ipackets");
2687 2705 stat.ierrors =
2688 2706 kstat_named_value(ksp,
2689 2707 "ierrors");
2690 2708 stat.opackets =
2691 2709 kstat_named_value(ksp,
2692 2710 "opackets");
2693 2711 stat.oerrors =
2694 2712 kstat_named_value(ksp,
2695 2713 "oerrors");
2696 2714 stat.collisions =
2697 2715 kstat_named_value(ksp,
2698 2716 "collisions");
2699 2717 if (first) {
2700 2718 if (!first_header)
2701 2719 (void) putchar('\n');
2702 2720 first_header = B_FALSE;
2703 2721 (void) printf(
2704 2722 "%-5.5s %-5.5s%-13.13s "
2705 2723 "%-14.14s %-6.6s %-5.5s "
2706 2724 "%-6.6s %-5.5s %-6.6s "
2707 2725 "%-6.6s\n",
2708 2726 "Name", "Mtu", "Net/Dest",
2709 2727 "Address", "Ipkts",
2710 2728 "Ierrs", "Opkts", "Oerrs",
2711 2729 "Collis", "Queue");
2712 2730
2713 2731 first = B_FALSE;
2714 2732 }
2715 2733 if_report_ip4(ap, ifname,
2716 2734 logintname, &stat, B_TRUE);
2717 2735 ifindex_v4 = new_ifindex;
2718 2736 } else {
2719 2737 if_report_ip4(ap, ifname,
2720 2738 logintname, &stat, B_FALSE);
2721 2739 }
2722 2740 } /* 'for' loop 2a ends */
2723 2741 } else if (!alreadydone) {
2724 2742 char ifname[LIFNAMSIZ + 1];
2725 2743 char buf[LIFNAMSIZ + 1];
2726 2744 mib2_ipAddrEntry_t *ap;
2727 2745 struct ifstat t;
2728 2746 struct iflist *tlp = NULL;
2729 2747 struct iflist **nextnew = &newlist;
2730 2748 struct iflist *walkold;
2731 2749 struct iflist *cleanlist;
2732 2750 boolean_t found_if = B_FALSE;
2733 2751
2734 2752 alreadydone = B_TRUE; /* ignore other case */
2735 2753
2736 2754 /*
2737 2755 * Check if there is anything to do.
2738 2756 */
2739 2757 if (item->length <
2740 2758 sizeof (mib2_ipAddrEntry_t)) {
2741 2759 fail(0, "No compatible interfaces");
2742 2760 }
2743 2761
2744 2762 /*
2745 2763 * 'for' loop 2b: find the "right" entry:
2746 2764 * If an interface name to match has been
2747 2765 * supplied then try and find it, otherwise
2748 2766 * match the first non-loopback interface found.
2749 2767 * Use lo0 if all else fails.
2750 2768 */
2751 2769 for (ap = (mib2_ipAddrEntry_t *)item->valp;
2752 2770 (char *)ap < (char *)item->valp
2753 2771 + item->length;
2754 2772 ap++) {
2755 2773 (void) octetstr(&ap->ipAdEntIfIndex,
2756 2774 'a', ifname, sizeof (ifname));
2757 2775 (void) strtok(ifname, ":");
2758 2776
2759 2777 if (matchname) {
2760 2778 if (strcmp(matchname,
2761 2779 ifname) == 0) {
2762 2780 /* 'for' loop 2b */
2763 2781 found_if = B_TRUE;
2764 2782 break;
2765 2783 }
2766 2784 } else if (strcmp(ifname, "lo0") != 0)
2767 2785 break; /* 'for' loop 2b */
2768 2786 } /* 'for' loop 2b ends */
2769 2787
2770 2788 if (matchname == NULL) {
2771 2789 matchname = ifname;
2772 2790 } else {
2773 2791 if (!found_if)
2774 2792 fail(0, "-I: %s no such "
2775 2793 "interface.", matchname);
2776 2794 }
2777 2795
2778 2796 if (Iflag_only == 0 || !reentry) {
2779 2797 (void) printf(" input %-6.6s "
2780 2798 "output ",
2781 2799 matchname);
2782 2800 (void) printf(" input (Total) "
2783 2801 "output\n");
2784 2802 (void) printf("%-7.7s %-5.5s %-7.7s "
2785 2803 "%-5.5s %-6.6s ",
2786 2804 "packets", "errs", "packets",
2787 2805 "errs", "colls");
2788 2806 (void) printf("%-7.7s %-5.5s %-7.7s "
2789 2807 "%-5.5s %-6.6s\n",
2790 2808 "packets", "errs", "packets",
2791 2809 "errs", "colls");
2792 2810 }
2793 2811
2794 2812 sum = zerostat;
2795 2813
2796 2814 /* 'for' loop 2c: */
2797 2815 for (ap = (mib2_ipAddrEntry_t *)item->valp;
2798 2816 (char *)ap < (char *)item->valp
2799 2817 + item->length;
2800 2818 ap++) {
2801 2819 (void) octetstr(&ap->ipAdEntIfIndex,
2802 2820 'a', buf, sizeof (buf));
2803 2821 (void) strtok(buf, ":");
2804 2822
2805 2823 /*
2806 2824 * We have reduced the IP interface
2807 2825 * name, which could have been a
2808 2826 * logical, down to a name suitable
2809 2827 * for use with kstats.
2810 2828 * We treat this name as unique and
2811 2829 * only collate statistics for it once
2812 2830 * per pass. This is to avoid falsely
2813 2831 * amplifying these statistics by the
2814 2832 * the number of logical instances.
2815 2833 */
2816 2834 if ((tlp != NULL) &&
2817 2835 ((strcmp(buf, tlp->ifname) == 0))) {
2818 2836 continue;
2819 2837 }
2820 2838
2821 2839 /*
2822 2840 * First lookup the "link" kstats in
2823 2841 * case the link is renamed. Then
2824 2842 * fallback to the legacy kstats for
2825 2843 * those non-GLDv3 links.
2826 2844 */
2827 2845 if (((ksp = kstat_lookup(kc, "link",
2828 2846 0, buf)) != NULL ||
2829 2847 (ksp = kstat_lookup(kc, NULL, -1,
2830 2848 buf)) != NULL) && (ksp->ks_type ==
2831 2849 KSTAT_TYPE_NAMED)) {
2832 2850 (void) safe_kstat_read(kc, ksp,
2833 2851 NULL);
2834 2852 }
2835 2853
2836 2854 t.ipackets = kstat_named_value(ksp,
2837 2855 "ipackets");
2838 2856 t.ierrors = kstat_named_value(ksp,
2839 2857 "ierrors");
2840 2858 t.opackets = kstat_named_value(ksp,
2841 2859 "opackets");
2842 2860 t.oerrors = kstat_named_value(ksp,
2843 2861 "oerrors");
2844 2862 t.collisions = kstat_named_value(ksp,
2845 2863 "collisions");
2846 2864
2847 2865 if (strcmp(buf, matchname) == 0)
2848 2866 new = t;
2849 2867
2850 2868 /* Build the interface list */
2851 2869
2852 2870 tlp = malloc(sizeof (struct iflist));
2853 2871 (void) strlcpy(tlp->ifname, buf,
2854 2872 sizeof (tlp->ifname));
2855 2873 tlp->tot = t;
2856 2874 *nextnew = tlp;
2857 2875 nextnew = &tlp->next_if;
2858 2876
2859 2877 /*
2860 2878 * First time through.
2861 2879 * Just add up the interface stats.
2862 2880 */
2863 2881
2864 2882 if (oldlist == NULL) {
2865 2883 if_stat_total(&zerostat,
2866 2884 &t, &sum);
2867 2885 continue;
2868 2886 }
2869 2887
2870 2888 /*
2871 2889 * Walk old list for the interface.
2872 2890 *
2873 2891 * If found, add difference to total.
2874 2892 *
2875 2893 * If not, an interface has been plumbed
2876 2894 * up. In this case, we will simply
2877 2895 * ignore the new interface until the
2878 2896 * next interval; as there's no easy way
2879 2897 * to acquire statistics between time
2880 2898 * of the plumb and the next interval
2881 2899 * boundary. This results in inaccurate
2882 2900 * total values for current interval.
2883 2901 *
2884 2902 * Note the case when an interface is
2885 2903 * unplumbed; as similar problems exist.
2886 2904 * The unplumbed interface is not in the
2887 2905 * current list, and there's no easy way
2888 2906 * to account for the statistics between
2889 2907 * the previous interval and time of the
2890 2908 * unplumb. Therefore, we (in a sense)
2891 2909 * ignore the removed interface by only
2892 2910 * involving "current" interfaces when
2893 2911 * computing the total statistics.
2894 2912 * Unfortunately, this also results in
2895 2913 * inaccurate values for interval total.
2896 2914 */
2897 2915
2898 2916 for (walkold = oldlist;
2899 2917 walkold != NULL;
2900 2918 walkold = walkold->next_if) {
2901 2919 if (strcmp(walkold->ifname,
2902 2920 buf) == 0) {
2903 2921 if_stat_total(
2904 2922 &walkold->tot,
2905 2923 &t, &sum);
2906 2924 break;
2907 2925 }
2908 2926 }
2909 2927
2910 2928 } /* 'for' loop 2c ends */
2911 2929
2912 2930 *nextnew = NULL;
2913 2931
2914 2932 (void) printf("%-7llu %-5llu %-7llu "
2915 2933 "%-5llu %-6llu ",
2916 2934 new.ipackets - old.ipackets,
2917 2935 new.ierrors - old.ierrors,
2918 2936 new.opackets - old.opackets,
2919 2937 new.oerrors - old.oerrors,
2920 2938 new.collisions - old.collisions);
2921 2939
2922 2940 (void) printf("%-7llu %-5llu %-7llu "
2923 2941 "%-5llu %-6llu\n", sum.ipackets,
2924 2942 sum.ierrors, sum.opackets,
2925 2943 sum.oerrors, sum.collisions);
2926 2944
2927 2945 /*
2928 2946 * Tidy things up once finished.
2929 2947 */
2930 2948
2931 2949 old = new;
2932 2950 cleanlist = oldlist;
2933 2951 oldlist = newlist;
2934 2952 while (cleanlist != NULL) {
2935 2953 tlp = cleanlist->next_if;
2936 2954 free(cleanlist);
2937 2955 cleanlist = tlp;
2938 2956 }
2939 2957 }
2940 2958 break;
2941 2959 }
2942 2960 case MIB2_IP6:
2943 2961 if (item->mib_id != MIB2_IP6_ADDR ||
2944 2962 !family_selected(AF_INET6))
2945 2963 continue; /* 'for' loop 1 */
2946 2964 {
2947 2965 static struct ifstat old6 = {0L, 0L, 0L, 0L, 0L};
2948 2966 static struct ifstat new6 = {0L, 0L, 0L, 0L, 0L};
2949 2967 struct ifstat sum6;
2950 2968 struct iflist *newlist6 = NULL;
2951 2969 static struct iflist *oldlist6 = NULL;
2952 2970 kstat_t *ksp;
2953 2971
2954 2972 if (once_only) {
2955 2973 char ifname[LIFNAMSIZ + 1];
2956 2974 char logintname[LIFNAMSIZ + 1];
2957 2975 mib2_ipv6AddrEntry_t *ap6;
2958 2976 struct ifstat stat = {0L, 0L, 0L, 0L, 0L};
2959 2977 boolean_t first = B_TRUE;
2960 2978 uint32_t new_ifindex;
2961 2979
2962 2980 if (Xflag)
2963 2981 (void) printf("if_report: %d items\n",
2964 2982 (item->length)
2965 2983 / sizeof (mib2_ipv6AddrEntry_t));
2966 2984 /* 'for' loop 2d: */
2967 2985 for (ap6 = (mib2_ipv6AddrEntry_t *)item->valp;
2968 2986 (char *)ap6 < (char *)item->valp
2969 2987 + item->length;
2970 2988 ap6++) {
2971 2989 (void) octetstr(&ap6->ipv6AddrIfIndex,
2972 2990 'a', logintname,
2973 2991 sizeof (logintname));
2974 2992 (void) strcpy(ifname, logintname);
2975 2993 (void) strtok(ifname, ":");
2976 2994 if (matchname != NULL &&
2977 2995 strcmp(matchname, ifname) != 0 &&
2978 2996 strcmp(matchname, logintname) != 0)
2979 2997 continue; /* 'for' loop 2d */
2980 2998 new_ifindex =
2981 2999 if_nametoindex(logintname);
2982 3000
2983 3001 /*
2984 3002 * First lookup the "link" kstats in
2985 3003 * case the link is renamed. Then
2986 3004 * fallback to the legacy kstats for
2987 3005 * those non-GLDv3 links.
2988 3006 */
2989 3007 if (new_ifindex != ifindex_v6 &&
2990 3008 ((ksp = kstat_lookup(kc, "link", 0,
2991 3009 ifname)) != NULL ||
2992 3010 (ksp = kstat_lookup(kc, NULL, -1,
2993 3011 ifname)) != NULL)) {
2994 3012 (void) safe_kstat_read(kc, ksp,
2995 3013 NULL);
2996 3014 stat.ipackets =
2997 3015 kstat_named_value(ksp,
2998 3016 "ipackets");
2999 3017 stat.ierrors =
3000 3018 kstat_named_value(ksp,
3001 3019 "ierrors");
3002 3020 stat.opackets =
3003 3021 kstat_named_value(ksp,
3004 3022 "opackets");
3005 3023 stat.oerrors =
3006 3024 kstat_named_value(ksp,
3007 3025 "oerrors");
3008 3026 stat.collisions =
3009 3027 kstat_named_value(ksp,
3010 3028 "collisions");
3011 3029 if (first) {
3012 3030 if (!first_header)
3013 3031 (void) putchar('\n');
3014 3032 first_header = B_FALSE;
3015 3033 (void) printf(
3016 3034 "%-5.5s %-5.5s%"
3017 3035 "-27.27s %-27.27s "
3018 3036 "%-6.6s %-5.5s "
3019 3037 "%-6.6s %-5.5s "
3020 3038 "%-6.6s\n",
3021 3039 "Name", "Mtu",
3022 3040 "Net/Dest",
3023 3041 "Address", "Ipkts",
3024 3042 "Ierrs", "Opkts",
3025 3043 "Oerrs", "Collis");
3026 3044 first = B_FALSE;
3027 3045 }
3028 3046 if_report_ip6(ap6, ifname,
3029 3047 logintname, &stat, B_TRUE);
3030 3048 ifindex_v6 = new_ifindex;
3031 3049 } else {
3032 3050 if_report_ip6(ap6, ifname,
3033 3051 logintname, &stat, B_FALSE);
3034 3052 }
3035 3053 } /* 'for' loop 2d ends */
3036 3054 } else if (!alreadydone) {
3037 3055 char ifname[LIFNAMSIZ + 1];
3038 3056 char buf[IFNAMSIZ + 1];
3039 3057 mib2_ipv6AddrEntry_t *ap6;
3040 3058 struct ifstat t;
3041 3059 struct iflist *tlp = NULL;
3042 3060 struct iflist **nextnew = &newlist6;
3043 3061 struct iflist *walkold;
3044 3062 struct iflist *cleanlist;
3045 3063 boolean_t found_if = B_FALSE;
3046 3064
3047 3065 alreadydone = B_TRUE; /* ignore other case */
3048 3066
3049 3067 /*
3050 3068 * Check if there is anything to do.
3051 3069 */
3052 3070 if (item->length <
3053 3071 sizeof (mib2_ipv6AddrEntry_t)) {
3054 3072 fail(0, "No compatible interfaces");
3055 3073 }
3056 3074
3057 3075 /*
3058 3076 * 'for' loop 2e: find the "right" entry:
3059 3077 * If an interface name to match has been
3060 3078 * supplied then try and find it, otherwise
3061 3079 * match the first non-loopback interface found.
3062 3080 * Use lo0 if all else fails.
3063 3081 */
3064 3082 for (ap6 = (mib2_ipv6AddrEntry_t *)item->valp;
3065 3083 (char *)ap6 < (char *)item->valp
3066 3084 + item->length;
3067 3085 ap6++) {
3068 3086 (void) octetstr(&ap6->ipv6AddrIfIndex,
3069 3087 'a', ifname, sizeof (ifname));
3070 3088 (void) strtok(ifname, ":");
3071 3089
3072 3090 if (matchname) {
3073 3091 if (strcmp(matchname,
3074 3092 ifname) == 0) {
3075 3093 /* 'for' loop 2e */
3076 3094 found_if = B_TRUE;
3077 3095 break;
3078 3096 }
3079 3097 } else if (strcmp(ifname, "lo0") != 0)
3080 3098 break; /* 'for' loop 2e */
3081 3099 } /* 'for' loop 2e ends */
3082 3100
3083 3101 if (matchname == NULL) {
3084 3102 matchname = ifname;
3085 3103 } else {
3086 3104 if (!found_if)
3087 3105 fail(0, "-I: %s no such "
3088 3106 "interface.", matchname);
3089 3107 }
3090 3108
3091 3109 if (Iflag_only == 0 || !reentry) {
3092 3110 (void) printf(
3093 3111 " input %-6.6s"
3094 3112 " output ",
3095 3113 matchname);
3096 3114 (void) printf(" input (Total)"
3097 3115 " output\n");
3098 3116 (void) printf("%-7.7s %-5.5s %-7.7s "
3099 3117 "%-5.5s %-6.6s ",
3100 3118 "packets", "errs", "packets",
3101 3119 "errs", "colls");
3102 3120 (void) printf("%-7.7s %-5.5s %-7.7s "
3103 3121 "%-5.5s %-6.6s\n",
3104 3122 "packets", "errs", "packets",
3105 3123 "errs", "colls");
3106 3124 }
3107 3125
3108 3126 sum6 = zerostat;
3109 3127
3110 3128 /* 'for' loop 2f: */
3111 3129 for (ap6 = (mib2_ipv6AddrEntry_t *)item->valp;
3112 3130 (char *)ap6 < (char *)item->valp
3113 3131 + item->length;
3114 3132 ap6++) {
3115 3133 (void) octetstr(&ap6->ipv6AddrIfIndex,
3116 3134 'a', buf, sizeof (buf));
3117 3135 (void) strtok(buf, ":");
3118 3136
3119 3137 /*
3120 3138 * We have reduced the IP interface
3121 3139 * name, which could have been a
3122 3140 * logical, down to a name suitable
3123 3141 * for use with kstats.
3124 3142 * We treat this name as unique and
3125 3143 * only collate statistics for it once
3126 3144 * per pass. This is to avoid falsely
3127 3145 * amplifying these statistics by the
3128 3146 * the number of logical instances.
3129 3147 */
3130 3148
3131 3149 if ((tlp != NULL) &&
3132 3150 ((strcmp(buf, tlp->ifname) == 0))) {
3133 3151 continue;
3134 3152 }
3135 3153
3136 3154 /*
3137 3155 * First lookup the "link" kstats in
3138 3156 * case the link is renamed. Then
3139 3157 * fallback to the legacy kstats for
3140 3158 * those non-GLDv3 links.
3141 3159 */
3142 3160 if (((ksp = kstat_lookup(kc, "link",
3143 3161 0, buf)) != NULL ||
3144 3162 (ksp = kstat_lookup(kc, NULL, -1,
3145 3163 buf)) != NULL) && (ksp->ks_type ==
3146 3164 KSTAT_TYPE_NAMED)) {
3147 3165 (void) safe_kstat_read(kc,
3148 3166 ksp, NULL);
3149 3167 }
3150 3168
3151 3169 t.ipackets = kstat_named_value(ksp,
3152 3170 "ipackets");
3153 3171 t.ierrors = kstat_named_value(ksp,
3154 3172 "ierrors");
3155 3173 t.opackets = kstat_named_value(ksp,
3156 3174 "opackets");
3157 3175 t.oerrors = kstat_named_value(ksp,
3158 3176 "oerrors");
3159 3177 t.collisions = kstat_named_value(ksp,
3160 3178 "collisions");
3161 3179
3162 3180 if (strcmp(buf, matchname) == 0)
3163 3181 new6 = t;
3164 3182
3165 3183 /* Build the interface list */
3166 3184
3167 3185 tlp = malloc(sizeof (struct iflist));
3168 3186 (void) strlcpy(tlp->ifname, buf,
3169 3187 sizeof (tlp->ifname));
3170 3188 tlp->tot = t;
3171 3189 *nextnew = tlp;
3172 3190 nextnew = &tlp->next_if;
3173 3191
3174 3192 /*
3175 3193 * First time through.
3176 3194 * Just add up the interface stats.
3177 3195 */
3178 3196
3179 3197 if (oldlist6 == NULL) {
3180 3198 if_stat_total(&zerostat,
3181 3199 &t, &sum6);
3182 3200 continue;
3183 3201 }
3184 3202
3185 3203 /*
3186 3204 * Walk old list for the interface.
3187 3205 *
3188 3206 * If found, add difference to total.
3189 3207 *
3190 3208 * If not, an interface has been plumbed
3191 3209 * up. In this case, we will simply
3192 3210 * ignore the new interface until the
3193 3211 * next interval; as there's no easy way
3194 3212 * to acquire statistics between time
3195 3213 * of the plumb and the next interval
3196 3214 * boundary. This results in inaccurate
3197 3215 * total values for current interval.
3198 3216 *
3199 3217 * Note the case when an interface is
3200 3218 * unplumbed; as similar problems exist.
3201 3219 * The unplumbed interface is not in the
3202 3220 * current list, and there's no easy way
3203 3221 * to account for the statistics between
3204 3222 * the previous interval and time of the
3205 3223 * unplumb. Therefore, we (in a sense)
3206 3224 * ignore the removed interface by only
3207 3225 * involving "current" interfaces when
3208 3226 * computing the total statistics.
3209 3227 * Unfortunately, this also results in
3210 3228 * inaccurate values for interval total.
3211 3229 */
3212 3230
3213 3231 for (walkold = oldlist6;
3214 3232 walkold != NULL;
3215 3233 walkold = walkold->next_if) {
3216 3234 if (strcmp(walkold->ifname,
3217 3235 buf) == 0) {
3218 3236 if_stat_total(
3219 3237 &walkold->tot,
3220 3238 &t, &sum6);
3221 3239 break;
3222 3240 }
3223 3241 }
3224 3242
3225 3243 } /* 'for' loop 2f ends */
3226 3244
3227 3245 *nextnew = NULL;
3228 3246
3229 3247 (void) printf("%-7llu %-5llu %-7llu "
3230 3248 "%-5llu %-6llu ",
3231 3249 new6.ipackets - old6.ipackets,
3232 3250 new6.ierrors - old6.ierrors,
3233 3251 new6.opackets - old6.opackets,
3234 3252 new6.oerrors - old6.oerrors,
3235 3253 new6.collisions - old6.collisions);
3236 3254
3237 3255 (void) printf("%-7llu %-5llu %-7llu "
3238 3256 "%-5llu %-6llu\n", sum6.ipackets,
3239 3257 sum6.ierrors, sum6.opackets,
3240 3258 sum6.oerrors, sum6.collisions);
3241 3259
3242 3260 /*
3243 3261 * Tidy things up once finished.
3244 3262 */
3245 3263
3246 3264 old6 = new6;
3247 3265 cleanlist = oldlist6;
3248 3266 oldlist6 = newlist6;
3249 3267 while (cleanlist != NULL) {
3250 3268 tlp = cleanlist->next_if;
3251 3269 free(cleanlist);
3252 3270 cleanlist = tlp;
3253 3271 }
3254 3272 }
3255 3273 break;
3256 3274 }
3257 3275 }
3258 3276 (void) fflush(stdout);
3259 3277 } /* 'for' loop 1 ends */
3260 3278 if ((Iflag_only == 0) && (!once_only))
3261 3279 (void) putchar('\n');
3262 3280 reentry = B_TRUE;
3263 3281 }
3264 3282
3265 3283 static void
3266 3284 if_report_ip4(mib2_ipAddrEntry_t *ap,
3267 3285 char ifname[], char logintname[], struct ifstat *statptr,
3268 3286 boolean_t ksp_not_null) {
3269 3287
3270 3288 char abuf[MAXHOSTNAMELEN + 1];
3271 3289 char dstbuf[MAXHOSTNAMELEN + 1];
3272 3290
3273 3291 if (ksp_not_null) {
3274 3292 (void) printf("%-5s %-4u ",
3275 3293 ifname, ap->ipAdEntInfo.ae_mtu);
3276 3294 if (ap->ipAdEntInfo.ae_flags & IFF_POINTOPOINT)
3277 3295 (void) pr_addr(ap->ipAdEntInfo.ae_pp_dst_addr,
3278 3296 abuf, sizeof (abuf));
3279 3297 else
3280 3298 (void) pr_netaddr(ap->ipAdEntAddr,
3281 3299 ap->ipAdEntNetMask, abuf, sizeof (abuf));
3282 3300 (void) printf("%-13s %-14s %-6llu %-5llu %-6llu %-5llu "
3283 3301 "%-6llu %-6llu\n",
3284 3302 abuf, pr_addr(ap->ipAdEntAddr, dstbuf, sizeof (dstbuf)),
3285 3303 statptr->ipackets, statptr->ierrors,
3286 3304 statptr->opackets, statptr->oerrors,
3287 3305 statptr->collisions, 0LL);
3288 3306 }
3289 3307 /*
3290 3308 * Print logical interface info if Aflag set (including logical unit 0)
3291 3309 */
3292 3310 if (Aflag) {
3293 3311 *statptr = zerostat;
3294 3312 statptr->ipackets = ap->ipAdEntInfo.ae_ibcnt;
3295 3313 statptr->opackets = ap->ipAdEntInfo.ae_obcnt;
3296 3314
3297 3315 (void) printf("%-5s %-4u ", logintname, ap->ipAdEntInfo.ae_mtu);
3298 3316 if (ap->ipAdEntInfo.ae_flags & IFF_POINTOPOINT)
3299 3317 (void) pr_addr(ap->ipAdEntInfo.ae_pp_dst_addr, abuf,
3300 3318 sizeof (abuf));
3301 3319 else
3302 3320 (void) pr_netaddr(ap->ipAdEntAddr, ap->ipAdEntNetMask,
3303 3321 abuf, sizeof (abuf));
3304 3322
3305 3323 (void) printf("%-13s %-14s %-6llu %-5s %-6s "
3306 3324 "%-5s %-6s %-6llu\n", abuf,
3307 3325 pr_addr(ap->ipAdEntAddr, dstbuf, sizeof (dstbuf)),
3308 3326 statptr->ipackets, "N/A", "N/A", "N/A", "N/A",
3309 3327 0LL);
3310 3328 }
3311 3329 }
3312 3330
3313 3331 static void
3314 3332 if_report_ip6(mib2_ipv6AddrEntry_t *ap6,
3315 3333 char ifname[], char logintname[], struct ifstat *statptr,
3316 3334 boolean_t ksp_not_null) {
3317 3335
3318 3336 char abuf[MAXHOSTNAMELEN + 1];
3319 3337 char dstbuf[MAXHOSTNAMELEN + 1];
3320 3338
3321 3339 if (ksp_not_null) {
3322 3340 (void) printf("%-5s %-4u ", ifname, ap6->ipv6AddrInfo.ae_mtu);
3323 3341 if (ap6->ipv6AddrInfo.ae_flags &
3324 3342 IFF_POINTOPOINT) {
3325 3343 (void) pr_addr6(&ap6->ipv6AddrInfo.ae_pp_dst_addr,
3326 3344 abuf, sizeof (abuf));
3327 3345 } else {
3328 3346 (void) pr_prefix6(&ap6->ipv6AddrAddress,
3329 3347 ap6->ipv6AddrPfxLength, abuf,
3330 3348 sizeof (abuf));
3331 3349 }
3332 3350 (void) printf("%-27s %-27s %-6llu %-5llu "
3333 3351 "%-6llu %-5llu %-6llu\n",
3334 3352 abuf, pr_addr6(&ap6->ipv6AddrAddress, dstbuf,
3335 3353 sizeof (dstbuf)),
3336 3354 statptr->ipackets, statptr->ierrors, statptr->opackets,
3337 3355 statptr->oerrors, statptr->collisions);
3338 3356 }
3339 3357 /*
3340 3358 * Print logical interface info if Aflag set (including logical unit 0)
3341 3359 */
3342 3360 if (Aflag) {
3343 3361 *statptr = zerostat;
3344 3362 statptr->ipackets = ap6->ipv6AddrInfo.ae_ibcnt;
3345 3363 statptr->opackets = ap6->ipv6AddrInfo.ae_obcnt;
3346 3364
3347 3365 (void) printf("%-5s %-4u ", logintname,
3348 3366 ap6->ipv6AddrInfo.ae_mtu);
3349 3367 if (ap6->ipv6AddrInfo.ae_flags & IFF_POINTOPOINT)
3350 3368 (void) pr_addr6(&ap6->ipv6AddrInfo.ae_pp_dst_addr,
3351 3369 abuf, sizeof (abuf));
3352 3370 else
3353 3371 (void) pr_prefix6(&ap6->ipv6AddrAddress,
3354 3372 ap6->ipv6AddrPfxLength, abuf, sizeof (abuf));
3355 3373 (void) printf("%-27s %-27s %-6llu %-5s %-6s %-5s %-6s\n",
3356 3374 abuf, pr_addr6(&ap6->ipv6AddrAddress, dstbuf,
3357 3375 sizeof (dstbuf)),
3358 3376 statptr->ipackets, "N/A", "N/A", "N/A", "N/A");
3359 3377 }
3360 3378 }
3361 3379
3362 3380 /* --------------------- DHCP_REPORT (netstat -D) ------------------------- */
3363 3381
3364 3382 static boolean_t
3365 3383 dhcp_do_ipc(dhcp_ipc_type_t type, const char *ifname, boolean_t printed_one)
3366 3384 {
3367 3385 dhcp_ipc_request_t *request;
3368 3386 dhcp_ipc_reply_t *reply;
3369 3387 int error;
3370 3388
3371 3389 request = dhcp_ipc_alloc_request(type, ifname, NULL, 0, DHCP_TYPE_NONE);
3372 3390 if (request == NULL)
3373 3391 fail(0, "dhcp_do_ipc: out of memory");
3374 3392
3375 3393 error = dhcp_ipc_make_request(request, &reply, DHCP_IPC_WAIT_DEFAULT);
3376 3394 if (error != 0) {
3377 3395 free(request);
3378 3396 fail(0, "dhcp_do_ipc: %s", dhcp_ipc_strerror(error));
3379 3397 }
3380 3398
3381 3399 free(request);
3382 3400 error = reply->return_code;
3383 3401 if (error == DHCP_IPC_E_UNKIF) {
3384 3402 free(reply);
3385 3403 return (printed_one);
3386 3404 }
3387 3405 if (error != 0) {
3388 3406 free(reply);
3389 3407 fail(0, "dhcp_do_ipc: %s", dhcp_ipc_strerror(error));
3390 3408 }
3391 3409
3392 3410 if (timestamp_fmt != NODATE)
3393 3411 print_timestamp(timestamp_fmt);
3394 3412
3395 3413 if (!printed_one)
3396 3414 (void) printf("%s", dhcp_status_hdr_string());
3397 3415
3398 3416 (void) printf("%s", dhcp_status_reply_to_string(reply));
3399 3417 free(reply);
3400 3418 return (B_TRUE);
3401 3419 }
3402 3420
3403 3421 /*
3404 3422 * dhcp_walk_interfaces: walk the list of interfaces for a given address
3405 3423 * family (af). For each, print out the DHCP status using dhcp_do_ipc.
3406 3424 */
3407 3425 static boolean_t
3408 3426 dhcp_walk_interfaces(int af, boolean_t printed_one)
3409 3427 {
3410 3428 struct lifnum lifn;
3411 3429 struct lifconf lifc;
3412 3430 int n_ifs, i, sock_fd;
3413 3431
3414 3432 sock_fd = socket(af, SOCK_DGRAM, 0);
3415 3433 if (sock_fd == -1)
3416 3434 return (printed_one);
3417 3435
3418 3436 /*
3419 3437 * SIOCGLIFNUM is just an estimate. If the ioctl fails, we don't care;
3420 3438 * just drive on and use SIOCGLIFCONF with increasing buffer sizes, as
3421 3439 * is traditional.
3422 3440 */
3423 3441 (void) memset(&lifn, 0, sizeof (lifn));
3424 3442 lifn.lifn_family = af;
3425 3443 lifn.lifn_flags = LIFC_ALLZONES | LIFC_NOXMIT | LIFC_UNDER_IPMP;
3426 3444 if (ioctl(sock_fd, SIOCGLIFNUM, &lifn) == -1)
3427 3445 n_ifs = LIFN_GUARD_VALUE;
3428 3446 else
3429 3447 n_ifs = lifn.lifn_count + LIFN_GUARD_VALUE;
3430 3448
3431 3449 (void) memset(&lifc, 0, sizeof (lifc));
3432 3450 lifc.lifc_family = af;
3433 3451 lifc.lifc_flags = lifn.lifn_flags;
3434 3452 lifc.lifc_len = n_ifs * sizeof (struct lifreq);
3435 3453 lifc.lifc_buf = malloc(lifc.lifc_len);
3436 3454 if (lifc.lifc_buf != NULL) {
3437 3455
3438 3456 if (ioctl(sock_fd, SIOCGLIFCONF, &lifc) == -1) {
3439 3457 (void) close(sock_fd);
3440 3458 free(lifc.lifc_buf);
3441 3459 return (NULL);
3442 3460 }
3443 3461
3444 3462 n_ifs = lifc.lifc_len / sizeof (struct lifreq);
3445 3463
3446 3464 for (i = 0; i < n_ifs; i++) {
3447 3465 printed_one = dhcp_do_ipc(DHCP_STATUS |
3448 3466 (af == AF_INET6 ? DHCP_V6 : 0),
3449 3467 lifc.lifc_req[i].lifr_name, printed_one);
3450 3468 }
3451 3469 }
3452 3470 (void) close(sock_fd);
3453 3471 free(lifc.lifc_buf);
3454 3472 return (printed_one);
3455 3473 }
3456 3474
3457 3475 static void
3458 3476 dhcp_report(char *ifname)
3459 3477 {
3460 3478 boolean_t printed_one;
3461 3479
3462 3480 if (!family_selected(AF_INET) && !family_selected(AF_INET6))
3463 3481 return;
3464 3482
3465 3483 printed_one = B_FALSE;
3466 3484 if (ifname != NULL) {
3467 3485 if (family_selected(AF_INET)) {
3468 3486 printed_one = dhcp_do_ipc(DHCP_STATUS, ifname,
3469 3487 printed_one);
3470 3488 }
3471 3489 if (family_selected(AF_INET6)) {
3472 3490 printed_one = dhcp_do_ipc(DHCP_STATUS | DHCP_V6,
3473 3491 ifname, printed_one);
3474 3492 }
3475 3493 if (!printed_one) {
3476 3494 fail(0, "%s: %s", ifname,
3477 3495 dhcp_ipc_strerror(DHCP_IPC_E_UNKIF));
3478 3496 }
3479 3497 } else {
3480 3498 if (family_selected(AF_INET)) {
3481 3499 printed_one = dhcp_walk_interfaces(AF_INET,
3482 3500 printed_one);
3483 3501 }
3484 3502 if (family_selected(AF_INET6))
3485 3503 (void) dhcp_walk_interfaces(AF_INET6, printed_one);
3486 3504 }
3487 3505 }
3488 3506
3489 3507 /* --------------------- GROUP_REPORT (netstat -g) ------------------------- */
3490 3508
3491 3509 static void
3492 3510 group_report(mib_item_t *item)
3493 3511 {
3494 3512 mib_item_t *v4grp = NULL, *v4src = NULL;
3495 3513 mib_item_t *v6grp = NULL, *v6src = NULL;
3496 3514 int jtemp = 0;
3497 3515 char ifname[LIFNAMSIZ + 1];
3498 3516 char abuf[MAXHOSTNAMELEN + 1];
3499 3517 ip_member_t *ipmp;
3500 3518 ip_grpsrc_t *ips;
3501 3519 ipv6_member_t *ipmp6;
3502 3520 ipv6_grpsrc_t *ips6;
3503 3521 boolean_t first, first_src;
3504 3522
3505 3523 /* 'for' loop 1: */
3506 3524 for (; item; item = item->next_item) {
3507 3525 if (Xflag) {
3508 3526 (void) printf("\n--- Entry %d ---\n", ++jtemp);
3509 3527 (void) printf("Group = %d, mib_id = %d, "
3510 3528 "length = %d, valp = 0x%p\n",
3511 3529 item->group, item->mib_id, item->length,
3512 3530 item->valp);
3513 3531 }
3514 3532 if (item->group == MIB2_IP && family_selected(AF_INET)) {
3515 3533 switch (item->mib_id) {
3516 3534 case EXPER_IP_GROUP_MEMBERSHIP:
3517 3535 v4grp = item;
3518 3536 if (Xflag)
3519 3537 (void) printf("item is v4grp info\n");
3520 3538 break;
3521 3539 case EXPER_IP_GROUP_SOURCES:
3522 3540 v4src = item;
3523 3541 if (Xflag)
3524 3542 (void) printf("item is v4src info\n");
3525 3543 break;
3526 3544 default:
3527 3545 continue;
3528 3546 }
3529 3547 continue;
3530 3548 }
3531 3549 if (item->group == MIB2_IP6 && family_selected(AF_INET6)) {
3532 3550 switch (item->mib_id) {
3533 3551 case EXPER_IP6_GROUP_MEMBERSHIP:
3534 3552 v6grp = item;
3535 3553 if (Xflag)
3536 3554 (void) printf("item is v6grp info\n");
3537 3555 break;
3538 3556 case EXPER_IP6_GROUP_SOURCES:
3539 3557 v6src = item;
3540 3558 if (Xflag)
3541 3559 (void) printf("item is v6src info\n");
3542 3560 break;
3543 3561 default:
3544 3562 continue;
3545 3563 }
3546 3564 }
3547 3565 }
3548 3566
3549 3567 if (family_selected(AF_INET) && v4grp != NULL) {
3550 3568 if (Xflag)
3551 3569 (void) printf("%u records for ipGroupMember:\n",
3552 3570 v4grp->length / sizeof (ip_member_t));
3553 3571
3554 3572 first = B_TRUE;
3555 3573 for (ipmp = (ip_member_t *)v4grp->valp;
3556 3574 (char *)ipmp < (char *)v4grp->valp + v4grp->length;
3557 3575 /* LINTED: (note 1) */
3558 3576 ipmp = (ip_member_t *)((char *)ipmp + ipMemberEntrySize)) {
3559 3577 if (first) {
3560 3578 (void) puts(v4compat ?
3561 3579 "Group Memberships" :
3562 3580 "Group Memberships: IPv4");
3563 3581 (void) puts("Interface "
3564 3582 "Group RefCnt");
3565 3583 (void) puts("--------- "
3566 3584 "-------------------- ------");
3567 3585 first = B_FALSE;
3568 3586 }
3569 3587
3570 3588 (void) printf("%-9s %-20s %6u\n",
3571 3589 octetstr(&ipmp->ipGroupMemberIfIndex, 'a',
3572 3590 ifname, sizeof (ifname)),
3573 3591 pr_addr(ipmp->ipGroupMemberAddress,
3574 3592 abuf, sizeof (abuf)),
3575 3593 ipmp->ipGroupMemberRefCnt);
3576 3594
3577 3595
3578 3596 if (!Vflag || v4src == NULL)
3579 3597 continue;
3580 3598
3581 3599 if (Xflag)
3582 3600 (void) printf("scanning %u ipGroupSource "
3583 3601 "records...\n",
3584 3602 v4src->length/sizeof (ip_grpsrc_t));
3585 3603
3586 3604 first_src = B_TRUE;
3587 3605 for (ips = (ip_grpsrc_t *)v4src->valp;
3588 3606 (char *)ips < (char *)v4src->valp + v4src->length;
3589 3607 /* LINTED: (note 1) */
3590 3608 ips = (ip_grpsrc_t *)((char *)ips +
3591 3609 ipGroupSourceEntrySize)) {
3592 3610 /*
3593 3611 * We assume that all source addrs for a given
3594 3612 * interface/group pair are contiguous, so on
3595 3613 * the first non-match after we've found at
3596 3614 * least one, we bail.
3597 3615 */
3598 3616 if ((ipmp->ipGroupMemberAddress !=
3599 3617 ips->ipGroupSourceGroup) ||
3600 3618 (!octetstrmatch(&ipmp->ipGroupMemberIfIndex,
3601 3619 &ips->ipGroupSourceIfIndex))) {
3602 3620 if (first_src)
3603 3621 continue;
3604 3622 else
3605 3623 break;
3606 3624 }
3607 3625 if (first_src) {
3608 3626 (void) printf("\t%s: %s\n",
3609 3627 fmodestr(
3610 3628 ipmp->ipGroupMemberFilterMode),
3611 3629 pr_addr(ips->ipGroupSourceAddress,
3612 3630 abuf, sizeof (abuf)));
3613 3631 first_src = B_FALSE;
3614 3632 continue;
3615 3633 }
3616 3634
3617 3635 (void) printf("\t %s\n",
3618 3636 pr_addr(ips->ipGroupSourceAddress, abuf,
3619 3637 sizeof (abuf)));
3620 3638 }
3621 3639 }
3622 3640 (void) putchar('\n');
3623 3641 }
3624 3642
3625 3643 if (family_selected(AF_INET6) && v6grp != NULL) {
3626 3644 if (Xflag)
3627 3645 (void) printf("%u records for ipv6GroupMember:\n",
3628 3646 v6grp->length / sizeof (ipv6_member_t));
3629 3647
3630 3648 first = B_TRUE;
3631 3649 for (ipmp6 = (ipv6_member_t *)v6grp->valp;
3632 3650 (char *)ipmp6 < (char *)v6grp->valp + v6grp->length;
3633 3651 /* LINTED: (note 1) */
3634 3652 ipmp6 = (ipv6_member_t *)((char *)ipmp6 +
3635 3653 ipv6MemberEntrySize)) {
3636 3654 if (first) {
3637 3655 (void) puts("Group Memberships: "
3638 3656 "IPv6");
3639 3657 (void) puts(" If "
3640 3658 "Group RefCnt");
3641 3659 (void) puts("----- "
3642 3660 "--------------------------- ------");
3643 3661 first = B_FALSE;
3644 3662 }
3645 3663
3646 3664 (void) printf("%-5s %-27s %5u\n",
3647 3665 ifindex2str(ipmp6->ipv6GroupMemberIfIndex, ifname),
3648 3666 pr_addr6(&ipmp6->ipv6GroupMemberAddress,
3649 3667 abuf, sizeof (abuf)),
3650 3668 ipmp6->ipv6GroupMemberRefCnt);
3651 3669
3652 3670 if (!Vflag || v6src == NULL)
3653 3671 continue;
3654 3672
3655 3673 if (Xflag)
3656 3674 (void) printf("scanning %u ipv6GroupSource "
3657 3675 "records...\n",
3658 3676 v6src->length/sizeof (ipv6_grpsrc_t));
3659 3677
3660 3678 first_src = B_TRUE;
3661 3679 for (ips6 = (ipv6_grpsrc_t *)v6src->valp;
3662 3680 (char *)ips6 < (char *)v6src->valp + v6src->length;
3663 3681 /* LINTED: (note 1) */
3664 3682 ips6 = (ipv6_grpsrc_t *)((char *)ips6 +
3665 3683 ipv6GroupSourceEntrySize)) {
3666 3684 /* same assumption as in the v4 case above */
3667 3685 if ((ipmp6->ipv6GroupMemberIfIndex !=
3668 3686 ips6->ipv6GroupSourceIfIndex) ||
3669 3687 (!IN6_ARE_ADDR_EQUAL(
3670 3688 &ipmp6->ipv6GroupMemberAddress,
3671 3689 &ips6->ipv6GroupSourceGroup))) {
3672 3690 if (first_src)
3673 3691 continue;
3674 3692 else
3675 3693 break;
3676 3694 }
3677 3695 if (first_src) {
3678 3696 (void) printf("\t%s: %s\n",
3679 3697 fmodestr(
3680 3698 ipmp6->ipv6GroupMemberFilterMode),
3681 3699 pr_addr6(
3682 3700 &ips6->ipv6GroupSourceAddress,
3683 3701 abuf, sizeof (abuf)));
3684 3702 first_src = B_FALSE;
3685 3703 continue;
3686 3704 }
3687 3705
3688 3706 (void) printf("\t %s\n",
3689 3707 pr_addr6(&ips6->ipv6GroupSourceAddress,
3690 3708 abuf, sizeof (abuf)));
3691 3709 }
3692 3710 }
3693 3711 (void) putchar('\n');
3694 3712 }
3695 3713
3696 3714 (void) putchar('\n');
3697 3715 (void) fflush(stdout);
3698 3716 }
3699 3717
3700 3718 /* --------------------- DCE_REPORT (netstat -d) ------------------------- */
3701 3719
3702 3720 #define FLBUFSIZE 8
3703 3721
3704 3722 /* Assumes flbuf is at least 5 characters; callers use FLBUFSIZE */
3705 3723 static char *
3706 3724 dceflags2str(uint32_t flags, char *flbuf)
3707 3725 {
3708 3726 char *str = flbuf;
3709 3727
3710 3728 if (flags & DCEF_DEFAULT)
3711 3729 *str++ = 'D';
3712 3730 if (flags & DCEF_PMTU)
3713 3731 *str++ = 'P';
3714 3732 if (flags & DCEF_UINFO)
3715 3733 *str++ = 'U';
3716 3734 if (flags & DCEF_TOO_SMALL_PMTU)
3717 3735 *str++ = 'S';
3718 3736 *str++ = '\0';
3719 3737 return (flbuf);
3720 3738 }
3721 3739
3722 3740 static void
3723 3741 dce_report(mib_item_t *item)
3724 3742 {
3725 3743 mib_item_t *v4dce = NULL;
3726 3744 mib_item_t *v6dce = NULL;
3727 3745 int jtemp = 0;
3728 3746 char ifname[LIFNAMSIZ + 1];
3729 3747 char abuf[MAXHOSTNAMELEN + 1];
3730 3748 char flbuf[FLBUFSIZE];
3731 3749 boolean_t first;
3732 3750 dest_cache_entry_t *dce;
3733 3751
3734 3752 /* 'for' loop 1: */
3735 3753 for (; item; item = item->next_item) {
3736 3754 if (Xflag) {
3737 3755 (void) printf("\n--- Entry %d ---\n", ++jtemp);
3738 3756 (void) printf("Group = %d, mib_id = %d, "
3739 3757 "length = %d, valp = 0x%p\n",
3740 3758 item->group, item->mib_id, item->length,
3741 3759 item->valp);
3742 3760 }
3743 3761 if (item->group == MIB2_IP && family_selected(AF_INET) &&
3744 3762 item->mib_id == EXPER_IP_DCE) {
3745 3763 v4dce = item;
3746 3764 if (Xflag)
3747 3765 (void) printf("item is v4dce info\n");
3748 3766 }
3749 3767 if (item->group == MIB2_IP6 && family_selected(AF_INET6) &&
3750 3768 item->mib_id == EXPER_IP_DCE) {
3751 3769 v6dce = item;
3752 3770 if (Xflag)
3753 3771 (void) printf("item is v6dce info\n");
3754 3772 }
3755 3773 }
3756 3774
3757 3775 if (family_selected(AF_INET) && v4dce != NULL) {
3758 3776 if (Xflag)
3759 3777 (void) printf("%u records for DestCacheEntry:\n",
3760 3778 v4dce->length / ipDestEntrySize);
3761 3779
3762 3780 first = B_TRUE;
3763 3781 for (dce = (dest_cache_entry_t *)v4dce->valp;
3764 3782 (char *)dce < (char *)v4dce->valp + v4dce->length;
3765 3783 /* LINTED: (note 1) */
3766 3784 dce = (dest_cache_entry_t *)((char *)dce +
3767 3785 ipDestEntrySize)) {
3768 3786 if (first) {
3769 3787 (void) putchar('\n');
3770 3788 (void) puts("Destination Cache Entries: IPv4");
3771 3789 (void) puts(
3772 3790 "Address PMTU Age Flags");
3773 3791 (void) puts(
3774 3792 "-------------------- ------ ----- -----");
3775 3793 first = B_FALSE;
3776 3794 }
3777 3795
3778 3796 (void) printf("%-20s %6u %5u %-5s\n",
3779 3797 pr_addr(dce->DestIpv4Address, abuf, sizeof (abuf)),
3780 3798 dce->DestPmtu, dce->DestAge,
3781 3799 dceflags2str(dce->DestFlags, flbuf));
3782 3800 }
3783 3801 }
3784 3802
3785 3803 if (family_selected(AF_INET6) && v6dce != NULL) {
3786 3804 if (Xflag)
3787 3805 (void) printf("%u records for DestCacheEntry:\n",
3788 3806 v6dce->length / ipDestEntrySize);
3789 3807
3790 3808 first = B_TRUE;
3791 3809 for (dce = (dest_cache_entry_t *)v6dce->valp;
3792 3810 (char *)dce < (char *)v6dce->valp + v6dce->length;
3793 3811 /* LINTED: (note 1) */
3794 3812 dce = (dest_cache_entry_t *)((char *)dce +
3795 3813 ipDestEntrySize)) {
3796 3814 if (first) {
3797 3815 (void) putchar('\n');
3798 3816 (void) puts("Destination Cache Entries: IPv6");
3799 3817 (void) puts(
3800 3818 "Address PMTU "
3801 3819 " Age Flags If ");
3802 3820 (void) puts(
3803 3821 "--------------------------- ------ "
3804 3822 "----- ----- ---");
3805 3823 first = B_FALSE;
3806 3824 }
3807 3825
3808 3826 (void) printf("%-27s %6u %5u %-5s %s\n",
3809 3827 pr_addr6(&dce->DestIpv6Address, abuf,
3810 3828 sizeof (abuf)),
3811 3829 dce->DestPmtu, dce->DestAge,
3812 3830 dceflags2str(dce->DestFlags, flbuf),
3813 3831 dce->DestIfindex == 0 ? "" :
3814 3832 ifindex2str(dce->DestIfindex, ifname));
3815 3833 }
3816 3834 }
3817 3835 (void) fflush(stdout);
3818 3836 }
3819 3837
3820 3838 /* --------------------- ARP_REPORT (netstat -p) -------------------------- */
3821 3839
3822 3840 static void
3823 3841 arp_report(mib_item_t *item)
3824 3842 {
3825 3843 int jtemp = 0;
3826 3844 char ifname[LIFNAMSIZ + 1];
3827 3845 char abuf[MAXHOSTNAMELEN + 1];
3828 3846 char maskbuf[STR_EXPAND * OCTET_LENGTH + 1];
3829 3847 char flbuf[32]; /* ACE_F_ flags */
3830 3848 char xbuf[STR_EXPAND * OCTET_LENGTH + 1];
3831 3849 mib2_ipNetToMediaEntry_t *np;
3832 3850 int flags;
3833 3851 boolean_t first;
3834 3852
3835 3853 if (!(family_selected(AF_INET)))
3836 3854 return;
3837 3855
3838 3856 /* 'for' loop 1: */
3839 3857 for (; item; item = item->next_item) {
3840 3858 if (Xflag) {
3841 3859 (void) printf("\n--- Entry %d ---\n", ++jtemp);
3842 3860 (void) printf("Group = %d, mib_id = %d, "
3843 3861 "length = %d, valp = 0x%p\n",
3844 3862 item->group, item->mib_id, item->length,
3845 3863 item->valp);
3846 3864 }
3847 3865 if (!(item->group == MIB2_IP && item->mib_id == MIB2_IP_MEDIA))
3848 3866 continue; /* 'for' loop 1 */
3849 3867
3850 3868 if (Xflag)
3851 3869 (void) printf("%u records for "
3852 3870 "ipNetToMediaEntryTable:\n",
3853 3871 item->length/sizeof (mib2_ipNetToMediaEntry_t));
3854 3872
3855 3873 first = B_TRUE;
3856 3874 /* 'for' loop 2: */
3857 3875 for (np = (mib2_ipNetToMediaEntry_t *)item->valp;
3858 3876 (char *)np < (char *)item->valp + item->length;
3859 3877 /* LINTED: (note 1) */
3860 3878 np = (mib2_ipNetToMediaEntry_t *)((char *)np +
3861 3879 ipNetToMediaEntrySize)) {
3862 3880 if (first) {
3863 3881 (void) puts(v4compat ?
3864 3882 "Net to Media Table" :
3865 3883 "Net to Media Table: IPv4");
3866 3884 (void) puts("Device "
3867 3885 " IP Address Mask "
3868 3886 "Flags Phys Addr");
3869 3887 (void) puts("------ "
3870 3888 "-------------------- --------------- "
3871 3889 "-------- ---------------");
3872 3890 first = B_FALSE;
3873 3891 }
3874 3892
3875 3893 flbuf[0] = '\0';
3876 3894 flags = np->ipNetToMediaInfo.ntm_flags;
3877 3895 /*
3878 3896 * Note that not all flags are possible at the same
3879 3897 * time. Patterns: SPLAy DUo
3880 3898 */
3881 3899 if (flags & ACE_F_PERMANENT)
3882 3900 (void) strcat(flbuf, "S");
3883 3901 if (flags & ACE_F_PUBLISH)
3884 3902 (void) strcat(flbuf, "P");
3885 3903 if (flags & ACE_F_DYING)
3886 3904 (void) strcat(flbuf, "D");
3887 3905 if (!(flags & ACE_F_RESOLVED))
3888 3906 (void) strcat(flbuf, "U");
3889 3907 if (flags & ACE_F_MAPPING)
3890 3908 (void) strcat(flbuf, "M");
3891 3909 if (flags & ACE_F_MYADDR)
3892 3910 (void) strcat(flbuf, "L");
3893 3911 if (flags & ACE_F_UNVERIFIED)
3894 3912 (void) strcat(flbuf, "d");
3895 3913 if (flags & ACE_F_AUTHORITY)
3896 3914 (void) strcat(flbuf, "A");
3897 3915 if (flags & ACE_F_OLD)
3898 3916 (void) strcat(flbuf, "o");
3899 3917 if (flags & ACE_F_DELAYED)
3900 3918 (void) strcat(flbuf, "y");
3901 3919 (void) printf("%-6s %-20s %-15s %-8s %s\n",
3902 3920 octetstr(&np->ipNetToMediaIfIndex, 'a',
3903 3921 ifname, sizeof (ifname)),
3904 3922 pr_addr(np->ipNetToMediaNetAddress,
3905 3923 abuf, sizeof (abuf)),
3906 3924 octetstr(&np->ipNetToMediaInfo.ntm_mask, 'd',
3907 3925 maskbuf, sizeof (maskbuf)),
3908 3926 flbuf,
3909 3927 octetstr(&np->ipNetToMediaPhysAddress, 'h',
3910 3928 xbuf, sizeof (xbuf)));
3911 3929 } /* 'for' loop 2 ends */
3912 3930 } /* 'for' loop 1 ends */
3913 3931 (void) fflush(stdout);
3914 3932 }
3915 3933
3916 3934 /* --------------------- NDP_REPORT (netstat -p) -------------------------- */
3917 3935
3918 3936 static void
3919 3937 ndp_report(mib_item_t *item)
3920 3938 {
3921 3939 int jtemp = 0;
3922 3940 char abuf[MAXHOSTNAMELEN + 1];
3923 3941 char *state;
3924 3942 char *type;
3925 3943 char xbuf[STR_EXPAND * OCTET_LENGTH + 1];
3926 3944 mib2_ipv6NetToMediaEntry_t *np6;
3927 3945 char ifname[LIFNAMSIZ + 1];
3928 3946 boolean_t first;
3929 3947
3930 3948 if (!(family_selected(AF_INET6)))
3931 3949 return;
3932 3950
3933 3951 /* 'for' loop 1: */
3934 3952 for (; item; item = item->next_item) {
3935 3953 if (Xflag) {
3936 3954 (void) printf("\n--- Entry %d ---\n", ++jtemp);
3937 3955 (void) printf("Group = %d, mib_id = %d, "
3938 3956 "length = %d, valp = 0x%p\n",
3939 3957 item->group, item->mib_id, item->length,
3940 3958 item->valp);
3941 3959 }
3942 3960 if (!(item->group == MIB2_IP6 &&
3943 3961 item->mib_id == MIB2_IP6_MEDIA))
3944 3962 continue; /* 'for' loop 1 */
3945 3963
3946 3964 first = B_TRUE;
3947 3965 /* 'for' loop 2: */
3948 3966 for (np6 = (mib2_ipv6NetToMediaEntry_t *)item->valp;
3949 3967 (char *)np6 < (char *)item->valp + item->length;
3950 3968 /* LINTED: (note 1) */
3951 3969 np6 = (mib2_ipv6NetToMediaEntry_t *)((char *)np6 +
3952 3970 ipv6NetToMediaEntrySize)) {
3953 3971 if (first) {
3954 3972 (void) puts("\nNet to Media Table: IPv6");
3955 3973 (void) puts(" If Physical Address "
3956 3974 " Type State Destination/Mask");
3957 3975 (void) puts("----- ----------------- "
3958 3976 "------- ------------ "
3959 3977 "---------------------------");
3960 3978 first = B_FALSE;
3961 3979 }
3962 3980
3963 3981 switch (np6->ipv6NetToMediaState) {
3964 3982 case ND_INCOMPLETE:
3965 3983 state = "INCOMPLETE";
3966 3984 break;
3967 3985 case ND_REACHABLE:
3968 3986 state = "REACHABLE";
3969 3987 break;
3970 3988 case ND_STALE:
3971 3989 state = "STALE";
3972 3990 break;
3973 3991 case ND_DELAY:
3974 3992 state = "DELAY";
3975 3993 break;
3976 3994 case ND_PROBE:
3977 3995 state = "PROBE";
3978 3996 break;
3979 3997 case ND_UNREACHABLE:
3980 3998 state = "UNREACHABLE";
3981 3999 break;
3982 4000 default:
3983 4001 state = "UNKNOWN";
3984 4002 }
3985 4003
3986 4004 switch (np6->ipv6NetToMediaType) {
3987 4005 case 1:
3988 4006 type = "other";
3989 4007 break;
3990 4008 case 2:
3991 4009 type = "dynamic";
3992 4010 break;
3993 4011 case 3:
3994 4012 type = "static";
3995 4013 break;
3996 4014 case 4:
3997 4015 type = "local";
3998 4016 break;
3999 4017 }
4000 4018 (void) printf("%-5s %-17s %-7s %-12s %-27s\n",
4001 4019 ifindex2str(np6->ipv6NetToMediaIfIndex, ifname),
4002 4020 octetstr(&np6->ipv6NetToMediaPhysAddress, 'h',
4003 4021 xbuf, sizeof (xbuf)),
4004 4022 type,
4005 4023 state,
4006 4024 pr_addr6(&np6->ipv6NetToMediaNetAddress,
4007 4025 abuf, sizeof (abuf)));
4008 4026 } /* 'for' loop 2 ends */
4009 4027 } /* 'for' loop 1 ends */
4010 4028 (void) putchar('\n');
4011 4029 (void) fflush(stdout);
4012 4030 }
4013 4031
4014 4032 /* ------------------------- ire_report (netstat -r) ------------------------ */
4015 4033
4016 4034 typedef struct sec_attr_list_s {
4017 4035 struct sec_attr_list_s *sal_next;
4018 4036 const mib2_ipAttributeEntry_t *sal_attr;
4019 4037 } sec_attr_list_t;
4020 4038
4021 4039 static boolean_t ire_report_item_v4(const mib2_ipRouteEntry_t *, boolean_t,
4022 4040 const sec_attr_list_t *);
4023 4041 static boolean_t ire_report_item_v6(const mib2_ipv6RouteEntry_t *, boolean_t,
4024 4042 const sec_attr_list_t *);
4025 4043 static const char *pr_secattr(const sec_attr_list_t *);
4026 4044
4027 4045 static void
4028 4046 ire_report(const mib_item_t *item)
4029 4047 {
4030 4048 int jtemp = 0;
4031 4049 boolean_t print_hdr_once_v4 = B_TRUE;
4032 4050 boolean_t print_hdr_once_v6 = B_TRUE;
4033 4051 mib2_ipRouteEntry_t *rp;
4034 4052 mib2_ipv6RouteEntry_t *rp6;
4035 4053 sec_attr_list_t **v4_attrs, **v4a;
4036 4054 sec_attr_list_t **v6_attrs, **v6a;
4037 4055 sec_attr_list_t *all_attrs, *aptr;
4038 4056 const mib_item_t *iptr;
4039 4057 int ipv4_route_count, ipv6_route_count;
4040 4058 int route_attrs_count;
4041 4059
4042 4060 /*
4043 4061 * Preparation pass: the kernel returns separate entries for IP routing
4044 4062 * table entries and security attributes. We loop through the
4045 4063 * attributes first and link them into lists.
4046 4064 */
4047 4065 ipv4_route_count = ipv6_route_count = route_attrs_count = 0;
4048 4066 for (iptr = item; iptr != NULL; iptr = iptr->next_item) {
4049 4067 if (iptr->group == MIB2_IP6 && iptr->mib_id == MIB2_IP6_ROUTE)
4050 4068 ipv6_route_count += iptr->length / ipv6RouteEntrySize;
4051 4069 if (iptr->group == MIB2_IP && iptr->mib_id == MIB2_IP_ROUTE)
4052 4070 ipv4_route_count += iptr->length / ipRouteEntrySize;
4053 4071 if ((iptr->group == MIB2_IP || iptr->group == MIB2_IP6) &&
4054 4072 iptr->mib_id == EXPER_IP_RTATTR)
4055 4073 route_attrs_count += iptr->length /
4056 4074 ipRouteAttributeSize;
4057 4075 }
4058 4076 v4_attrs = v6_attrs = NULL;
4059 4077 all_attrs = NULL;
4060 4078 if (family_selected(AF_INET) && ipv4_route_count > 0) {
4061 4079 v4_attrs = calloc(ipv4_route_count, sizeof (*v4_attrs));
4062 4080 if (v4_attrs == NULL) {
4063 4081 perror("ire_report calloc v4_attrs failed");
4064 4082 return;
4065 4083 }
4066 4084 }
4067 4085 if (family_selected(AF_INET6) && ipv6_route_count > 0) {
4068 4086 v6_attrs = calloc(ipv6_route_count, sizeof (*v6_attrs));
4069 4087 if (v6_attrs == NULL) {
4070 4088 perror("ire_report calloc v6_attrs failed");
4071 4089 goto ire_report_done;
4072 4090 }
4073 4091 }
4074 4092 if (route_attrs_count > 0) {
4075 4093 all_attrs = malloc(route_attrs_count * sizeof (*all_attrs));
4076 4094 if (all_attrs == NULL) {
4077 4095 perror("ire_report malloc all_attrs failed");
4078 4096 goto ire_report_done;
4079 4097 }
4080 4098 }
4081 4099 aptr = all_attrs;
4082 4100 for (iptr = item; iptr != NULL; iptr = iptr->next_item) {
4083 4101 mib2_ipAttributeEntry_t *iae;
4084 4102 sec_attr_list_t **alp;
4085 4103
4086 4104 if (v4_attrs != NULL && iptr->group == MIB2_IP &&
4087 4105 iptr->mib_id == EXPER_IP_RTATTR) {
4088 4106 alp = v4_attrs;
4089 4107 } else if (v6_attrs != NULL && iptr->group == MIB2_IP6 &&
4090 4108 iptr->mib_id == EXPER_IP_RTATTR) {
4091 4109 alp = v6_attrs;
4092 4110 } else {
4093 4111 continue;
4094 4112 }
4095 4113 for (iae = iptr->valp;
4096 4114 (char *)iae < (char *)iptr->valp + iptr->length;
4097 4115 /* LINTED: (note 1) */
4098 4116 iae = (mib2_ipAttributeEntry_t *)((char *)iae +
4099 4117 ipRouteAttributeSize)) {
4100 4118 aptr->sal_next = alp[iae->iae_routeidx];
4101 4119 aptr->sal_attr = iae;
4102 4120 alp[iae->iae_routeidx] = aptr++;
4103 4121 }
4104 4122 }
4105 4123
4106 4124 /* 'for' loop 1: */
4107 4125 v4a = v4_attrs;
4108 4126 v6a = v6_attrs;
4109 4127 for (; item != NULL; item = item->next_item) {
4110 4128 if (Xflag) {
4111 4129 (void) printf("\n--- Entry %d ---\n", ++jtemp);
4112 4130 (void) printf("Group = %d, mib_id = %d, "
4113 4131 "length = %d, valp = 0x%p\n",
4114 4132 item->group, item->mib_id,
4115 4133 item->length, item->valp);
4116 4134 }
4117 4135 if (!((item->group == MIB2_IP &&
4118 4136 item->mib_id == MIB2_IP_ROUTE) ||
4119 4137 (item->group == MIB2_IP6 &&
4120 4138 item->mib_id == MIB2_IP6_ROUTE)))
4121 4139 continue; /* 'for' loop 1 */
4122 4140
4123 4141 if (item->group == MIB2_IP && !family_selected(AF_INET))
4124 4142 continue; /* 'for' loop 1 */
4125 4143 else if (item->group == MIB2_IP6 && !family_selected(AF_INET6))
4126 4144 continue; /* 'for' loop 1 */
4127 4145
4128 4146 if (Xflag) {
4129 4147 if (item->group == MIB2_IP) {
4130 4148 (void) printf("%u records for "
4131 4149 "ipRouteEntryTable:\n",
4132 4150 item->length/sizeof (mib2_ipRouteEntry_t));
4133 4151 } else {
4134 4152 (void) printf("%u records for "
4135 4153 "ipv6RouteEntryTable:\n",
4136 4154 item->length/
4137 4155 sizeof (mib2_ipv6RouteEntry_t));
4138 4156 }
4139 4157 }
4140 4158
4141 4159 if (item->group == MIB2_IP) {
4142 4160 for (rp = (mib2_ipRouteEntry_t *)item->valp;
4143 4161 (char *)rp < (char *)item->valp + item->length;
4144 4162 /* LINTED: (note 1) */
4145 4163 rp = (mib2_ipRouteEntry_t *)((char *)rp +
4146 4164 ipRouteEntrySize)) {
4147 4165 aptr = v4a == NULL ? NULL : *v4a++;
4148 4166 print_hdr_once_v4 = ire_report_item_v4(rp,
4149 4167 print_hdr_once_v4, aptr);
4150 4168 }
4151 4169 } else {
4152 4170 for (rp6 = (mib2_ipv6RouteEntry_t *)item->valp;
4153 4171 (char *)rp6 < (char *)item->valp + item->length;
4154 4172 /* LINTED: (note 1) */
4155 4173 rp6 = (mib2_ipv6RouteEntry_t *)((char *)rp6 +
4156 4174 ipv6RouteEntrySize)) {
4157 4175 aptr = v6a == NULL ? NULL : *v6a++;
4158 4176 print_hdr_once_v6 = ire_report_item_v6(rp6,
4159 4177 print_hdr_once_v6, aptr);
4160 4178 }
4161 4179 }
4162 4180 } /* 'for' loop 1 ends */
4163 4181 (void) fflush(stdout);
4164 4182 ire_report_done:
4165 4183 if (v4_attrs != NULL)
4166 4184 free(v4_attrs);
4167 4185 if (v6_attrs != NULL)
4168 4186 free(v6_attrs);
4169 4187 if (all_attrs != NULL)
4170 4188 free(all_attrs);
4171 4189 }
4172 4190
4173 4191 /*
4174 4192 * Match a user-supplied device name. We do this by string because
4175 4193 * the MIB2 interface gives us interface name strings rather than
4176 4194 * ifIndex numbers. The "none" rule matches only routes with no
4177 4195 * interface. The "any" rule matches routes with any non-blank
4178 4196 * interface. A base name ("hme0") matches all aliases as well
4179 4197 * ("hme0:1").
4180 4198 */
4181 4199 static boolean_t
4182 4200 dev_name_match(const DeviceName *devnam, const char *ifname)
4183 4201 {
4184 4202 int iflen;
4185 4203
4186 4204 if (ifname == NULL)
4187 4205 return (devnam->o_length == 0); /* "none" */
4188 4206 if (*ifname == '\0')
4189 4207 return (devnam->o_length != 0); /* "any" */
4190 4208 iflen = strlen(ifname);
4191 4209 /* The check for ':' here supports interface aliases. */
4192 4210 if (iflen > devnam->o_length ||
4193 4211 (iflen < devnam->o_length && devnam->o_bytes[iflen] != ':'))
4194 4212 return (B_FALSE);
4195 4213 return (strncmp(ifname, devnam->o_bytes, iflen) == 0);
4196 4214 }
4197 4215
4198 4216 /*
4199 4217 * Match a user-supplied IP address list. The "any" rule matches any
4200 4218 * non-zero address. The "none" rule matches only the zero address.
4201 4219 * IPv6 addresses supplied by the user are ignored. If the user
4202 4220 * supplies a subnet mask, then match routes that are at least that
4203 4221 * specific (use the user's mask). If the user supplies only an
4204 4222 * address, then select any routes that would match (use the route's
4205 4223 * mask).
4206 4224 */
4207 4225 static boolean_t
4208 4226 v4_addr_match(IpAddress addr, IpAddress mask, const filter_t *fp)
4209 4227 {
4210 4228 char **app;
4211 4229 char *aptr;
4212 4230 in_addr_t faddr, fmask;
4213 4231
4214 4232 if (fp->u.a.f_address == NULL) {
4215 4233 if (IN6_IS_ADDR_UNSPECIFIED(&fp->u.a.f_mask))
4216 4234 return (addr != INADDR_ANY); /* "any" */
4217 4235 else
4218 4236 return (addr == INADDR_ANY); /* "none" */
4219 4237 }
4220 4238 if (!IN6_IS_V4MASK(fp->u.a.f_mask))
4221 4239 return (B_FALSE);
4222 4240 IN6_V4MAPPED_TO_IPADDR(&fp->u.a.f_mask, fmask);
4223 4241 if (fmask != IP_HOST_MASK) {
4224 4242 if (fmask > mask)
4225 4243 return (B_FALSE);
4226 4244 mask = fmask;
4227 4245 }
4228 4246 for (app = fp->u.a.f_address->h_addr_list; (aptr = *app) != NULL; app++)
4229 4247 /* LINTED: (note 1) */
4230 4248 if (IN6_IS_ADDR_V4MAPPED((in6_addr_t *)aptr)) {
4231 4249 /* LINTED: (note 1) */
4232 4250 IN6_V4MAPPED_TO_IPADDR((in6_addr_t *)aptr, faddr);
4233 4251 if (((faddr ^ addr) & mask) == 0)
4234 4252 return (B_TRUE);
4235 4253 }
4236 4254 return (B_FALSE);
4237 4255 }
4238 4256
4239 4257 /*
4240 4258 * Run through the filter list for an IPv4 MIB2 route entry. If all
4241 4259 * filters of a given type fail to match, then the route is filtered
4242 4260 * out (not displayed). If no filter is given or at least one filter
4243 4261 * of each type matches, then display the route.
4244 4262 */
4245 4263 static boolean_t
4246 4264 ire_filter_match_v4(const mib2_ipRouteEntry_t *rp, uint_t flag_b)
4247 4265 {
4248 4266 filter_t *fp;
4249 4267 int idx;
4250 4268
4251 4269 /* 'for' loop 1: */
4252 4270 for (idx = 0; idx < NFILTERKEYS; idx++)
4253 4271 if ((fp = filters[idx]) != NULL) {
4254 4272 /* 'for' loop 2: */
4255 4273 for (; fp != NULL; fp = fp->f_next) {
4256 4274 switch (idx) {
4257 4275 case FK_AF:
4258 4276 if (fp->u.f_family != AF_INET)
4259 4277 continue; /* 'for' loop 2 */
4260 4278 break;
4261 4279 case FK_OUTIF:
4262 4280 if (!dev_name_match(&rp->ipRouteIfIndex,
4263 4281 fp->u.f_ifname))
4264 4282 continue; /* 'for' loop 2 */
4265 4283 break;
4266 4284 case FK_DST:
4267 4285 if (!v4_addr_match(rp->ipRouteDest,
4268 4286 rp->ipRouteMask, fp))
4269 4287 continue; /* 'for' loop 2 */
4270 4288 break;
4271 4289 case FK_FLAGS:
4272 4290 if ((flag_b & fp->u.f.f_flagset) !=
4273 4291 fp->u.f.f_flagset ||
4274 4292 (flag_b & fp->u.f.f_flagclear))
4275 4293 continue; /* 'for' loop 2 */
4276 4294 break;
4277 4295 }
4278 4296 break;
4279 4297 } /* 'for' loop 2 ends */
4280 4298 if (fp == NULL)
4281 4299 return (B_FALSE);
4282 4300 }
4283 4301 /* 'for' loop 1 ends */
4284 4302 return (B_TRUE);
4285 4303 }
4286 4304
4287 4305 /*
4288 4306 * Given an IPv4 MIB2 route entry, form the list of flags for the
4289 4307 * route.
4290 4308 */
4291 4309 static uint_t
4292 4310 form_v4_route_flags(const mib2_ipRouteEntry_t *rp, char *flags)
4293 4311 {
4294 4312 uint_t flag_b;
4295 4313
4296 4314 flag_b = FLF_U;
4297 4315 (void) strcpy(flags, "U");
4298 4316 /* RTF_INDIRECT wins over RTF_GATEWAY - don't display both */
4299 4317 if (rp->ipRouteInfo.re_flags & RTF_INDIRECT) {
4300 4318 (void) strcat(flags, "I");
4301 4319 flag_b |= FLF_I;
4302 4320 } else if (rp->ipRouteInfo.re_ire_type & IRE_OFFLINK) {
4303 4321 (void) strcat(flags, "G");
4304 4322 flag_b |= FLF_G;
4305 4323 }
4306 4324 /* IRE_IF_CLONE wins over RTF_HOST - don't display both */
4307 4325 if (rp->ipRouteInfo.re_ire_type & IRE_IF_CLONE) {
4308 4326 (void) strcat(flags, "C");
4309 4327 flag_b |= FLF_C;
4310 4328 } else if (rp->ipRouteMask == IP_HOST_MASK) {
4311 4329 (void) strcat(flags, "H");
4312 4330 flag_b |= FLF_H;
4313 4331 }
4314 4332 if (rp->ipRouteInfo.re_flags & RTF_DYNAMIC) {
4315 4333 (void) strcat(flags, "D");
4316 4334 flag_b |= FLF_D;
4317 4335 }
4318 4336 if (rp->ipRouteInfo.re_ire_type == IRE_BROADCAST) { /* Broadcast */
4319 4337 (void) strcat(flags, "b");
4320 4338 flag_b |= FLF_b;
4321 4339 }
4322 4340 if (rp->ipRouteInfo.re_ire_type == IRE_LOCAL) { /* Local */
4323 4341 (void) strcat(flags, "L");
4324 4342 flag_b |= FLF_L;
4325 4343 }
4326 4344 if (rp->ipRouteInfo.re_flags & RTF_MULTIRT) {
4327 4345 (void) strcat(flags, "M"); /* Multiroute */
4328 4346 flag_b |= FLF_M;
4329 4347 }
4330 4348 if (rp->ipRouteInfo.re_flags & RTF_SETSRC) {
4331 4349 (void) strcat(flags, "S"); /* Setsrc */
4332 4350 flag_b |= FLF_S;
4333 4351 }
4334 4352 if (rp->ipRouteInfo.re_flags & RTF_REJECT) {
4335 4353 (void) strcat(flags, "R");
4336 4354 flag_b |= FLF_R;
4337 4355 }
4338 4356 if (rp->ipRouteInfo.re_flags & RTF_BLACKHOLE) {
4339 4357 (void) strcat(flags, "B");
4340 4358 flag_b |= FLF_B;
4341 4359 }
4342 4360 if (rp->ipRouteInfo.re_flags & RTF_ZONE) {
4343 4361 (void) strcat(flags, "Z");
4344 4362 flag_b |= FLF_Z;
4345 4363 }
4346 4364 return (flag_b);
4347 4365 }
4348 4366
4349 4367 static const char ire_hdr_v4[] =
4350 4368 "\n%s Table: IPv4\n";
4351 4369 static const char ire_hdr_v4_compat[] =
4352 4370 "\n%s Table:\n";
4353 4371 static const char ire_hdr_v4_verbose[] =
4354 4372 " Destination Mask Gateway Device "
4355 4373 " MTU Ref Flg Out In/Fwd %s\n"
4356 4374 "-------------------- --------------- -------------------- ------ "
4357 4375 "----- --- --- ----- ------ %s\n";
4358 4376
4359 4377 static const char ire_hdr_v4_normal[] =
4360 4378 " Destination Gateway Flags Ref Use Interface"
4361 4379 " %s\n-------------------- -------------------- ----- ----- ---------- "
4362 4380 "--------- %s\n";
4363 4381
4364 4382 static boolean_t
4365 4383 ire_report_item_v4(const mib2_ipRouteEntry_t *rp, boolean_t first,
4366 4384 const sec_attr_list_t *attrs)
4367 4385 {
4368 4386 char dstbuf[MAXHOSTNAMELEN + 1];
4369 4387 char maskbuf[MAXHOSTNAMELEN + 1];
4370 4388 char gwbuf[MAXHOSTNAMELEN + 1];
4371 4389 char ifname[LIFNAMSIZ + 1];
4372 4390 char flags[10]; /* RTF_ flags */
4373 4391 uint_t flag_b;
4374 4392
4375 4393 if (!(Aflag || (rp->ipRouteInfo.re_ire_type != IRE_IF_CLONE &&
4376 4394 rp->ipRouteInfo.re_ire_type != IRE_BROADCAST &&
4377 4395 rp->ipRouteInfo.re_ire_type != IRE_MULTICAST &&
4378 4396 rp->ipRouteInfo.re_ire_type != IRE_NOROUTE &&
4379 4397 rp->ipRouteInfo.re_ire_type != IRE_LOCAL))) {
4380 4398 return (first);
4381 4399 }
4382 4400
4383 4401 flag_b = form_v4_route_flags(rp, flags);
4384 4402
4385 4403 if (!ire_filter_match_v4(rp, flag_b))
4386 4404 return (first);
4387 4405
4388 4406 if (first) {
4389 4407 (void) printf(v4compat ? ire_hdr_v4_compat : ire_hdr_v4,
4390 4408 Vflag ? "IRE" : "Routing");
4391 4409 (void) printf(Vflag ? ire_hdr_v4_verbose : ire_hdr_v4_normal,
4392 4410 RSECflag ? " Gateway security attributes " : "",
4393 4411 RSECflag ? "-------------------------------" : "");
4394 4412 first = B_FALSE;
4395 4413 }
4396 4414
4397 4415 if (flag_b & FLF_H) {
4398 4416 (void) pr_addr(rp->ipRouteDest, dstbuf, sizeof (dstbuf));
4399 4417 } else {
4400 4418 (void) pr_net(rp->ipRouteDest, rp->ipRouteMask,
4401 4419 dstbuf, sizeof (dstbuf));
4402 4420 }
4403 4421 if (Vflag) {
4404 4422 (void) printf("%-20s %-15s %-20s %-6s %5u %3u "
4405 4423 "%-4s%6u %6u %s\n",
4406 4424 dstbuf,
4407 4425 pr_mask(rp->ipRouteMask, maskbuf, sizeof (maskbuf)),
4408 4426 pr_addrnz(rp->ipRouteNextHop, gwbuf, sizeof (gwbuf)),
4409 4427 octetstr(&rp->ipRouteIfIndex, 'a', ifname, sizeof (ifname)),
4410 4428 rp->ipRouteInfo.re_max_frag,
4411 4429 rp->ipRouteInfo.re_ref,
4412 4430 flags,
4413 4431 rp->ipRouteInfo.re_obpkt,
4414 4432 rp->ipRouteInfo.re_ibpkt,
4415 4433 pr_secattr(attrs));
4416 4434 } else {
4417 4435 (void) printf("%-20s %-20s %-5s %4u %10u %-9s %s\n",
4418 4436 dstbuf,
4419 4437 pr_addrnz(rp->ipRouteNextHop, gwbuf, sizeof (gwbuf)),
4420 4438 flags,
4421 4439 rp->ipRouteInfo.re_ref,
4422 4440 rp->ipRouteInfo.re_obpkt + rp->ipRouteInfo.re_ibpkt,
4423 4441 octetstr(&rp->ipRouteIfIndex, 'a',
4424 4442 ifname, sizeof (ifname)),
4425 4443 pr_secattr(attrs));
4426 4444 }
4427 4445 return (first);
4428 4446 }
4429 4447
4430 4448 /*
4431 4449 * Match a user-supplied IP address list against an IPv6 route entry.
4432 4450 * If the user specified "any," then any non-zero address matches. If
4433 4451 * the user specified "none," then only the zero address matches. If
4434 4452 * the user specified a subnet mask length, then use that in matching
4435 4453 * routes (select routes that are at least as specific). If the user
4436 4454 * specified only an address, then use the route's mask (select routes
4437 4455 * that would match that address). IPv4 addresses are ignored.
4438 4456 */
4439 4457 static boolean_t
4440 4458 v6_addr_match(const Ip6Address *addr, int masklen, const filter_t *fp)
4441 4459 {
4442 4460 const uint8_t *ucp;
4443 4461 int fmasklen;
4444 4462 int i;
4445 4463 char **app;
4446 4464 const uint8_t *aptr;
4447 4465
4448 4466 if (fp->u.a.f_address == NULL) {
4449 4467 if (IN6_IS_ADDR_UNSPECIFIED(&fp->u.a.f_mask)) /* any */
4450 4468 return (!IN6_IS_ADDR_UNSPECIFIED(addr));
4451 4469 return (IN6_IS_ADDR_UNSPECIFIED(addr)); /* "none" */
4452 4470 }
4453 4471 fmasklen = 0;
4454 4472 /* 'for' loop 1a: */
4455 4473 for (ucp = fp->u.a.f_mask.s6_addr;
4456 4474 ucp < fp->u.a.f_mask.s6_addr + sizeof (fp->u.a.f_mask.s6_addr);
4457 4475 ucp++) {
4458 4476 if (*ucp != 0xff) {
4459 4477 if (*ucp != 0)
4460 4478 fmasklen += 9 - ffs(*ucp);
4461 4479 break; /* 'for' loop 1a */
4462 4480 }
4463 4481 fmasklen += 8;
4464 4482 } /* 'for' loop 1a ends */
4465 4483 if (fmasklen != IPV6_ABITS) {
4466 4484 if (fmasklen > masklen)
4467 4485 return (B_FALSE);
4468 4486 masklen = fmasklen;
4469 4487 }
4470 4488 /* 'for' loop 1b: */
4471 4489 for (app = fp->u.a.f_address->h_addr_list;
4472 4490 (aptr = (uint8_t *)*app) != NULL; app++) {
4473 4491 /* LINTED: (note 1) */
4474 4492 if (IN6_IS_ADDR_V4MAPPED((in6_addr_t *)aptr))
4475 4493 continue; /* 'for' loop 1b */
4476 4494 ucp = addr->s6_addr;
4477 4495 for (i = masklen; i >= 8; i -= 8)
4478 4496 if (*ucp++ != *aptr++)
4479 4497 break; /* 'for' loop 1b */
4480 4498 if (i == 0 ||
4481 4499 (i < 8 && ((*ucp ^ *aptr) & ~(0xff >> i)) == 0))
4482 4500 return (B_TRUE);
4483 4501 } /* 'for' loop 1b ends */
4484 4502 return (B_FALSE);
4485 4503 }
4486 4504
4487 4505 /*
4488 4506 * Run through the filter list for an IPv6 MIB2 IRE. For a given
4489 4507 * type, if there's at least one filter and all filters of that type
4490 4508 * fail to match, then the route doesn't match and isn't displayed.
4491 4509 * If at least one matches, or none are specified, for each of the
4492 4510 * types, then the route is selected and displayed.
4493 4511 */
4494 4512 static boolean_t
4495 4513 ire_filter_match_v6(const mib2_ipv6RouteEntry_t *rp6, uint_t flag_b)
4496 4514 {
4497 4515 filter_t *fp;
4498 4516 int idx;
4499 4517
4500 4518 /* 'for' loop 1: */
4501 4519 for (idx = 0; idx < NFILTERKEYS; idx++)
4502 4520 if ((fp = filters[idx]) != NULL) {
4503 4521 /* 'for' loop 2: */
4504 4522 for (; fp != NULL; fp = fp->f_next) {
4505 4523 switch (idx) {
4506 4524 case FK_AF:
4507 4525 if (fp->u.f_family != AF_INET6)
4508 4526 /* 'for' loop 2 */
4509 4527 continue;
4510 4528 break;
4511 4529 case FK_OUTIF:
4512 4530 if (!dev_name_match(&rp6->
4513 4531 ipv6RouteIfIndex, fp->u.f_ifname))
4514 4532 /* 'for' loop 2 */
4515 4533 continue;
4516 4534 break;
4517 4535 case FK_DST:
4518 4536 if (!v6_addr_match(&rp6->ipv6RouteDest,
4519 4537 rp6->ipv6RoutePfxLength, fp))
4520 4538 /* 'for' loop 2 */
4521 4539 continue;
4522 4540 break;
4523 4541 case FK_FLAGS:
4524 4542 if ((flag_b & fp->u.f.f_flagset) !=
4525 4543 fp->u.f.f_flagset ||
4526 4544 (flag_b & fp->u.f.f_flagclear))
4527 4545 /* 'for' loop 2 */
4528 4546 continue;
4529 4547 break;
4530 4548 }
4531 4549 break;
4532 4550 } /* 'for' loop 2 ends */
4533 4551 if (fp == NULL)
4534 4552 return (B_FALSE);
4535 4553 }
4536 4554 /* 'for' loop 1 ends */
4537 4555 return (B_TRUE);
4538 4556 }
4539 4557
4540 4558 /*
4541 4559 * Given an IPv6 MIB2 route entry, form the list of flags for the
4542 4560 * route.
4543 4561 */
4544 4562 static uint_t
4545 4563 form_v6_route_flags(const mib2_ipv6RouteEntry_t *rp6, char *flags)
4546 4564 {
4547 4565 uint_t flag_b;
4548 4566
4549 4567 flag_b = FLF_U;
4550 4568 (void) strcpy(flags, "U");
4551 4569 /* RTF_INDIRECT wins over RTF_GATEWAY - don't display both */
4552 4570 if (rp6->ipv6RouteInfo.re_flags & RTF_INDIRECT) {
4553 4571 (void) strcat(flags, "I");
4554 4572 flag_b |= FLF_I;
4555 4573 } else if (rp6->ipv6RouteInfo.re_ire_type & IRE_OFFLINK) {
4556 4574 (void) strcat(flags, "G");
4557 4575 flag_b |= FLF_G;
4558 4576 }
4559 4577
4560 4578 /* IRE_IF_CLONE wins over RTF_HOST - don't display both */
4561 4579 if (rp6->ipv6RouteInfo.re_ire_type & IRE_IF_CLONE) {
4562 4580 (void) strcat(flags, "C");
4563 4581 flag_b |= FLF_C;
4564 4582 } else if (rp6->ipv6RoutePfxLength == IPV6_ABITS) {
4565 4583 (void) strcat(flags, "H");
4566 4584 flag_b |= FLF_H;
4567 4585 }
4568 4586
4569 4587 if (rp6->ipv6RouteInfo.re_flags & RTF_DYNAMIC) {
4570 4588 (void) strcat(flags, "D");
4571 4589 flag_b |= FLF_D;
4572 4590 }
4573 4591 if (rp6->ipv6RouteInfo.re_ire_type == IRE_LOCAL) { /* Local */
4574 4592 (void) strcat(flags, "L");
4575 4593 flag_b |= FLF_L;
4576 4594 }
4577 4595 if (rp6->ipv6RouteInfo.re_flags & RTF_MULTIRT) {
4578 4596 (void) strcat(flags, "M"); /* Multiroute */
4579 4597 flag_b |= FLF_M;
4580 4598 }
4581 4599 if (rp6->ipv6RouteInfo.re_flags & RTF_SETSRC) {
4582 4600 (void) strcat(flags, "S"); /* Setsrc */
4583 4601 flag_b |= FLF_S;
4584 4602 }
4585 4603 if (rp6->ipv6RouteInfo.re_flags & RTF_REJECT) {
4586 4604 (void) strcat(flags, "R");
4587 4605 flag_b |= FLF_R;
4588 4606 }
4589 4607 if (rp6->ipv6RouteInfo.re_flags & RTF_BLACKHOLE) {
4590 4608 (void) strcat(flags, "B");
4591 4609 flag_b |= FLF_B;
4592 4610 }
4593 4611 if (rp6->ipv6RouteInfo.re_flags & RTF_ZONE) {
4594 4612 (void) strcat(flags, "Z");
4595 4613 flag_b |= FLF_Z;
4596 4614 }
4597 4615 return (flag_b);
4598 4616 }
4599 4617
4600 4618 static const char ire_hdr_v6[] =
4601 4619 "\n%s Table: IPv6\n";
4602 4620 static const char ire_hdr_v6_verbose[] =
4603 4621 " Destination/Mask Gateway If MTU "
4604 4622 "Ref Flags Out In/Fwd %s\n"
4605 4623 "--------------------------- --------------------------- ----- ----- "
4606 4624 "--- ----- ------ ------ %s\n";
4607 4625 static const char ire_hdr_v6_normal[] =
4608 4626 " Destination/Mask Gateway Flags Ref Use "
4609 4627 " If %s\n"
4610 4628 "--------------------------- --------------------------- ----- --- ------- "
4611 4629 "----- %s\n";
4612 4630
4613 4631 static boolean_t
4614 4632 ire_report_item_v6(const mib2_ipv6RouteEntry_t *rp6, boolean_t first,
4615 4633 const sec_attr_list_t *attrs)
4616 4634 {
4617 4635 char dstbuf[MAXHOSTNAMELEN + 1];
4618 4636 char gwbuf[MAXHOSTNAMELEN + 1];
4619 4637 char ifname[LIFNAMSIZ + 1];
4620 4638 char flags[10]; /* RTF_ flags */
4621 4639 uint_t flag_b;
4622 4640
4623 4641 if (!(Aflag || (rp6->ipv6RouteInfo.re_ire_type != IRE_IF_CLONE &&
4624 4642 rp6->ipv6RouteInfo.re_ire_type != IRE_MULTICAST &&
4625 4643 rp6->ipv6RouteInfo.re_ire_type != IRE_NOROUTE &&
4626 4644 rp6->ipv6RouteInfo.re_ire_type != IRE_LOCAL))) {
4627 4645 return (first);
4628 4646 }
4629 4647
4630 4648 flag_b = form_v6_route_flags(rp6, flags);
4631 4649
4632 4650 if (!ire_filter_match_v6(rp6, flag_b))
4633 4651 return (first);
4634 4652
4635 4653 if (first) {
4636 4654 (void) printf(ire_hdr_v6, Vflag ? "IRE" : "Routing");
4637 4655 (void) printf(Vflag ? ire_hdr_v6_verbose : ire_hdr_v6_normal,
4638 4656 RSECflag ? " Gateway security attributes " : "",
4639 4657 RSECflag ? "-------------------------------" : "");
4640 4658 first = B_FALSE;
4641 4659 }
4642 4660
4643 4661 if (Vflag) {
4644 4662 (void) printf("%-27s %-27s %-5s %5u %3u "
4645 4663 "%-5s %6u %6u %s\n",
4646 4664 pr_prefix6(&rp6->ipv6RouteDest,
4647 4665 rp6->ipv6RoutePfxLength, dstbuf, sizeof (dstbuf)),
4648 4666 IN6_IS_ADDR_UNSPECIFIED(&rp6->ipv6RouteNextHop) ?
4649 4667 " --" :
4650 4668 pr_addr6(&rp6->ipv6RouteNextHop, gwbuf, sizeof (gwbuf)),
4651 4669 octetstr(&rp6->ipv6RouteIfIndex, 'a',
4652 4670 ifname, sizeof (ifname)),
4653 4671 rp6->ipv6RouteInfo.re_max_frag,
4654 4672 rp6->ipv6RouteInfo.re_ref,
4655 4673 flags,
4656 4674 rp6->ipv6RouteInfo.re_obpkt,
4657 4675 rp6->ipv6RouteInfo.re_ibpkt,
4658 4676 pr_secattr(attrs));
4659 4677 } else {
4660 4678 (void) printf("%-27s %-27s %-5s %3u %7u %-5s %s\n",
4661 4679 pr_prefix6(&rp6->ipv6RouteDest,
4662 4680 rp6->ipv6RoutePfxLength, dstbuf, sizeof (dstbuf)),
4663 4681 IN6_IS_ADDR_UNSPECIFIED(&rp6->ipv6RouteNextHop) ?
4664 4682 " --" :
4665 4683 pr_addr6(&rp6->ipv6RouteNextHop, gwbuf, sizeof (gwbuf)),
4666 4684 flags,
4667 4685 rp6->ipv6RouteInfo.re_ref,
4668 4686 rp6->ipv6RouteInfo.re_obpkt + rp6->ipv6RouteInfo.re_ibpkt,
4669 4687 octetstr(&rp6->ipv6RouteIfIndex, 'a',
4670 4688 ifname, sizeof (ifname)),
4671 4689 pr_secattr(attrs));
4672 4690 }
4673 4691 return (first);
4674 4692 }
4675 4693
4676 4694 /*
4677 4695 * Common attribute-gathering routine for all transports.
4678 4696 */
4679 4697 static mib2_transportMLPEntry_t **
4680 4698 gather_attrs(const mib_item_t *item, int group, int mib_id, int esize)
4681 4699 {
4682 4700 int transport_count = 0;
4683 4701 const mib_item_t *iptr;
4684 4702 mib2_transportMLPEntry_t **attrs, *tme;
4685 4703
4686 4704 for (iptr = item; iptr != NULL; iptr = iptr->next_item) {
4687 4705 if (iptr->group == group && iptr->mib_id == mib_id)
4688 4706 transport_count += iptr->length / esize;
4689 4707 }
4690 4708 if (transport_count <= 0)
4691 4709 return (NULL);
4692 4710 attrs = calloc(transport_count, sizeof (*attrs));
4693 4711 if (attrs == NULL) {
4694 4712 perror("gather_attrs calloc failed");
4695 4713 return (NULL);
4696 4714 }
4697 4715 for (iptr = item; iptr != NULL; iptr = iptr->next_item) {
4698 4716 if (iptr->group == group && iptr->mib_id == EXPER_XPORT_MLP) {
4699 4717 for (tme = iptr->valp;
4700 4718 (char *)tme < (char *)iptr->valp + iptr->length;
4701 4719 /* LINTED: (note 1) */
4702 4720 tme = (mib2_transportMLPEntry_t *)((char *)tme +
4703 4721 transportMLPSize)) {
4704 4722 attrs[tme->tme_connidx] = tme;
4705 4723 }
4706 4724 }
4707 4725 }
4708 4726 return (attrs);
4709 4727 }
4710 4728
4711 4729 static void
4712 4730 print_transport_label(const mib2_transportMLPEntry_t *attr)
4713 4731 {
4714 4732 if (!RSECflag || attr == NULL ||
4715 4733 !(attr->tme_flags & MIB2_TMEF_IS_LABELED))
4716 4734 return;
4717 4735
4718 4736 if (bisinvalid(&attr->tme_label)) {
4719 4737 (void) printf(" INVALID\n");
4720 4738 } else if (!blequal(&attr->tme_label, zone_security_label)) {
4721 4739 char *sl_str;
4722 4740
4723 4741 sl_str = sl_to_str(&attr->tme_label);
4724 4742 (void) printf(" %s\n", sl_str);
4725 4743 free(sl_str);
4726 4744 }
4727 4745 }
4728 4746
4729 4747 /* ------------------------------ TCP_REPORT------------------------------- */
4730 4748
4731 4749 static const char tcp_hdr_v4[] =
4732 4750 "\nTCP: IPv4\n";
4733 4751 static const char tcp_hdr_v4_compat[] =
4734 4752 "\nTCP\n";
↓ open down ↓ |
4067 lines elided |
↑ open up ↑ |
4735 4753 static const char tcp_hdr_v4_verbose[] =
4736 4754 "Local/Remote Address Swind Snext Suna Rwind Rnext Rack "
4737 4755 " Rto Mss State\n"
4738 4756 "-------------------- ----- -------- -------- ----- -------- -------- "
4739 4757 "----- ----- -----------\n";
4740 4758 static const char tcp_hdr_v4_normal[] =
4741 4759 " Local Address Remote Address Swind Send-Q Rwind Recv-Q "
4742 4760 " State\n"
4743 4761 "-------------------- -------------------- ----- ------ ----- ------ "
4744 4762 "-----------\n";
4763 +static const char tcp_hdr_v4_pid[] =
4764 +" Local Address Remote Address User Pid Command Swind"
4765 +" Send-Q Rwind Recv-Q State\n"
4766 +"-------------------- -------------------- -------- ------ ------------- ------"
4767 +"- ------ ------- ------ -----------\n";
4768 +static const char tcp_hdr_v4_pid_verbose[] =
4769 +"Local/Remote Address Swind Snext Suna Rwind Rnext Rack Rto "
4770 +" Mss State User Pid Command\n"
4771 +"-------------------- ------- -------- -------- ------- -------- -------- -----"
4772 +" ----- ----------- -------- ------ --------------\n";
4745 4773
4746 4774 static const char tcp_hdr_v6[] =
4747 4775 "\nTCP: IPv6\n";
4748 4776 static const char tcp_hdr_v6_verbose[] =
4749 4777 "Local/Remote Address Swind Snext Suna Rwind Rnext "
4750 4778 " Rack Rto Mss State If\n"
4751 4779 "--------------------------------- ----- -------- -------- ----- -------- "
4752 4780 "-------- ----- ----- ----------- -----\n";
4753 4781 static const char tcp_hdr_v6_normal[] =
4754 4782 " Local Address Remote Address "
4755 4783 "Swind Send-Q Rwind Recv-Q State If\n"
4756 4784 "--------------------------------- --------------------------------- "
4757 4785 "----- ------ ----- ------ ----------- -----\n";
4786 +static const char tcp_hdr_v6_pid[] =
4787 +" Local Address Remote Address User"
4788 +" Pid Command Swind Send-Q Rwind Recv-Q State If\n"
4789 +"--------------------------------- --------------------------------- --------"
4790 +" ------ -------------- ------- ------ ------- ------ ----------- -----\n";
4791 +static const char tcp_hdr_v6_pid_verbose[] =
4792 +"Local/Remote Address Swind Snext Suna Rwind Rnext"
4793 +" Rack Rto Mss State If User Pid Command\n"
4794 +"--------------------------------- ------- -------- -------- ------- --------"
4795 +" -------- ----- ----- ----------- ----- -------- ------ --------------\n";
4758 4796
4759 4797 static boolean_t tcp_report_item_v4(const mib2_tcpConnEntry_t *,
4760 - boolean_t first, const mib2_transportMLPEntry_t *);
4798 + conn_pid_node_list_hdr_t *, boolean_t first,
4799 + const mib2_transportMLPEntry_t *);
4761 4800 static boolean_t tcp_report_item_v6(const mib2_tcp6ConnEntry_t *,
4762 - boolean_t first, const mib2_transportMLPEntry_t *);
4801 + conn_pid_node_list_hdr_t *, boolean_t first,
4802 + const mib2_transportMLPEntry_t *);
4803 +
4763 4804
4764 4805 static void
4765 4806 tcp_report(const mib_item_t *item)
4766 4807 {
4767 - int jtemp = 0;
4768 - boolean_t print_hdr_once_v4 = B_TRUE;
4769 - boolean_t print_hdr_once_v6 = B_TRUE;
4770 - mib2_tcpConnEntry_t *tp;
4771 - mib2_tcp6ConnEntry_t *tp6;
4772 - mib2_transportMLPEntry_t **v4_attrs, **v6_attrs;
4773 - mib2_transportMLPEntry_t **v4a, **v6a;
4774 - mib2_transportMLPEntry_t *aptr;
4808 + int jtemp = 0;
4809 + boolean_t print_hdr_once_v4 = B_TRUE;
4810 + boolean_t print_hdr_once_v6 = B_TRUE;
4811 + mib2_tcpConnEntry_t *tp;
4812 + mib2_tcp6ConnEntry_t *tp6;
4813 + mib2_transportMLPEntry_t **v4_attrs, **v6_attrs;
4814 + mib2_transportMLPEntry_t **v4a, **v6a;
4815 + mib2_transportMLPEntry_t *aptr;
4816 + conn_pid_node_list_hdr_t *cph;
4775 4817
4776 4818 if (!protocol_selected(IPPROTO_TCP))
4777 4819 return;
4778 4820
4779 4821 /*
4780 4822 * Preparation pass: the kernel returns separate entries for TCP
4781 4823 * connection table entries and Multilevel Port attributes. We loop
4782 4824 * through the attributes first and set up an array for each address
4783 4825 * family.
4784 4826 */
4785 4827 v4_attrs = family_selected(AF_INET) && RSECflag ?
4786 4828 gather_attrs(item, MIB2_TCP, MIB2_TCP_CONN, tcpConnEntrySize) :
4787 4829 NULL;
4788 4830 v6_attrs = family_selected(AF_INET6) && RSECflag ?
4789 4831 gather_attrs(item, MIB2_TCP6, MIB2_TCP6_CONN, tcp6ConnEntrySize) :
4790 4832 NULL;
4791 4833
4792 4834 /* 'for' loop 1: */
4793 4835 v4a = v4_attrs;
4794 4836 v6a = v6_attrs;
4795 4837 for (; item != NULL; item = item->next_item) {
4796 4838 if (Xflag) {
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
4797 4839 (void) printf("\n--- Entry %d ---\n", ++jtemp);
4798 4840 (void) printf("Group = %d, mib_id = %d, "
4799 4841 "length = %d, valp = 0x%p\n",
4800 4842 item->group, item->mib_id,
4801 4843 item->length, item->valp);
4802 4844 }
4803 4845
4804 4846 if (!((item->group == MIB2_TCP &&
4805 4847 item->mib_id == MIB2_TCP_CONN) ||
4806 4848 (item->group == MIB2_TCP6 &&
4807 - item->mib_id == MIB2_TCP6_CONN)))
4849 + item->mib_id == MIB2_TCP6_CONN) ||
4850 + (item->group == MIB2_TCP &&
4851 + item->mib_id == EXPER_XPORT_PROC_INFO) ||
4852 + (item->group == MIB2_TCP6 &&
4853 + item->mib_id == EXPER_XPORT_PROC_INFO)))
4808 4854 continue; /* 'for' loop 1 */
4809 4855
4810 4856 if (item->group == MIB2_TCP && !family_selected(AF_INET))
4811 4857 continue; /* 'for' loop 1 */
4812 4858 else if (item->group == MIB2_TCP6 && !family_selected(AF_INET6))
4813 4859 continue; /* 'for' loop 1 */
4814 4860
4815 - if (item->group == MIB2_TCP) {
4861 + if ((!Uflag) && item->group == MIB2_TCP &&
4862 + item->mib_id == MIB2_TCP_CONN) {
4816 4863 for (tp = (mib2_tcpConnEntry_t *)item->valp;
4817 4864 (char *)tp < (char *)item->valp + item->length;
4818 4865 /* LINTED: (note 1) */
4819 4866 tp = (mib2_tcpConnEntry_t *)((char *)tp +
4820 4867 tcpConnEntrySize)) {
4821 4868 aptr = v4a == NULL ? NULL : *v4a++;
4822 4869 print_hdr_once_v4 = tcp_report_item_v4(tp,
4823 - print_hdr_once_v4, aptr);
4870 + NULL, print_hdr_once_v4, aptr);
4824 4871 }
4825 - } else {
4872 + } else if ((!Uflag) && item->group == MIB2_TCP6 &&
4873 + item->mib_id == MIB2_TCP6_CONN) {
4826 4874 for (tp6 = (mib2_tcp6ConnEntry_t *)item->valp;
4827 4875 (char *)tp6 < (char *)item->valp + item->length;
4828 4876 /* LINTED: (note 1) */
4829 4877 tp6 = (mib2_tcp6ConnEntry_t *)((char *)tp6 +
4830 4878 tcp6ConnEntrySize)) {
4831 4879 aptr = v6a == NULL ? NULL : *v6a++;
4832 4880 print_hdr_once_v6 = tcp_report_item_v6(tp6,
4833 - print_hdr_once_v6, aptr);
4881 + NULL, print_hdr_once_v6, aptr);
4882 + }
4883 + } else if ((Uflag) && item->group == MIB2_TCP &&
4884 + item->mib_id == EXPER_XPORT_PROC_INFO) {
4885 + for (tp = (mib2_tcpConnEntry_t *)item->valp;
4886 + (char *)tp < (char *)item->valp + item->length;
4887 + /* LINTED: (note 1) */
4888 + tp = (mib2_tcpConnEntry_t *)((char *)cph +
4889 + cph->cph_tot_size)) {
4890 + aptr = v4a == NULL ? NULL : *v4a++;
4891 + /* LINTED: (note 1) */
4892 + cph = (conn_pid_node_list_hdr_t *)
4893 + ((char *)tp + tcpConnEntrySize);
4894 + print_hdr_once_v4 = tcp_report_item_v4(tp,
4895 + cph, print_hdr_once_v4, aptr);
4896 + }
4897 + } else if ((Uflag) && item->group == MIB2_TCP6 &&
4898 + item->mib_id == EXPER_XPORT_PROC_INFO) {
4899 + for (tp6 = (mib2_tcp6ConnEntry_t *)item->valp;
4900 + (char *)tp6 < (char *)item->valp + item->length;
4901 + /* LINTED: (note 1) */
4902 + tp6 = (mib2_tcp6ConnEntry_t *)((char *)cph +
4903 + cph->cph_tot_size)) {
4904 + aptr = v6a == NULL ? NULL : *v6a++;
4905 + /* LINTED: (note 1) */
4906 + cph = (conn_pid_node_list_hdr_t *)
4907 + ((char *)tp6 + tcp6ConnEntrySize);
4908 + print_hdr_once_v6 = tcp_report_item_v6(tp6,
4909 + cph, print_hdr_once_v6, aptr);
4834 4910 }
4835 4911 }
4912 +
4836 4913 } /* 'for' loop 1 ends */
4837 4914 (void) fflush(stdout);
4838 4915
4839 4916 if (v4_attrs != NULL)
4840 4917 free(v4_attrs);
4841 4918 if (v6_attrs != NULL)
4842 4919 free(v6_attrs);
4843 4920 }
4844 4921
4845 4922 static boolean_t
4846 -tcp_report_item_v4(const mib2_tcpConnEntry_t *tp, boolean_t first,
4923 +tcp_report_item_v4(const mib2_tcpConnEntry_t *tp,
4924 + conn_pid_node_list_hdr_t * cph, boolean_t first,
4847 4925 const mib2_transportMLPEntry_t *attr)
4848 4926 {
4849 4927 /*
4850 4928 * lname and fname below are for the hostname as well as the portname
4851 4929 * There is no limit on portname length so we assume MAXHOSTNAMELEN
4852 4930 * as the limit
4853 4931 */
4854 4932 char lname[MAXHOSTNAMELEN + MAXHOSTNAMELEN + 1];
4855 4933 char fname[MAXHOSTNAMELEN + MAXHOSTNAMELEN + 1];
4856 4934
4935 +
4857 4936 if (!(Aflag || tp->tcpConnEntryInfo.ce_state >= TCPS_ESTABLISHED))
4858 4937 return (first); /* Nothing to print */
4859 4938
4860 4939 if (first) {
4861 4940 (void) printf(v4compat ? tcp_hdr_v4_compat : tcp_hdr_v4);
4862 - (void) printf(Vflag ? tcp_hdr_v4_verbose : tcp_hdr_v4_normal);
4941 + if (Uflag)
4942 + (void) printf(Vflag ? tcp_hdr_v4_pid_verbose :
4943 + tcp_hdr_v4_pid);
4944 + else
4945 + (void) printf(Vflag ? tcp_hdr_v4_verbose :
4946 + tcp_hdr_v4_normal);
4863 4947 }
4864 4948
4865 - if (Vflag) {
4949 + if ((!Uflag) && Vflag) {
4866 4950 (void) printf("%-20s\n%-20s %5u %08x %08x %5u %08x %08x "
4867 4951 "%5u %5u %s\n",
4868 4952 pr_ap(tp->tcpConnLocalAddress,
4869 4953 tp->tcpConnLocalPort, "tcp", lname, sizeof (lname)),
4870 4954 pr_ap(tp->tcpConnRemAddress,
4871 4955 tp->tcpConnRemPort, "tcp", fname, sizeof (fname)),
4872 4956 tp->tcpConnEntryInfo.ce_swnd,
4873 4957 tp->tcpConnEntryInfo.ce_snxt,
4874 4958 tp->tcpConnEntryInfo.ce_suna,
4875 4959 tp->tcpConnEntryInfo.ce_rwnd,
4876 4960 tp->tcpConnEntryInfo.ce_rnxt,
4877 4961 tp->tcpConnEntryInfo.ce_rack,
4878 4962 tp->tcpConnEntryInfo.ce_rto,
4879 4963 tp->tcpConnEntryInfo.ce_mss,
4880 4964 mitcp_state(tp->tcpConnEntryInfo.ce_state, attr));
4881 - } else {
4965 + } else if ((!Uflag) && (!Vflag)) {
4882 4966 int sq = (int)tp->tcpConnEntryInfo.ce_snxt -
4883 4967 (int)tp->tcpConnEntryInfo.ce_suna - 1;
4884 4968 int rq = (int)tp->tcpConnEntryInfo.ce_rnxt -
4885 4969 (int)tp->tcpConnEntryInfo.ce_rack;
4886 4970
4887 4971 (void) printf("%-20s %-20s %5u %6d %5u %6d %s\n",
4888 4972 pr_ap(tp->tcpConnLocalAddress,
4889 4973 tp->tcpConnLocalPort, "tcp", lname, sizeof (lname)),
4890 4974 pr_ap(tp->tcpConnRemAddress,
4891 4975 tp->tcpConnRemPort, "tcp", fname, sizeof (fname)),
4892 4976 tp->tcpConnEntryInfo.ce_swnd,
4893 4977 (sq >= 0) ? sq : 0,
4894 4978 tp->tcpConnEntryInfo.ce_rwnd,
4895 4979 (rq >= 0) ? rq : 0,
4896 4980 mitcp_state(tp->tcpConnEntryInfo.ce_state, attr));
4981 + } else if (Uflag && Vflag) {
4982 + int i = 0;
4983 + conn_pid_node_t *cpn = cph->cph_cpns;
4984 + proc_info_t *pinfo;
4985 +
4986 + do {
4987 + int pid = (cph->cph_pn_cnt)?cpn->cpn_pid:0;
4988 + pinfo = get_proc_info(cpn->cpn_pid);
4989 +
4990 + (void) printf("%-20s\n%-20s %7u %08x %08x %7u %08x %08x "
4991 + "%5u %5u %-11s %-8.8s %6u %s\n",
4992 + pr_ap(tp->tcpConnLocalAddress,
4993 + tp->tcpConnLocalPort, "tcp", lname, sizeof (lname)),
4994 + pr_ap(tp->tcpConnRemAddress,
4995 + tp->tcpConnRemPort, "tcp", fname, sizeof (fname)),
4996 + tp->tcpConnEntryInfo.ce_swnd,
4997 + tp->tcpConnEntryInfo.ce_snxt,
4998 + tp->tcpConnEntryInfo.ce_suna,
4999 + tp->tcpConnEntryInfo.ce_rwnd,
5000 + tp->tcpConnEntryInfo.ce_rnxt,
5001 + tp->tcpConnEntryInfo.ce_rack,
5002 + tp->tcpConnEntryInfo.ce_rto,
5003 + tp->tcpConnEntryInfo.ce_mss,
5004 + mitcp_state(tp->tcpConnEntryInfo.ce_state, attr),
5005 + pinfo->pr_user, pid, pinfo->pr_psargs);
5006 + i++; cpn++;
5007 + } while (i < cph->cph_pn_cnt);
5008 + } else if (Uflag && (!Vflag)) {
5009 + int sq = (int)tp->tcpConnEntryInfo.ce_snxt -
5010 + (int)tp->tcpConnEntryInfo.ce_suna - 1;
5011 + int rq = (int)tp->tcpConnEntryInfo.ce_rnxt -
5012 + (int)tp->tcpConnEntryInfo.ce_rack;
5013 + int i = 0;
5014 + conn_pid_node_t *cpn = cph->cph_cpns;
5015 + proc_info_t *pinfo;
5016 +
5017 + do {
5018 + int pid = (cph->cph_pn_cnt)?cpn->cpn_pid:0;
5019 + pinfo = get_proc_info(cpn->cpn_pid);
5020 +
5021 + (void) printf("%-20s %-20s %-8.8s %6u %-13.13s %7u %6d %7u %6d %s\n",
5022 + pr_ap(tp->tcpConnLocalAddress,
5023 + tp->tcpConnLocalPort, "tcp", lname, sizeof (lname)),
5024 + pr_ap(tp->tcpConnRemAddress,
5025 + tp->tcpConnRemPort, "tcp", fname, sizeof (fname)),
5026 + pinfo->pr_user, pid, pinfo->pr_fname,
5027 + tp->tcpConnEntryInfo.ce_swnd,
5028 + (sq >= 0) ? sq : 0,
5029 + tp->tcpConnEntryInfo.ce_rwnd,
5030 + (rq >= 0) ? rq : 0,
5031 + mitcp_state(tp->tcpConnEntryInfo.ce_state, attr));
5032 +
5033 + i++; cpn++;
5034 + } while (i < cph->cph_pn_cnt);
4897 5035 }
4898 5036
4899 5037 print_transport_label(attr);
4900 5038
4901 5039 return (B_FALSE);
4902 5040 }
4903 5041
4904 5042 static boolean_t
4905 -tcp_report_item_v6(const mib2_tcp6ConnEntry_t *tp6, boolean_t first,
5043 +tcp_report_item_v6(const mib2_tcp6ConnEntry_t *tp6,
5044 + conn_pid_node_list_hdr_t *cph, boolean_t first,
4906 5045 const mib2_transportMLPEntry_t *attr)
4907 5046 {
4908 5047 /*
4909 5048 * lname and fname below are for the hostname as well as the portname
4910 5049 * There is no limit on portname length so we assume MAXHOSTNAMELEN
4911 5050 * as the limit
4912 5051 */
4913 5052 char lname[MAXHOSTNAMELEN + MAXHOSTNAMELEN + 1];
4914 5053 char fname[MAXHOSTNAMELEN + MAXHOSTNAMELEN + 1];
4915 5054 char ifname[LIFNAMSIZ + 1];
4916 5055 char *ifnamep;
4917 5056
4918 5057 if (!(Aflag || tp6->tcp6ConnEntryInfo.ce_state >= TCPS_ESTABLISHED))
4919 5058 return (first); /* Nothing to print */
4920 5059
4921 5060 if (first) {
4922 5061 (void) printf(tcp_hdr_v6);
4923 - (void) printf(Vflag ? tcp_hdr_v6_verbose : tcp_hdr_v6_normal);
5062 + if (Uflag)
5063 + (void) printf(Vflag ? tcp_hdr_v6_pid_verbose :
5064 + tcp_hdr_v6_pid);
5065 + else
5066 + (void) printf(Vflag ? tcp_hdr_v6_verbose :
5067 + tcp_hdr_v6_normal);
4924 5068 }
4925 5069
4926 5070 ifnamep = (tp6->tcp6ConnIfIndex != 0) ?
4927 5071 if_indextoname(tp6->tcp6ConnIfIndex, ifname) : NULL;
4928 5072 if (ifnamep == NULL)
4929 5073 ifnamep = "";
4930 5074
4931 - if (Vflag) {
5075 + if ((!Uflag) && Vflag) {
4932 5076 (void) printf("%-33s\n%-33s %5u %08x %08x %5u %08x %08x "
4933 5077 "%5u %5u %-11s %s\n",
4934 5078 pr_ap6(&tp6->tcp6ConnLocalAddress,
4935 5079 tp6->tcp6ConnLocalPort, "tcp", lname, sizeof (lname)),
4936 5080 pr_ap6(&tp6->tcp6ConnRemAddress,
4937 5081 tp6->tcp6ConnRemPort, "tcp", fname, sizeof (fname)),
4938 5082 tp6->tcp6ConnEntryInfo.ce_swnd,
4939 5083 tp6->tcp6ConnEntryInfo.ce_snxt,
4940 5084 tp6->tcp6ConnEntryInfo.ce_suna,
4941 5085 tp6->tcp6ConnEntryInfo.ce_rwnd,
4942 5086 tp6->tcp6ConnEntryInfo.ce_rnxt,
4943 5087 tp6->tcp6ConnEntryInfo.ce_rack,
4944 5088 tp6->tcp6ConnEntryInfo.ce_rto,
4945 5089 tp6->tcp6ConnEntryInfo.ce_mss,
4946 5090 mitcp_state(tp6->tcp6ConnEntryInfo.ce_state, attr),
4947 5091 ifnamep);
4948 - } else {
5092 + } else if ((!Uflag) && (!Vflag)) {
4949 5093 int sq = (int)tp6->tcp6ConnEntryInfo.ce_snxt -
4950 5094 (int)tp6->tcp6ConnEntryInfo.ce_suna - 1;
4951 5095 int rq = (int)tp6->tcp6ConnEntryInfo.ce_rnxt -
4952 5096 (int)tp6->tcp6ConnEntryInfo.ce_rack;
4953 5097
4954 5098 (void) printf("%-33s %-33s %5u %6d %5u %6d %-11s %s\n",
4955 5099 pr_ap6(&tp6->tcp6ConnLocalAddress,
4956 5100 tp6->tcp6ConnLocalPort, "tcp", lname, sizeof (lname)),
4957 5101 pr_ap6(&tp6->tcp6ConnRemAddress,
4958 5102 tp6->tcp6ConnRemPort, "tcp", fname, sizeof (fname)),
4959 5103 tp6->tcp6ConnEntryInfo.ce_swnd,
4960 5104 (sq >= 0) ? sq : 0,
4961 5105 tp6->tcp6ConnEntryInfo.ce_rwnd,
4962 5106 (rq >= 0) ? rq : 0,
4963 5107 mitcp_state(tp6->tcp6ConnEntryInfo.ce_state, attr),
4964 5108 ifnamep);
5109 + } else if (Uflag && Vflag) {
5110 + int i = 0;
5111 + conn_pid_node_t *cpn = cph->cph_cpns;
5112 + proc_info_t *pinfo;
5113 +
5114 + do {
5115 + int pid = (cph->cph_pn_cnt)?cpn->cpn_pid:0;
5116 + pinfo = get_proc_info(cpn->cpn_pid);
5117 +
5118 + (void) printf("%-33s\n%-33s %7u %08x %08x %7u %08x %08x "
5119 + "%5u %5u %-11s %-5.5s %-8.8s %6u %s\n",
5120 + pr_ap6(&tp6->tcp6ConnLocalAddress,
5121 + tp6->tcp6ConnLocalPort, "tcp", lname, sizeof (lname)),
5122 + pr_ap6(&tp6->tcp6ConnRemAddress,
5123 + tp6->tcp6ConnRemPort, "tcp", fname, sizeof (fname)),
5124 + tp6->tcp6ConnEntryInfo.ce_swnd,
5125 + tp6->tcp6ConnEntryInfo.ce_snxt,
5126 + tp6->tcp6ConnEntryInfo.ce_suna,
5127 + tp6->tcp6ConnEntryInfo.ce_rwnd,
5128 + tp6->tcp6ConnEntryInfo.ce_rnxt,
5129 + tp6->tcp6ConnEntryInfo.ce_rack,
5130 + tp6->tcp6ConnEntryInfo.ce_rto,
5131 + tp6->tcp6ConnEntryInfo.ce_mss,
5132 + mitcp_state(tp6->tcp6ConnEntryInfo.ce_state, attr),
5133 + ifnamep, pinfo->pr_user, pid, pinfo->pr_psargs);
5134 + i++; cpn++;
5135 + } while (i < cph->cph_pn_cnt);
5136 + } else if (Uflag && (!Vflag)) {
5137 + int sq = (int)tp6->tcp6ConnEntryInfo.ce_snxt -
5138 + (int)tp6->tcp6ConnEntryInfo.ce_suna - 1;
5139 + int rq = (int)tp6->tcp6ConnEntryInfo.ce_rnxt -
5140 + (int)tp6->tcp6ConnEntryInfo.ce_rack;
5141 + int i = 0;
5142 + conn_pid_node_t *cpn = cph->cph_cpns;
5143 + proc_info_t *pinfo;
5144 +
5145 + do {
5146 + int pid = (cph->cph_pn_cnt)?cpn->cpn_pid:0;
5147 + pinfo = get_proc_info(cpn->cpn_pid);
5148 +
5149 + (void) printf("%-33s %-33s %-8.8s %6u %-14.14s %7d %6u %7d %6d %-11s %s\n",
5150 + pr_ap6(&tp6->tcp6ConnLocalAddress,
5151 + tp6->tcp6ConnLocalPort, "tcp", lname, sizeof (lname)),
5152 + pr_ap6(&tp6->tcp6ConnRemAddress,
5153 + tp6->tcp6ConnRemPort, "tcp", fname, sizeof (fname)),
5154 + pinfo->pr_user, pid, pinfo->pr_fname,
5155 + tp6->tcp6ConnEntryInfo.ce_swnd,
5156 + (sq >= 0) ? sq : 0,
5157 + tp6->tcp6ConnEntryInfo.ce_rwnd,
5158 + (rq >= 0) ? rq : 0,
5159 + mitcp_state(tp6->tcp6ConnEntryInfo.ce_state, attr),
5160 + ifnamep);
5161 +
5162 + i++; cpn++;
5163 + } while (i < cph->cph_pn_cnt);
4965 5164 }
4966 5165
4967 5166 print_transport_label(attr);
4968 5167
4969 5168 return (B_FALSE);
4970 5169 }
4971 5170
4972 5171 /* ------------------------------- UDP_REPORT------------------------------- */
4973 5172
4974 5173 static boolean_t udp_report_item_v4(const mib2_udpEntry_t *ude,
4975 - boolean_t first, const mib2_transportMLPEntry_t *attr);
5174 + conn_pid_node_list_hdr_t *cph, boolean_t first,
5175 + const mib2_transportMLPEntry_t *attr);
4976 5176 static boolean_t udp_report_item_v6(const mib2_udp6Entry_t *ude6,
4977 - boolean_t first, const mib2_transportMLPEntry_t *attr);
5177 + conn_pid_node_list_hdr_t *cph, boolean_t first,
5178 + const mib2_transportMLPEntry_t *attr);
4978 5179
4979 5180 static const char udp_hdr_v4[] =
4980 5181 " Local Address Remote Address State\n"
4981 5182 "-------------------- -------------------- ----------\n";
5183 +static const char udp_hdr_v4_pid[] =
5184 +" Local Address Remote Address User Pid "
5185 +" Command State\n"
5186 +"-------------------- -------------------- -------- ------ "
5187 +"-------------- ----------\n";
5188 +static const char udp_hdr_v4_pid_verbose[] =
5189 +" Local Address Remote Address User Pid State "
5190 +" Command\n"
5191 +"-------------------- -------------------- -------- ------ ---------- "
5192 +"----------------\n";
4982 5193
4983 5194 static const char udp_hdr_v6[] =
4984 5195 " Local Address Remote Address "
4985 5196 " State If\n"
4986 5197 "--------------------------------- --------------------------------- "
4987 5198 "---------- -----\n";
5199 +static const char udp_hdr_v6_pid[] =
5200 +" Local Address Remote Address "
5201 +" User Pid Command State If\n"
5202 +"--------------------------------- --------------------------------- "
5203 +"-------- ------ -------------- ---------- -----\n";
5204 +static const char udp_hdr_v6_pid_verbose[] =
5205 +" Local Address Remote Address "
5206 +" User Pid State If Command\n"
5207 +"--------------------------------- --------------------------------- "
5208 +"-------- ------ ---------- ----- ----------------\n";
5209 +
4988 5210
4989 5211 static void
4990 5212 udp_report(const mib_item_t *item)
4991 5213 {
4992 - int jtemp = 0;
4993 - boolean_t print_hdr_once_v4 = B_TRUE;
4994 - boolean_t print_hdr_once_v6 = B_TRUE;
4995 - mib2_udpEntry_t *ude;
4996 - mib2_udp6Entry_t *ude6;
4997 - mib2_transportMLPEntry_t **v4_attrs, **v6_attrs;
4998 - mib2_transportMLPEntry_t **v4a, **v6a;
4999 - mib2_transportMLPEntry_t *aptr;
5214 + int jtemp = 0;
5215 + boolean_t print_hdr_once_v4 = B_TRUE;
5216 + boolean_t print_hdr_once_v6 = B_TRUE;
5217 + mib2_udpEntry_t *ude;
5218 + mib2_udp6Entry_t *ude6;
5219 + mib2_transportMLPEntry_t **v4_attrs, **v6_attrs;
5220 + mib2_transportMLPEntry_t **v4a, **v6a;
5221 + mib2_transportMLPEntry_t *aptr;
5222 + conn_pid_node_list_hdr_t *cph;
5000 5223
5001 5224 if (!protocol_selected(IPPROTO_UDP))
5002 5225 return;
5003 5226
5004 5227 /*
5005 5228 * Preparation pass: the kernel returns separate entries for UDP
5006 5229 * connection table entries and Multilevel Port attributes. We loop
5007 5230 * through the attributes first and set up an array for each address
5008 5231 * family.
5009 5232 */
5010 5233 v4_attrs = family_selected(AF_INET) && RSECflag ?
5011 5234 gather_attrs(item, MIB2_UDP, MIB2_UDP_ENTRY, udpEntrySize) : NULL;
5012 5235 v6_attrs = family_selected(AF_INET6) && RSECflag ?
5013 5236 gather_attrs(item, MIB2_UDP6, MIB2_UDP6_ENTRY, udp6EntrySize) :
5014 5237 NULL;
5015 5238
5016 5239 v4a = v4_attrs;
5017 5240 v6a = v6_attrs;
5018 5241 /* 'for' loop 1: */
5019 5242 for (; item; item = item->next_item) {
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
5020 5243 if (Xflag) {
5021 5244 (void) printf("\n--- Entry %d ---\n", ++jtemp);
5022 5245 (void) printf("Group = %d, mib_id = %d, "
5023 5246 "length = %d, valp = 0x%p\n",
5024 5247 item->group, item->mib_id,
5025 5248 item->length, item->valp);
5026 5249 }
5027 5250 if (!((item->group == MIB2_UDP &&
5028 5251 item->mib_id == MIB2_UDP_ENTRY) ||
5029 5252 (item->group == MIB2_UDP6 &&
5030 - item->mib_id == MIB2_UDP6_ENTRY)))
5253 + item->mib_id == MIB2_UDP6_ENTRY) ||
5254 + (item->group == MIB2_UDP &&
5255 + item->mib_id == EXPER_XPORT_PROC_INFO) ||
5256 + (item->group == MIB2_UDP6 &&
5257 + item->mib_id == EXPER_XPORT_PROC_INFO)))
5031 5258 continue; /* 'for' loop 1 */
5032 5259
5033 5260 if (item->group == MIB2_UDP && !family_selected(AF_INET))
5034 5261 continue; /* 'for' loop 1 */
5035 5262 else if (item->group == MIB2_UDP6 && !family_selected(AF_INET6))
5036 5263 continue; /* 'for' loop 1 */
5037 5264
5038 5265 /* xxx.xxx.xxx.xxx,pppp sss... */
5039 - if (item->group == MIB2_UDP) {
5266 + if ((!Uflag) && item->group == MIB2_UDP &&
5267 + item->mib_id == MIB2_UDP_ENTRY) {
5040 5268 for (ude = (mib2_udpEntry_t *)item->valp;
5041 5269 (char *)ude < (char *)item->valp + item->length;
5042 5270 /* LINTED: (note 1) */
5043 5271 ude = (mib2_udpEntry_t *)((char *)ude +
5044 5272 udpEntrySize)) {
5045 5273 aptr = v4a == NULL ? NULL : *v4a++;
5046 5274 print_hdr_once_v4 = udp_report_item_v4(ude,
5047 - print_hdr_once_v4, aptr);
5275 + NULL, print_hdr_once_v4, aptr);
5048 5276 }
5049 - } else {
5277 + } else if ((!Uflag) && item->group == MIB2_UDP6 &&
5278 + item->mib_id == MIB2_UDP6_ENTRY) {
5050 5279 for (ude6 = (mib2_udp6Entry_t *)item->valp;
5051 5280 (char *)ude6 < (char *)item->valp + item->length;
5052 5281 /* LINTED: (note 1) */
5053 5282 ude6 = (mib2_udp6Entry_t *)((char *)ude6 +
5054 5283 udp6EntrySize)) {
5055 5284 aptr = v6a == NULL ? NULL : *v6a++;
5056 5285 print_hdr_once_v6 = udp_report_item_v6(ude6,
5057 - print_hdr_once_v6, aptr);
5286 + NULL, print_hdr_once_v6, aptr);
5287 + }
5288 + } else if ((Uflag) && item->group == MIB2_UDP &&
5289 + item->mib_id == EXPER_XPORT_PROC_INFO) {
5290 + for (ude = (mib2_udpEntry_t *)item->valp;
5291 + (char *)ude < (char *)item->valp + item->length;
5292 + /* LINTED: (note 1) */
5293 + ude = (mib2_udpEntry_t *)((char *)cph +
5294 + cph->cph_tot_size)) {
5295 + aptr = v4a == NULL ? NULL : *v4a++;
5296 + /* LINTED: (note 1) */
5297 + cph = (conn_pid_node_list_hdr_t *)
5298 + ((char *)ude + udpEntrySize);
5299 + print_hdr_once_v4 = udp_report_item_v4(ude,
5300 + cph, print_hdr_once_v4, aptr);
5301 + }
5302 + } else if ((Uflag) && item->group == MIB2_UDP6 &&
5303 + item->mib_id == EXPER_XPORT_PROC_INFO) {
5304 + for (ude6 = (mib2_udp6Entry_t *)item->valp;
5305 + (char *)ude6 < (char *)item->valp + item->length;
5306 + /* LINTED: (note 1) */
5307 + ude6 = (mib2_udp6Entry_t *)((char *)cph +
5308 + cph->cph_tot_size)) {
5309 + aptr = v6a == NULL ? NULL : *v6a++;
5310 + /* LINTED: (note 1) */
5311 + cph = (conn_pid_node_list_hdr_t *)
5312 + ((char *)ude6 + udp6EntrySize);
5313 + print_hdr_once_v6 = udp_report_item_v6(ude6,
5314 + cph, print_hdr_once_v6, aptr);
5058 5315 }
5059 5316 }
5060 5317 } /* 'for' loop 1 ends */
5061 5318 (void) fflush(stdout);
5062 5319
5063 5320 if (v4_attrs != NULL)
5064 5321 free(v4_attrs);
5065 5322 if (v6_attrs != NULL)
5066 5323 free(v6_attrs);
5067 5324 }
5068 5325
5069 5326 static boolean_t
5070 -udp_report_item_v4(const mib2_udpEntry_t *ude, boolean_t first,
5071 - const mib2_transportMLPEntry_t *attr)
5327 +udp_report_item_v4(const mib2_udpEntry_t *ude, conn_pid_node_list_hdr_t *cph,
5328 + boolean_t first, const mib2_transportMLPEntry_t *attr)
5072 5329 {
5073 5330 char lname[MAXHOSTNAMELEN + MAXHOSTNAMELEN + 1];
5074 5331 /* hostname + portname */
5075 5332
5076 5333 if (!(Aflag || ude->udpEntryInfo.ue_state >= MIB2_UDP_connected))
5077 5334 return (first); /* Nothing to print */
5078 5335
5079 5336 if (first) {
5080 5337 (void) printf(v4compat ? "\nUDP\n" : "\nUDP: IPv4\n");
5081 - (void) printf(udp_hdr_v4);
5338 +
5339 + if (Uflag)
5340 + (void) printf(Vflag ? udp_hdr_v4_pid_verbose :
5341 + udp_hdr_v4_pid);
5342 + else
5343 + (void) printf(udp_hdr_v4);
5344 +
5082 5345 first = B_FALSE;
5083 5346 }
5084 5347
5085 - (void) printf("%-20s ",
5348 + (void) printf("%-20s %-20s ",
5086 5349 pr_ap(ude->udpLocalAddress, ude->udpLocalPort, "udp",
5087 - lname, sizeof (lname)));
5088 - (void) printf("%-20s %s\n",
5350 + lname, sizeof (lname)),
5089 5351 ude->udpEntryInfo.ue_state == MIB2_UDP_connected ?
5090 5352 pr_ap(ude->udpEntryInfo.ue_RemoteAddress,
5091 5353 ude->udpEntryInfo.ue_RemotePort, "udp", lname, sizeof (lname)) :
5092 - "",
5093 - miudp_state(ude->udpEntryInfo.ue_state, attr));
5354 + "");
5355 + if (!Uflag) {
5356 + (void) printf("%s\n",
5357 + miudp_state(ude->udpEntryInfo.ue_state, attr));
5358 + } else {
5359 + int i = 0;
5360 + conn_pid_node_t *cpn = cph->cph_cpns;
5361 + proc_info_t *pinfo;
5362 +
5363 + do {
5364 + int pid = (cph->cph_pn_cnt)?cpn->cpn_pid:0;
5365 + pinfo = get_proc_info(cpn->cpn_pid);
5366 + (void) printf("%-8.8s %6u ", pinfo->pr_user, pid);
5367 +
5368 + if (Vflag) {
5369 + (void) printf("%-10.10s %s\n",
5370 + miudp_state(ude->udpEntryInfo.ue_state,
5371 + attr),
5372 + pinfo->pr_psargs);
5373 + } else {
5374 + (void) printf("%-14.14s %s\n", pinfo->pr_fname,
5375 + miudp_state(ude->udpEntryInfo.ue_state,
5376 + attr));
5377 + }
5378 + i++; cpn++;
5379 + } while (i < cph->cph_pn_cnt);
5380 + }
5094 5381
5095 5382 print_transport_label(attr);
5096 5383
5097 5384 return (first);
5098 5385 }
5099 5386
5100 5387 static boolean_t
5101 -udp_report_item_v6(const mib2_udp6Entry_t *ude6, boolean_t first,
5102 - const mib2_transportMLPEntry_t *attr)
5388 +udp_report_item_v6(const mib2_udp6Entry_t *ude6, conn_pid_node_list_hdr_t *cph,
5389 + boolean_t first, const mib2_transportMLPEntry_t *attr)
5103 5390 {
5104 5391 char lname[MAXHOSTNAMELEN + MAXHOSTNAMELEN + 1];
5105 5392 /* hostname + portname */
5106 5393 char ifname[LIFNAMSIZ + 1];
5107 5394 const char *ifnamep;
5108 5395
5109 5396 if (!(Aflag || ude6->udp6EntryInfo.ue_state >= MIB2_UDP_connected))
5110 5397 return (first); /* Nothing to print */
5111 5398
5112 5399 if (first) {
5113 5400 (void) printf("\nUDP: IPv6\n");
5114 - (void) printf(udp_hdr_v6);
5401 +
5402 + if (Uflag)
5403 + (void) printf(Vflag ? udp_hdr_v6_pid_verbose :
5404 + udp_hdr_v6_pid);
5405 + else
5406 + (void) printf(udp_hdr_v6);
5407 +
5115 5408 first = B_FALSE;
5116 5409 }
5117 5410
5118 5411 ifnamep = (ude6->udp6IfIndex != 0) ?
5119 5412 if_indextoname(ude6->udp6IfIndex, ifname) : NULL;
5120 5413
5121 - (void) printf("%-33s ",
5414 + (void) printf("%-33s %-33s ",
5122 5415 pr_ap6(&ude6->udp6LocalAddress,
5123 - ude6->udp6LocalPort, "udp", lname, sizeof (lname)));
5124 - (void) printf("%-33s %-10s %s\n",
5416 + ude6->udp6LocalPort, "udp", lname, sizeof (lname)),
5125 5417 ude6->udp6EntryInfo.ue_state == MIB2_UDP_connected ?
5126 5418 pr_ap6(&ude6->udp6EntryInfo.ue_RemoteAddress,
5127 5419 ude6->udp6EntryInfo.ue_RemotePort, "udp", lname, sizeof (lname)) :
5128 - "",
5129 - miudp_state(ude6->udp6EntryInfo.ue_state, attr),
5130 - ifnamep == NULL ? "" : ifnamep);
5420 + "");
5421 + if (!Uflag) {
5422 + (void) printf("%-10s %s\n",
5423 + miudp_state(ude6->udp6EntryInfo.ue_state, attr),
5424 + ifnamep == NULL ? "" : ifnamep);
5425 + } else {
5426 + int i = 0;
5427 + conn_pid_node_t *cpn = cph->cph_cpns;
5428 + proc_info_t *pinfo;
5429 +
5430 + do {
5431 + int pid = (cph->cph_pn_cnt)?cpn->cpn_pid:0;
5432 + pinfo = get_proc_info(cpn->cpn_pid);
5433 + (void) printf("%-8.8s %6u ", pinfo->pr_user, pid);
5434 +
5435 + if (Vflag) {
5436 + (void) printf("%-10.10s %-5.5s %s\n",
5437 + miudp_state(ude6->udp6EntryInfo.ue_state,
5438 + attr),
5439 + ifnamep == NULL ? "" : ifnamep,
5440 + pinfo->pr_psargs);
5441 + } else {
5442 + (void) printf("%-14.14s %-10.10s %s\n",
5443 + pinfo->pr_fname,
5444 + miudp_state(ude6->udp6EntryInfo.ue_state,
5445 + attr),
5446 + ifnamep == NULL ? "" : ifnamep);
5447 + }
5448 + i++; cpn++;
5449 + } while (i < cph->cph_pn_cnt);
5450 + }
5131 5451
5132 5452 print_transport_label(attr);
5133 5453
5134 5454 return (first);
5135 5455 }
5136 5456
5137 5457 /* ------------------------------ SCTP_REPORT------------------------------- */
5138 5458
5139 5459 static const char sctp_hdr[] =
5140 5460 "\nSCTP:";
5141 5461 static const char sctp_hdr_normal[] =
5142 5462 " Local Address Remote Address "
5143 5463 "Swind Send-Q Rwind Recv-Q StrsI/O State\n"
5144 5464 "------------------------------- ------------------------------- "
5145 5465 "------ ------ ------ ------ ------- -----------";
5466 +static const char sctp_hdr_pid[] =
5467 +" Local Address Remote Address "
5468 +"Swind Send-Q Rwind Recv-Q StrsI/O User Pid Command State\n"
5469 +"------------------------------- ------------------------------- ------ "
5470 +"------ ------ ------ ------- -------- ------ -------------- -----------";
5471 +static const char sctp_hdr_pid_verbose[] =
5472 +" Local Address Remote Address "
5473 +"Swind Send-Q Rwind Recv-Q StrsI/O User Pid State Command\n"
5474 +"------------------------------- ------------------------------- ------ "
5475 +"------ ------ ------ ------- -------- ------ ----------- --------------";
5146 5476
5147 5477 static const char *
5148 5478 nssctp_state(int state, const mib2_transportMLPEntry_t *attr)
5149 5479 {
5150 5480 static char sctpsbuf[50];
5151 5481 const char *cp;
5152 5482
5153 5483 switch (state) {
5154 5484 case MIB2_SCTP_closed:
5155 5485 cp = "CLOSED";
5156 5486 break;
5157 5487 case MIB2_SCTP_cookieWait:
5158 5488 cp = "COOKIE_WAIT";
5159 5489 break;
5160 5490 case MIB2_SCTP_cookieEchoed:
5161 5491 cp = "COOKIE_ECHOED";
5162 5492 break;
5163 5493 case MIB2_SCTP_established:
5164 5494 cp = "ESTABLISHED";
5165 5495 break;
5166 5496 case MIB2_SCTP_shutdownPending:
5167 5497 cp = "SHUTDOWN_PENDING";
5168 5498 break;
5169 5499 case MIB2_SCTP_shutdownSent:
5170 5500 cp = "SHUTDOWN_SENT";
5171 5501 break;
5172 5502 case MIB2_SCTP_shutdownReceived:
5173 5503 cp = "SHUTDOWN_RECEIVED";
5174 5504 break;
5175 5505 case MIB2_SCTP_shutdownAckSent:
5176 5506 cp = "SHUTDOWN_ACK_SENT";
5177 5507 break;
5178 5508 case MIB2_SCTP_listen:
5179 5509 cp = "LISTEN";
5180 5510 break;
5181 5511 default:
5182 5512 (void) snprintf(sctpsbuf, sizeof (sctpsbuf),
5183 5513 "UNKNOWN STATE(%d)", state);
5184 5514 cp = sctpsbuf;
5185 5515 break;
5186 5516 }
5187 5517
5188 5518 if (RSECflag && attr != NULL && attr->tme_flags != 0) {
5189 5519 if (cp != sctpsbuf) {
5190 5520 (void) strlcpy(sctpsbuf, cp, sizeof (sctpsbuf));
5191 5521 cp = sctpsbuf;
5192 5522 }
5193 5523 if (attr->tme_flags & MIB2_TMEF_PRIVATE)
5194 5524 (void) strlcat(sctpsbuf, " P", sizeof (sctpsbuf));
5195 5525 if (attr->tme_flags & MIB2_TMEF_SHARED)
5196 5526 (void) strlcat(sctpsbuf, " S", sizeof (sctpsbuf));
5197 5527 }
5198 5528
5199 5529 return (cp);
5200 5530 }
5201 5531
5202 5532 static const mib2_sctpConnRemoteEntry_t *
5203 5533 sctp_getnext_rem(const mib_item_t **itemp,
5204 5534 const mib2_sctpConnRemoteEntry_t *current, uint32_t associd)
5205 5535 {
5206 5536 const mib_item_t *item = *itemp;
5207 5537 const mib2_sctpConnRemoteEntry_t *sre;
5208 5538
5209 5539 for (; item != NULL; item = item->next_item, current = NULL) {
5210 5540 if (!(item->group == MIB2_SCTP &&
5211 5541 item->mib_id == MIB2_SCTP_CONN_REMOTE)) {
5212 5542 continue;
5213 5543 }
5214 5544
5215 5545 if (current != NULL) {
5216 5546 /* LINTED: (note 1) */
5217 5547 sre = (const mib2_sctpConnRemoteEntry_t *)
5218 5548 ((const char *)current + sctpRemoteEntrySize);
5219 5549 } else {
5220 5550 sre = item->valp;
5221 5551 }
5222 5552 for (; (char *)sre < (char *)item->valp + item->length;
5223 5553 /* LINTED: (note 1) */
5224 5554 sre = (const mib2_sctpConnRemoteEntry_t *)
5225 5555 ((const char *)sre + sctpRemoteEntrySize)) {
5226 5556 if (sre->sctpAssocId != associd) {
5227 5557 continue;
5228 5558 }
5229 5559 *itemp = item;
5230 5560 return (sre);
5231 5561 }
5232 5562 }
5233 5563 *itemp = NULL;
5234 5564 return (NULL);
5235 5565 }
5236 5566
5237 5567 static const mib2_sctpConnLocalEntry_t *
5238 5568 sctp_getnext_local(const mib_item_t **itemp,
5239 5569 const mib2_sctpConnLocalEntry_t *current, uint32_t associd)
5240 5570 {
5241 5571 const mib_item_t *item = *itemp;
5242 5572 const mib2_sctpConnLocalEntry_t *sle;
5243 5573
5244 5574 for (; item != NULL; item = item->next_item, current = NULL) {
5245 5575 if (!(item->group == MIB2_SCTP &&
5246 5576 item->mib_id == MIB2_SCTP_CONN_LOCAL)) {
5247 5577 continue;
5248 5578 }
5249 5579
5250 5580 if (current != NULL) {
5251 5581 /* LINTED: (note 1) */
5252 5582 sle = (const mib2_sctpConnLocalEntry_t *)
5253 5583 ((const char *)current + sctpLocalEntrySize);
5254 5584 } else {
5255 5585 sle = item->valp;
5256 5586 }
5257 5587 for (; (char *)sle < (char *)item->valp + item->length;
5258 5588 /* LINTED: (note 1) */
5259 5589 sle = (const mib2_sctpConnLocalEntry_t *)
5260 5590 ((const char *)sle + sctpLocalEntrySize)) {
5261 5591 if (sle->sctpAssocId != associd) {
5262 5592 continue;
5263 5593 }
5264 5594 *itemp = item;
5265 5595 return (sle);
5266 5596 }
5267 5597 }
5268 5598 *itemp = NULL;
5269 5599 return (NULL);
5270 5600 }
5271 5601
5272 5602 static void
5273 5603 sctp_pr_addr(int type, char *name, int namelen, const in6_addr_t *addr,
5274 5604 int port)
5275 5605 {
5276 5606 ipaddr_t v4addr;
5277 5607 in6_addr_t v6addr;
5278 5608
5279 5609 /*
5280 5610 * Address is either a v4 mapped or v6 addr. If
5281 5611 * it's a v4 mapped, convert to v4 before
5282 5612 * displaying.
5283 5613 */
5284 5614 switch (type) {
5285 5615 case MIB2_SCTP_ADDR_V4:
5286 5616 /* v4 */
5287 5617 v6addr = *addr;
5288 5618
5289 5619 IN6_V4MAPPED_TO_IPADDR(&v6addr, v4addr);
5290 5620 if (port > 0) {
5291 5621 (void) pr_ap(v4addr, port, "sctp", name, namelen);
5292 5622 } else {
5293 5623 (void) pr_addr(v4addr, name, namelen);
5294 5624 }
5295 5625 break;
5296 5626
5297 5627 case MIB2_SCTP_ADDR_V6:
5298 5628 /* v6 */
5299 5629 if (port > 0) {
5300 5630 (void) pr_ap6(addr, port, "sctp", name, namelen);
5301 5631 } else {
↓ open down ↓ |
146 lines elided |
↑ open up ↑ |
5302 5632 (void) pr_addr6(addr, name, namelen);
5303 5633 }
5304 5634 break;
5305 5635
5306 5636 default:
5307 5637 (void) snprintf(name, namelen, "<unknown addr type>");
5308 5638 break;
5309 5639 }
5310 5640 }
5311 5641
5312 -static void
5313 -sctp_conn_report_item(const mib_item_t *head, const mib2_sctpConnEntry_t *sp,
5642 +static boolean_t
5643 +sctp_conn_report_item(const mib_item_t *head, conn_pid_node_list_hdr_t * cph,
5644 + boolean_t print_sctp_hdr, const mib2_sctpConnEntry_t *sp,
5314 5645 const mib2_transportMLPEntry_t *attr)
5315 5646 {
5316 5647 char lname[MAXHOSTNAMELEN + MAXHOSTNAMELEN + 1];
5317 5648 char fname[MAXHOSTNAMELEN + MAXHOSTNAMELEN + 1];
5318 5649 const mib2_sctpConnRemoteEntry_t *sre = NULL;
5319 5650 const mib2_sctpConnLocalEntry_t *sle = NULL;
5320 5651 const mib_item_t *local = head;
5321 5652 const mib_item_t *remote = head;
5322 5653 uint32_t id = sp->sctpAssocId;
5323 5654 boolean_t printfirst = B_TRUE;
5324 5655
5656 + if (print_sctp_hdr == B_TRUE) {
5657 + (void) puts(sctp_hdr);
5658 + if (Uflag)
5659 + (void) puts(Vflag? sctp_hdr_pid_verbose: sctp_hdr_pid);
5660 + else
5661 + (void) puts(sctp_hdr_normal);
5662 +
5663 + print_sctp_hdr = B_FALSE;
5664 + }
5665 +
5325 5666 sctp_pr_addr(sp->sctpAssocRemPrimAddrType, fname, sizeof (fname),
5326 5667 &sp->sctpAssocRemPrimAddr, sp->sctpAssocRemPort);
5327 5668 sctp_pr_addr(sp->sctpAssocRemPrimAddrType, lname, sizeof (lname),
5328 5669 &sp->sctpAssocLocPrimAddr, sp->sctpAssocLocalPort);
5329 5670
5330 - (void) printf("%-31s %-31s %6u %6d %6u %6d %3d/%-3d %s\n",
5331 - lname, fname,
5332 - sp->sctpConnEntryInfo.ce_swnd,
5333 - sp->sctpConnEntryInfo.ce_sendq,
5334 - sp->sctpConnEntryInfo.ce_rwnd,
5335 - sp->sctpConnEntryInfo.ce_recvq,
5336 - sp->sctpAssocInStreams, sp->sctpAssocOutStreams,
5337 - nssctp_state(sp->sctpAssocState, attr));
5671 + if (Uflag) {
5672 + int i = 0;
5673 + conn_pid_node_t *cpn = cph->cph_cpns;
5674 + proc_info_t *pinfo;
5675 +
5676 + do {
5677 + int pid = (cph->cph_pn_cnt)?cpn->cpn_pid:0;
5678 + pinfo = get_proc_info(cpn->cpn_pid);
5679 + (void) printf("%-31s %-31s %6u %6d %6u %6d %3d/%-3d %-8.8s %6u ",
5680 + lname, fname,
5681 + sp->sctpConnEntryInfo.ce_swnd,
5682 + sp->sctpConnEntryInfo.ce_sendq,
5683 + sp->sctpConnEntryInfo.ce_rwnd,
5684 + sp->sctpConnEntryInfo.ce_recvq,
5685 + sp->sctpAssocInStreams,
5686 + sp->sctpAssocOutStreams,
5687 + pinfo->pr_user, pid);
5688 +
5689 + if (Vflag) {
5690 + (void) printf("%-11.11s %s\n",
5691 + nssctp_state(sp->sctpAssocState, attr),
5692 + pinfo->pr_psargs);
5693 + } else {
5694 + (void) printf("%-14.14s %s\n",
5695 + pinfo->pr_fname,
5696 + nssctp_state(sp->sctpAssocState, attr));
5697 + }
5698 +
5699 + i++; cpn++;
5700 + } while (i < cph->cph_pn_cnt);
5701 +
5702 + } else {
5703 +
5704 + (void) printf("%-31s %-31s %6u %6d %6u %6d %3d/%-3d %s\n",
5705 + lname, fname,
5706 + sp->sctpConnEntryInfo.ce_swnd,
5707 + sp->sctpConnEntryInfo.ce_sendq,
5708 + sp->sctpConnEntryInfo.ce_rwnd,
5709 + sp->sctpConnEntryInfo.ce_recvq,
5710 + sp->sctpAssocInStreams, sp->sctpAssocOutStreams,
5711 + nssctp_state(sp->sctpAssocState, attr));
5712 + }
5338 5713
5339 5714 print_transport_label(attr);
5340 5715
5341 5716 if (!Vflag) {
5342 - return;
5717 + return (print_sctp_hdr);
5343 5718 }
5344 5719
5345 5720 /* Print remote addresses/local addresses on following lines */
5346 5721 while ((sre = sctp_getnext_rem(&remote, sre, id)) != NULL) {
5347 5722 if (!IN6_ARE_ADDR_EQUAL(&sre->sctpAssocRemAddr,
5348 5723 &sp->sctpAssocRemPrimAddr)) {
5349 5724 if (printfirst == B_TRUE) {
5350 5725 (void) fputs("\t<Remote: ", stdout);
5351 5726 printfirst = B_FALSE;
5352 5727 } else {
5353 5728 (void) fputs(", ", stdout);
5354 5729 }
5355 5730 sctp_pr_addr(sre->sctpAssocRemAddrType, fname,
5356 5731 sizeof (fname), &sre->sctpAssocRemAddr, -1);
5357 5732 if (sre->sctpAssocRemAddrActive == MIB2_SCTP_ACTIVE) {
5358 5733 (void) fputs(fname, stdout);
5359 5734 } else {
5360 5735 (void) printf("(%s)", fname);
5361 5736 }
5362 5737 }
5363 5738 }
5364 5739 if (printfirst == B_FALSE) {
5365 5740 (void) puts(">");
5366 5741 printfirst = B_TRUE;
5367 5742 }
5368 5743 while ((sle = sctp_getnext_local(&local, sle, id)) != NULL) {
5369 5744 if (!IN6_ARE_ADDR_EQUAL(&sle->sctpAssocLocalAddr,
5370 5745 &sp->sctpAssocLocPrimAddr)) {
5371 5746 if (printfirst == B_TRUE) {
5372 5747 (void) fputs("\t<Local: ", stdout);
5373 5748 printfirst = B_FALSE;
5374 5749 } else {
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
5375 5750 (void) fputs(", ", stdout);
5376 5751 }
5377 5752 sctp_pr_addr(sle->sctpAssocLocalAddrType, lname,
5378 5753 sizeof (lname), &sle->sctpAssocLocalAddr, -1);
5379 5754 (void) fputs(lname, stdout);
5380 5755 }
5381 5756 }
5382 5757 if (printfirst == B_FALSE) {
5383 5758 (void) puts(">");
5384 5759 }
5760 +
5761 + return (print_sctp_hdr);
5385 5762 }
5386 5763
5387 5764 static void
5388 5765 sctp_report(const mib_item_t *item)
5389 5766 {
5390 5767 const mib_item_t *head;
5391 5768 const mib2_sctpConnEntry_t *sp;
5392 - boolean_t first = B_TRUE;
5393 - mib2_transportMLPEntry_t **attrs, **aptr;
5394 - mib2_transportMLPEntry_t *attr;
5769 + boolean_t print_sctp_hdr_once = B_TRUE;
5770 + mib2_transportMLPEntry_t **attrs, **aptr;
5771 + mib2_transportMLPEntry_t *attr;
5772 + conn_pid_node_list_hdr_t *cph;
5395 5773
5396 5774 /*
5397 5775 * Preparation pass: the kernel returns separate entries for SCTP
5398 5776 * connection table entries and Multilevel Port attributes. We loop
5399 5777 * through the attributes first and set up an array for each address
5400 5778 * family.
5401 5779 */
5402 5780 attrs = RSECflag ?
5403 5781 gather_attrs(item, MIB2_SCTP, MIB2_SCTP_CONN, sctpEntrySize) :
5404 5782 NULL;
5405 5783
5406 5784 aptr = attrs;
5407 5785 head = item;
5408 5786 for (; item != NULL; item = item->next_item) {
5409 5787
5410 - if (!(item->group == MIB2_SCTP &&
5411 - item->mib_id == MIB2_SCTP_CONN))
5788 + if (!((item->group == MIB2_SCTP &&
5789 + item->mib_id == MIB2_SCTP_CONN) ||
5790 + (item->group == MIB2_SCTP &&
5791 + item->mib_id == EXPER_XPORT_PROC_INFO)))
5412 5792 continue;
5413 5793
5414 - for (sp = item->valp;
5415 - (char *)sp < (char *)item->valp + item->length;
5416 - /* LINTED: (note 1) */
5417 - sp = (mib2_sctpConnEntry_t *)((char *)sp + sctpEntrySize)) {
5418 - attr = aptr == NULL ? NULL : *aptr++;
5419 - if (Aflag ||
5420 - sp->sctpAssocState >= MIB2_SCTP_established) {
5421 - if (first == B_TRUE) {
5422 - (void) puts(sctp_hdr);
5423 - (void) puts(sctp_hdr_normal);
5424 - first = B_FALSE;
5425 - }
5426 - sctp_conn_report_item(head, sp, attr);
5794 + if ((!Uflag) && item->group == MIB2_SCTP
5795 + && item->mib_id == MIB2_SCTP_CONN) {
5796 + for (sp = item->valp;
5797 + (char *)sp < (char *)item->valp + item->length;
5798 + /* LINTED: (note 1) */
5799 + sp = (mib2_sctpConnEntry_t *)((char *)sp + sctpEntrySize)) {
5800 + if (!(Aflag ||
5801 + sp->sctpAssocState >= MIB2_SCTP_established))
5802 + continue;
5803 + attr = aptr == NULL ? NULL : *aptr++;
5804 + print_sctp_hdr_once = sctp_conn_report_item(head, NULL,
5805 + print_sctp_hdr_once, sp,
5806 + attr);
5807 + }
5808 + } else if ((Uflag) && item->group == MIB2_SCTP &&
5809 + item->mib_id == EXPER_XPORT_PROC_INFO) {
5810 + for (sp = (mib2_sctpConnEntry_t *)item->valp;
5811 + (char *)sp < (char *)item->valp + item->length;
5812 + /* LINTED: (note 1) */
5813 + sp = (mib2_sctpConnEntry_t *)((char *)cph +
5814 + cph->cph_tot_size)) {
5815 + /* LINTED: (note 1) */
5816 + cph = (conn_pid_node_list_hdr_t *)
5817 + ((char *)sp + sctpEntrySize);
5818 + if (!(Aflag ||
5819 + sp->sctpAssocState >= MIB2_SCTP_established))
5820 + continue;
5821 + attr = aptr == NULL ? NULL : *aptr++;
5822 + print_sctp_hdr_once =
5823 + sctp_conn_report_item(head, cph,
5824 + print_sctp_hdr_once, sp, attr);
5427 5825 }
5428 5826 }
5429 5827 }
5430 5828 if (attrs != NULL)
5431 5829 free(attrs);
5432 5830 }
5433 5831
5434 5832 static char *
5435 5833 plural(int n)
5436 5834 {
5437 5835 return (n != 1 ? "s" : "");
5438 5836 }
5439 5837
5440 5838 static char *
5441 5839 pluraly(int n)
5442 5840 {
5443 5841 return (n != 1 ? "ies" : "y");
5444 5842 }
5445 5843
5446 5844 static char *
5447 5845 plurales(int n)
5448 5846 {
5449 5847 return (n != 1 ? "es" : "");
5450 5848 }
5451 5849
5452 5850 static char *
5453 5851 pktscale(n)
5454 5852 int n;
5455 5853 {
5456 5854 static char buf[6];
5457 5855 char t;
5458 5856
5459 5857 if (n < 1024) {
5460 5858 t = ' ';
5461 5859 } else if (n < 1024 * 1024) {
5462 5860 t = 'k';
5463 5861 n /= 1024;
5464 5862 } else if (n < 1024 * 1024 * 1024) {
5465 5863 t = 'm';
5466 5864 n /= 1024 * 1024;
5467 5865 } else {
5468 5866 t = 'g';
5469 5867 n /= 1024 * 1024 * 1024;
5470 5868 }
5471 5869
5472 5870 (void) snprintf(buf, sizeof (buf), "%4u%c", n, t);
5473 5871 return (buf);
5474 5872 }
5475 5873
5476 5874 /* --------------------- mrt_report (netstat -m) -------------------------- */
5477 5875
5478 5876 static void
5479 5877 mrt_report(mib_item_t *item)
5480 5878 {
5481 5879 int jtemp = 0;
5482 5880 struct vifctl *vip;
5483 5881 vifi_t vifi;
5484 5882 struct mfcctl *mfccp;
5485 5883 int numvifs = 0;
5486 5884 int nmfc = 0;
5487 5885 char abuf[MAXHOSTNAMELEN + 1];
5488 5886
5489 5887 if (!(family_selected(AF_INET)))
5490 5888 return;
5491 5889
5492 5890 /* 'for' loop 1: */
5493 5891 for (; item; item = item->next_item) {
5494 5892 if (Xflag) {
5495 5893 (void) printf("\n--- Entry %d ---\n", ++jtemp);
5496 5894 (void) printf("Group = %d, mib_id = %d, "
5497 5895 "length = %d, valp = 0x%p\n",
5498 5896 item->group, item->mib_id, item->length,
5499 5897 item->valp);
5500 5898 }
5501 5899 if (item->group != EXPER_DVMRP)
5502 5900 continue; /* 'for' loop 1 */
5503 5901
5504 5902 switch (item->mib_id) {
5505 5903
5506 5904 case EXPER_DVMRP_VIF:
5507 5905 if (Xflag)
5508 5906 (void) printf("%u records for ipVifTable:\n",
5509 5907 item->length/sizeof (struct vifctl));
5510 5908 if (item->length/sizeof (struct vifctl) == 0) {
5511 5909 (void) puts("\nVirtual Interface Table is "
5512 5910 "empty");
5513 5911 break;
5514 5912 }
5515 5913
5516 5914 (void) puts("\nVirtual Interface Table\n"
5517 5915 " Vif Threshold Rate_Limit Local-Address"
5518 5916 " Remote-Address Pkt_in Pkt_out");
5519 5917
5520 5918 /* 'for' loop 2: */
5521 5919 for (vip = (struct vifctl *)item->valp;
5522 5920 (char *)vip < (char *)item->valp + item->length;
5523 5921 /* LINTED: (note 1) */
5524 5922 vip = (struct vifctl *)((char *)vip +
5525 5923 vifctlSize)) {
5526 5924 if (vip->vifc_lcl_addr.s_addr == 0)
5527 5925 continue; /* 'for' loop 2 */
5528 5926 /* numvifs = vip->vifc_vifi; */
5529 5927
5530 5928 numvifs++;
5531 5929 (void) printf(" %2u %3u "
5532 5930 "%4u %-15.15s",
5533 5931 vip->vifc_vifi,
5534 5932 vip->vifc_threshold,
5535 5933 vip->vifc_rate_limit,
5536 5934 pr_addr(vip->vifc_lcl_addr.s_addr,
5537 5935 abuf, sizeof (abuf)));
5538 5936 (void) printf(" %-15.15s %8u %8u\n",
5539 5937 (vip->vifc_flags & VIFF_TUNNEL) ?
5540 5938 pr_addr(vip->vifc_rmt_addr.s_addr,
5541 5939 abuf, sizeof (abuf)) : "",
5542 5940 vip->vifc_pkt_in,
5543 5941 vip->vifc_pkt_out);
5544 5942 } /* 'for' loop 2 ends */
5545 5943
5546 5944 (void) printf("Numvifs: %d\n", numvifs);
5547 5945 break;
5548 5946
5549 5947 case EXPER_DVMRP_MRT:
5550 5948 if (Xflag)
5551 5949 (void) printf("%u records for ipMfcTable:\n",
5552 5950 item->length/sizeof (struct vifctl));
5553 5951 if (item->length/sizeof (struct vifctl) == 0) {
5554 5952 (void) puts("\nMulticast Forwarding Cache is "
5555 5953 "empty");
5556 5954 break;
5557 5955 }
5558 5956
5559 5957 (void) puts("\nMulticast Forwarding Cache\n"
5560 5958 " Origin-Subnet Mcastgroup "
5561 5959 "# Pkts In-Vif Out-vifs/Forw-ttl");
5562 5960
5563 5961 for (mfccp = (struct mfcctl *)item->valp;
5564 5962 (char *)mfccp < (char *)item->valp + item->length;
5565 5963 /* LINTED: (note 1) */
5566 5964 mfccp = (struct mfcctl *)((char *)mfccp +
5567 5965 mfcctlSize)) {
5568 5966
5569 5967 nmfc++;
5570 5968 (void) printf(" %-30.15s",
5571 5969 pr_addr(mfccp->mfcc_origin.s_addr,
5572 5970 abuf, sizeof (abuf)));
5573 5971 (void) printf("%-15.15s %6s %3u ",
5574 5972 pr_net(mfccp->mfcc_mcastgrp.s_addr,
5575 5973 mfccp->mfcc_mcastgrp.s_addr,
5576 5974 abuf, sizeof (abuf)),
5577 5975 pktscale((int)mfccp->mfcc_pkt_cnt),
5578 5976 mfccp->mfcc_parent);
5579 5977
5580 5978 for (vifi = 0; vifi < MAXVIFS; ++vifi) {
5581 5979 if (mfccp->mfcc_ttls[vifi]) {
5582 5980 (void) printf(" %u (%u)",
5583 5981 vifi,
5584 5982 mfccp->mfcc_ttls[vifi]);
5585 5983 }
5586 5984
5587 5985 }
5588 5986 (void) putchar('\n');
5589 5987 }
5590 5988 (void) printf("\nTotal no. of entries in cache: %d\n",
5591 5989 nmfc);
5592 5990 break;
5593 5991 }
5594 5992 } /* 'for' loop 1 ends */
5595 5993 (void) putchar('\n');
5596 5994 (void) fflush(stdout);
5597 5995 }
5598 5996
5599 5997 /*
5600 5998 * Get the stats for the cache named 'name'. If prefix != 0, then
5601 5999 * interpret the name as a prefix, and sum up stats for all caches
5602 6000 * named 'name*'.
5603 6001 */
5604 6002 static void
5605 6003 kmem_cache_stats(char *title, char *name, int prefix, int64_t *total_bytes)
5606 6004 {
5607 6005 int len;
5608 6006 int alloc;
5609 6007 int64_t total_alloc = 0;
5610 6008 int alloc_fail, total_alloc_fail = 0;
5611 6009 int buf_size = 0;
5612 6010 int buf_avail;
5613 6011 int buf_total;
5614 6012 int buf_max, total_buf_max = 0;
5615 6013 int buf_inuse, total_buf_inuse = 0;
5616 6014 kstat_t *ksp;
5617 6015 char buf[256];
5618 6016
5619 6017 len = prefix ? strlen(name) : 256;
5620 6018
5621 6019 /* 'for' loop 1: */
5622 6020 for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
5623 6021
5624 6022 if (strcmp(ksp->ks_class, "kmem_cache") != 0)
5625 6023 continue; /* 'for' loop 1 */
5626 6024
5627 6025 /*
5628 6026 * Hack alert: because of the way streams messages are
5629 6027 * allocated, every constructed free dblk has an associated
5630 6028 * mblk. From the allocator's viewpoint those mblks are
5631 6029 * allocated (because they haven't been freed), but from
5632 6030 * our viewpoint they're actually free (because they're
5633 6031 * not currently in use). To account for this caching
5634 6032 * effect we subtract the total constructed free dblks
5635 6033 * from the total allocated mblks to derive mblks in use.
5636 6034 */
5637 6035 if (strcmp(name, "streams_mblk") == 0 &&
5638 6036 strncmp(ksp->ks_name, "streams_dblk", 12) == 0) {
5639 6037 (void) safe_kstat_read(kc, ksp, NULL);
5640 6038 total_buf_inuse -=
5641 6039 kstat_named_value(ksp, "buf_constructed");
5642 6040 continue; /* 'for' loop 1 */
5643 6041 }
5644 6042
5645 6043 if (strncmp(ksp->ks_name, name, len) != 0)
5646 6044 continue; /* 'for' loop 1 */
5647 6045
5648 6046 (void) safe_kstat_read(kc, ksp, NULL);
5649 6047
5650 6048 alloc = kstat_named_value(ksp, "alloc");
5651 6049 alloc_fail = kstat_named_value(ksp, "alloc_fail");
5652 6050 buf_size = kstat_named_value(ksp, "buf_size");
5653 6051 buf_avail = kstat_named_value(ksp, "buf_avail");
5654 6052 buf_total = kstat_named_value(ksp, "buf_total");
5655 6053 buf_max = kstat_named_value(ksp, "buf_max");
5656 6054 buf_inuse = buf_total - buf_avail;
5657 6055
5658 6056 if (Vflag && prefix) {
5659 6057 (void) snprintf(buf, sizeof (buf), "%s%s", title,
5660 6058 ksp->ks_name + len);
5661 6059 (void) printf(" %-18s %6u %9u %11u %11u\n",
5662 6060 buf, buf_inuse, buf_max, alloc, alloc_fail);
5663 6061 }
5664 6062
5665 6063 total_alloc += alloc;
5666 6064 total_alloc_fail += alloc_fail;
5667 6065 total_buf_max += buf_max;
5668 6066 total_buf_inuse += buf_inuse;
5669 6067 *total_bytes += (int64_t)buf_inuse * buf_size;
5670 6068 } /* 'for' loop 1 ends */
5671 6069
5672 6070 if (buf_size == 0) {
5673 6071 (void) printf("%-22s [couldn't find statistics for %s]\n",
5674 6072 title, name);
5675 6073 return;
5676 6074 }
5677 6075
5678 6076 if (Vflag && prefix)
5679 6077 (void) snprintf(buf, sizeof (buf), "%s_total", title);
5680 6078 else
5681 6079 (void) snprintf(buf, sizeof (buf), "%s", title);
5682 6080
5683 6081 (void) printf("%-22s %6d %9d %11lld %11d\n", buf,
5684 6082 total_buf_inuse, total_buf_max, total_alloc, total_alloc_fail);
5685 6083 }
5686 6084
5687 6085 static void
5688 6086 m_report(void)
5689 6087 {
5690 6088 int64_t total_bytes = 0;
5691 6089
5692 6090 (void) puts("streams allocation:");
5693 6091 (void) printf("%63s\n", "cumulative allocation");
5694 6092 (void) printf("%63s\n",
5695 6093 "current maximum total failures");
5696 6094
5697 6095 kmem_cache_stats("streams",
5698 6096 "stream_head_cache", 0, &total_bytes);
5699 6097 kmem_cache_stats("queues", "queue_cache", 0, &total_bytes);
5700 6098 kmem_cache_stats("mblk", "streams_mblk", 0, &total_bytes);
5701 6099 kmem_cache_stats("dblk", "streams_dblk", 1, &total_bytes);
5702 6100 kmem_cache_stats("linkblk", "linkinfo_cache", 0, &total_bytes);
5703 6101 kmem_cache_stats("syncq", "syncq_cache", 0, &total_bytes);
5704 6102 kmem_cache_stats("qband", "qband_cache", 0, &total_bytes);
5705 6103
5706 6104 (void) printf("\n%lld Kbytes allocated for streams data\n",
5707 6105 total_bytes / 1024);
5708 6106
5709 6107 (void) putchar('\n');
5710 6108 (void) fflush(stdout);
5711 6109 }
5712 6110
5713 6111 /* --------------------------------- */
5714 6112
5715 6113 /*
5716 6114 * Print an IPv4 address. Remove the matching part of the domain name
5717 6115 * from the returned name.
5718 6116 */
5719 6117 static char *
5720 6118 pr_addr(uint_t addr, char *dst, uint_t dstlen)
5721 6119 {
5722 6120 char *cp;
5723 6121 struct hostent *hp = NULL;
5724 6122 static char domain[MAXHOSTNAMELEN + 1];
5725 6123 static boolean_t first = B_TRUE;
5726 6124 int error_num;
5727 6125
5728 6126 if (first) {
5729 6127 first = B_FALSE;
5730 6128 if (sysinfo(SI_HOSTNAME, domain, MAXHOSTNAMELEN) != -1 &&
5731 6129 (cp = strchr(domain, '.'))) {
5732 6130 (void) strncpy(domain, cp + 1, sizeof (domain));
5733 6131 } else
5734 6132 domain[0] = 0;
5735 6133 }
5736 6134 cp = NULL;
5737 6135 if (!Nflag) {
5738 6136 hp = getipnodebyaddr((char *)&addr, sizeof (uint_t), AF_INET,
5739 6137 &error_num);
5740 6138 if (hp) {
5741 6139 if ((cp = strchr(hp->h_name, '.')) != NULL &&
5742 6140 strcasecmp(cp + 1, domain) == 0)
5743 6141 *cp = 0;
5744 6142 cp = hp->h_name;
5745 6143 }
5746 6144 }
5747 6145 if (cp != NULL) {
5748 6146 (void) strncpy(dst, cp, dstlen);
5749 6147 dst[dstlen - 1] = 0;
5750 6148 } else {
5751 6149 (void) inet_ntop(AF_INET, (char *)&addr, dst, dstlen);
5752 6150 }
5753 6151 if (hp != NULL)
5754 6152 freehostent(hp);
5755 6153 return (dst);
5756 6154 }
5757 6155
5758 6156 /*
5759 6157 * Print a non-zero IPv4 address. Print " --" if the address is zero.
5760 6158 */
5761 6159 static char *
5762 6160 pr_addrnz(ipaddr_t addr, char *dst, uint_t dstlen)
5763 6161 {
5764 6162 if (addr == INADDR_ANY) {
5765 6163 (void) strlcpy(dst, " --", dstlen);
5766 6164 return (dst);
5767 6165 }
5768 6166 return (pr_addr(addr, dst, dstlen));
5769 6167 }
5770 6168
5771 6169 /*
5772 6170 * Print an IPv6 address. Remove the matching part of the domain name
5773 6171 * from the returned name.
5774 6172 */
5775 6173 static char *
5776 6174 pr_addr6(const struct in6_addr *addr, char *dst, uint_t dstlen)
5777 6175 {
5778 6176 char *cp;
5779 6177 struct hostent *hp = NULL;
5780 6178 static char domain[MAXHOSTNAMELEN + 1];
5781 6179 static boolean_t first = B_TRUE;
5782 6180 int error_num;
5783 6181
5784 6182 if (first) {
5785 6183 first = B_FALSE;
5786 6184 if (sysinfo(SI_HOSTNAME, domain, MAXHOSTNAMELEN) != -1 &&
5787 6185 (cp = strchr(domain, '.'))) {
5788 6186 (void) strncpy(domain, cp + 1, sizeof (domain));
5789 6187 } else
5790 6188 domain[0] = 0;
5791 6189 }
5792 6190 cp = NULL;
5793 6191 if (!Nflag) {
5794 6192 hp = getipnodebyaddr((char *)addr,
5795 6193 sizeof (struct in6_addr), AF_INET6, &error_num);
5796 6194 if (hp) {
5797 6195 if ((cp = strchr(hp->h_name, '.')) != NULL &&
5798 6196 strcasecmp(cp + 1, domain) == 0)
5799 6197 *cp = 0;
5800 6198 cp = hp->h_name;
5801 6199 }
5802 6200 }
5803 6201 if (cp != NULL) {
5804 6202 (void) strncpy(dst, cp, dstlen);
5805 6203 dst[dstlen - 1] = 0;
5806 6204 } else {
5807 6205 (void) inet_ntop(AF_INET6, (void *)addr, dst, dstlen);
5808 6206 }
5809 6207 if (hp != NULL)
5810 6208 freehostent(hp);
5811 6209 return (dst);
5812 6210 }
5813 6211
5814 6212 /* For IPv4 masks */
5815 6213 static char *
5816 6214 pr_mask(uint_t addr, char *dst, uint_t dstlen)
5817 6215 {
5818 6216 uint8_t *ip_addr = (uint8_t *)&addr;
5819 6217
5820 6218 (void) snprintf(dst, dstlen, "%d.%d.%d.%d",
5821 6219 ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);
5822 6220 return (dst);
5823 6221 }
5824 6222
5825 6223 /*
5826 6224 * For ipv6 masks format is : dest/mask
5827 6225 * Does not print /128 to save space in printout. H flag carries this notion.
5828 6226 */
5829 6227 static char *
5830 6228 pr_prefix6(const struct in6_addr *addr, uint_t prefixlen, char *dst,
5831 6229 uint_t dstlen)
5832 6230 {
5833 6231 char *cp;
5834 6232
5835 6233 if (IN6_IS_ADDR_UNSPECIFIED(addr) && prefixlen == 0) {
5836 6234 (void) strncpy(dst, "default", dstlen);
5837 6235 dst[dstlen - 1] = 0;
5838 6236 return (dst);
5839 6237 }
5840 6238
5841 6239 (void) pr_addr6(addr, dst, dstlen);
5842 6240 if (prefixlen != IPV6_ABITS) {
5843 6241 /* How much room is left? */
5844 6242 cp = strchr(dst, '\0');
5845 6243 if (dst + dstlen > cp) {
5846 6244 dstlen -= (cp - dst);
5847 6245 (void) snprintf(cp, dstlen, "/%d", prefixlen);
5848 6246 }
5849 6247 }
5850 6248 return (dst);
5851 6249 }
5852 6250
5853 6251 /* Print IPv4 address and port */
5854 6252 static char *
5855 6253 pr_ap(uint_t addr, uint_t port, char *proto,
5856 6254 char *dst, uint_t dstlen)
5857 6255 {
5858 6256 char *cp;
5859 6257
5860 6258 if (addr == INADDR_ANY) {
5861 6259 (void) strncpy(dst, " *", dstlen);
5862 6260 dst[dstlen - 1] = 0;
5863 6261 } else {
5864 6262 (void) pr_addr(addr, dst, dstlen);
5865 6263 }
5866 6264 /* How much room is left? */
5867 6265 cp = strchr(dst, '\0');
5868 6266 if (dst + dstlen > cp + 1) {
5869 6267 *cp++ = '.';
5870 6268 dstlen -= (cp - dst);
5871 6269 dstlen--;
5872 6270 (void) portname(port, proto, cp, dstlen);
5873 6271 }
5874 6272 return (dst);
5875 6273 }
5876 6274
5877 6275 /* Print IPv6 address and port */
5878 6276 static char *
5879 6277 pr_ap6(const in6_addr_t *addr, uint_t port, char *proto,
5880 6278 char *dst, uint_t dstlen)
5881 6279 {
5882 6280 char *cp;
5883 6281
5884 6282 if (IN6_IS_ADDR_UNSPECIFIED(addr)) {
5885 6283 (void) strncpy(dst, " *", dstlen);
5886 6284 dst[dstlen - 1] = 0;
5887 6285 } else {
5888 6286 (void) pr_addr6(addr, dst, dstlen);
5889 6287 }
5890 6288 /* How much room is left? */
5891 6289 cp = strchr(dst, '\0');
5892 6290 if (dst + dstlen + 1 > cp) {
5893 6291 *cp++ = '.';
5894 6292 dstlen -= (cp - dst);
5895 6293 dstlen--;
5896 6294 (void) portname(port, proto, cp, dstlen);
5897 6295 }
5898 6296 return (dst);
5899 6297 }
5900 6298
5901 6299 /*
5902 6300 * Return the name of the network whose address is given. The address is
5903 6301 * assumed to be that of a net or subnet, not a host.
5904 6302 */
5905 6303 static char *
5906 6304 pr_net(uint_t addr, uint_t mask, char *dst, uint_t dstlen)
5907 6305 {
5908 6306 char *cp = NULL;
5909 6307 struct netent *np = NULL;
5910 6308 struct hostent *hp = NULL;
5911 6309 uint_t net;
5912 6310 int subnetshift;
5913 6311 int error_num;
5914 6312
5915 6313 if (addr == INADDR_ANY && mask == INADDR_ANY) {
5916 6314 (void) strncpy(dst, "default", dstlen);
5917 6315 dst[dstlen - 1] = 0;
5918 6316 return (dst);
5919 6317 }
5920 6318
5921 6319 if (!Nflag && addr) {
5922 6320 if (mask == 0) {
5923 6321 if (IN_CLASSA(addr)) {
5924 6322 mask = (uint_t)IN_CLASSA_NET;
5925 6323 subnetshift = 8;
5926 6324 } else if (IN_CLASSB(addr)) {
5927 6325 mask = (uint_t)IN_CLASSB_NET;
5928 6326 subnetshift = 8;
5929 6327 } else {
5930 6328 mask = (uint_t)IN_CLASSC_NET;
5931 6329 subnetshift = 4;
5932 6330 }
5933 6331 /*
5934 6332 * If there are more bits than the standard mask
5935 6333 * would suggest, subnets must be in use. Guess at
5936 6334 * the subnet mask, assuming reasonable width subnet
5937 6335 * fields.
5938 6336 */
5939 6337 while (addr & ~mask)
5940 6338 /* compiler doesn't sign extend! */
5941 6339 mask = (mask | ((int)mask >> subnetshift));
5942 6340 }
5943 6341 net = addr & mask;
5944 6342 while ((mask & 1) == 0)
5945 6343 mask >>= 1, net >>= 1;
5946 6344 np = getnetbyaddr(net, AF_INET);
5947 6345 if (np && np->n_net == net)
5948 6346 cp = np->n_name;
5949 6347 else {
5950 6348 /*
5951 6349 * Look for subnets in hosts map.
5952 6350 */
5953 6351 hp = getipnodebyaddr((char *)&addr, sizeof (uint_t),
5954 6352 AF_INET, &error_num);
5955 6353 if (hp)
5956 6354 cp = hp->h_name;
5957 6355 }
5958 6356 }
5959 6357 if (cp != NULL) {
5960 6358 (void) strncpy(dst, cp, dstlen);
5961 6359 dst[dstlen - 1] = 0;
5962 6360 } else {
5963 6361 (void) inet_ntop(AF_INET, (char *)&addr, dst, dstlen);
5964 6362 }
5965 6363 if (hp != NULL)
5966 6364 freehostent(hp);
5967 6365 return (dst);
5968 6366 }
5969 6367
5970 6368 /*
5971 6369 * Return the name of the network whose address is given.
5972 6370 * The address is assumed to be a host address.
5973 6371 */
5974 6372 static char *
5975 6373 pr_netaddr(uint_t addr, uint_t mask, char *dst, uint_t dstlen)
5976 6374 {
5977 6375 char *cp = NULL;
5978 6376 struct netent *np = NULL;
5979 6377 struct hostent *hp = NULL;
5980 6378 uint_t net;
5981 6379 uint_t netshifted;
5982 6380 int subnetshift;
5983 6381 struct in_addr in;
5984 6382 int error_num;
5985 6383 uint_t nbo_addr = addr; /* network byte order */
5986 6384
5987 6385 addr = ntohl(addr);
5988 6386 mask = ntohl(mask);
5989 6387 if (addr == INADDR_ANY && mask == INADDR_ANY) {
5990 6388 (void) strncpy(dst, "default", dstlen);
5991 6389 dst[dstlen - 1] = 0;
5992 6390 return (dst);
5993 6391 }
5994 6392
5995 6393 /* Figure out network portion of address (with host portion = 0) */
5996 6394 if (addr) {
5997 6395 /* Try figuring out mask if unknown (all 0s). */
5998 6396 if (mask == 0) {
5999 6397 if (IN_CLASSA(addr)) {
6000 6398 mask = (uint_t)IN_CLASSA_NET;
6001 6399 subnetshift = 8;
6002 6400 } else if (IN_CLASSB(addr)) {
6003 6401 mask = (uint_t)IN_CLASSB_NET;
6004 6402 subnetshift = 8;
6005 6403 } else {
6006 6404 mask = (uint_t)IN_CLASSC_NET;
6007 6405 subnetshift = 4;
6008 6406 }
6009 6407 /*
6010 6408 * If there are more bits than the standard mask
6011 6409 * would suggest, subnets must be in use. Guess at
6012 6410 * the subnet mask, assuming reasonable width subnet
6013 6411 * fields.
6014 6412 */
6015 6413 while (addr & ~mask)
6016 6414 /* compiler doesn't sign extend! */
6017 6415 mask = (mask | ((int)mask >> subnetshift));
6018 6416 }
6019 6417 net = netshifted = addr & mask;
6020 6418 while ((mask & 1) == 0)
6021 6419 mask >>= 1, netshifted >>= 1;
6022 6420 }
6023 6421 else
6024 6422 net = netshifted = 0;
6025 6423
6026 6424 /* Try looking up name unless -n was specified. */
6027 6425 if (!Nflag) {
6028 6426 np = getnetbyaddr(netshifted, AF_INET);
6029 6427 if (np && np->n_net == netshifted)
6030 6428 cp = np->n_name;
6031 6429 else {
6032 6430 /*
6033 6431 * Look for subnets in hosts map.
6034 6432 */
6035 6433 hp = getipnodebyaddr((char *)&nbo_addr, sizeof (uint_t),
6036 6434 AF_INET, &error_num);
6037 6435 if (hp)
6038 6436 cp = hp->h_name;
6039 6437 }
6040 6438
6041 6439 if (cp != NULL) {
6042 6440 (void) strncpy(dst, cp, dstlen);
6043 6441 dst[dstlen - 1] = 0;
6044 6442 if (hp != NULL)
6045 6443 freehostent(hp);
6046 6444 return (dst);
6047 6445 }
6048 6446 /*
6049 6447 * No name found for net: fallthru and return in decimal
6050 6448 * dot notation.
6051 6449 */
6052 6450 }
6053 6451
6054 6452 in.s_addr = htonl(net);
6055 6453 (void) inet_ntop(AF_INET, (char *)&in, dst, dstlen);
6056 6454 if (hp != NULL)
6057 6455 freehostent(hp);
6058 6456 return (dst);
6059 6457 }
6060 6458
6061 6459 /*
6062 6460 * Return the filter mode as a string:
6063 6461 * 1 => "INCLUDE"
6064 6462 * 2 => "EXCLUDE"
6065 6463 * otherwise "<unknown>"
6066 6464 */
6067 6465 static char *
6068 6466 fmodestr(uint_t fmode)
6069 6467 {
6070 6468 switch (fmode) {
6071 6469 case 1:
6072 6470 return ("INCLUDE");
6073 6471 case 2:
6074 6472 return ("EXCLUDE");
6075 6473 default:
6076 6474 return ("<unknown>");
6077 6475 }
6078 6476 }
6079 6477
6080 6478 #define MAX_STRING_SIZE 256
6081 6479
6082 6480 static const char *
6083 6481 pr_secattr(const sec_attr_list_t *attrs)
6084 6482 {
6085 6483 int i;
6086 6484 char buf[MAX_STRING_SIZE + 1], *cp;
6087 6485 static char *sbuf;
6088 6486 static size_t sbuf_len;
6089 6487 struct rtsa_s rtsa;
6090 6488 const sec_attr_list_t *aptr;
6091 6489
6092 6490 if (!RSECflag || attrs == NULL)
6093 6491 return ("");
6094 6492
6095 6493 for (aptr = attrs, i = 1; aptr != NULL; aptr = aptr->sal_next)
6096 6494 i += MAX_STRING_SIZE;
6097 6495 if (i > sbuf_len) {
6098 6496 cp = realloc(sbuf, i);
6099 6497 if (cp == NULL) {
6100 6498 perror("realloc security attribute buffer");
6101 6499 return ("");
6102 6500 }
6103 6501 sbuf_len = i;
6104 6502 sbuf = cp;
6105 6503 }
6106 6504
6107 6505 cp = sbuf;
6108 6506 while (attrs != NULL) {
6109 6507 const mib2_ipAttributeEntry_t *iae = attrs->sal_attr;
6110 6508
6111 6509 /* note: effectively hard-coded in rtsa_keyword */
6112 6510 rtsa.rtsa_mask = RTSA_CIPSO | RTSA_SLRANGE | RTSA_DOI;
6113 6511 rtsa.rtsa_slrange = iae->iae_slrange;
6114 6512 rtsa.rtsa_doi = iae->iae_doi;
6115 6513
6116 6514 (void) snprintf(cp, MAX_STRING_SIZE,
6117 6515 "<%s>%s ", rtsa_to_str(&rtsa, buf, sizeof (buf)),
6118 6516 attrs->sal_next == NULL ? "" : ",");
6119 6517 cp += strlen(cp);
6120 6518 attrs = attrs->sal_next;
6121 6519 }
6122 6520 *cp = '\0';
6123 6521
6124 6522 return (sbuf);
6125 6523 }
6126 6524
6127 6525 /*
6128 6526 * Pretty print a port number. If the Nflag was
6129 6527 * specified, use numbers instead of names.
6130 6528 */
6131 6529 static char *
6132 6530 portname(uint_t port, char *proto, char *dst, uint_t dstlen)
6133 6531 {
6134 6532 struct servent *sp = NULL;
6135 6533
6136 6534 if (!Nflag && port)
6137 6535 sp = getservbyport(htons(port), proto);
6138 6536 if (sp || port == 0)
6139 6537 (void) snprintf(dst, dstlen, "%.*s", MAXHOSTNAMELEN,
6140 6538 sp ? sp->s_name : "*");
6141 6539 else
6142 6540 (void) snprintf(dst, dstlen, "%d", port);
6143 6541 dst[dstlen - 1] = 0;
6144 6542 return (dst);
6145 6543 }
6146 6544
6147 6545 /*PRINTFLIKE2*/
6148 6546 void
6149 6547 fail(int do_perror, char *message, ...)
6150 6548 {
6151 6549 va_list args;
6152 6550
6153 6551 va_start(args, message);
6154 6552 (void) fputs("netstat: ", stderr);
6155 6553 (void) vfprintf(stderr, message, args);
6156 6554 va_end(args);
6157 6555 if (do_perror)
6158 6556 (void) fprintf(stderr, ": %s", strerror(errno));
6159 6557 (void) fputc('\n', stderr);
6160 6558 exit(2);
6161 6559 }
6162 6560
6163 6561 /*
6164 6562 * Return value of named statistic for given kstat_named kstat;
6165 6563 * return 0LL if named statistic is not in list (use "ll" as a
6166 6564 * type qualifier when printing 64-bit int's with printf() )
6167 6565 */
6168 6566 static uint64_t
6169 6567 kstat_named_value(kstat_t *ksp, char *name)
6170 6568 {
6171 6569 kstat_named_t *knp;
6172 6570 uint64_t value;
6173 6571
6174 6572 if (ksp == NULL)
6175 6573 return (0LL);
6176 6574
6177 6575 knp = kstat_data_lookup(ksp, name);
6178 6576 if (knp == NULL)
6179 6577 return (0LL);
6180 6578
6181 6579 switch (knp->data_type) {
6182 6580 case KSTAT_DATA_INT32:
6183 6581 case KSTAT_DATA_UINT32:
6184 6582 value = (uint64_t)(knp->value.ui32);
6185 6583 break;
6186 6584 case KSTAT_DATA_INT64:
6187 6585 case KSTAT_DATA_UINT64:
6188 6586 value = knp->value.ui64;
6189 6587 break;
6190 6588 default:
6191 6589 value = 0LL;
6192 6590 break;
6193 6591 }
6194 6592
6195 6593 return (value);
6196 6594 }
6197 6595
6198 6596 kid_t
6199 6597 safe_kstat_read(kstat_ctl_t *kc, kstat_t *ksp, void *data)
6200 6598 {
6201 6599 kid_t kstat_chain_id = kstat_read(kc, ksp, data);
6202 6600
6203 6601 if (kstat_chain_id == -1)
6204 6602 fail(1, "kstat_read(%p, '%s') failed", (void *)kc,
6205 6603 ksp->ks_name);
6206 6604 return (kstat_chain_id);
6207 6605 }
6208 6606
6209 6607 /*
6210 6608 * Parse a list of IRE flag characters into a bit field.
6211 6609 */
6212 6610 static uint_t
6213 6611 flag_bits(const char *arg)
6214 6612 {
6215 6613 const char *cp;
6216 6614 uint_t val;
6217 6615
6218 6616 if (*arg == '\0')
6219 6617 fatal(1, "missing flag list\n");
6220 6618
6221 6619 val = 0;
6222 6620 while (*arg != '\0') {
6223 6621 if ((cp = strchr(flag_list, *arg)) == NULL)
6224 6622 fatal(1, "%c: illegal flag\n", *arg);
6225 6623 val |= 1 << (cp - flag_list);
6226 6624 arg++;
6227 6625 }
6228 6626 return (val);
6229 6627 }
6230 6628
6231 6629 /*
6232 6630 * Handle -f argument. Validate input format, sort by keyword, and
6233 6631 * save off digested results.
6234 6632 */
6235 6633 static void
6236 6634 process_filter(char *arg)
6237 6635 {
6238 6636 int idx;
6239 6637 int klen = 0;
6240 6638 char *cp, *cp2;
6241 6639 int val;
6242 6640 filter_t *newf;
6243 6641 struct hostent *hp;
6244 6642 int error_num;
6245 6643 uint8_t *ucp;
6246 6644 int maxv;
6247 6645
6248 6646 /* Look up the keyword first */
6249 6647 if (strchr(arg, ':') == NULL) {
6250 6648 idx = FK_AF;
6251 6649 } else {
6252 6650 for (idx = 0; idx < NFILTERKEYS; idx++) {
6253 6651 klen = strlen(filter_keys[idx]);
6254 6652 if (strncmp(filter_keys[idx], arg, klen) == 0 &&
6255 6653 arg[klen] == ':')
6256 6654 break;
6257 6655 }
6258 6656 if (idx >= NFILTERKEYS)
6259 6657 fatal(1, "%s: unknown filter keyword\n", arg);
6260 6658
6261 6659 /* Advance past keyword and separator. */
6262 6660 arg += klen + 1;
6263 6661 }
6264 6662
6265 6663 if ((newf = malloc(sizeof (*newf))) == NULL) {
6266 6664 perror("filter");
6267 6665 exit(1);
6268 6666 }
6269 6667 switch (idx) {
6270 6668 case FK_AF:
6271 6669 if (strcmp(arg, "inet") == 0) {
6272 6670 newf->u.f_family = AF_INET;
6273 6671 } else if (strcmp(arg, "inet6") == 0) {
6274 6672 newf->u.f_family = AF_INET6;
6275 6673 } else if (strcmp(arg, "unix") == 0) {
6276 6674 newf->u.f_family = AF_UNIX;
6277 6675 } else {
6278 6676 newf->u.f_family = strtol(arg, &cp, 0);
6279 6677 if (arg == cp || *cp != '\0')
6280 6678 fatal(1, "%s: unknown address family.\n", arg);
6281 6679 }
6282 6680 break;
6283 6681
6284 6682 case FK_OUTIF:
6285 6683 if (strcmp(arg, "none") == 0) {
6286 6684 newf->u.f_ifname = NULL;
6287 6685 break;
6288 6686 }
6289 6687 if (strcmp(arg, "any") == 0) {
6290 6688 newf->u.f_ifname = "";
6291 6689 break;
6292 6690 }
6293 6691 val = strtol(arg, &cp, 0);
6294 6692 if (val <= 0 || arg == cp || cp[0] != '\0') {
6295 6693 if ((val = if_nametoindex(arg)) == 0) {
6296 6694 perror(arg);
6297 6695 exit(1);
6298 6696 }
6299 6697 }
6300 6698 newf->u.f_ifname = arg;
6301 6699 break;
6302 6700
6303 6701 case FK_DST:
6304 6702 V4MASK_TO_V6(IP_HOST_MASK, newf->u.a.f_mask);
6305 6703 if (strcmp(arg, "any") == 0) {
6306 6704 /* Special semantics; any address *but* zero */
6307 6705 newf->u.a.f_address = NULL;
6308 6706 (void) memset(&newf->u.a.f_mask, 0,
6309 6707 sizeof (newf->u.a.f_mask));
6310 6708 break;
6311 6709 }
6312 6710 if (strcmp(arg, "none") == 0) {
6313 6711 newf->u.a.f_address = NULL;
6314 6712 break;
6315 6713 }
6316 6714 if ((cp = strrchr(arg, '/')) != NULL)
6317 6715 *cp++ = '\0';
6318 6716 hp = getipnodebyname(arg, AF_INET6, AI_V4MAPPED|AI_ALL,
6319 6717 &error_num);
6320 6718 if (hp == NULL)
6321 6719 fatal(1, "%s: invalid or unknown host address\n", arg);
6322 6720 newf->u.a.f_address = hp;
6323 6721 if (cp == NULL) {
6324 6722 V4MASK_TO_V6(IP_HOST_MASK, newf->u.a.f_mask);
6325 6723 } else {
6326 6724 val = strtol(cp, &cp2, 0);
6327 6725 if (cp != cp2 && cp2[0] == '\0') {
6328 6726 /*
6329 6727 * If decode as "/n" works, then translate
6330 6728 * into a mask.
6331 6729 */
6332 6730 if (hp->h_addr_list[0] != NULL &&
6333 6731 /* LINTED: (note 1) */
6334 6732 IN6_IS_ADDR_V4MAPPED((in6_addr_t *)
6335 6733 hp->h_addr_list[0])) {
6336 6734 maxv = IP_ABITS;
6337 6735 } else {
6338 6736 maxv = IPV6_ABITS;
6339 6737 }
6340 6738 if (val < 0 || val >= maxv)
6341 6739 fatal(1, "%d: not in range 0 to %d\n",
6342 6740 val, maxv - 1);
6343 6741 if (maxv == IP_ABITS)
6344 6742 val += IPV6_ABITS - IP_ABITS;
6345 6743 ucp = newf->u.a.f_mask.s6_addr;
6346 6744 while (val >= 8)
6347 6745 *ucp++ = 0xff, val -= 8;
6348 6746 *ucp++ = (0xff << (8 - val)) & 0xff;
6349 6747 while (ucp < newf->u.a.f_mask.s6_addr +
6350 6748 sizeof (newf->u.a.f_mask.s6_addr))
6351 6749 *ucp++ = 0;
6352 6750 /* Otherwise, try as numeric address */
6353 6751 } else if (inet_pton(AF_INET6,
6354 6752 cp, &newf->u.a.f_mask) <= 0) {
6355 6753 fatal(1, "%s: illegal mask format\n", cp);
6356 6754 }
6357 6755 }
6358 6756 break;
6359 6757
6360 6758 case FK_FLAGS:
6361 6759 if (*arg == '+') {
6362 6760 newf->u.f.f_flagset = flag_bits(arg + 1);
6363 6761 newf->u.f.f_flagclear = 0;
6364 6762 } else if (*arg == '-') {
6365 6763 newf->u.f.f_flagset = 0;
6366 6764 newf->u.f.f_flagclear = flag_bits(arg + 1);
6367 6765 } else {
6368 6766 newf->u.f.f_flagset = flag_bits(arg);
6369 6767 newf->u.f.f_flagclear = ~newf->u.f.f_flagset;
6370 6768 }
6371 6769 break;
6372 6770
6373 6771 default:
6374 6772 assert(0);
6375 6773 }
6376 6774 newf->f_next = filters[idx];
6377 6775 filters[idx] = newf;
6378 6776 }
6379 6777
6380 6778 /* Determine if user wants this address family printed. */
6381 6779 static boolean_t
6382 6780 family_selected(int family)
6383 6781 {
6384 6782 const filter_t *fp;
6385 6783
6386 6784 if (v4compat && family == AF_INET6)
6387 6785 return (B_FALSE);
6388 6786 if ((fp = filters[FK_AF]) == NULL)
6389 6787 return (B_TRUE);
6390 6788 while (fp != NULL) {
6391 6789 if (fp->u.f_family == family)
6392 6790 return (B_TRUE);
6393 6791 fp = fp->f_next;
6394 6792 }
6395 6793 return (B_FALSE);
6396 6794 }
6397 6795
6398 6796 /*
6399 6797 * Convert the interface index to a string using the buffer `ifname', which
6400 6798 * must be at least LIFNAMSIZ bytes. We first try to map it to name. If that
6401 6799 * fails (e.g., because we're inside a zone and it does not have access to
6402 6800 * interface for the index in question), just return "if#<num>".
6403 6801 */
↓ open down ↓ |
967 lines elided |
↑ open up ↑ |
6404 6802 static char *
6405 6803 ifindex2str(uint_t ifindex, char *ifname)
6406 6804 {
6407 6805 if (if_indextoname(ifindex, ifname) == NULL)
6408 6806 (void) snprintf(ifname, LIFNAMSIZ, "if#%d", ifindex);
6409 6807
6410 6808 return (ifname);
6411 6809 }
6412 6810
6413 6811 /*
6812 + * get proc info (psinfo_t) given pid. It doesn't return NULL.
6813 + */
6814 +
6815 +proc_info_t *
6816 +get_proc_info(uint32_t pid)
6817 +{
6818 + static uint32_t saved_pid = 0;
6819 + static proc_info_t saved_proc_info;
6820 + static proc_info_t unknown_proc_info = {"<unknown>","",""};
6821 + static psinfo_t pinfo;
6822 + char path[128];
6823 + int fd;
6824 +
6825 + /* hardcode pid = 0 */
6826 + if (pid == 0) {
6827 + saved_proc_info.pr_user = "root";
6828 + saved_proc_info.pr_fname = "sched";
6829 + saved_proc_info.pr_psargs = "sched";
6830 + saved_pid = 0;
6831 + return &saved_proc_info;
6832 + }
6833 +
6834 + if (pid == saved_pid)
6835 + return &saved_proc_info;
6836 + if ((snprintf(path, 128, "/proc/%u/psinfo",pid) > 0) &&
6837 + ((fd = open(path, O_RDONLY)) != -1)) {
6838 + if (read(fd, &pinfo, sizeof(pinfo)) == sizeof(pinfo)){
6839 + saved_proc_info.pr_user = get_username(pinfo.pr_uid);
6840 + saved_proc_info.pr_fname = pinfo.pr_fname;
6841 + saved_proc_info.pr_psargs = pinfo.pr_psargs;
6842 + saved_pid = pid;
6843 + (void) close(fd);
6844 + return &saved_proc_info;
6845 + } else {
6846 + (void) close(fd);
6847 + }
6848 + }
6849 +
6850 + return (&unknown_proc_info);
6851 +}
6852 +
6853 +/*
6854 + * get username given uid. It doesn't return NULL.
6855 + */
6856 +
6857 +static char *
6858 +get_username(uid_t u)
6859 +{
6860 + static uid_t saved_uid = UINT_MAX;
6861 + static char saved_username[128];
6862 + struct passwd *pw = NULL;
6863 + if (u == UINT_MAX)
6864 + return "<unknown>";
6865 + if (u == saved_uid && saved_username[0] != '\0')
6866 + return (saved_username);
6867 + setpwent();
6868 + if ((pw = getpwuid(u)) != NULL)
6869 + (void) strlcpy(saved_username, pw->pw_name, 128);
6870 + else
6871 + (void) snprintf(saved_username, 128, "%u", u);
6872 + saved_uid = u;
6873 + return saved_username;
6874 +}
6875 +
6876 +/*
6414 6877 * print the usage line
6415 6878 */
6416 6879 static void
6417 6880 usage(char *cmdname)
6418 6881 {
6419 - (void) fprintf(stderr, "usage: %s [-anv] [-f address_family] "
6882 + (void) fprintf(stderr, "usage: %s [-anuv] [-f address_family] "
6420 6883 "[-T d|u]\n", cmdname);
6421 6884 (void) fprintf(stderr, " %s [-n] [-f address_family] "
6422 6885 "[-P protocol] [-T d|u] [-g | -p | -s [interval [count]]]\n",
6423 6886 cmdname);
6424 6887 (void) fprintf(stderr, " %s -m [-v] [-T d|u] "
6425 6888 "[interval [count]]\n", cmdname);
6426 6889 (void) fprintf(stderr, " %s -i [-I interface] [-an] "
6427 6890 "[-f address_family] [-T d|u] [interval [count]]\n", cmdname);
6428 6891 (void) fprintf(stderr, " %s -r [-anv] "
6429 6892 "[-f address_family|filter] [-T d|u]\n", cmdname);
6430 6893 (void) fprintf(stderr, " %s -M [-ns] [-f address_family] "
6431 6894 "[-T d|u]\n", cmdname);
6432 6895 (void) fprintf(stderr, " %s -D [-I interface] "
6433 6896 "[-f address_family] [-T d|u]\n", cmdname);
6434 6897 exit(EXIT_FAILURE);
6435 6898 }
6436 6899
6437 6900 /*
6438 6901 * fatal: print error message to stderr and
6439 6902 * call exit(errcode)
6440 6903 */
6441 6904 /*PRINTFLIKE2*/
6442 6905 static void
6443 6906 fatal(int errcode, char *format, ...)
6444 6907 {
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
6445 6908 va_list argp;
6446 6909
6447 6910 if (format == NULL)
6448 6911 return;
6449 6912
6450 6913 va_start(argp, format);
6451 6914 (void) vfprintf(stderr, format, argp);
6452 6915 va_end(argp);
6453 6916
6454 6917 exit(errcode);
6918 +}
6919 +
6920 +
6921 +/* -------------------UNIX Domain Sockets Report---------------------------- */
6922 +
6923 +
6924 +#define NO_ADDR " "
6925 +#define SO_PAIR " (socketpair) "
6926 +
6927 +static char *typetoname(t_scalar_t);
6928 +static boolean_t uds_report_item(struct sockinfo *, boolean_t);
6929 +
6930 +
6931 +static char uds_hdr[] = "\nActive UNIX domain sockets\n";
6932 +
6933 +static char uds_hdr_normal[] =
6934 +" Type Local Adress "
6935 +" Remote Address\n"
6936 +"---------- --------------------------------------- "
6937 +"---------------------------------------\n";
6938 +
6939 +static char uds_hdr_pid[] =
6940 +" Type User Pid Command "
6941 +" Local Address "
6942 +" Remote Address\n"
6943 +"---------- -------- ------ -------------- "
6944 +"--------------------------------------- "
6945 +"---------------------------------------\n";
6946 +static char uds_hdr_pid_verbose[] =
6947 +" Type User Pid Local Address "
6948 +" Remote Address Command\n"
6949 +"---------- -------- ------ --------------------------------------- "
6950 +"--------------------------------------- --------------\n";
6951 +
6952 +/*
6953 + * Print a summary of connections related to a unix protocol.
6954 + */
6955 +static void
6956 +uds_report(kstat_ctl_t *kc)
6957 +{
6958 + int i;
6959 + kstat_t *ksp;
6960 + struct sockinfo *psi; /* ptr to current sockinfo */
6961 + boolean_t print_uds_hdr_once = B_TRUE;
6962 +
6963 + if (kc == NULL) { /* sanity check. */
6964 + fail(0, "uds_report: No kstat");
6965 + exit(3);
6966 + }
6967 +
6968 + /* find the sockfs kstat: */
6969 + if ((ksp = kstat_lookup(kc, "sockfs", 0, "sock_unix_list")) ==
6970 + (kstat_t *)NULL) {
6971 + fail(0, "kstat_data_lookup failed\n");
6972 + }
6973 +
6974 + if (kstat_read(kc, ksp, NULL) == -1) {
6975 + fail(0, "kstat_read failed for sock_unix_list\n");
6976 + }
6977 +
6978 + if (ksp->ks_ndata == 0) {
6979 + return; /* no AF_UNIX sockets found */
6980 + }
6981 +
6982 + /*
6983 + * Having ks_data set with ks_data == NULL shouldn't happen;
6984 + * If it does, the sockfs kstat is seriously broken.
6985 + */
6986 + if ((psi = ksp->ks_data) == NULL) {
6987 + fail(0, "uds_report: no kstat data\n");
6988 + }
6989 +
6990 + /* for each sockinfo structure, display what we need: */
6991 + for (i = 0; i < ksp->ks_ndata; i++) {
6992 +
6993 + /* process this entry */
6994 + print_uds_hdr_once = uds_report_item(psi, print_uds_hdr_once);
6995 +
6996 + /* if si_size didn't get filled in, then we're done */
6997 + if (psi->si_size == 0 ||
6998 + !IS_P2ALIGNED(psi->si_size, sizeof (psi))) {
6999 + break;
7000 + }
7001 +
7002 + /* point to the next sockinfo in the array */
7003 + /* LINTED: (note 1) */
7004 + psi = (struct sockinfo *)(((char *)psi) + psi->si_size);
7005 + }
7006 +}
7007 +
7008 +static boolean_t
7009 +uds_report_item(struct sockinfo *psi, boolean_t first)
7010 +{
7011 + int i = 0;
7012 + conn_pid_node_t *cpn;
7013 + proc_info_t *pinfo;
7014 + char *laddr, *raddr;
7015 +
7016 + if(first) {
7017 + (void) printf("%s", uds_hdr);
7018 + if (Uflag)
7019 + (void) printf("%s", Vflag?uds_hdr_pid_verbose:
7020 + uds_hdr_pid);
7021 + else
7022 + (void) printf("%s", uds_hdr_normal);
7023 +
7024 + first = B_FALSE;
7025 + }
7026 +
7027 + cpn = psi->si_pns;
7028 +
7029 + do {
7030 + int pid = (psi->si_pn_cnt)?cpn->cpn_pid:0;
7031 + pinfo = get_proc_info(cpn->cpn_pid);
7032 + raddr = laddr = NO_ADDR;
7033 +
7034 + /* laddr.soa_sa: */
7035 + if ((psi->si_state & SS_ISBOUND) &&
7036 + strlen(psi->si_laddr_sun_path) != 0 &&
7037 + psi->si_laddr_soa_len != 0) {
7038 + if (psi->si_faddr_noxlate) {
7039 + laddr = SO_PAIR;
7040 + } else {
7041 + if (psi->si_laddr_soa_len >
7042 + sizeof (psi->si_laddr_family))
7043 + laddr = psi->si_laddr_sun_path;
7044 + }
7045 + }
7046 +
7047 + /* faddr.soa_sa: */
7048 + if ((psi->si_state & SS_ISCONNECTED) &&
7049 + strlen(psi->si_faddr_sun_path) != 0 &&
7050 + psi->si_faddr_soa_len != 0) {
7051 +
7052 + if (psi->si_faddr_noxlate) {
7053 + raddr = SO_PAIR;
7054 + } else {
7055 + if (psi->si_faddr_soa_len >
7056 + sizeof (psi->si_faddr_family))
7057 + raddr = psi->si_faddr_sun_path;
7058 + }
7059 + }
7060 +
7061 + if (Uflag && Vflag) {
7062 + (void) printf("%-10.10s %-8.8s %6u "
7063 + "%-39.39s %-39.39s %s\n",
7064 + typetoname(psi->si_serv_type), pinfo->pr_user,
7065 + pid, laddr, raddr, pinfo->pr_psargs);
7066 + } else if (Uflag && (!Vflag)) {
7067 + (void) printf("%-10.10s %-8.8s %6u %-14.14s"
7068 + "%-39.39s %-39.39s\n",
7069 + typetoname(psi->si_serv_type), pinfo->pr_user,
7070 + pid, pinfo->pr_fname, laddr, raddr);
7071 + } else {
7072 + (void) printf("%-10.10s %s %s\n",
7073 + typetoname(psi->si_serv_type), laddr, raddr);
7074 + }
7075 +
7076 + i++; cpn++;
7077 + } while (i < psi->si_pn_cnt);
7078 +
7079 + return (first);
7080 +}
7081 +
7082 +static char *
7083 +typetoname(t_scalar_t type)
7084 +{
7085 + switch (type) {
7086 + case T_CLTS:
7087 + return ("dgram");
7088 +
7089 + case T_COTS:
7090 + return ("stream");
7091 +
7092 + case T_COTS_ORD:
7093 + return ("stream-ord");
7094 +
7095 + default:
7096 + return ("");
7097 + }
6455 7098 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX