1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29#include <sys/types.h>
30#include <stddef.h>
31#include <stdlib.h>
32#include <strings.h>
33#include <netinet/in.h>
34#include <netinet/dhcp.h>
35#include "dhcp_impl.h"
36
37/*
38 * Fetch a copy of the DHCP-supplied value of the parameter requested
39 * by code in value, and the parameter value length in *vallenp.
40 *
41 * Return values:
42 *
43 *      B_FALSE         If invalid code, or no parameter value.
44 *
45 *      B_TRUE          Valid code which has a parameter value.
46 *                      *vallenp is set to the parameter value length.
47 *                      If the parameter value length is less than or
48 *                      equal to *vallenp, value is set to the parameter
49 *                      value.
50 */
51
52boolean_t
53dhcp_getinfo_pl(PKT_LIST *pl, uchar_t optcat, uint16_t code, uint16_t optsize,
54    void *value, size_t *vallenp)
55{
56
57	if (pl == NULL)
58		return (B_FALSE);
59
60	if (optcat == DSYM_STANDARD) {
61		if (code > DHCP_LAST_OPT)
62			return (B_FALSE);
63
64		if (pl->opts[code] == NULL)
65			return (B_FALSE);
66
67		if (*vallenp < pl->opts[code]->len) {
68			*vallenp = pl->opts[code]->len;
69			return (B_TRUE);
70		}
71
72		bcopy(pl->opts[code]->value, value, pl->opts[code]->len);
73		*vallenp = pl->opts[code]->len;
74
75	} else if (optcat == DSYM_VENDOR) {
76		if (code > VS_OPTION_END)
77			return (B_FALSE);
78
79		if (pl->vs[code] == NULL)
80			return (B_FALSE);
81
82		if (*vallenp < pl->vs[code]->len) {
83			*vallenp = pl->vs[code]->len;
84			return (B_TRUE);
85		}
86
87		bcopy(pl->vs[code]->value, value, pl->vs[code]->len);
88		*vallenp = pl->vs[code]->len;
89
90	} else if (optcat == DSYM_FIELD) {
91		if (code + optsize > sizeof (PKT))
92			return (B_FALSE);
93
94		if (*vallenp < optsize) {
95			*vallenp = optsize;
96			return (B_TRUE);
97		}
98
99		*vallenp = optsize;
100		bcopy((caddr_t)pl->pkt + code, value, optsize);
101
102	} else
103		return (B_FALSE);
104
105	return (B_TRUE);
106}
107