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; }
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 struct json_object * respondd_provider_neighbours(void) { lldpctl_conn_t *conn; lldpctl_atom_t *ifaces, *iface, *port, *neighbors, *neighbor; const char *ctlname, *neighmac, *portmac; struct json_object *ret, *ret_lldp, *neighbors_obj; ret_lldp = json_object_new_object(); ctlname = lldpctl_get_default_transport(); conn = lldpctl_new_name(ctlname, NULL, NULL, NULL); ifaces = lldpctl_get_interfaces(conn); lldpctl_atom_foreach(ifaces, iface) { port = lldpctl_get_port(iface); // check if Port ID Subtype is MAC address if (lldpctl_atom_get_int(port, lldpctl_k_port_id_subtype) != LLDP_PORTID_SUBTYPE_LLADDR) continue; portmac = lldpctl_atom_get_str(port, lldpctl_k_port_id); if (!portmac) continue; neighbors_obj = json_object_new_object(); neighbors = lldpctl_atom_get(port, lldpctl_k_port_neighbors); lldpctl_atom_foreach(neighbors, neighbor) { // check if Chassis ID Subtype is MAC address if (lldpctl_atom_get_int(neighbor, lldpctl_k_chassis_id_subtype) != LLDP_CHASSISID_SUBTYPE_LLADDR) continue; neighmac = lldpctl_atom_get_str(neighbor, lldpctl_k_chassis_id); if (!neighmac) continue; json_object_object_add(neighbors_obj, neighmac, json_object_new_object()); } json_object_object_add(ret_lldp, portmac, neighbors_obj); }
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_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_custom_tlv_set(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { lldpctl_atom_t *iface; const char *s; 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 ((iface = cmd_iterate_on_interfaces(conn, env))) { lldpctl_atom_t *port = lldpctl_get_port(iface); 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"); } else { lldpctl_atom_t *tlv = lldpctl_atom_create(custom_tlvs); if (!tlv) { log_warnx("lldpctl", "unable to create new custom TLV for port"); } 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); } lldpctl_atom_dec_ref(port); } 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; }