Changeset 0041cd6d in mainline
- Timestamp:
- 2013-04-20T09:03:34Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9d8bd3ac
- Parents:
- ccb5165
- Location:
- uspace/srv/net/dnsres
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/dnsres/dns_msg.c
rccb5165 r0041cd6d 37 37 #include <byteorder.h> 38 38 #include <errno.h> 39 #include <macros.h> 39 40 #include <stdint.h> 40 41 #include <stdlib.h> … … 109 110 } 110 111 112 static int dns_name_decode(uint8_t *buf, size_t size, char **rname, 113 size_t *act_size) 114 { 115 uint8_t *bp; 116 size_t bsize; 117 size_t lsize; 118 size_t i; 119 120 bp = buf; 121 bsize = min(size, DNS_NAME_MAX_SIZE); 122 123 while (true) { 124 if (bsize == 0) { 125 return EINVAL; 126 } 127 128 129 lsize = *bp; 130 ++bp; 131 --bsize; 132 133 if (lsize == 0) 134 break; 135 136 if (bp != buf + 1) 137 printf("."); 138 139 if ((lsize & 0xc0) == 0xc0) { 140 /* Pointer */ 141 printf("compression not supported!\n"); 142 return EINVAL; 143 } 144 145 if (lsize > bsize) { 146 return EINVAL; 147 } 148 149 for (i = 0; i < lsize; i++) { 150 printf("%c", *bp); 151 ++bp; 152 --bsize; 153 } 154 } 155 156 printf("\n"); 157 158 *act_size = bp - buf; 159 return EOK; 160 } 161 162 /** Decode unaligned big-endian 16-bit integer */ 163 static uint16_t dns_uint16_t_decode(uint8_t *buf, size_t buf_size) 164 { 165 assert(buf_size >= 2); 166 167 return ((uint16_t)buf[0] << 8) + buf[1]; 168 } 169 170 /** Encode unaligned big-endian 16-bit integer */ 111 171 static void dns_uint16_t_encode(uint16_t w, uint8_t *buf, size_t buf_size) 112 172 { … … 116 176 if (buf != NULL && buf_size >= 2) 117 177 buf[1] = w & 0xff; 178 } 179 180 /** Decode unaligned big-endian 32-bit integer */ 181 static uint16_t dns_uint32_t_decode(uint8_t *buf, size_t buf_size) 182 { 183 assert(buf_size >= 4); 184 185 return ((uint32_t)buf[0] << 24) + 186 ((uint32_t)buf[1] << 16) + 187 ((uint32_t)buf[2] << 8) + 188 buf[0]; 118 189 } 119 190 … … 144 215 di += sizeof(uint16_t); 145 216 217 return EOK; 218 } 219 220 static int dns_question_decode(uint8_t *buf, size_t buf_size, 221 dns_question_t **rquestion, size_t *act_size) 222 { 223 dns_question_t *question; 224 size_t name_size; 225 int rc; 226 227 question = calloc(1, sizeof (dns_question_t)); 228 if (question == NULL) 229 return ENOMEM; 230 231 printf("decode name..\n"); 232 rc = dns_name_decode(buf, buf_size, &question->qname, &name_size); 233 if (rc != EOK) { 234 printf("error decoding name..\n"); 235 free(question); 236 return ENOMEM; 237 } 238 239 printf("ok decoding name..\n"); 240 if (name_size + 2 * sizeof(uint16_t) > buf_size) { 241 printf("name_size + 2 * 2 = %d > buf_size = %d\n", 242 name_size + 2 * sizeof(uint16_t), buf_size); 243 free(question); 244 return EINVAL; 245 } 246 247 question->qtype = dns_uint16_t_decode(buf + name_size, buf_size - name_size); 248 question->qclass = dns_uint16_t_decode(buf + sizeof(uint16_t) + name_size, 249 buf_size - sizeof(uint16_t) - name_size); 250 *act_size = name_size + 2 * sizeof(uint16_t); 251 252 *rquestion = question; 253 return EOK; 254 } 255 256 static int dns_rr_decode(uint8_t *buf, size_t buf_size, 257 dns_rr_t **retrr, size_t *act_size) 258 { 259 dns_rr_t *rr; 260 size_t name_size; 261 uint8_t *bp; 262 size_t bsz; 263 size_t rdlength; 264 int rc; 265 266 rr = calloc(1, sizeof (dns_rr_t)); 267 if (rr == NULL) 268 return ENOMEM; 269 270 printf("decode name..\n"); 271 rc = dns_name_decode(buf, buf_size, &rr->name, &name_size); 272 if (rc != EOK) { 273 printf("error decoding name..\n"); 274 free(rr); 275 return ENOMEM; 276 } 277 278 printf("ok decoding name..\n"); 279 if (name_size + 2 * sizeof(uint16_t) > buf_size) { 280 printf("name_size + 2 * 2 = %d > buf_size = %d\n", 281 name_size + 2 * sizeof(uint16_t), buf_size); 282 free(rr->name); 283 free(rr); 284 return EINVAL; 285 } 286 287 bp = buf + name_size; 288 bsz = buf_size - name_size; 289 290 if (bsz < 3 * sizeof(uint16_t) + sizeof(uint32_t)) { 291 free(rr->name); 292 free(rr); 293 return EINVAL; 294 } 295 296 rr->rtype = dns_uint16_t_decode(bp, bsz); 297 bp += sizeof(uint16_t); bsz -= sizeof(uint16_t); 298 299 rr->rclass = dns_uint16_t_decode(bp, bsz); 300 bp += sizeof(uint16_t); bsz -= sizeof(uint16_t); 301 302 rr->ttl = dns_uint32_t_decode(bp, bsz); 303 bp += sizeof(uint32_t); bsz -= sizeof(uint32_t); 304 305 rdlength = dns_uint16_t_decode(bp, bsz); 306 bp += sizeof(uint16_t); bsz -= sizeof(uint16_t); 307 308 if (rdlength > bsz) { 309 free(rr->name); 310 free(rr); 311 return EINVAL; 312 } 313 314 rr->rdata_size = rdlength; 315 rr->rdata = calloc(1, sizeof(rdlength)); 316 if (rr->rdata == NULL) { 317 free(rr->name); 318 free(rr); 319 return ENOMEM; 320 } 321 322 memcpy(rr->rdata, bp, rdlength); 323 bp += rdlength; 324 bsz -= rdlength; 325 326 *act_size = bp - buf; 327 *retrr = rr; 146 328 return EOK; 147 329 } … … 207 389 } 208 390 391 int dns_message_decode(void *data, size_t size, dns_message_t **rmsg) 392 { 393 dns_message_t *msg; 394 dns_header_t *hdr; 395 uint8_t *dp; 396 size_t dsize; 397 size_t field_size; 398 dns_question_t *question; 399 dns_rr_t *rr; 400 size_t qd_count; 401 size_t an_count; 402 size_t i; 403 int rc; 404 405 msg = calloc(1, sizeof(dns_message_t)); 406 if (msg == NULL) 407 return ENOMEM; 408 409 if (size < sizeof(dns_header_t)) 410 return EINVAL; 411 412 hdr = data; 413 414 msg->id = uint16_t_be2host(hdr->id); 415 msg->qr = BIT_RANGE_EXTRACT(uint16_t, OPB_QR, OPB_QR, hdr->opbits); 416 msg->opcode = BIT_RANGE_EXTRACT(uint16_t, OPB_OPCODE_h, OPB_OPCODE_l, 417 hdr->opbits); 418 msg->aa = BIT_RANGE_EXTRACT(uint16_t, OPB_AA, OPB_AA, hdr->opbits); 419 msg->tc = BIT_RANGE_EXTRACT(uint16_t, OPB_TC, OPB_TC, hdr->opbits); 420 msg->rd = BIT_RANGE_EXTRACT(uint16_t, OPB_RD, OPB_RD, hdr->opbits); 421 msg->ra = BIT_RANGE_EXTRACT(uint16_t, OPB_RA, OPB_RA, hdr->opbits); 422 msg->rcode = BIT_RANGE_EXTRACT(uint16_t, OPB_RCODE_h, OPB_RCODE_l, 423 hdr->opbits); 424 425 list_initialize(&msg->question); 426 list_initialize(&msg->answer); 427 list_initialize(&msg->authority); 428 list_initialize(&msg->additional); 429 430 dp = (uint8_t *)data + sizeof(dns_header_t); 431 dsize = size - sizeof(dns_header_t); 432 433 qd_count = uint16_t_be2host(hdr->qd_count); 434 printf("qd_count = %d\n", (int)qd_count); 435 436 for (i = 0; i < qd_count; i++) { 437 printf("decode question..\n"); 438 rc = dns_question_decode(dp, dsize, &question, &field_size); 439 if (rc != EOK) { 440 printf("error decoding question\n"); 441 goto error; 442 } 443 printf("ok decoding question\n"); 444 445 dp += field_size; 446 dsize -= field_size; 447 } 448 449 an_count = uint16_t_be2host(hdr->an_count); 450 printf("an_count = %d\n", an_count); 451 452 for (i = 0; i < an_count; i++) { 453 printf("decode answer..\n"); 454 rc = dns_rr_decode(dp, dsize, &rr, &field_size); 455 if (rc != EOK) { 456 printf("error decoding answer\n"); 457 goto error; 458 } 459 printf("ok decoding answer\n"); 460 461 dp += field_size; 462 dsize -= field_size; 463 } 464 465 printf("ns_count = %d\n", uint16_t_be2host(hdr->ns_count)); 466 printf("ar_count = %d\n", uint16_t_be2host(hdr->ar_count)); 467 468 *rmsg = msg; 469 return EOK; 470 error: 471 /* XXX Destroy message */ 472 return rc; 473 } 474 209 475 /** @} 210 476 */ -
uspace/srv/net/dnsres/dns_msg.h
rccb5165 r0041cd6d 44 44 45 45 extern int dns_message_encode(dns_message_t *, void **, size_t *); 46 extern int dns_message_decode(void *, size_t, dns_message_t **); 46 47 47 48 #endif -
uspace/srv/net/dnsres/transport.c
rccb5165 r0041cd6d 60 60 struct sockaddr_in src_addr; 61 61 socklen_t src_addr_size; 62 size_t recv_size; 62 63 int fd; 64 int i; 63 65 64 66 addr.sin_family = AF_INET; … … 101 103 } 102 104 103 printf("received %d bytes\n", (int)rc); 105 recv_size = (size_t)rc; 106 107 printf("received %d bytes\n", (int)recv_size); 108 for (i = 0; i < (int)recv_size; i++) { 109 if (recv_buf[i] >= 32 && recv_buf[i] < 127) 110 printf("%c", recv_buf[i]); 111 else 112 printf("?"); 113 } 114 printf("\n"); 104 115 105 116 printf("close socket\n"); … … 108 119 free(req_data); 109 120 110 resp = NULL; 121 rc = dns_message_decode(recv_buf, recv_size, &resp); 122 if (rc != EOK) 123 return EIO; 124 111 125 *rresp = resp; 112 126 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.