Esempio n. 1
0
/*
 * 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;
    }
}
Esempio n. 2
0
/*
 * 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;
}