xref: /titanic_50/usr/src/cmd/prtdscp/sparc/sun4u/prtdscp.c (revision 25cf1a301a396c38e8adf52c15f537b80d2483f7)
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 			trace(gettext("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 			trace(gettext("Lookup failed.  Aborting.\n"));
82 			exit(-1);
83 		}
84 	}
85 
86 	/*
87 	 * Print the IP addresses.
88 	 */
89 	if (options == OPT_SP) {
90 		(void) printf("%s\n", saddr);
91 	} else if (options == OPT_DOMAIN) {
92 		(void) printf("%s\n", daddr);
93 	} else {
94 		(void) printf(gettext("Domain Address: %s\n"), daddr);
95 		(void) printf(gettext("SP Address: %s\n"), saddr);
96 	}
97 
98 	return (0);
99 }
100 
101 /*
102  * parse_options()
103  *
104  *	Parse the commandline options.
105  */
106 static void
107 parse_options(int argc, char **argv, int *options)
108 {
109 	int		i;
110 	int		c;
111 	extern int	opterr;
112 	extern int	optopt;
113 
114 	/*
115 	 * Unless told otherwise, print everything.
116 	 */
117 	*options = (OPT_SP | OPT_DOMAIN);
118 
119 	/*
120 	 * Skip this routine if no options exist.
121 	 */
122 	if (argc == 1) {
123 		return;
124 	}
125 
126 	/*
127 	 * Scan for the -h option separately, so that
128 	 * other commandline options are ignored.
129 	 */
130 	for (i = 1; i < argc; i++) {
131 		if (strcmp(argv[i], "-h") == 0) {
132 			usage();
133 			exit(0);
134 		}
135 	}
136 
137 	/*
138 	 * Disable the built-in error reporting, so that
139 	 * error messages can be properly internationalized.
140 	 */
141 	opterr = 0;
142 
143 	/*
144 	 * The main loop for parsing options.
145 	 */
146 	while ((c = getopt(argc, argv, "vsd")) != -1) {
147 		switch (c) {
148 		case 'v':
149 			verbose = 1;
150 			break;
151 		case 's':
152 			if (*options == OPT_DOMAIN) {
153 				err(gettext("cannot use -s and -d together"));
154 				usage();
155 				exit(-1);
156 			}
157 			*options = OPT_SP;
158 			break;
159 		case 'd':
160 			if (*options == OPT_SP) {
161 				err(gettext("cannot use -s and -d together"));
162 				usage();
163 				exit(-1);
164 			}
165 			*options = OPT_DOMAIN;
166 			break;
167 		default:
168 			err(gettext("invalid option -%c"), optopt);
169 			usage();
170 			exit(-1);
171 		}
172 	}
173 }
174 
175 /*
176  * usage()
177  *
178  *	Print a brief synopsis of the program's usage.
179  */
180 static void
181 usage(void)
182 {
183 	(void) printf(gettext("Usage:  prtdscp -h \n"));
184 	(void) printf(gettext("        prtdscp [-v] [-s|-d]\n"));
185 }
186 
187 /*
188  * get_address()
189  *
190  *	Retrieve a DSCP IP address using libdscp.
191  */
192 static int
193 get_address(int which, char *addr)
194 {
195 	int			len;
196 	int			error;
197 	struct sockaddr_in	*sin;
198 	struct sockaddr		saddr;
199 
200 	error = dscpAddr(0, which, &saddr, &len);
201 	if (error != DSCP_OK) {
202 		err(gettext("dscpAddr() failed: %s"), dscp_strerror(error));
203 		return (-1);
204 	}
205 
206 	/* LINTED pointer cast may result in improper alignment */
207 	sin = (struct sockaddr_in *)&saddr;
208 	if (inet_ntop(AF_INET, &(sin->sin_addr), addr, sizeof (*sin)) == NULL) {
209 		err(gettext("address string conversion failed."));
210 		return (-1);
211 	}
212 
213 	return (0);
214 }
215 
216 /*
217  * trace()
218  *
219  *	Print tracing statements to stderr when in verbose mode.
220  */
221 /*PRINTFLIKE1*/
222 static void
223 trace(char *fmt, ...)
224 {
225 	va_list	args;
226 
227 	if (verbose != 0) {
228 		va_start(args, fmt);
229 		(void) vfprintf(stderr, fmt, args);
230 		va_end(args);
231 	}
232 }
233 
234 /*
235  * err()
236  *
237  *	Print error messages to stderr.
238  */
239 /*PRINTFLIKE1*/
240 static void
241 err(char *fmt, ...)
242 {
243 	va_list	args;
244 
245 	va_start(args, fmt);
246 
247 	(void) fprintf(stderr, gettext("ERROR: "));
248 	(void) vfprintf(stderr, fmt, args);
249 	(void) fprintf(stderr, "\n");
250 
251 	va_end(args);
252 }
253 
254 /*
255  * dscp_strerror()
256  *
257  *	Convert a DSCP error value into a localized string.
258  */
259 static char *
260 dscp_strerror(int error)
261 {
262 	switch (error) {
263 	case DSCP_OK:
264 		return (gettext("Success."));
265 	case DSCP_ERROR:
266 		return (gettext("General error."));
267 	case DSCP_ERROR_ALREADY:
268 		return (gettext("Socket already bound."));
269 	case DSCP_ERROR_INVALID:
270 		return (gettext("Invalid arguments."));
271 	case DSCP_ERROR_NOENT:
272 		return (gettext("No entry found."));
273 	case DSCP_ERROR_DB:
274 		return (gettext("Error reading database."));
275 	case DSCP_ERROR_REJECT:
276 		return (gettext("Connection rejected."));
277 	default:
278 		return (gettext("Unknown failure."));
279 	}
280 }
281