1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation. 3 * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org> 4 * All rights reserved. 5 */ 6 7 #include <stdio.h> 8 #include <stdint.h> 9 #include <string.h> 10 #include <stdlib.h> 11 #include <errno.h> 12 13 #include <cmdline_rdline.h> 14 #include <cmdline_parse.h> 15 #include <cmdline_parse_ipaddr.h> 16 #include <cmdline_parse_num.h> 17 #include <cmdline_parse_string.h> 18 #include <cmdline.h> 19 20 #include <rte_string_fns.h> 21 22 #include "parse_obj_list.h" 23 24 struct object_list global_obj_list; 25 26 /* not defined under linux */ 27 #ifndef NIPQUAD 28 #define NIPQUAD_FMT "%u.%u.%u.%u" 29 #define NIPQUAD(addr) \ 30 (unsigned)((unsigned char *)&addr)[0], \ 31 (unsigned)((unsigned char *)&addr)[1], \ 32 (unsigned)((unsigned char *)&addr)[2], \ 33 (unsigned)((unsigned char *)&addr)[3] 34 #endif 35 36 #ifndef NIP6 37 #define NIP6_FMT "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x" 38 #define NIP6(addr) \ 39 (unsigned)((addr).s6_addr[0]), \ 40 (unsigned)((addr).s6_addr[1]), \ 41 (unsigned)((addr).s6_addr[2]), \ 42 (unsigned)((addr).s6_addr[3]), \ 43 (unsigned)((addr).s6_addr[4]), \ 44 (unsigned)((addr).s6_addr[5]), \ 45 (unsigned)((addr).s6_addr[6]), \ 46 (unsigned)((addr).s6_addr[7]), \ 47 (unsigned)((addr).s6_addr[8]), \ 48 (unsigned)((addr).s6_addr[9]), \ 49 (unsigned)((addr).s6_addr[10]), \ 50 (unsigned)((addr).s6_addr[11]), \ 51 (unsigned)((addr).s6_addr[12]), \ 52 (unsigned)((addr).s6_addr[13]), \ 53 (unsigned)((addr).s6_addr[14]), \ 54 (unsigned)((addr).s6_addr[15]) 55 #endif 56 57 58 /**********************************************************/ 59 60 struct cmd_obj_del_show_result { 61 cmdline_fixed_string_t action; 62 struct object *obj; 63 }; 64 65 static void cmd_obj_del_show_parsed(void *parsed_result, 66 struct cmdline *cl, 67 __rte_unused void *data) 68 { 69 struct cmd_obj_del_show_result *res = parsed_result; 70 char ip_str[INET6_ADDRSTRLEN]; 71 72 if (res->obj->ip.family == AF_INET) 73 snprintf(ip_str, sizeof(ip_str), NIPQUAD_FMT, 74 NIPQUAD(res->obj->ip.addr.ipv4)); 75 else 76 snprintf(ip_str, sizeof(ip_str), NIP6_FMT, 77 NIP6(res->obj->ip.addr.ipv6)); 78 79 if (strcmp(res->action, "del") == 0) { 80 SLIST_REMOVE(&global_obj_list, res->obj, object, next); 81 cmdline_printf(cl, "Object %s removed, ip=%s\n", 82 res->obj->name, ip_str); 83 free(res->obj); 84 } 85 else if (strcmp(res->action, "show") == 0) { 86 cmdline_printf(cl, "Object %s, ip=%s\n", 87 res->obj->name, ip_str); 88 } 89 } 90 91 cmdline_parse_token_string_t cmd_obj_action = 92 TOKEN_STRING_INITIALIZER(struct cmd_obj_del_show_result, 93 action, "show#del"); 94 parse_token_obj_list_t cmd_obj_obj = 95 TOKEN_OBJ_LIST_INITIALIZER(struct cmd_obj_del_show_result, obj, 96 &global_obj_list); 97 98 cmdline_parse_inst_t cmd_obj_del_show = { 99 .f = cmd_obj_del_show_parsed, /* function to call */ 100 .data = NULL, /* 2nd arg of func */ 101 .help_str = "Show/del an object", 102 .tokens = { /* token list, NULL terminated */ 103 (void *)&cmd_obj_action, 104 (void *)&cmd_obj_obj, 105 NULL, 106 }, 107 }; 108 109 /**********************************************************/ 110 111 struct cmd_obj_add_result { 112 cmdline_fixed_string_t action; 113 cmdline_fixed_string_t name; 114 cmdline_ipaddr_t ip; 115 }; 116 117 static void cmd_obj_add_parsed(void *parsed_result, 118 struct cmdline *cl, 119 __rte_unused void *data) 120 { 121 struct cmd_obj_add_result *res = parsed_result; 122 struct object *o; 123 char ip_str[INET6_ADDRSTRLEN]; 124 125 SLIST_FOREACH(o, &global_obj_list, next) { 126 if (!strcmp(res->name, o->name)) { 127 cmdline_printf(cl, "Object %s already exist\n", res->name); 128 return; 129 } 130 break; 131 } 132 133 o = malloc(sizeof(*o)); 134 if (!o) { 135 cmdline_printf(cl, "mem error\n"); 136 return; 137 } 138 strlcpy(o->name, res->name, sizeof(o->name)); 139 o->ip = res->ip; 140 SLIST_INSERT_HEAD(&global_obj_list, o, next); 141 142 if (o->ip.family == AF_INET) 143 snprintf(ip_str, sizeof(ip_str), NIPQUAD_FMT, 144 NIPQUAD(o->ip.addr.ipv4)); 145 else 146 snprintf(ip_str, sizeof(ip_str), NIP6_FMT, 147 NIP6(o->ip.addr.ipv6)); 148 149 cmdline_printf(cl, "Object %s added, ip=%s\n", 150 o->name, ip_str); 151 } 152 153 cmdline_parse_token_string_t cmd_obj_action_add = 154 TOKEN_STRING_INITIALIZER(struct cmd_obj_add_result, action, "add"); 155 cmdline_parse_token_string_t cmd_obj_name = 156 TOKEN_STRING_INITIALIZER(struct cmd_obj_add_result, name, NULL); 157 cmdline_parse_token_ipaddr_t cmd_obj_ip = 158 TOKEN_IPADDR_INITIALIZER(struct cmd_obj_add_result, ip); 159 160 cmdline_parse_inst_t cmd_obj_add = { 161 .f = cmd_obj_add_parsed, /* function to call */ 162 .data = NULL, /* 2nd arg of func */ 163 .help_str = "Add an object (name, val)", 164 .tokens = { /* token list, NULL terminated */ 165 (void *)&cmd_obj_action_add, 166 (void *)&cmd_obj_name, 167 (void *)&cmd_obj_ip, 168 NULL, 169 }, 170 }; 171 172 /**********************************************************/ 173 174 struct cmd_help_result { 175 cmdline_fixed_string_t help; 176 }; 177 178 static void cmd_help_parsed(__rte_unused void *parsed_result, 179 struct cmdline *cl, 180 __rte_unused void *data) 181 { 182 cmdline_printf(cl, 183 "Demo example of command line interface in RTE\n\n" 184 "This is a readline-like interface that can be used to\n" 185 "debug your RTE application. It supports some features\n" 186 "of GNU readline like completion, cut/paste, and some\n" 187 "other special bindings.\n\n" 188 "This demo shows how rte_cmdline library can be\n" 189 "extended to handle a list of objects. There are\n" 190 "3 commands:\n" 191 "- add obj_name IP\n" 192 "- del obj_name\n" 193 "- show obj_name\n\n"); 194 } 195 196 cmdline_parse_token_string_t cmd_help_help = 197 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help"); 198 199 cmdline_parse_inst_t cmd_help = { 200 .f = cmd_help_parsed, /* function to call */ 201 .data = NULL, /* 2nd arg of func */ 202 .help_str = "show help", 203 .tokens = { /* token list, NULL terminated */ 204 (void *)&cmd_help_help, 205 NULL, 206 }, 207 }; 208 209 210 /**********************************************************/ 211 /**********************************************************/ 212 /****** CONTEXT (list of instruction) */ 213 214 cmdline_parse_ctx_t main_ctx[] = { 215 (cmdline_parse_inst_t *)&cmd_obj_del_show, 216 (cmdline_parse_inst_t *)&cmd_obj_add, 217 (cmdline_parse_inst_t *)&cmd_help, 218 NULL, 219 }; 220