| /* srp-log.h |
| * |
| * Copyright (c) 2020-2021 Apple Inc. All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * https://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * This file contains the utilities that are used to print log that |
| * redacts private information about the user, and function prototypes that |
| * helps to create better logs. |
| */ |
| |
| |
| #ifndef __SRP_LOG_H__ |
| #define __SRP_LOG_H__ |
| |
| #include <stdint.h> |
| #include <stdbool.h> |
| |
| #ifdef POSIX_BUILD |
| #include <limits.h> |
| #include <sys/param.h> |
| #endif |
| |
| #ifdef __APPLE__ |
| #include <os/log.h> // For os_log related APIs |
| #endif // #ifdef __APPLE__ |
| |
| #ifdef DEBUG |
| #undef DEBUG |
| // #define DEBUG_VERBOSE |
| #endif |
| |
| // We always want this until we start shipping |
| #define DEBUG_VERBOSE |
| |
| //====================================================================================================================== |
| // MARK: - Log Macros |
| |
| #ifdef FUZZING |
| #define OPENLOG(progname, consolep) |
| #define ERROR(fmt, ...) |
| #define INFO(fmt, ...) |
| #define DEBUG(fmt, ...) |
| #define FAULT(fmt, ...) |
| #elif defined(THREAD_DEVKIT_ADK) |
| |
| #include "srp-platform.h" |
| |
| #define OPENLOG(progname, consolep) srp_openlog(option) |
| #define ERROR(fmt, ...) srp_log_error(fmt, ##__VA_ARGS__) |
| #define INFO(fmt, ...) srp_log_info(fmt, ##__VA_ARGS__) |
| #ifdef DEBUG_VERBOSE |
| #define DEBUG(fmt, ...) srp_log_debug(fmt, ##__VA_ARGS__) |
| #else |
| #define DEBUG(fmt, ...) |
| #endif // DEBUG VERBOSE |
| #define FAULT(fmt, ...) srp_log_error(fmt, ##__VA_ARGS__) |
| #define NO_CLOCK |
| #else // ifdef THREAD_DEVKIT_ADK |
| |
| #ifdef LOG_FPRINTF_STDERR |
| #define OPENLOG(progname, consolep) do { (void)(consolep); (void)progname; } while (0) |
| #define ERROR(fmt, ...) fprintf(stderr, "%s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__) |
| #define INFO(fmt, ...) fprintf(stderr, "%s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__) |
| #define FAULT(fmt, ...) fprintf(stderr, "%s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__) |
| #ifdef DEBUG_VERBOSE |
| #ifdef IOLOOP_MACOS |
| int get_num_fds(void); |
| #endif // ifdef IOLOOP_MACOS |
| #define DEBUG(fmt, ...) fprintf(stderr, "%s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__) |
| #else // ifdef DEBUG_VERBOSE |
| #define DEBUG(fmt, ...) |
| #endif |
| #define FAULT(fmt, ...) fprintf(stderr, "%s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__) |
| #else // ifdef LOG_FPRINTF_STDERR |
| #include <syslog.h> |
| |
| // Apple device always has OS_LOG support. |
| #ifdef __APPLE__ |
| #define OS_LOG_ENABLED 1 |
| #include <os/log.h> |
| |
| // Define log level |
| #define LOG_TYPE_FAULT OS_LOG_TYPE_FAULT |
| #define LOG_TYPE_ERROR OS_LOG_TYPE_ERROR |
| #define LOG_TYPE_DEFAULT OS_LOG_TYPE_DEFAULT |
| #define LOG_TYPE_DEBUG OS_LOG_TYPE_DEBUG |
| // Define log macro |
| #define log_with_component_and_type(CATEGORY, LEVEL, FORMAT, ...) \ |
| os_log_with_type((CATEGORY), (LEVEL), ("%{public}s: " FORMAT), __FUNCTION__, ##__VA_ARGS__) |
| |
| #define OPENLOG(progname, consolep) \ |
| do { if (consolep) { putenv("ACTIVITY_LOG_STDERR=1"); } (void)progname; } while (0) |
| #define FAULT(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_FAULT, \ |
| FORMAT, ##__VA_ARGS__) |
| #define ERROR(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_ERROR, \ |
| FORMAT, ##__VA_ARGS__) |
| |
| #ifdef DEBUG_VERBOSE |
| #ifdef DEBUG_FD_LEAKS |
| int get_num_fds(void); |
| #define INFO(FORMAT, ...) \ |
| do { \ |
| int foo = get_num_fds(); \ |
| log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_DEFAULT, "%d " FORMAT, foo, \ |
| ##__VA_ARGS__); \ |
| } while(0) |
| #else // ifdef IOLOOP_MACOS |
| #define INFO(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, \ |
| LOG_TYPE_DEFAULT, FORMAT, ##__VA_ARGS__) |
| #endif // ifdef IOLOOP_MACOS |
| |
| #define DEBUG(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, \ |
| LOG_TYPE_DEBUG, FORMAT, ##__VA_ARGS__) |
| #else // ifdef DEBUG_VERBOSE |
| #define INFO(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, \ |
| LOG_TYPE_DEFAULT, FORMAT, ##__VA_ARGS__) |
| #define DEBUG(FORMAT, ...) do {} while(0) |
| #endif // ifdef DEBUG_VERBOSE |
| #else // ifdef __APPLE__ |
| #define OS_LOG_ENABLED 0 |
| |
| #define OPENLOG(progname, consolep) openlog(progname, (consolep ? LOG_PERROR : 0) | LOG_PID, LOG_DAEMON) |
| #define FAULT(fmt, ...) syslog(LOG_CRIT, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__) |
| #define ERROR(fmt, ...) syslog(LOG_ERR, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__) |
| |
| #ifdef DEBUG_VERBOSE |
| #ifdef DEBUG_FD_LEAKS |
| int get_num_fds(void); |
| #define INFO(fmt, ...) \ |
| do { \ |
| int foo = get_num_fds(); \ |
| syslog(LOG_INFO, "%s: %d " fmt, __FUNCTION__, foo, ##__VA_ARGS__); \ |
| } while (0) |
| #else // ifdef IOLOOP_MACOS |
| #define INFO(fmt, ...) syslog(LOG_INFO, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__) |
| #endif // ifdef IOLOOP_MACOS |
| #define DEBUG(fmt, ...) syslog(LOG_DEBUG, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__) |
| #else // ifdef DEBUG_VERBOSE |
| #define INFO(fmt, ...) syslog(LOG_INFO, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__) |
| #define DEBUG(fmt, ...) do {} while(0) |
| #endif // ifdef DEBUG_VERBOSE |
| #endif // ifdef __APPLE__ |
| #endif // ifdef LOG_FPRINTF_STDERR |
| #endif // ifdef THREAD_DEVKIT_ADK |
| |
| //====================================================================================================================== |
| // MARK: - Log Specifiers |
| /** |
| * With the logging routines defined above, the logging macros are defined to facilitate the log redaction enforced by |
| * os_log on Apple platforms. By using the specifier "%{mask.hash}", the "<private>" text in the logs of customer device |
| * would be shown as a hashing value, which could be used as a way to associate other SRP logs even if it's redacted. |
| * |
| * On Apple platforms, the current existing log routines will be defined as: |
| * #define log_with_component_and_type(CATEGORY, LEVEL, FORMAT, ...) os_log_with_type((CATEGORY), (LEVEL), (FORMAT), \ |
| * ##__VA_ARGS__) |
| * #define ERROR(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_ERROR, FORMAT, ##__VA_ARGS__) |
| * #define INFO(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_DEFAULT, FORMAT, ##__VA_ARGS__) |
| * #define DEBUG(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_DEBUG, FORMAT, ##__VA_ARGS__) |
| * And to follow the same log level with os_log, FAULT() is defined. |
| * #define FAULT(FORMAT, ...) log_with_component_and_type(OS_LOG_DEFAULT, LOG_TYPE_FAULT, FORMAT, ##__VA_ARGS__) |
| * Therefore, all the previous logs would be put under OS_LOG_DEFAULT category. |
| * FAULT level lof will be mapped to LOG_TYPE_FAULT in os_log. |
| * ERROR level log will be mapped to LOG_TYPE_ERROR in os_log. |
| * INFO level log will be mapped to LOG_TYPE_DEFAULT in os_log. |
| * DEBUG level log woll be mapped to LOG_TYPE_DEBUG in os_log. |
| * |
| * On platforms other than Apple, syslog will be used to write logs. |
| * FAULT level lof will be mapped to LOG_CRIT in syslog. |
| * ERROR level log will be mapped to LOG_ERR in syslog. |
| * INFO level log will be mapped to LOG_INFO in syslog. |
| * DEBUG level log woll be mapped to LOG_DEBUG in syslog. |
| * |
| * The defined specifiers are: |
| * String specifier: |
| * PUB_S_SRP: Use this in the format string when trying to log string and do not want it to be redacted. |
| * PRI_S_SRP: Use this when trying to log string and redact it to a hash string. |
| * Usage: |
| * INFO("Public string: " PUB_S_SRP, ", private string: " PRI_S_SRP, string_ptr, string_ptr); |
| * |
| * DNS name (with dns_label_t type) specifier: |
| * DNS_NAME_GEN_SRP: Always call this before logging DNS name. |
| * PUB_DNS_NAME_SRP: Use this in the format string when trying to log DNS name and do not want it to be redacted. |
| * PRI_DNS_NAME_SRP: Use this in the format string when trying to log DNS name and redact it to a hash string. |
| * DNS_NAME_PARAM_SRP: Always use DNS_NAME_PARAM_SRP in the paramter list. |
| * Usage: |
| * DNS_NAME_GEN_SRP(dns_name_ptr, dns_name_buf); |
| * INFO("Public DNS name: " PUB_DNS_NAME_SRP, ", private DNS name: " PRI_DNS_NAME_SRP, |
| * DNS_NAME_PARAM_SRP(dns_name_ptr, dns_name_buf), DNS_NAME_PARAM_SRP(dns_name_ptr, dns_name_buf)); |
| * |
| * IPv4 address specifier (with in_addr * type or a pointer to uint8_t[4]): |
| * IPv4_ADDR_GEN_SRP: Always call this before logging IPv4 address. |
| * PUB_IPv4_ADDR_SRP: Use this in the format string when trying to log IPv4 address and do not want it to be |
| * redacted. |
| * PRI_IPv4_ADDR_SRP: Use this in the format string when trying to log IPv4 address and redact it to a hash string. |
| * IPv4_ADDR_PARAM_SRP: Always use IPv4_ADDR_PARAM_SRP in the paramter list. |
| * Usage: |
| * IPv4_ADDR_GEN_SRP(in_addr_ptr_1, in_addr_buf_1); |
| * IPv4_ADDR_GEN_SRP(in_addr_ptr_2, in_addr_buf_2); |
| * INFO("Public IPv4 address: " PUB_IPv4_ADDR_SRP, ", private IPv4 address: " PRI_IPv4_ADDR_SRP, |
| * IPv4_ADDR_PARAM_SRP(in_addr_ptr_1, in_addr_buf_1), IPv4_ADDR_PARAM_SRP(in_addr_ptr_2, in_addr_buf_2)); |
| * |
| * IPv6 address specifier (with in6_addr * type or a pointer to uint8_t[16]): |
| * IPv6_ADDR_GEN_SRP: Always call this before logging IPv6 address. |
| * PUB_IPv6_ADDR_SRP: Use this in the format string when trying to log IPv6 address and do not want it to be |
| * redacted. |
| * PRI_IPv6_ADDR_SRP: Use this in the format string when trying to log IPv6 address and redact it to a hash string. |
| * IPv6_ADDR_PARAM_SRP: Always use IPv6_ADDR_PARAM_SRP in the paramter list. |
| * Usage: |
| * IPv6_ADDR_GEN_SRP(in6_addr_ptr_1, in6_addr_buf_1); |
| * IPv6_ADDR_GEN_SRP(in6_addr_ptr_2, in6_addr_buf_2); |
| * INFO("Public IPv6 address: " PUB_IPv6_ADDR_SRP, ", private IPv6 address: " PRI_IPv6_ADDR_SRP, |
| * IPv6_ADDR_PARAM_SRP(in6_addr_ptr_1, in6_addr_buf_1), |
| * IPv6_ADDR_PARAM_SRP(in6_addr_ptr_2, in6_addr_buf_2)); |
| * |
| * Segmented IPv6 address specifier (with in6_addr * type or a pointer to uint8_t[16]): |
| * SEGMENTED_IPv6_ADDR_GEN_SRP: Always call this before logging segmented IPv6 address. |
| * PUB_SEGMENTED_IPv6_ADDR_SRP: Use this in the format string when trying to log segmented IPv6 address and do not |
| * want it to be redacted. |
| * PRI_SEGMENTED_IPv6_ADDR_SRP: Use this in the format string when trying to log segmented IPv6 address and redact |
| * it to a hash string. |
| * SEGMENTED_IPv6_ADDR_PARAM_SRP: Always use SEGMENTED_IPv6_ADDR_PARAM_SRP in the paramter list. |
| * Usage: |
| * SEGMENTED_IPv6_ADDR_GEN_SRP(in6_addr_ptr_1, in6_addr_buf_1); |
| * SEGMENTED_IPv6_ADDR_GEN_SRP(in6_addr_ptr_2, in6_addr_buf_2); |
| * INFO("Public IPv6 address: " PUB_SEGMENTED_IPv6_ADDR_SRP, ", private IPv6 address: " |
| * PRI_SEGMENTED_IPv6_ADDR_SRP, SEGMENTED_IPv6_ADDR_PARAM_SRP(in6_addr_ptr_1, in6_addr_buf_1), |
| * SEGMENTED_IPv6_ADDR_PARAM_SRP(in6_addr_ptr_2, in6_addr_buf_2)); |
| * Note: |
| * Segmented IPv6 is prefered when logging IPv6 address in SRP, because the address is divided to: 48 bit |
| * prefix, 16 bit subnet, 64 bit host, which makes it easier to match the prefix even when log redaction is |
| * turned on and the address is hashed to a string. |
| * |
| * IPv6 prefix specifier (with a pointer to uint8_t[] array): |
| * IPv6_PREFIX_GEN_SRP: Always call this before logging IPv6 prefix (which is also segmented). |
| * PUB_IPv6_PREFIX_SRP: Use this in the format string when trying to log IPv6 prefix and do not want it to be |
| * redacted. |
| * PRI_IPv6_PREFIX_SRP: Use this in the format string when trying to log IPv6 prefix and redact it to a hash |
| * string. |
| * IPv6_PREFIX_PARAM_SRP: Always use IPv6_PREFIX_PARAM_SRP in the paramter list. |
| * Usage: |
| * IPv6_PREFIX_GEN_SRP(in6_prefix_ptr_1, sizeof(in6_prefix_1), in6_prefix_buf_1); |
| * IPv6_PREFIX_GEN_SRP(in6_prefix_ptr_2, sizeof(in6_prefix_2), in6_prefix_buf_2); |
| * INFO("Public IPv6 prefix: " PUB_IPv6_PREFIX_SRP, ", private IPv6 prefix: " PRI_IPv6_PREFIX_SRP, |
| * IPv6_PREFIX_PARAM_SRP(in6_prefix_buf_1), IPv6_PREFIX_PARAM_SRP(in6_prefix_buf_2)); |
| * |
| * Mac address specifier (with a pointer to uint8_t[6] array): |
| * PUB_MAC_ADDR_SRP: Use this in the format string when trying to log Mac address and do not want it to be |
| * redacted. |
| * PRI_MAC_ADDR_SRP: Use this in the format string when trying to log Mac address and redact it to a hash string. |
| * MAC_ADDR_PARAM_SRP: Always use MAC_ADDR_PARAM_SRP in the paramter list. |
| * Usage: |
| * INFO("Public MAC address: " PUB_MAC_ADDR_SRP, ", private MAC address: " PRI_MAC_ADDR_SRP, |
| * MAC_ADDR_PARAM_SRP(mac_addr), MAC_ADDR_PARAM_SRP(mac_addr)); |
| */ |
| |
| // Helper macro to display if the correspoding IPv6 is ULA (Unique Local Address), LUA (Link Local Address) |
| // or GUA (Global Unicast Address). |
| // ULA starts with FC00::/7. |
| // LUA starts with fe80::/10. |
| // GUA starts with 2000::/3. |
| #define IS_IPV6_ADDR_ULA(ADDR) ( ((ADDR)[0] & 0xFE) == 0xFC ) |
| #define IS_IPV6_ADDR_LUA(ADDR) ( ((ADDR)[0] == 0xFE) && ((uint8_t)(ADDR)[1] & 0xC0) == 0x80 ) |
| #define IS_IPV6_ADDR_GUA(ADDR) ( ((ADDR)[0] & 0xE0) == 0x20 ) |
| #define ADDRESS_RANGE_STR(ADDR) ( \ |
| IS_IPV6_ADDR_ULA(ADDR) ? \ |
| "ULA: " : \ |
| (( IS_IPV6_ADDR_LUA(ADDR) ) ? \ |
| "LUA: " : \ |
| ( IS_IPV6_ADDR_GUA(ADDR) ? "GUA: " : "" )) \ |
| ) |
| |
| // Logging macros |
| #if OS_LOG_ENABLED |
| // Define log specifier |
| // String |
| #define PUB_S_SRP "%{public}s" |
| #define PRI_S_SRP "%{private, mask.hash}s" |
| // DNS name, when the pointer to DNS name is NULL, <NULL> will be logged. |
| #define DNS_NAME_GEN_SRP(NAME, BUF_NAME) \ |
| char BUF_NAME[DNS_MAX_NAME_SIZE_ESCAPED + 1]; \ |
| if (NAME != NULL) { \ |
| dns_name_print(NAME, BUF_NAME, sizeof(BUF_NAME)); \ |
| } else { \ |
| snprintf(BUF_NAME, sizeof(BUF_NAME), "<null>"); \ |
| } |
| #define PUB_DNS_NAME_SRP PUB_S_SRP |
| #define PRI_DNS_NAME_SRP PRI_S_SRP |
| #define DNS_NAME_PARAM_SRP(NAME, BUF) (BUF) |
| // IP address |
| // IPv4 |
| #define IPv4_ADDR_GEN_SRP(ADDR, BUF_NAME) do {} while(0) |
| #define PUB_IPv4_ADDR_SRP "%{public, network:in_addr}.4P" |
| #define PRI_IPv4_ADDR_SRP "%{private, mask.hash, network:in_addr}.4P" |
| #define IPv4_ADDR_PARAM_SRP(ADDR, BUF) ((uint8_t *)ADDR) |
| // IPv6 |
| #define IPv6_ADDR_GEN_SRP(ADDR, BUF_NAME) do {} while(0) |
| #define PUB_IPv6_ADDR_SRP "%{public, network:in6_addr}.16P%{public}s" |
| #define PRI_IPv6_ADDR_SRP "%{public}s%{private, mask.hash, network:in6_addr}.16P" |
| #define IPv6_ADDR_PARAM_SRP(ADDR, BUF) ADDRESS_RANGE_STR((uint8_t *)(ADDR)), ((uint8_t *)(ADDR)) |
| // Segmented IPv6 |
| // Subnet part can always be public. |
| #define SEGMENTED_IPv6_ADDR_GEN_SRP(ADDR, BUF_NAME) do {} while(0) |
| #define PUB_SEGMENTED_IPv6_ADDR_SRP "{%{public, srp:in6_addr_segment}.6P%{public}s, " \ |
| "%{public, srp:in6_addr_segment}.2P, " \ |
| "%{public, srp:in6_addr_segment}.8P}" |
| #define PRI_SEGMENTED_IPv6_ADDR_SRP "{%{public}s%{private, mask.hash, srp:in6_addr_segment}.6P:" \ |
| "%{public, mask.hash, srp:in6_addr_segment}.2P:" \ |
| "%{private, mask.hash, srp:in6_addr_segment}.8P}" |
| #define SEGMENTED_IPv6_ADDR_PARAM_SRP(ADDR, BUF) ADDRESS_RANGE_STR((uint8_t *)(ADDR)), ((uint8_t *)(ADDR)), \ |
| ((uint8_t *)(ADDR) + 6), ((uint8_t *)(ADDR) + 8) |
| // MAC address |
| #define PUB_MAC_ADDR_SRP "%{public, srp:mac_addr}.6P" |
| #define PRI_MAC_ADDR_SRP "%{private, mask.hash, srp:mac_addr}.6P" |
| #define MAC_ADDR_PARAM_SRP(ADDR) ((uint8_t *)ADDR) |
| |
| #else // ifdef OS_LOG_ENABLED |
| // When os_log is not available, all logs would be public. |
| // Define log specifier |
| // String |
| #define PUB_S_SRP "%s" |
| #define PRI_S_SRP PUB_S_SRP |
| // DNS name, when the pointer to DNS name is NULL, <NULL> will be logged. |
| #if defined(MDNS_NO_STRICT) && (!MDNS_NO_STRICT) |
| #define SRP_LOG_STRNCPY_STRICT mdns_strlcpy |
| #else |
| #define SRP_LOG_STRNCPY_STRICT strlcpy |
| #endif |
| #ifdef IOLOOP_MACOS |
| #define SRP_LOG_STRNCPY SRP_LOG_STRNCPY_STRICT |
| #else |
| #define SRP_LOG_STRNCPY strncpy |
| #endif // IOLOOP_MACOS |
| #define DNS_NAME_GEN_SRP(NAME, BUF_NAME) \ |
| char BUF_NAME[DNS_MAX_NAME_SIZE_ESCAPED + 1]; \ |
| if (NAME != NULL) { \ |
| dns_name_print(NAME, BUF_NAME, sizeof(BUF_NAME)); \ |
| } else { \ |
| SRP_LOG_STRNCPY(BUF_NAME, "<null>", \ |
| sizeof("<null>") < sizeof(BUF_NAME) ? sizeof("<null>") : sizeof(BUF_NAME)); \ |
| } |
| #define PUB_DNS_NAME_SRP "%s" |
| #define PRI_DNS_NAME_SRP PUB_DNS_NAME_SRP |
| #define DNS_NAME_PARAM_SRP(NAME, BUF) (BUF) |
| // IP address |
| // IPv4 |
| #define IPv4_ADDR_GEN_SRP(ADDR, BUF_NAME) char BUF_NAME[INET_ADDRSTRLEN]; \ |
| inet_ntop(AF_INET, ((uint8_t *)ADDR), BUF_NAME, sizeof(BUF_NAME)) |
| #define PUB_IPv4_ADDR_SRP "%s" |
| #define PRI_IPv4_ADDR_SRP PUB_IPv4_ADDR_SRP |
| #define IPv4_ADDR_PARAM_SRP(ADDR, BUF) (BUF) |
| // IPv6 |
| #define IPv6_ADDR_GEN_SRP(ADDR, BUF_NAME) char BUF_NAME[INET6_ADDRSTRLEN]; \ |
| inet_ntop(AF_INET6, ((uint8_t *)ADDR), BUF_NAME, sizeof(BUF_NAME)) |
| #define PUB_IPv6_ADDR_SRP "%s%s" |
| #define PRI_IPv6_ADDR_SRP PUB_IPv6_ADDR_SRP |
| #define IPv6_ADDR_PARAM_SRP(ADDR, BUF) (BUF), ADDRESS_RANGE_STR((uint8_t *)ADDR) |
| // Segmented IPv6 |
| #define SEGMENTED_IPv6_ADDR_GEN_SRP(ADDR, BUF_NAME) IPv6_ADDR_GEN_SRP(ADDR, BUF_NAME) |
| |
| #define PUB_SEGMENTED_IPv6_ADDR_SRP PUB_IPv6_ADDR_SRP |
| #define PRI_SEGMENTED_IPv6_ADDR_SRP PRI_IPv6_ADDR_SRP |
| #define SEGMENTED_IPv6_ADDR_PARAM_SRP(ADDR, BUF) IPv6_ADDR_PARAM_SRP(ADDR, BUF) |
| // MAC address |
| #define PUB_MAC_ADDR_SRP "%02x:%02x:%02x:%02x:%02x:%02x" |
| #define PRI_MAC_ADDR_SRP PUB_MAC_ADDR_SRP |
| #define MAC_ADDR_PARAM_SRP(ADDR) ((uint8_t *)ADDR)[0], ((uint8_t *)ADDR)[1], ((uint8_t *)ADDR)[2], \ |
| ((uint8_t *)ADDR)[3], ((uint8_t *)ADDR)[4], ((uint8_t *)ADDR)[5] |
| |
| #endif // ifdef OS_LOG_ENABLED |
| |
| // IPv6 ULA 48-bit prefix |
| #define IPv6_PREFIX_GEN_SRP(PREFIX, PREFIX_LEN, BUF_NAME) \ |
| struct in6_addr _in6_addr_##BUF_NAME##_full_addr = {0}; \ |
| memcpy(_in6_addr_##BUF_NAME##_full_addr.s6_addr, (PREFIX), \ |
| MIN(sizeof(_in6_addr_##BUF_NAME##_full_addr.s6_addr), (PREFIX_LEN))); \ |
| SEGMENTED_IPv6_ADDR_GEN_SRP(_in6_addr_##BUF_NAME##_full_addr.s6_addr, BUF_NAME); |
| #define PUB_IPv6_PREFIX_SRP PUB_SEGMENTED_IPv6_ADDR_SRP |
| #define PRI_IPv6_PREFIX_SRP PRI_SEGMENTED_IPv6_ADDR_SRP |
| #define IPv6_PREFIX_PARAM_SRP(BUF_NAME) SEGMENTED_IPv6_ADDR_PARAM_SRP(_in6_addr_##BUF_NAME##_full_addr.s6_addr, \ |
| BUF_NAME) |
| |
| //====================================================================================================================== |
| // MARK: - To String Helpers |
| |
| /*! |
| * @brief |
| * Convert DNS question class to its corresponding text description. |
| * |
| * @param qclass |
| * The DNS question class value in the DNS message. |
| * |
| * @result |
| * The corresponding text description for the given DNS question class if it is valid. Otherwise, an error string will be returned. |
| */ |
| const char * |
| dns_qclass_to_string(uint16_t qclass); |
| |
| /*! |
| * @brief |
| * Convert DNS record type to its corresponding text description. |
| * |
| * @param rrtype |
| * The DNS record type value of the DNS record. |
| * |
| * @result |
| * The corresponding text description for the given DNS record type if it is valid. Otherwise, an error string will be returned. |
| */ |
| const char * |
| dns_rrtype_to_string(uint16_t rrtype); |
| |
| #endif // __SRP_LOG_H__ |
| |
| // Local Variables: |
| // mode: C |
| // tab-width: 4 |
| // c-file-style: "bsd" |
| // c-basic-offset: 4 |
| // fill-column: 108 |
| // indent-tabs-mode: nil |
| // End: |