|
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);
}