 /*
  *  module_socket.c: Socket module
  *
  *  Copyright (C) 2007 Mindspeed Technologies, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */


#include "cmm.h"
#include "module_socket.h"
#include "fpp_private.h"
#include "fpp.h"
#include "cmmd.h"

struct list_head socket_table[HASH_SOCKET_SIZE];
struct list_head socket_table_by_addr[HASH_SOCKET_SIZE];

pthread_mutex_t socket_lock = PTHREAD_MUTEX_INITIALIZER;

static u_int32_t internal_sock_ids[ROUTE_MAX_ID / (8 * sizeof(u_int32_t))] = {0, };
static u_int32_t internal_sock_id = 0;

u_int32_t new_socket_id(void)
{
	int offset, mask;
	int i = 0;

	for ( ;i < NUM_INTERNAL_SOCKET_ID; i++, internal_sock_id++)
	{
		if (internal_sock_id >= NUM_INTERNAL_SOCKET_ID)
			internal_sock_id = 0;

		offset = internal_sock_id / (8 * sizeof(u_int32_t));
		mask = 1 << (internal_sock_id & 0x1f);
		if (!(internal_sock_ids[offset] & mask))
			goto found;

	}
	/* we're running in circles, return zero, we've exhausted all of our reserved sockets */
	return 0;

found:
	internal_sock_ids[offset] |= mask;

	return internal_sock_id + SOCK_ID_PRIVATE_START;
}

void del_socket_id(u_int32_t sock_id_ext)
{
	int sock_id = sock_id_ext - SOCK_ID_PRIVATE_START;
	int offset = sock_id / (8 * sizeof(u_int32_t));
	int mask = 1 << (sock_id & 0x1f);

	internal_sock_ids[offset] &= ~mask;
}

static struct socket *socket_find(u_int16_t id)
{
	struct socket *s;
	int key;
	struct list_head *entry;

	cmm_print(DEBUG_INFO, "%s: find socket(%d)\n", __func__, id);

	key = HASH_SOCKET(id);

	entry = list_first(&socket_table[key]);

	while (entry != &socket_table[key])
	{
		s = container_of(entry, struct socket, list);
		if (s->id == id)
			//Entry found
			goto found;
		entry = list_next(entry);
	}

	s = NULL;

found:
	return s;
}
struct socket *socket_find_by_addr(int family, const u_int32_t *saddr, const u_int32_t *daddr, u_int16_t sport, u_int16_t dport, u_int16_t proto)
{
	struct socket *s;
	int key;
	struct list_head *entry;
	int ip_len = IPADDRLEN(family);

	cmm_print(DEBUG_INFO, "%s: find socket by address\n", __func__);

	key= HASH_SOCK_ADDR(family, saddr, daddr, sport, dport, proto);

	entry = list_first(&socket_table_by_addr[key]);

	while (entry != &socket_table_by_addr[key])
	{
		s = container_of(entry, struct socket, list);
		if (memcmp(saddr, s->saddr, ip_len) && memcmp(daddr, s->daddr, ip_len) 
		&& (sport == s->sport) && (dport == s->dport) && (proto == s->proto))
			goto found;

		entry = list_next(entry);
	}

	s = NULL;

found:
	return s;
}
void __socket_add(struct socket * s)
{
	int key;

	key = HASH_SOCKET(s->id);
	list_add(&socket_table[key], &s->list);

	key= HASH_SOCK_ADDR(s->family, s->saddr, s->daddr, s->sport, s->dport, s->proto);
	list_add(&socket_table_by_addr[key], &s->list_by_addr);

#ifdef COMCERTO_2000
	s->rx_flow = __cmmFlowGet(s->family, s->saddr, s->daddr, s->sport, s->dport, s->proto); /*tx and rx flows are swapped for sockets (L2TP sockets.), this is because unlike RTP Relay, for L2TP a single socket is used, so the socket is created with daddr  as local address and saddr as peer address. This might need revisiting if the flows are extended for other sockets  */ 
	s->tx_flow = __cmmFlowGet(s->family, s->daddr, s->saddr, s->dport, s->sport, s->proto);
	if( s->rx_flow || s->tx_flow )
		s->secure = 1;
#endif

}

static struct socket *socket_add(cmmd_socket_open_cmd_t *cmd)
{
	struct socket *s;


	s = malloc(sizeof(struct socket));
	if (!s)
	{
		cmm_print(DEBUG_ERROR, "%s: malloc() failed\n", __func__);
		goto err;
	}

	memset(s, 0, sizeof(struct socket));

	s->id = cmd->id;
	s->family = cmd->family;
	s->type = cmd->type;
	s->mode = cmd->mode;
	memcpy(s->saddr, cmd->saddr, IPADDRLEN(s->family));
	memcpy(s->daddr, cmd->daddr, IPADDRLEN(s->family));
	s->sport = cmd->sport;
	s->dport = cmd->dport;
	s->proto = cmd->proto;
	s->queue = cmd->queue;
	s->dscp = cmd->dscp;
	s->fwmark = cmd->fwmark;

	__socket_add(s);
err:
	return s;
}

void socket_remove(struct socket *s)
{
	list_del(&s->list);
	list_del(&s->list_by_addr);

	if((s->id >= SOCK_ID_PRIVATE_START) && (s->id <=  SOCK_ID_PRIVATE_END))
		del_socket_id(s->id);

	free(s);
}


/************************************************************
 *
 * socket4_send_cmd
 * Role: CMM to FPP commands in deamon context
 ************************************************************/
