Plan 9 from Bell Labs’s /usr/web/sources/contrib/rsc/snmp/tcmcmd.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


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

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.