예제 #1
0
char const *fr_app_io_socket_name(TALLOC_CTX *ctx, fr_app_io_t const *app_io,
				  fr_ipaddr_t const *src_ipaddr, int src_port,
				  fr_ipaddr_t const *dst_ipaddr, int dst_port)
{
	char		    dst_buf[128], src_buf[128];

	/*
	 *	Get our name.
	 */
	if (fr_ipaddr_is_inaddr_any(dst_ipaddr)) {
		if (dst_ipaddr->af == AF_INET) {
			strlcpy(dst_buf, "*", sizeof(dst_buf));
		} else {
			rad_assert(dst_ipaddr->af == AF_INET6);
			strlcpy(dst_buf, "::", sizeof(dst_buf));
		}
	} else {
		fr_value_box_snprint(dst_buf, sizeof(dst_buf), fr_box_ipaddr(*dst_ipaddr), 0);
	}

	if (!src_ipaddr) {
		return talloc_typed_asprintf(ctx, "proto_%s server %s port %u",
					     app_io->name, dst_buf, dst_port);
	}


	fr_value_box_snprint(src_buf, sizeof(src_buf), fr_box_ipaddr(*src_ipaddr), 0);

	return talloc_typed_asprintf(ctx, "proto_%s from client %s port %u to server %s port %u",
				     app_io->name, src_buf, src_port, dst_buf, dst_port);
}
예제 #2
0
/** Write the result of a get or getnext operation back to net-snmp
 *
 * Returns three lines of output per attribute:
 * - OID string
 * - type
 * - value
 *
 * Index attributes (num 0) must be in order of depth (shallowest first).
 *
 * If no attributes were written, will write "NONE\n" to inform net-snmp
 * that no value was available at the specified OID.
 *
 * @param fd to write to.
 * @param root of the SNMP portion of the main dictionary.
 * @param type attribute.
 * @param head of list of attributes to convert and write.
 * @return
 *	- >=0 on success (the number of varbind responses written).
 *	- -1 on failure.
 */