static int socket4_send_cmd(FCI_CLIENT *fci_handle, int action, struct socket *s)
{
	int ret = CMMD_ERR_OK;

	switch (action)
	{
	default:
		ret = CMMD_ERR_UNKNOWN_ACTION;
		break;

	case FPP_ACTION_REGISTER:
	{
		fpp_socket4_open_cmd_t cmd;

		memset(&cmd, 0, sizeof(cmd));

		cmd.id = s->id;
		cmd.type = s->type;
		cmd.mode = s->mode; 
		cmd.saddr = s->saddr[0];
		cmd.daddr = s->daddr[0];
		cmd.sport = s->sport;
		cmd.dport = s->dport;
		cmd.proto = s->proto;
		cmd.queue = s->queue;
		cmd.dscp = s->dscp;
		cmd.route_id = s->rt.fpp_route_id;
#ifdef COMCERTO_2000
		cmd.secure = s->secure;
		if (s->rx_flow)
		{
			int i;
			cmd.sa_nr_rx = s->rx_flow->sa_nr;
			for (i = 0; i < cmd.sa_nr_rx; i++)
				cmd.sa_handle_rx[i] = s->rx_flow->sa_handle[i];
		}
		if (s->tx_flow)
		{
			int i;
			cmd.sa_nr_tx = s->tx_flow->sa_nr;
			for (i = 0; i < cmd.sa_nr_tx; i++)
				cmd.sa_handle_tx[i] = s->tx_flow->sa_handle[i];
		}
#endif

		//Send message to forward engine
		cmm_print(DEBUG_COMMAND, "Send CMD_IPV4_SOCK_OPEN\n");

		ret = fci_write(fci_handle, FPP_CMD_IPV4_SOCK_OPEN, sizeof(fpp_socket4_open_cmd_t), (u_int16_t *) &cmd);
		if (ret == FPP_ERR_OK)
		{
			s->flags |= FPP_PROGRAMMED;
			s->flags &= ~FPP_NEEDS_UPDATE;
		}
		else
		{
			if (ret > 0)
				cmm_print(DEBUG_ERROR, "%s: Error %d while sending CMD_IPV4_SOCK_OPEN\n", __func__, ret);
			else
				cmm_print(DEBUG_ERROR, "%s: Error '%s' while sending CMD_IPV4_SOCK_OPEN\n", __func__, strerror(errno));
			break;
		}
	}

		break;

	case FPP_ACTION_UPDATE:
	{
		fpp_socket4_update_cmd_t cmd;

		memset(&cmd, 0, sizeof(cmd));

		cmd.id = s->id;
		cmd.saddr = s->saddr[0];
		cmd.sport = s->sport;
		cmd.queue = s->queue;
		cmd.dscp = s->dscp;
		cmd.route_id = s->rt.fpp_route_id;
#ifdef COMCERTO_2000
		cmd.secure = s->secure;
		if (s->rx_flow)
		{
			int i;
			cmd.sa_nr_rx = s->rx_flow->sa_nr;
			for (i = 0; i < cmd.sa_nr_rx; i++)
				cmd.sa_handle_rx[i] = s->rx_flow->sa_handle[i];
		}
		if (s->tx_flow)
		{
			int i;
			cmd.sa_nr_tx = s->tx_flow->sa_nr;
			for (i = 0; i < cmd.sa_nr_tx; i++)
				cmd.sa_handle_tx[i] = s->tx_flow->sa_handle[i];
		}
#endif

		//Send message to forward engine
		cmm_print(DEBUG_COMMAND, "Send CMD_IPV4_SOCK_UPDATE\n");

		ret = fci_write(fci_handle, FPP_CMD_IPV4_SOCK_UPDATE, sizeof(fpp_socket4_update_cmd_t), (u_int16_t *) &cmd);
		if (ret == FPP_ERR_OK)
		{
			s->flags &= ~FPP_NEEDS_UPDATE;
		}
		else
		{
			if (ret > 0)
				cmm_print(DEBUG_ERROR, "%s: Error %d while sending CMD_IPV4_SOCK_UPDATE\n", __func__, ret);
			else
				cmm_print(DEBUG_ERROR, "%s: Error '%s' while sending CMD_IPV4_SOCK_UPDATE\n", __func__, strerror(errno));
			break;
		}
	}

		break;

	case FPP_ACTION_DEREGISTER:
	{
		fpp_socket4_close_cmd_t cmd;

		memset(&cmd, 0, sizeof(cmd));

		//Send message to forward engine
		cmm_print(DEBUG_COMMAND, "Send CMD_IPV4_SOCK_CLOSE\n");

		cmd.id = s->id;

		ret = fci_write(fci_handle, FPP_CMD_IPV4_SOCK_CLOSE, sizeof(fpp_socket4_close_cmd_t), (unsigned short *) &cmd);
		if (ret == FPP_ERR_OK)
		{
			s->flags &= ~FPP_PROGRAMMED;
		}
		else
		{
			if (ret > 0)
				cmm_print(DEBUG_ERROR, "%s: Error %d while sending CMD_IPV4_SOCK_CLOSE\n", __func__, ret);
			else
				cmm_print(DEBUG_ERROR, "%s: Error '%s' while sending CMD_IPV4_SOCK_CLOSE\n", __func__, strerror(errno));
			break;
		}
	}
		break;
	}

	return ret;
}

/************************************************************
 *
 * socket6_send_cmd
 * Role: CMM to FPP commands in deamon context
 ************************************************************/
static int socket6_send_cmd(FCI_CLIENT *fci_handle, int action, struct socket *s)
{
	int ret = CMMD_ERR_OK;

	switch (action)
	{
	default:
		ret = CMMD_ERR_UNKNOWN_ACTION;
		break;
	case FPP_ACTION_REGISTER:
	{
		fpp_socket6_open_cmd_t cmd;

		memset(&cmd, 0, sizeof(cmd));

		cmd.id = s->id;
		cmd.type = s->type;
		cmd.mode = s->mode; 
		memcpy(cmd.saddr, s->saddr, 16);
		memcpy(cmd.daddr, s->daddr, 16);
		cmd.sport = s->sport;
		cmd.dport = s->dport;
		cmd.proto = s->proto;
		cmd.queue = s->queue;
		cmd.dscp = s->dscp;
		cmd.route_id = s->rt.fpp_route_id;
#ifdef COMCERTO_2000
		if (s->rx_flow)
		{
			int i;
			cmd.secure = 1;
			cmd.sa_nr_rx = s->rx_flow->sa_nr;
			for (i = 0; i < cmd.sa_nr_rx; i++)
				cmd.sa_handle_rx[i] = s->rx_flow->sa_handle[i];
		}
		if (s->tx_flow)
		{
			int i;
			cmd.secure = 1;
			cmd.sa_nr_tx = s->tx_flow->sa_nr;
			for (i = 0; i < cmd.sa_nr_tx; i++)
				cmd.sa_handle_tx[i] = s->tx_flow->sa_handle[i];
		}
#endif

		//Send message to forward engine
		cmm_print(DEBUG_COMMAND, "Send CMD_IPV6_SOCK_OPEN\n");

		ret = fci_write(fci_handle, FPP_CMD_IPV6_SOCK_OPEN, sizeof(fpp_socket6_open_cmd_t), (u_int16_t *) &cmd);
		if (ret == FPP_ERR_OK)
		{
			s->flags |= FPP_PROGRAMMED;
			s->flags &= ~FPP_NEEDS_UPDATE;
		}
		else
		{
			if (ret > 0)
				cmm_print(DEBUG_ERROR, "%s: Error %d while sending CMD_IPV6_SOCK_OPEN\n", __func__, ret);
			else
				cmm_print(DEBUG_ERROR, "%s: Error '%s' while sending CMD_IPV6_SOCK_OPEN\n", __func__, strerror(errno));
			break;
		}
	}

		break;

	case FPP_ACTION_UPDATE:
	{
		fpp_socket6_update_cmd_t cmd;

		memset(&cmd, 0, sizeof(cmd));

		cmd.id = s->id;
		memcpy(cmd.saddr, s->saddr, 16);
		cmd.sport = s->sport;
		cmd.queue = s->queue;
		cmd.dscp = s->dscp;
		cmd.route_id = s->rt.fpp_route_id;
#ifdef COMCERTO_2000
		if (s->rx_flow)
		{
			int i;
			cmd.secure = 1;
			cmd.sa_nr_rx = s->rx_flow->sa_nr;
			for (i = 0; i < cmd.sa_nr_rx; i++)
				cmd.sa_handle_rx[i] = s->rx_flow->sa_handle[i];
		}
		if (s->tx_flow)
		{
			int i;
			cmd.secure = 1;
			cmd.sa_nr_tx = s->tx_flow->sa_nr;
			for (i = 0; i < cmd.sa_nr_tx; i++)
				cmd.sa_handle_tx[i] = s->tx_flow->sa_handle[i];
		}
#endif

		//Send message to forward engine
		cmm_print(DEBUG_COMMAND, "Send CMD_IPV6_SOCK_UPDATE\n");

		ret = fci_write(fci_handle, FPP_CMD_IPV6_SOCK_UPDATE, sizeof(fpp_socket6_update_cmd_t), (u_int16_t *) &cmd);
		if (ret == FPP_ERR_OK)
		{
			s->flags &= ~FPP_NEEDS_UPDATE;
		}
		else
		{
			if (ret > 0)
				cmm_print(DEBUG_ERROR, "%s: Error %d while sending CMD_IPV6_SOCK_UPDATE\n", __func__, ret);
			else
				cmm_print(DEBUG_ERROR, "%s: Error '%s' while sending CMD_IPV6_SOCK_UPDATE\n", __func__, strerror(errno));
			break;
		}
	}

		break;
	
	case FPP_ACTION_DEREGISTER:
	{
		fpp_socket6_close_cmd_t cmd;

		memset(&cmd, 0, sizeof(cmd));

		//Send message to forward engine
		cmm_print(DEBUG_COMMAND, "Send CMD_IPV6_SOCK_CLOSE\n");

		cmd.id = s->id;

		ret = fci_write(fci_handle, FPP_CMD_IPV6_SOCK_CLOSE, sizeof(fpp_socket6_close_cmd_t), (unsigned short *) &cmd);
		if (ret == FPP_ERR_OK)
		{
			s->flags &= ~FPP_PROGRAMMED;
		}
		else
		{
			if (ret > 0)
				cmm_print(DEBUG_ERROR, "%s: Error %d while sending CMD_IPV6_SOCK_CLOSE\n", __func__, ret);
			else
				cmm_print(DEBUG_ERROR, "%s: Error '%s' while sending CMD_IPV6_SOCK_CLOSE\n", __func__, strerror(errno));
			break;
		}
	}
		break;
	}

	return ret;
}


