iodine/read.c

157 lines
2.6 KiB
C
Raw Normal View History

/*
* Copyright (c) 2006 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
2006-08-24 22:04:27 +00:00
static int
readname_loop(char *packet, char **src, char *dst, size_t length, size_t loop)
{
char *dummy;
int len;
char *p;
char c;
2006-08-24 22:04:27 +00:00
if (loop <= 0)
return 0;
len = 0;
p = *src;
2006-08-24 22:04:27 +00:00
while(*p && len < length - 2) {
c = *p++;
/* is this a compressed label? */
if((c & 0xc0) == 0xc0) {
dummy = packet + (((p[-1] & 0x3f) << 8) | p[0]);
2006-08-24 22:04:27 +00:00
len += readname_loop(packet, &dummy, dst, length - len, loop - 1);
break;
}
2006-08-24 22:04:27 +00:00
while(c && len < length - 2) {
*dst++ = *p++;
len++;
c--;
}
2006-08-24 22:04:27 +00:00
if (*p != 0 && len < length - 2)
2006-08-16 20:18:16 +00:00
*dst++ = '.';
else
2006-08-16 20:18:16 +00:00
*dst++ = '\0';
}
(*src) = p+1;
return strlen(dst);
}
2006-08-24 22:04:27 +00:00
int
readname(char *packet, char **src, char *dst, size_t length)
{
return readname_loop(packet, src, dst, length, 10);
}
int
readshort(char *packet, char **src, short *dst)
{
2006-08-23 16:03:24 +00:00
unsigned char *p;
p = *src;
2006-08-23 16:03:24 +00:00
*dst = (p[0] << 8) | p[1];
(*src) += sizeof(short);
return sizeof(short);
}
int
readlong(char *packet, char **src, long *dst)
{
2006-08-23 16:03:24 +00:00
unsigned char *p;
p = *src;
*dst = ((long)p[0] << 24)
| ((long)p[1] << 16)
| ((long)p[2] << 8)
| ((long)p[3]);
(*src) += sizeof(long);
return sizeof(long);
}
int
readdata(char *packet, char **src, char *dst, size_t len)
{
2006-08-23 16:03:24 +00:00
if (len < 0)
2006-08-23 16:38:58 +00:00
return 0;
2006-08-23 16:03:24 +00:00
memcpy(dst, *src, len);
(*src) += len;
return len;
}
int
putbyte(char **dst, char value)
{
**dst = value;
(*dst)++;
return sizeof(char);
}
int
putshort(char **dst, short value)
{
2006-08-23 16:03:24 +00:00
unsigned char *p;
p = *dst;
*p++ = (value >> 8);
*p++ = value;
(*dst) = p;
return sizeof(short);
}
int
putlong(char **dst, long value)
{
2006-08-23 16:03:24 +00:00
unsigned char *p;
p = *dst;
*p++ = (value >> 24);
*p++ = (value >> 16);
*p++ = (value >> 8);
*p++ = (value);
(*dst) = p;
return sizeof(long);
}
int
putdata(char **dst, char *data, size_t len)
{
2006-08-23 16:03:24 +00:00
if (len < 0)
2006-08-23 16:38:58 +00:00
return 0;
2006-08-23 16:03:24 +00:00
memcpy(*dst, data, len);
(*dst) += len;
return len;
}