📄 nsupdate.c
字号:
static voidmaybeshutdown(void) { ddebug("Shutting down request manager"); dns_requestmgr_shutdown(requestmgr); if (requests != 0) return; doshutdown();}static voidshutdown_program(isc_task_t *task, isc_event_t *event) { REQUIRE(task == global_task); UNUSED(task); ddebug("shutdown_program()"); isc_event_free(&event); shuttingdown = ISC_TRUE; maybeshutdown();}static voidsetup_system(void) { isc_result_t result; isc_sockaddr_t bind_any, bind_any6; lwres_result_t lwresult; unsigned int attrs, attrmask; int i; ddebug("setup_system()"); dns_result_register(); result = isc_net_probeipv4(); if (result == ISC_R_SUCCESS) have_ipv4 = ISC_TRUE; result = isc_net_probeipv6(); if (result == ISC_R_SUCCESS) have_ipv6 = ISC_TRUE; if (!have_ipv4 && !have_ipv6) fatal("could not find either IPv4 or IPv6"); result = isc_mem_create(0, 0, &mctx); check_result(result, "isc_mem_create"); lwresult = lwres_context_create(&lwctx, mctx, mem_alloc, mem_free, 1); if (lwresult != LWRES_R_SUCCESS) fatal("lwres_context_create failed"); (void)lwres_conf_parse(lwctx, RESOLV_CONF); lwconf = lwres_conf_get(lwctx); ns_total = lwconf->nsnext; if (ns_total <= 0) { /* No name servers in resolv.conf; default to loopback. */ struct in_addr localhost; ns_total = 1; servers = isc_mem_get(mctx, ns_total * sizeof(isc_sockaddr_t)); if (servers == NULL) fatal("out of memory"); localhost.s_addr = htonl(INADDR_LOOPBACK); isc_sockaddr_fromin(&servers[0], &localhost, DNSDEFAULTPORT); } else { servers = isc_mem_get(mctx, ns_total * sizeof(isc_sockaddr_t)); if (servers == NULL) fatal("out of memory"); for (i = 0; i < ns_total; i++) { if (lwconf->nameservers[i].family == LWRES_ADDRTYPE_V4) { struct in_addr in4; memcpy(&in4, lwconf->nameservers[i].address, 4); isc_sockaddr_fromin(&servers[i], &in4, DNSDEFAULTPORT); } else { struct in6_addr in6; memcpy(&in6, lwconf->nameservers[i].address, 16); isc_sockaddr_fromin6(&servers[i], &in6, DNSDEFAULTPORT); } } } result = isc_entropy_create(mctx, &entp); check_result(result, "isc_entropy_create"); result = isc_hash_create(mctx, entp, DNS_NAME_MAXWIRE); check_result(result, "isc_hash_create"); isc_hash_init(); result = dns_dispatchmgr_create(mctx, entp, &dispatchmgr); check_result(result, "dns_dispatchmgr_create"); result = isc_socketmgr_create(mctx, &socketmgr); check_result(result, "dns_socketmgr_create"); result = isc_timermgr_create(mctx, &timermgr); check_result(result, "dns_timermgr_create"); result = isc_taskmgr_create(mctx, 1, 0, &taskmgr); check_result(result, "isc_taskmgr_create"); result = isc_task_create(taskmgr, 0, &global_task); check_result(result, "isc_task_create"); result = isc_task_onshutdown(global_task, shutdown_program, NULL); check_result(result, "isc_task_onshutdown"); result = dst_lib_init(mctx, entp, 0); check_result(result, "dst_lib_init"); is_dst_up = ISC_TRUE; attrmask = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP; attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; if (have_ipv6) { attrs = DNS_DISPATCHATTR_UDP; attrs |= DNS_DISPATCHATTR_MAKEQUERY; attrs |= DNS_DISPATCHATTR_IPV6; isc_sockaddr_any6(&bind_any6); result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &bind_any6, PACKETSIZE, 4, 2, 3, 5, attrs, attrmask, &dispatchv6); check_result(result, "dns_dispatch_getudp (v6)"); } if (have_ipv4) { attrs = DNS_DISPATCHATTR_UDP; attrs |= DNS_DISPATCHATTR_MAKEQUERY; attrs |= DNS_DISPATCHATTR_IPV4; isc_sockaddr_any(&bind_any); result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &bind_any, PACKETSIZE, 4, 2, 3, 5, attrs, attrmask, &dispatchv4); check_result(result, "dns_dispatch_getudp (v4)"); } result = dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr, dispatchmgr, dispatchv4, dispatchv6, &requestmgr); check_result(result, "dns_requestmgr_create"); if (keystr != NULL) setup_keystr(); else if (keyfile != NULL) setup_keyfile();}static voidget_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr) { int count; isc_result_t result; isc_app_block(); result = bind9_getaddresses(host, port, sockaddr, 1, &count); isc_app_unblock(); if (result != ISC_R_SUCCESS) fatal("couldn't get address for '%s': %s", host, isc_result_totext(result)); INSIST(count == 1);}static voidparse_args(int argc, char **argv) { int ch; isc_result_t result; debug("parse_args"); while ((ch = isc_commandline_parse(argc, argv, "dDMy:vk:r:t:u:")) != -1) { switch (ch) { case 'd': debugging = ISC_TRUE; break; case 'D': /* was -dd */ debugging = ISC_TRUE; ddebugging = ISC_TRUE; break; case 'M': /* was -dm */ debugging = ISC_TRUE; ddebugging = ISC_TRUE; memdebugging = ISC_TRUE; isc_mem_debugging = ISC_MEM_DEBUGTRACE | ISC_MEM_DEBUGRECORD; break; case 'y': keystr = isc_commandline_argument; break; case 'v': usevc = ISC_TRUE; break; case 'k': keyfile = isc_commandline_argument; break; case 't': result = isc_parse_uint32(&timeout, isc_commandline_argument, 10); if (result != ISC_R_SUCCESS) { fprintf(stderr, "bad timeout '%s'\n", isc_commandline_argument); exit(1); } if (timeout == 0) timeout = UINT_MAX; break; case 'u': result = isc_parse_uint32(&udp_timeout, isc_commandline_argument, 10); if (result != ISC_R_SUCCESS) { fprintf(stderr, "bad udp timeout '%s'\n", isc_commandline_argument); exit(1); } if (udp_timeout == 0) udp_timeout = UINT_MAX; break; case 'r': result = isc_parse_uint32(&udp_retries, isc_commandline_argument, 10); if (result != ISC_R_SUCCESS) { fprintf(stderr, "bad udp retries '%s'\n", isc_commandline_argument); exit(1); } break; default: fprintf(stderr, "%s: invalid argument -%c\n", argv[0], ch); fprintf(stderr, "usage: nsupdate [-d] " "[-y keyname:secret | -k keyfile] [-v] " "[filename]\n"); exit(1); } } if (keyfile != NULL && keystr != NULL) { fprintf(stderr, "%s: cannot specify both -k and -y\n", argv[0]); exit(1); } if (argv[isc_commandline_index] != NULL) { if (strcmp(argv[isc_commandline_index], "-") == 0) { input = stdin; } else { result = isc_stdio_open(argv[isc_commandline_index], "r", &input); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not open '%s': %s\n", argv[isc_commandline_index], isc_result_totext(result)); exit(1); } } interactive = ISC_FALSE; }}static isc_uint16_tparse_name(char **cmdlinep, dns_message_t *msg, dns_name_t **namep) { isc_result_t result; char *word; isc_buffer_t *namebuf = NULL; isc_buffer_t source; word = nsu_strsep(cmdlinep, " \t\r\n"); if (*word == 0) { fprintf(stderr, "could not read owner name\n"); return (STATUS_SYNTAX); } result = dns_message_gettempname(msg, namep); check_result(result, "dns_message_gettempname"); result = isc_buffer_allocate(mctx, &namebuf, DNS_NAME_MAXWIRE); check_result(result, "isc_buffer_allocate"); dns_name_init(*namep, NULL); dns_name_setbuffer(*namep, namebuf); dns_message_takebuffer(msg, &namebuf); isc_buffer_init(&source, word, strlen(word)); isc_buffer_add(&source, strlen(word)); result = dns_name_fromtext(*namep, &source, dns_rootname, ISC_FALSE, NULL); check_result(result, "dns_name_fromtext"); isc_buffer_invalidate(&source); return (STATUS_MORE);}static isc_uint16_tparse_rdata(char **cmdlinep, dns_rdataclass_t rdataclass, dns_rdatatype_t rdatatype, dns_message_t *msg, dns_rdata_t *rdata){ char *cmdline = *cmdlinep; isc_buffer_t source, *buf = NULL, *newbuf = NULL; isc_region_t r; isc_lex_t *lex = NULL; dns_rdatacallbacks_t callbacks; isc_result_t result; while (*cmdline != 0 && isspace((unsigned char)*cmdline)) cmdline++; if (*cmdline != 0) { dns_rdatacallbacks_init(&callbacks); result = isc_lex_create(mctx, strlen(cmdline), &lex); check_result(result, "isc_lex_create"); isc_buffer_init(&source, cmdline, strlen(cmdline)); isc_buffer_add(&source, strlen(cmdline)); result = isc_lex_openbuffer(lex, &source); check_result(result, "isc_lex_openbuffer"); result = isc_buffer_allocate(mctx, &buf, MAXWIRE); check_result(result, "isc_buffer_allocate"); result = dns_rdata_fromtext(rdata, rdataclass, rdatatype, lex, dns_rootname, 0, mctx, buf, &callbacks); isc_lex_destroy(&lex); if (result == ISC_R_SUCCESS) { isc_buffer_usedregion(buf, &r); result = isc_buffer_allocate(mctx, &newbuf, r.length); check_result(result, "isc_buffer_allocate"); isc_buffer_putmem(newbuf, r.base, r.length); isc_buffer_usedregion(newbuf, &r); dns_rdata_fromregion(rdata, rdataclass, rdatatype, &r); isc_buffer_free(&buf); dns_message_takebuffer(msg, &newbuf); } else { fprintf(stderr, "invalid rdata format: %s\n", isc_result_totext(result)); isc_buffer_free(&buf); return (STATUS_SYNTAX); } } else { rdata->flags = DNS_RDATA_UPDATE; } *cmdlinep = cmdline; return (STATUS_MORE);}static isc_uint16_tmake_prereq(char *cmdline, isc_boolean_t ispositive, isc_boolean_t isrrset) { isc_result_t result; char *word; dns_name_t *name = NULL; isc_textregion_t region; dns_rdataset_t *rdataset = NULL; dns_rdatalist_t *rdatalist = NULL; dns_rdataclass_t rdataclass; dns_rdatatype_t rdatatype; dns_rdata_t *rdata = NULL; isc_uint16_t retval; ddebug("make_prereq()"); /* * Read the owner name */ retval = parse_name(&cmdline, updatemsg, &name); if (retval != STATUS_MORE) return (retval); /* * If this is an rrset prereq, read the class or type. */ if (isrrset) { word = nsu_strsep(&cmdline, " \t\r\n"); if (*word == 0) { 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) { if (!setzoneclass(rdataclass)) { fprintf(stderr, "class mismatch: %s\n", word); goto failure; } /* * Now read the type. */ word = nsu_strsep(&cmdline, " \t\r\n"); if (*word == 0) { 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, "invalid type: %s\n", word); goto failure; } } else { rdataclass = getzoneclass(); result = dns_rdatatype_fromtext(&rdatatype, ®ion); if (result != ISC_R_SUCCESS) { fprintf(stderr, "invalid type: %s\n", word); goto failure; } } } else rdatatype = dns_rdatatype_any; result = dns_message_gettemprdata(updatemsg, &rdata); check_result(result, "dns_message_gettemprdata"); rdata->data = NULL; rdata->length = 0; if (isrrset && ispositive) { retval = parse_rdata(&cmdline, rdataclass, rdatatype, updatemsg, rdata); if (retval != STATUS_MORE) goto failure; } else rdata->flags = DNS_RDATA_UPDATE; 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; if (ispositive) { if (isrrset && rdata->data != NULL) rdatalist->rdclass = rdataclass; else rdatalist->rdclass = dns_rdataclass_any; } else rdatalist->rdclass = dns_rdataclass_none; rdatalist->covers = 0; rdatalist->ttl = 0; rdata->rdclass = rdatalist->rdclass; rdata->type = rdatatype; 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_PREREQUISITE); return (STATUS_MORE); failure: if (name != NULL) dns_message_puttempname(updatemsg, &name); return (STATUS_SYNTAX);}static isc_uint16_tevaluate_prereq(char *cmdline) { char *word; isc_boolean_t ispositive, isrrset; ddebug("evaluate_prereq()"); word = nsu_strsep(&cmdline, " \t\r\n"); if (*word == 0) { fprintf(stderr, "could not read operation code\n"); return (STATUS_SYNTAX); } if (strcasecmp(word, "nxdomain") == 0) { ispositive = ISC_FALSE; isrrset = ISC_FALSE; } else if (strcasecmp(word, "yxdomain") == 0) { ispositive = ISC_TRUE; isrrset = ISC_FALSE; } else if (strcasecmp(word, "nxrrset") == 0) { ispositive = ISC_FALSE; isrrset = ISC_TRUE; } else if (strcasecmp(word, "yxrrset") == 0) { ispositive = ISC_TRUE; isrrset = ISC_TRUE; } else { fprintf(stderr, "incorrect operation code: %s\n", word); return (STATUS_SYNTAX); } return (make_prereq(cmdline, ispositive, isrrset));}static isc_uint16_tevaluate_server(char *cmdline) { char *word, *server; long port; word = nsu_strsep(&cmdline, " \t\r\n"); if (*word == 0) { fprintf(stderr, "could not read server name\n"); 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 "
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -