12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. var reIpv4FirstPass = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
  2. var reSubnetString = /\/\d{1,3}(?=%|$)/
  3. var reForwardSlash = /\//
  4. var reZone = /%.*$/
  5. var reBadCharacters = /([^0-9a-f:/%])/i
  6. var reBadAddress = /([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\/$)/i
  7. function validate4 (input) {
  8. if (!(reIpv4FirstPass.test(input))) return false
  9. var parts = input.split('.')
  10. if (parts.length !== 4) return false
  11. if (parts[0][0] === '0' && parts[0].length > 1) return false
  12. if (parts[1][0] === '0' && parts[1].length > 1) return false
  13. if (parts[2][0] === '0' && parts[2].length > 1) return false
  14. if (parts[3][0] === '0' && parts[3].length > 1) return false
  15. var n0 = Number(parts[0])
  16. var n1 = Number(parts[1])
  17. var n2 = Number(parts[2])
  18. var n3 = Number(parts[3])
  19. return (n0 >= 0 && n0 < 256 && n1 >= 0 && n1 < 256 && n2 >= 0 && n2 < 256 && n3 >= 0 && n3 < 256)
  20. }
  21. function validate6 (input) {
  22. var withoutSubnet = input.replace(reSubnetString, '')
  23. var hasSubnet = (input.length !== withoutSubnet.length)
  24. // FIXME: this should probably be an option in the future
  25. if (hasSubnet) return false
  26. if (!hasSubnet) {
  27. if (reForwardSlash.test(input)) return false
  28. }
  29. var withoutZone = withoutSubnet.replace(reZone, '')
  30. var lastPartSeparator = withoutZone.lastIndexOf(':')
  31. if (lastPartSeparator === -1) return false
  32. var lastPart = withoutZone.substring(lastPartSeparator + 1)
  33. var hasV4Part = validate4(lastPart)
  34. var address = (hasV4Part ? withoutZone.substring(0, lastPartSeparator + 1) + '1234:5678' : withoutZone)
  35. if (reBadCharacters.test(address)) return false
  36. if (reBadAddress.test(address)) return false
  37. var halves = address.split('::')
  38. if (halves.length > 2) return false
  39. if (halves.length === 2) {
  40. var first = (halves[0] === '' ? [] : halves[0].split(':'))
  41. var last = (halves[1] === '' ? [] : halves[1].split(':'))
  42. var remainingLength = 8 - (first.length + last.length)
  43. if (remainingLength <= 0) return false
  44. } else {
  45. if (address.split(':').length !== 8) return false
  46. }
  47. return true
  48. }
  49. function validate (input) {
  50. return validate4(input) || validate6(input)
  51. }
  52. module.exports = function validator (options) {
  53. if (!options) options = {}
  54. if (options.version === 4) return validate4
  55. if (options.version === 6) return validate6
  56. if (options.version == null) return validate
  57. throw new Error('Unknown version: ' + options.version)
  58. }
  59. module.exports['__all_regexes__'] = [
  60. reIpv4FirstPass,
  61. reSubnetString,
  62. reForwardSlash,
  63. reZone,
  64. reBadCharacters,
  65. reBadAddress
  66. ]