static int cmd_system_chassisid(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { const char *value; value = cmdenv_get(env, "description"); log_debug("lldpctl", "set chassis ID"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } if (lldpctl_atom_set_str(config, lldpctl_k_config_cid_string, value) == NULL) { log_warnx("lldpctl", "unable to set chassis ID. %s", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "chassis ID set to new value %s", value?value:"(none)"); lldpctl_atom_dec_ref(config); return 1; }
static int cmd_faststart(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_debug("lldpctl", "configure fast interval support"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } char *action = arg; if ((!strcmp(action, "enable") && (lldpctl_atom_set_int(config, lldpctl_k_config_fast_start_enabled, 1) == NULL)) || (!strcmp(action, "disable") && (lldpctl_atom_set_int(config, lldpctl_k_config_fast_start_enabled, 0) == NULL)) || (!strcmp(action, "delay") && (lldpctl_atom_set_str(config, lldpctl_k_config_fast_start_interval, cmdenv_get(env, "tx-interval")) == NULL))) { log_warnx("lldpctl", "unable to setup fast start. %s", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "configruation for fast start applied"); lldpctl_atom_dec_ref(config); return 1; }
static int cmd_hostname(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { struct utsname un; log_debug("lldpctl", "set system name"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } const char *value = cmdenv_get(env, "hostname"); if (value && strlen(value) == 1 && value[0] == '.') { if (uname(&un) < 0) { log_warn("lldpctl", "cannot get node name"); return 0; } value = un.nodename; } if (lldpctl_atom_set_str(config, lldpctl_k_config_hostname, value) == NULL) { log_warnx("lldpctl", "unable to set system name. %s", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "system name set to new value %s", value?value:"(none)"); lldpctl_atom_dec_ref(config); return 1; }
/* FIXME: see about compressing this with other functions */ static int cmd_chassis_mgmt_advertise(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_debug("lldpctl", "lldp management-addresses-advertisements %s", arg?"enable":"disable"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } if (lldpctl_atom_set_int(config, lldpctl_k_config_chassis_mgmt_advertise, arg?1:0) == NULL) { log_warnx("lldpctl", "unable to %s management addresses advertisement: %s", arg?"enable":"disable", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "management addresses advertisement %s", arg?"enabled":"disabled"); lldpctl_atom_dec_ref(config); return 1; }
static int cmd_perm_iface_pattern(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_debug("lldpctl", "set permanent iface pattern"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } const char *value = cmdenv_get(env, "iface-pattern"); if (lldpctl_atom_set_str(config, lldpctl_k_config_perm_iface_pattern, value) == NULL) { log_warnx("lldpctl", "unable to set permanent iface pattern. %s", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "permanent iface pattern set to new value %s", value?value:"(none)"); lldpctl_atom_dec_ref(config); return 1; }
static int cmd_system_description(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { int platform = 0; const char *value = cmdenv_get(env, "description"); if (!value) { platform = 1; value = cmdenv_get(env, "platform"); } log_debug("lldpctl", "set %s description", platform?"platform":"system"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } if (lldpctl_atom_set_str(config, platform?lldpctl_k_config_platform:lldpctl_k_config_description, value) == NULL) { log_warnx("lldpctl", "unable to set description. %s", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "description set to new value %s", value); lldpctl_atom_dec_ref(config); return 1; }
/** * Pause or resume execution of lldpd. * * @param conn The connection to lldpd. * @param pause 1 if we want to pause lldpd, 0 otherwise * @return 1 on success, 0 on error */ static int cmd_pause_resume(lldpctl_conn_t *conn, int pause) { lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } if (lldpctl_atom_get_int(config, lldpctl_k_config_paused) == pause) { log_debug("lldpctl", "lldpd is already %s", pause?"paused":"resumed"); lldpctl_atom_dec_ref(config); return 1; } if (lldpctl_atom_set_int(config, lldpctl_k_config_paused, pause) == NULL) { log_warnx("lldpctl", "unable to ask lldpd to %s operations. %s", pause?"pause":"resume", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "lldpd should %s operations", pause?"pause":"resume"); lldpctl_atom_dec_ref(config); return 1; }
static int cmd_medpower(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_debug("lldpctl", "set MED power"); lldpctl_atom_t *iface; while ((iface = cmd_iterate_on_interfaces(conn, env))) { const char *name = lldpctl_atom_get_str(iface, lldpctl_k_interface_name); lldpctl_atom_t *port = lldpctl_get_port(iface); lldpctl_atom_t *med_power; const char *what = NULL; med_power = lldpctl_atom_get(port, lldpctl_k_port_med_power); if (med_power == NULL) { log_warnx("lldpctl", "unable to set LLDP-MED power: support seems unavailable"); goto end; } if ((what = "device type", lldpctl_atom_set_str(med_power, lldpctl_k_med_power_type, cmdenv_get(env, "device-type"))) == NULL || (what = "power source", lldpctl_atom_set_str(med_power, lldpctl_k_med_power_source, cmdenv_get(env, "source"))) == NULL || (what = "power priority", lldpctl_atom_set_str(med_power, lldpctl_k_med_power_priority, cmdenv_get(env, "priority"))) == NULL || (what = "power value", lldpctl_atom_set_str(med_power, lldpctl_k_med_power_val, cmdenv_get(env, "value"))) == NULL) log_warnx("lldpctl", "unable to set LLDP MED power value for %s on %s. %s.", what, name, lldpctl_last_strerror(conn)); else { if (lldpctl_atom_set(port, lldpctl_k_port_med_power, med_power) == NULL) { log_warnx("lldpctl", "unable to set LLDP MED power on %s. %s.", name, lldpctl_last_strerror(conn)); } else log_info("lldpctl", "LLDP-MED power has been set for port %s", name); } end: lldpctl_atom_dec_ref(med_power); lldpctl_atom_dec_ref(port); } return 1; }
static void _lldpctl_atom_free_port(lldpctl_atom_t *atom) { struct _lldpctl_atom_port_t *port = (struct _lldpctl_atom_port_t *)atom; struct lldpd_hardware *hardware = port->hardware; struct lldpd_chassis *one_chassis, *one_chassis_next; struct lldpd_port *one_port; /* Free internal chassis atom. Should be freed immediately since we * should have the only reference. */ lldpctl_atom_dec_ref((lldpctl_atom_t*)port->chassis); /* We need to free the whole struct lldpd_hardware: local port, local * chassis and remote ports... The same chassis may be present several * times. We build a list of chassis (we don't use reference count). */ struct chassis_list chassis_list; TAILQ_INIT(&chassis_list); if (port->parent) lldpctl_atom_dec_ref((lldpctl_atom_t*)port->parent); else if (!hardware && port->port) { /* No parent, no hardware, we assume a single neighbor: one * port, one chassis. */ if (port->port->p_chassis) { lldpd_chassis_cleanup(port->port->p_chassis, 1); port->port->p_chassis = NULL; } lldpd_port_cleanup(port->port, 1); free(port->port); } if (!hardware) return; add_chassis(&chassis_list, port->port->p_chassis); TAILQ_FOREACH(one_port, &hardware->h_rports, p_entries) add_chassis(&chassis_list, one_port->p_chassis); /* Free hardware port */ lldpd_remote_cleanup(hardware, NULL, 1); lldpd_port_cleanup(port->port, 1); free(port->hardware); /* Free list of chassis */ for (one_chassis = TAILQ_FIRST(&chassis_list); one_chassis != NULL; one_chassis = one_chassis_next) { one_chassis_next = TAILQ_NEXT(one_chassis, c_entries); lldpd_chassis_cleanup(one_chassis, 1); } }
static void _lldpctl_atom_free_mgmt(lldpctl_atom_t *atom) { struct _lldpctl_atom_mgmt_t *mgmt = (struct _lldpctl_atom_mgmt_t *)atom; lldpctl_atom_dec_ref((lldpctl_atom_t *)mgmt->parent); }
static void _lldpctl_atom_free_mgmts_list(lldpctl_atom_t *atom) { struct _lldpctl_atom_mgmts_list_t *plist = (struct _lldpctl_atom_mgmts_list_t *)atom; lldpctl_atom_dec_ref((lldpctl_atom_t *)plist->parent); }
static void _lldpctl_atom_free_custom(lldpctl_atom_t *atom) { struct _lldpctl_atom_custom_t *custom = (struct _lldpctl_atom_custom_t *)atom; lldpctl_atom_dec_ref((lldpctl_atom_t *)custom->parent); }
static void _lldpctl_atom_free_ppvid(lldpctl_atom_t *atom) { struct _lldpctl_atom_ppvid_t *ppvid = (struct _lldpctl_atom_ppvid_t *)atom; lldpctl_atom_dec_ref((lldpctl_atom_t *)ppvid->parent); }
static void _lldpctl_atom_free_pi(lldpctl_atom_t *atom) { struct _lldpctl_atom_pi_t *pi = (struct _lldpctl_atom_pi_t *)atom; lldpctl_atom_dec_ref((lldpctl_atom_t *)pi->parent); }
static void _lldpctl_atom_free_vlan(lldpctl_atom_t *atom) { struct _lldpctl_atom_vlan_t *vlan = (struct _lldpctl_atom_vlan_t *)atom; lldpctl_atom_dec_ref((lldpctl_atom_t *)vlan->parent); }
static int cmd_portid_type_local(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { lldpctl_atom_t *iface; const char *id = cmdenv_get(env, "port-id"); const char *descr = cmdenv_get(env, "port-descr"); log_debug("lldpctl", "lldp PortID TLV Subtype Local port-id '%s' port-descr '%s'", id, descr); if (!id || !strlen(id)) { log_warnx("lldpctl", "no id specified"); return 0; } while ((iface = cmd_iterate_on_interfaces(conn, env))) { lldpctl_atom_t *port = lldpctl_get_port(iface); if (lldpctl_atom_set_str(port, lldpctl_k_port_id, id) == NULL) { log_warnx("lldpctl", "unable to set LLDP PortID." " %s", lldpctl_last_strerror(conn)); } if (descr && lldpctl_atom_set_str(port, lldpctl_k_port_descr, descr) == NULL) { log_warnx("lldpctl", "unable to set LLDP Port Description." " %s", lldpctl_last_strerror(conn)); } lldpctl_atom_dec_ref(port); } return 1; }
void _lldpctl_atom_free_any_list(lldpctl_atom_t *atom) { struct _lldpctl_atom_any_list_t *plist = (struct _lldpctl_atom_any_list_t *)atom; lldpctl_atom_dec_ref((lldpctl_atom_t *)plist->parent); }
static int cmd_portid_type(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { char *value_str; int value = -1; log_debug("lldpctl", "lldp PortID TLV Subtype"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } value_str = arg; for (lldpctl_map_t *b_map = lldpctl_key_get_map(lldpctl_k_config_lldp_portid_type); b_map->string; b_map++) { if (!strcmp(b_map->string, value_str)) { value = b_map->value; break; } } if (value == -1) { log_warnx("lldpctl", "invalid value"); lldpctl_atom_dec_ref(config); return 0; } if (lldpctl_atom_set_int(config, lldpctl_k_config_lldp_portid_type, value) == NULL) { log_warnx("lldpctl", "unable to set LLDP PortID type." " %s", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "LLDP PortID TLV type set to new value : %s", value_str); lldpctl_atom_dec_ref(config); return 1; }
static int cmd_maxneighs(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_debug("lldpctl", "set maximum neighbors"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } if (lldpctl_atom_set_str(config, lldpctl_k_config_max_neighbors, cmdenv_get(env, "max-neighbors")) == NULL) { log_warnx("lldpctl", "unable to set maximum of neighbors. %s", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "maximum neighbors set to new value %s", cmdenv_get(env, "max-neighbors")); lldpctl_atom_dec_ref(config); return 1; }
/** * Send an "update" request. */ static int cmd_update(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_info("lldpctl", "ask for global update"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } if (lldpctl_atom_set_int(config, lldpctl_k_config_tx_interval, -1) == NULL) { log_warnx("lldpctl", "unable to ask lldpd for immediate retransmission. %s", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "immediate retransmission requested successfuly"); lldpctl_atom_dec_ref(config); return 1; }
static int cmd_txhold(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_debug("lldpctl", "set transmit hold"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } if (lldpctl_atom_set_str(config, lldpctl_k_config_tx_hold, cmdenv_get(env, "tx-hold")) == NULL) { log_warnx("lldpctl", "unable to set transmit hold. %s", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "transmit hold set to new value %s", cmdenv_get(env, "tx-hold")); lldpctl_atom_dec_ref(config); return 1; }
static int cmd_update_descriptions(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } if (lldpctl_atom_set_int(config, lldpctl_k_config_ifdescr_update, arg?1:0) == NULL) { log_warnx("lldpctl", "unable to %s interface description update: %s", arg?"enable":"disable", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "interface description update %s", arg?"enabled":"disabled"); lldpctl_atom_dec_ref(config); return 1; }
static int cmd_medpolicy(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_debug("lldpctl", "set MED policy"); lldpctl_atom_t *iface; while ((iface = cmd_iterate_on_interfaces(conn, env))) { const char *name = lldpctl_atom_get_str(iface, lldpctl_k_interface_name); lldpctl_atom_t *port = lldpctl_get_port(iface); lldpctl_atom_t *med_policy = NULL, *med_policies = NULL; const char *what = NULL; med_policies = lldpctl_atom_get(port, lldpctl_k_port_med_policies); if (med_policies == NULL) { log_warnx("lldpctl", "unable to set LLDP-MED policies: support seems unavailable"); goto end; } med_policy = lldpctl_atom_iter_value(med_policies, lldpctl_atom_iter_next(med_policies, lldpctl_atom_iter(med_policies))); if ((what = "application", lldpctl_atom_set_str(med_policy, lldpctl_k_med_policy_type, cmdenv_get(env, "application"))) == NULL || (what = "unknown flag", lldpctl_atom_set_int(med_policy, lldpctl_k_med_policy_unknown, cmdenv_get(env, "unknown")?1:0)) == NULL || (what = "vlan", cmdenv_get(env, "vlan")? lldpctl_atom_set_str(med_policy, lldpctl_k_med_policy_vid, cmdenv_get(env, "vlan")): lldpctl_atom_set_int(med_policy, lldpctl_k_med_policy_vid, 0)) == NULL || (what = "priority", cmdenv_get(env, "priority")? lldpctl_atom_set_str(med_policy, lldpctl_k_med_policy_priority, cmdenv_get(env, "priority")): lldpctl_atom_set_int(med_policy, lldpctl_k_med_policy_priority, 0)) == NULL || (what = "dscp", cmdenv_get(env, "dscp")? lldpctl_atom_set_str(med_policy, lldpctl_k_med_policy_dscp, cmdenv_get(env, "dscp")): lldpctl_atom_set_int(med_policy, lldpctl_k_med_policy_dscp, 0)) == NULL) log_warnx("lldpctl", "unable to set LLDP MED policy value for %s on %s. %s.", what, name, lldpctl_last_strerror(conn)); else { if (lldpctl_atom_set(port, lldpctl_k_port_med_policies, med_policy) == NULL) { log_warnx("lldpctl", "unable to set LLDP MED policy on %s. %s.", name, lldpctl_last_strerror(conn)); } else log_info("lldpctl", "LLDP-MED policy has been set for port %s", name); } end: lldpctl_atom_dec_ref(med_policy); lldpctl_atom_dec_ref(med_policies); lldpctl_atom_dec_ref(port); } return 1; }
static int _cmd_medlocation(struct lldpctl_conn_t *conn, struct cmd_env *env, int format) { lldpctl_atom_t *iface; while ((iface = cmd_iterate_on_interfaces(conn, env))) { const char *name = lldpctl_atom_get_str(iface, lldpctl_k_interface_name); lldpctl_atom_t *port = lldpctl_get_port(iface); lldpctl_atom_t *med_location = NULL, *med_locations = NULL; const char *what = NULL; int ok = 0; med_locations = lldpctl_atom_get(port, lldpctl_k_port_med_locations); if (med_locations == NULL) { log_warnx("lldpctl", "unable to set LLDP-MED location: support seems unavailable"); goto end; } med_location = lldpctl_atom_iter_value(med_locations, lldpctl_atom_iter_next(med_locations, lldpctl_atom_iter(med_locations))); switch (format) { case LLDP_MED_LOCFORMAT_COORD: if ((what = "format", lldpctl_atom_set_int(med_location, lldpctl_k_med_location_format, format)) == NULL || (what = "latitude", lldpctl_atom_set_str(med_location, lldpctl_k_med_location_latitude, cmdenv_get(env, "latitude"))) == NULL || (what = "longitude", lldpctl_atom_set_str(med_location, lldpctl_k_med_location_longitude, cmdenv_get(env, "longitude"))) == NULL || (what = "altitude", lldpctl_atom_set_str(med_location, lldpctl_k_med_location_altitude, cmdenv_get(env, "altitude"))) == NULL || (what = "altitude unit", lldpctl_atom_set_str(med_location, lldpctl_k_med_location_altitude_unit, cmdenv_get(env, "altitude-unit"))) == NULL || (what = "datum", lldpctl_atom_set_str(med_location, lldpctl_k_med_location_geoid, cmdenv_get(env, "datum"))) == NULL) log_warnx("lldpctl", "unable to set LLDP MED location value for %s on %s. %s.", what, name, lldpctl_last_strerror(conn)); else ok = 1; break; case LLDP_MED_LOCFORMAT_CIVIC: if ((what = "format", lldpctl_atom_set_int(med_location, lldpctl_k_med_location_format, format)) == NULL || (what = "country", lldpctl_atom_set_str(med_location, lldpctl_k_med_location_country, cmdenv_get(env, "country"))) == NULL) { log_warnx("lldpctl", "unable to set LLDP MED location value for %s on %s. %s.", what, name, lldpctl_last_strerror(conn)); break; } ok = 1; for (lldpctl_map_t *addr_map = lldpctl_key_get_map(lldpctl_k_med_civicaddress_type); addr_map->string; addr_map++) { lldpctl_atom_t *cael, *caels; const char *value = cmdenv_get(env, addr_map->string); if (!value) continue; caels = lldpctl_atom_get(med_location, lldpctl_k_med_location_ca_elements); cael = lldpctl_atom_create(caels); if (lldpctl_atom_set_str(cael, lldpctl_k_med_civicaddress_type, addr_map->string) == NULL || lldpctl_atom_set_str(cael, lldpctl_k_med_civicaddress_value, value) == NULL || lldpctl_atom_set(med_location, lldpctl_k_med_location_ca_elements, cael) == NULL) { log_warnx("lldpctl", "unable to add a civic address element `%s`. %s", addr_map->string, lldpctl_last_strerror(conn)); ok = 0; } lldpctl_atom_dec_ref(cael); lldpctl_atom_dec_ref(caels); if (!ok) break; } break; case LLDP_MED_LOCFORMAT_ELIN: if (lldpctl_atom_set_int(med_location, lldpctl_k_med_location_format, format) == NULL || lldpctl_atom_set_str(med_location, lldpctl_k_med_location_elin, cmdenv_get(env, "elin")) == NULL) log_warnx("lldpctl", "unable to set LLDP MED location on %s. %s", name, lldpctl_last_strerror(conn)); else ok = 1; break; } if (ok) { if (lldpctl_atom_set(port, lldpctl_k_port_med_locations, med_location) == NULL) { log_warnx("lldpctl", "unable to set LLDP MED location on %s. %s.", name, lldpctl_last_strerror(conn)); } else log_info("lldpctl", "LLDP-MED location has been set for port %s", name); } end: lldpctl_atom_dec_ref(med_location); lldpctl_atom_dec_ref(med_locations); lldpctl_atom_dec_ref(port); } return 1; }
static int cmd_custom_tlv_set(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { lldpctl_atom_t *port; const char *s; const char *name; uint8_t oui[LLDP_TLV_ORG_OUI_LEN]; uint8_t oui_info[LLDP_TLV_ORG_OUI_INFO_MAXLEN]; int oui_info_len = 0; uint16_t subtype = 0; log_debug("lldpctl", "lldp custom-tlv(s) %s", arg?"set":"clear"); if (!arg) goto set; s = cmdenv_get(env, "oui"); if (!s || ( sscanf(s, "%02hhx,%02hhx,%02hhx", &oui[0], &oui[1], &oui[2]) != 3 && sscanf(s, "%02hhX,%02hhX,%02hhX", &oui[0], &oui[1], &oui[2]) != 3) ) { log_warnx("lldpctl", "invalid OUI value '%s'", s); return 0; } s = cmdenv_get(env, "subtype"); if (!s) { log_warnx("lldpctl", "no subtype specified"); return 0; } else { subtype = (uint16_t)atoi(s); if (subtype > 255) { log_warnx("lldpctl", "invalid subtype range value '%s'", s); return 0; } } s = cmdenv_get(env, "oui-info"); /* This info is optional */ if (s) { const char delim[] = ","; char *s_copy = strdup(s); char *token = strtok(s_copy, delim); while (token != NULL) { if (sscanf(token, "%02hhx", &oui_info[oui_info_len]) == 1 || sscanf(token, "%02hhX", &oui_info[oui_info_len]) == 1) oui_info_len++; if (oui_info_len >= sizeof(oui_info)) break; token = strtok(NULL, delim); } free(s_copy); } set: while ((port = cmd_iterate_on_ports(conn, env, &name))) { lldpctl_atom_t *custom_tlvs; if (!arg) { lldpctl_atom_set(port, lldpctl_k_custom_tlvs_clear, NULL); } else if (!(custom_tlvs = lldpctl_atom_get(port, lldpctl_k_custom_tlvs))) { log_warnx("lldpctl", "unable to get custom TLVs for port %s", name); } else { lldpctl_atom_t *tlv = lldpctl_atom_create(custom_tlvs); if (!tlv) { log_warnx("lldpctl", "unable to create new custom TLV for port %s", name); } else { /* Configure custom TLV */ lldpctl_atom_set_buffer(tlv, lldpctl_k_custom_tlv_oui, oui, sizeof(oui)); lldpctl_atom_set_int(tlv, lldpctl_k_custom_tlv_oui_subtype, subtype); lldpctl_atom_set_buffer(tlv, lldpctl_k_custom_tlv_oui_info_string, oui_info, oui_info_len); /* Assign it to port */ lldpctl_atom_set(port, lldpctl_k_custom_tlv, tlv); lldpctl_atom_dec_ref(tlv); } lldpctl_atom_dec_ref(custom_tlvs); } } return 1; }
static int cmd_dot3power(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_debug("lldpctl", "set dot3 power"); lldpctl_atom_t *iface; while ((iface = cmd_iterate_on_interfaces(conn, env))) { const char *name = lldpctl_atom_get_str(iface, lldpctl_k_interface_name); lldpctl_atom_t *port = lldpctl_get_port(iface); lldpctl_atom_t *dot3_power; const char *what = NULL; int ok = 1; dot3_power = lldpctl_atom_get(port, lldpctl_k_port_dot3_power); if (dot3_power == NULL) { log_warnx("lldpctl", "unable to set Dot3 power: support seems unavailable"); goto end; } if ((what = "device type", lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_devicetype, cmdenv_get(env, "device-type"))) == NULL || /* Flags */ (what = "supported flag", lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_supported, cmdenv_get(env, "supported")?1:0)) == NULL || (what = "enabled flag", lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_enabled, cmdenv_get(env, "enabled")?1:0)) == NULL || (what = "paircontrol flag", lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_paircontrol, cmdenv_get(env, "paircontrol")?1:0)) == NULL || /* Powerpairs */ (what = "power pairs", lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_pairs, cmdenv_get(env, "powerpairs"))) == NULL || /* Class */ (what = "power class", cmdenv_get(env, "class")? lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_class, cmdenv_get(env, "class")): lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_class, 0)) == NULL || (what = "802.3at type", lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_type, 0)) == NULL) { log_warnx("lldpctl", "unable to set LLDP Dot3 power value for %s on %s. %s.", what, name, lldpctl_last_strerror(conn)); ok = 0; } else if (cmdenv_get(env, "typeat")) { int typeat = cmdenv_get(env, "typeat")[0] - '0'; const char *source = cmdenv_get(env, "source"); if ((what = "802.3at type", lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_type, typeat)) == NULL || (what = "source", lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_source, (!strcmp(source, "primary"))?LLDP_DOT3_POWER_SOURCE_PRIMARY: (!strcmp(source, "backup"))? LLDP_DOT3_POWER_SOURCE_BACKUP: (!strcmp(source, "pse"))? LLDP_DOT3_POWER_SOURCE_PSE: (!strcmp(source, "local"))? LLDP_DOT3_POWER_SOURCE_LOCAL: (!strcmp(source, "both"))? LLDP_DOT3_POWER_SOURCE_BOTH: LLDP_DOT3_POWER_SOURCE_UNKNOWN)) == NULL || (what = "priority", lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_priority, cmdenv_get(env, "priority"))) == NULL || (what = "requested power", lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_requested, cmdenv_get(env, "requested"))) == NULL || (what = "allocated power", lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_allocated, cmdenv_get(env, "allocated"))) == NULL) { log_warnx("lldpctl", "unable to set LLDP Dot3 power value for %s on %s. %s.", what, name, lldpctl_last_strerror(conn)); ok = 0; } } if (ok) { if (lldpctl_atom_set(port, lldpctl_k_port_dot3_power, dot3_power) == NULL) { log_warnx("lldpctl", "unable to set LLDP Dot3 power on %s. %s.", name, lldpctl_last_strerror(conn)); } else log_info("lldpctl", "LLDP Dot3 power has been set for port %s", name); } end: lldpctl_atom_dec_ref(dot3_power); lldpctl_atom_dec_ref(port); } return 1; }
static void display_med(struct writer *w, lldpctl_atom_t *port) { lldpctl_atom_t *medpolicies, *medpolicy; lldpctl_atom_t *medlocations, *medlocation; lldpctl_atom_t *caelements, *caelement; long int cap = lldpctl_atom_get_int(port, lldpctl_k_chassis_med_cap); const char *type; if (lldpctl_atom_get_int(port, lldpctl_k_chassis_med_type) <= 0) return; tag_start(w, "lldp-med", "LLDP-MED"); tag_datatag(w, "device-type", "Device Type", lldpctl_atom_get_str(port, lldpctl_k_chassis_med_type)); display_med_capability(w, cap, LLDP_MED_CAP_CAP, "Capabilities"); display_med_capability(w, cap, LLDP_MED_CAP_POLICY, "Policy"); display_med_capability(w, cap, LLDP_MED_CAP_LOCATION, "Location"); display_med_capability(w, cap, LLDP_MED_CAP_MDI_PSE, "MDI/PSE"); display_med_capability(w, cap, LLDP_MED_CAP_MDI_PD, "MDI/PD"); display_med_capability(w, cap, LLDP_MED_CAP_IV, "Inventory"); /* LLDP MED policies */ medpolicies = lldpctl_atom_get(port, lldpctl_k_port_med_policies); lldpctl_atom_foreach(medpolicies, medpolicy) { if (lldpctl_atom_get_int(medpolicy, lldpctl_k_med_policy_type) <= 0) continue; tag_start(w, "policy", "LLDP-MED Network Policy for"); tag_attr(w, "apptype", "", lldpctl_atom_get_str(medpolicy, lldpctl_k_med_policy_type)); tag_attr(w, "defined", "Defined", (lldpctl_atom_get_int(medpolicy, lldpctl_k_med_policy_unknown) > 0)?"no":"yes"); if (lldpctl_atom_get_int(medpolicy, lldpctl_k_med_policy_tagged) > 0) { int vid = lldpctl_atom_get_int(medpolicy, lldpctl_k_med_policy_vid); tag_start(w, "vlan", "VLAN"); if (vid == 0) { tag_attr(w, "vid", "", "priority"); } else if (vid == 4095) { tag_attr(w, "vid", "", "reserved"); } else { tag_attr(w, "vid", "", lldpctl_atom_get_str(medpolicy, lldpctl_k_med_policy_vid)); } tag_end(w); } tag_datatag(w, "priority", "Priority", lldpctl_atom_get_str(medpolicy, lldpctl_k_med_policy_priority)); tag_datatag(w, "dscp", "DSCP Value", lldpctl_atom_get_str(medpolicy, lldpctl_k_med_policy_dscp)); tag_end(w); } lldpctl_atom_dec_ref(medpolicies); /* LLDP MED locations */ medlocations = lldpctl_atom_get(port, lldpctl_k_port_med_locations); lldpctl_atom_foreach(medlocations, medlocation) { int format = lldpctl_atom_get_int(medlocation, lldpctl_k_med_location_format); if (format <= 0) continue; tag_start(w, "location", "LLDP-MED Location Identification"); tag_attr(w, "type", "Type", lldpctl_atom_get_str(medlocation, lldpctl_k_med_location_format)); switch (format) { case LLDP_MED_LOCFORMAT_COORD: tag_attr(w, "geoid", "Geoid", lldpctl_atom_get_str(medlocation, lldpctl_k_med_location_geoid)); tag_datatag(w, "lat", "Latitude", lldpctl_atom_get_str(medlocation, lldpctl_k_med_location_latitude)); tag_datatag(w, "lon", "Longitude", lldpctl_atom_get_str(medlocation, lldpctl_k_med_location_longitude)); tag_start(w, "altitude", "Altitude"); tag_attr(w, "unit", "", lldpctl_atom_get_str(medlocation, lldpctl_k_med_location_altitude_unit)); tag_data(w, lldpctl_atom_get_str(medlocation, lldpctl_k_med_location_altitude)); tag_end(w); break; case LLDP_MED_LOCFORMAT_CIVIC: tag_datatag(w, "country", "Country", lldpctl_atom_get_str(medlocation, lldpctl_k_med_location_country)); caelements = lldpctl_atom_get(medlocation, lldpctl_k_med_location_ca_elements); lldpctl_atom_foreach(caelements, caelement) { type = lldpctl_atom_get_str(caelement, lldpctl_k_med_civicaddress_type); tag_datatag(w, totag(type), type, lldpctl_atom_get_str(caelement, lldpctl_k_med_civicaddress_value)); } lldpctl_atom_dec_ref(caelements); break; case LLDP_MED_LOCFORMAT_ELIN: tag_datatag(w, "ecs", "ECS ELIN", lldpctl_atom_get_str(medlocation, lldpctl_k_med_location_elin)); break; }