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