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