1 /* $NetBSD: util.h,v 1.9 2025/01/26 16:25:44 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 AND ISC 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /* 17 * Copyright (C) 2001 Nominum, Inc. 18 * 19 * Permission to use, copy, modify, and/or distribute this software for any 20 * purpose with or without fee is hereby granted, provided that the above 21 * copyright notice and this permission notice appear in all copies. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL 24 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY 26 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 27 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 28 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 29 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 30 */ 31 32 #pragma once 33 34 #include <inttypes.h> 35 36 #include <isc/util.h> 37 38 /*! \file isccc/util.h 39 * \brief 40 * Macros for dealing with unaligned numbers. 41 * 42 * \note no side effects are allowed when invoking these macros! 43 */ 44 45 #define GET8(v, w) \ 46 do { \ 47 v = *w; \ 48 w++; \ 49 } while (0) 50 51 #define GET16(v, w) \ 52 do { \ 53 v = (unsigned int)w[0] << 8; \ 54 v |= (unsigned int)w[1]; \ 55 w += 2; \ 56 } while (0) 57 58 #define GET24(v, w) \ 59 do { \ 60 v = (unsigned int)w[0] << 16; \ 61 v |= (unsigned int)w[1] << 8; \ 62 v |= (unsigned int)w[2]; \ 63 w += 3; \ 64 } while (0) 65 66 #define GET32(v, w) \ 67 do { \ 68 v = (unsigned int)w[0] << 24; \ 69 v |= (unsigned int)w[1] << 16; \ 70 v |= (unsigned int)w[2] << 8; \ 71 v |= (unsigned int)w[3]; \ 72 w += 4; \ 73 } while (0) 74 75 #define GET64(v, w) \ 76 do { \ 77 v = (uint64_t)w[0] << 56; \ 78 v |= (uint64_t)w[1] << 48; \ 79 v |= (uint64_t)w[2] << 40; \ 80 v |= (uint64_t)w[3] << 32; \ 81 v |= (uint64_t)w[4] << 24; \ 82 v |= (uint64_t)w[5] << 16; \ 83 v |= (uint64_t)w[6] << 8; \ 84 v |= (uint64_t)w[7]; \ 85 w += 8; \ 86 } while (0) 87 88 #define GETC16(v, w, d) \ 89 do { \ 90 GET8(v, w); \ 91 if (v == 0) { \ 92 d = ISCCC_TRUE; \ 93 } else { \ 94 d = ISCCC_FALSE; \ 95 if (v == 255) \ 96 GET16(v, w); \ 97 } \ 98 } while (0) 99 100 #define GETC32(v, w) \ 101 do { \ 102 GET24(v, w); \ 103 if (v == 0xffffffu) { \ 104 GET32(v, w); \ 105 } \ 106 } while (0) 107 108 #define GET_OFFSET(v, w) GET32(v, w) 109 110 #define GET_MEM(v, c, w) \ 111 do { \ 112 memmove(v, w, c); \ 113 w += c; \ 114 } while (0) 115 116 #define GET_TYPE(v, w) \ 117 do { \ 118 GET8(v, w); \ 119 if (v > 127) { \ 120 if (v < 255) { \ 121 v = ((v & 0x7f) << 16) | ISCCC_RDATATYPE_SIG; \ 122 } else { \ 123 GET32(v, w); \ 124 } \ 125 } \ 126 } while (0) 127 128 #define PUT8(v, w) \ 129 do { \ 130 *w = (v & 0x000000ffU); \ 131 w++; \ 132 } while (0) 133 134 #define PUT16(v, w) \ 135 do { \ 136 w[0] = (v & 0x0000ff00U) >> 8; \ 137 w[1] = (v & 0x000000ffU); \ 138 w += 2; \ 139 } while (0) 140 141 #define PUT24(v, w) \ 142 do { \ 143 w[0] = (v & 0x00ff0000U) >> 16; \ 144 w[1] = (v & 0x0000ff00U) >> 8; \ 145 w[2] = (v & 0x000000ffU); \ 146 w += 3; \ 147 } while (0) 148 149 #define PUT32(v, w) \ 150 do { \ 151 w[0] = (v & 0xff000000U) >> 24; \ 152 w[1] = (v & 0x00ff0000U) >> 16; \ 153 w[2] = (v & 0x0000ff00U) >> 8; \ 154 w[3] = (v & 0x000000ffU); \ 155 w += 4; \ 156 } while (0) 157 158 #define PUT64(v, w) \ 159 do { \ 160 w[0] = (v & 0xff00000000000000ULL) >> 56; \ 161 w[1] = (v & 0x00ff000000000000ULL) >> 48; \ 162 w[2] = (v & 0x0000ff0000000000ULL) >> 40; \ 163 w[3] = (v & 0x000000ff00000000ULL) >> 32; \ 164 w[4] = (v & 0x00000000ff000000ULL) >> 24; \ 165 w[5] = (v & 0x0000000000ff0000ULL) >> 16; \ 166 w[6] = (v & 0x000000000000ff00ULL) >> 8; \ 167 w[7] = (v & 0x00000000000000ffULL); \ 168 w += 8; \ 169 } while (0) 170 171 #define PUTC16(v, w) \ 172 do { \ 173 if (v > 0 && v < 255) { \ 174 PUT8(v, w); \ 175 } else { \ 176 PUT8(255, w); \ 177 PUT16(v, w); \ 178 } \ 179 } while (0) 180 181 #define PUTC32(v, w) \ 182 do { \ 183 if (v < 0xffffffU) { \ 184 PUT24(v, w); \ 185 } else { \ 186 PUT24(0xffffffU, w); \ 187 PUT32(v, w); \ 188 } \ 189 } while (0) 190 191 #define PUT_OFFSET(v, w) PUT32(v, w) 192 193 #include <string.h> 194 195 #define PUT_MEM(s, c, w) \ 196 do { \ 197 memmove(w, s, c); \ 198 w += c; \ 199 } while (0) 200 201 /* 202 * Regions. 203 */ 204 #define REGION_SIZE(r) ((unsigned int)((r).rend - (r).rstart)) 205 #define REGION_EMPTY(r) ((r).rstart == (r).rend) 206 #define REGION_FROMSTRING(r, s) \ 207 do { \ 208 (r).rstart = (unsigned char *)s; \ 209 (r).rend = (r).rstart + strlen(s); \ 210 } while (0) 211