source: mainline/uspace/srv/net/dnsres/dns_msg.c@ 141a20d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 141a20d was 08a6382, checked in by Jiri Svoboda <jiri@…>, 13 years ago

Fixes to get DNS query acceptable by looking at analyzer output. Fix assertion failure in UDP.

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*
2 * Copyright (c) 2012 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup dnsres
30 * @{
31 */
32/**
33 * @file
34 */
35
36#include <bitops.h>
37#include <byteorder.h>
38#include <errno.h>
39#include <stdint.h>
40#include <stdlib.h>
41#include <str.h>
42
43#include "dns_msg.h"
44#include "dns_std.h"
45
46#define NAME "dnsres"
47
48#include <stdio.h>
49static int dns_name_encode(char *name, uint8_t *buf, size_t buf_size,
50 size_t *act_size)
51{
52 size_t off;
53 wchar_t c;
54 size_t lsize;
55 size_t pi, di;
56
57 pi = 0;
58 di = 1;
59 off = 0;
60
61 printf("dns_name_encode(name='%s', buf=%p, buf_size=%zu, act_size=%p\n",
62 name, buf, buf_size, act_size);
63 lsize = 0;
64 while (true) {
65 printf("off=%zu\n", off);
66 c = str_decode(name, &off, STR_NO_LIMIT);
67 printf("c=%d\n", (int)c);
68 if (c > 127) {
69 /* Non-ASCII character */
70 printf("non-ascii character\n");
71 return EINVAL;
72 }
73
74 if (c == '.' || c == '\0') {
75 /* Empty string, starting with period or two consecutive periods. */
76 if (lsize == 0) {
77 printf("empty token\n");
78 return EINVAL;
79 }
80
81 if (lsize > DNS_LABEL_MAX_SIZE) {
82 /* Label too long */
83 printf("label too long\n");
84 return EINVAL;
85 }
86
87 if (buf != NULL && pi < buf_size)
88 buf[pi] = (uint8_t)lsize;
89
90 lsize = 0;
91 pi = di;
92 ++di;
93
94 if (c == '\0')
95 break;
96 } else {
97 if (buf != NULL && di < buf_size)
98 buf[di] = c;
99 ++di;
100 ++lsize;
101 }
102 }
103
104 if (buf != NULL && pi < buf_size)
105 buf[pi] = 0;
106
107 *act_size = di;
108 return EOK;
109}
110
111static void dns_uint16_t_encode(uint16_t w, uint8_t *buf, size_t buf_size)
112{
113 if (buf != NULL && buf_size >= 1)
114 buf[0] = w >> 8;
115
116 if (buf != NULL && buf_size >= 2)
117 buf[1] = w & 0xff;
118}
119
120static int dns_question_encode(dns_question_t *question, uint8_t *buf,
121 size_t buf_size, size_t *act_size)
122{
123 size_t name_size;
124 size_t di;
125 int rc;
126
127 rc = dns_name_encode(question->qname, buf, buf_size, &name_size);
128 if (rc != EOK)
129 return rc;
130
131 printf("name_size=%zu\n", name_size);
132
133 *act_size = name_size + sizeof(uint16_t) + sizeof(uint16_t);
134 printf("act_size=%zu\n", *act_size);
135 if (buf == NULL)
136 return EOK;
137
138 di = name_size;
139
140 dns_uint16_t_encode(question->qtype, buf + di, buf_size - di);
141 di += sizeof(uint16_t);
142
143 dns_uint16_t_encode(question->qclass, buf + di, buf_size - di);
144 di += sizeof(uint16_t);
145
146 return EOK;
147}
148
149int dns_message_encode(dns_message_t *msg, void **rdata, size_t *rsize)
150{
151 uint8_t *data;
152 size_t size;
153 dns_header_t hdr;
154 size_t q_size;
155 size_t di;
156 int rc;
157
158 hdr.id = host2uint16_t_be(msg->id);
159
160 hdr.opbits = host2uint16_t_be(
161 (msg->qr << OPB_QR) |
162 (msg->opcode << OPB_OPCODE_l) |
163 (msg->aa ? BIT_V(uint16_t, OPB_AA) : 0) |
164 (msg->tc ? BIT_V(uint16_t, OPB_TC) : 0) |
165 (msg->rd ? BIT_V(uint16_t, OPB_RD) : 0) |
166 (msg->ra ? BIT_V(uint16_t, OPB_RA) : 0) |
167 msg->rcode
168 );
169
170 hdr.qd_count = host2uint16_t_be(list_count(&msg->question));
171 hdr.an_count = 0;
172 hdr.ns_count = 0;
173 hdr.ar_count = 0;
174
175 size = sizeof(dns_header_t);
176 printf("dns header size=%zu\n", size);
177
178 list_foreach(msg->question, link) {
179 dns_question_t *q = list_get_instance(link, dns_question_t, msg);
180 rc = dns_question_encode(q, NULL, 0, &q_size);
181 if (rc != EOK)
182 return rc;
183
184 printf("q_size=%zu\n", q_size);
185 size += q_size;
186 }
187
188 data = calloc(1, size);
189 if (data == NULL)
190 return ENOMEM;
191
192 memcpy(data, &hdr, sizeof(dns_header_t));
193 di = sizeof(dns_header_t);
194
195 list_foreach(msg->question, link) {
196 dns_question_t *q = list_get_instance(link, dns_question_t, msg);
197 rc = dns_question_encode(q, data + di, size - di, &q_size);
198 assert(rc == EOK);
199
200 di += q_size;
201 }
202
203 printf("-> size=%zu, di=%zu\n", size, di);
204 *rdata = data;
205 *rsize = size;
206 return EOK;
207}
208
209/** @}
210 */
Note: See TracBrowser for help on using the repository browser.