1#!/usr/bin/env python3
2#
3# Copyright (C) 2023 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17import argparse
18
19# The following list must be in sync with
20# https://cs.android.com/android/platform/superproject/+/master:packages/modules/NetworkStack/src/android/net/apf/ApfFilter.java;l=139?q=ApfFilter.java
21Counter = (
22    "TOTAL_PACKETS",
23    "PASSED_ARP",
24    "PASSED_DHCP",
25    "PASSED_IPV4",
26    "PASSED_IPV6_NON_ICMP",
27    "PASSED_IPV4_UNICAST",
28    "PASSED_IPV6_ICMP",
29    "PASSED_IPV6_UNICAST_NON_ICMP",
30    "PASSED_ARP_NON_IPV4",
31    "PASSED_ARP_UNKNOWN",
32    "PASSED_ARP_UNICAST_REPLY",
33    "PASSED_NON_IP_UNICAST",
34    "PASSED_MDNS",
35    "DROPPED_ETH_BROADCAST",
36    "DROPPED_RA",
37    "DROPPED_GARP_REPLY",
38    "DROPPED_ARP_OTHER_HOST",
39    "DROPPED_IPV4_L2_BROADCAST",
40    "DROPPED_IPV4_BROADCAST_ADDR",
41    "DROPPED_IPV4_BROADCAST_NET",
42    "DROPPED_IPV4_MULTICAST",
43    "DROPPED_IPV6_ROUTER_SOLICITATION",
44    "DROPPED_IPV6_MULTICAST_NA",
45    "DROPPED_IPV6_MULTICAST",
46    "DROPPED_IPV6_MULTICAST_PING",
47    "DROPPED_IPV6_NON_ICMP_MULTICAST",
48    "DROPPED_802_3_FRAME",
49    "DROPPED_ETHERTYPE_BLACKLISTED",
50    "DROPPED_ARP_REPLY_SPA_NO_HOST",
51    "DROPPED_IPV4_KEEPALIVE_ACK",
52    "DROPPED_IPV6_KEEPALIVE_ACK",
53    "DROPPED_IPV4_NATT_KEEPALIVE",
54    "DROPPED_MDNS"
55)
56
57def main():
58  parser = argparse.ArgumentParser(description='Parse APF counter HEX string.')
59  parser.add_argument('hexstring')
60  args = parser.parse_args()
61  data_hexstring = args.hexstring
62  data_bytes = bytes.fromhex(data_hexstring)
63  data_bytes_len = len(data_bytes)
64  for i in range(len(Counter)):
65    cnt = int.from_bytes(data_bytes[data_bytes_len - 4 * (i + 1) :
66                                    data_bytes_len - 4 * i], byteorder = "big")
67    if cnt != 0:
68      print("{} : {}".format(Counter[i], cnt))
69
70if __name__ == "__main__":
71  main()
72