Пример #1
0
u_char *
getStatPtr(
    oid		*name,	    /* IN - name of var, OUT - name matched */
    size_t	*namelen,   /* IN -number of sub-ids in name,
                               OUT - subid-is in matched name */
    u_char	*type,	    /* OUT - type of matched variable */
    size_t	*len,	    /* OUT - length of matched variable */
    u_short	*acl,	    /* OUT - access control list */
    int		exact,	    /* IN - TRUE if exact match wanted */
    WriteMethod **write_method,
    struct snmp_pdu *pdu,   /* IN - relevant auth info re PDU */
    int		*noSuchObject)
{
    struct subtree	*tp;
    oid			save[MAX_OID_LEN];
    size_t		savelen = 0;
    u_char              result_type;
    u_short             result_acl;
    u_char        	*search_return=NULL;

    found = FALSE;

    if (!exact){
	memcpy(save, name, *namelen * sizeof(oid));
	savelen = *namelen;
    }
    *write_method = NULL;

    DEBUGMSGTL(("snmp_vars", "Looking for: "));
    DEBUGMSGOID(("snmp_vars", name, *namelen));
    DEBUGMSG(("snmp_vars"," ...\n"));

    tp = find_subtree(name, *namelen, NULL);
    
    while ( search_return == NULL && tp != NULL ) {
	DEBUGMSGTL(("snmp_vars", "Trying tree: "));
	DEBUGMSGOID(("snmp_vars", tp->name, tp->namelen));
	DEBUGMSG(("snmp_vars"," ...\n"));
	search_return = search_subtree_vars( tp, name, namelen, &result_type,
                                        len, &result_acl, exact, write_method,
                                        pdu, noSuchObject);
	if ( search_return != NULL || exact )
	    break;
	tp = tp->next;
    }
    if ( tp == NULL ) {
	if (!search_return && !exact){
	    memcpy(name, save, savelen * sizeof(oid));
	    *namelen = savelen;
	}
	if (found)
	    *noSuchObject = FALSE;
	else
	    *noSuchObject = TRUE;
        return NULL;
    }
    *type = result_type;
    *acl =  result_acl;
    return search_return;
}
Пример #2
0
int
header_hrdisk(struct variable *vp,
	      oid *name,
	      size_t *length,
	      int exact,
	      size_t *var_len,
	      WriteMethod **write_method)
{
#define HRDISK_ENTRY_NAME_LENGTH	11
    oid newname[MAX_OID_LEN];
    int disk_idx, LowIndex = -1;
    int result;

    DEBUGMSGTL(("host/hr_disk", "var_hrdisk: "));
    DEBUGMSGOID(("host/hr_disk", name, *length));
    DEBUGMSG(("host/hr_disk"," %d\n", exact));
    
    memcpy( (char *)newname,(char *)vp->name, (int)vp->namelen * sizeof(oid));
	/* Find "next" disk entry */

    Init_HR_Disk();
    for ( ;; ) {
        disk_idx = Get_Next_HR_Disk();
        if ( disk_idx == -1 )
	    break;
	newname[HRDISK_ENTRY_NAME_LENGTH] = disk_idx;
        result = snmp_oid_compare(name, *length, newname, (int)vp->namelen + 1);
        if (exact && (result == 0)) {
	    LowIndex = disk_idx;
	    Save_HR_Disk_Specific();
            break;
	}
	if ((!exact && (result < 0)) &&
		( LowIndex == -1 ||  disk_idx < LowIndex )) {
	    LowIndex = disk_idx;
	    Save_HR_Disk_Specific();
#ifdef HRD_MONOTONICALLY_INCREASING
	    break;
#endif
        }
    }

    if ( LowIndex == -1 ) {
      DEBUGMSGTL(("host/hr_disk", "... index out of range\n"));
      return(MATCH_FAILED);
    }

    newname[HRDISK_ENTRY_NAME_LENGTH] = LowIndex;
    memcpy( (char *)name,(char *)newname, ((int)vp->namelen + 1) * sizeof(oid));
    *length = vp->namelen + 1;
    *write_method = 0;
    *var_len = sizeof(long);	/* default to 'long' results */

    DEBUGMSGTL(("host/hr_disk", "... get disk stats "));
    DEBUGMSGOID(("host/hr_disk", name, *length));
    DEBUGMSG(("host/hr_disk","\n"));
    
    return LowIndex;
}
Пример #3
0
int
header_hrnet(struct variable *vp,
             oid * name,
             size_t * length,
             int exact, size_t * var_len, WriteMethod ** write_method)
{
#define HRNET_ENTRY_NAME_LENGTH	11
    oid             newname[MAX_OID_LEN];
    int             net_idx;
    int             result;
    int             LowIndex = -1;

    DEBUGMSGTL(("host/hr_network", "var_hrnet: "));
    DEBUGMSGOID(("host/hr_network", name, *length));
    DEBUGMSG(("host/hr_network", " %d\n", exact));

    memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
    /*
     * Find "next" net entry 
     */

    Init_HR_Network();
    for (;;) {
        net_idx = Get_Next_HR_Network();
        if (net_idx == -1)
            break;
        newname[HRNET_ENTRY_NAME_LENGTH] = net_idx;
        result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
        if (exact && (result == 0)) {
            LowIndex = net_idx;
            break;
        }
        if (!exact && (result < 0) &&
            (LowIndex == -1 || net_idx < LowIndex)) {
            LowIndex = net_idx;
#ifdef HRN_MONOTONICALLY_INCREASING
            break;
#endif
        }
    }

    if (LowIndex == -1) {
        DEBUGMSGTL(("host/hr_network", "... index out of range\n"));
        return (MATCH_FAILED);
    }

    newname[HRNET_ENTRY_NAME_LENGTH] = LowIndex;
    memcpy((char *) name, (char *) newname,
           (vp->namelen + 1) * sizeof(oid));
    *length = vp->namelen + 1;
    *write_method = 0;
    *var_len = sizeof(long);    /* default to 'long' results */

    DEBUGMSGTL(("host/hr_network", "... get net stats "));
    DEBUGMSGOID(("host/hr_network", name, *length));
    DEBUGMSG(("host/hr_network", "\n"));
    return LowIndex;
}
Пример #4
0
int
header_hrfilesys(struct variable *vp,
                 oid * name,
                 size_t * length,
                 int exact, size_t * var_len, WriteMethod ** write_method)
{
#define HRFSYS_ENTRY_NAME_LENGTH	11
    oid             newname[MAX_OID_LEN];
    int             fsys_idx, LowIndex = -1;
    int             result;

    DEBUGMSGTL(("host/hr_filesys", "var_hrfilesys: "));
    DEBUGMSGOID(("host/hr_filesys", name, *length));
    DEBUGMSG(("host/hr_filesys", " %d\n", exact));

    memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
    /*
     * Find "next" file system entry 
     */

    Init_HR_FileSys();
    for (;;) {
        fsys_idx = Get_Next_HR_FileSys();
        if (fsys_idx == -1)
            break;
        newname[HRFSYS_ENTRY_NAME_LENGTH] = fsys_idx;
        result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
        if (exact && (result == 0)) {
            LowIndex = fsys_idx;
            break;
        }
        if ((!exact && (result < 0)) &&
            (LowIndex == -1 || fsys_idx < LowIndex)) {
            LowIndex = fsys_idx;
#ifdef HRFS_MONOTONICALLY_INCREASING
            break;
#endif
        }
    }

    if (LowIndex == -1) {
        DEBUGMSGTL(("host/hr_filesys", "... index out of range\n"));
        return (MATCH_FAILED);
    }

    memcpy((char *) name, (char *) newname,
           (vp->namelen + 1) * sizeof(oid));
    *length = vp->namelen + 1;
    *write_method = (WriteMethod*)0;
    *var_len = sizeof(long);    /* default to 'long' results */

    DEBUGMSGTL(("host/hr_filesys", "... get filesys stats "));
    DEBUGMSGOID(("host/hr_filesys", name, *length));
    DEBUGMSG(("host/hr_filesys", "\n"));

    return LowIndex;
}
Пример #5
0
/* header_dummy(...
   Arguments:
   vp            IN     - pointer to variable entry that points here
   name          IN/OUT - IN/name requested, OUT/name found
   length        IN/OUT - length of input and output oid's
   exact         IN     - TRUE if an exact match was requested. 
   var_len       OUT     - length of variable or 0 if function returned.
   write_method  OUT     - pointer to function to set variable, otherwise 0
*/
int
header_dummy(struct variable *vp,
	     oid *name,
	     int *length,
	     int exact,
	     int *var_len,
	     WriteMethod **write_method) 
{
#define DUMMY_NAME_LENGTH	8
    oid newname[MAX_OID_LEN];
    int result;

    /* just do trace and token print */
    DEBUGMSGTL(("dummy/dummy:var_dummy", ""));
    DEBUGMSGOID(("dummy/dummy:var_dummy", name, *length));
    DEBUGMSG(("dummy/dummy:var_dummy", " %d\n", exact));

    memcpy(newname, vp->name, (int)vp->namelen * sizeof(oid));
    newname[DUMMY_NAME_LENGTH] = 0;
    result = snmp_oid_compare(name, *length, newname, (int)vp->namelen + 1);
    if ((exact && (result != 0)) || (!exact && (result >= 0)))
        return(MATCH_FAILED);
    memcpy(name, newname, ((int)vp->namelen + 1) * sizeof(oid));
    *length = vp->namelen + 1;

    *write_method = 0;
    *var_len = sizeof(long);	/* default to 'long' results */
    return(MATCH_SUCCEEDED);
}
Пример #6
0
void
header_complex_generate_oid(oid * name, /* out */
                            size_t * length,    /* out */
                            oid * prefix,
                            size_t prefix_len,
                            netsnmp_variable_list * data)
{

    oid            *oidptr;
    netsnmp_variable_list *var;

    if (prefix) {
        memcpy(name, prefix, prefix_len * sizeof(oid));
        oidptr = (name + (prefix_len));
        *length = prefix_len;
    } else {
        oidptr = name;
        *length = 0;
    }

    for (var = data; var != NULL; var = var->next_variable) {
        header_complex_generate_varoid(var);
        memcpy(oidptr, var->name, sizeof(oid) * var->name_length);
        oidptr = oidptr + var->name_length;
        *length += var->name_length;
    }

    DEBUGMSGTL(("header_complex_generate_oid", "generated: "));
    DEBUGMSGOID(("header_complex_generate_oid", name, *length));
    DEBUGMSG(("header_complex_generate_oid", "\n"));
}
int
header_hrswinst(struct variable *vp,
                oid * name,
                size_t * length,
                int exact, size_t * var_len, WriteMethod ** write_method)
{
#define HRSWINST_NAME_LENGTH	9
    oid             newname[MAX_OID_LEN];
    int             result;

    DEBUGMSGTL(("host/hr_swinst", "var_hrswinst: "));
    DEBUGMSGOID(("host/hr_swinst", name, *length));
    DEBUGMSG(("host/hr_swinst", " %d\n", exact));

    memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
    newname[HRSWINST_NAME_LENGTH] = 0;
    result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
    if ((exact && (result != 0)) || (!exact && (result >= 0)))
        return (MATCH_FAILED);
    memcpy((char *) name, (char *) newname,
           (vp->namelen + 1) * sizeof(oid));
    *length = vp->namelen + 1;

    *write_method = 0;
    *var_len = sizeof(long);    /* default to 'long' results */
    return (MATCH_SUCCEEDED);
}
Пример #8
0
int
header_hrdevice (struct variable *vp,
                 oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method)
{
#define HRDEV_ENTRY_NAME_LENGTH    11
    oid newname[MAX_OID_LEN];

    int dev_idx, LowIndex = -1, LowType = -1;

    int result;

    DEBUGMSGTL (("host/hr_device", "var_hrdevice: "));
    DEBUGMSGOID (("host/hr_device", name, *length));
    DEBUGMSG (("host/hr_device", " %d\n", exact));

    memcpy ((char *) newname, (char *) vp->name, (int) vp->namelen * sizeof (oid));


    /*
     *  Find the "next" device entry.
     *  If we're in the middle of the table, then there's
     *     no point in examining earlier types of devices,
     *     so set the starting type to that of the variable
     *     being queried.
     *  If we've moved from one column of the table to another,
     *     then we need to start at the beginning again.
     *     (i.e. the 'compare' fails to match)
     *  Similarly if we're at the start of the table
     *     (i.e. *length is too short to be a full instance)
     */

    if ((snmp_oid_compare (vp->name, vp->namelen, name, vp->namelen) == 0) && (*length > HRDEV_ENTRY_NAME_LENGTH))
        current_type = (name[HRDEV_ENTRY_NAME_LENGTH] >> HRDEV_TYPE_SHIFT);
    else
Пример #9
0
int
netsnmp_null_handler(netsnmp_mib_handler *handler,
                     netsnmp_handler_registration *reginfo,
                     netsnmp_agent_request_info *reqinfo,
                     netsnmp_request_info *requests)
{
    DEBUGMSGTL(("helper:null", "Got request\n"));

    DEBUGMSGTL(("helper:null", "  oid:"));
    DEBUGMSGOID(("helper:null", requests->requestvb->name,
                 requests->requestvb->name_length));
    DEBUGMSG(("helper:null", "\n"));

    switch (reqinfo->mode) {
    case MODE_GETNEXT:
    case MODE_GETBULK:
        return SNMP_ERR_NOERROR;

    case MODE_GET:
        netsnmp_set_all_requests_error(reqinfo, requests,
                                       SNMP_NOSUCHOBJECT);
        return SNMP_ERR_NOERROR;

    default:
        netsnmp_set_all_requests_error(reqinfo, requests,
                                       SNMP_ERR_NOSUCHNAME);
        return SNMP_ERR_NOERROR;
    }
}
Пример #10
0
u_char *
agentx_var(struct variable *vp,
           oid *name,
           size_t *length,
           int exact,
           size_t *var_len,
           WriteMethod **write_method)
{
    int result;
    AddVarMethod *add_method;

    DEBUGMSGTL(("agentx/master","request to pass to client:  "));
    DEBUGMSGOID(("agentx/master", name, *length));
    DEBUGMSG(("agentx/master","\n"));
	/*
	 * If the requested OID precedes the area of responsibility
	 * of this subagent (and hence it's presumable a non-exact match),
	 * then update the "matched" name to be the starting point
	 */
        /* XXX shouldn't we check exact in this case? */
    result = snmp_oid_compare(name, *length, vp->name, vp->namelen);
    if ( result < 0 ) {
	memcpy((char *)name,(char *)vp->name, vp->namelen*sizeof(oid));
	*length = vp->namelen;
    }
				/* Return a pointer to an appropriate method */
    add_method  = agentx_add_request;
    return (u_char*)add_method;
}
Пример #11
0
/** starts the recurring cache_load callback */
unsigned int
netsnmp_cache_timer_start(netsnmp_cache *cache)
{
    if(NULL == cache)
        return 0;

    DEBUGMSGTL(( "cache_timer:start", "OID: "));
    DEBUGMSGOID(("cache_timer:start", cache->rootoid, cache->rootoid_len));
    DEBUGMSG((   "cache_timer:start", "\n"));

    if(0 != cache->timer_id) {
        snmp_log(LOG_WARNING, "cache has existing timer id.\n");
        return cache->timer_id;
    }
    
    if(! (cache->flags & NETSNMP_CACHE_AUTO_RELOAD)) {
        snmp_log(LOG_ERR,
                 "cache_timer_start called but auto_reload not set.\n");
        return 0;
    }

    cache->timer_id = snmp_alarm_register(cache->timeout, SA_REPEAT,
                                          _timer_reload, cache);
    if(0 == cache->timer_id) {
        snmp_log(LOG_ERR,"could not register alarm\n");
        return 0;
    }

    cache->flags &= ~NETSNMP_CACHE_AUTO_RELOAD;
    DEBUGMSGT(("cache_timer:start",
               "starting timer %lu for cache %p\n", cache->timer_id, cache));
    return cache->timer_id;
}
Пример #12
0
int
add(netsnmp_pdu *pdu, const char *mibnodename,
    oid * index, size_t indexlen)
{
    oid             base[MAX_OID_LEN];
    size_t          base_length = MAX_OID_LEN;

    memset(base, 0, MAX_OID_LEN * sizeof(oid));

    if (!snmp_parse_oid(mibnodename, base, &base_length)) {
        snmp_perror(mibnodename);
        fprintf(stderr, "couldn't find mib node %s, giving up\n",
                mibnodename);
#if HAVE_CURSES_H
        endwin();
#endif
        exit(1);
    }

    if (index && indexlen) {
        memcpy(&(base[base_length]), index, indexlen * sizeof(oid));
        base_length += indexlen;
    }
    DEBUGMSGTL(("add", "created: "));
    DEBUGMSGOID(("add", base, base_length));
    DEBUGMSG(("add", "\n"));
    snmp_add_null_var(pdu, base, base_length);

    return base_length;
}
Пример #13
0
int
my_test_handler(netsnmp_mib_handler *handler,
                netsnmp_handler_registration *reginfo,
                netsnmp_agent_request_info *reqinfo,
                netsnmp_request_info *requests)
{

    oid             myoid1[] = { 1, 2, 3, 4, 5, 6 };
    static u_long   accesses = 0;

    DEBUGMSGTL(("testhandler", "Got request:\n"));
    /*
     * loop through requests 
     */
    while (requests) {
        netsnmp_variable_list *var = requests->requestvb;

        DEBUGMSGTL(("testhandler", "  oid:"));
        DEBUGMSGOID(("testhandler", var->name, var->name_length));
        DEBUGMSG(("testhandler", "\n"));

        switch (reqinfo->mode) {
        case MODE_GET:
            if (netsnmp_oid_equals(var->name, var->name_length, myoid1, 6)
                == 0) {
                snmp_set_var_typed_value(var, ASN_INTEGER,
                                         (u_char *) & accesses,
                                         sizeof(accesses));
                return SNMP_ERR_NOERROR;
            }
            break;

        case MODE_GETNEXT:
            if (snmp_oid_compare(var->name, var->name_length, myoid1, 6)
                < 0) {
                snmp_set_var_objid(var, myoid1, 6);
                snmp_set_var_typed_value(var, ASN_INTEGER,
                                         (u_char *) & accesses,
                                         sizeof(accesses));
                return SNMP_ERR_NOERROR;
            }
            break;

        default:
            netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
            break;
        }

        requests = requests->next;
    }
    return SNMP_ERR_NOERROR;
}
Пример #14
0
void
header_complex_dump(struct header_complex_index *thestuff)
{
    struct header_complex_index *hciptr;
    oid             oidsave[MAX_OID_LEN];
    size_t          len;

    for (hciptr = thestuff; hciptr != NULL; hciptr = hciptr->next) {
        DEBUGMSGTL(("header_complex_dump", "var:  "));
        header_complex_generate_oid(oidsave, &len, NULL, 0, hciptr->);
        DEBUGMSGOID(("header_complex_dump", oidsave, len));
        DEBUGMSG(("header_complex_dump", "\n"));
    }
}
Пример #15
0
static void
fillConfigOid(oid * name, struct tunnel *tunnel)
{
    name[0] = ((unsigned char *) &tunnel->local)[0];
    name[1] = ((unsigned char *) &tunnel->local)[1];
    name[2] = ((unsigned char *) &tunnel->local)[2];
    name[3] = ((unsigned char *) &tunnel->local)[3];
    name[4] = ((unsigned char *) &tunnel->remote)[0];
    name[5] = ((unsigned char *) &tunnel->remote)[1];
    name[6] = ((unsigned char *) &tunnel->remote)[2];
    name[7] = ((unsigned char *) &tunnel->remote)[3];
    name[8] = tunnel->encaps;
    name[9] = tunnel->id;
    DEBUGMSGOID(("tunnel", name, 10));
}
Пример #16
0
int
netsnmp_watched_spinlock_handler(netsnmp_mib_handler *handler,
                               netsnmp_handler_registration *reginfo,
                               netsnmp_agent_request_info *reqinfo,
                               netsnmp_request_info *requests)
{
    int     *spinlock = (int *) handler->myvoid;
    netsnmp_request_info *request;

    DEBUGMSGTL(("helper:watcher:spinlock",
                               "Got request:  %d\n", reqinfo->mode));
    DEBUGMSGTL(( "helper:watcher:spinlock", "  oid:"));
    DEBUGMSGOID(("helper:watcher:spinlock", requests->requestvb->name,
                                   requests->requestvb->name_length));
    DEBUGMSG((   "helper:watcher:spinlock", "\n"));

    switch (reqinfo->mode) {
        /*
         * Ensure the assigned value matches the current one
         */
    case MODE_SET_RESERVE1:
        for (request=requests; request; request=request->next) {
            if (request->processed)
                continue;

            if (*request->requestvb->val.integer != *spinlock) {
                netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_WRONGVALUE);
                handler->flags |= MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE;
                return SNMP_ERR_WRONGVALUE;

            }
        }
        break;

        /*
         * Everything else worked, so increment the spinlock
         */
    case MODE_SET_COMMIT:
	(*spinlock)++;
	break;
    }

    /* next handler called automatically - 'AUTO_NEXT' */
    return SNMP_ERR_NOERROR;
}
Пример #17
0
int register_sysORTable_sess(oid *oidin,
			 size_t oidlen,
			 const char *descr,
			 struct snmp_session *ss)
{
  struct sysORTable **ptr=&table;
  struct register_sysOR_parameters reg_sysOR_parms;

