--- 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;
|