/************************************************************
 *
 * socket_send_cmd
 * Role: CMM to FPP commands in deamon context
 ************************************************************/
static int socket_send_cmd(FCI_CLIENT *fci_handle, int request, struct socket *s)
{
	int action;

	switch (request)
	{
	case (ADD | UPDATE):
		if ((s->flags & (FPP_PROGRAMMED | FPP_NEEDS_UPDATE)) == FPP_PROGRAMMED)
			return CMMD_ERR_OK;

		if ((s->flags & (FPP_PROGRAMMED | FPP_NEEDS_UPDATE)) == (FPP_PROGRAMMED | FPP_NEEDS_UPDATE))
			action = FPP_ACTION_UPDATE;
		else
			action = FPP_ACTION_REGISTER;

		break;

	case UPDATE:
		if (!((s->flags & FPP_PROGRAMMED) && (s->flags & FPP_NEEDS_UPDATE)))
			return CMMD_ERR_OK;

		action = FPP_ACTION_UPDATE;
		break;
	
	case REMOVE:
		if (!(s->flags & FPP_PROGRAMMED))
			return CMMD_ERR_OK;

		action = FPP_ACTION_DEREGISTER;

		break;

	default:
		cmm_print(DEBUG_ERROR, "%s: Action not supported\n", __func__);
		return CMMD_ERR_UNKNOWN_ACTION;
	}

	if (s->family == AF_INET)
		return socket4_send_cmd(fci_handle, action, s);
	else if (s->family == AF_INET6)
		return socket6_send_cmd(fci_handle, action, s);
	else
		return CMMD_ERR_UNKNOWN;
}

int __socket_open(FCI_CLIENT *fci_handle, struct socket *s)
{
	int rc;

	cmm_print(DEBUG_INFO, "%s\n", __func__);

	if ((s->type == CMMD_SOCKET_TYPE_LANWAN) || (s->type == CMMD_SOCKET_TYPE_L2TP))
	{
		struct flow flow = {
					.family = s->family,
					.sAddr = s->daddr,
					.dAddr = s->saddr,
					.fwmark = s->fwmark,
				};

		if (__cmmRouteRegister(&s->rt, &flow, 0, "socket") < 0)
		{
			goto program;
		}

		cmmFeRouteUpdate(fci_handle, ADD | UPDATE, s->rt.fpp_route);
	}


program:
	__cmmCheckFPPRouteIdUpdate(&s->rt, &s->flags);

	if(((s->rx_flow) && (s->rx_flow->flags & FPP_NEEDS_UPDATE ) )
		|| ((s->tx_flow) && (s->tx_flow->flags & FPP_NEEDS_UPDATE )))
		s->flags |= FPP_NEEDS_UPDATE;	

	rc = socket_send_cmd(fci_handle, ADD | UPDATE, s);

	return rc;
}


#ifdef COMCERTO_2000
/************************************************************
 *
 * __cmmSocketFindFromFlow
 *
 ************************************************************/
struct socket *__cmmSocketFindFromFlow(int family, unsigned int *saddr, unsigned int *daddr, unsigned char proto, char *orig)
{
	struct socket *s;
	struct list_head *entry;
	int i;

	for (i = 0; i < HASH_SOCKET_SIZE; i++)
	{
		for (entry = list_first(&socket_table[i]); entry != &socket_table[i]; entry = list_next(entry))
		{
			s = container_of(entry, struct socket, list);
			if (s->family == family && s->proto == proto)
			{
				if (!memcmp(s->saddr, saddr, IPADDRLEN(family)) && !memcmp(s->daddr, daddr, IPADDRLEN(family)))
				{
					*orig = 1;
					goto found;
				}

				if (!memcmp(s->saddr, daddr, IPADDRLEN(family)) && !memcmp(s->daddr, saddr, IPADDRLEN(family)))
				{
					*orig = 0;
					goto found;
				}
			}
		}
	}

	s = NULL;

found:
	return s;
}
#endif	// COMCERTO_2000

/************************************************************
 *
 * __cmmSocketUpdateWithRoute
 *
 ************************************************************/
