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