--- netstat.c.ms	2009-09-14 10:47:30.000000000 +0200
+++ netstat.c	2009-09-14 10:47:37.000000000 +0200
@@ -105,6 +105,8 @@
 /* prototypes for statistics.c */
 void parsesnmp(int, int, int, int);
 void inittab(void);
+void parsesnmp6(int, int, int, int);
+void inittab6(void);
 
 typedef enum {
     SS_FREE = 0,		/* not allocated                */
@@ -2183,9 +2185,28 @@
     }
 
     if (flag_sta) {
-        inittab();
-	parsesnmp(flag_raw, flag_tcp, flag_udp, flag_sctp);
-	exit(0);
+		char *tmp1, *tmp2;
+		char buf[256];
+		if (!afname[0]) {
+			inittab();
+			parsesnmp(flag_raw, flag_tcp, flag_udp, flag_sctp);
+		} else {
+			safe_strncpy(buf, afname, sizeof(buf));
+			tmp1 = buf;
+			if ((tmp2 = index(tmp1, ','))) {
+				printf("Multiple interface\n");
+			} else if(!strncmp(buf,"inet6",5)) {
+#if HAVE_AFINET6
+				inittab6();
+				parsesnmp6(flag_raw, flag_tcp, flag_udp, flag_sctp);
+#else
+				printf("Address type not supported for stats\n");
+#endif
+			} else {
+				printf("Address type not supported for stats\n");
+			}
+		}
+		exit(1);
     }
     
     if (flag_rou) {
--- statistics.c.ms	2009-09-14 10:47:18.000000000 +0200
+++ statistics.c	2009-09-14 10:49:26.000000000 +0200
@@ -83,6 +83,32 @@
     {"FragCreates", N_("%lu fragments created"), opt_number}
 };
 
+struct entry Ip6tab[] =
+{
+    {"Ip6InReceives", N_("%u total packets received"), number},
+    {"Ip6InHdrErrors", N_("%u with invalid headers"), opt_number},
+    {"Ip6InTooBigErrors", N_("%u with packets too big"), opt_number},
+    {"Ip6InNoRoutes", N_("%u incoming packets with no route"), opt_number},
+    {"Ip6InAddrErrors", N_("%u with invalid addresses"), opt_number},
+    {"Ip6InUnknownProtos", N_("%u with unknown protocol"), opt_number},
+    {"Ip6InTruncatedPkts", N_("%u with truncated packets"), opt_number},
+    {"Ip6InDiscards", N_("%u incoming packets discarded"), number},
+    {"Ip6InDelivers", N_("%u incoming packets delivered"), number},
+    {"Ip6OutForwDatagrams", N_("%u forwarded"), number},
+    {"Ip6OutRequests", N_("%u requests sent out"), number},     /*? */
+    {"Ip6OutDiscards", N_("%u outgoing packets dropped"), opt_number},
+    {"Ip6OutNoRoutes", N_("%u dropped because of missing route"), opt_number},
+    {"Ip6ReasmTimeout", N_("%u fragments dropped after timeout"), opt_number},
+    {"Ip6ReasmReqds", N_("%u reassemblies required"), opt_number}, /* ? */
+    {"Ip6ReasmOKs", N_("%u packets reassembled ok"), opt_number},
+    {"Ip6ReasmFails", N_("%u packet reassembles failed"), opt_number},
+    {"Ip6FragOKs", N_("%u fragments received ok"), opt_number},
+    {"Ip6FragFails", N_("%u fragments failed"), opt_number},
+    {"Ip6FragCreates", N_("%u fragments created"), opt_number},
+    {"Ip6InMcastPkts", N_("%u incoming multicast packets"), opt_number},
+    {"Ip6OutMcastPkts", N_("%u outgoing multicast packets"), opt_number}
+};
+
 struct entry Icmptab[] =
 {
     {"InMsgs", N_("%lu ICMP messages received"), number},
@@ -113,6 +139,41 @@
     {"OutAddrMaskReps", N_("address mask replies: %lu"), i_outp_icmp | I_TITLE},
 };
 
