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
↓ 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>
↓ 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 && \
↓ 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);
↓ 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);
↓ 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;
↓ 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  
↓ 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) {
↓ 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) {
↓ 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);
↓ 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++;
↓ 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));
↓ 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));
↓ 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           */
↓ 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           */
↓ 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";
↓ 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 {
↓ 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  {
↓ 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) {
↓ 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);
↓ 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