~ubuntu-branches/debian/sid/net-tools/sid

« back to all changes in this revision

Viewing changes to .pc/netstat.c-assorted_changes.patch/netstat.c

  • Committer: Package Import Robot
  • Author(s): Martín Ferrari
  • Date: 2015-09-07 01:54:07 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20150907015407-v2tfsgxayjd3iq4i
Tags: 1.60+git20150829.73cef8a-1
* After 14 years without an upstream release, I am producing a new package
  based on today's upstream repository.
  Closes: #391495, #486448, #323261, #260587, #545328, #511395.
* Remove many patches now merged upstream, delete unmaintainable and
  undocumented local changes, and update the rest.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * netstat    This file contains an implementation of the command
3
 
 *              that helps in debugging the networking modules.
4
 
 *
5
 
 * NET-TOOLS    A collection of programs that form the base set of the
6
 
 *              NET-3 Networking Distribution for the LINUX operating
7
 
 *              system.
8
 
 *
9
 
 * Version:     $Id: netstat.c,v 1.54 2007/12/01 18:12:34 ecki Exp $
10
 
 *
11
 
 * Authors:     Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de>
12
 
 *              Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
13
 
 *              Phil Packer, <pep@wicked.demon.co.uk>
14
 
 *              Johannes Stille, <johannes@titan.os.open.de>
15
 
 *              Bernd Eckenfels, <net-tools@lina.inka.de>
16
 
 *              Phil Blundell <philb@gnu.org>
17
 
 *              Tuan Hoang <tqhoang@bigfoot.com>
18
 
 *
19
 
 * Tuned for NET3 by:
20
 
 *              Alan Cox, <A.Cox@swansea.ac.uk>
21
 
 *              Copyright (c) 1993  Fred Baumgarten
22
 
 *
23
 
 * Modified:
24
 
 *
25
 
 *960116 {1.01} Bernd Eckenfels:        verbose, cleanups
26
 
 *960204 {1.10} Bernd Eckenfels:        aftrans, usage, new route_info, 
27
 
 *                                      DLFT_AF
28
 
 *960204 {1.11} Bernd Eckenfels:        netlink support
29
 
 *960204 {1.12} Bernd Eckenfels:        route_init()
30
 
 *960215 {1.13} Bernd Eckenfels:        netlink_print honors HAVE_
31
 
 *960217 {1.14} Bernd Eckenfels:        masq_info from Jos Vos and 
32
 
 *                                      ax25_info from Jonathan Naylor.
33
 
 *960218 {1.15} Bernd Eckenfels:        ipx_info rewritten, -e for tcp/ipx
34
 
 *960220 {1.16} Bernd Eckenfels:        minor output reformats, -a for -x
35
 
 *960221 {1.17} Bernd Eckenfels:        route_init->getroute_init
36
 
 *960426 {1.18} Bernd Eckenfels:        new RTACTION, SYM/NUM, FIB/CACHE
37
 
 *960517 {1.19} Bernd Eckenfels:        usage() spelling fix and --unix inode, 
38
 
 *                                      ':' is part of sock_addr for --inet
39
 
 *960822 {x.xx} Frank Strauss:          INET6 support
40
 
 *
41
 
 *970406 {1.33} Philip Copeland         Added snmp reporting support module -s
42
 
 *                                      code provided by Andi Kleen
43
 
 *                                      (relly needs to be kernel hooked but 
44
 
 *                                      this will do in the meantime)
45
 
 *                                      minor header file misplacement tidy up.
46
 
 *980815 {1.xx} Stephane Fillod:       X.25 support
47
 
 *980411 {1.34} Arnaldo Carvalho        i18n: catgets -> gnu gettext, substitution
48
 
 *                                      of sprintf for snprintf
49
 
 *10/1998       Andi Kleen              Use new interface primitives.
50
 
 *990101 {1.36} Bernd Eckenfels         usage updated to include -s and -C -F,
51
 
 *                                      fixed netstat -rC output (lib/inet_gr.c)
52
 
 *                                      removed broken NETLINK Support
53
 
 *                                      fixed format for /proc/net/udp|tcp|raw
54
 
 *                                      added -w,-t,-u TcpExt support to -s
55
 
 *990131 {1.37} Jan Kratochvil          added -p for prg_cache() & friends
56
 
 *                                      Flames to <short@ucw.cz>.
57
 
 *              Tuan Hoang              added IGMP support for IPv4 and IPv6
58
 
 *
59
 
 *990420 {1.38} Tuan Hoang              removed a useless assignment from igmp_do_one()
60
 
 *20010404 {1.39} Arnaldo Carvalho de Melo - use setlocale
61
 
 *
62
 
 *              This program is free software; you can redistribute it
63
 
 *              and/or  modify it under  the terms of  the GNU General
64
 
 *              Public  License as  published  by  the  Free  Software
65
 
 *              Foundation;  either  version 2 of the License, or  (at
66
 
 *              your option) any later version.
67
 
 *
68
 
 */
69
 
#include <errno.h>
70
 
#include <stdio.h>
71
 
#include <stdlib.h>
72
 
#include <string.h>
73
 
#include <strings.h>
74
 
#include <unistd.h>
75
 
#include <ctype.h>
76
 
#include <fcntl.h>
77
 
#include <netdb.h>
78
 
#include <paths.h>
79
 
#include <pwd.h>
80
 
#include <getopt.h>
81
 
#include <sys/param.h>
82
 
#include <sys/socket.h>
83
 
#include <arpa/inet.h>
84
 
#include <netinet/in.h>
85
 
#include <sys/ioctl.h>
86
 
#include <net/if.h>
87
 
#include <dirent.h>
88
 
 
89
 
#include "net-support.h"
90
 
#include "pathnames.h"
91
 
#include "version.h"
92
 
#include "config.h"
93
 
#include "intl.h"
94
 
#include "sockets.h"
95
 
#include "interface.h"
96
 
#include "util.h"
97
 
 
98
 
#define PROGNAME_WIDTH 20
99
 
 
100
 
#if !defined(s6_addr32) && defined(in6a_words)
101
 
#define s6_addr32 in6a_words    /* libinet6                     */
102
 
#endif
103
 
 
104
 
/* prototypes for statistics.c */
105
 
void parsesnmp(int, int, int);
106
 
void inittab(void);
107
 
 
108
 
typedef enum {
109
 
    SS_FREE = 0,                /* not allocated                */
110
 
    SS_UNCONNECTED,             /* unconnected to any socket    */
111
 
    SS_CONNECTING,              /* in process of connecting     */
112
 
    SS_CONNECTED,               /* connected to socket          */
113
 
    SS_DISCONNECTING            /* in process of disconnecting  */
114
 
} socket_state;
115
 
 
116
 
#define SO_ACCEPTCON    (1<<16) /* performed a listen           */
117
 
#define SO_WAITDATA     (1<<17) /* wait data to read            */
118
 
#define SO_NOSPACE      (1<<18) /* no space to write            */
119
 
 
120
 
#define DFLT_AF "inet"
121
 
 
122
 
#define FEATURE_NETSTAT
123
 
#include "lib/net-features.h"
124
 
 
125
 
char *Release = RELEASE, *Version = "netstat 1.42 (2001-04-15)", *Signature = "Fred Baumgarten, Alan Cox, Bernd Eckenfels, Phil Blundell, Tuan Hoang and others";
126
 
 
127
 
 
128
 
#define E_READ  -1
129
 
#define E_IOCTL -3
130
 
 
131
 
int flag_int = 0;
132
 
int flag_rou = 0;
133
 
int flag_mas = 0;
134
 
int flag_sta = 0;
135
 
 
136
 
int flag_all = 0;
137
 
int flag_lst = 0;
138
 
int flag_cnt = 0;
139
 
int flag_deb = 0;
140
 
int flag_not = 0;
141
 
int flag_cf  = 0;
142
 
int flag_opt = 0;
143
 
int flag_raw = 0;
144
 
int flag_tcp = 0;
145
 
int flag_udp = 0;
146
 
int flag_igmp= 0;
147
 
int flag_rom = 0;
148
 
int flag_exp = 1;
149
 
int flag_prg = 0;
150
 
int flag_arg = 0;
151
 
int flag_ver = 0;
152
 
 
153
 
FILE *procinfo;
154
 
 
155
 
#define INFO_GUTS1(file,name,proc)                      \
156
 
  procinfo = fopen((file), "r");                        \
157
 
  if (procinfo == NULL) {                               \
158
 
    if (errno != ENOENT) {                              \
159
 
      perror((file));                                   \
160
 
      return -1;                                        \
161
 
    }                                                   \
162
 
    if (flag_arg || flag_ver)                           \
163
 
      ESYSNOT("netstat", (name));                       \
164
 
    if (flag_arg)                                       \
165
 
      rc = 1;                                           \
166
 
  } else {                                              \
167
 
    do {                                                \
168
 
      if (fgets(buffer, sizeof(buffer), procinfo))      \
169
 
        (proc)(lnr++, buffer);                          \
170
 
    } while (!feof(procinfo));                          \
171
 
    fclose(procinfo);                                   \
172
 
  }
173
 
 
174
 
#if HAVE_AFINET6
175
 
#define INFO_GUTS2(file,proc)                           \
176
 
  lnr = 0;                                              \
177
 
  procinfo = fopen((file), "r");                        \
178
 
  if (procinfo != NULL) {                               \
179
 
    do {                                                \
180
 
      if (fgets(buffer, sizeof(buffer), procinfo))      \
181
 
        (proc)(lnr++, buffer);                          \
182
 
    } while (!feof(procinfo));                          \
183
 
    fclose(procinfo);                                   \
184
 
  }
185
 
#else
186
 
#define INFO_GUTS2(file,proc)
187
 
#endif
188
 
 
189
 
#define INFO_GUTS3                                      \
190
 
 return rc;
191
 
 
192
 
#define INFO_GUTS6(file,file6,name,proc)                \
193
 
 char buffer[8192];                                     \
194
 
 int rc = 0;                                            \
195
 
 int lnr = 0;                                           \
196
 
 if (!flag_arg || flag_inet) {                          \
197
 
    INFO_GUTS1(file,name,proc)                          \
198
 
 }                                                      \
199
 
 if (!flag_arg || flag_inet6) {                         \
200
 
    INFO_GUTS2(file6,proc)                              \
201
 
 }                                                      \
202
 
 INFO_GUTS3
203
 
 
204
 
#define INFO_GUTS(file,name,proc)                       \
205
 
 char buffer[8192];                                     \
