/*
* Russ Cox, 17 August 1997
* rsc@research.att.com
*
* This program sends commands to the USR modem
* racks. Things like resetting cards and stuff.
* It waits for and prints the response.
*/
#include <u.h>
#include <libc.h>
#include "a1.h"
extern void chat(char*, ...);
int chatty;
int nfd;
char *usage = "usage: %s [-f] host card[,modem] cmd\n"
" for cards, commands are:\n"
" last none srvremove srvrestore hardreset\n"
" for modems, commands are:\n"
" last none softreset storenvram\n"
" readdefault readnvram offhook onhook\n"
"\n"
" last prints the last cmd given and the status\n"
;
char *a1top0 = "1.3.6.1.4.1.429.1.6.12.1.1";
char *a1top1 = "1.3.6.1.4.1.429.1.1.7.1.1";
char *ccmdstr[9] = {
"last", "none", "srvremove", "srvrestore", "hardreset", 0
};
char *mcmdstr[9] = {
"last", "none", "softreset", "storenvram",
"readdefault", "readnvram", "offhook", "onhook", 0
};
char *resultstr[256] = {
0, "none", "success", "in progress", "not supported",
"unable to run", "aborted", "failed"
};
char *whystr[256] = {
0, "no error", "unable",
[6] "unrecognized command",
[8] "slot empty",
[12] "no response",
[13] "not connected",
[14] "connected",
[17] "online",
[20] "unsupported command",
[22] "device disabled",
};
char *
sendcmd(int cmd, int force, int card, int modem)
{
static char result[128];
Snmp *s, *srep;
char b;
char *prefix;
char **cmdstr;
int id, n;
int r1, r2;
if(modem) {
cmdstr = mcmdstr;
prefix = a1top0;
id = card * 1000 + modem;
}else{
cmdstr = ccmdstr;
prefix = a1top1;
id = card;
}
if((s = Salloc()) == 0 || (srep = Salloc()) == 0)
return "cannot alloc snmp";
if(cmd == 0)
goto query;
s->vers = 0;
s->private = 1;
s->type = Pset;
s->estat = s->eindex = 0;
s->npdu = 3;
sprint(s->pdu[0].objid, "%s.4.%d", prefix, id);
sprint(s->pdu[1].objid, "%s.6.%d", prefix, id);
sprint(s->pdu[2].objid, "%s.5.%d", prefix, id);
s->pdu[0].type = Aint;
s->pdu[0].i = cmd;
s->pdu[1].type = Aoctstr;
s->pdu[1].len = 1;
s->pdu[1].s = &b;
b = '\0';
s->pdu[2].type = Aint;
s->pdu[2].i = force ? 1 : 2;
if(dosnmp(nfd, s, srep) < 0)
return "bad snmp exch";
/* then check responses:
do{
send 1.3.6.1.4.1.429.1.6.12.1.1.4.CC00M nil,
.1.7.CC00M nil,
.1.8.CC00M nil,
.1.7 ==
1 none
2 success
3 inprogress
4 not supported
5 unable to run
6 aborted
7 failed
} while response to .1.7 == 3 (in progress)
*/
query:
s->vers = 0;
s->private = 0; /* ! */
s->type = Pget;
s->estat = s->eindex = 0;
s->npdu = 3;
sprint(s->pdu[0].objid, "%s.4.%d", prefix, id);
sprint(s->pdu[1].objid, "%s.7.%d", prefix, id);
sprint(s->pdu[2].objid, "%s.8.%d", prefix, id);
s->pdu[0].type = s->pdu[1].type = s->pdu[2].type = Anull;
n = 0;
do {
sleep(1000);
if(dosnmp(nfd, s, srep) < 0)
return "bad snmp exch0";
n++;
} while(n <= 15 && srep->pdu[1].type == Aint && srep->pdu[1].i == 3);
if(srep->pdu[1].type != Aint || srep->pdu[2].type != Aint)
return "unexpected snmp packet";
r1 = srep->pdu[1].i;
r2 = srep->pdu[2].i;
if(r1 < 0 || r1 > 255) r1 = 0;
if(r2 < 0 || r2 > 255) r2 = 0;
if(cmd == 0) {
n = srep->pdu[0].i;
r1 = srep->pdu[1].i;
r2 = srep->pdu[2].i;
sprint(result, "cmd=%s[%d] err=%s[%d] why=%s[%d]",
n >= 0 && n < 9 ? cmdstr[n]: "?", n,
resultstr[r1] ? resultstr[r1] : "?", r1,
whystr[r2] ? whystr[r2] : "?", r2);
return result;
}
if(r1 <= 2) /* success! */
return 0;
sprint(result, "%s/%s",
resultstr[r1] ? resultstr[r1] : "(?)",
whystr[r2] ? whystr[r2] : "(?)");
return result;
}
void
main(int argc, char **argv)
{
int card, modem;
int force = 0;
int cmd;
char *s;
char *host;
ARGBEGIN{
case 'f':
force++;
break;
default:
fprint(2, usage, argv0);
exits("usage");
}ARGEND;
if(argc != 3) {
fprint(2, usage, argv0);
exits("usage");
}
host = argv[0];
card = atoi(argv[1]);
if((s = strchr(argv[1], ',')) == 0)
modem = 0;
else
modem = atoi(s+1);
if((nfd = dial(netmkaddr(host, "udp", "161"), 0, 0, 0)) < 0) {
fprint(2, "cannot dial: %r\n");
exits("dial");
}
if(modem) {
for(cmd = 0; mcmdstr[cmd]; cmd++) {
if(strcmp(argv[2], mcmdstr[cmd]) == 0)
break;
}
if(mcmdstr[cmd] == 0) {
fprint(2, usage, argv0);
exits("usage");
}
} else {
for(cmd = 0; ccmdstr[cmd]; cmd++) {
if(strcmp(argv[2], ccmdstr[cmd]) == 0)
break;
}
if(ccmdstr[cmd] == 0) {
fprint(2, usage, argv0);
exits("usage");
}
}
s = sendcmd(cmd, force, card, modem);
if(s == 0)
exits(0);
fprint(2, "%s\n", s);
exits(s);
}
|