xref: /illumos-gate/usr/src/cmd/prtdscp/sparc/sun4u/prtdscp.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 
47 static void	usage(void);
48 static void	parse_options(int, char **, int *);
49 static int	get_address(int, char *);
50 static void	trace(char *, ...);
51 static void	err(char *, ...);
52 static char	*dscp_strerror(int);
53 
54 static int	verbose = 0;
55 
56 int
57 main(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  */
107 static void
108 parse_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  */
181 static void
182 usage(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  */
193 static int
194 get_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*/
223 static void
224 trace(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*/
241 static void
242 err(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  */
260 static char *
261 dscp_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