blob: a604bccaaa1cb80a2008292df5bb0b0dff98fb84 [file] [log] [blame]
/*
*
* 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 <stdlib.h>
#include <string.h>
#include "module_natpt.h"
static void cmmNATPTSetUsage(void)
{
cmm_print(DEBUG_STDOUT,
"Usage: set natpt \n"
"\n"
" [open]\n"
" [sock_id_a {socket ID}]\n"
" [sock_id_b {socket ID}]\n"
" [6to4] \n"
" [4to6] \n"
"\n"
" [close]\n"
" [sock_id_a {socket ID}]\n"
" [sock_id_b {socket ID}]\n"
"\n"
);
}
static void cmmNATPTQueryUsage(void)
{
cmm_print(DEBUG_STDOUT,
"Usage: query natpt\n"
" [sock_id_a {socket ID}]\n"
" [sock_id_b {socket ID}]\n"
"\n"
);
}
int cmmNATPTSetProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle)
{
int cpt = tabStart;
unsigned int tmp;
char * endptr;
char rcvBuffer[256];
if(!keywords[cpt])
goto print_help;
if (strcasecmp(keywords[cpt], "open") == 0)
{
fpp_natpt_open_cmd_t cmd;
if(!keywords[++cpt])
goto print_help;
memset(&cmd, 0, sizeof(cmd));
if((strcasecmp(keywords[cpt], "sock_id_a") == 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_a parameter must be a number between 0 and %d\n", USHRT_MAX);
goto print_help;
}
cmd.socket_a= tmp;
}
else
goto keyword_error;
if(!keywords[++cpt])
goto print_help;
if((strcasecmp(keywords[cpt], "sock_id_b") == 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_b parameter must be a number between 0 and %d\n", USHRT_MAX);
goto print_help;
}
cmd.socket_b= tmp;
}
else
goto keyword_error;
while (keywords[++cpt])
{
if((strcasecmp(keywords[cpt], "6to4") == 0))
cmd.control |= FPP_NATPT_CONTROL_6to4;
else if((strcasecmp(keywords[cpt], "4to6") == 0))
cmd.control |= FPP_NATPT_CONTROL_4to6;
else
goto keyword_error;
}
if (cmd.control == 0)
{
cmm_print(DEBUG_CRIT, "ERROR: 6to4 or 4to6 must be specified\n");
goto print_help;
}
// Send command
if(cmmSendToDaemon(daemon_handle, FPP_CMD_NATPT_OPEN, &cmd, sizeof(cmd), &rcvBuffer) == 2)
{
if ((((unsigned short*)rcvBuffer)[0]) != 0)
cmm_print(DEBUG_STDERR, "Error %d received from FPP \n", ((unsigned short*)rcvBuffer)[0]);
}
}
else if (strcasecmp(keywords[cpt], "close") == 0)
{
fpp_natpt_close_cmd cmd;
if(!keywords[++cpt])
goto print_help;
memset(&cmd, 0, sizeof(cmd));
if((strcasecmp(keywords[cpt], "sock_id_a") == 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_a parameter must be a number between 0 and %d\n", USHRT_MAX);
goto print_help;
}
cmd.socket_a= tmp;
}
else
goto keyword_error;
if(!keywords[++cpt])
goto print_help;
if((strcasecmp(keywords[cpt], "sock_id_b") == 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_b parameter must be a number between 0 and %d\n", USHRT_MAX);
goto print_help;
}
cmd.socket_b= tmp;
}
else
goto keyword_error;
if (keywords[++cpt])
goto keyword_error;
// Send command
if(cmmSendToDaemon(daemon_handle, FPP_CMD_NATPT_CLOSE, &cmd, sizeof(cmd), &rcvBuffer) == 2)
{
if ((((unsigned short*)rcvBuffer)[0]) != 0)
cmm_print(DEBUG_STDERR, "Error %d received from FPP \n", ((unsigned short*)rcvBuffer)[0]);
}
}
else
{
goto keyword_error;
}
return 0;
keyword_error:
cmm_print(DEBUG_STDOUT,"ERR: unknown keyword %s\n", keywords[cpt]);
print_help:
cmmNATPTSetUsage();
return -1;
}
int cmmNATPTQueryProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle)
{
int rcvBytes;
int cpt = tabStart;
unsigned int tmp;
char * endptr;
char rcvBuffer[256];
fpp_natpt_query_cmd_t cmd;
fpp_natpt_query_response_t *pEntryResponse;
if(!keywords[cpt])
goto print_help;
memset(&cmd, 0, sizeof(cmd));
if((strcasecmp(keywords[cpt], "sock_id_a") == 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_a parameter must be a number between 0 and %d\n", USHRT_MAX);
goto print_help;
}
cmd.socket_a= tmp;
}
else
goto keyword_error;
if(!keywords[++cpt])
goto print_help;
if((strcasecmp(keywords[cpt], "sock_id_b") == 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_b parameter must be a number between 0 and %d\n", USHRT_MAX);
goto print_help;
}
cmd.socket_b= tmp;
}
else
goto keyword_error;
if (keywords[++cpt])
goto keyword_error;
// Send command
rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_NATPT_QUERY, &cmd, sizeof(cmd), &rcvBuffer);
if (rcvBytes != sizeof(fpp_natpt_query_response_t))
{
cmm_print(DEBUG_STDERR, "ERROR: CMD_NATPT_QUERY Unexpected result returned from FPP rc:%04x - received %d - expected %d\n",
(rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer),
rcvBytes, sizeof(fpp_natpt_query_response_t)
);
return -1;
}
pEntryResponse = (fpp_natpt_query_response_t *)rcvBuffer;
if (pEntryResponse->retcode != 0)
{
cmm_print(DEBUG_STDERR, "Error %d received from FPP \n", pEntryResponse->retcode);
return -1;
}
cmm_print(DEBUG_STDOUT, "NAT-PT Entry:\n\tSocket A: %d, Socket B: %d%s%s%s\n",
pEntryResponse->socket_a, pEntryResponse->socket_b,
(pEntryResponse->control & FPP_NATPT_CONTROL_6to4) ? ", 6to4" : "",
(pEntryResponse->control & FPP_NATPT_CONTROL_4to6) ? ", 4to6" : "",
(pEntryResponse->control & FPP_NATPT_CONTROL_TCPFIN) ? ", TCP_FIN" : "");
cmm_print(DEBUG_STDOUT, "\t# of IPv6 Packets Received: %lld\n", pEntryResponse->stat_v6_received);
cmm_print(DEBUG_STDOUT, "\t# of IPv6 Packets Transmitted: %lld\n", pEntryResponse->stat_v6_transmitted);
cmm_print(DEBUG_STDOUT, "\t# of IPv6 Packets Dropped: %lld\n", pEntryResponse->stat_v6_dropped);
cmm_print(DEBUG_STDOUT, "\t# of IPv6 Packets Sent to ACP: %lld\n", pEntryResponse->stat_v6_sent_to_ACP);
cmm_print(DEBUG_STDOUT, "\t# of IPv4 Packets Received: %lld\n", pEntryResponse->stat_v4_received);
cmm_print(DEBUG_STDOUT, "\t# of IPv4 Packets Transmitted: %lld\n", pEntryResponse->stat_v4_transmitted);
cmm_print(DEBUG_STDOUT, "\t# of IPv4 Packets Dropped: %lld\n", pEntryResponse->stat_v4_dropped);
cmm_print(DEBUG_STDOUT, "\t# of IPv4 Packets Sent to ACP: %lld\n", pEntryResponse->stat_v4_sent_to_ACP);
return 0;
keyword_error:
cmm_print(DEBUG_STDOUT,"ERR: unknown keyword %s\n", keywords[cpt]);
print_help:
cmmNATPTQueryUsage();
return -1;
}