1 #include <u.h>
2 #include <libc.h>
3 #include <venti.h>
4 #include <libsec.h>
5
6 #define MAGIC 0x54798314
7 #define NOTFREE(p) assert((p)->magic == MAGIC)
8
9 struct Packet
10 {
11 char *data;
12 int len;
13 void (*free)(void*);
14 void *arg;
15 int magic;
16 };
17
18 Packet*
packetalloc(void)19 packetalloc(void)
20 {
21 Packet *p;
22
23 p = vtmallocz(sizeof *p);
24 p->free = vtfree;
25 p->arg = nil;
26 p->magic = MAGIC;
27 return p;
28 }
29
30 void
packetappend(Packet * p,uchar * buf,int n)31 packetappend(Packet *p, uchar *buf, int n)
32 {
33 NOTFREE(p);
34 if(n < 0)
35 abort();
36 if(p->free != vtfree)
37 sysfatal("packetappend");
38 p->data = vtrealloc(p->data, p->len+n);
39 p->arg = p->data;
40 memmove(p->data+p->len, buf, n);
41 p->len += n;
42 }
43
44 uint
packetasize(Packet * p)45 packetasize(Packet *p)
46 {
47 NOTFREE(p);
48 return p->len;
49 }
50
51 int
packetcmp(Packet * p,Packet * q)52 packetcmp(Packet *p, Packet *q)
53 {
54 int i, len;
55
56 NOTFREE(p);
57 NOTFREE(q);
58 len = p->len;
59 if(len > q->len)
60 len = q->len;
61 if(len && (i=memcmp(p->data, q->data, len)) != 0)
62 return i;
63 if(p->len > len)
64 return 1;
65 if(q->len > len)
66 return -1;
67 return 0;
68 }
69
70 void
packetconcat(Packet * p,Packet * q)71 packetconcat(Packet *p, Packet *q)
72 {
73 NOTFREE(p);
74 NOTFREE(q);
75 packetappend(p, q->data, q->len);
76 if(q->free == vtfree)
77 memset(q->data, 0xFE, q->len);
78 q->free(q->arg);
79 q->data = nil;
80 q->len = 0;
81 }
82
83 int
packetconsume(Packet * p,uchar * buf,int n)84 packetconsume(Packet *p, uchar *buf, int n)
85 {
86 NOTFREE(p);
87 if(n < 0)
88 abort();
89 if(p->len < n)
90 abort();
91 memmove(buf, p->data, n);
92 p->len -= n;
93 memmove(p->data, p->data+n, p->len);
94 return 0;
95 }
96
97 int
packetcopy(Packet * p,uchar * buf,int offset,int n)98 packetcopy(Packet *p, uchar *buf, int offset, int n)
99 {
100 NOTFREE(p);
101 if(offset < 0 || n < 0)
102 abort();
103 if(offset > p->len)
104 abort();
105 if(offset+n > p->len)
106 n = p->len - offset;
107 memmove(buf, p->data+offset, n);
108 return 0;
109 }
110
111 Packet*
packetdup(Packet * p,int offset,int n)112 packetdup(Packet *p, int offset, int n)
113 {
114 Packet *q;
115
116 NOTFREE(p);
117 if(offset < 0 || n < 0)
118 abort();
119 if(offset > p->len)
120 abort();
121 if(offset+n > p->len)
122 n = p->len - offset;
123 q = packetalloc();
124 packetappend(q, p->data+offset, n);
125 return q;
126 }
127
128 Packet*
packetforeign(uchar * buf,int n,void (* free)(void *),void * a)129 packetforeign(uchar *buf, int n, void (*free)(void*), void *a)
130 {
131 Packet *p;
132
133 if(n < 0)
134 abort();
135 p = packetalloc();
136 p->data = (char*)buf;
137 p->len = n;
138 p->free = free;
139 p->arg = a;
140 return p;
141 }
142
143 int
packetfragments(Packet * p,IOchunk * io,int nio,int offset)144 packetfragments(Packet *p, IOchunk *io, int nio, int offset)
145 {
146 NOTFREE(p);
147 if(offset < 0)
148 abort();
149 if(nio == 0)
150 return 0;
151 memset(io, 0, sizeof(io[0])*nio);
152 if(offset >= p->len)
153 return 0;
154 io[0].addr = p->data + offset;
155 io[0].len = p->len - offset;
156 return p->len;
157 }
158
159 void
packetfree(Packet * p)160 packetfree(Packet *p)
161 {
162 NOTFREE(p);
163 if(p->free == free)
164 memset(p->data, 0xFE, p->len);
165 p->free(p->arg);
166 p->data = nil;
167 p->len = 0;
168 memset(p, 0xFB, sizeof *p);
169 free(p);
170 }
171
172 uchar*
packetheader(Packet * p,int n)173 packetheader(Packet *p, int n)
174 {
175 NOTFREE(p);
176 if(n < 0)
177 abort();
178 if(n > p->len)
179 abort();
180 return p->data;
181 }
182
183 uchar*
packetpeek(Packet * p,uchar * buf,int offset,int n)184 packetpeek(Packet *p, uchar *buf, int offset, int n)
185 {
186 NOTFREE(p);
187 if(offset < 0 || n < 0)
188 abort();
189 if(offset+n > p->len)
190 abort();
191 return p->data+offset;
192 }
193
194 void
packetprefix(Packet * p,uchar * buf,int n)195 packetprefix(Packet *p, uchar *buf, int n)
196 {
197 NOTFREE(p);
198 if(n < 0)
199 abort();
200 if(p->free != free)
201 sysfatal("packetappend");
202 p->data = vtrealloc(p->data, p->len+n);
203 p->arg = p->data;
204 memmove(p->data+n, p->data, p->len);
205 memmove(p->data, buf, n);
206 p->len += n;
207 }
208
209 void
packetsha1(Packet * p,uchar d[20])210 packetsha1(Packet *p, uchar d[20])
211 {
212 NOTFREE(p);
213 sha1((uchar*)p->data, p->len, d, nil);
214 }
215
216 uint
packetsize(Packet * p)217 packetsize(Packet *p)
218 {
219 NOTFREE(p);
220 return p->len;
221 }
222
223 Packet*
packetsplit(Packet * p,int n)224 packetsplit(Packet *p, int n)
225 {
226 Packet *q;
227
228 NOTFREE(p);
229 q = packetalloc();
230 q->data = vtmalloc(n);
231 q->arg = q->data;
232 q->free = vtfree;
233 packetconsume(p, q->data, n);
234 return q;
235 }
236
237 void
packetstats(void)238 packetstats(void)
239 {
240 }
241
242 uchar*
packettrailer(Packet * p,int n)243 packettrailer(Packet *p, int n)
244 {
245 NOTFREE(p);
246 if(n < 0)
247 abort();
248 if(n > p->len)
249 abort();
250 return p->data + p->len - n;
251 }
252
253 int
packettrim(Packet * p,int offset,int n)254 packettrim(Packet *p, int offset, int n)
255 {
256 NOTFREE(p);
257 if(offset < 0 || n < 0)
258 abort();
259 if(offset+n > p->len)
260 abort();
261 memmove(p->data+offset, p->data+offset+n, p->len-offset-n);
262 p->len -= n;
263 return 0;
264 }
265