OSSP CVS Repository

ossp - Check-in [848]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 848
Date: 2001-Sep-04 21:34:33 (local)
2001-Sep-04 19:34:33 (UTC)
User:ms
Branch:
Comment: Completed IPv4 and IPv6 implementations of configure, open, and write callbacks functions.
Tickets:
Inspections:
Files:
ossp-pkg/l2/l2_ch_socket.c      1.10 -> 1.11     103 inserted, 46 deleted

ossp-pkg/l2/l2_ch_socket.c 1.10 -> 1.11

--- l2_ch_socket.c       2001/09/04 19:18:49     1.10
+++ l2_ch_socket.c       2001/09/04 19:34:33     1.11
@@ -30,7 +30,6 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
-#include <arpa/inet.h>
 #include <netdb.h>
 #include <unistd.h>
 
@@ -40,14 +39,13 @@
 #define HAVE_INET_ATON
 #ifndef HAVE_INET_PTON
 #ifdef HAVE_INET_ATON
-/* !!! TODO change pton1 to pton !!! */
-static int inet_pton1(int iFamily, const char *pszAddress, void *pvMemref)
+static int inet_pton(int iFamily, const char *pszAddress, void *pvMemref)
 {
     int             i    = 0;
     struct in_addr  IP4Addr;
     struct in6_addr IP6Addr;
-    char            *pszNextfield = NULL;          /* For IPv6 address trans */
-    char            **ppszVerify  = &pszNextfield; /* To check IPv6 validity */
+    char            *pszIndex     = NULL;    /* To index IPv6 validity */
+    char            *pszNextfield = NULL;    /* For IPv6 address trans */
 
     if (iFamily == AF_INET)
     {
@@ -59,18 +57,23 @@
         return 0;
     }
 
-    else if (iFamily == AF_INET6)
-    {
-        for (i = 0; i < 16; i++)   /* Iterate through the IPv6 address fields */
+    else if (iFamily == AF_INET6) /* If we are translating IPv6 addresses     */
+    {                             /* the user needs to use precise notation   */
+        pszIndex = malloc(strlen(pszAddress));
+        strcpy(pszIndex, pszAddress);           /* Initialize, verify in loop */
+        for (i = 0; i < 8; i++)    /* Iterate through the IPv6 address fields */
         {
-            ppszVerify = &pszNextfield;  /* Reset and compare later to verify */
-            IP6Addr.__u6_addr.__u6_addr8[i] = (u_int8_t)strtol(pszAddress,\
-                &pszNextfield, 16);
-            *pszNextfield++; /* !!! TODO Problema !!! */
-
-            if ((&pszNextfield - ppszVerify) != 2)
+            IP6Addr.__u6_addr.__u6_addr16[i] =\
+                ntohs((u_int16_t)strtol(pszIndex, &pszNextfield, 16));
+            if ((pszNextfield == '\0') ||\
+               ((pszNextfield - pszIndex) != (4 * sizeof(char))))
+            {
                 return 0; /* User is supplying a IPv6 format we don't support */
+            }
+
+            pszIndex = ++pszNextfield;
         }
+
         memcpy(pvMemref, &IP6Addr, sizeof(struct in6_addr));
         return 1;
     }
@@ -89,6 +92,7 @@
 /* declare private channel configuration */
 typedef struct
 {
+    int iFamily;             /* IP version to use, AF_INET4 or AF_INET6  */
     char *pszHost;           /* IP Address or name of host to connect to */
     int iPort;               /* TCP Port to connect to                   */
     int iSocket;             /* Socket descriptor used during writing    */
@@ -118,7 +122,7 @@
 static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
 {
     l2_ch_socket_t *cfg;
-    l2_param_t pa[3];
+    l2_param_t pa[4];
     l2_result_t rv;
 
     /* parameter checks */
@@ -126,9 +130,10 @@
         return L2_ERROR;
 
     /* feed and call generic parameter parsing engine */
-    L2_PARAM_SET(pa[0], host, CHARPTR, &cfg->pszHost);
-    L2_PARAM_SET(pa[1], port, INT,     &cfg->iPort);
-    L2_PARAM_END(pa[2]);
+    L2_PARAM_SET(pa[0], ipversion, INT,     &cfg->iFamily);
+    L2_PARAM_SET(pa[1], host,      CHARPTR, &cfg->pszHost);
+    L2_PARAM_SET(pa[2], port,      INT,     &cfg->iPort);
+    L2_PARAM_END(pa[3]);
     rv = l2_util_setparams(pa, fmt, ap);
 
     return rv;
@@ -141,6 +146,7 @@
     struct hostent      *pHostentry;
     struct sockaddr_in  IP4Sockaddr;
     struct sockaddr_in6 IP6Sockaddr;
+    struct in6_addr     *IP6Addr;
 
     /* parameter checks */
     if ((cfg = (l2_ch_socket_t *)ctx->vp) == NULL)
@@ -149,45 +155,85 @@
         return L2_ERROR;
 
     /* open channel socket      */
-    /* resolve host numerically */
-    if (inet_pton1(AF_INET, cfg->pszHost, &IP4Sockaddr.sin_addr.s_addr) == 1)
-    {
-        IP4Sockaddr.sin_family = AF_INET;
-        IP4Sockaddr.sin_port   = htons(cfg->iPort);
-    }
-
-    /* resolve host nominally   */
-    else if ((pHostentry = gethostbyname(cfg->pszHost)) != NULL)
+    if (cfg->iFamily == AF_INET) /* IPv4 */
     {
-        if (pHostentry->h_addrtype == AF_INET)
+        /* resolve host numerically */
+        if (inet_pton(AF_INET, cfg->pszHost, &IP4Sockaddr.sin_addr.s_addr) == 1)
         {
             IP4Sockaddr.sin_family = AF_INET;
             IP4Sockaddr.sin_port   = htons(cfg->iPort);
-            memcpy(&IP4Sockaddr.sin_addr.s_addr, pHostentry->h_addr_list[0],\
-                sizeof(IP4Sockaddr.sin_addr.s_addr));
         }
 
-        else if (pHostentry->h_addrtype == AF_INET6)
+        /* resolve host nominally */
+        else if ((pHostentry = gethostbyname(cfg->pszHost)) != NULL)
+        {
+            if (pHostentry->h_addrtype == AF_INET)
+            {
+                IP4Sockaddr.sin_family = AF_INET;
+                IP4Sockaddr.sin_port   = htons(cfg->iPort);
+                memcpy(&IP4Sockaddr.sin_addr.s_addr, pHostentry->h_addr_list[0],\
+                    sizeof(IP4Sockaddr.sin_addr.s_addr));
+            }
+
+            else
+                return L2_ERROR; /* what?? we specify IPv4 when it is not? */
+        }
+
+        else /* host string was not parsable for some reason */
+            return L2_ERROR;
+
+        if ((cfg->iSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
+            return L2_ERROR;
+
+        if (connect(cfg->iSocket, (struct sockaddr *)&IP4Sockaddr, sizeof(IP4Sockaddr)))
+        {
+            close(cfg->iSocket);
+            return L2_ERROR;
+        }
+
+        return L2_OK; /* we are connected */
+    }
+
+    else if (cfg->iFamily == AF_INET6) /* IPv6 */
+    {
+        /* resolve host numerically */
+        if (inet_pton(AF_INET6, cfg->pszHost, &IP6Sockaddr.sin6_addr.s6_addr) == 1)
         {
             IP6Sockaddr.sin6_family = AF_INET6;
             IP6Sockaddr.sin6_port   = htons(cfg->iPort);
-            memcpy(&IP6Sockaddr.sin6_addr.__u6_addr, pHostentry->h_addr_list[0],\
-                sizeof(IP6Sockaddr.sin6_addr.__u6_addr));
         }
-    }
 
-    else
-        return L2_ERROR;
+        /* resolve host nominally */
+        else if ((pHostentry = gethostbyname2(cfg->pszHost, AF_INET6)) != NULL)
+        {
+            if (pHostentry->h_addrtype == AF_INET6)
+            {
+                IP6Sockaddr.sin6_family = AF_INET6;
+                IP6Sockaddr.sin6_port   = htons(cfg->iPort);
+                memcpy(&IP6Sockaddr.sin6_addr.__u6_addr, pHostentry->h_addr_list[0],\
+                    sizeof(IP6Sockaddr.sin6_addr.__u6_addr));
+            }
 
-    if ((cfg->iSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
-        return L2_ERROR;
-    if (connect(cfg->iSocket, (struct sockaddr *)&IP4Sockaddr, sizeof(IP4Sockaddr)))
-    {
-        close(cfg->iSocket);
-        return L2_ERROR;
+            else
+                return L2_ERROR; /* what?? we specify IPv6 when it is not? */
+        }
+
+        else /* host string was not parsable for some reason */
+            return L2_ERROR;
+
+        if ((cfg->iSocket = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP)) == -1)
+            return L2_ERROR;
+
+        if (connect(cfg->iSocket, (struct sockaddr *)&IP6Sockaddr, sizeof(IP6Sockaddr)))
+        {
+            close(cfg->iSocket);
+            return L2_ERROR;
+        }
+
+        return L2_OK; /* we are connected */
     }
 
-    return L2_OK;
+    return L2_ERROR;
 }
 
 /* write to channel */
@@ -195,6 +241,8 @@
                       const char *buf, size_t buf_size)
 {
     l2_ch_socket_t *cfg;
+    size_t          sizeWrite;
+    size_t          sizeRemain;
 
     /* parameter checks */
     if ((cfg = (l2_ch_socket_t *)ctx->vp) == NULL)
@@ -202,9 +250,18 @@
     if (cfg->iSocket == -1)
         return L2_ERROR;
 
-    /* write message to channel socket */
-    if (send(cfg->iSocket, buf, buf_size, 0) == -1)
-        return L2_ERROR;
+    /* write message to channel socket, but check to make   */
+    /* sure that the whole message was successfully written */
+    sizeWrite  = 0;
+    sizeRemain = buf_size;
+    while(sizeRemain)
+    {
+        sizeWrite  = send(cfg->iSocket, buf + sizeWrite, sizeRemain, 0);
+        sizeRemain = sizeRemain - sizeWrite; /* how much is left? */
+
+        if (sizeWrite == -1)
+            return L2_ERROR;
+    }
 
     return L2_OK;
 }

CVSTrac 2.0.1