Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/networking/netstat.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
File MIME type: text/plain
File size: 16357 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 niro 532 /* vi: set sw=4 ts=4: */
2     /*
3     * Mini netstat implementation(s) for busybox
4     * based in part on the netstat implementation from net-tools.
5     *
6     * Copyright (C) 2002 by Bart Visscher <magick@linux-fan.com>
7     *
8     * 2002-04-20
9     * IPV6 support added by Bart Visscher <magick@linux-fan.com>
10     *
11     * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
12     */
13    
14     #include "busybox.h"
15     #include "inet_common.h"
16    
17     #ifdef CONFIG_ROUTE
18     extern void displayroutes(int noresolve, int netstatfmt);
19     #endif
20    
21     #define NETSTAT_CONNECTED 0x01
22     #define NETSTAT_LISTENING 0x02
23     #define NETSTAT_NUMERIC 0x04
24     /* Must match getopt32 option string */
25     #define NETSTAT_TCP 0x10
26     #define NETSTAT_UDP 0x20
27     #define NETSTAT_RAW 0x40
28     #define NETSTAT_UNIX 0x80
29     #define NETSTAT_ALLPROTO (NETSTAT_TCP|NETSTAT_UDP|NETSTAT_RAW|NETSTAT_UNIX)
30    
31     static int flags = NETSTAT_CONNECTED | NETSTAT_ALLPROTO;
32    
33     #define PROGNAME_WIDTHs PROGNAME_WIDTH1(PROGNAME_WIDTH)
34     #define PROGNAME_WIDTH1(s) PROGNAME_WIDTH2(s)
35     #define PROGNAME_WIDTH2(s) #s
36    
37     #define PRG_HASH_SIZE 211
38    
39     enum {
40     TCP_ESTABLISHED = 1,
41     TCP_SYN_SENT,
42     TCP_SYN_RECV,
43     TCP_FIN_WAIT1,
44     TCP_FIN_WAIT2,
45     TCP_TIME_WAIT,
46     TCP_CLOSE,
47     TCP_CLOSE_WAIT,
48     TCP_LAST_ACK,
49     TCP_LISTEN,
50     TCP_CLOSING /* now a valid state */
51     };
52    
53     static const char * const tcp_state[] =
54     {
55     "",
56     "ESTABLISHED",
57     "SYN_SENT",
58     "SYN_RECV",
59     "FIN_WAIT1",
60     "FIN_WAIT2",
61     "TIME_WAIT",
62     "CLOSE",
63     "CLOSE_WAIT",
64     "LAST_ACK",
65     "LISTEN",
66     "CLOSING"
67     };
68    
69     typedef enum {
70     SS_FREE = 0, /* not allocated */
71     SS_UNCONNECTED, /* unconnected to any socket */
72     SS_CONNECTING, /* in process of connecting */
73     SS_CONNECTED, /* connected to socket */
74     SS_DISCONNECTING /* in process of disconnecting */
75     } socket_state;
76    
77     #define SO_ACCEPTCON (1<<16) /* performed a listen */
78     #define SO_WAITDATA (1<<17) /* wait data to read */
79     #define SO_NOSPACE (1<<18) /* no space to write */
80    
81     static char *get_sname(int port, const char *proto, int num)
82     {
83     char *str=itoa(ntohs(port));
84     if (num) {
85     } else {
86     struct servent *se=getservbyport(port,proto);
87     if (se)
88     str=se->s_name;
89     }
90     if (!port) {
91     str="*";
92     }
93     return str;
94     }
95    
96     static void snprint_ip_port(char *ip_port, int size, struct sockaddr *addr, int port, char *proto, int numeric)
97     {
98     char *port_name;
99    
100     #ifdef CONFIG_FEATURE_IPV6
101     if (addr->sa_family == AF_INET6) {
102     INET6_rresolve(ip_port, size, (struct sockaddr_in6 *)addr,
103     (numeric&NETSTAT_NUMERIC) ? 0x0fff : 0);
104     } else
105     #endif
106     {
107     INET_rresolve(ip_port, size, (struct sockaddr_in *)addr,
108     0x4000 | ((numeric&NETSTAT_NUMERIC) ? 0x0fff : 0),
109     0xffffffff);
110     }
111     port_name=get_sname(htons(port), proto, numeric);
112     if ((strlen(ip_port) + strlen(port_name)) > 22)
113     ip_port[22 - strlen(port_name)] = '\0';
114     ip_port+=strlen(ip_port);
115     strcat(ip_port, ":");
116     strcat(ip_port, port_name);
117     }
118    
119     static void tcp_do_one(int lnr, const char *line)
120     {
121     char local_addr[64], rem_addr[64];
122     const char *state_str;
123     char more[512];
124     int num, local_port, rem_port, d, state, timer_run, uid, timeout;
125     #ifdef CONFIG_FEATURE_IPV6
126     struct sockaddr_in6 localaddr, remaddr;
127     char addr6[INET6_ADDRSTRLEN];
128     struct in6_addr in6;
129     #else
130     struct sockaddr_in localaddr, remaddr;
131     #endif
132     unsigned long rxq, txq, time_len, retr, inode;
133    
134     if (lnr == 0)
135     return;
136    
137     more[0] = '\0';
138     num = sscanf(line,
139     "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %ld %512s\n",
140     &d, local_addr, &local_port,
141     rem_addr, &rem_port, &state,
142     &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
143    
144     if (strlen(local_addr) > 8) {
145     #ifdef CONFIG_FEATURE_IPV6
146     sscanf(local_addr, "%08X%08X%08X%08X",
147     &in6.s6_addr32[0], &in6.s6_addr32[1],
148     &in6.s6_addr32[2], &in6.s6_addr32[3]);
149     inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
150     inet_pton(AF_INET6, addr6, (struct sockaddr *) &localaddr.sin6_addr);
151     sscanf(rem_addr, "%08X%08X%08X%08X",
152     &in6.s6_addr32[0], &in6.s6_addr32[1],
153     &in6.s6_addr32[2], &in6.s6_addr32[3]);
154     inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
155     inet_pton(AF_INET6, addr6, (struct sockaddr *) &remaddr.sin6_addr);
156     localaddr.sin6_family = AF_INET6;
157     remaddr.sin6_family = AF_INET6;
158     #endif
159     } else {
160     sscanf(local_addr, "%X",
161     &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
162     sscanf(rem_addr, "%X",
163     &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
164     ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
165     ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
166     }
167    
168     if (num < 10) {
169     bb_error_msg("warning, got bogus tcp line");
170     return;
171     }
172     state_str = tcp_state[state];
173     if ((rem_port && (flags&NETSTAT_CONNECTED)) ||
174     (!rem_port && (flags&NETSTAT_LISTENING)))
175     {
176     snprint_ip_port(local_addr, sizeof(local_addr),
177     (struct sockaddr *) &localaddr, local_port,
178     "tcp", flags&NETSTAT_NUMERIC);
179    
180     snprint_ip_port(rem_addr, sizeof(rem_addr),
181     (struct sockaddr *) &remaddr, rem_port,
182     "tcp", flags&NETSTAT_NUMERIC);
183    
184     printf("tcp %6ld %6ld %-23s %-23s %-12s\n",
185     rxq, txq, local_addr, rem_addr, state_str);
186    
187     }
188     }
189    
190     static void udp_do_one(int lnr, const char *line)
191     {
192     char local_addr[64], rem_addr[64];
193     char *state_str, more[512];
194     int num, local_port, rem_port, d, state, timer_run, uid, timeout;
195     #ifdef CONFIG_FEATURE_IPV6
196     struct sockaddr_in6 localaddr, remaddr;
197     char addr6[INET6_ADDRSTRLEN];
198     struct in6_addr in6;
199     #else
200     struct sockaddr_in localaddr, remaddr;
201     #endif
202     unsigned long rxq, txq, time_len, retr, inode;
203    
204     if (lnr == 0)
205     return;
206    
207     more[0] = '\0';
208     num = sscanf(line,
209     "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %ld %512s\n",
210     &d, local_addr, &local_port,
211     rem_addr, &rem_port, &state,
212     &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
213    
214     if (strlen(local_addr) > 8) {
215     #ifdef CONFIG_FEATURE_IPV6
216     /* Demangle what the kernel gives us */
217     sscanf(local_addr, "%08X%08X%08X%08X",
218     &in6.s6_addr32[0], &in6.s6_addr32[1],
219     &in6.s6_addr32[2], &in6.s6_addr32[3]);
220     inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
221     inet_pton(AF_INET6, addr6, (struct sockaddr *) &localaddr.sin6_addr);
222     sscanf(rem_addr, "%08X%08X%08X%08X",
223     &in6.s6_addr32[0], &in6.s6_addr32[1],
224     &in6.s6_addr32[2], &in6.s6_addr32[3]);
225     inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
226     inet_pton(AF_INET6, addr6, (struct sockaddr *) &remaddr.sin6_addr);
227     localaddr.sin6_family = AF_INET6;
228     remaddr.sin6_family = AF_INET6;
229     #endif
230     } else {
231     sscanf(local_addr, "%X",
232     &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
233     sscanf(rem_addr, "%X",
234     &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
235     ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
236     ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
237     }
238    
239     if (num < 10) {
240     bb_error_msg("warning, got bogus udp line");
241     return;
242     }
243     switch (state) {
244     case TCP_ESTABLISHED:
245     state_str = "ESTABLISHED";
246     break;
247    
248     case TCP_CLOSE:
249     state_str = "";
250     break;
251    
252     default:
253     state_str = "UNKNOWN";
254     break;
255     }
256    
257     #ifdef CONFIG_FEATURE_IPV6
258     # define notnull(A) (((A.sin6_family == AF_INET6) && \
259     ((A.sin6_addr.s6_addr32[0]) || \
260     (A.sin6_addr.s6_addr32[1]) || \
261     (A.sin6_addr.s6_addr32[2]) || \
262     (A.sin6_addr.s6_addr32[3]))) || \
263     ((A.sin6_family == AF_INET) && \
264     ((struct sockaddr_in *) &A)->sin_addr.s_addr))
265     #else
266     # define notnull(A) (A.sin_addr.s_addr)
267     #endif
268     if ((notnull(remaddr) && (flags&NETSTAT_CONNECTED)) ||
269     (!notnull(remaddr) && (flags&NETSTAT_LISTENING)))
270     {
271     snprint_ip_port(local_addr, sizeof(local_addr),
272     (struct sockaddr *) &localaddr, local_port,
273     "udp", flags&NETSTAT_NUMERIC);
274    
275     snprint_ip_port(rem_addr, sizeof(rem_addr),
276     (struct sockaddr *) &remaddr, rem_port,
277     "udp", flags&NETSTAT_NUMERIC);
278    
279     printf("udp %6ld %6ld %-23s %-23s %-12s\n",
280     rxq, txq, local_addr, rem_addr, state_str);
281    
282     }
283     }
284    
285     static void raw_do_one(int lnr, const char *line)
286     {
287     char local_addr[64], rem_addr[64];
288     char *state_str, more[512];
289     int num, local_port, rem_port, d, state, timer_run, uid, timeout;
290     #ifdef CONFIG_FEATURE_IPV6
291     struct sockaddr_in6 localaddr, remaddr;
292     char addr6[INET6_ADDRSTRLEN];
293     struct in6_addr in6;
294     #else
295     struct sockaddr_in localaddr, remaddr;
296     #endif
297     unsigned long rxq, txq, time_len, retr, inode;
298    
299     if (lnr == 0)
300     return;
301    
302     more[0] = '\0';
303     num = sscanf(line,
304     "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %ld %512s\n",
305     &d, local_addr, &local_port,
306     rem_addr, &rem_port, &state,
307     &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
308    
309     if (strlen(local_addr) > 8) {
310     #ifdef CONFIG_FEATURE_IPV6
311     sscanf(local_addr, "%08X%08X%08X%08X",
312     &in6.s6_addr32[0], &in6.s6_addr32[1],
313     &in6.s6_addr32[2], &in6.s6_addr32[3]);
314     inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
315     inet_pton(AF_INET6, addr6, (struct sockaddr *) &localaddr.sin6_addr);
316     sscanf(rem_addr, "%08X%08X%08X%08X",
317     &in6.s6_addr32[0], &in6.s6_addr32[1],
318     &in6.s6_addr32[2], &in6.s6_addr32[3]);
319     inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
320     inet_pton(AF_INET6, addr6, (struct sockaddr *) &remaddr.sin6_addr);
321     localaddr.sin6_family = AF_INET6;
322     remaddr.sin6_family = AF_INET6;
323     #endif
324     } else {
325     sscanf(local_addr, "%X",
326     &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
327     sscanf(rem_addr, "%X",
328     &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
329     ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
330     ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
331     }
332    
333     if (num < 10) {
334     bb_error_msg("warning, got bogus raw line");
335     return;
336     }
337     state_str=itoa(state);
338    
339     #ifdef CONFIG_FEATURE_IPV6
340     # define notnull(A) (((A.sin6_family == AF_INET6) && \
341     ((A.sin6_addr.s6_addr32[0]) || \
342     (A.sin6_addr.s6_addr32[1]) || \
343     (A.sin6_addr.s6_addr32[2]) || \
344     (A.sin6_addr.s6_addr32[3]))) || \
345     ((A.sin6_family == AF_INET) && \
346     ((struct sockaddr_in *) &A)->sin_addr.s_addr))
347     #else
348     # define notnull(A) (A.sin_addr.s_addr)
349     #endif
350     if ((notnull(remaddr) && (flags&NETSTAT_CONNECTED)) ||
351     (!notnull(remaddr) && (flags&NETSTAT_LISTENING)))
352     {
353     snprint_ip_port(local_addr, sizeof(local_addr),
354     (struct sockaddr *) &localaddr, local_port,
355     "raw", flags&NETSTAT_NUMERIC);
356    
357     snprint_ip_port(rem_addr, sizeof(rem_addr),
358     (struct sockaddr *) &remaddr, rem_port,
359     "raw", flags&NETSTAT_NUMERIC);
360    
361     printf("raw %6ld %6ld %-23s %-23s %-12s\n",
362     rxq, txq, local_addr, rem_addr, state_str);
363    
364     }
365     }
366    
367     #define HAS_INODE 1
368    
369     static void unix_do_one(int nr, const char *line)
370     {
371     static int has = 0;
372     char path[PATH_MAX], ss_flags[32];
373     char *ss_proto, *ss_state, *ss_type;
374     int num, state, type, inode;
375     void *d;
376     unsigned long refcnt, proto, unix_flags;
377    
378     if (nr == 0) {
379     if (strstr(line, "Inode"))
380     has |= HAS_INODE;
381     return;
382     }
383     path[0] = '\0';
384     num = sscanf(line, "%p: %lX %lX %lX %X %X %d %s",
385     &d, &refcnt, &proto, &unix_flags, &type, &state, &inode, path);
386     if (num < 6) {
387     bb_error_msg("warning, got bogus unix line");
388     return;
389     }
390     if (!(has & HAS_INODE))
391     snprintf(path,sizeof(path),"%d",inode);
392    
393     if ((flags&(NETSTAT_LISTENING|NETSTAT_CONNECTED))!=(NETSTAT_LISTENING|NETSTAT_CONNECTED)) {
394     if ((state == SS_UNCONNECTED) && (unix_flags & SO_ACCEPTCON)) {
395     if (!(flags&NETSTAT_LISTENING))
396     return;
397     } else {
398     if (!(flags&NETSTAT_CONNECTED))
399     return;
400     }
401     }
402    
403     switch (proto) {
404     case 0:
405     ss_proto = "unix";
406     break;
407    
408     default:
409     ss_proto = "??";
410     }
411    
412     switch (type) {
413     case SOCK_STREAM:
414     ss_type = "STREAM";
415     break;
416    
417     case SOCK_DGRAM:
418     ss_type = "DGRAM";
419     break;
420    
421     case SOCK_RAW:
422     ss_type = "RAW";
423     break;
424    
425     case SOCK_RDM:
426     ss_type = "RDM";
427     break;
428    
429     case SOCK_SEQPACKET:
430     ss_type = "SEQPACKET";
431     break;
432    
433     default:
434     ss_type = "UNKNOWN";
435     }
436    
437     switch (state) {
438     case SS_FREE:
439     ss_state = "FREE";
440     break;
441    
442     case SS_UNCONNECTED:
443     /*
444     * Unconnected sockets may be listening
445     * for something.
446     */
447     if (unix_flags & SO_ACCEPTCON) {
448     ss_state = "LISTENING";
449     } else {
450     ss_state = "";
451     }
452     break;
453    
454     case SS_CONNECTING:
455     ss_state = "CONNECTING";
456     break;
457    
458     case SS_CONNECTED:
459     ss_state = "CONNECTED";
460     break;
461    
462     case SS_DISCONNECTING:
463     ss_state = "DISCONNECTING";
464     break;
465    
466     default:
467     ss_state = "UNKNOWN";
468     }
469    
470     strcpy(ss_flags, "[ ");
471     if (unix_flags & SO_ACCEPTCON)
472     strcat(ss_flags, "ACC ");
473     if (unix_flags & SO_WAITDATA)
474     strcat(ss_flags, "W ");
475     if (unix_flags & SO_NOSPACE)
476     strcat(ss_flags, "N ");
477    
478     strcat(ss_flags, "]");
479    
480     printf("%-5s %-6ld %-11s %-10s %-13s ",
481     ss_proto, refcnt, ss_flags, ss_type, ss_state);
482     if (has & HAS_INODE)
483     printf("%-6d ",inode);
484     else
485     printf("- ");
486     puts(path);
487     }
488    
489     #define _PATH_PROCNET_UDP "/proc/net/udp"
490     #define _PATH_PROCNET_UDP6 "/proc/net/udp6"
491     #define _PATH_PROCNET_TCP "/proc/net/tcp"
492     #define _PATH_PROCNET_TCP6 "/proc/net/tcp6"
493     #define _PATH_PROCNET_RAW "/proc/net/raw"
494     #define _PATH_PROCNET_RAW6 "/proc/net/raw6"
495     #define _PATH_PROCNET_UNIX "/proc/net/unix"
496    
497     static void do_info(const char *file, const char *name, void (*proc)(int, const char *))
498     {
499     int lnr = 0;
500     FILE *procinfo;
501    
502     procinfo = fopen(file, "r");
503     if (procinfo == NULL) {
504     if (errno != ENOENT) {
505     perror(file);
506     } else {
507     bb_error_msg("no support for '%s' on this system", name);
508     }
509     } else {
510     do {
511     char *buffer = xmalloc_fgets(procinfo);
512     if (buffer) {
513     (proc)(lnr++, buffer);
514     free(buffer);
515     }
516     } while (!feof(procinfo));
517     fclose(procinfo);
518     }
519     }
520    
521     /*
522     * Our main function.
523     */
524    
525     int netstat_main(int argc, char **argv)
526     {
527     enum {
528     OPT_extended = 0x4,
529     OPT_showroute = 0x100,
530     };
531     unsigned opt;
532     #ifdef CONFIG_FEATURE_IPV6
533     int inet = 1;
534     int inet6 = 1;
535     #else
536     # define inet 1
537     # define inet6 0
538     #endif
539    
540     /* Option string must match NETSTAT_xxx constants */
541     opt = getopt32(argc, argv, "laentuwxr");
542     if (opt & 0x1) { // -l
543     flags &= ~NETSTAT_CONNECTED;
544     flags |= NETSTAT_LISTENING;
545     }
546     if (opt & 0x2) flags |= NETSTAT_LISTENING | NETSTAT_CONNECTED; // -a
547     //if (opt & 0x4) // -e
548     if (opt & 0x8) flags |= NETSTAT_NUMERIC; // -n
549     //if (opt & 0x10) // -t: NETSTAT_TCP
550     //if (opt & 0x20) // -u: NETSTAT_UDP
551     //if (opt & 0x40) // -w: NETSTAT_RAW
552     //if (opt & 0x80) // -x: NETSTAT_UNIX
553     if (opt & OPT_showroute) { // -r
554     #ifdef CONFIG_ROUTE
555     displayroutes(flags & NETSTAT_NUMERIC, !(opt & OPT_extended));
556     return 0;
557     #else
558     bb_error_msg_and_die("-r (display routing table) is not compiled in");
559     #endif
560     }
561    
562     opt &= NETSTAT_ALLPROTO;
563     if (opt) {
564     flags &= ~NETSTAT_ALLPROTO;
565     flags |= opt;
566     }
567     if (flags & (NETSTAT_TCP|NETSTAT_UDP|NETSTAT_RAW)) {
568     printf("Active Internet connections "); /* xxx */
569    
570     if ((flags&(NETSTAT_LISTENING|NETSTAT_CONNECTED))==(NETSTAT_LISTENING|NETSTAT_CONNECTED))
571     printf("(servers and established)");
572     else {
573     if (flags & NETSTAT_LISTENING)
574     printf("(only servers)");
575     else
576     printf("(w/o servers)");
577     }
578     printf("\nProto Recv-Q Send-Q Local Address Foreign Address State\n");
579     }
580     if (inet && flags&NETSTAT_TCP)
581     do_info(_PATH_PROCNET_TCP,"AF INET (tcp)",tcp_do_one);
582     #ifdef CONFIG_FEATURE_IPV6
583     if (inet6 && flags&NETSTAT_TCP)
584     do_info(_PATH_PROCNET_TCP6,"AF INET6 (tcp)",tcp_do_one);
585     #endif
586     if (inet && flags&NETSTAT_UDP)
587     do_info(_PATH_PROCNET_UDP,"AF INET (udp)",udp_do_one);
588     #ifdef CONFIG_FEATURE_IPV6
589     if (inet6 && flags&NETSTAT_UDP)
590     do_info(_PATH_PROCNET_UDP6,"AF INET6 (udp)",udp_do_one);
591     #endif
592     if (inet && flags&NETSTAT_RAW)
593     do_info(_PATH_PROCNET_RAW,"AF INET (raw)",raw_do_one);
594     #ifdef CONFIG_FEATURE_IPV6
595     if (inet6 && flags&NETSTAT_RAW)
596     do_info(_PATH_PROCNET_RAW6,"AF INET6 (raw)",raw_do_one);
597     #endif
598     if (flags&NETSTAT_UNIX) {
599     printf("Active UNIX domain sockets ");
600     if ((flags&(NETSTAT_LISTENING|NETSTAT_CONNECTED))==(NETSTAT_LISTENING|NETSTAT_CONNECTED))
601     printf("(servers and established)");
602     else {
603     if (flags&NETSTAT_LISTENING)
604     printf("(only servers)");
605     else
606     printf("(w/o servers)");
607     }
608    
609     printf("\nProto RefCnt Flags Type State I-Node Path\n");
610     do_info(_PATH_PROCNET_UNIX,"AF UNIX",unix_do_one);
611     }
612     return 0;
613     }