netstat.c revision 2f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5c
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (c) 2008, The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * All rights reserved.
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Redistribution and use in source and binary forms, with or without
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * modification, are permitted provided that the following conditions
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * are met:
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *  * Redistributions of source code must retain the above copyright
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *  * Redistributions in binary form must reproduce the above copyright
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    notice, this list of conditions and the following disclaimer in
122f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom *    the documentation and/or other materials provided with the
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    distribution.
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *  * Neither the name of Google, Inc. nor the names of its contributors
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    may be used to endorse or promote products derived from this
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    software without specific prior written permission.
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
252f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * SUCH DAMAGE.
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
322f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom#include <arpa/inet.h>
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
352f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom#include <sys/socket.h>
362f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom#include <sys/types.h>
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef union iaddr iaddr;
392f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstromtypedef union iaddr6 iaddr6;
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunion iaddr {
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned u;
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned char b[4];
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
452f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom
462f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstromunion iaddr6 {
472f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    struct {
482f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        unsigned a;
492f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        unsigned b;
502f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        unsigned c;
512f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        unsigned d;
522f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    } u;
532f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    unsigned char b[16];
542f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom};
552f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *state2str(unsigned state)
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch(state){
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 0x1: return "ESTABLISHED";
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 0x2: return "SYN_SENT";
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 0x3: return "SYN_RECV";
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 0x4: return "FIN_WAIT1";
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 0x5: return "FIN_WAIT2";
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 0x6: return "TIME_WAIT";
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 0x7: return "CLOSE";
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 0x8: return "CLOSE_WAIT";
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 0x9: return "LAST_ACK";
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 0xA: return "LISTEN";
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 0xB: return "CLOSING";
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    default: return "UNKNOWN";
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
742f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom/* addr + : + port + \0 */
752f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom#define ADDR_LEN INET6_ADDRSTRLEN + 1 + 5 + 1
762f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom
772f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstromstatic void addr2str(int af, const void *addr, unsigned port, char *buf)
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
792f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    if (inet_ntop(af, addr, buf, ADDR_LEN) == NULL) {
802f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        *buf = '\0';
812f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        return;
822f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    }
832f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    size_t len = strlen(buf);
842f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    if (port) {
852f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        snprintf(buf+len, ADDR_LEN-len, ":%d", port);
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
872f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        strncat(buf+len, ":*", ADDR_LEN-len-1);
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
912f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstromstatic void ipv4(const char *filename, const char *label) {
922f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    FILE *fp = fopen(filename, "r");
932f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    if (fp == NULL) {
942f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        return;
952f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    }
962f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    char buf[BUFSIZ];
972f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    fgets(buf, BUFSIZ, fp);
982f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    while (fgets(buf, BUFSIZ, fp)){
992f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        char lip[ADDR_LEN];
1002f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        char rip[ADDR_LEN];
1012f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        iaddr laddr, raddr;
1022f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        unsigned lport, rport, state, txq, rxq, num;
1032f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        int n = sscanf(buf, " %d: %x:%x %x:%x %x %x:%x",
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                       &num, &laddr.u, &lport, &raddr.u, &rport,
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                       &state, &txq, &rxq);
1062f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        if (n == 8) {
1072f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom            addr2str(AF_INET, &laddr, lport, lip);
1082f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom            addr2str(AF_INET, &raddr, rport, rip);
1092f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom
1102f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom            printf("%4s  %6d %6d %-22s %-22s %s\n",
1112f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom                   label, txq, rxq, lip, rip,
1122f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom                   state2str(state));
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1152f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    fclose(fp);
1162f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom}
1172f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom
1182f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstromstatic void ipv6(const char *filename, const char *label) {
1192f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    FILE *fp = fopen(filename, "r");
1202f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    if (fp == NULL) {
1212f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        return;
1222f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    }
1232f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    char buf[BUFSIZ];
1242f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    fgets(buf, BUFSIZ, fp);
1252f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    while (fgets(buf, BUFSIZ, fp)){
1262f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        char lip[ADDR_LEN];
1272f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        char rip[ADDR_LEN];
1282f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        iaddr6 laddr6, raddr6;
1292f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        unsigned lport, rport, state, txq, rxq, num;
1302f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        int n = sscanf(buf, " %d: %8x%8x%8x%8x:%x %8x%8x%8x%8x:%x %x %x:%x",
1312f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom                       &num, &laddr6.u.a, &laddr6.u.b, &laddr6.u.c, &laddr6.u.d, &lport,
1322f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom                       &raddr6.u.a, &raddr6.u.b, &raddr6.u.c, &raddr6.u.d, &rport,
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                       &state, &txq, &rxq);
1342f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom        if (n == 14) {
1352f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom            addr2str(AF_INET6, &laddr6, lport, lip);
1362f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom            addr2str(AF_INET6, &raddr6, rport, rip);
1372f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom
1382f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom            printf("%4s  %6d %6d %-22s %-22s %s\n",
1392f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom                   label, txq, rxq, lip, rip,
1402f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom                   state2str(state));
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1432f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    fclose(fp);
1442f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom}
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1462f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstromint netstat_main(int argc, char *argv[])
1472f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom{
1482f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    printf("Proto Recv-Q Send-Q Local Address          Foreign Address        State\n");
1492f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    ipv4("/proc/net/tcp",  "tcp");
1502f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    ipv4("/proc/net/udp",  "udp");
1512f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    ipv6("/proc/net/tcp6", "tcp6");
1522f7b72f9e8d06c80957cdf384d23d3bf5bd5ce5cBrian Carlstrom    ipv6("/proc/net/udp6", "udp6");
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
155