Example #1
0
/*
 *	Allow single attribute values to be retrieved from the dhcp.
 */
static ssize_t dhcp_options_xlat(UNUSED void *instance, REQUEST *request,
				 char const *fmt, char **out, size_t freespace)
{
	vp_cursor_t	cursor, src_cursor;
	vp_tmpl_t	src;
	VALUE_PAIR	*vp, *head = NULL;
	int		decoded = 0;
	ssize_t		slen;

	while (isspace((int) *fmt)) fmt++;

	slen = tmpl_from_attr_str(&src, fmt, REQUEST_CURRENT, PAIR_LIST_REQUEST, false, false);
	if (slen <= 0) {
		REMARKER(fmt, slen, fr_strerror());
	error:
		return -1;
	}

	if (src.type != TMPL_TYPE_ATTR) {
		REDEBUG("dhcp_options cannot operate on a %s", fr_int2str(tmpl_names, src.type, "<INVALID>"));
		goto error;
	}

	if (src.tmpl_da->type != PW_TYPE_OCTETS) {
		REDEBUG("dhcp_options got a %s attribute needed octets",
			fr_int2str(dict_attr_types, src.tmpl_da->type, "<INVALID>"));
		goto error;
	}

	for (vp = tmpl_cursor_init(NULL, &src_cursor, request, &src);
	     vp;
	     vp = tmpl_cursor_next(&src_cursor, &src)) {
		/*
		 *	@fixme: we should pass in a cursor, then decoding multiple
		 *	source attributes can be made atomic.
		 */
		if ((fr_dhcp_decode_options(request->packet, &head, vp->vp_octets, vp->vp_length) < 0) || (!head)) {
			RWDEBUG("DHCP option decoding failed: %s", fr_strerror());
			goto error;
		}

		for (vp = fr_cursor_init(&cursor, &head);
		     vp;
		     vp = fr_cursor_next(&cursor)) {
			rdebug_pair(L_DBG_LVL_2, request, vp, "dhcp_options: ");
			decoded++;
		}

		fr_pair_list_move(request->packet, &(request->packet->vps), &head);

		/* Free any unmoved pairs */
		fr_pair_list_free(&head);
	}

	snprintf(*out, freespace, "%i", decoded);

	return strlen(*out);
}
Example #2
0
/*
 *	Allow single attribute values to be retrieved from the dhcp.
 */
static size_t dhcp_options_xlat(UNUSED void *instance, REQUEST *request,
                                char const *fmt, char *out, size_t freespace)
{
    vp_cursor_t cursor;
    VALUE_PAIR *vp, *head = NULL;
    int decoded = 0;

    while (isspace((int) *fmt)) fmt++;


    if ((radius_get_vp(request, fmt, &vp) < 0) || !vp) {
        *out = '\0';

        return 0;
    }

    if ((fr_dhcp_decode_options(request->packet,
                                vp->vp_octets, vp->length, &head) < 0) ||
            (!head)) {
        RWDEBUG("DHCP option decoding failed");
        goto fail;
    }


    for (vp = paircursor(&cursor, &head);
            vp;
            vp = pairnext(&cursor)) {
        decoded++;
    }

    pairmove(request->packet, &(request->packet->vps), &head);

    /* Free any unmoved pairs */
    pairfree(&head);

fail:

    snprintf(out, freespace, "%i", decoded);

    return strlen(out);
}
/*
 *	Allow single attribute values to be retrieved from the dhcp.
 */
static size_t dhcp_options_xlat(UNUSED void *instance, REQUEST *request,
			 	const char *fmt, char *out, size_t freespace)
{
	VALUE_PAIR *vp, *head = NULL, *next;
	int decoded = 0;
	
	while (isspace((int) *fmt)) fmt++;
	
	
	if ((radius_get_vp(request, fmt, &vp) < 0) || !vp) {
		 *out = '\0';
		 
		 return 0;
	}
	
	if ((fr_dhcp_decode_options(vp->vp_octets, vp->length, &head) < 0) ||
	    (head == NULL)) {
		RDEBUG("WARNING: DHCP option decoding failed");
		goto fail;
	}
	
	next = head;
	
	do {
		 next = next->next;
		 decoded++;
	} while (next);
	
	pairmove(&(request->packet->vps), &head);
	
	/* Free any unmoved pairs */
	pairfree(&head);
	
	fail:
	
	snprintf(out, freespace, "%i", decoded);
			 
	return strlen(out);
}