static void register_send(settings_t *settings) { dns_t *dns; uint8_t *packet; uint32_t packet_length; /* Create the DNS object. */ dns = dns_create(); dns->flags = FLAGS_R_REQUEST | FLAGS_NM_RD | FLAGS_NM_B; if(settings->query_type == TYPE_REGISTER) dns->flags = FLAGS_OPCODE_NAME_REGISTRATION; else if(settings->query_type == TYPE_REFRESH) dns->flags = FLAGS_OPCODE_NAME_REFRESH; else if(settings->query_type == TYPE_RELEASE) dns->flags = FLAGS_OPCODE_NAME_RELEASE; else fprintf(stderr, "Unknown query type made it into register_send() -- %d\n", settings->query_type); dns->trn_id = 0x1337; /* Add the question/additional. */ dns_add_netbios_question(dns, settings->name, settings->name_type, NULL, DNS_TYPE_NB, 0x0001); dns_add_additional_NB(dns, settings->name, settings->name_type, NULL, 0x0001, 0, 0x0000, settings->source); /* Convert the DNS object to a packet. */ packet = dns_to_packet(dns, &packet_length); dns_destroy(dns); /* Put it on the wire. */ fprintf(stderr, "Sending query.\n"); udp_send(settings->socket, settings->target, settings->port, packet, packet_length); safe_free(packet); }
static void send_poison_response(settings_t *settings, int socket, char *addr, uint16_t port, char *name, uint8_t name_type, uint16_t trn_id) { dns_t *response = dns_create(); uint8_t *packet; uint32_t packet_length; fprintf(stderr, "Replying to request for '%s<%02x>' with %s\n", name, name_type, settings->source); response->trn_id = trn_id; response->flags = FLAGS_R_RESPONSE | FLAGS_OPCODE_QUERY | FLAGS_NM_AA | FLAGS_NM_RD; dns_add_answer_NB(response, name, name_type, NULL, 1, 0, 0x0000, settings->source); packet = dns_to_packet(response, &packet_length); dns_destroy(response); udp_send(socket, addr, port, packet, packet_length); safe_free(packet); }
static void send_conflict_response(settings_t *settings, int socket, char *addr, uint16_t port, char *name, uint8_t name_type, uint16_t trn_id) { dns_t *response = dns_create(); uint8_t *packet; uint32_t packet_length; fprintf(stderr, "Replying to registration request for '%s<%02x>' with a conflict (%s)\n", name, name_type, settings->source); response->trn_id = trn_id; response->flags = FLAGS_R_RESPONSE | FLAGS_OPCODE_NAME_REGISTRATION | FLAGS_NM_AA | FLAGS_NM_RD | FLAGS_NM_RA | FLAGS_RCODE_ACT_ERR; dns_add_answer_NB(response, name, name_type, NULL, 1, 0, 0x0000, settings->source ? settings->source : "0.0.0.0"); packet = dns_to_packet(response, &packet_length); dns_destroy(response); udp_send(socket, addr, port, packet, packet_length); safe_free(packet); }
static void query_send(settings_t *settings) { dns_t *dns; uint8_t *packet; uint32_t packet_length; /* Create the DNS object. */ dns = dns_create(); dns->flags = FLAGS_R_REQUEST | FLAGS_OPCODE_QUERY | FLAGS_NM_B; dns->trn_id = 0x1337; /* Add the question. */ dns_add_netbios_question(dns, settings->name, settings->name_type, NULL, settings->query_type == TYPE_QUERY_NB ? DNS_TYPE_NB : DNS_TYPE_NBSTAT, 0x0001); /* Convert the DNS object to a packet. */ packet = dns_to_packet(dns, &packet_length); dns_destroy(dns); /* Put it on the wire. */ fprintf(stderr, "Sending query.\n"); udp_send(settings->socket, settings->target, settings->port, packet, packet_length); safe_free(packet); }
static SELECT_RESPONSE_t dns_callback(void *group, int socket, uint8_t *packet, size_t packet_length, char *addr, uint16_t port, void *s) { settings_t *settings = (settings_t*) s; dns_t *response; uint8_t *response_packet; uint32_t response_packet_length; /* Parse the DNS packet. */ dns_t *request = dns_create_from_packet(packet, packet_length); /* Create the response packet. */ response = dns_create(); response->trn_id = request->trn_id; response->flags = 0x8000; if(request->question_count > 0) { int i; /* Display the questions. */ for(i = 0; i < request->question_count; i++) { /* Grab the question and display it. */ question_t this_question = request->questions[i]; fprintf(stderr, "Question %d: %s (0x%04x 0x%04x)\n", i, this_question.name, this_question.type, this_question.class); /* Add an answer, if appropriate. */ dns_add_question(response, this_question.name, this_question.type, this_question.class); if(settings->A && (this_question.type == DNS_TYPE_A || this_question.type == DNS_TYPE_ANY)) { fprintf(stderr, "(Responding with %s)\n", settings->A); dns_add_answer_A(response, this_question.name, 0x0001, settings->TTL, settings->A); } #ifndef WIN32 else if(settings->AAAA && this_question.type == DNS_TYPE_AAAA) { fprintf(stderr, "(Responding with %s)\n", settings->AAAA); dns_add_answer_AAAA(response, this_question.name, 0x0001, settings->TTL, settings->AAAA); } #endif } /* If we have any answers, send back our packet. */ if(response->answer_count > 0) { /* Send the packet. */ response_packet = dns_to_packet(response, &response_packet_length); udp_send(socket, addr, port, response_packet, response_packet_length); } else { /* Send back an error. */ response_packet = dns_create_error_string(request->trn_id, request->questions[0], &response_packet_length); udp_send(socket, addr, port, response_packet, response_packet_length); } /* Delete the response. */ safe_free(response_packet); dns_destroy(response); /* Delete the request. */ dns_destroy(request); }
static grpc_resolver *dns_factory_create_resolver( grpc_resolver_factory *factory, grpc_uri *uri, grpc_subchannel_factory *subchannel_factory) { return dns_create(uri, "https", grpc_create_pick_first_lb_policy, subchannel_factory); }
/* This function expects to receive the proper length of data. */ static void handle_packet_out(driver_dns_t *driver, uint8_t *data, size_t length) { size_t i; dns_t *dns; buffer_t *buffer; uint8_t *encoded_bytes; size_t encoded_length; uint8_t *dns_bytes; size_t dns_length; size_t section_length; assert(driver->s != -1); /* Make sure we have a valid socket. */ assert(data); /* Make sure they aren't trying to send NULL. */ assert(length > 0); /* Make sure they aren't trying to send 0 bytes. */ assert(length <= MAX_DNSCAT_LENGTH(driver->domain)); buffer = buffer_create(BO_BIG_ENDIAN); /* If no domain is set, add the wildcard prefix at the start. */ if(!driver->domain) { buffer_add_bytes(buffer, (uint8_t*)WILDCARD_PREFIX, strlen(WILDCARD_PREFIX)); buffer_add_int8(buffer, '.'); } section_length = 0; /* TODO: I don't much care for this loop... */ for(i = 0; i < length; i++) { char hex_buf[3]; #ifdef WIN32 sprintf_s(hex_buf, 3, "%02x", data[i]); #else sprintf(hex_buf, "%02x", data[i]); #endif buffer_add_bytes(buffer, hex_buf, 2); /* Add periods when we need them. */ section_length += 2; if(i + 1 != length && section_length + 2 >= MAX_FIELD_LENGTH) { section_length = 0; buffer_add_int8(buffer, '.'); } } /* If a domain is set, instead of the wildcard prefix, add the domain to the end. */ if(driver->domain) { buffer_add_int8(buffer, '.'); buffer_add_bytes(buffer, driver->domain, strlen(driver->domain)); } buffer_add_int8(buffer, '\0'); /* Get the result out. */ encoded_bytes = buffer_create_string_and_destroy(buffer, &encoded_length); /* Double-check we didn't mess up the length. */ assert(encoded_length <= MAX_DNS_LENGTH); dns = dns_create(_DNS_OPCODE_QUERY, _DNS_FLAG_RD, _DNS_RCODE_SUCCESS); dns_add_question(dns, (char*)encoded_bytes, driver->type, _DNS_CLASS_IN); dns_bytes = dns_to_packet(dns, &dns_length); LOG_INFO("Sending DNS query for: %s to %s:%d", encoded_bytes, driver->dns_host, driver->dns_port); udp_send(driver->s, driver->dns_host, driver->dns_port, dns_bytes, dns_length); safe_free(dns_bytes); safe_free(encoded_bytes); dns_destroy(dns); }
static grpc_resolver *dns_factory_create_resolver( grpc_resolver_factory *factory, grpc_resolver_args *args) { return dns_create(args, "https", "pick_first"); }
int main (int argc, char **argv) { int opt; enum log_level log_level = LOG_LEVEL; int err = 0; struct event_main *event_main; struct options options = { .resolver = "localhost", }; while ((opt = getopt_long(argc, argv, "hqvdR:", long_options, NULL)) >= 0) { switch (opt) { case 'h': help(argv[0]); return 0; case 'q': log_level = LOG_ERROR; break; case 'v': log_level = LOG_INFO; break; case 'd': log_level = LOG_DEBUG; break; case 'R': options.resolver = optarg; break; default: help(argv[0]); return 1; } } // apply log_set_level(log_level); if ((err = event_main_create(&event_main))) { log_fatal("event_main_create"); goto error; } if ((err = dns_create(event_main, &options.dns, options.resolver))) { log_fatal("dns_create: %s", options.resolver); goto error; } while (optind < argc && !err) { struct dns_task task = { .options = &options, .arg = argv[optind++], }; // start async task if ((err = event_start(event_main, dns, &task))) { log_fatal("event_start: %s", task.arg); } } // mainloop if ((err = event_main_run(event_main))) { log_fatal("event_main"); } error: if (options.dns) dns_destroy(options.dns); return err; }
int main(int argc, char *argv[]) { dnsPacket *dns, *dnsresponse; int iResult, iReceived; char *qdomain, *qserver, *response; unsigned short qtype = 1, qclass = 1; qdomain = ((qdomain = command_arg_get(0, '-', argc, argv)) != NULL) ? qdomain : DNS_DEFAULT_LOOKUP; qserver = ((qserver = command_arg_get(1, '-', argc, argv)) != NULL) ? qserver : DNS_LOOKUP_SERVER; // create our empty DNS packet dns = dns_create(); // set the required header fields dns->base->id = DNS_IDENTIFIER; // use recursive query? if (command_opt_set("-r", argc, argv)) { dns->base->flags |= DNS_FLAGS_RD; printf("+ Using recursive querying\n"); } // use a different query type? if (command_opt_set("-cname", argc, argv)) { qtype = DNS_TYPE_CNAME; printf("+ Using CNAME query type\n"); } else if (command_opt_set("-ns", argc, argv)) { qtype = DNS_TYPE_NS; printf("+ Using NS query type\n"); } else if (command_opt_set("-mx", argc, argv)) { qtype = DNS_TYPE_MX; printf("+ Using MX query type\n"); } else if (command_opt_set("-ptr", argc, argv)) { qtype = DNS_TYPE_PTR; printf("+ Using PTR query type\n"); } else if (command_opt_set("-aaaa", argc, argv)) { qtype = DNS_TYPE_AAAA; printf("+ Using AAAA query type\n"); } // add our question section dns_add_question(dns, qdomain, strlen(qdomain), qtype, qclass); dns_hton(dns); // initialize the network network_init(qserver, DNS_PORT); network_connect_udp(); // send the packet out printf("Looking up %s using %s...\n", qdomain, qserver); iResult = network_send((char *)dns->base, dns->size); assert(iResult > 0); // block until a response is ready response = network_receive(&iReceived); assert(iReceived > 0); // load up the response packet dnsresponse = dns_parse(response, iReceived); assert(dnsresponse->base->flags & DNS_FLAGS_RESPONSE && dnsresponse->base->id == DNS_IDENTIFIER); output_print_response(dnsresponse); output_print_sections(dnsresponse); }
static grpc_resolver *dns_factory_create_resolver( grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory, grpc_resolver_args *args) { return dns_create(exec_ctx, args, "https"); }