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.17' '-r1.18' -u '/v/ossp/cvs/ossp-pkg/l2/l2_ch_socket.c,v' 2>/dev/null --- l2_ch_socket.c 2001/09/06 16:14:54 1.17 +++ l2_ch_socket.c 2001/09/06 19:28:24 1.18 @@ -50,37 +50,37 @@ struct in_addr IP4Addr; struct in6_addr IP6Addr; char *pszIndex = NULL; /* To index IPv6 validity */ - char *pszNextfield = NULL; /* For IPv6 address trans */ + char *pszNextfield = -1; /* For IPv6 address trans */ if (iFamily == AF_INET) { if (inet_aton(pszAddress, &IP4Addr)) { memcpy(pvMemref, &IP4Addr, sizeof(struct in_addr)); - return 1; + return 1; /* Success */ } return 0; } 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 */ + pszIndex = pszAddress; /* Initialize, verify in loop */ + for (i = 0; (i < 8) && pszNextfield; i++) /* Iterate through fields */ { 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 + 1; + } + + if ((i != 8) || (*pszNextfield)) + return 0; - pszIndex = ++pszNextfield; + else /* Success */ + { + memcpy(pvMemref, &IP6Addr, sizeof(struct in6_addr)); + return 1; } - memcpy(pvMemref, &IP6Addr, sizeof(struct in6_addr)); - return 1; } else /* User converting from an address family that we don't support */ @@ -96,10 +96,11 @@ /* 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 */ + char *pszHost; /* IP Address or name of host to connect to */ + int iFamily; /* IP version to use, AF_INET4 or AF_INET6 */ + int iProto; /* Protocol to use, IPPROTO_TCP or IPPROTO_UDP */ + int iPort; /* TCP Port to connect to */ + int iSocket; /* Socket descriptor used during writing */ } l2_ch_socket_t; /* create channel */ @@ -113,6 +114,8 @@ /* initialize configuration with reasonable defaults */ cfg->pszHost = NULL; + cfg->iFamily = -1; + cfg->iProto = -1; cfg->iPort = 0; cfg->iSocket = -1; @@ -126,14 +129,15 @@ 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_ch_socket_t *)ctx->vp; - l2_param_t pa[4]; + l2_param_t pa[5]; l2_result_t rv; /* feed and call generic parameter parsing engine */ 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]); + L2_PARAM_SET(pa[1], protocol, INT, &cfg->iProto ); + L2_PARAM_SET(pa[2], host, CHARPTR, &cfg->pszHost); + L2_PARAM_SET(pa[3], port, INT, &cfg->iPort ); + L2_PARAM_END(pa[4]); rv = l2_util_setparams(pa, fmt, ap); return rv; @@ -142,11 +146,12 @@ /* open channel */ static l2_result_t hook_open(l2_context_t *ctx, l2_channel_t *ch) { - l2_ch_socket_t *cfg = (l2_ch_socket_t *)ctx->vp; - struct hostent *pHostentry; - struct sockaddr_in IP4Sockaddr; + int i; + l2_ch_socket_t *cfg = (l2_ch_socket_t *)ctx->vp; + struct hostent *pHostentry; + struct sockaddr_in IP4Sockaddr; struct sockaddr_in6 IP6Sockaddr; - struct in6_addr *IP6Addr; + struct in6_addr *IP6Addr; /* make sure a target is configured */ if (cfg->pszHost == NULL) @@ -175,15 +180,22 @@ else /* host string was not parsable for some reason */ return L2_ERR_SYS; - if ((cfg->iSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) - return L2_ERR_SYS; + if (cfg->iProto == IPPROTO_TCP) /* With TCP we must connect */ + { + if ((cfg->iSocket = socket(PF_INET, SOCK_STREAM, cfg->iProto)) == -1) + return L2_ERR_SYS; - if (connect(cfg->iSocket, (struct sockaddr *)&IP4Sockaddr, sizeof(IP4Sockaddr))) { - close(cfg->iSocket); - return L2_ERR_SYS; + if (connect(cfg->iSocket, (struct sockaddr *)&IP4Sockaddr, sizeof(IP4Sockaddr))) + { + close(cfg->iSocket); + return L2_ERR_SYS; + } } + else if (cfg->iProto == IPPROTO_UDP) /* With UDP we do not connect */ + if ((cfg->iSocket = socket(PF_INET, SOCK_DGRAM, cfg->iProto)) == -1) + return L2_ERR_SYS; - return L2_OK; /* we are connected */ + return L2_OK; } else if (cfg->iFamily == AF_INET6) { /* IPv6 */ @@ -208,15 +220,21 @@ else /* host string was not parsable for some reason */ return L2_ERR_SYS; - if ((cfg->iSocket = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP)) == -1) - return L2_ERR_SYS; - - if (connect(cfg->iSocket, (struct sockaddr *)&IP6Sockaddr, sizeof(IP6Sockaddr))) { - close(cfg->iSocket); - return L2_ERR_SYS; + if (cfg->iProto == IPPROTO_TCP) { /* With TCP we must connect */ + if ((cfg->iSocket = socket(PF_INET6, SOCK_STREAM, cfg->iProto)) == -1) + return L2_ERR_SYS; + + if (connect(cfg->iSocket, (struct sockaddr *)&IP6Sockaddr,\ + sizeof(IP6Sockaddr))) { + close(cfg->iSocket); + return L2_ERR_SYS; + } } + else if (cfg->iProto == IPPROTO_UDP) /* With UDP we do not connect */ + if ((cfg->iSocket = socket(PF_INET, SOCK_DGRAM, cfg->iProto)) == -1) + return L2_ERR_SYS; - return L2_OK; /* we are connected */ + return L2_OK; } return L2_ERR_USE; @@ -226,23 +244,64 @@ static l2_result_t hook_write(l2_context_t *ctx, l2_channel_t *ch, const char *buf, size_t buf_size) { - l2_ch_socket_t *cfg = (l2_ch_socket_t *)ctx->vp; - size_t sizeWrite; - size_t sizeRemain; + struct sockaddr_in IP4Sockaddr, IP6Sockaddr; + l2_ch_socket_t *cfg = (l2_ch_socket_t *)ctx->vp; + size_t sizeWrite; + size_t sizeRemain; /* parameter checks */ if (cfg->iSocket == -1) - return L2_ERR_USE; + return L2_ERR_ARG; - /* 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; - if (sizeWrite == -1) - return L2_ERR_SYS; + if (cfg->iProto == IPPROTO_TCP) + { + /* 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_ERR_SYS; + } + } + + else if (cfg->iProto == IPPROTO_UDP) + { + /* write message to the host target, but check to make */ + /* sure that the whole message was successfully written */ + sizeWrite = 0; + sizeRemain = buf_size; + while(sizeRemain) + { + if (cfg->iFamily == AF_INET) /* IPv4 */ + { +/* TODO !!! */ sizeWrite = sendto(cfg->iSocket, buf + sizeWrite, sizeRemain, 0,\ +/* Fill in */ (struct sockaddr *)&IP4Sockaddr, sizeof(IP4Sockaddr)); +/* the host */ +/* address */ sizeRemain = sizeRemain - sizeWrite; /* how much is left? */ +/* structs */ + if (sizeWrite == -1) + return L2_ERR_SYS; + } + + else if (cfg->iFamily == AF_INET6) /* IPv6 */ + { + /* TODO !!! */ sizeWrite = sendto(cfg->iSocket, buf + sizeWrite, sizeRemain, 0,\ + /* Fill in */ (struct sockaddr *)&IP6Sockaddr, sizeof(IP6Sockaddr)); + /* the host */ + /* address */ sizeRemain = sizeRemain - sizeWrite; /* how much is left? */ + /* structs */ + if (sizeWrite == -1) + return L2_ERR_USE; + } + + else /* Neither IPv4 nor IPv6 */ + return L2_ERR_USE; + } } return L2_OK;