Beispiel #1
0
int _set(ng_netdev_t *dev, netopt_t opt, void *value, size_t value_len)
{
    (void)dev;

    switch (opt) {
        case NETOPT_ADDRESS:
            return _set_address(value, value_len);
        case NETOPT_CHANNEL:
            return _set_channel(value, value_len);
        case NETOPT_NID:
            return _set_pan(value, value_len);
        case NETOPT_TX_POWER:
            return _set_txpower(value, value_len);
        case NETOPT_STATE:
            return _set_state(value, value_len);
        default:
            return -ENOTSUP;
    }
}
Beispiel #2
0
/*
 * Print a description of the network interfaces.
 */
void
intpr(int interval)
{
    oid    ifcol_oid[]  = { 1,3,6,1,2,1,2,2,1,0 };
    size_t ifcol_len    = OID_LENGTH( ifcol_oid );

    struct _if_info *if_head, *if_tail, *cur_if;
    netsnmp_variable_list *var, *vp;
           /*
            * Track maximum field widths, expanding as necessary
            *   This is one reason why results can't be
            *   displayed immediately they are retrieved.
            */
    int    max_name  = 4, max_ip    = 7, max_route = 7, max_outq  = 5;
    int    max_ipkts = 5, max_ierrs = 5, max_opkts = 5, max_oerrs = 5;
    int    max_ibytes = 6, max_obytes = 6;
    int    i;


    if (interval) {
        sidewaysintpr((unsigned)interval);
        return;
    }

        /*
         * The traditional "netstat -i" output combines information
         *   from two SNMP tables:
         *      ipAddrTable   (for the IP address/network)
         *      ifTable       (for the interface statistics)
         *
         * The previous approach was to retrieve (and save) the
         *   address information first. Then walk the main ifTable,
         *   add the relevant stored addresses, and saving the
         *   full information for each interface, before displaying 
         *   the results as a separate pass.
         *
         * This code reverses this general structure, by first retrieving
         *   (and storing) the interface statistics for the whole table,
         *   then inserting the address information obtained from the
         *   ipAddrTable, and finally displaying the results.
         * Such an arrangement should make it easier to extend this
         *   to handle non-IP interfaces (hence not in ipAddrTable)
         */
    if_head = NULL;
    if_tail = NULL;
    var     = NULL;

#define ADD_IFVAR( x ) ifcol_oid[ ifcol_len-1 ] = x; \
    snmp_varlist_add_variable( &var, ifcol_oid, ifcol_len, ASN_NULL, NULL,  0)
    ADD_IFVAR( 2 );                 /* ifName  */
    ADD_IFVAR( 4 );                 /* ifMtu   */
    ADD_IFVAR( 8 );                 /* ifOperStatus */
    /*
     * The Net/Open-BSD behaviour is to display *either* byte
     *   counts *or* packet/error counts (but not both). FreeBSD
     *   integrates the byte counts into the traditional display.
     *
     * The previous 'snmpnetstat' implementation followed the
     *   separatist model.  This re-write offers an opportunity
     *   to adopt the (more useful, IMO) Free-BSD approach.
     *
     * Or we could perhaps support both styles? :-)
     */
    if (bflag || oflag) {
        ADD_IFVAR( 10 );            /* ifInOctets   */
        ADD_IFVAR( 16 );            /* ifOutOctets  */
    }
    if (!oflag) {
        ADD_IFVAR( 11 );            /* ifInUcastPkts  */
        ADD_IFVAR( 12 );            /* ifInNUcastPkts */
        ADD_IFVAR( 14 );            /* ifInErrors     */
        ADD_IFVAR( 17 );            /* ifOutUcastPkts */
        ADD_IFVAR( 18 );            /* ifOutNUcastPkts */
        ADD_IFVAR( 20 );            /* ifOutErrors    */
        ADD_IFVAR( 21 );            /* ifOutQLen      */
    }
#if 0
    if (tflag) {
        ADD_IFVAR( XX );            /* ??? */
    }
#endif
    if (dflag) {
        ADD_IFVAR( 19 );            /* ifOutDiscards  */
    }
#undef ADD_IFVAR

        /*
	 * Now walk the ifTable, creating a list of interfaces
	 */
    while ( 1 ) {
        if (netsnmp_query_getnext( var, ss ) != SNMP_ERR_NOERROR)
            break;
        ifcol_oid[ ifcol_len-1 ] = 2;	/* ifDescr */
        if ( snmp_oid_compare( ifcol_oid, ifcol_len,
                               var->name, ifcol_len) != 0 )
            break;    /* End of Table */
        cur_if = SNMP_MALLOC_TYPEDEF( struct _if_info );
        if (!cur_if)
            break;
        cur_if->ifindex = var->name[ var->name_length-1 ];
        for ( vp=var; vp; vp=vp->next_variable ) {
            if ( ! vp->val.integer )
                continue;
            if ( var->name[ var->name_length-1 ] != cur_if->ifindex ) {
                /*
                 * Inconsistent index information
                 * XXX - Try to recover ?
                 */
                SNMP_FREE( cur_if );
                cur_if = NULL;
                break;    /* not for now, no */
            }
            switch ( vp->name[ var->name_length-2 ] ) {
            case 2:     /* ifDescr */
                if (vp->val_len >= sizeof(cur_if->name))
                    vp->val_len  = sizeof(cur_if->name)-1;
                memmove( cur_if->name, vp->val.string, vp->val_len );
                cur_if->name[vp->val_len] = 0;
                if ((i = strlen(cur_if->name) + 1) > max_name)
                    max_name = i;
                break;
            case 4:     /* ifMtu   */
                cur_if->mtu = *vp->val.integer;
                break;
            case 8:     /* ifOperStatus   */
                cur_if->operstatus = *vp->val.integer;
                /* XXX - any special processing ?? */
                break;
            case 10:	/* ifInOctets     */
                sprintf(cur_if->s_ibytes, "%lu", *vp->val.integer);
                i = strlen(cur_if->s_ibytes);
                if (i > max_ibytes)
                    max_ibytes = i;
                break;
            case 11:	/* ifInUcastPkts  */
                cur_if->ipkts += *vp->val.integer;
                sprintf(cur_if->s_ipkts, "%lu", cur_if->ipkts);
                i = strlen(cur_if->s_ipkts);
                if (i > max_ipkts)
                    max_ipkts = i;
                break;
            case 12:	/* ifInNUcastPkts  */
                cur_if->ipkts += *vp->val.integer;
                sprintf(cur_if->s_ipkts, "%lu", cur_if->ipkts);
                i = strlen(cur_if->s_ipkts);
                if (i > max_ipkts)
                    max_ipkts = i;
                break;
            case 14:	/* ifInErrors      */
                sprintf(cur_if->s_ierrs, "%lu", *vp->val.integer);
                i = strlen(cur_if->s_ierrs);
                if (i > max_ierrs)
                    max_ierrs = i;
                break;
            case 16:	/* ifOutOctets      */
                sprintf(cur_if->s_obytes, "%lu", *vp->val.integer);
                i = strlen(cur_if->s_obytes);
                if (i > max_obytes)
                    max_obytes = i;
                break;
            case 17:	/* ifOutUcastPkts */
                cur_if->opkts += *vp->val.integer;
                sprintf(cur_if->s_opkts, "%lu", cur_if->opkts);
                i = strlen(cur_if->s_opkts);
                if (i > max_opkts)
                    max_opkts = i;
                break;
            case 18:	/* ifOutNUcastPkts */
                cur_if->opkts += *vp->val.integer;
                sprintf(cur_if->s_opkts, "%lu", cur_if->opkts);
                i = strlen(cur_if->s_opkts);
                if (i > max_opkts)
                    max_opkts = i;
                break;
            case 19:    /* ifOutDiscards   */
                cur_if->drops = *vp->val.integer;
                break;
            case 20:	/* ifOutErrors     */
                sprintf(cur_if->s_oerrs, "%lu", *vp->val.integer);
                i = strlen(cur_if->s_oerrs);
                if (i > max_oerrs)
                    max_oerrs = i;
                break;
            case 21:	/* ifOutQLen       */
                sprintf(cur_if->s_outq, "%lu", *vp->val.integer);
                i = strlen(cur_if->s_outq);
                if (i > max_outq)
                    max_outq = i;
                break;
            }
        }

        /*
         *  XXX - Perhaps query ifXTable for additional info ??
         *    (ifName/ifAlias, or HC counters)
         */

        /*
         * If we're to monitor a particular interface, then
         *   ignore all others.  It would be more efficient
         *   to check this earlier (as part of processing 
         *   the varbind list).  But performing this test here
         *   means we can recognise ifXTable names as well)
         */
        if ( intrface && strcmp( cur_if->name, intrface ) != 0) {
            SNMP_FREE( cur_if );
            cur_if = NULL;
        }

        /*
         * Insert the IP address and network settings, and
         *   add the new _if_stat structure to the list.
         */
        if ( cur_if ) {
            _set_address( cur_if );
            i = strlen(cur_if->ip);
            if (i > max_ip)
                max_ip = i;
            i = strlen(cur_if->route);
            if (i > max_route)
                max_route = i;

            if ( if_tail ) {
                if_tail->next = cur_if;
                if_tail       = cur_if;
            } else {
                if_head       = cur_if;
                if_tail       = cur_if;
            }
        }
    }   /* while (1) */

        /*
         * Now display the specified results (in Free-BSD format)
         *   setting the field widths appropriately....
         */
    printf("%*.*s %5.5s %*.*s %*.*s",
           -max_name,  max_name,  "Name", "Mtu",
           -max_route, max_route, "Network",
           -max_ip,    max_ip,    "Address");
    if (oflag) {
        printf(" %*s %*s", max_ibytes,  "Ibytes",
                           max_obytes,  "Obytes");
    } else {
        printf(" %*s %*s", max_ipkts,   "Ipkts",
                           max_ierrs,   "Ierrs");
        if (bflag) 
            printf(" %*s", max_ibytes,  "Ibytes");

        printf(" %*s %*s", max_opkts,   "Opkts",
                           max_oerrs,   "Oerrs");
        if (bflag) 
            printf(" %*s", max_obytes,  "Obytes");

        printf(" %*s",     max_outq,    "Queue");
    }
 /* if (tflag)
        printf(" %s", "Time");
  */
    if (dflag)
        printf(" %s", "Drop");
    putchar('\n');

    for (cur_if = if_head; cur_if; cur_if=cur_if->next) {
        if (cur_if->name[0] == 0)
            continue;
        printf( "%*.*s %5d", -max_name,  max_name,  cur_if->name, cur_if->mtu);
        printf(" %*.*s",     -max_route, max_route, cur_if->route);
        printf(" %*.*s",     -max_ip,    max_ip,    cur_if->ip);

        if (oflag) {
            printf(" %*s %*s", max_ibytes,  cur_if->s_ibytes,
                               max_obytes,  cur_if->s_obytes);
        } else {
            printf(" %*s %*s", max_ipkts,   cur_if->s_ipkts,
                               max_ierrs,   cur_if->s_ierrs);
            if (bflag) 
                printf(" %*s", max_ibytes,  cur_if->s_ibytes);
    
            printf(" %*s %*s", max_opkts,   cur_if->s_opkts,
                               max_oerrs,   cur_if->s_oerrs);
            if (bflag) 
                printf(" %*s", max_obytes,  cur_if->s_obytes);
            printf(" %*s",     max_outq,    cur_if->s_outq);
        }
     /* if (tflag)
            printf(" %4d", cur_if->???);
      */
        if (dflag)
            printf(" %4d", cur_if->drops);
        putchar('\n');
    }

        /*
         * ... and tidy up.
         */
    for (cur_if = if_head; cur_if; cur_if=if_head) {
        if_head=cur_if->next;
        cur_if->next = NULL;
        SNMP_FREE( cur_if );
    }
}