/* * var_dot3StatsTable(): * Handle this table separately from the scalar value case. * The workings of this are basically the same as for var_dot3StatsTable above. */ unsigned char * var_dot3StatsTable(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { static long long_ret; static oid nullobjid[] = { 0,0 }; static oid etherobjid[ SNMP_CHIPSET_LEN ]; register struct ifnet *ifp; int interface_count = 0; int supports_dot3 = 0, i; struct ether_drv_stats x; interface_count = cyg_snmp_num_interfaces(); if ( header_simple_table( vp,name,length,exact,var_len,write_method, interface_count) == MATCH_FAILED ) return NULL; ifp = cyg_snmp_get_if(name[ (*length)-1 ]); if ( ! ifp ) return NULL; /* If its an ethernet call the IOCTL and see if the device supports dot3. If it does it will return all the values needed */ if ( IFT_ETHER == ifp->if_type ) { bzero( &x, sizeof( x ) ); if ( NULL != ifp->if_ioctl ) { if (!(*ifp->if_ioctl)(ifp, SIOCGIFSTATSUD, (caddr_t)&x)) { supports_dot3 = x.supports_dot3; } } } if ( (IFT_LOOP == ifp->if_type ) || (IFT_PROPVIRTUAL == ifp->if_type ) || (!supports_dot3)) { switch(vp->magic) { case DOT3STATSINDEX: long_ret = name[(*length)-1]; return (unsigned char *) &long_ret; case DOT3STATSETHERCHIPSET: *var_len = sizeof(nullobjid); return (unsigned char *) nullobjid; case DOT3STATSDUPLEXSTATUS: long_ret = 1; return (unsigned char *) &long_ret; default: long_ret = 0; // a dummy value for most of them return (unsigned char *) &long_ret; } } /* If we got here, the device does support dot3 */ switch(vp->magic) { case DOT3STATSINDEX: long_ret = name[(*length)-1]; return (unsigned char *) &long_ret; case DOT3STATSALIGNMENTERRORS: long_ret = x.rx_align_errors; return (unsigned char *) &long_ret; case DOT3STATSFCSERRORS: long_ret = x.rx_crc_errors; return (unsigned char *) &long_ret; case DOT3STATSSINGLECOLLISIONFRAMES: long_ret = x.tx_single_collisions; return (unsigned char *) &long_ret; case DOT3STATSMULTIPLECOLLISIONFRAMES: long_ret = x.tx_mult_collisions; return (unsigned char *) &long_ret; case DOT3STATSSQETESTERRORS: long_ret = x.tx_sqetesterrors; return (unsigned char *) &long_ret; case DOT3STATSDEFERREDTRANSMISSIONS: long_ret = x.tx_deferred; return (unsigned char *) &long_ret; case DOT3STATSLATECOLLISIONS: long_ret = x.tx_late_collisions; return (unsigned char *) &long_ret; case DOT3STATSEXCESSIVECOLLISIONS: long_ret = x.tx_max_collisions; return (unsigned char *) &long_ret; case DOT3STATSINTERNALMACTRANSMITERRORS: long_ret = x.tx_underrun; return (unsigned char *) &long_ret; case DOT3STATSCARRIERSENSEERRORS: long_ret = x.tx_carrier_loss; return (unsigned char *) &long_ret; case DOT3STATSFRAMETOOLONGS: long_ret = x.rx_too_long_frames; return (unsigned char *) &long_ret; case DOT3STATSINTERNALMACRECEIVEERRORS: long_ret = x.rx_overrun_errors + x.rx_resource_errors; return (unsigned char *) &long_ret; case DOT3STATSSYMBOLERRORS: long_ret = x.rx_symbol_errors; return (unsigned char *) &long_ret; case DOT3STATSETHERCHIPSET: i = 0; while ( i < sizeof(etherobjid) ) { if ( 0 == (etherobjid[i] = x.snmp_chipset[i]) ) break; i++; } if (i) { *var_len = i; return (unsigned char *) etherobjid; } else { *var_len = sizeof(nullobjid); return (unsigned char *) nullobjid; } case DOT3STATSDUPLEXSTATUS: long_ret = x.duplex; if ( 1 > long_ret || 3 < long_ret ) long_ret = 1; return (unsigned char *) &long_ret; default: ERROR_MSG(""); return NULL; } }
/* * var_ifTable(): * Handle this table separately from the scalar value case. * The workings of this are basically the same as for var_interfaces above. */ unsigned char * var_ifTable(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { /* variables we may use later */ static long long_ret; static unsigned char string[SPRINT_MAX_LEN]; static oid objid[MAX_OID_LEN]; struct ifnet *ifp; int if_num; int interface_count = cyg_snmp_num_interfaces(); /* * This assumes that the table is a 'simple' table. * See the implementation documentation for the meaning of this. * You will need to provide the correct value for the TABLE_SIZE parameter * * If this table does not meet the requirements for a simple table, * you will need to provide the replacement code yourself. * Mib2c is not smart enough to write this for you. * Again, see the implementation documentation for what is required. */ if ( header_simple_table( vp,name,length,exact,var_len,write_method, interface_count) == MATCH_FAILED ) return NULL; if_num = name[ (*length)-1 ]; ifp = cyg_snmp_get_if(if_num); if (!ifp) return NULL; // This is to assist customers with their own special interfaces; if they // define IFT_CUSTOMER_SPECIAL to whatever their own device is, then its // ioctl() will be called to handle these enquiries. #ifdef IFT_CUSTOMER_SPECIAL if ( (ifp->if_type == IFT_CUSTOMER_SPECIAL) && (NULL != ifp->if_ioctl) ) { if( (vp->magic == IFDESCR) || (vp->magic == IFPHYSADDRESS) ) { (*ifp->if_ioctl)(ifp, vp->magic, (caddr_t)string); *var_len = strlen(string); return (unsigned char *) string; } else { (*ifp->if_ioctl)(ifp, vp->magic, (caddr_t)&long_ret); return (unsigned char *) &long_ret; } } #endif // IFT_CUSTOMER_SPECIAL if ( IFT_ETHER == ifp->if_type && ((IFDESCR == vp->magic) || (IFSPEED == vp->magic) || (IFOUTDISCARDS == vp->magic) || (IFOUTQLEN == vp->magic) ) ) { // then acquire up to date information and deal with the relevent // keys (only): int i = -1; struct ether_drv_stats x; bzero( &x, sizeof( x ) ); // Call the ioctl to get all the info. // (We KNOW it's an ether dev here, it should have an ioctl()) if ( NULL != ifp->if_ioctl ) i = (*ifp->if_ioctl)(ifp, SIOCGIFSTATSUD, (caddr_t)&x); switch(vp->magic) { case IFDESCR: if ( i || 0 == x.description[0] ) strcpy( string, "<Ethernet, details not available>" ); else strcpy( string, x.description ); *var_len = strlen(string); return (unsigned char *) string; case IFSPEED: long_ret = x.speed; return (unsigned char *) &long_ret; case IFOUTDISCARDS: long_ret = x.tx_dropped; return (unsigned char *) &long_ret; case IFOUTQLEN: long_ret = x.tx_queue_len; return (unsigned char *) &long_ret; default: CYG_FAIL( "Bad magic; shouldn't be in here" ); break; } } switch(vp->magic) { case IFINDEX: long_ret = name[(*length)-1]; return (unsigned char *) &long_ret; case IFDESCR: switch ( ifp->if_type ) { case IFT_LOOP: strcpy( string, "(Loopback device)" ); break; case IFT_PROPVIRTUAL: strcpy( string, "(Proprietary Virtual/Internal)" ); break; default: strcpy( string, "Some shy network adaptor" ); break; } *var_len = strlen(string); return (unsigned char *) string; case IFTYPE: long_ret = ifp->if_type; return (unsigned char *) &long_ret; case IFMTU: long_ret = ifp->if_mtu; return (unsigned char *) &long_ret; case IFSPEED: if ( IFT_LOOP == ifp->if_type ) long_ret = 0; else long_ret = ifp->if_baudrate; return (unsigned char *) &long_ret; case IFPHYSADDRESS: { if ( IFT_ETHER == ifp->if_type ) { struct arpcom *ac = (struct arpcom *)ifp; bcopy(&ac->ac_enaddr, string, ETHER_ADDR_LEN); } else { bzero( string, ETHER_ADDR_LEN ); } *var_len = ETHER_ADDR_LEN; return (unsigned char *) string; } case IFADMINSTATUS: //NOTSUPPORTED: *write_method = write_ifAdminStatus; long_ret = (ifp->if_flags & IFF_RUNNING) ? 1 : 2; return (unsigned char *) &long_ret; case IFOPERSTATUS: long_ret = (ifp->if_flags & IFF_UP) ? 1 : 2; return (unsigned char *) &long_ret; case IFLASTCHANGE: long_ret = 0; //FIXME: ifp->if_lastchange; return (unsigned char *) &long_ret; case IFINOCTETS: long_ret = ifp->if_ibytes; return (unsigned char *) &long_ret; case IFINUCASTPKTS: long_ret = ifp->if_ipackets - ifp->if_imcasts; return (unsigned char *) &long_ret; case IFINNUCASTPKTS: long_ret = ifp->if_imcasts; return (unsigned char *) &long_ret; case IFINDISCARDS: long_ret = ifp->if_iqdrops; return (unsigned char *) &long_ret; case IFINERRORS: long_ret = ifp->if_ierrors; return (unsigned char *) &long_ret; case IFINUNKNOWNPROTOS: long_ret = ifp->if_noproto; return (unsigned char *) &long_ret; case IFOUTOCTETS: long_ret = ifp->if_obytes; return (unsigned char *) &long_ret; case IFOUTUCASTPKTS: long_ret = ifp->if_opackets - ifp->if_omcasts; return (unsigned char *) &long_ret; case IFOUTNUCASTPKTS: long_ret = ifp->if_omcasts; return (unsigned char *) &long_ret; case IFOUTDISCARDS: long_ret = 0; // ETHER case dealt with above return (unsigned char *) &long_ret; case IFOUTERRORS: long_ret = ifp->if_oerrors; return (unsigned char *) &long_ret; case IFOUTQLEN: long_ret = 0; // ETHER case dealt with above return (unsigned char *) &long_ret; case IFSPECIFIC: objid[0] = 0; objid[1] = 0; *var_len = 2*sizeof(oid); return (unsigned char *) objid; default: ERROR_MSG(""); } return NULL; }