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