ipmatch.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package netutils
  2. import (
  3. "net"
  4. "net/http"
  5. "strings"
  6. )
  7. /*
  8. MatchIP.go
  9. This script contains function for matching IP address, comparing
  10. CIDR and IPv4 / v6 validations
  11. */
  12. func GetRequesterIP(r *http.Request) string {
  13. ip := r.Header.Get("X-Real-Ip")
  14. if ip == "" {
  15. ip = r.Header.Get("X-Forwarded-For")
  16. }
  17. if ip == "" {
  18. ip = r.RemoteAddr
  19. }
  20. /*
  21. Possible shits that might be extracted by this code
  22. 127.0.0.1:61001
  23. [15c4:cbb4:cc98:4291:ffc1:3a46:06a1:51a7]:61002
  24. 127.0.0.1
  25. 158.250.160.114,109.21.249.211
  26. [15c4:cbb4:cc98:4291:ffc1:3a46:06a1:51a7],109.21.249.211
  27. We need to extract just the first ip address
  28. */
  29. requesterRawIp := ip
  30. if strings.Contains(requesterRawIp, ",") {
  31. //Trim off all the forwarder IPs
  32. requesterRawIp = strings.Split(requesterRawIp, ",")[0]
  33. }
  34. //Trim away the port number
  35. reqHost, _, err := net.SplitHostPort(requesterRawIp)
  36. if err == nil {
  37. requesterRawIp = reqHost
  38. }
  39. if strings.HasPrefix(requesterRawIp, "[") && strings.HasSuffix(requesterRawIp, "]") {
  40. //e.g. [15c4:cbb4:cc98:4291:ffc1:3a46:06a1:51a7]
  41. requesterRawIp = requesterRawIp[1 : len(requesterRawIp)-1]
  42. }
  43. return requesterRawIp
  44. }
  45. // Match the IP address with a wildcard string
  46. func MatchIpWildcard(ipAddress, wildcard string) bool {
  47. // Split IP address and wildcard into octets
  48. ipOctets := strings.Split(ipAddress, ".")
  49. wildcardOctets := strings.Split(wildcard, ".")
  50. // Check that both have 4 octets
  51. if len(ipOctets) != 4 || len(wildcardOctets) != 4 {
  52. return false
  53. }
  54. // Check each octet to see if it matches the wildcard or is an exact match
  55. for i := 0; i < 4; i++ {
  56. if wildcardOctets[i] == "*" {
  57. continue
  58. }
  59. if ipOctets[i] != wildcardOctets[i] {
  60. return false
  61. }
  62. }
  63. return true
  64. }
  65. // Match ip address with CIDR
  66. func MatchIpCIDR(ip string, cidr string) bool {
  67. // parse the CIDR string
  68. _, cidrnet, err := net.ParseCIDR(cidr)
  69. if err != nil {
  70. return false
  71. }
  72. // parse the IP address
  73. ipAddr := net.ParseIP(ip)
  74. // check if the IP address is within the CIDR range
  75. return cidrnet.Contains(ipAddr)
  76. }
  77. // Check if a ip is private IP range
  78. func IsPrivateIP(ipStr string) bool {
  79. if ipStr == "127.0.0.1" || ipStr == "::1" {
  80. //local loopback
  81. return true
  82. }
  83. ip := net.ParseIP(ipStr)
  84. if ip == nil {
  85. return false
  86. }
  87. return ip.IsPrivate()
  88. }
  89. // Check if an Ip string is ipv6
  90. func IsIPv6(ipStr string) bool {
  91. ip := net.ParseIP(ipStr)
  92. if ip == nil {
  93. return false
  94. }
  95. return ip.To4() == nil && ip.To16() != nil
  96. }
  97. // Check if an Ip string is ipv6
  98. func IsIPv4(ipStr string) bool {
  99. ip := net.ParseIP(ipStr)
  100. if ip == nil {
  101. return false
  102. }
  103. return ip.To4() != nil
  104. }