blob: 5b042e2350327ca0443314d8c7d199390cb0a49c [file] [log] [blame]
/*
* Copyright (c) 2020 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
#include <vlib/vlib.h>
#include <vlibapi/api_types.h>
#include <vppinfra/cJSON.h>
/* VPP API client includes */
#include <vpp-api/client/vppapiclient.h>
#include <limits.h>
#include "vat2.h"
uword *function_by_name;
bool debug = false;
char *vat2_plugin_path;
static void
vat2_find_plugin_path ()
{
char *p, path[PATH_MAX];
int rv;
u8 *s;
/* find executable path */
if ((rv = readlink ("/proc/self/exe", path, PATH_MAX - 1)) == -1)
return;
/* readlink doesn't provide null termination */
path[rv] = 0;
/* strip filename */
if ((p = strrchr (path, '/')) == 0)
return;
*p = 0;
/* strip bin/ */
if ((p = strrchr (path, '/')) == 0)
return;
*p = 0;
s = format (0, "%s/lib/" CLIB_TARGET_TRIPLET "/vat2_plugins:"
"%s/lib/vat2_plugins", path, path);
vec_add1 (s, 0);
vat2_plugin_path = (char *) s;
}
void
vac_callback (unsigned char *data, int len)
{
u16 result_msg_id = ntohs(*((u16 *)data));
DBG("Received something async: %d\n", result_msg_id);
}
int vat2_load_plugins (char *path, char *filter, int *loaded);
static int
register_function (void)
{
int loaded;
vat2_find_plugin_path();
DBG("Plugin Path %s\n", vat2_plugin_path);
int rv = vat2_load_plugins(vat2_plugin_path, 0, &loaded);
DBG("Loaded %u plugins\n", loaded);
return rv;
}
void
vat2_register_function(char *name, cJSON (*f)(cJSON *))
{
hash_set_mem(function_by_name, name, f);
}
int main (int argc, char **argv)
{
/* Create a heap of 64MB */
clib_mem_init (0, 64 << 20);
char *filename = 0;
int index;
int c;
opterr = 0;
cJSON *o = 0;
uword *p = 0;
while ((c = getopt (argc, argv, "df:")) != -1) {
switch (c) {
case 'd':
debug = true;
break;
case 'f':
filename = optarg;
break;
case '?':
if (optopt == 'f')
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
else if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf (stderr,
"Unknown option character `\\x%x'.\n",
optopt);
return 1;
default:
abort ();
}
}
DBG("debug = %d, filename = %s\n", debug, filename);
for (index = optind; index < argc; index++)
DBG ("Non-option argument %s\n", argv[index]);
index = optind;
/* Load plugins */
function_by_name = hash_create_string (0, sizeof (uword));
int res = register_function();
if (res < 0) {
fprintf(stderr, "%s: loading plugins failed\n", argv[0]);
exit(-1);
}
if (argc > index + 2) {
fprintf(stderr, "%s: Too many arguments\n", argv[0]);
exit(-1);
}
/* Read JSON from stdin, command line or file */
if (argc >= (index + 1)) {
p = hash_get_mem (function_by_name, argv[index]);
if (p == 0) {
fprintf(stderr, "%s: Unknown command: %s\n", argv[0], argv[index]);
exit(-1);
}
}
if (argc == (index + 2)) {
o = cJSON_Parse(argv[index+1]);
if (!o) {
fprintf(stderr, "%s: Failed parsing JSON input: %s\n", argv[0], cJSON_GetErrorPtr());
exit(-1);
}
}
if (filename) {
if (argc > index + 1) {
fprintf(stderr, "%s: Superfluous arguments when filename given\n", argv[0]);
exit(-1);
}
FILE *f = fopen(filename, "r");
size_t bufsize = 1024;
size_t n_read = 0;
size_t n;
if (!f) {
fprintf(stderr, "%s: can't open file: %s\n", argv[0], filename);
exit(-1);
}
char *buf = malloc(bufsize);
while ((n = fread(buf, 1, bufsize, f))) {
n_read += n;
if (n == bufsize)
buf = realloc(buf, bufsize);
}
fclose(f);
if (n_read) {
o = cJSON_Parse(buf);
free(buf);
if (!o) {
fprintf(stderr, "%s: Failed parsing JSON input: %s\n", argv[0], cJSON_GetErrorPtr());
exit(-1);
}
}
}
if (!o) {
fprintf(stderr, "%s: Failed parsing JSON input\n", argv[0]);
exit(-1);
}
if (vac_connect("vat2", 0, 0, 1024)) {
fprintf(stderr, "Failed connecting to VPP\n");
exit(-1);
}
if (!p) {
fprintf(stderr, "No such command\n");
exit(-1);
}
cJSON * (*fp) (cJSON *);
fp = (void *) p[0];
cJSON *r = (*fp) (o);
if (o)
cJSON_Delete(o);
if (r) {
char *output = cJSON_Print(r);
cJSON_Delete(r);
printf("%s\n", output);
free(output);
} else {
fprintf(stderr, "Call failed\n");
exit(-1);
}
vac_disconnect();
exit (0);
}