1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "NetworkStatsNative"
18 
19 #include <cutils/qtaguid.h>
20 #include <dirent.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <inttypes.h>
24 #include <jni.h>
25 #include <nativehelper/ScopedUtfChars.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <utils/Log.h>
29 #include <utils/misc.h>
30 
31 #include "bpf/BpfUtils.h"
32 #include "netdbpf/BpfNetworkStats.h"
33 #include "netdbpf/NetworkTraceHandler.h"
34 
35 using android::bpf::bpfGetUidStats;
36 using android::bpf::bpfGetIfaceStats;
37 using android::bpf::NetworkTraceHandler;
38 
39 namespace android {
40 
41 // NOTE: keep these in sync with TrafficStats.java
42 static const uint64_t UNKNOWN = -1;
43 
44 enum StatsType {
45     RX_BYTES = 0,
46     RX_PACKETS = 1,
47     TX_BYTES = 2,
48     TX_PACKETS = 3,
49     TCP_RX_PACKETS = 4,
50     TCP_TX_PACKETS = 5
51 };
52 
getStatsType(Stats * stats,StatsType type)53 static uint64_t getStatsType(Stats* stats, StatsType type) {
54     switch (type) {
55         case RX_BYTES:
56             return stats->rxBytes;
57         case RX_PACKETS:
58             return stats->rxPackets;
59         case TX_BYTES:
60             return stats->txBytes;
61         case TX_PACKETS:
62             return stats->txPackets;
63         case TCP_RX_PACKETS:
64             return stats->tcpRxPackets;
65         case TCP_TX_PACKETS:
66             return stats->tcpTxPackets;
67         default:
68             return UNKNOWN;
69     }
70 }
71 
nativeGetTotalStat(JNIEnv * env,jclass clazz,jint type)72 static jlong nativeGetTotalStat(JNIEnv* env, jclass clazz, jint type) {
73     Stats stats = {};
74 
75     if (bpfGetIfaceStats(NULL, &stats) == 0) {
76         return getStatsType(&stats, (StatsType) type);
77     } else {
78         return UNKNOWN;
79     }
80 }
81 
nativeGetIfaceStat(JNIEnv * env,jclass clazz,jstring iface,jint type)82 static jlong nativeGetIfaceStat(JNIEnv* env, jclass clazz, jstring iface, jint type) {
83     ScopedUtfChars iface8(env, iface);
84     if (iface8.c_str() == NULL) {
85         return UNKNOWN;
86     }
87 
88     Stats stats = {};
89 
90     if (bpfGetIfaceStats(iface8.c_str(), &stats) == 0) {
91         return getStatsType(&stats, (StatsType) type);
92     } else {
93         return UNKNOWN;
94     }
95 }
96 
nativeGetUidStat(JNIEnv * env,jclass clazz,jint uid,jint type)97 static jlong nativeGetUidStat(JNIEnv* env, jclass clazz, jint uid, jint type) {
98     Stats stats = {};
99 
100     if (bpfGetUidStats(uid, &stats) == 0) {
101         return getStatsType(&stats, (StatsType) type);
102     } else {
103         return UNKNOWN;
104     }
105 }
106 
nativeInitNetworkTracing(JNIEnv * env,jclass clazz)107 static void nativeInitNetworkTracing(JNIEnv* env, jclass clazz) {
108     NetworkTraceHandler::InitPerfettoTracing();
109 }
110 
111 static const JNINativeMethod gMethods[] = {
112         {"nativeGetTotalStat", "(I)J", (void*)nativeGetTotalStat},
113         {"nativeGetIfaceStat", "(Ljava/lang/String;I)J", (void*)nativeGetIfaceStat},
114         {"nativeGetUidStat", "(II)J", (void*)nativeGetUidStat},
115         {"nativeInitNetworkTracing", "()V", (void*)nativeInitNetworkTracing},
116 };
117 
register_android_server_net_NetworkStatsService(JNIEnv * env)118 int register_android_server_net_NetworkStatsService(JNIEnv* env) {
119     return jniRegisterNativeMethods(env,
120             "android/net/connectivity/com/android/server/net/NetworkStatsService", gMethods,
121             NELEM(gMethods));
122 }
123 
124 }
125