Пример #1
0
/**
 * Allocate a buffer inside an atom and dump another buffer in it.
 *
 * The dump is done in hexadecimal with the provided separator.
 *
 * @param atom   Atom which will be used as a container.
 * @param input  Buffer we want to dump.
 * @param size   Size of the buffer
 * @param sep    Separator to use.
 * @param max    Maximum number of bytes to dump. Can be 0 if no maximum.
 * @return A string representing the dump of the buffer or @c NULL if error.
 */
const char*
_lldpctl_dump_in_atom(lldpctl_atom_t *atom,
    const uint8_t *input, size_t size,
    char sep, size_t max)
{
	static const char truncation[] = "[...]";
	size_t i, len;
	char *buffer = NULL;

	if (max > 0 && size > max)
		len = max * 3 + sizeof(truncation) + 1;
	else
		len = size * 3 + 1;

	if ((buffer = _lldpctl_alloc_in_atom(atom, len)) == NULL)
		return NULL;

	for (i = 0; (i < size) && (max == 0 || i < max); i++)
		snprintf(buffer + i * 3, 4, "%02x%c", *(u_int8_t*)(input + i), sep);
	if (max > 0 && size > max)
		snprintf(buffer + i * 3, sizeof(truncation) + 1, "%s", truncation);
	else
		*(buffer + i*3 - 1) = 0;
	return buffer;
}
Пример #2
0
static lldpctl_atom_t*
_lldpctl_atom_set_buffer_custom(lldpctl_atom_t *atom, lldpctl_key_t key,
    const u_int8_t *buf, size_t n)
{
	struct _lldpctl_atom_custom_t *custom =
	    (struct _lldpctl_atom_custom_t *)atom;

	/* Only local port can be modified */
	if (!custom->parent->local) {
		SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
		return NULL;
	}

	switch (key) {
	case lldpctl_k_custom_tlv_oui:
		memcpy(&custom->tlv->oui, buf, min(n, sizeof(custom->tlv->oui)));
		return atom;
	case lldpctl_k_custom_tlv_oui_info_string:
		if (n == 0 || n > LLDP_TLV_ORG_OUI_INFO_MAXLEN) {
			SET_ERROR(atom->conn, LLDPCTL_ERR_BAD_VALUE);
			return NULL;
		}
		custom->tlv->oui_info_len = n;
		if (!(custom->tlv->oui_info = _lldpctl_alloc_in_atom(atom, n))) {
			custom->tlv->oui_info_len = 0;
			SET_ERROR(atom->conn, LLDPCTL_ERR_NOMEM);
			return NULL;
		}
		memcpy(custom->tlv->oui_info, buf, n);
		return atom;
	default:
		SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
		return NULL;
	}
}
Пример #3
0
static lldpctl_atom_t*
_lldpctl_atom_create_custom_list(lldpctl_atom_t *atom)
{
	struct _lldpctl_atom_custom_list_t *custom =
	    (struct _lldpctl_atom_custom_list_t *)atom;
	struct lldpd_custom *tlv;

	tlv = _lldpctl_alloc_in_atom(atom, sizeof(struct lldpd_custom));
	if (!tlv)
		return NULL;
	return _lldpctl_new_atom(atom->conn, atom_custom, custom->parent, tlv);
}
Пример #4
0
const char*
lldpctl_atom_get_str(lldpctl_atom_t *atom, lldpctl_key_t key)
{
    char *strresult = NULL;
    const uint8_t *bufresult = NULL;
    long int intresult = -1;
    int n1;
    size_t n2;

    if (atom == NULL) return NULL;
    RESET_ERROR(atom->conn);

    if (atom->get_str != NULL) {
        strresult = (char *)atom->get_str(atom, key);
        if (strresult) return strresult;
        if (lldpctl_last_error(atom->conn) != LLDPCTL_ERR_NOT_EXIST)
            return NULL;
    }

    RESET_ERROR(atom->conn);
    if (atom->get_int != NULL) {
        intresult = atom->get_int(atom, key);
        if (lldpctl_last_error(atom->conn) != LLDPCTL_ERR_NOT_EXIST) {
            strresult = _lldpctl_alloc_in_atom(atom, 21);
            if (!strresult) return NULL;
            n1 = snprintf(strresult, 21, "%ld", intresult);
            if (n1 > -1 && n1 < 21)
                return strresult;
            SET_ERROR(atom->conn, LLDPCTL_ERR_NOMEM); /* Not really true... */
            return NULL;
        }
    }

    RESET_ERROR(atom->conn);
    if (atom->get_buffer != NULL) {
        bufresult = atom->get_buffer(atom, key, &n2);
        if (bufresult)
            return _lldpctl_dump_in_atom(atom, bufresult, n2, ' ', 0);
        if (lldpctl_last_error(atom->conn) != LLDPCTL_ERR_NOT_EXIST)
            return NULL;
    }

    SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
    return NULL;
}
Пример #5
0
static struct _lldpctl_atom_config_t*
__lldpctl_atom_set_str_config(struct _lldpctl_atom_config_t *c,
    char **local, char **global,
    const char *value) {
	if (value) {
		char *aval = NULL;
		size_t len = strlen(value) + 1;
		aval = _lldpctl_alloc_in_atom((lldpctl_atom_t *)c, len);
		if (!aval) return NULL;
		memcpy(aval, value, len);
		*local = aval;
		free(*global); *global = strdup(aval);
	} else {
		free(*global);
		*local = *global = NULL;
	}
	return c;
}
Пример #6
0
static const char*
_lldpctl_atom_get_str_mgmt(lldpctl_atom_t *atom, lldpctl_key_t key)
{
	char *ipaddress = NULL;
	size_t len; int af;
	struct _lldpctl_atom_mgmt_t *m =
	    (struct _lldpctl_atom_mgmt_t *)atom;

	/* Local and remote port */
	switch (key) {
	case lldpctl_k_mgmt_ip:
		switch (m->mgmt->m_family) {
		case LLDPD_AF_IPV4:
			len = INET_ADDRSTRLEN + 1;
			af  = AF_INET;
			break;
		case LLDPD_AF_IPV6:
			len = INET6_ADDRSTRLEN + 1;
			af = AF_INET6;
			break;
		default:
			len = 0;
		}
		if (len == 0) break;
		ipaddress = _lldpctl_alloc_in_atom(atom, len);
		if (!ipaddress) return NULL;
		if (inet_ntop(af, &m->mgmt->m_addr, ipaddress, len) == NULL)
			break;
		return ipaddress;
	default:
		SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
		return NULL;
	}
	SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
	return NULL;
}
Пример #7
0
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);
	}
}