xref: /netbsd/external/mpl/dhcp/dist/omapip/convert.c (revision 13df4856)
1 /*	$NetBSD: convert.c,v 1.3 2022/04/03 01:10:59 christos Exp $	*/
2 
3 /* convert.c
4 
5    Safe copying of option values into and out of the option buffer, which
6    can't be assumed to be aligned. */
7 
8 /*
9  * Copyright (C) 2004-2022 Internet Systems Consortium, Inc. ("ISC")
10  * Copyright (c) 1996-2003 by Internet Software Consortium
11  *
12  * This Source Code Form is subject to the terms of the Mozilla Public
13  * License, v. 2.0. If a copy of the MPL was not distributed with this
14  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
17  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
19  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
22  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  *
24  *   Internet Systems Consortium, Inc.
25  *   PO Box 360
26  *   Newmarket, NH 03857 USA
27  *   <info@isc.org>
28  *   https://www.isc.org/
29  *
30  */
31 
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: convert.c,v 1.3 2022/04/03 01:10:59 christos Exp $");
34 
35 #include "dhcpd.h"
36 
37 #include <omapip/omapip_p.h>
38 
getULong(buf)39 u_int32_t getULong (buf)
40 	const unsigned char *buf;
41 {
42 	u_int32_t ibuf;
43 
44 	memcpy (&ibuf, buf, sizeof (u_int32_t));
45 	return ntohl (ibuf);
46 }
47 
getLong(buf)48 int32_t getLong (buf)
49 	const unsigned char *buf;
50 {
51 	int32_t ibuf;
52 
53 	memcpy (&ibuf, buf, sizeof (int32_t));
54 	return ntohl (ibuf);
55 }
56 
getUShort(buf)57 u_int32_t getUShort (buf)
58 	const unsigned char *buf;
59 {
60 	unsigned short ibuf;
61 
62 	memcpy (&ibuf, buf, sizeof (u_int16_t));
63 	return ntohs (ibuf);
64 }
65 
getShort(buf)66 int32_t getShort (buf)
67 	const unsigned char *buf;
68 {
69 	short ibuf;
70 
71 	memcpy (&ibuf, buf, sizeof (int16_t));
72 	return ntohs (ibuf);
73 }
74 
putULong(obuf,val)75 void putULong (obuf, val)
76 	unsigned char *obuf;
77 	u_int32_t val;
78 {
79 	u_int32_t tmp = htonl (val);
80 	memcpy (obuf, &tmp, sizeof tmp);
81 }
82 
putLong(obuf,val)83 void putLong (obuf, val)
84 	unsigned char *obuf;
85 	int32_t val;
86 {
87 	int32_t tmp = htonl (val);
88 	memcpy (obuf, &tmp, sizeof tmp);
89 }
90 
putUShort(obuf,val)91 void putUShort (obuf, val)
92 	unsigned char *obuf;
93 	u_int32_t val;
94 {
95 	u_int16_t tmp = htons (val);
96 	memcpy (obuf, &tmp, sizeof tmp);
97 }
98 
putShort(obuf,val)99 void putShort (obuf, val)
100 	unsigned char *obuf;
101 	int32_t val;
102 {
103 	int16_t tmp = htons (val);
104 	memcpy (obuf, &tmp, sizeof tmp);
105 }
106 
putUChar(obuf,val)107 void putUChar (obuf, val)
108 	unsigned char *obuf;
109 	u_int32_t val;
110 {
111 	*obuf = val;
112 }
113 
getUChar(obuf)114 u_int32_t getUChar (obuf)
115 	const unsigned char *obuf;
116 {
117 	return obuf [0];
118 }
119 
converted_length(buf,base,width)120 int converted_length (buf, base, width)
121 	const unsigned char *buf;
122 	unsigned int base;
123 	unsigned int width;
124 {
125 	u_int32_t number;
126 	u_int32_t column;
127 	int power = 1;
128 	u_int32_t newcolumn = base;
129 
130 	if (base > 16)
131 		return 0;
132 
133 	if (width == 1)
134 		number = getUChar (buf);
135 	else if (width == 2)
136 		number = getUShort (buf);
137 	else if (width == 4)
138 		number = getULong (buf);
139 	else
140 		return 0;
141 
142 	do {
143 		column = newcolumn;
144 
145 		if (number < column)
146 			return power;
147 		power++;
148 		newcolumn = column * base;
149 		/* If we wrap around, it must be the next power of two up. */
150 	} while (newcolumn > column);
151 
152 	return power;
153 }
154 
binary_to_ascii(outbuf,inbuf,base,width)155 int binary_to_ascii (outbuf, inbuf, base, width)
156 	unsigned char *outbuf;
157 	const unsigned char *inbuf;
158 	unsigned int base;
159 	unsigned int width;
160 {
161 	u_int32_t number;
162 	static char h2a [] = "0123456789abcdef";
163 	int power = converted_length (inbuf, base, width);
164 	int i;
165 
166 	if (base > 16)
167 		return 0;
168 
169 	if (width == 1)
170 		number = getUChar (inbuf);
171 	else if (width == 2)
172 		number = getUShort (inbuf);
173 	else if (width == 4)
174 		number = getULong (inbuf);
175 	else
176 		return 0;
177 
178 	for (i = power - 1 ; i >= 0; i--) {
179 		outbuf [i] = h2a [number % base];
180 		number /= base;
181 	}
182 
183 	return power;
184 }
185