--- embedaddon/mpd/src/ngfunc.c	2012/02/21 23:32:47	1.1
+++ embedaddon/mpd/src/ngfunc.c	2021/03/17 00:39:23	1.1.1.4
@@ -44,8 +44,8 @@
 #endif
 #ifdef USE_NG_NETFLOW
 #include <netgraph/netflow/ng_netflow.h>
-#if NGM_NETFLOW_COOKIE >= 1309868867
 #include <netgraph/netflow/netflow.h>
+#if NGM_NETFLOW_COOKIE >= 1309868867
 #include <netgraph/netflow/netflow_v9.h>
 #endif
 #endif
@@ -82,7 +82,7 @@
  */
 
 #ifdef USE_NG_NETFLOW
-  static int	NetflowSetCommand(Context ctx, int ac, char *av[], void *arg);
+  static int	NetflowSetCommand(Context ctx, int ac, const char *const av[], const void *arg);
 #endif
 
 /*
@@ -109,7 +109,7 @@
         NetflowSetCommand, NULL, 2, (void *) SET_NODE },
     { "hook {number}", "Set initial hook number" ,
         NetflowSetCommand, NULL, 2, (void *) SET_HOOK },
-    { NULL },
+    { NULL, NULL, NULL, NULL, 0, NULL },
   };
 #endif
 
@@ -131,10 +131,10 @@
   uint32_t gNetflowInactive = 0;
   uint32_t gNetflowActive = 0;
 #if NGM_NETFLOW_COOKIE >= 1309868867
-  uint16_t gNetflowTime = 0;
-  uint16_t gNetflowPackets = 0;
-  uint16_t gNetflowMTU = 0;
-  u_int gNetflowVer = 5;
+  static uint16_t gNetflowTime = 0;
+  static uint16_t gNetflowPackets = 0;
+  static uint16_t gNetflowMTU = 0;
+  static u_int gNetflowVer = 5;
 #endif
 #endif
   
@@ -160,7 +160,10 @@ NgFuncInitGlobalNetflow(void)
     /* If node exist just get it's ID. */
     if (gNetflowNode) {
 	snprintf(path, sizeof(path), "%s:", gNetflowNodeName);
-	gNetflowNodeID = NgGetNodeID(csock, path);
+	if ((gNetflowNodeID = NgGetNodeID(csock, path)) == 0) {
+	    Perror("NETFLOW: Cannot get %s node id", NG_NETFLOW_NODE_TYPE);
+	    goto fail;
+	}
 	close(csock);
 	return (0);
     }
@@ -179,7 +182,10 @@ NgFuncInitGlobalNetflow(void)
     }
     
     /* Get new node ID. */
-    gNetflowNodeID = NgGetNodeID(csock, TEMPHOOK);
+    if ((gNetflowNodeID = NgGetNodeID(csock, TEMPHOOK)) == 0) {
+	Perror("NETFLOW: Cannot get %s node id", NG_NETFLOW_NODE_TYPE);
+	goto fail;
+    }
 
     /* Set the new node's name. */
     strcpy(nm.name, gNetflowNodeName);
@@ -460,8 +466,10 @@ NgFuncSendQuery(const char *path, int cookie, int cmd,
     }
 
     /* Send message */
-    if (NgSendMsg(gNgStatSock, path, cookie, cmd, args, arglen) < 0)
+    if (NgSendMsg(gNgStatSock, path, cookie, cmd, args, arglen) < 0) {
+	Perror("NgFuncSendQuery: can't send message");
 	return (-1);
+    }
 
     /* Read message */
     if (NgRecvMsg(gNgStatSock, rbuf, replen, raddr) < 0) {
@@ -627,7 +635,7 @@ NgFuncWriteFrame(int dsock, const char *hookname, cons
     /* ENOBUFS can be expected on some links, e.g., ng_pptpgre(4) */
     if (rtn < 0 && errno != ENOBUFS) {
 	Perror("[%s] error writing len %d frame to %s",
-	    label, MBLEN(bp), hookname);
+	    label, (int)MBLEN(bp), hookname);
     }
     mbfree(bp);
     return (rtn);
@@ -654,6 +662,8 @@ NgFuncClrStats(Bund b, u_int16_t linkNum)
     return(0);
 }
 
