1*368c31abSDavid du Colombier #include <u.h>
2*368c31abSDavid du Colombier #include <libc.h>
3*368c31abSDavid du Colombier #include <venti.h>
4*368c31abSDavid du Colombier
5*368c31abSDavid du Colombier Packet*
vtfcallpack(VtFcall * f)6*368c31abSDavid du Colombier vtfcallpack(VtFcall *f)
7*368c31abSDavid du Colombier {
8*368c31abSDavid du Colombier uchar buf[4];
9*368c31abSDavid du Colombier Packet *p;
10*368c31abSDavid du Colombier
11*368c31abSDavid du Colombier p = packetalloc();
12*368c31abSDavid du Colombier
13*368c31abSDavid du Colombier buf[0] = f->msgtype;
14*368c31abSDavid du Colombier buf[1] = f->tag;
15*368c31abSDavid du Colombier packetappend(p, buf, 2);
16*368c31abSDavid du Colombier
17*368c31abSDavid du Colombier switch(f->msgtype){
18*368c31abSDavid du Colombier default:
19*368c31abSDavid du Colombier werrstr("vtfcallpack: unknown packet type %d", f->msgtype);
20*368c31abSDavid du Colombier goto Err;
21*368c31abSDavid du Colombier
22*368c31abSDavid du Colombier case VtRerror:
23*368c31abSDavid du Colombier if(vtputstring(p, f->error) < 0)
24*368c31abSDavid du Colombier goto Err;
25*368c31abSDavid du Colombier break;
26*368c31abSDavid du Colombier
27*368c31abSDavid du Colombier case VtTping:
28*368c31abSDavid du Colombier break;
29*368c31abSDavid du Colombier
30*368c31abSDavid du Colombier case VtRping:
31*368c31abSDavid du Colombier break;
32*368c31abSDavid du Colombier
33*368c31abSDavid du Colombier case VtThello:
34*368c31abSDavid du Colombier if(vtputstring(p, f->version) < 0
35*368c31abSDavid du Colombier || vtputstring(p, f->uid) < 0)
36*368c31abSDavid du Colombier goto Err;
37*368c31abSDavid du Colombier buf[0] = f->strength;
38*368c31abSDavid du Colombier buf[1] = f->ncrypto;
39*368c31abSDavid du Colombier packetappend(p, buf, 2);
40*368c31abSDavid du Colombier packetappend(p, f->crypto, f->ncrypto);
41*368c31abSDavid du Colombier buf[0] = f->ncodec;
42*368c31abSDavid du Colombier packetappend(p, buf, 1);
43*368c31abSDavid du Colombier packetappend(p, f->codec, f->ncodec);
44*368c31abSDavid du Colombier break;
45*368c31abSDavid du Colombier
46*368c31abSDavid du Colombier case VtRhello:
47*368c31abSDavid du Colombier if(vtputstring(p, f->sid) < 0)
48*368c31abSDavid du Colombier goto Err;
49*368c31abSDavid du Colombier buf[0] = f->rcrypto;
50*368c31abSDavid du Colombier buf[1] = f->rcodec;
51*368c31abSDavid du Colombier packetappend(p, buf, 2);
52*368c31abSDavid du Colombier break;
53*368c31abSDavid du Colombier
54*368c31abSDavid du Colombier case VtTgoodbye:
55*368c31abSDavid du Colombier break;
56*368c31abSDavid du Colombier
57*368c31abSDavid du Colombier case VtTread:
58*368c31abSDavid du Colombier packetappend(p, f->score, VtScoreSize);
59*368c31abSDavid du Colombier buf[0] = vttodisktype(f->blocktype);
60*368c31abSDavid du Colombier if(~buf[0] == 0)
61*368c31abSDavid du Colombier goto Err;
62*368c31abSDavid du Colombier buf[1] = 0;
63*368c31abSDavid du Colombier buf[2] = f->count >> 8;
64*368c31abSDavid du Colombier buf[3] = f->count;
65*368c31abSDavid du Colombier packetappend(p, buf, 4);
66*368c31abSDavid du Colombier break;
67*368c31abSDavid du Colombier
68*368c31abSDavid du Colombier case VtRread:
69*368c31abSDavid du Colombier packetconcat(p, f->data);
70*368c31abSDavid du Colombier break;
71*368c31abSDavid du Colombier
72*368c31abSDavid du Colombier case VtTwrite:
73*368c31abSDavid du Colombier buf[0] = vttodisktype(f->blocktype);
74*368c31abSDavid du Colombier if(~buf[0] == 0)
75*368c31abSDavid du Colombier goto Err;
76*368c31abSDavid du Colombier buf[1] = 0;
77*368c31abSDavid du Colombier buf[2] = 0;
78*368c31abSDavid du Colombier buf[3] = 0;
79*368c31abSDavid du Colombier packetappend(p, buf, 4);
80*368c31abSDavid du Colombier packetconcat(p, f->data);
81*368c31abSDavid du Colombier break;
82*368c31abSDavid du Colombier
83*368c31abSDavid du Colombier case VtRwrite:
84*368c31abSDavid du Colombier packetappend(p, f->score, VtScoreSize);
85*368c31abSDavid du Colombier break;
86*368c31abSDavid du Colombier
87*368c31abSDavid du Colombier case VtTsync:
88*368c31abSDavid du Colombier break;
89*368c31abSDavid du Colombier
90*368c31abSDavid du Colombier case VtRsync:
91*368c31abSDavid du Colombier break;
92*368c31abSDavid du Colombier }
93*368c31abSDavid du Colombier
94*368c31abSDavid du Colombier return p;
95*368c31abSDavid du Colombier
96*368c31abSDavid du Colombier Err:
97*368c31abSDavid du Colombier packetfree(p);
98*368c31abSDavid du Colombier return nil;
99*368c31abSDavid du Colombier }
100*368c31abSDavid du Colombier
101*368c31abSDavid du Colombier int
vtfcallunpack(VtFcall * f,Packet * p)102*368c31abSDavid du Colombier vtfcallunpack(VtFcall *f, Packet *p)
103*368c31abSDavid du Colombier {
104*368c31abSDavid du Colombier uchar buf[4];
105*368c31abSDavid du Colombier
106*368c31abSDavid du Colombier memset(f, 0, sizeof *f);
107*368c31abSDavid du Colombier
108*368c31abSDavid du Colombier if(packetconsume(p, buf, 2) < 0)
109*368c31abSDavid du Colombier return -1;
110*368c31abSDavid du Colombier
111*368c31abSDavid du Colombier f->msgtype = buf[0];
112*368c31abSDavid du Colombier f->tag = buf[1];
113*368c31abSDavid du Colombier
114*368c31abSDavid du Colombier switch(f->msgtype){
115*368c31abSDavid du Colombier default:
116*368c31abSDavid du Colombier werrstr("vtfcallunpack: unknown bad packet type %d", f->msgtype);
117*368c31abSDavid du Colombier vtfcallclear(f);
118*368c31abSDavid du Colombier return -1;
119*368c31abSDavid du Colombier
120*368c31abSDavid du Colombier case VtRerror:
121*368c31abSDavid du Colombier if(vtgetstring(p, &f->error) < 0)
122*368c31abSDavid du Colombier goto Err;
123*368c31abSDavid du Colombier break;
124*368c31abSDavid du Colombier
125*368c31abSDavid du Colombier case VtTping:
126*368c31abSDavid du Colombier break;
127*368c31abSDavid du Colombier
128*368c31abSDavid du Colombier case VtRping:
129*368c31abSDavid du Colombier break;
130*368c31abSDavid du Colombier
131*368c31abSDavid du Colombier case VtThello:
132*368c31abSDavid du Colombier if(vtgetstring(p, &f->version) < 0
133*368c31abSDavid du Colombier || vtgetstring(p, &f->uid) < 0
134*368c31abSDavid du Colombier || packetconsume(p, buf, 2) < 0)
135*368c31abSDavid du Colombier goto Err;
136*368c31abSDavid du Colombier f->strength = buf[0];
137*368c31abSDavid du Colombier f->ncrypto = buf[1];
138*368c31abSDavid du Colombier if(f->ncrypto){
139*368c31abSDavid du Colombier f->crypto = vtmalloc(f->ncrypto);
140*368c31abSDavid du Colombier if(packetconsume(p, buf, f->ncrypto) < 0)
141*368c31abSDavid du Colombier goto Err;
142*368c31abSDavid du Colombier }
143*368c31abSDavid du Colombier if(packetconsume(p, buf, 1) < 0)
144*368c31abSDavid du Colombier goto Err;
145*368c31abSDavid du Colombier f->ncodec = buf[0];
146*368c31abSDavid du Colombier if(f->ncodec){
147*368c31abSDavid du Colombier f->codec = vtmalloc(f->ncodec);
148*368c31abSDavid du Colombier if(packetconsume(p, buf, f->ncodec) < 0)
149*368c31abSDavid du Colombier goto Err;
150*368c31abSDavid du Colombier }
151*368c31abSDavid du Colombier break;
152*368c31abSDavid du Colombier
153*368c31abSDavid du Colombier case VtRhello:
154*368c31abSDavid du Colombier if(vtgetstring(p, &f->sid) < 0
155*368c31abSDavid du Colombier || packetconsume(p, buf, 2) < 0)
156*368c31abSDavid du Colombier goto Err;
157*368c31abSDavid du Colombier f->rcrypto = buf[0];
158*368c31abSDavid du Colombier f->rcodec = buf[1];
159*368c31abSDavid du Colombier break;
160*368c31abSDavid du Colombier
161*368c31abSDavid du Colombier case VtTgoodbye:
162*368c31abSDavid du Colombier break;
163*368c31abSDavid du Colombier
164*368c31abSDavid du Colombier case VtTread:
165*368c31abSDavid du Colombier if(packetconsume(p, f->score, VtScoreSize) < 0
166*368c31abSDavid du Colombier || packetconsume(p, buf, 4) < 0)
167*368c31abSDavid du Colombier goto Err;
168*368c31abSDavid du Colombier f->blocktype = vtfromdisktype(buf[0]);
169*368c31abSDavid du Colombier if(~f->blocktype == 0)
170*368c31abSDavid du Colombier goto Err;
171*368c31abSDavid du Colombier f->count = (buf[2] << 8) | buf[3];
172*368c31abSDavid du Colombier break;
173*368c31abSDavid du Colombier
174*368c31abSDavid du Colombier case VtRread:
175*368c31abSDavid du Colombier f->data = packetalloc();
176*368c31abSDavid du Colombier packetconcat(f->data, p);
177*368c31abSDavid du Colombier break;
178*368c31abSDavid du Colombier
179*368c31abSDavid du Colombier case VtTwrite:
180*368c31abSDavid du Colombier if(packetconsume(p, buf, 4) < 0)
181*368c31abSDavid du Colombier goto Err;
182*368c31abSDavid du Colombier f->blocktype = vtfromdisktype(buf[0]);
183*368c31abSDavid du Colombier if(~f->blocktype == 0)
184*368c31abSDavid du Colombier goto Err;
185*368c31abSDavid du Colombier f->data = packetalloc();
186*368c31abSDavid du Colombier packetconcat(f->data, p);
187*368c31abSDavid du Colombier break;
188*368c31abSDavid du Colombier
189*368c31abSDavid du Colombier case VtRwrite:
190*368c31abSDavid du Colombier if(packetconsume(p, f->score, VtScoreSize) < 0)
191*368c31abSDavid du Colombier goto Err;
192*368c31abSDavid du Colombier break;
193*368c31abSDavid du Colombier
194*368c31abSDavid du Colombier case VtTsync:
195*368c31abSDavid du Colombier break;
196*368c31abSDavid du Colombier
197*368c31abSDavid du Colombier case VtRsync:
198*368c31abSDavid du Colombier break;
199*368c31abSDavid du Colombier }
200*368c31abSDavid du Colombier
201*368c31abSDavid du Colombier if(packetsize(p) != 0)
202*368c31abSDavid du Colombier goto Err;
203*368c31abSDavid du Colombier
204*368c31abSDavid du Colombier return 0;
205*368c31abSDavid du Colombier
206*368c31abSDavid du Colombier Err:
207*368c31abSDavid du Colombier werrstr("bad packet");
208*368c31abSDavid du Colombier vtfcallclear(f);
209*368c31abSDavid du Colombier return -1;
210*368c31abSDavid du Colombier }
211*368c31abSDavid du Colombier
212*368c31abSDavid du Colombier void
vtfcallclear(VtFcall * f)213*368c31abSDavid du Colombier vtfcallclear(VtFcall *f)
214*368c31abSDavid du Colombier {
215*368c31abSDavid du Colombier vtfree(f->error);
216*368c31abSDavid du Colombier f->error = nil;
217*368c31abSDavid du Colombier vtfree(f->uid);
218*368c31abSDavid du Colombier f->uid = nil;
219*368c31abSDavid du Colombier vtfree(f->sid);
220*368c31abSDavid du Colombier f->sid = nil;
221*368c31abSDavid du Colombier vtfree(f->version);
222*368c31abSDavid du Colombier f->version = nil;
223*368c31abSDavid du Colombier vtfree(f->crypto);
224*368c31abSDavid du Colombier f->crypto = nil;
225*368c31abSDavid du Colombier vtfree(f->codec);
226*368c31abSDavid du Colombier f->codec = nil;
227*368c31abSDavid du Colombier vtfree(f->auth);
228*368c31abSDavid du Colombier f->auth = nil;
229*368c31abSDavid du Colombier packetfree(f->data);
230*368c31abSDavid du Colombier f->data = nil;
231*368c31abSDavid du Colombier }
232