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", 1113c412f6260d88765f06232e7e9799f7bf68d7741Brian Carlstrom label, rxq, txq, 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", 1393c412f6260d88765f06232e7e9799f7bf68d7741Brian Carlstrom label, rxq, txq, 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