7 flxDnsPacket* flx_dns_packet_new(void) {
9 p = g_new(flxDnsPacket, 1);
10 p->size = p->rindex = 2*6;
11 memset(p->data, 0, p->size);
15 void flx_dns_packet_free(flxDnsPacket *p) {
20 void flx_dns_packet_set_field(flxDnsPacket *p, guint index, guint16 v) {
22 g_assert(index < 2*6);
24 ((guint16*) p->data)[index] = g_htons(v);
27 guint16 flx_dns_packet_get_field(flxDnsPacket *p, guint index) {
29 g_assert(index < 2*6);
31 return g_ntohs(((guint16*) p->data)[index]);
34 guint8* flx_dns_packet_append_name(flxDnsPacket *p, const gchar *name) {
41 guint n = strcspn(name, ".");
45 d = flx_dns_packet_extend(p, n+1);
64 d = flx_dns_packet_extend(p, 1);
70 guint8* flx_dns_packet_append_uint16(flxDnsPacket *p, guint16 v) {
75 d = flx_dns_packet_extend(p, sizeof(guint16));
76 *((guint16*) d) = g_htons(v);
81 guint8 *flx_dns_packet_append_uint32(flxDnsPacket *p, guint32 v) {
85 d = flx_dns_packet_extend(p, sizeof(guint32));
86 *((guint32*) d) = g_htonl(v);
91 guint8 *flx_dns_packet_append_bytes(flxDnsPacket *p, gconstpointer b, guint l) {
98 d = flx_dns_packet_extend(p, l);
106 guint8 *flx_dns_packet_extend(flxDnsPacket *p, guint l) {
110 g_assert(p->size+l <= sizeof(p->data));
112 d = p->data + p->size;
118 guint8 *flx_dns_packet_append_name_compressed(flxDnsPacket *p, const gchar *name, guint8 *prev) {
124 return flx_dns_packet_append_name(p, name);
127 if (k < 0 || k >= 0x4000 || (guint) k >= p->size)
128 return flx_dns_packet_append_name(p, name);
130 d = (guint16*) flx_dns_packet_extend(p, sizeof(guint16));
131 *d = g_htons((0xC000 | k));
136 gint flx_dns_packet_check_valid(flxDnsPacket *p) {
143 flags = flx_dns_packet_get_field(p, DNS_FIELD_FLAGS);
145 if (flags & DNS_FLAG_OPCODE || flags & DNS_FLAG_RCODE)
151 gint flx_dns_packet_is_query(flxDnsPacket *p) {
154 return !(flx_dns_packet_get_field(p, DNS_FIELD_FLAGS) & DNS_FLAG_QR);
157 static gint consume_labels(flxDnsPacket *p, guint index, gchar *ret_name, guint l) {
161 g_assert(p && ret_name && l);
166 if (index+1 > p->size)
182 } else if (n <= 63) {
183 /* Uncompressed label */
188 if (index + n > p->size)
191 if ((guint) n + 1 > l)
200 memcpy(ret_name, p->data + index, n);
207 } else if ((n & 0xC0) == 0xC0) {
208 /* Compressed label */
210 if (index+2 > p->size)
213 index = ((guint) (p->data[index] & ~0xC0)) << 8 | p->data[index+1];
224 gint flx_dns_packet_consume_name(flxDnsPacket *p, gchar *ret_name, guint l) {
227 if ((r = consume_labels(p, p->rindex, ret_name, l)) < 0)
234 gint flx_dns_packet_consume_uint16(flxDnsPacket *p, guint16 *ret_v) {
238 if (p->rindex + sizeof(guint16) > p->size)
241 *ret_v = g_ntohs(*((guint16*) (p->data + p->rindex)));
242 p->rindex += sizeof(guint16);
247 gint flx_dns_packet_consume_uint32(flxDnsPacket *p, guint32 *ret_v) {
251 if (p->rindex + sizeof(guint32) > p->size)
254 *ret_v = g_ntohl(*((guint32*) (p->data + p->rindex)));
255 p->rindex += sizeof(guint32);
260 gint flx_dns_packet_consume_bytes(flxDnsPacket *p, gpointer ret_data, guint l) {
265 if (p->rindex + l > p->size)
268 memcpy(ret_data, p->data + p->rindex, l);
274 gconstpointer flx_dns_packet_get_rptr(flxDnsPacket *p) {
277 if (p->rindex >= p->size)
280 return p->data + p->rindex;
283 gint flx_dns_packet_skip(flxDnsPacket *p, guint length) {
286 if (p->rindex + length > p->size)
293 flxRecord* flx_dns_packet_consume_record(flxDnsPacket *p, gboolean *ret_cache_flush) {
301 g_assert(ret_cache_flush);
303 if (flx_dns_packet_consume_name(p, name, sizeof(name)) < 0 ||
304 flx_dns_packet_consume_uint16(p, &type) < 0 ||
305 flx_dns_packet_consume_uint16(p, &class) < 0 ||
306 flx_dns_packet_consume_uint32(p, &ttl) < 0 ||
307 flx_dns_packet_consume_uint16(p, &rdlength) < 0 ||
308 !(data = flx_dns_packet_get_rptr(p)) ||
309 flx_dns_packet_skip(p, rdlength) < 0)
312 *ret_cache_flush = !!(class & MDNS_CACHE_FLUSH);
313 class &= ~ MDNS_CACHE_FLUSH;
315 return flx_record_new_full(name, class, type, data, rdlength, ttl);
318 flxKey* flx_dns_packet_consume_key(flxDnsPacket *p) {
324 if (flx_dns_packet_consume_name(p, name, sizeof(name)) < 0 ||
325 flx_dns_packet_consume_uint16(p, &type) < 0 ||
326 flx_dns_packet_consume_uint16(p, &class) < 0)
329 class &= ~ MDNS_CACHE_FLUSH;
331 return flx_key_new(name, class, type);
334 guint8* flx_dns_packet_append_key(flxDnsPacket *p, flxKey *k) {
340 if (!(t = flx_dns_packet_append_name(p, k->name)) ||
341 !flx_dns_packet_append_uint16(p, k->type) ||
342 !flx_dns_packet_append_uint16(p, k->class))
348 guint8* flx_dns_packet_append_record(flxDnsPacket *p, flxRecord *r, gboolean cache_flush) {
354 if (!(t = flx_dns_packet_append_name(p, r->key->name)) ||
355 !flx_dns_packet_append_uint16(p, r->key->type) ||
356 !flx_dns_packet_append_uint16(p, cache_flush ? (r->key->class | MDNS_CACHE_FLUSH) : (r->key->class &~ MDNS_CACHE_FLUSH)) ||
357 !flx_dns_packet_append_uint32(p, r->ttl) ||
358 !flx_dns_packet_append_uint16(p, r->size) ||
359 !flx_dns_packet_append_bytes(p, r->data, r->size))