xref: /plan9/sys/src/cmd/aux/portmap.c (revision 2b5f567beda2274a3ad03ae549b930bf3db1bf9e)
134e04225SDavid du Colombier /* Copyright © 2003 Russ Cox, MIT; see /sys/src/libsunrpc/COPYING */
234e04225SDavid du Colombier #include <u.h>
334e04225SDavid du Colombier #include <libc.h>
434e04225SDavid du Colombier #include <thread.h>
534e04225SDavid du Colombier #include <sunrpc.h>
634e04225SDavid du Colombier 
734e04225SDavid du Colombier int chatty;
834e04225SDavid du Colombier SunClient *client;
934e04225SDavid du Colombier 
1034e04225SDavid du Colombier void
usage(void)1134e04225SDavid du Colombier usage(void)
1234e04225SDavid du Colombier {
1334e04225SDavid du Colombier 	fprint(2, "usage: portmap address [cmd]\n"
1434e04225SDavid du Colombier 		"cmd is one of:\n"
1534e04225SDavid du Colombier 		"\tnull\n"
1634e04225SDavid du Colombier 		"\tset prog vers proto port\n"
1734e04225SDavid du Colombier 		"\tunset prog vers proto port\n"
1834e04225SDavid du Colombier 		"\tgetport prog vers proto\n"
1934e04225SDavid du Colombier 		"\tdump (default)\n");
2034e04225SDavid du Colombier 	threadexitsall("usage");
2134e04225SDavid du Colombier }
2234e04225SDavid du Colombier 
2334e04225SDavid du Colombier void
portCall(SunCall * c,PortCallType type)2434e04225SDavid du Colombier portCall(SunCall *c, PortCallType type)
2534e04225SDavid du Colombier {
2634e04225SDavid du Colombier 	c->rpc.prog = PortProgram;
2734e04225SDavid du Colombier 	c->rpc.vers = PortVersion;
2834e04225SDavid du Colombier 	c->rpc.proc = type>>1;
2934e04225SDavid du Colombier 	c->rpc.iscall = !(type&1);
3034e04225SDavid du Colombier 	c->type = type;
3134e04225SDavid du Colombier }
3234e04225SDavid du Colombier 
3334e04225SDavid du Colombier void
tnull(char ** argv)3434e04225SDavid du Colombier tnull(char **argv)
3534e04225SDavid du Colombier {
3634e04225SDavid du Colombier 	PortTNull tx;
3734e04225SDavid du Colombier 	PortRNull rx;
3834e04225SDavid du Colombier 
3934e04225SDavid du Colombier 	USED(argv);
4034e04225SDavid du Colombier 
4134e04225SDavid du Colombier 	memset(&tx, 0, sizeof tx);
4234e04225SDavid du Colombier 	portCall(&tx.call, PortCallTNull);
4334e04225SDavid du Colombier 
4434e04225SDavid du Colombier 	memset(&rx, 0, sizeof rx);
4534e04225SDavid du Colombier 	portCall(&rx.call, PortCallRNull);
4634e04225SDavid du Colombier 
4734e04225SDavid du Colombier 	if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
4834e04225SDavid du Colombier 		sysfatal("rpc: %r");
4934e04225SDavid du Colombier }
5034e04225SDavid du Colombier 
5134e04225SDavid du Colombier void
tset(char ** argv)5234e04225SDavid du Colombier tset(char **argv)
5334e04225SDavid du Colombier {
5434e04225SDavid du Colombier 	PortTSet tx;
5534e04225SDavid du Colombier 	PortRSet rx;
5634e04225SDavid du Colombier 
5734e04225SDavid du Colombier 	memset(&tx, 0, sizeof tx);
5834e04225SDavid du Colombier 	portCall(&tx.call, PortCallTSet);
5934e04225SDavid du Colombier 	tx.map.prog = strtol(argv[0], 0, 0);
6034e04225SDavid du Colombier 	tx.map.vers = strtol(argv[1], 0, 0);
6134e04225SDavid du Colombier 	tx.map.prot = strtol(argv[2], 0, 0);
6234e04225SDavid du Colombier 	tx.map.port = strtol(argv[3], 0, 0);
6334e04225SDavid du Colombier 
6434e04225SDavid du Colombier 	memset(&rx, 0, sizeof rx);
6534e04225SDavid du Colombier 	portCall(&rx.call, PortCallRSet);
6634e04225SDavid du Colombier 
6734e04225SDavid du Colombier 	if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
6834e04225SDavid du Colombier 		sysfatal("rpc: %r");
6934e04225SDavid du Colombier 
7034e04225SDavid du Colombier 	if(rx.b == 0)
7134e04225SDavid du Colombier 		print("rejected\n");
7234e04225SDavid du Colombier }
7334e04225SDavid du Colombier 
7434e04225SDavid du Colombier void
tunset(char ** argv)7534e04225SDavid du Colombier tunset(char **argv)
7634e04225SDavid du Colombier {
7734e04225SDavid du Colombier 	PortTUnset tx;
7834e04225SDavid du Colombier 	PortRUnset rx;
7934e04225SDavid du Colombier 
8034e04225SDavid du Colombier 	memset(&tx, 0, sizeof tx);
8134e04225SDavid du Colombier 	portCall(&tx.call, PortCallTUnset);
8234e04225SDavid du Colombier 	tx.map.prog = strtol(argv[0], 0, 0);
8334e04225SDavid du Colombier 	tx.map.vers = strtol(argv[1], 0, 0);
8434e04225SDavid du Colombier 	tx.map.prot = strtol(argv[2], 0, 0);
8534e04225SDavid du Colombier 	tx.map.port = strtol(argv[3], 0, 0);
8634e04225SDavid du Colombier 
8734e04225SDavid du Colombier 	memset(&rx, 0, sizeof rx);
8834e04225SDavid du Colombier 	portCall(&rx.call, PortCallRUnset);
8934e04225SDavid du Colombier 
9034e04225SDavid du Colombier 	if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
9134e04225SDavid du Colombier 		sysfatal("rpc: %r");
9234e04225SDavid du Colombier 
9334e04225SDavid du Colombier 	if(rx.b == 0)
9434e04225SDavid du Colombier 		print("rejected\n");
9534e04225SDavid du Colombier }
9634e04225SDavid du Colombier 
9734e04225SDavid du Colombier void
tgetport(char ** argv)9834e04225SDavid du Colombier tgetport(char **argv)
9934e04225SDavid du Colombier {
10034e04225SDavid du Colombier 	PortTGetport tx;
10134e04225SDavid du Colombier 	PortRGetport rx;
10234e04225SDavid du Colombier 
10334e04225SDavid du Colombier 	memset(&tx, 0, sizeof tx);
10434e04225SDavid du Colombier 	portCall(&tx.call, PortCallTGetport);
10534e04225SDavid du Colombier 	tx.map.prog = strtol(argv[0], 0, 0);
10634e04225SDavid du Colombier 	tx.map.vers = strtol(argv[1], 0, 0);
10734e04225SDavid du Colombier 	tx.map.prot = strtol(argv[2], 0, 0);
10834e04225SDavid du Colombier 
10934e04225SDavid du Colombier 	memset(&rx, 0, sizeof rx);
11034e04225SDavid du Colombier 	portCall(&rx.call, PortCallRGetport);
11134e04225SDavid du Colombier 
11234e04225SDavid du Colombier 	if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
11334e04225SDavid du Colombier 		sysfatal("rpc: %r");
11434e04225SDavid du Colombier 
11534e04225SDavid du Colombier 	print("%d\n", rx.port);
11634e04225SDavid du Colombier }
11734e04225SDavid du Colombier 
11834e04225SDavid du Colombier void
tdump(char ** argv)11934e04225SDavid du Colombier tdump(char **argv)
12034e04225SDavid du Colombier {
12134e04225SDavid du Colombier 	int i;
12234e04225SDavid du Colombier 	uchar *p;
12334e04225SDavid du Colombier 	PortTDump tx;
12434e04225SDavid du Colombier 	PortRDump rx;
12534e04225SDavid du Colombier 	PortMap *m;
12634e04225SDavid du Colombier 
12734e04225SDavid du Colombier 	USED(argv);
12834e04225SDavid du Colombier 
12934e04225SDavid du Colombier 	memset(&tx, 0, sizeof tx);
13034e04225SDavid du Colombier 	portCall(&tx.call, PortCallTDump);
13134e04225SDavid du Colombier 
13234e04225SDavid du Colombier 	memset(&rx, 0, sizeof rx);
13334e04225SDavid du Colombier 	portCall(&rx.call, PortCallRDump);
13434e04225SDavid du Colombier 
13534e04225SDavid du Colombier 	if(sunClientRpc(client, 0, &tx.call, &rx.call, &p) < 0)
13634e04225SDavid du Colombier 		sysfatal("rpc: %r");
13734e04225SDavid du Colombier 
13834e04225SDavid du Colombier 	for(i=0, m=rx.map; i<rx.nmap; i++, m++)
13934e04225SDavid du Colombier 		print("%ud %ud %ud %ud\n", (uint)m->prog, (uint)m->vers, (uint)m->prot, (uint)m->port);
14034e04225SDavid du Colombier 
14134e04225SDavid du Colombier 	free(p);
14234e04225SDavid du Colombier }
14334e04225SDavid du Colombier 
14434e04225SDavid du Colombier static struct {
14534e04225SDavid du Colombier 	char *cmd;
14634e04225SDavid du Colombier 	int narg;
14734e04225SDavid du Colombier 	void (*fn)(char**);
14834e04225SDavid du Colombier } tab[] = {
14934e04225SDavid du Colombier 	"null",	0,	tnull,
15034e04225SDavid du Colombier 	"set",	4,	tset,
15134e04225SDavid du Colombier 	"unset",	4,	tunset,
15234e04225SDavid du Colombier 	"getport",	3,	tgetport,
15334e04225SDavid du Colombier 	"dump",	0,	tdump,
15434e04225SDavid du Colombier };
15534e04225SDavid du Colombier 
15634e04225SDavid du Colombier void
threadmain(int argc,char ** argv)15734e04225SDavid du Colombier threadmain(int argc, char **argv)
15834e04225SDavid du Colombier {
15934e04225SDavid du Colombier 	char *dflt[] = { "dump", };
16034e04225SDavid du Colombier 	char *addr, *cmd;
16134e04225SDavid du Colombier 	int i;
16234e04225SDavid du Colombier 
16334e04225SDavid du Colombier 	ARGBEGIN{
16434e04225SDavid du Colombier 	case 'R':
16534e04225SDavid du Colombier 		chatty++;
16634e04225SDavid du Colombier 		break;
16734e04225SDavid du Colombier 	}ARGEND
16834e04225SDavid du Colombier 
169*2b5f567bSDavid du Colombier 	if(argc < 1)
17034e04225SDavid du Colombier 		usage();
17134e04225SDavid du Colombier 
17234e04225SDavid du Colombier 	fmtinstall('B', sunRpcFmt);
17334e04225SDavid du Colombier 	fmtinstall('C', sunCallFmt);
17434e04225SDavid du Colombier 	fmtinstall('H', encodefmt);
17534e04225SDavid du Colombier 	sunFmtInstall(&portProg);
17634e04225SDavid du Colombier 
17734e04225SDavid du Colombier 	addr = netmkaddr(argv[0], "udp", "portmap");
17834e04225SDavid du Colombier 	if((client = sunDial(addr)) == nil)
17934e04225SDavid du Colombier 		sysfatal("dial %s: %r", addr);
18034e04225SDavid du Colombier 
18134e04225SDavid du Colombier 	client->chatty = chatty;
18234e04225SDavid du Colombier 	sunClientProg(client, &portProg);
18334e04225SDavid du Colombier 
18434e04225SDavid du Colombier 	argv++;
18534e04225SDavid du Colombier 	argc--;
18634e04225SDavid du Colombier 
18734e04225SDavid du Colombier 	if(argc == 0){
18834e04225SDavid du Colombier 		argc = 1;
18934e04225SDavid du Colombier 		argv = dflt;
19034e04225SDavid du Colombier 	}
19134e04225SDavid du Colombier 	cmd = argv[0];
19234e04225SDavid du Colombier 	argv++;
19334e04225SDavid du Colombier 	argc--;
19434e04225SDavid du Colombier 
19534e04225SDavid du Colombier 	for(i=0; i<nelem(tab); i++){
19634e04225SDavid du Colombier 		if(strcmp(tab[i].cmd, cmd) == 0){
19734e04225SDavid du Colombier 			if(tab[i].narg != argc)
19834e04225SDavid du Colombier 				usage();
19934e04225SDavid du Colombier 			(*tab[i].fn)(argv);
20034e04225SDavid du Colombier 			threadexitsall(nil);
20134e04225SDavid du Colombier 		}
20234e04225SDavid du Colombier 	}
20334e04225SDavid du Colombier 	usage();
20434e04225SDavid du Colombier }
205