void __cmmSocketUpdateWithRoute(FCI_CLIENT *fci_handle, struct RtEntry *route)
{
	struct socket *s;
	struct list_head *entry;
	struct fpp_rt *fpp_route;
	int i;
	
	__pthread_mutex_lock(&socket_lock);

	for (i = 0; i < HASH_SOCKET_SIZE; i++)
	{
		for (entry = list_first(&socket_table[i]); entry != &socket_table[i]; entry = list_next(entry))
		{
			s = container_of(entry, struct socket, list);

			if (s->rt.route == route)
			{
				fpp_route = s->rt.fpp_route;
				s->rt.fpp_route = NULL;

				__socket_open(fci_handle, s);

				__cmmFPPRouteDeregister(fci_handle, fpp_route, "socket");
			}
		}
	}

	__pthread_mutex_unlock(&socket_lock);
}


int __socket_close(FCI_CLIENT *fci_handle, FCI_CLIENT *fci_key_handle, struct socket *s)
{
	int rc = socket_send_cmd(fci_handle, REMOVE, s);
	if (rc != CMMD_ERR_OK)
		return rc;

	__cmmRouteDeregister(fci_handle, &s->rt, "socket");

#ifdef COMCERTO_2000
	if (s->rx_flow)
		if (!cmmFlowKeyEngineRemove(fci_key_handle, s->rx_flow))
		{
			__cmmFlowPut(s->rx_flow);
			s->rx_flow = NULL;
		}
	if (s->tx_flow)
		if (!cmmFlowKeyEngineRemove(fci_key_handle, s->tx_flow))
		{
			__cmmFlowPut(s->tx_flow);
			s->tx_flow = NULL;
		}
#endif

	/* In case of error the socket may still be programmed in fpp,
	   so don't remove it */
	if (s->flags & FPP_PROGRAMMED)
		goto err;

	socket_remove(s);

err:
	return rc;
}

static int socket_open(FCI_CLIENT *fci_handle, FCI_CLIENT *fci_key_handle, cmmd_socket_open_cmd_t *cmd)
{
	struct socket *s;
	unsigned short rc = 0; // rc=2 OK, rc=0 KO, cmm_client error code hack 

	cmm_print(DEBUG_INFO, "%s\n", __func__);

	__pthread_mutex_lock(&itf_table.lock);
	__pthread_mutex_lock(&rtMutex);
	__pthread_mutex_lock(&neighMutex);
	__pthread_mutex_lock(&flowMutex);
	__pthread_mutex_lock(&socket_lock);

	s = socket_find(cmd->id);
	if (!s)
	{
		s = socket_add(cmd);
		if (!s)
		{
			rc = -1;
			goto exit;
		}
	}
	else
		goto exit;

	rc = __socket_open(fci_handle, s);
	if(rc != CMMD_ERR_OK)
		__socket_close(fci_handle, fci_key_handle, s);

exit:
	__pthread_mutex_unlock(&socket_lock);
	__pthread_mutex_unlock(&flowMutex);
	__pthread_mutex_unlock(&neighMutex);
	__pthread_mutex_unlock(&rtMutex);
	__pthread_mutex_unlock(&itf_table.lock);

	return rc;
}


static int socket_update(FCI_CLIENT *fci_handle, cmmd_socket_update_cmd_t *cmd)
{
	struct socket *s;
	unsigned short rc = 0; // rc=2 OK, rc=0 KO, cmm_client error code hack 
	struct ct_route old_route;
	u_int8_t del_old_route=0;
	u_int32_t null_addr[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};

	cmm_print(DEBUG_INFO, "%s\n", __func__);

	__pthread_mutex_lock(&itf_table.lock);
	__pthread_mutex_lock(&rtMutex);
	__pthread_mutex_lock(&neighMutex);
	__pthread_mutex_lock(&flowMutex);
	__pthread_mutex_lock(&socket_lock);

	s = socket_find(cmd->id);
	if (!s)
	{
		cmm_print(DEBUG_ERROR, "invalid socket ID %d \n", cmd->id);
		rc = CMMD_ERR_NOT_FOUND;
		goto exit;
	}

	if (s->family != cmd->family)
	{
		cmm_print(DEBUG_ERROR, "invalid socket family %d \n", cmd->family);
		rc = CMMD_ERR_WRONG_COMMAND_PARAM;
		goto exit;
	}

	if (memcmp(cmd->saddr, null_addr, IPADDRLEN(s->family)) && memcmp(cmd->saddr, s->saddr, IPADDRLEN(s->family))) // source has changed -> new route
	{
		old_route = s->rt;
		memcpy(s->saddr, cmd->saddr, IPADDRLEN(s->family));
		s->rt.route = NULL;
		s->rt.fpp_route = NULL;
		del_old_route = 1;
	}

	if (cmd->sport != 0xffff)
		s->sport = cmd->sport;
	if (cmd->queue != 0xff)
		s->queue = cmd->queue;
	if (cmd->dscp != 0xffff)	
		s->dscp = cmd->dscp;

	s->secure = 0;
#ifdef COMCERTO_2000
	s->rx_flow = __cmmFlowGet(s->family, s->saddr, s->daddr, s->sport, s->dport, s->proto);
	s->tx_flow = __cmmFlowGet(s->family, s->daddr, s->saddr, s->dport, s->sport, s->proto);
	if(s->rx_flow || s->tx_flow)
		s->secure = 1;
#endif

	s->flags |= FPP_NEEDS_UPDATE;

	rc = __socket_open(fci_handle, s);

exit:

	if (del_old_route)	
	{
		cmm_print(DEBUG_INFO, "Removing old socket route entry\n");

		__cmmRouteDeregister(fci_handle, &old_route, "socket");
	}

	__pthread_mutex_unlock(&socket_lock);
	__pthread_mutex_unlock(&flowMutex);
	__pthread_mutex_unlock(&neighMutex);
	__pthread_mutex_unlock(&rtMutex);
	__pthread_mutex_unlock(&itf_table.lock);

	return rc;
}


static int socket_close(FCI_CLIENT *fci_handle, FCI_CLIENT *fci_key_handle, cmmd_socket_close_cmd_t *cmd)
{
	struct socket *s;
	int ret = 0;

	cmm_print(DEBUG_INFO, "%s\n", __func__);

	__pthread_mutex_lock(&itf_table.lock);
	__pthread_mutex_lock(&rtMutex);
	__pthread_mutex_lock(&neighMutex);
	__pthread_mutex_lock(&flowMutex);
	__pthread_mutex_lock(&socket_lock);

	s = socket_find(cmd->id);
	if (!s)
	{
		cmm_print(DEBUG_ERROR, "%s: socket_find(%d) failed\n", __func__, cmd->id);
		ret = CMMD_ERR_NOT_FOUND;
		goto out;
	}

	ret = __socket_close(fci_handle, fci_key_handle, s);
	
out:
	__pthread_mutex_unlock(&socket_lock);
	__pthread_mutex_unlock(&flowMutex);
	__pthread_mutex_unlock(&neighMutex);
	__pthread_mutex_unlock(&rtMutex);
	__pthread_mutex_unlock(&itf_table.lock);

	return ret;
}



