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
main(int argc,char * argv[])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
usage(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
l_to_str(const m_label_t * l,char ** str,int ltype)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
print_rhtp(const char * rhtp_name)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
print_rh(const char * rh_name)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
iterate_mlps(tsol_mlpent_t * tsme,const char * type)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
print_mlp(const char * zonename)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