github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/ipv4/addr.go (about) 1 /* For license and copyright information please see LEGAL file in repository */ 2 3 package ipv4 4 5 import "../protocol" 6 7 // An Addr is an IP address version 4. 8 type Addr [Addrlen]byte 9 10 const ( 11 // Addrlen address lengths 32 bit equal 4 byte. 12 Addrlen = 4 13 ) 14 15 // Well-known IPv4 addresses 16 var ( 17 AddrZero = Addr{0, 0, 0, 0} // all zeros 18 AddrAllRouters = Addr{224, 0, 0, 2} // all routers 19 AddrAllSystems = Addr{224, 0, 0, 1} // all systems 20 AddrBroadcast = Addr{255, 255, 255, 255} // limited broadcast 21 22 v4InV6Prefix = [12]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff} 23 ) 24 25 // ToIPv6 returns the IPv4 address in 16-byte form 26 func (addr Addr) ToIPv6() (v6 [16]byte) { 27 copy(v6[:], v4InV6Prefix) 28 copy(v6[12:], addr[:]) 29 return 30 } 31 32 func (addr Addr) ToString() string { 33 const maxIPv4StringLen = len("255.255.255.255") 34 var b = make([]byte, maxIPv4StringLen) 35 36 var n = ubtoa(b, 0, addr[0]) 37 b[n] = '.' 38 n++ 39 40 n += ubtoa(b, n, addr[1]) 41 b[n] = '.' 42 n++ 43 44 n += ubtoa(b, n, addr[2]) 45 b[n] = '.' 46 n++ 47 48 n += ubtoa(b, n, addr[3]) 49 return string(b[:n]) 50 } 51 52 func (addr *Addr) FromString(ipv4 string) (err protocol.Error) { 53 for i := 0; i < Addrlen; i++ { 54 if len(ipv4) == 0 { 55 // err = Missing octets 56 return 57 } 58 if i > 0 { 59 if ipv4[0] != '.' { 60 // err = 61 return 62 } 63 ipv4 = ipv4[1:] 64 } 65 n, c, ok := dtoi(ipv4) 66 if !ok || n > 0xFF { 67 // err = 68 return 69 } 70 if c > 1 && ipv4[0] == '0' { 71 // err = Reject non-zero components with leading zeroes. 72 return 73 } 74 ipv4 = ipv4[c:] 75 *addr[i] = byte(n) 76 } 77 if len(ipv4) != 0 { 78 // Mask?? 79 // err = 80 } 81 return 82 } 83 84 // ubtoa encodes the string form of the integer v to dst[start:] and 85 // returns the number of bytes written to dst. The caller must ensure 86 // that dst has sufficient length. 87 func ubtoa(dst []byte, start int, v byte) int { 88 if v < 10 { 89 dst[start] = v + '0' 90 return 1 91 } else if v < 100 { 92 dst[start+1] = v%10 + '0' 93 dst[start] = v/10 + '0' 94 return 2 95 } 96 97 dst[start+2] = v%10 + '0' 98 dst[start+1] = (v/10)%10 + '0' 99 dst[start] = v/100 + '0' 100 return 3 101 } 102 103 // Decimal to integer. 104 // Returns number, characters consumed, success. 105 func dtoi(s string) (n int, i int, ok bool) { 106 n = 0 107 for i = 0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ { 108 n = n*10 + int(s[i]-'0') 109 if n >= big { 110 return big, i, false 111 } 112 } 113 if i == 0 { 114 return 0, 0, false 115 } 116 return n, i, true 117 }