1175061Sobrien/*- 2139463Srwatson * Copyright (c) 2004, Robert N. M. Watson 311848Sjulian * Copyright (c) 1983, 1988, 1993 411848Sjulian * The Regents of the University of California. All rights reserved. 511848Sjulian * 611848Sjulian * Redistribution and use in source and binary forms, with or without 711848Sjulian * modification, are permitted provided that the following conditions 811848Sjulian * are met: 911848Sjulian * 1. Redistributions of source code must retain the above copyright 1011848Sjulian * notice, this list of conditions and the following disclaimer. 1111848Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1211848Sjulian * notice, this list of conditions and the following disclaimer in the 1311848Sjulian * documentation and/or other materials provided with the distribution. 1411848Sjulian * 3. All advertising materials mentioning features or use of this software 1511848Sjulian * must display the following acknowledgement: 1611848Sjulian * This product includes software developed by the University of 1711848Sjulian * California, Berkeley and its contributors. 1811848Sjulian * 4. Neither the name of the University nor the names of its contributors 1911848Sjulian * may be used to endorse or promote products derived from this software 2011848Sjulian * without specific prior written permission. 2111848Sjulian * 2211848Sjulian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2311848Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2411848Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2511848Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2611848Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2711848Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2811848Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2911848Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3011848Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3111848Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3211848Sjulian * SUCH DAMAGE. 3311848Sjulian */ 3411848Sjulian 35132671Scharnier#if 0 3611848Sjulian#ifndef lint 3711848Sjulianstatic char sccsid[] = "@(#)ns.c 8.1 (Berkeley) 6/6/93"; 3811848Sjulian#endif /* not lint */ 39132671Scharnier#endif 4011848Sjulian 41132671Scharnier#include <sys/cdefs.h> 42132671Scharnier__FBSDID("$FreeBSD$"); 43132671Scharnier 4411848Sjulian#include <sys/param.h> 4514543Sdg#include <sys/queue.h> 4611848Sjulian#include <sys/socket.h> 4711848Sjulian#include <sys/socketvar.h> 4811848Sjulian#include <sys/protosw.h> 4911848Sjulian 5011848Sjulian#include <net/route.h> 5111848Sjulian 52175061Sobrien#define TCPSTATES 5311848Sjulian#include <netinet/tcp_fsm.h> 5411848Sjulian 5511848Sjulian#include <netipx/ipx.h> 5611848Sjulian#include <netipx/ipx_pcb.h> 5711848Sjulian#include <netipx/ipx_var.h> 5825654Sjhay#ifdef IPXERRORMSGS 5911848Sjulian#include <netipx/ipx_error.h> 6025654Sjhay#endif 6111848Sjulian#include <netipx/spx.h> 6211848Sjulian#include <netipx/spx_timer.h> 6311848Sjulian#include <netipx/spx_var.h> 64175061Sobrien#define SANAMES 6511848Sjulian#include <netipx/spx_debug.h> 6611848Sjulian 67200462Sdelphij#include <nlist.h> 68200462Sdelphij#include <errno.h> 69160787Syar#include <stdint.h> 7011848Sjulian#include <stdio.h> 7111848Sjulian#include <string.h> 7211848Sjulian#include "netstat.h" 7311848Sjulian 74175061Sobrienstatic char *ipx_prpr(struct ipx_addr *); 7511848Sjulian 7611848Sjulian/* 7711848Sjulian * Print a summary of connections related to a Network Systems 7811848Sjulian * protocol. For SPX, also give state of connection. 7911848Sjulian * Listening processes (aflag) are suppressed unless the 8011848Sjulian * -a (all) flag is specified. 8111848Sjulian */ 8211848Sjulian 8311848Sjulianvoid 84171465Sjhbipxprotopr(u_long off, const char *name, int af1 __unused, int proto __unused) 8511848Sjulian{ 86139480Srwatson struct ipxpcbhead cb; 87139594Srwatson struct ipxpcb *ipxp; 88139480Srwatson struct ipxpcb ipxpcb; 89139480Srwatson struct spxpcb spxpcb; 90139480Srwatson struct socket sockb; 91139480Srwatson static int first = 1; 9211848Sjulian int isspx; 9311848Sjulian 9411848Sjulian if (off == 0) 9511848Sjulian return; 96139463Srwatson 9711848Sjulian isspx = strcmp(name, "spx") == 0; 98139480Srwatson kread(off, (char *)&cb, sizeof (struct ipxpcbhead)); 99139594Srwatson ipxp = LIST_FIRST(&cb); 100139594Srwatson while (ipxp != NULL) { 10111848Sjulian u_long ppcb; 10211848Sjulian 103139594Srwatson kread((u_long)ipxp, (char *)&ipxpcb, sizeof (ipxpcb)); 104139594Srwatson ipxp = LIST_NEXT(&ipxpcb, ipxp_list); 105139480Srwatson 10611848Sjulian if (!aflag && ipx_nullhost(ipxpcb.ipxp_faddr) ) { 10711848Sjulian continue; 10811848Sjulian } 10911848Sjulian kread((u_long)ipxpcb.ipxp_socket, 11011848Sjulian (char *)&sockb, sizeof (sockb)); 11111848Sjulian ppcb = (u_long) ipxpcb.ipxp_pcb; 11211848Sjulian if (ppcb) { 11311848Sjulian if (isspx) { 11411848Sjulian kread(ppcb, (char *)&spxpcb, sizeof (spxpcb)); 11511848Sjulian } else continue; 11611848Sjulian } else 11711848Sjulian if (isspx) continue; 11811848Sjulian if (first) { 11911848Sjulian printf("Active IPX connections"); 12011848Sjulian if (aflag) 12111848Sjulian printf(" (including servers)"); 12211848Sjulian putchar('\n'); 12311848Sjulian if (Aflag) 12411848Sjulian printf("%-8.8s ", "PCB"); 12511848Sjulian printf(Aflag ? 12611848Sjulian "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" : 12711848Sjulian "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", 12811848Sjulian "Proto", "Recv-Q", "Send-Q", 12911848Sjulian "Local Address", "Foreign Address", "(state)"); 13011848Sjulian first = 0; 13111848Sjulian } 13211848Sjulian if (Aflag) 13316080Salex printf("%8lx ", ppcb); 134100591Sjdp printf("%-5.5s %6u %6u ", name, sockb.so_rcv.sb_cc, 13511848Sjulian sockb.so_snd.sb_cc); 13611848Sjulian printf(Aflag?" %-18.18s":" %-22.22s", ipx_prpr(&ipxpcb.ipxp_laddr)); 13711848Sjulian printf(Aflag?" %-18.18s":" %-22.22s", ipx_prpr(&ipxpcb.ipxp_faddr)); 13811848Sjulian if (isspx) { 13911848Sjulian if (spxpcb.s_state >= TCP_NSTATES) 14011848Sjulian printf(" %d", spxpcb.s_state); 14111848Sjulian else 14211848Sjulian printf(" %s", tcpstates[spxpcb.s_state]); 14311848Sjulian } 14411848Sjulian putchar('\n'); 14511848Sjulian } 14611848Sjulian} 14711848Sjulian 148175061Sobrien#define ANY(x,y,z) \ 14952376Sbp if (x || sflag <= 1) printf("\t%u %s%s%s\n", x, y, plural(x), z) 150175061Sobrien#define ANYl(x,y,z) \ 15152376Sbp if (x || sflag <= 1) printf("\t%lu %s%s%s\n", x, y, plural(x), z) 15225654Sjhay 15311848Sjulian/* 15411848Sjulian * Dump SPX statistics structure. 15511848Sjulian */ 15611848Sjulianvoid 157171465Sjhbspx_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 15811848Sjulian{ 15911848Sjulian struct spx_istat spx_istat; 160175061Sobrien#define spxstat spx_istat.newstats 16111848Sjulian 16211848Sjulian if (off == 0) 16311848Sjulian return; 16411848Sjulian kread(off, (char *)&spx_istat, sizeof (spx_istat)); 16511848Sjulian printf("%s:\n", name); 16611848Sjulian ANY(spx_istat.nonucn, "connection", " dropped due to no new sockets "); 16711848Sjulian ANY(spx_istat.gonawy, "connection", " terminated due to our end dying"); 16811848Sjulian ANY(spx_istat.nonucn, "connection", 16911848Sjulian " dropped due to inability to connect"); 17011848Sjulian ANY(spx_istat.noconn, "connection", 17111848Sjulian " dropped due to inability to connect"); 17211848Sjulian ANY(spx_istat.notme, "connection", 17311848Sjulian " incompleted due to mismatched id's"); 17411848Sjulian ANY(spx_istat.wrncon, "connection", " dropped due to mismatched id's"); 17511848Sjulian ANY(spx_istat.bdreas, "packet", " dropped out of sequence"); 17611848Sjulian ANY(spx_istat.lstdup, "packet", " duplicating the highest packet"); 17711848Sjulian ANY(spx_istat.notyet, "packet", " refused as exceeding allocation"); 17837453Sbde ANYl(spxstat.spxs_connattempt, "connection", " initiated"); 17937453Sbde ANYl(spxstat.spxs_accepts, "connection", " accepted"); 18037453Sbde ANYl(spxstat.spxs_connects, "connection", " established"); 18137453Sbde ANYl(spxstat.spxs_drops, "connection", " dropped"); 18237453Sbde ANYl(spxstat.spxs_conndrops, "embryonic connection", " dropped"); 18337453Sbde ANYl(spxstat.spxs_closed, "connection", " closed (includes drops)"); 18437453Sbde ANYl(spxstat.spxs_segstimed, "packet", " where we tried to get rtt"); 18537453Sbde ANYl(spxstat.spxs_rttupdated, "time", " we got rtt"); 18637453Sbde ANYl(spxstat.spxs_delack, "delayed ack", " sent"); 18737453Sbde ANYl(spxstat.spxs_timeoutdrop, "connection", 18837453Sbde " dropped in rxmt timeout"); 18937453Sbde ANYl(spxstat.spxs_rexmttimeo, "retransmit timeout", ""); 19037453Sbde ANYl(spxstat.spxs_persisttimeo, "persist timeout", ""); 19137453Sbde ANYl(spxstat.spxs_keeptimeo, "keepalive timeout", ""); 19237453Sbde ANYl(spxstat.spxs_keepprobe, "keepalive probe", " sent"); 19337453Sbde ANYl(spxstat.spxs_keepdrops, "connection", " dropped in keepalive"); 19437453Sbde ANYl(spxstat.spxs_sndtotal, "total packet", " sent"); 19537453Sbde ANYl(spxstat.spxs_sndpack, "data packet", " sent"); 19637453Sbde ANYl(spxstat.spxs_sndbyte, "data byte", " sent"); 19737453Sbde ANYl(spxstat.spxs_sndrexmitpack, "data packet", " retransmitted"); 19837453Sbde ANYl(spxstat.spxs_sndrexmitbyte, "data byte", " retransmitted"); 19937453Sbde ANYl(spxstat.spxs_sndacks, "ack-only packet", " sent"); 20037453Sbde ANYl(spxstat.spxs_sndprobe, "window probe", " sent"); 20137453Sbde ANYl(spxstat.spxs_sndurg, "packet", " sent with URG only"); 20237453Sbde ANYl(spxstat.spxs_sndwinup, "window update-only packet", " sent"); 20337453Sbde ANYl(spxstat.spxs_sndctrl, "control (SYN|FIN|RST) packet", " sent"); 204228992Suqs ANYl(spxstat.spxs_sndvoid, "request", " to send a non-existent packet"); 20537453Sbde ANYl(spxstat.spxs_rcvtotal, "total packet", " received"); 20637453Sbde ANYl(spxstat.spxs_rcvpack, "packet", " received in sequence"); 20737453Sbde ANYl(spxstat.spxs_rcvbyte, "byte", " received in sequence"); 20837453Sbde ANYl(spxstat.spxs_rcvbadsum, "packet", " received with ccksum errs"); 20937453Sbde ANYl(spxstat.spxs_rcvbadoff, "packet", " received with bad offset"); 21037453Sbde ANYl(spxstat.spxs_rcvshort, "packet", " received too short"); 21137453Sbde ANYl(spxstat.spxs_rcvduppack, "duplicate-only packet", " received"); 21237453Sbde ANYl(spxstat.spxs_rcvdupbyte, "duplicate-only byte", " received"); 21337453Sbde ANYl(spxstat.spxs_rcvpartduppack, "packet", 21437453Sbde " with some duplicate data"); 21537453Sbde ANYl(spxstat.spxs_rcvpartdupbyte, "dup. byte", " in part-dup. packet"); 21637453Sbde ANYl(spxstat.spxs_rcvoopack, "out-of-order packet", " received"); 21737453Sbde ANYl(spxstat.spxs_rcvoobyte, "out-of-order byte", " received"); 21837453Sbde ANYl(spxstat.spxs_rcvpackafterwin, "packet", " with data after window"); 21937453Sbde ANYl(spxstat.spxs_rcvbyteafterwin, "byte", " rcvd after window"); 22037453Sbde ANYl(spxstat.spxs_rcvafterclose, "packet", " rcvd after 'close'"); 22137453Sbde ANYl(spxstat.spxs_rcvwinprobe, "rcvd window probe packet", ""); 22237453Sbde ANYl(spxstat.spxs_rcvdupack, "rcvd duplicate ack", ""); 22337453Sbde ANYl(spxstat.spxs_rcvacktoomuch, "rcvd ack", " for unsent data"); 22437453Sbde ANYl(spxstat.spxs_rcvackpack, "rcvd ack packet", ""); 22537453Sbde ANYl(spxstat.spxs_rcvackbyte, "byte", " acked by rcvd acks"); 22637453Sbde ANYl(spxstat.spxs_rcvwinupd, "rcvd window update packet", ""); 22711848Sjulian} 22825654Sjhay 22911848Sjulian/* 23011848Sjulian * Dump IPX statistics structure. 23111848Sjulian */ 23211848Sjulianvoid 233171465Sjhbipx_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 23411848Sjulian{ 23511848Sjulian struct ipxstat ipxstat; 23611848Sjulian 23711848Sjulian if (off == 0) 23811848Sjulian return; 23911848Sjulian kread(off, (char *)&ipxstat, sizeof (ipxstat)); 24011848Sjulian printf("%s:\n", name); 24137453Sbde ANYl(ipxstat.ipxs_total, "total packet", " received"); 24237453Sbde ANYl(ipxstat.ipxs_badsum, "packet", " with bad checksums"); 24337453Sbde ANYl(ipxstat.ipxs_tooshort, "packet", " smaller than advertised"); 24437453Sbde ANYl(ipxstat.ipxs_toosmall, "packet", " smaller than a header"); 24537453Sbde ANYl(ipxstat.ipxs_forward, "packet", " forwarded"); 24637453Sbde ANYl(ipxstat.ipxs_cantforward, "packet", " not forwardable"); 24737453Sbde ANYl(ipxstat.ipxs_delivered, "packet", " for this host"); 24837453Sbde ANYl(ipxstat.ipxs_localout, "packet", " sent from this host"); 24937453Sbde ANYl(ipxstat.ipxs_odropped, "packet", " dropped due to no bufs, etc."); 25037453Sbde ANYl(ipxstat.ipxs_noroute, "packet", " discarded due to no route"); 25137453Sbde ANYl(ipxstat.ipxs_mtutoosmall, "packet", " too big"); 25211848Sjulian} 25311848Sjulian 25452415Sjulian#ifdef IPXERRORMSGS 25511848Sjulianstatic struct { 25611848Sjulian u_short code; 25711848Sjulian char *name; 25811848Sjulian char *where; 25911848Sjulian} ipx_errnames[] = { 26011848Sjulian {0, "Unspecified Error", " at Destination"}, 26111848Sjulian {1, "Bad Checksum", " at Destination"}, 26211848Sjulian {2, "No Listener", " at Socket"}, 26311848Sjulian {3, "Packet", " Refused due to lack of space at Destination"}, 26411848Sjulian {01000, "Unspecified Error", " while gatewayed"}, 26511848Sjulian {01001, "Bad Checksum", " while gatewayed"}, 26611848Sjulian {01002, "Packet", " forwarded too many times"}, 26711848Sjulian {01003, "Packet", " too large to be forwarded"}, 26811848Sjulian {-1, 0, 0}, 26911848Sjulian}; 27011848Sjulian 27111848Sjulian/* 27211848Sjulian * Dump IPX Error statistics structure. 27311848Sjulian */ 27411848Sjulian/*ARGSUSED*/ 27511848Sjulianvoid 276171465Sjhbipxerr_stats(u_long off, const char *name, int af __unused, int proto __unused) 27711848Sjulian{ 27811848Sjulian struct ipx_errstat ipx_errstat; 279102975Sdwmalone int j; 280102975Sdwmalone int histoprint = 1; 28111848Sjulian int z; 28211848Sjulian 28311848Sjulian if (off == 0) 28411848Sjulian return; 28511848Sjulian kread(off, (char *)&ipx_errstat, sizeof (ipx_errstat)); 28611848Sjulian printf("IPX error statistics:\n"); 28711848Sjulian ANY(ipx_errstat.ipx_es_error, "call", " to ipx_error"); 28811848Sjulian ANY(ipx_errstat.ipx_es_oldshort, "error", 28911848Sjulian " ignored due to insufficient addressing"); 29011848Sjulian ANY(ipx_errstat.ipx_es_oldipx_err, "error request", 29111848Sjulian " in response to error packets"); 29211848Sjulian ANY(ipx_errstat.ipx_es_tooshort, "error packet", 29311848Sjulian " received incomplete"); 29411848Sjulian ANY(ipx_errstat.ipx_es_badcode, "error packet", 29511848Sjulian " received of unknown type"); 29611848Sjulian for(j = 0; j < IPX_ERR_MAX; j ++) { 29711848Sjulian z = ipx_errstat.ipx_es_outhist[j]; 29811848Sjulian if (z && histoprint) { 29911848Sjulian printf("Output Error Histogram:\n"); 30011848Sjulian histoprint = 0; 30111848Sjulian } 30211848Sjulian ipx_erputil(z, ipx_errstat.ipx_es_codes[j]); 30311848Sjulian } 30411848Sjulian histoprint = 1; 30511848Sjulian for(j = 0; j < IPX_ERR_MAX; j ++) { 30611848Sjulian z = ipx_errstat.ipx_es_inhist[j]; 30711848Sjulian if (z && histoprint) { 30811848Sjulian printf("Input Error Histogram:\n"); 30911848Sjulian histoprint = 0; 31011848Sjulian } 31111848Sjulian ipx_erputil(z, ipx_errstat.ipx_es_codes[j]); 31211848Sjulian } 31311848Sjulian} 31411848Sjulian 31511848Sjulianstatic void 31678314Sassaripx_erputil(int z, int c) 31711848Sjulian{ 31811848Sjulian int j; 31911848Sjulian char codebuf[30]; 32011848Sjulian char *name, *where; 32111848Sjulian 32211848Sjulian for(j = 0;; j ++) { 32311848Sjulian if ((name = ipx_errnames[j].name) == 0) 32411848Sjulian break; 32511848Sjulian if (ipx_errnames[j].code == c) 32611848Sjulian break; 32711848Sjulian } 32811848Sjulian if (name == 0) { 32911848Sjulian if (c > 01000) 33011848Sjulian where = "in transit"; 33111848Sjulian else 33211848Sjulian where = "at destination"; 33311848Sjulian sprintf(codebuf, "Unknown IPX error code 0%o", c); 33411848Sjulian name = codebuf; 33511848Sjulian } else 33611848Sjulian where = ipx_errnames[j].where; 33711848Sjulian ANY(z, name, where); 33811848Sjulian} 33925654Sjhay#endif /* IPXERRORMSGS */ 34011848Sjulian 341160789Syarstatic struct sockaddr_ipx ssipx = { .sipx_family = AF_IPX }; 34211848Sjulian 34311848Sjulianstatic 34478314Sassarchar *ipx_prpr(struct ipx_addr *x) 34511848Sjulian{ 34611848Sjulian struct sockaddr_ipx *sipx = &ssipx; 34711848Sjulian 34811848Sjulian sipx->sipx_addr = *x; 34911848Sjulian return(ipx_print((struct sockaddr *)sipx)); 35011848Sjulian} 351