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