1
0

network.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. package analytic
  2. import (
  3. stdnet "net"
  4. "github.com/shirou/gopsutil/v4/net"
  5. "github.com/uozi-tech/cosy/logger"
  6. )
  7. func GetNetworkStat() (data *net.IOCountersStat, err error) {
  8. networkStats, err := net.IOCounters(true)
  9. if err != nil {
  10. return
  11. }
  12. if len(networkStats) == 0 {
  13. return &net.IOCountersStat{}, nil
  14. }
  15. // Get all network interfaces
  16. interfaces, err := stdnet.Interfaces()
  17. if err != nil {
  18. logger.Error(err)
  19. return
  20. }
  21. var (
  22. totalBytesRecv uint64
  23. totalBytesSent uint64
  24. totalPacketsRecv uint64
  25. totalPacketsSent uint64
  26. totalErrIn uint64
  27. totalErrOut uint64
  28. totalDropIn uint64
  29. totalDropOut uint64
  30. totalFifoIn uint64
  31. totalFifoOut uint64
  32. )
  33. // Create a map of external interface names
  34. externalInterfaces := make(map[string]bool)
  35. // Identify external interfaces
  36. for _, iface := range interfaces {
  37. // Skip down or loopback interfaces
  38. if iface.Flags&stdnet.FlagUp == 0 ||
  39. iface.Flags&stdnet.FlagLoopback != 0 {
  40. continue
  41. }
  42. // Get addresses for this interface
  43. addrs, err := iface.Addrs()
  44. if err != nil {
  45. logger.Error(err)
  46. continue
  47. }
  48. // Skip interfaces without addresses
  49. if len(addrs) == 0 {
  50. continue
  51. }
  52. // Check for non-private IP addresses
  53. for _, addr := range addrs {
  54. ip, ipNet, err := stdnet.ParseCIDR(addr.String())
  55. if err != nil {
  56. continue
  57. }
  58. // Skip virtual, local, multicast, and special purpose IPs
  59. if !isRealExternalIP(ip, ipNet) {
  60. continue
  61. }
  62. externalInterfaces[iface.Name] = true
  63. break
  64. }
  65. }
  66. // Accumulate stats only from external interfaces
  67. for _, stat := range networkStats {
  68. if externalInterfaces[stat.Name] {
  69. totalBytesRecv += stat.BytesRecv
  70. totalBytesSent += stat.BytesSent
  71. totalPacketsRecv += stat.PacketsRecv
  72. totalPacketsSent += stat.PacketsSent
  73. totalErrIn += stat.Errin
  74. totalErrOut += stat.Errout
  75. totalDropIn += stat.Dropin
  76. totalDropOut += stat.Dropout
  77. totalFifoIn += stat.Fifoin
  78. totalFifoOut += stat.Fifoout
  79. }
  80. }
  81. return &net.IOCountersStat{
  82. Name: "analytic.network",
  83. BytesRecv: totalBytesRecv,
  84. BytesSent: totalBytesSent,
  85. PacketsRecv: totalPacketsRecv,
  86. PacketsSent: totalPacketsSent,
  87. Errin: totalErrIn,
  88. Errout: totalErrOut,
  89. Dropin: totalDropIn,
  90. Dropout: totalDropOut,
  91. Fifoin: totalFifoIn,
  92. Fifoout: totalFifoOut,
  93. }, nil
  94. }
  95. // isRealExternalIP checks if an IP is a genuine external (public) IP
  96. func isRealExternalIP(ip stdnet.IP, ipNet *stdnet.IPNet) bool {
  97. // Skip if it's not a global unicast address
  98. if !ip.IsGlobalUnicast() {
  99. return false
  100. }
  101. // Skip private IPs
  102. if ip.IsPrivate() {
  103. return false
  104. }
  105. // Skip link-local addresses
  106. if ip.IsLinkLocalUnicast() {
  107. return false
  108. }
  109. // Skip loopback
  110. if ip.IsLoopback() {
  111. return false
  112. }
  113. // Skip multicast
  114. if ip.IsMulticast() {
  115. return false
  116. }
  117. // Check for special reserved ranges
  118. if isReservedIP(ip) {
  119. return false
  120. }
  121. return true
  122. }
  123. // isReservedIP checks if an IP belongs to special reserved ranges
  124. func isReservedIP(ip stdnet.IP) bool {
  125. // Handle IPv4
  126. if ip4 := ip.To4(); ip4 != nil {
  127. // TEST-NET-1: 192.0.2.0/24 (RFC 5737)
  128. if ip4[0] == 192 && ip4[1] == 0 && ip4[2] == 2 {
  129. return true
  130. }
  131. // TEST-NET-2: 198.51.100.0/24 (RFC 5737)
  132. if ip4[0] == 198 && ip4[1] == 51 && ip4[2] == 100 {
  133. return true
  134. }
  135. // TEST-NET-3: 203.0.113.0/24 (RFC 5737)
  136. if ip4[0] == 203 && ip4[1] == 0 && ip4[2] == 113 {
  137. return true
  138. }
  139. // Benchmark tests: 198.18.0.0/15 (includes 198.19.0.0/16) (RFC 2544)
  140. if ip4[0] == 198 && (ip4[1] == 18 || ip4[1] == 19) {
  141. return true
  142. }
  143. // Documentation: 240.0.0.0/4 (RFC 1112)
  144. if ip4[0] >= 240 {
  145. return true
  146. }
  147. // CGNAT: 100.64.0.0/10 (RFC 6598)
  148. if ip4[0] == 100 && (ip4[1]&0xC0) == 64 {
  149. return true
  150. }
  151. } else if ip.To16() != nil {
  152. // Documentation prefix (2001:db8::/32) - RFC 3849
  153. if ip[0] == 0x20 && ip[1] == 0x01 && ip[2] == 0x0d && ip[3] == 0xb8 {
  154. return true
  155. }
  156. // Unique Local Addresses (fc00::/7) - RFC 4193
  157. if (ip[0] & 0xfe) == 0xfc {
  158. return true
  159. }
  160. // 6to4 relay (2002::/16) - RFC 3056
  161. if ip[0] == 0x20 && ip[1] == 0x02 {
  162. return true
  163. }
  164. // Teredo tunneling (2001:0::/32) - RFC 4380
  165. if ip[0] == 0x20 && ip[1] == 0x01 && ip[2] == 0x00 && ip[3] == 0x00 {
  166. return true
  167. }
  168. // Deprecated site-local addresses (fec0::/10) - RFC 3879
  169. if (ip[0]&0xff) == 0xfe && (ip[1]&0xc0) == 0xc0 {
  170. return true
  171. }
  172. // Old 6bone addresses (3ffe::/16) - Deprecated
  173. if ip[0] == 0x3f && ip[1] == 0xfe {
  174. return true
  175. }
  176. // ORCHID addresses (2001:10::/28) - RFC 4843
  177. if ip[0] == 0x20 && ip[1] == 0x01 && ip[2] == 0x00 && (ip[3]&0xf0) == 0x10 {
  178. return true
  179. }
  180. // ORCHID v2 addresses (2001:20::/28) - RFC 7343
  181. if ip[0] == 0x20 && ip[1] == 0x01 && ip[2] == 0x00 && (ip[3]&0xf0) == 0x20 {
  182. return true
  183. }
  184. }
  185. return false
  186. }