266 lines
3.7 KiB
C
266 lines
3.7 KiB
C
#include <u.h>
|
|
#include <libc.h>
|
|
#include <venti.h>
|
|
#include <libsec.h>
|
|
|
|
#define MAGIC 0x54798314
|
|
#define NOTFREE(p) assert((p)->magic == MAGIC)
|
|
|
|
struct Packet
|
|
{
|
|
char *data;
|
|
int len;
|
|
void (*free)(void*);
|
|
void *arg;
|
|
int magic;
|
|
};
|
|
|
|
Packet*
|
|
packetalloc(void)
|
|
{
|
|
Packet *p;
|
|
|
|
p = vtmallocz(sizeof *p);
|
|
p->free = vtfree;
|
|
p->arg = nil;
|
|
p->magic = MAGIC;
|
|
return p;
|
|
}
|
|
|
|
void
|
|
packetappend(Packet *p, uchar *buf, int n)
|
|
{
|
|
NOTFREE(p);
|
|
if(n < 0)
|
|
abort();
|
|
if(p->free != vtfree)
|
|
sysfatal("packetappend");
|
|
p->data = vtrealloc(p->data, p->len+n);
|
|
p->arg = p->data;
|
|
memmove(p->data+p->len, buf, n);
|
|
p->len += n;
|
|
}
|
|
|
|
uint
|
|
packetasize(Packet *p)
|
|
{
|
|
NOTFREE(p);
|
|
return p->len;
|
|
}
|
|
|
|
int
|
|
packetcmp(Packet *p, Packet *q)
|
|
{
|
|
int i, len;
|
|
|
|
NOTFREE(p);
|
|
NOTFREE(q);
|
|
len = p->len;
|
|
if(len > q->len)
|
|
len = q->len;
|
|
if(len && (i=memcmp(p->data, q->data, len)) != 0)
|
|
return i;
|
|
if(p->len > len)
|
|
return 1;
|
|
if(q->len > len)
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
packetconcat(Packet *p, Packet *q)
|
|
{
|
|
NOTFREE(p);
|
|
NOTFREE(q);
|
|
packetappend(p, q->data, q->len);
|
|
if(q->free == vtfree)
|
|
memset(q->data, 0xFE, q->len);
|
|
q->free(q->arg);
|
|
q->data = nil;
|
|
q->len = 0;
|
|
}
|
|
|
|
int
|
|
packetconsume(Packet *p, uchar *buf, int n)
|
|
{
|
|
NOTFREE(p);
|
|
if(n < 0)
|
|
abort();
|
|
if(p->len < n)
|
|
abort();
|
|
memmove(buf, p->data, n);
|
|
p->len -= n;
|
|
memmove(p->data, p->data+n, p->len);
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
packetcopy(Packet *p, uchar *buf, int offset, int n)
|
|
{
|
|
NOTFREE(p);
|
|
if(offset < 0 || n < 0)
|
|
abort();
|
|
if(offset > p->len)
|
|
abort();
|
|
if(offset+n > p->len)
|
|
n = p->len - offset;
|
|
memmove(buf, p->data+offset, n);
|
|
return 0;
|
|
}
|
|
|
|
Packet*
|
|
packetdup(Packet *p, int offset, int n)
|
|
{
|
|
Packet *q;
|
|
|
|
NOTFREE(p);
|
|
if(offset < 0 || n < 0)
|
|
abort();
|
|
if(offset > p->len)
|
|
abort();
|
|
if(offset+n > p->len)
|
|
n = p->len - offset;
|
|
q = packetalloc();
|
|
packetappend(q, p->data+offset, n);
|
|
return q;
|
|
}
|
|
|
|
Packet*
|
|
packetforeign(uchar *buf, int n, void (*free)(void*), void *a)
|
|
{
|
|
Packet *p;
|
|
|
|
if(n < 0)
|
|
abort();
|
|
p = packetalloc();
|
|
p->data = (char*)buf;
|
|
p->len = n;
|
|
p->free = free;
|
|
p->arg = a;
|
|
return p;
|
|
}
|
|
|
|
int
|
|
packetfragments(Packet *p, IOchunk *io, int nio, int offset)
|
|
{
|
|
NOTFREE(p);
|
|
if(offset < 0)
|
|
abort();
|
|
if(nio == 0)
|
|
return 0;
|
|
memset(io, 0, sizeof(io[0])*nio);
|
|
if(offset >= p->len)
|
|
return 0;
|
|
io[0].addr = p->data + offset;
|
|
io[0].len = p->len - offset;
|
|
return p->len;
|
|
}
|
|
|
|
void
|
|
packetfree(Packet *p)
|
|
{
|
|
NOTFREE(p);
|
|
if(p->free == free)
|
|
memset(p->data, 0xFE, p->len);
|
|
p->free(p->arg);
|
|
p->data = nil;
|
|
p->len = 0;
|
|
memset(p, 0xFB, sizeof *p);
|
|
free(p);
|
|
}
|
|
|
|
uchar*
|
|
packetheader(Packet *p, int n)
|
|
{
|
|
NOTFREE(p);
|
|
if(n < 0)
|
|
abort();
|
|
if(n > p->len)
|
|
abort();
|
|
return p->data;
|
|
}
|
|
|
|
uchar*
|
|
packetpeek(Packet *p, uchar *buf, int offset, int n)
|
|
{
|
|
NOTFREE(p);
|
|
if(offset < 0 || n < 0)
|
|
abort();
|
|
if(offset+n > p->len)
|
|
abort();
|
|
return p->data+offset;
|
|
}
|
|
|
|
void
|
|
packetprefix(Packet *p, uchar *buf, int n)
|
|
{
|
|
NOTFREE(p);
|
|
if(n < 0)
|
|
abort();
|
|
if(p->free != free)
|
|
sysfatal("packetappend");
|
|
p->data = vtrealloc(p->data, p->len+n);
|
|
p->arg = p->data;
|
|
memmove(p->data+n, p->data, p->len);
|
|
memmove(p->data, buf, n);
|
|
p->len += n;
|
|
}
|
|
|
|
void
|
|
packetsha1(Packet *p, uchar d[20])
|
|
{
|
|
NOTFREE(p);
|
|
sha1((uchar*)p->data, p->len, d, nil);
|
|
}
|
|
|
|
uint
|
|
packetsize(Packet *p)
|
|
{
|
|
NOTFREE(p);
|
|
return p->len;
|
|
}
|
|
|
|
Packet*
|
|
packetsplit(Packet *p, int n)
|
|
{
|
|
Packet *q;
|
|
|
|
NOTFREE(p);
|
|
q = packetalloc();
|
|
q->data = vtmalloc(n);
|
|
q->arg = q->data;
|
|
q->free = vtfree;
|
|
packetconsume(p, q->data, n);
|
|
return q;
|
|
}
|
|
|
|
void
|
|
packetstats(void)
|
|
{
|
|
}
|
|
|
|
uchar*
|
|
packettrailer(Packet *p, int n)
|
|
{
|
|
NOTFREE(p);
|
|
if(n < 0)
|
|
abort();
|
|
if(n > p->len)
|
|
abort();
|
|
return p->data + p->len - n;
|
|
}
|
|
|
|
int
|
|
packettrim(Packet *p, int offset, int n)
|
|
{
|
|
NOTFREE(p);
|
|
if(offset < 0 || n < 0)
|
|
abort();
|
|
if(offset+n > p->len)
|
|
abort();
|
|
memmove(p->data+offset, p->data+offset+n, p->len-offset-n);
|
|
p->len -= n;
|
|
return 0;
|
|
}
|
|
|