summaryrefslogtreecommitdiff
path: root/lib/curl_addrinfo.c
diff options
context:
space:
mode:
authorYang Tse <yangsita@gmail.com>2008-11-06 17:19:56 +0000
committerYang Tse <yangsita@gmail.com>2008-11-06 17:19:56 +0000
commita0ef686c542bee30be0b20cd4d3243bec6b4f059 (patch)
treef2eeaa5b9920664defdd021eea0b98e9d6119f41 /lib/curl_addrinfo.c
parent2903a5c0500210f0a3934352fe29217b2b8e1dbf (diff)
downloadcurl-a0ef686c542bee30be0b20cd4d3243bec6b4f059.tar.gz
Merged existing IPv4 and IPv6 Curl_ip2addr functions into a single one
which now also takes a protocol address family argument.
Diffstat (limited to 'lib/curl_addrinfo.c')
-rw-r--r--lib/curl_addrinfo.c103
1 files changed, 100 insertions, 3 deletions
diff --git a/lib/curl_addrinfo.c b/lib/curl_addrinfo.c
index 8c538b821..826eae8ce 100644
--- a/lib/curl_addrinfo.c
+++ b/lib/curl_addrinfo.c
@@ -190,7 +190,8 @@ Curl_getaddrinfo_ex(const char *nodename,
*result = cafirst;
- return error; /* This is not a CURLcode */
+ /* This is not a CURLcode */
+ return error;
}
#endif /* HAVE_GETADDRINFO */
@@ -254,6 +255,8 @@ Curl_he2ai(const struct hostent *he, int port)
/* no input == no output! */
return NULL;
+ DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
+
for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) {
int ss_size;
@@ -300,7 +303,7 @@ Curl_he2ai(const struct hostent *he, int port)
switch (ai->ai_family) {
case AF_INET:
- addr = (struct sockaddr_in *)ai->ai_addr; /* storage area for this info */
+ addr = (void *)ai->ai_addr; /* storage area for this info */
memcpy(&addr->sin_addr, curr, sizeof(struct in_addr));
addr->sin_family = (unsigned short)(he->h_addrtype);
@@ -309,7 +312,7 @@ Curl_he2ai(const struct hostent *he, int port)
#ifdef ENABLE_IPV6
case AF_INET6:
- addr6 = (struct sockaddr_in6 *)ai->ai_addr; /* storage area for this info */
+ addr6 = (void *)ai->ai_addr; /* storage area for this info */
memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr));
addr6->sin6_family = (unsigned short)(he->h_addrtype);
@@ -330,6 +333,100 @@ Curl_he2ai(const struct hostent *he, int port)
}
+struct namebuff {
+ struct hostent hostentry;
+ union {
+ struct in_addr ina4;
+#ifdef ENABLE_IPV6
+ struct in6_addr ina6;
+#endif
+ } addrentry;
+ char *h_addr_list[2];
+};
+
+
+/*
+ * Curl_ip2addr()
+ *
+ * This function takes an internet address, in binary form, as input parameter
+ * along with its address family and the string version of the address, and it
+ * returns a Curl_addrinfo chain filled in correctly with information for the
+ * given address/host
+ */
+
+Curl_addrinfo *
+Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
+{
+ Curl_addrinfo *ai;
+
+#if defined(VMS) && \
+ defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
+#pragma pointer_size save
+#pragma pointer_size short
+#pragma message disable PTRMISMATCH
+#endif
+
+ struct hostent *h;
+ struct namebuff *buf;
+ char *addrentry;
+ char *hoststr;
+ int addrsize;
+
+ DEBUGASSERT(inaddr && hostname);
+
+ buf = malloc(sizeof(struct namebuff));
+ if(!buf)
+ return NULL;
+
+ hoststr = strdup(hostname);
+ if(!hoststr) {
+ free(buf);
+ return NULL;
+ }
+
+ switch(af) {
+ case AF_INET:
+ addrsize = sizeof(struct in_addr);
+ addrentry = (void *)&buf->addrentry.ina4;
+ memcpy(addrentry, inaddr, sizeof(struct in_addr));
+ break;
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ addrsize = sizeof(struct in6_addr);
+ addrentry = (void *)&buf->addrentry.ina6;
+ memcpy(addrentry, inaddr, sizeof(struct in6_addr));
+ break;
+#endif
+ default:
+ free(hoststr);
+ free(buf);
+ return NULL;
+ }
+
+ h = &buf->hostentry;
+ h->h_name = hoststr;
+ h->h_aliases = NULL;
+ h->h_addrtype = (short)af;
+ h->h_length = (short)addrsize;
+ h->h_addr_list = &buf->h_addr_list[0];
+ h->h_addr_list[0] = addrentry;
+ h->h_addr_list[1] = NULL; /* terminate list of entries */
+
+#if defined(VMS) && \
+ defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
+#pragma pointer_size restore
+#pragma message enable PTRMISMATCH
+#endif
+
+ ai = Curl_he2ai(h, port);
+
+ free(hoststr);
+ free(buf);
+
+ return ai;
+}
+
+
#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
/*
* curl_dofreeaddrinfo()