diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-02-07 02:45:03 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-02-07 02:45:03 +0100 |
| commit | 343dfd7abe44a32b329379ec9039f2560543518d (patch) | |
| tree | 3c222f19d6a278397450d3d7c58f4f9580ec1be8 | |
| parent | e66a09ba9c167b210694cf940648757868a3f994 (diff) | |
| download | busybox-w32-343dfd7abe44a32b329379ec9039f2560543518d.tar.gz busybox-w32-343dfd7abe44a32b329379ec9039f2560543518d.tar.bz2 busybox-w32-343dfd7abe44a32b329379ec9039f2560543518d.zip | |
dnsd: add -s option. This allows (clumsy) operation with read dns servers
function old new delta
packed_usage 26816 26886 +70
dnsd_main 1299 1303 +4
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | include/usage.h | 7 | ||||
| -rw-r--r-- | networking/dnsd.c | 73 |
2 files changed, 45 insertions, 35 deletions
diff --git a/include/usage.h b/include/usage.h index 109a35d05..c2ffb6d6e 100644 --- a/include/usage.h +++ b/include/usage.h | |||
| @@ -893,7 +893,7 @@ | |||
| 893 | "\n -s SIZE Buffer size" \ | 893 | "\n -s SIZE Buffer size" \ |
| 894 | 894 | ||
| 895 | #define dnsd_trivial_usage \ | 895 | #define dnsd_trivial_usage \ |
| 896 | "[-c CONFFILE] [-t TTL_SEC] [-p PORT] [-i ADDR] [-d]" | 896 | "[-dvs] [-c CONFFILE] [-t TTL_SEC] [-p PORT] [-i ADDR]" |
| 897 | #define dnsd_full_usage "\n\n" \ | 897 | #define dnsd_full_usage "\n\n" \ |
| 898 | "Small static DNS server daemon\n" \ | 898 | "Small static DNS server daemon\n" \ |
| 899 | "\nOptions:" \ | 899 | "\nOptions:" \ |
| @@ -902,6 +902,11 @@ | |||
| 902 | "\n -p PORT Listen on PORT" \ | 902 | "\n -p PORT Listen on PORT" \ |
| 903 | "\n -i ADDR Listen on ADDR" \ | 903 | "\n -i ADDR Listen on ADDR" \ |
| 904 | "\n -d Daemonize" \ | 904 | "\n -d Daemonize" \ |
| 905 | "\n -v Verbose" \ | ||
| 906 | "\n -s Send successful replies only. Use this if you want" \ | ||
| 907 | "\n to use /etc/resolv.conf with two nameserver lines:" \ | ||
| 908 | "\n nameserver DNSD_SERVER" \ | ||
| 909 | "\n nameserver NORNAL_DNS_SERVER" \ | ||
| 905 | 910 | ||
| 906 | #define dos2unix_trivial_usage \ | 911 | #define dos2unix_trivial_usage \ |
| 907 | "[OPTIONS] [FILE]" | 912 | "[OPTIONS] [FILE]" |
diff --git a/networking/dnsd.c b/networking/dnsd.c index 42deb1f35..e73e244b0 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c | |||
| @@ -56,7 +56,8 @@ struct dns_entry { | |||
| 56 | char name[1]; | 56 | char name[1]; |
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | #define OPT_verbose (option_mask32) | 59 | #define OPT_verbose (option_mask32 & 1) |
| 60 | #define OPT_silent (option_mask32 & 2) | ||
| 60 | 61 | ||
| 61 | 62 | ||
| 62 | /* | 63 | /* |
| @@ -351,10 +352,11 @@ static int process_packet(struct dns_entry *conf_data, | |||
| 351 | uint32_t conf_ttl, | 352 | uint32_t conf_ttl, |
| 352 | uint8_t *buf) | 353 | uint8_t *buf) |
| 353 | { | 354 | { |
| 354 | char *answstr; | ||
| 355 | struct dns_head *head; | 355 | struct dns_head *head; |
| 356 | struct type_and_class *unaligned_type_class; | 356 | struct type_and_class *unaligned_type_class; |
| 357 | const char *err_msg; | ||
| 357 | char *query_string; | 358 | char *query_string; |
| 359 | char *answstr; | ||
| 358 | uint8_t *answb; | 360 | uint8_t *answb; |
| 359 | uint16_t outr_rlen; | 361 | uint16_t outr_rlen; |
| 360 | uint16_t outr_flags; | 362 | uint16_t outr_flags; |
| @@ -365,12 +367,19 @@ static int process_packet(struct dns_entry *conf_data, | |||
| 365 | head = (struct dns_head *)buf; | 367 | head = (struct dns_head *)buf; |
| 366 | if (head->nquer == 0) { | 368 | if (head->nquer == 0) { |
| 367 | bb_error_msg("packet has 0 queries, ignored"); | 369 | bb_error_msg("packet has 0 queries, ignored"); |
| 368 | return -1; | 370 | return 0; /* don't reply */ |
| 369 | } | 371 | } |
| 370 | |||
| 371 | if (head->flags & htons(0x8000)) { /* QR bit */ | 372 | if (head->flags & htons(0x8000)) { /* QR bit */ |
| 372 | bb_error_msg("response packet, ignored"); | 373 | bb_error_msg("response packet, ignored"); |
| 373 | return -1; | 374 | return 0; /* don't reply */ |
| 375 | } | ||
| 376 | /* QR = 1 "response", RCODE = 4 "Not Implemented" */ | ||
| 377 | outr_flags = htons(0x8000 | 4); | ||
| 378 | err_msg = NULL; | ||
| 379 | /* OPCODE != 0 "standard query" ? */ | ||
| 380 | if ((head->flags & htons(0x7800)) != 0) { | ||
| 381 | err_msg = "opcode != 0"; | ||
| 382 | goto empty_packet; | ||
| 374 | } | 383 | } |
| 375 | 384 | ||
| 376 | /* start of query string */ | 385 | /* start of query string */ |
| @@ -383,28 +392,16 @@ static int process_packet(struct dns_entry *conf_data, | |||
| 383 | /* where to append answer block */ | 392 | /* where to append answer block */ |
| 384 | answb = (void *)(unaligned_type_class + 1); | 393 | answb = (void *)(unaligned_type_class + 1); |
| 385 | 394 | ||
| 386 | /* QR = 1 "response", RCODE = 4 "Not Implemented" */ | ||
| 387 | outr_flags = htons(0x8000 | 4); | ||
| 388 | |||
| 389 | move_from_unaligned16(type, &unaligned_type_class->type); | ||
| 390 | if (type != htons(REQ_A) && type != htons(REQ_PTR)) { | ||
| 391 | /* we can't handle this query type */ | ||
| 392 | //TODO: handle REQ_AAAA (0x1c) requests | ||
| 393 | bb_error_msg("type %u is !REQ_A and !REQ_PTR%s", | ||
| 394 | (int)ntohs(type), | ||
| 395 | ", returning Not Implemented reply"); | ||
| 396 | goto empty_packet; | ||
| 397 | } | ||
| 398 | move_from_unaligned16(class, &unaligned_type_class->class); | 395 | move_from_unaligned16(class, &unaligned_type_class->class); |
| 399 | if (class != htons(1)) { /* not class INET? */ | 396 | if (class != htons(1)) { /* not class INET? */ |
| 400 | bb_error_msg("class != 1%s", | 397 | err_msg = "class != 1"; |
| 401 | ", returning Not Implemented reply"); | ||
| 402 | goto empty_packet; | 398 | goto empty_packet; |
| 403 | } | 399 | } |
| 404 | /* OPCODE != 0 "standard query" ? */ | 400 | move_from_unaligned16(type, &unaligned_type_class->type); |
| 405 | if ((head->flags & htons(0x7800)) != 0) { | 401 | if (type != htons(REQ_A) && type != htons(REQ_PTR)) { |
| 406 | bb_error_msg("opcode != 0%s", | 402 | /* we can't handle this query type */ |
| 407 | ", returning Not Implemented reply"); | 403 | //TODO: happens all the time with REQ_AAAA (0x1c) requests - implement those? |
| 404 | err_msg = "type is !REQ_A and !REQ_PTR"; | ||
| 408 | goto empty_packet; | 405 | goto empty_packet; |
| 409 | } | 406 | } |
| 410 | 407 | ||
| @@ -425,8 +422,7 @@ static int process_packet(struct dns_entry *conf_data, | |||
| 425 | /* QR = 1 "response" | 422 | /* QR = 1 "response" |
| 426 | * AA = 1 "Authoritative Answer" | 423 | * AA = 1 "Authoritative Answer" |
| 427 | * RCODE = 3 "Name Error" */ | 424 | * RCODE = 3 "Name Error" */ |
| 428 | if (OPT_verbose) | 425 | err_msg = "name is not found"; |
| 429 | bb_error_msg("returning Name Error reply"); | ||
| 430 | outr_flags = htons(0x8000 | 0x0400 | 3); | 426 | outr_flags = htons(0x8000 | 0x0400 | 3); |
| 431 | goto empty_packet; | 427 | goto empty_packet; |
| 432 | } | 428 | } |
| @@ -455,6 +451,16 @@ static int process_packet(struct dns_entry *conf_data, | |||
| 455 | head->nansw = htons(1); | 451 | head->nansw = htons(1); |
| 456 | 452 | ||
| 457 | empty_packet: | 453 | empty_packet: |
| 454 | if ((outr_flags & htons(0xf)) != 0) { /* not a positive response */ | ||
| 455 | if (OPT_verbose) { | ||
| 456 | bb_error_msg("%s, %s", | ||
| 457 | err_msg, | ||
| 458 | OPT_silent ? "dropping query" : "sending error reply" | ||
| 459 | ); | ||
| 460 | } | ||
| 461 | if (OPT_silent) | ||
| 462 | return 0; | ||
| 463 | } | ||
| 458 | head->flags |= outr_flags; | 464 | head->flags |= outr_flags; |
| 459 | head->nauth = head->nadd = 0; | 465 | head->nauth = head->nadd = 0; |
| 460 | head->nquer = htons(1); // why??? | 466 | head->nquer = htons(1); // why??? |
| @@ -476,21 +482,20 @@ int dnsd_main(int argc UNUSED_PARAM, char **argv) | |||
| 476 | uint16_t port = 53; | 482 | uint16_t port = 53; |
| 477 | uint8_t buf[MAX_PACK_LEN + 1]; | 483 | uint8_t buf[MAX_PACK_LEN + 1]; |
| 478 | 484 | ||
| 479 | opts = getopt32(argv, "vi:c:t:p:d", &listen_interface, &fileconf, &sttl, &sport); | 485 | opts = getopt32(argv, "vsi:c:t:p:d", &listen_interface, &fileconf, &sttl, &sport); |
| 480 | //if (opts & 0x1) // -v | 486 | //if (opts & (1 << 0)) // -v |
| 481 | //if (opts & 0x2) // -i | 487 | //if (opts & (1 << 1)) // -s |
| 482 | //if (opts & 0x4) // -c | 488 | //if (opts & (1 << 2)) // -i |
| 483 | if (opts & 0x8) // -t | 489 | //if (opts & (1 << 3)) // -c |
| 490 | if (opts & (1 << 4)) // -t | ||
| 484 | conf_ttl = xatou_range(sttl, 1, 0xffffffff); | 491 | conf_ttl = xatou_range(sttl, 1, 0xffffffff); |
| 485 | if (opts & 0x10) // -p | 492 | if (opts & (1 << 5)) // -p |
| 486 | port = xatou_range(sport, 1, 0xffff); | 493 | port = xatou_range(sport, 1, 0xffff); |
| 487 | if (opts & 0x20) { // -d | 494 | if (opts & (1 << 6)) { // -d |
| 488 | bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS, argv); | 495 | bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS, argv); |
| 489 | openlog(applet_name, LOG_PID, LOG_DAEMON); | 496 | openlog(applet_name, LOG_PID, LOG_DAEMON); |
| 490 | logmode = LOGMODE_SYSLOG; | 497 | logmode = LOGMODE_SYSLOG; |
| 491 | } | 498 | } |
| 492 | /* Clear all except "verbose" bit */ | ||
| 493 | option_mask32 &= 1; | ||
| 494 | 499 | ||
| 495 | conf_data = parse_conf_file(fileconf); | 500 | conf_data = parse_conf_file(fileconf); |
| 496 | 501 | ||