206
 
 int rc = 0;                                            \
207
 
 int lnr = 0;                                           \
208
 
 INFO_GUTS1(file,name,proc)                             \
209
 
 INFO_GUTS3
210
 
 
211
 
#define PROGNAME_WIDTHs PROGNAME_WIDTH1(PROGNAME_WIDTH)
212
 
#define PROGNAME_WIDTH1(s) PROGNAME_WIDTH2(s)
213
 
#define PROGNAME_WIDTH2(s) #s
214
 
 
215
 
#define PRG_HASH_SIZE 211
216
 
 
217
 
static struct prg_node {
218
 
    struct prg_node *next;
219
 
    unsigned long inode;
220
 
    char name[PROGNAME_WIDTH];
221
 
} *prg_hash[PRG_HASH_SIZE];
222
 
 
223
 
static char prg_cache_loaded = 0;
224
 
 
225
 
#define PRG_HASHIT(x) ((x) % PRG_HASH_SIZE)
226
 
 
227
 
#define PROGNAME_BANNER "PID/Program name"
228
 
 
229
 
#define print_progname_banner() do { if (flag_prg) printf("%-" PROGNAME_WIDTHs "s"," " PROGNAME_BANNER); } while (0)
230
 
 
231
 
#define PRG_LOCAL_ADDRESS "local_address"
232
 
#define PRG_INODE        "inode"
233
 
#define PRG_SOCKET_PFX    "socket:["
234
 
#define PRG_SOCKET_PFXl (strlen(PRG_SOCKET_PFX))
235
 
#define PRG_SOCKET_PFX2   "[0000]:"
236
 
#define PRG_SOCKET_PFX2l  (strlen(PRG_SOCKET_PFX2))
237
 
 
238
 
 
239
 
#ifndef LINE_MAX
240
 
#define LINE_MAX 4096
241
 
#endif
242
 
 
243
 
#define PATH_PROC          "/proc"
244
 
#define PATH_FD_SUFF    "fd"
245
 
#define PATH_FD_SUFFl       strlen(PATH_FD_SUFF)
246
 
#define PATH_PROC_X_FD      PATH_PROC "/%s/" PATH_FD_SUFF
247
 
#define PATH_CMDLINE    "cmdline"
248
 
#define PATH_CMDLINEl       strlen(PATH_CMDLINE)
249
 
/* NOT working as of glibc-2.0.7: */
250
 
#undef  DIRENT_HAVE_D_TYPE_WORKS
251
 
 
252
 
static void prg_cache_add(unsigned long inode, char *name)
253
 
{
254
 
    unsigned hi = PRG_HASHIT(inode);
255
 
    struct prg_node **pnp,*pn;
256
 
 
257
 
    prg_cache_loaded=2;
258
 
    for (pnp=prg_hash+hi;(pn=*pnp);pnp=&pn->next) {
259
 
        if (pn->inode==inode) {
260
 
            /* Some warning should be appropriate here
261
 
               as we got multiple processes for one i-node */
262
 
            return;
263
 
        }
264
 
    }
265
 
    if (!(*pnp=malloc(sizeof(**pnp)))) 
266
 
        return;
267
 
    pn=*pnp;
268
 
    pn->next=NULL;
269
 
    pn->inode=inode;
270
 
    if (strlen(name)>sizeof(pn->name)-1) 
271
 
        name[sizeof(pn->name)-1]='\0';
272
 
    strcpy(pn->name,name);
273
 
}
274
 
 
275
 
static const char *prg_cache_get(unsigned long inode)
276
 
{
277
 
    unsigned hi=PRG_HASHIT(inode);
278
 
    struct prg_node *pn;
279
 
 
280
 
    for (pn=prg_hash[hi];pn;pn=pn->next)
281
 
        if (pn->inode==inode) return(pn->name);
282
 
    return("-");
283
 
}
284
 
 
285
 
static void prg_cache_clear(void)
286
 
{
287
 
    struct prg_node **pnp,*pn;
288
 
 
289
 
    if (prg_cache_loaded == 2)
290
 
        for (pnp=prg_hash;pnp<prg_hash+PRG_HASH_SIZE;pnp++)
291
 
            while ((pn=*pnp)) {
292
 
                *pnp=pn->next;
293
 
                free(pn);
294
 
            }
295
 
    prg_cache_loaded=0;
296
 
}
297
 
 
298
 
static int extract_type_1_socket_inode(const char lname[], unsigned long * inode_p) {
299
 
 
300
 
    /* If lname is of the form "socket:[12345]", extract the "12345"
301
 
       as *inode_p.  Otherwise, return -1 as *inode_p.
302
 
       */
303
 
 
304
 
    if (strlen(lname) < PRG_SOCKET_PFXl+3) return(-1);
305
 
    
306
 
    if (memcmp(lname, PRG_SOCKET_PFX, PRG_SOCKET_PFXl)) return(-1);
307
 
    if (lname[strlen(lname)-1] != ']') return(-1);
308
 
 
309
 
    {
310
 
        char inode_str[strlen(lname + 1)];  /* e.g. "12345" */
311
 
        const int inode_str_len = strlen(lname) - PRG_SOCKET_PFXl - 1;
312
 
        char *serr;
313
 
 
314
 
        strncpy(inode_str, lname+PRG_SOCKET_PFXl, inode_str_len);
315
 
        inode_str[inode_str_len] = '\0';
316
 
        *inode_p = strtol(inode_str,&serr,0);
317
 
        if (!serr || *serr || *inode_p < 0 || *inode_p >= INT_MAX) 
318
 
            return(-1);
319
 
    }
320
 
    return(0);
321
 
}
322
 
 
323
 
 
324
 
 
325
 
static int extract_type_2_socket_inode(const char lname[], unsigned long * inode_p) {
326
 
 
327
 
    /* If lname is of the form "[0000]:12345", extract the "12345"
328
 
       as *inode_p.  Otherwise, return -1 as *inode_p.
329
 
       */
330
 
 
331
 
    if (strlen(lname) < PRG_SOCKET_PFX2l+1) return(-1);
332
 
    if (memcmp(lname, PRG_SOCKET_PFX2, PRG_SOCKET_PFX2l)) return(-1);
333
 
 
334
 
    {
335
 
        char *serr;
336
 
 
337
 
        *inode_p=strtol(lname + PRG_SOCKET_PFX2l,&serr,0);
338
 
        if (!serr || *serr || *inode_p < 0 || *inode_p >= INT_MAX) 
339
 
            return(-1);
340
 
    }
341
 
    return(0);
342
 
}
343
 
 
344
 
 
345
 
 
346
 
 
347
 
static void prg_cache_load(void)
348
 
{
349
 
    char line[LINE_MAX],eacces=0;
350
 
    int procfdlen,fd,cmdllen,lnamelen;
351
 
    char lname[30],cmdlbuf[512],finbuf[PROGNAME_WIDTH];
352
 
    unsigned long inode;
353
 
    const char *cs,*cmdlp;
354
 
    DIR *dirproc=NULL,*dirfd=NULL;
355
 
    struct dirent *direproc,*direfd;
356
 
 
357
 
    if (prg_cache_loaded || !flag_prg) return;
358
 
    prg_cache_loaded=1;
359
 
    cmdlbuf[sizeof(cmdlbuf)-1]='\0';
360
 
    if (!(dirproc=opendir(PATH_PROC))) goto fail;
361
 
    while (errno=0,direproc=readdir(dirproc)) {
362
 
#ifdef DIRENT_HAVE_D_TYPE_WORKS
363
 
        if (direproc->d_type!=DT_DIR) continue;
364
 
#endif
365
 
        for (cs=direproc->d_name;*cs;cs++)
366
 
            if (!isdigit(*cs)) 
367
 
                break;
368
 
        if (*cs) 
369
 
            continue;
370
 
        procfdlen=snprintf(line,sizeof(line),PATH_PROC_X_FD,direproc->d_name);
371
 
        if (procfdlen<=0 || procfdlen>=sizeof(line)-5) 
372
 
            continue;
373
 
        errno=0;
374
 
        dirfd=opendir(line);
375
 
        if (! dirfd) {
376
 
            if (errno==EACCES) 
377
 
                eacces=1;
378
 
            continue;
379
 
        }
380
 
        line[procfdlen] = '/';
381
 
        cmdlp = NULL;
382
 
        while ((direfd = readdir(dirfd))) {
383
 
#ifdef DIRENT_HAVE_D_TYPE_WORKS
384
 
            if (direfd->d_type!=DT_LNK) 
385
 
                continue;
386
 
#endif
387
 
            if (procfdlen+1+strlen(direfd->d_name)+1>sizeof(line)) 
388
 
                continue;
389
 
            memcpy(line + procfdlen - PATH_FD_SUFFl, PATH_FD_SUFF "/",
390
 
                   PATH_FD_SUFFl+1);
391
 
            strcpy(line + procfdlen + 1, direfd->d_name);
392
 
            lnamelen=readlink(line,lname,sizeof(lname)-1);
393
 
            lname[lnamelen] = '\0';  /*make it a null-terminated string*/
394
 
 
395
 
            if (extract_type_1_socket_inode(lname, &inode) < 0)
396
 
              if (extract_type_2_socket_inode(lname, &inode) < 0)
397
 
                continue;
398
 
 
399
 
            if (!cmdlp) {
400
 
                if (procfdlen - PATH_FD_SUFFl + PATH_CMDLINEl >= 
401
 
                    sizeof(line) - 5) 
402
 
                    continue;
403
 
                strcpy(line + procfdlen-PATH_FD_SUFFl, PATH_CMDLINE);
404
 
                fd = open(line, O_RDONLY);
405
 
                if (fd < 0) 
406
 
                    continue;
407
 
                cmdllen = read(fd, cmdlbuf, sizeof(cmdlbuf) - 1);
408
 
                if (close(fd)) 
409
 
                    continue;
410
 
                if (cmdllen == -1) 
411
 
                    continue;
412
 
                if (cmdllen < sizeof(cmdlbuf) - 1) 
413
 
                    cmdlbuf[cmdllen]='\0';
414
 
                if ((cmdlp = strrchr(cmdlbuf, '/'))) 
415
 
                    cmdlp++;
416
 
                else 
417
 
                    cmdlp = cmdlbuf;
418
 
            }
419
 
 
420
 
            snprintf(finbuf, sizeof(finbuf), "%s/%s", direproc->d_name, cmdlp);
421
 
            prg_cache_add(inode, finbuf);
422
 
        }
423
 
        closedir(dirfd); 
424
 
        dirfd = NULL;
425
 
    }
426
 
    if (dirproc) 
427
 
        closedir(dirproc);
428
 
    if (dirfd) 
429
 
        closedir(dirfd);
430
 
    if (!eacces) 
431
 
        return;
432
 
    if (prg_cache_loaded == 1) {
433
 
    fail:
434
 
        fprintf(stderr,_("(No info could be read for \"-p\": geteuid()=%d but you should be root.)\n"),
435
 
                geteuid());
436
 
    }
437
 
    else
438
 
        fprintf(stderr, _("(Not all processes could be identified, non-owned process info\n"
439
 
                         " will not be shown, you would have to be root to see it all.)\n"));
440
 
}
441
 
 
442
 
