Ejemplo n.º 1
0
int
main(int argc, char **argv)
{
	int c;
	int i;

	/* LDNS types */
	ldns_pkt *notify;
	ldns_rr *question;
	ldns_resolver *res;
	ldns_rdf *ldns_zone_name = NULL;
	ldns_status status;
	const char *zone_name = NULL;
	int include_soa = 0;
	uint32_t soa_version = 0;
	ldns_tsig_credentials tsig_cred = {0,0,0};
	int do_hexdump = 1;
	uint8_t *wire = NULL;
	size_t wiresize = 0;
	char *port = "53";

	srandom(time(NULL) ^ getpid());

        while ((c = getopt(argc, argv, "vhdp:r:s:y:z:")) != -1) {
                switch (c) {
                case 'd':
			verbose++;
			break;
                case 'p':
			port = optarg;
			break;
                case 'r':
			max_num_retry = atoi(optarg);
			break;
                case 's':
			include_soa = 1;
			soa_version = (uint32_t)atoi(optarg);
			break;
                case 'y':
			tsig_cred.algorithm = "hmac-md5.sig-alg.reg.int.";
			tsig_cred.keyname = optarg;
			tsig_cred.keydata = strchr(optarg, ':');
			*tsig_cred.keydata = '\0';
			tsig_cred.keydata++;
			printf("Sign with %s : %s\n", tsig_cred.keyname,
				tsig_cred.keydata);
			break;
                case 'z':
			zone_name = optarg;
			ldns_zone_name = ldns_dname_new_frm_str(zone_name);
			if(!ldns_zone_name) {
				printf("cannot parse zone name: %s\n", 
					zone_name);
				exit(1);
			}
                        break;
		case 'v':
			version();
                case 'h':
                case '?':
                default:
                        usage();
                }
        }
        argc -= optind;
        argv += optind;

        if (argc == 0 || zone_name == NULL) {
                usage();
        }

	notify = ldns_pkt_new();
	question = ldns_rr_new();
	res = ldns_resolver_new();

	if (!notify || !question || !res) {
		/* bail out */
		printf("error: cannot create ldns types\n");
		exit(1);
	}

	/* create the rr for inside the pkt */
	ldns_rr_set_class(question, LDNS_RR_CLASS_IN);
	ldns_rr_set_owner(question, ldns_zone_name);
	ldns_rr_set_type(question, LDNS_RR_TYPE_SOA);
	ldns_pkt_set_opcode(notify, LDNS_PACKET_NOTIFY);
	ldns_pkt_push_rr(notify, LDNS_SECTION_QUESTION, question);
	ldns_pkt_set_aa(notify, true);
	ldns_pkt_set_id(notify, random()&0xffff);
	if(include_soa) {
		char buf[10240];
		ldns_rr *soa_rr=NULL;
		ldns_rdf *prev=NULL;
		snprintf(buf, sizeof(buf), "%s 3600 IN SOA . . %u 0 0 0 0",
			zone_name, (unsigned)soa_version);
		/*printf("Adding soa %s\n", buf);*/
		status = ldns_rr_new_frm_str(&soa_rr, buf, 3600, NULL, &prev);
		if(status != LDNS_STATUS_OK) {
			printf("Error adding SOA version: %s\n",
				ldns_get_errorstr_by_id(status));
		}
		ldns_pkt_push_rr(notify, LDNS_SECTION_ANSWER, soa_rr);
	}

	if(tsig_cred.keyname) {
#ifdef HAVE_SSL
		status = ldns_pkt_tsig_sign(notify, tsig_cred.keyname,
			tsig_cred.keydata, 300, tsig_cred.algorithm,
			NULL);
		if(status != LDNS_STATUS_OK) {
			printf("Error TSIG sign query: %s\n",
				ldns_get_errorstr_by_id(status));
		}
#else
	fprintf(stderr, "Warning: TSIG needs OpenSSL support, which has not been compiled in, TSIG skipped\n");
#endif
	}

	if(verbose) {
		printf("# Sending packet:\n");
		ldns_pkt_print(stdout, notify);

	}

	status = ldns_pkt2wire(&wire, notify, &wiresize);
	if(wiresize == 0) {
		printf("Error converting notify packet to hex.\n");
		exit(1);
	}

	if(do_hexdump && verbose > 1) {
		printf("Hexdump of notify packet:\n");
		for(i=0; i<(int)wiresize; i++)
			printf("%02x", (unsigned)wire[i]);
		printf("\n");
	}

	for(i=0; i<argc; i++)
	{
		struct addrinfo hints, *res0, *res;
		int error;
		int default_family = AF_INET;

		if(verbose)
			printf("# sending to %s\n", argv[i]);
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = default_family;
		hints.ai_socktype = SOCK_DGRAM;
		hints.ai_protocol = IPPROTO_UDP;
		error = getaddrinfo(argv[i], port, &hints, &res0);
		if (error) {
			printf("skipping bad address: %s: %s\n", argv[i],
				gai_strerror(error));
			continue;
		}
		for (res = res0; res; res = res->ai_next) {
			int s = socket(res->ai_family, res->ai_socktype, 
				res->ai_protocol);
			if(s == -1)
				continue;
			/* send the notify */
			notify_host(s, res, wire, wiresize, argv[i]);
		}
		freeaddrinfo(res0);
	}

	ldns_pkt_free(notify);
	free(wire);
        return 0;
}
Ejemplo n.º 2
0
/** parse REPLY line */
static void replyline(char* line, ldns_pkt *reply)
{
	char* parse = line;
	while(*parse) {
		if(isendline(*parse)) 
			return;
			/* opcodes */
		if(str_keyword(&parse, "QUERY")) {
			ldns_pkt_set_opcode(reply, LDNS_PACKET_QUERY);
		} else if(str_keyword(&parse, "IQUERY")) {
			ldns_pkt_set_opcode(reply, LDNS_PACKET_IQUERY);
		} else if(str_keyword(&parse, "STATUS")) {
			ldns_pkt_set_opcode(reply, LDNS_PACKET_STATUS);
		} else if(str_keyword(&parse, "NOTIFY")) {
			ldns_pkt_set_opcode(reply, LDNS_PACKET_NOTIFY);
		} else if(str_keyword(&parse, "UPDATE")) {
			ldns_pkt_set_opcode(reply, LDNS_PACKET_UPDATE);
			/* rcodes */
		} else if(str_keyword(&parse, "NOERROR")) {
			ldns_pkt_set_rcode(reply, LDNS_RCODE_NOERROR);
		} else if(str_keyword(&parse, "FORMERR")) {
			ldns_pkt_set_rcode(reply, LDNS_RCODE_FORMERR);
		} else if(str_keyword(&parse, "SERVFAIL")) {
			ldns_pkt_set_rcode(reply, LDNS_RCODE_SERVFAIL);
		} else if(str_keyword(&parse, "NXDOMAIN")) {
			ldns_pkt_set_rcode(reply, LDNS_RCODE_NXDOMAIN);
		} else if(str_keyword(&parse, "NOTIMPL")) {
			ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTIMPL);
		} else if(str_keyword(&parse, "REFUSED")) {
			ldns_pkt_set_rcode(reply, LDNS_RCODE_REFUSED);
		} else if(str_keyword(&parse, "YXDOMAIN")) {
			ldns_pkt_set_rcode(reply, LDNS_RCODE_YXDOMAIN);
		} else if(str_keyword(&parse, "YXRRSET")) {
			ldns_pkt_set_rcode(reply, LDNS_RCODE_YXRRSET);
		} else if(str_keyword(&parse, "NXRRSET")) {
			ldns_pkt_set_rcode(reply, LDNS_RCODE_NXRRSET);
		} else if(str_keyword(&parse, "NOTAUTH")) {
			ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTAUTH);
		} else if(str_keyword(&parse, "NOTZONE")) {
			ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTZONE);
			/* flags */
		} else if(str_keyword(&parse, "QR")) {
			ldns_pkt_set_qr(reply, true);
		} else if(str_keyword(&parse, "AA")) {
			ldns_pkt_set_aa(reply, true);
		} else if(str_keyword(&parse, "TC")) {
			ldns_pkt_set_tc(reply, true);
		} else if(str_keyword(&parse, "RD")) {
			ldns_pkt_set_rd(reply, true);
		} else if(str_keyword(&parse, "CD")) {
			ldns_pkt_set_cd(reply, true);
		} else if(str_keyword(&parse, "RA")) {
			ldns_pkt_set_ra(reply, true);
		} else if(str_keyword(&parse, "AD")) {
			ldns_pkt_set_ad(reply, true);
		} else if(str_keyword(&parse, "DO")) {
			ldns_pkt_set_edns_udp_size(reply, 4096);
			ldns_pkt_set_edns_do(reply, true);
		} else {
			error("could not parse REPLY: '%s'", parse);
		}
	}
}