prtdscp.c revision 1870:e2dc1d5bbd2c
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 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#pragma ident	"%Z%%M%	%I%	%E% SMI"
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <stdarg.h>
31#include <strings.h>
32#include <sys/types.h>
33#include <sys/socket.h>
34#include <netinet/in.h>
35#include <arpa/inet.h>
36#include <libintl.h>
37#include <locale.h>
38#include <libdscp.h>
39
40#if	!defined(TEXT_DOMAIN)
41#define	TEXT_DOMAIN "SYS_TEST"
42#endif
43
44#define	OPT_SP		1
45#define	OPT_DOMAIN	2
46
47static void	usage(void);
48static void	parse_options(int, char **, int *);
49static int	get_address(int, char *);
50static void	trace(char *, ...);
51static void	err(char *, ...);
52static char	*dscp_strerror(int);
53
54static int	verbose = 0;
55
56int
57main(int argc, char **argv)
58{
59	int	options;
60	char	saddr[INET_ADDRSTRLEN];
61	char	daddr[INET_ADDRSTRLEN];
62
63	(void) setlocale(LC_ALL, "");
64	(void) textdomain(TEXT_DOMAIN);
65
66	parse_options(argc, argv, &options);
67
68	/*
69	 * Get the desired IP addresses.
70	 */
71	if ((options & OPT_SP) != 0) {
72		trace(gettext("Looking up SP address...\n"));
73		if (get_address(DSCP_ADDR_REMOTE, saddr) < 0) {
74			err(gettext("SP Address lookup failed. Aborting.\n"));
75			exit(-1);
76		}
77	}
78	if ((options & OPT_DOMAIN) != 0) {
79		trace(gettext("Looking up domain address...\n"));
80		if (get_address(DSCP_ADDR_LOCAL, daddr) < 0) {
81			err(gettext("Domain Address lookup failed. "
82			    "Aborting.\n"));
83			exit(-1);
84		}
85	}
86
87	/*
88	 * Print the IP addresses.
89	 */
90	if (options == OPT_SP) {
91		(void) printf("%s\n", saddr);
92	} else if (options == OPT_DOMAIN) {
93		(void) printf("%s\n", daddr);
94	} else {
95		(void) printf(gettext("Domain Address: %s\n"), daddr);
96		(void) printf(gettext("SP Address: %s\n"), saddr);
97	}
98
99	return (0);
100}
101
102/*
103 * parse_options()
104 *
105 *	Parse the commandline options.
106 */
107static void
108parse_options(int argc, char **argv, int *options)
109{
110	int		i;
111	int		c;
112	extern int	opterr;
113	extern int	optopt;
114
115	/*
116	 * Unless told otherwise, print everything.
117	 */
118	*options = (OPT_SP | OPT_DOMAIN);
119
120	/*
121	 * Skip this routine if no options exist.
122	 */
123	if (argc == 1) {
124		return;
125	}
126
127	/*
128	 * Scan for the -h option separately, so that
129	 * other commandline options are ignored.
130	 */
131	for (i = 1; i < argc; i++) {
132		if (strcmp(argv[i], "-h") == 0) {
133			usage();
134			exit(0);
135		}
136	}
137
138	/*
139	 * Disable the built-in error reporting, so that
140	 * error messages can be properly internationalized.
141	 */
142	opterr = 0;
143
144	/*
145	 * The main loop for parsing options.
146	 */
147	while ((c = getopt(argc, argv, "vsd")) != -1) {
148		switch (c) {
149		case 'v':
150			verbose = 1;
151			break;
152		case 's':
153			if (*options == OPT_DOMAIN) {
154				err(gettext("cannot use -s and -d together"));
155				usage();
156				exit(-1);
157			}
158			*options = OPT_SP;
159			break;
160		case 'd':
161			if (*options == OPT_SP) {
162				err(gettext("cannot use -s and -d together"));
163				usage();
164				exit(-1);
165			}
166			*options = OPT_DOMAIN;
167			break;
168		default:
169			err(gettext("invalid option -%c"), optopt);
170			usage();
171			exit(-1);
172		}
173	}
174}
175
176/*
177 * usage()
178 *
179 *	Print a brief synopsis of the program's usage.
180 */
181static void
182usage(void)
183{
184	(void) printf(gettext("Usage:  prtdscp -h \n"));
185	(void) printf(gettext("        prtdscp [-v] [-s|-d]\n"));
186}
187
188/*
189 * get_address()
190 *
191 *	Retrieve a DSCP IP address using libdscp.
192 */
193static int
194get_address(int which, char *addr)
195{
196	int			len;
197	int			error;
198	struct sockaddr_in	*sin;
199	struct sockaddr		saddr;
200
201	error = dscpAddr(0, which, &saddr, &len);
202	if (error != DSCP_OK) {
203		trace(gettext("dscpAddr() failed: %s"), dscp_strerror(error));
204		return (-1);
205	}
206
207	/* LINTED pointer cast may result in improper alignment */
208	sin = (struct sockaddr_in *)&saddr;
209	if (inet_ntop(AF_INET, &(sin->sin_addr), addr, sizeof (*sin)) == NULL) {
210		trace(gettext("address string conversion failed."));
211		return (-1);
212	}
213
214	return (0);
215}
216
217/*
218 * trace()
219 *
220 *	Print tracing statements to stderr when in verbose mode.
221 */
222/*PRINTFLIKE1*/
223static void
224trace(char *fmt, ...)
225{
226	va_list	args;
227
228	if (verbose != 0) {
229		va_start(args, fmt);
230		(void) vfprintf(stderr, fmt, args);
231		va_end(args);
232	}
233}
234
235/*
236 * err()
237 *
238 *	Print error messages to stderr.
239 */
240/*PRINTFLIKE1*/
241static void
242err(char *fmt, ...)
243{
244	va_list	args;
245
246	va_start(args, fmt);
247
248	(void) fprintf(stderr, gettext("ERROR: "));
249	(void) vfprintf(stderr, fmt, args);
250	(void) fprintf(stderr, "\n");
251
252	va_end(args);
253}
254
255/*
256 * dscp_strerror()
257 *
258 *	Convert a DSCP error value into a localized string.
259 */
260static char *
261dscp_strerror(int error)
262{
263	switch (error) {
264	case DSCP_OK:
265		return (gettext("Success."));
266	case DSCP_ERROR:
267		return (gettext("General error."));
268	case DSCP_ERROR_ALREADY:
269		return (gettext("Socket already bound."));
270	case DSCP_ERROR_INVALID:
271		return (gettext("Invalid arguments."));
272	case DSCP_ERROR_NOENT:
273		return (gettext("No entry found."));
274	case DSCP_ERROR_DB:
275		return (gettext("Error reading database."));
276	case DSCP_ERROR_REJECT:
277		return (gettext("Connection rejected."));
278	default:
279		return (gettext("Unknown failure."));
280	}
281}
282