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
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    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
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 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
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h>
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h>
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h>
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/ioctl.h>
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/socket.h>
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <net/if.h>
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define PROC_NET_DEV    "/proc/net/dev"
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define MAX_IF           8   /* max interfaces we can handle */
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef PAGE_SIZE
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project# define PAGE_SIZE 4096
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define _STR(s) #s
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define STR(s) _STR(s)
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct if_stats {
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char name[IFNAMSIZ];
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int mtu;
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int rx_bytes;
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int rx_packets;
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int rx_errors;
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int rx_dropped;
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int tx_bytes;
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int tx_packets;
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int tx_errors;
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int tx_dropped;
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int get_mtu(const char *if_name)
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct ifreq ifr;
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int s, ret;
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    s = socket(AF_INET, SOCK_DGRAM, 0);
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (s < 0) {
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        perror("socket");
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(EXIT_FAILURE);
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memset(&ifr, 0, sizeof(struct ifreq));
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ifr.ifr_addr.sa_family = AF_INET;
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    strcpy(ifr.ifr_name, if_name);
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ret = ioctl(s, SIOCGIFMTU, &ifr);
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (ret < 0) {
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        perror("ioctl");
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(EXIT_FAILURE);
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ret = close(s);
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (ret < 0) {
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        perror("close");
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(EXIT_FAILURE);
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return ifr.ifr_mtu;
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int get_interfaces(struct if_stats *ifs)
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char buf[PAGE_SIZE];
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *p;
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int ret, nr, fd;
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = open(PROC_NET_DEV, O_RDONLY);
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (fd < 0) {
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        perror("open");
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(EXIT_FAILURE);
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ret = read(fd, buf, sizeof(buf) - 1);
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (ret < 0) {
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        perror("read");
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(EXIT_FAILURE);
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (!ret) {
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "reading " PROC_NET_DEV " returned premature EOF\n");
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(EXIT_FAILURE);
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buf[ret] = '\0';
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* skip down to the third line */
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p = strchr(buf, '\n');
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!p) {
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "parsing " PROC_NET_DEV " failed unexpectedly\n");
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(EXIT_FAILURE);
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p = strchr(p + 1, '\n');
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!p) {
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "parsing " PROC_NET_DEV " failed unexpectedly\n");
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(EXIT_FAILURE);
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p += 1;
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /*
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     * Key:
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     * if: (Rx) bytes packets errs drop fifo frame compressed multicast \
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     *     (Tx) bytes packets errs drop fifo colls carrier compressed
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     */
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (nr = 0; nr < MAX_IF; nr++) {
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *c;
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = sscanf(p, "%" STR(IFNAMSIZ) "s", ifs->name);
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret != 1) {
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "parsing " PROC_NET_DEV " failed unexpectedly\n");
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            exit(EXIT_FAILURE);
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /*
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         * This works around a bug in the proc file where large interface names
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         * or Rx byte counts eat the delimiter, breaking sscanf.
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         */
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c = strchr(ifs->name, ':');
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (c)
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            *c = '\0';
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        p = strchr(p, ':') + 1;
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = sscanf(p, "%u %u %u %u %*u %*u %*u %*u %u %u %u %u %*u %*u "
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                     "%*u %*u\n", &ifs->rx_bytes, &ifs->rx_packets,
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                     &ifs->rx_errors, &ifs->rx_dropped, &ifs->tx_bytes,
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                     &ifs->tx_packets, &ifs->tx_errors, &ifs->tx_dropped);
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret != 8) {
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "parsing " PROC_NET_DEV " failed unexpectedly\n");
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            exit(EXIT_FAILURE);
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ifs->mtu = get_mtu(ifs->name);
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        p = strchr(p, '\n') + 1;
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (*p == '\0') {
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            nr++;
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ifs++;
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ret = close(fd);
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (ret) {
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        perror("close");
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(EXIT_FAILURE);
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return nr;
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void print_header(void)
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("               Rx                              Tx\n");
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("%-8s %-5s %-10s %-8s %-5s %-5s %-10s %-8s %-5s %-5s\n",
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project           "name", "MTU", "bytes", "packets", "errs", "drpd", "bytes",
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project           "packets", "errs", "drpd");
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int print_interfaces(struct if_stats *old, struct if_stats *new, int nr)
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i = 0;
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (nr--) {
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (old->rx_packets || old->tx_packets) {
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            printf("%-8s %-5u %-10u %-8u %-5u %-5u %-10u %-8u %-5u %-5u\n",
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                   new->name, new->mtu,
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                   new->rx_bytes - old->rx_bytes,
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                   new->rx_packets - old->rx_packets,
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                   new->rx_errors - old->rx_errors,
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                   new->rx_dropped - old->rx_dropped,
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                   new->tx_bytes - old->tx_bytes,
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                   new->tx_packets - old->tx_packets,
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                   new->tx_errors - old->tx_errors,
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                   new->tx_dropped - old->tx_dropped);
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            i++;
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        old++;
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        new++;
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return i;
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void usage(const char *cmd)
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "usage: %s [ -r repeats] [ -d delay ]\n", cmd);
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint iftop_main(int argc, char *argv[])
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct if_stats ifs[2][MAX_IF];
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int count = 0, header_interval = 22, delay = 1, i;
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int toggle = 0;
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 1; i < argc; i++) {
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(argv[i], "-d")) {
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (i >= argc - 1) {
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fprintf(stderr, "Option -d requires an argument.\n");
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                exit(EXIT_FAILURE);
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            delay = atoi(argv[i++]);
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (!delay)
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                delay = 1;
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(argv[i], "-r")) {
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (i >= argc - 1) {
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fprintf(stderr, "Option -r requires an argument.\n");
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                exit(EXIT_FAILURE);
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            header_interval = atoi(argv[i++]);
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (header_interval < MAX_IF)
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                header_interval = MAX_IF;
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(argv[i], "-h")) {
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            usage(argv[0]);
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            exit(EXIT_SUCCESS);
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        usage(argv[0]);
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(EXIT_FAILURE);
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    get_interfaces(ifs[!toggle]);
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (header_interval)
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        print_header();
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (1) {
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int nr;
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sleep(delay);
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        nr = get_interfaces(ifs[toggle]);
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (header_interval && count + nr > header_interval) {
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            print_header();
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            count = 0;
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        count += print_interfaces(ifs[!toggle], ifs[toggle], nr);
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        toggle = !toggle;
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
279