xref: /titanic_41/usr/src/common/net/dhcp/dhcpinfo.c (revision 40db2e2b777b79f3dd0d6d9629593a07f86b9c0a)
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 
52 boolean_t
53 dhcp_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