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
rpcM2S(void * ap,Rpccall * r,int n)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
auth2unix(Auth * arg,Authunix * r)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
string2S(void * arg,String * r)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
rpcS2M(Rpccall * r,int ndata,void * ap)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
rpcprint(int fd,Rpccall * r)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
showauth(Auth * ap)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
garbage(Rpccall * reply,char * msg)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
error(Rpccall * reply,int errno)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