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