1*59596c01SRobert Mustacchi /* 2*59596c01SRobert Mustacchi * This file and its contents are supplied under the terms of the 3*59596c01SRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0. 4*59596c01SRobert Mustacchi * You may only use this file in accordance with the terms of version 5*59596c01SRobert Mustacchi * 1.0 of the CDDL. 6*59596c01SRobert Mustacchi * 7*59596c01SRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this 8*59596c01SRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at 9*59596c01SRobert Mustacchi * http://www.illumos.org/license/CDDL. 10*59596c01SRobert Mustacchi */ 11*59596c01SRobert Mustacchi 12*59596c01SRobert Mustacchi /* 13*59596c01SRobert Mustacchi * Copyright (c) 2017, Joyent, Inc. 14*59596c01SRobert Mustacchi */ 15*59596c01SRobert Mustacchi 16*59596c01SRobert Mustacchi /* 17*59596c01SRobert Mustacchi * Private utility to dump transceiver information for each physical datalink. 18*59596c01SRobert Mustacchi * Something like this should eventually be a part of dladm or similar. 19*59596c01SRobert Mustacchi */ 20*59596c01SRobert Mustacchi 21*59596c01SRobert Mustacchi #include <stdio.h> 22*59596c01SRobert Mustacchi #include <sys/types.h> 23*59596c01SRobert Mustacchi #include <sys/stat.h> 24*59596c01SRobert Mustacchi #include <fcntl.h> 25*59596c01SRobert Mustacchi #include <strings.h> 26*59596c01SRobert Mustacchi #include <errno.h> 27*59596c01SRobert Mustacchi #include <ctype.h> 28*59596c01SRobert Mustacchi #include <unistd.h> 29*59596c01SRobert Mustacchi #include <limits.h> 30*59596c01SRobert Mustacchi #include <stdarg.h> 31*59596c01SRobert Mustacchi #include <libgen.h> 32*59596c01SRobert Mustacchi 33*59596c01SRobert Mustacchi #include <libdladm.h> 34*59596c01SRobert Mustacchi #include <libdllink.h> 35*59596c01SRobert Mustacchi #include <sys/dld.h> 36*59596c01SRobert Mustacchi #include <sys/dld_ioc.h> 37*59596c01SRobert Mustacchi #include <sys/dls_mgmt.h> 38*59596c01SRobert Mustacchi #include <libsff.h> 39*59596c01SRobert Mustacchi 40*59596c01SRobert Mustacchi #define DLTRAN_KIND_LEN 64 41*59596c01SRobert Mustacchi 42*59596c01SRobert Mustacchi static dladm_handle_t dltran_hdl; 43*59596c01SRobert Mustacchi static char dltran_dlerrmsg[DLADM_STRSIZE]; 44*59596c01SRobert Mustacchi static const char *dltran_progname; 45*59596c01SRobert Mustacchi static boolean_t dltran_verbose; 46*59596c01SRobert Mustacchi static boolean_t dltran_hex; 47*59596c01SRobert Mustacchi static boolean_t dltran_write; 48*59596c01SRobert Mustacchi static int dltran_outfd; 49*59596c01SRobert Mustacchi static int dltran_errors; 50*59596c01SRobert Mustacchi 51*59596c01SRobert Mustacchi /* 52*59596c01SRobert Mustacchi * This routine basically assumes that we'll have 16 byte aligned output to 53*59596c01SRobert Mustacchi * print out the human readable output. 54*59596c01SRobert Mustacchi */ 55*59596c01SRobert Mustacchi static void 56*59596c01SRobert Mustacchi dltran_dump_page(uint8_t *buf, size_t nbytes, uint_t page) 57*59596c01SRobert Mustacchi { 58*59596c01SRobert Mustacchi size_t i; 59*59596c01SRobert Mustacchi static boolean_t first = B_TRUE; 60*59596c01SRobert Mustacchi 61*59596c01SRobert Mustacchi if (first) { 62*59596c01SRobert Mustacchi (void) printf("page %*s 0", 4, ""); 63*59596c01SRobert Mustacchi for (i = 1; i < 16; i++) { 64*59596c01SRobert Mustacchi if (i % 4 == 0 && i % 16 != 0) { 65*59596c01SRobert Mustacchi (void) printf(" "); 66*59596c01SRobert Mustacchi } 67*59596c01SRobert Mustacchi 68*59596c01SRobert Mustacchi (void) printf("%2x", i); 69*59596c01SRobert Mustacchi } 70*59596c01SRobert Mustacchi (void) printf(" v123456789abcdef\n"); 71*59596c01SRobert Mustacchi first = B_FALSE; 72*59596c01SRobert Mustacchi } 73*59596c01SRobert Mustacchi for (i = 0; i < nbytes; i++) { 74*59596c01SRobert Mustacchi 75*59596c01SRobert Mustacchi if (i % 16 == 0) { 76*59596c01SRobert Mustacchi (void) printf("0x%02x %04x: ", page, i); 77*59596c01SRobert Mustacchi } 78*59596c01SRobert Mustacchi 79*59596c01SRobert Mustacchi if (i % 4 == 0 && i % 16 != 0) { 80*59596c01SRobert Mustacchi (void) printf(" "); 81*59596c01SRobert Mustacchi } 82*59596c01SRobert Mustacchi 83*59596c01SRobert Mustacchi 84*59596c01SRobert Mustacchi (void) printf("%02x", buf[i]); 85*59596c01SRobert Mustacchi 86*59596c01SRobert Mustacchi if (i % 16 == 15) { 87*59596c01SRobert Mustacchi int j; 88*59596c01SRobert Mustacchi (void) printf(" "); 89*59596c01SRobert Mustacchi for (j = i - (i % 16); j <= i; j++) { 90*59596c01SRobert Mustacchi if (!isprint(buf[j])) { 91*59596c01SRobert Mustacchi (void) printf("."); 92*59596c01SRobert Mustacchi } else { 93*59596c01SRobert Mustacchi (void) printf("%c", buf[j]); 94*59596c01SRobert Mustacchi } 95*59596c01SRobert Mustacchi } 96*59596c01SRobert Mustacchi (void) printf("\n"); 97*59596c01SRobert Mustacchi } 98*59596c01SRobert Mustacchi } 99*59596c01SRobert Mustacchi } 100*59596c01SRobert Mustacchi 101*59596c01SRobert Mustacchi static int 102*59596c01SRobert Mustacchi dltran_read_page(datalink_id_t link, uint_t tranid, uint_t page, uint8_t *bufp, 103*59596c01SRobert Mustacchi size_t *buflen) 104*59596c01SRobert Mustacchi { 105*59596c01SRobert Mustacchi dld_ioc_tranio_t dti; 106*59596c01SRobert Mustacchi 107*59596c01SRobert Mustacchi bzero(bufp, *buflen); 108*59596c01SRobert Mustacchi bzero(&dti, sizeof (dti)); 109*59596c01SRobert Mustacchi 110*59596c01SRobert Mustacchi dti.dti_linkid = link; 111*59596c01SRobert Mustacchi dti.dti_tran_id = tranid; 112*59596c01SRobert Mustacchi dti.dti_page = page; 113*59596c01SRobert Mustacchi dti.dti_nbytes = *buflen; 114*59596c01SRobert Mustacchi dti.dti_off = 0; 115*59596c01SRobert Mustacchi dti.dti_buf = (uintptr_t)(void *)bufp; 116*59596c01SRobert Mustacchi 117*59596c01SRobert Mustacchi if (ioctl(dladm_dld_fd(dltran_hdl), DLDIOC_READTRAN, &dti) != 0) { 118*59596c01SRobert Mustacchi (void) fprintf(stderr, "failed to read transceiver page " 119*59596c01SRobert Mustacchi "0x%2x: %s\n", page, strerror(errno)); 120*59596c01SRobert Mustacchi return (1); 121*59596c01SRobert Mustacchi } 122*59596c01SRobert Mustacchi 123*59596c01SRobert Mustacchi *buflen = dti.dti_nbytes; 124*59596c01SRobert Mustacchi return (0); 125*59596c01SRobert Mustacchi } 126*59596c01SRobert Mustacchi 127*59596c01SRobert Mustacchi static boolean_t 128*59596c01SRobert Mustacchi dltran_is_8472(uint8_t *buf) 129*59596c01SRobert Mustacchi { 130*59596c01SRobert Mustacchi switch (buf[0]) { 131*59596c01SRobert Mustacchi case 0xc: 132*59596c01SRobert Mustacchi case 0xd: 133*59596c01SRobert Mustacchi case 0x11: 134*59596c01SRobert Mustacchi /* 135*59596c01SRobert Mustacchi * Catch cases that refer explicitly to QSFP and newer. 136*59596c01SRobert Mustacchi */ 137*59596c01SRobert Mustacchi return (B_FALSE); 138*59596c01SRobert Mustacchi default: 139*59596c01SRobert Mustacchi break; 140*59596c01SRobert Mustacchi } 141*59596c01SRobert Mustacchi 142*59596c01SRobert Mustacchi /* 143*59596c01SRobert Mustacchi * Check the byte that indicates compliance with SFF 8472. Use this to 144*59596c01SRobert Mustacchi * know if we can read page 0xa2 or not. 145*59596c01SRobert Mustacchi */ 146*59596c01SRobert Mustacchi if (buf[94] == 0) 147*59596c01SRobert Mustacchi return (B_FALSE); 148*59596c01SRobert Mustacchi 149*59596c01SRobert Mustacchi return (B_TRUE); 150*59596c01SRobert Mustacchi } 151*59596c01SRobert Mustacchi 152*59596c01SRobert Mustacchi static void 153*59596c01SRobert Mustacchi dltran_hex_dump(datalink_id_t linkid, uint_t tranid) 154*59596c01SRobert Mustacchi { 155*59596c01SRobert Mustacchi uint8_t buf[256]; 156*59596c01SRobert Mustacchi size_t buflen = sizeof (buf); 157*59596c01SRobert Mustacchi 158*59596c01SRobert Mustacchi if (dltran_read_page(linkid, tranid, 0xa0, buf, &buflen) != 0) { 159*59596c01SRobert Mustacchi dltran_errors++; 160*59596c01SRobert Mustacchi return; 161*59596c01SRobert Mustacchi } 162*59596c01SRobert Mustacchi 163*59596c01SRobert Mustacchi dltran_dump_page(buf, buflen, 0xa0); 164*59596c01SRobert Mustacchi 165*59596c01SRobert Mustacchi if (!dltran_is_8472(buf)) { 166*59596c01SRobert Mustacchi return; 167*59596c01SRobert Mustacchi } 168*59596c01SRobert Mustacchi 169*59596c01SRobert Mustacchi buflen = sizeof (buf); 170*59596c01SRobert Mustacchi if (dltran_read_page(linkid, tranid, 0xa2, buf, &buflen) != 0) { 171*59596c01SRobert Mustacchi dltran_errors++; 172*59596c01SRobert Mustacchi return; 173*59596c01SRobert Mustacchi } 174*59596c01SRobert Mustacchi 175*59596c01SRobert Mustacchi dltran_dump_page(buf, buflen, 0xa2); 176*59596c01SRobert Mustacchi } 177*59596c01SRobert Mustacchi 178*59596c01SRobert Mustacchi static void 179*59596c01SRobert Mustacchi dltran_write_page(datalink_id_t linkid, uint_t tranid) 180*59596c01SRobert Mustacchi { 181*59596c01SRobert Mustacchi uint8_t buf[256]; 182*59596c01SRobert Mustacchi size_t buflen = sizeof (buf); 183*59596c01SRobert Mustacchi off_t off; 184*59596c01SRobert Mustacchi 185*59596c01SRobert Mustacchi if (dltran_read_page(linkid, tranid, 0xa0, buf, &buflen) != 0) { 186*59596c01SRobert Mustacchi dltran_errors++; 187*59596c01SRobert Mustacchi return; 188*59596c01SRobert Mustacchi } 189*59596c01SRobert Mustacchi 190*59596c01SRobert Mustacchi off = 0; 191*59596c01SRobert Mustacchi while (buflen > 0) { 192*59596c01SRobert Mustacchi ssize_t ret; 193*59596c01SRobert Mustacchi 194*59596c01SRobert Mustacchi ret = write(dltran_outfd, buf + off, buflen); 195*59596c01SRobert Mustacchi if (ret == -1) { 196*59596c01SRobert Mustacchi (void) fprintf(stderr, "failed to write data " 197*59596c01SRobert Mustacchi "to output file: %s\n", strerror(errno)); 198*59596c01SRobert Mustacchi dltran_errors++; 199*59596c01SRobert Mustacchi return; 200*59596c01SRobert Mustacchi } 201*59596c01SRobert Mustacchi 202*59596c01SRobert Mustacchi off += ret; 203*59596c01SRobert Mustacchi buflen -= ret; 204*59596c01SRobert Mustacchi } 205*59596c01SRobert Mustacchi } 206*59596c01SRobert Mustacchi 207*59596c01SRobert Mustacchi static void 208*59596c01SRobert Mustacchi dltran_verbose_dump(datalink_id_t linkid, uint_t tranid) 209*59596c01SRobert Mustacchi { 210*59596c01SRobert Mustacchi uint8_t buf[256]; 211*59596c01SRobert Mustacchi size_t buflen = sizeof (buf); 212*59596c01SRobert Mustacchi int ret; 213*59596c01SRobert Mustacchi nvlist_t *nvl; 214*59596c01SRobert Mustacchi 215*59596c01SRobert Mustacchi if (dltran_read_page(linkid, tranid, 0xa0, buf, &buflen) != 0) { 216*59596c01SRobert Mustacchi dltran_errors++; 217*59596c01SRobert Mustacchi return; 218*59596c01SRobert Mustacchi } 219*59596c01SRobert Mustacchi 220*59596c01SRobert Mustacchi ret = libsff_parse(buf, buflen, 0xa0, &nvl); 221*59596c01SRobert Mustacchi if (ret == 0) { 222*59596c01SRobert Mustacchi dump_nvlist(nvl, 8); 223*59596c01SRobert Mustacchi nvlist_free(nvl); 224*59596c01SRobert Mustacchi } else { 225*59596c01SRobert Mustacchi fprintf(stderr, "failed to parse sfp data: %s\n", 226*59596c01SRobert Mustacchi strerror(ret)); 227*59596c01SRobert Mustacchi dltran_errors++; 228*59596c01SRobert Mustacchi } 229*59596c01SRobert Mustacchi } 230*59596c01SRobert Mustacchi 231*59596c01SRobert Mustacchi static int 232*59596c01SRobert Mustacchi dltran_dump_transceivers(dladm_handle_t hdl, datalink_id_t linkid, void *arg) 233*59596c01SRobert Mustacchi { 234*59596c01SRobert Mustacchi dladm_status_t status; 235*59596c01SRobert Mustacchi char name[MAXLINKNAMELEN]; 236*59596c01SRobert Mustacchi dld_ioc_gettran_t gt; 237*59596c01SRobert Mustacchi uint_t count, i, tranid = UINT_MAX; 238*59596c01SRobert Mustacchi boolean_t tran_found = B_FALSE; 239*59596c01SRobert Mustacchi uint_t *tranidp = arg; 240*59596c01SRobert Mustacchi 241*59596c01SRobert Mustacchi if (tranidp != NULL) 242*59596c01SRobert Mustacchi tranid = *tranidp; 243*59596c01SRobert Mustacchi 244*59596c01SRobert Mustacchi if ((status = dladm_datalink_id2info(hdl, linkid, NULL, NULL, NULL, 245*59596c01SRobert Mustacchi name, sizeof (name))) != DLADM_STATUS_OK) { 246*59596c01SRobert Mustacchi (void) fprintf(stderr, "failed to get datalink name for link " 247*59596c01SRobert Mustacchi "%d: %s", linkid, dladm_status2str(status, 248*59596c01SRobert Mustacchi dltran_dlerrmsg)); 249*59596c01SRobert Mustacchi dltran_errors++; 250*59596c01SRobert Mustacchi return (DLADM_WALK_CONTINUE); 251*59596c01SRobert Mustacchi } 252*59596c01SRobert Mustacchi 253*59596c01SRobert Mustacchi bzero(>, sizeof (gt)); 254*59596c01SRobert Mustacchi gt.dgt_linkid = linkid; 255*59596c01SRobert Mustacchi gt.dgt_tran_id = DLDIOC_GETTRAN_GETNTRAN; 256*59596c01SRobert Mustacchi 257*59596c01SRobert Mustacchi if (ioctl(dladm_dld_fd(hdl), DLDIOC_GETTRAN, >) != 0) { 258*59596c01SRobert Mustacchi if (errno != ENOTSUP) { 259*59596c01SRobert Mustacchi (void) fprintf(stderr, "failed to get transceiver " 260*59596c01SRobert Mustacchi "count for device %s: %s\n", 261*59596c01SRobert Mustacchi name, strerror(errno)); 262*59596c01SRobert Mustacchi dltran_errors++; 263*59596c01SRobert Mustacchi } 264*59596c01SRobert Mustacchi return (DLADM_WALK_CONTINUE); 265*59596c01SRobert Mustacchi } 266*59596c01SRobert Mustacchi 267*59596c01SRobert Mustacchi count = gt.dgt_tran_id; 268*59596c01SRobert Mustacchi (void) printf("%s: discovered %d transceiver%s\n", name, count, 269*59596c01SRobert Mustacchi count > 1 ? "s" : ""); 270*59596c01SRobert Mustacchi for (i = 0; i < count; i++) { 271*59596c01SRobert Mustacchi if (tranid != UINT_MAX && i != tranid) 272*59596c01SRobert Mustacchi continue; 273*59596c01SRobert Mustacchi if (tranid != UINT_MAX) 274*59596c01SRobert Mustacchi tran_found = B_TRUE; 275*59596c01SRobert Mustacchi bzero(>, sizeof (gt)); 276*59596c01SRobert Mustacchi gt.dgt_linkid = linkid; 277*59596c01SRobert Mustacchi gt.dgt_tran_id = i; 278*59596c01SRobert Mustacchi 279*59596c01SRobert Mustacchi if (ioctl(dladm_dld_fd(hdl), DLDIOC_GETTRAN, >) != 0) { 280*59596c01SRobert Mustacchi (void) fprintf(stderr, "failed to get tran info for " 281*59596c01SRobert Mustacchi "%s: %s\n", name, strerror(errno)); 282*59596c01SRobert Mustacchi dltran_errors++; 283*59596c01SRobert Mustacchi return (DLADM_WALK_CONTINUE); 284*59596c01SRobert Mustacchi } 285*59596c01SRobert Mustacchi 286*59596c01SRobert Mustacchi if (dltran_hex && !gt.dgt_present) 287*59596c01SRobert Mustacchi continue; 288*59596c01SRobert Mustacchi if (!dltran_hex && !dltran_write) { 289*59596c01SRobert Mustacchi (void) printf("\ttransceiver %d present: %s\n", i, 290*59596c01SRobert Mustacchi gt.dgt_present ? "yes" : "no"); 291*59596c01SRobert Mustacchi if (!gt.dgt_present) 292*59596c01SRobert Mustacchi continue; 293*59596c01SRobert Mustacchi (void) printf("\ttransceiver %d usable: %s\n", i, 294*59596c01SRobert Mustacchi gt.dgt_usable ? "yes" : "no"); 295*59596c01SRobert Mustacchi } 296*59596c01SRobert Mustacchi 297*59596c01SRobert Mustacchi if (dltran_verbose) { 298*59596c01SRobert Mustacchi dltran_verbose_dump(linkid, i); 299*59596c01SRobert Mustacchi } 300*59596c01SRobert Mustacchi 301*59596c01SRobert Mustacchi if (dltran_write) { 302*59596c01SRobert Mustacchi if (!gt.dgt_present) { 303*59596c01SRobert Mustacchi (void) fprintf(stderr, "warning: no " 304*59596c01SRobert Mustacchi "transceiver present in port %d, not " 305*59596c01SRobert Mustacchi "writing\n", i); 306*59596c01SRobert Mustacchi dltran_errors++; 307*59596c01SRobert Mustacchi continue; 308*59596c01SRobert Mustacchi } 309*59596c01SRobert Mustacchi dltran_write_page(linkid, i); 310*59596c01SRobert Mustacchi } 311*59596c01SRobert Mustacchi 312*59596c01SRobert Mustacchi if (dltran_hex) { 313*59596c01SRobert Mustacchi printf("transceiver %d data:\n", i); 314*59596c01SRobert Mustacchi dltran_hex_dump(linkid, i); 315*59596c01SRobert Mustacchi } 316*59596c01SRobert Mustacchi } 317*59596c01SRobert Mustacchi 318*59596c01SRobert Mustacchi if (tranid != UINT_MAX && !tran_found) { 319*59596c01SRobert Mustacchi dltran_errors++; 320*59596c01SRobert Mustacchi (void) fprintf(stderr, "failed to find transceiver %d on " 321*59596c01SRobert Mustacchi "link %s\n", tranid, name); 322*59596c01SRobert Mustacchi } 323*59596c01SRobert Mustacchi 324*59596c01SRobert Mustacchi return (DLADM_WALK_CONTINUE); 325*59596c01SRobert Mustacchi } 326*59596c01SRobert Mustacchi 327*59596c01SRobert Mustacchi 328*59596c01SRobert Mustacchi static void 329*59596c01SRobert Mustacchi dltran_usage(const char *fmt, ...) 330*59596c01SRobert Mustacchi { 331*59596c01SRobert Mustacchi if (fmt != NULL) { 332*59596c01SRobert Mustacchi va_list ap; 333*59596c01SRobert Mustacchi 334*59596c01SRobert Mustacchi (void) fprintf(stderr, "%s: ", dltran_progname); 335*59596c01SRobert Mustacchi va_start(ap, fmt); 336*59596c01SRobert Mustacchi (void) vfprintf(stderr, fmt, ap); 337*59596c01SRobert Mustacchi va_end(ap); 338*59596c01SRobert Mustacchi } 339*59596c01SRobert Mustacchi 340*59596c01SRobert Mustacchi (void) fprintf(stderr, "Usage: %s [-x | -v | -w file] [tran]...\n" 341*59596c01SRobert Mustacchi "\n" 342*59596c01SRobert Mustacchi "\t-v display all transceiver information\n" 343*59596c01SRobert Mustacchi "\t-w write transceiver data page 0xa0 to file\n" 344*59596c01SRobert Mustacchi "\t-x dump raw hexadecimal for transceiver\n", 345*59596c01SRobert Mustacchi dltran_progname); 346*59596c01SRobert Mustacchi } 347*59596c01SRobert Mustacchi 348*59596c01SRobert Mustacchi int 349*59596c01SRobert Mustacchi main(int argc, char *argv[]) 350*59596c01SRobert Mustacchi { 351*59596c01SRobert Mustacchi int c; 352*59596c01SRobert Mustacchi dladm_status_t status; 353*59596c01SRobert Mustacchi const char *outfile = NULL; 354*59596c01SRobert Mustacchi uint_t count = 0; 355*59596c01SRobert Mustacchi 356*59596c01SRobert Mustacchi dltran_progname = basename(argv[0]); 357*59596c01SRobert Mustacchi 358*59596c01SRobert Mustacchi while ((c = getopt(argc, argv, ":xvw:")) != -1) { 359*59596c01SRobert Mustacchi switch (c) { 360*59596c01SRobert Mustacchi case 'v': 361*59596c01SRobert Mustacchi dltran_verbose = B_TRUE; 362*59596c01SRobert Mustacchi break; 363*59596c01SRobert Mustacchi case 'x': 364*59596c01SRobert Mustacchi dltran_hex = B_TRUE; 365*59596c01SRobert Mustacchi break; 366*59596c01SRobert Mustacchi case 'w': 367*59596c01SRobert Mustacchi dltran_write = B_TRUE; 368*59596c01SRobert Mustacchi outfile = optarg; 369*59596c01SRobert Mustacchi break; 370*59596c01SRobert Mustacchi case ':': 371*59596c01SRobert Mustacchi dltran_usage("option -%c requires an " 372*59596c01SRobert Mustacchi "operand\n", optopt); 373*59596c01SRobert Mustacchi return (2); 374*59596c01SRobert Mustacchi case '?': 375*59596c01SRobert Mustacchi default: 376*59596c01SRobert Mustacchi dltran_usage("unknown option: -%c\n", optopt); 377*59596c01SRobert Mustacchi return (2); 378*59596c01SRobert Mustacchi } 379*59596c01SRobert Mustacchi } 380*59596c01SRobert Mustacchi 381*59596c01SRobert Mustacchi argc -= optind; 382*59596c01SRobert Mustacchi argv += optind; 383*59596c01SRobert Mustacchi 384*59596c01SRobert Mustacchi if (dltran_verbose) 385*59596c01SRobert Mustacchi count++; 386*59596c01SRobert Mustacchi if (dltran_hex) 387*59596c01SRobert Mustacchi count++; 388*59596c01SRobert Mustacchi if (dltran_write) 389*59596c01SRobert Mustacchi count++; 390*59596c01SRobert Mustacchi if (count > 1) { 391*59596c01SRobert Mustacchi (void) fprintf(stderr, "only one of -v, -w, and -x may be " 392*59596c01SRobert Mustacchi "specified\n"); 393*59596c01SRobert Mustacchi return (2); 394*59596c01SRobert Mustacchi } 395*59596c01SRobert Mustacchi 396*59596c01SRobert Mustacchi if (dltran_write) { 397*59596c01SRobert Mustacchi if ((dltran_outfd = open(outfile, O_RDWR | O_TRUNC | O_CREAT, 398*59596c01SRobert Mustacchi 0644)) < 0) { 399*59596c01SRobert Mustacchi (void) fprintf(stderr, "failed to open output file " 400*59596c01SRobert Mustacchi "%s: %s\n", outfile, strerror(errno)); 401*59596c01SRobert Mustacchi return (1); 402*59596c01SRobert Mustacchi } 403*59596c01SRobert Mustacchi } 404*59596c01SRobert Mustacchi 405*59596c01SRobert Mustacchi if ((status = dladm_open(&dltran_hdl)) != DLADM_STATUS_OK) { 406*59596c01SRobert Mustacchi (void) fprintf(stderr, "failed to open /dev/dld: %s\n", 407*59596c01SRobert Mustacchi dladm_status2str(status, dltran_dlerrmsg)); 408*59596c01SRobert Mustacchi return (1); 409*59596c01SRobert Mustacchi } 410*59596c01SRobert Mustacchi 411*59596c01SRobert Mustacchi if (argc == 0) { 412*59596c01SRobert Mustacchi (void) dladm_walk_datalink_id(dltran_dump_transceivers, 413*59596c01SRobert Mustacchi dltran_hdl, NULL, DATALINK_CLASS_PHYS, 414*59596c01SRobert Mustacchi DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE); 415*59596c01SRobert Mustacchi } else { 416*59596c01SRobert Mustacchi int i; 417*59596c01SRobert Mustacchi char *c; 418*59596c01SRobert Mustacchi 419*59596c01SRobert Mustacchi for (i = 0; i < argc; i++) { 420*59596c01SRobert Mustacchi uint_t tran; 421*59596c01SRobert Mustacchi uint_t *tranidp = NULL; 422*59596c01SRobert Mustacchi datalink_id_t linkid; 423*59596c01SRobert Mustacchi 424*59596c01SRobert Mustacchi if ((c = strrchr(argv[i], '/')) != NULL) { 425*59596c01SRobert Mustacchi unsigned long u; 426*59596c01SRobert Mustacchi char *eptr; 427*59596c01SRobert Mustacchi 428*59596c01SRobert Mustacchi c++; 429*59596c01SRobert Mustacchi errno = 0; 430*59596c01SRobert Mustacchi u = strtoul(c, &eptr, 10); 431*59596c01SRobert Mustacchi if (errno != 0 || *eptr != '\0' || 432*59596c01SRobert Mustacchi u >= UINT_MAX) { 433*59596c01SRobert Mustacchi (void) fprintf(stderr, "failed to " 434*59596c01SRobert Mustacchi "parse link/transceiver: %s\n", 435*59596c01SRobert Mustacchi argv[i]); 436*59596c01SRobert Mustacchi return (1); 437*59596c01SRobert Mustacchi } 438*59596c01SRobert Mustacchi c--; 439*59596c01SRobert Mustacchi *c = '\0'; 440*59596c01SRobert Mustacchi tran = (uint_t)u; 441*59596c01SRobert Mustacchi tranidp = &tran; 442*59596c01SRobert Mustacchi } 443*59596c01SRobert Mustacchi 444*59596c01SRobert Mustacchi if ((status = dladm_name2info(dltran_hdl, argv[i], 445*59596c01SRobert Mustacchi &linkid, NULL, NULL, NULL)) != DLADM_STATUS_OK) { 446*59596c01SRobert Mustacchi (void) fprintf(stderr, "failed to get link " 447*59596c01SRobert Mustacchi "id for link %s: %s\n", argv[i], 448*59596c01SRobert Mustacchi dladm_status2str(status, dltran_dlerrmsg)); 449*59596c01SRobert Mustacchi return (1); 450*59596c01SRobert Mustacchi } 451*59596c01SRobert Mustacchi 452*59596c01SRobert Mustacchi (void) dltran_dump_transceivers(dltran_hdl, linkid, 453*59596c01SRobert Mustacchi tranidp); 454*59596c01SRobert Mustacchi } 455*59596c01SRobert Mustacchi } 456*59596c01SRobert Mustacchi 457*59596c01SRobert Mustacchi return (dltran_errors != 0 ? 1 : 0); 458*59596c01SRobert Mustacchi } 459