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_extend(flxDnsPacket *p, guint l) {
85 g_assert(p->size+l <= sizeof(p->data));
87 d = p->data + p->size;
93 guint8 *flx_dns_packet_append_name_compressed(flxDnsPacket *p, const gchar *name, guint8 *prev) {
99 return flx_dns_packet_append_name(p, name);
102 if (k < 0 || k >= 0x4000 || (guint) k >= p->size)
103 return flx_dns_packet_append_name(p, name);
105 d = (guint16*) flx_dns_packet_extend(p, sizeof(guint16));
106 *d = g_htons((0xC000 | k));
111 gint flx_dns_packet_check_valid(flxDnsPacket *p) {
118 flags = flx_dns_packet_get_field(p, DNS_FIELD_FLAGS);
120 if (flags & DNS_FLAG_OPCODE || flags & DNS_FLAG_RCODE)
126 gint flx_dns_packet_is_query(flxDnsPacket *p) {
129 return !(flx_dns_packet_get_field(p, DNS_FIELD_FLAGS) & DNS_FLAG_QR);
132 static gint consume_labels(flxDnsPacket *p, guint index, gchar *ret_name, guint l) {
136 g_assert(p && ret_name && l);
141 if (index+1 > p->size)
157 } else if (n <= 63) {
158 /* Uncompressed label */
163 if (index + n > p->size)
166 if ((guint) n + 1 > l)
175 memcpy(ret_name, p->data + index, n);
182 } else if ((n & 0xC0) == 0xC0) {
183 /* Compressed label */
185 if (index+2 > p->size)
188 index = ((guint) (p->data[index] & ~0xC0)) << 8 | p->data[index+1];
199 gint flx_dns_packet_consume_name(flxDnsPacket *p, gchar *ret_name, guint l) {
202 if ((r = consume_labels(p, p->rindex, ret_name, l)) < 0)
209 gint flx_dns_packet_consume_uint16(flxDnsPacket *p, guint16 *ret_v) {
213 if (p->rindex + sizeof(guint16) > p->size)
216 *ret_v = g_ntohs(*((guint16*) (p->data + p->rindex)));
217 p->rindex += sizeof(guint16);
222 gint flx_dns_packet_consume_uint32(flxDnsPacket *p, guint32 *ret_v) {
226 if (p->rindex + sizeof(guint32) > p->size)
229 *ret_v = g_ntohl(*((guint32*) (p->data + p->rindex)));
230 p->rindex += sizeof(guint32);
235 gint flx_dns_packet_consume_bytes(flxDnsPacket *p, gpointer ret_data, guint l) {
240 if (p->rindex + l > p->size)
243 memcpy(ret_data, p->data + p->rindex, l);
249 gconstpointer flx_dns_packet_get_rptr(flxDnsPacket *p) {
252 if (p->rindex >= p->size)
255 return p->data + p->rindex;
258 gint flx_dns_packet_skip(flxDnsPacket *p, guint length) {
261 if (p->rindex + length > p->size)
268 flxRecord* flx_dns_packet_consume_record(flxDnsPacket *p, gboolean *ret_cache_flush) {
276 g_assert(ret_cache_flush);
278 if (flx_dns_packet_consume_name(p, name, sizeof(name)) < 0 ||
279 flx_dns_packet_consume_uint16(p, &type) < 0 ||
280 flx_dns_packet_consume_uint16(p, &class) < 0 ||
281 flx_dns_packet_consume_uint32(p, &ttl) < 0 ||
282 flx_dns_packet_consume_uint16(p, &rdlength) < 0 ||
283 !(data = flx_dns_packet_get_rptr(p)) ||
284 flx_dns_packet_skip(p, rdlength) < 0)
287 *ret_cache_flush = !!(class & MDNS_CACHE_FLUSH);
288 class &= ~ MDNS_CACHE_FLUSH;
290 return flx_record_new_full(name, class, type, data, rdlength, ttl);
293 flxKey* flx_dns_packet_consume_key(flxDnsPacket *p) {
299 if (flx_dns_packet_consume_name(p, name, sizeof(name)) < 0 ||
300 flx_dns_packet_consume_uint16(p, &type) < 0 ||
301 flx_dns_packet_consume_uint16(p, &class) < 0)
304 class &= ~ MDNS_CACHE_FLUSH;
306 return flx_key_new(name, class, type);
309 guint8* flx_dns_packet_append_key(flxDnsPacket *p, flxKey *k) {
315 if (!(t = flx_dns_packet_append_name(p, k->name)) ||
316 !flx_dns_packet_append_uint16(p, k->type) ||
317 !flx_dns_packet_append_uint16(p, k->class))
323 guint8* flx_dns_packet_append_record(flxDnsPacket *p, flxRecord *r, gboolean cache_flush) {