+#ifndef NG_PPP_STATS64
+
 /*
  * NgFuncGetStats()
  *
@@ -682,7 +692,7 @@ NgFuncGetStats(Bund b, u_int16_t linkNum, struct ng_pp
     return(0);
 }
 
-#ifdef NG_PPP_STATS64
+#else
 /*
  * NgFuncGetStats64()
  *
@@ -750,7 +760,7 @@ NgFuncErr(const char *fmt, ...)
  */
        
 static int
-NetflowSetCommand(Context ctx, int ac, char *av[], void *arg)
+NetflowSetCommand(Context ctx, int ac, const char *const av[], const void *arg)
 {
     struct sockaddr_storage *sin;
 
@@ -763,6 +773,8 @@ NetflowSetCommand(Context ctx, int ac, char *av[], voi
     	    gNetflowExport = *sin;
     	    break;
 	case SET_SELF:
+	    if (ac != 1 && ac != 2)
+		return (-1);
     	    if ((sin = ParseAddrPort(ac, av, ALLOW_IPV4|ALLOW_IPV6)) == NULL)
 		return (-1);
     	    gNetflowSource = *sin;
@@ -791,7 +803,7 @@ NetflowSetCommand(Context ctx, int ac, char *av[], voi
 	case SET_MTU:
     	    if (ac != 1)
 		return (-1);
-    	    if (atoi(av[0]) < MIN_MTU || atoi(av[0]) > MAX_MTU)
+    	    if (atoi(av[0]) < (int)MIN_MTU || atoi(av[0]) > (int)MAX_MTU)
 		Error("Bad netflow v9 MTU \"%s\"", av[0]);
     	    gNetflowMTU = atoi(av[0]);		/* Default 1500 */
     	    break;
@@ -815,7 +827,7 @@ NetflowSetCommand(Context ctx, int ac, char *av[], voi
 	case SET_HOOK:
     	    if (ac != 1)
 		return (-1);
-    	    if (atoi(av[0]) <= 0)
+    	    if (atoi(av[0]) <= 0 || atoi(av[0]) >= NG_NETFLOW_MAXIFACES)
 		Error("Bad netflow hook number \"%s\"", av[0]);
     	    gNetflowIface = atoi(av[0])-1;
     	    break;
@@ -826,6 +838,140 @@ NetflowSetCommand(Context ctx, int ac, char *av[], voi
 
     return (0);
 }
+
+/*
+ * ShowNetflow()
+ *
+ * Show state of a Netflow
+ */
+
+int
+ShowNetflow(Context ctx, int ac, const char *const av[], const void *arg)
+{
+    struct u_addr addr;
+    in_port_t port;
+    char buf[64];
+    char path[NG_PATHSIZ];
+    union {
+        u_char buf[sizeof(struct ng_mesg) + sizeof(struct ng_netflow_info)];
+        struct ng_mesg reply;
+    } u;
+    struct ng_netflow_info *const ni = \
+        (struct ng_netflow_info *)(void *)u.reply.data;
+#ifdef NGM_NETFLOW_V9_COOKIE
+    union {
+        u_char buf[sizeof(struct ng_mesg) + sizeof(struct ng_netflow_v9info)];
+        struct ng_mesg reply;
+    } uv9;
+    struct ng_netflow_v9info *const niv9 = \
+        (struct ng_netflow_v9info *)(void *)uv9.reply.data;
+#endif /* NGM_NETFLOW_V9_COOKIE */
+
+    (void)ac;
+    (void)av;
+    (void)arg;
+
+    if (gNetflowNodeID>0) {
+        snprintf(path, sizeof(path), "[%x]:", gNetflowNodeID);
+        if (NgFuncSendQuery(path, NGM_NETFLOW_COOKIE, NGM_NETFLOW_INFO,
+        NULL, 0, &u.reply, sizeof(u), NULL) < 0)
+            return(-7);
+#ifdef NGM_NETFLOW_V9_COOKIE
+        if (NgFuncSendQuery(path, NGM_NETFLOW_COOKIE, NGM_NETFLOW_V9INFO,
+        NULL, 0, &uv9.reply, sizeof(uv9), NULL) < 0)
+            return(-7);
+#endif /* NGM_NETFLOW_V9_COOKIE */
+    }
+
+    Printf("Netflow status:\r\n");
+    Printf("\tNode created   : %s\r\n", gNetflowNodeID ? "Yes" : "No");
+    Printf("Netflow settings:\r\n");
+    Printf("\tNode name      : %s\r\n", gNetflowNodeName);
+    Printf("\tInitial hook   : %d\r\n", gNetflowIface);
+    Printf("\tTimeouts, sec:\r\n");
+    Printf("\t  Active       : %u\r\n",
+        (gNetflowNodeID>0) ? ni->nfinfo_act_t :
+        (gNetflowActive ? gNetflowActive : ACTIVE_TIMEOUT));
+    Printf("\t  Inactive     : %u\r\n",
+        (gNetflowNodeID>0) ? ni->nfinfo_inact_t :
+        (gNetflowInactive ? gNetflowInactive : INACTIVE_TIMEOUT));
+    sockaddrtou_addr(&gNetflowExport, &addr, &port);
+    Printf("\tExport address : %s port %d\r\n",
+        u_addrtoa(&addr, buf, sizeof(buf)), (int)port);
+    sockaddrtou_addr(&gNetflowSource, &addr, &port);
+    Printf("\tSource address : %s port %d\r\n",
+        u_addrtoa(&addr, buf, sizeof(buf)), (int)port);
+#if NGM_NETFLOW_COOKIE >= 1309868867
+    Printf("\tExport version : v%d\r\n", gNetflowVer);
+    Printf("Netflow v9 configuration:\r\n");
+    Printf("\tTemplate:\r\n");
+#ifdef NGM_NETFLOW_V9_COOKIE
+    Printf("\t  Time         : %d\r\n",
+        (gNetflowNodeID>0) ? niv9->templ_time :
+        (gNetflowTime ? gNetflowTime : NETFLOW_V9_MAX_TIME_TEMPL));
+    Printf("\t  Packets      : %d\r\n",
+        (gNetflowNodeID>0) ? niv9->templ_packets :
+        (gNetflowPackets ? gNetflowPackets : NETFLOW_V9_MAX_PACKETS_TEMPL));
+    Printf("\tNetflow v9 MTU : %d\r\n",
+        (gNetflowNodeID>0) ? niv9->mtu :
+        (gNetflowMTU ? gNetflowMTU : BASE_MTU));
+#else
+    Printf("\t  Time         : %d\r\n",
+        gNetflowTime ? gNetflowTime : NETFLOW_V9_MAX_TIME_TEMPL);
+    Printf("\t  Packets      : %d\r\n",
+        gNetflowPackets ? gNetflowPackets : NETFLOW_V9_MAX_PACKETS_TEMPL);
+    Printf("\tNetflow v9 MTU : %d\r\n",
+        gNetflowMTU ? gNetflowMTU : BASE_MTU);
+#endif /* NGM_NETFLOW_V9_COOKIE */
+#endif
+    if (gNetflowNodeID>0) {
+        Printf("Traffic stats:\r\n");
+#if NGM_NETFLOW_COOKIE >= 1365756954
+        Printf("\tAccounted IPv4 octets  : %llu\r\n", (unsigned long long)ni->nfinfo_bytes);
+        Printf("\tAccounted IPv4 packets : %llu\r\n", (unsigned long long)ni->nfinfo_packets);
+        Printf("\tAccounted IPv6 octets  : %llu\r\n", (unsigned long long)ni->nfinfo_bytes6);
+        Printf("\tAccounted IPv6 packets : %llu\r\n", (unsigned long long)ni->nfinfo_packets6);
+        Printf("\tSkipped IPv4 octets    : %llu\r\n", (unsigned long long)ni->nfinfo_sbytes);
+        Printf("\tSkipped IPv4 packets   : %llu\r\n", (unsigned long long)ni->nfinfo_spackets);
+        Printf("\tSkipped IPv6 octets    : %llu\r\n", (unsigned long long)ni->nfinfo_sbytes6);
+        Printf("\tSkipped IPv6 packets   : %llu\r\n", (unsigned long long)ni->nfinfo_spackets6);
+        Printf("\tActive expiries        : %llu\r\n", (unsigned long long)ni->nfinfo_act_exp);
+        Printf("\tInactive expiries      : %llu\r\n", (unsigned long long)ni->nfinfo_inact_exp);
+        Printf("\tUsed IPv4 cache records: %u\r\n", ni->nfinfo_used);
+        Printf("\tUsed IPv6 cache records: %u\r\n", ni->nfinfo_used6);
+        Printf("\tFailed allocations     : %u\r\n", ni->nfinfo_alloc_failed);
+        Printf("\tFailed v5 export       : %u\r\n", ni->nfinfo_export_failed);
+        Printf("\tFailed v9 export       : %u\r\n", ni->nfinfo_export9_failed);
+        Printf("\tRallocated mbufs       : %u\r\n", ni->nfinfo_realloc_mbuf);
+        Printf("\tFibs allocated         : %u\r\n", ni->nfinfo_alloc_fibs);
+#else /* NGM_NETFLOW_COOKIE >= 1365756954 */
+        Printf("\tAccounted IPv4 octets  : %llu\r\n", (unsigned long long)ni->nfinfo_bytes);
+        Printf("\tAccounted IPv4 packets : %u\r\n", ni->nfinfo_packets);
+#if NGM_NETFLOW_COOKIE >= 1309868867
+        Printf("\tAccounted IPv6 octets  : %llu\r\n", (unsigned long long)ni->nfinfo_bytes6);
+        Printf("\tAccounted IPv6 packets : %u\r\n", ni->nfinfo_packets6);
+        Printf("\tSkipped IPv4 octets    : %llu\r\n", (unsigned long long)ni->nfinfo_sbytes);
+        Printf("\tSkipped IPv4 packets   : %u\r\n", ni->nfinfo_spackets);
+        Printf("\tSkipped IPv6 octets    : %llu\r\n", (unsigned long long)ni->nfinfo_sbytes6);
+        Printf("\tSkipped IPv6 packets   : %u\r\n", ni->nfinfo_spackets6);
+#endif
+        Printf("\tUsed IPv4 cache records: %u\r\n", ni->nfinfo_used);
+#if NGM_NETFLOW_COOKIE >= 1309868867
+        Printf("\tUsed IPv6 cache records: %u\r\n", ni->nfinfo_used6);
+#endif
+        Printf("\tFailed allocations     : %u\r\n", ni->nfinfo_alloc_failed);
+        Printf("\tFailed v5 export       : %u\r\n", ni->nfinfo_export_failed);
+#if NGM_NETFLOW_COOKIE >= 1309868867
+        Printf("\tFailed v9 export       : %u\r\n", ni->nfinfo_export9_failed);
+        Printf("\tRallocated mbufs       : %u\r\n", ni->nfinfo_realloc_mbuf);
+        Printf("\tFibs allocated         : %u\r\n", ni->nfinfo_alloc_fibs);
+#endif
+        Printf("\tActive expiries        : %u\r\n", ni->nfinfo_act_exp);
+        Printf("\tInactive expiries      : %u\r\n", ni->nfinfo_inact_exp);
+#endif /* NGM_NETFLOW_COOKIE >= 1365756954 */
+    }
+    return(0);
+}
 #endif /* USE_NG_NETFLOW */
 
 ng_ID_t
@@ -844,8 +990,9 @@ NgGetNodeID(int csock, const char *path)
 	    /* Create a netgraph socket node */
 	    snprintf(name, sizeof(name), "mpd%d-stats", gPid);
 	    if (NgMkSockNode(name, &gNgStatSock, NULL) < 0) {
-    		Perror("NgFuncSendQuery: can't create %s node", NG_SOCKET_NODE_TYPE);
-    		return(-1);
+    		Perror("NgMkSockNode: can't create %s node",
+    		     NG_SOCKET_NODE_TYPE);
+    		return (0);
 	    }
 	    (void) fcntl(gNgStatSock, F_SETFD, 1);
 	}
@@ -853,11 +1000,15 @@ NgGetNodeID(int csock, const char *path)
     }
 
     if (NgSendMsg(csock, path,
-      NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0)
-        return (0);
-    if (NgRecvMsg(csock, &u.reply, sizeof(u), NULL) < 0)
+      NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0) {
+	Perror("NgSendMsg to %s", path);
 	return (0);
-    
+    }
+    if (NgRecvMsg(csock, &u.reply, sizeof(u), NULL) < 0) {
+	Perror("NgRecvMsg from %s", path);
+	return (0);
+    }
+
     return (ni->id);
 }