1*f875b4ebSrica /* 2*f875b4ebSrica * CDDL HEADER START 3*f875b4ebSrica * 4*f875b4ebSrica * The contents of this file are subject to the terms of the 5*f875b4ebSrica * Common Development and Distribution License (the "License"). 6*f875b4ebSrica * You may not use this file except in compliance with the License. 7*f875b4ebSrica * 8*f875b4ebSrica * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*f875b4ebSrica * or http://www.opensolaris.org/os/licensing. 10*f875b4ebSrica * See the License for the specific language governing permissions 11*f875b4ebSrica * and limitations under the License. 12*f875b4ebSrica * 13*f875b4ebSrica * When distributing Covered Code, include this CDDL HEADER in each 14*f875b4ebSrica * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*f875b4ebSrica * If applicable, add the following below this CDDL HEADER, with the 16*f875b4ebSrica * fields enclosed by brackets "[]" replaced with your own identifying 17*f875b4ebSrica * information: Portions Copyright [yyyy] [name of copyright owner] 18*f875b4ebSrica * 19*f875b4ebSrica * CDDL HEADER END 20*f875b4ebSrica */ 21*f875b4ebSrica 22*f875b4ebSrica /* 23*f875b4ebSrica * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24*f875b4ebSrica * Use is subject to license terms. 25*f875b4ebSrica */ 26*f875b4ebSrica 27*f875b4ebSrica #pragma ident "%Z%%M% %I% %E% SMI" 28*f875b4ebSrica 29*f875b4ebSrica /* 30*f875b4ebSrica * tninfo.c - Trusted network reporting utility 31*f875b4ebSrica */ 32*f875b4ebSrica #include <sys/types.h> 33*f875b4ebSrica #include <errno.h> 34*f875b4ebSrica #include <stdio.h> 35*f875b4ebSrica #include <locale.h> 36*f875b4ebSrica #include <string.h> 37*f875b4ebSrica #include <stdlib.h> 38*f875b4ebSrica #include <libtsnet.h> 39*f875b4ebSrica #include <netinet/in.h> 40*f875b4ebSrica #include <arpa/inet.h> 41*f875b4ebSrica #include <netdb.h> 42*f875b4ebSrica #include <tsol/label.h> 43*f875b4ebSrica #include <zone.h> 44*f875b4ebSrica 45*f875b4ebSrica /* maximum string size desired as returned by sb*tos calls */ 46*f875b4ebSrica #define MAX_STRING_SIZE 60 47*f875b4ebSrica 48*f875b4ebSrica static void usage(void); 49*f875b4ebSrica static int print_rhtp(const char *); 50*f875b4ebSrica static int print_rh(const char *); 51*f875b4ebSrica static int print_mlp(const char *); 52*f875b4ebSrica 53*f875b4ebSrica int 54*f875b4ebSrica main(int argc, char *argv[]) 55*f875b4ebSrica { 56*f875b4ebSrica int chr; 57*f875b4ebSrica int ret = 0; /* return code */ 58*f875b4ebSrica 59*f875b4ebSrica /* set the locale for only the messages system (all else is clean) */ 60*f875b4ebSrica (void) setlocale(LC_ALL, ""); 61*f875b4ebSrica #ifndef TEXT_DOMAIN /* Should be defined by cc -D */ 62*f875b4ebSrica #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 63*f875b4ebSrica #endif 64*f875b4ebSrica 65*f875b4ebSrica (void) textdomain(TEXT_DOMAIN); 66*f875b4ebSrica 67*f875b4ebSrica if (argc <= 1) 68*f875b4ebSrica usage(); 69*f875b4ebSrica 70*f875b4ebSrica while ((chr = getopt(argc, argv, "h:m:t:")) != EOF) { 71*f875b4ebSrica switch (chr) { 72*f875b4ebSrica case 'h': 73*f875b4ebSrica ret |= print_rh(optarg); 74*f875b4ebSrica break; 75*f875b4ebSrica case 'm': 76*f875b4ebSrica ret |= print_mlp(optarg); 77*f875b4ebSrica break; 78*f875b4ebSrica case 't': 79*f875b4ebSrica ret |= print_rhtp(optarg); 80*f875b4ebSrica break; 81*f875b4ebSrica default: 82*f875b4ebSrica usage(); 83*f875b4ebSrica } 84*f875b4ebSrica } 85*f875b4ebSrica 86*f875b4ebSrica return (ret); 87*f875b4ebSrica } 88*f875b4ebSrica 89*f875b4ebSrica static void 90*f875b4ebSrica usage(void) 91*f875b4ebSrica { 92*f875b4ebSrica (void) fprintf(stderr, gettext("usage: tninfo [-h host_name] " 93*f875b4ebSrica "[-m zone_name] [-t template_name]\n")); 94*f875b4ebSrica exit(1); 95*f875b4ebSrica } 96*f875b4ebSrica 97*f875b4ebSrica static int 98*f875b4ebSrica print_rhtp(const char *rhtp_name) 99*f875b4ebSrica { 100*f875b4ebSrica tsol_tpent_t tp; 101*f875b4ebSrica const char *str, *str2; 102*f875b4ebSrica const bslabel_t *l1, *l2; 103*f875b4ebSrica int i; 104*f875b4ebSrica 105*f875b4ebSrica (void) strlcpy(tp.name, rhtp_name, sizeof (tp.name)); 106*f875b4ebSrica 107*f875b4ebSrica if (tnrhtp(TNDB_GET, &tp) != 0) { 108*f875b4ebSrica if (errno == ENOENT) 109*f875b4ebSrica (void) fprintf(stderr, gettext("tninfo: tnrhtp entry " 110*f875b4ebSrica "%1$s does not exist\n"), tp.name); 111*f875b4ebSrica else 112*f875b4ebSrica (void) fprintf(stderr, 113*f875b4ebSrica gettext("tninfo: tnrhtp TNDB_GET(%1$s) failed: " 114*f875b4ebSrica "%2$s\n"), tp.name, strerror(errno)); 115*f875b4ebSrica return (1); 116*f875b4ebSrica } 117*f875b4ebSrica 118*f875b4ebSrica (void) printf("=====================================\n"); 119*f875b4ebSrica (void) printf(gettext("Remote Host Template Table Entries:\n")); 120*f875b4ebSrica 121*f875b4ebSrica (void) printf("__________________________\n"); 122*f875b4ebSrica (void) printf(gettext("template: %s\n"), tp.name); 123*f875b4ebSrica 124*f875b4ebSrica switch (tp.host_type) { 125*f875b4ebSrica case UNLABELED: 126*f875b4ebSrica (void) printf(gettext("host_type: UNLABELED\n")); 127*f875b4ebSrica (void) printf(gettext("doi: %d\n"), tp.tp_doi); 128*f875b4ebSrica 129*f875b4ebSrica if (tp.tp_mask_unl & TSOL_MSK_DEF_LABEL) { 130*f875b4ebSrica str = sbsltos(&tp.tp_def_label, MAX_STRING_SIZE); 131*f875b4ebSrica if (str == NULL) 132*f875b4ebSrica str = gettext("translation failed"); 133*f875b4ebSrica str2 = bsltoh(&tp.tp_def_label); 134*f875b4ebSrica if (str2 == NULL) 135*f875b4ebSrica str2 = gettext("translation failed"); 136*f875b4ebSrica (void) printf(gettext("def_label: %s\nhex: %s\n"), 137*f875b4ebSrica str, str2); 138*f875b4ebSrica } 139*f875b4ebSrica 140*f875b4ebSrica if (tp.tp_mask_unl & TSOL_MSK_SL_RANGE_TSOL) { 141*f875b4ebSrica (void) printf(gettext("For routing only:\n")); 142*f875b4ebSrica str = sbsltos(&tp.tp_gw_sl_range.lower_bound, 143*f875b4ebSrica MAX_STRING_SIZE); 144*f875b4ebSrica if (str == NULL) 145*f875b4ebSrica str = gettext("translation failed"); 146*f875b4ebSrica str2 = bsltoh(&tp.tp_gw_sl_range.lower_bound); 147*f875b4ebSrica if (str2 == NULL) 148*f875b4ebSrica str2 = gettext("translation failed"); 149*f875b4ebSrica (void) printf(gettext("min_sl: %s\nhex: %s\n"), 150*f875b4ebSrica str, str2); 151*f875b4ebSrica 152*f875b4ebSrica str = sbsltos(&tp.tp_gw_sl_range.upper_bound, 153*f875b4ebSrica MAX_STRING_SIZE); 154*f875b4ebSrica if (str == NULL) 155*f875b4ebSrica str = gettext("translation failed"); 156*f875b4ebSrica str2 = bsltoh(&tp.tp_gw_sl_range.upper_bound); 157*f875b4ebSrica if (str2 == NULL) 158*f875b4ebSrica str2 = gettext("translation failed"); 159*f875b4ebSrica (void) printf(gettext("max_sl: %s\nhex: %s\n"), 160*f875b4ebSrica str, str2); 161*f875b4ebSrica 162*f875b4ebSrica l1 = (const blevel_t *)&tp.tp_gw_sl_set[0]; 163*f875b4ebSrica l2 = (const blevel_t *)&tp.tp_gw_sl_set[NSLS_MAX]; 164*f875b4ebSrica for (i = 0; l1 < l2; l1++, i++) { 165*f875b4ebSrica if (bisinvalid(l1)) 166*f875b4ebSrica break; 167*f875b4ebSrica str = sbsltos(l1, MAX_STRING_SIZE); 168*f875b4ebSrica if (str == NULL) 169*f875b4ebSrica str = gettext("translation failed"); 170*f875b4ebSrica if ((str2 = bsltoh(l1)) == NULL) 171*f875b4ebSrica str2 = gettext("translation failed"); 172*f875b4ebSrica (void) printf(gettext("sl_set[%1$d]: %2$s\n" 173*f875b4ebSrica "hex: %3$s\n"), i, str, str2); 174*f875b4ebSrica } 175*f875b4ebSrica } 176*f875b4ebSrica break; 177*f875b4ebSrica 178*f875b4ebSrica case SUN_CIPSO: 179*f875b4ebSrica (void) printf(gettext("host_type: CIPSO\n")); 180*f875b4ebSrica (void) printf(gettext("doi: %d\n"), tp.tp_doi); 181*f875b4ebSrica if (tp.tp_mask_cipso & TSOL_MSK_SL_RANGE_TSOL) { 182*f875b4ebSrica str = sbsltos(&tp.tp_sl_range_cipso.lower_bound, 183*f875b4ebSrica MAX_STRING_SIZE); 184*f875b4ebSrica if (str == NULL) 185*f875b4ebSrica str = gettext("translation failed"); 186*f875b4ebSrica str2 = bsltoh(&tp.tp_sl_range_cipso.lower_bound); 187*f875b4ebSrica if (str2 == NULL) 188*f875b4ebSrica str2 = gettext("translation failed"); 189*f875b4ebSrica (void) printf(gettext("min_sl: %s\nhex: %s\n"), 190*f875b4ebSrica str, str2); 191*f875b4ebSrica str = sbsltos(&tp.tp_sl_range_cipso.upper_bound, 192*f875b4ebSrica MAX_STRING_SIZE); 193*f875b4ebSrica if (str == NULL) 194*f875b4ebSrica str = gettext("translation failed"); 195*f875b4ebSrica str2 = bsltoh(&tp.tp_sl_range_cipso.upper_bound); 196*f875b4ebSrica if (str2 == NULL) 197*f875b4ebSrica str2 = gettext("translation failed"); 198*f875b4ebSrica (void) printf(gettext("max_sl: %s\nhex: %s\n"), 199*f875b4ebSrica str, str2); 200*f875b4ebSrica 201*f875b4ebSrica l1 = (const blevel_t *)&tp.tp_sl_set_cipso[0]; 202*f875b4ebSrica l2 = (const blevel_t *)&tp.tp_sl_set_cipso[NSLS_MAX]; 203*f875b4ebSrica for (i = 0; l1 < l2; l1++, i++) { 204*f875b4ebSrica if (bisinvalid(l1)) 205*f875b4ebSrica break; 206*f875b4ebSrica str = sbsltos(l1, MAX_STRING_SIZE); 207*f875b4ebSrica if (str == NULL) 208*f875b4ebSrica str = gettext("translation failed"); 209*f875b4ebSrica if ((str2 = bsltoh(l1)) == NULL) 210*f875b4ebSrica str2 = gettext("translation failed"); 211*f875b4ebSrica (void) printf(gettext("sl_set[%1$d]: %2$s\n" 212*f875b4ebSrica "hex: %3$s\n"), i, str, str2); 213*f875b4ebSrica } 214*f875b4ebSrica } 215*f875b4ebSrica break; 216*f875b4ebSrica 217*f875b4ebSrica default: 218*f875b4ebSrica (void) printf(gettext("unsupported host type: %ld\n"), 219*f875b4ebSrica tp.host_type); 220*f875b4ebSrica } 221*f875b4ebSrica return (0); 222*f875b4ebSrica } 223*f875b4ebSrica 224*f875b4ebSrica static int 225*f875b4ebSrica print_rh(const char *rh_name) 226*f875b4ebSrica { 227*f875b4ebSrica int herr; 228*f875b4ebSrica struct hostent *hp; 229*f875b4ebSrica in6_addr_t in6; 230*f875b4ebSrica char abuf[INET6_ADDRSTRLEN]; 231*f875b4ebSrica tsol_rhent_t rhent; 232*f875b4ebSrica 233*f875b4ebSrica if ((hp = getipnodebyname(rh_name, AF_INET6, 234*f875b4ebSrica AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED, &herr)) == NULL) { 235*f875b4ebSrica (void) fprintf(stderr, gettext("tninfo: unknown host or " 236*f875b4ebSrica "invalid literal address: %s\n"), rh_name); 237*f875b4ebSrica if (herr == TRY_AGAIN) 238*f875b4ebSrica (void) fprintf(stderr, 239*f875b4ebSrica gettext("\t(try again later)\n")); 240*f875b4ebSrica return (1); 241*f875b4ebSrica } 242*f875b4ebSrica 243*f875b4ebSrica (void) memset(&rhent, 0, sizeof (rhent)); 244*f875b4ebSrica (void) memcpy(&in6, hp->h_addr, hp->h_length); 245*f875b4ebSrica 246*f875b4ebSrica if (IN6_IS_ADDR_V4MAPPED(&in6)) { 247*f875b4ebSrica rhent.rh_address.ta_family = AF_INET; 248*f875b4ebSrica IN6_V4MAPPED_TO_INADDR(&in6, &rhent.rh_address.ta_addr_v4); 249*f875b4ebSrica (void) inet_ntop(AF_INET, &rhent.rh_address.ta_addr_v4, abuf, 250*f875b4ebSrica sizeof (abuf)); 251*f875b4ebSrica } else { 252*f875b4ebSrica rhent.rh_address.ta_family = AF_INET6; 253*f875b4ebSrica rhent.rh_address.ta_addr_v6 = in6; 254*f875b4ebSrica (void) inet_ntop(AF_INET6, &in6, abuf, sizeof (abuf)); 255*f875b4ebSrica } 256*f875b4ebSrica 257*f875b4ebSrica (void) printf(gettext("IP address= %s\n"), abuf); 258*f875b4ebSrica 259*f875b4ebSrica if (tnrh(TNDB_GET, &rhent) != 0) { 260*f875b4ebSrica if (errno == ENOENT) 261*f875b4ebSrica (void) fprintf(stderr, gettext("tninfo: tnrhdb entry " 262*f875b4ebSrica "%1$s does not exist\n"), abuf); 263*f875b4ebSrica else 264*f875b4ebSrica (void) fprintf(stderr, gettext("tninfo: TNDB_GET(%1$s) " 265*f875b4ebSrica "failed: %2$s\n"), abuf, strerror(errno)); 266*f875b4ebSrica return (1); 267*f875b4ebSrica } 268*f875b4ebSrica 269*f875b4ebSrica if (rhent.rh_template[0] != '\0') 270*f875b4ebSrica (void) printf(gettext("Template = %.*s\n"), TNTNAMSIZ, 271*f875b4ebSrica rhent.rh_template); 272*f875b4ebSrica else 273*f875b4ebSrica (void) printf(gettext("No template exists.\n")); 274*f875b4ebSrica 275*f875b4ebSrica return (0); 276*f875b4ebSrica } 277*f875b4ebSrica 278*f875b4ebSrica static int 279*f875b4ebSrica iterate_mlps(tsol_mlpent_t *tsme, const char *type) 280*f875b4ebSrica { 281*f875b4ebSrica struct protoent *pe; 282*f875b4ebSrica 283*f875b4ebSrica /* get the first entry */ 284*f875b4ebSrica tsme->tsme_mlp.mlp_ipp = 0; 285*f875b4ebSrica tsme->tsme_mlp.mlp_port = 0; 286*f875b4ebSrica tsme->tsme_mlp.mlp_port_upper = 0; 287*f875b4ebSrica if (tnmlp(TNDB_GET, tsme) == -1) { 288*f875b4ebSrica if (errno == ENOENT) { 289*f875b4ebSrica (void) printf(gettext("%s: no entries\n"), type); 290*f875b4ebSrica return (0); 291*f875b4ebSrica } else { 292*f875b4ebSrica perror("tnmlp TNDB_GET"); 293*f875b4ebSrica return (-1); 294*f875b4ebSrica } 295*f875b4ebSrica } 296*f875b4ebSrica (void) printf("%s: ", type); 297*f875b4ebSrica for (;;) { 298*f875b4ebSrica (void) printf("%u", tsme->tsme_mlp.mlp_port); 299*f875b4ebSrica if (tsme->tsme_mlp.mlp_port != tsme->tsme_mlp.mlp_port_upper) 300*f875b4ebSrica (void) printf("-%u", tsme->tsme_mlp.mlp_port_upper); 301*f875b4ebSrica if ((pe = getprotobynumber(tsme->tsme_mlp.mlp_ipp)) == NULL) 302*f875b4ebSrica (void) printf("/%u", tsme->tsme_mlp.mlp_ipp); 303*f875b4ebSrica else 304*f875b4ebSrica (void) printf("/%s", pe->p_name); 305*f875b4ebSrica if (tsme->tsme_mlp.mlp_ipp == 255) { 306*f875b4ebSrica tsme->tsme_mlp.mlp_port++; 307*f875b4ebSrica tsme->tsme_mlp.mlp_ipp = 0; 308*f875b4ebSrica } else { 309*f875b4ebSrica tsme->tsme_mlp.mlp_ipp++; 310*f875b4ebSrica } 311*f875b4ebSrica if (tnmlp(TNDB_GET, tsme) == -1) 312*f875b4ebSrica break; 313*f875b4ebSrica (void) putchar(';'); 314*f875b4ebSrica } 315*f875b4ebSrica (void) putchar('\n'); 316*f875b4ebSrica return (0); 317*f875b4ebSrica } 318*f875b4ebSrica 319*f875b4ebSrica /* 320*f875b4ebSrica * Print all of the MLPs for the given zone. 321*f875b4ebSrica */ 322*f875b4ebSrica static int 323*f875b4ebSrica print_mlp(const char *zonename) 324*f875b4ebSrica { 325*f875b4ebSrica tsol_mlpent_t tsme; 326*f875b4ebSrica 327*f875b4ebSrica if ((tsme.tsme_zoneid = getzoneidbyname(zonename)) == -1) { 328*f875b4ebSrica (void) fprintf(stderr, gettext("tninfo: zone '%s' unknown\n"), 329*f875b4ebSrica zonename); 330*f875b4ebSrica return (1); 331*f875b4ebSrica } 332*f875b4ebSrica tsme.tsme_flags = 0; 333*f875b4ebSrica if (iterate_mlps(&tsme, gettext("private")) == -1) 334*f875b4ebSrica return (1); 335*f875b4ebSrica tsme.tsme_flags = TSOL_MEF_SHARED; 336*f875b4ebSrica if (iterate_mlps(&tsme, gettext("shared")) == -1) 337*f875b4ebSrica return (1); 338*f875b4ebSrica return (0); 339*f875b4ebSrica } 340