2 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
3 * 2006-2009 Bjorn Andersson <flex@kryo.se>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 readname_loop(char *packet, int packetlen, char **src, char *dst, size_t length, size_t loop)
38 while(*s && len < length - 2) {
41 /* is this a compressed label? */
42 if((c & 0xc0) == 0xc0) {
43 offset = (((s[-1] & 0x3f) << 8) | (s[0] & 0xff));
44 if (offset > packetlen) {
46 /* Bad jump first in packet */
49 /* Bad jump after some data */
53 dummy = packet + offset;
54 len += readname_loop(packet, packetlen, &dummy, d, length - len, loop - 1);
58 while(c && len < length - 1) {
65 if (len >= length - 1) {
66 break; /* We used up all space */
82 readname(char *packet, int packetlen, char **src, char *dst, size_t length)
84 return readname_loop(packet, packetlen, src, dst, length, 10);
88 readshort(char *packet, char **src, unsigned short *dst)
92 p = (unsigned char *) *src;
93 *dst = (p[0] << 8) | p[1];
95 (*src) += sizeof(unsigned short);
96 return sizeof(unsigned short);
100 readlong(char *packet, char **src, uint32_t *dst)
102 /* A long as described in dns protocol is always 32 bits */
105 p = (unsigned char *) *src;
107 *dst = ((uint32_t)p[0] << 24)
108 | ((uint32_t)p[1] << 16)
109 | ((uint32_t)p[2] << 8)
112 (*src) += sizeof(uint32_t);
113 return sizeof(uint32_t);
117 readdata(char *packet, char **src, char *dst, size_t len)
119 memcpy(dst, *src, len);
127 readtxtbin(char *packet, char **src, size_t srcremain, char *dst, size_t dstremain)
133 while (srcremain > 0)
135 uc = (unsigned char*) (*src);
140 if (tocopy > srcremain)
141 return 0; /* illegal, better have nothing */
142 if (tocopy > dstremain)
143 return 0; /* doesn't fit, better have nothing */
145 memcpy(dst, *src, tocopy);
156 putname(char **buf, size_t buflen, const char *host)
167 word = strtok(h, ".");
169 if (strlen(word) > 63 || strlen(word) > left) {
174 left -= (strlen(word) + 1);
175 *p++ = (char)strlen(word);
176 memcpy(p, word, strlen(word));
179 word = strtok(NULL, ".");
187 return buflen - left;
191 putbyte(char **dst, unsigned char value)
200 putshort(char **dst, unsigned short value)
204 p = (unsigned char *) *dst;
210 return sizeof(short);
214 putlong(char **dst, uint32_t value)
216 /* A long as described in dns protocol is always 32 bits */
219 p = (unsigned char *) *dst;
221 *p++ = (value >> 24);
222 *p++ = (value >> 16);
227 return sizeof(uint32_t);
231 putdata(char **dst, char *data, size_t len)
233 memcpy(*dst, data, len);
240 puttxtbin(char **buf, size_t bufremain, char *from, size_t fromremain)
243 unsigned char *ucp = &uc;
244 char *cp = (char *) ucp;
248 while (fromremain > 0)
252 tocopy = 252; /* allow off-by-1s in caches etc */
253 if (tocopy + 1 > bufremain)
254 return -1; /* doesn't fit, better have nothing */
262 memcpy(*buf, from, tocopy);
266 fromremain -= tocopy;