static int radsnmp_get_response(int fd,
				fr_dict_attr_t const *root, fr_dict_attr_t const *type,
				VALUE_PAIR *head)
{
	fr_cursor_t		cursor;
	VALUE_PAIR		*vp, *type_vp;
	fr_dict_attr_t const	*parent = root;
	unsigned int		written = 0;

	ssize_t			slen;
	size_t			len;

	char			type_buff[32];	/* type */
	size_t			type_len = 0;
	char			oid_buff[256];
	char			value_buff[128];
	char			*p = oid_buff, *end = p + sizeof(oid_buff);

	struct iovec		io_vector[6];

	char			newline[] = "\n";

	type_buff[0] = '\0';

	/*
	 *	Print first part of OID string.
	 */
	slen = snprintf(oid_buff, sizeof(oid_buff), "%u.", parent->attr);
	if (is_truncated((size_t)slen, sizeof(oid_buff))) {
	oob:
		fr_strerror_printf("OID Buffer too small");
		return -1;
	}
	p += slen;

	/*
	 *	@fixme, this is very dependent on ordering
	 *
	 *	This code should be reworked when we have proper
	 *	attribute grouping to coalesce all related index
	 *	attributes under a single request OID.
	 */
	 for (vp = fr_cursor_init(&cursor, &head);
	      vp;
	      vp = fr_cursor_next(&cursor)) {
	      	fr_dict_attr_t const *common;
	      	/*
	      	 *	We only care about TLV attributes beneath our root
	      	 */
		if (!fr_dict_parent_common(root, vp->da, true)) continue;

		/*
		 *	Sanity checks to ensure we're processing attributes
		 *	in the right order.
		 */
		common = fr_dict_parent_common(parent, vp->da, true);
		if (!common) {
			fr_strerror_printf("Out of order index attributes.  \"%s\" is not a child of \"%s\"",
					   vp->da->name, parent->name);
			return -1;
		}

		/*
		 *	Index attribute
		 */
		if (vp->da->attr == 0) {
			/*
			 *	Print OID from last index/root up to the parent of
			 *	the index attribute.
			 */
			slen = fr_dict_print_attr_oid(p, end - p, parent, vp->da->parent);
			if (slen < 0) return -1;

			if (vp->vp_type != FR_TYPE_UINT32) {
				fr_strerror_printf("Index attribute \"%s\" is not of type \"integer\"", vp->da->name);
				return -1;
			}

			if (slen >= (end - p)) goto oob;
			p += slen;

			/*
			 *	Add the value of the index attribute as the next
			 *	OID component.
			 */
			len = snprintf(p, end - p, ".%i.", vp->vp_uint32);
			if (is_truncated(len, end - p)) goto oob;

			p += len;

			/*
			 *	Set the parent to be the attribute representing
			 *	the entry.
			 */
			parent = fr_dict_attr_child_by_num(vp->da->parent, 1);
			continue;
		}

		/*
		 *	Actual TLV attribute
		 */
		slen = fr_dict_print_attr_oid(p, end - p, parent, vp->da);
		if (slen < 0) return -1;

		/*
		 *	Next attribute should be the type
		 */
		type_vp = fr_cursor_next(&cursor);
		if (!type_vp || (type_vp->da != type)) {
			fr_strerror_printf("No %s found in response, or occurred out of order", type->name);
			return -1;
		}
		type_len = fr_pair_value_snprint(type_buff, sizeof(type_buff), type_vp, '\0');

		/*
		 *	Build up the vector
		 *
		 *	This represents output for a single varbind attribute
		 */
		io_vector[0].iov_base = oid_buff;
		io_vector[0].iov_len = strlen(oid_buff);
		io_vector[1].iov_base = newline;
		io_vector[1].iov_len = 1;
		io_vector[2].iov_base = type_buff;
		io_vector[2].iov_len = type_len;
		io_vector[3].iov_base = newline;
		io_vector[3].iov_len = 1;

		switch (vp->vp_type) {
		case FR_TYPE_OCTETS:
			memcpy(&io_vector[4].iov_base, &vp->vp_strvalue, sizeof(io_vector[4].iov_base));
			io_vector[4].iov_len = vp->vp_length;
			break;

		case FR_TYPE_STRING:
			memcpy(&io_vector[4].iov_base, &vp->vp_strvalue, sizeof(io_vector[4].iov_base));
			io_vector[4].iov_len = vp->vp_length;
			break;

		default:
			/*
			 *	We call fr_value_box_snprint with a NULL da pointer
			 *	because we always need return integer values not
			 *	value aliases.
			 */
			len = fr_value_box_snprint(value_buff, sizeof(value_buff), &vp->data, '\0');
			if (is_truncated(len, sizeof(value_buff))) {
				fr_strerror_printf("Insufficient fixed value buffer");
				return -1;
			}
			io_vector[4].iov_base = value_buff;
			io_vector[4].iov_len = len;
			break;
		}
		io_vector[5].iov_base = newline;
		io_vector[5].iov_len = 1;

		DEBUG2("said: %s", (char *)io_vector[0].iov_base);
		DEBUG2("said: %s", (char *)io_vector[2].iov_base);
		DEBUG2("said: %s", (char *)io_vector[4].iov_base);

		if (writev(fd, io_vector, sizeof(io_vector) / sizeof(*io_vector)) < 0) {
			fr_strerror_printf("Failed writing varbind result: %s", fr_syserror(errno));
			return -1;
		}

		/*
		 *	Reset in case we're encoding multiple values
		 */
		parent = root;
		p = oid_buff;
		type_buff[0] = '\0';
		written++;
	}

	if (!written && (write(fd, "NONE\n", 5)) < 0) {
		fr_strerror_printf("Failed writing get response: %s", fr_syserror(errno));
		return -1;
	}

	return written;
}