+struct entry Icmp6tab[] =
+{
+    {"Icmp6InMsgs", N_("%u ICMP messages received"), number},
+    {"Icmp6InErrors", N_("%u input ICMP message failed."), number},
+    {"Icmp6InDestUnreachs", N_("destination unreachable: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6InPktTooBigs", N_("packets too big: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6InTimeExcds", N_("received ICMPv6 time exceeded: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6InParmProblems", N_("parameter problem: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6InEchos", N_("echo requests: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6InEchoReplies", N_("echo replies: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6InGroupMembQueries", N_("group member queries: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6InGroupMembResponses", N_("group member responses: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6InGroupMembReductions", N_("group member reductions: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6InRouterSolicits", N_("router solicits: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6InRouterAdvertisements", N_("router advertisement: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6InNeighborSolicits", N_("neighbour solicits: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6InNeighborAdvertisements", N_("neighbour advertisement: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6InRedirects", N_("redirects: %u"), i_inp_icmp | I_TITLE},
+    {"Icmp6OutMsgs", N_("%u ICMP messages sent"), number},
+    {"Icmp6OutDestUnreachs", N_("destination unreachable: %u"), i_outp_icmp | I_TITLE},
+    {"Icmp6OutPktTooBigs", N_("packets too big: %u"), i_outp_icmp | I_TITLE},
+    {"Icmp6OutTimeExcds", N_("sent ICMPv6 time exceeded: %u"), i_outp_icmp | I_TITLE},
+    {"Icmp6OutParmProblems", N_("parameter problem: %u"), i_outp_icmp | I_TITLE},
+    {"Icmp6OutEchos", N_("echo requests: %u"), i_outp_icmp | I_TITLE},
+    {"Icmp6OutEchoReplies", N_("echo replies: %u"), i_outp_icmp | I_TITLE},
+    {"Icmp6OutGroupMembQueries", N_("group member queries: %u"), i_outp_icmp | I_TITLE},
+    {"Icmp6OutGroupMembResponses", N_("group member responses: %u"), i_outp_icmp | I_TITLE},
+    {"Icmp6OutGroupMembReductions", N_("group member reductions: %u"), i_outp_icmp | I_TITLE},
+    {"Icmp6OutRouterSolicits", N_("router solicits: %u"), i_outp_icmp | I_TITLE},
+    {"Icmp6OutRouterAdvertisements ", N_("router advertisement: %u"), i_outp_icmp | I_TITLE},
+    {"Icmp6OutNeighborSolicits", N_("neighbor solicits: %u"), i_outp_icmp | I_TITLE},
+    {"Icmp6OutNeighborAdvertisements", N_("neighbor advertisements: %u"), i_outp_icmp | I_TITLE},
+    {"Icmp6OutRedirects", N_("redirects: %u"), i_outp_icmp | I_TITLE},
+};
+
 struct entry Tcptab[] =
 {
     {"RtoAlgorithm", N_("RTO algorithm is %s"), i_rto_alg | I_STATIC},
@@ -139,6 +200,14 @@
     {"OutDatagrams", N_("%lu packets sent"), number},
 };
 
+struct entry Udp6tab[] =
+{
+    {"Udp6InDatagrams", N_("%u packets received"), number},
+    {"Udp6NoPorts", N_("%u packets to unknown port received."), number},
+    {"Udp6InErrors", N_("%u packet receive errors"), number},
+    {"Udp6OutDatagrams", N_("%u packets sent"), number},
+};
+
 struct entry Tcpexttab[] =
 {
     {"SyncookiesSent", N_("%lu SYN cookies sent"), opt_number},
@@ -226,6 +295,15 @@
     {NULL}
 };
 
+struct tabtab snmp6tabs[] =
+{
+    {"Ip6", Ip6tab, sizeof(Ip6tab), &f_raw},
+    {"Icmp6", Icmp6tab, sizeof(Icmp6tab), &f_raw},
+    {"Udp6", Udp6tab, sizeof(Udp6tab), &f_udp},
+    {"Tcp6", Tcptab, sizeof(Tcptab), &f_tcp},
+    {NULL}
+};
+
 /* XXX IGMP */
 
 int cmpentries(const void *a, const void *b)
@@ -311,7 +389,7 @@
 	return &dummytab;
 }
 
-void process_fd(FILE *f)
+void process_fd(FILE *f, int all, char *filter)
 {
     char buf1[8192], buf2[8192];
     char *sp, *np, *p;
@@ -327,6 +405,12 @@
 	    goto formaterr;
 	*sp = '\0';
 
+	if (!all) {
+		if (strncmp(buf1, filter, strlen(filter))) {
+			continue;
+		}
+	}
+
 	tab = newtable(snmptabs, buf1);
 	if (tab == NULL) {
 		printf("unknown %s\n", buf1);
@@ -387,6 +471,40 @@
   return;
 }
 
+void cpytitle(char *original, char *new)
+{
+	char *ptr = original;
+	while(*ptr != '6' && *ptr != '\0') {
+		*new = *ptr;
+		new++;
+		ptr++;
+	}
+	*new = *ptr;
+	new++;
+	*new = '\0';
+}
+
+void process6_fd(FILE *f)
+{
+	char buf1[1024],buf2[50],buf3[1024];
+	unsigned long val;
+	struct tabtab *tab = NULL;
+	int cpflg = 0;
+
+	while (fgets(buf1, sizeof buf1, f)) {
+		sscanf(buf1, "%s %lu", buf2, &val);
+		if(!cpflg) {
+			cpytitle(buf2, buf3);
+			tab = newtable(snmp6tabs, buf3);
+			cpflg = 1;
+		}
+		if(!strstr(buf2, buf3)) {
+			cpytitle(buf2, buf3);
+			tab = newtable(snmp6tabs, buf3);
+		}
+		printval(tab, buf2, val);
+	}
+}
 
 void parsesnmp(int flag_raw, int flag_tcp, int flag_udp, int flag_sctp)
 {
@@ -399,7 +517,7 @@
 	perror(_("cannot open /proc/net/snmp"));
 	return;
     }
-    process_fd(f);
+	process_fd(f, 1, NULL);
 
     if (ferror(f))
 	perror("/proc/net/snmp");
@@ -409,7 +527,7 @@
     f = fopen("/proc/net/netstat", "r");
 
     if (f) {
-    	process_fd(f);
+		process_fd(f, 1, NULL);
 
         if (ferror(f))
 	    perror("/proc/net/netstat");
@@ -429,7 +547,33 @@
 
     return;
 }
-    
+
+void parsesnmp6(int flag_raw, int flag_tcp, int flag_udp, int flag_sctp)
+{
+	FILE *f;
+
+	f_raw = flag_raw; f_tcp = flag_tcp; f_udp = flag_udp, f_sctp = flag_sctp;
+
+	f = fopen("/proc/net/snmp6", "r");
+	if (!f) {
+		perror(_("cannot open /proc/net/snmp6"));
+		return;
+	}
+	process6_fd(f);
+	if (ferror(f))
+		perror("/proc/net/snmp6");
+
+	fclose(f);
+	f = fopen("/proc/net/snmp", "r");
+	if (!f) {
+		perror(_("cannot open /proc/net/snmp"));
+		return;
+	}
+	process_fd(f, 0, "Tcp");
+	if (ferror(f))
+		perror("/proc/net/snmp");
+	fclose(f);
+}
 
 void inittab(void)
 {
@@ -440,3 +584,13 @@
 	qsort(t->tab, t->size / sizeof(struct entry),
 	      sizeof(struct entry), cmpentries);
 }
+
+void inittab6(void)
+{
+	struct tabtab *t;
+
+	for (t = snmp6tabs; t->title; t++)
+		qsort(t->tab, t->size / sizeof(struct entry),
+			sizeof(struct entry), cmpentries);
+}
+
