/* 9 April 1996. SMS. * * Program to get a VAX/VMS hardware Ethernet address. */ #include #include #include descrip #include iodef #include ssdef #include starlet /* * Define: Hardware address parameter type code (no .h file), and * Size of the device characteristics buffer. */ #define HWA_PARAM_TYPE 1160 #define SENSE_BUF_LEN 256 main() { char *buf_ptr_byte; char *buf_ptr_byte_end; char *eth_name; static char sense_buf[ SENSE_BUF_LEN]; /* * Legal Ethernet device names. Assign any unlisted (new) device to * "ZCD$ETH_LNM" with DCL ASSIGN or DEFINE. */ char *eth_type[] = { "ZCD$ETH_LNM" , "EIA0:", "ERA0:", "ESA0:", "ETA0:", "EWA0:", "EXA0:", "EZA0:", "XEA0:", "XQA0:"}; short int *buf_ptr_word; short int eth_chan; short int param_type; short int param_type_12; int eth_dev_index; int i; int ssstatus; $DESCRIPTOR( eth_name_dsc, ""); /* IOSB for QIOW. */ union { short int s[ 4]; int l[ 2]; } iosb; /* Descriptor for device characteristics buffer. */ struct { int length; int *buf; } sense_buf_dsc = { SENSE_BUF_LEN, (int*)&sense_buf }; /* Storage for the Ethernet hardware address. */ struct { unsigned char byte[ 6]; } hwa = { 0, 0, 0, 0, 0, 0 }; /* Start. */ /* Find the first available Ethernet device. */ eth_dev_index = 0; ssstatus = 0; while (!(ssstatus & 1) && (eth_dev_index < sizeof( eth_type)/ sizeof( int*))) { eth_name_dsc.dsc$a_pointer = eth_type[ eth_dev_index]; eth_name_dsc.dsc$w_length = strlen( eth_name_dsc.dsc$a_pointer); ssstatus = sys$assign( ð_name_dsc, ð_chan, 0, 0); eth_dev_index++; } /* If sys$assign worked, try to sense the characteristics. */ if (ssstatus & 1) { ssstatus = sys$qiow( 0, /* Event flag. */ eth_chan, /* Channel. */ (IO$_SENSEMODE | IO$M_CTRL), /* Function. */ &iosb, /* IOSB. */ 0, /* AST address. */ 0, /* AST parameter. */ 0, /* P1. */ &sense_buf_dsc, /* P2 (buffer). */ 0, /* P3. */ 0, /* P4. */ 0, /* P5. */ 0); /* P6. */ /* If initial status was good, use final status. */ if (ssstatus & 1) { ssstatus = iosb.s[ 0]; } /* If sense worked, search for the hardware address field. */ if (ssstatus & 1) { param_type_12 = 0; buf_ptr_byte = (char *) &sense_buf; buf_ptr_byte_end = (char *) &sense_buf+ SENSE_BUF_LEN; /* Search while not found and more buffer. */ while ((param_type_12 != HWA_PARAM_TYPE) && (buf_ptr_byte <= buf_ptr_byte_end)) { buf_ptr_word = (short int *) buf_ptr_byte; param_type = *buf_ptr_word; param_type_12 = param_type & ((short) (1<< 12)- 1); /* If found, store the hardware address. Otherwise, advance the pointer to the next field. */ if (param_type_12 == HWA_PARAM_TYPE) { buf_ptr_byte += 4; for (i = 0; i < 6; i++) { hwa.byte[ i] = *( buf_ptr_byte++); } } else if (param_type & ((short) (1<< 12))) { /* String field. Skip type, length, and length-bytes. */ buf_ptr_byte += 4+ *(buf_ptr_word+ 1); } else { /* Longword field. Skip type and longword. */ buf_ptr_byte += 6; } } } } ssstatus = sys$dassgn( eth_chan); /* Print the hardware address. */ printf( " HWA (%s) = ", eth_name_dsc.dsc$a_pointer); for (i = 0; i < 5; i++) { printf( "%02x-", hwa.byte[ i]); } printf( "%02x.\n", hwa.byte[ 5]); }