4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #include <stdio.h>
  27 #include <locale.h>
  28 #include <stdarg.h>
  29 #include <stdlib.h>
  30 #include <fcntl.h>
  31 #include <string.h>
  32 #include <stropts.h>
  33 #include <errno.h>
  34 #include <strings.h>
  35 #include <getopt.h>
  36 #include <unistd.h>
  37 #include <priv.h>
  38 #include <netdb.h>
  39 #include <libintl.h>
  40 #include <libdlflow.h>
  41 #include <libdllink.h>
  42 #include <libdlstat.h>
  43 #include <sys/types.h>
 
 
 173         offsetof(history_l_fields_buf_t, history_l_etime), print_default_cb},
 174 { "RBYTES",     9,
 175         offsetof(history_l_fields_buf_t, history_l_rbytes), print_default_cb},
 176 { "OBYTES",     9,
 177         offsetof(history_l_fields_buf_t, history_l_obytes), print_default_cb},
 178 { "BANDWIDTH",  15,
 179         offsetof(history_l_fields_buf_t, history_l_bandwidth),
 180             print_default_cb},
 181 NULL_OFMT}
 182 ;
 183 
 184 static char *progname;
 185 
 186 /*
 187  * Handle to libdladm.  Opened in main() before the sub-command
 188  * specific function is called.
 189  */
 190 static dladm_handle_t handle = NULL;
 191 
 192 const char *usage_ermsg = "flowstat [-r | -t] [-i interval] "
 193             "[-l link] [flow]\n"
 194             "       flowstat [-S] [-A] [-i interval] [-p] [ -o field[,...]]\n"
 195             "                [-u R|K|M|G|T|P] [-l link] [flow]\n"
 196             "       flowstat -h [-a] [-d] [-F format]"
 197             " [-s <DD/MM/YYYY,HH:MM:SS>]\n"
 198             "                [-e <DD/MM/YYYY,HH:MM:SS>] -f <logfile> "
 199             "[<flow>]";
 200 
 201 static void
 202 usage(void)
 203 {
 204         (void) fprintf(stderr, "%s\n", gettext(usage_ermsg));
 205 
 206         /* close dladm handle if it was opened */
 207         if (handle != NULL)
 208                 dladm_close(handle);
 209 
 210         exit(1);
 211 }
 212 
 213 boolean_t
 214 flowstat_unit(char *oarg, char *unit)
 215 {
 
 539 {
 540         dladm_status_t          status;
 541         int                     option;
 542         boolean_t               r_arg = B_FALSE;
 543         boolean_t               t_arg = B_FALSE;
 544         boolean_t               p_arg = B_FALSE;
 545         boolean_t               i_arg = B_FALSE;
 546         boolean_t               o_arg = B_FALSE;
 547         boolean_t               u_arg = B_FALSE;
 548         boolean_t               A_arg = B_FALSE;
 549         boolean_t               S_arg = B_FALSE;
 550         boolean_t               flow_arg = B_FALSE;
 551         datalink_id_t           linkid = DATALINK_ALL_LINKID;
 552         char                    linkname[MAXLINKNAMELEN];
 553         char                    flowname[MAXFLOWNAMELEN];
 554         uint32_t                interval = 0;
 555         char                    unit = '\0';
 556         show_flow_state_t       state;
 557         char                    *fields_str = NULL;
 558         char                    *o_fields_str = NULL;
 559 
 560         char                    *total_stat_fields =
 561             "flow,ipkts,rbytes,ierrs,opkts,obytes,oerrs";
 562         char                    *rx_stat_fields =
 563             "flow,ipkts,rbytes,ierrs";
 564         char                    *tx_stat_fields =
 565             "flow,opkts,obytes,oerrs";
 566 
 567         ofmt_handle_t           ofmt;
 568         ofmt_status_t           oferr;
 569         uint_t                  ofmtflags = OFMT_RIGHTJUST;
 570 
 571         dladm_flow_attr_t       attr;
 572 
 573         (void) setlocale(LC_ALL, "");
 574 #if !defined(TEXT_DOMAIN)
 575 #define TEXT_DOMAIN "SYS_TEST"
 576 #endif
 577         (void) textdomain(TEXT_DOMAIN);
 578 
 579         progname = argv[0];
 580 
 581         /* Open the libdladm handle */
 582         if ((status = dladm_open(&handle)) != DLADM_STATUS_OK)
 583                 die_dlerr(status, "could not open /dev/dld");
 584 
 585         bzero(&state, sizeof (state));
 586 
 587         opterr = 0;
 588         while ((option = getopt_long(argc, argv, ":rtApSi:o:u:l:h",
 589             NULL, NULL)) != -1) {
 590                 switch (option) {
 591                 case 'r':
 592                         if (r_arg)
 593                                 die_optdup(option);
 594 
 595                         r_arg = B_TRUE;
 596                         break;
 597                 case 't':
 598                         if (t_arg)
 599                                 die_optdup(option);
 600 
 601                         t_arg = B_TRUE;
 602                         break;
 603                 case 'A':
 604                         if (A_arg)
 605                                 die_optdup(option);
 606 
 607                         A_arg = B_TRUE;
 608                         break;
 
 625                         if (!dladm_str2interval(optarg, &interval))
 626                                 die("invalid interval value '%s'", optarg);
 627                         break;
 628                 case 'o':
 629                         o_arg = B_TRUE;
 630                         o_fields_str = optarg;
 631                         break;
 632                 case 'u':
 633                         if (u_arg)
 634                                 die_optdup(option);
 635 
 636                         u_arg = B_TRUE;
 637                         if (!flowstat_unit(optarg, &unit))
 638                                 die("invalid unit value '%s',"
 639                                     "unit must be R|K|M|G|T|P", optarg);
 640                         break;
 641                 case 'l':
 642                         if (strlcpy(linkname, optarg, MAXLINKNAMELEN)
 643                             >= MAXLINKNAMELEN)
 644                                 die("link name too long\n");
 645                         if (dladm_name2info(handle, linkname, &linkid, NULL,
 646                             NULL, NULL) != DLADM_STATUS_OK)
 647                                 die("invalid link '%s'", linkname);
 648                         break;
 649                 case 'h':
 650                         if (r_arg || t_arg || p_arg || o_arg || u_arg ||
 651                             i_arg || S_arg || A_arg) {
 652                                 die("the option -h is not compatible with "
 653                                     "-r, -t, -p, -o, -u, -i, -S, -A");
 654                         }
 655                         do_show_history(argc, argv);
 656                         return (0);
 657                         break;
 658                 default:
 659                         die_opterr(optopt, option, usage_ermsg);
 660                         break;
 661                 }
 662         }
 663 
 664         if (r_arg && t_arg)
 665                 die("the option -t and -r are not compatible");
 666 
 667         if (u_arg && p_arg)
 668                 die("the option -u and -p are not compatible");
 669 
 670         if (p_arg && !o_arg)
 671                 die("-p requires -o");
 672 
 673         if (p_arg && strcasecmp(o_fields_str, "all") == 0)
 674                 die("\"-o all\" is invalid with -p");
 675 
 676         if (S_arg &&
 677             (r_arg || t_arg || p_arg || o_arg || u_arg))
 678                 die("the option -S is not compatible with "
 679                     "-r, -t, -p, -o, -u");
 680 
 681         if (A_arg &&
 682             (r_arg || t_arg || p_arg || o_arg || u_arg || i_arg))
 683                 die("the option -A is not compatible with "
 684                     "-r, -t, -p, -o, -u, -i");
 685 
 686         /* get flow name (optional last argument) */
 687         if (optind == (argc-1)) {
 688                 if (strlcpy(flowname, argv[optind], MAXFLOWNAMELEN)
 689                     >= MAXFLOWNAMELEN)
 690                         die("flow name too long");
 691                 flow_arg = B_TRUE;
 692         } else if (optind != argc) {
 693                 usage();
 694         }
 695 
 696         if (S_arg) {
 697                 dladm_continuous(handle, linkid, (flow_arg ? flowname : NULL),
 698                     interval, FLOW_REPORT);
 699                 return (0);
 700         }
 701 
 702         if (flow_arg &&
 703             dladm_flow_info(handle, flowname, &attr) != DLADM_STATUS_OK)
 704                 die("invalid flow %s", flowname);
 705 
 
 | 
 
 
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright 2011 Joyent, Inc.  All rights reserved.
  25  */
  26 
  27 #include <stdio.h>
  28 #include <locale.h>
  29 #include <stdarg.h>
  30 #include <stdlib.h>
  31 #include <fcntl.h>
  32 #include <string.h>
  33 #include <stropts.h>
  34 #include <errno.h>
  35 #include <strings.h>
  36 #include <getopt.h>
  37 #include <unistd.h>
  38 #include <priv.h>
  39 #include <netdb.h>
  40 #include <libintl.h>
  41 #include <libdlflow.h>
  42 #include <libdllink.h>
  43 #include <libdlstat.h>
  44 #include <sys/types.h>
 
 
 174         offsetof(history_l_fields_buf_t, history_l_etime), print_default_cb},
 175 { "RBYTES",     9,
 176         offsetof(history_l_fields_buf_t, history_l_rbytes), print_default_cb},
 177 { "OBYTES",     9,
 178         offsetof(history_l_fields_buf_t, history_l_obytes), print_default_cb},
 179 { "BANDWIDTH",  15,
 180         offsetof(history_l_fields_buf_t, history_l_bandwidth),
 181             print_default_cb},
 182 NULL_OFMT}
 183 ;
 184 
 185 static char *progname;
 186 
 187 /*
 188  * Handle to libdladm.  Opened in main() before the sub-command
 189  * specific function is called.
 190  */
 191 static dladm_handle_t handle = NULL;
 192 
 193 const char *usage_ermsg = "flowstat [-r | -t] [-i interval] "
 194             "[-l link] [-z zonename] [flow]\n"
 195             "       flowstat [-S] [-A] [-i interval] [-p] [ -o field[,...]]\n"
 196             "                [-u R|K|M|G|T|P] [-l link] [-z zonename] [flow]\n"
 197             "       flowstat -h [-a] [-d] [-F format]"
 198             " [-s <DD/MM/YYYY,HH:MM:SS>]\n"
 199             "                [-e <DD/MM/YYYY,HH:MM:SS>] -f <logfile> "
 200             "[<flow>]";
 201 
 202 static void
 203 usage(void)
 204 {
 205         (void) fprintf(stderr, "%s\n", gettext(usage_ermsg));
 206 
 207         /* close dladm handle if it was opened */
 208         if (handle != NULL)
 209                 dladm_close(handle);
 210 
 211         exit(1);
 212 }
 213 
 214 boolean_t
 215 flowstat_unit(char *oarg, char *unit)
 216 {
 
 540 {
 541         dladm_status_t          status;
 542         int                     option;
 543         boolean_t               r_arg = B_FALSE;
 544         boolean_t               t_arg = B_FALSE;
 545         boolean_t               p_arg = B_FALSE;
 546         boolean_t               i_arg = B_FALSE;
 547         boolean_t               o_arg = B_FALSE;
 548         boolean_t               u_arg = B_FALSE;
 549         boolean_t               A_arg = B_FALSE;
 550         boolean_t               S_arg = B_FALSE;
 551         boolean_t               flow_arg = B_FALSE;
 552         datalink_id_t           linkid = DATALINK_ALL_LINKID;
 553         char                    linkname[MAXLINKNAMELEN];
 554         char                    flowname[MAXFLOWNAMELEN];
 555         uint32_t                interval = 0;
 556         char                    unit = '\0';
 557         show_flow_state_t       state;
 558         char                    *fields_str = NULL;
 559         char                    *o_fields_str = NULL;
 560         char                    *zonename = NULL;
 561 
 562         char                    *total_stat_fields =
 563             "flow,ipkts,rbytes,ierrs,opkts,obytes,oerrs";
 564         char                    *rx_stat_fields =
 565             "flow,ipkts,rbytes,ierrs";
 566         char                    *tx_stat_fields =
 567             "flow,opkts,obytes,oerrs";
 568 
 569         ofmt_handle_t           ofmt;
 570         ofmt_status_t           oferr;
 571         uint_t                  ofmtflags = OFMT_RIGHTJUST;
 572 
 573         dladm_flow_attr_t       attr;
 574 
 575         (void) setlocale(LC_ALL, "");
 576 #if !defined(TEXT_DOMAIN)
 577 #define TEXT_DOMAIN "SYS_TEST"
 578 #endif
 579         (void) textdomain(TEXT_DOMAIN);
 580 
 581         progname = argv[0];
 582 
 583         /* Open the libdladm handle */
 584         if ((status = dladm_open(&handle)) != DLADM_STATUS_OK)
 585                 die_dlerr(status, "could not open /dev/dld");
 586 
 587         linkname[0] = '\0';
 588         bzero(&state, sizeof (state));
 589 
 590         opterr = 0;
 591         while ((option = getopt_long(argc, argv, ":rtApSi:o:u:l:hz:",
 592             NULL, NULL)) != -1) {
 593                 switch (option) {
 594                 case 'r':
 595                         if (r_arg)
 596                                 die_optdup(option);
 597 
 598                         r_arg = B_TRUE;
 599                         break;
 600                 case 't':
 601                         if (t_arg)
 602                                 die_optdup(option);
 603 
 604                         t_arg = B_TRUE;
 605                         break;
 606                 case 'A':
 607                         if (A_arg)
 608                                 die_optdup(option);
 609 
 610                         A_arg = B_TRUE;
 611                         break;
 
 628                         if (!dladm_str2interval(optarg, &interval))
 629                                 die("invalid interval value '%s'", optarg);
 630                         break;
 631                 case 'o':
 632                         o_arg = B_TRUE;
 633                         o_fields_str = optarg;
 634                         break;
 635                 case 'u':
 636                         if (u_arg)
 637                                 die_optdup(option);
 638 
 639                         u_arg = B_TRUE;
 640                         if (!flowstat_unit(optarg, &unit))
 641                                 die("invalid unit value '%s',"
 642                                     "unit must be R|K|M|G|T|P", optarg);
 643                         break;
 644                 case 'l':
 645                         if (strlcpy(linkname, optarg, MAXLINKNAMELEN)
 646                             >= MAXLINKNAMELEN)
 647                                 die("link name too long\n");
 648                         break;
 649                 case 'h':
 650                         if (r_arg || t_arg || p_arg || o_arg || u_arg ||
 651                             i_arg || S_arg || A_arg) {
 652                                 die("the option -h is not compatible with "
 653                                     "-r, -t, -p, -o, -u, -i, -S, -A");
 654                         }
 655                         do_show_history(argc, argv);
 656                         return (0);
 657                         break;
 658                 case 'z':
 659                         zonename = optarg;
 660                         break;
 661                 default:
 662                         die_opterr(optopt, option, usage_ermsg);
 663                         break;
 664                 }
 665         }
 666 
 667         if (r_arg && t_arg)
 668                 die("the option -t and -r are not compatible");
 669 
 670         if (u_arg && p_arg)
 671                 die("the option -u and -p are not compatible");
 672 
 673         if (p_arg && !o_arg)
 674                 die("-p requires -o");
 675 
 676         if (p_arg && strcasecmp(o_fields_str, "all") == 0)
 677                 die("\"-o all\" is invalid with -p");
 678 
 679         if (S_arg &&
 680             (r_arg || t_arg || p_arg || o_arg || u_arg))
 681                 die("the option -S is not compatible with "
 682                     "-r, -t, -p, -o, -u");
 683 
 684         if (A_arg &&
 685             (r_arg || t_arg || p_arg || o_arg || u_arg || i_arg))
 686                 die("the option -A is not compatible with "
 687                     "-r, -t, -p, -o, -u, -i");
 688 
 689         if (linkname[0] != '\0') {
 690                 if (dladm_zname2info(handle, zonename, linkname, &linkid, NULL,
 691                     NULL, NULL) != DLADM_STATUS_OK)
 692                         die("invalid link '%s'", linkname);
 693         }
 694 
 695         /* get flow name (optional last argument) */
 696         if (optind == (argc-1)) {
 697                 if (strlcpy(flowname, argv[optind], MAXFLOWNAMELEN)
 698                     >= MAXFLOWNAMELEN)
 699                         die("flow name too long");
 700                 flow_arg = B_TRUE;
 701         } else if (optind != argc) {
 702                 usage();
 703         }
 704 
 705         if (S_arg) {
 706                 dladm_continuous(handle, linkid, (flow_arg ? flowname : NULL),
 707                     interval, FLOW_REPORT);
 708                 return (0);
 709         }
 710 
 711         if (flow_arg &&
 712             dladm_flow_info(handle, flowname, &attr) != DLADM_STATUS_OK)
 713                 die("invalid flow %s", flowname);
 714 
 
 |