/* * 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 #include #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); }