Browse code

extend management interface command "state"

Currently the state command shows only the tun/tap IPv4 address. The
IPv4 address of the remote peer is also displayed. In case you connect
via IPv6 it just shows the first 4 bytes of the address in IPv4 notation.

This patch extends the state command, so it handles IPv6 addresses.
In addition it also displays the local address and the both port numbers
of the connection, e.g.

1447250958,CONNECTED,SUCCESS,10.0.0.2,fd00::1,1193,fd00::2,6492,fdff::1002

Signed-off-by: Heiko Hund <heiko.hund@sophos.com>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <1448456220-2042-1-git-send-email-heiko.hund@sophos.com>
URL: http://article.gmane.org/gmane.network.openvpn.devel/10603
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Heiko Hund authored on 2015/11/25 21:57:00
Showing 11 changed files
... ...
@@ -366,14 +366,23 @@ Command examples:
366 366
                   same time enable real-time state notification
367 367
 		  of future state transitions.
368 368
 
369
-The output format consists of 4 comma-separated parameters: 
369
+The output format consists of up to 9 comma-separated parameters:
370 370
   (a) the integer unix date/time,
371 371
   (b) the state name,
372 372
   (c) optional descriptive string (used mostly on RECONNECTING
373 373
       and EXITING to show the reason for the disconnect),
374
-  (d) optional TUN/TAP local IP address (shown for ASSIGN_IP
375
-      and CONNECTED), and
376
-  (e) optional address of remote server (OpenVPN 2.1 or higher).
374
+  (d) optional TUN/TAP local IPv4 address
375
+  (e) optional address of remote server,
376
+  (f) optional port of remote server,
377
+  (g) optional local address,
378
+  (h) optional local port, and
379
+  (i) optional TUN/TAP local IPv6 address.
380
+
381
+Fields (e)-(h) are shown for CONNECTED state,
382
+(d) and (i) are shown for ASSIGN_IP and CONNECTED states.
383
+
384
+(e) is available starting from OpenVPN 2.1
385
+(f)-(i) are available starting from OpenVPN 2.4
377 386
 
378 387
 Real-time state notifications will have a ">STATE:" prefix
379 388
 prepended to them.
... ...
@@ -208,8 +208,10 @@ check_connection_established_dowork (struct context *c)
208 208
 		  management_set_state (management,
209 209
 					OPENVPN_STATE_GET_CONFIG,
210 210
 					NULL,
211
-					0,
212
-					0);
211
+                                        NULL,
212
+                                        NULL,
213
+                                        NULL,
214
+                                        NULL);
213 215
 		}
214 216
 #endif
215 217
 	      /* fire up push request right away (already 1s delayed) */
... ...
@@ -44,6 +44,7 @@
44 44
 #include "ping.h"
45 45
 #include "mstats.h"
46 46
 #include "ssl_verify.h"
47
+#include "forward-inline.h"
47 48
 
48 49
 #include "memdbg.h"
49 50
 
... ...
@@ -1273,26 +1274,48 @@ initialization_sequence_completed (struct context *c, const unsigned int flags)
1273 1273
   /* Tell management interface that we initialized */
1274 1274
   if (management)
