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