125cf1a30Sjl /*
225cf1a30Sjl  * CDDL HEADER START
325cf1a30Sjl  *
425cf1a30Sjl  * The contents of this file are subject to the terms of the
525cf1a30Sjl  * Common Development and Distribution License (the "License").
625cf1a30Sjl  * You may not use this file except in compliance with the License.
725cf1a30Sjl  *
825cf1a30Sjl  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
925cf1a30Sjl  * or http://www.opensolaris.org/os/licensing.
1025cf1a30Sjl  * See the License for the specific language governing permissions
1125cf1a30Sjl  * and limitations under the License.
1225cf1a30Sjl  *
1325cf1a30Sjl  * When distributing Covered Code, include this CDDL HEADER in each
1425cf1a30Sjl  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1525cf1a30Sjl  * If applicable, add the following below this CDDL HEADER, with the
1625cf1a30Sjl  * fields enclosed by brackets "[]" replaced with your own identifying
1725cf1a30Sjl  * information: Portions Copyright [yyyy] [name of copyright owner]
1825cf1a30Sjl  *
1925cf1a30Sjl  * CDDL HEADER END
2025cf1a30Sjl  */
2125cf1a30Sjl /*
2225cf1a30Sjl  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
2325cf1a30Sjl  * Use is subject to license terms.
2425cf1a30Sjl  */
2525cf1a30Sjl 
2625cf1a30Sjl #include <stdio.h>
2725cf1a30Sjl #include <stdlib.h>
2825cf1a30Sjl #include <stdarg.h>
2925cf1a30Sjl #include <strings.h>
3025cf1a30Sjl #include <sys/types.h>
3125cf1a30Sjl #include <sys/socket.h>
3225cf1a30Sjl #include <netinet/in.h>
3325cf1a30Sjl #include <arpa/inet.h>
3425cf1a30Sjl #include <libintl.h>
3525cf1a30Sjl #include <locale.h>
3625cf1a30Sjl #include <libdscp.h>
3725cf1a30Sjl 
3825cf1a30Sjl #if	!defined(TEXT_DOMAIN)
3925cf1a30Sjl #define	TEXT_DOMAIN "SYS_TEST"
4025cf1a30Sjl #endif
4125cf1a30Sjl 
4225cf1a30Sjl #define	OPT_SP		1
4325cf1a30Sjl #define	OPT_DOMAIN	2
4425cf1a30Sjl 
4525cf1a30Sjl static void	usage(void);
4625cf1a30Sjl static void	parse_options(int, char **, int *);
4725cf1a30Sjl static int	get_address(int, char *);
4825cf1a30Sjl static void	trace(char *, ...);
4925cf1a30Sjl static void	err(char *, ...);
5025cf1a30Sjl static char	*dscp_strerror(int);
5125cf1a30Sjl 
5225cf1a30Sjl static int	verbose = 0;
5325cf1a30Sjl 
5425cf1a30Sjl int
main(int argc,char ** argv)5525cf1a30Sjl main(int argc, char **argv)
5625cf1a30Sjl {
5725cf1a30Sjl 	int	options;
5825cf1a30Sjl 	char	saddr[INET_ADDRSTRLEN];
5925cf1a30Sjl 	char	daddr[INET_ADDRSTRLEN];
6025cf1a30Sjl 
6125cf1a30Sjl 	(void) setlocale(LC_ALL, "");
6225cf1a30Sjl 	(void) textdomain(TEXT_DOMAIN);
6325cf1a30Sjl 
6425cf1a30Sjl 	parse_options(argc, argv, &options);
6525cf1a30Sjl 
6625cf1a30Sjl 	/*
6725cf1a30Sjl 	 * Get the desired IP addresses.
6825cf1a30Sjl 	 */
6925cf1a30Sjl 	if ((options & OPT_SP) != 0) {
7025cf1a30Sjl 		trace(gettext("Looking up SP address...\n"));
7125cf1a30Sjl 		if (get_address(DSCP_ADDR_REMOTE, saddr) < 0) {
72*8bfd22b4Sraghuram 			err(gettext("SP Address lookup failed. Aborting.\n"));
7325cf1a30Sjl 			exit(-1);
7425cf1a30Sjl 		}
7525cf1a30Sjl 	}
7625cf1a30Sjl 	if ((options & OPT_DOMAIN) != 0) {
7725cf1a30Sjl 		trace(gettext("Looking up domain address...\n"));
7825cf1a30Sjl 		if (get_address(DSCP_ADDR_LOCAL, daddr) < 0) {
79*8bfd22b4Sraghuram 			err(gettext("Domain Address lookup failed. "
80*8bfd22b4Sraghuram 			    "Aborting.\n"));
8125cf1a30Sjl 			exit(-1);
8225cf1a30Sjl 		}
8325cf1a30Sjl 	}
8425cf1a30Sjl 
8525cf1a30Sjl 	/*
8625cf1a30Sjl 	 * Print the IP addresses.
8725cf1a30Sjl 	 */
8825cf1a30Sjl 	if (options == OPT_SP) {
8925cf1a30Sjl 		(void) printf("%s\n", saddr);
9025cf1a30Sjl 	} else if (options == OPT_DOMAIN) {
9125cf1a30Sjl 		(void) printf("%s\n", daddr);
9225cf1a30Sjl 	} else {
9325cf1a30Sjl 		(void) printf(gettext("Domain Address: %s\n"), daddr);
9425cf1a30Sjl 		(void) printf(gettext("SP Address: %s\n"), saddr);
9525cf1a30Sjl 	}
9625cf1a30Sjl 
9725cf1a30Sjl 	return (0);
9825cf1a30Sjl }
9925cf1a30Sjl 
10025cf1a30Sjl /*
10125cf1a30Sjl  * parse_options()
10225cf1a30Sjl  *
10325cf1a30Sjl  *	Parse the commandline options.
10425cf1a30Sjl  */
10525cf1a30Sjl static void
parse_options(int argc,char ** argv,int * options)10625cf1a30Sjl parse_options(int argc, char **argv, int *options)
10725cf1a30Sjl {
10825cf1a30Sjl 	int		i;
10925cf1a30Sjl 	int		c;
11025cf1a30Sjl 	extern int	opterr;
11125cf1a30Sjl 	extern int	optopt;
11225cf1a30Sjl 
11325cf1a30Sjl 	/*
11425cf1a30Sjl 	 * Unless told otherwise, print everything.
11525cf1a30Sjl 	 */
11625cf1a30Sjl 	*options = (OPT_SP | OPT_DOMAIN);
11725cf1a30Sjl 
11825cf1a30Sjl 	/*
11925cf1a30Sjl 	 * Skip this routine if no options exist.
12025cf1a30Sjl 	 */
12125cf1a30Sjl 	if (argc == 1) {
12225cf1a30Sjl 		return;
12325cf1a30Sjl 	}
12425cf1a30Sjl 
12525cf1a30Sjl 	/*
12625cf1a30Sjl 	 * Scan for the -h option separately, so that
12725cf1a30Sjl 	 * other commandline options are ignored.
12825cf1a30Sjl 	 */
12925cf1a30Sjl 	for (i = 1; i < argc; i++) {
13025cf1a30Sjl 		if (strcmp(argv[i], "-h") == 0) {
13125cf1a30Sjl 			usage();
13225cf1a30Sjl 			exit(0);
13325cf1a30Sjl 		}
13425cf1a30Sjl 	}
13525cf1a30Sjl 
13625cf1a30Sjl 	/*
13725cf1a30Sjl 	 * Disable the built-in error reporting, so that
13825cf1a30Sjl 	 * error messages can be properly internationalized.
13925cf1a30Sjl 	 */
14025cf1a30Sjl 	opterr = 0;
14125cf1a30Sjl 
14225cf1a30Sjl 	/*
14325cf1a30Sjl 	 * The main loop for parsing options.
14425cf1a30Sjl 	 */
14525cf1a30Sjl 	while ((c = getopt(argc, argv, "vsd")) != -1) {
14625cf1a30Sjl 		switch (c) {
14725cf1a30Sjl 		case 'v':
14825cf1a30Sjl 			verbose = 1;
14925cf1a30Sjl 			break;
15025cf1a30Sjl 		case 's':
15125cf1a30Sjl 			if (*options == OPT_DOMAIN) {
15225cf1a30Sjl 				err(gettext("cannot use -s and -d together"));
15325cf1a30Sjl 				usage();
15425cf1a30Sjl 				exit(-1);
15525cf1a30Sjl 			}
15625cf1a30Sjl 			*options = OPT_SP;
15725cf1a30Sjl 			break;
15825cf1a30Sjl 		case 'd':
15925cf1a30Sjl 			if (*options == OPT_SP) {
16025cf1a30Sjl 				err(gettext("cannot use -s and -d together"));
16125cf1a30Sjl 				usage();
16225cf1a30Sjl 				exit(-1);
16325cf1a30Sjl 			}
16425cf1a30Sjl 			*options = OPT_DOMAIN;
16525cf1a30Sjl 			break;
16625cf1a30Sjl 		default:
16725cf1a30Sjl 			err(gettext("invalid option -%c"), optopt);
16825cf1a30Sjl 			usage();
16925cf1a30Sjl 			exit(-1);
17025cf1a30Sjl 		}
17125cf1a30Sjl 	}
17225cf1a30Sjl }
17325cf1a30Sjl 
17425cf1a30Sjl /*
17525cf1a30Sjl  * usage()
17625cf1a30Sjl  *
17725cf1a30Sjl  *	Print a brief synopsis of the program's usage.
17825cf1a30Sjl  */
17925cf1a30Sjl static void
usage(void)18025cf1a30Sjl usage(void)
18125cf1a30Sjl {
18225cf1a30Sjl 	(void) printf(gettext("Usage:  prtdscp -h \n"));
18325cf1a30Sjl 	(void) printf(gettext("        prtdscp [-v] [-s|-d]\n"));
18425cf1a30Sjl }
18525cf1a30Sjl 
18625cf1a30Sjl /*
18725cf1a30Sjl  * get_address()
18825cf1a30Sjl  *
18925cf1a30Sjl  *	Retrieve a DSCP IP address using libdscp.
19025cf1a30Sjl  */
19125cf1a30Sjl static int
get_address(int which,char * addr)19225cf1a30Sjl get_address(int which, char *addr)
19325cf1a30Sjl {
19425cf1a30Sjl 	int			len;
19525cf1a30Sjl 	int			error;
19625cf1a30Sjl 	struct sockaddr_in	*sin;
19725cf1a30Sjl 	struct sockaddr		saddr;
19825cf1a30Sjl 
19925cf1a30Sjl 	error = dscpAddr(0, which, &saddr, &len);
20025cf1a30Sjl 	if (error != DSCP_OK) {
201*8bfd22b4Sraghuram 		trace(gettext("dscpAddr() failed: %s"), dscp_strerror(error));
20225cf1a30Sjl 		return (-1);
20325cf1a30Sjl 	}
20425cf1a30Sjl 
20525cf1a30Sjl 	/* LINTED pointer cast may result in improper alignment */
20625cf1a30Sjl 	sin = (struct sockaddr_in *)&saddr;
20725cf1a30Sjl 	if (inet_ntop(AF_INET, &(sin->sin_addr), addr, sizeof (*sin)) == NULL) {
208*8bfd22b4Sraghuram 		trace(gettext("address string conversion failed."));
20925cf1a30Sjl 		return (-1);
21025cf1a30Sjl 	}
21125cf1a30Sjl 
21225cf1a30Sjl 	return (0);
21325cf1a30Sjl }
21425cf1a30Sjl 
21525cf1a30Sjl /*
21625cf1a30Sjl  * trace()
21725cf1a30Sjl  *
21825cf1a30Sjl  *	Print tracing statements to stderr when in verbose mode.
21925cf1a30Sjl  */
22025cf1a30Sjl /*PRINTFLIKE1*/
22125cf1a30Sjl static void
trace(char * fmt,...)22225cf1a30Sjl trace(char *fmt, ...)
22325cf1a30Sjl {
22425cf1a30Sjl 	va_list	args;
22525cf1a30Sjl 
22625cf1a30Sjl 	if (verbose != 0) {
22725cf1a30Sjl 		va_start(args, fmt);
22825cf1a30Sjl 		(void) vfprintf(stderr, fmt, args);
22925cf1a30Sjl 		va_end(args);
23025cf1a30Sjl 	}
23125cf1a30Sjl }
23225cf1a30Sjl 
23325cf1a30Sjl /*
23425cf1a30Sjl  * err()
23525cf1a30Sjl  *
23625cf1a30Sjl  *	Print error messages to stderr.
23725cf1a30Sjl  */
23825cf1a30Sjl /*PRINTFLIKE1*/
23925cf1a30Sjl static void
err(char * fmt,...)24025cf1a30Sjl err(char *fmt, ...)
24125cf1a30Sjl {
24225cf1a30Sjl 	va_list	args;
24325cf1a30Sjl 
24425cf1a30Sjl 	va_start(args, fmt);
24525cf1a30Sjl 
24625cf1a30Sjl 	(void) fprintf(stderr, gettext("ERROR: "));
24725cf1a30Sjl 	(void) vfprintf(stderr, fmt, args);
24825cf1a30Sjl 	(void) fprintf(stderr, "\n");
24925cf1a30Sjl 
25025cf1a30Sjl 	va_end(args);
25125cf1a30Sjl }
25225cf1a30Sjl 
25325cf1a30Sjl /*
25425cf1a30Sjl  * dscp_strerror()
25525cf1a30Sjl  *
25625cf1a30Sjl  *	Convert a DSCP error value into a localized string.
25725cf1a30Sjl  */
25825cf1a30Sjl static char *
dscp_strerror(int error)25925cf1a30Sjl dscp_strerror(int error)
26025cf1a30Sjl {
26125cf1a30Sjl 	switch (error) {
26225cf1a30Sjl 	case DSCP_OK:
26325cf1a30Sjl 		return (gettext("Success."));
26425cf1a30Sjl 	case DSCP_ERROR:
26525cf1a30Sjl 		return (gettext("General error."));
26625cf1a30Sjl 	case DSCP_ERROR_ALREADY:
26725cf1a30Sjl 		return (gettext("Socket already bound."));
26825cf1a30Sjl 	case DSCP_ERROR_INVALID:
26925cf1a30Sjl 		return (gettext("Invalid arguments."));
27025cf1a30Sjl 	case DSCP_ERROR_NOENT:
27125cf1a30Sjl 		return (gettext("No entry found."));
27225cf1a30Sjl 	case DSCP_ERROR_DB:
27325cf1a30Sjl 		return (gettext("Error reading database."));
27425cf1a30Sjl 	case DSCP_ERROR_REJECT:
27525cf1a30Sjl 		return (gettext("Connection rejected."));
27625cf1a30Sjl 	default:
27725cf1a30Sjl 		return (gettext("Unknown failure."));
27825cf1a30Sjl 	}
27925cf1a30Sjl }
280