Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}