/* CMM server side socket control */
int socket_daemon(FCI_CLIENT *fci_handle, FCI_CLIENT *fci_key_handle, int fc, u_int8_t *cmd_buf, u_int16_t cmd_len, u_int16_t *res_buf, u_int16_t *res_len)
{
	int rc = 0; 
	
	cmm_print(DEBUG_INFO, "%s\n", __func__);

	res_buf[0] = CMMD_ERR_WRONG_COMMAND_SIZE;

	switch (fc)
	{
	case CMMD_CMD_SOCKET_OPEN:
	{
		cmmd_socket_open_cmd_t *cmd = (cmmd_socket_open_cmd_t *)cmd_buf;
		*res_len = 2;

		if (cmd_len < sizeof(*cmd))
		{
			cmm_print(DEBUG_ERROR, "%s: socket open command size too small(%d, %d)\n", __func__, cmd_len, sizeof(*cmd));
			break;
		}
		if(( cmd->id >= SOCK_ID_PRIVATE_START) && ( cmd->id <= (SOCK_ID_PRIVATE_END)) )
		{
			rc = res_buf[0] = CMMD_ERR_WRONG_SOCKID;
			break;
		}

		rc = socket_open(fci_handle, fci_key_handle, cmd);
		if (rc >= 0)
		{
			res_buf[0] = rc;
			rc = 0;
		}

		break;
	}

	case CMMD_CMD_SOCKET_UPDATE:
	{
		cmmd_socket_update_cmd_t *cmd = (cmmd_socket_update_cmd_t *)cmd_buf;
		*res_len = 2;

		if (cmd_len < sizeof(*cmd))
		{
			cmm_print(DEBUG_ERROR, "%s: socket update command size too small(%d, %d)\n", __func__, cmd_len, sizeof(*cmd));
			break;
		}
		if(( cmd->id >= SOCK_ID_PRIVATE_START) && ( cmd->id <= (SOCK_ID_PRIVATE_END)) )
		{
			rc = res_buf[0] = CMMD_ERR_WRONG_SOCKID;
			break;
		}


		rc = socket_update(fci_handle, cmd);
		if (rc >= 0)
		{
			res_buf[0] = rc;
			rc = 0;
		}

		break;
	}

	case CMMD_CMD_SOCKET_CLOSE:
	{
		cmmd_socket_close_cmd_t *cmd = (cmmd_socket_close_cmd_t *)cmd_buf;
		*res_len = 2;

		if (cmd_len < sizeof(*cmd))
		{
			cmm_print(DEBUG_ERROR, "%s: socket close command size too small(%d, %d)\n", __func__, cmd_len, sizeof(*cmd));
			break;
		}

		if(( cmd->id >= SOCK_ID_PRIVATE_START) && ( cmd->id <= (SOCK_ID_PRIVATE_END)) )
		{
			rc = res_buf[0] = CMMD_ERR_WRONG_SOCKID;
			break;
		}

		rc = socket_close(fci_handle, fci_key_handle, cmd);
		if (rc >= 0)
		{
			res_buf[0] = rc;
			rc = 0;
		}

		break;
	}

	case CMMD_CMD_SOCKET_SHOW:
	{
		int i;
		struct socket *s;
		cmmd_socket_show_cmd_t *cmd = (cmmd_socket_show_cmd_t *)cmd_buf;

		cmm_print(DEBUG_INFO, "reserve start and end(%d, %d)\n", SOCK_ID_PRIVATE_START, SOCK_ID_PRIVATE_END);

		__pthread_mutex_lock(&socket_lock);
		if (!cmd->dump_all)
		{
			s = socket_find(cmd->id);
			if(!s)
			{
				res_buf[0] = CMMD_ERR_NOT_FOUND;
				*res_len = 2;
			}
			else
			{
				memcpy(res_buf, s,sizeof(struct socket));
				res_buf[0] = CMMD_ERR_OK; /* XXX: overwrite first 2 bytes with return code.
							   * This is a hack. Should be fixed by defining correct response
							   * structure.
							   */
				*res_len = sizeof(struct socket);
			}
		}
		else
		{
			struct list_head *entry;
			cmmd_socket_show_res_t *res = (cmmd_socket_show_res_t*)(res_buf);
			res->rc = CMMD_ERR_OK;
			res->nb_socket = 0;

			for (i = 0; i < HASH_SOCKET_SIZE; i++)
			{
				for (entry = list_first(&socket_table[i]); entry != &socket_table[i]; entry = list_next(entry), res->nb_socket++)
				{
					if ((res->nb_socket + 1) * sizeof(res->sockets[0]) + sizeof(cmmd_socket_show_res_t) > CMM_BUF_SIZE) 
						/* no room for next entry */
						goto end;

					s = container_of(entry, struct socket, list);
					res->sockets[res->nb_socket].sock_id = s->id;
					res->sockets[res->nb_socket].flags = s->flags;
				}
			}

end:
			*res_len = res->nb_socket * sizeof(res->sockets[0]) + sizeof(cmmd_socket_show_res_t);
		}

		__pthread_mutex_unlock(&socket_lock);
	}
		break;

	default:
		res_buf[0] = CMMD_ERR_UNKNOWN_COMMAND;
		*res_len = 2;
		break;
	}

	return rc;
}


static void cmmSocketSetUsage(unsigned char family)
{
	if (family == AF_INET)
	cmm_print(DEBUG_STDOUT, 
			"Usage: set socket \n"
			"\n"
			"                                  [open]\n"
			"                                       [sock_id {socket_id}] \n"
			"                                       [type {acp | fpp | msp}]\n"
			"                                       [saddr {IPv4 addr}] \n"
			"                                       [daddr {IPv4 addr}] \n"
			"                                       [sport {port number}] \n"
			"                                       [dport {port number}] \n"
			"                                       [proto {udp | tcp}] \n"
			"                                       [queue {0-19}] \n"
			"                                       [dscp {0-63}]  (Optional parameter, if not set ToS inherited from packet)\n"
			"                                       [fwmark {unsigned int}]  (Optional parameter)\n"
			"                                       [mode {connected | unconnected}] (Optional parameter default unconnected)\n"


			"                                  [update]\n"
			"                                       [sock_id {socket_id}] \n"
			"                                       [saddr {IPv4 addr}] \n"
			"                                       [sport {port number}] \n"
			"                                       [queue {0-19}] \n"
			"                                       [dscp {0-63}]  \n"
			"                                       [fwmark {unsigned int}]\n"



			"\n"
			"                                  [close]\n"
			"                                       [sock_id {socket_id}] \n"
	          );
	else
	cmm_print(DEBUG_STDOUT, 
			"Usage: set socket6 \n"
			"\n"
			"                                  [open]\n"
			"                                       [sock_id {socket_id}] \n"
			"                                       [type {acp | fpp}]\n"
			"                                       [saddr {IPv6 addr}] \n"
			"                                       [daddr {IPv6 addr}] \n"
			"                                       [sport {port number}] \n"
			"                                       [dport {port number}] \n"
			"                                       [proto {udp | tcp}] \n"
			"                                       [queue {0-19}] \n"
			"                                       [dscp {0-63}]  (Optional parameter, if not set Traffic Class inherited from packet)\n"
			"                                       [fwmark {unsigned int}]  (Optional parameter)\n"
			"                                       [mode {connected | unconnected}] (Optional parameter default unconnected)\n"


			"                                  [update]\n"
			"                                       [sock_id {socket_id}] \n"
			"                                       [saddr {IPv6 addr}] \n"
			"                                       [sport {port number}] \n"
			"                                       [queue {0-19}] \n"
			"                                       [dscp {0-63}]  \n"
			"                                       [fwmark {unsigned int}]\n"


			"\n"
			"                                  [close]\n"
			"                                       [sock_id {socket_id}] \n"
	          );
}

