View Javadoc
1   /*
2    * Copyright 2020-2022 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.software.os.unix.freebsd;
6   
7   import static oshi.util.Memoizer.defaultExpiration;
8   import static oshi.util.Memoizer.memoize;
9   
10  import java.util.function.Supplier;
11  
12  import com.sun.jna.Memory;
13  
14  import oshi.annotation.concurrent.ThreadSafe;
15  import oshi.driver.unix.NetStat;
16  import oshi.jna.platform.unix.CLibrary.BsdTcpstat;
17  import oshi.jna.platform.unix.CLibrary.BsdUdpstat;
18  import oshi.software.common.AbstractInternetProtocolStats;
19  import oshi.util.ParseUtil;
20  import oshi.util.platform.unix.freebsd.BsdSysctlUtil;
21  import oshi.util.tuples.Pair;
22  
23  /**
24   * Internet Protocol Stats implementation
25   */
26  @ThreadSafe
27  public class FreeBsdInternetProtocolStats extends AbstractInternetProtocolStats {
28  
29      private Supplier<Pair<Long, Long>> establishedv4v6 = memoize(NetStat::queryTcpnetstat, defaultExpiration());
30      private Supplier<BsdTcpstat> tcpstat = memoize(FreeBsdInternetProtocolStats::queryTcpstat, defaultExpiration());
31      private Supplier<BsdUdpstat> udpstat = memoize(FreeBsdInternetProtocolStats::queryUdpstat, defaultExpiration());
32  
33      @Override
34      public TcpStats getTCPv4Stats() {
35          BsdTcpstat tcp = tcpstat.get();
36          return new TcpStats(establishedv4v6.get().getA(), ParseUtil.unsignedIntToLong(tcp.tcps_connattempt),
37                  ParseUtil.unsignedIntToLong(tcp.tcps_accepts), ParseUtil.unsignedIntToLong(tcp.tcps_conndrops),
38                  ParseUtil.unsignedIntToLong(tcp.tcps_drops), ParseUtil.unsignedIntToLong(tcp.tcps_sndpack),
39                  ParseUtil.unsignedIntToLong(tcp.tcps_rcvpack), ParseUtil.unsignedIntToLong(tcp.tcps_sndrexmitpack),
40                  ParseUtil.unsignedIntToLong(
41                          tcp.tcps_rcvbadsum + tcp.tcps_rcvbadoff + tcp.tcps_rcvmemdrop + tcp.tcps_rcvshort),
42                  0L);
43      }
44  
45      @Override
46      public UdpStats getUDPv4Stats() {
47          BsdUdpstat stat = udpstat.get();
48          return new UdpStats(ParseUtil.unsignedIntToLong(stat.udps_opackets),
49                  ParseUtil.unsignedIntToLong(stat.udps_ipackets), ParseUtil.unsignedIntToLong(stat.udps_noportmcast),
50                  ParseUtil.unsignedIntToLong(stat.udps_hdrops + stat.udps_badsum + stat.udps_badlen));
51      }
52  
53      @Override
54      public UdpStats getUDPv6Stats() {
55          BsdUdpstat stat = udpstat.get();
56          return new UdpStats(ParseUtil.unsignedIntToLong(stat.udps_snd6_swcsum),
57                  ParseUtil.unsignedIntToLong(stat.udps_rcv6_swcsum), 0L, 0L);
58      }
59  
60      private static BsdTcpstat queryTcpstat() {
61          BsdTcpstat ft = new BsdTcpstat();
62          try (Memory m = BsdSysctlUtil.sysctl("net.inet.tcp.stats")) {
63              if (m != null && m.size() >= 128) {
64                  ft.tcps_connattempt = m.getInt(0);
65                  ft.tcps_accepts = m.getInt(4);
66                  ft.tcps_drops = m.getInt(12);
67                  ft.tcps_conndrops = m.getInt(16);
68                  ft.tcps_sndpack = m.getInt(64);
69                  ft.tcps_sndrexmitpack = m.getInt(72);
70                  ft.tcps_rcvpack = m.getInt(104);
71                  ft.tcps_rcvbadsum = m.getInt(112);
72                  ft.tcps_rcvbadoff = m.getInt(116);
73                  ft.tcps_rcvmemdrop = m.getInt(120);
74                  ft.tcps_rcvshort = m.getInt(124);
75              }
76          }
77          return ft;
78      }
79  
80      private static BsdUdpstat queryUdpstat() {
81          BsdUdpstat ut = new BsdUdpstat();
82          try (Memory m = BsdSysctlUtil.sysctl("net.inet.udp.stats")) {
83              if (m != null && m.size() >= 1644) {
84                  ut.udps_ipackets = m.getInt(0);
85                  ut.udps_hdrops = m.getInt(4);
86                  ut.udps_badsum = m.getInt(8);
87                  ut.udps_badlen = m.getInt(12);
88                  ut.udps_opackets = m.getInt(36);
89                  ut.udps_noportmcast = m.getInt(48);
90                  ut.udps_rcv6_swcsum = m.getInt(64);
91                  ut.udps_snd6_swcsum = m.getInt(80);
92              }
93          }
94          return ut;
95      }
96  }