From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail04.ics.ntt-tx.co.jp (mail05.ics.ntt-tx.co.jp [210.232.35.69]) by dpdk.org (Postfix) with ESMTP id 8EDA21B396 for ; Fri, 8 Feb 2019 09:46:00 +0100 (CET) Received: from gwchk03.silk.ntt-tx.co.jp (gwchk03.silk.ntt-tx.co.jp [10.107.0.111]) by mail04.ics.ntt-tx.co.jp (unknown) with ESMTP id x188jwTw008975; Fri, 8 Feb 2019 17:45:58 +0900 Received: (from root@localhost) by gwchk03.silk.ntt-tx.co.jp (unknown) id x188jwo3025793; Fri, 8 Feb 2019 17:45:58 +0900 Received: from gwchk.silk.ntt-tx.co.jp [10.107.0.110] by gwchk03.silk.ntt-tx.co.jp with ESMTP id TAA25052; Fri, 8 Feb 2019 17:44:38 +0900 Received: from imss04.silk.ntt-tx.co.jp (localhost [127.0.0.1]) by imss04.silk.ntt-tx.co.jp (unknown) with ESMTP id x188icjF030813; Fri, 8 Feb 2019 17:44:38 +0900 Received: from mgate02.silk.ntt-tx.co.jp (smtp02.silk.ntt-tx.co.jp [10.107.0.37]) by imss04.silk.ntt-tx.co.jp (unknown) with ESMTP id x188ic3I030810; Fri, 8 Feb 2019 17:44:38 +0900 Message-Id: <201902080844.x188ic3I030810@imss04.silk.ntt-tx.co.jp> Received: from localhost by mgate02.silk.ntt-tx.co.jp (unknown) id x188icfx028979 ; Fri, 8 Feb 2019 17:44:38 +0900 From: x-fn-spp@sl.ntt-tx.co.jp To: ferruh.yigit@intel.com, ogawa.yasufumi@lab.ntt.co.jp Cc: spp@dpdk.org Date: Fri, 8 Feb 2019 17:44:33 +0900 X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190208084438.7952-1-x-fn-spp@sl.ntt-tx.co.jp> References: <20190208084438.7952-1-x-fn-spp@sl.ntt-tx.co.jp> X-TM-AS-MML: No Subject: [spp] [PATCH v2 2/7] spp_pcap: add command decode X-BeenThere: spp@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Soft Patch Panel List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Feb 2019 08:46:01 -0000 From: Hideyuki Yamashita Add command decode part for start, stop and status. Signed-off-by: Hideyuki Yamashita Signed-off-by: Naoki Takada --- src/pcap/command_dec.c | 187 +++++++++++++++++++++++++++++++++++++++++ src/pcap/command_dec.h | 110 ++++++++++++++++++++++++ 2 files changed, 297 insertions(+) create mode 100644 src/pcap/command_dec.c create mode 100644 src/pcap/command_dec.h diff --git a/src/pcap/command_dec.c b/src/pcap/command_dec.c new file mode 100644 index 0000000..943ab0f --- /dev/null +++ b/src/pcap/command_dec.c @@ -0,0 +1,187 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019 Nippon Telegraph and Telephone Corporation + */ + +#include +#include + +#include +#include +#include + +#include "command_dec.h" + +#define RTE_LOGTYPE_SPP_COMMAND_DEC RTE_LOGTYPE_USER2 + +/* set parse error */ +static inline int +set_parse_error(struct spp_command_parse_error *error, + const int error_code, const char *error_name) +{ + error->code = error_code; + + if (likely(error_name != NULL)) + strcpy(error->value_name, error_name); + + return error->code; +} + +/* set parse error */ +static inline int +set_string_value_parse_error(struct spp_command_parse_error *error, + const char *value, const char *error_name) +{ + strcpy(error->value, value); + return set_parse_error(error, BAD_VALUE, error_name); +} + +/* Split command line parameter with spaces */ +static int +parse_parameter_value(char *string, int max, int *argc, char *argv[]) +{ + int cnt = 0; + const char *delim = " "; + char *argv_tok = NULL; + char *saveptr = NULL; + + argv_tok = strtok_r(string, delim, &saveptr); + while (argv_tok != NULL) { + if (cnt >= max) + return SPP_RET_NG; + argv[cnt] = argv_tok; + cnt++; + argv_tok = strtok_r(NULL, delim, &saveptr); + } + *argc = cnt; + + return SPP_RET_OK; +} + +/* command list for parse */ +struct parse_command_list { + const char *name; /* Command name */ + int param_min; /* Min number of parameters */ + int param_max; /* Max number of parameters */ + int (*func)(struct spp_command_request *request, int argc, + char *argv[], struct spp_command_parse_error *error, + int maxargc); + /* Pointer to command handling function */ + enum spp_command_type type; + /* Command type */ +}; + +/* command list */ +static struct parse_command_list command_list_pcap[] = { + { "_get_client_id", 1, 1, NULL, CMD_CLIENT_ID }, + { "status", 1, 1, NULL, CMD_STATUS }, + { "exit", 1, 1, NULL, CMD_EXIT }, + { "start", 1, 1, NULL, CMD_START }, + { "stop", 1, 1, NULL, CMD_STOP }, + { "", 0, 0, NULL, 0 } /* termination */ +}; + +/* Parse command line parameters */ +static int +parse_command_in_list(struct spp_command_request *request, + const char *request_str, + struct spp_command_parse_error *error) +{ + int ret = SPP_RET_OK; + int command_name_check = 0; + struct parse_command_list *list = NULL; + int i = 0; + int argc = 0; + char *argv[SPP_CMD_MAX_PARAMETERS]; + char tmp_str[SPP_CMD_MAX_PARAMETERS*SPP_CMD_VALUE_BUFSZ]; + memset(argv, 0x00, sizeof(argv)); + memset(tmp_str, 0x00, sizeof(tmp_str)); + + strcpy(tmp_str, request_str); + ret = parse_parameter_value(tmp_str, SPP_CMD_MAX_PARAMETERS, + &argc, argv); + if (ret < SPP_RET_OK) { + RTE_LOG(ERR, SPP_COMMAND_DEC, "Parameter number over limit." + "request_str=%s\n", request_str); + return set_parse_error(error, BAD_FORMAT, NULL); + } + RTE_LOG(DEBUG, SPP_COMMAND_DEC, "Decode array. num=%d\n", argc); + + for (i = 0; command_list_pcap[i].name[0] != '\0'; i++) { + list = &command_list_pcap[i]; + if (strcmp(argv[0], list->name) != 0) + continue; + + if (unlikely(argc < list->param_min) || + unlikely(list->param_max < argc)) { + command_name_check = 1; + continue; + } + + request->commands[0].type = command_list_pcap[i].type; + if (list->func != NULL) + return (*list->func)(request, argc, argv, error, + list->param_max); + + return SPP_RET_OK; + } + + if (command_name_check != 0) { + RTE_LOG(ERR, SPP_COMMAND_DEC, "Parameter number out of range." + "request_str=%s\n", request_str); + return set_parse_error(error, BAD_FORMAT, NULL); + } + + RTE_LOG(ERR, SPP_COMMAND_DEC, + "Unknown command. command=%s, request_str=%s\n", + argv[0], request_str); + return set_string_value_parse_error(error, argv[0], "command"); +} + +/* parse request from no-null-terminated string */ +int +spp_command_parse_request( + struct spp_command_request *request, + const char *request_str, size_t request_str_len, + struct spp_command_parse_error *error) +{ + int ret = SPP_RET_NG; + int i; + + /* parse request */ + request->num_command = 1; + ret = parse_command_in_list(request, request_str, error); + if (unlikely(ret != SPP_RET_OK)) { + RTE_LOG(ERR, SPP_COMMAND_DEC, + "Cannot parse command request. " + "ret=%d, request_str=%.*s\n", + ret, (int)request_str_len, request_str); + return ret; + } + request->num_valid_command = 1; + + /* check getter command */ + for (i = 0; i < request->num_valid_command; ++i) { + switch (request->commands[i].type) { + case CMD_CLIENT_ID: + request->is_requested_client_id = 1; + break; + case CMD_STATUS: + request->is_requested_status = 1; + break; + case CMD_EXIT: + request->is_requested_exit = 1; + break; + case CMD_START: + request->is_requested_start = 1; + break; + case CMD_STOP: + request->is_requested_stop = 1; + break; + default: + /* nothing to do */ + break; + } + } + + return ret; +} diff --git a/src/pcap/command_dec.h b/src/pcap/command_dec.h new file mode 100644 index 0000000..0835382 --- /dev/null +++ b/src/pcap/command_dec.h @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019 Nippon Telegraph and Telephone Corporation + */ + +#ifndef _SPP_PCAP_COMMAND_DEC_H_ +#define _SPP_PCAP_COMMAND_DEC_H_ + +/** + * @file + * SPP pcap command parse + * + * Decode and validate the command message string. + */ + +#include "spp_proc.h" + +/** max number of command per request */ +#define SPP_CMD_MAX_COMMANDS 32 + +/** maximum number of parameters per command */ +#define SPP_CMD_MAX_PARAMETERS 8 + +/** command name string buffer size (include null char) */ +#define SPP_CMD_NAME_BUFSZ 32 + +/** command value string buffer size (include null char) */ +#define SPP_CMD_VALUE_BUFSZ 111 + +/** parse error code */ +enum spp_command_parse_error_code { + /* not use 0, in general 0 is OK */ + BAD_FORMAT = 1, /**< Wrong format */ + UNKNOWN_COMMAND, /**< Unknown command */ + NO_PARAM, /**< No parameters */ + BAD_TYPE, /**< Wrong data type */ + BAD_VALUE, /**< Wrong value */ +}; + +/** + * spp command type. + * + * @attention This enumerated type must have the same order of command_list + * defined in command_dec_pcap.c + */ +enum spp_command_type { + /** get_client_id command */ + CMD_CLIENT_ID, + + /** status command */ + CMD_STATUS, + + /** exit command */ + CMD_EXIT, + + /** start command */ + CMD_START, + + /** stop command */ + CMD_STOP, + +}; + +/** command parameters */ +struct spp_command { + enum spp_command_type type; /**< Command type */ +}; + +/** request parameters */ +struct spp_command_request { + int num_command; /**< Number of accepted commands */ + int num_valid_command; /**< Number of executed commands */ + struct spp_command commands[SPP_CMD_MAX_COMMANDS]; + /**