1 /* srp.h 2 * 3 * Copyright (c) 2018 Apple Computer, Inc. All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 * Service Registration Protocol common definitions 18 */ 19 20 #ifndef __SRP_H 21 #define __SRP_H 22 23 #include <stdint.h> 24 #include <stdbool.h> 25 26 #ifdef __clang__ 27 #define NULLABLE _Nullable 28 #define NONNULL _Nonnull 29 #else 30 #define NULLABLE 31 #define NONNULL 32 #endif 33 34 #ifdef DEBUG 35 #undef DEBUG 36 // #define DEBUG_VERBOSE 37 #endif 38 39 // We always want this until we start shipping 40 #define DEBUG_VERBOSE 41 42 #pragma clang diagnostic push 43 #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" 44 #ifdef THREAD_DEVKIT_ADK 45 46 #include "nrf_delay.h" 47 48 #define NULLABLE 49 #define NONNULL 50 51 #if !(DARWIN) 52 struct in_addr { 53 uint8_t s_addr; 54 }; 55 typedef struct in6_addr { 56 union { 57 __uint8_t __u6_addr8[16]; 58 __uint16_t __u6_addr16[8]; 59 __uint32_t __u6_addr32[4]; 60 } __u6_addr; /* 128-bit IP6 address */ 61 } in6_addr_t; 62 63 #define s6_addr __u6_addr.__u6_addr8 64 65 #define ntohs(x) ((((uint16_t)(x) & 0xff00) >> 8) | (((uint16_t)(x) & 0xff) << 8)) 66 #define htons(x) ntohs(x) 67 68 struct iovec { 69 void *base; 70 size_t len; 71 }; 72 #endif // !(DARWIN) 73 74 #define OPENLOG(consolep) 75 #define DELAY 250 76 #define ERROR(fmt, ...) do { \ 77 nrf_delay_ms(DELAY); \ 78 HAPLogError(&kHAPLog_Default, fmt, ##__VA_ARGS__); \ 79 nrf_delay_ms(DELAY); \ 80 } while (0) 81 #define INFO(fmt, ...) do { \ 82 nrf_delay_ms(DELAY); \ 83 HAPLogInfo(&kHAPLog_Default, fmt, ##__VA_ARGS__); \ 84 nrf_delay_ms(DELAY); \ 85 } while (0) 86 87 #ifdef DEBUG_VERBOSE 88 #define DEBUG(fmt, ...) do { \ 89 nrf_delay_ms(DELAY); \ 90 HAPLogDebug(&kHAPLog_Default, fmt, ##__VA_ARGS__); \ 91 nrf_delay_ms(DELAY); \ 92 } while (0) 93 #else // ifdef DEBUG_VERBOSE 94 #define DEBUG(fmt, ...) 95 #endif // ifdef DEBUG_VERBOSE 96 97 #define NO_CLOCK 98 #else // ifdef THREAD_DEVKIT_ADK 99 100 #ifdef LOG_FPRINTF_STDERR 101 #define OPENLOG(consolep) 102 #define ERROR(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__) 103 #define INFO(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__) 104 #ifdef DEBUG_VERBOSE 105 #ifdef IOLOOP_MACOS 106 int get_num_fds(void); 107 #endif // ifdef IOLOOP_MACOS 108 #define DEBUG(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__) 109 #else // ifdef DEBUG_VERBOSE 110 #define DEBUG(fmt, ...) 111 #endif 112 #else // ifdef LOG_FPRINTF_STDERR 113 #include <syslog.h> 114 115 // Apple device always has OS_LOG support. 116 #ifdef __APPLE__ 117 #define OS_LOG_ENABLED 1 118 #include <os/log.h> 119 120 // Define log level 121 #define LOG_TYPE_FAULT OS_LOG_TYPE_FAULT 122 #define LOG_TYPE_ERROR OS_LOG_TYPE_ERROR 123 #define LOG_TYPE_DEFAULT OS_LOG_TYPE_DEFAULT 124 #define LOG_TYPE_DEBUG OS_LOG_TYPE_DEBUG 125 // Define log macro 126 #define log_with_component_and_type(CATEGORY, LEVEL, FORMAT, ...) os_log_with_type((CATEGORY), (LEVEL), \ 127 (FORMAT), ##__VA_ARGS__) 128 129 #define OPENLOG(consolep) do {} while(0) 130 #define FAULT(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_FAULT, FORMAT, \ 131 ##__VA_ARGS__) 132 #define ERROR(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_ERROR, FORMAT, \ 133 ##__VA_ARGS__) 134 135 #ifdef DEBUG_VERBOSE 136 #ifdef DEBUG_FD_LEAKS 137 int get_num_fds(void); 138 #define INFO(FORMAT, ...) \ 139 do { \ 140 int foo = get_num_fds(); \ 141 log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_DEFAULT, "%d " FORMAT, foo, \ 142 ##__VA_ARGS__); \ 143 } while(0) 144 #else // ifdef IOLOOP_MACOS 145 #define INFO(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_DEFAULT, FORMAT, \ 146 ##__VA_ARGS__) 147 #endif // ifdef IOLOOP_MACOS 148 149 #define DEBUG(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_DEBUG, FORMAT, \ 150 ##__VA_ARGS__) 151 #else // ifdef DEBUG_VERBOSE 152 #define INFO(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_DEFAULT, FORMAT, \ 153 ##__VA_ARGS__) 154 #define DEBUG(FORMAT, ...) do {} while(0) 155 #endif // ifdef DEBUG_VERBOSE 156 #else // ifdef __APPLE__ 157 #define OS_LOG_ENABLED 0 158 159 #define OPENLOG(consolep) openlog("srp-mdns-proxy", (consolep ? LOG_PERROR : 0) | LOG_PID, LOG_DAEMON) 160 #define FAULT(fmt, ...) syslog(LOG_CRIT, fmt, ##__VA_ARGS__) 161 #define ERROR(fmt, ...) syslog(LOG_ERR, fmt, ##__VA_ARGS__) 162 163 #ifdef DEBUG_VERBOSE 164 #ifdef DEBUG_FD_LEAKS 165 int get_num_fds(void); 166 #define INFO(fmt, ...) \ 167 do { \ 168 int foo = get_num_fds(); \ 169 syslog(LOG_INFO, "%d " fmt, foo, ##__VA_ARGS__); \ 170 } while (0) 171 #else // ifdef IOLOOP_MACOS 172 #define INFO(fmt, ...) syslog(LOG_INFO, fmt, ##__VA_ARGS__) 173 #endif // ifdef IOLOOP_MACOS 174 #define DEBUG(fmt, ...) syslog(LOG_DEBUG, fmt, ##__VA_ARGS__) 175 #else // ifdef DEBUG_VERBOSE 176 #define INFO(fmt, ...) syslog(LOG_INFO, fmt, ##__VA_ARGS__) 177 #define DEBUG(fmt, ...) do {} while(0) 178 #endif // ifdef DEBUG_VERBOSE 179 #endif // ifdef __APPLE__ 180 #endif // ifdef LOG_FPRINTF_STDERR 181 #endif // ifdef THREAD_DEVKIT_ADK 182 183 //====================================================================================================================== 184 // MARK: - Logging Macros 185 /** 186 * With the logging routines defined above, the logging macros are defined to facilitate the log redaction enforced by 187 * os_log on Apple platforms. By using the specifier "%{mask.hash}", the "<private>" text in the logs of customer device 188 * would be shown as a hashing value, which could be used as a way to associate other SRP logs even if it's redacted. 189 * 190 * On Apple platforms, the current existing log routines will be defined as: 191 * #define log_with_component_and_type(CATEGORY, LEVEL, FORMAT, ...) os_log_with_type((CATEGORY), (LEVEL), (FORMAT), \ 192 * ##__VA_ARGS__) 193 * #define ERROR(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_ERROR, FORMAT, ##__VA_ARGS__) 194 * #define INFO(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_DEFAULT, FORMAT, ##__VA_ARGS__) 195 * #define DEBUG(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_DEBUG, FORMAT, ##__VA_ARGS__) 196 * And to follow the same log level with os_log, FAULT() is defined. 197 * #define FAULT(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_FAULT, FORMAT, ##__VA_ARGS__) 198 * Therefore, all the previous logs would be put under OS_LOG_DEFAULT category. 199 * FAULT level lof will be mapped to LOG_TYPE_FAULT in os_log. 200 * ERROR level log will be mapped to LOG_TYPE_ERROR in os_log. 201 * INFO level log will be mapped to LOG_TYPE_DEFAULT in os_log. 202 * DEBUG level log woll be mapped to LOG_TYPE_DEBUG in os_log. 203 * 204 * On platforms other than Apple, syslog will be used to write logs. 205 * FAULT level lof will be mapped to LOG_CRIT in syslog. 206 * ERROR level log will be mapped to LOG_ERR in syslog. 207 * INFO level log will be mapped to LOG_INFO in syslog. 208 * DEBUG level log woll be mapped to LOG_DEBUG in syslog. 209 * 210 * The defined specifiers are: 211 * String specifier: 212 * PUB_S_SRP: Use this in the format string when trying to log string and do not want it to be redacted. 213 * PRI_S_SRP: Use this when trying to log string and redact it to a hash string. 214 * Usage: 215 * INFO("Public string: " PUB_S_SRP, ", private string: " PRI_S_SRP, string_ptr, string_ptr); 216 * 217 * DNS name (with dns_label_t type) specifier: 218 * DNS_NAME_GEN_SRP: Always call this before logging DNS name. 219 * PUB_DNS_NAME_SRP: Use this in the format string when trying to log DNS name and do not want it to be redacted. 220 * PRI_DNS_NAME_SRP: Use this in the format string when trying to log DNS name and redact it to a hash string. 221 * DNS_NAME_PARAM_SRP: Always use DNS_NAME_PARAM_SRP in the paramter list. 222 * Usage: 223 * DNS_NAME_GEN_SRP(dns_name_ptr, dns_name_buf); 224 * INFO("Public DNS name: " PUB_DNS_NAME_SRP, ", private DNS name: " PRI_DNS_NAME_SRP, 225 * DNS_NAME_PARAM_SRP(dns_name_ptr, dns_name_buf), DNS_NAME_PARAM_SRP(dns_name_ptr, dns_name_buf)); 226 * 227 * IPv4 address specifier (with in_addr * type or a pointer to uint8_t[4]): 228 * IPv4_ADDR_GEN_SRP: Always call this before logging IPv4 address. 229 * PUB_IPv4_ADDR_SRP: Use this in the format string when trying to log IPv4 address and do not want it to be 230 * redacted. 231 * PRI_IPv4_ADDR_SRP: Use this in the format string when trying to log IPv4 address and redact it to a hash string. 232 * IPv4_ADDR_PARAM_SRP: Always use IPv4_ADDR_PARAM_SRP in the paramter list. 233 * Usage: 234 * IPv4_ADDR_GEN_SRP(in_addr_ptr_1, in_addr_buf_1); 235 * IPv4_ADDR_GEN_SRP(in_addr_ptr_2, in_addr_buf_2); 236 * INFO("Public IPv4 address: " PUB_IPv4_ADDR_SRP, ", private IPv4 address: " PRI_IPv4_ADDR_SRP, 237 * IPv4_ADDR_PARAM_SRP(in_addr_ptr_1, in_addr_buf_1), IPv4_ADDR_PARAM_SRP(in_addr_ptr_2, in_addr_buf_2)); 238 * 239 * IPv6 address specifier (with in6_addr * type or a pointer to uint8_t[16]): 240 * IPv6_ADDR_GEN_SRP: Always call this before logging IPv6 address. 241 * PUB_IPv6_ADDR_SRP: Use this in the format string when trying to log IPv6 address and do not want it to be 242 * redacted. 243 * PRI_IPv6_ADDR_SRP: Use this in the format string when trying to log IPv6 address and redact it to a hash string. 244 * IPv6_ADDR_PARAM_SRP: Always use IPv6_ADDR_PARAM_SRP in the paramter list. 245 * Usage: 246 * IPv6_ADDR_GEN_SRP(in6_addr_ptr_1, in6_addr_buf_1); 247 * IPv6_ADDR_GEN_SRP(in6_addr_ptr_2, in6_addr_buf_2); 248 * INFO("Public IPv6 address: " PUB_IPv6_ADDR_SRP, ", private IPv6 address: " PRI_IPv6_ADDR_SRP, 249 * IPv6_ADDR_PARAM_SRP(in6_addr_ptr_1, in6_addr_buf_1), 250 * IPv6_ADDR_PARAM_SRP(in6_addr_ptr_2, in6_addr_buf_2)); 251 * 252 * Segmented IPv6 address specifier (with in6_addr * type or a pointer to uint8_t[16]): 253 * SEGMENTED_IPv6_ADDR_GEN_SRP: Always call this before logging segmented IPv6 address. 254 * PUB_SEGMENTED_IPv6_ADDR_SRP: Use this in the format string when trying to log segmented IPv6 address and do not 255 * want it to be redacted. 256 * PRI_SEGMENTED_IPv6_ADDR_SRP: Use this in the format string when trying to log segmented IPv6 address and redact 257 * it to a hash string. 258 * SEGMENTED_IPv6_ADDR_PARAM_SRP: Always use SEGMENTED_IPv6_ADDR_PARAM_SRP in the paramter list. 259 * Usage: 260 * SEGMENTED_IPv6_ADDR_GEN_SRP(in6_addr_ptr_1, in6_addr_buf_1); 261 * SEGMENTED_IPv6_ADDR_GEN_SRP(in6_addr_ptr_2, in6_addr_buf_2); 262 * INFO("Public IPv6 address: " PUB_SEGMENTED_IPv6_ADDR_SRP, ", private IPv6 address: " 263 * PRI_SEGMENTED_IPv6_ADDR_SRP, SEGMENTED_IPv6_ADDR_PARAM_SRP(in6_addr_ptr_1, in6_addr_buf_1), 264 * SEGMENTED_IPv6_ADDR_PARAM_SRP(in6_addr_ptr_2, in6_addr_buf_2)); 265 * Note: 266 * Segmented IPv6 is prefered when logging IPv6 address in SRP, because the address is divided to: 48 bit 267 * prefix, 16 bit subnet, 64 bit host, which makes it easier to match the prefix even when log redaction is 268 * turned on and the address is hashed to a string. 269 * 270 * IPv6 prefix specifier (with a pointer to uint8_t[] array): 271 * IPv6_PREFIX_GEN_SRP: Always call this before logging IPv6 prefix (which is also segmented). 272 * PUB_IPv6_PREFIX_SRP: Use this in the format string when trying to log IPv6 prefix and do not want it to be 273 * redacted. 274 * PRI_IPv6_PREFIX_SRP: Use this in the format string when trying to log IPv6 prefix and redact it to a hash 275 * string. 276 * IPv6_PREFIX_PARAM_SRP: Always use IPv6_PREFIX_PARAM_SRP in the paramter list. 277 * Usage: 278 * IPv6_PREFIX_GEN_SRP(in6_prefix_ptr_1, sizeof(in6_prefix_1), in6_prefix_buf_1); 279 * IPv6_PREFIX_GEN_SRP(in6_prefix_ptr_2, sizeof(in6_prefix_2), in6_prefix_buf_2); 280 * INFO("Public IPv6 prefix: " PUB_IPv6_PREFIX_SRP, ", private IPv6 prefix: " PRI_IPv6_PREFIX_SRP, 281 * IPv6_PREFIX_PARAM_SRP(in6_prefix_buf_1), IPv6_PREFIX_PARAM_SRP(in6_prefix_buf_2)); 282 * 283 * Mac address specifier (with a pointer to uint8_t[6] array): 284 * PUB_MAC_ADDR_SRP: Use this in the format string when trying to log Mac address and do not want it to be 285 * redacted. 286 * PRI_MAC_ADDR_SRP: Use this in the format string when trying to log Mac address and redact it to a hash string. 287 * MAC_ADDR_PARAM_SRP: Always use MAC_ADDR_PARAM_SRP in the paramter list. 288 * Usage: 289 * INFO("Public MAC address: " PUB_MAC_ADDR_SRP, ", private MAC address: " PRI_MAC_ADDR_SRP, 290 * MAC_ADDR_PARAM_SRP(mac_addr), MAC_ADDR_PARAM_SRP(mac_addr)); 291 */ 292 293 // Helper macro to display if the correspoding IPv6 is ULA (Unique Local Address), LUA (Link Local Address) 294 // or GUA (Global Unicast Address). 295 // ULA starts with FC00::/7. 296 // LUA starts with fe80::/10. 297 // GUA starts with 2000::/3. 298 #define ADDRESS_RANGE_STR(ADDR) ( \ 299 ((ADDR)[0] & 0xFE) == 0xFC ? \ 300 " (ULA)" : \ 301 ( \ 302 ( ((ADDR)[0] == 0xFE) && ((uint8_t)(ADDR)[1] & 0xC0) == 0x80 ) ? \ 303 " (LUA)" : \ 304 ( ((ADDR)[0] & 0xE0) == 0x20 ? " (GUA)" : "" ) \ 305 ) \ 306 ) 307 308 // Logging macros 309 #if OS_LOG_ENABLED 310 // Define log specifier 311 // String 312 #define PUB_S_SRP "%{public}s" 313 #define PRI_S_SRP "%{private, mask.hash}s" 314 // DNS name, when the pointer to DNS name is NULL, <NULL> will be logged. 315 #define DNS_NAME_GEN_SRP(NAME, BUF_NAME) \ 316 char BUF_NAME[DNS_MAX_NAME_SIZE_ESCAPED + 1]; \ 317 if (NAME != NULL) { \ 318 dns_name_print(NAME, BUF_NAME, sizeof(BUF_NAME)); \ 319 } else { \ 320 strncpy(BUF_NAME, "<null>", sizeof("<null>") < sizeof(BUF_NAME) ? sizeof("<null>") : sizeof(BUF_NAME)); \ 321 } 322 #define PUB_DNS_NAME_SRP PUB_S_SRP 323 #define PRI_DNS_NAME_SRP PRI_S_SRP 324 #define DNS_NAME_PARAM_SRP(NAME, BUF) (BUF) 325 // IP address 326 // IPv4 327 #define IPv4_ADDR_GEN_SRP(ADDR, BUF_NAME) do {} while(0) 328 #define PUB_IPv4_ADDR_SRP "%{public, network:in_addr}.4P" 329 #define PRI_IPv4_ADDR_SRP "%{private, mask.hash, network:in_addr}.4P" 330 #define IPv4_ADDR_PARAM_SRP(ADDR, BUF) ((uint8_t *)ADDR) 331 // IPv6 332 #define IPv6_ADDR_GEN_SRP(ADDR, BUF_NAME) do {} while(0) 333 #define PUB_IPv6_ADDR_SRP "%{public, network:in6_addr}.16P%{public}s" 334 #define PRI_IPv6_ADDR_SRP "%{private, mask.hash, network:in6_addr}.16P%{public}s" 335 #define IPv6_ADDR_PARAM_SRP(ADDR, BUF) ((uint8_t *)ADDR), ADDRESS_RANGE_STR((uint8_t *)ADDR) 336 // Segmented IPv6 337 // Subnet part can always be public. 338 #define SEGMENTED_IPv6_ADDR_GEN_SRP(ADDR, BUF_NAME) do {} while(0) 339 #define PUB_SEGMENTED_IPv6_ADDR_SRP "{%{public, srp:in6_addr_segment}.6P%{public}s, " \ 340 "%{public, srp:in6_addr_segment}.2P, " \ 341 "%{public, srp:in6_addr_segment}.8P}" 342 #define PRI_SEGMENTED_IPv6_ADDR_SRP "{%{private, mask.hash, srp:in6_addr_segment}.6P%{public}s, " \ 343 "%{public, mask.hash, srp:in6_addr_segment}.2P, " \ 344 "%{private, mask.hash, srp:in6_addr_segment}.8P}" 345 #define SEGMENTED_IPv6_ADDR_PARAM_SRP(ADDR, BUF) ((uint8_t *)(ADDR)), ADDRESS_RANGE_STR((uint8_t *)ADDR), \ 346 ((uint8_t *)(ADDR) + 6), ((uint8_t *)(ADDR) + 8) 347 // MAC address 348 #define PUB_MAC_ADDR_SRP "%{public, srp:mac_addr}.6P" 349 #define PRI_MAC_ADDR_SRP "%{private, mask.hash, srp:mac_addr}.6P" 350 #define MAC_ADDR_PARAM_SRP(ADDR) ((uint8_t *)ADDR) 351 352 #else // ifdef OS_LOG_ENABLED 353 // When os_log is not available, all logs would be public. 354 // Define log specifier 355 // String 356 #define PUB_S_SRP "%s" 357 #define PRI_S_SRP PUB_S_SRP 358 // DNS name, when the pointer to DNS name is NULL, <NULL> will be logged. 359 #define DNS_NAME_GEN_SRP(NAME, BUF_NAME) \ 360 char BUF_NAME[DNS_MAX_NAME_SIZE_ESCAPED + 1]; \ 361 if (NAME != NULL) { \ 362 dns_name_print(NAME, BUF_NAME, sizeof(BUF_NAME)); \ 363 } else { \ 364 strncpy(BUF_NAME, "<null>", sizeof("<null>") < sizeof(BUF_NAME) ? sizeof("<null>") : sizeof(BUF_NAME)); \ 365 } 366 #define PUB_DNS_NAME_SRP "%s" 367 #define PRI_DNS_NAME_SRP PUB_DNS_NAME_SRP 368 #define DNS_NAME_PARAM_SRP(NAME, BUF) (BUF) 369 // IP address 370 // IPv4 371 #define IPv4_ADDR_GEN_SRP(ADDR, BUF_NAME) char BUF_NAME[INET_ADDRSTRLEN]; \ 372 inet_ntop(AF_INET, ((uint8_t *)ADDR), BUF_NAME, sizeof(BUF_NAME)) 373 #define PUB_IPv4_ADDR_SRP "%s" 374 #define PRI_IPv4_ADDR_SRP PUB_IPv4_ADDR_SRP 375 #define IPv4_ADDR_PARAM_SRP(ADDR, BUF) (BUF) 376 // IPv6 377 #define IPv6_ADDR_GEN_SRP(ADDR, BUF_NAME) char BUF_NAME[INET6_ADDRSTRLEN]; \ 378 inet_ntop(AF_INET6, ((uint8_t *)ADDR), BUF_NAME, sizeof(BUF_NAME)) 379 #define PUB_IPv6_ADDR_SRP "%s%s" 380 #define PRI_IPv6_ADDR_SRP PUB_IPv6_ADDR_SRP 381 #define IPv6_ADDR_PARAM_SRP(ADDR, BUF) (BUF), ADDRESS_RANGE_STR((uint8_t *)ADDR) 382 // Segmented IPv6 383 #define SEGMENTED_IPv6_ADDR_GEN_SRP(ADDR, BUF_NAME) IPv6_ADDR_GEN_SRP(ADDR, BUF_NAME) 384 385 #define PUB_SEGMENTED_IPv6_ADDR_SRP PUB_IPv6_ADDR_SRP 386 #define PRI_SEGMENTED_IPv6_ADDR_SRP PRI_IPv6_ADDR_SRP 387 #define SEGMENTED_IPv6_ADDR_PARAM_SRP(ADDR, BUF) IPv6_ADDR_PARAM_SRP(ADDR, BUF) 388 // MAC address 389 #define PUB_MAC_ADDR_SRP "%02x:%02x:%02x:%02x:%02x:%02x" 390 #define PRI_MAC_ADDR_SRP PUB_MAC_ADDR_SRP 391 #define MAC_ADDR_PARAM_SRP(ADDR) ((uint8_t *)ADDR)[0], ((uint8_t *)ADDR)[1], ((uint8_t *)ADDR)[2], \ 392 ((uint8_t *)ADDR)[3], ((uint8_t *)ADDR)[4], ((uint8_t *)ADDR)[5] 393 394 #endif // ifdef OS_LOG_ENABLED 395 396 // IPv6 ULA 48-bit prefix 397 #define IPv6_PREFIX_GEN_SRP(PREFIX, PREFIX_LEN, BUF_NAME) \ 398 struct in6_addr _in6_addr_##BUF_NAME##_full_addr = {0}; \ 399 memcpy(_in6_addr_##BUF_NAME##_full_addr.s6_addr, (PREFIX), \ 400 MIN(sizeof(_in6_addr_##BUF_NAME##_full_addr.s6_addr), (PREFIX_LEN))); \ 401 SEGMENTED_IPv6_ADDR_GEN_SRP(_in6_addr_##BUF_NAME##_full_addr.s6_addr, BUF_NAME); 402 #define PUB_IPv6_PREFIX_SRP PUB_SEGMENTED_IPv6_ADDR_SRP 403 #define PRI_IPv6_PREFIX_SRP PRI_SEGMENTED_IPv6_ADDR_SRP 404 #define IPv6_PREFIX_PARAM_SRP(BUF_NAME) SEGMENTED_IPv6_ADDR_PARAM_SRP(_in6_addr_##BUF_NAME##_full_addr.s6_addr, \ 405 BUF_NAME) 406 407 //====================================================================================================================== 408 409 #pragma clang diagnostic pop 410 411 #ifdef DEBUG_VERBOSE 412 #ifdef __clang_analyzer__ 413 #define RELEASE_BASE(x, finalize, file, line) \ 414 finalize(x) 415 #else 416 #define RELEASE_BASE(x, finalize, file, line) \ 417 do { \ 418 INFO("ALLOC: release at %2.2d: %p (%10s): %s:%d", \ 419 (x)->ref_count, (void *)(x), # x, strrchr(file, '/') + 1, line); \ 420 --(x)->ref_count; \ 421 if ((x)->ref_count == 0) { \ 422 INFO("ALLOC: finalize: %p (%10s): %s:%d", \ 423 (void *)(x), # x, strrchr(file, '/') + 1, line); \ 424 finalize(x); \ 425 } \ 426 } while (0) 427 #endif // __clang_analyzer__ 428 #define RETAIN_BASE(x, file, line) \ 429 do { \ 430 INFO("ALLOC: retain at %2.2d: %p (%10s): %s:%d", \ 431 (x)->ref_count, (void *)(x), # x, strrchr(file, '/') + 1, line); \ 432 ++(x)->ref_count; \ 433 } while (0) 434 #define RELEASE(x, finalize) RELEASE_BASE(x, finalize, file, line) 435 #define RETAIN(x) RETAIN_BASE(x, file, line) 436 #define RELEASE_HERE(x, finalize) RELEASE_BASE(x, finalize, __FILE__, __LINE__) 437 #define RETAIN_HERE(x) RETAIN_BASE(x, __FILE__, __LINE__) 438 #else 439 #ifdef __clang_analyzer__ 440 #define RELEASE(x, finalize) finalize(x) 441 #define RELEASE_HERE(x, finalize) finalize(x) 442 #define RETAIN(x) 443 #define RETAIN_HERE(x) 444 #else 445 #define RELEASE(x, finalize) do { \ 446 if (--(x)->ref_count == 0) { \ 447 finalize(x); \ 448 (void)file; (void)line; \ 449 } \ 450 } while (0) 451 #define RETAIN(x) do { \ 452 (x)->ref_count++; \ 453 (void)file; (void)line; \ 454 } while (0) 455 #define RELEASE_HERE(x, finalize) do { \ 456 if (--(x)->ref_count == 0) { \ 457 finalize(x); \ 458 } \ 459 } while (0) 460 #define RETAIN_HERE(x) ((x)->ref_count++) 461 #endif 462 #endif // DEBUG_VERBOSE 463 464 #define THREAD_ENTERPRISE_NUMBER ((uint64_t)44970) 465 #define THREAD_SRP_SERVER_OPTION 0x5d 466 #define THREAD_PREF_ID_OPTION 0x9d 467 468 #define IS_SRP_SERVICE(service) \ 469 ((cti_service)->enterprise_number == THREAD_ENTERPRISE_NUMBER && \ 470 (cti_service)->service_type == THREAD_SRP_SERVER_OPTION && \ 471 (cti_service)->service_version == 1 && \ 472 (cti_service)->server_length == 18) 473 #define IS_PREF_ID_SERVICE(service) \ 474 ((cti_service)->enterprise_number == THREAD_ENTERPRISE_NUMBER && \ 475 (cti_service)->service_type == THREAD_PREF_ID_OPTION && \ 476 (cti_service)->service_version == 1 && \ 477 (cti_service)->server_length == 9) 478 479 #ifdef MALLOC_DEBUG_LOGGING 480 void *debug_malloc(size_t len, const char *file, int line); 481 void *debug_calloc(size_t count, size_t len, const char *file, int line); 482 char *debug_strdup(const char *s, const char *file, int line); 483 void debug_free(void *p, const char *file, int line); 484 485 #define malloc(x) debug_malloc(x, __FILE__, __LINE__) 486 #define calloc(c, y) debug_calloc(c, y, __FILE__, __LINE__) 487 #define strdup(s) debug_strdup(s, __FILE__, __LINE__) 488 #define free(p) debug_free(p, __FILE__, __LINE__) 489 #endif 490 491 typedef struct srp_key srp_key_t; 492 #endif // __SRP_H 493 494 // Local Variables: 495 // mode: C 496 // tab-width: 4 497 // c-file-style: "bsd" 498 // c-basic-offset: 4 499 // fill-column: 108 500 // indent-tabs-mode: nil 501 // End: 502