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_check_valid_response(flxDnsPacket *p) {
130 if (flx_dns_packet_check_valid(p) < 0)
133 flags = flx_dns_packet_get_field(p, DNS_FIELD_FLAGS);
135 if (!(flags & DNS_FLAG_QR))
138 if (flx_dns_packet_get_field(p, DNS_FIELD_QDCOUNT) > 0)
144 static gint consume_labels(flxDnsPacket *p, guint index, gchar *ret_name, guint l) {
148 g_assert(p && ret_name && l);
153 if (index+1 > p->size)
169 } else if (n <= 63) {
170 /* Uncompressed label */
175 if (index + n > p->size)
178 if ((guint) n + 1 > l)
187 memcpy(ret_name, p->data + index, n);
194 } else if ((n & 0xC0) == 0xC0) {
195 /* Compressed label */
197 if (index+2 > p->size)
200 index = ((guint) (p->data[index] & ~0xC0)) << 8 | p->data[index+1];
211 gint flx_dns_packet_consume_name(flxDnsPacket *p, gchar *ret_name, guint l) {
214 if ((r = consume_labels(p, p->rindex, ret_name, l)) < 0)
221 gint flx_dns_packet_consume_uint16(flxDnsPacket *p, guint16 *ret_v) {
225 if (p->rindex + sizeof(guint16) > p->size)
228 *ret_v = g_ntohs(*((guint16*) (p->data + p->rindex)));
229 p->rindex += sizeof(guint16);
234 gint flx_dns_packet_consume_uint32(flxDnsPacket *p, guint32 *ret_v) {
238 if (p->rindex + sizeof(guint32) > p->size)
241 *ret_v = g_ntohl(*((guint32*) (p->data + p->rindex)));
242 p->rindex += sizeof(guint32);
247 gint flx_dns_packet_consume_bytes(flxDnsPacket *p, gpointer ret_data, guint l) {
252 if (p->rindex + l > p->size)
255 memcpy(ret_data, p->data + p->rindex, l);
261 gint flx_dns_packet_skip(flxDnsPacket *p, guint length) {
264 if (p->rindex + length > p->size)