xref: /illumos-gate/usr/src/common/net/dhcp/dhcpinfo.c (revision dd72704bd9e794056c558153663c739e2012d721)
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 #include <sys/types.h>
28 #include <stddef.h>
29 #include <stdlib.h>
30 #include <strings.h>
31 #include <netinet/in.h>
32 #include <netinet/dhcp.h>
33 #include "dhcp_impl.h"
34 
35 /*
36  * Fetch a copy of the DHCP-supplied value of the parameter requested
37  * by code in value, and the parameter value length in *vallenp.
38  *
39  * Return values:
40  *
41  *      B_FALSE         If invalid code, or no parameter value.
42  *
43  *      B_TRUE          Valid code which has a parameter value.
44  *                      *vallenp is set to the parameter value length.
45  *                      If the parameter value length is less than or
46  *                      equal to *vallenp, value is set to the parameter
47  *                      value.
48  */
49 
50 boolean_t
51 dhcp_getinfo_pl(PKT_LIST *pl, uchar_t optcat, uint16_t code, uint16_t optsize,
52     void *value, size_t *vallenp)
53 {
54 
55 	if (pl == NULL)
56 		return (B_FALSE);
57 
58 	if (optcat == DSYM_STANDARD) {
59 		if (code > DHCP_LAST_OPT)
60 			return (B_FALSE);
61 
62 		if (pl->opts[code] == NULL)
63 			return (B_FALSE);
64 
65 		if (*vallenp < pl->opts[code]->len) {
66 			*vallenp = pl->opts[code]->len;
67 			return (B_TRUE);
68 		}
69 
70 		bcopy(pl->opts[code]->value, value, pl->opts[code]->len);
71 		*vallenp = pl->opts[code]->len;
72 
73 	} else if (optcat == DSYM_VENDOR) {
74 		if (code > VS_OPTION_END)
75 			return (B_FALSE);
76 
77 		if (pl->vs[code] == NULL)
78 			return (B_FALSE);
79 
80 		if (*vallenp < pl->vs[code]->len) {
81 			*vallenp = pl->vs[code]->len;
82 			return (B_TRUE);
83 		}
84 
85 		bcopy(pl->vs[code]->value, value, pl->vs[code]->len);
86 		*vallenp = pl->vs[code]->len;
87 
88 	} else if (optcat == DSYM_FIELD) {
89 		if (code + optsize > sizeof (PKT))
90 			return (B_FALSE);
91 
92 		if (*vallenp < optsize) {
93 			*vallenp = optsize;
94 			return (B_TRUE);
95 		}
96 
97 		*vallenp = optsize;
98 		bcopy((caddr_t)pl->pkt + code, value, optsize);
99 
100 	} else
101 		return (B_FALSE);
102 
103 	return (B_TRUE);
104 }
105