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