#if HAVE_AFNETROM
443
 
static const char *netrom_state[] =
444
 
{
445
 
    N_("LISTENING"),
446
 
    N_("CONN SENT"),
447
 
    N_("DISC SENT"),
448
 
    N_("ESTABLISHED")
449
 
};
450
 
 
451
 
static int netrom_info(void)
452
 
{
453
 
    FILE *f;
454
 
    char buffer[256], dev[16];
455
 
    int st, vs, vr, sendq, recvq, ret;
456
 
 
457
 
    f = fopen(_PATH_PROCNET_NR, "r");
458
 
    if (f == NULL) {
459
 
        if (errno != ENOENT) {
460
 
            perror(_PATH_PROCNET_NR);
461
 
            return (-1);
462
 
        }
463
 
        if (flag_arg || flag_ver)
464
 
            ESYSNOT("netstat", "AF NETROM");
465
 
        if (flag_arg)
466
 
            return (1);
467
 
        else
468
 
            return (0);
469
 
    }
470
 
    printf(_("Active NET/ROM sockets\n"));
471
 
    printf(_("User       Dest       Source     Device  State        Vr/Vs    Send-Q  Recv-Q\n"));
472
 
    fgets(buffer, 256, f);
473
 
 
474
 
    while (fgets(buffer, 256, f)) {
475
 
        buffer[9] = 0;
476
 
        buffer[19] = 0;
477
 
        buffer[29] = 0;
478
 
        ret = sscanf(buffer + 30, "%s %*x/%*x %*x/%*x %d %d %d %*d %*d/%*d %*d/%*d %*d/%*d %*d/%*d %*d/%*d %*d %d %d %*d",
479
 
               dev, &st, &vs, &vr, &sendq, &recvq);
480
 
        if (ret != 6) {
481
 
            printf(_("Problem reading data from %s\n"), _PATH_PROCNET_NR);
482
 
            continue;
483
 
        }
484
 
        printf("%-9s  %-9s  %-9s  %-6s  %-11s  %03d/%03d  %-6d  %-6d\n",
485
 
               buffer, buffer + 10, buffer + 20,
486
 
               dev,
487
 
               _(netrom_state[st]),
488
 
               vr, vs, sendq, recvq);
489
 
    }
490
 
    fclose(f);
491
 
    return 0;
492
 
}
493
 
#endif
494
 
 
495
 
/* These enums are used by IPX too. :-( */
496
 
enum {
497
 
    TCP_ESTABLISHED = 1,
498
 
    TCP_SYN_SENT,
499
 
    TCP_SYN_RECV,
500
 
    TCP_FIN_WAIT1,
501
 
    TCP_FIN_WAIT2,
502
 
    TCP_TIME_WAIT,
503
 
    TCP_CLOSE,
504
 
    TCP_CLOSE_WAIT,
505
 
    TCP_LAST_ACK,
506
 
    TCP_LISTEN,
507
 
    TCP_CLOSING                 /* now a valid state */
508
 
};
509
 
 
510
 
#if HAVE_AFINET || HAVE_AFINET6
511
 
 
512
 
static const char *tcp_state[] =
513
 
{
514
 
    "",
515
 
    N_("ESTABLISHED"),
516
 
    N_("SYN_SENT"),
517
 
    N_("SYN_RECV"),
518
 
    N_("FIN_WAIT1"),
519
 
    N_("FIN_WAIT2"),
520
 
    N_("TIME_WAIT"),
521
 
    N_("CLOSE"),
522
 
    N_("CLOSE_WAIT"),
523
 
    N_("LAST_ACK"),
524
 
    N_("LISTEN"),
525
 
    N_("CLOSING")
526
 
};
527
 
 
528
 
static void finish_this_one(int uid, unsigned long inode, const char *timers)
529
 
{
530
 
    struct passwd *pw;
531
 
 
532
 
    if (flag_exp > 1) {
533
 
        if (!(flag_not & FLAG_NUM_USER) && ((pw = getpwuid(uid)) != NULL))
534
 
            printf(" %-10s ", pw->pw_name);
535
 
        else
536
 
            printf(" %-10d ", uid);
537
 
        printf("%-10lu ",inode);
538
 
    }
539
 
    if (flag_prg)
540
 
        printf("%-" PROGNAME_WIDTHs "s",prg_cache_get(inode));
541
 
    if (flag_opt)
542
 
        printf("%s", timers);
543
 
    putchar('\n');
544
 
}
545
 
 
546
 
static void igmp_do_one(int lnr, const char *line)
547
 
{
548
 
    char mcast_addr[128];
549
 
#if HAVE_AFINET6
550
 
    struct sockaddr_in6 mcastaddr;
551
 
    char addr6[INET6_ADDRSTRLEN];
552
 
    struct in6_addr in6;
553
 
    extern struct aftype inet6_aftype;
554
 
#else
555
 
    struct sockaddr_in mcastaddr;
556
 
#endif
557
 
    struct aftype *ap;
558
 
    static int idx_flag = 0;
559
 
    static int igmp6_flag = 0;
560
 
    static char device[16];
561
 
    int num, idx, refcnt;
562
 
 
563
 
    if (lnr == 0) {
564
 
        /* IPV6 ONLY */
565
 
        /* igmp6 file does not have any comments on first line */
566
 
        if ( strstr( line, "Device" ) == NULL ) {
567
 
            igmp6_flag = 1;
568
 
        } else {
569
 
            /* IPV4 ONLY */
570
 
            /* 2.1.x kernels and up have Idx field */
571
 
            /* 2.0.x and below do not have Idx field */
572
 
            if ( strncmp( line, "Idx", strlen("Idx") ) == 0 )
573
 
                idx_flag = 1;
574
 
            else
575
 
                idx_flag = 0;
576
 
            return;
577
 
        }
578
 
    }
579
 
 
580
 
    if (igmp6_flag) {    /* IPV6 */
581
 
#if HAVE_AFINET6
582
 
        num = sscanf( line, "%d %15s %64[0-9A-Fa-f] %d", &idx, device, mcast_addr, &refcnt );
583
 
        if (num == 4) {
584
 
            /* Demangle what the kernel gives us */
585
 
            sscanf(mcast_addr, "%08X%08X%08X%08X",
586
 
                   &in6.s6_addr32[0], &in6.s6_addr32[1],
587
 
           &in6.s6_addr32[2], &in6.s6_addr32[3]);
588
 
            in6.s6_addr32[0] = htonl(in6.s6_addr32[0]);
589
 
            in6.s6_addr32[1] = htonl(in6.s6_addr32[1]);
590
 
            in6.s6_addr32[2] = htonl(in6.s6_addr32[2]);
591
 
            in6.s6_addr32[3] = htonl(in6.s6_addr32[3]);
592
 
        inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
593
 
            inet6_aftype.input(1, addr6, (struct sockaddr *) &mcastaddr);
594
 
            mcastaddr.sin6_family = AF_INET6;
595
 
        } else {
596
 
            fprintf(stderr, _("warning, got bogus igmp6 line %d.\n"), lnr);
597
 
            return;
598
 
        }
599
 
 
600
 
        if ((ap = get_afntype(((struct sockaddr *) &mcastaddr)->sa_family)) == NULL) {
601
 
            fprintf(stderr, _("netstat: unsupported address family %d !\n"),
602
 
                    ((struct sockaddr *) &mcastaddr)->sa_family);
603
 
            return;
604
 
        }
605
 
        safe_strncpy(mcast_addr, ap->sprint((struct sockaddr *) &mcastaddr, 
606
 
                                      flag_not), sizeof(mcast_addr));
607
 
        printf("%-15s %-6d %s\n", device, refcnt, mcast_addr);
608
 
#endif
609
 
    } else {    /* IPV4 */
610
 
#if HAVE_AFINET
611
 
        if (line[0] != '\t') {
612
 
            if (idx_flag) {
613
 
                if ((num = sscanf( line, "%d\t%10c", &idx, device)) < 2) {
614
 
                    fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
615
 
                    return;
616
 
                }
617
 
            } else {
618
 
                if ( (num = sscanf( line, "%10c", device )) < 1 ) {
619
 
                    fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
620
 
                    return;
621
 
                }
622
 
            }
623
 
            device[10] = '\0';
624
 
            return;
625
 
        } else if ( line[0] == '\t' ) {
626
 
            if ( (num = sscanf(line, "\t%8[0-9A-Fa-f] %d", mcast_addr, &refcnt)) < 2 ) {
627
 
                fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
628
 
                return;
629
 
            }
630
 
            sscanf( mcast_addr, "%X",
631
 
                    &((struct sockaddr_in *) &mcastaddr)->sin_addr.s_addr );
632
 
            ((struct sockaddr *) &mcastaddr)->sa_family = AF_INET;
633
 
        } else {
634
 
            fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
635
 
            return;
636
 
        }
637
 
        
638
 
        if ((ap = get_afntype(((struct sockaddr *) &mcastaddr)->sa_family)) == NULL) {
639
 
            fprintf(stderr, _("netstat: unsupported address family %d !\n"),
640
 
                    ((struct sockaddr *) &mcastaddr)->sa_family);
641
 
            return;
642
 
        }
643
 
        safe_strncpy(mcast_addr, ap->sprint((struct sockaddr *) &mcastaddr, 
644
 
                                      flag_not), sizeof(mcast_addr));
645
 
        printf("%-15s %-6d %s\n", device, refcnt, mcast_addr );
646
 
#endif
647
 
    }    /* IPV4 */
648
 
}
649
 
 
650
 
#if HAVE_AFX25
651
 
static int x25_info(void)
652
 