1275 1275
     {
1276
-      in_addr_t tun_local = 0;
1277
-      in_addr_t tun_remote = 0; /* FKS */
1276
+      in_addr_t *tun_local = NULL;
1277
+      struct in6_addr *tun_local6 = NULL;
1278
+      struct openvpn_sockaddr local, remote;
1279
+      struct link_socket_actual *actual;
1280
+      socklen_t sa_len = sizeof(local);
1278 1281
       const char *detail = "SUCCESS";
1279
-      if (c->c1.tuntap)
1280
-	tun_local = c->c1.tuntap->local;
1281
-      /* TODO(jjo): for ipv6 this will convert some 32bits in the ipv6 addr
1282
-       *            to a meaningless ipv4 address.
1283
-       *            In any case, is somewhat inconsistent to send local tunnel
1284
-       *            addr with remote _endpoint_ addr (?)
1285
-       */
1286
-      tun_remote = htonl (c->c1.link_socket_addr.actual.dest.addr.in4.sin_addr.s_addr);
1287 1282
       if (flags & ISC_ERRORS)
1288
-	detail = "ERROR";
1283
+        detail = "ERROR";
1284
+
1285
+      CLEAR (local);
1286
+      actual = &get_link_socket_info(c)->lsa->actual;
1287
+      remote = actual->dest;
1288
+      getsockname(c->c2.link_socket->sd, &local.addr.sa, &sa_len);
1289
+#if ENABLE_IP_PKTINFO
1290
+      if (!addr_defined(&local))
1291
+        {
1292
+          switch (local.addr.sa.sa_family)
1293
+            {
1294
+            case AF_INET:
1295
+              local.addr.in4.sin_addr = actual->pi.in4.ipi_spec_dst;
1296
+              break;
1297
+            case AF_INET6:
1298
+              local.addr.in6.sin6_addr = actual->pi.in6.ipi6_addr;
1299
+              break;
1300
+            }
1301
+        }
1302
+#endif
1303
+
1304
+      if (c->c1.tuntap)
1305
+        {
1306
+          tun_local = &c->c1.tuntap->local;
1307
+          tun_local6 = &c->c1.tuntap->local_ipv6;
1308
+        }
1289 1309
       management_set_state (management,
1290 1310
 			    OPENVPN_STATE_CONNECTED,
1291 1311
 			    detail,
1292 1312
 			    tun_local,
1293
-			    tun_remote);
1313
+                            tun_local6,
1314
+                            &local,
1315
+                            &remote);
1294 1316
       if (tun_local)
1295
-	management_post_tunnel_open (management, tun_local);
1317
+	management_post_tunnel_open (management, *tun_local);
1296 1318
     }
1297 1319
 #endif
1298 1320
 }
... ...
@@ -3288,8 +3311,10 @@ open_management (struct context *c)
3288 3288
 	      management_set_state (management,
3289 3289
 				    OPENVPN_STATE_CONNECTING,
3290 3290
 				    NULL,
3291
-				    (in_addr_t)0,
3292
-				    (in_addr_t)0);
3291
+                                    NULL,
3292
+                                    NULL,
3293
+                                    NULL,
3294
+                                    NULL);
3293 3295
 	    }
3294 3296
 
3295 3297
 	  /* initial management hold, called early, before first context initialization */
