/** * Callback for the next function to display a new neighbor. */ static void watchcb(lldpctl_conn_t *conn, lldpctl_change_t type, lldpctl_atom_t *interface, lldpctl_atom_t *neighbor, void *data) { struct watcharg *wa = data; struct cmd_env *env = wa->env; struct writer *w = wa->w; const char *interfaces = cmdenv_get(env, "ports"); const char *proto_str; int protocol = LLDPD_MODE_MAX; if (interfaces && !contains(interfaces, lldpctl_atom_get_str(interface, lldpctl_k_interface_name))) return; /* user might have specified protocol to filter display results */ proto_str = cmdenv_get(env, "protocol"); if (proto_str) { log_debug("display", "filter protocol: %s ", proto_str); protocol = 0; /* unsupported */ for (lldpctl_map_t *protocol_map = lldpctl_key_get_map(lldpctl_k_port_protocol); protocol_map->string; protocol_map++) { if (!strcasecmp(proto_str, protocol_map->string)) { protocol = protocol_map->value; break; } } } switch (type) { case lldpctl_c_deleted: tag_start(w, "lldp-deleted", "LLDP neighbor deleted"); break; case lldpctl_c_updated: tag_start(w, "lldp-updated", "LLDP neighbor updated"); break; case lldpctl_c_added: tag_start(w, "lldp-added", "LLDP neighbor added"); break; default: return; } display_interface(conn, w, 1, interface, neighbor, cmdenv_get(env, "summary")?DISPLAY_BRIEF: cmdenv_get(env, "detailed")?DISPLAY_DETAILS: DISPLAY_NORMAL, protocol); tag_end(w); }
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 const char* _lldpctl_atom_get_str_port(lldpctl_atom_t *atom, lldpctl_key_t key) { struct _lldpctl_atom_port_t *p = (struct _lldpctl_atom_port_t *)atom; struct lldpd_port *port = p->port; struct lldpd_hardware *hardware = p->hardware; char *ipaddress = NULL; size_t len; /* Local port only */ switch (key) { case lldpctl_k_port_name: if (hardware != NULL) return hardware->h_ifname; break; case lldpctl_k_port_status: if (p->local) return map_lookup(port_status_map.map, LLDPD_RXTX_FROM_PORT(port)); break; default: break; } if (!port) return NULL; /* Local and remote port */ switch (key) { case lldpctl_k_port_protocol: return map_lookup(lldpd_protocol_map.map, port->p_protocol); case lldpctl_k_port_id_subtype: return map_lookup(port_id_subtype_map, port->p_id_subtype); case lldpctl_k_port_id: switch (port->p_id_subtype) { case LLDP_PORTID_SUBTYPE_IFNAME: case LLDP_PORTID_SUBTYPE_IFALIAS: case LLDP_PORTID_SUBTYPE_LOCAL: return port->p_id; case LLDP_PORTID_SUBTYPE_LLADDR: return _lldpctl_dump_in_atom(atom, (uint8_t*)port->p_id, port->p_id_len, ':', 0); case LLDP_PORTID_SUBTYPE_ADDR: switch (port->p_id[0]) { case LLDP_MGMT_ADDR_IP4: len = INET_ADDRSTRLEN + 1; break; case LLDP_MGMT_ADDR_IP6: len = INET6_ADDRSTRLEN + 1; break; default: len = 0; } if (len > 0) { ipaddress = _lldpctl_alloc_in_atom(atom, len); if (!ipaddress) return NULL; if (inet_ntop((port->p_id[0] == LLDP_MGMT_ADDR_IP4)? AF_INET:AF_INET6, &port->p_id[1], ipaddress, len) == NULL) break; return ipaddress; } break; } SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); return NULL; case lldpctl_k_port_descr: return port->p_descr; #ifdef ENABLE_DOT3 case lldpctl_k_port_dot3_mautype: return map_lookup(operational_mau_type_values, port->p_macphy.mau_type); #endif default: /* Compatibility: query the associated chassis too */ return lldpctl_atom_get_str(p->chassis, key); } }
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; }
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_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; }