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
main(int argc,char ** argv)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
parse_options(int argc,char ** argv,int * options)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
usage(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
get_address(int which,char * addr)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
trace(char * fmt,...)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
err(char * fmt,...)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 *
dscp_strerror(int error)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