Index: ossp-pkg/l2/l2_ch_socket.c RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_ch_socket.c,v rcsdiff -q -kk '-r1.10' '-r1.11' -u '/v/ossp/cvs/ossp-pkg/l2/l2_ch_socket.c,v' 2>/dev/null --- 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 #include #include -#include #include #include @@ -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; }