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