#include <sys/types.h> #include <netinet/in.h> #include <arpa/nameser.h> #include <resolv.h> int res_ninit(state* res)
The res_ninit() function is similar to res_init() but it uses a user-declared res pointer instead of the shared _res.
For a description of this function and more information on the parameters, authorities required, return values, error conditions, error messages, usage notes, and related information, see res_init()--Initialize _res Structure.
The RES_INIT and RES_XINIT options flags must be initialized to zero before the first call to any resolver API or the res structure will not be properly initialized. For example:
state res; res.options &= ~ (RES_INIT | RES_XINIT); int n = res_ninit(&res);
res_ninit() returns an integer. Possible values are:
When the res_ninit() function fails, errno can be set to one of the following:
The system detected a pointer that was invalid while attempting to access an input pointer.
The res appears to have been previously initialized but the reserved field is not set to zeros.
See Code disclaimer information for information pertaining to code examples.
The following example shows how res_ninit() is used and how initialization defaults can be changed after initialization:
#include <stdio.h> #include <errno.h> #include <netinet/in.h> #include <arpa/nameser.h> #include <resolv.h> #include <netdb.h> /* Declare update records - a zone record, a pre-requisite record, and an update record */ ns_updrec update_records[] = { { {NULL,NULL}, {NULL,&update_records[1]}, ns_s_zn, /* a zone record */ "mydomain.ibm.com.", ns_c_in, ns_t_soa, 0, NULL, 0, 0, NULL, NULL, 0 }, { {NULL,NULL}, {&update_records[0],&update_records[2]}, ns_s_pr, /* pre-req record */ "mypc.mydomain.ibm.com.", ns_c_in, ns_t_a, 0, NULL, 0, ns_r_nxdomain, /* record must not exist */ NULL, NULL, 0 }, { {NULL,NULL}, {&update_records[1],NULL}, ns_s_ud, /* update record */ "mypc.mydomain.ibm.com.", ns_c_in, ns_t_a, 10, (unsigned char *)"10.10.10.10", 11, ns_uop_add, /* to be added */ NULL, NULL, 0 } }; void main() { struct state res; int result; unsigned char update_buffer[2048]; int buffer_length = sizeof update_buffer; unsigned char answer_buffer[2048]; /* Turn off the init flags so that the structure will be initialized */ res.options &= ~ (RES_INIT | RES_XINIT); result = res_ninit(&res); /* Put processing here to check the result and handle errors */ /* We choose to use TCP and not UDP, so set the appropriate option now that the res variable has been initialized. */ res.options |= RES_USEVC; /* Send a query for mypc.mydomain.ibm.com address records */ result = res_nquerydomain(&res,"mypc", "mydomain.ibm.com.", ns_c_in, ns_t_a, update_buffer, buffer_length); /* Sample error handling and printing errors */ if (result == -1) { printf("\nquery domain failed. result = %d \nerrno: %d: %s \nh_errno: %d: %s", result, errno, strerror(errno), h_errno, hstrerror(h_errno)); return; } /* The output on a failure will be: query domain failed. result = -1 errno: 0: There is no error. h_errno: 5: Unknown host */ { /* Build an update buffer (packet to be sent) from the update records */ result = res_nmkupdate(&res, update_records, update_buffer, buffer_length); /* Put processing here to check the result and handle errors */ } { char zone_name[NS_MAXDNAME]; size_t zone_name_size = sizeof zone_name; struct sockaddr_in s_address; struct in_addr addresses[1]; int number_addresses = 1; /* Find the DNS server that is authoritative for the domain that we want to update */ result = res_findzonecut(&res, "mypc.mydomain.ibm.com", ns_c_in, 0, zone_name, zone_name_size, addresses, number_addresses); /* Put processing here to check the result and handle errors */ /* Check if the DNS server found is one of our regular DNS addresses */ s_address.sin_addr = addresses[0]; s_address.sin_family = res.nsaddr_list[0].sin_family; s_address.sin_port = res.nsaddr_list[0].sin_port; memset(s_address.sin_zero, 0x00, 8); result = res_nisourserver(&res, &s_address); /* Put processing here to check the result and handle errors */ /* Set the DNS address found with res_findzonecut into the res structure. We will send the (TSIG signed) update to that DNS. */ res.nscount = 1; res.nsaddr_list[0] = s_address; } { ns_tsig_key my_key = { "my-long-key", /* This key must exist on the DNS */ NS_TSIG_ALG_HMAC_MD5, (unsigned char*) "abcdefghijklmnopqrstuvwx", 24 }; /* Send a TSIG signed update to the DNS */ result = res_nsendsigned(&res, update_buffer, result, &my_key, answer_buffer, sizeof answer_buffer); /* Put processing here to check the result and handle errors */ } /* The res_findzonecut(), res_nmkupdate(), and res_nsendsigned() could be replaced with one call to res_nupdate() using update_records[1] to skip the zone record:: result = res_nupdate(&res, &update_records[1], &my_key); */ return; }
Top | UNIX-Type APIs | APIs by category |