Merge branch 'expose-debugging' into 'master'

Debugging API

See merge request slirp/libslirp!139
diff --git a/src/debug.h b/src/debug.h
index f4da00c..8741226 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -6,61 +6,55 @@
 #ifndef DEBUG_H_
 #define DEBUG_H_
 
-#define DBG_CALL (1 << 0)
-#define DBG_MISC (1 << 1)
-#define DBG_ERROR (1 << 2)
-#define DBG_TFTP (1 << 3)
-#define DBG_VERBOSE_CALL (1 << 4)
+extern unsigned int slirp_debug;
 
-extern int slirp_debug;
-
-#define DEBUG_CALL(name)                          \
-    do {                                          \
-        if (G_UNLIKELY(slirp_debug & DBG_CALL)) { \
-            g_debug(name "...");                  \
-        }                                         \
+#define DEBUG_CALL(name)                                \
+    do {                                                \
+        if (G_UNLIKELY(slirp_debug & SLIRP_DBG_CALL)) { \
+            g_debug(name "...");                        \
+        }                                               \
     } while (0)
 
-#define DEBUG_VERBOSE_CALL(name)                          \
-    do {                                                  \
-        if (G_UNLIKELY(slirp_debug & DBG_VERBOSE_CALL)) { \
-            g_debug(name "...");                          \
-        }                                                 \
+#define DEBUG_VERBOSE_CALL(name)                                \
+    do {                                                        \
+        if (G_UNLIKELY(slirp_debug & SLIRP_DBG_VERBOSE_CALL)) { \
+            g_debug(name "...");                                \
+        }                                                       \
     } while (0)
 
-#define DEBUG_RAW_CALL(...)                       \
-    do {                                          \
-        if (G_UNLIKELY(slirp_debug & DBG_CALL)) { \
-            g_debug(__VA_ARGS__);                 \
-        }                                         \
+#define DEBUG_RAW_CALL(...)                             \
+    do {                                                \
+        if (G_UNLIKELY(slirp_debug & SLIRP_DBG_CALL)) { \
+            g_debug(__VA_ARGS__);                       \
+        }                                               \
     } while (0)
 
-#define DEBUG_ARG(...)                            \
-    do {                                          \
-        if (G_UNLIKELY(slirp_debug & DBG_CALL)) { \
-            g_debug(" " __VA_ARGS__);             \
-        }                                         \
+#define DEBUG_ARG(...)                                  \
+    do {                                                \
+        if (G_UNLIKELY(slirp_debug & SLIRP_DBG_CALL)) { \
+            g_debug(" " __VA_ARGS__);                   \
+        }                                               \
     } while (0)
 
-#define DEBUG_MISC(...)                           \
-    do {                                          \
-        if (G_UNLIKELY(slirp_debug & DBG_MISC)) { \
-            g_debug(__VA_ARGS__);                 \
-        }                                         \
+#define DEBUG_MISC(...)                                 \
+    do {                                                \
+        if (G_UNLIKELY(slirp_debug & SLIRP_DBG_MISC)) { \
+            g_debug(__VA_ARGS__);                       \
+        }                                               \
     } while (0)
 
-#define DEBUG_ERROR(...)                           \
-    do {                                           \
-        if (G_UNLIKELY(slirp_debug & DBG_ERROR)) { \
-            g_debug(__VA_ARGS__);                  \
-        }                                          \
+#define DEBUG_ERROR(...)                                 \
+    do {                                                 \
+        if (G_UNLIKELY(slirp_debug & SLIRP_DBG_ERROR)) { \
+            g_debug(__VA_ARGS__);                        \
+        }                                                \
     } while (0)
 
-#define DEBUG_TFTP(...)                           \
-    do {                                          \
-        if (G_UNLIKELY(slirp_debug & DBG_TFTP)) { \
-            g_debug(__VA_ARGS__);                 \
-        }                                         \
+#define DEBUG_TFTP(...)                                 \
+    do {                                                \
+        if (G_UNLIKELY(slirp_debug & SLIRP_DBG_TFTP)) { \
+            g_debug(__VA_ARGS__);                       \
+        }                                               \
     } while (0)
 
 #endif /* DEBUG_H_ */
diff --git a/src/ip_icmp.c b/src/ip_icmp.c
index 083249c..d74d24b 100644
--- a/src/ip_icmp.c
+++ b/src/ip_icmp.c
@@ -329,7 +329,7 @@
     if (!msrc)
         goto end_error;
     ip = mtod(msrc, struct ip *);
-    if (slirp_debug & DBG_MISC) {
+    if (slirp_debug & SLIRP_DBG_MISC) {
         char addr_src[INET_ADDRSTRLEN];
         char addr_dst[INET_ADDRSTRLEN];
 
diff --git a/src/libslirp.h b/src/libslirp.h
index d4c9244..240dfe8 100644
--- a/src/libslirp.h
+++ b/src/libslirp.h
@@ -76,6 +76,15 @@
     SLIRP_POLL_HUP = 1 << 4,
 };
 
+/* Debugging flags. */
+enum {
+    SLIRP_DBG_CALL         = 1 << 0,
+    SLIRP_DBG_MISC         = 1 << 1,
+    SLIRP_DBG_ERROR        = 1 << 2,
+    SLIRP_DBG_TFTP         = 1 << 3,
+    SLIRP_DBG_VERBOSE_CALL = 1 << 4,
+};
+
 /* Callback for application to get data from the guest */
 typedef slirp_ssize_t (*SlirpReadCb)(void *buf, size_t len, void *opaque);
 /* Callback for application to send data to the guest */
@@ -383,6 +392,24 @@
 SLIRP_EXPORT
 const char *slirp_version_string(void);
 
+/* Debugging support: There are two methods for enabling debugging
+ * in libslirp: the SLIRP_DEBUG environment variable and the
+ * slirp_(set|reset)_debug() functions.
+ *
+ * SLIRP_DEBUG is a list of debug options separated by colons, spaces
+ * or commas. Valid debug options are 'call', 'misc', 'error', 'tftp'
+ * and 'verbose_call'.
+ */
+
+/* Set debugging flags independently of the SLIRP_DEBUG environment
+ * variable. */
+SLIRP_EXPORT 
+void slirp_set_debug(unsigned int flags);
+
+/* Reset debugging flags. */
+SLIRP_EXPORT
+void slirp_reset_debug(unsigned int flags);
+
 #if defined(_WIN32)
 /* Windows utility functions: */
 
diff --git a/src/libslirp.map b/src/libslirp.map
index b087844..315bdf0 100644
--- a/src/libslirp.map
+++ b/src/libslirp.map
@@ -41,4 +41,6 @@
 
 SLIRP_4.9 {
     slirp_pollfds_fill_socket;
+    slirp_set_debug;
+    slirp_reset_debug;
 } SLIRP_4.7;
diff --git a/src/slirp.c b/src/slirp.c
index cd17d13..bccee53 100644
--- a/src/slirp.c
+++ b/src/slirp.c
@@ -69,7 +69,7 @@
 
 #endif
 
-int slirp_debug;
+unsigned int slirp_debug;
 
 /* Define to 1 if you want KEEPALIVE timers */
 bool slirp_do_keepalive;
@@ -314,7 +314,7 @@
         if (found > 3) {
             DEBUG_MISC("  (more)");
             break;
-        } else if (slirp_debug & DBG_MISC) {
+        } else if (slirp_debug & SLIRP_DBG_MISC) {
             char s[INET6_ADDRSTRLEN];
             const char *res = inet_ntop(af, addr, s, sizeof(s));
             if (!res) {
@@ -423,7 +423,7 @@
 
     if (found > 2) {
 	DEBUG_MISC("  (more)");
-    } else if (slirp_debug & DBG_MISC) {
+    } else if (slirp_debug & SLIRP_DBG_MISC) {
 	char s[INET6_ADDRSTRLEN];
 	const char *res = inet_ntop(af, &tmp_addr, s, sizeof(s));
 	if (!res) {
@@ -551,11 +551,11 @@
     debug = g_getenv("SLIRP_DEBUG");
     if (debug) {
         const GDebugKey keys[] = {
-            { "call", DBG_CALL },
-            { "misc", DBG_MISC },
-            { "error", DBG_ERROR },
-            { "tftp", DBG_TFTP },
-            { "verbose_call", DBG_VERBOSE_CALL },
+            { "call", SLIRP_DBG_CALL },
+            { "misc", SLIRP_DBG_MISC },
+            { "error", SLIRP_DBG_ERROR },
+            { "tftp", SLIRP_DBG_TFTP },
+            { "verbose_call", SLIRP_DBG_VERBOSE_CALL },
         };
         slirp_debug = g_parse_debug_string(debug, keys, G_N_ELEMENTS(keys));
     }
diff --git a/src/util.c b/src/util.c
index f69a663..9f3a334 100644
--- a/src/util.c
+++ b/src/util.c
@@ -35,6 +35,7 @@
 #include <errno.h>
 
 #include "util.h"
+#include "debug.h"
 
 #if defined(_WIN32)
 int slirp_inet_aton(const char *cp, struct in_addr *ia)
@@ -449,3 +450,16 @@
 
     return out_str;
 }
+
+/* Programatically set and reset debugging flags in slirp_debug vice
+ * setting them via the SLIRP_DEBUG environment variable. */
+
+void slirp_set_debug(unsigned int flags)
+{
+  slirp_debug |= flags;
+}
+
+void slirp_reset_debug(unsigned int flags)
+{
+  slirp_debug &= ~flags;
+}