⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if.c

📁 开发snmp的开发包有两个开放的SNMP开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	$OpenBSD: if.c,v 1.42 2005/03/13 16:05:50 mpf Exp $	*//*	$NetBSD: if.c,v 1.16.4.2 1996/06/07 21:46:46 thorpej Exp $	*//* * Copyright (c) 1983, 1988, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifdef  INHERITED_CODE#ifndef lint#if 0static char sccsid[] = "from: @(#)if.c	8.2 (Berkeley) 2/21/94";#elsestatic char *rcsid = "$OpenBSD: if.c,v 1.42 2005/03/13 16:05:50 mpf Exp $";#endif#endif /* not lint */#endif#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_NET_IF_H#include <net/if.h>#endif#define __USE_XOPEN#define __USE_XOPEN_EXTENDED#include <signal.h>#include "main.h"#include "netstat.h"#define	YES	1#define	NO	0static void sidewaysintpr(u_int);static void timerSet(int interval_seconds);static void timerPause(void);    struct _if_info {        char            name[128];        char            ip[128], route[128];        int             mtu;        int             drops;        int             ifindex;                        /*                         * Save "expandable" fields as string values                         *  rather than integer statistics                         */        char            s_ipkts[20], s_ierrs[20];        char            s_opkts[20], s_oerrs[20];        char            s_ibytes[20], s_obytes[20];        char            s_outq[20];        unsigned long   ipkts, opkts;  /* Need to combine 2 MIB values */        int             operstatus;/*        u_long          netmask;        struct in_addr  ifip, ifroute; */        struct _if_info *next;    };/* * Retrieve the interface addressing information * XXX - This could also be extended to handle non-IP interfaces */void_set_address( struct _if_info *cur_if ){    oid    ipaddr_oid[] = { 1,3,6,1,2,1,4,20,1,0 };    size_t ipaddr_len   = OID_LENGTH( ipaddr_oid );    static netsnmp_variable_list *addr_if_var  =NULL;    static netsnmp_variable_list *addr_mask_var=NULL;    netsnmp_variable_list *vp, *vp2;    union {        in_addr_t addr;        char      data[4];    } tmpAddr;    char *cp;    in_addr_t ifAddr, mask;        /*         *  Note that this information only needs to be retrieved          *    once, and can be re-used for subsequent calls.         */    if ( addr_if_var == NULL ) {        ipaddr_oid[ 9 ] = 2;  /* ipAdEntIfIndex */        snmp_varlist_add_variable( &addr_if_var, ipaddr_oid, ipaddr_len,                                   ASN_NULL, NULL,  0);        netsnmp_query_walk( addr_if_var, ss );        ipaddr_oid[ 9 ] = 3;  /* ipAdEntNetMask */        snmp_varlist_add_variable( &addr_mask_var, ipaddr_oid, ipaddr_len,                                   ASN_NULL, NULL,  0);        netsnmp_query_walk( addr_mask_var, ss );    }    /*     * Find the address row relevant to this interface     */    for (vp=addr_if_var, vp2=addr_mask_var;  vp;         vp=vp->next_variable, vp2=vp2->next_variable) {        if ( vp->val.integer && *vp->val.integer == cur_if->ifindex )            break;    }    if (vp2) {        /*         * Always want a numeric interface IP address         */        snprintf( cur_if->ip, 128, "%lu.%lu.%lu.%lu",                  vp2->name[10],                  vp2->name[11],                  vp2->name[12],                  vp2->name[13]);        /*         * But re-use the routing table utilities/code for         *   displaying the local network information         */        cp = tmpAddr.data;        cp[0] = vp2->name[ 10 ] & 0xff;        cp[1] = vp2->name[ 11 ] & 0xff;        cp[2] = vp2->name[ 12 ] & 0xff;        cp[3] = vp2->name[ 13 ] & 0xff;        ifAddr = tmpAddr.addr;        cp = tmpAddr.data;        cp[0] = vp2->val.string[ 0 ] & 0xff;        cp[1] = vp2->val.string[ 1 ] & 0xff;        cp[2] = vp2->val.string[ 2 ] & 0xff;        cp[3] = vp2->val.string[ 3 ] & 0xff;        mask = tmpAddr.addr;        snprintf( cur_if->route, 128, "%s", netname(ifAddr, mask));    }}/* * Print a description of the network interfaces. */voidintpr(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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -