1
0
Files
irix-657m-src/irix/cmd/smt/lib/sm_map.c
2022-09-29 17:59:04 +03:00

355 lines
7.4 KiB
C

/*
* Copyright 1989,1990,1991 Silicon Graphics, Inc. All rights reserved.
*
* $Revision: 1.19 $
*/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <bstring.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_var.h>
#include <ctype.h>
#include <netdb.h>
#include <sys/types.h>
#include <sm_types.h>
#include <sm_log.h>
#include <sm_mib.h>
#include <smt_mib.h>
#include <smt_snmp.h>
#include <smt_snmp_impl.h>
#include <smt_snmp_api.h>
#include <smtd_parm.h>
#include <smtd.h>
#include <smt_subr.h>
#include <smt_snmp_clnt.h>
#include <smtd_fs.h>
#include <sm_map.h>
static struct snmp_session *map_ss = 0;
/* Must be at most (14-1) chars long -- used as Unix socket name */
static char map_tmplt[] = "/tmp/.MXXXXXX";
static char *tfname = 0;
static char *peername = "localhost";
void
map_setpeer(char *peer)
{
static char peerary[MAXHOSTNAMELEN];
if (!peer || *peer == '\0') {
peername = "localhost";
return;
}
strcpy(peerary, peer);
peername = peerary;
}
char *
map_getpeer()
{
return(peername);
}
static int maprtry = 0;
static int maptimo = SNMP_DEFAULT_TIMEOUT;
void
map_settimo(int timo, int rtry)
{
maprtry = rtry;
maptimo = timo*1000000L;
}
void
map_resettimo(void)
{
maprtry = 0;
maptimo = SNMP_DEFAULT_TIMEOUT;
}
int
map_open(char *community, char *(*auth)())
{
struct snmp_session session;
int s = -1;
if (map_ss) {
sm_log(LOG_INFO, 0, "map_open: redundant open request ignored");
return(-1);
}
if ((!tfname) && !strcmp(peername, "localhost")) {
if ((tfname = mktemp(map_tmplt)) == NULL) {
sm_log(LOG_ERR, SM_ISSYSERR, "map_open: mktemp failed");
return(-1);
}
}
bzero((char *)&session, sizeof(session));
session.peername = peername;
session.community = community;
session.community_len = strlen(community);
session.retries = maprtry;
session.timeout = maptimo;
session.authenticator = auth;
snmp_synch_setup(&session);
if ((map_ss = snmp_open(&session, &s, tfname)) == 0)
return(-1);
return(0);
}
void
map_close(void)
{
if (!map_ss)
return;
snmp_close(map_ss);
if (tfname) {
unlink(tfname);
tfname = 0;
}
map_setpeer(0);
map_ss = 0;
}
static char *
action2name(action)
{
#ifdef __STDC__
#define ACASE(x) case FDDI_SNMP_ ## x: return #x
#else
#define ACASE(x) case FDDI_SNMP_/**/x: return "x"
#endif
switch (action) {
ACASE(INFO);
ACASE(UP);
ACASE(DOWN);
ACASE(THRUA);
ACASE(THRUB);
ACASE(WRAPA);
ACASE(WRAPB);
ACASE(STAT);
ACASE(SINGLE);
ACASE(DUAL);
ACASE(DUMP);
ACASE(REGFS);
ACASE(UNREGFS);
ACASE(TRACE);
ACASE(MAINT);
ACASE(SENDFRAME);
ACASE(FSSTAT);
ACASE(FSDELETE);
ACASE(VERSION);
default:
return "???";
}
}
#undef ACASE
/*
* Get 1 variable each time.
*/
int
map_smt(char *ifname, int action, void *buf, int buflen, int phyidx)
{
oid subid;
int unit;
struct snmp_pdu *pdu, *response = 0;
struct variable_list *vars;
oid name[MAX_NAME_LEN];
int name_length;
int status;
int pos;
int rtry;
if (!ifname) {
subid = 1; /* SMT */
unit = phyidx;
} else if (strncmp(ifname, "rns", 3) == 0) {
subid = 6;
unit = (int)(ifname[3] - '0');
} else if (strncmp(ifname, "xpi", 3) == 0) {
subid = 5;
unit = (int)(ifname[3] - '0');
} else if (strncmp(ifname, "ipg", 3) == 0) {
subid = 4;
unit = (int)(ifname[3] - '0');
#ifdef undef
} else if (strncmp(ifname, "xxx", 3) == 0) {
subid = 3;
unit = (int)(ifname[3] - '0');
} else if (strncmp(ifname, "xxx", 2) == 0) {
subid = 2;
unit = (int)(ifname[2] - '0');
#endif
} else {
sm_log(LOG_ERR,0,"map_smt: FDDI interface %s not found",ifname);
return(STAT_ERROR);
}
if (!map_ss) {
status = map_open("public", NULL);
if (status)
return(STAT_ERROR);
}
pos = get_sgifddimib((char *)name);
name[pos ] = (oid)subid;
name[pos+1] = (oid)action;
name[pos+2] = (oid)(unit);
pos += 3;
if ((action == FDDI_SNMP_STAT) ||
(action == FDDI_SNMP_MAINT)) {
name[pos] = (oid)(phyidx);
pos++;
}
name_length = pos;
name[pos] = 0;
rtry = map_ss->retries;
retry:
switch (action) {
case FDDI_SNMP_INFO:
case FDDI_SNMP_STAT:
case FDDI_SNMP_DUMP:
case FDDI_SNMP_FSSTAT:
case FDDI_SNMP_VERSION:
pdu = snmp_pdu_create(GET_REQ_MSG);
snmp_add_null_var(pdu, name, name_length);
break;
case FDDI_SNMP_UP:
case FDDI_SNMP_DOWN:
case FDDI_SNMP_THRUA:
case FDDI_SNMP_THRUB:
case FDDI_SNMP_WRAPA:
case FDDI_SNMP_WRAPB:
case FDDI_SNMP_SINGLE:
case FDDI_SNMP_DUAL:
case FDDI_SNMP_TRACE:
pdu = snmp_pdu_create(SET_REQ_MSG);
vars = (struct variable_list *)Malloc(sizeof(*vars));
pdu->variables = vars;
vars->next_variable = NULL;
vars->name = (oid *)Malloc(name_length * sizeof(oid));
bcopy((char *)name, (char *)vars->name,
name_length * sizeof(oid));
vars->name_length = name_length;
vars->type = ASN_OCTET_STR;
vars->val.string = Malloc(2);
bcopy("on", vars->val.string, 2);
vars->val_len = 2;
break;
case FDDI_SNMP_REGFS:
case FDDI_SNMP_UNREGFS:
case FDDI_SNMP_MAINT:
case FDDI_SNMP_SENDFRAME:
case FDDI_SNMP_FSDELETE:
pdu = snmp_pdu_create(SET_REQ_MSG);
vars = (struct variable_list *)Malloc(sizeof(*vars));
pdu->variables = vars;
vars->next_variable = NULL;
vars->name = (oid *)Malloc(name_length * sizeof(oid));
bcopy((char *)name, (char *)vars->name,
name_length * sizeof(oid));
vars->name_length = name_length;
vars->type = ASN_OCTET_STR;
vars->val.string = Malloc(buflen);
bcopy(buf, vars->val.string, buflen);
vars->val_len = buflen;
break;
default:
sm_log(LOG_EMERG,0,"map_smt: BAD command %d", action);
exit(99);
}
status = snmp_synch_response(map_ss, pdu, &response);
if (!response || status != STAT_SUCCESS) {
/* XXX routine should return useful error status codes */
sm_log(LOG_ERR, 0,
((status == STAT_TIMEOUT)
? "No response from daemon: timed-out"
: "Can't get response from daemon"));
goto snmp_stat_ret;
}
if (response->errstat != SNMP_ERR_NOERROR) {
sm_log(LOG_ERR,0,"Error: %s.%d %s: %s",
ifname ? ifname: "smt", phyidx, action2name(action),
snmp_errstring(response->errstat));
if (response->errstat == SNMP_ERR_NOSUCHNAME &&
(vars = response->variables) != 0) {
char loc_buf[256];
sprint_objid(loc_buf, vars->name, vars->name_length);
sm_log(LOG_ERR, 0, "map_smt: %s doesn't exist",
loc_buf);
}
snmp_free_pdu(response);
response = 0;
rtry--;
if (rtry > 0)
goto retry;
status = STAT_ERROR;
goto snmp_stat_ret;
}
vars = response->variables;
switch (action) {
case FDDI_SNMP_INFO:
case FDDI_SNMP_STAT:
case FDDI_SNMP_DUMP:
case FDDI_SNMP_FSSTAT:
case FDDI_SNMP_VERSION:
if (buf) {
if (buflen > response->variables->val_len)
buflen = response->variables->val_len;
bcopy(response->variables->val.string, buf, buflen);
}
break;
case FDDI_SNMP_UP:
case FDDI_SNMP_DOWN:
case FDDI_SNMP_THRUA:
case FDDI_SNMP_THRUB:
case FDDI_SNMP_WRAPA:
case FDDI_SNMP_WRAPB:
case FDDI_SNMP_SINGLE:
case FDDI_SNMP_DUAL:
case FDDI_SNMP_REGFS:
case FDDI_SNMP_UNREGFS:
case FDDI_SNMP_MAINT:
case FDDI_SNMP_TRACE:
case FDDI_SNMP_SENDFRAME:
case FDDI_SNMP_FSDELETE:
break;
default:
sm_log(LOG_EMERG, 0, "map_smt: Invalid action: %d", action);
exit(99);
}
snmp_stat_ret:
if (response)
snmp_free_pdu(response);
return(status);
}
void
map_exit(int es)
{
map_close();
exit(es);
}