Esempio n. 1
0
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;
		}
Esempio n. 2
0
static void
display_med(struct writer *w, struct lldpd_chassis *chassis, struct lldpd_port *port)
{
	int i;
	char *value;

	tag_start(w, "lldp-med", "LLDP-MED");

	tag_datatag(w, "device-type", "Device Type",
		map_lookup(chassis_med_type_map, chassis->c_med_type));

	display_med_capability(w, chassis, LLDPMED_CAP_CAP);
	display_med_capability(w, chassis, LLDPMED_CAP_POLICY);
	display_med_capability(w, chassis, LLDPMED_CAP_LOCATION);
	display_med_capability(w, chassis, LLDPMED_CAP_MDI_PSE);
	display_med_capability(w, chassis, LLDPMED_CAP_MDI_PD);
	display_med_capability(w, chassis, LLDPMED_CAP_IV);

	for (i = 0; i < LLDPMED_APPTYPE_LAST; i++) {
		if (i+1 == port->p_med_policy[i].type) {
			tag_start(w, "policy", "LLDP-MED Network Policy for");
			tag_attr(w, "apptype", "AppType",
				 u2str(port->p_med_policy[i].type));
			tag_attr(w, "defined", "Defined",
			         (port->p_med_policy[i].unknown)?"no":"yes");

			tag_datatag(w, "descr", "",
			    map_lookup(port_med_policy_map, port->p_med_policy[i].type));

			if (port->p_med_policy[i].tagged) {
				tag_start(w, "vlan", "VLAN");
				if (port->p_med_policy[i].vid == 0) {
					tag_attr(w, "vid", "", "priority");
				} else if (port->p_med_policy[i].vid == 4095) {
					tag_attr(w, "vid", "", "reserved");
				} else {
					tag_attr(w, "vid", "",
						 u2str(port->p_med_policy[i].vid));
				}
				tag_end(w);
			}

			tag_datatag(w, "priority", "Layer 2 Priority",
				    u2str(port->p_med_policy[i].priority));

			tag_datatag(w, "dscp", "DSCP Value",
				    u2str(port->p_med_policy[i].dscp));

			tag_end(w);
		}
	}
	for (i = 0; i < LLDPMED_LOCFORMAT_LAST; i++) {
		if (i+1 == port->p_med_location[i].format) {
			tag_start(w, "location", "LLDP-MED Location Identification");

			switch(port->p_med_location[i].format) {
			case LLDPMED_LOCFORMAT_COORD:
				tag_attr(w, "type", "Type", "coordinates");

				if (port->p_med_location[i].data_len != 16) {
					tag_datatag(w, "error", "Error", "bad data length");
				} else {
					u_int64_t l;
					u_int8_t  v;
					char *    s;

					v = *(u_int8_t*)(port->p_med_location[i].data + 15);
					tag_attr(w, "geoid", "Geoid",
						 map_lookup(port_med_geoid_map,v));

					/* Latitude and longitude */
					memcpy(&l, port->p_med_location[i].data,
					    sizeof(u_int64_t));
					l = (ntohll(l) &
					    0x03FFFFFFFF000000ULL) >> 24;
					display_latitude_or_longitude(w,0, l);
					memcpy(&l, port->p_med_location[i].data + 5,
					    sizeof(u_int64_t));
					l = (ntohll(l) &
					    0x03FFFFFFFF000000ULL) >> 24;
					display_latitude_or_longitude(w,1, l);

					/* Altitude */
					memcpy(&l, port->p_med_location[i].data + 10,
					    sizeof(u_int64_t));
					l = (ntohll(l) &
					    0x3FFFFFFF000000ULL) >> 24;
					display_fixed_precision(l, 22, 8, 1, &s);

					tag_start(w, "altitude", "Altitude");
					switch ((*(u_int8_t*)(port->p_med_location[i].data +
						    10)) & 0xf0) {
					case (1 << 4):
						tag_attr(w, "unit", "", "m");
						break;
					case (2 << 4):
						tag_attr(w, "unit", "", "floor");
						break;
					default:
						tag_attr(w, "unit", "", "unknown");
					}
					tag_data(w,s);
					tag_end(w);

				}
				break;
			case LLDPMED_LOCFORMAT_CIVIC:
				tag_attr(w, "type", "Type", "address");

				if ((port->p_med_location[i].data_len < 3) ||
				    (port->p_med_location[i].data_len - 1 !=
					*(u_int8_t*)port->p_med_location[i].data)) {
					tag_datatag(w, "error", "Error", "bad data length");
				} else {
					int l = 4, n, catype, calength; 
					char country[3];
					country[0] = ((char *)port->p_med_location[i].data)[2];
					country[1] = ((char *)port->p_med_location[i].data)[3];
					country[2] = 0;

					tag_datatag(w, "country", "Country", country);

					while ((n = (port->
						    p_med_location[i].data_len - l)) >= 2) {
						catype = *(u_int8_t*)(port->
						    p_med_location[i].data + l);
						calength = *(u_int8_t*)(port->
						    p_med_location[i].data + l + 1);
						if (n < 2 + calength) {
							tag_datatag(w, "error", "Error", "bad data length");
							break;
						}

						if ((value = strndup((char *)(port->
							p_med_location[i].data + l + 2),
							    calength)) == NULL) {
							fatalx("not enough memory");
							break;
						}
						tag_datatag(w,
							map_lookup(civic_address_type_tags,catype),
							map_lookup(civic_address_type_values,catype),
							value);
						free(value);
						l += 2 + calength;
					}
				}
				break;
			case LLDPMED_LOCFORMAT_ELIN:
				if ((value = strndup((char *)(port->
						p_med_location[i].data),
					    port->p_med_location[i].data_len)) == NULL) {
					fatalx( "not enough memory");
					break;
				}
				tag_attr(w, "type", "Type", "elin");
				tag_datatag(w, "ecs", "ECS ELIN", value);
				free(value);
				break;
			default:
				tag_attr(w, "type", "", "unknown");
				tag_datatag(w, "unknown", "Data",
					dump(port->p_med_location[i].data,
				             port->p_med_location[i].data_len, 20, ' '));
			}
			tag_end(w);
		}
	}