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