PageRenderTime 52ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/ip.go

http://goesmtp.googlecode.com/
Go | 440 lines | 311 code | 40 blank | 89 comment | 107 complexity | 73c0e3e131135809618a9ea37225c3a5 MD5 | raw file
Possible License(s): GPL-2.0
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // IP address manipulations
  5. //
  6. // IPv4 addresses are 4 bytes; IPv6 addresses are 16 bytes.
  7. // An IPv4 address can be converted to an IPv6 address by
  8. // adding a canonical prefix (10 zeros, 2 0xFFs).
  9. // This library accepts either size of byte array but always
  10. // returns 16-byte addresses.
  11. package main
  12. // IP address lengths (bytes).
  13. const (
  14. IPv4len = 4
  15. IPv6len = 16
  16. )
  17. // An IP is a single IP address, an array of bytes.
  18. // Functions in this package accept either 4-byte (IP v4)
  19. // or 16-byte (IP v6) arrays as input. Unless otherwise
  20. // specified, functions in this package always return
  21. // IP addresses in 16-byte form using the canonical
  22. // embedding.
  23. //
  24. // Note that in this documentation, referring to an
  25. // IP address as an IPv4 address or an IPv6 address
  26. // is a semantic property of the address, not just the
  27. // length of the byte array: a 16-byte array can still
  28. // be an IPv4 address.
  29. type IP []byte
  30. // An IP mask is an IP address.
  31. type IPMask []byte
  32. // IPv4 returns the IP address (in 16-byte form) of the
  33. // IPv4 address a.b.c.d.
  34. func IPv4(a, b, c, d byte) IP {
  35. p := make(IP, IPv6len)
  36. for i := 0; i < 10; i++ {
  37. p[i] = 0
  38. }
  39. p[10] = 0xff
  40. p[11] = 0xff
  41. p[12] = a
  42. p[13] = b
  43. p[14] = c
  44. p[15] = d
  45. return p
  46. }
  47. // IPv4Mask returns the IP mask (in 16-byte form) of the
  48. // IPv4 mask a.b.c.d.
  49. func IPv4Mask(a, b, c, d byte) IPMask {
  50. p := make(IPMask, IPv6len)
  51. for i := 0; i < 12; i++ {
  52. p[i] = 0xff
  53. }
  54. p[12] = a
  55. p[13] = b
  56. p[14] = c
  57. p[15] = d
  58. return p
  59. }
  60. // Well-known IPv4 addresses
  61. var (
  62. IPv4bcast = IPv4(255, 255, 255, 255) // broadcast
  63. IPv4allsys = IPv4(224, 0, 0, 1) // all systems
  64. IPv4allrouter = IPv4(224, 0, 0, 2) // all routers
  65. IPv4zero = IPv4(0, 0, 0, 0) // all zeros
  66. )
  67. // Well-known IPv6 addresses
  68. var (
  69. IPzero = make(IP, IPv6len) // all zeros
  70. )
  71. // Is p all zeros?
  72. func isZeros(p IP) bool {
  73. for i := 0; i < len(p); i++ {
  74. if p[i] != 0 {
  75. return false
  76. }
  77. }
  78. return true
  79. }
  80. // To4 converts the IPv4 address ip to a 4-byte representation.
  81. // If ip is not an IPv4 address, To4 returns nil.
  82. func (ip IP) To4() IP {
  83. if len(ip) == IPv4len {
  84. return ip
  85. }
  86. if len(ip) == IPv6len &&
  87. isZeros(ip[0:10]) &&
  88. ip[10] == 0xff &&
  89. ip[11] == 0xff {
  90. return ip[12:16]
  91. }
  92. return nil
  93. }
  94. // To16 converts the IP address ip to a 16-byte representation.
  95. // If ip is not an IP address (it is the wrong length), To16 returns nil.
  96. func (ip IP) To16() IP {
  97. if len(ip) == IPv4len {
  98. return IPv4(ip[0], ip[1], ip[2], ip[3])
  99. }
  100. if len(ip) == IPv6len {
  101. return ip
  102. }
  103. return nil
  104. }
  105. // Default route masks for IPv4.
  106. var (
  107. classAMask = IPv4Mask(0xff, 0, 0, 0)
  108. classBMask = IPv4Mask(0xff, 0xff, 0, 0)
  109. classCMask = IPv4Mask(0xff, 0xff, 0xff, 0)
  110. )
  111. // DefaultMask returns the default IP mask for the IP address ip.
  112. // Only IPv4 addresses have default masks; DefaultMask returns
  113. // nil if ip is not a valid IPv4 address.
  114. func (ip IP) DefaultMask() IPMask {
  115. if ip = ip.To4(); ip == nil {
  116. return nil
  117. }
  118. switch true {
  119. case ip[0] < 0x80:
  120. return classAMask
  121. case ip[0] < 0xC0:
  122. return classBMask
  123. default:
  124. return classCMask
  125. }
  126. return nil // not reached
  127. }
  128. // Mask returns the result of masking the IP address ip with mask.
  129. func (ip IP) Mask(mask IPMask) IP {
  130. n := len(ip)
  131. if n != len(mask) {
  132. return nil
  133. }
  134. out := make(IP, n)
  135. for i := 0; i < n; i++ {
  136. out[i] = ip[i] & mask[i]
  137. }
  138. return out
  139. }
  140. // Convert i to decimal string.
  141. func itod(i uint) string {
  142. if i == 0 {
  143. return "0"
  144. }
  145. // Assemble decimal in reverse order.
  146. var b [32]byte
  147. bp := len(b)
  148. for ; i > 0; i /= 10 {
  149. bp--
  150. b[bp] = byte(i%10) + '0'
  151. }
  152. return string(b[bp:])
  153. }
  154. // Convert i to hexadecimal string.
  155. func itox(i uint) string {
  156. if i == 0 {
  157. return "0"
  158. }
  159. // Assemble hexadecimal in reverse order.
  160. var b [32]byte
  161. bp := len(b)
  162. for ; i > 0; i /= 16 {
  163. bp--
  164. b[bp] = "0123456789abcdef"[byte(i%16)]
  165. }
  166. return string(b[bp:])
  167. }
  168. // String returns the string form of the IP address ip.
  169. // If the address is an IPv4 address, the string representation
  170. // is dotted decimal ("74.125.19.99"). Otherwise the representation
  171. // is IPv6 ("2001:4860:0:2001::68").
  172. func (ip IP) String() string {
  173. p := ip
  174. if len(ip) == 0 {
  175. return ""
  176. }
  177. // If IPv4, use dotted notation.
  178. if p4 := p.To4(); len(p4) == 4 {
  179. return itod(uint(p4[0])) + "." +
  180. itod(uint(p4[1])) + "." +
  181. itod(uint(p4[2])) + "." +
  182. itod(uint(p4[3]))
  183. }
  184. if len(p) != IPv6len {
  185. return "?"
  186. }
  187. // Find longest run of zeros.
  188. e0 := -1
  189. e1 := -1
  190. for i := 0; i < 16; i += 2 {
  191. j := i
  192. for j < 16 && p[j] == 0 && p[j+1] == 0 {
  193. j += 2
  194. }
  195. if j > i && j-i > e1-e0 {
  196. e0 = i
  197. e1 = j
  198. }
  199. }
  200. // Print with possible :: in place of run of zeros
  201. var s string
  202. for i := 0; i < 16; i += 2 {
  203. if i == e0 {
  204. s += "::"
  205. i = e1
  206. if i >= 16 {
  207. break
  208. }
  209. } else if i > 0 {
  210. s += ":"
  211. }
  212. s += itox((uint(p[i]) << 8) | uint(p[i+1]))
  213. }
  214. return s
  215. }
  216. // If mask is a sequence of 1 bits followed by 0 bits,
  217. // return the number of 1 bits.
  218. func simpleMaskLength(mask IPMask) int {
  219. var n int
  220. for i, v := range mask {
  221. if v == 0xff {
  222. n += 8
  223. continue
  224. }
  225. // found non-ff byte
  226. // count 1 bits
  227. for v&0x80 != 0 {
  228. n++
  229. v <<= 1
  230. }
  231. // rest must be 0 bits
  232. if v != 0 {
  233. return -1
  234. }
  235. for i++; i < len(mask); i++ {
  236. if mask[i] != 0 {
  237. return -1
  238. }
  239. }
  240. break
  241. }
  242. return n
  243. }
  244. // String returns the string representation of mask.
  245. // If the mask is in the canonical form--ones followed by zeros--the
  246. // string representation is just the decimal number of ones.
  247. // If the mask is in a non-canonical form, it is formatted
  248. // as an IP address.
  249. func (mask IPMask) String() string {
  250. switch len(mask) {
  251. case 4:
  252. n := simpleMaskLength(mask)
  253. if n >= 0 {
  254. return itod(uint(n + (IPv6len-IPv4len)*8))
  255. }
  256. case 16:
  257. n := simpleMaskLength(mask)
  258. if n >= 12*8 {
  259. return itod(uint(n - 12*8))
  260. }
  261. }
  262. return IP(mask).String()
  263. }
  264. // Parse IPv4 address (d.d.d.d).
  265. func parseIPv4(s string) IP {
  266. var p [IPv4len]byte
  267. i := 0
  268. for j := 0; j < IPv4len; j++ {
  269. if i >= len(s) {
  270. // Missing octets.
  271. return nil
  272. }
  273. if j > 0 {
  274. if s[i] != '.' {
  275. return nil
  276. }
  277. i++
  278. }
  279. var (
  280. n int
  281. ok bool
  282. )
  283. n, i, ok = dtoi(s, i)
  284. if !ok || n > 0xFF {
  285. return nil
  286. }
  287. p[j] = byte(n)
  288. }
  289. if i != len(s) {
  290. return nil
  291. }
  292. return IPv4(p[0], p[1], p[2], p[3])
  293. }
  294. // Parse IPv6 address. Many forms.
  295. // The basic form is a sequence of eight colon-separated
  296. // 16-bit hex numbers separated by colons,
  297. // as in 0123:4567:89ab:cdef:0123:4567:89ab:cdef.
  298. // Two exceptions:
  299. // * A run of zeros can be replaced with "::".
  300. // * The last 32 bits can be in IPv4 form.
  301. // Thus, ::ffff:1.2.3.4 is the IPv4 address 1.2.3.4.
  302. func parseIPv6(s string) IP {
  303. p := make(IP, 16)
  304. ellipsis := -1 // position of ellipsis in p
  305. i := 0 // index in string s
  306. // Might have leading ellipsis
  307. if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
  308. ellipsis = 0
  309. i = 2
  310. // Might be only ellipsis
  311. if i == len(s) {
  312. return p
  313. }
  314. }
  315. // Loop, parsing hex numbers followed by colon.
  316. j := 0
  317. L: for j < IPv6len {
  318. // Hex number.
  319. n, i1, ok := xtoi(s, i)
  320. if !ok || n > 0xFFFF {
  321. return nil
  322. }
  323. // If followed by dot, might be in trailing IPv4.
  324. if i1 < len(s) && s[i1] == '.' {
  325. if ellipsis < 0 && j != IPv6len-IPv4len {
  326. // Not the right place.
  327. return nil
  328. }
  329. if j+IPv4len > IPv6len {
  330. // Not enough room.
  331. return nil
  332. }
  333. p4 := parseIPv4(s[i:])
  334. if p4 == nil {
  335. return nil
  336. }
  337. p[j] = p4[12]
  338. p[j+1] = p4[13]
  339. p[j+2] = p4[14]
  340. p[j+3] = p4[15]
  341. i = len(s)
  342. j += 4
  343. break
  344. }
  345. // Save this 16-bit chunk.
  346. p[j] = byte(n >> 8)
  347. p[j+1] = byte(n)
  348. j += 2
  349. // Stop at end of string.
  350. i = i1
  351. if i == len(s) {
  352. break
  353. }
  354. // Otherwise must be followed by colon and more.
  355. if s[i] != ':' && i+1 == len(s) {
  356. return nil
  357. }
  358. i++
  359. // Look for ellipsis.
  360. if s[i] == ':' {
  361. if ellipsis >= 0 { // already have one
  362. return nil
  363. }
  364. ellipsis = j
  365. if i++; i == len(s) { // can be at end
  366. break
  367. }
  368. }
  369. }
  370. // Must have used entire string.
  371. if i != len(s) {
  372. return nil
  373. }
  374. // If didn't parse enough, expand ellipsis.
  375. if j < IPv6len {
  376. if ellipsis < 0 {
  377. return nil
  378. }
  379. n := IPv6len - j
  380. for k := j - 1; k >= ellipsis; k-- {
  381. p[k+n] = p[k]
  382. }
  383. for k := ellipsis + n - 1; k >= ellipsis; k-- {
  384. p[k] = 0
  385. }
  386. }
  387. return p
  388. }
  389. // ParseIP parses s as an IP address, returning the result.
  390. // The string s can be in dotted decimal ("74.125.19.99")
  391. // or IPv6 ("2001:4860:0:2001::68") form.
  392. // If s is not a valid textual representation of an IP address,
  393. // ParseIP returns nil.
  394. func ParseIP(s string) IP {
  395. p := parseIPv4(s)
  396. if p != nil {
  397. return p
  398. }
  399. return parseIPv6(s)
  400. }