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 /* 36 static char sccsid[] = "@(#)netcmds.c 8.1 (Berkeley) 6/6/93"; 37 */ 38 static const char rcsid[] = 39 "$FreeBSD$"; 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 #include <arpa/inet.h> 57 58 #include <netdb.h> 59 #include <stdlib.h> 60 #include <string.h> 61 #include <ctype.h> 62 #include "systat.h" 63 #include "extern.h" 64 65 #define streq(a,b) (strcmp(a,b)==0) 66 67 static struct hitem { 68 struct in_addr addr; 69 int onoff; 70 } *hosts; 71 72 int nports, nhosts, protos; 73 74 static void changeitems __P((char *, int)); 75 static int selectproto __P((char *)); 76 static void showprotos __P((void)); 77 static int selectport __P((long, int)); 78 static void showports __P((void)); 79 static int selecthost __P((struct in_addr *, int)); 80 static void showhosts __P((void)); 81 82 int 83 netcmd(cmd, args) 84 char *cmd, *args; 85 { 86 87 if (prefix(cmd, "proto")) { 88 if (*args == '\0') { 89 move(CMDLINE, 0); 90 clrtoeol(); 91 addstr("which proto?"); 92 } else if (!selectproto(args)) { 93 error("%s: Unknown protocol.", args); 94 } 95 return (1); 96 } 97 if (prefix(cmd, "ignore") || prefix(cmd, "display")) { 98 changeitems(args, prefix(cmd, "display")); 99 return (1); 100 } 101 if (prefix(cmd, "reset")) { 102 selectproto(0); 103 selecthost(0, 0); 104 selectport(-1, 0); 105 return (1); 106 } 107 if (prefix(cmd, "show")) { 108 move(CMDLINE, 0); clrtoeol(); 109 if (*args == '\0') { 110 showprotos(); 111 showhosts(); 112 showports(); 113 return (1); 114 } 115 if (prefix(args, "protos")) 116 showprotos(); 117 else if (prefix(args, "hosts")) 118 showhosts(); 119 else if (prefix(args, "ports")) 120 showports(); 121 else 122 addstr("show what?"); 123 return (1); 124 } 125 return (0); 126 } 127 128 129 static void 130 changeitems(args, onoff) 131 char *args; 132 int onoff; 133 { 134 register char *cp; 135 struct servent *sp; 136 struct hostent *hp; 137 struct in_addr in; 138 char *index(); 139 140 cp = index(args, '\n'); 141 if (cp) 142 *cp = '\0'; 143 for (;;args = cp) { 144 for (cp = args; *cp && isspace(*cp); cp++) 145 ; 146 args = cp; 147 for (; *cp && !isspace(*cp); cp++) 148 ; 149 if (*cp) 150 *cp++ = '\0'; 151 if (cp - args == 0) 152 break; 153 sp = getservbyname(args, 154 protos == TCP ? "tcp" : protos == UDP ? "udp" : 0); 155 if (sp) { 156 selectport(sp->s_port, onoff); 157 continue; 158 } 159 hp = gethostbyname(args); 160 if (hp == 0) { 161 in.s_addr = inet_addr(args); 162 if (in.s_addr == -1) { 163 error("%s: unknown host or port", args); 164 continue; 165 } 166 } else 167 in = *(struct in_addr *)hp->h_addr; 168 selecthost(&in, onoff); 169 } 170 } 171 172 static int 173 selectproto(proto) 174 char *proto; 175 { 176 177 if (proto == 0 || streq(proto, "all")) 178 protos = TCP | UDP; 179 else if (streq(proto, "tcp")) 180 protos = TCP; 181 else if (streq(proto, "udp")) 182 protos = UDP; 183 else 184 return (0); 185 186 return (protos); 187 } 188 189 static void 190 showprotos() 191 { 192 193 if ((protos&TCP) == 0) 194 addch('!'); 195 addstr("tcp "); 196 if ((protos&UDP) == 0) 197 addch('!'); 198 addstr("udp "); 199 } 200 201 static struct pitem { 202 long port; 203 int onoff; 204 } *ports; 205 206 static int 207 selectport(port, onoff) 208 long port; 209 int onoff; 210 { 211 register struct pitem *p; 212 213 if (port == -1) { 214 if (ports == 0) 215 return (0); 216 free((char *)ports), ports = 0; 217 nports = 0; 218 return (1); 219 } 220 for (p = ports; p < ports+nports; p++) 221 if (p->port == port) { 222 p->onoff = onoff; 223 return (0); 224 } 225 if (nports == 0) 226 ports = (struct pitem *)malloc(sizeof (*p)); 227 else 228 ports = (struct pitem *)realloc(ports, (nports+1)*sizeof (*p)); 229 p = &ports[nports++]; 230 p->port = port; 231 p->onoff = onoff; 232 return (1); 233 } 234 235 int 236 checkport(inp) 237 register struct inpcb *inp; 238 { 239 register struct pitem *p; 240 241 if (ports) 242 for (p = ports; p < ports+nports; p++) 243 if (p->port == inp->inp_lport || p->port == inp->inp_fport) 244 return (p->onoff); 245 return (1); 246 } 247 248 static void 249 showports() 250 { 251 register struct pitem *p; 252 struct servent *sp; 253 254 for (p = ports; p < ports+nports; p++) { 255 sp = getservbyport(p->port, 256 protos == (TCP|UDP) ? 0 : protos == TCP ? "tcp" : "udp"); 257 if (!p->onoff) 258 addch('!'); 259 if (sp) 260 printw("%s ", sp->s_name); 261 else 262 printw("%d ", p->port); 263 } 264 } 265 266 static int 267 selecthost(in, onoff) 268 struct in_addr *in; 269 int onoff; 270 { 271 register struct hitem *p; 272 273 if (in == 0) { 274 if (hosts == 0) 275 return (0); 276 free((char *)hosts), hosts = 0; 277 nhosts = 0; 278 return (1); 279 } 280 for (p = hosts; p < hosts+nhosts; p++) 281 if (p->addr.s_addr == in->s_addr) { 282 p->onoff = onoff; 283 return (0); 284 } 285 if (nhosts == 0) 286 hosts = (struct hitem *)malloc(sizeof (*p)); 287 else 288 hosts = (struct hitem *)realloc(hosts, (nhosts+1)*sizeof (*p)); 289 p = &hosts[nhosts++]; 290 p->addr = *in; 291 p->onoff = onoff; 292 return (1); 293 } 294 295 int 296 checkhost(inp) 297 register struct inpcb *inp; 298 { 299 register struct hitem *p; 300 301 if (hosts) 302 for (p = hosts; p < hosts+nhosts; p++) 303 if (p->addr.s_addr == inp->inp_laddr.s_addr || 304 p->addr.s_addr == inp->inp_faddr.s_addr) 305 return (p->onoff); 306 return (1); 307 } 308 309 static void 310 showhosts() 311 { 312 register struct hitem *p; 313 struct hostent *hp; 314 315 for (p = hosts; p < hosts+nhosts; p++) { 316 hp = gethostbyaddr((char *)&p->addr, sizeof (p->addr), AF_INET); 317 if (!p->onoff) 318 addch('!'); 319 printw("%s ", hp ? hp->h_name : (char *)inet_ntoa(p->addr)); 320 } 321 } 322