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 * 4. Neither the name of the University nor the names of its contributors 141590Srgrimes * may be used to endorse or promote products derived from this software 151590Srgrimes * without specific prior written permission. 161590Srgrimes * 171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271590Srgrimes * SUCH DAMAGE. 281590Srgrimes */ 291590Srgrimes 3087715Smarkm#include <sys/cdefs.h> 311590Srgrimes 3287715Smarkm__FBSDID("$FreeBSD$"); 3387715Smarkm 3487715Smarkm#ifdef lint 3587715Smarkmstatic const char sccsid[] = "@(#)netcmds.c 8.1 (Berkeley) 6/6/93"; 3687715Smarkm#endif 3787715Smarkm 381590Srgrimes/* 391590Srgrimes * Common network command support routines. 401590Srgrimes */ 411590Srgrimes#include <sys/param.h> 4214543Sdg#include <sys/queue.h> 431590Srgrimes#include <sys/socket.h> 441590Srgrimes#include <sys/socketvar.h> 451590Srgrimes#include <sys/protosw.h> 461590Srgrimes 471590Srgrimes#include <net/route.h> 481590Srgrimes#include <netinet/in.h> 491590Srgrimes#include <netinet/in_systm.h> 501590Srgrimes#include <netinet/ip.h> 511590Srgrimes#include <netinet/in_pcb.h> 5236916Speter#include <arpa/inet.h> 531590Srgrimes 5487715Smarkm#include <ctype.h> 551590Srgrimes#include <netdb.h> 561590Srgrimes#include <stdlib.h> 571590Srgrimes#include <string.h> 5887715Smarkm 591590Srgrimes#include "systat.h" 601590Srgrimes#include "extern.h" 611590Srgrimes 621590Srgrimes#define streq(a,b) (strcmp(a,b)==0) 631590Srgrimes 641590Srgrimesstatic struct hitem { 651590Srgrimes struct in_addr addr; 661590Srgrimes int onoff; 671590Srgrimes} *hosts; 681590Srgrimes 691590Srgrimesint nports, nhosts, protos; 701590Srgrimes 7192922Simpstatic void changeitems(const char *, int); 7292922Simpstatic int selectproto(const char *); 7392922Simpstatic void showprotos(void); 7492922Simpstatic int selectport(long, int); 7592922Simpstatic void showports(void); 7692922Simpstatic int selecthost(struct in_addr *, int); 7792922Simpstatic void showhosts(void); 781590Srgrimes 791590Srgrimesint 80175387Sdelphijnetcmd(const char *cmd, const char *args) 811590Srgrimes{ 821590Srgrimes 8331522Ssteve if (prefix(cmd, "proto")) { 8431522Ssteve if (*args == '\0') { 8531522Ssteve move(CMDLINE, 0); 8631522Ssteve clrtoeol(); 8731522Ssteve addstr("which proto?"); 8831522Ssteve } else if (!selectproto(args)) { 8931522Ssteve error("%s: Unknown protocol.", args); 9031522Ssteve } 911590Srgrimes return (1); 921590Srgrimes } 931590Srgrimes if (prefix(cmd, "ignore") || prefix(cmd, "display")) { 941590Srgrimes changeitems(args, prefix(cmd, "display")); 951590Srgrimes return (1); 961590Srgrimes } 971590Srgrimes if (prefix(cmd, "reset")) { 981590Srgrimes selectproto(0); 991590Srgrimes selecthost(0, 0); 1001590Srgrimes selectport(-1, 0); 1011590Srgrimes return (1); 1021590Srgrimes } 1031590Srgrimes if (prefix(cmd, "show")) { 1041590Srgrimes move(CMDLINE, 0); clrtoeol(); 1051590Srgrimes if (*args == '\0') { 1061590Srgrimes showprotos(); 1071590Srgrimes showhosts(); 1081590Srgrimes showports(); 1091590Srgrimes return (1); 1101590Srgrimes } 1111590Srgrimes if (prefix(args, "protos")) 1121590Srgrimes showprotos(); 1131590Srgrimes else if (prefix(args, "hosts")) 1141590Srgrimes showhosts(); 1151590Srgrimes else if (prefix(args, "ports")) 1161590Srgrimes showports(); 1171590Srgrimes else 1181590Srgrimes addstr("show what?"); 1191590Srgrimes return (1); 1201590Srgrimes } 1211590Srgrimes return (0); 1221590Srgrimes} 1231590Srgrimes 1241590Srgrimes 1251590Srgrimesstatic void 126175387Sdelphijchangeitems(const char *args, int onoff) 1271590Srgrimes{ 12887715Smarkm char *cp, *tmpstr, *tmpstr1; 1291590Srgrimes struct servent *sp; 1301590Srgrimes struct hostent *hp; 1311590Srgrimes struct in_addr in; 1321590Srgrimes 13387715Smarkm tmpstr = tmpstr1 = strdup(args); 13487715Smarkm cp = index(tmpstr1, '\n'); 1351590Srgrimes if (cp) 1361590Srgrimes *cp = '\0'; 13787715Smarkm for (;;tmpstr1 = cp) { 13887715Smarkm for (cp = tmpstr1; *cp && isspace(*cp); cp++) 1391590Srgrimes ; 14087715Smarkm tmpstr1 = cp; 1411590Srgrimes for (; *cp && !isspace(*cp); cp++) 1421590Srgrimes ; 1431590Srgrimes if (*cp) 1441590Srgrimes *cp++ = '\0'; 14587715Smarkm if (cp - tmpstr1 == 0) 1461590Srgrimes break; 14787715Smarkm sp = getservbyname(tmpstr1, 1481590Srgrimes protos == TCP ? "tcp" : protos == UDP ? "udp" : 0); 1491590Srgrimes if (sp) { 1501590Srgrimes selectport(sp->s_port, onoff); 1511590Srgrimes continue; 1521590Srgrimes } 15387715Smarkm hp = gethostbyname(tmpstr1); 1541590Srgrimes if (hp == 0) { 15587715Smarkm in.s_addr = inet_addr(tmpstr1); 15687715Smarkm if ((int)in.s_addr == -1) { 15787715Smarkm error("%s: unknown host or port", tmpstr1); 1581590Srgrimes continue; 1591590Srgrimes } 1601590Srgrimes } else 1611590Srgrimes in = *(struct in_addr *)hp->h_addr; 1621590Srgrimes selecthost(&in, onoff); 1631590Srgrimes } 16487715Smarkm free(tmpstr); 1651590Srgrimes} 1661590Srgrimes 1671590Srgrimesstatic int 168175387Sdelphijselectproto(const char *proto) 1691590Srgrimes{ 1701590Srgrimes 1711590Srgrimes if (proto == 0 || streq(proto, "all")) 17231522Ssteve protos = TCP | UDP; 1731590Srgrimes else if (streq(proto, "tcp")) 17431522Ssteve protos = TCP; 1751590Srgrimes else if (streq(proto, "udp")) 17631522Ssteve protos = UDP; 17731522Ssteve else 17831522Ssteve return (0); 17931522Ssteve 18031522Ssteve return (protos); 1811590Srgrimes} 1821590Srgrimes 1831590Srgrimesstatic void 184175387Sdelphijshowprotos(void) 1851590Srgrimes{ 1861590Srgrimes 1871590Srgrimes if ((protos&TCP) == 0) 1881590Srgrimes addch('!'); 1891590Srgrimes addstr("tcp "); 1901590Srgrimes if ((protos&UDP) == 0) 1911590Srgrimes addch('!'); 1921590Srgrimes addstr("udp "); 1931590Srgrimes} 1941590Srgrimes 1951590Srgrimesstatic struct pitem { 1961590Srgrimes long port; 1971590Srgrimes int onoff; 1981590Srgrimes} *ports; 1991590Srgrimes 2001590Srgrimesstatic int 201175387Sdelphijselectport(long port, int onoff) 2021590Srgrimes{ 203175387Sdelphij struct pitem *p; 2041590Srgrimes 2051590Srgrimes if (port == -1) { 2061590Srgrimes if (ports == 0) 2071590Srgrimes return (0); 2081590Srgrimes free((char *)ports), ports = 0; 2091590Srgrimes nports = 0; 2101590Srgrimes return (1); 2111590Srgrimes } 2121590Srgrimes for (p = ports; p < ports+nports; p++) 2131590Srgrimes if (p->port == port) { 2141590Srgrimes p->onoff = onoff; 2151590Srgrimes return (0); 2161590Srgrimes } 2171590Srgrimes if (nports == 0) 2181590Srgrimes ports = (struct pitem *)malloc(sizeof (*p)); 2191590Srgrimes else 2201590Srgrimes ports = (struct pitem *)realloc(ports, (nports+1)*sizeof (*p)); 2211590Srgrimes p = &ports[nports++]; 2221590Srgrimes p->port = port; 2231590Srgrimes p->onoff = onoff; 2241590Srgrimes return (1); 2251590Srgrimes} 2261590Srgrimes 2271590Srgrimesint 228175387Sdelphijcheckport(struct inpcb *inp) 2291590Srgrimes{ 230175387Sdelphij struct pitem *p; 2311590Srgrimes 2321590Srgrimes if (ports) 2331590Srgrimes for (p = ports; p < ports+nports; p++) 2341590Srgrimes if (p->port == inp->inp_lport || p->port == inp->inp_fport) 2351590Srgrimes return (p->onoff); 2361590Srgrimes return (1); 2371590Srgrimes} 2381590Srgrimes 2391590Srgrimesstatic void 240175387Sdelphijshowports(void) 2411590Srgrimes{ 242175387Sdelphij struct pitem *p; 2431590Srgrimes struct servent *sp; 2441590Srgrimes 2451590Srgrimes for (p = ports; p < ports+nports; p++) { 2461590Srgrimes sp = getservbyport(p->port, 24774671Stmm protos == (TCP|UDP) ? 0 : protos == TCP ? "tcp" : "udp"); 2481590Srgrimes if (!p->onoff) 2491590Srgrimes addch('!'); 2501590Srgrimes if (sp) 2511590Srgrimes printw("%s ", sp->s_name); 2521590Srgrimes else 2531590Srgrimes printw("%d ", p->port); 2541590Srgrimes } 2551590Srgrimes} 2561590Srgrimes 2571590Srgrimesstatic int 258175387Sdelphijselecthost(struct in_addr *in, int onoff) 2591590Srgrimes{ 260175387Sdelphij struct hitem *p; 2611590Srgrimes 2621590Srgrimes if (in == 0) { 2631590Srgrimes if (hosts == 0) 2641590Srgrimes return (0); 2651590Srgrimes free((char *)hosts), hosts = 0; 2661590Srgrimes nhosts = 0; 2671590Srgrimes return (1); 2681590Srgrimes } 2691590Srgrimes for (p = hosts; p < hosts+nhosts; p++) 2701590Srgrimes if (p->addr.s_addr == in->s_addr) { 2711590Srgrimes p->onoff = onoff; 2721590Srgrimes return (0); 2731590Srgrimes } 2741590Srgrimes if (nhosts == 0) 2751590Srgrimes hosts = (struct hitem *)malloc(sizeof (*p)); 2761590Srgrimes else 2771590Srgrimes hosts = (struct hitem *)realloc(hosts, (nhosts+1)*sizeof (*p)); 2781590Srgrimes p = &hosts[nhosts++]; 2791590Srgrimes p->addr = *in; 2801590Srgrimes p->onoff = onoff; 2811590Srgrimes return (1); 2821590Srgrimes} 2831590Srgrimes 2841590Srgrimesint 285175387Sdelphijcheckhost(struct inpcb *inp) 2861590Srgrimes{ 287175387Sdelphij struct hitem *p; 2881590Srgrimes 2891590Srgrimes if (hosts) 2901590Srgrimes for (p = hosts; p < hosts+nhosts; p++) 2911590Srgrimes if (p->addr.s_addr == inp->inp_laddr.s_addr || 2921590Srgrimes p->addr.s_addr == inp->inp_faddr.s_addr) 2931590Srgrimes return (p->onoff); 2941590Srgrimes return (1); 2951590Srgrimes} 2961590Srgrimes 2971590Srgrimesstatic void 298175387Sdelphijshowhosts(void) 2991590Srgrimes{ 300175387Sdelphij struct hitem *p; 3011590Srgrimes struct hostent *hp; 3021590Srgrimes 3031590Srgrimes for (p = hosts; p < hosts+nhosts; p++) { 3041590Srgrimes hp = gethostbyaddr((char *)&p->addr, sizeof (p->addr), AF_INET); 3051590Srgrimes if (!p->onoff) 3061590Srgrimes addch('!'); 3071590Srgrimes printw("%s ", hp ? hp->h_name : (char *)inet_ntoa(p->addr)); 3081590Srgrimes } 3091590Srgrimes} 310