Print this page
4770 soconfig(1M) needs an option to print the in-kernel socket configuration table


   3  *
   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 (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.

  23  */
  24 
  25 #include <ctype.h>
  26 #include <dirent.h>
  27 #include <errno.h>
  28 #include <locale.h>
  29 #include <stdio.h>
  30 #include <stdlib.h>
  31 #include <string.h>
  32 #include <sys/socket.h>
  33 #include <sys/socketvar.h>
  34 #include <sys/stat.h>
  35 #include <unistd.h>
  36 
  37 #define MAXLINELEN      4096
  38 
  39 /*
  40  * Usage:
  41  *      soconfig -d <dir>
  42  *              Reads input from files in dir.
  43  *
  44  *      soconfig -f <file>
  45  *              Reads input from file. The file is structured as
  46  *                       <fam> <type> <protocol> <path|module>
  47  *                       <fam> <type> <protocol>
  48  *              with the first line registering and the second line
  49  *              deregistering.
  50  *
  51  *      soconfig <fam> <type> <protocol> <path|module>
  52  *              registers
  53  *
  54  *      soconfig <fam> <type> <protocol>
  55  *              deregisters
  56  *



  57  * Filter Operations (Consolidation Private):
  58  *
  59  *      soconfig -F <name> <modname> {auto [top | bottom | before:filter |
  60  *              after:filter] | prog} <fam>:<type>:<proto>,...
  61  *              configure filter
  62  *
  63  *      soconfig -F <name>
  64  *              unconfigures filter
  65  */
  66 
  67 static int      parse_files_in_dir(const char *dir);
  68 
  69 static int      parse_file(char *filename);
  70 
  71 static int      split_line(char *line, char *argvec[], int maxargvec);
  72 
  73 static int      parse_params(char *famstr, char *typestr, char *protostr,
  74                                 char *path, const char *file, int line);
  75 
  76 static int      parse_int(char *str);
  77 
  78 static void     usage(void);
  79 
  80 static int      parse_filter_params(int argc, char **argv);
  81 


  82 int
  83 main(argc, argv)
  84         int argc;
  85         char *argv[];
  86 {
  87         int ret;
  88 
  89         argc--; argv++;
  90 
  91         (void) setlocale(LC_ALL, "");
  92 #if !defined(TEXT_DOMAIN)
  93 #define TEXT_DOMAIN "SYS_TEST"
  94 #endif
  95         (void) textdomain(TEXT_DOMAIN);
  96 





  97         if (argc >= 2 && strcmp(argv[0], "-F") == 0) {
  98                 argc--; argv++;
  99                 ret = parse_filter_params(argc, argv);
 100                 exit(ret);
 101         }
 102         if (argc == 2 && strcmp(argv[0], "-d") == 0) {
 103                 ret = parse_files_in_dir(argv[1]);
 104                 exit(ret);
 105         }
 106         if (argc == 2 && strcmp(argv[0], "-f") == 0) {
 107                 ret = parse_file(argv[1]);
 108                 exit(ret);
 109         }
 110         if (argc == 3) {
 111                 ret = parse_params(argv[0], argv[1], argv[2], NULL, NULL, -1);
 112                 exit(ret);
 113         }
 114         if (argc == 4) {
 115                 ret = parse_params(argv[0], argv[1], argv[2], argv[3],
 116                     NULL, -1);
 117                 exit(ret);
 118         }
 119         usage();
 120         exit(1);
 121         /* NOTREACHED */
 122 }
 123 
 124 static void
 125 usage(void)
 126 {
 127         fprintf(stderr, gettext(
 128             "Usage:     soconfig -d <dir>\n"
 129             "\tsoconfig -f <file>\n"
 130             "\tsoconfig <fam> <type> <protocol> <path|module>\n"
 131             "\tsoconfig <fam> <type> <protocol>\n"));

 132 }
 133 
 134 /*
 135  * Parse all files in the given directory.
 136  */
 137 static int
 138 parse_files_in_dir(const char *dirname)
 139 {
 140         DIR             *dp;
 141         struct dirent   *dirp;
 142         struct stat     stats;
 143         char            buf[MAXPATHLEN];
 144 
 145         if ((dp = opendir(dirname)) == NULL) {
 146                 fprintf(stderr, gettext("failed to open directory '%s': %s\n"),
 147                     dirname, strerror(errno));
 148                 return (1);
 149         }
 150 
 151         while ((dirp = readdir(dp)) != NULL) {


 558                         break;
 559                 case EEXIST:
 560                         fprintf(stderr,
 561                             gettext("socket filter is already configured "
 562                             "'%s'\n"), argv[0]);
 563                         break;
 564                 case ENOSPC:
 565                         fprintf(stderr, gettext("unable to satisfy placement "
 566                             "constraint\n"));
 567                         break;
 568                 default:
 569                         perror("sockconfig");
 570                         break;
 571                 }
 572                 free(socktuples);
 573                 return (1);
 574         }
 575         free(socktuples);
 576         return (0);
 577 }


























































   3  *
   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 (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
  24  */
  25 
  26 #include <ctype.h>
  27 #include <dirent.h>
  28 #include <errno.h>
  29 #include <locale.h>
  30 #include <stdio.h>
  31 #include <stdlib.h>
  32 #include <string.h>
  33 #include <sys/socket.h>
  34 #include <sys/socketvar.h>
  35 #include <sys/stat.h>
  36 #include <unistd.h>
  37 
  38 #define MAXLINELEN      4096
  39 
  40 /*
  41  * Usage:
  42  *      soconfig -d <dir>
  43  *              Reads input from files in dir.
  44  *
  45  *      soconfig -f <file>
  46  *              Reads input from file. The file is structured as
  47  *                       <fam> <type> <protocol> <path|module>
  48  *                       <fam> <type> <protocol>
  49  *              with the first line registering and the second line
  50  *              deregistering.
  51  *
  52  *      soconfig <fam> <type> <protocol> <path|module>
  53  *              registers
  54  *
  55  *      soconfig <fam> <type> <protocol>
  56  *              deregisters
  57  *
  58  *      soconfig -l
  59  *              print the in-kernel socket configuration table
  60  *
  61  * Filter Operations (Consolidation Private):
  62  *
  63  *      soconfig -F <name> <modname> {auto [top | bottom | before:filter |
  64  *              after:filter] | prog} <fam>:<type>:<proto>,...
  65  *              configure filter
  66  *
  67  *      soconfig -F <name>
  68  *              unconfigures filter
  69  */
  70 
  71 static int      parse_files_in_dir(const char *dir);
  72 
  73 static int      parse_file(char *filename);
  74 
  75 static int      split_line(char *line, char *argvec[], int maxargvec);
  76 
  77 static int      parse_params(char *famstr, char *typestr, char *protostr,
  78                                 char *path, const char *file, int line);
  79 
  80 static int      parse_int(char *str);
  81 
  82 static void     usage(void);
  83 
  84 static int      parse_filter_params(int argc, char **argv);
  85 
  86 static int      print_socktable();
  87 
  88 int
  89 main(argc, argv)
  90         int argc;
  91         char *argv[];
  92 {
  93         int ret;
  94 
  95         argc--; argv++;
  96 
  97         (void) setlocale(LC_ALL, "");
  98 #if !defined(TEXT_DOMAIN)
  99 #define TEXT_DOMAIN "SYS_TEST"
 100 #endif
 101         (void) textdomain(TEXT_DOMAIN);
 102 
 103         if (argc == 1 && strcmp(argv[0], "-l") == 0) {
 104                 ret = print_socktable();
 105                 exit(ret);
 106         }
 107 
 108         if (argc >= 2 && strcmp(argv[0], "-F") == 0) {
 109                 argc--; argv++;
 110                 ret = parse_filter_params(argc, argv);
 111                 exit(ret);
 112         }
 113         if (argc == 2 && strcmp(argv[0], "-d") == 0) {
 114                 ret = parse_files_in_dir(argv[1]);
 115                 exit(ret);
 116         }
 117         if (argc == 2 && strcmp(argv[0], "-f") == 0) {
 118                 ret = parse_file(argv[1]);
 119                 exit(ret);
 120         }
 121         if (argc == 3) {
 122                 ret = parse_params(argv[0], argv[1], argv[2], NULL, NULL, -1);
 123                 exit(ret);
 124         }
 125         if (argc == 4) {
 126                 ret = parse_params(argv[0], argv[1], argv[2], argv[3],
 127                     NULL, -1);
 128                 exit(ret);
 129         }
 130         usage();
 131         exit(1);
 132         /* NOTREACHED */
 133 }
 134 
 135 static void
 136 usage(void)
 137 {
 138         fprintf(stderr, gettext(
 139             "Usage:     soconfig -d <dir>\n"
 140             "\tsoconfig -f <file>\n"
 141             "\tsoconfig <fam> <type> <protocol> <path|module>\n"
 142             "\tsoconfig <fam> <type> <protocol>\n"
 143             "\tsoconfig -l\n"));
 144 }
 145 
 146 /*
 147  * Parse all files in the given directory.
 148  */
 149 static int
 150 parse_files_in_dir(const char *dirname)
 151 {
 152         DIR             *dp;
 153         struct dirent   *dirp;
 154         struct stat     stats;
 155         char            buf[MAXPATHLEN];
 156 
 157         if ((dp = opendir(dirname)) == NULL) {
 158                 fprintf(stderr, gettext("failed to open directory '%s': %s\n"),
 159                     dirname, strerror(errno));
 160                 return (1);
 161         }
 162 
 163         while ((dirp = readdir(dp)) != NULL) {


 570                         break;
 571                 case EEXIST:
 572                         fprintf(stderr,
 573                             gettext("socket filter is already configured "
 574                             "'%s'\n"), argv[0]);
 575                         break;
 576                 case ENOSPC:
 577                         fprintf(stderr, gettext("unable to satisfy placement "
 578                             "constraint\n"));
 579                         break;
 580                 default:
 581                         perror("sockconfig");
 582                         break;
 583                 }
 584                 free(socktuples);
 585                 return (1);
 586         }
 587         free(socktuples);
 588         return (0);
 589 }
 590 
 591 /*
 592  *  Print the in-kernel socket configuration table
 593  */
 594 
 595 static int
 596 print_socktable()
 597 {
 598         sockconfig_socktable_t sc_table;
 599         int i;
 600 
 601         (void) memset(&sc_table, 0, sizeof (sockconfig_socktable_t));
 602 
 603         /* get number of entries */
 604         if (_sockconfig(SOCKCONFIG_GET_SOCKTABLE, &sc_table) == -1) {
 605                 fprintf(stderr,
 606                     gettext("cannot get in-kernel socket table: %s\n"),
 607                     strerror(errno));
 608                 return (-1);
 609         }
 610         if (sc_table.num_of_entries == 0)
 611                 return (0);
 612 
 613         sc_table.st_entries = calloc(sc_table.num_of_entries,
 614             sizeof (sockconfig_socktable_entry_t));
 615         if (sc_table.st_entries == NULL) {
 616                 fprintf(stderr, gettext("out of memory\n"));
 617                 return (-1);
 618         }
 619 
 620         /* get socket table entries */
 621         if (_sockconfig(SOCKCONFIG_GET_SOCKTABLE, &sc_table) == -1) {
 622                 fprintf(stderr,
 623                     gettext("cannot get in-kernel socket table: %s\n"),
 624                     strerror(errno));
 625                 return (-1);
 626         }
 627 
 628         printf("%6s %4s %5s %15s %15s %6s %6s\n",
 629             "FAMILY", "TYPE", "PROTO", "STRDEV", "SOCKMOD",
 630             "REFS", "FLAGS");
 631         for (i = 0; i < sc_table.num_of_entries; i++) {
 632                 printf("%6u %4u %5u %15s %15s %6u %#6x\n",
 633                     sc_table.st_entries[i].se_family,
 634                     sc_table.st_entries[i].se_type,
 635                     sc_table.st_entries[i].se_protocol,
 636                     (strcmp(sc_table.st_entries[i].se_modname,
 637                     "socktpi") == 0) ?
 638                     sc_table.st_entries[i].se_strdev : "-",
 639                     sc_table.st_entries[i].se_modname,
 640                     sc_table.st_entries[i].se_refcnt,
 641                     sc_table.st_entries[i].se_flags);
 642         }
 643         free(sc_table.st_entries);
 644         return (0);
 645 }