diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-02-06 22:48:10 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-02-06 22:48:10 +0100 |
| commit | 5fb38491e3ef093fb9cf642f0f3da5f2ed051f33 (patch) | |
| tree | 3566bdff9b5ce23b1bd4531653a66cf112715dca | |
| parent | cb7edc26611f8df6b81ef4337206d5833ea98771 (diff) | |
| download | busybox-w32-5fb38491e3ef093fb9cf642f0f3da5f2ed051f33.tar.gz busybox-w32-5fb38491e3ef093fb9cf642f0f3da5f2ed051f33.tar.bz2 busybox-w32-5fb38491e3ef093fb9cf642f0f3da5f2ed051f33.zip | |
dnsd: fix one big-endian goof; add a TODO about RA bit
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | include/platform.h | 5 | ||||
| -rw-r--r-- | networking/dnsd.c | 39 |
2 files changed, 26 insertions, 18 deletions
diff --git a/include/platform.h b/include/platform.h index dcc61a77b..a134a9e42 100644 --- a/include/platform.h +++ b/include/platform.h | |||
| @@ -208,6 +208,7 @@ typedef uint32_t bb__aliased_uint32_t FIX_ALIASING; | |||
| 208 | # define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp)) | 208 | # define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp)) |
| 209 | # define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p)) | 209 | # define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p)) |
| 210 | # define move_from_unaligned32(v, u32p) ((v) = *(bb__aliased_uint32_t*)(u32p)) | 210 | # define move_from_unaligned32(v, u32p) ((v) = *(bb__aliased_uint32_t*)(u32p)) |
| 211 | # define move_to_unaligned16(u16p, v) (*(bb__aliased_uint16_t*)(u16p) = (v)) | ||
| 211 | # define move_to_unaligned32(u32p, v) (*(bb__aliased_uint32_t*)(u32p) = (v)) | 212 | # define move_to_unaligned32(u32p, v) (*(bb__aliased_uint32_t*)(u32p) = (v)) |
| 212 | /* #elif ... - add your favorite arch today! */ | 213 | /* #elif ... - add your favorite arch today! */ |
| 213 | #else | 214 | #else |
| @@ -215,6 +216,10 @@ typedef uint32_t bb__aliased_uint32_t FIX_ALIASING; | |||
| 215 | # define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int))) | 216 | # define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int))) |
| 216 | # define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2)) | 217 | # define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2)) |
| 217 | # define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4)) | 218 | # define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4)) |
| 219 | # define move_to_unaligned16(u16p, v) do { \ | ||
| 220 | uint16_t __t = (v); \ | ||
| 221 | memcpy((u16p), &__t, 4); \ | ||
| 222 | } while (0) | ||
| 218 | # define move_to_unaligned32(u32p, v) do { \ | 223 | # define move_to_unaligned32(u32p, v) do { \ |
| 219 | uint32_t __t = (v); \ | 224 | uint32_t __t = (v); \ |
| 220 | memcpy((u32p), &__t, 4); \ | 225 | memcpy((u32p), &__t, 4); \ |
diff --git a/networking/dnsd.c b/networking/dnsd.c index 56ede3fca..91d66edcc 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c | |||
| @@ -44,7 +44,7 @@ struct dns_head { | |||
| 44 | uint16_t nauth; | 44 | uint16_t nauth; |
| 45 | uint16_t nadd; | 45 | uint16_t nadd; |
| 46 | }; | 46 | }; |
| 47 | struct dns_prop { | 47 | struct type_and_class { |
| 48 | uint16_t type; | 48 | uint16_t type; |
| 49 | uint16_t class; | 49 | uint16_t class; |
| 50 | }; | 50 | }; |
| @@ -291,7 +291,7 @@ QCLASS a two octet code that specifies the class of the query. | |||
| 291 | (others are historic only) | 291 | (others are historic only) |
| 292 | 255 any class | 292 | 255 any class |
| 293 | 293 | ||
| 294 | 4.1.3. Resource record format | 294 | 4.1.3. Resource Record format |
| 295 | 295 | ||
| 296 | The answer, authority, and additional sections all share the same format: | 296 | The answer, authority, and additional sections all share the same format: |
| 297 | a variable number of resource records, where the number of records | 297 | a variable number of resource records, where the number of records |
| @@ -353,14 +353,14 @@ static int process_packet(struct dns_entry *conf_data, | |||
| 353 | { | 353 | { |
| 354 | char *answstr; | 354 | char *answstr; |
| 355 | struct dns_head *head; | 355 | struct dns_head *head; |
| 356 | struct dns_prop *unaligned_qprop; | 356 | struct type_and_class *unaligned_type_class; |
| 357 | char *query_string; | 357 | char *query_string; |
| 358 | uint8_t *answb; | 358 | uint8_t *answb; |
| 359 | uint16_t outr_rlen; | 359 | uint16_t outr_rlen; |
| 360 | uint16_t outr_flags; | 360 | uint16_t outr_flags; |
| 361 | uint16_t type; | 361 | uint16_t type; |
| 362 | uint16_t class; | 362 | uint16_t class; |
| 363 | int querystr_len; | 363 | int query_len; |
| 364 | 364 | ||
| 365 | head = (struct dns_head *)buf; | 365 | head = (struct dns_head *)buf; |
| 366 | if (head->nquer == 0) { | 366 | if (head->nquer == 0) { |
| @@ -376,22 +376,22 @@ static int process_packet(struct dns_entry *conf_data, | |||
| 376 | /* start of query string */ | 376 | /* start of query string */ |
| 377 | query_string = (void *)(head + 1); | 377 | query_string = (void *)(head + 1); |
| 378 | /* caller guarantees strlen is <= MAX_PACK_LEN */ | 378 | /* caller guarantees strlen is <= MAX_PACK_LEN */ |
| 379 | querystr_len = strlen(query_string) + 1; | 379 | query_len = strlen(query_string) + 1; |
| 380 | /* may be unaligned! */ | 380 | /* may be unaligned! */ |
| 381 | unaligned_qprop = (void *)(query_string + querystr_len); | 381 | unaligned_type_class = (void *)(query_string + query_len); |
| 382 | querystr_len += sizeof(unaligned_qprop); | 382 | query_len += sizeof(unaligned_type_class); |
| 383 | /* where to append answer block */ | 383 | /* where to append answer block */ |
| 384 | answb = (void *)(unaligned_qprop + 1); | 384 | answb = (void *)(unaligned_type_class + 1); |
| 385 | 385 | ||
| 386 | /* QR = 1 "response", RCODE = 4 "Not Implemented" */ | 386 | /* QR = 1 "response", RCODE = 4 "Not Implemented" */ |
| 387 | outr_flags = htons(0x8000 | 4); | 387 | outr_flags = htons(0x8000 | 4); |
| 388 | 388 | ||
| 389 | move_from_unaligned16(type, &unaligned_qprop->type); | 389 | move_from_unaligned16(type, &unaligned_type_class->type); |
| 390 | if (type != htons(REQ_A) && type != htons(REQ_PTR)) { | 390 | if (type != htons(REQ_A) && type != htons(REQ_PTR)) { |
| 391 | /* we can't handle the query type */ | 391 | /* we can't handle the query type */ |
| 392 | goto empty_packet; | 392 | goto empty_packet; |
| 393 | } | 393 | } |
| 394 | move_from_unaligned16(class, &unaligned_qprop->class); | 394 | move_from_unaligned16(class, &unaligned_type_class->class); |
| 395 | if (class != htons(1)) { /* not class INET? */ | 395 | if (class != htons(1)) { /* not class INET? */ |
| 396 | goto empty_packet; | 396 | goto empty_packet; |
| 397 | } | 397 | } |
| @@ -408,11 +408,11 @@ static int process_packet(struct dns_entry *conf_data, | |||
| 408 | answstr = table_lookup(conf_data, type, query_string); | 408 | answstr = table_lookup(conf_data, type, query_string); |
| 409 | outr_rlen = 4; | 409 | outr_rlen = 4; |
| 410 | if (answstr && type == htons(REQ_PTR)) { | 410 | if (answstr && type == htons(REQ_PTR)) { |
| 411 | /* return a host name */ | 411 | /* returning a host name */ |
| 412 | outr_rlen = strlen(answstr) + 1; | 412 | outr_rlen = strlen(answstr) + 1; |
| 413 | } | 413 | } |
| 414 | if (!answstr | 414 | if (!answstr |
| 415 | || (unsigned)(answb - buf) + querystr_len + 4 + 2 + outr_rlen > MAX_PACK_LEN | 415 | || (unsigned)(answb - buf) + query_len + 4 + 2 + outr_rlen > MAX_PACK_LEN |
| 416 | ) { | 416 | ) { |
| 417 | /* QR = 1 "response" | 417 | /* QR = 1 "response" |
| 418 | * AA = 1 "Authoritative Answer" | 418 | * AA = 1 "Authoritative Answer" |
| @@ -421,20 +421,23 @@ static int process_packet(struct dns_entry *conf_data, | |||
| 421 | goto empty_packet; | 421 | goto empty_packet; |
| 422 | } | 422 | } |
| 423 | 423 | ||
| 424 | /* copy query block to answer block */ | 424 | /* Append answer Resource Record */ |
| 425 | memcpy(answb, query_string, querystr_len); | 425 | memcpy(answb, query_string, query_len); /* name, type, class */ |
| 426 | answb += querystr_len; | 426 | answb += query_len; |
| 427 | /* append answer Resource Record */ | ||
| 428 | move_to_unaligned32((uint32_t *)answb, htonl(conf_ttl)); | 427 | move_to_unaligned32((uint32_t *)answb, htonl(conf_ttl)); |
| 429 | answb += 4; | 428 | answb += 4; |
| 430 | move_to_unaligned32((uint16_t *)answb, htons(outr_rlen)); | 429 | move_to_unaligned16((uint16_t *)answb, htons(outr_rlen)); |
| 431 | answb += 2; | 430 | answb += 2; |
| 432 | memcpy(answb, answstr, outr_rlen); | 431 | memcpy(answb, answstr, outr_rlen); |
| 433 | answb += outr_rlen; | 432 | answb += outr_rlen; |
| 434 | 433 | ||
| 435 | /* QR = 1 "response", | 434 | /* QR = 1 "response", |
| 436 | * AA = 1 "Authoritative Answer", | 435 | * AA = 1 "Authoritative Answer", |
| 437 | * RCODE = 0 "success" */ | 436 | * TODO: need to set RA bit 0x80? One user says nslookup complains |
| 437 | * "Got recursion not available from SERVER, trying next server" | ||
| 438 | * "** server can't find HOSTNAME" | ||
| 439 | * RCODE = 0 "success" | ||
| 440 | */ | ||
| 438 | outr_flags = htons(0x8000 | 0x0400 | 0); | 441 | outr_flags = htons(0x8000 | 0x0400 | 0); |
| 439 | /* we have one answer */ | 442 | /* we have one answer */ |
| 440 | head->nansw = htons(1); | 443 | head->nansw = htons(1); |
