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