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 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 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 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 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 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 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 * 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