snmp_api.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1998 by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "snmp_msg.h"
#include "snmp_api.h"
#include "error.h"
/***** GLOBAL VARIABLES *****/
int snmp_errno = 0;
/***** LOCAL CONSTANTS *****/
#define DEFAULT_COMMUNITY "public"
#define DEFAULT_RETRIES 4
#define DEFAULT_TIMEOUT 1000000L
#define DEFAULT_REMPORT SNMP_PORT
#define DEFAULT_LOCPORT 0
#define DEFAULT_ENTERPRISE &sun_oid
/***** LOCAL TYPES *****/
/*
* A list of all the outstanding requests
* for a particular session
*/
typedef struct _SNMP_request_list {
struct _SNMP_request_list *next_request;
int predefined_id;
int retries; /* Number of retries */
/*
* Internal information about the state of the snmp session
*/
typedef struct _SNMP_internal_session {
int sd; /* socket descriptor for this connection */
/*
*/
typedef struct _SNMP_session_list {
struct _SNMP_session_list *next;
/***** STATIC VARIABLES *****/
static uint32_t static_request_id = 0;
static char *snmp_api_errors[5] = {
"System error",
"Unknown session",
"Unknown host",
"Invalid local port",
"Unknown Error"
};
/***** STATIC FUNCTIONS *****/
static char *api_errstring(int snmp_errnumber);
/*
static init_snmp();
*/
static int snmp_session_timeout_loop();
/*******************************************************************/
static char *api_errstring(int snmp_errnumber)
{
{
}
else
{
return "Unknown Error";
}
}
/*******************************************************************/
/*
* Gets initial request ID for all transactions
*/
/*
static init_snmp()
{
struct timeval tv;
(void)gettimeofday(&tv, (struct timezone *) 0);
static_request_id = random();
}
*/
/*******************************************************************/
SNMP_session *snmp_session_open_default(char *peername, void callback(), void *callback_magic, char *error_label)
{
return snmp_session_open(peername,
}
/*******************************************************************/
SNMP_session *snmp_session_open(char *peername, char *community, int retries, int32_t timeout, void callback(), void *callback_magic, char *error_label)
{
char *peername_dup;
char *community_dup;
struct sockaddr_in me;
error_label[0] = '\0';
{
return NULL;
}
{
return NULL;
}
if(community == SNMP_DEFAULT_COMMUNITY)
{
}
if(retries == SNMP_DEFAULT_RETRIES)
{
}
if(timeout == SNMP_DEFAULT_TIMEOUT)
{
}
if(remote_port == SNMP_DEFAULT_REMPORT)
{
}
if(local_port == SNMP_DEFAULT_LOCPORT)
{
}
{
return NULL;
}
/****************************************/
/* 1) allocate the different structures */
/****************************************/
if(peername_dup == NULL)
{
return NULL;
}
if(community_dup == NULL)
{
return NULL;
}
{
return NULL;
}
{
return NULL;
}
{
return NULL;
}
/*************************************/
/* 2) now link the SNMP_session_list */
/*************************************/
first_session = slp;
/***************************************/
/* 3) initialize SNMP_session */
/***************************************/
/***************************************/
/* 4) initialize SNMP_internal_session */
/***************************************/
/* Set up connections */
{
{
exit(1);
}
return NULL;
}
/* initialize address */
/* bind */
{
{
exit(1);
}
return NULL;
}
/* request list */
return session;
}
/*******************************************************************/
/*
* Free each element in the input request list.
*/
{
while(rp)
{
{
}
}
return;
}
/*******************************************************************/
{
error_label[0] = '\0';
{
/* If first entry */
slp = first_session;
}
else
{
{
{
if(oslp) /* if we found entry that points here */
{
}
break;
}
}
}
/* If we found the session, free all data associated with it */
if(slp)
{
{
}
{
}
{
{
}
}
}
else
{
return -1;
}
return 0;
}
/*******************************************************************/
/*
* 1) sends the input pdu on the specified session
* 2) if this request is a pdu, add it to the request list
*
* Upon success, 0 is returned.
* On any error, -1 is returned and error_label is set.
*
* The pdu is freed by snmp_session_send() unless a failure occured.
*/
{
error_label[0] = '\0';
{
{
break;
}
}
{
return -1;
}
{
{
return -1;
}
}
{
}
else
{
pdu->request_id = 0;
}
{
/* set up to expect a response */
{
return -1;
}
}
{
return -1;
}
{
/*
printf("%d NOW: %d sec and %d usec\n",
rp->retries,
tv.tv_sec,
tv.tv_usec);
*/
/*
printf("%d EXPIRE: %d sec and %d usec\n\n",
rp->retries,
tv.tv_sec,
tv.tv_usec);
*/
}
else
{
}
return 0;
}
/*******************************************************************/
{
while(snmp_session_read_loop(fdset));
}
/*
* We need this function because the user may close the session
* in the callback and then corrupt the session list
*/
{
{
{
{
return 0;
}
{
{
{
/* delete request */
{
/* first in list */
}
else
{
{
{
break;
}
}
}
/*
* Then we should return as soon as possible
* because may have closed the session and
* corrupted the pointers
*/
break;
}
}
}
else
{
/*
* Then we should return as soon as possible
* because may have closed the session and
* corrupted the pointers
*/
}
return 1;
}
}
return 0;
}
void snmp_session_read_2(int fd)
{
{
{
{
return;
}
{
{
{
/* delete request */
{
/* first in list */
}
else
{
{
{
break;
}
}
}
/*
* Then we should return as soon as possible
* because may have closed the session and
* corrupted the pointers
*/
break;
}
}
}
else
{
/*
* Then we should return as soon as possible
* because may have closed the session and
* corrupted the pointers
*/
}
return;
}
}
return;
}
/*******************************************************************/
{
/*
* For each request outstanding, add it's socket to the fdset,
* and if it is the earliest timeout to expire, mark it as lowest.
*/
{
active++;
{
}
{
/* found another session with outstanding requests */
{
requests++;
{
}
}
}
}
/*
printf("NUM REQUESTS: %d\n",
requests);
*/
if(requests == 0)
{
/* if none are active, skip arithmetic */
return 0;
}
/*
printf("EARLIEST TIMEOUT: %d sec and %d usec\n\n",
earliest.tv_sec,
earliest.tv_usec);
*/
/*
* Now find out how much time until the earliest timeout. This
* transforms earliest from an absolute time into a delta time, the
* time left until the select should timeout.
*/
{
}
{
}
{
}
{
}
else
{
}
/*
printf("NEW TIMEOUT: %d sec and %d usec\n\n",
timeout->tv_sec,
timeout->tv_usec);
*/
return requests;
}
{
int numfds = 0;
}
/*******************************************************************/
/*
* It may remain some bugs in this function
* because the user may close the session in the callback
* and then corrupt the list
*/
void snmp_session_timeout()
{
while(snmp_session_timeout_loop());
}
static int snmp_session_timeout_loop()
{
/*
* For each request outstanding, check to see if it has expired.
*/
{
{
{
/* this timer has expired */
{
/* No more chances, delete this entry */
{
}
else
{
}
return 1;
}
else
{
/* retransmit this pdu */
{
}
/*
printf("%d NOW: %d sec and %d usec\n",
rp->retries,
tv.tv_sec,
tv.tv_usec);
*/
/*
printf("%d EXPIRE: %d sec and %d usec\n\n",
rp->retries,
tv.tv_sec,
tv.tv_usec);
*/
}
}
}
}
return 0;
}