📄 nsupdate.c
字号:
return (STATUS_SYNTAX); } server = word; word = nsu_strsep(&cmdline, " \t\r\n"); if (*word == 0) port = DNSDEFAULTPORT; else { char *endp; port = strtol(word, &endp, 10); if (*endp != 0) { fprintf(stderr, "port '%s' is not numeric\n", word); return (STATUS_SYNTAX); } else if (port < 1 || port > 65535) { fprintf(stderr, "port '%s' is out of range " "(1 to 65535)\n", word); return (STATUS_SYNTAX); } } if (userserver == NULL) { userserver = isc_mem_get(mctx, sizeof(isc_sockaddr_t)); if (userserver == NULL) fatal("out of memory"); } get_address(server, (in_port_t)port, userserver); return (STATUS_MORE);}static isc_uint16_tevaluate_local(char *cmdline) { char *word, *local; long port; struct in_addr in4; struct in6_addr in6; word = nsu_strsep(&cmdline, " \t\r\n"); if (*word == 0) { fprintf(stderr, "could not read server name\n"); return (STATUS_SYNTAX); } local = word; word = nsu_strsep(&cmdline, " \t\r\n"); if (*word == 0) port = 0; else { char *endp; port = strtol(word, &endp, 10); if (*endp != 0) { fprintf(stderr, "port '%s' is not numeric\n", word); return (STATUS_SYNTAX); } else if (port < 1 || port > 65535) { fprintf(stderr, "port '%s' is out of range " "(1 to 65535)\n", word); return (STATUS_SYNTAX); } } if (localaddr == NULL) { localaddr = isc_mem_get(mctx, sizeof(isc_sockaddr_t)); if (localaddr == NULL) fatal("out of memory"); } if (have_ipv6 && inet_pton(AF_INET6, local, &in6) == 1) isc_sockaddr_fromin6(localaddr, &in6, (in_port_t)port); else if (have_ipv4 && inet_pton(AF_INET, local, &in4) == 1) isc_sockaddr_fromin(localaddr, &in4, (in_port_t)port); else { fprintf(stderr, "invalid address %s", local); return (STATUS_SYNTAX); } return (STATUS_MORE);}static isc_uint16_tevaluate_key(char *cmdline) { char *namestr; char *secretstr; isc_buffer_t b; isc_result_t result; dns_fixedname_t fkeyname; dns_name_t *keyname; int secretlen; unsigned char *secret = NULL; isc_buffer_t secretbuf; namestr = nsu_strsep(&cmdline, " \t\r\n"); if (*namestr == 0) { fprintf(stderr, "could not read key name\n"); return (STATUS_SYNTAX); } dns_fixedname_init(&fkeyname); keyname = dns_fixedname_name(&fkeyname); isc_buffer_init(&b, namestr, strlen(namestr)); isc_buffer_add(&b, strlen(namestr)); result = dns_name_fromtext(keyname, &b, dns_rootname, ISC_FALSE, NULL); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not parse key name\n"); return (STATUS_SYNTAX); } secretstr = nsu_strsep(&cmdline, "\r\n"); if (*secretstr == 0) { fprintf(stderr, "could not read key secret\n"); return (STATUS_SYNTAX); } secretlen = strlen(secretstr) * 3 / 4; secret = isc_mem_allocate(mctx, secretlen); if (secret == NULL) fatal("out of memory"); isc_buffer_init(&secretbuf, secret, secretlen); result = isc_base64_decodestring(secretstr, &secretbuf); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not create key from %s: %s\n", secretstr, isc_result_totext(result)); isc_mem_free(mctx, secret); return (STATUS_SYNTAX); } secretlen = isc_buffer_usedlength(&secretbuf); if (key != NULL) dns_tsigkey_detach(&key); result = dns_tsigkey_create(keyname, dns_tsig_hmacmd5_name, secret, secretlen, ISC_TRUE, NULL, 0, 0, mctx, NULL, &key); isc_mem_free(mctx, secret); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not create key from %s %s: %s\n", namestr, secretstr, dns_result_totext(result)); return (STATUS_SYNTAX); } return (STATUS_MORE);}static isc_uint16_tevaluate_zone(char *cmdline) { char *word; isc_buffer_t b; isc_result_t result; word = nsu_strsep(&cmdline, " \t\r\n"); if (*word == 0) { fprintf(stderr, "could not read zone name\n"); return (STATUS_SYNTAX); } dns_fixedname_init(&fuserzone); userzone = dns_fixedname_name(&fuserzone); isc_buffer_init(&b, word, strlen(word)); isc_buffer_add(&b, strlen(word)); result = dns_name_fromtext(userzone, &b, dns_rootname, ISC_FALSE, NULL); if (result != ISC_R_SUCCESS) { userzone = NULL; /* Lest it point to an invalid name */ fprintf(stderr, "could not parse zone name\n"); return (STATUS_SYNTAX); } return (STATUS_MORE);}static isc_uint16_tupdate_addordelete(char *cmdline, isc_boolean_t isdelete) { isc_result_t result; dns_name_t *name = NULL; unsigned long ttl; char *word; dns_rdataclass_t rdataclass; dns_rdatatype_t rdatatype; dns_rdata_t *rdata = NULL; dns_rdatalist_t *rdatalist = NULL; dns_rdataset_t *rdataset = NULL; isc_textregion_t region; char *endp; isc_uint16_t retval; ddebug("update_addordelete()"); /* * Read the owner name. */ retval = parse_name(&cmdline, updatemsg, &name); if (retval != STATUS_MORE) return (retval); result = dns_message_gettemprdata(updatemsg, &rdata); check_result(result, "dns_message_gettemprdata"); rdata->rdclass = 0; rdata->type = 0; rdata->data = NULL; rdata->length = 0; /* * If this is an add, read the TTL and verify that it's in range. * If it's a delete, ignore a TTL if present (for compatibility). */ word = nsu_strsep(&cmdline, " \t\r\n"); if (*word == 0) { if (!isdelete) { fprintf(stderr, "could not read owner ttl\n"); goto failure; } else { ttl = 0; rdataclass = dns_rdataclass_any; rdatatype = dns_rdatatype_any; rdata->flags = DNS_RDATA_UPDATE; goto doneparsing; } } ttl = strtoul(word, &endp, 10); if (!isdigit((unsigned char)*word) || *endp != '\0') { if (isdelete) { ttl = 0; goto parseclass; } else { fprintf(stderr, "ttl '%s' is not legal\n", word); goto failure; } } if (isdelete) ttl = 0; else if (ttl > TTL_MAX) { fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n", word, TTL_MAX); goto failure; } /* * Read the class or type. */ word = nsu_strsep(&cmdline, " \t\r\n"); parseclass: if (*word == 0) { if (isdelete) { rdataclass = dns_rdataclass_any; rdatatype = dns_rdatatype_any; rdata->flags = DNS_RDATA_UPDATE; goto doneparsing; } else { fprintf(stderr, "could not read class or type\n"); goto failure; } } region.base = word; region.length = strlen(word); result = dns_rdataclass_fromtext(&rdataclass, ®ion); if (result == ISC_R_SUCCESS) { /* * Now read the type. */ word = nsu_strsep(&cmdline, " \t\r\n"); if (*word == 0) { if (isdelete) { rdataclass = dns_rdataclass_any; rdatatype = dns_rdatatype_any; rdata->flags = DNS_RDATA_UPDATE; goto doneparsing; } else { fprintf(stderr, "could not read type\n"); goto failure; } } region.base = word; region.length = strlen(word); result = dns_rdatatype_fromtext(&rdatatype, ®ion); if (result != ISC_R_SUCCESS) { fprintf(stderr, "'%s' is not a valid type: %s\n", word, isc_result_totext(result)); goto failure; } } else { rdataclass = dns_rdataclass_in; result = dns_rdatatype_fromtext(&rdatatype, ®ion); if (result != ISC_R_SUCCESS) { fprintf(stderr, "'%s' is not a valid class or type: " "%s\n", word, isc_result_totext(result)); goto failure; } } retval = parse_rdata(&cmdline, rdataclass, rdatatype, updatemsg, rdata); if (retval != STATUS_MORE) goto failure; if (isdelete) { if ((rdata->flags & DNS_RDATA_UPDATE) != 0) rdataclass = dns_rdataclass_any; else rdataclass = dns_rdataclass_none; } else { if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { fprintf(stderr, "could not read rdata\n"); goto failure; } } doneparsing: result = dns_message_gettemprdatalist(updatemsg, &rdatalist); check_result(result, "dns_message_gettemprdatalist"); result = dns_message_gettemprdataset(updatemsg, &rdataset); check_result(result, "dns_message_gettemprdataset"); dns_rdatalist_init(rdatalist); rdatalist->type = rdatatype; rdatalist->rdclass = rdataclass; rdatalist->covers = rdatatype; rdatalist->ttl = (dns_ttl_t)ttl; ISC_LIST_INIT(rdatalist->rdata); ISC_LIST_APPEND(rdatalist->rdata, rdata, link); dns_rdataset_init(rdataset); dns_rdatalist_tordataset(rdatalist, rdataset); ISC_LIST_INIT(name->list); ISC_LIST_APPEND(name->list, rdataset, link); dns_message_addname(updatemsg, name, DNS_SECTION_UPDATE); return (STATUS_MORE); failure: if (name != NULL) dns_message_puttempname(updatemsg, &name); if (rdata != NULL) dns_message_puttemprdata(updatemsg, &rdata); return (STATUS_SYNTAX);}static isc_uint16_tevaluate_update(char *cmdline) { char *word; isc_boolean_t isdelete; ddebug("evaluate_update()"); word = nsu_strsep(&cmdline, " \t\r\n"); if (*word == 0) { fprintf(stderr, "could not read operation code\n"); return (STATUS_SYNTAX); } if (strcasecmp(word, "delete") == 0) isdelete = ISC_TRUE; else if (strcasecmp(word, "add") == 0) isdelete = ISC_FALSE; else { fprintf(stderr, "incorrect operation code: %s\n", word); return (STATUS_SYNTAX); } return (update_addordelete(cmdline, isdelete));}static voidshow_message(dns_message_t *msg) { isc_result_t result; isc_buffer_t *buf = NULL; int bufsz; ddebug("show_message()"); bufsz = INITTEXT; do { if (bufsz > MAXTEXT) { fprintf(stderr, "could not allocate large enough " "buffer to display message\n"); exit(1); } if (buf != NULL) isc_buffer_free(&buf); result = isc_buffer_allocate(mctx, &buf, bufsz); check_result(result, "isc_buffer_allocate"); result = dns_message_totext(msg, style, 0, buf); bufsz *= 2; } while (result == ISC_R_NOSPACE); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not convert message to text format.\n"); isc_buffer_free(&buf); return; } printf("Outgoing update query:\n%.*s", (int)isc_buffer_usedlength(buf), (char*)isc_buffer_base(buf)); isc_buffer_free(&buf);}static isc_uint16_tget_next_command(void) { char cmdlinebuf[MAXCMD]; char *cmdline; char *word; ddebug("get_next_command()"); if (interactive) fprintf(stdout, "> "); isc_app_block(); cmdline = fgets(cmdlinebuf, MAXCMD, input); isc_app_unblock(); if (cmdline == NULL) return (STATUS_QUIT); word = nsu_strsep(&cmdline, " \t\r\n"); if (feof(input)) return (STATUS_QUIT); if (*word == 0) return (STATUS_SEND); if (word[0] == ';') return (STATUS_MORE); if (strcasecmp(word, "quit") == 0) return (STATUS_QUIT); if (strcasecmp(word, "prereq") == 0) return (evaluate_prereq(cmdline)); if (strcasecmp(word, "update") == 0) return (evaluate_update(cmdline)); if (strcasecmp(word, "server") == 0) return (evaluate_server(cmdline)); if (strcasecmp(word, "local") == 0) return (evaluate_local(cmdline)); if (strcasecmp(word, "zone") == 0) return (evaluate_zone(cmdline)); if (strcasecmp(word, "send") == 0) return (STATUS_SEND); if (strcasecmp(word, "show") == 0) { show_message(updatemsg); return (STATUS_MORE); } if (strcasecmp(word, "key") == 0) return (evaluate_key(cmdline)); fprintf(stderr, "incorrect section name: %s\n", word); return (STATUS_SYNTAX);}static isc_boolean_tuser_interaction(void) { isc_uint16_t result = STATUS_MORE; ddebug("user_interaction()"); while ((result == STATUS_MORE) || (result == STATUS_SYNTAX)) result = get_next_command(); if (result == STATUS_SEND) return (ISC_TRUE); return (ISC_FALSE);}static voiddone_update(void) { isc_event_t *event = global_event; ddebug("done_update()"); isc_task_send(global_task, &event);}static voidupdate_completed(isc_task_t *task, isc_event_t *event) { dns_requestevent_t *reqev = NULL; isc_result_t result; dns_message_t *rcvmsg = NULL; dns_request_t *request; UNUSED(task); ddebug("update_completed()"); requests--; REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); reqev = (dns_requestevent_t *)event; request = reqev->request;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -