diff options
Diffstat (limited to 'pgm4/inet_addrs.d')
-rw-r--r-- | pgm4/inet_addrs.d/Makefile | 10 | ||||
-rw-r--r-- | pgm4/inet_addrs.d/README | 11 | ||||
-rw-r--r-- | pgm4/inet_addrs.d/getaddrs.c | 171 | ||||
-rw-r--r-- | pgm4/inet_addrs.d/gethost.c | 57 |
4 files changed, 249 insertions, 0 deletions
diff --git a/pgm4/inet_addrs.d/Makefile b/pgm4/inet_addrs.d/Makefile new file mode 100644 index 0000000..a10866c --- /dev/null +++ b/pgm4/inet_addrs.d/Makefile @@ -0,0 +1,10 @@ +all: gethost getaddrs + +gethost: gethost.c + gcc -Wall -o gethost gethost.c + +getaddrs: getaddrs.c + gcc -Wall -o getaddrs getaddrs.c + +clean: + rm -f getaddrs gethost diff --git a/pgm4/inet_addrs.d/README b/pgm4/inet_addrs.d/README new file mode 100644 index 0000000..fbfb676 --- /dev/null +++ b/pgm4/inet_addrs.d/README @@ -0,0 +1,11 @@ +A pair of simple programs which play with symbolic and IP addresses. + +Invoke as: + getaddrs host service + host should be a symbolic host name + service should be a service name, port number, or 0 + + gethost ipaddr + ipaddr should be a dotted decimal IP address + + diff --git a/pgm4/inet_addrs.d/getaddrs.c b/pgm4/inet_addrs.d/getaddrs.c new file mode 100644 index 0000000..f229662 --- /dev/null +++ b/pgm4/inet_addrs.d/getaddrs.c @@ -0,0 +1,171 @@ +// Using getaddrinfo() to get IPv4 address for +// hostname (argv[1]) and service (argv[2]). +// +// The print_XXX() functions are from Stevens +// and Rago. +// +// P. Kearns, February 2009 + + +#include <netdb.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +void +print_family(struct addrinfo *aip) +{ + printf(" family "); + switch (aip->ai_family) { + case AF_INET: + printf("inet"); + break; + case AF_INET6: + printf("inet6"); + break; + case AF_UNIX: + printf("unix"); + break; + case AF_UNSPEC: + printf("unspecified"); + break; + default: + printf("unknown"); + } + +} +void +print_type(struct addrinfo *aip) +{ + printf(" type "); + switch (aip->ai_socktype) { + case SOCK_STREAM: + printf("stream"); + break; + case SOCK_DGRAM: + printf("datagram"); + break; + case SOCK_SEQPACKET: + printf("seqpacket"); + break; + case SOCK_RAW: + printf("raw"); + break; + default: + printf("unknown (%d)", aip->ai_socktype); + } +} + +void +print_protocol(struct addrinfo *aip) +{ + printf(" protocol "); + switch (aip->ai_protocol) { + case 0: + printf("default"); + break; + case IPPROTO_TCP: + printf("TCP"); + break; + case IPPROTO_UDP: + printf("UDP"); + break; + case IPPROTO_RAW: + printf("raw"); + break; + default: + printf("unknown (%d)", aip->ai_protocol); + } +} + +void +print_flags(struct addrinfo *aip) +{ + printf("flags"); + if (aip->ai_flags == 0) { + printf(" 0"); + + } else { + if (aip->ai_flags & AI_PASSIVE) + printf(" passive"); + if (aip->ai_flags & AI_CANONNAME) + printf(" canon"); + if (aip->ai_flags & AI_NUMERICHOST) + printf(" numhost"); +#if defined(AI_NUMERICSERV) + if (aip->ai_flags & AI_NUMERICSERV) + printf(" numserv"); +#endif +#if defined(AI_V4MAPPED) + if (aip->ai_flags & AI_V4MAPPED) + printf(" v4mapped"); +#endif +#if defined(AI_ALL) + if (aip->ai_flags & AI_ALL) + printf(" all"); +#endif + } +} + +int main(int argc,char **argv) +{ + struct addrinfo *addrlist, *aptr, hints; + struct sockaddr_in *saddrptr; + const char * p; char addrbuffer[INET_ADDRSTRLEN]; int ecode; + + if(argc != 3) { + fprintf(stderr, "usage: getaddrs node service\n"); + exit(1); + } + +// Want IPv4 lookup only. + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = 0; + hints.ai_flags = AI_CANONNAME; + hints.ai_protocol = 0; + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + +// Do the lookup. + + ecode = getaddrinfo(argv[1], argv[2], &hints, &addrlist); + if (ecode != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ecode)); + exit(1); + } + +// Scan the list of results. + + for (aptr = addrlist; aptr != NULL; aptr = aptr->ai_next) { + print_flags(aptr); print_family(aptr); + print_type(aptr); print_protocol(aptr); + + if (aptr->ai_family == AF_INET){ + printf("\tName: %s\n", aptr->ai_canonname?aptr->ai_canonname:"none"); + + // Get at filled-in sockaddr_in hanging off the addrinfo. + + saddrptr = (struct sockaddr_in *) aptr->ai_addr; + p = inet_ntop(AF_INET, &saddrptr->sin_addr.s_addr, addrbuffer, INET_ADDRSTRLEN); + + if (!p) { + perror("inet_ntop"); + exit(1); + } + + printf("IP Address: %s\n", p?p:"unknown"); + printf("Port: %d\n", ntohs(saddrptr->sin_port)); + } + } + + // Give back result structs (not really impt here). + + freeaddrinfo(addrlist); + exit(0); +} diff --git a/pgm4/inet_addrs.d/gethost.c b/pgm4/inet_addrs.d/gethost.c new file mode 100644 index 0000000..dcfc7fd --- /dev/null +++ b/pgm4/inet_addrs.d/gethost.c @@ -0,0 +1,57 @@ +// Using getnameinfo() to get host name for a +// given IP address (argv[1]). +// +// P. Kearns, February 2009 + +#include <netdb.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +int main(int argc, char **argv) +{ + + int ecode; + struct in_addr fillin; + struct sockaddr_in addr; + char host[NI_MAXHOST]; + + if (argc != 2) { + fprintf(stderr,"usage: gethost address\n"); + exit(1); + } + +// Dotted decimal to binary IP address. + + ecode = inet_pton(AF_INET, argv[1], &fillin); + if (ecode == 0) { + fprintf(stderr,"inet_pton: invalid address\n"); + exit(1); + } + if (ecode < 0) { + perror("inet_pton"); exit(1); + exit(1); + } + +// Fill in blanks of a sockaddr_in after zeroing it out. + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(0); + memcpy(&(addr.sin_addr), &fillin, sizeof(addr.sin_addr)); + +// Do the lookup. + + ecode = getnameinfo((struct sockaddr *) &addr, sizeof(addr), + host, NI_MAXHOST, NULL, 0, NI_NAMEREQD); + if (ecode) { + fprintf(stderr, "getnameinfo: %s\n", gai_strerror(ecode)); + exit(1); + } + + printf("Hostname: %s\n", host); + exit(0); +} |