{
653
 
       FILE *f=fopen(_PATH_PROCNET_X25, "r");
654
 
       char buffer[256],dev[16];
655
 
       int st,vs,vr,sendq,recvq,lci;
656
 
       static char *x25_state[5]=
657
 
       {
658
 
               "LISTENING",
659
 
               "SABM_SENT",
660
 
               "DISC_SENT",
661
 
               "ESTABLISHED",
662
 
               "RECOVERY"
663
 
       };
664
 
       if(!(f=fopen(_PATH_PROCNET_X25, "r")))
665
 
       {
666
 
               if (errno != ENOENT) {
667
 
                       perror(_PATH_PROCNET_X25);
668
 
                       return(-1);
669
 
               }
670
 
               if (flag_arg || flag_ver)
671
 
                       ESYSNOT("netstat","AF X25");
672
 
               if (flag_arg)
673
 
                       return(1);
674
 
               else
675
 
                       return(0);
676
 
       }
677
 
       printf( _("Active X.25 sockets\n"));
678
 
       /* IMHO, Vr/Vs is not very usefull --SF */
679
 
       printf( _("Dest         Source          Device  LCI  State        Vr/Vs  Send-Q  Recv-Q\n"));
680
 
       fgets(buffer,256,f);
681
 
       while(fgets(buffer,256,f))
682
 
       {
683
 
               buffer[10]=0;
684
 
               buffer[20]=0;
685
 
               sscanf(buffer+22,"%s %d %d %d %d %*d %*d %*d %*d %*d %*d %d %d %*d",
686
 
                       dev,&lci,&st,&vs,&vr,&sendq,&recvq);
687
 
               if (!(flag_all || lci))
688
 
                       continue;
689
 
               printf("%-15s %-15s %-7s %-3d  %-11s  %02d/%02d  %-6d  %-6d\n",
690
 
                       buffer,buffer+11,
691
 
                       dev,
692
 
                       lci,
693
 
                       x25_state[st],
694
 
                       vr,vs,sendq,recvq);
695
 
       }
696
 
       fclose(f);
697
 
       return 0;               
698
 
}
699
 
#endif
700
 
 
701
 
static int igmp_info(void)
702
 
{
703
 
    INFO_GUTS6(_PATH_PROCNET_IGMP, _PATH_PROCNET_IGMP6, "AF INET (igmp)",
704
 
               igmp_do_one);
705
 
}
706
 
 
707
 
static void tcp_do_one(int lnr, const char *line)
708
 
