예제 #1
0
int
main(int argc, char *argv[]) {
	int ch;
	struct addrinfo hints, *res;
	int gai_error;
	dns_client_t *client = NULL;
	char *zonenamestr = NULL;
	char *keyfilename = NULL;
	char *prereqstr = NULL;
	isc_sockaddrlist_t auth_servers;
	char *auth_server = NULL;
	char *recursive_server = NULL;
	isc_sockaddr_t sa_auth, sa_recursive;
	isc_sockaddrlist_t rec_servers;
	isc_result_t result;
	isc_boolean_t isdelete;
	isc_buffer_t b, *buf;
	dns_fixedname_t zname0, pname0, uname0;
	size_t namelen;
	dns_name_t *zname = NULL, *uname, *pname;
	dns_rdataset_t *rdataset;
	dns_rdatalist_t *rdatalist;
	dns_rdata_t *rdata;
	dns_namelist_t updatelist, prereqlist, *prereqlistp = NULL;
	isc_mem_t *umctx = NULL;

	while ((ch = getopt(argc, argv, "a:k:p:r:z:")) != -1) {
		switch (ch) {
		case 'k':
			keyfilename = optarg;
			break;
		case 'a':
			auth_server = optarg;
			break;
		case 'p':
			prereqstr = optarg;
			break;
		case 'r':
			recursive_server = optarg;
			break;
		case 'z':
			zonenamestr = optarg;
			break;
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;
	if (argc < 2)
		usage();

	/* command line argument validation */
	if (strcmp(argv[0], "delete") == 0)
		isdelete = ISC_TRUE;
	else if (strcmp(argv[0], "add") == 0)
		isdelete = ISC_FALSE;
	else {
		fprintf(stderr, "invalid update command: %s\n", argv[0]);
		exit(1);
	}

	if (auth_server == NULL && recursive_server == NULL) {
		fprintf(stderr, "authoritative or recursive server "
			"must be specified\n");
		usage();
	}

	/* Initialization */
	ISC_LIST_INIT(usedbuffers);
	ISC_LIST_INIT(usedrdatalists);
	ISC_LIST_INIT(prereqlist);
	ISC_LIST_INIT(auth_servers);
	isc_lib_register();
	result = dns_lib_init();
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "dns_lib_init failed: %d\n", result);
		exit(1);
	}
	result = isc_mem_create(0, 0, &umctx);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "failed to crate mctx\n");
		exit(1);
	}

	result = dns_client_create(&client, 0);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "dns_client_create failed: %d\n", result);
		exit(1);
	}

	/* Set the authoritative server */
	if (auth_server != NULL) {
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_DGRAM;
		hints.ai_protocol = IPPROTO_UDP;
		hints.ai_flags = AI_NUMERICHOST;
		gai_error = getaddrinfo(auth_server, "53", &hints, &res);
		if (gai_error != 0) {
			fprintf(stderr, "getaddrinfo failed: %s\n",
				gai_strerror(gai_error));
			exit(1);
		}
		INSIST(res->ai_addrlen <= sizeof(sa_auth.type));
		memmove(&sa_auth.type, res->ai_addr, res->ai_addrlen);
		freeaddrinfo(res);
		sa_auth.length = res->ai_addrlen;
		ISC_LINK_INIT(&sa_auth, link);

		ISC_LIST_APPEND(auth_servers, &sa_auth, link);
	}

	/* Set the recursive server */
	if (recursive_server != NULL) {
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_DGRAM;
		hints.ai_protocol = IPPROTO_UDP;
		hints.ai_flags = AI_NUMERICHOST;
		gai_error = getaddrinfo(recursive_server, "53", &hints, &res);
		if (gai_error != 0) {
			fprintf(stderr, "getaddrinfo failed: %s\n",
				gai_strerror(gai_error));
			exit(1);
		}
		INSIST(res->ai_addrlen <= sizeof(sa_recursive.type));
		memmove(&sa_recursive.type, res->ai_addr, res->ai_addrlen);
		freeaddrinfo(res);
		sa_recursive.length = res->ai_addrlen;
		ISC_LINK_INIT(&sa_recursive, link);
		ISC_LIST_INIT(rec_servers);
		ISC_LIST_APPEND(rec_servers, &sa_recursive, link);
		result = dns_client_setservers(client, dns_rdataclass_in,
					       NULL, &rec_servers);
		if (result != ISC_R_SUCCESS) {
			fprintf(stderr, "set server failed: %d\n", result);
			exit(1);
		}
	}

	/* Construct zone name */
	zname = NULL;
	if (zonenamestr != NULL) {
		namelen = strlen(zonenamestr);
		isc_buffer_init(&b, zonenamestr, namelen);
		isc_buffer_add(&b, namelen);
		dns_fixedname_init(&zname0);
		zname = dns_fixedname_name(&zname0);
		result = dns_name_fromtext(zname, &b, dns_rootname, 0, NULL);
		if (result != ISC_R_SUCCESS)
			fprintf(stderr, "failed to convert zone name: %d\n",
				result);
	}

	/* Construct prerequisite name (if given) */
	if (prereqstr != NULL) {
		dns_fixedname_init(&pname0);
		pname = dns_fixedname_name(&pname0);
		evaluate_prereq(umctx, prereqstr, pname);
		ISC_LIST_APPEND(prereqlist, pname, link);
		prereqlistp = &prereqlist;
	}

	/* Construct update name */
	ISC_LIST_INIT(updatelist);
	dns_fixedname_init(&uname0);
	uname = dns_fixedname_name(&uname0);
	update_addordelete(umctx, argv[1], isdelete, uname);
	ISC_LIST_APPEND(updatelist, uname, link);

	/* Set up TSIG/SIG(0) key (if given) */
	if (keyfilename != NULL)
		setup_tsec(keyfilename, umctx);

	/* Perform update */
	result = dns_client_update(client,
				   default_rdataclass, /* XXX: fixed */
				   zname, prereqlistp, &updatelist,
				   (auth_server == NULL) ? NULL :
				   &auth_servers, tsec, 0);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr,
			"update failed: %s\n", dns_result_totext(result));
	} else
		fprintf(stderr, "update succeeded\n");

	/* Cleanup */
	while ((pname = ISC_LIST_HEAD(prereqlist)) != NULL) {
		while ((rdataset = ISC_LIST_HEAD(pname->list)) != NULL) {
			ISC_LIST_UNLINK(pname->list, rdataset, link);
			dns_rdataset_disassociate(rdataset);
			isc_mem_put(umctx, rdataset, sizeof(*rdataset));
		}
		ISC_LIST_UNLINK(prereqlist, pname, link);
	}
	while ((uname = ISC_LIST_HEAD(updatelist)) != NULL) {
		while ((rdataset = ISC_LIST_HEAD(uname->list)) != NULL) {
			ISC_LIST_UNLINK(uname->list, rdataset, link);
			dns_rdataset_disassociate(rdataset);
			isc_mem_put(umctx, rdataset, sizeof(*rdataset));
		}
		ISC_LIST_UNLINK(updatelist, uname, link);
	}
	while ((rdatalist = ISC_LIST_HEAD(usedrdatalists)) != NULL) {
		while ((rdata = ISC_LIST_HEAD(rdatalist->rdata)) != NULL) {
			ISC_LIST_UNLINK(rdatalist->rdata, rdata, link);
			isc_mem_put(umctx, rdata, sizeof(*rdata));
		}
		ISC_LIST_UNLINK(usedrdatalists, rdatalist, link);
		isc_mem_put(umctx, rdatalist, sizeof(*rdatalist));
	}
	while ((buf = ISC_LIST_HEAD(usedbuffers)) != NULL) {
		ISC_LIST_UNLINK(usedbuffers, buf, link);
		isc_buffer_free(&buf);
	}
	if (tsec != NULL)
		dns_tsec_destroy(&tsec);
	isc_mem_destroy(&umctx);
	dns_client_destroy(&client);
	dns_lib_shutdown();

	return (0);
}
예제 #2
0
int
main(int argc, char *argv[]) {
	int ch;
	dns_client_t *client = NULL;
	char *zonenamestr = NULL;
	char *keyfilename = NULL;
	char *prereqstr = NULL;
	isc_sockaddr_t sa_auth[10], sa_recursive[10];
	unsigned int nsa_auth = 0, nsa_recursive = 0;
	isc_sockaddrlist_t rec_servers;
	isc_sockaddrlist_t auth_servers;
	isc_result_t result;
	isc_boolean_t isdelete;
	isc_buffer_t b, *buf;
	dns_fixedname_t zname0, pname0, uname0;
	unsigned int namelen;
	dns_name_t *zname = NULL, *uname, *pname;
	dns_rdataset_t *rdataset;
	dns_rdatalist_t *rdatalist;
	dns_rdata_t *rdata;
	dns_namelist_t updatelist, prereqlist, *prereqlistp = NULL;
	isc_mem_t *umctx = NULL;

	ISC_LIST_INIT(auth_servers);
	ISC_LIST_INIT(rec_servers);

	while ((ch = isc_commandline_parse(argc, argv, "a:k:p:P:r:z:")) != EOF) {
		switch (ch) {
		case 'k':
			keyfilename = isc_commandline_argument;
			break;
		case 'a':
			if (nsa_auth < sizeof(sa_auth)/sizeof(*sa_auth) &&
			    addserver(isc_commandline_argument, &auth_servers,
				      &sa_auth[nsa_auth]))
				nsa_auth++;
			break;
		case 'p':
			prereqstr = isc_commandline_argument;
			break;
		case 'P':
			port = isc_commandline_argument;
			break;
		case 'r':
			if (nsa_recursive <
				sizeof(sa_recursive)/sizeof(*sa_recursive) &&
			    addserver(isc_commandline_argument, &rec_servers,
				      &sa_recursive[nsa_recursive]))
				nsa_recursive++;
			break;
		case 'z':
			zonenamestr = isc_commandline_argument;
			break;
		default:
			usage();
		}
	}

	argc -= isc_commandline_index;
	argv += isc_commandline_index;
	if (argc < 2)
		usage();

	/* command line argument validation */
	if (strcmp(argv[0], "delete") == 0)
		isdelete = ISC_TRUE;
	else if (strcmp(argv[0], "add") == 0)
		isdelete = ISC_FALSE;
	else {
		fprintf(stderr, "invalid update command: %s\n", argv[0]);
		exit(1);
	}

	if (ISC_LIST_HEAD(auth_servers) == NULL &&
	    ISC_LIST_HEAD(rec_servers) == NULL) {
		fprintf(stderr, "authoritative or recursive servers "
			"must be specified\n");
		usage();
	}

	/* Initialization */
	ISC_LIST_INIT(usedbuffers);
	ISC_LIST_INIT(usedrdatalists);
	ISC_LIST_INIT(prereqlist);
	isc_lib_register();
	result = dns_lib_init();
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "dns_lib_init failed: %d\n", result);
		exit(1);
	}
	result = isc_mem_create(0, 0, &umctx);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "failed to crate mctx\n");
		exit(1);
	}

	result = dns_client_create(&client, 0);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "dns_client_create failed: %d\n", result);
		exit(1);
	}

	/* Construct zone name */
	zname = NULL;
	if (zonenamestr != NULL) {
		namelen = strlen(zonenamestr);
		isc_buffer_init(&b, zonenamestr, namelen);
		isc_buffer_add(&b, namelen);
		dns_fixedname_init(&zname0);
		zname = dns_fixedname_name(&zname0);
		result = dns_name_fromtext(zname, &b, dns_rootname, 0, NULL);
		if (result != ISC_R_SUCCESS)
			fprintf(stderr, "failed to convert zone name: %d\n",
				result);
	}

	/* Construct prerequisite name (if given) */
	if (prereqstr != NULL) {
		dns_fixedname_init(&pname0);
		pname = dns_fixedname_name(&pname0);
		evaluate_prereq(umctx, prereqstr, pname);
		ISC_LIST_APPEND(prereqlist, pname, link);
		prereqlistp = &prereqlist;
	}

	/* Construct update name */
	ISC_LIST_INIT(updatelist);
	dns_fixedname_init(&uname0);
	uname = dns_fixedname_name(&uname0);
	update_addordelete(umctx, argv[1], isdelete, uname);
	ISC_LIST_APPEND(updatelist, uname, link);

	/* Set up TSIG/SIG(0) key (if given) */
	if (keyfilename != NULL)
		setup_tsec(keyfilename, umctx);

	/* Perform update */
	result = dns_client_update(client,
				   default_rdataclass, /* XXX: fixed */
				   zname, prereqlistp, &updatelist,
				   (ISC_LIST_HEAD(auth_servers) == NULL) ?
				    NULL : &auth_servers, tsec, 0);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr,
			"update failed: %s\n", dns_result_totext(result));
	} else
		fprintf(stderr, "update succeeded\n");

	/* Cleanup */
	while ((pname = ISC_LIST_HEAD(prereqlist)) != NULL) {
		while ((rdataset = ISC_LIST_HEAD(pname->list)) != NULL) {
			ISC_LIST_UNLINK(pname->list, rdataset, link);
			dns_rdataset_disassociate(rdataset);
			isc_mem_put(umctx, rdataset, sizeof(*rdataset));
		}
		ISC_LIST_UNLINK(prereqlist, pname, link);
	}
	while ((uname = ISC_LIST_HEAD(updatelist)) != NULL) {
		while ((rdataset = ISC_LIST_HEAD(uname->list)) != NULL) {
			ISC_LIST_UNLINK(uname->list, rdataset, link);
			dns_rdataset_disassociate(rdataset);
			isc_mem_put(umctx, rdataset, sizeof(*rdataset));
		}
		ISC_LIST_UNLINK(updatelist, uname, link);
	}
	while ((rdatalist = ISC_LIST_HEAD(usedrdatalists)) != NULL) {
		while ((rdata = ISC_LIST_HEAD(rdatalist->rdata)) != NULL) {
			ISC_LIST_UNLINK(rdatalist->rdata, rdata, link);
			isc_mem_put(umctx, rdata, sizeof(*rdata));
		}
		ISC_LIST_UNLINK(usedrdatalists, rdatalist, link);
		isc_mem_put(umctx, rdatalist, sizeof(*rdatalist));
	}
	while ((buf = ISC_LIST_HEAD(usedbuffers)) != NULL) {
		ISC_LIST_UNLINK(usedbuffers, buf, link);
		isc_buffer_free(&buf);
	}
	if (tsec != NULL)
		dns_tsec_destroy(&tsec);
	isc_mem_destroy(&umctx);
	dns_client_destroy(&client);
	dns_lib_shutdown();

	return (0);
}