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