    DEBUGMSGTL(("mibII/sysORTable", "sysORTable registering: "));
    DEBUGMSGOID(("mibII/sysORTable", oidin, oidlen));
    DEBUGMSG(("mibII/sysORTable","\n"));

  while(*ptr != NULL)
    ptr = &((*ptr)->next);
  *ptr = (struct sysORTable *) malloc(sizeof(struct sysORTable));
  if ( *ptr == NULL ) {
	return SYS_ORTABLE_REGISTRATION_FAILED;
  }
  (*ptr)->OR_descr = (char *) malloc(strlen(descr)+1);
  if ( (*ptr)->OR_descr == NULL ) {
	free( *ptr );
	return SYS_ORTABLE_REGISTRATION_FAILED;
  }
  strcpy((*ptr)->OR_descr, descr);
  (*ptr)->OR_oidlen = oidlen;
  (*ptr)->OR_oid = (oid *) malloc(sizeof(oid)*oidlen);
  if ( (*ptr)->OR_oid == NULL ) {
	free( *ptr );
	free( (*ptr)->OR_descr );
	return SYS_ORTABLE_REGISTRATION_FAILED;
  }
  memcpy((*ptr)->OR_oid, oidin, sizeof(oid)*oidlen);
  gettimeofday(&((*ptr)->OR_uptime), NULL);
  (*ptr)->OR_sess = ss;
  (*ptr)->next = NULL;
  numEntries++;

  reg_sysOR_parms.name    = oidin;
  reg_sysOR_parms.namelen = oidlen;
  reg_sysOR_parms.descr   = descr;
  snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_REG_SYSOR,
                                       &reg_sysOR_parms);

  return SYS_ORTABLE_REGISTERED_OK;
}
Пример #18
0
int
netsnmp_watched_timestamp_handler(netsnmp_mib_handler *handler,
                               netsnmp_handler_registration *reginfo,
                               netsnmp_agent_request_info *reqinfo,
                               netsnmp_request_info *requests)
{
    marker_t timestamp = (marker_t) handler->myvoid;
    long     uptime;

    DEBUGMSGTL(("helper:watcher:timestamp",
                               "Got request:  %d\n", reqinfo->mode));
    DEBUGMSGTL(( "helper:watcher:timestamp", "  oid:"));
    DEBUGMSGOID(("helper:watcher:timestamp", requests->requestvb->name,
                                   requests->requestvb->name_length));
    DEBUGMSG((   "helper:watcher:timestamp", "\n"));

    switch (reqinfo->mode) {
        /*
         * data requests 
         */
    case MODE_GET:
        if (handler->flags & NETSNMP_WATCHER_DIRECT)
            uptime = * (long*)timestamp;
        else
            uptime = netsnmp_marker_uptime( timestamp );
        snmp_set_var_typed_value(requests->requestvb,
                                 ASN_TIMETICKS,
                                 (u_char *) &uptime,
                                 sizeof(uptime));
        break;

        /*
         * Timestamps are inherently Read-Only,
         *  so don't need to support SET requests.
         */
    case MODE_SET_RESERVE1:
        netsnmp_set_request_error(reqinfo, requests,
                                  SNMP_ERR_NOTWRITABLE);
        handler->flags |= MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE;
        return SNMP_ERR_NOTWRITABLE;
    }

    /* next handler called automatically - 'AUTO_NEXT' */
    return SNMP_ERR_NOERROR;
}
Пример #19
0
int
agentx_register( struct snmp_session *ss, oid start[], size_t startlen,
                 int priority, int range_subid, oid range_ubound)
{
    struct snmp_pdu *pdu, *response;

    DEBUGMSGTL(("agentx/subagent","registering: "));
    DEBUGMSGOID(("agentx/subagent", start, startlen));
    DEBUGMSG(("agentx/subagent","\n"));
    if (! IS_AGENTX_VERSION( ss->version ))
        return 0;

    pdu = snmp_pdu_create(AGENTX_MSG_REGISTER);
    if ( pdu == NULL )
        return 0;
    pdu->time = 0;
    pdu->priority = priority;
    pdu->sessid = ss->sessid;
    pdu->range_subid = range_subid;
    if ( range_subid ) {
        snmp_pdu_add_variable( pdu, start, startlen,
                               ASN_OBJECT_ID, (u_char *)start, startlen);
        pdu->variables->val.objid[ range_subid-1 ] = range_ubound;
    }
    else
        snmp_add_null_var( pdu, start, startlen);

    if ( agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS ) {
        DEBUGMSGTL(("agentx/subagent","registering failed!\n"));
        return 0;
    }

    if ( response->errstat != SNMP_ERR_NOERROR ) {
        DEBUGMSGTL(("agentx/subagent","registering pdu failed: %d!\n",
                    response->errstat));
        snmp_free_pdu(response);
        return 0;
    }

    snmp_free_pdu(response);
    DEBUGMSGTL(("agentx/subagent","registered\n"));
    return 1;
}
Пример #20
0
void _mteEvent_dump (void)
{
    struct mteEvent *entry;

    netsnmp_tdata_row *row;

    int i = 0;

    for (row = netsnmp_tdata_row_first (event_table_data); row; row = netsnmp_tdata_row_next (event_table_data, row))
    {
        entry = (struct mteEvent *) row->data;
        DEBUGMSGTL (("disman:event:dump", "EventTable entry %d: ", i));
        DEBUGMSGOID (("disman:event:dump", row->oid_index.oids, row->oid_index.len));
        DEBUGMSG (("disman:event:dump", "(%s, %s)", row->indexes->val.string, row->indexes->next_variable->val.string));
        DEBUGMSG (("disman:event:dump", ": %p, %p\n", row, entry));
        i++;
    }
    DEBUGMSGTL (("disman:event:dump", "EventTable %d entries\n", i));
}
Пример #21
0
static void
netsnmp_tdomain_dump(void)
{
    netsnmp_tdomain *d;
    int i = 0;

    DEBUGMSGTL(("tdomain", "domain_list -> "));
    for (d = domain_list; d != NULL; d = d->next) {
        DEBUGMSG(("tdomain", "{ "));
        DEBUGMSGOID(("tdomain", d->name, d->name_length));
        DEBUGMSG(("tdomain", ", \""));
        for (i = 0; d->prefix[i] != NULL; i++) {
            DEBUGMSG(("tdomain", "%s%s", d->prefix[i],
		      (d->prefix[i + 1]) ? "/" : ""));
        }
        DEBUGMSG(("tdomain", "\" } -> "));
    }
    DEBUGMSG(("tdomain", "[NIL]\n"));
}
Пример #22
0
static struct tunnel *
getNextTunnelByConfigOid(oid * name, size_t * length)
{
    struct tunnel  *tunnel, *last_tunnel;
    oid             tname[10], last_tname[10];

    DEBUGMSG(("tunnel", "getNextTunnelByConfigOid("));
    DEBUGMSGOID(("tunnel", name, *length));
    DEBUGMSG(("tunnel", "): "));

    last_tunnel = NULL;
    for (tunnel = tunnels; tunnel; tunnel = tunnel->next) {
        if (!tunnel->active)
            continue;
        fillConfigOid(tname, tunnel);
        if (snmp_oid_compare(tname, 10,
                             &name[tunnel_len + 3],
                             (*length) - tunnel_len - 3) > 0) {
            if (!last_tunnel) {
                last_tunnel = tunnel;
                memcpy((char *) last_tname, (char *) tname,
                       10 * sizeof(oid));
            } else {
                if (snmp_oid_compare(tname, 10, last_tname, 10) < 0) {
                    last_tunnel = tunnel;
                    memcpy((char *) last_tname, (char *) tname,
                           10 * sizeof(oid));
                }
            }
        }
    }

    if (last_tunnel) {
        DEBUGMSG(("tunnel", "%s (index=%" NETSNMP_PRIo "u)\n",
                  last_tunnel->ifname, last_tunnel->ifindex));
    } else {
        DEBUGMSG(("tunnel", "NONE\n"));
    }

    return last_tunnel;
}
Пример #23
0
void
proxy_free_config(void)
{
    struct simple_proxy *rm;

    DEBUGMSGTL(("proxy_free_config", "Free config\n"));
    while (proxies) {
        rm = proxies;
        proxies = rm->next;

        DEBUGMSGTL(( "proxy_free_config", "freeing "));
        DEBUGMSGOID(("proxy_free_config", rm->name, rm->name_len));
        DEBUGMSG((   "proxy_free_config", " (%s)\n", rm->context));
        unregister_mib_context(rm->name, rm->name_len,
                               DEFAULT_MIB_PRIORITY, 0, 0,
                               rm->context);
        SNMP_FREE(rm->variables);
        SNMP_FREE(rm->context);
        snmp_close(rm->sess);
        SNMP_FREE(rm);
    }
}
Пример #24
0
int unregister_sysORTable_sess(oid *oidin,
			 size_t oidlen,
			 struct snmp_session *ss)
{
  struct sysORTable **ptr=&table, *prev=NULL;
  int found = SYS_ORTABLE_NO_SUCH_REGISTRATION;
  struct register_sysOR_parameters reg_sysOR_parms;

