1 /*- 2 * Copyright (c) 1980, 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)netcmds.c 5.7 (Berkeley) 05/21/93"; 10 #endif /* not lint */ 11 12 /* 13 * Common network command support routines. 14 */ 15 #include <sys/param.h> 16 #include <sys/socket.h> 17 #include <sys/socketvar.h> 18 #include <sys/mbuf.h> 19 #include <sys/protosw.h> 20 21 #include <net/route.h> 22 #include <netinet/in.h> 23 #include <netinet/in_systm.h> 24 #include <netinet/ip.h> 25 #include <netinet/in_pcb.h> 26 27 #include <netdb.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <ctype.h> 31 #include "systat.h" 32 #include "extern.h" 33 34 #define streq(a,b) (strcmp(a,b)==0) 35 36 static struct hitem { 37 struct in_addr addr; 38 int onoff; 39 } *hosts; 40 41 int nports, nhosts, protos; 42 43 static void changeitems __P((char *, int)); 44 static int selectproto __P((char *)); 45 static void showprotos __P((void)); 46 static int selectport __P((long, int)); 47 static void showports __P((void)); 48 static int selecthost __P((struct in_addr *, int)); 49 static void showhosts __P((void)); 50 51 int 52 netcmd(cmd, args) 53 char *cmd, *args; 54 { 55 56 if (prefix(cmd, "tcp") || prefix(cmd, "udp")) { 57 selectproto(cmd); 58 return (1); 59 } 60 if (prefix(cmd, "ignore") || prefix(cmd, "display")) { 61 changeitems(args, prefix(cmd, "display")); 62 return (1); 63 } 64 if (prefix(cmd, "reset")) { 65 selectproto(0); 66 selecthost(0, 0); 67 selectport(-1, 0); 68 return (1); 69 } 70 if (prefix(cmd, "show")) { 71 move(CMDLINE, 0); clrtoeol(); 72 if (*args == '\0') { 73 showprotos(); 74 showhosts(); 75 showports(); 76 return (1); 77 } 78 if (prefix(args, "protos")) 79 showprotos(); 80 else if (prefix(args, "hosts")) 81 showhosts(); 82 else if (prefix(args, "ports")) 83 showports(); 84 else 85 addstr("show what?"); 86 return (1); 87 } 88 return (0); 89 } 90 91 92 static void 93 changeitems(args, onoff) 94 char *args; 95 int onoff; 96 { 97 register char *cp; 98 struct servent *sp; 99 struct hostent *hp; 100 struct in_addr in; 101 char *index(); 102 103 cp = index(args, '\n'); 104 if (cp) 105 *cp = '\0'; 106 for (;;args = cp) { 107 for (cp = args; *cp && isspace(*cp); cp++) 108 ; 109 args = cp; 110 for (; *cp && !isspace(*cp); cp++) 111 ; 112 if (*cp) 113 *cp++ = '\0'; 114 if (cp - args == 0) 115 break; 116 sp = getservbyname(args, 117 protos == TCP ? "tcp" : protos == UDP ? "udp" : 0); 118 if (sp) { 119 selectport(sp->s_port, onoff); 120 continue; 121 } 122 hp = gethostbyname(args); 123 if (hp == 0) { 124 in.s_addr = inet_addr(args); 125 if (in.s_addr == -1) { 126 error("%s: unknown host or port", args); 127 continue; 128 } 129 } else 130 in = *(struct in_addr *)hp->h_addr; 131 selecthost(&in, onoff); 132 } 133 } 134 135 static int 136 selectproto(proto) 137 char *proto; 138 { 139 int new = protos; 140 141 if (proto == 0 || streq(proto, "all")) 142 new = TCP|UDP; 143 else if (streq(proto, "tcp")) 144 new = TCP; 145 else if (streq(proto, "udp")) 146 new = UDP; 147 return (new != protos, protos = new); 148 } 149 150 static void 151 showprotos() 152 { 153 154 if ((protos&TCP) == 0) 155 addch('!'); 156 addstr("tcp "); 157 if ((protos&UDP) == 0) 158 addch('!'); 159 addstr("udp "); 160 } 161 162 static struct pitem { 163 long port; 164 int onoff; 165 } *ports; 166 167 static int 168 selectport(port, onoff) 169 long port; 170 int onoff; 171 { 172 register struct pitem *p; 173 174 if (port == -1) { 175 if (ports == 0) 176 return (0); 177 free((char *)ports), ports = 0; 178 nports = 0; 179 return (1); 180 } 181 for (p = ports; p < ports+nports; p++) 182 if (p->port == port) { 183 p->onoff = onoff; 184 return (0); 185 } 186 if (nports == 0) 187 ports = (struct pitem *)malloc(sizeof (*p)); 188 else 189 ports = (struct pitem *)realloc(ports, (nports+1)*sizeof (*p)); 190 p = &ports[nports++]; 191 p->port = port; 192 p->onoff = onoff; 193 return (1); 194 } 195 196 int 197 checkport(inp) 198 register struct inpcb *inp; 199 { 200 register struct pitem *p; 201 202 if (ports) 203 for (p = ports; p < ports+nports; p++) 204 if (p->port == inp->inp_lport || p->port == inp->inp_fport) 205 return (p->onoff); 206 return (1); 207 } 208 209 static void 210 showports() 211 { 212 register struct pitem *p; 213 struct servent *sp; 214 215 for (p = ports; p < ports+nports; p++) { 216 sp = getservbyport(p->port, 217 protos == TCP|UDP ? 0 : protos == TCP ? "tcp" : "udp"); 218 if (!p->onoff) 219 addch('!'); 220 if (sp) 221 printw("%s ", sp->s_name); 222 else 223 printw("%d ", p->port); 224 } 225 } 226 227 static int 228 selecthost(in, onoff) 229 struct in_addr *in; 230 int onoff; 231 { 232 register struct hitem *p; 233 234 if (in == 0) { 235 if (hosts == 0) 236 return (0); 237 free((char *)hosts), hosts = 0; 238 nhosts = 0; 239 return (1); 240 } 241 for (p = hosts; p < hosts+nhosts; p++) 242 if (p->addr.s_addr == in->s_addr) { 243 p->onoff = onoff; 244 return (0); 245 } 246 if (nhosts == 0) 247 hosts = (struct hitem *)malloc(sizeof (*p)); 248 else 249 hosts = (struct hitem *)realloc(hosts, (nhosts+1)*sizeof (*p)); 250 p = &hosts[nhosts++]; 251 p->addr = *in; 252 p->onoff = onoff; 253 return (1); 254 } 255 256 int 257 checkhost(inp) 258 register struct inpcb *inp; 259 { 260 register struct hitem *p; 261 262 if (hosts) 263 for (p = hosts; p < hosts+nhosts; p++) 264 if (p->addr.s_addr == inp->inp_laddr.s_addr || 265 p->addr.s_addr == inp->inp_faddr.s_addr) 266 return (p->onoff); 267 return (1); 268 } 269 270 static void 271 showhosts() 272 { 273 register struct hitem *p; 274 struct hostent *hp; 275 276 for (p = hosts; p < hosts+nhosts; p++) { 277 hp = gethostbyaddr((char *)&p->addr, sizeof (p->addr), AF_INET); 278 if (!p->onoff) 279 addch('!'); 280 printw("%s ", hp ? hp->h_name : (char *)inet_ntoa(p->addr)); 281 } 282 } 283