{
709
 
    unsigned long rxq, txq, time_len, retr, inode;
710
 
    int num, local_port, rem_port, d, state, uid, timer_run, timeout;
711
 
    char rem_addr[128], local_addr[128], timers[64], buffer[1024], more[512];
712
 
    char *protname;
713
 
    struct aftype *ap;
714
 
#if HAVE_AFINET6
715
 
    struct sockaddr_in6 localaddr, remaddr;
716
 
    char addr6[INET6_ADDRSTRLEN];
717
 
    struct in6_addr in6;
718
 
    extern struct aftype inet6_aftype;
719
 
#else
720
 
    struct sockaddr_in localaddr, remaddr;
721
 
#endif
722
 
 
723
 
    if (lnr == 0)
724
 
        return;
725
 
 
726
 
    num = sscanf(line,
727
 
    "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %512s\n",
728
 
                 &d, local_addr, &local_port, rem_addr, &rem_port, &state,
729
 
                 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
730
 
 
731
 
    if (strlen(local_addr) > 8) {
732
 
#if HAVE_AFINET6
733
 
        protname = "tcp6";
734
 
        /* Demangle what the kernel gives us */
735
 
        sscanf(local_addr, "%08X%08X%08X%08X",
736
 
               &in6.s6_addr32[0], &in6.s6_addr32[1],
737
 
           &in6.s6_addr32[2], &in6.s6_addr32[3]);
738
 
        inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
739
 
        inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
740
 
        sscanf(rem_addr, "%08X%08X%08X%08X",
741
 
               &in6.s6_addr32[0], &in6.s6_addr32[1],
742
 
               &in6.s6_addr32[2], &in6.s6_addr32[3]);
743
 
        inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
744
 
        inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
745
 
        localaddr.sin6_family = AF_INET6;
746
 
        remaddr.sin6_family = AF_INET6;
747
 
#endif
748
 
    } else {
749
 
        protname = "tcp";
750
 
        sscanf(local_addr, "%X",
751
 
               &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
752
 
        sscanf(rem_addr, "%X",
753
 
               &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
754
 
        ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
755
 
        ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
756
 
    }
757
 
 
758
 
    if (num < 11) {
759
 
        fprintf(stderr, _("warning, got bogus tcp line.\n"));
760
 
        return;
761
 
    }
762
 
    if ((ap = get_afntype(((struct sockaddr *) &localaddr)->sa_family)) == NULL) {
763
 
        fprintf(stderr, _("netstat: unsupported address family %d !\n"),
764
 
                ((struct sockaddr *) &localaddr)->sa_family);
765
 
        return;
766
 
    }
767
 
    if (state == TCP_LISTEN) {
768
 
        time_len = 0;
769
 
        retr = 0L;
770
 
        rxq = 0L;
771
 
        txq = 0L;
772
 
    }
773
 
    safe_strncpy(local_addr, ap->sprint((struct sockaddr *) &localaddr, 
774
 
                                        flag_not), sizeof(local_addr));
775
 
    safe_strncpy(rem_addr, ap->sprint((struct sockaddr *) &remaddr, flag_not),
776
 
                 sizeof(rem_addr));
777
 
    if (flag_all || (flag_lst && !rem_port) || (!flag_lst && rem_port)) {
778
 
        snprintf(buffer, sizeof(buffer), "%s",
779
 
                 get_sname(htons(local_port), "tcp",
780
 
                           flag_not & FLAG_NUM_PORT));
781
 
 
782
 
        if ((strlen(local_addr) + strlen(buffer)) > 22)
783
 
            local_addr[22 - strlen(buffer)] = '\0';
784
 
 
785
 
        strcat(local_addr, ":");
786
 
        strcat(local_addr, buffer);
787
 
        snprintf(buffer, sizeof(buffer), "%s",
788
 
                 get_sname(htons(rem_port), "tcp", flag_not & FLAG_NUM_PORT));
789
 
 
790
 
        if ((strlen(rem_addr) + strlen(buffer)) > 22)
791
 
            rem_addr[22 - strlen(buffer)] = '\0';
792
 
 
793
 
        strcat(rem_addr, ":");
794
 
        strcat(rem_addr, buffer);
795
 
        timers[0] = '\0';
796
 
 
797
 
        if (flag_opt)
798
 
            switch (timer_run) {
799
 
            case 0:
800
 
                snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
801
 
                break;
802
 
 
803
 
            case 1:
804
 
                snprintf(timers, sizeof(timers), _("on (%2.2f/%ld/%d)"),
805
 
                         (double) time_len / HZ, retr, timeout);
806
 
                break;
807
 
 
808
 
            case 2:
809
 
                snprintf(timers, sizeof(timers), _("keepalive (%2.2f/%ld/%d)"),
810
 
                         (double) time_len / HZ, retr, timeout);
811
 
                break;
812
 
 
813
 
            case 3:
814
 
                snprintf(timers, sizeof(timers), _("timewait (%2.2f/%ld/%d)"),
815
 
                         (double) time_len / HZ, retr, timeout);
816
 
                break;
817
 
 
818
 
            default:
819
 
                snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"),
820
 
                         timer_run, (double) time_len / HZ, retr, timeout);
821
 
                break;
822
 
            }
823
 
        printf("%-4s  %6ld %6ld %-*s %-*s %-11s",
824
 
               protname, rxq, txq, netmax(23,strlen(local_addr)), local_addr, netmax(23,strlen(rem_addr)), rem_addr, _(tcp_state[state]));
825
 
 
826
 
        finish_this_one(uid,inode,timers);
827
 
    }
828
 
}
829
 
 
830
 
static int tcp_info(void)
831
 
{
832
 
    INFO_GUTS6(_PATH_PROCNET_TCP, _PATH_PROCNET_TCP6, "AF INET (tcp)",
833
 
               tcp_do_one);
834
 
}
835
 
 
836
 
static void udp_do_one(int lnr, const char *line)
837
 
{
838
 
    char buffer[8192], local_addr[64], rem_addr[64];
839
 
    char *udp_state, timers[64], more[512];
840
 
    int num, local_port, rem_port, d, state, timer_run, uid, timeout;
841
 
    char *protname;
842
 
#if HAVE_AFINET6
843
 
    struct sockaddr_in6 localaddr, remaddr;
844
 
    char addr6[INET6_ADDRSTRLEN];
845
 
    struct in6_addr in6;
846
 
    extern struct aftype inet6_aftype;
847
 
#else
848
 
    struct sockaddr_in localaddr, remaddr;
849
 
#endif
850
 
    struct aftype *ap;
851
 
    unsigned long rxq, txq, time_len, retr, inode;
852
 
 
853
 
    if (lnr == 0)
854
 
        return;
855
 
 
856
 
    more[0] = '\0';
857
 
    num = sscanf(line,
858
 
                 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %512s\n",
859
 
                 &d, local_addr, &local_port,
860
 
                 rem_addr, &rem_port, &state,
861
 
          &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
862
 
 
863
 
    if (strlen(local_addr) > 8) {
864
 
#if HAVE_AFINET6
865
 
        protname="udp6";
866
 
        sscanf(local_addr, "%08X%08X%08X%08X",
867
 
               &in6.s6_addr32[0], &in6.s6_addr32[1],
868
 
               &in6.s6_addr32[2], &in6.s6_addr32[3]);
869
 
        inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
870
 
        inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
871
 
        sscanf(rem_addr, "%08X%08X%08X%08X",
872
 
               &in6.s6_addr32[0], &in6.s6_addr32[1],
873
 
               &in6.s6_addr32[2], &in6.s6_addr32[3]);
874
 
        inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
875
 
        inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
876
 
        localaddr.sin6_family = AF_INET6;
877
 
        remaddr.sin6_family = AF_INET6;
878
 
#endif
879
 
    } else {
880
 
        protname="udp";
881
 
        sscanf(local_addr, "%X",
882
 
               &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
883
 
        sscanf(rem_addr, "%X",
884
 
               &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
885
 
        ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
886
 
        ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
887
 
    }
888
 
 
889
 
    retr = 0L;
890
 
    if (!flag_opt)
891
 
        more[0] = '\0';
892
 
 
893
 
    if (num < 10) {
894
 
        fprintf(stderr, _("warning, got bogus udp line.\n"));
895
 
        return;
896
 
    }
897
 
    if ((ap = get_afntype(((struct sockaddr *) &localaddr)->sa_family)) == NULL) {
898
 
        fprintf(stderr, _("netstat: unsupported address family %d !\n"),
899
 
                ((struct sockaddr *) &localaddr)->sa_family);
900
 
        return;
901
 
    }
902
 
    switch (state) {
903
 
    case TCP_ESTABLISHED:
904
 
        udp_state = _("ESTABLISHED");
905
 
        break;
906
 
 
907
 
    case TCP_CLOSE:
908
 
        udp_state = "";
909
 
        break;
910
 
 
911
 
    default:
912
 
        udp_state = _("UNKNOWN");
913
 
        break;
914
 
    }
915
 
 
916
 
#if HAVE_AFINET6
917
 
#define notnull(A) (((A.sin6_family == AF_INET6) && \
918
 
         ((A.sin6_addr.s6_addr32[0]) ||            \
919
 
          (A.sin6_addr.s6_addr32[1]) ||            \
920
 
          (A.sin6_addr.s6_addr32[2]) ||            \
921
 
          (A.sin6_addr.s6_addr32[3]))) ||          \
922
 
        ((A.sin6_family == AF_INET) &&             \
923
 
         ((struct sockaddr_in *) &A)->sin_addr.s_addr))
924
 
#else
925
 
#define notnull(A) (A.sin_addr.s_addr)
926
 
#endif
927
 
 
928
 
    if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst))
929
 
    {
930
 
        safe_strncpy(local_addr, ap->sprint((struct sockaddr *) &localaddr, 
931
 
                                            flag_not), sizeof(local_addr));
932
 
        snprintf(buffer, sizeof(buffer), "%s",
933
 
                 get_sname(htons(local_port), "udp",
934
 
                           flag_not & FLAG_NUM_PORT));
935
 
        if (!flag_wide) {
936
 
            if ((strlen(local_addr) + strlen(buffer)) > 22)
937
 
                local_addr[22 - strlen(buffer)] = '\0';
938
 
        }
939
 
        strcat(local_addr, ":");
940
 
        strcat(local_addr, buffer);
941
 
 
942
 
        snprintf(buffer, sizeof(buffer), "%s",
943
 
                 get_sname(htons(rem_port), "udp", flag_not & FLAG_NUM_PORT));
944
 
        safe_strncpy(rem_addr, ap->sprint((struct sockaddr *) &remaddr, 
945
 
                                          flag_not), sizeof(rem_addr));
946
 
        if (!flag_wide) {
947
 
            if ((strlen(rem_addr) + strlen(buffer)) > 22)
948
 
                rem_addr[22 - strlen(buffer)] = '\0';
949
 
        }
950
 
        strcat(rem_addr, ":");
951
 
        strcat(rem_addr, buffer);
952
 
 
953
 
        timers[0] = '\0';
954
 
        if (flag_opt)
955
 
            switch (timer_run) {
956
 
            case 0:
957
 
                snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
958
 
                break;
959
 
 
960
 
            case 1:
961
 
            case 2:
962
 
                snprintf(timers, sizeof(timers), _("on%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100, retr, timeout);
963
 
                break;
964
 
 
965
 
            default:
966
 
                snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100,
967
 
                         retr, timeout);
968
 
                break;
969
 
            }
970
 
        printf("%-4s  %6ld %6ld %-23s %-23s %-11s",
971
 
               protname, rxq, txq, local_addr, rem_addr, udp_state);
972
 
 
973
 
        finish_this_one(uid,inode,timers);
974
 
    }
975
 
}
976
 
 
977
 
static int udp_info(void)
978
 
{
979
 
    INFO_GUTS6(_PATH_PROCNET_UDP, _PATH_PROCNET_UDP6, "AF INET (udp)",
980
 
               udp_do_one);
981
 
}
982
 
 
983
 
static void raw_do_one(int lnr, const char *line)
984
 
{
985
 
    char buffer[8192], local_addr[64], rem_addr[64];
986
 
    char timers[64], more[512];
987
 
    int num, local_port, rem_port, d, state, timer_run, uid, timeout;
988
 
    char *protname;
989
 
#if HAVE_AFINET6
990
 
    struct sockaddr_in6 localaddr, remaddr;
991
 
    char addr6[INET6_ADDRSTRLEN];
992
 
    struct in6_addr in6;
993
 
    extern struct aftype inet6_aftype;
994
 
#else
995
 
    struct sockaddr_in localaddr, remaddr;
996
 
#endif
997
 
    struct aftype *ap;
998
 
    unsigned long rxq, txq, time_len, retr, inode;
999
 
 
1000
 
    if (lnr == 0)
1001
 
        return;
1002
 
 
1003
 
    more[0] = '\0';
1004
 
    num = sscanf(line,
1005
 
                 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %512s\n",
1006
 
                 &d, local_addr, &local_port, rem_addr, &rem_port, &state,
1007
 
          &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
1008
 
 
1009
 
    if (strlen(local_addr) > 8) {
1010
 
#if HAVE_AFINET6
1011
 
        protname = "raw6";
1012
 
        sscanf(local_addr, "%08X%08X%08X%08X",
1013
 
               &in6.s6_addr32[0], &in6.s6_addr32[1],
1014
 
           &in6.s6_addr32[2], &in6.s6_addr32[3]);
1015
 
    inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1016
 
        inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
1017
 
        sscanf(rem_addr, "%08X%08X%08X%08X",
1018
 
               &in6.s6_addr32[0], &in6.s6_addr32[1],
1019
 
           &in6.s6_addr32[2], &in6.s6_addr32[3]);
1020
 
    inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1021
 
        inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
1022
 
        localaddr.sin6_family = AF_INET6;
1023
 
        remaddr.sin6_family = AF_INET6;
1024
 
#endif
1025
 
    } else {
1026
 
        protname = "raw";
1027
 
        sscanf(local_addr, "%X",
1028
 
               &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
1029
 
        sscanf(rem_addr, "%X",
1030
 
               &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
1031
 
        ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
1032
 
        ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
1033
 
    }
1034
 
#if HAVE_AFINET6
1035
 
    if ((ap = get_afntype(localaddr.sin6_family)) == NULL) {
1036
 
        fprintf(stderr, _("netstat: unsupported address family %d !\n"), localaddr.sin6_family);
1037
 
        return;
1038
 
    }
1039
 
#else
1040
 
    if ((ap = get_afntype(localaddr.sin_family)) == NULL) {
1041
 
        fprintf(stderr, _("netstat: unsupported address family %d !\n"), localaddr.sin_family);
1042
 
        return;
1043
 
    }
1044
 
#endif
1045
 
 
1046
 
    if (!flag_opt)
1047
 
        more[0] = '\0';
1048
 
 
1049
 
    if (num < 10) {
1050
 
        fprintf(stderr, _("warning, got bogus raw line.\n"));
1051
 
        return;
1052
 
    }
1053
 
 
1054
 
    if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst))
1055
 
    {
1056
 
        snprintf(buffer, sizeof(buffer), "%s",
1057
 
                 get_sname(htons(local_port), "raw",
1058
 
                           flag_not & FLAG_NUM_PORT));
1059
 
        safe_strncpy(local_addr, ap->sprint((struct sockaddr *) &localaddr, 
1060
 
                                            flag_not), sizeof(local_addr));
1061
 
        if (!flag_wide) {
1062
 
            if ((strlen(local_addr) + strlen(buffer)) > 22)
1063
 
                local_addr[22 - strlen(buffer)] = '\0';
1064
 
        }
1065
 
        strcat(local_addr, ":");
1066
 
        strcat(local_addr, buffer);
1067
 
 
1068
 
        snprintf(buffer, sizeof(buffer), "%s",
1069
 
                 get_sname(htons(rem_port), "raw", flag_not & FLAG_NUM_PORT));
1070
 
        safe_strncpy(rem_addr, ap->sprint((struct sockaddr *) &remaddr, 
1071
 
                                          flag_not), sizeof(rem_addr));
1072
 
        if (!flag_wide) {
1073
 
            if ((strlen(rem_addr) + strlen(buffer)) > 22)
1074
 
                rem_addr[22 - strlen(buffer)] = '\0';
1075
 
        }
1076
 
        strcat(rem_addr, ":");
1077
 
        strcat(rem_addr, buffer);
1078
 
 
1079
 
        timers[0] = '\0';
1080
 
        if (flag_opt)
1081
 
            switch (timer_run) {
1082
 
            case 0:
1083
 
                snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
1084
 
                break;
1085
 
 
1086
 
            case 1:
1087
 
            case 2:
1088
 
                snprintf(timers, sizeof(timers), _("on%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100,
1089
 
                         retr, timeout);
1090
 
                break;
1091
 
 
1092
 
            default:
1093
 
                snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"),
1094
 
                         timer_run, (double) time_len / 100,
1095
 
                         retr, timeout);
1096
 
                break;
1097
 
            }
1098
 
        printf("%-4s  %6ld %6ld %-23s %-23s %-11d",
1099
 
               protname, rxq, txq, local_addr, rem_addr, state);
1100
 
 
1101
 
        finish_this_one(uid,inode,timers);
1102
 
    }
1103
 
}
1104
 
 
1105
 
static int raw_info(void)
1106
 
{
1107
 
    INFO_GUTS6(_PATH_PROCNET_RAW, _PATH_PROCNET_RAW6, "AF INET (raw)",
1108
 
               raw_do_one);
1109
 
}
1110
 
 
1111
 
#endif
1112
 
 
1113
 
 
1114
 
#if HAVE_AFUNIX
1115
 
 
1116
 
#define HAS_INODE 1
1117
 
 
1118
 
static void unix_do_one(int nr, const char *line)
1119
 
{
1120
 
    static int has = 0;
1121
 
    char path[MAXPATHLEN], ss_flags[32];
1122
 
    char *ss_proto, *ss_state, *ss_type;
1123
 
    int num, state, type;
1124
 
    void *d;
1125
 
    unsigned long refcnt, proto, flags, inode;
1126
 
 
1127
 
    if (nr == 0) {
1128
 
        if (strstr(line, "Inode"))
1129
 
            has |= HAS_INODE;
1130
 
        return;
1131
 
    }
1132
 
    path[0] = '\0';
1133
 
    num = sscanf(line, "%p: %lX %lX %lX %X %X %lu %s",
1134
 
                 &d, &refcnt, &proto, &flags, &type, &state, &inode, path);
1135
 
    if (num < 6) {
1136
 
        fprintf(stderr, _("warning, got bogus unix line.\n"));
1137
 
        return;
1138
 
    }
1139
 
    if (!(has & HAS_INODE))
1140
 
        snprintf(path,sizeof(path),"%lu",inode);
1141
 
 
1142
 
    if (!flag_all) {
1143
 
        if ((state == SS_UNCONNECTED) && (flags & SO_ACCEPTCON)) {
1144
 
                if (!flag_lst)
1145
 
                        return;
1146
 
        } else {
1147
 
                if (flag_lst)
1148
 
                        return;
1149
 
        }
1150
 
    }
1151
 
 
1152
 
    switch (proto) {
1153
 
    case 0:
1154
 
        ss_proto = "unix";
1155
 
        break;
1156
 
 
1157
 
    default:
1158
 
        ss_proto = "??";
1159
 
    }
1160
 
 
1161
 
    switch (type) {
1162
 
    case SOCK_STREAM:
1163
 
        ss_type = _("STREAM");
1164
 
        break;
1165
 
 
1166
 
    case SOCK_DGRAM:
1167
 
        ss_type = _("DGRAM");
1168
 
        break;
1169
 
 
1170
 
    case SOCK_RAW:
1171
 
        ss_type = _("RAW");
1172
 
        break;
1173
 
 
1174
 
    case SOCK_RDM:
1175
 
        ss_type = _("RDM");
1176
 
        break;
1177
 
 
1178
 
    case SOCK_SEQPACKET:
1179
 
        ss_type = _("SEQPACKET");
1180
 
        break;
1181
 
 
1182
 
    default:
1183
 
        ss_type = _("UNKNOWN");
1184
 
    }
1185
 
 
1186
 
    switch (state) {
1187
 
    case SS_FREE:
1188
 
        ss_state = _("FREE");
1189
 
        break;
1190
 
 
1191
 
    case SS_UNCONNECTED:
1192
 
        /*
1193
 
         * Unconnected sockets may be listening
1194
 
         * for something.
1195
 
         */
1196
 
        if (flags & SO_ACCEPTCON) {
1197
 
            ss_state = _("LISTENING");
1198
 
        } else {
1199
 
            ss_state = "";
1200
 
        }
1201
 
        break;
1202
 
 
1203
 
    case SS_CONNECTING:
1204
 
        ss_state = _("CONNECTING");
1205
 
        break;
1206
 
 
1207
 
    case SS_CONNECTED:
1208
 
        ss_state = _("CONNECTED");
1209
 
        break;
1210
 
 
1211
 
    case SS_DISCONNECTING:
1212
 
        ss_state = _("DISCONNECTING");
1213
 
        break;
1214
 
 
1215
 
    default:
1216
 
        ss_state = _("UNKNOWN");
1217
 
    }
1218
 
 
1219
 
    strcpy(ss_flags, "[ ");
1220
 
    if (flags & SO_ACCEPTCON)
1221
 
        strcat(ss_flags, "ACC ");
1222
 
    if (flags & SO_WAITDATA)
1223
 
        strcat(ss_flags, "W ");
1224
 
    if (flags & SO_NOSPACE)
1225
 
        strcat(ss_flags, "N ");
1226
 
 
1227
 
    strcat(ss_flags, "]");
1228
 
 
1229
 
    printf("%-5s %-6ld %-11s %-10s %-13s ",
1230
 
           ss_proto, refcnt, ss_flags, ss_type, ss_state);
1231
 
    if (has & HAS_INODE)
1232
 
        printf("%-8lu ",inode);
1233
 
    else
1234
 
        printf("-        ");
1235
 
    if (flag_prg)
1236
 
        printf("%-" PROGNAME_WIDTHs "s",(has & HAS_INODE?prg_cache_get(inode):"-"));
1237
 
    puts(path);
1238
 
}
1239
 
 
1240
 
static int unix_info(void)
1241
 
{
1242
 
 
1243
 
    printf(_("Active UNIX domain sockets "));
1244
 
    if (flag_all)
1245
 
        printf(_("(servers and established)"));
1246
 
    else {
1247
 
      if (flag_lst)
1248
 
        printf(_("(only servers)"));
1249
 
      else
1250
 
        printf(_("(w/o servers)"));
1251
 
    }
1252
 
 
1253
 
    printf(_("\nProto RefCnt Flags       Type       State         I-Node"));
1254
 
    print_progname_banner();
1255
 
    printf(_(" Path\n"));       /* xxx */
1256
 
 
1257
 
    {
1258
 
        INFO_GUTS(_PATH_PROCNET_UNIX, "AF UNIX", unix_do_one);
1259
 
    }
1260
 
}
1261
 
#endif
1262
 
 
1263
 
 
1264
 
#if HAVE_AFAX25
1265
 
static int ax25_info(void)
1266
 
{
1267
 
    FILE *f;
1268
 
    char buffer[256], buf[16];
1269
 
    char *src, *dst, *dev, *p;
1270
 
    int st, vs, vr, sendq, recvq, ret;
1271
 
    int new = -1;               /* flag for new (2.1.x) kernels */
1272
 
    static char *ax25_state[5] =
1273
 
    {
1274
 
        N_("LISTENING"),
1275
 
        N_("SABM SENT"),
1276
 
        N_("DISC SENT"),
1277
 
        N_("ESTABLISHED"),
1278
 
        N_("RECOVERY")
1279
 
    };
1280
 
    if (!(f = fopen(_PATH_PROCNET_AX25, "r"))) {
1281
 
        if (errno != ENOENT) {
1282
 
            perror(_PATH_PROCNET_AX25);
1283
 
            return (-1);
1284
 
        }
1285
 
        if (flag_arg || flag_ver)
1286
 
            ESYSNOT("netstat", "AF AX25");
1287
 
        if (flag_arg)
1288
 
            return (1);
1289
 
        else
1290
 
            return (0);
1291
 
    }
1292
 
    printf(_("Active AX.25 sockets\n"));
1293
 
    printf(_("Dest       Source     Device  State        Vr/Vs    Send-Q  Recv-Q\n"));
1294
 
    while (fgets(buffer, 256, f)) {
1295
 
        if (new == -1) {
1296
 
            if (!strncmp(buffer, "dest_addr", 9)) {
1297
 
                new = 0;
1298
 
                continue;       /* old kernels have a header line */
1299
 
            } else
1300
 
                new = 1;
1301
 
        }
1302
 
        /*
1303
 
         * In a network connection with no user socket the Snd-Q, Rcv-Q
1304
 
         * and Inode fields are empty in 2.0.x and '*' in 2.1.x
1305
 
         */
1306
 
        sendq = 0;
1307
 
        recvq = 0;
1308
 
        if (new == 0) {
1309
 
            dst = buffer;
1310
 
            src = buffer + 10;
1311
 
            dst[9] = 0;
1312
 
            src[9] = 0;
1313
 
            ret = sscanf(buffer + 20, "%s %d %d %d %*d %*d/%*d %*d/%*d %*d/%*d %*d/%*d %*d/%*d %*d %*d %*d %d %d %*d",
1314
 
                   buf, &st, &vs, &vr, &sendq, &recvq);
1315
 
            if (ret != 4 && ret != 6) {
1316
 
                printf(_("Problem reading data from %s\n"), _PATH_PROCNET_AX25);
1317
 
                continue;
1318
 
            }
1319
 
            dev = buf;
1320
 
        } else {
1321
 
            p = buffer;
1322
 
            while (*p != ' ') p++;
1323
 
            p++;
1324
 
            dev = p;
1325
 
            while (*p != ' ') p++;
1326
 
            *p++ = 0;
1327
 
            src = p;
1328
 
            while (*p != ' ') p++;
1329
 
            *p++ = 0;
1330
 
            dst = p;
1331
 
            while (*p != ' ') p++;
1332
 
            *p++ = 0;
1333
 
            ret = sscanf(p, "%d %d %d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d %*d",
1334
 
                   &st, &vs, &vr, &sendq, &recvq);
1335
 
            if (ret != 3 && ret != 5) {
1336
 
                    printf(_("problem reading data from %s\n"), _PATH_PROCNET_AX25);
1337
 
                    continue;
1338
 
            }
1339
 
            /*
1340
 
             * FIXME: digipeaters should be handled somehow.
1341
 
             * For now we just strip them.
1342
 
             */
1343
 
            p = dst;
1344
 
            while (*p && *p != ',') p++;
1345
 
            *p = 0;
1346
 
        }
1347
 
        printf("%-9s  %-9s  %-6s  %-11s  %03d/%03d  %-6d  %-6d\n",
1348
 
               dst, src,
1349
 
               dev,
1350
 
               _(ax25_state[st]),
1351
 
               vr, vs, sendq, recvq);
1352
 
    }
1353
 
    fclose(f);
1354
 
    return 0;
1355
 
}
1356
 
#endif
1357
 
 
1358
 
 
1359
 
#if HAVE_AFIPX
1360
 
static int ipx_info(void)
1361
 
{
1362
 
    FILE *f;
1363
 
    char buf[256];
1364
 
    unsigned long txq, rxq;
1365
 
    unsigned int state;
1366
 
    unsigned int uid;
1367
 
    char *st;
1368
 
    int nc;
1369
 
    struct aftype *ap;
1370
 
    struct passwd *pw;
1371
 
    char sad[50], dad[50];
1372
 
    struct sockaddr sa;
1373
 
    unsigned sport = 0, dport = 0;
1374
 
    struct stat s;
1375
 
    
1376
 
    f = fopen(_PATH_PROCNET_IPX_SOCKET1, "r");
1377
 
    if (!f) {
1378
 
        if (errno != ENOENT) {
1379
 
            perror(_PATH_PROCNET_IPX_SOCKET1);
1380
 
            return (-1);
1381
 
        }
1382
 
        f = fopen(_PATH_PROCNET_IPX_SOCKET2, "r");
1383
 
 
1384
 
        /* We need to check for directory */
1385
 
        if (f) {
1386
 
            fstat(fileno(f), &s);
1387
 
            if (!S_ISREG(s.st_mode)) {
1388
 
                fclose(f);
1389
 
                f=NULL;
1390
 
            }
1391
 
        }
1392
 
 
1393
 
        if (!f) {
1394
 
            if (errno != ENOENT) {
1395
 
                perror(_PATH_PROCNET_IPX_SOCKET2);
1396
 
                return (-1);
1397
 
            }
1398
 
            if (flag_arg || flag_ver)
1399
 
                ESYSNOT("netstat", "AF IPX");
1400
 
            if (flag_arg)
1401
 
                return (1);
1402
 
            else
1403
 
                return (0);
1404
 
        }
1405
 
    }
1406
 
    printf(_("Active IPX sockets\nProto Recv-Q Send-Q Local Address              Foreign Address            State"));   /* xxx */
1407
 
    if (flag_exp > 1)
1408
 
        printf(_(" User"));     /* xxx */
1409
 
    printf("\n");
1410
 
    if ((ap = get_afntype(AF_IPX)) == NULL) {
1411
 
        EINTERN("netstat.c", "AF_IPX missing");
1412
 
        return (-1);
1413
 
    }
1414
 
    fgets(buf, 255, f);
1415
 
 
1416
 
    while (fgets(buf, 255, f) != NULL) {
1417
 
        sscanf(buf, "%s %s %lX %lX %d %d",
1418
 
               sad, dad, &txq, &rxq, &state, &uid);
1419
 
        if ((st = rindex(sad, ':'))) {
1420
 
            *st++ = '\0';
1421
 
            sscanf(st, "%X", &sport);   /* net byt order */
1422
 
            sport = ntohs(sport);
1423
 
        } else {
1424
 
            EINTERN("netstat.c", "ipx socket format error in source port");
1425
 
            return (-1);
1426
 
        }
1427
 
        nc = 0;
1428
 
        if (strcmp(dad, "Not_Connected") != 0) {
1429
 
            if ((st = rindex(dad, ':'))) {
1430
 
                *st++ = '\0';
1431
 
                sscanf(st, "%X", &dport);       /* net byt order */
1432
 
                dport = ntohs(dport);
1433
 
            } else {
1434
 
                EINTERN("netstat.c", "ipx soket format error in destination port");
1435
 
                return (-1);
1436
 
            }
1437
 
        } else
1438
 
            nc = 1;
1439
 
 
1440
 
        switch (state) {
1441
 
        case TCP_ESTABLISHED:
1442
 
            st = _("ESTAB");
1443
 
            break;
1444
 
 
1445
 
        case TCP_CLOSE:
1446
 
            st = "";
1447
 
            break;
1448
 
 
1449
 
        default:
1450
 
            st = _("UNK.");
1451
 
            break;
1452
 
        }
1453
 
 
1454
 
        /* Fetch and resolve the Source */
1455
 
        (void) ap->input(4, sad, &sa);
1456
 
        safe_strncpy(buf, ap->sprint(&sa, flag_not), sizeof(buf));
1457
 
        snprintf(sad, sizeof(sad), "%s:%04X", buf, sport);
1458
 
 
1459
 
        if (!nc) {
1460
 
            /* Fetch and resolve the Destination */
1461
 
            (void) ap->input(4, dad, &sa);
1462
 
            safe_strncpy(buf, ap->sprint(&sa, flag_not), sizeof(buf));
1463
 
            snprintf(dad, sizeof(dad), "%s:%04X", buf, dport);
1464
 
        } else
1465
 
            strcpy(dad, "-");
1466
 
 
1467
 
        printf("IPX   %6ld %6ld %-26s %-26s %-5s", txq, rxq, sad, dad, st);
1468
 
        if (flag_exp > 1) {
1469
 
            if (!(flag_not & FLAG_NUM_USER) && ((pw = getpwuid(uid)) != NULL))
1470
 
                printf(" %-10s", pw->pw_name);
1471
 
            else
1472
 
                printf(" %-10d", uid);
1473
 
        }
1474
 
        printf("\n");
1475
 
    }
1476
 
    fclose(f);
1477
 
    return 0;
1478
 
}
1479
 
#endif
1480
 
 
1481
 
static int iface_info(void)
1482
 
{
1483
 
    if (skfd < 0) {
1484
 
        if ((skfd = sockets_open(0)) < 0) {
1485
 
            perror("socket");
1486
 
            exit(1);
1487
 
        }
1488
 
        printf(_("Kernel Interface table\n"));
1489
 
    }
1490
 
    if (flag_exp < 2) {
1491
 
        ife_short = 1;
1492
 
        printf(_("Iface   MTU Met   RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg\n"));
1493
 
    }
1494
 
 
1495
 
    if (for_all_interfaces(do_if_print, &flag_all) < 0) {
1496
 
        perror(_("missing interface information"));
1497
 
        exit(1);
1498
 
    }
1499
 
    if (flag_cnt)
1500
 
        if_cache_free();
1501
 
    else {
1502
 
        close(skfd);
1503
 
        skfd = -1;
1504
 
    }
1505
 
 
1506
 
    return 0;
1507
 
}
1508
 
 
1509
 
 
1510
 
static void version(void)
1511
 
{
1512
 
    printf("%s\n%s\n%s\n%s\n", Release, Version, Signature, Features);
1513
 
    exit(E_VERSION);
1514
 
}
1515
 
 
1516
 
 
1517
 
static void usage(void)
1518
 
{
1519
 
    fprintf(stderr, _("usage: netstat [-veenNcCF] [<Af>] -r         netstat {-V|--version|-h|--help}\n"));
1520
 
    fprintf(stderr, _("       netstat [-vnNcaeol] [<Socket> ...]\n"));
1521
 
    fprintf(stderr, _("       netstat { [-veenNac] -i | [-cnNe] -M | -s }\n\n"));
1522
 
 
1523
 
    fprintf(stderr, _("        -r, --route              display routing table\n"));
1524
 
    fprintf(stderr, _("        -i, --interfaces         display interface table\n"));
1525
 
    fprintf(stderr, _("        -g, --groups             display multicast group memberships\n"));
1526
 
    fprintf(stderr, _("        -s, --statistics         display networking statistics (like SNMP)\n"));
1527
 
#if HAVE_FW_MASQUERADE
1528
 
    fprintf(stderr, _("        -M, --masquerade         display masqueraded connections\n\n"));
1529
 
#endif
1530
 
    fprintf(stderr, _("        -v, --verbose            be verbose\n"));
1531
 
    fprintf(stderr, _("        -n, --numeric            don't resolve names\n"));
1532
 
    fprintf(stderr, _("        --numeric-hosts          don't resolve host names\n"));
1533
 
    fprintf(stderr, _("        --numeric-ports          don't resolve port names\n"));
1534
 
    fprintf(stderr, _("        --numeric-users          don't resolve user names\n"));
1535
 
    fprintf(stderr, _("        -N, --symbolic           resolve hardware names\n"));
1536
 
    fprintf(stderr, _("        -e, --extend             display other/more information\n"));
1537
 
    fprintf(stderr, _("        -p, --programs           display PID/Program name for sockets\n"));
1538
 
    fprintf(stderr, _("        -c, --continuous         continuous listing\n\n"));
1539
 
    fprintf(stderr, _("        -l, --listening          display listening server sockets\n"));
1540
 
    fprintf(stderr, _("        -a, --all, --listening   display all sockets (default: connected)\n"));
1541
 
    fprintf(stderr, _("        -o, --timers             display timers\n"));
1542
 
    fprintf(stderr, _("        -F, --fib                display Forwarding Information Base (default)\n"));
1543
 
    fprintf(stderr, _("        -C, --cache              display routing cache instead of FIB\n\n"));
1544
 
 
1545
 
    fprintf(stderr, _("  <Socket>={-t|--tcp} {-u|--udp} {-w|--raw} {-x|--unix} --ax25 --ipx --netrom\n"));
1546
 
    fprintf(stderr, _("  <AF>=Use '-6|-4' or '-A <af>' or '--<af>'; default: %s\n"), DFLT_AF);
1547
 
    fprintf(stderr, _("  List of possible address families (which support routing):\n"));
1548
 
    print_aflist(1); /* 1 = routeable */
1549
 
    exit(E_USAGE);
1550
 
}
1551
 
 
1552
 
 
1553
 
int main
1554
 
 (int argc, char *argv[]) {
1555
 
    int i;
1556
 
    int lop;
1557
 
    static struct option longopts[] =
1558
 
    {
1559
 
        AFTRANS_OPTS,
1560
 
        {"version", 0, 0, 'V'},
1561
 
        {"interfaces", 0, 0, 'i'},
1562
 
        {"help", 0, 0, 'h'},
1563
 
        {"route", 0, 0, 'r'},
1564
 
#if HAVE_FW_MASQUERADE
1565
 
        {"masquerade", 0, 0, 'M'},
1566
 
#endif
1567
 
        {"protocol", 1, 0, 'A'},
1568
 
        {"tcp", 0, 0, 't'},
1569
 
        {"udp", 0, 0, 'u'},
1570
 
        {"raw", 0, 0, 'w'},
1571
 
        {"unix", 0, 0, 'x'},
1572
 
        {"listening", 0, 0, 'l'},
1573
 
        {"all", 0, 0, 'a'},
1574
 
        {"timers", 0, 0, 'o'},
1575
 
        {"continuous", 0, 0, 'c'},
1576
 
        {"extend", 0, 0, 'e'},
1577
 
        {"programs", 0, 0, 'p'},
1578
 
        {"verbose", 0, 0, 'v'},
1579
 
        {"statistics", 0, 0, 's'},
1580
 
        {"numeric", 0, 0, 'n'},
1581
 
        {"numeric-hosts", 0, 0, '!'},
1582
 
        {"numeric-ports", 0, 0, '@'},
1583
 
        {"numeric-users", 0, 0, '#'},
1584
 
        {"symbolic", 0, 0, 'N'},
1585
 
        {"cache", 0, 0, 'C'},
1586
 
        {"fib", 0, 0, 'F'},
1587
 
        {"groups", 0, 0, 'g'},
1588
 
        {NULL, 0, 0, 0}
1589
 
    };
1590
 
 
1591
 
#if I18N
1592
 
    setlocale (LC_ALL, "");
1593
 
    bindtextdomain("net-tools", "/usr/share/locale");
1594
 
    textdomain("net-tools");
1595
 
#endif
1596
 
    getroute_init();            /* Set up AF routing support */
1597
 
 
1598
 
    afname[0] = '\0';
1599
 
    while ((i = getopt_long(argc, argv, "MCFA:acdegphinNorstuVv?wxl64", longopts, &lop)) != EOF)
1600
 
        switch (i) {
1601
 
        case -1:
1602
 
            break;
1603
 
        case 1:
1604
 
            if (lop < 0 || lop >= AFTRANS_CNT) {
1605
 
                EINTERN("netstat.c", "longopts 1 range");
1606
 
                break;
1607
 
            }
1608
 
            if (aftrans_opt(longopts[lop].name))
1609
 
                exit(1);
1610
 
            break;
1611
 
        case 'A':
1612
 
            if (aftrans_opt(optarg))
1613
 
                exit(1);
1614
 
            break;
1615
 
        case 'M':
1616
 
            flag_mas++;
1617
 
            break;
1618
 
        case 'a':
1619
 
            flag_all++;
1620
 
            break;
1621
 
        case 'l':
1622
 
            flag_lst++;
1623
 
            break;
1624
 
        case 'c':
1625
 
            flag_cnt++;
1626
 
            break;
1627
 
 
1628
 
        case 'd':
1629
 
            flag_deb++;
1630
 
            break;
1631
 
        case 'g':
1632
 
            flag_igmp++;
1633
 
            break;
1634
 
        case 'e':
1635
 
            flag_exp++;
1636
 
            break;
1637
 
        case 'p':
1638
 
            flag_prg++;
1639
 
            break;
1640
 
        case 'i':
1641
 
            flag_int++;
1642
 
            break;
1643
 
        case 'n':
1644
 
            flag_not |= FLAG_NUM;
1645
 
            break;
1646
 
        case '!':
1647
 
            flag_not |= FLAG_NUM_HOST;
1648
 
            break;
1649
 
        case '@':
1650
 
            flag_not |= FLAG_NUM_PORT;
1651
 
            break;
1652
 
        case '#':
1653
 
            flag_not |= FLAG_NUM_USER;
1654
 
            break;
1655
 
        case 'N':
1656
 
            flag_not |= FLAG_SYM;
1657
 
            break;
1658
 
        case 'C':
1659
 
            flag_cf |= FLAG_CACHE;
1660
 
            break;
1661
 
        case 'F':
1662
 
            flag_cf |= FLAG_FIB;
1663
 
            break;
1664
 
        case 'o':
1665
 
            flag_opt++;
1666
 
            break;
1667
 
        case '6':
1668
 
            if (aftrans_opt("inet6"))
1669
 
                exit(1);
1670
 
            break;
1671
 
        case '4':
1672
 
            if (aftrans_opt("inet"))
1673
 
                exit(1);
1674
 
            break;
1675
 
        case 'V':
1676
 
            version();
1677
 
            /*NOTREACHED */
1678
 
        case 'v':
1679
 
            flag_ver |= FLAG_VERBOSE;
1680
 
            break;
1681
 
        case 'r':
1682
 
            flag_rou++;
1683
 
            break;
1684
 
 
1685
 
        case 't':
1686
 
            flag_tcp++;
1687
 
            break;
1688
 
 
1689
 
        case 'u':
1690
 
            flag_udp++;
1691
 
            break;
1692
 
        case 'w':
1693
 
            flag_raw++;
1694
 
            break;
1695
 
        case 'x':
1696
 
            if (aftrans_opt("unix"))
1697
 
                exit(1);
1698
 
            break;
1699
 
        case '?':
1700
 
        case 'h':
1701
 
            usage();
1702
 
        case 's':
1703
 
            flag_sta++;
1704
 
        }
1705
 
 
1706
 
    if (flag_int + flag_rou + flag_mas + flag_sta > 1)
1707
 
        usage();
1708
 
 
1709
 
    if ((flag_inet || flag_inet6 || flag_sta) && !(flag_tcp || flag_udp || flag_raw))
1710
 
        flag_tcp = flag_udp = flag_raw = 1;
1711
 
 
1712
 
    if ((flag_tcp || flag_udp || flag_raw || flag_igmp) && !(flag_inet || flag_inet6))
1713
 
        flag_inet = flag_inet6 = 1;
1714
 
 
1715
 
    flag_arg = flag_tcp + flag_udp + flag_raw + flag_unx + flag_ipx
1716
 
        + flag_ax25 + flag_netrom + flag_igmp + flag_x25;
1717
 
 
1718
 
    if (flag_mas) {
1719
 
#if HAVE_FW_MASQUERADE && HAVE_AFINET
1720
 
#if MORE_THAN_ONE_MASQ_AF
1721
 
        if (!afname[0])
1722
 
            strcpy(afname, DFLT_AF);
1723
 
#endif
1724
 
        for (;;) {
1725
 
            i = ip_masq_info(flag_not & FLAG_NUM_HOST,
1726
 
                             flag_not & FLAG_NUM_PORT, flag_exp);
1727
 
            if (i || !flag_cnt)
1728
 
                break;
1729
 
            sleep(1);
1730
 
        }
1731
 
#else
1732
 
        ENOSUPP("netstat.c", "FW_MASQUERADE");
1733
 
        i = -1;
1734
 
#endif
1735
 
        return (i);
1736
 
    }
1737
 
 
1738
 
    if (flag_sta) {
1739
 
        inittab();
1740
 
        parsesnmp(flag_raw, flag_tcp, flag_udp);
1741
 
        exit(0);
1742
 
    }
1743
 
    
1744
 
    if (flag_rou) {
1745
 
        int options = 0;
1746
 
 
1747
 
        if (!afname[0])
1748
 
            strcpy(afname, DFLT_AF);
1749
 
 
1750
 
        if (flag_exp == 2)
1751
 
            flag_exp = 1;
1752
 
        else if (flag_exp == 1)
1753
 
            flag_exp = 2;
1754
 
 
1755
 
        options = (flag_exp & FLAG_EXT) | flag_not | flag_cf | flag_ver;
1756
 
        if (!flag_cf)
1757
 
            options |= FLAG_FIB;
1758
 
 
1759
 
        for (;;) {
1760
 
            i = route_info(afname, options);
1761
 
            if (i || !flag_cnt)
1762
 
                break;
1763
 
            sleep(1);
1764
 
        }
1765
 
        return (i);
1766
 
    }
1767
 
    if (flag_int) {
1768
 
        for (;;) {
1769
 
            i = iface_info();
1770
 
            if (!flag_cnt || i)
1771
 
                break;
1772
 
            sleep(1);
1773
 
        }
1774
 
        return (i);
1775
 
    }
1776
 
    for (;;) {
1777
 
        if (!flag_arg || flag_tcp || flag_udp || flag_raw) {
1778
 
#if HAVE_AFINET
1779
 
            prg_cache_load();
1780
 
            printf(_("Active Internet connections "));  /* xxx */
1781
 
 
1782
 
            if (flag_all)
1783
 
                printf(_("(servers and established)"));
1784
 
            else {
1785
 
              if (flag_lst)
1786
 
                printf(_("(only servers)"));
1787
 
              else
1788
 
                printf(_("(w/o servers)"));
1789
 
            }
1790
 
            printf(_("\nProto Recv-Q Send-Q Local Address           Foreign Address         State      "));     /* xxx */
1791
 
            if (flag_exp > 1)
1792
 
                printf(_(" User       Inode     "));
1793
 
            print_progname_banner();
1794
 
            if (flag_opt)
1795
 
                printf(_(" Timer"));    /* xxx */
1796
 
            printf("\n");
1797
 
#else
1798
 
            if (flag_arg) {
1799
 
                i = 1;
1800
 
                ENOSUPP("netstat", "AF INET");
1801
 
            }
1802
 
#endif
1803
 
        }
1804
 
#if HAVE_AFINET
1805
 
        if (!flag_arg || flag_tcp) {
1806
 
            i = tcp_info();
1807
 
            if (i)
1808
 
                return (i);
1809
 
        }
1810
 
        if (!flag_arg || flag_udp) {
1811
 
            i = udp_info();
1812
 
            if (i)
1813
 
                return (i);
1814
 
        }
1815
 
        if (!flag_arg || flag_raw) {
1816
 
            i = raw_info();
1817
 
            if (i)
1818
 
                return (i);
1819
 
        }
1820
 
 
1821
 
        if (flag_igmp) {
1822
 
#if HAVE_AFINET6
1823
 
            printf( "IPv6/");
1824
 
#endif
1825
 
            printf( _("IPv4 Group Memberships\n") );
1826
 
            printf( _("Interface       RefCnt Group\n") );
1827
 
            printf( "--------------- ------ ---------------------\n" );
1828
 
            i = igmp_info();
1829
 
            if (i)
1830
 
                return (i);
1831
 
        }
1832
 
#endif
1833
 
 
1834
 
        if (!flag_arg || flag_unx) {
1835
 
#if HAVE_AFUNIX
1836
 
            prg_cache_load();
1837
 
            i = unix_info();
1838
 
            if (i)
1839
 
                return (i);
1840
 
#else
1841
 
            if (flag_arg) {
1842
 
                i = 1;
1843
 
                ENOSUPP("netstat", "AF UNIX");
1844
 
            }
1845
 
#endif
1846
 
        }
1847
 
        if (!flag_arg || flag_ipx) {
1848
 
#if HAVE_AFIPX
1849
 
            i = ipx_info();
1850
 
            if (i)
1851
 
                return (i);
1852
 
#else
1853
 
            if (flag_arg) {
1854
 
                i = 1;
1855
 
                ENOSUPP("netstat", "AF IPX");
1856
 
            }
1857
 
#endif
1858
 
        }
1859
 
        if (!flag_arg || flag_ax25) {
1860
 
#if HAVE_AFAX25
1861
 
            i = ax25_info();
1862
 
            if (i)
1863
 
                return (i);
1864
 
#else
1865
 
            if (flag_arg) {
1866
 
                i = 1;
1867
 
                ENOSUPP("netstat", "AF AX25");
1868
 
            }
1869
 
#endif
1870
 
        }
1871
 
        if(!flag_arg || flag_x25) {
1872
 
#if HAVE_AFX25
1873
 
            /* FIXME */
1874
 
            i = x25_info();
1875
 
            if (i)
1876
 
                return(i);
1877
 
#else
1878
 
            if (flag_arg) {
1879
 
                i = 1;
1880
 
                ENOSUPP("netstat", "AF X25");
1881
 
            }
1882
 
#endif
1883
 
        }
1884
 
        if (!flag_arg || flag_netrom) {
1885
 
#if HAVE_AFNETROM
1886
 
            i = netrom_info();
1887
 
            if (i)
1888
 
                return (i);
1889
 
#else
1890
 
            if (flag_arg) {
1891
 
                i = 1;
1892
 
                ENOSUPP("netstat", "AF NETROM");
1893
 
            }
1894
 
#endif
1895
 
        }
1896
 
        if (!flag_cnt || i)
1897
 
            break;
1898
 
        sleep(1);
1899
 
        prg_cache_clear();
1900
 
    }
1901
 
    return (i);
1902
 
}