1 /* -*- mode: c; c-file-style: "openbsd" -*- */
3 * Copyright (c) 2012 Vincent Bernat <bernat@luffy.cx>
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 * The environment will contain the following keys:
26 * - C{ports} list of ports we want to restrict showing.
27 * - C{hidden} if we should show hidden ports.
28 * - C{summary} if we want to show only a summary
29 * - C{detailed} for a detailed overview
32 cmd_show_neighbors(struct lldpctl_conn_t
*conn
, struct writer
*w
,
33 struct cmd_env
*env
, void *arg
)
35 log_debug("lldpctl", "show neighbors data (%s) %s hidden neighbors",
36 cmdenv_get(env
, "summary")?"summary":
37 cmdenv_get(env
, "detailed")?"detailed":
38 "normal", cmdenv_get(env
, "hidden")?"with":"without");
39 if (cmdenv_get(env
, "ports"))
40 log_debug("lldpctl", "restrict to the following ports: %s",
41 cmdenv_get(env
, "ports"));
43 display_interfaces(conn
, w
, env
, !!cmdenv_get(env
, "hidden"),
44 cmdenv_get(env
, "summary")?DISPLAY_BRIEF
:
45 cmdenv_get(env
, "detailed")?DISPLAY_DETAILS
:
54 * The environment will contain the following keys:
55 * - C{summary} if we want to show only a summary
56 * - C{detailed} for a detailed overview
59 cmd_show_chassis(struct lldpctl_conn_t
*conn
, struct writer
*w
,
60 struct cmd_env
*env
, void *arg
)
62 log_debug("lldpctl", "show chassis data (%s)",
63 cmdenv_get(env
, "summary")?"summary":
64 cmdenv_get(env
, "detailed")?"detailed":
67 display_local_chassis(conn
, w
, env
,
68 cmdenv_get(env
, "summary")?DISPLAY_BRIEF
:
69 cmdenv_get(env
, "detailed")?DISPLAY_DETAILS
:
78 * The environment will contain the following keys:
79 * - C{ports} list of ports we want to restrict showing.
80 * - C{summary} summary of stats
83 cmd_show_interface_stats(struct lldpctl_conn_t
*conn
, struct writer
*w
,
84 struct cmd_env
*env
, void *arg
)
86 log_debug("lldpctl", "show stats data");
87 if (cmdenv_get(env
, "ports"))
88 log_debug("lldpctl", "restrict to the following ports: %s",
89 cmdenv_get(env
, "ports"));
90 if (cmdenv_get(env
, "summary"))
91 log_debug("lldpctl", "show summary of stats across ports");
93 display_interfaces_stats(conn
, w
, env
);
99 cmd_check_no_detailed_nor_summary(struct cmd_env
*env
, void *arg
)
101 if (cmdenv_get(env
, "detailed")) return 0;
102 if (cmdenv_get(env
, "summary")) return 0;
107 * Show running configuration.
110 cmd_show_configuration(struct lldpctl_conn_t
*conn
, struct writer
*w
,
111 struct cmd_env
*env
, void *arg
)
113 log_debug("lldpctl", "show running configuration");
114 display_configuration(conn
, w
);
125 * Callback for the next function to display a new neighbor.
128 watchcb(lldpctl_conn_t
*conn
,
129 lldpctl_change_t type
,
130 lldpctl_atom_t
*interface
,
131 lldpctl_atom_t
*neighbor
,
134 struct watcharg
*wa
= data
;
135 struct cmd_env
*env
= wa
->env
;
136 struct writer
*w
= wa
->w
;
137 const char *interfaces
= cmdenv_get(env
, "ports");
138 const char *proto_str
;
139 int protocol
= LLDPD_MODE_MAX
;
141 if (interfaces
&& !contains(interfaces
, lldpctl_atom_get_str(interface
,
142 lldpctl_k_interface_name
)))
145 /* user might have specified protocol to filter display results */
146 proto_str
= cmdenv_get(env
, "protocol");
149 log_debug("display", "filter protocol: %s ", proto_str
);
151 protocol
= 0; /* unsupported */
152 for (lldpctl_map_t
*protocol_map
=
153 lldpctl_key_get_map(lldpctl_k_port_protocol
);
154 protocol_map
->string
;
156 if (!strcasecmp(proto_str
, protocol_map
->string
)) {
157 protocol
= protocol_map
->value
;
164 case lldpctl_c_deleted
:
165 tag_start(w
, "lldp-deleted", "LLDP neighbor deleted");
167 case lldpctl_c_updated
:
168 tag_start(w
, "lldp-updated", "LLDP neighbor updated");
170 case lldpctl_c_added
:
171 tag_start(w
, "lldp-added", "LLDP neighbor added");
175 display_interface(conn
, w
, 1, interface
, neighbor
,
176 cmdenv_get(env
, "summary")?DISPLAY_BRIEF
:
177 cmdenv_get(env
, "detailed")?DISPLAY_DETAILS
:
178 DISPLAY_NORMAL
, protocol
);
184 * Watch for neighbor changes.
187 cmd_watch_neighbors(struct lldpctl_conn_t
*conn
, struct writer
*w
,
188 struct cmd_env
*env
, void *arg
)
190 struct watcharg wa
= {
195 const char *limit_str
= cmdenv_get(env
, "limit");
200 limit
= strtonum(limit_str
, 1, LLONG_MAX
, &errstr
);
201 if (errstr
!= NULL
) {
202 log_warnx("lldpctl", "specified limit (%s) is %s and ignored",
207 log_debug("lldpctl", "watch for neighbor changes");
208 if (lldpctl_watch_callback(conn
, watchcb
, &wa
) < 0) {
209 log_warnx("lldpctl", "unable to watch for neighbors. %s",
210 lldpctl_last_strerror(conn
));
214 if (lldpctl_watch(conn
) < 0) {
215 log_warnx("lldpctl", "unable to watch for neighbors. %s",
216 lldpctl_last_strerror(conn
));
219 if (limit
> 0 && wa
.nb
>= limit
)
226 * Register common subcommands for `watch` and `show neighbors` and `show chassis'
229 register_common_commands(struct cmd_node
*root
, int neighbor
)
231 /* With more details */
235 cmd_check_no_detailed_nor_summary
, cmd_store_env_and_pop
, "detailed");
237 /* With less details */
241 cmd_check_no_detailed_nor_summary
, cmd_store_env_and_pop
, "summary");
243 if (!neighbor
) return;
245 /* With hidden neighbors */
248 "Include hidden neighbors",
249 cmd_check_no_env
, cmd_store_env_and_pop
, "hidden");
251 /* Some specific port */
252 cmd_restrict_ports(root
);
254 /* Specific protocol */
255 cmd_restrict_protocol(root
);
259 * Register sub command summary
262 register_summary_command(struct cmd_node
*root
)
267 cmd_check_no_detailed_nor_summary
, cmd_store_env_and_pop
, "summary");
271 * Register subcommands to `show`
273 * @param root Root node
276 register_commands_show(struct cmd_node
*root
)
278 struct cmd_node
*show
= commands_new(
281 "Show running system information",
283 struct cmd_node
*neighbors
= commands_new(
286 "Show neighbors data",
289 struct cmd_node
*chassis
= commands_new(
292 "Show local chassis data",
295 struct cmd_node
*stats
= commands_new(
302 commands_new(neighbors
,
304 "Show neighbors data",
305 NULL
, cmd_show_neighbors
, NULL
);
307 register_common_commands(neighbors
, 1);
310 commands_new(chassis
,
312 "Show local chassis data",
313 NULL
, cmd_show_chassis
, NULL
);
315 register_common_commands(chassis
, 0);
321 NULL
, cmd_show_interface_stats
, NULL
);
323 cmd_restrict_ports(stats
);
324 register_summary_command(stats
);
326 /* Register "show configuration" and "show running-configuration" */
330 "Show running configuration",
333 "Show running configuration",
334 NULL
, cmd_show_configuration
, NULL
);
337 "running-configuration",
338 "Show running configuration",
341 "Show running configuration",
342 NULL
, cmd_show_configuration
, NULL
);
346 * Register subcommands to `watch`
348 * @param root Root node
351 register_commands_watch(struct cmd_node
*root
)
353 struct cmd_node
*watch
= commands_new(
356 "Monitor neighbor changes",
361 "Monitor neighbors change",
362 NULL
, cmd_watch_neighbors
, NULL
);
367 "Don't show more than X events",
368 cmd_check_no_env
, NULL
, "limit"),
370 "Stop after getting X events",
371 NULL
, cmd_store_env_value_and_pop2
, "limit");
373 register_common_commands(watch
, 1);