summaryrefslogtreecommitdiff
path: root/pgm4/inet_addrs.d/getaddrs.c
diff options
context:
space:
mode:
Diffstat (limited to 'pgm4/inet_addrs.d/getaddrs.c')
-rw-r--r--pgm4/inet_addrs.d/getaddrs.c171
1 files changed, 171 insertions, 0 deletions
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);
+}