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

📄 ipmedia.c

📁 ucd-snmp源代码
💻 C
字号:
/* *  IP Net->Media translation MIB group implementation - ipMedia.c * */#include <config.h>#include "mibincl.h"#if HAVE_STRING_H#include <string.h>#endif#if defined(IFNET_NEEDS_KERNEL) && !defined(_KERNEL)#define _KERNEL 1#define _I_DEFINED_KERNEL#endif#include <sys/types.h>#include <sys/socket.h>#include <net/if.h>#if HAVE_NET_IF_VAR_H#include <net/if_var.h>#endif#ifdef _I_DEFINED_KERNEL#undef _KERNEL#endif#if HAVE_NETINET_IF_ETHER_H#include <netinet/if_ether.h>#endif#if HAVE_INET_MIB2_H#include <inet/mib2.h>#endif#if HAVE_SYS_PARAM_H#include <sys/param.h>#endif#if HAVE_SYS_SYSCTL_H#include <sys/sysctl.h>#endif#if HAVE_NET_IF_DL_H#include <net/if_dl.h>#endif#if HAVE_SYS_STREAM_H#include <sys/stream.h>#endif#if HAVE_NET_ROUTE_H#include <net/route.h>#endif#ifdef solaris2#include "kernel_sunos5.h"#endif#ifdef hpux#include <sys/mib.h>#include "kernel_hpux.h"#endif#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#include "ipMedia.h"#include "interfaces.h"#include "if_fields.h"#include "auto_nlist.h"#include "system.h"#include "util_funcs.h"#if defined(HAVE_SYS_SYSCTL_H) && !defined(CAN_USE_SYSCTL)# if defined(RTF_LLINFO) && !defined(irix6)#  define CAN_USE_SYSCTL 1# endif#endif#ifndef MEDIA_CACHE_TIMEOUT#define MEDIA_CACHE_TIMEOUT MIB_STATS_CACHE_TIMEOUT#endifmib_table_t media_table;	/*********************	 *	 *  Kernel & interface information,	 *   and internal forward declarations	 *	 *********************/#ifdef solaris2#define MEDIA_TYPE	mib2_ipNetToMediaEntry_t#define AT_INDEX_FIELD		ipNetToMediaIfIndex#define AT_PHYSADDR_FIELD	ipNetToMediaPhysAddress#define AT_ADDRESS_FIELD	ipNetToMediaNetAddress#define AT_TYPE_FIELD		ipNetToMediaType#define PHYSADDR_LEN(x)		sizeof(x)#endif#ifdef hpux#define MEDIA_TYPE	mib_ipNetToMediaEnt#define AT_INDEX_FIELD		IfIndex#define AT_PHYSADDR_FIELD	PhysAddr#define AT_ADDRESS_FIELD	NetAddr#define AT_TYPE_FIELD		Type#undef STRUCT_ARPHD_HAS_AT_NEXT#undef  SOCKADDR#define SOCKADDR(x)	x#define PHYSADDR_LEN(x)	6#endif#ifdef freebsd4struct dummy_arptab {    int			index;    char		at_enaddr[6];    struct sockaddr_in	at_iaddr;	/* XXX */    int			at_flags;};#define MEDIA_TYPE	struct dummy_arptab#define AT_INDEX_FIELD		index#define AT_PHYSADDR_FIELD	at_enaddr#define AT_ADDRESS_FIELD	at_iaddr#define AT_FLAGS_FIELD		at_flags#define PHYSADDR_LEN(x)		sizeof(x)#endif#ifndef MEDIA_TYPE#define MEDIA_TYPE	struct arptab#define AT_INDEX_FIELD		at_state	/* unused field */#define AT_PHYSADDR_FIELD	at_enaddr#define AT_ADDRESS_FIELD	at_iaddr#define AT_FLAGS_FIELD		at_flags#define PHYSADDR_LEN(x)		sizeof(x)#endifint Arp_Scan_Reload ( mib_table_t );int Arp_Compare(const void *, const void *);MEDIA_TYPE* search_arp(oid* idx, int idx_len, int exact, int is_atQuery);	/*********************	 *	 *  Initialisation	 *	 *********************//* define the structures we're going to ask the agent to register our   information at */struct variable2 at_variables[] = {    {ATIFINDEX,     ASN_INTEGER,   RONLY, var_atEntry, 1, {1}},    {ATPHYSADDRESS, ASN_OCTET_STR, RONLY, var_atEntry, 1, {2}},    {ATNETADDRESS,  ASN_IPADDRESS, RONLY, var_atEntry, 1, {3}}};struct variable2 ipMedia_variables[] = {    {ATIFINDEX,     ASN_INTEGER,   RONLY, var_atEntry, 1, {1}},    {ATPHYSADDRESS, ASN_OCTET_STR, RONLY, var_atEntry, 1, {2}},    {ATNETADDRESS,  ASN_IPADDRESS, RONLY, var_atEntry, 1, {3}},    {IPMEDIATYPE,   ASN_INTEGER,   RONLY, var_atEntry, 1, {4}}};/* Define the OID pointers to the top of the mib trees that we're   registering underneath */oid at_variables_oid[]      = { SNMP_OID_MIB2,3,1,1 };oid ipMedia_variables_oid[] = { SNMP_OID_MIB2,4,22,1 };void init_ipMedia(void){    /* register ourselves with the agent to handle our mib tree */    REGISTER_MIB("mibII/ipMedia", at_variables,      variable2, at_variables_oid);    REGISTER_MIB("mibII/ipMedia", ipMedia_variables, variable2, ipMedia_variables_oid);    media_table = Initialise_Table( sizeof( MEDIA_TYPE ),			MEDIA_CACHE_TIMEOUT,			Arp_Scan_Reload, Arp_Compare);}	/*********************	 *	 *  Main variable handling routines	 *	 *********************//*  var_atEntry(...  Arguments:  vp	  IN      - pointer to variable entry that points here  name    IN/OUT  - IN/name requested, OUT/name found  length  IN/OUT  - length of IN/OUT oid's   exact   IN      - TRUE if an exact match was requested  var_len OUT     - length of variable or 0 if function returned  write_method  */u_char *var_atEntry(struct variable *vp,	    oid *name,	    size_t *length,	    int exact,	    size_t *var_len,	    WriteMethod **write_method){    /*     * Address Translation table object identifier is of form:     * 1.3.6.1.2.1.3.1.1.1.interface.1.A.B.C.D,  where A.B.C.D is IP address.     * Interface is at offset 10,     * IPADDR starts at offset 12.     *     * IP Net to Media table object identifier is of form:     * 1.3.6.1.2.1.4.22.1.1.1.interface.A.B.C.D,  where A.B.C.D is IP address.     * Interface is at offset 10,     * IPADDR starts at offset 11.     */    int i, idx;    oid newname[MAX_OID_LEN], *op;    u_char *cp;    MEDIA_TYPE *atEntry;    int is_atQuery;		/*		 * Check the name given in the request,		 *  and indentify the index part of it		 */    switch (snmp_oid_compare(name, MIN(*length, vp->namelen),			     vp->name, vp->namelen)) {	case -1:	/* name given is earlier than this table */		if ( exact )		    return NULL;		op = NULL;		i = 0;		break;	case 0:		/* name given matches this table */		op = &name[vp->namelen];		i  = *length - vp->namelen;		break;	case 1:		/* name given is later than this table */		return NULL;	default:	/* Can't happen */		return NULL;    }    is_atQuery = ( vp->name[6] == 3 );    		/*		 *  Search for the relevant ARP entry,		 *   either the index just identified,		 *   or the next one, depending on whether		 *   this is an exact match or not.		 */    atEntry = search_arp( op, i, exact, is_atQuery );    if ( !atEntry )	return NULL;		/*		 * We've found something we can use.		 *  Update the 'newname' with the relevant index		 */    memcpy((char *)newname, (char *)vp->name, (int)vp->namelen * sizeof(oid));    cp = (u_char *)&(SOCKADDR(atEntry->AT_ADDRESS_FIELD));    op = newname + vp->namelen;    *op++ = atEntry->AT_INDEX_FIELD;    if ( is_atQuery )	*op++ = 1;    *op++ = *cp++;    *op++ = *cp++;    *op++ = *cp++;    *op++ = *cp++;       if ( is_atQuery )	*length = vp->namelen + 6;    else	*length = vp->namelen + 5;    memcpy( (char *)name,(char *)newname, (*length) * sizeof(oid));    *write_method = 0;    *var_len = sizeof(long_return);    switch(vp->magic){	case ATIFINDEX:	    long_return = atEntry->AT_INDEX_FIELD;	    return (u_char *)&long_return;	case ATPHYSADDRESS:	    *var_len = sizeof(atEntry->AT_PHYSADDR_FIELD);	    return (u_char *)atEntry->AT_PHYSADDR_FIELD;	case ATNETADDRESS:	    long_return = SOCKADDR(atEntry->AT_ADDRESS_FIELD);	    return (u_char *)&long_return;	case IPMEDIATYPE:#ifdef AT_TYPE_FIELD	    long_return = atEntry->AT_TYPE_FIELD;	    return (u_char *)&long_return;#else#ifdef AT_FLAGS_FIELD	    long_return = (atEntry->AT_FLAGS_FIELD & ATF_PERM		 ? 4	/* static */		 : 3);	/* dynamic */	    return (u_char *)&long_return;#else	    return NULL;#endif#endif	default:	    DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_atEntry\n", vp->magic));   }   return NULL;}	/*********************	 *	 *  System-independent implementation functions	 *	 *********************/	/*	 *  Search the list of ARP entries and return	 *    the appropriate one for this query	 */MEDIA_TYPE* search_arp(oid* idx, int idx_len, int exact, int is_atQuery){    static MEDIA_TYPE entry;    char *cp;    oid  *op;    int desired_len = ( is_atQuery ? 6 : 5);    if ( exact && idx_len != desired_len )	return NULL;    if ( idx_len < desired_len ) {	SOCKADDR(entry.AT_ADDRESS_FIELD) = 0;	entry.AT_INDEX_FIELD   = 0;    }    else {        cp = (u_char *)&SOCKADDR(entry.AT_ADDRESS_FIELD);	op = idx;	entry.AT_INDEX_FIELD   = *op++;	if ( is_atQuery )	    op++;	*cp++ = *op++;	*cp++ = *op++;	*cp++ = *op++;	*cp++ = *op++;    }    if ( Search_Table( media_table, (void*)&entry, exact ) == 0 )	return &entry;    else	return NULL;}	/*	 *  Compare two ARP entries	 */intArp_Compare(const void* first, const void* second){    const MEDIA_TYPE *at1 = (const MEDIA_TYPE *) first;    const MEDIA_TYPE *at2 = (const MEDIA_TYPE *) second;    if (at1->AT_INDEX_FIELD == at2->AT_INDEX_FIELD)	return (ntohl(SOCKADDR(at1->AT_ADDRESS_FIELD)) -	        ntohl(SOCKADDR(at2->AT_ADDRESS_FIELD)));    return (at1->AT_INDEX_FIELD - at2->AT_INDEX_FIELD);}	/*********************	 *	 *  System-specific functions to read in the ARP table	 *	 *********************/#ifdef  hpux#define ARP_SCAN_RELOADint Arp_Scan_Reload( mib_table_t t ){    int numEntries, size, i;    mib_ipNetToMediaEnt *entries;   if (hpux_read_stat((char *)&numEntries, sizeof(int), ID_ipNetToMediaTableNum) == -1)	return -1;    size = numEntries*sizeof(mib_ipNetToMediaEnt);    if ( (entries=(mib_ipNetToMediaEnt *)malloc ( size )) == NULL )	return -1;    if (hpux_read_stat((char *)entries, size, ID_ipNetToMediaTable) == -1) {	free( entries );	return -1;    }		/* XXX - Need to check (& correct?) ifIndex values */				/* Or add all in one go ? */    for ( i = 0 ; i<numEntries ; i++ )	if ( Add_Entry( t, (void*)&(entries[i])) < 0 )	    break;    free( entries );    return 0;}#endif#ifdef linux#define ARP_SCAN_RELOADint Arp_Scan_Reload( mib_table_t t ){    FILE *in;    char line [256], name[32];    struct arptab entry;    int za, zb, zc, zd, ze, zf, zg, zh, zi, zj;    if (! (in = fopen ("/proc/net/arp", "r"))) {	snmp_log(LOG_ERR, "snmpd: cannot open /proc/net/arp ...\n");	return -1;    }    while (fgets (line, sizeof(line), in)) {	if ( 12 != sscanf (line, "%d.%d.%d.%d 0x%*x 0x%x %x:%x:%x:%x:%x:%x %*s %s",			&za, &zb, &zc, &zd, &entry.at_flags,			&ze, &zf, &zg, &zh, &zi, &zj, name))			continue;	entry.at_enaddr[0] = ze;	entry.at_enaddr[1] = zf;	entry.at_enaddr[2] = zg;	entry.at_enaddr[3] = zh;	entry.at_enaddr[4] = zi;	entry.at_enaddr[5] = zj;	SOCKADDR(entry.at_iaddr) = (zd << 24) | (zc << 16) | (zb << 8) | za;	entry.AT_INDEX_FIELD = Interface_Index_By_Name(name);	if (Add_Entry( t, (void *)&entry) < 0 )	    break;    }    fclose( in );    return 0;}#endif#ifdef CAN_USE_SYSCTL#define ARP_SCAN_RELOAD#define ROUNDUP(a) \	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))int Arp_Scan_Reload( mib_table_t t ){    size_t size = 0;    int name[] = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_LLINFO };    char *arpbuf, *lim, *next;    struct rt_msghdr *rtm;    struct sockaddr_inarp *sin;    struct sockaddr_dl *sdl;    MEDIA_TYPE at_entry;    if (sysctl (name, sizeof (name) / sizeof (int), 0, &size, 0, 0) == -1) {	snmp_log(LOG_ERR,"sysctl size fail\n");	return -1;    }    if (size == 0)	return -1;    if ((arpbuf = malloc (size)) == NULL) {	snmp_log(LOG_ERR,"out of memory allocating arp table\n");	return -1;    }    if (sysctl (name, sizeof (name) / sizeof (int), arpbuf, &size, 0, 0) == -1) {	snmp_log(LOG_ERR,"sysctl get fail\n");	free(arpbuf);	return -1;    }    lim = arpbuf + size;    for ( next = arpbuf; next<lim; next += rtm->rtm_msglen) {	rtm = (struct rt_msghdr *)next;	sin = (struct sockaddr_inarp *)(rtm + 1);	(char *)sdl = (char *)sin + ROUNDUP(sin->sin_len);	if ( sdl->sdl_alen ) {	    memset(&at_entry, 0, sizeof(at_entry));	    at_entry.index = sdl->sdl_index;	    memcpy(at_entry.at_enaddr, sdl->sdl_data, sizeof(at_entry.at_enaddr));	    at_entry.at_iaddr.sin_addr = sin->sin_addr;	    at_entry.at_flags = 0;			/* XXX */	    if (Add_Entry( t, (void *)&at_entry) < 0 )		break;	}    }    free( arpbuf );    return 0;}#endif#ifdef solaris2#define ARP_SCAN_RELOADint Arp_Scan_Reload( mib_table_t t ){		/* Do something clever with 'getMibstat() */    return 0;}#endif#ifdef STRUCT_ARPHD_HAS_AT_NEXT#define ARP_SCAN_RELOADint Arp_Scan_Reload( mib_table_t t ){    int arptab_size, arptab_current;    struct arphd *at;    struct arptab *at_ptr, at_entry;    struct arpcom  at_com;    char name[32];    auto_nlist(ARPTAB_SIZE_SYMBOL, (char *)&arptab_size, sizeof arptab_size);    at = (struct arphd  *) malloc(arptab_size * sizeof(struct arphd));    auto_nlist(ARPTAB_SYMBOL, (char *)at, arptab_size * sizeof(struct arphd));    at_ptr = at[0].at_next;    arptab_current = 0;    while (arptab_current < arptab_size) {		/*		 * The arp table is an array of linked lists		 * of arptab entries.  Unused slots have		 * pointers back to the array entry itself		 */	if ( at_ptr == (auto_nlist_value(ARPTAB_SYMBOL) +		arptab_current*sizeof(struct arphd))) {			/* Unused */	    arptab_current++;	    at_ptr = at[arptab_current].at_next;	    continue;	}	klookup( at_ptr, (char *)&at_entry, sizeof(struct arptab));	if (!( at_entry.at_flags & ATF_COM ))	    continue;	klookup( at_entry.at_ac, (char *)&at_com, sizeof(struct arpcom));	sprintf(name, "%s%d", at_com.ac_if.if_name, at_com.ac_if.if_unit);	at_entry.AT_INDEX_FIELD = Interface_Index_By_Name(name);	if (Add_Entry( t, (void *)&at_entry) < 0 )	    break;	at_ptr = at_entry.at_next;	    }    free( at );    return 0;}#endif#ifndef ARP_SCAN_RELOAD			/* i.e. 'other' */int Arp_Scan_Reload( mib_table_t t ){    int arptab_size, arptab_current;    struct arptab *at, at_ptr;    char name[32];    auto_nlist(ARPTAB_SIZE_SYMBOL, (char *)&arptab_size, sizeof arptab_size);    at = (struct arptab  *) malloc(arptab_size * sizeof(struct arptab));    auto_nlist(ARPTAB_SYMBOL, (char *)at, arptab_size * sizeof(struct arptab));    arptab_current = 0;    while (arptab_current < arptab_size) {	at_ptr = at[ arptab_current++ ];	if (!( at_ptr->at_flags & ATF_COM ))	    continue;/*	at_ptr->AT_INDEX_FIELD = Interface_Index_By_Name(name);		*/	if (Add_Entry( t, (void *)at_ptr) < 0 )	    break;    }    free( at );    return 0;}#endif

⌨️ 快捷键说明

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