    DEBUGMSGTL(("mibII/sysORTable", "sysORTable unregistering: "));
    DEBUGMSGOID(("mibII/sysORTable", oidin, oidlen));
    DEBUGMSG(("mibII/sysORTable","\n"));

  while(*ptr != NULL) {
    if ( snmp_oid_compare( oidin, oidlen, (*ptr)->OR_oid, (*ptr)->OR_oidlen) == 0 ) {
      if ( (*ptr)->OR_sess != ss )
	continue;	/* different session */
      if ( prev == NULL )
        table      = (*ptr)->next;
      else 
        prev->next = (*ptr)->next;

      free( (*ptr)->OR_descr );
      free( (*ptr)->OR_oid );
      free( (*ptr) );
      numEntries--;
      found = SYS_ORTABLE_UNREGISTERED_OK;
      break;
    }
    prev = *ptr;
    ptr = &((*ptr)->next);
  }

  reg_sysOR_parms.name    = oidin;
  reg_sysOR_parms.namelen = oidlen;
  snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_UNREG_SYSOR,
                                       &reg_sysOR_parms);

  return found;
}
Пример #25
0
netsnmp_transport *
netsnmp_tdomain_transport_oid(const oid * dom,
                              size_t dom_len,
                              const u_char * o, size_t o_len, int local)
{
    netsnmp_tdomain *d;
    int             i;

    DEBUGMSGTL(("tdomain", "domain \""));
    DEBUGMSGOID(("tdomain", dom, dom_len));
    DEBUGMSG(("tdomain", "\"\n"));

    for (d = domain_list; d != NULL; d = d->next) {
        for (i = 0; d->prefix[i] != NULL; i++) {
            if (netsnmp_oid_equals(dom, dom_len, d->name, d->name_length) ==
                0) {
                return d->f_create_from_ostring(o, o_len, local);
            }
        }
    }

    snmp_log(LOG_ERR, "No support for requested transport domain\n");
    return NULL;
}
u_char         *
var_bgp(struct variable *vp,
        oid * name,
        int *length, int exact, int *var_len, WriteMethod ** write_method)
{
    u_char         *var;
    int             result;

    DEBUGMSGTL(("smux/snmp_bgp",
                "[var_bgp] var len %d, oid requested Len %d-", *var_len,
                *length));
    DEBUGMSGOID(("smux/snmp_bgp", name, *length));
    DEBUGMSG(("smux/snmp_bgp", "\n"));

    /*
     * Pass on the request to Gated.
     * If the request sent out was a get next, check to see if
     * it lies in the bgp range. If it doesn't, return NULL.
     * In either case, make sure that errors are checked on the
     * returned packets.
     */

    /*
     * No writes for now 
     */
    *write_method = NULL;

    /*
     * Donot allow access to the peer stuff as it crashes gated.
     * However A GetNext on the last 23.3.1.9 variable will force gated into
     * the peer stuff and cause it to crash.
     * The only way to fix this is to either solve the Gated problem, or 
     * remove the peer variables from Gated itself and cause it to return
     * NULL at the crossing. Currently doing the later.
     */

    /*
     * Reject GET and GETNEXT for anything above bgpifconf range 
     */
    result = snmp_oid_compare(name, *length, max_bgp_mib,
                              sizeof(max_bgp_mib) / sizeof(u_int));

    if (result >= 0) {
        DEBUGMSGTL(("smux/snmp_bgp", "Over shot\n"));
        return NULL;
    }

    /*
     * for GETs we need to be in the bgp range so reject anything below 
     */
    result = snmp_oid_compare(name, *length, min_bgp_mib,
                              sizeof(min_bgp_mib) / sizeof(u_int));
    if (exact && (result < 0)) {
        DEBUGMSGTL(("smux/snmp_bgp",
                    "Exact but doesn't match length %d, size %d\n",
                    *length, sizeof(min_bgp_mib)));
        return NULL;
    }

    /*
     * On return, 'var' points to the value returned which is of length
     * '*var_len'. 'name' points to the new (same as the one passed in for 
     * GETs) oid which has 'length' suboids.
     * 'smux_type' contains the type of the variable.
     */
    var = smux_snmp_process(exact, name, length, var_len);

    DEBUGMSGTL(("smux/snmp_bgp",
                "[var_bgp] var len %d, oid obtained Len %d-", *var_len,
                *length));
    DEBUGMSGOID(("smux/snmp_bgp", name, *length));
    DEBUGMSG(("smux/snmp_bgp", "\n"));

    vp->type = smux_type;

    /*
     * XXX Need a mechanism to return errors in gated's responses 
     */

    if (var == NULL)
        return NULL;

    /*
     * Any resullt returned should be within the bgp tree.
     * bgp_mib - static u_int bgp_mib[] = {1, 3, 6, 1, 2, 1, 15};
     */
    if (memcmp(bgp_mib, name, sizeof(bgp_mib)) != 0) {
        return NULL;
    } else {
        return var;
    }
}
Пример #27
0
static u_char *
search_subtree_vars(struct subtree *tp,
		    oid *name,    /* IN - name of var, OUT - name matched */
		    size_t *namelen, /* IN -number of sub-ids in name,
                                     OUT - subid-is in matched name */
		    u_char *type, /* OUT - type of matched variable */
		    size_t *len,  /* OUT - length of matched variable */
		    u_short *acl, /* OUT - access control list */
		    int exact,    /* IN - TRUE if exact match wanted */
		    WriteMethod **write_method,
		    struct snmp_pdu *pdu, /* IN - relevant auth info re PDU */
		    int *noSuchObject)
{
    register struct variable *vp;
    struct variable	compat_var, *cvp = &compat_var;
    register int	x;
    u_char		*access = NULL;
    int			result;
    oid 		*suffix;
    size_t		suffixlen;
#if MIB_CLIENTS_ARE_EVIL
    oid			save[MAX_OID_LEN];
    size_t		savelen = 0;
#endif

	    if ( tp->variables == NULL )
		return NULL;

	    result = compare_tree(name, *namelen, tp->name, tp->namelen);
	    suffixlen = *namelen - tp->namelen;
	    suffix = name + tp->namelen;
	    /* the following is part of the setup for the compatability
	       structure below that has been moved out of the main loop.
	     */
	    memcpy(cvp->name, tp->name, tp->namelen * sizeof(oid));

            *noSuchObject = TRUE;	/* In case of null variables_len */
	    for(x = 0, vp = tp->variables; x < tp->variables_len;
		vp =(struct variable *)((char *)vp +tp->variables_width), x++){
		/* if exact and ALWAYS
		   if next  and result >= 0 */
                /* and if vp->namelen != 0   -- Wes */
		if (vp->namelen && (exact || result >= 0)){
		    result = compare_tree(suffix, suffixlen, vp->name,
				     vp->namelen);
		}
		/* if exact and result == 0
		   if next  and result <= 0 */
                /* or if vp->namelen == 0    -- Wes */
		if ((!exact && (result <= 0)) || (exact && (result == 0)) ||
                  vp->namelen == 0) {
		    /* builds an old (long) style variable structure to retain
		       compatability with var_* functions written previously.
		     */
                  if (vp->namelen)
                    memcpy((cvp->name + tp->namelen),
			  vp->name, vp->namelen * sizeof(oid));
		    cvp->namelen = tp->namelen + vp->namelen;
		    cvp->type = vp->type;
		    cvp->magic = vp->magic;
		    cvp->acl = vp->acl;
		    cvp->findVar = vp->findVar;
                    *write_method = NULL;
#if MIB_CLIENTS_ARE_EVIL
                    memcpy(save, name, *namelen*sizeof(oid));
                    savelen = *namelen;
#endif
		    DEBUGMSGTL(("snmp_vars", "Trying variable: "));
		    DEBUGMSGOID(("snmp_vars", cvp->name, cvp->namelen));
		    DEBUGMSG(("snmp_vars"," ...\n"));

		gaga:
		    access = (*(vp->findVar))(cvp, name, namelen, exact,
						  len, write_method);
	    	    DEBUGMSGTL(("snmp_vars", "Returned %s\n",
				(access==NULL) ? "(null)" : "something" ));

			/*
			 * Check that the answer is acceptable.
			 *  i.e. lies within the current subtree chunk
			 *
			 * It might be worth saving this answer just in
			 *  case it turns out to be valid, but for now
			 *  we'll simply discard it.
			 */
		    if ( access && snmp_oid_compare(name, *namelen,
						    tp->end, tp->end_len) > 0) {
			memcpy(name, tp->end, tp->end_len);
			access = 0;
		    }
#if MIB_CLIENTS_ARE_EVIL
                    if (access == NULL) {
		      if (snmp_oid_compare(name, *namelen, save, savelen) != 0) {
			DEBUGMSGTL(("snmp_vars", "evil_client: "));
			DEBUGMSGOID(("snmp_vars", save, savelen));
			DEBUGMSG(("snmp_vars"," =>"));
			DEBUGMSGOID(("snmp_vars", name, *namelen));
			DEBUGMSG(("snmp_vars","\n"));
                        memcpy(name, save, savelen*sizeof(oid));
                        *namelen = savelen;
                      }
                    }
#endif
		    if (*write_method)
			*acl = cvp->acl;
                    /* check for permission to view this part of the OID tree */
		    if ((access != NULL || (*write_method != NULL && exact)) &&
                        in_a_view(name, namelen, pdu, cvp->type)) {
			if ( access && !exact ) {
				/*
				 * We've got an answer, but shouldn't use it.
				 * But we *might* be able to use a later
				 *  instance of the same object, so we can't
				 *  legitimately move on to the next variable
				 *  in the variable structure just yet.
				 * Let's try re-calling the findVar routine
				 *  with the returned name, and see whether
				 *  the next answer is acceptable
				 */
			   *write_method = NULL;
			   goto gaga;
			}
                        access = NULL;
			*write_method = NULL;
		    } else if (exact){
			found = TRUE;
		    }
		    if (access != NULL || (*write_method != NULL && exact))
			break;
		}
		/* if exact and result <= 0 */
		if (exact && (result  <= 0)){
	            *type = cvp->type;
		    *acl = cvp->acl;
		    if (found)
                      *noSuchObject = FALSE;
		    else
                      *noSuchObject = TRUE;
		    return NULL;
		}
	    }
	    if (access != NULL || (exact && *write_method != NULL)) {
	        *type = cvp->type;
		*acl = cvp->acl;
		return access;
	    }
	    return NULL;
}
Пример #28
0
u_char         *
var_extensible_version(struct variable *vp,
                       oid * name,
                       size_t * length,
                       int exact,
                       size_t * var_len, WriteMethod ** write_method)
{

    static long     long_ret;
    static char     errmsg[300];
    char           *cptr;
    time_t          curtime;
#ifdef CONFIGURE_OPTIONS
    static char     config_opts[] = CONFIGURE_OPTIONS;
#endif

    DEBUGMSGTL(("ucd-snmp/versioninfo", "var_extensible_version: "));
    DEBUGMSGOID(("ucd-snmp/versioninfo", name, *length));
    DEBUGMSG(("ucd-snmp/versioninfo", " %d\n", exact));

    if (header_generic(vp, name, length, exact, var_len, write_method))
        return (NULL);

    switch (vp->magic) {
    case MIBINDEX:
        long_ret = name[8];
        return ((u_char *) (&long_ret));
    case VERTAG:
        sprintf(errmsg, netsnmp_get_version());
        *var_len = strlen(errmsg);
        return ((u_char *) errmsg);
    case VERDATE:
        sprintf(errmsg, "$Date: 2004/01/27 17:24:26 $");
        *var_len = strlen(errmsg);
        return ((u_char *) errmsg);
    case VERCDATE:
        curtime = time(NULL);
        cptr = ctime(&curtime);
        sprintf(errmsg, cptr);
        *var_len = strlen(errmsg) - 1;
        return ((u_char *) errmsg);
    case VERIDENT:
        sprintf(errmsg,
                "$Id: versioninfo.c,v 5.2 2004/01/27 17:24:26 slif Exp $");
        *var_len = strlen(errmsg);
        return ((u_char *) errmsg);
    case VERCONFIG:
#ifdef CONFIGURE_OPTIONS
        *var_len = strlen(config_opts);
        if (*var_len > 1024)
            *var_len = 1024;    /* mib imposed restriction */
        return (u_char *) config_opts;
#else
        sprintf(errmsg, "");
        *var_len = strlen(errmsg);
        return ((u_char *) errmsg);
#endif
    case VERCLEARCACHE:
        *write_method = clear_cache;
        long_ret = 0;
        return ((u_char *) & long_ret);
    case VERUPDATECONFIG:
        *write_method = update_hook;
        long_ret = 0;
        return ((u_char *) & long_ret);
    case VERRESTARTAGENT:
        *write_method = restart_hook;
        long_ret = 0;
        return ((u_char *) & long_ret);
    case VERSAVEPERSISTENT:
        *write_method = save_persistent;
        long_ret = 0;
        return ((u_char *) & long_ret);
    case VERDEBUGGING:
        *write_method = debugging_hook;
        long_ret = snmp_get_do_debugging();
        return ((u_char *) & long_ret);
    }
    return NULL;
}
Пример #29
0
u_char         *
var_atEntry(struct variable * vp,
            oid * name,
            size_t * length,
            int exact, size_t * var_len, WriteMethod ** write_method)
{
    /*
     * 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.
     */
#define AT_MAX_NAME_LENGTH	16
#define AT_IFINDEX_OFF	10
    u_char         *cp;
    oid            *op;
    oid             lowest[AT_MAX_NAME_LENGTH];
    oid             current[AT_MAX_NAME_LENGTH];
    if_ip_t         NextAddr;
    mib2_ipNetToMediaEntry_t entry;
    static mib2_ipNetToMediaEntry_t Lowentry;
    int             Found = 0;
    req_e           req_type;
    int             offset, olength;
    static in_addr_t      addr_ret;

    /*
     * fill in object part of name for current (less sizeof instance part) 
     */

    DEBUGMSGTL(("mibII/at", "var_atEntry: "));
    DEBUGMSGOID(("mibII/at", vp->name, vp->namelen));
    DEBUGMSG(("mibII/at", " %d\n", exact));

    memset(&Lowentry, 0, sizeof(Lowentry));
    memcpy((char *) current, (char *) vp->name, vp->namelen * sizeof(oid));
    lowest[0] = 1024;
    for (NextAddr.ipAddr = (u_long) - 1, NextAddr.ifIdx = 255, req_type =
         GET_FIRST;;
         NextAddr.ipAddr = entry.ipNetToMediaNetAddress, NextAddr.ifIdx =
         current[AT_IFINDEX_OFF], req_type = GET_NEXT) {
        if (getMibstat
            (MIB_IP_NET, &entry, sizeof(mib2_ipNetToMediaEntry_t),
             req_type, &AT_Cmp, &NextAddr) != 0)
            break;
#ifdef NETSNMP_INCLUDE_IFTABLE_REWRITES
        entry.ipNetToMediaIfIndex.o_bytes[entry.ipNetToMediaIfIndex.o_length] = '\0';
        current[AT_IFINDEX_OFF] = netsnmp_access_interface_index_find(
           entry.ipNetToMediaIfIndex.o_bytes);
#else
        current[AT_IFINDEX_OFF] = 
           Interface_Index_By_Name(entry.ipNetToMediaIfIndex.o_bytes,
                                   entry.ipNetToMediaIfIndex.o_length);
#endif
        if (current[6] == 3) {  /* AT group oid */
            current[AT_IFINDEX_OFF + 1] = 1;
            offset = AT_IFINDEX_OFF + 2;
            olength = AT_IFINDEX_OFF + 6;
        } else {
            offset = AT_IFINDEX_OFF + 1;
            olength = AT_IFINDEX_OFF + 5;
        }
        COPY_IPADDR(cp, (u_char *) & entry.ipNetToMediaNetAddress, op,
                    current + offset);
        if (exact) {
            if (snmp_oid_compare(current, olength, name, *length) == 0) {
                memcpy((char *) lowest, (char *) current,
                       olength * sizeof(oid));
                Lowentry = entry;
                Found++;
                break;          /* no need to search further */
            }
        } else {
            if (snmp_oid_compare(current, olength, name, *length) > 0
                && snmp_oid_compare(current, olength, lowest,
                                    *length) < 0) {
                /*
                 * if new one is greater than input and closer to input than
                 * previous lowest, and is not equal to it, save this one as the "next" one.
                 */
                memcpy((char *) lowest, (char *) current,
                       olength * sizeof(oid));
                Lowentry = entry;
                Found++;
            }
        }
    }
    DEBUGMSGTL(("mibII/at", "... Found = %d\n", Found));
    if (Found == 0)
        return (NULL);
    memcpy((char *) name, (char *) lowest, olength * sizeof(oid));
    *length = olength;
    *write_method = 0;
    switch (vp->magic) {
    case IPMEDIAIFINDEX:
        *var_len = sizeof long_return;
#ifdef NETSNMP_INCLUDE_IFTABLE_REWRITES
        Lowentry.ipNetToMediaIfIndex.o_bytes[
            Lowentry.ipNetToMediaIfIndex.o_length] = '\0';
        long_return = netsnmp_access_interface_index_find(
            Lowentry.ipNetToMediaIfIndex.o_bytes);
#else
        long_return = Interface_Index_By_Name(
            Lowentry.ipNetToMediaIfIndex.o_bytes,
            Lowentry.ipNetToMediaIfIndex.o_length);
#endif
        return (u_char *) & long_return;
    case IPMEDIAPHYSADDRESS:
        *var_len = Lowentry.ipNetToMediaPhysAddress.o_length;
        return Lowentry.ipNetToMediaPhysAddress.o_bytes;
    case IPMEDIANETADDRESS:
        *var_len = sizeof(addr_ret);
        addr_ret = Lowentry.ipNetToMediaNetAddress;
        return (u_char *) &addr_ret;
    case IPMEDIATYPE:
        *var_len = sizeof long_return;
        long_return = Lowentry.ipNetToMediaType;
        return (u_char *) & long_return;
    default:
        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_atEntry\n",
                    vp->magic));
    }
    return NULL;
}
Пример #30
0
int
ip_handler(netsnmp_mib_handler          *handler,
           netsnmp_handler_registration *reginfo,
           netsnmp_agent_request_info   *reqinfo,
           netsnmp_request_info         *requests)
{
    netsnmp_request_info  *request;
    netsnmp_variable_list *requestvb;
    long     ret_value;
    oid      subid;
    int      type = ASN_COUNTER;

    /*
     * The cached data should already have been loaded by the
     *    cache handler, higher up the handler chain.
     */
#ifdef _USE_PERFSTAT_PROTOCOL
    ip_load(NULL, NULL);
#endif


    /*
     * 
     *
     */
    DEBUGMSGTL(("mibII/ip", "Handler - mode %s\n",
                    se_find_label_in_slist("agent_mode", reqinfo->mode)));
    switch (reqinfo->mode) {
    case MODE_GET:
        for (request=requests; request; request=request->next) {
            requestvb = request->requestvb;
            subid = requestvb->name[OID_LENGTH(ip_oid)];  /* XXX */
            DEBUGMSGTL(( "mibII/ip", "oid: "));
            DEBUGMSGOID(("mibII/ip", requestvb->name,
                                     requestvb->name_length));
            DEBUGMSG((   "mibII/ip", "\n"));

            switch (subid) {
#ifdef USES_SNMP_DESIGNED_IPSTAT
    case IPFORWARDING:
        ret_value = ipstat.ipForwarding;
        type = ASN_INTEGER;
        break;
    case IPDEFAULTTTL:
        ret_value = ipstat.ipDefaultTTL;
        type = ASN_INTEGER;
        break;
    case IPINRECEIVES:
        ret_value = ipstat.ipInReceives & 0xffffffff;
        break;
    case IPINHDRERRORS:
        ret_value = ipstat.ipInHdrErrors;
        break;
    case IPINADDRERRORS:
        ret_value = ipstat.ipInAddrErrors;
        break;
    case IPFORWDATAGRAMS:
        ret_value = ipstat.ipForwDatagrams;
        break;
    case IPINUNKNOWNPROTOS:
        ret_value = ipstat.ipInUnknownProtos;
        break;
    case IPINDISCARDS:
        ret_value = ipstat.ipInDiscards;
        break;
    case IPINDELIVERS:
        ret_value = ipstat.ipInDelivers & 0xffffffff;
        break;
    case IPOUTREQUESTS:
        ret_value = ipstat.ipOutRequests & 0xffffffff;
        break;
    case IPOUTDISCARDS:
        ret_value = ipstat.ipOutDiscards;
        break;
    case IPOUTNOROUTES:
        ret_value = ipstat.ipOutNoRoutes;
        break;
    case IPREASMTIMEOUT:
        ret_value = ipstat.ipReasmTimeout;
        type = ASN_INTEGER;
        break;
    case IPREASMREQDS:
        ret_value = ipstat.ipReasmReqds;
        break;
    case IPREASMOKS:
        ret_value = ipstat.ipReasmOKs;
        break;
    case IPREASMFAILS:
        ret_value = ipstat.ipReasmFails;
        break;
    case IPFRAGOKS:
        ret_value = ipstat.ipFragOKs;
        break;
    case IPFRAGFAILS:
        ret_value = ipstat.ipFragFails;
        break;
    case IPFRAGCREATES:
        ret_value = ipstat.ipFragCreates;
        break;
    case IPROUTEDISCARDS:
        ret_value = ipstat.ipRoutingDiscards;
        break;

#elif defined(USES_TRADITIONAL_IPSTAT) && !defined(_USE_PERFSTAT_PROTOCOL)
#ifdef HAVE_SYS_TCPIPSTATS_H
    /*
     * This actually reads statistics for *all* the groups together,
     * so we need to isolate the IP-specific bits.  
     */
#define	ipstat		ipstat.ipstat
#endif
    case IPFORWARDING:
    case IPDEFAULTTTL:
        /* 
         * Query these two individually
         */
        ret_value = ip_load(NULL, (void *)subid);
        if (ret_value == -1 ) {
            netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
            continue;
	}
        type = ASN_INTEGER;
        break;
    case IPINRECEIVES:
        ret_value = ipstat.ips_total & 0xffffffff;
        break;
    case IPINHDRERRORS:
        ret_value = ipstat.ips_badsum
            + ipstat.ips_tooshort
            + ipstat.ips_toosmall + ipstat.ips_badhlen + ipstat.ips_badlen;
        break;
    case IPINADDRERRORS:
        ret_value = ipstat.ips_cantforward;
        break;
    case IPFORWDATAGRAMS:
        ret_value = ipstat.ips_forward;
        break;
    case IPINUNKNOWNPROTOS:
#if HAVE_STRUCT_IPSTAT_IPS_NOPROTO
        ret_value = ipstat.ips_noproto;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPINDISCARDS:
#if HAVE_STRUCT_IPSTAT_IPS_FRAGDROPPED
        ret_value = ipstat.ips_fragdropped;   /* ?? */
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPINDELIVERS:
#if HAVE_STRUCT_IPSTAT_IPS_DELIVERED
        ret_value = ipstat.ips_delivered & 0xffffffff;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPOUTREQUESTS:
#if HAVE_STRUCT_IPSTAT_IPS_LOCALOUT
        ret_value = ipstat.ips_localout & 0xffffffff;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPOUTDISCARDS:
#if HAVE_STRUCT_IPSTAT_IPS_ODROPPED
        ret_value = ipstat.ips_odropped;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPOUTNOROUTES:
        /*
         * XXX: how to calculate this (counts dropped routes, not packets)?
         * ipstat.ips_cantforward isn't right, as it counts packets.
         * ipstat.ips_noroute is also incorrect.
         */
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
    case IPREASMTIMEOUT:
        ret_value = IPFRAGTTL;
        type = ASN_INTEGER;
        break;
    case IPREASMREQDS:
        ret_value = ipstat.ips_fragments;
        break;
    case IPREASMOKS:
#if HAVE_STRUCT_IPSTAT_IPS_REASSEMBLED
        ret_value = ipstat.ips_reassembled;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPREASMFAILS:
        ret_value = ipstat.ips_fragdropped + ipstat.ips_fragtimeout;
        break;
    case IPFRAGOKS:
#if HAVE_STRUCT_IPSTAT_IPS_FRAGMENTED
        ret_value = ipstat.ips_fragments;
        break;
#else            /* XXX */
        ret_value = ipstat.ips_fragments
            - (ipstat.ips_fragdropped + ipstat.ips_fragtimeout);
        break;
#endif
    case IPFRAGFAILS:
#if HAVE_STRUCT_IPSTAT_IPS_CANTFRAG
        ret_value = ipstat.ips_cantfrag;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPFRAGCREATES:
#if HAVE_STRUCT_IPSTAT_IPS_OFRAGMENTS
        ret_value = ipstat.ips_ofragments;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPROUTEDISCARDS:
#if HAVE_STRUCT_IPSTAT_IPS_NOROUTE
        ret_value = ipstat.ips_noroute;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
#ifdef HAVE_SYS_TCPIPSTATS_H
#undef ipstat
#endif
#elif defined(hpux11)
    case IPFORWARDING:
    case IPDEFAULTTTL:
    case IPREASMTIMEOUT:
        type = ASN_INTEGER;
    case IPINRECEIVES:
    case IPINHDRERRORS:
    case IPINADDRERRORS:
    case IPFORWDATAGRAMS:
    case IPINUNKNOWNPROTOS:
    case IPINDISCARDS:
    case IPINDELIVERS:
    case IPOUTREQUESTS:
    case IPOUTDISCARDS:
    case IPOUTNOROUTES:
    case IPREASMREQDS:
    case IPREASMOKS:
    case IPREASMFAILS:
    case IPFRAGOKS:
    case IPFRAGFAILS:
    case IPFRAGCREATES:
    case IPROUTEDISCARDS:
	/*
	 * This is a bit of a hack, to shoehorn the HP-UX 11
	 * single-object retrieval approach into the caching
	 * architecture.
	 */
	if (ip_load(NULL, (void*)subid) == -1 ) {
            netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
            continue;
	}
        ret_value = ipstat;
        break;
#elif defined (WIN32) || defined (cygwin)
    case IPFORWARDING:
        ipForwarding = ipstat.dwForwarding;
        ret_value    = ipstat.dwForwarding;
        type = ASN_INTEGER;
        break;
    case IPDEFAULTTTL:
        ipTTL     = ipstat.dwDefaultTTL;
        ret_value = ipstat.dwDefaultTTL;
        type = ASN_INTEGER;
        break;
    case IPINRECEIVES:
        ret_value = ipstat.dwInReceives;
        break;
    case IPINHDRERRORS:
        ret_value = ipstat.dwInHdrErrors;
        break;
    case IPINADDRERRORS:
        ret_value = ipstat.dwInAddrErrors;
        break;
    case IPFORWDATAGRAMS:
        ret_value = ipstat.dwForwDatagrams;
        break;
    case IPINUNKNOWNPROTOS:
        ret_value = ipstat.dwInUnknownProtos;
        break;
    case IPINDISCARDS:
        ret_value = ipstat.dwInDiscards;
        break;
    case IPINDELIVERS:
        ret_value = ipstat.dwInDelivers;
        break;
    case IPOUTREQUESTS:
        ret_value = ipstat.dwOutRequests;
        break;
    case IPOUTDISCARDS:
        ret_value = ipstat.dwOutDiscards;
        break;
    case IPOUTNOROUTES:
        ret_value = ipstat.dwOutNoRoutes;
        break;
    case IPREASMTIMEOUT:
        ret_value = ipstat.dwReasmTimeout;
        type = ASN_INTEGER;
        break;
    case IPREASMREQDS:
        ret_value = ipstat.dwReasmReqds;
        break;
    case IPREASMOKS:
        ret_value = ipstat.dwReasmOks;
        break;
    case IPREASMFAILS:
        ret_value = ipstat.dwReasmFails;
        break;
    case IPFRAGOKS:
        ret_value = ipstat.dwFragOks;
        break;
    case IPFRAGFAILS:
        ret_value = ipstat.dwFragFails;
        break;
    case IPFRAGCREATES:
        ret_value = ipstat.dwFragCreates;
        break;
    case IPROUTEDISCARDS:
        ret_value = ipstat.dwRoutingDiscards;
        break;
#elif defined(_USE_PERFSTAT_PROTOCOL)
    case IPFORWARDING:
        ret_value    = 0;
        type = ASN_INTEGER;
        break;
    case IPDEFAULTTTL:
        ret_value = 0;
        type = ASN_INTEGER;
        break;
    case IPINRECEIVES:
        ret_value = ps_proto.u.ip.ipackets;
        break;
    case IPINHDRERRORS:
    case IPINADDRERRORS:
    case IPFORWDATAGRAMS:
        ret_value = 0;
        break;
    case IPINUNKNOWNPROTOS:
        ret_value = ps_proto.u.ip.ierrors;
        break;
    case IPINDISCARDS:
        ret_value = 0;
        break;
    case IPINDELIVERS:
    case IPOUTREQUESTS:
        ret_value = ps_proto.u.ip.opackets;
        break;
    case IPOUTDISCARDS:
    case IPOUTNOROUTES:
        ret_value = 0;
        break;
    case IPREASMTIMEOUT:
        ret_value = 0;
        type = ASN_INTEGER;
        break;
    case IPREASMREQDS:
    case IPREASMOKS:
    case IPREASMFAILS:
    case IPFRAGOKS:
    case IPFRAGFAILS:
    case IPFRAGCREATES:
        ret_value = 0;
        break;
    case IPROUTEDISCARDS:
        ret_value = ps_proto.u.ip.oerrors;
        break;
#endif			/* USES_SNMP_DESIGNED_IPSTAT */

    case IPADDRTABLE:
    case IPROUTETABLE:
    case IPMEDIATABLE:
        /*
	 * These are not actually valid scalar objects.
	 * The relevant table registrations should take precedence,
	 *   so skip these three subtrees, regardless of architecture.
	 */
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;

	    }
	    snmp_set_var_typed_value(request->requestvb, (u_char)type,
			             (u_char *)&ret_value, sizeof(ret_value));
	}
        break;

    case MODE_GETNEXT:
    case MODE_GETBULK:
#ifndef NETSNMP_NO_WRITE_SUPPORT
    case MODE_SET_RESERVE1:
		/* XXX - Windows currently supports setting this */
    case MODE_SET_RESERVE2:
    case MODE_SET_ACTION:
    case MODE_SET_COMMIT:
    case MODE_SET_FREE:
    case MODE_SET_UNDO:
        snmp_log(LOG_WARNING, "mibII/ip: Unsupported mode (%d)\n",
                               reqinfo->mode);
        break;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
    default:
        snmp_log(LOG_WARNING, "mibII/ip: Unrecognised mode (%d)\n",
                               reqinfo->mode);
        break;
    }

    return SNMP_ERR_NOERROR;
}