original files of m241
This commit is contained in:
@@ -0,0 +1,790 @@
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipdhcpc6_shell.c,v $ $Revision: 1.13.18.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcpc6/src/ipdhcpc6_shell.c,v $
|
||||
* $Author: ulf $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcpc6_config.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_sock.h>
|
||||
#include <ipcom_sock6.h>
|
||||
#include <ipcom_list.h>
|
||||
#include <ipcom_hash.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_tmo2.h>
|
||||
|
||||
#include "ipdhcpc6.h"
|
||||
#include "ipdhcpc6_h.h"
|
||||
#include "ipdhcpc6_msg.h"
|
||||
#include "ipdhcpc6_if.h"
|
||||
#include "ipdhcpc6_ia.h"
|
||||
#include "ipdhcpc6_shell.h"
|
||||
#include "ipdhcpc6_attr.h"
|
||||
#include "ipdhcpc6_rtadv.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
typedef struct Ipdhcpc6_shell_args
|
||||
{
|
||||
Ipdhcpc6_context_t *context;
|
||||
Ipdhcpc6_tagcomm_buffer_t *buf;
|
||||
Ipdhcpc6_if_t *ifp;
|
||||
Ipdhcpc6_ia_t *ia;
|
||||
Ip_u32 cmd;
|
||||
} Ipdhcpc6_shell_args_t;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_STATIC int ipdhcpc6_shell_parse_ia_command(Ipdhcpc6_shell_args_t *args,
|
||||
Ipdhcpc6_tagcomm_tag_t *tag);
|
||||
IP_STATIC int ipdhcpc6_shell_parse_ia_command_attributes(Ipdhcpc6_shell_args_t *args,
|
||||
Ipdhcpc6_tagcomm_tag_t *tag);
|
||||
IP_STATIC int ipdhcpc6_shell_parse_ia_ifobj_attributes(Ipdhcpc6_shell_args_t *args,
|
||||
Ipdhcpc6_tagcomm_tag_t *tag);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
static Ipdhcpc6_tagcomm_parser_t ipdhcpc6_shell_commands[] =
|
||||
{
|
||||
{
|
||||
IPDHCPC6_CMD_IA_INFO,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t) ipdhcpc6_shell_parse_ia_command
|
||||
},
|
||||
|
||||
{
|
||||
IPDHCPC6_CMD_IA_REFRESH,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t) ipdhcpc6_shell_parse_ia_command
|
||||
},
|
||||
|
||||
{
|
||||
IPDHCPC6_CMD_IA_RELEASE,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t) ipdhcpc6_shell_parse_ia_command
|
||||
},
|
||||
|
||||
{
|
||||
IPDHCPC6_CMD_IA_HISTORY_FLUSH,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t) ipdhcpc6_shell_parse_ia_command
|
||||
},
|
||||
|
||||
{
|
||||
IPDHCPC6_CMD_IA_RTSOL,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t) ipdhcpc6_shell_parse_ia_command
|
||||
},
|
||||
|
||||
{
|
||||
IPDHCPC6_CMD_IA_BOUND_ADD,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t) ipdhcpc6_shell_parse_ia_command
|
||||
},
|
||||
|
||||
{
|
||||
IPDHCPC6_CMD_IA_BOUND_DEL,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t) ipdhcpc6_shell_parse_ia_command
|
||||
},
|
||||
|
||||
{ 0, IP_NULL }
|
||||
};
|
||||
|
||||
|
||||
static Ipdhcpc6_tagcomm_parser_t ipdhcpc6_shell_ia_command_attributes[] =
|
||||
{
|
||||
{
|
||||
IPDHCPC6_IA_OBJECT_IF,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t) ipdhcpc6_shell_parse_ia_command_attributes
|
||||
},
|
||||
{
|
||||
IPDHCPC6_IA_IDENT_DUID,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t) ipdhcpc6_shell_parse_ia_command_attributes
|
||||
},
|
||||
{ 0, IP_NULL }
|
||||
};
|
||||
|
||||
static Ipdhcpc6_tagcomm_parser_t ipdhcpc6_shell_ia_ifobj_attributes[] =
|
||||
{
|
||||
{
|
||||
IPDHCPC6_IA_OBJECT_IF_AUTOMATIC,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t) ipdhcpc6_shell_parse_ia_ifobj_attributes
|
||||
},
|
||||
{
|
||||
IPDHCPC6_IA_OBJECT_IF_CONFIG,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t) ipdhcpc6_shell_parse_ia_ifobj_attributes
|
||||
},
|
||||
{
|
||||
IPDHCPC6_IA_OBJECT_IA,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t) ipdhcpc6_shell_parse_ia_ifobj_attributes
|
||||
},
|
||||
|
||||
{ 0, IP_NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_shell_context_client_free
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipdhcpc6_shell_context_client_free(Ipdhcpc6_shell_client_t *cfd)
|
||||
{
|
||||
ipcom_list_remove(&cfd->next);
|
||||
|
||||
ipdhcpc6_util_free(&cfd->rbuf.buffer);
|
||||
if (cfd->fd != IP_INVALID_SOCKET)
|
||||
ipcom_socketclose(cfd->fd);
|
||||
ipdhcpc6_util_free(&cfd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_shell_parse_errout
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipdhcpc6_shell_parse_errout(Ipdhcpc6_shell_args_t *args,
|
||||
Ipdhcpc6_tagcomm_tag_t *tag)
|
||||
{
|
||||
ipdhcpc6_tagcomm_failure(args->buf,
|
||||
tag,
|
||||
IPDHCPC6_TAGCOMM_STATUS_UNKNOWN_TAG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_shell_parse_ia_ifobj_attributes
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipdhcpc6_shell_parse_ia_ifobj_attributes(Ipdhcpc6_shell_args_t *args,
|
||||
Ipdhcpc6_tagcomm_tag_t *tag)
|
||||
{
|
||||
Ipdhcpc6_attr_ia_t *iaobj;
|
||||
|
||||
switch (tag->tag)
|
||||
{
|
||||
case IPDHCPC6_IA_OBJECT_IF_CONFIG:
|
||||
if (args->cmd == IPDHCPC6_CMD_IA_INFO)
|
||||
{
|
||||
ipdhcpc6_tagcomm_enter_tag(args->buf,
|
||||
IPDHCPC6_IA_OBJECT_IF_CONFIG,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK);
|
||||
ipdhcpc6_tagcomm_add_tag(args->buf,
|
||||
IPDHCPC6_IA_ATTR_IF_CONFIG_RAPID_COMMIT,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK,
|
||||
&args->ifp->conf.rapid_commit,
|
||||
sizeof(args->ifp->conf.rapid_commit));
|
||||
|
||||
ipdhcpc6_tagcomm_add_tag(args->buf,
|
||||
IPDHCPC6_IA_ATTR_IF_CONFIG_INFO_ONLY,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK,
|
||||
&args->ifp->conf.information_only,
|
||||
sizeof(args->ifp->conf.information_only));
|
||||
ipdhcpc6_tagcomm_add_tag(args->buf,
|
||||
IPDHCPC6_IA_ATTR_IF_CONFIG_DNS,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK,
|
||||
&args->ifp->conf.dns,
|
||||
sizeof(args->ifp->conf.dns));
|
||||
ipdhcpc6_tagcomm_add_tag(args->buf,
|
||||
IPDHCPC6_IA_ATTR_IF_CONFIG_SNTP,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK,
|
||||
&args->ifp->conf.sntp,
|
||||
sizeof(args->ifp->conf.sntp));
|
||||
ipdhcpc6_tagcomm_add_tag(args->buf,
|
||||
IPDHCPC6_IA_ATTR_IF_CONFIG_INFO_REFRESH,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK,
|
||||
&args->ifp->conf.information_only,
|
||||
sizeof(args->ifp->conf.information_only));
|
||||
ipdhcpc6_tagcomm_add_tag(args->buf,
|
||||
IPDHCPC6_IA_ATTR_IF_CONFIG_SIP,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK,
|
||||
&args->ifp->conf.sip,
|
||||
sizeof(args->ifp->conf.sip));
|
||||
|
||||
ipdhcpc6_tagcomm_add_tag(args->buf,
|
||||
IPDHCPC6_IA_ATTR_IF_CONFIG_FQDN,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK,
|
||||
&args->ifp->conf.fqdn.fqdn,
|
||||
sizeof(args->ifp->conf.fqdn.fqdn));
|
||||
ipdhcpc6_tagcomm_leave_tag(args->buf);
|
||||
}
|
||||
break;
|
||||
case IPDHCPC6_IA_OBJECT_IF_AUTOMATIC:
|
||||
if (args->cmd == IPDHCPC6_CMD_IA_INFO)
|
||||
{
|
||||
if (args->ifp->mode == IPDHCPC6_MODE_AUTOMATIC)
|
||||
{
|
||||
ipdhcpc6_tagcomm_enter_tag(args->buf,
|
||||
IPDHCPC6_IA_OBJECT_IF_AUTOMATIC,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK);
|
||||
if (IP_IN6_ARE_ADDR_EQUAL(&args->ifp->automatic.rtr, &ip_in6addr_any) == IP_FALSE)
|
||||
{
|
||||
ipdhcpc6_tagcomm_enter_tag(args->buf,
|
||||
IPDHCPC6_IA_OBJECT_SERVER,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK);
|
||||
|
||||
ipdhcpc6_tagcomm_add_tag(args->buf,
|
||||
IPDHCPC6_IA_ATTR_ADDRESS,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK,
|
||||
&args->ifp->automatic.rtr,
|
||||
sizeof(args->ifp->automatic.rtr));
|
||||
|
||||
|
||||
ipdhcpc6_tagcomm_leave_tag(args->buf);
|
||||
}
|
||||
|
||||
ipdhcpc6_tagcomm_add_tag(args->buf,
|
||||
IPDHCPC6_IA_ATTR_IF_AUTOMATIC_MANAGED,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK,
|
||||
&args->ifp->automatic.runtime.managed,
|
||||
sizeof(args->ifp->automatic.runtime.managed));
|
||||
ipdhcpc6_tagcomm_add_tag(args->buf,
|
||||
IPDHCPC6_IA_ATTR_IF_AUTOMATIC_OTHER,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK,
|
||||
&args->ifp->automatic.runtime.other,
|
||||
sizeof(args->ifp->automatic.runtime.other));
|
||||
ipdhcpc6_tagcomm_leave_tag(args->buf);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IPDHCPC6_IA_OBJECT_IA:
|
||||
iaobj = ipdhcpc6_attr_ia_parse(tag, IPDHCPC6_TAGCOMM_TAG_IDENTITY);
|
||||
if (iaobj)
|
||||
{
|
||||
if (iaobj->iatype >= IPDHCPC6_IA_TYPE_MAX)
|
||||
{
|
||||
ipdhcpc6_tagcomm_failure(args->buf,
|
||||
tag,
|
||||
IPDHCPC6_ATTR_TAG_STATUS_UNKNOWN_IA);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not specified */
|
||||
if (iaobj->ianame == IP_NULL && iaobj->iaid == 0)
|
||||
{
|
||||
args->ia = IPCOM_LIST_FIRST(&args->ifp->ia_head[iaobj->iatype]);
|
||||
while (args->ia != IP_NULL)
|
||||
{
|
||||
args->ia->table->attributes(args->cmd,
|
||||
args->ia,
|
||||
tag,
|
||||
args->buf);
|
||||
|
||||
/* Next IA */
|
||||
args->ia = IPCOM_LIST_NEXT(&args->ia->next);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
args->ia = ipdhcpc6_ia_lookup_by_iaobj(args->ifp, iaobj);
|
||||
if (args->ia == IP_NULL)
|
||||
{
|
||||
ipdhcpc6_tagcomm_failure(args->buf,
|
||||
tag,
|
||||
IPDHCPC6_ATTR_TAG_STATUS_UNKNOWN_IA);
|
||||
}
|
||||
else
|
||||
{
|
||||
args->ia->table->attributes(args->cmd,
|
||||
args->ia,
|
||||
tag,
|
||||
args->buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ipdhcpc6_attr_ia_free(&iaobj);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipdhcpc6_tagcomm_failure(args->buf,
|
||||
tag,
|
||||
IPDHCPC6_TAGCOMM_STATUS_PARSE_FAILED);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_shell_parse_ia_command_attributes
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipdhcpc6_shell_parse_ia_command_attributes(Ipdhcpc6_shell_args_t *args,
|
||||
Ipdhcpc6_tagcomm_tag_t *tag)
|
||||
{
|
||||
int result = 0;
|
||||
Ipdhcpc6_attr_if_t *ifobj;
|
||||
|
||||
/* Store base command */
|
||||
switch (tag->tag)
|
||||
{
|
||||
case IPDHCPC6_IA_OBJECT_IF:
|
||||
|
||||
ifobj = ipdhcpc6_attr_if_parse(tag, IPDHCPC6_TAGCOMM_TAG_IDENTITY);
|
||||
if (ifobj)
|
||||
{
|
||||
if (ifobj->ifname == IP_NULL)
|
||||
{
|
||||
/* Wild card match */
|
||||
args->ifp = IPCOM_LIST_FIRST(&args->context->ifctx->ifp_head);
|
||||
while (args->ifp != IP_NULL)
|
||||
{
|
||||
ipdhcpc6_tagcomm_enter_tag(args->buf, tag->tag, IPDHCPC6_TAGCOMM_STATUS_OK);
|
||||
ipdhcpc6_if_attr_header(args->ifp, args->buf);
|
||||
|
||||
switch (args->cmd)
|
||||
{
|
||||
case IPDHCPC6_CMD_IA_RTSOL:
|
||||
ipdhcpc6_rtadv_up(args->ifp->context->context, args->ifp);
|
||||
break;
|
||||
default:
|
||||
result = ipdhcpc6_tagcomm_parse(ipdhcpc6_shell_ia_ifobj_attributes,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t)ipdhcpc6_shell_parse_errout,
|
||||
tag,
|
||||
args);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
ipdhcpc6_tagcomm_leave_tag(args->buf);
|
||||
|
||||
if (result != 0)
|
||||
break;
|
||||
|
||||
/* Next interface */
|
||||
args->ifp = IPCOM_LIST_NEXT(&args->ifp->next);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
args->ifp = ipdhcpc6_if_lookup_by_ifobj(args->context, ifobj);
|
||||
if (args->ifp == IP_NULL)
|
||||
{
|
||||
ipdhcpc6_tagcomm_failure(args->buf,
|
||||
tag,
|
||||
IPDHCPC6_ATTR_TAG_STATUS_UNKNOWN_INTERFACE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipdhcpc6_tagcomm_enter_tag(args->buf, tag->tag, IPDHCPC6_TAGCOMM_STATUS_OK);
|
||||
ipdhcpc6_if_attr_header(args->ifp, args->buf);
|
||||
|
||||
switch (args->cmd)
|
||||
{
|
||||
case IPDHCPC6_CMD_IA_RTSOL:
|
||||
ipdhcpc6_rtadv_up(args->ifp->context->context, args->ifp);
|
||||
break;
|
||||
default:
|
||||
result = ipdhcpc6_tagcomm_parse(ipdhcpc6_shell_ia_ifobj_attributes,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t)ipdhcpc6_shell_parse_errout,
|
||||
tag,
|
||||
args);
|
||||
break;
|
||||
}
|
||||
|
||||
ipdhcpc6_tagcomm_leave_tag(args->buf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ipdhcpc6_attr_if_free(&ifobj);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipdhcpc6_tagcomm_failure(args->buf,
|
||||
tag,
|
||||
IPDHCPC6_TAGCOMM_STATUS_PARSE_FAILED);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_shell_parse_ia_command
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipdhcpc6_shell_parse_ia_command(Ipdhcpc6_shell_args_t *args,
|
||||
Ipdhcpc6_tagcomm_tag_t *tag)
|
||||
{
|
||||
int result;
|
||||
|
||||
/* Store base command */
|
||||
args->cmd = tag->tag;
|
||||
|
||||
ipdhcpc6_tagcomm_enter_tag(args->buf, tag->tag, IPDHCPC6_TAGCOMM_STATUS_OK);
|
||||
|
||||
/* Add the DUID */
|
||||
ipdhcpc6_tagcomm_add_tag(args->buf,
|
||||
IPDHCPC6_IA_IDENT_DUID,
|
||||
IPDHCPC6_TAGCOMM_STATUS_OK,
|
||||
args->context->ifctx->duid.head,
|
||||
args->context->ifctx->duid.offset);
|
||||
|
||||
result = ipdhcpc6_tagcomm_parse(ipdhcpc6_shell_ia_command_attributes,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t)ipdhcpc6_shell_parse_errout,
|
||||
tag,
|
||||
args);
|
||||
|
||||
|
||||
ipdhcpc6_tagcomm_leave_tag(args->buf);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_shell_command
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipdhcpc6_shell_parse_command(Ipdhcpc6_context_t *context,
|
||||
Ipdhcpc6_tagcomm_tag_t *tag,
|
||||
Ipdhcpc6_tagcomm_buffer_t *response)
|
||||
{
|
||||
Ipdhcpc6_shell_args_t args;
|
||||
|
||||
ipcom_memset(&args, 0, sizeof(args));
|
||||
|
||||
args.context = context;
|
||||
args.buf = response;
|
||||
|
||||
return ipdhcpc6_tagcomm_parse(ipdhcpc6_shell_commands,
|
||||
(Ipdhcpc6_tagcomm_parse_object_t)ipdhcpc6_shell_parse_errout,
|
||||
tag,
|
||||
&args);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_shell_context_alloc
|
||||
*===========================================================================
|
||||
* Description: Allocate an shell context
|
||||
* Parameters: context - The DHCPC6 context.
|
||||
* Returns: An shell context.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipdhcpc6_shell_context_t *
|
||||
ipdhcpc6_shell_context_alloc(struct Ipdhcpc6_context *context)
|
||||
{
|
||||
Ipdhcpc6_shell_context_t *shellctx = ipcom_calloc(1, sizeof(*shellctx));
|
||||
if (shellctx)
|
||||
{
|
||||
struct Ip_sockaddr_in6 sin6;
|
||||
int opt;
|
||||
|
||||
shellctx->context = context;
|
||||
|
||||
/* Create the client head */
|
||||
ipcom_list_init(&shellctx->head);
|
||||
|
||||
/* Create the FD */
|
||||
shellctx->client_fd = ipcom_socket(IP_AF_INET6, IP_SOCK_STREAM, IP_IPPROTO_TCP);
|
||||
if (shellctx->client_fd == IP_INVALID_SOCKET)
|
||||
goto errout;
|
||||
|
||||
ipcom_memset(&sin6, 0, sizeof(sin6));
|
||||
sin6.sin6_family = IP_AF_INET6;
|
||||
sin6.sin6_len = sizeof(sin6);
|
||||
sin6.sin6_port = ip_htons(IPDHCPC6_CLIENT_PORT);
|
||||
sin6.sin6_addr = ip_in6addr_loopback;
|
||||
|
||||
opt = 1;
|
||||
if (ipcom_setsockopt(shellctx->client_fd, IP_SOL_SOCKET, IP_SO_REUSEPORT, (char *)&opt, sizeof(opt)) < 0)
|
||||
{
|
||||
IPCOM_LOG2(WARNING,
|
||||
"%s: Failed to set reuse port on client socket, errno = %d", context->name, ipcom_errno);
|
||||
}
|
||||
|
||||
if (ipcom_bind(shellctx->client_fd, (struct Ip_sockaddr *) &sin6, sizeof(sin6)) < 0)
|
||||
{
|
||||
IPCOM_LOG2(ERR,
|
||||
"%s: Failed to bind client socket, errno = %d", context->name, ipcom_errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (ipcom_listen(shellctx->client_fd, 5) < 0)
|
||||
{
|
||||
IPCOM_LOG2(ERR,
|
||||
"%s: Failed to listen on client socket, errno = %d", context->name, ipcom_errno);
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
return shellctx;
|
||||
|
||||
errout:
|
||||
if (shellctx->client_fd != IP_INVALID_SOCKET)
|
||||
ipcom_socketclose(shellctx->client_fd);
|
||||
ipdhcpc6_util_free(&shellctx);
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_shell_context_free
|
||||
*===========================================================================
|
||||
* Description: Free an shell context
|
||||
* Parameters: shellctxp - Pointer to the DHCPC6 shellcontext.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcpc6_shell_context_free(Ipdhcpc6_shell_context_t **shellctxp)
|
||||
{
|
||||
Ipdhcpc6_shell_context_t *shellctx = *shellctxp;
|
||||
if (shellctx)
|
||||
{
|
||||
Ipdhcpc6_shell_client_t *cfd;
|
||||
while ((cfd = IPCOM_LIST_FIRST(&shellctx->head)) != IP_NULL)
|
||||
ipdhcpc6_shell_context_client_free(cfd);
|
||||
|
||||
ipcom_socketclose(shellctx->client_fd);
|
||||
ipdhcpc6_util_free(&shellctx);
|
||||
}
|
||||
|
||||
*shellctxp = IP_NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_shell_context_fdset_init
|
||||
*===========================================================================
|
||||
* Description: Initialize all file descriptors of this context
|
||||
* Parameters: shellctx - Attribute context
|
||||
* rset - Read set to initialize.
|
||||
* mfd - Maximum file descriptor.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcpc6_shell_context_fdset_init(Ipdhcpc6_shell_context_t *shellctx,
|
||||
Ip_fd_set *rset,
|
||||
int *mfd)
|
||||
{
|
||||
int maxfd = *mfd;
|
||||
Ipdhcpc6_shell_client_t *cfd;
|
||||
|
||||
/* Add the client socket */
|
||||
IP_FD_SET(shellctx->client_fd, rset);
|
||||
maxfd = IP_MAX(shellctx->client_fd, maxfd);
|
||||
|
||||
cfd = IPCOM_LIST_FIRST(&shellctx->head);
|
||||
while (cfd != IP_NULL)
|
||||
{
|
||||
IP_FD_SET(cfd->fd, rset);
|
||||
maxfd = IP_MAX(cfd->fd, maxfd);
|
||||
cfd = IPCOM_LIST_NEXT(&cfd->next);
|
||||
}
|
||||
|
||||
*mfd = maxfd;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_shell_context_fdset_process
|
||||
*===========================================================================
|
||||
* Description: Process all file descriptors of this context
|
||||
* Parameters: shellctx - Attribute context
|
||||
* rset - Read set to initialize.
|
||||
* status - Incoming status
|
||||
* Returns: Outgoing status
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL int
|
||||
ipdhcpc6_shell_context_fdset_process(Ipdhcpc6_shell_context_t *shellctx,
|
||||
Ip_fd_set *rset,
|
||||
int status)
|
||||
{
|
||||
Ipdhcpc6_shell_client_t *cfd, *ncfd;
|
||||
/* Check the clients */
|
||||
|
||||
cfd = IPCOM_LIST_FIRST(&shellctx->head);
|
||||
while (cfd != IP_NULL)
|
||||
{
|
||||
Ip_ssize_t ret;
|
||||
ncfd = IPCOM_LIST_NEXT(&cfd->next);
|
||||
|
||||
/**/
|
||||
if (IP_FD_ISSET(cfd->fd, rset))
|
||||
{
|
||||
if (cfd->rbuf.buffer == IP_NULL)
|
||||
{
|
||||
if (ipdhcpc6_attr_recvhdr(cfd->fd, &cfd->rbuf) == IP_FALSE)
|
||||
{
|
||||
ipdhcpc6_shell_context_client_free(cfd);
|
||||
cfd = IP_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfd)
|
||||
{
|
||||
ret = ipdhcpc6_attr_read(cfd->fd, &cfd->rbuf, IP_FALSE);
|
||||
if (ret < 0)
|
||||
ipdhcpc6_shell_context_client_free(cfd);
|
||||
else if (ret == 0)
|
||||
{
|
||||
Ipdhcpc6_tagcomm_buffer_t *response = ipdhcpc6_tagcomm_buffer_alloc();
|
||||
|
||||
if (response)
|
||||
{
|
||||
/* We've got an entire command */
|
||||
if (ipdhcpc6_shell_parse_command(shellctx->context,
|
||||
(void *)cfd->rbuf.buffer,
|
||||
response) == 0)
|
||||
{
|
||||
ipdhcpc6_attr_sendmsg(cfd->fd, response);
|
||||
}
|
||||
|
||||
ipdhcpc6_tagcomm_buffer_free(&response);
|
||||
}
|
||||
|
||||
/* Free the current buffer */
|
||||
ipdhcpc6_util_free(&cfd->rbuf.buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do next */
|
||||
cfd = ncfd;
|
||||
}
|
||||
|
||||
/* Check the */
|
||||
if (IP_FD_ISSET(shellctx->client_fd, rset))
|
||||
{
|
||||
/* Do create a new client */
|
||||
ncfd = ipcom_calloc(1, sizeof(*ncfd));
|
||||
if (ncfd)
|
||||
{
|
||||
struct Ip_sockaddr_in6 sin6;
|
||||
Ip_socklen_t slen = sizeof(sin6);
|
||||
|
||||
ipcom_list_insert_last(&shellctx->head, &ncfd->next);
|
||||
ncfd->fd = ipcom_accept(shellctx->client_fd, (struct Ip_sockaddr *)&sin6, &slen);
|
||||
|
||||
if (ncfd->fd == IP_INVALID_SOCKET)
|
||||
ipdhcpc6_shell_context_client_free(ncfd);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
Reference in New Issue
Block a user