xref: /plan9/sys/src/cmd/aux/portmap.c (revision 34e0422554c8e8bef66509534d2c44f4660bf678)
1*34e04225SDavid du Colombier /* Copyright © 2003 Russ Cox, MIT; see /sys/src/libsunrpc/COPYING */
2*34e04225SDavid du Colombier #include <u.h>
3*34e04225SDavid du Colombier #include <libc.h>
4*34e04225SDavid du Colombier #include <thread.h>
5*34e04225SDavid du Colombier #include <sunrpc.h>
6*34e04225SDavid du Colombier 
7*34e04225SDavid du Colombier int chatty;
8*34e04225SDavid du Colombier SunClient *client;
9*34e04225SDavid du Colombier 
10*34e04225SDavid du Colombier void
11*34e04225SDavid du Colombier usage(void)
12*34e04225SDavid du Colombier {
13*34e04225SDavid du Colombier 	fprint(2, "usage: portmap address [cmd]\n"
14*34e04225SDavid du Colombier 		"cmd is one of:\n"
15*34e04225SDavid du Colombier 		"\tnull\n"
16*34e04225SDavid du Colombier 		"\tset prog vers proto port\n"
17*34e04225SDavid du Colombier 		"\tunset prog vers proto port\n"
18*34e04225SDavid du Colombier 		"\tgetport prog vers proto\n"
19*34e04225SDavid du Colombier 		"\tdump (default)\n");
20*34e04225SDavid du Colombier 	threadexitsall("usage");
21*34e04225SDavid du Colombier }
22*34e04225SDavid du Colombier 
23*34e04225SDavid du Colombier void
24*34e04225SDavid du Colombier portCall(SunCall *c, PortCallType type)
25*34e04225SDavid du Colombier {
26*34e04225SDavid du Colombier 	c->rpc.prog = PortProgram;
27*34e04225SDavid du Colombier 	c->rpc.vers = PortVersion;
28*34e04225SDavid du Colombier 	c->rpc.proc = type>>1;
29*34e04225SDavid du Colombier 	c->rpc.iscall = !(type&1);
30*34e04225SDavid du Colombier 	c->type = type;
31*34e04225SDavid du Colombier }
32*34e04225SDavid du Colombier 
33*34e04225SDavid du Colombier void
34*34e04225SDavid du Colombier tnull(char **argv)
35*34e04225SDavid du Colombier {
36*34e04225SDavid du Colombier 	PortTNull tx;
37*34e04225SDavid du Colombier 	PortRNull rx;
38*34e04225SDavid du Colombier 
39*34e04225SDavid du Colombier 	USED(argv);
40*34e04225SDavid du Colombier 
41*34e04225SDavid du Colombier 	memset(&tx, 0, sizeof tx);
42*34e04225SDavid du Colombier 	portCall(&tx.call, PortCallTNull);
43*34e04225SDavid du Colombier 
44*34e04225SDavid du Colombier 	memset(&rx, 0, sizeof rx);
45*34e04225SDavid du Colombier 	portCall(&rx.call, PortCallRNull);
46*34e04225SDavid du Colombier 
47*34e04225SDavid du Colombier 	if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
48*34e04225SDavid du Colombier 		sysfatal("rpc: %r");
49*34e04225SDavid du Colombier }
50*34e04225SDavid du Colombier 
51*34e04225SDavid du Colombier void
52*34e04225SDavid du Colombier tset(char **argv)
53*34e04225SDavid du Colombier {
54*34e04225SDavid du Colombier 	PortTSet tx;
55*34e04225SDavid du Colombier 	PortRSet rx;
56*34e04225SDavid du Colombier 
57*34e04225SDavid du Colombier 	memset(&tx, 0, sizeof tx);
58*34e04225SDavid du Colombier 	portCall(&tx.call, PortCallTSet);
59*34e04225SDavid du Colombier 	tx.map.prog = strtol(argv[0], 0, 0);
60*34e04225SDavid du Colombier 	tx.map.vers = strtol(argv[1], 0, 0);
61*34e04225SDavid du Colombier 	tx.map.prot = strtol(argv[2], 0, 0);
62*34e04225SDavid du Colombier 	tx.map.port = strtol(argv[3], 0, 0);
63*34e04225SDavid du Colombier 
64*34e04225SDavid du Colombier 	memset(&rx, 0, sizeof rx);
65*34e04225SDavid du Colombier 	portCall(&rx.call, PortCallRSet);
66*34e04225SDavid du Colombier 
67*34e04225SDavid du Colombier 	if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
68*34e04225SDavid du Colombier 		sysfatal("rpc: %r");
69*34e04225SDavid du Colombier 
70*34e04225SDavid du Colombier 	if(rx.b == 0)
71*34e04225SDavid du Colombier 		print("rejected\n");
72*34e04225SDavid du Colombier }
73*34e04225SDavid du Colombier 
74*34e04225SDavid du Colombier void
75*34e04225SDavid du Colombier tunset(char **argv)
76*34e04225SDavid du Colombier {
77*34e04225SDavid du Colombier 	PortTUnset tx;
78*34e04225SDavid du Colombier 	PortRUnset rx;
79*34e04225SDavid du Colombier 
80*34e04225SDavid du Colombier 	memset(&tx, 0, sizeof tx);
81*34e04225SDavid du Colombier 	portCall(&tx.call, PortCallTUnset);
82*34e04225SDavid du Colombier 	tx.map.prog = strtol(argv[0], 0, 0);
83*34e04225SDavid du Colombier 	tx.map.vers = strtol(argv[1], 0, 0);
84*34e04225SDavid du Colombier 	tx.map.prot = strtol(argv[2], 0, 0);
85*34e04225SDavid du Colombier 	tx.map.port = strtol(argv[3], 0, 0);
86*34e04225SDavid du Colombier 
87*34e04225SDavid du Colombier 	memset(&rx, 0, sizeof rx);
88*34e04225SDavid du Colombier 	portCall(&rx.call, PortCallRUnset);
89*34e04225SDavid du Colombier 
90*34e04225SDavid du Colombier 	if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
91*34e04225SDavid du Colombier 		sysfatal("rpc: %r");
92*34e04225SDavid du Colombier 
93*34e04225SDavid du Colombier 	if(rx.b == 0)
94*34e04225SDavid du Colombier 		print("rejected\n");
95*34e04225SDavid du Colombier }
96*34e04225SDavid du Colombier 
97*34e04225SDavid du Colombier void
98*34e04225SDavid du Colombier tgetport(char **argv)
99*34e04225SDavid du Colombier {
100*34e04225SDavid du Colombier 	PortTGetport tx;
101*34e04225SDavid du Colombier 	PortRGetport rx;
102*34e04225SDavid du Colombier 
103*34e04225SDavid du Colombier 	memset(&tx, 0, sizeof tx);
104*34e04225SDavid du Colombier 	portCall(&tx.call, PortCallTGetport);
105*34e04225SDavid du Colombier 	tx.map.prog = strtol(argv[0], 0, 0);
106*34e04225SDavid du Colombier 	tx.map.vers = strtol(argv[1], 0, 0);
107*34e04225SDavid du Colombier 	tx.map.prot = strtol(argv[2], 0, 0);
108*34e04225SDavid du Colombier 
109*34e04225SDavid du Colombier 	memset(&rx, 0, sizeof rx);
110*34e04225SDavid du Colombier 	portCall(&rx.call, PortCallRGetport);
111*34e04225SDavid du Colombier 
112*34e04225SDavid du Colombier 	if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
113*34e04225SDavid du Colombier 		sysfatal("rpc: %r");
114*34e04225SDavid du Colombier 
115*34e04225SDavid du Colombier 	print("%d\n", rx.port);
116*34e04225SDavid du Colombier }
117*34e04225SDavid du Colombier 
118*34e04225SDavid du Colombier void
119*34e04225SDavid du Colombier tdump(char **argv)
120*34e04225SDavid du Colombier {
121*34e04225SDavid du Colombier 	int i;
122*34e04225SDavid du Colombier 	uchar *p;
123*34e04225SDavid du Colombier 	PortTDump tx;
124*34e04225SDavid du Colombier 	PortRDump rx;
125*34e04225SDavid du Colombier 	PortMap *m;
126*34e04225SDavid du Colombier 
127*34e04225SDavid du Colombier 	USED(argv);
128*34e04225SDavid du Colombier 
129*34e04225SDavid du Colombier 	memset(&tx, 0, sizeof tx);
130*34e04225SDavid du Colombier 	portCall(&tx.call, PortCallTDump);
131*34e04225SDavid du Colombier 
132*34e04225SDavid du Colombier 	memset(&rx, 0, sizeof rx);
133*34e04225SDavid du Colombier 	portCall(&rx.call, PortCallRDump);
134*34e04225SDavid du Colombier 
135*34e04225SDavid du Colombier 	if(sunClientRpc(client, 0, &tx.call, &rx.call, &p) < 0)
136*34e04225SDavid du Colombier 		sysfatal("rpc: %r");
137*34e04225SDavid du Colombier 
138*34e04225SDavid du Colombier 	for(i=0, m=rx.map; i<rx.nmap; i++, m++)
139*34e04225SDavid du Colombier 		print("%ud %ud %ud %ud\n", (uint)m->prog, (uint)m->vers, (uint)m->prot, (uint)m->port);
140*34e04225SDavid du Colombier 
141*34e04225SDavid du Colombier 	free(p);
142*34e04225SDavid du Colombier }
143*34e04225SDavid du Colombier 
144*34e04225SDavid du Colombier static struct {
145*34e04225SDavid du Colombier 	char *cmd;
146*34e04225SDavid du Colombier 	int narg;
147*34e04225SDavid du Colombier 	void (*fn)(char**);
148*34e04225SDavid du Colombier } tab[] = {
149*34e04225SDavid du Colombier 	"null",	0,	tnull,
150*34e04225SDavid du Colombier 	"set",	4,	tset,
151*34e04225SDavid du Colombier 	"unset",	4,	tunset,
152*34e04225SDavid du Colombier 	"getport",	3,	tgetport,
153*34e04225SDavid du Colombier 	"dump",	0,	tdump,
154*34e04225SDavid du Colombier };
155*34e04225SDavid du Colombier 
156*34e04225SDavid du Colombier void
157*34e04225SDavid du Colombier threadmain(int argc, char **argv)
158*34e04225SDavid du Colombier {
159*34e04225SDavid du Colombier 	char *dflt[] = { "dump", };
160*34e04225SDavid du Colombier 	char *addr, *cmd;
161*34e04225SDavid du Colombier 	int i;
162*34e04225SDavid du Colombier 
163*34e04225SDavid du Colombier 	ARGBEGIN{
164*34e04225SDavid du Colombier 	case 'R':
165*34e04225SDavid du Colombier 		chatty++;
166*34e04225SDavid du Colombier 		break;
167*34e04225SDavid du Colombier 	}ARGEND
168*34e04225SDavid du Colombier 
169*34e04225SDavid du Colombier 	if(argc < 2)
170*34e04225SDavid du Colombier 		usage();
171*34e04225SDavid du Colombier 
172*34e04225SDavid du Colombier 	fmtinstall('B', sunRpcFmt);
173*34e04225SDavid du Colombier 	fmtinstall('C', sunCallFmt);
174*34e04225SDavid du Colombier 	fmtinstall('H', encodefmt);
175*34e04225SDavid du Colombier 	sunFmtInstall(&portProg);
176*34e04225SDavid du Colombier 
177*34e04225SDavid du Colombier 	addr = netmkaddr(argv[0], "udp", "portmap");
178*34e04225SDavid du Colombier 	if((client = sunDial(addr)) == nil)
179*34e04225SDavid du Colombier 		sysfatal("dial %s: %r", addr);
180*34e04225SDavid du Colombier 
181*34e04225SDavid du Colombier 	client->chatty = chatty;
182*34e04225SDavid du Colombier 	sunClientProg(client, &portProg);
183*34e04225SDavid du Colombier 
184*34e04225SDavid du Colombier 	argv++;
185*34e04225SDavid du Colombier 	argc--;
186*34e04225SDavid du Colombier 
187*34e04225SDavid du Colombier 	if(argc == 0){
188*34e04225SDavid du Colombier 		argc = 1;
189*34e04225SDavid du Colombier 		argv = dflt;
190*34e04225SDavid du Colombier 	}
191*34e04225SDavid du Colombier 	cmd = argv[0];
192*34e04225SDavid du Colombier 	argv++;
193*34e04225SDavid du Colombier 	argc--;
194*34e04225SDavid du Colombier 
195*34e04225SDavid du Colombier 	for(i=0; i<nelem(tab); i++){
196*34e04225SDavid du Colombier 		if(strcmp(tab[i].cmd, cmd) == 0){
197*34e04225SDavid du Colombier 			if(tab[i].narg != argc)
198*34e04225SDavid du Colombier 				usage();
199*34e04225SDavid du Colombier 			(*tab[i].fn)(argv);
200*34e04225SDavid du Colombier 			threadexitsall(nil);
201*34e04225SDavid du Colombier 		}
202*34e04225SDavid du Colombier 	}
203*34e04225SDavid du Colombier 	usage();
204*34e04225SDavid du Colombier }
205