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