1 /* debug.c -- debug utilities
3 * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
5 * Permission is hereby granted, free of charge, to any person
6 * obtaining a copy of this software and associated documentation
7 * files (the "Software"), to deal in the Software without
8 * restriction, including without limitation the rights to use, copy,
9 * modify, merge, publish, distribute, sublicense, and/or sell copies
10 * of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 #include "dtls_config.h"
29 #if defined(HAVE_ASSERT_H) && !defined(assert)
36 #ifdef HAVE_ARPA_INET_H
37 #include <arpa/inet.h>
45 #include <android/log.h>
51 static int maxlog = DTLS_LOG_WARN; /* default maximum log level */
53 const char *dtls_package_name() {
57 const char *dtls_package_version() {
58 return PACKAGE_VERSION;
62 dtls_get_log_level() {
67 dtls_set_log_level(log_t level) {
71 /* this array has the same order as the type log_t */
73 static android_LogPriority loglevels_android[] = {
83 static char *loglevels[] = {
84 "EMRG", "ALRT", "CRIT", "WARN", "NOTE", "INFO", "DEBG"
91 print_timestamp(char *s, size_t len, time_t t) {
94 return strftime(s, len, "%b %d %H:%M:%S", tmp);
97 #else /* alternative implementation: just print the timestamp */
100 print_timestamp(char *s, size_t len, clock_time_t t) {
102 return snprintf(s, len, "%u.%03u",
103 (unsigned int)(t / CLOCK_SECOND),
104 (unsigned int)(t % CLOCK_SECOND));
105 #else /* HAVE_SNPRINTF */
106 /* @todo do manual conversion of timestamp */
108 #endif /* HAVE_SNPRINTF */
111 #endif /* HAVE_TIME_H */
114 * A length-safe strlen() fake.
116 * @param s The string to count characters != 0.
117 * @param maxlen The maximum length of @p s.
119 * @return The length of @p s.
122 dtls_strnlen(const char *s, size_t maxlen) {
124 while(*s++ && n < maxlen)
130 #define min(a,b) ((a) < (b) ? (a) : (b))
134 dsrv_print_addr(const session_t *addr, char *buf, size_t len) {
135 #if defined(HAVE_ARPA_INET_H) || defined(_WIN32)
136 const void *addrptr = NULL;
137 #if defined(__ANDROID__) || defined(_WIN32)
138 unsigned short int port;
144 switch (addr->addr.sa.sa_family) {
146 if (len < INET_ADDRSTRLEN)
149 addrptr = &addr->addr.sin.sin_addr;
150 port = ntohs(addr->addr.sin.sin_port);
153 if (len < INET6_ADDRSTRLEN + 2)
158 addrptr = &addr->addr.sin6.sin6_addr;
159 port = ntohs(addr->addr.sin6.sin6_port);
163 memcpy(buf, "(unknown address type)", min(22, len));
167 if (inet_ntop(addr->addr.sa.sa_family, addrptr, p, len) == 0) {
168 perror("dsrv_print_addr");
172 p += dtls_strnlen(p, len);
174 if (addr->addr.sa.sa_family == AF_INET6) {
181 p += snprintf(p, buf + len - p + 1, ":%d", port);
184 #else /* HAVE_ARPA_INET_H */
187 # ifdef UIP_CONF_IPV6
189 const char hex[] = "0123456789ABCDEF";
196 for (i=0; i < 16; i += 2) {
200 *p++ = hex[(addr->addr.u8[i] & 0xf0) >> 4];
201 *p++ = hex[(addr->addr.u8[i] & 0x0f)];
202 *p++ = hex[(addr->addr.u8[i+1] & 0xf0) >> 4];
203 *p++ = hex[(addr->addr.u8[i+1] & 0x0f)];
206 # else /* UIP_CONF_IPV6 */
207 # warning "IPv4 network addresses will not be included in debug output"
211 # endif /* UIP_CONF_IPV6 */
212 if (buf + len - p < 6)
215 p += sprintf(p, ":%d", uip_htons(addr->port));
218 # else /* WITH_CONTIKI */
219 /* TODO: output addresses manually */
220 # warning "inet_ntop() not available, network addresses will not be included in debug output"
221 # endif /* WITH_CONTIKI */
228 dsrv_log(log_t level, char *format, ...) {
234 va_start(ap, format);
235 __android_log_vprint(loglevels_android[level], PACKAGE_NAME, format, ap);
238 #elif !defined (WITH_CONTIKI)
240 dsrv_log(log_t level, char *format, ...) {
241 static char timebuf[32];
248 log_fd = level <= DTLS_LOG_CRIT ? stderr : stdout;
250 if (print_timestamp(timebuf,sizeof(timebuf), time(NULL)))
251 fprintf(log_fd, "%s ", timebuf);
253 if (level <= DTLS_LOG_DEBUG)
254 fprintf(log_fd, "%s ", loglevels[level]);
256 va_start(ap, format);
257 vfprintf(log_fd, format, ap);
261 #elif defined (HAVE_VPRINTF) /* WITH_CONTIKI */
263 dsrv_log(log_t level, char *format, ...) {
264 static char timebuf[32];
270 if (print_timestamp(timebuf,sizeof(timebuf), clock_time()))
271 PRINTF("%s ", timebuf);
273 if (level <= DTLS_LOG_DEBUG)
274 PRINTF("%s ", loglevels[level]);
276 va_start(ap, format);
280 #endif /* WITH_CONTIKI */
283 /** dumps packets in usual hexdump format */
284 void hexdump(const unsigned char *packet, int length) {
291 printf("%02X ", *packet++);
303 /** dump as narrow string of hex digits */
304 void dump(unsigned char *buf, size_t len) {
306 printf("%02x", *buf++);
309 void dtls_dsrv_log_addr(log_t level, const char *name, const session_t *addr)
314 len = dsrv_print_addr(addr, addrbuf, sizeof(addrbuf));
317 dsrv_log(level, "%s: %s\n", name, addrbuf);
322 dtls_dsrv_hexdump_log(log_t level, const char *name, const unsigned char *buf, size_t length, int extend) {
331 size = length * 3 + strlen(name) + 22;
332 hex_dump_text = malloc(size);
338 ret = snprintf(p, size, "%s: (%zu bytes): ", name, length);
344 ret = snprintf(p, size, "%02X ", *buf++);
351 __android_log_print(loglevels_android[level], PACKAGE_NAME, "%s\n", hex_dump_text);
354 #elif !defined (WITH_CONTIKI)
356 dtls_dsrv_hexdump_log(log_t level, const char *name, const unsigned char *buf, size_t length, int extend) {
357 static char timebuf[32];
364 log_fd = level <= DTLS_LOG_CRIT ? stderr : stdout;
366 if (print_timestamp(timebuf, sizeof(timebuf), time(NULL)))
367 fprintf(log_fd, "%s ", timebuf);
369 if (level <= DTLS_LOG_DEBUG)
370 fprintf(log_fd, "%s ", loglevels[level]);
373 fprintf(log_fd, "%s: (%zu bytes):\n", name, length);
377 fprintf(log_fd, "%08X ", n);
379 fprintf(log_fd, "%02X ", *buf++);
384 fprintf(log_fd, "\n");
386 fprintf(log_fd, " ");
390 fprintf(log_fd, "%s: (%zu bytes): ", name, length);
392 fprintf(log_fd, "%02X", *buf++);
394 fprintf(log_fd, "\n");
398 #else /* WITH_CONTIKI */
400 dtls_dsrv_hexdump_log(log_t level, const char *name, const unsigned char *buf, size_t length, int extend) {
401 static char timebuf[32];
407 if (print_timestamp(timebuf,sizeof(timebuf), clock_time()))
408 PRINTF("%s ", timebuf);
410 if (level >= 0 && level <= DTLS_LOG_DEBUG)
411 PRINTF("%s ", loglevels[level]);
414 PRINTF("%s: (%zu bytes):\n", name, length);
420 PRINTF("%02X ", *buf++);
431 PRINTF("%s: (%zu bytes): ", name, length);
433 PRINTF("%02X", *buf++);
437 #endif /* WITH_CONTIKI */