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