... ...
@@ -2422,8 +2422,10 @@ void
2422 2422
 management_set_state (struct management *man,
2423 2423
 		      const int state,
2424 2424
 		      const char *detail,
2425
-		      const in_addr_t tun_local_ip,
2426
-		      const in_addr_t tun_remote_ip)
2425
+                      const in_addr_t *tun_local_ip,
2426
+                      const struct in6_addr *tun_local_ip6,
2427
+                      const struct openvpn_sockaddr *local,
2428
+                      const struct openvpn_sockaddr *remote)
2427 2429
 {
2428 2430
   if (man->persist.state && (!(man->settings.flags & MF_SERVER) || state < OPENVPN_STATE_CLIENT_BASE))
2429 2431
     {
... ...
@@ -2436,9 +2438,15 @@ management_set_state (struct management *man,
2436 2436
       e.timestamp = now;
2437 2437
       e.u.state = state;
2438 2438
       e.string = detail;
2439
-      e.local_ip = tun_local_ip;
2440
-      e.remote_ip = tun_remote_ip;
2441
-      
2439
+      if (tun_local_ip)
2440
+        e.local_ip = *tun_local_ip;
2441
+      if (tun_local_ip6)
2442
+        e.local_ip6 = *tun_local_ip6;
2443
+      if (local)
2444
+        e.local_sock = *local;
2445
+      if (remote)
2446
+        e.remote_sock = *remote;
2447
+
2442 2448
       log_history_add (man->persist.state, &e);
2443 2449
 
2444 2450
       if (man->connection.state_realtime)
... ...
@@ -3460,7 +3468,14 @@ log_entry_print (const struct log_entry *e, unsigned int flags, struct gc_arena
3460 3460
   if (flags & LOG_PRINT_LOCAL_IP)
3461 3461
     buf_printf (&out, ",%s", print_in_addr_t (e->local_ip, IA_EMPTY_IF_UNDEF, gc));
3462 3462
   if (flags & LOG_PRINT_REMOTE_IP)
3463
-    buf_printf (&out, ",%s", print_in_addr_t (e->remote_ip, IA_EMPTY_IF_UNDEF, gc));
3463
+    {
3464
+      buf_printf (&out, ",%s", (!addr_defined (&e->remote_sock) ? "," :
3465
+        print_sockaddr_ex (&e->remote_sock.addr.sa, ",", PS_DONT_SHOW_FAMILY|PS_SHOW_PORT, gc)));
3466
+      buf_printf (&out, ",%s", (!addr_defined (&e->local_sock) ? "," :
3467
+        print_sockaddr_ex (&e->local_sock.addr.sa, ",", PS_DONT_SHOW_FAMILY|PS_SHOW_PORT, gc)));
3468
+    }
3469
+  if (flags & LOG_PRINT_LOCAL_IP && !IN6_IS_ADDR_UNSPECIFIED(&e->local_ip6))
3470
+    buf_printf (&out, ",%s", print_in6_addr (e->local_ip6, IA_EMPTY_IF_UNDEF, gc));
3464 3471
   if (flags & LOG_ECHO_TO_LOG)
3465 3472
     msg (D_MANAGEMENT, "MANAGEMENT: %s", BSTR (&out));
3466 3473
   if (flags & LOG_PRINT_CRLF)
... ...
@@ -88,7 +88,9 @@ struct log_entry
88 88
   time_t timestamp;
89 89
   const char *string;
90 90
   in_addr_t local_ip;
91
-  in_addr_t remote_ip;
91
+  struct in6_addr local_ip6;
92
+  struct openvpn_sockaddr local_sock;
93
+  struct openvpn_sockaddr remote_sock;
92 94
   union log_entry_union u;
93 95
 };
94 96
 
... ...
@@ -496,8 +498,10 @@ management_enable_def_auth (const struct management *man)
496 496
 void management_set_state (struct management *man,
497 497
 			   const int state,
498 498
 			   const char *detail,
499
-			   const in_addr_t tun_local_ip,
500
-			   const in_addr_t tun_remote_ip);
499
+                           const in_addr_t *tun_local_ip,
500
+                           const struct in6_addr *tun_local_ip6,
501
+                           const struct openvpn_sockaddr *local_addr,
502
+                           const struct openvpn_sockaddr *remote_addr);
501 503
 
502 504
 /*
503 505
  * The management object keeps track of OpenVPN --echo
... ...
@@ -1093,8 +1093,10 @@ add_routes (struct route_list *rl, struct route_ipv6_list *rl6, const struct tun
1093 1093
 	  management_set_state (management,
1094 1094
 				OPENVPN_STATE_ADD_ROUTES,
1095 1095
 				NULL,
1096
-				0,
1097
-				0);
1096
+                                NULL,
1097
+                                NULL,
1098
+                                NULL,
1099
+                                NULL);
1098 1100
 	}
1099 1101
 #endif
1100 1102
 
... ...
@@ -189,8 +189,10 @@ signal_restart_status (const struct signal_info *si)
189 189
 	management_set_state (management,
190 190
 			      state,
191 191
 			      si->signal_text ? si->signal_text : signal_name (si->signal_received, true),
192
-			      (in_addr_t)0,
193
-			      (in_addr_t)0);
192
+                              NULL,
193
+                              NULL,
194
+                              NULL,
195
+                              NULL);
194 196
     }
195 197
 #endif
196 198
 }
... ...
@@ -363,8 +363,10 @@ openvpn_getaddrinfo (unsigned int flags,
363 363
             management_set_state (management,
364 364
                                   OPENVPN_STATE_RESOLVE,
365 365
                                   NULL,
366
-                                  (in_addr_t)0,
367
-                                  (in_addr_t)0);
366
+                                  NULL,
367
+                                  NULL,
368
+                                  NULL,
369
+                                  NULL);
368 370
         }
369 371
 #endif
370 372
 
... ...
@@ -1244,8 +1246,10 @@ socket_connect (socket_descriptor_t* sd,
1244 1244
 	management_set_state (management,
1245 1245
 			      OPENVPN_STATE_TCP_CONNECT,
1246 1246
 			      NULL,
1247
-			      (in_addr_t)0,
1248
-			      (in_addr_t)0);
1247
+                              NULL,
1248
+                              NULL,
1249
+                              NULL,
1250
+                              NULL);
1249 1251
 #endif
1250 1252
 
1251 1253
   /* Set the actual address */
... ...
@@ -2371,17 +2375,22 @@ print_sockaddr_ex (const struct sockaddr *sa,
2371 2371
   switch(sa->sa_family)
2372 2372
     {
2373 2373
     case AF_INET:
2374
-      buf_puts (&out, "[AF_INET]");
2374
+      if (!(flags & PS_DONT_SHOW_FAMILY))
2375
+        buf_puts (&out, "[AF_INET]");
2375 2376
       salen = sizeof (struct sockaddr_in);
2376 2377
       addr_is_defined = ((struct sockaddr_in*) sa)->sin_addr.s_addr != 0;
2377 2378
       break;
2378 2379
     case AF_INET6:
2379
-      buf_puts (&out, "[AF_INET6]");
2380
+      if (!(flags & PS_DONT_SHOW_FAMILY))
2381
+        buf_puts (&out, "[AF_INET6]");
2380 2382
       salen = sizeof (struct sockaddr_in6);
2381 2383
       addr_is_defined = !IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6*) sa)->sin6_addr);
2382 2384
       break;
2383 2385
     case AF_UNSPEC:
2384
-      return "[AF_UNSPEC]";
2386
+      if (!(flags & PS_DONT_SHOW_FAMILY))
2387
+        return "[AF_UNSPEC]";
2388
+      else
2389
+        return "";
2385 2390
     default:
2386 2391
       ASSERT(0);
2387 2392
     }
