OSSP CVS Repository

ossp - Difference in ossp-pkg/l2/l2_ch_socket.c versions 1.5 and 1.6
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/l2/l2_ch_socket.c 1.5 -> 1.6

--- l2_ch_socket.c       2001/08/26 13:07:27     1.5
+++ l2_ch_socket.c       2001/09/02 14:38:51     1.6
@@ -27,37 +27,86 @@
 **  l2_ch_socket.c: socket channel implementation
 */
 
-#include "l2.h"
-#include "l2_p.h"
-
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+
+#include "l2.h"
+#include "l2_p.h"
+
+#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)
+{
+    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 */
+
+    if (iFamily == AF_INET)
+    {
+        if (inet_aton(pszAddress, &IP4Addr))
+        {
+            memcpy(pvMemref, &IP4Addr, sizeof(struct in_addr));
+            return 1;
+        }
+        return 0;
+    }
+
+    else if (iFamily == AF_INET6)
+    {
+        for (i = 0; i < 16; 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)
+                return 0; /* User is supplying a IPv6 format we don't support */
+        }
+        memcpy(pvMemref, &IP6Addr, sizeof(struct in6_addr));
+        return 1;
+    }
+
+    else      /* User converting from an address family that we don't support */
+    {
+        errno = EAFNOSUPPORT;
+        return -1;
+    }
+}
+#else
+#error "neither inet_pton nor inet_aton available"
+#endif
+#endif
 
 /* declare private channel configuration */
-typedef struct {
-    int iSocket;             /* Socket descriptor                        */
-    int iDomain;             /* Hardcoded to support only IPv4 and IPv6  */
-    int iProtocol;           /* Hardcoded to support only IPv4 and IPv6  */
-    int iType;               /* Hardcoded for writing streams to iSocket */
-    struct sockaddr *pAddr;  /* Where do we open a socket?               */
+typedef struct
+{
+    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    */
 } l2_ch_socket_t;
 
 /* create channel */
 static int hook_create(l2_context_t *ctx)
 {
-    l2_ch_socket_t *cfg;
+    l2_ch_socket_t *cfg = NULL;
 
     /* allocate private channel configuration */
     if ((cfg = (l2_ch_socket_t *)malloc(sizeof(l2_ch_socket_t))) == NULL)
         return L2_ERROR;
 
     /* initialize configuration with reasonable defaults */
-    cfg->iSocket   = 0;
-    cfg->iDomain   = PF_INET;         /* Internet family             */
-    cfg->iType     = SOCK_STREAM;     /* We write streams reliably   */
-    cfg->iProtocol = IPPROTO_TCP;     /* TCP socket                  */
-    cfg->pAddr      = NULL;
+    cfg->pszHost   = NULL;
+    cfg->iPort     = 0;
+    cfg->iSocket   = -1;
 
     /* link private channel configuration into channel context */
     ctx->vp = cfg;
@@ -69,21 +118,16 @@
 static int hook_configure(l2_context_t *ctx, const char *fmt, va_list ap)
 {
     l2_ch_socket_t *cfg;
-    char pszAddress[L2_MAX_STRING];
-    unsigned short unInport;
     l2_param_t pa[3];
     l2_result_t rv;
 
-    unInport = 0;
-
     /* parameter checks */
     if ((cfg = (l2_ch_socket_t *)ctx->vp) == NULL)
         return L2_ERROR;
 
     /* feed and call generic parameter parsing engine */
-    L2_PARAM_SET(pa[0], address, CHARPTR, pszAddress);
-    L2_PARAM_SET(pa[1], port,    USHORT,     &unInport);
-/* TODO: Fill in the cfg-> structure after building the socket */
+    L2_PARAM_SET(pa[0], host, CHARPTR, &cfg->pszHost);
+    L2_PARAM_SET(pa[1], port, INT,     &cfg->iPort);
     L2_PARAM_END(pa[2]);
     rv = l2_channel_setparams(pa, fmt, ap);
 
@@ -93,13 +137,55 @@
 /* open channel */
 static int hook_open(l2_context_t *ctx, l2_channel_t *downstream)
 {
-    l2_ch_socket_t *cfg;
+    l2_ch_socket_t      *cfg;
+    struct hostent      *pHostentry;
+    struct sockaddr_in  IP4Sockaddr;
+    struct sockaddr_in6 IP6Sockaddr;
 
     /* parameter checks */
     if ((cfg = (l2_ch_socket_t *)ctx->vp) == NULL)
         return L2_ERROR;
+    if (cfg->pszHost == NULL)
+        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 (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 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));
+        }
+    }
+
+    else
+        return L2_ERROR;
 
-    /* open channel socket */
+    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;
+    }
 
     /* optionally open downstream channel, too */
     if (downstream != NULL)
@@ -118,8 +204,12 @@
     /* parameter checks */
     if ((cfg = (l2_ch_socket_t *)ctx->vp) == NULL)
         return L2_ERROR;
+    if (cfg->iSocket == -1)
+        return L2_ERROR;
 
     /* write message to channel socket */
+    if (send(cfg->iSocket, buf, buf_size, 0) == -1)
+        return L2_ERROR;
 
     /* optionally write to downstream channel, too */
     if (downstream != NULL)
@@ -132,6 +222,8 @@
 /* flush channel */
 static int hook_flush(l2_context_t *ctx, l2_channel_t *downstream)
 {
+    /* NOP for this channel, because Unix I/O sockets are unbuffered! */
+
     /* optionally flush downstream channel, too */
     if (downstream != NULL)
         if (l2_channel_flush(downstream) == L2_ERROR)
@@ -153,8 +245,12 @@
     /* parameter checks */
     if ((cfg = (l2_ch_socket_t *)ctx->vp) == NULL)
         return L2_ERROR;
+    if (cfg->iSocket == -1)
+        return L2_ERROR;
 
     /* close channel socket */
+    if ((shutdown(cfg->iSocket, SHUT_RDWR)) || (close(cfg->iSocket)))
+        return L2_ERROR;
 
     return L2_OK;
 }

CVSTrac 2.0.1