1 /* $NetBSD: netcmds.c,v 1.20 2004/11/04 07:18:47 dsl Exp $ */
4 * Copyright (c) 1980, 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "@(#)netcmds.c 8.1 (Berkeley) 6/6/93";
37 __RCSID("$NetBSD: netcmds.c,v 1.20 2004/11/04 07:18:47 dsl Exp $");
41 * Common network command support routines.
43 #include <sys/param.h>
45 #include <sys/protosw.h>
47 #include <net/route.h>
48 #include <netinet/in.h>
49 #include <netinet/in_systm.h>
50 #include <netinet/ip.h>
51 #include <netinet/in_pcb.h>
53 #include <netinet/ip6.h>
54 #include <netinet6/in6_pcb.h>
57 #include <arpa/inet.h>
67 #define streq(a,b) (strcmp(a,b)==0)
70 struct sockaddr_storage addr
;
74 int nports
, nhosts
, protos
;
76 static void changeitems(char *, int);
77 static void selectproto(const char *);
78 static void showprotos(void);
79 static int selectport(long, int);
80 static void showports(void);
81 static int addrcmp(struct sockaddr
*, struct sockaddr
*);
82 static int selecthost(struct sockaddr
*, int);
83 static void showhosts(void);
85 /* please note: there are also some netstat commands in netstat.c */
88 netstat_display(char *args
)
94 netstat_ignore(char *args
)
100 netstat_reset(char *args
)
108 netstat_show(char *args
)
110 move(CMDLINE
, 0); clrtoeol();
111 if (!args
|| *args
== '\0') {
117 if (strstr(args
, "protos") == args
)
119 else if (strstr(args
, "hosts") == args
)
121 else if (strstr(args
, "ports") == args
)
124 addstr("show what?");
128 netstat_tcp(char *args
)
134 netstat_udp(char *args
)
140 changeitems(char *args
, int onoff
)
144 struct addrinfo hints
, *res
, *res0
;
146 cp
= strchr(args
, '\n');
150 for (cp
= args
; *cp
&& isspace((unsigned char)*cp
); cp
++)
153 for (; *cp
&& !isspace((unsigned char)*cp
); cp
++)
159 sp
= getservbyname(args
,
160 protos
== TCP
? "tcp" : protos
== UDP
? "udp" : 0);
162 selectport(sp
->s_port
, onoff
);
166 memset(&hints
, 0, sizeof(hints
));
167 hints
.ai_family
= PF_UNSPEC
;
168 hints
.ai_socktype
= SOCK_DGRAM
;
169 if (getaddrinfo(args
, "0", &hints
, &res0
) != 0) {
170 error("%s: unknown host or port", args
);
173 for (res
= res0
; res
; res
= res
->ai_next
)
174 selecthost(res
->ai_addr
, onoff
);
180 selectproto(const char *proto
)
183 if (proto
== 0 || streq(proto
, "all"))
185 else if (streq(proto
, "tcp"))
187 else if (streq(proto
, "udp"))
195 if ((protos
& TCP
) == 0)
198 if ((protos
& UDP
) == 0)
203 static struct pitem
{
209 selectport(long port
, int onoff
)
221 for (p
= ports
; p
< ports
+nports
; p
++)
222 if (p
->port
== port
) {
226 p
= (struct pitem
*)realloc(ports
, (nports
+1)*sizeof (*p
));
228 error("malloc failed");
232 p
= &ports
[nports
++];
239 checkport(struct inpcb
*inp
)
244 for (p
= ports
; p
< ports
+nports
; p
++)
245 if (p
->port
== inp
->inp_lport
|| p
->port
== inp
->inp_fport
)
252 checkport6(struct in6pcb
*in6p
)
257 for (p
= ports
; p
< ports
+nports
; p
++)
258 if (p
->port
== in6p
->in6p_lport
|| p
->port
== in6p
->in6p_fport
)
270 for (p
= ports
; p
< ports
+nports
; p
++) {
271 sp
= getservbyport(p
->port
,
272 protos
== (TCP
|UDP
) ? 0 : protos
== TCP
? "tcp" : "udp");
276 printw("%s ", sp
->s_name
);
278 printw("%ld ", p
->port
);
283 addrcmp(struct sockaddr
*sa1
, struct sockaddr
*sa2
)
285 if (sa1
->sa_family
!= sa2
->sa_family
)
287 if (sa1
->sa_len
!= sa2
->sa_len
)
289 switch (sa1
->sa_family
) {
291 if (((struct sockaddr_in
*)sa1
)->sin_addr
.s_addr
==
292 ((struct sockaddr_in
*)sa2
)->sin_addr
.s_addr
)
297 if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6
*)sa1
)->sin6_addr
,
298 &((struct sockaddr_in6
*)sa2
)->sin6_addr
))
303 if (memcmp(sa1
, sa2
, sa1
->sa_len
) == 0)
311 selecthost(struct sockaddr
*sa
, int onoff
)
318 free((char *)hosts
), hosts
= 0;
322 for (p
= hosts
; p
< hosts
+nhosts
; p
++)
323 if (addrcmp((struct sockaddr
*)&p
->addr
, sa
)) {
327 if (sa
->sa_len
> sizeof(struct sockaddr_storage
))
329 p
= (struct hitem
*)realloc(hosts
, (nhosts
+1)*sizeof (*p
));
331 error("malloc failed");
335 p
= &hosts
[nhosts
++];
336 memcpy(&p
->addr
, sa
, sa
->sa_len
);
342 checkhost(struct inpcb
*inp
)
345 struct sockaddr_in
*s_in
;
348 for (p
= hosts
; p
< hosts
+nhosts
; p
++) {
349 if (((struct sockaddr
*)&p
->addr
)->sa_family
!= AF_INET
)
351 s_in
= (struct sockaddr_in
*)&p
->addr
;
352 if (s_in
->sin_addr
.s_addr
== inp
->inp_laddr
.s_addr
||
353 s_in
->sin_addr
.s_addr
== inp
->inp_faddr
.s_addr
)
361 checkhost6(struct in6pcb
*in6p
)
364 struct sockaddr_in6
*sin6
;
367 for (p
= hosts
; p
< hosts
+nhosts
; p
++) {
368 if (((struct sockaddr
*)&p
->addr
)->sa_family
!= AF_INET6
)
370 sin6
= (struct sockaddr_in6
*)&p
->addr
;
371 if (IN6_ARE_ADDR_EQUAL(&sin6
->sin6_addr
, &in6p
->in6p_laddr
) ||
372 IN6_ARE_ADDR_EQUAL(&sin6
->sin6_addr
, &in6p
->in6p_faddr
))
383 char hbuf
[NI_MAXHOST
];
388 flags
= nflag
? NI_NUMERICHOST
: 0;
392 for (p
= hosts
; p
< hosts
+nhosts
; p
++) {
393 sa
= (struct sockaddr
*)&p
->addr
;
394 if (getnameinfo(sa
, sa
->sa_len
, hbuf
, sizeof(hbuf
), NULL
, 0,
396 strlcpy(hbuf
, "(invalid)", sizeof(hbuf
));