1175061Sobrien/*- 216178Sjulian * Copyright (c) 1983, 1988, 1993 316178Sjulian * The Regents of the University of California. All rights reserved. 416178Sjulian * 516178Sjulian * Redistribution and use in source and binary forms, with or without 616178Sjulian * modification, are permitted provided that the following conditions 716178Sjulian * are met: 816178Sjulian * 1. Redistributions of source code must retain the above copyright 916178Sjulian * notice, this list of conditions and the following disclaimer. 1016178Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1116178Sjulian * notice, this list of conditions and the following disclaimer in the 1216178Sjulian * documentation and/or other materials provided with the distribution. 1316178Sjulian * 4. Neither the name of the University nor the names of its contributors 1416178Sjulian * may be used to endorse or promote products derived from this software 1516178Sjulian * without specific prior written permission. 1616178Sjulian * 1716178Sjulian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1816178Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1916178Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2016178Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2116178Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2216178Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2316178Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2416178Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2516178Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2616178Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2716178Sjulian * SUCH DAMAGE. 2816178Sjulian */ 2916178Sjulian 30132671Scharnier#if 0 3116178Sjulian#ifndef lint 3216178Sjulianstatic char sccsid[] = "@(#)atalk.c 1.1 (Whistle) 6/6/96"; 3316178Sjulian#endif /* not lint */ 34132671Scharnier#endif 3516178Sjulian 36132671Scharnier#include <sys/cdefs.h> 37132671Scharnier__FBSDID("$FreeBSD$"); 38132671Scharnier 3916178Sjulian#include <sys/param.h> 4016178Sjulian#include <sys/queue.h> 4116178Sjulian#include <sys/socket.h> 4216178Sjulian#include <sys/socketvar.h> 4316178Sjulian#include <sys/protosw.h> 4416178Sjulian 45102975Sdwmalone#include <arpa/inet.h> 4616178Sjulian#include <net/route.h> 4716178Sjulian 4816178Sjulian#include <netatalk/at.h> 4916178Sjulian#include <netatalk/ddp_var.h> 5016178Sjulian 51200462Sdelphij#include <errno.h> 52200462Sdelphij#include <nlist.h> 5378294Simp#include <netdb.h> 54160787Syar#include <stdint.h> 5516178Sjulian#include <stdio.h> 5616178Sjulian#include <string.h> 5716178Sjulian#include "netstat.h" 5816178Sjulian 5916178Sjulianstruct ddpcb ddpcb; 6016178Sjulianstruct socket sockb; 6116178Sjulian 6216178Sjulianstatic int first = 1; 6316178Sjulian 6416178Sjulian/* 6516178Sjulian * Print a summary of connections related to a Network Systems 6616178Sjulian * protocol. For XXX, also give state of connection. 6716178Sjulian * Listening processes (aflag) are suppressed unless the 6816178Sjulian * -a (all) flag is specified. 6916178Sjulian */ 7016178Sjulian 71102975Sdwmalonestatic const char * 7217254Sjulianat_pr_net(struct sockaddr_at *sat, int numeric) 7316285Sjulian{ 7416285Sjulianstatic char mybuf[50]; 7516285Sjulian 7617254Sjulian if (!numeric) { 7717254Sjulian switch(sat->sat_addr.s_net) { 7817254Sjulian case 0xffff: 7917254Sjulian return "????"; 8017254Sjulian case ATADDR_ANYNET: 8117254Sjulian return("*"); 8217254Sjulian } 8316285Sjulian } 84228668Sdim sprintf(mybuf,"%hu",ntohs(sat->sat_addr.s_net)); 8516285Sjulian return mybuf; 8616285Sjulian} 8716285Sjulian 88102975Sdwmalonestatic const char * 8917254Sjulianat_pr_host(struct sockaddr_at *sat, int numeric) 9016285Sjulian{ 9116285Sjulianstatic char mybuf[50]; 9216285Sjulian 9317254Sjulian if (!numeric) { 9417254Sjulian switch(sat->sat_addr.s_node) { 9517254Sjulian case ATADDR_BCAST: 9617254Sjulian return "bcast"; 9717254Sjulian case ATADDR_ANYNODE: 9817254Sjulian return("*"); 9917254Sjulian } 10016285Sjulian } 10117254Sjulian sprintf(mybuf,"%d",(unsigned int)sat->sat_addr.s_node); 10216285Sjulian return mybuf; 10316285Sjulian} 10416285Sjulian 105102975Sdwmalonestatic const char * 10616285Sjulianat_pr_port(struct sockaddr_at *sat) 10716285Sjulian{ 10816285Sjulianstatic char mybuf[50]; 10978294Simp struct servent *serv; 11016285Sjulian 11116285Sjulian switch(sat->sat_port) { 11216285Sjulian case ATADDR_ANYPORT: 11317024Sjulian return("*"); 11416285Sjulian case 0xff: 11516285Sjulian return "????"; 11616285Sjulian default: 11778308Sassar if (numeric_port) { 11878294Simp (void)snprintf(mybuf, sizeof(mybuf), "%d", 11978294Simp (unsigned int)sat->sat_port); 12078294Simp } else { 12178294Simp serv = getservbyport(sat->sat_port, "ddp"); 12278294Simp if (serv == NULL) 12378294Simp (void)snprintf(mybuf, sizeof(mybuf), "%d", 12478294Simp (unsigned int) sat->sat_port); 12578294Simp else 12678294Simp (void) snprintf(mybuf, sizeof(mybuf), "%s", 12778294Simp serv->s_name); 12878294Simp } 12916285Sjulian } 13016285Sjulian return mybuf; 13116285Sjulian} 13216285Sjulian 13317966Sjulianstatic char * 13417966Sjulianat_pr_range(struct sockaddr_at *sat) 13517966Sjulian{ 13617966Sjulianstatic char mybuf[50]; 13717966Sjulian 13817966Sjulian if(sat->sat_range.r_netrange.nr_firstnet 13917966Sjulian != sat->sat_range.r_netrange.nr_lastnet) { 14017966Sjulian sprintf(mybuf,"%d-%d", 14117966Sjulian ntohs(sat->sat_range.r_netrange.nr_firstnet), 14217966Sjulian ntohs(sat->sat_range.r_netrange.nr_lastnet)); 14317966Sjulian } else { 14417966Sjulian sprintf(mybuf,"%d", 14517966Sjulian ntohs(sat->sat_range.r_netrange.nr_firstnet)); 14617966Sjulian } 14717966Sjulian return mybuf; 14817966Sjulian} 14917966Sjulian 15017966Sjulian 15116285Sjulian/* what == 0 for addr only == 3 */ 15216285Sjulian/* 1 for net */ 15316285Sjulian/* 2 for host */ 15416285Sjulian/* 4 for port */ 15517254Sjulian/* 8 for numeric only */ 15616285Sjulianchar * 15778314Sassaratalk_print(struct sockaddr *sa, int what) 15816285Sjulian{ 15916285Sjulian struct sockaddr_at *sat = (struct sockaddr_at *)sa; 16017254Sjulian static char mybuf[50]; 16117254Sjulian int numeric = (what & 0x08); 16216285Sjulian 16316285Sjulian mybuf[0] = 0; 16417966Sjulian switch (what & 0x13) { 16516285Sjulian case 0: 16616285Sjulian mybuf[0] = 0; 16716285Sjulian break; 16816285Sjulian case 1: 16917254Sjulian sprintf(mybuf,"%s",at_pr_net(sat, numeric)); 17016285Sjulian break; 17116285Sjulian case 2: 17217254Sjulian sprintf(mybuf,"%s",at_pr_host(sat, numeric)); 17316285Sjulian break; 17416285Sjulian case 3: 17517254Sjulian sprintf(mybuf,"%s.%s", 17617254Sjulian at_pr_net(sat, numeric), 17717254Sjulian at_pr_host(sat, numeric)); 17817966Sjulian break; 17917966Sjulian case 0x10: 18017966Sjulian sprintf(mybuf,"%s", at_pr_range(sat)); 18116285Sjulian } 18216285Sjulian if (what & 4) { 18317966Sjulian sprintf(mybuf+strlen(mybuf),".%s",at_pr_port(sat)); 18416285Sjulian } 18516285Sjulian return mybuf; 18616285Sjulian} 18717254Sjulian 18817254Sjulianchar * 18917254Sjulianatalk_print2(struct sockaddr *sa, struct sockaddr *mask, int what) 19017254Sjulian{ 19117254Sjulian int n; 19217254Sjulian static char buf[100]; 19317966Sjulian struct sockaddr_at *sat1, *sat2; 19417966Sjulian struct sockaddr_at thesockaddr; 19517966Sjulian struct sockaddr *sa2; 19617254Sjulian 19717966Sjulian sat1 = (struct sockaddr_at *)sa; 19817966Sjulian sat2 = (struct sockaddr_at *)mask; 19917966Sjulian sa2 = (struct sockaddr *)&thesockaddr; 20017966Sjulian 20117966Sjulian thesockaddr.sat_addr.s_net = sat1->sat_addr.s_net & sat2->sat_addr.s_net; 20281960Sbrian snprintf(buf, sizeof(buf), "%s", atalk_print(sa2, 1 |(what & 8))); 20317966Sjulian if(sat2->sat_addr.s_net != 0xFFFF) { 20417966Sjulian thesockaddr.sat_addr.s_net = sat1->sat_addr.s_net | ~sat2->sat_addr.s_net; 20581960Sbrian n = strlen(buf); 20681960Sbrian snprintf(buf + n, sizeof(buf) - n, "-%s", atalk_print(sa2, 1 |(what & 8))); 20717966Sjulian } 20881960Sbrian if(what & 2) { 20981960Sbrian n = strlen(buf); 21081960Sbrian snprintf(buf + n, sizeof(buf) - n, ".%s", atalk_print(sa, what & (~1))); 21181960Sbrian } 21217254Sjulian return(buf); 21317254Sjulian} 21417254Sjulian 21516178Sjulianvoid 216171465Sjhbatalkprotopr(u_long off __unused, const char *name, int af1 __unused, 217171465Sjhb int proto __unused) 21816178Sjulian{ 21952415Sjulian struct ddpcb *this, *next; 22016178Sjulian 22116178Sjulian if (off == 0) 22216178Sjulian return; 22352415Sjulian kread(off, (char *)&this, sizeof (struct ddpcb *)); 22452415Sjulian for ( ; this != NULL; this = next) { 22552415Sjulian kread((u_long)this, (char *)&ddpcb, sizeof (ddpcb)); 22616178Sjulian next = ddpcb.ddp_next; 22716178Sjulian#if 0 22816178Sjulian if (!aflag && atalk_nullhost(ddpcb.ddp_lsat) ) { 22916178Sjulian continue; 23016178Sjulian } 23116178Sjulian#endif 23252415Sjulian kread((u_long)ddpcb.ddp_socket, (char *)&sockb, sizeof (sockb)); 23316178Sjulian if (first) { 23416178Sjulian printf("Active ATALK connections"); 23516178Sjulian if (aflag) 23616178Sjulian printf(" (including servers)"); 23716178Sjulian putchar('\n'); 23816178Sjulian if (Aflag) 23916178Sjulian printf("%-8.8s ", "PCB"); 24016178Sjulian printf(Aflag ? 24116178Sjulian "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" : 24216178Sjulian "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", 24316178Sjulian "Proto", "Recv-Q", "Send-Q", 24416178Sjulian "Local Address", "Foreign Address", "(state)"); 24516178Sjulian first = 0; 24616178Sjulian } 24716178Sjulian if (Aflag) 24852415Sjulian printf("%8lx ", (u_long) this); 249100591Sjdp printf("%-5.5s %6u %6u ", name, sockb.so_rcv.sb_cc, 25016178Sjulian sockb.so_snd.sb_cc); 25116178Sjulian printf(Aflag?" %-18.18s":" %-22.22s", atalk_print( 25216285Sjulian (struct sockaddr *)&ddpcb.ddp_lsat,7)); 25316178Sjulian printf(Aflag?" %-18.18s":" %-22.22s", atalk_print( 25416285Sjulian (struct sockaddr *)&ddpcb.ddp_fsat,7)); 25516178Sjulian putchar('\n'); 25616178Sjulian } 25716178Sjulian} 25837453Sbde 259175061Sobrien#define ANY(x,y,z) if (x || sflag <= 1) \ 26078141Sru printf("\t%lu %s%s%s\n",x,y,plural(x),z) 26116178Sjulian 26216178Sjulian/* 26316178Sjulian * Dump DDP statistics structure. 26416178Sjulian */ 26516178Sjulianvoid 266171465Sjhbddp_stats(u_long off __unused, const char *name, int af1 __unused, 267171465Sjhb int proto __unused) 26816178Sjulian{ 26916178Sjulian struct ddpstat ddpstat; 27016178Sjulian 27116178Sjulian if (off == 0) 27216178Sjulian return; 27316178Sjulian kread(off, (char *)&ddpstat, sizeof (ddpstat)); 27416178Sjulian printf("%s:\n", name); 27516178Sjulian ANY(ddpstat.ddps_short, "packet", " with short headers "); 27616178Sjulian ANY(ddpstat.ddps_long, "packet", " with long headers "); 27716178Sjulian ANY(ddpstat.ddps_nosum, "packet", " with no checksum "); 27816178Sjulian ANY(ddpstat.ddps_tooshort, "packet", " too short "); 27916178Sjulian ANY(ddpstat.ddps_badsum, "packet", " with bad checksum "); 28016178Sjulian ANY(ddpstat.ddps_toosmall, "packet", " with not enough data "); 28116178Sjulian ANY(ddpstat.ddps_forward, "packet", " forwarded "); 28216178Sjulian ANY(ddpstat.ddps_encap, "packet", " encapsulated "); 28316178Sjulian ANY(ddpstat.ddps_cantforward, "packet", " rcvd for unreachable dest "); 28416178Sjulian ANY(ddpstat.ddps_nosockspace, "packet", " dropped due to no socket space "); 28516178Sjulian} 286