Using the Domaing Name System
with Examples in C |
Prof. David Bernstein |
Computer Science Department |
bernstdh@jmu.edu |
int getaddrinfo(const char *host, const char *service, const struct addrinfo *hints, struct addrinfo **first)
host
|
The host name |
service
|
The service name (or port number) |
hints
|
Further criteria to use |
first
|
The first IP address (in a linked structure) |
Return | 0 on success; non-zero on error |
struct addrinfo { int ai_flags; int ai_family; // AF_INET, AF_INET6 int ai_socktype; // SOCK_STREAM, SOCK_DGRAM int ai_protocol; // Protocol (name or number) socklen_t ai_addrlen; // sizeof(si_addr) struct sockaddr *ai_addr; // Socket address char *ai_canonname; // Canonical name of host (or NULL) struct addrinfo *ai_next; // Pointer to next struct in linked structure };
Note: ai_canonname
will be NULL
for all elements
in the linked structure after the first.
#define _POSIX_C_SOURCE 201112L #include <arpa/inet.h> #include <ifaddrs.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char* argv[]) { char dotted_quad[16]; struct addrinfo hints; struct addrinfo *current, *first; struct sockaddr_in *address; // Initialize unused fields to 0 or NULL as appropriate memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; // Initialize used fields hints.ai_flags = AI_CANONNAME | AI_NUMERICSERV; hints.ai_family = AF_INET; hints.ai_socktype = 0; // Any socket type (could be SOCK_DGRAM or SOCK_STREAM) hints.ai_protocol = 0; // Get the linked structure of addresses getaddrinfo(argv[1], "0", &hints, &first); if (first) printf("IP Addresses for %s:\n", first->ai_canonname); else printf("No addresses found for %s\n", first->ai_canonname); // Iterate through the linked structure current = first; while (current) { // Get the address address = (struct sockaddr_in *)current->ai_addr; // Convert to a human-readable string memset(&dotted_quad, 0, 16); inet_ntop(AF_INET, &address->sin_addr, dotted_quad, 16); printf("%s\n", dotted_quad); current = current->ai_next; } // Free the memory used by the linked structure freeaddrinfo(first); exit(0); }
int getnameinfo(const struct sockaddr *address, socklen_t addrlen, char *host, socklen_t hostlen, char* service, socklen servlen, int flags)
address
|
The IP address of interest |
addrlen
|
The length of the IP address |
host
|
The corresponding host nam |
hostlen
|
The maximum length of a host name |
service
|
The corresponding service |
servlen
|
The maximum length of a service name |
flags
|
A bit mask of flags |
Return | 0 on success; non-zero on error |
#define _GNU_SOURCE #define _POSIX_C_SOURCE 201112L #include <arpa/inet.h> #include <ifaddrs.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h> int main(int argc, char* argv[]) { char name[NI_MAXHOST], service[NI_MAXSERV]; struct sockaddr_in address; uint16_t port = 0; // Initialize the arrays that will hold the result memset(&name, 0, sizeof(name)); memset(&service, 0, sizeof(service)); if (argc > 2) port = atoi(argv[2]); // Set the attributes of the address address.sin_family = AF_INET; // IPv4 address.sin_port = htons(port); // Use network byte order // Convert the command-line argument from human-readable format inet_pton(AF_INET, argv[1], &(address.sin_addr)); // Get the name getnameinfo((struct sockaddr *)&address, sizeof(struct sockaddr), name, NI_MAXHOST, service, NI_MAXSERV, 0); printf("Host Name: %s\n", name); printf("Service: %s\n", service); exit(0); }