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