Sun Feb 22 07:43:01 2009 UTC ()
Make netstat handle -a properly; that is, don't show unconnected
listener sockets unless -a was given. (It was checking the local
address instead of the remote address for being INADDR_ANY or
equivalent.)

PR 38093 from Dieter Roelants; I adjusted the patch a little.

This needs pullups for both -4 and -5.


(dholland)
diff -r1.88 -r1.89 src/usr.bin/netstat/inet.c
diff -r1.50 -r1.51 src/usr.bin/netstat/inet6.c
diff -r1.30 -r1.31 src/usr.bin/netstat/iso.c

cvs diff -r1.88 -r1.89 src/usr.bin/netstat/inet.c (expand / switch to unified diff)

--- src/usr.bin/netstat/inet.c 2008/04/24 04:09:27 1.88
+++ src/usr.bin/netstat/inet.c 2009/02/22 07:43:01 1.89
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: inet.c,v 1.88 2008/04/24 04:09:27 thorpej Exp $ */ 1/* $NetBSD: inet.c,v 1.89 2009/02/22 07:43:01 dholland Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1983, 1988, 1993 4 * Copyright (c) 1983, 1988, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 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 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 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34#if 0 34#if 0
35static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94"; 35static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94";
36#else 36#else
37__RCSID("$NetBSD: inet.c,v 1.88 2008/04/24 04:09:27 thorpej Exp $"); 37__RCSID("$NetBSD: inet.c,v 1.89 2009/02/22 07:43:01 dholland Exp $");
38#endif 38#endif
39#endif /* not lint */ 39#endif /* not lint */
40 40
41#define _CALLOUT_PRIVATE /* for defs in sys/callout.h */ 41#define _CALLOUT_PRIVATE /* for defs in sys/callout.h */
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/queue.h> 44#include <sys/queue.h>
45#include <sys/socket.h> 45#include <sys/socket.h>
46#include <sys/socketvar.h> 46#include <sys/socketvar.h>
47#include <sys/mbuf.h> 47#include <sys/mbuf.h>
48#include <sys/protosw.h> 48#include <sys/protosw.h>
49#include <sys/sysctl.h> 49#include <sys/sysctl.h>
50 50
@@ -205,26 +205,30 @@ protopr(u_long off, char *name) @@ -205,26 +205,30 @@ protopr(u_long off, char *name)
205 mib[6] = sizeof(*pcblist); 205 mib[6] = sizeof(*pcblist);
206 mib[7] = size / sizeof(*pcblist); 206 mib[7] = size / sizeof(*pcblist);
207 207
208 if (sysctl(mib, sizeof(mib) / sizeof(*mib), pcblist, 208 if (sysctl(mib, sizeof(mib) / sizeof(*mib), pcblist,
209 &size, NULL, 0) == -1) 209 &size, NULL, 0) == -1)
210 err(1, "sysctl (copy)"); 210 err(1, "sysctl (copy)");
211 211
212 for (i = 0; i < size / sizeof(*pcblist); i++) { 212 for (i = 0; i < size / sizeof(*pcblist); i++) {
213 struct sockaddr_in src, dst; 213 struct sockaddr_in src, dst;
214 214
215 memcpy(&src, &pcblist[i].ki_s, sizeof(src)); 215 memcpy(&src, &pcblist[i].ki_s, sizeof(src));
216 memcpy(&dst, &pcblist[i].ki_d, sizeof(dst)); 216 memcpy(&dst, &pcblist[i].ki_d, sizeof(dst));
217 217
 218 if (!aflag &&
 219 inet_lnaof(dst.sin_addr) == INADDR_ANY)
 220 continue;
 221
218 if (first) { 222 if (first) {
219 protoprhdr(); 223 protoprhdr();
220 first = 0; 224 first = 0;
221 } 225 }
222 226
223 protopr0((intptr_t) pcblist[i].ki_ppcbaddr, 227 protopr0((intptr_t) pcblist[i].ki_ppcbaddr,
224 pcblist[i].ki_rcvq, pcblist[i].ki_sndq, 228 pcblist[i].ki_rcvq, pcblist[i].ki_sndq,
225 &src.sin_addr, src.sin_port, 229 &src.sin_addr, src.sin_port,
226 &dst.sin_addr, dst.sin_port, 230 &dst.sin_addr, dst.sin_port,
227 pcblist[i].ki_tstate, name); 231 pcblist[i].ki_tstate, name);
228 } 232 }
229 233
230 free(pcblist); 234 free(pcblist);
@@ -242,27 +246,27 @@ protopr(u_long off, char *name) @@ -242,27 +246,27 @@ protopr(u_long off, char *name)
242 while (next != head) { 246 while (next != head) {
243 kread((u_long)next, (char *)&inpcb, sizeof inpcb); 247 kread((u_long)next, (char *)&inpcb, sizeof inpcb);
244 if ((struct inpcb *)inpcb.inp_queue.cqe_prev != prev) { 248 if ((struct inpcb *)inpcb.inp_queue.cqe_prev != prev) {
245 printf("???\n"); 249 printf("???\n");
246 break; 250 break;
247 } 251 }
248 prev = next; 252 prev = next;
249 next = (struct inpcb *)inpcb.inp_queue.cqe_next; 253 next = (struct inpcb *)inpcb.inp_queue.cqe_next;
250 254
251 if (inpcb.inp_af != AF_INET) 255 if (inpcb.inp_af != AF_INET)
252 continue; 256 continue;
253 257
254 if (!aflag && 258 if (!aflag &&
255 inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) 259 inet_lnaof(inpcb.inp_faddr) == INADDR_ANY)
256 continue; 260 continue;
257 kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb)); 261 kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb));
258 if (istcp) { 262 if (istcp) {
259 kread((u_long)inpcb.inp_ppcb, 263 kread((u_long)inpcb.inp_ppcb,
260 (char *)&tcpcb, sizeof (tcpcb)); 264 (char *)&tcpcb, sizeof (tcpcb));
261 } 265 }
262 266
263 if (first) { 267 if (first) {
264 protoprhdr(); 268 protoprhdr();
265 first = 0; 269 first = 0;
266 } 270 }
267 271
268 protopr0(istcp ? (intptr_t) inpcb.inp_ppcb : (intptr_t) prev, 272 protopr0(istcp ? (intptr_t) inpcb.inp_ppcb : (intptr_t) prev,

cvs diff -r1.50 -r1.51 src/usr.bin/netstat/inet6.c (expand / switch to unified diff)

--- src/usr.bin/netstat/inet6.c 2008/04/24 04:09:27 1.50
+++ src/usr.bin/netstat/inet6.c 2009/02/22 07:43:01 1.51
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: inet6.c,v 1.50 2008/04/24 04:09:27 thorpej Exp $ */ 1/* $NetBSD: inet6.c,v 1.51 2009/02/22 07:43:01 dholland Exp $ */
2/* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */ 2/* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 *  7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -54,27 +54,27 @@ @@ -54,27 +54,27 @@
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE. 59 * SUCH DAMAGE.
60 */ 60 */
61 61
62#include <sys/cdefs.h> 62#include <sys/cdefs.h>
63#ifndef lint 63#ifndef lint
64#if 0 64#if 0
65static char sccsid[] = "@(#)inet.c 8.4 (Berkeley) 4/20/94"; 65static char sccsid[] = "@(#)inet.c 8.4 (Berkeley) 4/20/94";
66#else 66#else
67__RCSID("$NetBSD: inet6.c,v 1.50 2008/04/24 04:09:27 thorpej Exp $"); 67__RCSID("$NetBSD: inet6.c,v 1.51 2009/02/22 07:43:01 dholland Exp $");
68#endif 68#endif
69#endif /* not lint */ 69#endif /* not lint */
70 70
71#include <sys/param.h> 71#include <sys/param.h>
72#include <sys/socket.h> 72#include <sys/socket.h>
73#include <sys/socketvar.h> 73#include <sys/socketvar.h>
74#include <sys/ioctl.h> 74#include <sys/ioctl.h>
75#include <sys/mbuf.h> 75#include <sys/mbuf.h>
76#include <sys/protosw.h> 76#include <sys/protosw.h>
77#include <sys/sysctl.h> 77#include <sys/sysctl.h>
78 78
79#include <net/route.h> 79#include <net/route.h>
80#include <net/if.h> 80#include <net/if.h>
@@ -263,26 +263,29 @@ ip6protopr(u_long off, char *name) @@ -263,26 +263,29 @@ ip6protopr(u_long off, char *name)
263 mib[6] = sizeof(*pcblist); 263 mib[6] = sizeof(*pcblist);
264 mib[7] = size / sizeof(*pcblist); 264 mib[7] = size / sizeof(*pcblist);
265 265
266 if (sysctl(mib, sizeof(mib) / sizeof(*mib), pcblist, 266 if (sysctl(mib, sizeof(mib) / sizeof(*mib), pcblist,
267 &size, NULL, 0) == -1) 267 &size, NULL, 0) == -1)
268 err(1, "sysctl (copy)"); 268 err(1, "sysctl (copy)");
269 269
270 for (i = 0; i < size / sizeof(*pcblist); i++) { 270 for (i = 0; i < size / sizeof(*pcblist); i++) {
271 struct sockaddr_in6 src, dst; 271 struct sockaddr_in6 src, dst;
272 272
273 memcpy(&src, &pcblist[i].ki_s, sizeof(src)); 273 memcpy(&src, &pcblist[i].ki_s, sizeof(src));
274 memcpy(&dst, &pcblist[i].ki_d, sizeof(dst)); 274 memcpy(&dst, &pcblist[i].ki_d, sizeof(dst));
275 275
 276 if (!aflag && IN6_IS_ADDR_UNSPECIFIED(&dst.sin6_addr))
 277 continue;
 278
276 if (first) { 279 if (first) {
277 ip6protoprhdr(); 280 ip6protoprhdr();
278 first = 0; 281 first = 0;
279 } 282 }
280 283
281 ip6protopr0((intptr_t) pcblist[i].ki_ppcbaddr, 284 ip6protopr0((intptr_t) pcblist[i].ki_ppcbaddr,
282 pcblist[i].ki_rcvq, pcblist[i].ki_sndq, 285 pcblist[i].ki_rcvq, pcblist[i].ki_sndq,
283 &src.sin6_addr, src.sin6_port, 286 &src.sin6_addr, src.sin6_port,
284 &dst.sin6_addr, dst.sin6_port, 287 &dst.sin6_addr, dst.sin6_port,
285 pcblist[i].ki_tstate, name); 288 pcblist[i].ki_tstate, name);
286 } 289 }
287 290
288 free(pcblist); 291 free(pcblist);
@@ -299,27 +302,27 @@ ip6protopr(u_long off, char *name) @@ -299,27 +302,27 @@ ip6protopr(u_long off, char *name)
299 302
300 while (next != head) { 303 while (next != head) {
301 kread((u_long)next, (char *)&in6pcb, sizeof in6pcb); 304 kread((u_long)next, (char *)&in6pcb, sizeof in6pcb);
302 if ((struct in6pcb *)in6pcb.in6p_queue.cqe_prev != prev) { 305 if ((struct in6pcb *)in6pcb.in6p_queue.cqe_prev != prev) {
303 printf("???\n"); 306 printf("???\n");
304 break; 307 break;
305 } 308 }
306 prev = next; 309 prev = next;
307 next = (struct in6pcb *)in6pcb.in6p_queue.cqe_next; 310 next = (struct in6pcb *)in6pcb.in6p_queue.cqe_next;
308 311
309 if (in6pcb.in6p_af != AF_INET6) 312 if (in6pcb.in6p_af != AF_INET6)
310 continue; 313 continue;
311 314
312 if (!aflag && IN6_IS_ADDR_UNSPECIFIED(&in6pcb.in6p_laddr)) 315 if (!aflag && IN6_IS_ADDR_UNSPECIFIED(&in6pcb.in6p_faddr))
313 continue; 316 continue;
314 kread((u_long)in6pcb.in6p_socket, (char *)&sockb,  317 kread((u_long)in6pcb.in6p_socket, (char *)&sockb,
315 sizeof (sockb)); 318 sizeof (sockb));
316 if (istcp) { 319 if (istcp) {
317#ifdef TCP6 320#ifdef TCP6
318 kread((u_long)in6pcb.in6p_ppcb, 321 kread((u_long)in6pcb.in6p_ppcb,
319 (char *)&tcp6cb, sizeof (tcp6cb)); 322 (char *)&tcp6cb, sizeof (tcp6cb));
320#else 323#else
321 kread((u_long)in6pcb.in6p_ppcb, 324 kread((u_long)in6pcb.in6p_ppcb,
322 (char *)&tcpcb, sizeof (tcpcb)); 325 (char *)&tcpcb, sizeof (tcpcb));
323#endif 326#endif
324 } 327 }
325 if (first) { 328 if (first) {

cvs diff -r1.30 -r1.31 src/usr.bin/netstat/Attic/iso.c (expand / switch to unified diff)

--- src/usr.bin/netstat/Attic/iso.c 2008/04/23 08:26:47 1.30
+++ src/usr.bin/netstat/Attic/iso.c 2009/02/22 07:43:01 1.31
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: iso.c,v 1.30 2008/04/23 08:26:47 plunky Exp $ */ 1/* $NetBSD: iso.c,v 1.31 2009/02/22 07:43:01 dholland Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1983, 1988, 1993 4 * Copyright (c) 1983, 1988, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 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 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 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34#if 0 34#if 0
35static char sccsid[] = "from: @(#)iso.c 8.1 (Berkeley) 6/6/93"; 35static char sccsid[] = "from: @(#)iso.c 8.1 (Berkeley) 6/6/93";
36#else 36#else
37__RCSID("$NetBSD: iso.c,v 1.30 2008/04/23 08:26:47 plunky Exp $"); 37__RCSID("$NetBSD: iso.c,v 1.31 2009/02/22 07:43:01 dholland Exp $");
38#endif 38#endif
39#endif /* not lint */ 39#endif /* not lint */
40 40
41/******************************************************************************* 41/*******************************************************************************
42 Copyright IBM Corporation 1987 42 Copyright IBM Corporation 1987
43 43
44 All Rights Reserved 44 All Rights Reserved
45 45
46Permission to use, copy, modify, and distribute this software and its 46Permission to use, copy, modify, and distribute this software and its
47documentation for any purpose and without fee is hereby granted, 47documentation for any purpose and without fee is hereby granted,
48provided that the above copyright notice appear in all copies and that 48provided that the above copyright notice appear in all copies and that
49both that copyright notice and this permission notice appear in 49both that copyright notice and this permission notice appear in
50supporting documentation, and that the name of IBM not be 50supporting documentation, and that the name of IBM not be
@@ -362,27 +362,27 @@ tp_protopr(off, name) @@ -362,27 +362,27 @@ tp_protopr(off, name)
362 printf(" %-12.12s", tp_sstring[tpcb.tp_state]); 362 printf(" %-12.12s", tp_sstring[tpcb.tp_state]);
363 putchar('\n'); 363 putchar('\n');
364 } 364 }
365 free(tpr_base); 365 free(tpr_base);
366} 366}
367 367
368void 368void
369tp_inproto(pcb) 369tp_inproto(pcb)
370 u_long pcb; 370 u_long pcb;
371{ 371{
372 struct inpcb inpcb; 372 struct inpcb inpcb;
373 373
374 kget(tpcb.tp_npcb, inpcb); 374 kget(tpcb.tp_npcb, inpcb);
375 if (!aflag && inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) 375 if (!aflag && inet_lnaof(inpcb.inp_faddr) == INADDR_ANY)
376 return; 376 return;
377 if (Aflag) 377 if (Aflag)
378 printf("%8lx ", pcb); 378 printf("%8lx ", pcb);
379 printf("%-5.5s %6ld %6ld ", "tpip", 379 printf("%-5.5s %6ld %6ld ", "tpip",
380 sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); 380 sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc);
381 inetprint(&inpcb.inp_laddr, inpcb.inp_lport, "tp", 1); 381 inetprint(&inpcb.inp_laddr, inpcb.inp_lport, "tp", 1);
382 inetprint(&inpcb.inp_faddr, inpcb.inp_fport, "tp", 1); 382 inetprint(&inpcb.inp_faddr, inpcb.inp_fport, "tp", 1);
383} 383}
384 384
385/* 385/*
386 * Pretty print an iso address (net address + port). 386 * Pretty print an iso address (net address + port).
387 * If the numeric_addr or numeric_port were specified, 387 * If the numeric_addr or numeric_port were specified,
388 * use numbers instead of names. 388 * use numbers instead of names.