1*34e04225SDavid du Colombier #include <u.h>
2*34e04225SDavid du Colombier #include <libc.h>
3*34e04225SDavid du Colombier #include <thread.h>
4*34e04225SDavid du Colombier #include <sunrpc.h>
5*34e04225SDavid du Colombier
6*34e04225SDavid du Colombier /*
7*34e04225SDavid du Colombier * RPC protocol constants
8*34e04225SDavid du Colombier */
9*34e04225SDavid du Colombier enum
10*34e04225SDavid du Colombier {
11*34e04225SDavid du Colombier RpcVersion = 2,
12*34e04225SDavid du Colombier
13*34e04225SDavid du Colombier /* msg type */
14*34e04225SDavid du Colombier MsgCall = 0,
15*34e04225SDavid du Colombier MsgReply = 1,
16*34e04225SDavid du Colombier
17*34e04225SDavid du Colombier /* reply stat */
18*34e04225SDavid du Colombier MsgAccepted = 0,
19*34e04225SDavid du Colombier MsgDenied = 1,
20*34e04225SDavid du Colombier
21*34e04225SDavid du Colombier /* accept stat */
22*34e04225SDavid du Colombier MsgSuccess = 0,
23*34e04225SDavid du Colombier MsgProgUnavail = 1,
24*34e04225SDavid du Colombier MsgProgMismatch = 2,
25*34e04225SDavid du Colombier MsgProcUnavail = 3,
26*34e04225SDavid du Colombier MsgGarbageArgs = 4,
27*34e04225SDavid du Colombier MsgSystemErr = 5,
28*34e04225SDavid du Colombier
29*34e04225SDavid du Colombier /* reject stat */
30*34e04225SDavid du Colombier MsgRpcMismatch = 0,
31*34e04225SDavid du Colombier MsgAuthError = 1,
32*34e04225SDavid du Colombier
33*34e04225SDavid du Colombier /* msg auth xxx */
34*34e04225SDavid du Colombier MsgAuthOk = 0,
35*34e04225SDavid du Colombier MsgAuthBadCred = 1,
36*34e04225SDavid du Colombier MsgAuthRejectedCred = 2,
37*34e04225SDavid du Colombier MsgAuthBadVerf = 3,
38*34e04225SDavid du Colombier MsgAuthRejectedVerf = 4,
39*34e04225SDavid du Colombier MsgAuthTooWeak = 5,
40*34e04225SDavid du Colombier MsgAuthInvalidResp = 6,
41*34e04225SDavid du Colombier MsgAuthFailed = 7,
42*34e04225SDavid du Colombier };
43*34e04225SDavid du Colombier
44*34e04225SDavid du Colombier SunStatus
sunRpcPack(uchar * a,uchar * ea,uchar ** pa,SunRpc * rpc)45*34e04225SDavid du Colombier sunRpcPack(uchar *a, uchar *ea, uchar **pa, SunRpc *rpc)
46*34e04225SDavid du Colombier {
47*34e04225SDavid du Colombier u32int x;
48*34e04225SDavid du Colombier
49*34e04225SDavid du Colombier if(sunUint32Pack(a, ea, &a, &rpc->xid) < 0)
50*34e04225SDavid du Colombier goto Err;
51*34e04225SDavid du Colombier if(rpc->iscall){
52*34e04225SDavid du Colombier if(sunUint32Pack(a, ea, &a, (x=MsgCall, &x)) < 0
53*34e04225SDavid du Colombier || sunUint32Pack(a, ea, &a, (x=RpcVersion, &x)) < 0
54*34e04225SDavid du Colombier || sunUint32Pack(a, ea, &a, &rpc->prog) < 0
55*34e04225SDavid du Colombier || sunUint32Pack(a, ea, &a, &rpc->vers) < 0
56*34e04225SDavid du Colombier || sunUint32Pack(a, ea, &a, &rpc->proc) < 0
57*34e04225SDavid du Colombier || sunAuthInfoPack(a, ea, &a, &rpc->cred) < 0
58*34e04225SDavid du Colombier || sunAuthInfoPack(a, ea, &a, &rpc->verf) < 0
59*34e04225SDavid du Colombier || sunFixedOpaquePack(a, ea, &a, rpc->data, rpc->ndata) < 0)
60*34e04225SDavid du Colombier goto Err;
61*34e04225SDavid du Colombier }else{
62*34e04225SDavid du Colombier if(sunUint32Pack(a, ea, &a, (x=MsgReply, &x)) < 0)
63*34e04225SDavid du Colombier goto Err;
64*34e04225SDavid du Colombier switch(rpc->status&0xF0000){
65*34e04225SDavid du Colombier case 0:
66*34e04225SDavid du Colombier case SunAcceptError:
67*34e04225SDavid du Colombier if(sunUint32Pack(a, ea, &a, (x=MsgAccepted, &x)) < 0
68*34e04225SDavid du Colombier || sunAuthInfoPack(a, ea, &a, &rpc->verf) < 0)
69*34e04225SDavid du Colombier goto Err;
70*34e04225SDavid du Colombier break;
71*34e04225SDavid du Colombier default:
72*34e04225SDavid du Colombier if(sunUint32Pack(a, ea, &a, (x=MsgDenied, &x)) < 0)
73*34e04225SDavid du Colombier goto Err;
74*34e04225SDavid du Colombier break;
75*34e04225SDavid du Colombier }
76*34e04225SDavid du Colombier
77*34e04225SDavid du Colombier switch(rpc->status){
78*34e04225SDavid du Colombier case SunSuccess:
79*34e04225SDavid du Colombier if(sunUint32Pack(a, ea, &a, (x=MsgSuccess, &x)) < 0
80*34e04225SDavid du Colombier || sunFixedOpaquePack(a, ea, &a, rpc->data, rpc->ndata) < 0)
81*34e04225SDavid du Colombier goto Err;
82*34e04225SDavid du Colombier break;
83*34e04225SDavid du Colombier case SunRpcMismatch:
84*34e04225SDavid du Colombier case SunProgMismatch:
85*34e04225SDavid du Colombier if(sunUint32Pack(a, ea, &a, (x=rpc->status&0xFFFF, &x)) < 0
86*34e04225SDavid du Colombier || sunUint32Pack(a, ea, &a, &rpc->low) < 0
87*34e04225SDavid du Colombier || sunUint32Pack(a, ea, &a, &rpc->high) < 0)
88*34e04225SDavid du Colombier goto Err;
89*34e04225SDavid du Colombier break;
90*34e04225SDavid du Colombier default:
91*34e04225SDavid du Colombier if(sunUint32Pack(a, ea, &a, (x=rpc->status&0xFFFF, &x)) < 0)
92*34e04225SDavid du Colombier goto Err;
93*34e04225SDavid du Colombier break;
94*34e04225SDavid du Colombier }
95*34e04225SDavid du Colombier }
96*34e04225SDavid du Colombier *pa = a;
97*34e04225SDavid du Colombier return SunSuccess;
98*34e04225SDavid du Colombier
99*34e04225SDavid du Colombier Err:
100*34e04225SDavid du Colombier *pa = ea;
101*34e04225SDavid du Colombier return SunGarbageArgs;
102*34e04225SDavid du Colombier }
103*34e04225SDavid du Colombier
104*34e04225SDavid du Colombier uint
sunRpcSize(SunRpc * rpc)105*34e04225SDavid du Colombier sunRpcSize(SunRpc *rpc)
106*34e04225SDavid du Colombier {
107*34e04225SDavid du Colombier uint a;
108*34e04225SDavid du Colombier
109*34e04225SDavid du Colombier a = 4;
110*34e04225SDavid du Colombier if(rpc->iscall){
111*34e04225SDavid du Colombier a += 5*4;
112*34e04225SDavid du Colombier a += sunAuthInfoSize(&rpc->cred);
113*34e04225SDavid du Colombier a += sunAuthInfoSize(&rpc->verf);
114*34e04225SDavid du Colombier a += sunFixedOpaqueSize(rpc->ndata);
115*34e04225SDavid du Colombier }else{
116*34e04225SDavid du Colombier a += 4;
117*34e04225SDavid du Colombier switch(rpc->status&0xF0000){
118*34e04225SDavid du Colombier case 0:
119*34e04225SDavid du Colombier case SunAcceptError:
120*34e04225SDavid du Colombier a += 4+sunAuthInfoSize(&rpc->verf);
121*34e04225SDavid du Colombier break;
122*34e04225SDavid du Colombier default:
123*34e04225SDavid du Colombier a += 4;
124*34e04225SDavid du Colombier break;
125*34e04225SDavid du Colombier }
126*34e04225SDavid du Colombier
127*34e04225SDavid du Colombier switch(rpc->status){
128*34e04225SDavid du Colombier case SunSuccess:
129*34e04225SDavid du Colombier a += 4+sunFixedOpaqueSize(rpc->ndata);
130*34e04225SDavid du Colombier break;
131*34e04225SDavid du Colombier case SunRpcMismatch:
132*34e04225SDavid du Colombier case SunProgMismatch:
133*34e04225SDavid du Colombier a += 3*4;
134*34e04225SDavid du Colombier default:
135*34e04225SDavid du Colombier a += 4;
136*34e04225SDavid du Colombier }
137*34e04225SDavid du Colombier }
138*34e04225SDavid du Colombier return a;
139*34e04225SDavid du Colombier }
140*34e04225SDavid du Colombier
141*34e04225SDavid du Colombier SunStatus
sunRpcUnpack(uchar * a,uchar * ea,uchar ** pa,SunRpc * rpc)142*34e04225SDavid du Colombier sunRpcUnpack(uchar *a, uchar *ea, uchar **pa, SunRpc *rpc)
143*34e04225SDavid du Colombier {
144*34e04225SDavid du Colombier u32int x;
145*34e04225SDavid du Colombier
146*34e04225SDavid du Colombier memset(rpc, 0, sizeof *rpc);
147*34e04225SDavid du Colombier if(sunUint32Unpack(a, ea, &a, &rpc->xid) < 0
148*34e04225SDavid du Colombier || sunUint32Unpack(a, ea, &a, &x) < 0)
149*34e04225SDavid du Colombier goto Err;
150*34e04225SDavid du Colombier
151*34e04225SDavid du Colombier switch(x){
152*34e04225SDavid du Colombier default:
153*34e04225SDavid du Colombier goto Err;
154*34e04225SDavid du Colombier case MsgCall:
155*34e04225SDavid du Colombier rpc->iscall = 1;
156*34e04225SDavid du Colombier if(sunUint32Unpack(a, ea, &a, &x) < 0 || x != RpcVersion
157*34e04225SDavid du Colombier || sunUint32Unpack(a, ea, &a, &rpc->prog) < 0
158*34e04225SDavid du Colombier || sunUint32Unpack(a, ea, &a, &rpc->vers) < 0
159*34e04225SDavid du Colombier || sunUint32Unpack(a, ea, &a, &rpc->proc) < 0
160*34e04225SDavid du Colombier || sunAuthInfoUnpack(a, ea, &a, &rpc->cred) < 0
161*34e04225SDavid du Colombier || sunAuthInfoUnpack(a, ea, &a, &rpc->verf) < 0)
162*34e04225SDavid du Colombier goto Err;
163*34e04225SDavid du Colombier rpc->ndata = ea-a;
164*34e04225SDavid du Colombier rpc->data = a;
165*34e04225SDavid du Colombier a = ea;
166*34e04225SDavid du Colombier break;
167*34e04225SDavid du Colombier
168*34e04225SDavid du Colombier case MsgReply:
169*34e04225SDavid du Colombier rpc->iscall = 0;
170*34e04225SDavid du Colombier if(sunUint32Unpack(a, ea, &a, &x) < 0)
171*34e04225SDavid du Colombier goto Err;
172*34e04225SDavid du Colombier switch(x){
173*34e04225SDavid du Colombier default:
174*34e04225SDavid du Colombier goto Err;
175*34e04225SDavid du Colombier case MsgAccepted:
176*34e04225SDavid du Colombier if(sunAuthInfoUnpack(a, ea, &a, &rpc->verf) < 0
177*34e04225SDavid du Colombier || sunUint32Unpack(a, ea, &a, &x) < 0)
178*34e04225SDavid du Colombier goto Err;
179*34e04225SDavid du Colombier switch(x){
180*34e04225SDavid du Colombier case MsgSuccess:
181*34e04225SDavid du Colombier rpc->status = SunSuccess;
182*34e04225SDavid du Colombier rpc->ndata = ea-a;
183*34e04225SDavid du Colombier rpc->data = a;
184*34e04225SDavid du Colombier a = ea;
185*34e04225SDavid du Colombier break;
186*34e04225SDavid du Colombier case MsgProgUnavail:
187*34e04225SDavid du Colombier case MsgProcUnavail:
188*34e04225SDavid du Colombier case MsgGarbageArgs:
189*34e04225SDavid du Colombier case MsgSystemErr:
190*34e04225SDavid du Colombier rpc->status = SunAcceptError | x;
191*34e04225SDavid du Colombier break;
192*34e04225SDavid du Colombier case MsgProgMismatch:
193*34e04225SDavid du Colombier rpc->status = SunAcceptError | x;
194*34e04225SDavid du Colombier if(sunUint32Unpack(a, ea, &a, &rpc->low) < 0
195*34e04225SDavid du Colombier || sunUint32Unpack(a, ea, &a, &rpc->high) < 0)
196*34e04225SDavid du Colombier goto Err;
197*34e04225SDavid du Colombier break;
198*34e04225SDavid du Colombier }
199*34e04225SDavid du Colombier break;
200*34e04225SDavid du Colombier case MsgDenied:
201*34e04225SDavid du Colombier if(sunUint32Unpack(a, ea, &a, &x) < 0)
202*34e04225SDavid du Colombier goto Err;
203*34e04225SDavid du Colombier switch(x){
204*34e04225SDavid du Colombier default:
205*34e04225SDavid du Colombier goto Err;
206*34e04225SDavid du Colombier case MsgAuthError:
207*34e04225SDavid du Colombier if(sunUint32Unpack(a, ea, &a, &x) < 0)
208*34e04225SDavid du Colombier goto Err;
209*34e04225SDavid du Colombier rpc->status = SunAuthError | x;
210*34e04225SDavid du Colombier break;
211*34e04225SDavid du Colombier case MsgRpcMismatch:
212*34e04225SDavid du Colombier rpc->status = SunRejectError | x;
213*34e04225SDavid du Colombier if(sunUint32Unpack(a, ea, &a, &rpc->low) < 0
214*34e04225SDavid du Colombier || sunUint32Unpack(a, ea, &a, &rpc->high) < 0)
215*34e04225SDavid du Colombier goto Err;
216*34e04225SDavid du Colombier break;
217*34e04225SDavid du Colombier }
218*34e04225SDavid du Colombier break;
219*34e04225SDavid du Colombier }
220*34e04225SDavid du Colombier }
221*34e04225SDavid du Colombier *pa = a;
222*34e04225SDavid du Colombier return SunSuccess;
223*34e04225SDavid du Colombier
224*34e04225SDavid du Colombier Err:
225*34e04225SDavid du Colombier *pa = ea;
226*34e04225SDavid du Colombier return SunGarbageArgs;
227*34e04225SDavid du Colombier }
228*34e04225SDavid du Colombier
229*34e04225SDavid du Colombier void
sunRpcPrint(Fmt * fmt,SunRpc * rpc)230*34e04225SDavid du Colombier sunRpcPrint(Fmt *fmt, SunRpc *rpc)
231*34e04225SDavid du Colombier {
232*34e04225SDavid du Colombier fmtprint(fmt, "xid=%#ux", rpc->xid);
233*34e04225SDavid du Colombier if(rpc->iscall){
234*34e04225SDavid du Colombier fmtprint(fmt, " prog %#ux vers %#ux proc %#ux [", rpc->prog, rpc->vers, rpc->proc);
235*34e04225SDavid du Colombier sunAuthInfoPrint(fmt, &rpc->cred);
236*34e04225SDavid du Colombier fmtprint(fmt, "] [");
237*34e04225SDavid du Colombier sunAuthInfoPrint(fmt, &rpc->verf);
238*34e04225SDavid du Colombier fmtprint(fmt, "]");
239*34e04225SDavid du Colombier }else{
240*34e04225SDavid du Colombier fmtprint(fmt, " status %#ux [", rpc->status);
241*34e04225SDavid du Colombier sunAuthInfoPrint(fmt, &rpc->verf);
242*34e04225SDavid du Colombier fmtprint(fmt, "] low %#ux high %#ux", rpc->low, rpc->high);
243*34e04225SDavid du Colombier }
244*34e04225SDavid du Colombier }
245*34e04225SDavid du Colombier
246*34e04225SDavid du Colombier void
sunAuthInfoPrint(Fmt * fmt,SunAuthInfo * ai)247*34e04225SDavid du Colombier sunAuthInfoPrint(Fmt *fmt, SunAuthInfo *ai)
248*34e04225SDavid du Colombier {
249*34e04225SDavid du Colombier switch(ai->flavor){
250*34e04225SDavid du Colombier case SunAuthNone:
251*34e04225SDavid du Colombier fmtprint(fmt, "none");
252*34e04225SDavid du Colombier break;
253*34e04225SDavid du Colombier case SunAuthShort:
254*34e04225SDavid du Colombier fmtprint(fmt, "short");
255*34e04225SDavid du Colombier break;
256*34e04225SDavid du Colombier case SunAuthSys:
257*34e04225SDavid du Colombier fmtprint(fmt, "sys");
258*34e04225SDavid du Colombier break;
259*34e04225SDavid du Colombier default:
260*34e04225SDavid du Colombier fmtprint(fmt, "%#ux", ai->flavor);
261*34e04225SDavid du Colombier break;
262*34e04225SDavid du Colombier }
263*34e04225SDavid du Colombier // if(ai->ndata)
264*34e04225SDavid du Colombier // fmtprint(fmt, " %.*H", ai->ndata, ai->data);
265*34e04225SDavid du Colombier }
266*34e04225SDavid du Colombier
267*34e04225SDavid du Colombier uint
sunAuthInfoSize(SunAuthInfo * ai)268*34e04225SDavid du Colombier sunAuthInfoSize(SunAuthInfo *ai)
269*34e04225SDavid du Colombier {
270*34e04225SDavid du Colombier return 4 + sunVarOpaqueSize(ai->ndata);
271*34e04225SDavid du Colombier }
272*34e04225SDavid du Colombier
273*34e04225SDavid du Colombier int
sunAuthInfoPack(uchar * a,uchar * ea,uchar ** pa,SunAuthInfo * ai)274*34e04225SDavid du Colombier sunAuthInfoPack(uchar *a, uchar *ea, uchar **pa, SunAuthInfo *ai)
275*34e04225SDavid du Colombier {
276*34e04225SDavid du Colombier if(sunUint32Pack(a, ea, &a, &ai->flavor) < 0
277*34e04225SDavid du Colombier || sunVarOpaquePack(a, ea, &a, &ai->data, &ai->ndata, 400) < 0)
278*34e04225SDavid du Colombier goto Err;
279*34e04225SDavid du Colombier *pa = a;
280*34e04225SDavid du Colombier return 0;
281*34e04225SDavid du Colombier
282*34e04225SDavid du Colombier Err:
283*34e04225SDavid du Colombier *pa = ea;
284*34e04225SDavid du Colombier return -1;
285*34e04225SDavid du Colombier }
286*34e04225SDavid du Colombier
287*34e04225SDavid du Colombier int
sunAuthInfoUnpack(uchar * a,uchar * ea,uchar ** pa,SunAuthInfo * ai)288*34e04225SDavid du Colombier sunAuthInfoUnpack(uchar *a, uchar *ea, uchar **pa, SunAuthInfo *ai)
289*34e04225SDavid du Colombier {
290*34e04225SDavid du Colombier if(sunUint32Unpack(a, ea, &a, &ai->flavor) < 0
291*34e04225SDavid du Colombier || sunVarOpaqueUnpack(a, ea, &a, &ai->data, &ai->ndata, 400) < 0)
292*34e04225SDavid du Colombier goto Err;
293*34e04225SDavid du Colombier *pa = a;
294*34e04225SDavid du Colombier return 0;
295*34e04225SDavid du Colombier
296*34e04225SDavid du Colombier Err:
297*34e04225SDavid du Colombier *pa = ea;
298*34e04225SDavid du Colombier return -1;
299*34e04225SDavid du Colombier }
300*34e04225SDavid du Colombier
301*34e04225SDavid du Colombier int
sunEnumPack(uchar * a,uchar * ea,uchar ** pa,int * e)302*34e04225SDavid du Colombier sunEnumPack(uchar *a, uchar *ea, uchar **pa, int *e)
303*34e04225SDavid du Colombier {
304*34e04225SDavid du Colombier u32int x;
305*34e04225SDavid du Colombier
306*34e04225SDavid du Colombier x = *e;
307*34e04225SDavid du Colombier return sunUint32Pack(a, ea, pa, &x);
308*34e04225SDavid du Colombier }
309*34e04225SDavid du Colombier
310*34e04225SDavid du Colombier int
sunUint1Pack(uchar * a,uchar * ea,uchar ** pa,u1int * u)311*34e04225SDavid du Colombier sunUint1Pack(uchar *a, uchar *ea, uchar **pa, u1int *u)
312*34e04225SDavid du Colombier {
313*34e04225SDavid du Colombier u32int x;
314*34e04225SDavid du Colombier
315*34e04225SDavid du Colombier x = *u;
316*34e04225SDavid du Colombier return sunUint32Pack(a, ea, pa, &x);
317*34e04225SDavid du Colombier }
318*34e04225SDavid du Colombier
319*34e04225SDavid du Colombier int
sunUint32Pack(uchar * a,uchar * ea,uchar ** pa,u32int * u)320*34e04225SDavid du Colombier sunUint32Pack(uchar *a, uchar *ea, uchar **pa, u32int *u)
321*34e04225SDavid du Colombier {
322*34e04225SDavid du Colombier u32int x;
323*34e04225SDavid du Colombier
324*34e04225SDavid du Colombier if(ea-a < 4)
325*34e04225SDavid du Colombier goto Err;
326*34e04225SDavid du Colombier
327*34e04225SDavid du Colombier x = *u;
328*34e04225SDavid du Colombier *a++ = x>>24;
329*34e04225SDavid du Colombier *a++ = x>>16;
330*34e04225SDavid du Colombier *a++ = x>>8;
331*34e04225SDavid du Colombier *a++ = x;
332*34e04225SDavid du Colombier *pa = a;
333*34e04225SDavid du Colombier return 0;
334*34e04225SDavid du Colombier
335*34e04225SDavid du Colombier Err:
336*34e04225SDavid du Colombier *pa = ea;
337*34e04225SDavid du Colombier return -1;
338*34e04225SDavid du Colombier }
339*34e04225SDavid du Colombier
340*34e04225SDavid du Colombier int
sunEnumUnpack(uchar * a,uchar * ea,uchar ** pa,int * e)341*34e04225SDavid du Colombier sunEnumUnpack(uchar *a, uchar *ea, uchar **pa, int *e)
342*34e04225SDavid du Colombier {
343*34e04225SDavid du Colombier u32int x;
344*34e04225SDavid du Colombier if(sunUint32Unpack(a, ea, pa, &x) < 0)
345*34e04225SDavid du Colombier return -1;
346*34e04225SDavid du Colombier *e = x;
347*34e04225SDavid du Colombier return 0;
348*34e04225SDavid du Colombier }
349*34e04225SDavid du Colombier
350*34e04225SDavid du Colombier int
sunUint1Unpack(uchar * a,uchar * ea,uchar ** pa,u1int * u)351*34e04225SDavid du Colombier sunUint1Unpack(uchar *a, uchar *ea, uchar **pa, u1int *u)
352*34e04225SDavid du Colombier {
353*34e04225SDavid du Colombier u32int x;
354*34e04225SDavid du Colombier if(sunUint32Unpack(a, ea, pa, &x) < 0 || (x!=0 && x!=1)){
355*34e04225SDavid du Colombier *pa = ea;
356*34e04225SDavid du Colombier return -1;
357*34e04225SDavid du Colombier }
358*34e04225SDavid du Colombier *u = x;
359*34e04225SDavid du Colombier return 0;
360*34e04225SDavid du Colombier }
361*34e04225SDavid du Colombier
362*34e04225SDavid du Colombier int
sunUint32Unpack(uchar * a,uchar * ea,uchar ** pa,u32int * u)363*34e04225SDavid du Colombier sunUint32Unpack(uchar *a, uchar *ea, uchar **pa, u32int *u)
364*34e04225SDavid du Colombier {
365*34e04225SDavid du Colombier u32int x;
366*34e04225SDavid du Colombier
367*34e04225SDavid du Colombier if(ea-a < 4)
368*34e04225SDavid du Colombier goto Err;
369*34e04225SDavid du Colombier x = *a++ << 24;
370*34e04225SDavid du Colombier x |= *a++ << 16;
371*34e04225SDavid du Colombier x |= *a++ << 8;
372*34e04225SDavid du Colombier x |= *a++;
373*34e04225SDavid du Colombier *pa = a;
374*34e04225SDavid du Colombier *u = x;
375*34e04225SDavid du Colombier return 0;
376*34e04225SDavid du Colombier
377*34e04225SDavid du Colombier Err:
378*34e04225SDavid du Colombier *pa = ea;
379*34e04225SDavid du Colombier return -1;
380*34e04225SDavid du Colombier }
381*34e04225SDavid du Colombier
382*34e04225SDavid du Colombier int
sunUint64Unpack(uchar * a,uchar * ea,uchar ** pa,u64int * u)383*34e04225SDavid du Colombier sunUint64Unpack(uchar *a, uchar *ea, uchar **pa, u64int *u)
384*34e04225SDavid du Colombier {
385*34e04225SDavid du Colombier u32int x, y;
386*34e04225SDavid du Colombier
387*34e04225SDavid du Colombier if(sunUint32Unpack(a, ea, &a, &x) < 0
388*34e04225SDavid du Colombier || sunUint32Unpack(a, ea, &a, &y) < 0)
389*34e04225SDavid du Colombier goto Err;
390*34e04225SDavid du Colombier *u = ((uvlong)x<<32) | y;
391*34e04225SDavid du Colombier *pa = a;
392*34e04225SDavid du Colombier return 0;
393*34e04225SDavid du Colombier Err:
394*34e04225SDavid du Colombier *pa = ea;
395*34e04225SDavid du Colombier return -1;
396*34e04225SDavid du Colombier }
397*34e04225SDavid du Colombier
398*34e04225SDavid du Colombier int
sunUint64Pack(uchar * a,uchar * ea,uchar ** pa,u64int * u)399*34e04225SDavid du Colombier sunUint64Pack(uchar *a, uchar *ea, uchar **pa, u64int *u)
400*34e04225SDavid du Colombier {
401*34e04225SDavid du Colombier u32int x, y;
402*34e04225SDavid du Colombier
403*34e04225SDavid du Colombier x = *u >> 32;
404*34e04225SDavid du Colombier y = *u;
405*34e04225SDavid du Colombier if(sunUint32Pack(a, ea, &a, &x) < 0
406*34e04225SDavid du Colombier || sunUint32Pack(a, ea, &a, &y) < 0)
407*34e04225SDavid du Colombier goto Err;
408*34e04225SDavid du Colombier *pa = a;
409*34e04225SDavid du Colombier return 0;
410*34e04225SDavid du Colombier Err:
411*34e04225SDavid du Colombier *pa = ea;
412*34e04225SDavid du Colombier return -1;
413*34e04225SDavid du Colombier }
414*34e04225SDavid du Colombier
415*34e04225SDavid du Colombier uint
sunStringSize(char * s)416*34e04225SDavid du Colombier sunStringSize(char *s)
417*34e04225SDavid du Colombier {
418*34e04225SDavid du Colombier return (4+strlen(s)+3) & ~3;
419*34e04225SDavid du Colombier }
420*34e04225SDavid du Colombier
421*34e04225SDavid du Colombier int
sunStringUnpack(uchar * a,uchar * ea,uchar ** pa,char ** s,u32int max)422*34e04225SDavid du Colombier sunStringUnpack(uchar *a, uchar *ea, uchar **pa, char **s, u32int max)
423*34e04225SDavid du Colombier {
424*34e04225SDavid du Colombier uchar *dat;
425*34e04225SDavid du Colombier u32int n;
426*34e04225SDavid du Colombier
427*34e04225SDavid du Colombier if(sunVarOpaqueUnpack(a, ea, pa, &dat, &n, max) < 0)
428*34e04225SDavid du Colombier goto Err;
429*34e04225SDavid du Colombier /* slide string down over length to make room for NUL */
430*34e04225SDavid du Colombier memmove(dat-1, dat, n);
431*34e04225SDavid du Colombier dat[-1+n] = 0;
432*34e04225SDavid du Colombier *s = (char*)(dat-1);
433*34e04225SDavid du Colombier return 0;
434*34e04225SDavid du Colombier Err:
435*34e04225SDavid du Colombier return -1;
436*34e04225SDavid du Colombier }
437*34e04225SDavid du Colombier
438*34e04225SDavid du Colombier int
sunStringPack(uchar * a,uchar * ea,uchar ** pa,char ** s,u32int max)439*34e04225SDavid du Colombier sunStringPack(uchar *a, uchar *ea, uchar **pa, char **s, u32int max)
440*34e04225SDavid du Colombier {
441*34e04225SDavid du Colombier u32int n;
442*34e04225SDavid du Colombier
443*34e04225SDavid du Colombier n = strlen(*s);
444*34e04225SDavid du Colombier return sunVarOpaquePack(a, ea, pa, (uchar**)s, &n, max);
445*34e04225SDavid du Colombier }
446*34e04225SDavid du Colombier
447*34e04225SDavid du Colombier uint
sunVarOpaqueSize(u32int n)448*34e04225SDavid du Colombier sunVarOpaqueSize(u32int n)
449*34e04225SDavid du Colombier {
450*34e04225SDavid du Colombier return (4+n+3) & ~3;
451*34e04225SDavid du Colombier }
452*34e04225SDavid du Colombier
453*34e04225SDavid du Colombier int
sunVarOpaquePack(uchar * a,uchar * ea,uchar ** pa,uchar ** dat,u32int * ndat,u32int max)454*34e04225SDavid du Colombier sunVarOpaquePack(uchar *a, uchar *ea, uchar **pa, uchar **dat, u32int *ndat, u32int max)
455*34e04225SDavid du Colombier {
456*34e04225SDavid du Colombier if(*ndat > max || sunUint32Pack(a, ea, &a, ndat) < 0
457*34e04225SDavid du Colombier || sunFixedOpaquePack(a, ea, &a, *dat, *ndat) < 0)
458*34e04225SDavid du Colombier goto Err;
459*34e04225SDavid du Colombier *pa = a;
460*34e04225SDavid du Colombier return 0;
461*34e04225SDavid du Colombier
462*34e04225SDavid du Colombier Err:
463*34e04225SDavid du Colombier *pa = ea;
464*34e04225SDavid du Colombier return -1;
465*34e04225SDavid du Colombier }
466*34e04225SDavid du Colombier
467*34e04225SDavid du Colombier int
sunVarOpaqueUnpack(uchar * a,uchar * ea,uchar ** pa,uchar ** dat,u32int * ndat,u32int max)468*34e04225SDavid du Colombier sunVarOpaqueUnpack(uchar *a, uchar *ea, uchar **pa, uchar **dat, u32int *ndat, u32int max)
469*34e04225SDavid du Colombier {
470*34e04225SDavid du Colombier if(sunUint32Unpack(a, ea, &a, ndat) < 0
471*34e04225SDavid du Colombier || *ndat > max)
472*34e04225SDavid du Colombier goto Err;
473*34e04225SDavid du Colombier *dat = a;
474*34e04225SDavid du Colombier a += (*ndat+3)&~3;
475*34e04225SDavid du Colombier if(a > ea)
476*34e04225SDavid du Colombier goto Err;
477*34e04225SDavid du Colombier *pa = a;
478*34e04225SDavid du Colombier return 0;
479*34e04225SDavid du Colombier
480*34e04225SDavid du Colombier Err:
481*34e04225SDavid du Colombier *pa = ea;
482*34e04225SDavid du Colombier return -1;
483*34e04225SDavid du Colombier }
484*34e04225SDavid du Colombier
485*34e04225SDavid du Colombier uint
sunFixedOpaqueSize(u32int n)486*34e04225SDavid du Colombier sunFixedOpaqueSize(u32int n)
487*34e04225SDavid du Colombier {
488*34e04225SDavid du Colombier return (n+3) & ~3;
489*34e04225SDavid du Colombier }
490*34e04225SDavid du Colombier
491*34e04225SDavid du Colombier int
sunFixedOpaquePack(uchar * a,uchar * ea,uchar ** pa,uchar * dat,u32int n)492*34e04225SDavid du Colombier sunFixedOpaquePack(uchar *a, uchar *ea, uchar **pa, uchar *dat, u32int n)
493*34e04225SDavid du Colombier {
494*34e04225SDavid du Colombier uint nn;
495*34e04225SDavid du Colombier
496*34e04225SDavid du Colombier nn = (n+3)&~3;
497*34e04225SDavid du Colombier if(a+nn > ea)
498*34e04225SDavid du Colombier goto Err;
499*34e04225SDavid du Colombier memmove(a, dat, n);
500*34e04225SDavid du Colombier if(nn > n)
501*34e04225SDavid du Colombier memset(a+n, 0, nn-n);
502*34e04225SDavid du Colombier a += nn;
503*34e04225SDavid du Colombier *pa = a;
504*34e04225SDavid du Colombier return 0;
505*34e04225SDavid du Colombier
506*34e04225SDavid du Colombier Err:
507*34e04225SDavid du Colombier *pa = ea;
508*34e04225SDavid du Colombier return -1;
509*34e04225SDavid du Colombier }
510*34e04225SDavid du Colombier
511*34e04225SDavid du Colombier int
sunFixedOpaqueUnpack(uchar * a,uchar * ea,uchar ** pa,uchar * dat,u32int n)512*34e04225SDavid du Colombier sunFixedOpaqueUnpack(uchar *a, uchar *ea, uchar **pa, uchar *dat, u32int n)
513*34e04225SDavid du Colombier {
514*34e04225SDavid du Colombier uint nn;
515*34e04225SDavid du Colombier
516*34e04225SDavid du Colombier nn = (n+3)&~3;
517*34e04225SDavid du Colombier if(a+nn > ea)
518*34e04225SDavid du Colombier goto Err;
519*34e04225SDavid du Colombier memmove(dat, a, n);
520*34e04225SDavid du Colombier a += nn;
521*34e04225SDavid du Colombier *pa = a;
522*34e04225SDavid du Colombier return 0;
523*34e04225SDavid du Colombier
524*34e04225SDavid du Colombier Err:
525*34e04225SDavid du Colombier *pa = ea;
526*34e04225SDavid du Colombier return -1;
527*34e04225SDavid du Colombier }
528*34e04225SDavid du Colombier
529