netcmds.c revision 92922
11590Srgrimes/*- 21590Srgrimes * Copyright (c) 1980, 1992, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 3487715Smarkm#include <sys/cdefs.h> 351590Srgrimes 3687715Smarkm__FBSDID("$FreeBSD: head/usr.bin/systat/netcmds.c 92922 2002-03-22 01:42:45Z imp $"); 3787715Smarkm 3887715Smarkm#ifdef lint 3987715Smarkmstatic const char sccsid[] = "@(#)netcmds.c 8.1 (Berkeley) 6/6/93"; 4087715Smarkm#endif 4187715Smarkm 421590Srgrimes/* 431590Srgrimes * Common network command support routines. 441590Srgrimes */ 451590Srgrimes#include <sys/param.h> 4614543Sdg#include <sys/queue.h> 471590Srgrimes#include <sys/socket.h> 481590Srgrimes#include <sys/socketvar.h> 491590Srgrimes#include <sys/protosw.h> 501590Srgrimes 511590Srgrimes#include <net/route.h> 521590Srgrimes#include <netinet/in.h> 531590Srgrimes#include <netinet/in_systm.h> 541590Srgrimes#include <netinet/ip.h> 551590Srgrimes#include <netinet/in_pcb.h> 5636916Speter#include <arpa/inet.h> 571590Srgrimes 5887715Smarkm#include <ctype.h> 591590Srgrimes#include <netdb.h> 601590Srgrimes#include <stdlib.h> 611590Srgrimes#include <string.h> 6287715Smarkm 631590Srgrimes#include "systat.h" 641590Srgrimes#include "extern.h" 651590Srgrimes 661590Srgrimes#define streq(a,b) (strcmp(a,b)==0) 671590Srgrimes 681590Srgrimesstatic struct hitem { 691590Srgrimes struct in_addr addr; 701590Srgrimes int onoff; 711590Srgrimes} *hosts; 721590Srgrimes 731590Srgrimesint nports, nhosts, protos; 741590Srgrimes 7592922Simpstatic void changeitems(const char *, int); 7692922Simpstatic int selectproto(const char *); 7792922Simpstatic void showprotos(void); 7892922Simpstatic int selectport(long, int); 7992922Simpstatic void showports(void); 8092922Simpstatic int selecthost(struct in_addr *, int); 8192922Simpstatic void showhosts(void); 821590Srgrimes 831590Srgrimesint 841590Srgrimesnetcmd(cmd, args) 8587715Smarkm const char *cmd, *args; 861590Srgrimes{ 871590Srgrimes 8831522Ssteve if (prefix(cmd, "proto")) { 8931522Ssteve if (*args == '\0') { 9031522Ssteve move(CMDLINE, 0); 9131522Ssteve clrtoeol(); 9231522Ssteve addstr("which proto?"); 9331522Ssteve } else if (!selectproto(args)) { 9431522Ssteve error("%s: Unknown protocol.", args); 9531522Ssteve } 961590Srgrimes return (1); 971590Srgrimes } 981590Srgrimes if (prefix(cmd, "ignore") || prefix(cmd, "display")) { 991590Srgrimes changeitems(args, prefix(cmd, "display")); 1001590Srgrimes return (1); 1011590Srgrimes } 1021590Srgrimes if (prefix(cmd, "reset")) { 1031590Srgrimes selectproto(0); 1041590Srgrimes selecthost(0, 0); 1051590Srgrimes selectport(-1, 0); 1061590Srgrimes return (1); 1071590Srgrimes } 1081590Srgrimes if (prefix(cmd, "show")) { 1091590Srgrimes move(CMDLINE, 0); clrtoeol(); 1101590Srgrimes if (*args == '\0') { 1111590Srgrimes showprotos(); 1121590Srgrimes showhosts(); 1131590Srgrimes showports(); 1141590Srgrimes return (1); 1151590Srgrimes } 1161590Srgrimes if (prefix(args, "protos")) 1171590Srgrimes showprotos(); 1181590Srgrimes else if (prefix(args, "hosts")) 1191590Srgrimes showhosts(); 1201590Srgrimes else if (prefix(args, "ports")) 1211590Srgrimes showports(); 1221590Srgrimes else 1231590Srgrimes addstr("show what?"); 1241590Srgrimes return (1); 1251590Srgrimes } 1261590Srgrimes return (0); 1271590Srgrimes} 1281590Srgrimes 1291590Srgrimes 1301590Srgrimesstatic void 1311590Srgrimeschangeitems(args, onoff) 13287715Smarkm const char *args; 1331590Srgrimes int onoff; 1341590Srgrimes{ 13587715Smarkm char *cp, *tmpstr, *tmpstr1; 1361590Srgrimes struct servent *sp; 1371590Srgrimes struct hostent *hp; 1381590Srgrimes struct in_addr in; 1391590Srgrimes 14087715Smarkm tmpstr = tmpstr1 = strdup(args); 14187715Smarkm cp = index(tmpstr1, '\n'); 1421590Srgrimes if (cp) 1431590Srgrimes *cp = '\0'; 14487715Smarkm for (;;tmpstr1 = cp) { 14587715Smarkm for (cp = tmpstr1; *cp && isspace(*cp); cp++) 1461590Srgrimes ; 14787715Smarkm tmpstr1 = cp; 1481590Srgrimes for (; *cp && !isspace(*cp); cp++) 1491590Srgrimes ; 1501590Srgrimes if (*cp) 1511590Srgrimes *cp++ = '\0'; 15287715Smarkm if (cp - tmpstr1 == 0) 1531590Srgrimes break; 15487715Smarkm sp = getservbyname(tmpstr1, 1551590Srgrimes protos == TCP ? "tcp" : protos == UDP ? "udp" : 0); 1561590Srgrimes if (sp) { 1571590Srgrimes selectport(sp->s_port, onoff); 1581590Srgrimes continue; 1591590Srgrimes } 16087715Smarkm hp = gethostbyname(tmpstr1); 1611590Srgrimes if (hp == 0) { 16287715Smarkm in.s_addr = inet_addr(tmpstr1); 16387715Smarkm if ((int)in.s_addr == -1) { 16487715Smarkm error("%s: unknown host or port", tmpstr1); 1651590Srgrimes continue; 1661590Srgrimes } 1671590Srgrimes } else 1681590Srgrimes in = *(struct in_addr *)hp->h_addr; 1691590Srgrimes selecthost(&in, onoff); 1701590Srgrimes } 17187715Smarkm free(tmpstr); 1721590Srgrimes} 1731590Srgrimes 1741590Srgrimesstatic int 1751590Srgrimesselectproto(proto) 17687715Smarkm const char *proto; 1771590Srgrimes{ 1781590Srgrimes 1791590Srgrimes if (proto == 0 || streq(proto, "all")) 18031522Ssteve protos = TCP | UDP; 1811590Srgrimes else if (streq(proto, "tcp")) 18231522Ssteve protos = TCP; 1831590Srgrimes else if (streq(proto, "udp")) 18431522Ssteve protos = UDP; 18531522Ssteve else 18631522Ssteve return (0); 18731522Ssteve 18831522Ssteve return (protos); 1891590Srgrimes} 1901590Srgrimes 1911590Srgrimesstatic void 1921590Srgrimesshowprotos() 1931590Srgrimes{ 1941590Srgrimes 1951590Srgrimes if ((protos&TCP) == 0) 1961590Srgrimes addch('!'); 1971590Srgrimes addstr("tcp "); 1981590Srgrimes if ((protos&UDP) == 0) 1991590Srgrimes addch('!'); 2001590Srgrimes addstr("udp "); 2011590Srgrimes} 2021590Srgrimes 2031590Srgrimesstatic struct pitem { 2041590Srgrimes long port; 2051590Srgrimes int onoff; 2061590Srgrimes} *ports; 2071590Srgrimes 2081590Srgrimesstatic int 2091590Srgrimesselectport(port, onoff) 2101590Srgrimes long port; 2111590Srgrimes int onoff; 2121590Srgrimes{ 2131590Srgrimes register struct pitem *p; 2141590Srgrimes 2151590Srgrimes if (port == -1) { 2161590Srgrimes if (ports == 0) 2171590Srgrimes return (0); 2181590Srgrimes free((char *)ports), ports = 0; 2191590Srgrimes nports = 0; 2201590Srgrimes return (1); 2211590Srgrimes } 2221590Srgrimes for (p = ports; p < ports+nports; p++) 2231590Srgrimes if (p->port == port) { 2241590Srgrimes p->onoff = onoff; 2251590Srgrimes return (0); 2261590Srgrimes } 2271590Srgrimes if (nports == 0) 2281590Srgrimes ports = (struct pitem *)malloc(sizeof (*p)); 2291590Srgrimes else 2301590Srgrimes ports = (struct pitem *)realloc(ports, (nports+1)*sizeof (*p)); 2311590Srgrimes p = &ports[nports++]; 2321590Srgrimes p->port = port; 2331590Srgrimes p->onoff = onoff; 2341590Srgrimes return (1); 2351590Srgrimes} 2361590Srgrimes 2371590Srgrimesint 2381590Srgrimescheckport(inp) 2391590Srgrimes register struct inpcb *inp; 2401590Srgrimes{ 2411590Srgrimes register struct pitem *p; 2421590Srgrimes 2431590Srgrimes if (ports) 2441590Srgrimes for (p = ports; p < ports+nports; p++) 2451590Srgrimes if (p->port == inp->inp_lport || p->port == inp->inp_fport) 2461590Srgrimes return (p->onoff); 2471590Srgrimes return (1); 2481590Srgrimes} 2491590Srgrimes 2501590Srgrimesstatic void 2511590Srgrimesshowports() 2521590Srgrimes{ 2531590Srgrimes register struct pitem *p; 2541590Srgrimes struct servent *sp; 2551590Srgrimes 2561590Srgrimes for (p = ports; p < ports+nports; p++) { 2571590Srgrimes sp = getservbyport(p->port, 25874671Stmm protos == (TCP|UDP) ? 0 : protos == TCP ? "tcp" : "udp"); 2591590Srgrimes if (!p->onoff) 2601590Srgrimes addch('!'); 2611590Srgrimes if (sp) 2621590Srgrimes printw("%s ", sp->s_name); 2631590Srgrimes else 2641590Srgrimes printw("%d ", p->port); 2651590Srgrimes } 2661590Srgrimes} 2671590Srgrimes 2681590Srgrimesstatic int 2691590Srgrimesselecthost(in, onoff) 2701590Srgrimes struct in_addr *in; 2711590Srgrimes int onoff; 2721590Srgrimes{ 2731590Srgrimes register struct hitem *p; 2741590Srgrimes 2751590Srgrimes if (in == 0) { 2761590Srgrimes if (hosts == 0) 2771590Srgrimes return (0); 2781590Srgrimes free((char *)hosts), hosts = 0; 2791590Srgrimes nhosts = 0; 2801590Srgrimes return (1); 2811590Srgrimes } 2821590Srgrimes for (p = hosts; p < hosts+nhosts; p++) 2831590Srgrimes if (p->addr.s_addr == in->s_addr) { 2841590Srgrimes p->onoff = onoff; 2851590Srgrimes return (0); 2861590Srgrimes } 2871590Srgrimes if (nhosts == 0) 2881590Srgrimes hosts = (struct hitem *)malloc(sizeof (*p)); 2891590Srgrimes else 2901590Srgrimes hosts = (struct hitem *)realloc(hosts, (nhosts+1)*sizeof (*p)); 2911590Srgrimes p = &hosts[nhosts++]; 2921590Srgrimes p->addr = *in; 2931590Srgrimes p->onoff = onoff; 2941590Srgrimes return (1); 2951590Srgrimes} 2961590Srgrimes 2971590Srgrimesint 2981590Srgrimescheckhost(inp) 2991590Srgrimes register struct inpcb *inp; 3001590Srgrimes{ 3011590Srgrimes register struct hitem *p; 3021590Srgrimes 3031590Srgrimes if (hosts) 3041590Srgrimes for (p = hosts; p < hosts+nhosts; p++) 3051590Srgrimes if (p->addr.s_addr == inp->inp_laddr.s_addr || 3061590Srgrimes p->addr.s_addr == inp->inp_faddr.s_addr) 3071590Srgrimes return (p->onoff); 3081590Srgrimes return (1); 3091590Srgrimes} 3101590Srgrimes 3111590Srgrimesstatic void 3121590Srgrimesshowhosts() 3131590Srgrimes{ 3141590Srgrimes register struct hitem *p; 3151590Srgrimes struct hostent *hp; 3161590Srgrimes 3171590Srgrimes for (p = hosts; p < hosts+nhosts; p++) { 3181590Srgrimes hp = gethostbyaddr((char *)&p->addr, sizeof (p->addr), AF_INET); 3191590Srgrimes if (!p->onoff) 3201590Srgrimes addch('!'); 3211590Srgrimes printw("%s ", hp ? hp->h_name : (char *)inet_ntoa(p->addr)); 3221590Srgrimes } 3231590Srgrimes} 324