... ...
@@ -344,6 +344,7 @@ void sd_close (socket_descriptor_t *sd);
344 344
 #define PS_SHOW_PORT            (1<<1)
345 345
 #define PS_SHOW_PKTINFO         (1<<2)
346 346
 #define PS_DONT_SHOW_ADDR       (1<<3)
347
+#define PS_DONT_SHOW_FAMILY     (1<<4)
347 348
 
348 349
 const char *print_sockaddr_ex (const struct sockaddr *addr,
349 350
 			       const char* separator,
... ...
@@ -2307,8 +2307,10 @@ tls_process (struct tls_multi *multi,
2307 2307
 		      management_set_state (management,
2308 2308
 					    OPENVPN_STATE_WAIT,
2309 2309
 					    NULL,
2310
-					    0,
2311
-					    0);
2310
+                                            NULL,
2311
+                                            NULL,
2312
+                                            NULL,
2313
+                                            NULL);
2312 2314
 		    }
2313 2315
 #endif
2314 2316
 		}
... ...
@@ -3016,8 +3018,10 @@ tls_pre_decrypt (struct tls_multi *multi,
3016 3016
 		      management_set_state (management,
3017 3017
 					    OPENVPN_STATE_AUTH,
3018 3018
 					    NULL,
3019
-					    0,
3020
-					    0);
3019
+                                            NULL,
3020
+                                            NULL,
3021
+                                            NULL,
3022
+                                            NULL);
3021 3023
 		    }
3022 3024
 #endif
3023 3025
 
... ...
@@ -711,8 +711,10 @@ do_ifconfig (struct tuntap *tt,
711 711
       management_set_state (management,
712 712
 			    OPENVPN_STATE_ASSIGN_IP,
713 713
 			    NULL,
714
-			    tt->local,
715
-			    0);
714
+                            &tt->local,
715
+                            &tt->local_ipv6,
716
+                            NULL,
717
+                            NULL);
716 718
     }
717 719
 #endif
718 720