1 #include "all.h" 2 3 #define SHORT(x) r->x = (p[1] | (p[0]<<8)); p += 2 4 #define LONG(x) r->x = (p[3] | (p[2]<<8) |\ 5 (p[1]<<16) | (p[0]<<24)); p += 4 6 #define SKIPLONG p += 4 7 #define PTR(x, n) r->x = (void *)(p); p += ROUNDUP(n) 8 9 uchar v4prefix[12] = { 10 0, 0, 0, 0, 11 0, 0, 0, 0, 12 0, 0, 0xff, 0xff, 13 }; 14 15 int 16 rpcM2S(void *ap, Rpccall *r, int n) 17 { 18 uchar *p = ap; 19 int k; 20 21 p += 12; 22 LONG(host); 23 p += 12; 24 LONG(lhost); 25 SHORT(port); 26 SHORT(lport); 27 LONG(xid); 28 LONG(mtype); 29 switch(r->mtype){ 30 case CALL: 31 LONG(rpcvers); 32 if(r->rpcvers != 2) 33 break; 34 LONG(prog); 35 LONG(vers); 36 LONG(proc); 37 LONG(cred.flavor); 38 LONG(cred.count); 39 PTR(cred.data, r->cred.count); 40 LONG(verf.flavor); 41 LONG(verf.count); 42 PTR(verf.data, r->verf.count); 43 r->up = 0; 44 k = n - (p - (uchar *)ap); 45 if(k < 0) 46 break; 47 PTR(args, k); 48 break; 49 case REPLY: 50 LONG(stat); 51 switch(r->stat){ 52 case MSG_ACCEPTED: 53 LONG(averf.flavor); 54 LONG(averf.count); 55 PTR(averf.data, r->averf.count); 56 LONG(astat); 57 switch(r->astat){ 58 case SUCCESS: 59 k = n - (p - (uchar *)ap); 60 if(k < 0) 61 break; 62 PTR(results, k); 63 break; 64 case PROG_MISMATCH: 65 LONG(plow); 66 LONG(phigh); 67 break; 68 } 69 break; 70 case MSG_DENIED: 71 LONG(rstat); 72 switch(r->rstat){ 73 case RPC_MISMATCH: 74 LONG(rlow); 75 LONG(rhigh); 76 break; 77 case AUTH_ERROR: 78 LONG(authstat); 79 break; 80 } 81 break; 82 } 83 break; 84 } 85 n -= p - (uchar *)ap; 86 return n; 87 } 88 89 int 90 auth2unix(Auth *arg, Authunix *r) 91 { 92 int i, n; 93 uchar *p; 94 95 if(arg->flavor != AUTH_UNIX) 96 return -1; 97 p = arg->data; 98 LONG(stamp); 99 LONG(mach.n); 100 PTR(mach.s, r->mach.n); 101 LONG(uid); 102 LONG(gid); 103 LONG(gidlen); 104 n = r->gidlen; 105 for(i=0; i<n && i < nelem(r->gids); i++){ 106 LONG(gids[i]); 107 } 108 for(; i<n; i++){ 109 SKIPLONG; 110 } 111 return arg->count - (p - (uchar *)arg->data); 112 } 113 114 int 115 string2S(void *arg, String *r) 116 { 117 uchar *p; 118 char *s; 119 120 p = arg; 121 LONG(n); 122 PTR(s, r->n); 123 /* must NUL terminate */ 124 s = malloc(r->n+1); 125 if(s == nil) 126 panic("malloc(%ld) failed in string2S\n", r->n+1); 127 memmove(s, r->s, r->n); 128 s[r->n] = '\0'; 129 r->s = strstore(s); 130 free(s); 131 return p - (uchar *)arg; 132 } 133 134 #undef SHORT 135 #undef LONG 136 #undef PTR 137 138 #define SHORT(x) p[1] = r->x; p[0] = r->x>>8; p += 2 139 #define LONG(x) p[3] = r->x; p[2] = r->x>>8; p[1] = r->x>>16; p[0] = r->x>>24; p += 4 140 141 #define PTR(x,n) memmove(p, r->x, n); p += ROUNDUP(n) 142 143 int 144 rpcS2M(Rpccall *r, int ndata, void *ap) 145 { 146 uchar *p = ap; 147 148 memmove(p, v4prefix, 12); 149 p += 12; 150 LONG(host); 151 memmove(p, v4prefix, 12); 152 p += 12; 153 LONG(lhost); 154 SHORT(port); 155 SHORT(lport); 156 LONG(xid); 157 LONG(mtype); 158 switch(r->mtype){ 159 case CALL: 160 LONG(rpcvers); 161 LONG(prog); 162 LONG(vers); 163 LONG(proc); 164 LONG(cred.flavor); 165 LONG(cred.count); 166 PTR(cred.data, r->cred.count); 167 LONG(verf.flavor); 168 LONG(verf.count); 169 PTR(verf.data, r->verf.count); 170 PTR(args, ndata); 171 break; 172 case REPLY: 173 LONG(stat); 174 switch(r->stat){ 175 case MSG_ACCEPTED: 176 LONG(averf.flavor); 177 LONG(averf.count); 178 PTR(averf.data, r->averf.count); 179 LONG(astat); 180 switch(r->astat){ 181 case SUCCESS: 182 PTR(results, ndata); 183 break; 184 case PROG_MISMATCH: 185 LONG(plow); 186 LONG(phigh); 187 break; 188 } 189 break; 190 case MSG_DENIED: 191 LONG(rstat); 192 switch(r->rstat){ 193 case RPC_MISMATCH: 194 LONG(rlow); 195 LONG(rhigh); 196 break; 197 case AUTH_ERROR: 198 LONG(authstat); 199 break; 200 } 201 break; 202 } 203 break; 204 } 205 return p - (uchar *)ap; 206 } 207 208 #undef SHORT 209 #undef LONG 210 #undef PTR 211 212 #define LONG(m, x) fprint(fd, "%s = %ld\n", m, r->x) 213 214 #define PTR(m, count) fprint(fd, "%s [%ld]\n", m, count) 215 216 void 217 rpcprint(int fd, Rpccall *r) 218 { 219 fprint(fd, "%s: host = %I, port = %ld\n", 220 argv0, r->host, r->port); 221 LONG("xid", xid); 222 LONG("mtype", mtype); 223 switch(r->mtype){ 224 case CALL: 225 LONG("rpcvers", rpcvers); 226 LONG("prog", prog); 227 LONG("vers", vers); 228 LONG("proc", proc); 229 LONG("cred.flavor", cred.flavor); 230 PTR("cred.data", r->cred.count); 231 LONG("verf.flavor", verf.flavor); 232 PTR("verf.data", r->verf.count); 233 fprint(fd, "args...\n"); 234 break; 235 case REPLY: 236 LONG("stat", stat); 237 switch(r->stat){ 238 case MSG_ACCEPTED: 239 LONG("averf.flavor", averf.flavor); 240 PTR("averf.data", r->averf.count); 241 LONG("astat", astat); 242 switch(r->astat){ 243 case SUCCESS: 244 fprint(fd, "results...\n"); 245 break; 246 case PROG_MISMATCH: 247 LONG("plow", plow); 248 LONG("phigh", phigh); 249 break; 250 } 251 break; 252 case MSG_DENIED: 253 LONG("rstat", rstat); 254 switch(r->rstat){ 255 case RPC_MISMATCH: 256 LONG("rlow", rlow); 257 LONG("rhigh", rhigh); 258 break; 259 case AUTH_ERROR: 260 LONG("authstat", authstat); 261 break; 262 } 263 break; 264 } 265 } 266 } 267 268 void 269 showauth(Auth *ap) 270 { 271 Authunix au; 272 int i; 273 274 if(auth2unix(ap, &au) != 0){ 275 chat("auth flavor=%ld, count=%ld", 276 ap->flavor, ap->count); 277 for(i=0; i<ap->count; i++) 278 chat(" %.2ux", ((uchar *)ap->data)[i]); 279 }else{ 280 chat("auth: %ld %.*s u=%ld g=%ld", 281 au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid); 282 for(i=0; i<au.gidlen; i++) 283 chat(", %ld", au.gids[i]); 284 } 285 chat("..."); 286 } 287 288 int 289 garbage(Rpccall *reply, char *msg) 290 { 291 chat("%s\n", msg ? msg : "garbage"); 292 reply->astat = GARBAGE_ARGS; 293 return 0; 294 } 295 296 int 297 error(Rpccall *reply, int errno) 298 { 299 uchar *dataptr = reply->results; 300 301 chat("error %d\n", errno); 302 PLONG(errno); 303 return dataptr - (uchar *)reply->results; 304 } 305