static void cmmSocketShowUsage(void)
{
	cmm_print(DEBUG_STDOUT, 
			"Usage: show socket  [sock_id {socket ID} | all]\n"
			"\n"
	          );
}

int cmmSocketSetProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle)
{
	int cpt = tabStart;
	unsigned int tmp;
	char * endptr;
	char rcvBuffer[CMM_BUF_SIZE];
	int family;
	int rc;

	if (!strcasecmp(keywords[cpt - 1], "socket6"))
		family = AF_INET6;
	else
		family = AF_INET;

	if (!keywords[cpt])
		goto print_help;

	if (strcasecmp(keywords[cpt], "open") == 0)
	{
		cmmd_socket_open_cmd_t cmd;
		memset(&cmd, 0, sizeof(cmmd_socket_open_cmd_t));
		
		if (!keywords[++cpt])
			goto print_help;

		cmd.family = family;

		if (strcasecmp(keywords[cpt], "sock_id") == 0)
		{
			if (!keywords[++cpt])
				goto print_help;
			
			/*Get an integer from the string*/
			endptr = NULL;
			tmp = strtoul(keywords[cpt], &endptr, 0);
			if ((keywords[cpt] == endptr) ||  (tmp > USHRT_MAX))
			{
				cmm_print(DEBUG_CRIT, "ERROR: sock_id must be a number between 0 and %d\n", USHRT_MAX);
				goto  print_help;
			}
			cmd.id = tmp;
		}
		else
			goto keyword_error;

		if(!keywords[++cpt])
			goto print_help;
	
		if(strcasecmp(keywords[cpt], "type") == 0)
		{
			if(!keywords[++cpt])
				goto print_help;
		
			if(strcasecmp(keywords[cpt], "fpp") == 0)
			{
				cmd.type = CMMD_SOCKET_TYPE_LANWAN; 
			}
			else if(strcasecmp(keywords[cpt], "acp") == 0)
			{
				cmd.type = CMMD_SOCKET_TYPE_ACP;
			}
			else if(strcasecmp(keywords[cpt], "msp") == 0)
			{
				cmd.type = CMMD_SOCKET_TYPE_MSP;
			}
			else
			{
				cmm_print(DEBUG_CRIT, "socket ERROR: type must be either acp, fpp or msp \n");
				goto  print_help;
			}
		}
		else
			goto keyword_error;

		if (!keywords[++cpt])
			goto print_help;
	
		if (strcasecmp(keywords[cpt], "saddr") == 0)
		{
			if (!keywords[++cpt])
				goto print_help;
		
			if (!inet_pton(family, keywords[cpt], &cmd.saddr))
			{
				cmm_print(DEBUG_CRIT,"%s: error reading source address %s\n", __func__, keywords[cpt]);
				goto keyword_error;
			}
		}
		else
			goto keyword_error;
	
		if (!keywords[++cpt])
			goto print_help;
	
		if (strcasecmp(keywords[cpt], "daddr") == 0)
		{
			if (!keywords[++cpt])
				goto print_help;
		
			if (!inet_pton(family, keywords[cpt], cmd.daddr))
			{
				cmm_print(DEBUG_CRIT,"%s: error reading destination address %s\n", __func__,keywords[cpt]);
				goto keyword_error;
			}
		}
		else
			goto keyword_error;

		if (!keywords[++cpt])
			goto print_help;
	
		if (strcasecmp(keywords[cpt], "sport") == 0)
		{
			if(!keywords[++cpt])
				goto print_help;
				
			/*Get an integer from the string*/
			endptr = NULL;
			tmp = strtoul(keywords[cpt], &endptr, 0);
			if ((keywords[cpt] == endptr) ||  (tmp > USHRT_MAX))
			{
				cmm_print(DEBUG_CRIT, "ERROR: sport must be a number between 0 and %d\n", USHRT_MAX);
				goto  print_help;
			}
			cmd.sport= htons(tmp);
		}
		else
			goto keyword_error;

		if(!keywords[++cpt])
			goto print_help;
	
		if(strcasecmp(keywords[cpt], "dport") == 0)
		{
			if(!keywords[++cpt])
				goto print_help;
				
			/*Get an integer from the string*/
			endptr = NULL;
			tmp = strtoul(keywords[cpt], &endptr, 0);
			if ((keywords[cpt] == endptr) ||  (tmp > USHRT_MAX))
			{
				cmm_print(DEBUG_CRIT, "ERROR: dport must be a number between 0 and %d\n", USHRT_MAX);
				goto  print_help;
			}
			cmd.dport= htons(tmp);
		}
		else
			goto keyword_error;

		if(!keywords[++cpt])
			goto print_help;
	
		if(strcasecmp(keywords[cpt], "proto") == 0)
		{
			if(!keywords[++cpt])
				goto print_help;
	
			if(strcasecmp(keywords[cpt], "udp") == 0)
			{
				cmd.proto= 17; 
			}
			else if(strcasecmp(keywords[cpt], "tcp") == 0)
			{
				cmd.proto = 6;
			}
			else
			{
				cmm_print(DEBUG_CRIT, "socket ERROR: proto must be either udp or tcp\n");
				goto  print_help;
			}
		}
		else
			goto keyword_error;

		if(!keywords[++cpt])
			goto print_help;
	
		if(strcasecmp(keywords[cpt], "queue") == 0)
		{
			if(!keywords[++cpt])
				goto print_help;
			
			/*Get an integer from the string*/
			endptr = NULL;
			tmp = strtoul(keywords[cpt], &endptr, 0);
			if ((keywords[cpt] == endptr) ||  (tmp > (FPP_NUM_QUEUES - 1) ))
			{
				cmm_print(DEBUG_CRIT, "ERROR: queue number must be a number between 0 and %d\n", FPP_NUM_QUEUES - 1);
				goto  print_help;
			}
			cmd.queue= tmp;
		}
		else
			goto keyword_error;

		while (keywords[++cpt] != NULL)
		{
			if(strcasecmp(keywords[cpt], "dscp") == 0)
			{
				if(!keywords[++cpt])
					goto print_help;
			
				/*Get an integer from the string*/
				endptr = NULL;
				tmp = strtoul(keywords[cpt], &endptr, 0);
				if ((keywords[cpt] == endptr) ||  (tmp > 63))
				{
					cmm_print(DEBUG_CRIT, "ERROR: dscp number must be a number between 0 and 63\n");
					goto  print_help;
				}
				cmd.dscp= tmp;
			}
			else if(strcasecmp(keywords[cpt], "fwmark") == 0)
			{
				if(!keywords[++cpt])
					goto print_help;
				
				/*Get an integer from the string*/
				endptr = NULL;
				tmp = strtoul(keywords[cpt], &endptr, 0);
				if ((keywords[cpt] == endptr) ||  (tmp > UINT_MAX))
				{
					cmm_print(DEBUG_CRIT, "ERROR: dscp number must be a number between 0 and %d\n", UINT_MAX);
					goto  print_help;
				}
				cmd.fwmark= tmp;
			}
			else if(strcasecmp(keywords[cpt], "mode") == 0)
			{
				if(!keywords[++cpt])
					goto print_help;
			
				if(strcasecmp(keywords[cpt], "connected") == 0)
				{
					cmd.mode = SOCKET_CONNECTED; 
				}
				else if(strcasecmp(keywords[cpt], "unconnected") == 0)
				{
					cmd.mode = SOCKET_UNCONNECTED;
				}
				else
				{
					cmm_print(DEBUG_CRIT, "socket ERROR: mode  must be either connected or unconnected \n");
					goto  print_help;
				}
			}
#ifdef COMCERTO_2000
			else if(strcasecmp(keywords[cpt], "ipsec") == 0)
			{
				if(!keywords[++cpt])
					goto print_help;
				
				/*Get an integer from the string*/
				endptr = NULL;
				tmp = strtoul(keywords[cpt], &endptr, 0);
				if ((keywords[cpt] == endptr) ||  (tmp > 1))
				{
					cmm_print(DEBUG_CRIT, "ERROR: ipsec flag must be 0 or 1\n");
					goto  print_help;
				}
				cmd.secure = tmp;
			}
#endif
			else
				goto keyword_error;
		}

		if (!cmd.dscp)
			cmd.dscp = 0xFFFF;

		rc = cmmSendToDaemon(daemon_handle, CMMD_CMD_SOCKET_OPEN, &cmd, sizeof(cmd), rcvBuffer);
		if (rc == 2)
		{
			if (((u_int16_t*)rcvBuffer)[0] != CMMD_ERR_OK)
				cmm_print(DEBUG_CRIT,  "%s: error %d when sending CMD_SOCKET_OPEN\n", __func__, ((u_int16_t*)rcvBuffer)[0]);
		}
		else if (rc > 0)
			cmm_print(DEBUG_CRIT,  "%s: wrong response size %d received\n", __func__, rc);

	}
	else if(strcasecmp(keywords[cpt], "update") == 0)
	{
		cmmd_socket_update_cmd_t cmd;

		cmd.saddr[0] = 0xffffffff;
		cmd.saddr[1] = 0xffffffff;
		cmd.saddr[2] = 0xffffffff;
		cmd.saddr[3] = 0xffffffff;
		cmd.sport = 0xffff;
		cmd.dscp = 0xffff;
		cmd.queue = 0xff;
		cmd.fwmark = 0xffffffff;
#ifdef COMCERTO_2000
		cmd.secure = 0xffff;
#endif

		if(!keywords[++cpt])
			goto print_help;

		cmd.family = family;

		if(strcasecmp(keywords[cpt], "sock_id") == 0)
		{
			if(!keywords[++cpt])
				goto print_help;
			
			/*Get an integer from the string*/
			endptr = NULL;
			tmp = strtoul(keywords[cpt], &endptr, 0);
			if ((keywords[cpt] == endptr) ||  (tmp > USHRT_MAX))
			{
				cmm_print(DEBUG_CRIT, "ERROR: sock_id must be a number between 0 and %d\n", USHRT_MAX);
				goto  print_help;
			}
			cmd.id = tmp;
		}
		else
			goto keyword_error;
		
	
		while (keywords[++cpt] != NULL)
		{
			if(strcasecmp(keywords[cpt], "saddr") == 0)
			{
				if(!keywords[++cpt])
					goto print_help;
			
				if (!inet_pton(family, keywords[cpt], cmd.saddr))
				{
					cmm_print(DEBUG_CRIT,"%s: error reading source address %s\n", __func__, keywords[cpt]);
					goto keyword_error;
				}
			}
		
			else if(strcasecmp(keywords[cpt], "sport") == 0)
			{
				if(!keywords[++cpt])
					goto print_help;
					
				/*Get an integer from the string*/
				endptr = NULL;
				tmp = strtoul(keywords[cpt], &endptr, 0);
				if ((keywords[cpt] == endptr) ||  (tmp > USHRT_MAX))
				{
					cmm_print(DEBUG_CRIT, "ERROR: sport must be a number between 0 and %d\n", USHRT_MAX);
					goto  print_help;
				}
				cmd.sport= htons(tmp);
			}
			else if(strcasecmp(keywords[cpt], "queue") == 0)
			{
				if(!keywords[++cpt])
					goto print_help;
				
				/*Get an integer from the string*/
				endptr = NULL;
				tmp = strtoul(keywords[cpt], &endptr, 0);
				if ((keywords[cpt] == endptr) ||  (tmp > (FPP_NUM_QUEUES - 1) ))
				{
					cmm_print(DEBUG_CRIT, "ERROR: queue number must be a number between 0 and %d\n", FPP_NUM_QUEUES - 1);
					goto  print_help;
				}
				cmd.queue= tmp;
			}
			else if(strcasecmp(keywords[cpt], "dscp") == 0)
			{
				if(!keywords[++cpt])
					goto print_help;
				
				/*Get an integer from the string*/
				endptr = NULL;
				tmp = strtoul(keywords[cpt], &endptr, 0);
				if ((keywords[cpt] == endptr) ||  (tmp > 63))
				{
					cmm_print(DEBUG_CRIT, "ERROR: dscp number must be a number between 0 and 63\n");
					goto  print_help;
				}
				cmd.dscp= tmp;
			}
			else if(strcasecmp(keywords[cpt], "fwmark") == 0)
			{
				if(!keywords[++cpt])
					goto print_help;
				
				/*Get an integer from the string*/
				endptr = NULL;
				tmp = strtoul(keywords[cpt], &endptr, 0);
				if ((keywords[cpt] == endptr) ||  (tmp > UINT_MAX))
				{
					cmm_print(DEBUG_CRIT, "ERROR: dscp number must be a number between 0 and %d\n", UINT_MAX);
					goto  print_help;
				}
				cmd.fwmark= tmp;
			}
#ifdef COMCERTO_2000
			else if(strcasecmp(keywords[cpt], "ipsec") == 0)
			{
				if(!keywords[++cpt])
					goto print_help;
				
				/*Get an integer from the string*/
				endptr = NULL;
				tmp = strtoul(keywords[cpt], &endptr, 0);
				if ((keywords[cpt] == endptr) ||  (tmp > 1))
				{
					cmm_print(DEBUG_CRIT, "ERROR: ipsec flag must be 0 or 1\n");
					goto  print_help;
				}
				cmd.secure = tmp;
			}
#endif
			else
				goto keyword_error;

		}
		rc = cmmSendToDaemon(daemon_handle, CMMD_CMD_SOCKET_UPDATE, &cmd, sizeof(cmd), rcvBuffer);
		if (rc == 2)
		{
			if (((u_int16_t*)rcvBuffer)[0] != CMMD_ERR_OK)
				cmm_print(DEBUG_CRIT,  "%s: error %d when sending CMD_SOCKET_UPDATE\n", __func__, ((u_int16_t*)rcvBuffer)[0]);
		}
		else if (rc > 0)
			cmm_print(DEBUG_CRIT,  "%s: wrong response size %d received\n", __func__, rc);
	}

	
	else if(strcasecmp(keywords[cpt], "close") == 0)
	{
		cmmd_socket_close_cmd_t cmd;
		
		if(!keywords[++cpt])
			goto print_help;
		
		if(strcasecmp(keywords[cpt], "sock_id") == 0)
		{
			if(!keywords[++cpt])
				goto print_help;
			
			/*Get an integer from the string*/
			endptr = NULL;
			tmp = strtoul(keywords[cpt], &endptr, 0);
			if ((keywords[cpt] == endptr) ||  (tmp > USHRT_MAX))
			{
				cmm_print(DEBUG_CRIT, "ERROR: sock_id must be a number between 0 and %d\n", USHRT_MAX);
				goto  print_help;
			}
			cmd.id = tmp;
		}
		else
			goto keyword_error;
		
		rc = cmmSendToDaemon(daemon_handle, CMMD_CMD_SOCKET_CLOSE, &cmd, sizeof(cmd), rcvBuffer);
		if (rc == 2)
		{
			if (((u_int16_t*)rcvBuffer)[0] != CMMD_ERR_OK)
				cmm_print(DEBUG_CRIT,  "%s: error %d when sending CMD_SOCKET_CLOSE\n", __func__, ((u_int16_t*)rcvBuffer)[0]);
		}
		else if (rc > 0)
			cmm_print(DEBUG_CRIT,  "%s: wrong response size %d received\n", __func__, rc);
	}
	else
		goto keyword_error;
	
	return 0;



keyword_error:
	cmm_print(DEBUG_STDOUT,"ERR: unknown keyword %s\n", keywords[cpt]);

print_help:
	cmmSocketSetUsage(family);

	return -1;
}

int cmmSocketShowProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle)
{
	char rcvBuffer[CMM_BUF_SIZE];
	int cpt = tabStart;
	cmmd_socket_show_cmd_t cmd;
	struct socket *s;
	int rc;
	unsigned int tmp;
	char * endptr;

	if (!keywords[cpt])
		goto print_help;

	if (strcasecmp(keywords[cpt], "sock_id") == 0)
	{
		if (!keywords[++cpt])
			goto print_help;
		
		/*Get an integer from the string*/
		endptr = NULL;
		tmp = strtoul(keywords[cpt], &endptr, 0);

		if ((keywords[cpt] == endptr) ||  (tmp > USHRT_MAX))
		{
			cmm_print(DEBUG_CRIT, "ERROR: sock_id must be a number between 0 and %d\n", USHRT_MAX);
			goto print_help;
		}

		cmd.id = tmp;
		cmd.dump_all = 0;
	}
	else if(strcasecmp(keywords[cpt], "all") == 0)
	{
		if(keywords[++cpt])
			goto print_help;
			
		cmd.id = 0;
		cmd.dump_all = 1;	
	}
	else
		goto keyword_error;

	rc = cmmSendToDaemon(daemon_handle, CMMD_CMD_SOCKET_SHOW, &cmd, sizeof(cmd), rcvBuffer);
	if (rc >= 2)
	{
		if (((u_int16_t*)rcvBuffer)[0] != CMMD_ERR_OK)
		{
			cmm_print(DEBUG_CRIT,  "%s: error %d when sending CMD_SOCKET_SHOW\n", __func__, ((u_int16_t*)rcvBuffer)[0]);
			return -1;
		}
	}
	else
	{
		if (rc > 0)
			cmm_print(DEBUG_CRIT,  "%s: wrong response size %d received\n", __func__, rc);
		return -1;
	}

	if (!cmd.dump_all)
	{

		char saddr_buf[INET6_ADDRSTRLEN], daddr_buf[INET6_ADDRSTRLEN];
		s = (struct socket *)(rcvBuffer);

		cmm_print(DEBUG_STDOUT,	"socket id   : %d\n"
									"saddr       : %s\n"
									"daddr       : %s\n"
									"sport       : %d\n"
									"dport       : %d\n"
									"proto       : %d\n"
									"queue       : %d\n"
									"dscp        : %d\n"
#ifdef COMCERTO_2000
									"ipsec       : %d\n"
#endif
									"flags       : %d\n",
						s->id,
						inet_ntop(s->family, s->saddr, saddr_buf, sizeof(saddr_buf)),
						inet_ntop(s->family, s->daddr, daddr_buf, sizeof(daddr_buf)),
						ntohs(s->sport),
						ntohs(s->dport),
						s->proto,
						s->queue,
						s->dscp,
#ifdef COMCERTO_2000
						s->secure,
#endif
						s->flags);
			return 0;
	}
	else
	{
		cmmd_socket_show_res_t *res = (cmmd_socket_show_res_t*)(rcvBuffer);
		int i = 0;
		cmm_print(DEBUG_STDOUT, "%d socket(s) programmed\n", res->nb_socket);
		for(i = 0; i < res->nb_socket; i++)
			cmm_print(DEBUG_STDOUT, "socket id : %d, flags: %d\n", res->sockets[i].sock_id, res->sockets[i].flags);
		return 0;
	}
	
	keyword_error:
		cmm_print(DEBUG_STDOUT,"ERR: unknown keyword %s\n", keywords[cpt]);

	print_help:
		cmmSocketShowUsage();
		
	return 0;
}
