netcmds.c revision 31522
1/*- 2 * Copyright (c) 1980, 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint 35/* 36static char sccsid[] = "@(#)netcmds.c 8.1 (Berkeley) 6/6/93"; 37*/ 38static const char rcsid[] = 39 "$Id: netcmds.c,v 1.6 1997/02/22 19:57:16 peter Exp $"; 40#endif /* not lint */ 41 42/* 43 * Common network command support routines. 44 */ 45#include <sys/param.h> 46#include <sys/queue.h> 47#include <sys/socket.h> 48#include <sys/socketvar.h> 49#include <sys/protosw.h> 50 51#include <net/route.h> 52#include <netinet/in.h> 53#include <netinet/in_systm.h> 54#include <netinet/ip.h> 55#include <netinet/in_pcb.h> 56 57#include <netdb.h> 58#include <stdlib.h> 59#include <string.h> 60#include <ctype.h> 61#include "systat.h" 62#include "extern.h" 63 64#define streq(a,b) (strcmp(a,b)==0) 65 66static struct hitem { 67 struct in_addr addr; 68 int onoff; 69} *hosts; 70 71int nports, nhosts, protos; 72 73static void changeitems __P((char *, int)); 74static int selectproto __P((char *)); 75static void showprotos __P((void)); 76static int selectport __P((long, int)); 77static void showports __P((void)); 78static int selecthost __P((struct in_addr *, int)); 79static void showhosts __P((void)); 80 81int 82netcmd(cmd, args) 83 char *cmd, *args; 84{ 85 86 if (prefix(cmd, "proto")) { 87 if (*args == '\0') { 88 move(CMDLINE, 0); 89 clrtoeol(); 90 addstr("which proto?"); 91 } else if (!selectproto(args)) { 92 error("%s: Unknown protocol.", args); 93 } 94 return (1); 95 } 96 if (prefix(cmd, "ignore") || prefix(cmd, "display")) { 97 changeitems(args, prefix(cmd, "display")); 98 return (1); 99 } 100 if (prefix(cmd, "reset")) { 101 selectproto(0); 102 selecthost(0, 0); 103 selectport(-1, 0); 104 return (1); 105 } 106 if (prefix(cmd, "show")) { 107 move(CMDLINE, 0); clrtoeol(); 108 if (*args == '\0') { 109 showprotos(); 110 showhosts(); 111 showports(); 112 return (1); 113 } 114 if (prefix(args, "protos")) 115 showprotos(); 116 else if (prefix(args, "hosts")) 117 showhosts(); 118 else if (prefix(args, "ports")) 119 showports(); 120 else 121 addstr("show what?"); 122 return (1); 123 } 124 return (0); 125} 126 127 128static void 129changeitems(args, onoff) 130 char *args; 131 int onoff; 132{ 133 register char *cp; 134 struct servent *sp; 135 struct hostent *hp; 136 struct in_addr in; 137 char *index(); 138 139 cp = index(args, '\n'); 140 if (cp) 141 *cp = '\0'; 142 for (;;args = cp) { 143 for (cp = args; *cp && isspace(*cp); cp++) 144 ; 145 args = cp; 146 for (; *cp && !isspace(*cp); cp++) 147 ; 148 if (*cp) 149 *cp++ = '\0'; 150 if (cp - args == 0) 151 break; 152 sp = getservbyname(args, 153 protos == TCP ? "tcp" : protos == UDP ? "udp" : 0); 154 if (sp) { 155 selectport(sp->s_port, onoff); 156 continue; 157 } 158 hp = gethostbyname(args); 159 if (hp == 0) { 160 in.s_addr = inet_addr(args); 161 if (in.s_addr == -1) { 162 error("%s: unknown host or port", args); 163 continue; 164 } 165 } else 166 in = *(struct in_addr *)hp->h_addr; 167 selecthost(&in, onoff); 168 } 169} 170 171static int 172selectproto(proto) 173 char *proto; 174{ 175 176 if (proto == 0 || streq(proto, "all")) 177 protos = TCP | UDP; 178 else if (streq(proto, "tcp")) 179 protos = TCP; 180 else if (streq(proto, "udp")) 181 protos = UDP; 182 else 183 return (0); 184 185 return (protos); 186} 187 188static void 189showprotos() 190{ 191 192 if ((protos&TCP) == 0) 193 addch('!'); 194 addstr("tcp "); 195 if ((protos&UDP) == 0) 196 addch('!'); 197 addstr("udp "); 198} 199 200static struct pitem { 201 long port; 202 int onoff; 203} *ports; 204 205static int 206selectport(port, onoff) 207 long port; 208 int onoff; 209{ 210 register struct pitem *p; 211 212 if (port == -1) { 213 if (ports == 0) 214 return (0); 215 free((char *)ports), ports = 0; 216 nports = 0; 217 return (1); 218 } 219 for (p = ports; p < ports+nports; p++) 220 if (p->port == port) { 221 p->onoff = onoff; 222 return (0); 223 } 224 if (nports == 0) 225 ports = (struct pitem *)malloc(sizeof (*p)); 226 else 227 ports = (struct pitem *)realloc(ports, (nports+1)*sizeof (*p)); 228 p = &ports[nports++]; 229 p->port = port; 230 p->onoff = onoff; 231 return (1); 232} 233 234int 235checkport(inp) 236 register struct inpcb *inp; 237{ 238 register struct pitem *p; 239 240 if (ports) 241 for (p = ports; p < ports+nports; p++) 242 if (p->port == inp->inp_lport || p->port == inp->inp_fport) 243 return (p->onoff); 244 return (1); 245} 246 247static void 248showports() 249{ 250 register struct pitem *p; 251 struct servent *sp; 252 253 for (p = ports; p < ports+nports; p++) { 254 sp = getservbyport(p->port, 255 protos == TCP|UDP ? 0 : protos == TCP ? "tcp" : "udp"); 256 if (!p->onoff) 257 addch('!'); 258 if (sp) 259 printw("%s ", sp->s_name); 260 else 261 printw("%d ", p->port); 262 } 263} 264 265static int 266selecthost(in, onoff) 267 struct in_addr *in; 268 int onoff; 269{ 270 register struct hitem *p; 271 272 if (in == 0) { 273 if (hosts == 0) 274 return (0); 275 free((char *)hosts), hosts = 0; 276 nhosts = 0; 277 return (1); 278 } 279 for (p = hosts; p < hosts+nhosts; p++) 280 if (p->addr.s_addr == in->s_addr) { 281 p->onoff = onoff; 282 return (0); 283 } 284 if (nhosts == 0) 285 hosts = (struct hitem *)malloc(sizeof (*p)); 286 else 287 hosts = (struct hitem *)realloc(hosts, (nhosts+1)*sizeof (*p)); 288 p = &hosts[nhosts++]; 289 p->addr = *in; 290 p->onoff = onoff; 291 return (1); 292} 293 294int 295checkhost(inp) 296 register struct inpcb *inp; 297{ 298 register struct hitem *p; 299 300 if (hosts) 301 for (p = hosts; p < hosts+nhosts; p++) 302 if (p->addr.s_addr == inp->inp_laddr.s_addr || 303 p->addr.s_addr == inp->inp_faddr.s_addr) 304 return (p->onoff); 305 return (1); 306} 307 308static void 309showhosts() 310{ 311 register struct hitem *p; 312 struct hostent *hp; 313 314 for (p = hosts; p < hosts+nhosts; p++) { 315 hp = gethostbyaddr((char *)&p->addr, sizeof (p->addr), AF_INET); 316 if (!p->onoff) 317 addch('!'); 318 printw("%s ", hp ? hp->h_name : (char *)inet_ntoa(p->addr)); 319 } 320} 321