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